示例#1
0
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 add_dataset(*args, **kwargs):
    '''if create_config=True is passed, a configuration file
    will be created for the dataset passed in to this function'''
 
 
    #kwargs = {}
    arg_list = list(args)
 
    #kwargs = zettaknight_utils.create_kwargs_from_args(arg_list)
    #print("This is kwargs : {0}".format(kwargs))
 
    for arg in arg_list[0:]:
        if "=" in arg:
            k, v = arg.split("=", 1)
            kwargs[k] = v
            arg_list.remove(arg)
 
    dataset = arg_list[0]
    ret = {}
    ret[dataset] = {}
    
    gerp_run = zettaknight_utils.pipe_this2("zfs list | /bin/grep {0}".format(dataset))
    gerp_out = gerp_run.stdout.read()
    
    
    if 'create_config' not in kwargs.iterkeys():
        kwargs['create_config'] = True
        
    if kwargs['create_config'] == 'False':
        kwargs['create_config'] == False
        
    if kwargs['create_config']:
        print(zettaknight_utils.printcolors("\nWill create {0} after completion of config file\n".format(dataset), "OKGREEN"))
        conf_dict = {'dataset' : dataset}
        zettaknight_utils.create_config(**conf_dict)
    
    #create dataset after commit of file
    if int(gerp_run.returncode) is not 0:
        create_cmd = "zfs create -p {0}".format(dataset)
        create_run = zettaknight_utils.spawn_job(create_cmd)
        ret[dataset]['add_dataset'] = create_run
    else:
        ret[dataset]['add_dataset'] = {'0' : "{0} exists".format(dataset)}
        
    question = zettaknight_utils.query_yes_no("Would you like to create an NFS share for: {0}".format(dataset))
    if question:
        nfs_share = zettaknight_utils.query_return_item("Where would you like to share it? <i.e 10.20.30.1/24 or my.server>")
        zettaknight_utils.sharenfs(dataset, nfs_share)
 
    #zettaknight_utils.parse_output(ret)
 
    return ret
def recover(snapshot, filename, relocate=None):
    '''
    '''
    
    file = filename
    snap = snapshot
    dataset, snap_date = snap.split('@', 1)
    find_snap = find_versions(dataset, file, "quiet")
    find_snap_keys = find_snap.iterkeys()
    snap_basedir = "/{0}/.zfs/snapshot".format(dataset)
    active_basedir = "/{0}".format(dataset)
    dir_flag = False
    ret = {}
    ret[dataset] = {}
    
    
    if dataset in file.split("/"):
        file = file.split(dataset, 1)[1]
        last_ref = file.rsplit("/",1)[1]
    
    if snap not in find_snap_keys:
        try:
            raise Exception("Recoverable versions of {0} not found in dataset {1}".format(file, dataset))
        except Exception as e:
            print(zettaknight_utils.printcolors(e, "FAIL"))
    
    path_list1 = find_snap[snap]
    
    path_list = []
    
    if os.path.isdir("/{0}/{1}".format(dataset, file)):
        dir_flag = True
    
    for line in path_list1:
        if line.startswith("-") or line.startswith("M"):
            a, b = line.rsplit("/", 1)
            if not dir_flag:
                try:
                    if str(b) == str(last_ref):
                        path_list.append(line)
                except:
                    if str(b) == str(file):
                        path_list.append(line)
                    pass
                        

            else:
                if a.startswith("-"):
                    a, b = line.rsplit(dataset, 2)
                    if os.path.isdir("{0}/{1}{2}".format(snap_basedir, snap_date, b)):
                        dir_flag = True
                        path_list.append(line)

    if len(path_list) > 1:
        exc_out = ""
        for i in path_list:
            if exc_out:
                exc_out = "{0}\n\t{1}".format(exc_out, i)
            else:
                exc_out = str(i)
        err_msg = "Matching files/folders in snapshot:"
        print(zettaknight_utils.printcolors("\nAmbiguous recover request.  Multiple matches for {0}.".format(file), "FAIL"))
        print("{0} {1}".format(zettaknight_utils.printcolors(err_msg, "FAIL"), zettaknight_utils.printcolors(snap, "OKBLUE")))
        print("\t{0}".format(zettaknight_utils.printcolors(exc_out, "WARNING")))
        print(zettaknight_utils.printcolors("Re-run with explicit path to file.\n", "FAIL"))
        try:
            raise Exception("Ambiguous file reference.")
        except Exception as e:
            print(zettaknight_utils.printcolors(e, "FAIL"))
            sys.exit(0)
    
    if len(path_list) < 1:
        try:
            raise Exception("No restorable files or folders identified. \nRe-run with explicit path to file?")
        except Exception as e:
            print(zettaknight_utils.printcolors(e, "FAIL"))
            sys.exit(0)
    
    a, p = path_list[0].split(dataset, 1)
    path, dirs = p.split(file, 1)

    if dir_flag:
        bad, dir_path = path_list[0].split(file, 1)
        list_dirs = dir_path.rsplit("/", 1)
        try:
            out_dir = list_dirs[0]
        except:
            out_dir = ""
            pass
        
        file_loc = "{0}/{1}/{2}{3}/".format(snap_basedir, snap_date, file, dir_path )
        mkdir_cmd = "/bin/mkdir {0}/{1}.R".format(active_basedir, file)
        mkdir_run = zettaknight_utils.spawn_job(mkdir_cmd)
        mkdir_cmd = "/bin/mkdir -p {0}/{1}.R/{2}".format(active_basedir, file, dir_path)
        mkdir_run = zettaknight_utils.spawn_job(mkdir_cmd)
        out_path = "{0}{1}{2}.R{3}/".format(active_basedir, str(path), file, out_dir)

    else:
        file_loc = "{0}/{1}/{2}".format(snap_basedir, snap_date, p)
        out_path = "{0}{1}{2}.R".format(active_basedir, str(path), file)

    if relocate:
        out_path = relocate
    
    rec_cmd = "/bin/cp ""-r ""{0}"" ""{1}".format(file_loc, out_path)
    rec_run = zettaknight_utils.spawn_job(rec_cmd)
    rec_dict = eval(str(rec_run))
    for k,v in rec_dict.iteritems():
        if str(k) is "0":
            print("Recover operation succeeded.")
            print("\tFilename: {0}".format(zettaknight_utils.printcolors(file, "OKBLUE")))
            print("\t\tFile(s) restored to version: {0}".format(zettaknight_utils.printcolors(snap_date, "OKGREEN")))
            print("\t\tFile(s) restored to: {0}".format(zettaknight_utils.printcolors(out_path, "OKGREEN")))

        if str(k) is not "0":
            print("Recover operation failed.")
            print("\tFilename: {0}".format(zettaknight_utils.printcolors(file, "OKBLUE")))
            print("\t\tRestore failed with error: {0}".format(zettaknight_utils.printcolors(v, "FAIL")))
    
    return
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 recover(snapshot, filename, relocate=None):
    '''
    '''
    if zettaknight_globs.help_flag:
        ret = """Recover:

	Usage:
		zettaknight recover <snapshot> <filepath> (<directory to recover file to>)*optional
	
    Recovers a previous version of a file or folder from a specified snapshot.  Information to use in calling zettaknight recover can be found in the output from the find_versions function.  By default, files/folders will be recovered to their original location with .R appended to the end of the name.

    Required Arguments:
        snapshot
            Specifies the snapshot to recover files from.
		filename
			Defines target file(s) to recover.  This should be the full path to a file or folder (/zfs_data/<some dataset>/<some filename>.<ext>)
			
	Optional Arguments:
		relocate
			Defines an alternate path to recover files/folders to.  If used, .R will not be appended, and the recover will overwrite any existing files."""
        return ret
		
    file = filename
    snap = snapshot
    dataset, snap_date = snap.split('@', 1)
    find_snap = find_versions(dataset, file, "quiet")
    find_snap_keys = find_snap.iterkeys()
    snap_basedir = "/{0}/.zfs/snapshot".format(dataset)
    active_basedir = "/{0}".format(dataset)
    dir_flag = False
    ret = {}
    ret[dataset] = {}
    
  
    try:
        if str(dataset) in str(file):
            file = file.split(dataset, 1)[1]
            last_ref = file.rsplit("/", 1)[1]
    except Exception as e:
        pass

    if dataset in file.rsplit("/", 1):
        file = file.split(dataset, 1)[1]
        last_ref = file.rsplit("/",1)[1]

    if snap not in find_snap_keys:
        try:
            raise Exception("Recoverable versions of {0} not found in dataset {1}".format(file, dataset))
        except Exception as e:
            zettaknight_utils.zlog("{0}".format(e), "ERROR")
    
    path_list1 = find_snap[snap]
    
    path_list = []
    
    if os.path.isdir("/{0}{1}".format(dataset, file)):
        dir_flag = True

    for line in path_list1:
        if line.startswith("-") or line.startswith("M") or line.startswith("R"):
            a, b = line.rsplit("/", 1)
            if not dir_flag:
                try:
                    if str(b) == str(last_ref):
                        path_list.append(line)
                except:
                    if str(b) == str(file):
                        path_list.append(line)
                    pass
                        

            else:
                if a.startswith("-") or line.startswith("M") or line.startswith("R"):
                    a, b = line.rsplit(dataset, 2)
                    if os.path.isdir("{0}/{1}{2}".format(snap_basedir, snap_date, b)):
                        dir_flag = True
                        path_list.append(line)

    if len(path_list) > 1:
        exc_out = ""
        for i in path_list:
            if exc_out:
                exc_out = "{0}\n\t{1}".format(exc_out, i)
            else:
                exc_out = str(i)
        err_msg = "Matching files/folders in snapshot:"
        print(zettaknight_utils.printcolors("\nAmbiguous recover request.  Multiple matches for {0}.".format(file), "FAIL"))
        print("{0} {1}".format(zettaknight_utils.printcolors(err_msg, "FAIL"), zettaknight_utils.printcolors(snap, "OKBLUE")))
        print("\t{0}".format(zettaknight_utils.printcolors(exc_out, "WARNING")))
        print(zettaknight_utils.printcolors("Re-run with explicit path to file.\n", "FAIL"))
        try:
            raise Exception("Ambiguous file reference.")
        except Exception as e:
            zettaknight_utils.zlog("{0}".format(e), "ERROR")
            sys.exit(0)
    
    if len(path_list) < 1:
        try:
            raise Exception("No restorable files or folders identified. \nRe-run with explicit path to file?")
        except Exception as e:
            zettaknight_utils.zlog("{0}".format(e), "ERROR")
            sys.exit(0)
    
    a, p = path_list[0].split(dataset, 1)
    path, dirs = p.split(file, 1)

    if dir_flag:
        a, b = path_list[0].rsplit(dataset, 2)
        file_loc = "{0}/{1}{2}".format(snap_basedir, snap_date, b)
        #bad, dir_path = path_list[0].split(file, 1)
        #list_dirs = dir_path.rsplit("/", 1)
        #try:
        #    out_dir = list_dirs[0]
        #except:
        out_dir = ""
        #    pass
        
        #file_loc = "{0}/{1}/{2}{3}/".format(snap_basedir, snap_date, file, dir_path )
        #mkdir_cmd = "/bin/mkdir {0}/{1}.R".format(active_basedir, file)
        #mkdir_run = zettaknight_utils.spawn_job(mkdir_cmd)
        #mkdir_cmd = "/bin/mkdir -p {0}/{1}.R/{2}".format(active_basedir, file, dir_path)
        #mkdir_run = zettaknight_utils.spawn_job(mkdir_cmd)
        out_path = "{0}{1}{2}.R{3}/".format(active_basedir, str(path), file, out_dir)

    else:
        file_loc = "{0}/{1}/{2}".format(snap_basedir, snap_date, p)
        out_path = "{0}{1}{2}.R".format(active_basedir, str(path), file)

    if relocate:
        out_path = relocate
    
    rec_cmd = "/bin/cp ""-r -p ""{0}"" ""{1}".format(file_loc, out_path)
    rec_run = zettaknight_utils.spawn_job(rec_cmd)
    rec_dict = eval(str(rec_run))
    for k,v in rec_dict.iteritems():
        if str(k) is "0":
            print("Recover operation succeeded.")
            print("\tFilename: {0}".format(zettaknight_utils.printcolors(file, "OKBLUE")))
            print("\t\tFile(s) restored to version: {0}".format(zettaknight_utils.printcolors(snap_date, "OKGREEN")))
            print("\t\tFile(s) restored to: {0}".format(zettaknight_utils.printcolors(out_path, "OKGREEN")))

        if str(k) is not "0":
            print("Recover operation failed.")
            print("\tFilename: {0}".format(zettaknight_utils.printcolors(file, "OKBLUE")))
            print("\t\tRestore failed with error: {0}".format(zettaknight_utils.printcolors(v, "FAIL")))
    
    return
def recover(snapshot, filename, relocate=None):
    '''
    '''
    if zettaknight_globs.help_flag:
        ret = """Recover:

	Usage:
		zettaknight recover <snapshot> <filepath> (<directory to recover file to>)*optional
	
    Recovers a previous version of a file or folder from a specified snapshot.  Information to use in calling zettaknight recover can be found in the output from the find_versions function.  By default, files/folders will be recovered to their original location with .R appended to the end of the name.

    Required Arguments:
        snapshot
            Specifies the snapshot to recover files from.
		filename
			Defines target file(s) to recover.  This should be the full path to a file or folder (/zfs_data/<some dataset>/<some filename>.<ext>)
			
	Optional Arguments:
		relocate
			Defines an alternate path to recover files/folders to.  If used, .R will not be appended, and the recover will overwrite any existing files."""
        return ret

    file = filename
    snap = snapshot
    dataset, snap_date = snap.split('@', 1)
    find_snap = find_versions(dataset, file, "quiet")
    find_snap_keys = find_snap.iterkeys()
    snap_basedir = "/{0}/.zfs/snapshot".format(dataset)
    active_basedir = "/{0}".format(dataset)
    dir_flag = False
    ret = {}
    ret[dataset] = {}

    try:
        if str(dataset) in str(file):
            file = file.split(dataset, 1)[1]
            last_ref = file.rsplit("/", 1)[1]
    except Exception as e:
        pass

    if dataset in file.rsplit("/", 1):
        file = file.split(dataset, 1)[1]
        last_ref = file.rsplit("/", 1)[1]

    if snap not in find_snap_keys:
        try:
            raise Exception(
                "Recoverable versions of {0} not found in dataset {1}".format(
                    file, dataset))
        except Exception as e:
            zettaknight_utils.zlog("{0}".format(e), "ERROR")

    path_list1 = find_snap[snap]

    path_list = []

    if os.path.isdir("/{0}{1}".format(dataset, file)):
        dir_flag = True

    for line in path_list1:
        if line.startswith("-") or line.startswith("M") or line.startswith(
                "R"):
            a, b = line.rsplit("/", 1)
            if not dir_flag:
                try:
                    if str(b) == str(last_ref):
                        path_list.append(line)
                except:
                    if str(b) == str(file):
                        path_list.append(line)
                    pass

            else:
                if a.startswith("-") or line.startswith(
                        "M") or line.startswith("R"):
                    a, b = line.rsplit(dataset, 2)
                    if os.path.isdir("{0}/{1}{2}".format(
                            snap_basedir, snap_date, b)):
                        dir_flag = True
                        path_list.append(line)

    if len(path_list) > 1:
        exc_out = ""
        for i in path_list:
            if exc_out:
                exc_out = "{0}\n\t{1}".format(exc_out, i)
            else:
                exc_out = str(i)
        err_msg = "Matching files/folders in snapshot:"
        print(
            zettaknight_utils.printcolors(
                "\nAmbiguous recover request.  Multiple matches for {0}.".
                format(file), "FAIL"))
        print("{0} {1}".format(zettaknight_utils.printcolors(err_msg, "FAIL"),
                               zettaknight_utils.printcolors(snap, "OKBLUE")))
        print("\t{0}".format(zettaknight_utils.printcolors(exc_out,
                                                           "WARNING")))
        print(
            zettaknight_utils.printcolors(
                "Re-run with explicit path to file.\n", "FAIL"))
        try:
            raise Exception("Ambiguous file reference.")
        except Exception as e:
            zettaknight_utils.zlog("{0}".format(e), "ERROR")
            sys.exit(0)

    if len(path_list) < 1:
        try:
            raise Exception(
                "No restorable files or folders identified. \nRe-run with explicit path to file?"
            )
        except Exception as e:
            zettaknight_utils.zlog("{0}".format(e), "ERROR")
            sys.exit(0)

    a, p = path_list[0].split(dataset, 1)
    path, dirs = p.split(file, 1)

    if dir_flag:
        a, b = path_list[0].rsplit(dataset, 2)
        file_loc = "{0}/{1}{2}".format(snap_basedir, snap_date, b)
        #bad, dir_path = path_list[0].split(file, 1)
        #list_dirs = dir_path.rsplit("/", 1)
        #try:
        #    out_dir = list_dirs[0]
        #except:
        out_dir = ""
        #    pass

        #file_loc = "{0}/{1}/{2}{3}/".format(snap_basedir, snap_date, file, dir_path )
        #mkdir_cmd = "/bin/mkdir {0}/{1}.R".format(active_basedir, file)
        #mkdir_run = zettaknight_utils.spawn_job(mkdir_cmd)
        #mkdir_cmd = "/bin/mkdir -p {0}/{1}.R/{2}".format(active_basedir, file, dir_path)
        #mkdir_run = zettaknight_utils.spawn_job(mkdir_cmd)
        out_path = "{0}{1}{2}.R{3}/".format(active_basedir, str(path), file,
                                            out_dir)

    else:
        file_loc = "{0}/{1}/{2}".format(snap_basedir, snap_date, p)
        out_path = "{0}{1}{2}.R".format(active_basedir, str(path), file)

    if relocate:
        out_path = relocate

    rec_cmd = "/bin/cp " "-r -p " "{0}" " " "{1}".format(file_loc, out_path)
    rec_run = zettaknight_utils.spawn_job(rec_cmd)
    rec_dict = eval(str(rec_run))
    for k, v in rec_dict.iteritems():
        if str(k) is "0":
            print("Recover operation succeeded.")
            print("\tFilename: {0}".format(
                zettaknight_utils.printcolors(file, "OKBLUE")))
            print("\t\tFile(s) restored to version: {0}".format(
                zettaknight_utils.printcolors(snap_date, "OKGREEN")))
            print("\t\tFile(s) restored to: {0}".format(
                zettaknight_utils.printcolors(out_path, "OKGREEN")))

        if str(k) is not "0":
            print("Recover operation failed.")
            print("\tFilename: {0}".format(
                zettaknight_utils.printcolors(file, "OKBLUE")))
            print("\t\tRestore failed with error: {0}".format(
                zettaknight_utils.printcolors(v, "FAIL")))

    return
示例#7
0
def first_step():
    ret = {}
    arg_dict = {}

    try:

        pool_name = "zfs_data"  #default pool name
        arg_dict["pool_name"] = pool_name

        ret[pool_name] = {}

        ############### creation of the zpool ################
        ######################################################

        #test if a zpool exists
        zpool_list_cmd = "/sbin/zpool list -H"
        zpool_list_run = zettaknight_utils.spawn_job(zpool_list_cmd)
        chk_code, chk_msg = zpool_list_run.popitem()
        if int(chk_code) != 0:  #if zpool list -H returns empty
            #query_return_item is defined in zettaknight_utils
            create_pool_question = zettaknight_utils.query_yes_no(
                "No pool detected, would you like to create one?")
            if create_pool_question:
                arg_dict["disk_list"] = zettaknight_utils.query_return_item(
                    "File containing all list of disks to be used for {0}, I.E /tmp/bunchofdisks.txt: "
                    .format(pool_name))
                arg_dict["raid"] = zettaknight_utils.query_return_item(
                    "Raid level to be used [1-3]. I.E. 4+1, 5+2, 1+1: ")
                arg_dict["ashift"] = zettaknight_utils.query_return_item(
                    "ashift value for {0}, value is 9 for 512 block disks and 12 for 4096 block disks: "
                    .format(pool_name))
                arg_dict["luks"] = zettaknight_utils.query_yes_no(
                    "encrypt data disks with LUKS? ")

                print("creating zpool: {0}".format(pool_name))
                create_output = zettaknight_zpools.create(
                    pool_name, **arg_dict)  #from zettaknight_zpools
            #ret[pool_name]['Zpool Create'] = create_output[pool_name]['Zpool Create'] #'NoneType' object has no attribute '__getitem__'
        else:
            print("a pool already exists, moving on")
        ######################################################
        ######################################################

        ################## ssh key creation  #################
        print("checking for {0}".format(zettaknight_globs.identity_file))
        if not os.path.isfile(zettaknight_globs.identity_file):
            print(
                zettaknight_utils.printcolors(
                    "zettaknight id file not found, generating.", "WARNING"))
            keygen_output = zettaknight_utils.ssh_keygen(
                zettaknight_globs.identity_file)
            ret[pool_name]['Generate SSH Keygen'] = keygen_output[
                zettaknight_globs.fqdn]['Generate SSH Key']
        else:
            print("{0} exists, moving on".format(
                zettaknight_globs.identity_file))
        ######################################################

        ############# backup luks headers ####################
        print("backing up luks headers for {0}".format(pool_name))
        luks_backup_output = zettaknight_utils.backup_luks_headers()
        ret[pool_name]['Backup Luks Headers'] = luks_backup_output[
            zettaknight_globs.fqdn]['Backup Luks Headers']
        ######################################################

        ######## create zettaknight configuration file #######
        if not os.path.isdir(zettaknight_globs.conf_dir_new
                             ):  #if new directory does not exists, make it
            print("creating {0}".format(zettaknight_globs.conf_dir_new))
            os.mkdir(zettaknight_globs.conf_dir_new)
        ######################################################

        ########### create zettaknight store #################
        ######################################################
        if not os.path.isdir("/{0}".format(
                zettaknight_globs.zettaknight_store)):
            dataset_check_run = zettaknight_utils.pipe_this2(
                "/sbin/zfs list -H | grep {0}".format(
                    zettaknight_globs.zettaknight_store))
            if int(dataset_check_run.returncode) != 0:
                print("creating configuration file for {0}".format(
                    zettaknight_globs.zettaknight_store))
                zettaknight_utils.create_config(
                    dataset=zettaknight_globs.zettaknight_store)

        gerp_run = zettaknight_utils.pipe_this2(
            "/sbin/zfs list -H | /bin/grep {0}".format(
                zettaknight_globs.zettaknight_store))
        if int(gerp_run.returncode) is not 0:
            zettaknight_zfs.add_dataset(zettaknight_globs.zettaknight_store)

        #backup files to store
        files = [
            "/etc/exports", "/etc/crypttab",
            "{0}".format(zettaknight_globs.config_file_new)
        ]
        for file in files:
            if os.path.exists(file):
                destination_dir = "/{0}/{1}".format(
                    zettaknight_globs.zettaknight_store, zettaknight_globs.fqdn
                )  #add leading slash, zfs_share defined
                filename = file.replace(
                    "/", ""
                )  #remove illegal characters from file path and save file as the concatenated version
                if not os.path.isdir(destination_dir):
                    os.mkdir(destination_dir)
                print("backing up {0} to {1}".format(file, destination_dir))
                shutil.copyfile(file, "{0}/{1}".format(destination_dir,
                                                       filename))
        ######################################################
        ######################################################

        ############ create the first dataset ################
        dataset = zettaknight_utils.query_return_list(
            "Datasets to be created on {0}: ".format(pool_name))
        for item in dataset:
            dset_args = []
            dataset_full = "{0}/{1}".format(pool_name, item)
            dset_args.append(dataset_full)
            dset_args.append("create_config=True")
            add_dset_output = zettaknight_zfs.add_dataset(
                *dset_args)  #from zettaknight_utils
            ret[pool_name]['Add dataset {0}'.format(
                dataset_full)] = add_dset_output[dataset_full]['add_dataset']
        ######################################################

        ###### create server to server transfer pathing ######
        replication_output = zettaknight_zfs.configure_replication(
        )  #from zettaknight_zfs
        for repl_job, repl_job_output in replication_output[
                dataset_full].itervalues():
            ret[pool_name]['{0}'.format(repl_job)] = repl_job_output
        ######################################################

    except Exception as e:
        print(zettaknight_utils.printcolors(e, "FAIL"))
        sys.exit(1)

    zettaknight_globs.zfs_conf = _get_conf()

    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 rename_dataset(**kwargs):
    '''
    '''
    
    import paramiko
    
    try: 
        
        conf_file = zettaknight_globs.config_file_new
        
        if not 'keyfile' in kwargs.iterkeys():
            keyfile = zettaknight_globs.identity_file
        
        if not 'dataset' in kwargs.iterkeys():
            raise ValueError('A very specific bad thing happened')
            #required argument, show_help
        else:
            dataset = kwargs['dataset']
        
        if not 'new_dataset' in kwargs.iterkeys():
            #required argument, show_help
            raise ValueError('A very specific bad thing happened')
        else:
            new_dataset = kwargs['new_dataset']
            
        if not 'user' in kwargs.iterkeys():
            user = zettaknight_globs.zfs_conf[dataset]['user']
            print("user is {0}".format(user))
            
        remote_server = []
        for r_server in zettaknight_globs.zfs_conf[dataset]['snap']['remote_server']:
            remote_server.append(r_server)
            print(remote_server)
    
    except Exception as e:
        print(zettaknight_utils.printcolors(e, "FAIL"))
        sys.exit(1)
        
    ret = {}
    ret[zettaknight_globs.fqdn] = {}
    ret[zettaknight_globs.fqdn]['rename {0}'.format(dataset)] = {}
    
    try:
        for r in remote_server:
            ssh = paramiko.SSHClient()
            ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
            ssh.connect(r, username=user, key_filename=keyfile)
            remote_sudo_cmd = "zfs rename {0} {1}".format(dataset, new_dataset)
            ssh_stdin, ssh_stdout, ssh_stderr = ssh.exec_command(remote_sudo_cmd)  
            print ssh_stdout.read()
 
        #call function replace_string
        replace_string(dataset, new_dataset, conf_file)
 
        cmd = "zfs rename {0} {1}".format(dataset, new_dataset)
        zettaknight_utils.spawn_job(cmd)
    except Exception as e:
        print(zettaknight_utils.printcolors(e, "FAIL"))
        sys.exit(1)
        
        
    ret[zettaknight_globs.fqdn]['rename {0}'.format(dataset)] = {0 : "successfully renamed {0} to {1}, all records have been updated".format(dataset, new_dataset)}
    
    return ret
示例#10
0
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 first_step():
    ret = {}
    arg_dict = {}
    
    try:
        
        pool_name = "zfs_data" #default pool name 
        arg_dict["pool_name"] = pool_name
        
        ret[pool_name] = {}
        
        ############### creation of the zpool ################
        ######################################################
        
        #test if a zpool exists
        zpool_list_cmd = "/sbin/zpool list -H"
        zpool_list_run = zettaknight_utils.spawn_job(zpool_list_cmd)
        chk_code, chk_msg = zpool_list_run.popitem()
        if int(chk_code) != 0: #if zpool list -H returns empty
            #query_return_item is defined in zettaknight_utils
            create_pool_question = zettaknight_utils.query_yes_no("No pool detected, would you like to create one?")
            if create_pool_question:
                arg_dict["disk_list"] = zettaknight_utils.query_return_item("File containing all list of disks to be used for {0}, I.E /tmp/bunchofdisks.txt: ".format(pool_name))
                arg_dict["raid"] = zettaknight_utils.query_return_item("Raid level to be used [1-3]. I.E. 4+1, 5+2, 1+1: ")
                arg_dict["ashift"] = zettaknight_utils.query_return_item("ashift value for {0}, value is 9 for 512 block disks and 12 for 4096 block disks: ".format(pool_name))
                arg_dict["luks"] = zettaknight_utils.query_yes_no("encrypt data disks with LUKS? ")
        
                print("creating zpool: {0}".format(pool_name))
                create_output = zettaknight_zpools.create(pool_name, **arg_dict) #from zettaknight_zpools
            #ret[pool_name]['Zpool Create'] = create_output[pool_name]['Zpool Create'] #'NoneType' object has no attribute '__getitem__'
        else:
            print("a pool already exists, moving on")
        ######################################################
        ######################################################
        
        ################## ssh key creation  #################
        print("checking for {0}".format(zettaknight_globs.identity_file))
        if not os.path.isfile(zettaknight_globs.identity_file):
            print(zettaknight_utils.printcolors("zettaknight id file not found, generating.", "WARNING"))
            keygen_output = zettaknight_utils.ssh_keygen(zettaknight_globs.identity_file)
            ret[pool_name]['Generate SSH Keygen'] = keygen_output[zettaknight_globs.fqdn]['Generate SSH Key']
        else:
            print("{0} exists, moving on".format(zettaknight_globs.identity_file))
        ######################################################
        
        ############# backup luks headers ####################
        print("backing up luks headers for {0}".format(pool_name))
        luks_backup_output = zettaknight_utils.backup_luks_headers()
        ret[pool_name]['Backup Luks Headers'] = luks_backup_output[zettaknight_globs.fqdn]['Backup Luks Headers']
        ######################################################
        
        
        ######## create zettaknight configuration file #######
        if not os.path.isdir(zettaknight_globs.conf_dir_new): #if new directory does not exists, make it
            print("creating {0}".format(zettaknight_globs.conf_dir_new))
            os.mkdir(zettaknight_globs.conf_dir_new)
        ######################################################
        
        ########### create zettaknight store #################
        ######################################################
        if not os.path.isdir("/{0}".format(zettaknight_globs.zettaknight_store)):
            dataset_check_run = zettaknight_utils.pipe_this2("/sbin/zfs list -H | grep {0}".format(zettaknight_globs.zettaknight_store))
            if int(dataset_check_run.returncode) != 0:
                print("creating configuration file for {0}".format(zettaknight_globs.zettaknight_store))
                zettaknight_utils.create_config(dataset=zettaknight_globs.zettaknight_store)
                
        gerp_run = zettaknight_utils.pipe_this2("/sbin/zfs list -H | /bin/grep {0}".format(zettaknight_globs.zettaknight_store))
        if int(gerp_run.returncode) is not 0:
            zettaknight_zfs.add_dataset(zettaknight_globs.zettaknight_store)
        
        
        #backup files to store
        files = ["/etc/exports", "/etc/crypttab", "{0}".format(zettaknight_globs.config_file_new)]
        for file in files:
            if os.path.exists(file):
                destination_dir = "/{0}/{1}".format(zettaknight_globs.zettaknight_store, zettaknight_globs.fqdn) #add leading slash, zfs_share defined
                filename = file.replace("/", "") #remove illegal characters from file path and save file as the concatenated version
                if not os.path.isdir(destination_dir):
                    os.mkdir(destination_dir)
                print("backing up {0} to {1}".format(file, destination_dir))
                shutil.copyfile(file, "{0}/{1}".format(destination_dir, filename))
        ######################################################
        ######################################################
        
        ############ create the first dataset ################
        dataset = zettaknight_utils.query_return_list("Datasets to be created on {0}: ".format(pool_name))
        for item in dataset:
            dset_args = []
            dataset_full = "{0}/{1}".format(pool_name, item)
            dset_args.append(dataset_full)
            dset_args.append("create_config=True")
            add_dset_output = zettaknight_zfs.add_dataset(*dset_args) #from zettaknight_utils
            ret[pool_name]['Add dataset {0}'.format(dataset_full)] = add_dset_output[dataset_full]['add_dataset']
        ######################################################
        
        ###### create server to server transfer pathing ######
        replication_output = zettaknight_zfs.configure_replication() #from zettaknight_zfs
        for repl_job, repl_job_output in replication_output[dataset_full].itervalues():
            ret[pool_name]['{0}'.format(repl_job)] = repl_job_output
        ######################################################
    
    except Exception as e:
        print(zettaknight_utils.printcolors(e, "FAIL"))
        sys.exit(1)
    
    zettaknight_globs.zfs_conf = _get_conf()
    
    return ret
示例#12
0
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