def create_snap(dataset, quiet=False): ''' ''' zettaknight_utils.zlog("create_snap started", "DEBUG") zettaknight_utils.check_quiet(quiet) snap = "{0}@{1}".format(dataset, zettaknight_globs.today_date) snap_list = zettaknight_utils.spawn_job("/sbin/zfs list -r -t snapshot -o name -H {0}".format(snap)) if int(0) not in snap_list.iterkeys(): ret = zettaknight_utils.spawn_job("/sbin/zfs snapshot -r {0}".format(snap)) else: ret = {0: "Snapshot {0} already exists.".format(snap)} zettaknight_utils.zlog("snapshot {0} already exists".format(snap), "INFO") for exit_status, output in ret.iteritems(): if str(exit_status) == "0" and str(output) == "Job succeeded": ret[exit_status] = "Snapshot created: {0}".format(snap) zettaknight_utils.zlog("snapshot created: {0}".format(snap), "SUCCESS") if not quiet: snap_out = {} snap_out[dataset] = {} snap_out[dataset][inspect.stack()[0][3]] = ret zettaknight_utils.parse_output(snap_out) zettaknight_utils.zlog("create_snap exiting", "DEBUG") return ret
def create_snap(dataset, quiet=False): ''' ''' zettaknight_utils.zlog("create_snap started", "DEBUG") zettaknight_utils.check_quiet(quiet) snap = "{0}@{1}".format(dataset, zettaknight_globs.today_date) snap_list = zettaknight_utils.spawn_job( "/sbin/zfs list -r -t snapshot -o name -H {0}".format(snap)) if int(0) not in snap_list.iterkeys(): ret = zettaknight_utils.spawn_job( "/sbin/zfs snapshot -r {0}".format(snap)) else: ret = {0: "Snapshot {0} already exists.".format(snap)} zettaknight_utils.zlog("snapshot {0} already exists".format(snap), "INFO") for exit_status, output in ret.iteritems(): if str(exit_status) == "0" and str(output) == "Job succeeded": ret[exit_status] = "Snapshot created: {0}".format(snap) zettaknight_utils.zlog("snapshot created: {0}".format(snap), "SUCCESS") if not quiet: snap_out = {} snap_out[dataset] = {} snap_out[dataset][inspect.stack()[0][3]] = ret zettaknight_utils.parse_output(snap_out) zettaknight_utils.zlog("create_snap exiting", "DEBUG") return ret
def scrub(pool): ''' initiates a scrub of the pool ''' ret = {} if zettaknight_globs.help_flag: ret = """Scrub: Initiates a scrub of provided pool. Usage: zettaknight scrub <pool> Required Arguments: pool Specifies the pool to scrub.""" return ret ret[pool] = {} ret[pool]['Scrub'] = {} scrub_cmd = "/sbin/zpool scrub {0}".format(pool) scrub_run = zettaknight_utils.spawn_job(scrub_cmd) for k,v in scrub_run.iteritems(): if str(k) is "0": ret[pool]['Scrub']['0'] = "Scrub initiated." else: ret[pool]['Scrub']['1'] = v zettaknight_utils.parse_output(ret) return ret
def scrub(pool): ''' initiates a scrub of the pool ''' ret = {} if zettaknight_globs.help_flag: ret = """Scrub: Initiates a scrub of provided pool. Usage: zettaknight scrub <pool> Required Arguments: pool Specifies the pool to scrub.""" return ret ret[pool] = {} ret[pool]['Scrub'] = {} scrub_cmd = "/sbin/zpool scrub {0}".format(pool) scrub_run = zettaknight_utils.spawn_job(scrub_cmd) for k, v in scrub_run.iteritems(): if str(k) is "0": ret[pool]['Scrub']['0'] = "Scrub initiated." else: ret[pool]['Scrub']['1'] = v zettaknight_utils.parse_output(ret) return ret
def create_snap(dataset, quiet=False): ''' ''' zettaknight_utils.check_quiet(quiet) snap = "{0}@{1}".format(dataset, zettaknight_globs.today_date) gerp_run = zettaknight_utils.pipe_this2("/sbin/zfs list -r -t snapshot -o name -H {0} | /bin/grep {1}".format(dataset, snap)) gerp_out = gerp_run.stdout.read() if int(gerp_run.returncode) is not 0: ret = zettaknight_utils.spawn_job("/sbin/zfs snapshot -r {0}".format(snap)) if int(gerp_run.returncode) == 0: ret = {0: "Snapshot {0} already exists.".format(snap)} for exit_status, output in ret.iteritems(): if str(exit_status) == "0" and str(output) == "Job succeeded": ret[exit_status] = "Snapshot created: {0}".format(snap) if not quiet: snap_out = {} snap_out[dataset] = {} snap_out[dataset][inspect.stack()[0][3]] = ret zettaknight_utils.parse_output(snap_out) return ret
def get_cifs_quota(**kwargs): ''' get quota for user or group cifs share. ''' if zettaknight_globs.help_flag: ret = """Get CIFS Quota: Function to get and display quota on a user or group CIFS share. Arguments should be passed as key/value pairs. Required Arguments: user or group Specifies the username or group name tied to the relevant share to set the quota on. Optional Arguments: dataset Specifies the parent dataset to search for the share under. If not specified, the default will be pulled from Zettaknight conf files""" return ret ret = {} user = False group = False try: if kwargs and kwargs['dataset']: dataset = kwargs['dataset'] except: dataset = "{0}/{1}".format(zettaknight_globs.pool_name, zettaknight_globs.cifs_dset_suffix) pass if kwargs and "user" in kwargs.iterkeys(): user = kwargs['user'] if kwargs and "group" in kwargs.iterkeys(): group = kwargs['group'] if user and group: ret[dataset] = {} try: raise Exception( "Arguments user and group must be specified separately. Arguments passed: {0}" .format(kwargs)) except Exception as e: ret[dataset]['Get User Quota'] = {1: e} zettaknight_utils.parse_output(ret) return ret if user: dset = "{0}/{1}".format(dataset, user) elif group: dset = "{0}/{1}".format(dataset, group) ret[dset] = {} quota_cmd = "/sbin/zfs get refquota -H {0} -o value".format(dset) ret[dset]['Get User Quota'] = zettaknight_utils.spawn_job(quota_cmd) return ret
def create_zpool(pool=False, disk_list=False, raid=False, luks=False, slog=False, create_config=False, ldap=False, recordsize=False, ashift=False, keyfile=False): ret = {} ret[pool] = {} ret[pool]['Create Zpool'] = {} if not raid: raid = "12+2" try: disks, z_level = raid.split("+") except Exception as e: ret[pool]['Create Zpool'] = {'1': "{0}\nargument raid must be in x+y format, i.e. 2+1".format(e)} zettaknight_utils.parse_output(ret) sys.exit(0) create_cmd = "bash {0} -d {1} -z {2}".format(zettaknight_globs.zpool_create_script, disks, z_level) if disk_list: create_cmd = "{0} -f '{1}'".format(create_cmd, disk_list) if pool: create_cmd = "{0} -p '{1}'".format(create_cmd, pool) if luks: create_cmd = "{0} -l".format(create_cmd) if slog: create_cmd = "{0} -s '{1}'".format(create_cmd, slog) if ldap: create_cmd = "{0} -i".format(create_cmd) if recordsize: if any(i in recordsize for i in 'KM'): create_cmd = "{0} -r {1}".format(create_cmd, recordsize) else: print(zettaknight_utils.printcolors("Recordsize must be in number/unit format. ie. 1M, or 512K", "FAIL")) sys.exit(0) if ashift: create_cmd = "{0} -a {1}".format(create_cmd, ashift) if keyfile: create_cmd = "{0} -k {1}".format(create_cmd, keyfile) try: ret[pool]['Create Zpool'] = zettaknight_utils.spawn_job(create_cmd) zettaknight_utils.parse_output(ret) if create_config: zettaknight_utils.create_config(pool) except Exception as e: print(zettaknight_utils.printcolors(e, "FAIL")) sys.exit(0) return ret
def get_cifs_quota(**kwargs): ''' get quota for user or group cifs share. ''' if zettaknight_globs.help_flag: ret = """Get CIFS Quota: Function to get and display quota on a user or group CIFS share. Arguments should be passed as key/value pairs. Required Arguments: user or group Specifies the username or group name tied to the relevant share to set the quota on. Optional Arguments: dataset Specifies the parent dataset to search for the share under. If not specified, the default will be pulled from Zettaknight conf files""" return ret ret = {} user = False group = False try: if kwargs and kwargs['dataset']: dataset = kwargs['dataset'] except: dataset = "{0}/{1}".format(zettaknight_globs.pool_name, zettaknight_globs.cifs_dset_suffix) pass if kwargs and "user" in kwargs.iterkeys(): user = kwargs['user'] if kwargs and "group" in kwargs.iterkeys(): group = kwargs['group'] if user and group: ret[dataset] = {} try: raise Exception("Arguments user and group must be specified separately. Arguments passed: {0}".format(kwargs)) except Exception as e: ret[dataset]['Get User Quota'] = {1: e} zettaknight_utils.parse_output(ret) return ret if user: dset = "{0}/{1}".format(dataset, user) elif group: dset = "{0}/{1}".format(dataset, group) ret[dset] = {} quota_cmd = "/sbin/zfs get refquota -H {0} -o value".format(dset) ret[dset]['Get User Quota'] = zettaknight_utils.spawn_job(quota_cmd) return ret
def get_cifs_share(**kwargs): ''' get quota for user or group cifs share. ''' ret = {} user = False group = False try: if kwargs and kwargs['dataset']: dataset = kwargs['dataset'] except: dataset = "{0}/{1}".format(zettaknight_globs.pool_name, zettaknight_globs.cifs_dset_suffix) pass if kwargs and "user" in kwargs.iterkeys(): user = kwargs['user'] if kwargs and "group" in kwargs.iterkeys(): group = kwargs['group'] if user and group: ret[dataset] = {} try: raise Exception("Arguments user and group must be specified separately. Arguments passed: {0}".format(kwargs)) except Exception as e: ret[dataset]['Get User Quota'] = {1: e} zettaknight_utils.parse_output(ret) return ret if user: dset = "{0}/{1}".format(dataset, user) elif group: dset = "{0}/{1}".format(dataset, group) ret[dset] = {} quota_cmd = "/sbin/zfs list -H {0} -o name".format(dset) #ret[dset]['Get User Share'] = zettaknight_utils.spawn_job(quota_cmd) job_out = zettaknight_utils.spawn_job(quota_cmd) print("JOB OUT: {0}".format(job_out)) if 0 in job_out.iterkeys(): job_out[0] = "//{0}/{1}/{2}".format(str(zettaknight_globs.samba_service_name), str(zettaknight_globs.samba_share_suffix), str(user)) print("JOB OUT: {0}".format(job_out)) ret[dset]['Get User Share'] = job_out return ret
def zfs_monitor(email_recipients, protocol=False): ret = {} ret[zettaknight_globs.fqdn] = {} protocol = "ssh" for dataset in zettaknight_globs.zfs_conf.iterkeys(): if str(zettaknight_globs.zfs_conf[dataset]['secure']) == "False": protocol = "xinetd" monitor_cmd = "bash {0} -r \"{1}\" -p \"{2}\"".format(zettaknight_globs.zfs_monitor_script, email_recipients, protocol) ret[zettaknight_globs.fqdn]['Monitor ZFS System Health'] = zettaknight_utils.spawn_job(monitor_cmd) zettaknight_utils.parse_output(ret) return ret
def scrub(pool): ''' initiates a scrub of the pool ''' ret = {} ret[pool] = {} ret[pool]['Scrub'] = {} scrub_cmd = "/sbin/zpool scrub {0}".format(pool) scrub_run = zettaknight_utils.spawn_job(scrub_cmd) for k,v in scrub_run.iteritems(): if str(k) is "0": ret[pool]['Scrub']['0'] = "Scrub initiated." else: ret[pool]['Scrub']['1'] = v zettaknight_utils.parse_output(ret) return ret
def get_cifs_quota(**kwargs): ''' get quota for user or group cifs share. ''' ret = {} user = False group = False try: if kwargs and kwargs['dataset']: dataset = kwargs['dataset'] except: dataset = "{0}/{1}".format(zettaknight_globs.pool_name, zettaknight_globs.cifs_dset_suffix) pass if kwargs and "user" in kwargs.iterkeys(): user = kwargs['user'] if kwargs and "group" in kwargs.iterkeys(): group = kwargs['group'] if user and group: ret[dataset] = {} try: raise Exception("Arguments user and group must be specified separately. Arguments passed: {0}".format(kwargs)) except Exception as e: ret[dataset]['Get User Quota'] = {1: e} zettaknight_utils.parse_output(ret) return ret if user: dset = "{0}/{1}".format(dataset, user) elif group: dset = "{0}/{1}".format(dataset, group) ret[dset] = {} quota_cmd = "/sbin/zfs get quota -H {0} -o value".format(dset) ret[dset]['Get User Quota'] = zettaknight_utils.spawn_job(quota_cmd) return ret
def failover(dataset, remote_server=False): ''' ''' ret = {} ret[dataset] = {} ret[dataset]['Failover'] = {} try: user = zettaknight_globs.zfs_conf[dataset]['user'] secure = zettaknight_globs.zfs_conf[dataset]['secure'] except Exception as e: ret[dataset]['Failover']['1'] = "Dataset: {0} not configured in configuration file.".format(dataset) zettaknight_utils.parse_output(ret) sys.exit(0) try: if not remote_server: remote_server = zettaknight_globs.zfs_conf[dataset]['snap']['remote_server'] if isinstance(remote_server, list): if len(remote_server) > 1: raise Exception("Multiple remote servers defined in configuration.") except Exception as e: ret[dataset]['Failover']['1'] = "{0}\nRemote servers defined:\n - {1}\nRe-run with explicit remote server to failover to.".format(e, list(zettaknight_globs.zfs_conf[dataset]['snap']['remote_server'])) zettaknight_utils.parse_output(ret) sys.exit(0) snap_cmd = "bash {0} -d {1} -s {2}@{3} -i {4} -f".format(zettaknight_globs.snap_script, dataset, user, remote_server[0], zettaknight_globs.identity_file) if secure: snap_cmd = "{0} -e".format(snap_cmd) ret[dataset]['Failover'] = zettaknight_utils.spawn_job(snap_cmd) zettaknight_utils.parse_output(ret) return ret
def failover(dataset, remote_server=False): ''' ''' ret = {} if zettaknight_globs.help_flag: ret = """Failover: Attempts a controlled failover for provided dataset to remote host defined in configuration files. Usage: zettaknight failover <dataset> Required Arguments: dataset Specifies the dataset to fail over. Optional Arguments: remote_server Specifies a remote server to attempt a failover to. By default, this information is pulled from dataset configuration files.""" return ret ret[dataset] = {} ret[dataset]['Failover'] = {} try: user = zettaknight_globs.zfs_conf[dataset]['user'] secure = zettaknight_globs.zfs_conf[dataset]['secure'] except Exception as e: ret[dataset]['Failover']['1'] = "Dataset: {0} not configured in configuration file.".format(dataset) zettaknight_utils.parse_output(ret) sys.exit(0) try: if not remote_server: remote_server = zettaknight_globs.zfs_conf[dataset]['snap']['remote_server'] if isinstance(remote_server, list): if len(remote_server) > 1: raise Exception("Multiple remote servers defined in configuration.") except Exception as e: ret[dataset]['Failover']['1'] = "{0}\nRemote servers defined:\n - {1}\nRe-run with explicit remote server to failover to.".format(e, list(zettaknight_globs.zfs_conf[dataset]['snap']['remote_server'])) zettaknight_utils.parse_output(ret) sys.exit(0) snap_cmd = "bash {0} -d {1} -s {2}@{3} -i {4} -f".format(zettaknight_globs.snap_script, dataset, user, remote_server[0], zettaknight_globs.identity_file) if secure: snap_cmd = "{0} -e".format(snap_cmd) ret[dataset]['Failover'] = zettaknight_utils.spawn_job(snap_cmd) zettaknight_utils.parse_output(ret) return ret
def create_cifs_share(**kwargs): ''' Creates a zfs dataset for a given user or group. ''' ret = {} user = False group = False if kwargs: try: if kwargs['dataset']: dataset = kwargs['dataset'] except: dataset = "{0}/{1}".format(zettaknight_globs.pool_name, zettaknight_globs.cifs_dset_suffix) pass if kwargs and "user" in kwargs.iterkeys(): user = kwargs['user'] if kwargs and "group" in kwargs.iterkeys(): group = kwargs['group'] ret[dataset] = {} if user and group: try: raise Exception("Arguments user and group must be specified separately. Arguments passed: {0}".format(kwargs)) except Exception as e: ret[dataset]['Create CIFS Share'] = {1: e} zettaknight_utils.parse_output(ret) return ret if user: cifs_cmd = "{0} -u {1} -d {2}".format(zettaknight_globs.cifs_share_script, user, dataset) if group: cifs_cmd = "{0} -g {1} -d {2}".format(zettaknight_globs.cifs_share_script, group, dataset) if user: obj = user elif group: obj = group try: if str(zettaknight_globs.zfs_conf[dataset]['primary']) == str(zettaknight_globs.fqdn): if zettaknight_globs.zfs_conf[dataset]['snap']['remote_server']: for remote_server in zettaknight_globs.zfs_conf[dataset]['snap']['remote_server']: remote_user = zettaknight_globs.zfs_conf[dataset]['user'] remote_ssh = "{0}@{1}".format(remote_user, remote_server) try: ssh2 = paramiko.SSHClient() ssh2.set_missing_host_key_policy(paramiko.AutoAddPolicy()) ssh2.connect(remote_server, username=remote_user, key_filename=zettaknight_globs.identity_file) remote_cmd = "zettaknight create_cifs_share user={0} dataset={1}".format(obj, dataset) ssh2_stdin, ssh2_stdout, ssh2_stderr = ssh2.exec_command(remote_cmd) ssh2.close() except Exception as e: pass except: pass try: ret[dataset]['Create CIFS Share'] = zettaknight_utils.spawn_job(cifs_cmd) except Exception as e: ret[dataset]['Create CIFS Share'] = {1: e} #zettaknight_utils.parse_output(ret) return ret
def create_cifs_share(**kwargs): ''' Creates a zfs dataset for a given user or group. ''' ret = {} if zettaknight_globs.help_flag: ret = """Create CIFS Share: Function to create a new directory with proper permissions for user/group access over CIFS on primary and secondary ZFS servers. Arguments should be passed as key/value pairs. Required Arguments: user or group Specifies the username or group name to create the share for. Optional Arguments: dataset Specifies the parent dataset to create the share under. If not specified, the default will be pulled from Zettaknight conf files""" return ret user = False group = False if kwargs: try: if kwargs['dataset']: dataset = kwargs['dataset'] except: dataset = "{0}/{1}".format(zettaknight_globs.pool_name, zettaknight_globs.cifs_dset_suffix) pass if kwargs and "user" in kwargs.iterkeys(): user = kwargs['user'] if kwargs and "group" in kwargs.iterkeys(): group = kwargs['group'] ret[dataset] = {} if user and group: try: raise Exception("Arguments user and group must be specified separately. Arguments passed: {0}".format(kwargs)) except Exception as e: ret[dataset]['Create CIFS Share'] = {1: e} zettaknight_utils.parse_output(ret) return ret if user: cifs_cmd = "{0} -u {1} -d {2}".format(zettaknight_globs.cifs_share_script, user, dataset) if group: cifs_cmd = "{0} -g {1} -d {2}".format(zettaknight_globs.cifs_share_script, group, dataset) if user: obj = user elif group: obj = group try: if str(zettaknight_globs.zfs_conf[dataset]['primary']) == str(zettaknight_globs.fqdn): if zettaknight_globs.zfs_conf[dataset]['snap']['remote_server']: for remote_server in zettaknight_globs.zfs_conf[dataset]['snap']['remote_server']: remote_user = zettaknight_globs.zfs_conf[dataset]['user'] remote_ssh = "{0}@{1}".format(remote_user, remote_server) try: ssh2 = paramiko.SSHClient() ssh2.set_missing_host_key_policy(paramiko.AutoAddPolicy()) ssh2.connect(remote_server, username=remote_user, key_filename=zettaknight_globs.identity_file) remote_cmd = "zettaknight create_cifs_share user={0} dataset={1}".format(obj, dataset) ssh2_stdin, ssh2_stdout, ssh2_stderr = ssh2.exec_command(remote_cmd) ssh2.close() except Exception as e: pass except: pass try: ret[dataset]['Create CIFS Share'] = zettaknight_utils.spawn_job(cifs_cmd) except Exception as e: ret[dataset]['Create CIFS Share'] = {1: e} #zettaknight_utils.parse_output(ret) return ret
def get_cifs_share(**kwargs): ''' get quota for user or group cifs share. ''' if zettaknight_globs.help_flag: ret = """Get CIFS Share: Returns location UNC path of CIFS share for provided user or group. Arguments should be passed as key/value pairs. Required Arguments: user or group Specifies the username or group name to query. Optional Arguments: dataset Specifies the parent dataset to query for the share under. If not specified, the default will be pulled from Zettaknight conf files""" return ret ret = {} user = False group = False try: if kwargs and kwargs['dataset']: dataset = kwargs['dataset'] except: dataset = "{0}/{1}".format(zettaknight_globs.pool_name, zettaknight_globs.cifs_dset_suffix) pass if kwargs and "user" in kwargs.iterkeys(): user = kwargs['user'] if kwargs and "group" in kwargs.iterkeys(): group = kwargs['group'] if user and group: ret[dataset] = {} try: raise Exception("Arguments user and group must be specified separately. Arguments passed: {0}".format(kwargs)) except Exception as e: ret[dataset]['Get User Quota'] = {1: e} zettaknight_utils.parse_output(ret) return ret if user: dset = "{0}/{1}".format(dataset, user) elif group: dset = "{0}/{1}".format(dataset, group) ret[dset] = {} quota_cmd = "/sbin/zfs list -H {0} -o name".format(dset) #ret[dset]['Get User Share'] = zettaknight_utils.spawn_job(quota_cmd) job_out = zettaknight_utils.spawn_job(quota_cmd) print("JOB OUT: {0}".format(job_out)) if 0 in job_out.iterkeys(): job_out[0] = "//{0}/{1}/{2}".format(str(zettaknight_globs.samba_service_name), str(zettaknight_globs.samba_share_suffix), str(user)) print("JOB OUT: {0}".format(job_out)) ret[dset]['Get User Share'] = job_out return ret
def get_cifs_share(**kwargs): ''' get quota for user or group cifs share. ''' if zettaknight_globs.help_flag: ret = """Get CIFS Share: Returns location UNC path of CIFS share for provided user or group. Arguments should be passed as key/value pairs. Required Arguments: user or group Specifies the username or group name to query. Optional Arguments: dataset Specifies the parent dataset to query for the share under. If not specified, the default will be pulled from Zettaknight conf files""" return ret ret = {} user = False group = False try: if kwargs and kwargs['dataset']: dataset = kwargs['dataset'] except: dataset = "{0}/{1}".format(zettaknight_globs.pool_name, zettaknight_globs.cifs_dset_suffix) pass if kwargs and "user" in kwargs.iterkeys(): user = kwargs['user'] if kwargs and "group" in kwargs.iterkeys(): group = kwargs['group'] if user and group: ret[dataset] = {} try: raise Exception( "Arguments user and group must be specified separately. Arguments passed: {0}" .format(kwargs)) except Exception as e: ret[dataset]['Get User Quota'] = {1: e} zettaknight_utils.parse_output(ret) return ret if user: dset = "{0}/{1}".format(dataset, user) elif group: dset = "{0}/{1}".format(dataset, group) ret[dset] = {} quota_cmd = "/sbin/zfs list -H {0} -o name".format(dset) #ret[dset]['Get User Share'] = zettaknight_utils.spawn_job(quota_cmd) job_out = zettaknight_utils.spawn_job(quota_cmd) print("JOB OUT: {0}".format(job_out)) if 0 in job_out.iterkeys(): job_out[0] = "//{0}/{1}/{2}".format( str(zettaknight_globs.samba_service_name), str(zettaknight_globs.samba_share_suffix), str(user)) print("JOB OUT: {0}".format(job_out)) ret[dset]['Get User Share'] = job_out return ret
def set_cifs_quota(**kwargs): ''' Set quota for user or group cifs share. ''' ret = {} if zettaknight_globs.help_flag: ret = """Set CIFS Quota: Function to set a quota on a user or group CIFS share. Sets the quota on primary and secondary ZFS servers. Arguments should be passed as key/value pairs. Required Arguments: user or group Specifies the username or group name tied to the relevant share to set the quota on. quota Quota to be set. Should be specified with a number and unit, ie. 10T, 100G, 10M. 'None' should be specified to remove the quota. Optional Arguments: dataset Specifies the parent dataset to search for the share under. If not specified, the default will be pulled from Zettaknight conf files""" return ret user = False group = False quota = False try: if kwargs and kwargs['dataset']: dataset = kwargs['dataset'] except: dataset = "{0}/{1}".format(zettaknight_globs.pool_name, zettaknight_globs.cifs_dset_suffix) pass if kwargs and "user" in kwargs.iterkeys(): user = kwargs['user'] if kwargs and "group" in kwargs.iterkeys(): group = kwargs['group'] if kwargs and "quota" in kwargs.iterkeys(): quota = kwargs['quota'] if user and group: ret[dataset] = {} try: raise Exception("Arguments user and group must be specified separately. Arguments passed: {0}".format(kwargs)) except Exception as e: ret[dataset]['Set User Quota'] = {1: e} zettaknight_utils.parse_output(ret) return ret if not quota: ret[dataset] = {} try: raise Exception("Quota argument must be supplied. Arguments passed: {0}".format(kwargs)) except Exception as e: ret[dataset]['Set User Quota'] = {1: e} zettaknight_utils.parse_output(ret) return ret if user: obj = user dset = "{0}/{1}".format(dataset, user) elif group: obj = group dset = "{0}/{1}".format(dataset, group) try: if str(zettaknight_globs.zfs_conf[dataset]['primary']) == str(zettaknight_globs.fqdn): if zettaknight_globs.zfs_conf[dataset]['snap']['remote_server']: for remote_server in zettaknight_globs.zfs_conf[dataset]['snap']['remote_server']: remote_user = zettaknight_globs.zfs_conf[dataset]['user'] remote_ssh = "{0}@{1}".format(remote_user, remote_server) try: ssh2 = paramiko.SSHClient() ssh2.set_missing_host_key_policy(paramiko.AutoAddPolicy()) ssh2.connect(remote_server, username=remote_user, key_filename=zettaknight_globs.identity_file) remote_cmd = "zettaknight set_cifs_quota user={0} dataset={1} quota={2}".format(obj, dataset, quota) ssh2_stdin, ssh2_stdout, ssh2_stderr = ssh2.exec_command(remote_cmd) ssh2.close() except Exception as e: pass except: pass ret[dset] = {} quota_cmd = "/sbin/zfs set refquota={0} {1}".format(quota, dset) ret[dset]['Set User Quota'] = zettaknight_utils.spawn_job(quota_cmd) return ret
def create_cifs_share(**kwargs): ''' Creates a zfs dataset for a given user or group. ''' ret = {} if zettaknight_globs.help_flag: ret = """Create CIFS Share: Function to create a new directory with proper permissions for user/group access over CIFS on primary and secondary ZFS servers. Arguments should be passed as key/value pairs. Required Arguments: user or group Specifies the username or group name to create the share for. Optional Arguments: dataset Specifies the parent dataset to create the share under. If not specified, the default will be pulled from Zettaknight conf files""" return ret user = False group = False if kwargs: try: if kwargs['dataset']: dataset = kwargs['dataset'] except: dataset = "{0}/{1}".format(zettaknight_globs.pool_name, zettaknight_globs.cifs_dset_suffix) pass if kwargs and "user" in kwargs.iterkeys(): user = kwargs['user'] if kwargs and "group" in kwargs.iterkeys(): group = kwargs['group'] ret[dataset] = {} if user and group: try: raise Exception( "Arguments user and group must be specified separately. Arguments passed: {0}" .format(kwargs)) except Exception as e: ret[dataset]['Create CIFS Share'] = {1: e} zettaknight_utils.parse_output(ret) return ret if user: cifs_cmd = "{0} -u {1} -d {2}".format( zettaknight_globs.cifs_share_script, user, dataset) if group: cifs_cmd = "{0} -g {1} -d {2}".format( zettaknight_globs.cifs_share_script, group, dataset) if user: obj = user elif group: obj = group try: if str(zettaknight_globs.zfs_conf[dataset]['primary']) == str( zettaknight_globs.fqdn): if zettaknight_globs.zfs_conf[dataset]['snap']['remote_server']: for remote_server in zettaknight_globs.zfs_conf[dataset][ 'snap']['remote_server']: remote_user = zettaknight_globs.zfs_conf[dataset]['user'] remote_ssh = "{0}@{1}".format(remote_user, remote_server) try: ssh2 = paramiko.SSHClient() ssh2.set_missing_host_key_policy( paramiko.AutoAddPolicy()) ssh2.connect( remote_server, username=remote_user, key_filename=zettaknight_globs.identity_file) remote_cmd = "zettaknight create_cifs_share user={0} dataset={1}".format( obj, dataset) ssh2_stdin, ssh2_stdout, ssh2_stderr = ssh2.exec_command( remote_cmd) ssh2.close() except Exception as e: pass except: pass try: ret[dataset]['Create CIFS Share'] = zettaknight_utils.spawn_job( cifs_cmd) except Exception as e: ret[dataset]['Create CIFS Share'] = {1: e} #zettaknight_utils.parse_output(ret) return ret
def set_cifs_quota(**kwargs): ''' Set quota for user or group cifs share. ''' ret = {} if zettaknight_globs.help_flag: ret = """Set CIFS Quota: Function to set a quota on a user or group CIFS share. Sets the quota on primary and secondary ZFS servers. Arguments should be passed as key/value pairs. Required Arguments: user or group Specifies the username or group name tied to the relevant share to set the quota on. quota Quota to be set. Should be specified with a number and unit, ie. 10T, 100G, 10M. 'None' should be specified to remove the quota. Optional Arguments: dataset Specifies the parent dataset to search for the share under. If not specified, the default will be pulled from Zettaknight conf files""" return ret user = False group = False quota = False try: if kwargs and kwargs['dataset']: dataset = kwargs['dataset'] except: dataset = "{0}/{1}".format(zettaknight_globs.pool_name, zettaknight_globs.cifs_dset_suffix) pass if kwargs and "user" in kwargs.iterkeys(): user = kwargs['user'] if kwargs and "group" in kwargs.iterkeys(): group = kwargs['group'] if kwargs and "quota" in kwargs.iterkeys(): quota = kwargs['quota'] if user and group: ret[dataset] = {} try: raise Exception( "Arguments user and group must be specified separately. Arguments passed: {0}" .format(kwargs)) except Exception as e: ret[dataset]['Set User Quota'] = {1: e} zettaknight_utils.parse_output(ret) return ret if not quota: ret[dataset] = {} try: raise Exception( "Quota argument must be supplied. Arguments passed: {0}". format(kwargs)) except Exception as e: ret[dataset]['Set User Quota'] = {1: e} zettaknight_utils.parse_output(ret) return ret if user: obj = user dset = "{0}/{1}".format(dataset, user) elif group: obj = group dset = "{0}/{1}".format(dataset, group) try: if str(zettaknight_globs.zfs_conf[dataset]['primary']) == str( zettaknight_globs.fqdn): if zettaknight_globs.zfs_conf[dataset]['snap']['remote_server']: for remote_server in zettaknight_globs.zfs_conf[dataset][ 'snap']['remote_server']: remote_user = zettaknight_globs.zfs_conf[dataset]['user'] remote_ssh = "{0}@{1}".format(remote_user, remote_server) try: ssh2 = paramiko.SSHClient() ssh2.set_missing_host_key_policy( paramiko.AutoAddPolicy()) ssh2.connect( remote_server, username=remote_user, key_filename=zettaknight_globs.identity_file) remote_cmd = "zettaknight set_cifs_quota user={0} dataset={1} quota={2}".format( obj, dataset, quota) ssh2_stdin, ssh2_stdout, ssh2_stderr = ssh2.exec_command( remote_cmd) ssh2.close() except Exception as e: pass except: pass ret[dset] = {} quota_cmd = "/sbin/zfs set refquota={0} {1}".format(quota, dset) ret[dset]['Set User Quota'] = zettaknight_utils.spawn_job(quota_cmd) return ret
def find_versions(dataset, filename, quiet=False): ''' ''' if zettaknight_globs.help_flag: ret = """Find Versions: Usage: zettaknight find_versions zfs_data/<some dataset> <some filename> Searches snapshots of provided dataset for previous versions of filename. Required Arguments: dataset Specifies the dataset whose snapshots will be searched. filename Defines target file(s) to find previous versions of. This can be a full path to a file (/zfs_data/<some dataset>/<some filename>.<ext>), just a filename with or without an extension (<some filename> or <some filename>.<ext>), or just an extension (.<ext>)""" return ret zettaknight_utils.check_quiet(quiet) snaps = {} ret = {} ret[dataset] = {} snaplist_cmd = "/sbin/zfs list -r -t snapshot -o name -H {0}".format(dataset) snaplist_run = subprocess.Popen(shlex.split(snaplist_cmd), stdout = subprocess.PIPE, stderr = subprocess.STDOUT) snaplist_run.wait() snaplist_out = snaplist_run.stdout.read() if not snaplist_out: try: out_dict = {} out_dict[dataset] = {} job = inspect.stack()[0][3] if str(inspect.stack()[1][3]) is 'recover': job = inspect.stack()[1][3] out_dict[dataset][job] = {} out_dict[dataset][job]['1'] = "No snapshots found." raise Exception except Exception as e: zettaknight_utils.parse_output(out_dict) sys.exit(0) for snap in snaplist_out.split(): if snap.startswith("cannot"): try: raise Exception("{0}".format(snaplist_out)) except Exception as e: zettaknight_utils.zlog("{0}".format(e), "ERROR") sys.exit(0) snapdiff_cmd = "/sbin/zfs diff {0}".format(snap) gerp_cmd = "/bin/grep {0}".format(filename) gerp_run = zettaknight_utils.pipe_this(snapdiff_cmd, gerp_cmd) gerp_out = gerp_run.stdout.read() gerp_list = [] if gerp_out: for gerp in gerp_out.split('\n'): if gerp.startswith("-") or gerp.startswith("M") or gerp.startswith("R"): gerp_list.append(gerp) if gerp_list: snaps[snap] = gerp_list gerp_msg = "" for z in gerp_list: if gerp_msg: gerp_msg = "{0}\n{1}".format(gerp_msg, z) else: gerp_msg = str(z) job = "Snapshot: {0}".format(snap) ret[dataset][job] = {} job_out = "Path:\n{0}".format(gerp_msg) ret[dataset][job]['0'] = job_out if not ret[dataset]: ret[dataset]['Snapshot'] = {} ret[dataset]['Snapshot']['1'] = "No modified versions of {0} found.".format(filename, dataset) if not quiet: zettaknight_utils.parse_output(ret) return snaps
def set_cifs_quota(**kwargs): ''' Set quota for user or group cifs share. ''' ret = {} user = False group = False quota = False try: if kwargs and kwargs['dataset']: dataset = kwargs['dataset'] except: dataset = "{0}/{1}".format(zettaknight_globs.pool_name, zettaknight_globs.cifs_dset_suffix) pass if kwargs and "user" in kwargs.iterkeys(): user = kwargs['user'] if kwargs and "group" in kwargs.iterkeys(): group = kwargs['group'] if kwargs and "quota" in kwargs.iterkeys(): quota = kwargs['quota'] if user and group: ret[dataset] = {} try: raise Exception("Arguments user and group must be specified separately. Arguments passed: {0}".format(kwargs)) except Exception as e: ret[dataset]['Set User Quota'] = {1: e} zettaknight_utils.parse_output(ret) return ret if not quota: ret[dataset] = {} try: raise Exception("Quota argument must be supplied. Arguments passed: {0}".format(kwargs)) except Exception as e: ret[dataset]['Set User Quota'] = {1: e} zettaknight_utils.parse_output(ret) return ret if user: obj = user dset = "{0}/{1}".format(dataset, user) elif group: obj = group dset = "{0}/{1}".format(dataset, group) try: if str(zettaknight_globs.zfs_conf[dataset]['primary']) == str(zettaknight_globs.fqdn): if zettaknight_globs.zfs_conf[dataset]['snap']['remote_server']: for remote_server in zettaknight_globs.zfs_conf[dataset]['snap']['remote_server']: remote_user = zettaknight_globs.zfs_conf[dataset]['user'] remote_ssh = "{0}@{1}".format(remote_user, remote_server) try: ssh2 = paramiko.SSHClient() ssh2.set_missing_host_key_policy(paramiko.AutoAddPolicy()) ssh2.connect(remote_server, username=remote_user, key_filename=zettaknight_globs.identity_file) remote_cmd = "zettaknight set_cifs_quota user={0} dataset={1} quota={2}".format(obj, dataset, quota) ssh2_stdin, ssh2_stdout, ssh2_stderr = ssh2.exec_command(remote_cmd) ssh2.close() except Exception as e: pass except: pass ret[dset] = {} quota_cmd = "/sbin/zfs set quota={0} {1}".format(quota, dset) ret[dset]['Set User Quota'] = zettaknight_utils.spawn_job(quota_cmd) return ret
def check_usage(dset=False, quiet=False): ''' ''' ret = {} zettaknight_utils.check_quiet(quiet) if dset and str(dset) not in zettaknight_globs.zfs_conf.iterkeys(): ret[dset] = {} ret[dset]['Check Usage'] = { 1: "{0} is not a Zettaknight controlled dataset.".format(dset) } zettaknight_utils.parse_output(ret) return ret for dataset in zettaknight_globs.zfs_conf.iterkeys(): if dset: if str(dset) != str(dataset): continue ret[dataset] = {} ret[dataset]['Check Usage'] = {} quota = zettaknight_globs.zfs_conf[dataset]['quota'] reservation = zettaknight_globs.zfs_conf[dataset]['reservation'] #find conversion multiplier to convert reservation to bytes if 'G' in reservation: res_x = float(1073741824) res_unit = "G" if 'T' in reservation: res_x = float(1099511627776) res_unit = "T" if 'M' in reservation: res_x = float(1048576) res_unit = "M" if str(reservation) == 'none': res_x = float(1073741824) res_unit = "G" contact = zettaknight_globs.zfs_conf[dataset]['contact'] check_usage_cmd = "/sbin/zfs list -ro space {0} -H -p".format(dataset) check_usage_run = zettaknight_utils.spawn_job(check_usage_cmd) chk_code, chk_msg = check_usage_run.popitem() chk_msg = re.sub("\n", "", chk_msg) chk_msg_split = chk_msg.split("\t") if not str(chk_code) == "0": ret[dataset]['Check Usage'][ '1'] = "{0}Verify correct datasets are defined in configuration file\n".format( re.sub("[\[\"\]]", "", str(chk_msg_split))) continue if str(chk_msg_split[0]) == str(dataset): avail = float( re.sub("[A-Za-z]", "", chk_msg_split[1])) #space available for dataset used = float(re.sub( "[A-Za-z]", "", chk_msg_split[2])) #how much space is used by the dataset usnap = float( re.sub("[A-Za-z]", "", chk_msg_split[3] )) #how much of the used space is consumed by snapshots uds = float( re.sub("[A-Za-z]", "", chk_msg_split[4]) ) #how much of the space is consumed by the dataset itself if str(reservation) != 'none': res = (float(re.sub("[A-Za-z]", "", reservation)) * res_x) avail_friendly = "{0:.2f}{1}".format((avail / res_x), res_unit) used_friendly = "{0:.2f}{1}".format((used / res_x), res_unit) usnap_friendly = "{0:.2f}{1}".format((usnap / res_x), res_unit) uds_friendly = "{0:.2f}{1}".format((uds / res_x), res_unit) if "e-" in str(used_friendly): used_friendly = "{0}{1}".format(int(0), res_unit) if "e-" in str(usnap_friendly): usnap_friendly = "{0}{1}".format(int(0), res_unit) if "e-" in str(uds_friendly): uds_friendly = "{0}{1}".format(int(0), res_unit) if str(reservation) != 'none' and used > res: a = "{0}: {1}\n\t\t".format( zettaknight_utils.printcolors("Dataset", "OKBLUE"), zettaknight_utils.printcolors(dataset, "FAIL")) b = "{0}: {1}\n{2}: {3}\n{4}: {5}\n{6}: {7}".format( zettaknight_utils.printcolors("Reservation", "OKBLUE"), zettaknight_utils.printcolors(reservation, "OKGREEN"), zettaknight_utils.printcolors("Total Used", "OKBLUE"), zettaknight_utils.printcolors(used_friendly, "WARNING"), zettaknight_utils.printcolors("Used by Snapshots", "OKBLUE"), zettaknight_utils.printcolors(usnap_friendly, "WARNING"), zettaknight_utils.printcolors("Active Dataset size", "OKBLUE"), zettaknight_utils.printcolors(uds_friendly, "WARNING")) c = zettaknight_utils.printcolors( "\nDataset exceeds space reservation", "WARNING") msg = "{0}{1}{2}".format(a, b, c) ret[dataset]['Check Usage']['1'] = "{0}{1}".format(b, c) else: a = "{0}: {1}\n\t\t".format( zettaknight_utils.printcolors("Dataset", "OKBLUE"), zettaknight_utils.printcolors(dataset, "OKGREEN")) b = "{0}: {1}\n{2}: {3}\n{4}: {5}\n{6}: {7}".format( zettaknight_utils.printcolors("Reservation", "OKBLUE"), zettaknight_utils.printcolors(reservation, "OKGREEN"), zettaknight_utils.printcolors("Total Used", "OKBLUE"), zettaknight_utils.printcolors(used_friendly, "OKGREEN"), zettaknight_utils.printcolors("Used by Snapshots", "OKBLUE"), zettaknight_utils.printcolors(usnap_friendly, "OKGREEN"), zettaknight_utils.printcolors("Active Dataset size", "OKBLUE"), zettaknight_utils.printcolors(uds_friendly, "OKGREEN")) msg = "{0}{1}".format(a, b) ret[dataset]['Check Usage']['0'] = b return ret
def failover(dataset, remote_server=False): ''' ''' ret = {} if zettaknight_globs.help_flag: ret = """Failover: Attempts a controlled failover for provided dataset to remote host defined in configuration files. Usage: zettaknight failover <dataset> Required Arguments: dataset Specifies the dataset to fail over. Optional Arguments: remote_server Specifies a remote server to attempt a failover to. By default, this information is pulled from dataset configuration files.""" return ret ret[dataset] = {} ret[dataset]['Failover'] = {} try: user = zettaknight_globs.zfs_conf[dataset]['user'] secure = zettaknight_globs.zfs_conf[dataset]['secure'] except Exception as e: ret[dataset]['Failover'][ '1'] = "Dataset: {0} not configured in configuration file.".format( dataset) zettaknight_utils.parse_output(ret) sys.exit(0) try: if not remote_server: remote_server = zettaknight_globs.zfs_conf[dataset]['snap'][ 'remote_server'] if isinstance(remote_server, list): if len(remote_server) > 1: raise Exception( "Multiple remote servers defined in configuration.") except Exception as e: ret[dataset]['Failover'][ '1'] = "{0}\nRemote servers defined:\n - {1}\nRe-run with explicit remote server to failover to.".format( e, list(zettaknight_globs.zfs_conf[dataset]['snap'] ['remote_server'])) zettaknight_utils.parse_output(ret) sys.exit(0) snap_cmd = "bash {0} -d {1} -s {2}@{3} -i {4} -f".format( zettaknight_globs.snap_script, dataset, user, remote_server[0], zettaknight_globs.identity_file) if secure: snap_cmd = "{0} -e".format(snap_cmd) ret[dataset]['Failover'] = zettaknight_utils.spawn_job(snap_cmd) zettaknight_utils.parse_output(ret) return ret
def find_versions(dataset, filename, quiet=False): ''' ''' if zettaknight_globs.help_flag: ret = """Find Versions: Usage: zettaknight find_versions zfs_data/<some dataset> <some filename> Searches snapshots of provided dataset for previous versions of filename. Required Arguments: dataset Specifies the dataset whose snapshots will be searched. filename Defines target file(s) to find previous versions of. This can be a full path to a file (/zfs_data/<some dataset>/<some filename>.<ext>), just a filename with or without an extension (<some filename> or <some filename>.<ext>), or just an extension (.<ext>)""" return ret zettaknight_utils.check_quiet(quiet) snaps = {} ret = {} ret[dataset] = {} snaplist_cmd = "/sbin/zfs list -r -t snapshot -o name -H {0}".format( dataset) snaplist_run = subprocess.Popen(shlex.split(snaplist_cmd), stdout=subprocess.PIPE, stderr=subprocess.STDOUT) snaplist_run.wait() snaplist_out = snaplist_run.stdout.read() if not snaplist_out: try: out_dict = {} out_dict[dataset] = {} job = inspect.stack()[0][3] if str(inspect.stack()[1][3]) is 'recover': job = inspect.stack()[1][3] out_dict[dataset][job] = {} out_dict[dataset][job]['1'] = "No snapshots found." raise Exception except Exception as e: zettaknight_utils.parse_output(out_dict) sys.exit(0) for snap in snaplist_out.split(): if snap.startswith("cannot"): try: raise Exception("{0}".format(snaplist_out)) except Exception as e: zettaknight_utils.zlog("{0}".format(e), "ERROR") sys.exit(0) snapdiff_cmd = "/sbin/zfs diff {0}".format(snap) gerp_cmd = "/bin/grep {0}".format(filename) gerp_run = zettaknight_utils.pipe_this(snapdiff_cmd, gerp_cmd) gerp_out = gerp_run.stdout.read() gerp_list = [] if gerp_out: for gerp in gerp_out.split('\n'): if gerp.startswith("-") or gerp.startswith( "M") or gerp.startswith("R"): gerp_list.append(gerp) if gerp_list: snaps[snap] = gerp_list gerp_msg = "" for z in gerp_list: if gerp_msg: gerp_msg = "{0}\n{1}".format(gerp_msg, z) else: gerp_msg = str(z) job = "Snapshot: {0}".format(snap) ret[dataset][job] = {} job_out = "Path:\n{0}".format(gerp_msg) ret[dataset][job]['0'] = job_out if not ret[dataset]: ret[dataset]['Snapshot'] = {} ret[dataset]['Snapshot'][ '1'] = "No modified versions of {0} found.".format( filename, dataset) if not quiet: zettaknight_utils.parse_output(ret) return snaps
def check_usage(dset=False, quiet=False): ''' ''' ret = {} zettaknight_utils.check_quiet(quiet) if dset and str(dset) not in zettaknight_globs.zfs_conf.iterkeys(): ret[dset] = {} ret[dset]['Check Usage'] = {1: "{0} is not a Zettaknight controlled dataset.".format(dset)} zettaknight_utils.parse_output(ret) return ret for dataset in zettaknight_globs.zfs_conf.iterkeys(): if dset: if str(dset) != str(dataset): continue ret[dataset] = {} ret[dataset]['Check Usage'] = {} quota = zettaknight_globs.zfs_conf[dataset]['quota'] reservation = zettaknight_globs.zfs_conf[dataset]['reservation'] #find conversion multiplier to convert reservation to bytes if 'G' in reservation: res_x = float(1073741824) res_unit = "G" if 'T' in reservation: res_x = float(1099511627776) res_unit = "T" if 'M' in reservation: res_x = float(1048576) res_unit = "M" if str(reservation) == 'none': res_x = float(1073741824) res_unit = "G" contact = zettaknight_globs.zfs_conf[dataset]['contact'] check_usage_cmd = "/sbin/zfs list -ro space {0} -H -p".format(dataset) check_usage_run = zettaknight_utils.spawn_job(check_usage_cmd) chk_code, chk_msg = check_usage_run.popitem() chk_msg = re.sub("\n", "", chk_msg) chk_msg_split = chk_msg.split("\t") if not str(chk_code) == "0": ret[dataset]['Check Usage']['1'] = "{0}Verify correct datasets are defined in configuration file\n".format(re.sub("[\[\"\]]", "", str(chk_msg_split))) continue if str(chk_msg_split[0]) == str(dataset): avail = float(re.sub("[A-Za-z]", "", chk_msg_split[1])) #space available for dataset used = float(re.sub("[A-Za-z]", "", chk_msg_split[2])) #how much space is used by the dataset usnap = float(re.sub("[A-Za-z]", "", chk_msg_split[3])) #how much of the used space is consumed by snapshots uds = float(re.sub("[A-Za-z]", "", chk_msg_split[4])) #how much of the space is consumed by the dataset itself if str(reservation) != 'none': res = (float(re.sub("[A-Za-z]", "", reservation)) * res_x) avail_friendly = "{0:.2f}{1}".format((avail / res_x), res_unit) used_friendly = "{0:.2f}{1}".format((used / res_x), res_unit) usnap_friendly = "{0:.2f}{1}".format((usnap / res_x), res_unit) uds_friendly = "{0:.2f}{1}".format((uds / res_x), res_unit) if "e-" in str(used_friendly): used_friendly = "{0}{1}".format(int(0), res_unit) if "e-" in str(usnap_friendly): usnap_friendly = "{0}{1}".format(int(0), res_unit) if "e-" in str(uds_friendly): uds_friendly = "{0}{1}".format(int(0), res_unit) if str(reservation) != 'none' and used > res: a = "{0}: {1}\n\t\t".format(zettaknight_utils.printcolors("Dataset", "OKBLUE"),zettaknight_utils.printcolors(dataset, "FAIL")) b = "{0}: {1}\n{2}: {3}\n{4}: {5}\n{6}: {7}".format(zettaknight_utils.printcolors("Reservation", "OKBLUE"),zettaknight_utils.printcolors(reservation, "OKGREEN"),zettaknight_utils.printcolors("Total Used", "OKBLUE"),zettaknight_utils.printcolors(used_friendly, "WARNING"),zettaknight_utils.printcolors("Used by Snapshots", "OKBLUE"),zettaknight_utils.printcolors(usnap_friendly, "WARNING"),zettaknight_utils.printcolors("Active Dataset size", "OKBLUE"),zettaknight_utils.printcolors(uds_friendly, "WARNING")) c = zettaknight_utils.printcolors("\nDataset exceeds space reservation", "WARNING") msg = "{0}{1}{2}".format(a, b, c) ret[dataset]['Check Usage']['1'] = "{0}{1}".format(b, c) else: a = "{0}: {1}\n\t\t".format(zettaknight_utils.printcolors("Dataset", "OKBLUE"),zettaknight_utils.printcolors(dataset, "OKGREEN")) b = "{0}: {1}\n{2}: {3}\n{4}: {5}\n{6}: {7}".format(zettaknight_utils.printcolors("Reservation", "OKBLUE"),zettaknight_utils.printcolors(reservation, "OKGREEN"),zettaknight_utils.printcolors("Total Used", "OKBLUE"),zettaknight_utils.printcolors(used_friendly, "OKGREEN"),zettaknight_utils.printcolors("Used by Snapshots", "OKBLUE"),zettaknight_utils.printcolors(usnap_friendly, "OKGREEN"),zettaknight_utils.printcolors("Active Dataset size", "OKBLUE"),zettaknight_utils.printcolors(uds_friendly, "OKGREEN")) msg = "{0}{1}".format(a, b) ret[dataset]['Check Usage']['0'] = b return ret
def find_versions(dataset, filename, quiet=False): ''' ''' zettaknight_utils.check_quiet(quiet) snaps = {} ret = {} ret[dataset] = {} snaplist_cmd = "/sbin/zfs list -r -t snapshot -o name -H {0}".format(dataset) snaplist_run = subprocess.Popen(shlex.split(snaplist_cmd), stdout = subprocess.PIPE, stderr = subprocess.STDOUT) snaplist_run.wait() snaplist_out = snaplist_run.stdout.read() if not snaplist_out: try: out_dict = {} out_dict[dataset] = {} job = inspect.stack()[0][3] if str(inspect.stack()[1][3]) is 'recover': job = inspect.stack()[1][3] out_dict[dataset][job] = {} out_dict[dataset][job]['1'] = "No snapshots found." raise Exception except Exception as e: zettaknight_utils.parse_output(out_dict) sys.exit(0) for snap in snaplist_out.split(): if snap.startswith("cannot"): try: raise Exception("{0}".format(snaplist_out)) except Exception as e: print(zettaknight_utils.printcolors(e, "FAIL")) sys.exit(0) snapdiff_cmd = "/sbin/zfs diff {0}".format(snap) gerp_cmd = "/bin/grep {0}".format(filename) gerp_run = zettaknight_utils.pipe_this(snapdiff_cmd, gerp_cmd) gerp_out = gerp_run.stdout.read() gerp_list = [] if gerp_out: for gerp in gerp_out.split('\n'): if gerp.startswith("-") or gerp.startswith("M"): gerp_list.append(gerp) if gerp_list: snaps[snap] = gerp_list gerp_msg = "" for z in gerp_list: if gerp_msg: gerp_msg = "{0}\n{1}".format(gerp_msg, z) else: gerp_msg = str(z) job = "Snapshot: {0}".format(snap) ret[dataset][job] = {} job_out = "Path:\n{0}".format(gerp_msg) ret[dataset][job]['0'] = job_out if not ret[dataset]: ret[dataset]['Snapshot'] = {} ret[dataset]['Snapshot']['1'] = "No modified versions of {0} found.".format(filename, dataset) if not quiet: zettaknight_utils.parse_output(ret) return snaps
def create_zpool(pool=False, disk_list=False, raid=False, luks=False, slog=False, create_config=False, ldap=False, recordsize=False, ashift=False, keyfile=False): if zettaknight_globs.help_flag: ret = """Create Zpool: See help entry for create function. zettaknight help create """ return ret ret = {} ret[pool] = {} ret[pool]['Create Zpool'] = {} if not raid: raid = "12+2" try: disks, z_level = raid.split("+") except Exception as e: ret[pool]['Create Zpool'] = { '1': "{0}\nargument raid must be in x+y format, i.e. 2+1".format(e) } zettaknight_utils.parse_output(ret) sys.exit(0) create_cmd = "bash {0} -d {1} -z {2}".format( zettaknight_globs.zpool_create_script, disks, z_level) if disk_list: create_cmd = "{0} -f '{1}'".format(create_cmd, disk_list) if pool: create_cmd = "{0} -p '{1}'".format(create_cmd, pool) if luks: create_cmd = "{0} -l".format(create_cmd) if slog: create_cmd = "{0} -s '{1}'".format(create_cmd, slog) if ldap: create_cmd = "{0} -i".format(create_cmd) if recordsize: if any(i in recordsize for i in 'KM'): create_cmd = "{0} -r {1}".format(create_cmd, recordsize) else: print( zettaknight_utils.printcolors( "Recordsize must be in number/unit format. ie. 1M, or 512K", "FAIL")) sys.exit(0) if ashift: create_cmd = "{0} -a {1}".format(create_cmd, ashift) if keyfile: create_cmd = "{0} -k {1}".format(create_cmd, keyfile) try: ret[pool]['Create Zpool'] = zettaknight_utils.spawn_job(create_cmd) except Exception as e: zettaknight_utils.zlog("{0}".format(e), "ERROR") ret[pool]['Create Zpool']['1'] = e return ret