예제 #1
0
def in_cli(argv=sys.argv[1:]):
    try:
        arguments = commandline_to_docopt(argv)
        return arguments_to_functions(arguments)
    except KeyboardInterrupt:
        log(logger, "Keyboard break received, exiting")
        return 1
예제 #2
0
파일: lib.py 프로젝트: Infinidat/smb.cli
def prechecks():
    from smb.cli.ibox_connect import InfiSdkObjects
    log(logger, "Running Prechecks...", level=INFO)
    sdk = InfiSdkObjects()
    sdk.get_ibox()
    is_cluster_online()
    am_I_master()
    return sdk
예제 #3
0
def run_fs_attach(arguments, sdk):
    from smb.cli.fs import fs_attach
    config = config_get(silent=True)
    lib.approve_danger_op(
        "Adding volume {} to Cluster {}".format(arguments['--name'],
                                                config['Cluster']), arguments)
    log(logger, "calling {}")
    fs_attach(arguments['--name'], sdk, arguments['--force'])
예제 #4
0
def delete_volume_on_infinibox(volume_name, sdk):
    ibox = sdk.get_ibox()
    volume = ibox.volumes.choose(name=volume_name)
    volume.delete()
    log(logger,
        "Volume {} was deleted".format(volume_name),
        level=INFO,
        color="yellow")
예제 #5
0
def unmap_vol_from_cluster_infinibox(volume_name, sdk):
    ibox = sdk.get_ibox()
    cluster = sdk.get_cluster()
    volume = ibox.volumes.choose(name=volume_name)
    cluster.unmap_volume(volume)
    log(logger,
        "Volume {} was unmapped".format(volume.get_name()),
        color="yellow",
        level=INFO)
예제 #6
0
def map_vol_to_cluster_infinibox(volume, sdk):
    cluster = sdk.get_cluster()
    try:
        mapping = cluster.map_volume(volume)
    except:
        error = sys.exc_info()[1]
        log_n_raise(
            logger, "Couldn't Map Volume {} to {}! {!r}".format(
                volume.get_name(), cluster.get_name(), str(error.message)))
    log(logger,
        "Mapping {} to {}".format(volume.get_name(), cluster.get_name()),
        level=INFO)
예제 #7
0
def unmap_volume(volume_name, mountpoint, sdk):
    import os
    unmap_vol_from_cluster_infinibox(volume_name, sdk)
    try:
        if os.listdir(mountpoint) == []:
            os.rmdir(mountpoint)
        else:
            log(logger,
                "Not Deleting {} Because it's Not Empty".format(mountpoint),
                color="yellow",
                level=INFO)
    except Exception as e:
        log(logger, "{}".format(e))
예제 #8
0
def read_config(filename):
    if path.exists(filename):
        config = powershell_config_to_dict(filename)
        if config is None:
            log(
                logger, "config file {} was empty!".format(filename,
                                                           level=WARNING,
                                                           color="yellow"))
            generate_config()
        return config
    else:
        log(logger,
            "Config file did not exist on {}. Generating it".format(filename),
            level=INFO)
        generate_config()
예제 #9
0
def _winid_serial_table_to_dict():
    import re
    disk_list = []
    cmd_output = execute([
        'powershell', '-c', 'Get-Disk', '|', 'Select-Object',
        'Number,SerialNumber'
    ]).get_stdout()
    cmd_output = cmd_output.replace("Number SerialNumber", "").replace("-", "")
    regex = re.compile(r'(?P<winid>\d+)\ (?P<serial>\w+)')
    for line in cmd_output.splitlines():
        result = re.search(regex, line)
        if result:
            disk_list.append(result.groupdict())
    log(logger, "winid serial dict: {}".format(disk_list))
    return disk_list
예제 #10
0
def change_powershell_config(key, value):
    import fileinput
    config = read_config(conf_file)
    if not config:
        log_n_raise(logger, "Problem reading config file")
    log(logger, "Changing {} = {}".format(key, value), level=INFO)
    for line in fileinput.input(conf_file, inplace=True):
        if "=" not in line:
            print line,
            continue
        line_key, line_val = line.split("=")
        if line_key.strip() == key:
            print '    {} = "{}"'.format(key, value)
        else:
            print line,
    fileinput.close()
예제 #11
0
def generate_config():
    default_conf_content = '''@{
    TempDriveLetter = "Z:\"
    MountRoot = "G:\"
    PoolName = "<infinibox_pool>"
    Cluster = "<infinibox_cluster>"
    IboxAddress = "<infinibox_address>"
    FSRoleName = "<ms_role_name>"
}
'''
    with open(conf_file, 'w') as fd:
        fd.write(default_conf_content)
    log(logger,
        "Vanilla config file was generated at {}".format(conf_file),
        level=INFO,
        color="green")
    raise SmbCliExited()
예제 #12
0
 def tearDownClass(cls):
     log(logger, "Starting Teardown")
     sdk = InfiSdkObjects()
     for fs in fs_names + ['fs_test_for_shares']:
         try:
             cmd = [
                 'smbmgr', 'fs', 'delete', '--name={}'.format(fs), '--yes'
             ]
             execute(cmd)
         except:
             pass
     try:
         for fs in fs_names + ['fs_test_for_shares']:
             vol = sdk.volumes.choose(name=fs)
             vol.delete
     except:
         pass
예제 #13
0
def config_get(silent=False, skip_validation=False):
    if not path.exists(conf_dir):
        mkdir(conf_dir)
        generate_config()
    config = read_config(conf_file)
    if silent or not config:
        return config
    log(logger, "Current Config:", level=INFO, raw=True)
    for key, val in config.items():
        message = "    {}: {}".format(key, val)
        log(logger, message, level=INFO, raw=True)
    if not skip_validation:
        validate_config(config)
    if not path.exists(infinihost_bin):
        log_n_raise(
            logger,
            'smb.cli depends on "Host Power Tools" and can NOT find it!')
    return config
예제 #14
0
파일: lib.py 프로젝트: Infinidat/smb.cli
def get_path_free_size(full_path):
    ''' inspired by:
    http://code.activestate.com/recipes/577972-disk-usage/
    '''
    import ctypes
    from capacity import byte
    size = {}
    _, total, free = ctypes.c_ulonglong(), ctypes.c_ulonglong(), ctypes.c_ulonglong()
    space = ctypes.windll.kernel32.GetDiskFreeSpaceExA
    result = space(str(full_path), ctypes.byref(_), ctypes.byref(total), ctypes.byref(free))
    if result == 0:
        return
    used = total.value - free.value
    size['size'] = total.value * byte
    size['used'] = used * byte
    size['avail'] = free.value * byte
    log(logger, "sizes are {}".format(size))
    return size
예제 #15
0
def fs_create(volume_name, volume_pool, volume_size, sdk):
    _validate_max_amount_of_volumes(sdk)
    _validate_vol_name(volume_name)
    ibox = sdk.get_ibox()
    volume = create_volume_on_infinibox(volume_name, volume_pool, volume_size,
                                        sdk)
    try:
        map_vol_to_cluster_infinibox(volume, sdk)
        lib.exit_if_vol_not_mapped(volume)
    except:
        log(logger,
            "Something went wrong. Rolling back operations...",
            level=ERROR,
            color="red")
        unmap_volume(volume_name, _get_default_mountpoint(volume_name), sdk)
        delete_volume_on_infinibox(volume_name, sdk)
        raise SmbCliExited
    fs = Fs(volume, sdk)
    log(logger,
        "Preparing Filesystem for {}. This might take a while. \nDO NOT EXIT!".
        format(volume_name),
        level=INFO,
        color="yellow")
    if fs.get_winid() is None:
        fs = Fs(volume, sdk)
    try:
        ps_cmd._run_prep_vol_to_cluster_script(fs)
    except:
        log(logger,
            "Something went wrong. Rolling back operations...",
            level=ERROR,
            color="red")
        unmap_volume(volume_name, _get_default_mountpoint(volume_name), sdk)
        delete_volume_on_infinibox(volume_name, sdk)
        raise SmbCliExited
    try:
        fs_attach(volume_name, sdk, force=True)
    except:
        log(logger,
            "Something went wrong. Rolling back operations...",
            level=ERROR,
            color="red")
        try:
            ps_cmd._run_move_cluster_volume_offline(volume_name)
        except:
            pass
        try:
            lib.cluster_remove_ms_volume_and_wait(volume_name)
        except:
            pass
        unmap_volume(volume_name, _get_default_mountpoint(volume_name), sdk)
        delete_volume_on_infinibox(volume_name, sdk)
        raise SmbCliExited
예제 #16
0
def create_volume_on_infinibox(volume_name, pool_name, size, sdk):
    ibox = sdk.get_ibox()
    pool = _validate_pool(pool_name, ibox, size)
    try:
        log(logger,
            "Creating Volume {} at {}".format(volume_name, pool_name),
            level=INFO)
        volume = ibox.volumes.create(name=volume_name,
                                     pool=pool,
                                     size=size,
                                     provtype='THIN')
        volume.set_metadata('volume.provisionedby',
                            'smb.cli-{}'.format(__version__))
        return volume
    except:
        error = sys.exc_info()[1]
        log_n_raise(
            logger, "Volume {} couldn't be created. {!r}".format(
                volume_name, str(error.message)))
예제 #17
0
def fs_attach(volume_name, sdk, force=False):
    ibox = sdk.get_ibox()
    _validate_max_amount_of_volumes(sdk)
    _validate_vol_name(volume_name)
    volume = _validate_vol(ibox, volume_name)
    if force and lib.is_volume_mapped_to_cluster(volume, sdk):
        pass
    else:
        map_vol_to_cluster_infinibox(volume, sdk)
    lib.exit_if_vol_not_mapped(volume)
    fs = Fs(volume, sdk)
    _mountpoint_exist(fs.get_mountpoint())
    try:
        ps_cmd._run_attach_vol_to_cluster_script(fs)
    except:
        log_n_raise(logger,
                    "Couldn't add {} to SMB Cluster".format(volume_name))
    log(logger,
        "Volume {} Attached to Cluster Successfully.".format(volume_name),
        level=INFO,
        color="green")
예제 #18
0
def arguments_to_functions(arguments):
    log(logger, "Arguments received from user:{}".format(arguments))
    try:
        if arguments['config']:
            if arguments['get']:
                run_config_get()
                return
            if arguments['set']:
                run_config_set(arguments)
                return
        try:
            config = config_get(silent=True)
        except SmbCliExited:
            return
        sdk = lib.prechecks()
        if arguments['fs']:
            arguments = _use_default_config_if_needed(arguments)
            if arguments['create']:
                run_fs_create(arguments, sdk)
            if arguments['delete']:
                run_fs_delete(arguments, sdk)
            if arguments['attach']:
                run_fs_attach(arguments, sdk)
            if arguments['detach']:
                run_fs_detach(arguments, sdk)
            if arguments['query']:
                run_fs_query(arguments, sdk)
        if arguments['share']:
            if arguments['create']:
                run_share_create(arguments, sdk)
            if arguments['query']:
                run_share_query(arguments, sdk)
            if arguments['resize']:
                run_share_resize(arguments, sdk)
            if arguments['delete']:
                run_share_delete(arguments)
    except KeyboardInterrupt:
        log(logger, "Keyboard break received, exiting")
        return
    except SmbCliExited:
        return 1
    except Exception as e:
        log(logger, traceback.format_exc())
        message = '''{} \n(This is Unusual)
Please collect the Logs from "{}" and open a ticket on github'''
        log(logger,
            message.format(e, logger.handlers[0].baseFilename),
            level=ERROR,
            color="red")
        return 1
예제 #19
0
def run_config_set(arguments):
    from smb.cli.config import config_set, config_get
    config = config_get(silent=True)
    log(logger, "Current Config:", raw=True)
    if config is None:
        return
    key, value = arguments.get('<key=value>', "").split("=")
    config_case_sensitive = {item.lower(): item for item in config.keys()}
    if key.lower() not in config_case_sensitive.keys():
        log(logger,
            "{} is not valid for your config".format(key),
            color="red",
            raw=True)
        return
    config_set(config_case_sensitive[key.lower()], value)
    log(logger, "New Config:", level=INFO)
    config_get(skip_validation=True)
예제 #20
0
def commandline_to_docopt(argv):
    import docopt
    global output_stream
    lib._init_colorama()
    output_stream = sys.stdout
    doc = __doc__
    try:
        return docopt.docopt(
            doc.format(version=__version__,
                       privileges_text=lib.get_privileges_text()).strip(),
            version=__version__,
            help=True,
            argv=argv)
    except docopt.DocoptExit as e:
        log(logger, e, level=INFO, raw=True)
        log(logger, "Invalid Arguments", level=ERROR, color="red")
        log(logger, argv)
        exit(1)
예제 #21
0
def _mountpoint_exist(mountpoint):
    '''Check if mount point exist otherwise create it
    '''
    if not path.exists(mountpoint):
        log(logger, "Creating mount path {}".format(mountpoint), level=DEBUG)
        mkdir(mountpoint)
예제 #22
0
def print_fs_query(mapped_vols, print_units, serial_list, sdk, detailed=False):
    from smb.cli.share import _share_query_to_share_instance
    shares = _share_query_to_share_instance()
    shares_paths = [share.get_path() for share in shares]
    if len(mapped_vols) <= 2:
        log(logger,
            "No InfiniBox Volumes are Mapped to the Cluster",
            level=INFO)
        return
    ibox = mapped_vols[0].get_system()
    vols_in_cluster = ps_cmd._get_cluster_vols().splitlines()
    print_output = ""
    for volume in mapped_vols:
        volume_name = volume.get_name()
        # Hide irrelevant stuff
        if volume_name in ["mountpoint", "witness"]:
            continue
        if volume_name not in vols_in_cluster:
            continue
        if not path.exists(_get_default_mountpoint(volume_name)):
            continue
        volume_serial = volume.get_serial()
        win_id = None
        for disk in serial_list:
            if disk['serial'] == volume_serial:
                win_id = disk['winid']
                break
        fs = Fs(volume, sdk, win_id)
        num_of_shares = lib.count_shares_on_fs(fs.get_mountpoint(),
                                               shares_paths)
        if print_units:
            fs_size = "{:.2f}".format(
                float(
                    str(
                        float(fs.get_fs_size().roundup(MiB) / MiB) * MiB /
                        print_units)))
            fs_size = fs_size + " " + str(print_units)[2:]
            used_size = "{:.2f}".format(
                float(
                    str(
                        float(fs.get_used_size().roundup(MiB) / MiB) * MiB /
                        print_units)))
            used_size = used_size + " " + str(print_units)[2:]
        else:
            fs_size = fs.get_fs_size(
            ) if Capacity(0) != fs.get_fs_size() else 0
            used_size = fs.get_used_size(
            ) if Capacity(0) != fs.get_used_size() else 0
        if detailed:
            line = [
                "{}: {}".format("name", fs.get_name()),
                "{}: {}".format("mount", fs.get_mountpoint()),
                "{}: {}".format("size", str(fs_size)),
                "{}: {}".format("used_size", str(used_size)),
                "{}: {}".format("snaps", str(fs.get_num_snaps())),
                "{}: {}".format("shares", str(num_of_shares))
            ]
        else:
            line = [
                _print_format(fs.get_name(), "name"),
                _print_format(fs.get_mountpoint(), "mount"),
                _print_format(
                    str(fs_size),
                    "size",
                ),
                _print_format(str(used_size), "used_size"),
                _print_format(str(fs.get_num_snaps()), "snaps"),
                _print_format(str(num_of_shares), "shares")
            ]
        log(logger, line)
        print_output = print_output + " ".join(line) + '\n'
    if print_output.splitlines() == []:
        log(logger,
            "No InfiniBox Volumes are Mapped to the Cluster",
            level=INFO)
        return
    header = 'Name               Mount              Size         Used Size    Snaps   Shares'
    log(logger, header, level=INFO, raw=True)
    print print_output
예제 #23
0
파일: lib.py 프로젝트: Infinidat/smb.cli
def approve_danger_op(message, arguments):
    if arguments['--yes'] is False:
        full_massage = "This Operations is considered dangerous!\nPlease Confirm: {}".format(message)
        log(logger, full_massage, level=WARNING, color="yellow")
        approve_operation()