Class: ZFS::Snapshot

Inherits:
ZFS
  • Object
show all
Defined in:
lib/zfs.rb

Instance Attribute Summary

Attributes inherited from ZFS

#name, #path, #pool

Instance Method Summary collapse

Methods inherited from ZFS

#==, #[], #[]=, #children, #create, #destroy!, #exist?, #initialize, mounts, pools, property, #to_s

Constructor Details

This class inherits a constructor from ZFS

Instance Method Details

#+(path) ⇒ Object

Return sub-filesystem

Raises:



328
329
330
331
332
# File 'lib/zfs.rb', line 328

def +(path)
	raise InvalidName if path.match(/@/)

	parent + path + name.sub(/^.+@/, '@')
end

#clone!(clone, opts = {}) ⇒ Object

Clone snapshot

Raises:



361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
# File 'lib/zfs.rb', line 361

def clone!(clone, opts={})
	clone = clone.name if clone.is_a? ZFS

	raise AlreadyExists if ZFS(clone).exist?

	cmd = [ZFS.zfs_path].flatten + ['clone']
	cmd << '-p' if opts[:parents]
	cmd << name
	cmd << clone

	out, status = Open3.capture2e(*cmd)

	if status.success? and out.empty?
		return ZFS(clone)
	else
		raise Exception, "something went wrong"
	end
end

#parentObject

Just remove the snapshot-name



335
336
337
# File 'lib/zfs.rb', line 335

def parent
	ZFS(name.sub(/@.+/, ''))
end

#rename!(newname, opts = {}) ⇒ Object

Rename snapshot

Raises:



340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
# File 'lib/zfs.rb', line 340

def rename!(newname, opts={})
	raise AlreadyExists if (parent + "@#{newname}").exist?

	newname = (parent + "@#{newname}").name

	cmd = [ZFS.zfs_path].flatten + ['rename']
	cmd << '-r' if opts[:children]
	cmd << name
	cmd << newname

	out, status = Open3.capture2e(*cmd)

	if status.success? and out.empty?
		initialize(newname)
		return self
	else
		raise Exception, "something went wrong"
	end
end

#send_to(dest, opts = {}) ⇒ Object

Send snapshot to another filesystem



381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
# File 'lib/zfs.rb', line 381

def send_to(dest, opts={})
	incr_snap = nil
	dest = ZFS(dest)

	if opts[:incremental] and opts[:intermediary]
		raise ArgumentError, "can't specify both :incremental and :intermediary"
	end

	incr_snap = opts[:incremental] || opts[:intermediary]
	if incr_snap
		if incr_snap.is_a? String and incr_snap.match(/^@/)
			incr_snap = self.parent + incr_snap
		else
			incr_snap = ZFS(incr_snap)
			raise ArgumentError, "incremental snapshot must be in the same filesystem as #{self}" if incr_snap.parent != self.parent
		end

		snapname = incr_snap.name.sub(/^.+@/, '@')

		raise NotFound, "destination must already exist when receiving incremental stream" unless dest.exist?
		raise NotFound, "snapshot #{snapname} must exist at #{self.parent}" if self.parent.snapshots.grep(incr_snap).empty?
		raise NotFound, "snapshot #{snapname} must exist at #{dest}" if dest.snapshots.grep(dest + snapname).empty?
	elsif opts[:use_sent_name]
		raise NotFound, "destination must already exist when using sent name" unless dest.exist?
	elsif dest.exist?
		raise AlreadyExists, "destination must not exist when receiving full stream"
	end

	dest = dest.name if dest.is_a? ZFS
	incr_snap = incr_snap.name if incr_snap.is_a? ZFS

	send_opts = ZFS.zfs_path.flatten + ['send']
	send_opts.concat ['-i', incr_snap] if opts[:incremental]
	send_opts.concat ['-I', incr_snap] if opts[:intermediary]
	send_opts << '-R' if opts[:replication]
	send_opts << name

	receive_opts = ZFS.zfs_path.flatten + ['receive']
	receive_opts << '-d' if opts[:use_sent_name]
	receive_opts << dest

	Open3.popen3(*receive_opts) do |rstdin, rstdout, rstderr, rthr|
		Open3.popen3(*send_opts) do |sstdin, sstdout, sstderr, sthr|
			while !sstdout.eof?
				rstdin.write(sstdout.read(16384))
			end
			raise "stink" unless sstderr.read == ''
		end
	end
end