def backup_guard_recurse(pool, class_nr): """Recurse version tower of hanoi backup rotation scheme for ZFS: http://en.wikipedia.org/wiki/Backup_rotation_scheme#Tower_of_Hanoi Snapshots are taken atomically, so that all recursive snapshots corre- spond to the same moment in time. :param fs: zpool name to backup (snapshot make also for all child zfs) :type fs: str :param class_nr: number of class used for rotation :type class_nr: int :raises: zfswrapper.ZfsException """ # tag for new snapshot snp_tag = _gen_snapshot_tag() unknown_label = 'unknown' unknown_control_nr = 'X' # make new recursive snapshot - if problem ZfsException is throw zfs.zfs_snapshot(fs=pool, tag=snp_tag, recurse=True, properties={_backup_property:unknown_label, _backup_control_nr:unknown_control_nr}) # get all filesystem given pool all_fs = zfs.zfs_list(fs=pool, types='filesystem') or [] for fs in all_fs: print 'fs', fs ## Note: you can set class_num per filesystem, exclude some zfs filesystems, e.g. pool # get all snapshots given fs fs_snapshots = zfs.zfs_list(fs=fs, types='snapshot') or [] # get list of snapshots and properties sorted by creation time. First is allready taken snapshot. srt_snapshots = _get_current_hanoi_state(fs, fs_snapshots)[1:] # get control number - useful for debuging and checking hanoi rotation scheme _hanoi_builder(fs, snp_tag, class_nr, srt_snapshots, recurse=True)
def test_zfs_list_defined_types(self): """zfs_list with defined types - return list all 'types' for given fs""" expected_fs = ["unittest01/mine01@coal001", "unittest01/mine01@coal002", "unittest01/mine02@copper001"] not_expected_fs = ["unittest01", "unittest01/mine01", "unittest01/mine02", "unittest01/mine03"] zlist = zfs.zfs_list(types="snapshot") for fs in expected_fs: self.assertTrue(fs in zlist) for fs in not_expected_fs: self.assertFalse(fs in zlist)
def test_zfs_list_defined_fs(self): """zfs_list with defined fs - return list only filesystems and snapshots given fs""" expected_fs = ["unittest01/mine01", "unittest01/mine01@coal001", "unittest01/mine01@coal002"] not_expected_fs = ["unittest01", "unittest01/mine02", "unittest01/mine03", "unittest01/mine02@copper001"] zlist = zfs.zfs_list(fs="unittest01/mine01") for fs in expected_fs: self.assertTrue(fs in zlist) for fs in not_expected_fs: self.assertFalse(fs in zlist)
def test_zfs_list(self): """zfs_list without args - return list all filesystems and snapshots. By default volumes are not included.""" expected_fs = [ "unittest01", "unittest01/mine01", "unittest01/mine02", "unittest01/mine03", "unittest01/mine01@coal001", "unittest01/mine01@coal002", "unittest01/mine02@copper001", ] zlist = zfs.zfs_list() for fs in expected_fs: self.assertTrue(fs in zlist)
def backup_guard(fs, class_nr): """Guard tower of hanoi backup rotation scheme for ZFS: http://en.wikipedia.org/wiki/Backup_rotation_scheme#Tower_of_Hanoi .. note:: It cover [2^(n-2)+1; 2^(n-1)] days/time_units, where n is class_nr. Fast calculation: 26 classes cover at least 2^24 + 1 = 16777217 time_units :param fs: zfs filesystem/volume name to backup :type fs: str :param class_nr: number of class used for rotation :type class_nr: int :raises: zfswrapper.ZfsException """ # tag for new snapshot snp_tag = _gen_snapshot_tag() # get all snapshots given fs all_snapshots = zfs.zfs_list(fs=fs, types='snapshot') or [] # get list of snapshots and properties sorted by creation time. srt_snapshots = _get_current_hanoi_state(fs, all_snapshots) _hanoi_builder(fs, snp_tag, class_nr, srt_snapshots)
def create_filesystem(zfs_scheme): """Creates zfs datasets from given zfs_scheme. :param zfs_scheme: python reprezentation of zfs datasets :type zfs_scheme: dict :raises: zfswrapper.ZfsException """ for zpool in zfs_scheme: # extract discs from vdev description reserved = ['mirror', 'raidz[0-9]*', 'spare', 'log', 'cache'] regex = re.compile(r'|'.join(reserved)) vdev = zfs_scheme[zpool]['vdev'] discs = filter(lambda x: not regex.search(x), vdev) # create discs to play for disc in discs: create_disc(disc) time.sleep(0.5) # create zpool if not zfs.zpool_list(zpool): zfs.zpool_create(zpool, vdev) # create zfs for fs in zfs_scheme[zpool]['fs']: if not zfs.zfs_list(fs['name']): zfs.zfs_create(fs['name'])
def replication_simulator(): """Demo - send and receive snapshot. .. warning:: recv_fs can't exist on recv_host, otherwise error is risen """ send_fs = "galaxy01/fleet11" send_tag = "satellite-red01" to_send = "%s@%s" % (send_fs, send_tag) # create local snapshot to teleport if not exist if not zfs.zfs_list(fs=to_send): zfs.zfs_snapshot(send_fs, send_tag) # Remote repl. - using ssh recv_fs = "galaxy_slave01/fleet11_alfa" # recv_fs = 'galaxy_slave01/fleet11_beta' zfs.zfs_teleport_snapshot(to_send, recv_fs, recv_host="zepto") # Local repl. recv_fs = "galaxy02/fleet11_alfa" # recv_fs = 'galaxy02/fleet11_beta' zfs.zfs_teleport_snapshot(to_send, recv_fs)
def test_zfs_list_not_existing_fs(self): """zfs_list return None if given fs not exist""" zlist = zfs.zfs_list(fs="non_existing_filesystem") self.assertEqual(zlist, None)