def _login(iqn, portals, multipath, lun): retries = 10 if not multipath: portals = [portals[0]] if lun == 0: for portal in portals: while True: dprint("Trying to log into target:", portal) try: exe("sudo iscsiadm -m discovery -t st -p {}:3260".format( portal)) exe("sudo iscsiadm -m node -T {iqn} -p {ip}:3260 " "--login".format(iqn=iqn, ip=portal)) break except EnvironmentError as e: if 'returned non-zero exit status 15' in str(e): break retries -= 1 if not retries: dprint("Could not log into portal before end of " "polling period") raise dprint("Failed to login to portal, retrying") time.sleep(2) _set_noop_scheduler(portals, iqn, lun) path = DEV_TEMPLATE.format(ip=portals[0], iqn=iqn, lun=lun) if multipath: dprint('Sleeping to allow for multipath devices to finish linking') time.sleep(2) dpath = _get_multipath_disk(path) else: dpath = path return dpath
def run_health(api): config = scaffold.get_config() try: exe('ping -c 1 -w 1 {}'.format(config['mgmt_ip'])) except EnvironmentError: print('Could not ping mgmt_ip:', config['mgmt_ip']) return False try: api.app_instances.list() except Exception as e: print("Could not connect to cluster", e) return False npass = True av = api.system.network.access_vip.get() for np in av['network_paths']: ip = np.get('ip') if ip: try: exe('ping -c 1 -w 1 {}'.format(ip)) except EnvironmentError: print('Could not ping: {} {}'.format(np.get('name'), ip)) npass = False if not npass: return False print("Health Check Completed Successfully") return True
def _unmount(ai_name, si_name, vol_name, directory): folder = get_dirname(directory, ai_name, si_name, vol_name) try: exe("sudo umount {}".format(folder)) except EnvironmentError as e: dprint(e) return exe("sudo rmdir {}".format(folder))
def _find_mount(ai, si, lun, multipath): ip = si.access['ips'][0] iqn = si.access['iqn'] path = DEV_TEMPLATE.format(ip=ip, iqn=iqn, lun=lun) if multipath: path = _get_multipath_disk(path) out = exe("ls -l {} | awk '{{print $NF}}'".format(path)) device = out.split("/")[-1].strip() if not device: return None, path, device mount = exe( "cat /proc/mounts | grep {} | awk '{{print $2}}'".format(device)) return mount.strip(), path, device
def _set_noop_scheduler(portals, iqn, lun): for portal in portals: path = DEV_TEMPLATE.format(ip=portal, iqn=iqn, lun=lun) device = None while True: out = exe("ls -l {} | awk '{{print $NF}}'".format(path)) device = out.split("/")[-1].strip() if device: break dprint("Waiting for device to be ready:", path) time.sleep(1) dprint("Setting noop scheduler for device:", device) exe("echo 'noop' | sudo tee /sys/block/{}/queue/scheduler".format( device))
def _logout(iqn, portals): for portal in portals: exe("sudo iscsiadm -m node -T {iqn} -p {ip}:3260 --logout".format( iqn=iqn, ip=portal), fail_ok=True) exe("sudo iscsiadm -m node -T {iqn} -p {ip}:3260 --op delete".format( iqn=iqn, ip=portal), fail_ok=True) exe("sudo iscsiadm -m discoverydb -p {ip}:3260 --op delete".format( ip=portal), fail_ok=True) exe("sudo iscsiadm -m session --rescan", fail_ok=True) exe("sudo multipath -F", fail_ok=True) dprint("Sleeping to wait for logout") time.sleep(2) dprint("Logout complete")
def _format_mount_device(path, fs, fsargs, folder): timeout = 5 while True: try: exe("sudo mkfs.{} {} {} ".format(fs, fsargs, path)) break except EnvironmentError: dprint("Checking for existing filesystem on:", path) try: out = exe( "sudo blkid {} | grep -Eo '(TYPE=\".*\")'".format(path)) parts = out.split("=") if len(parts) == 2: found_fs = parts[-1].lower().strip().strip('"') if found_fs == fs.lower(): dprint("Found existing filesystem, continuing") break except EnvironmentError: pass dprint("Failed to format {}. Waiting for device to be " "ready".format(path)) if not timeout: raise time.sleep(1) timeout -= 1 exe("sudo mkdir -p /{}".format(folder.strip("/"))) exe("sudo mount {} {}".format(path, folder)) print("Volume mount:", folder)
def _get_initiator(): file_path = '/etc/iscsi/initiatorname.iscsi' try: out = exe('sudo cat {}'.format(file_path)) for line in out.splitlines(): if line.startswith('InitiatorName='): return line.split("=", 1)[-1].strip() except EnvironmentError: dprint("Could not find the iSCSI Initiator File %s", file_path) raise
def _setup_initiator(api): initiator = _get_initiator() host = exe('hostname').strip() initiator_obj = None try: initiator_obj = api.initiators.get(initiator) # Handle case where initiator exists in parent tenant # We want to create a new initiator in the case tenant = api.context.tenant if not tenant: tenant = '/root' if initiator_obj.tenant != tenant: raise dat_exceptions.ApiNotFoundError() except dat_exceptions.ApiNotFoundError: initiator_obj = api.initiators.create(name=host, id=initiator) return initiator_obj
def _setup_initiator(api, force): initiator = _get_initiator() host = exe('hostname').strip() initiator_obj = None try: initiator_obj = api.initiators.get(initiator) # Handle case where initiator exists in parent tenant # We want to create a new initiator in the case tenant = api.context.tenant if not tenant: tenant = '/root' if initiator_obj.tenant != tenant: raise dat_exceptions.ApiNotFoundError(msg="Non matching tenant") except dat_exceptions.ApiNotFoundError: try: initiator_obj = api.initiators.create(name=host, id=initiator, force=force) except dat_exceptions.ApiInvalidRequestError: try: initiator_obj = api.initiators.create(name=host, id=initiator) except dat_exceptions.ApiInvalidRequestError as e: if "override this warning" in str(e) and not force: out = input("First initiator within a tenant needs to be " "force created. Would you like to do so? " "[Y/n]: ").strip() if out in ("Y", "y"): initiator_obj = api.initiators.create(name=host, id=initiator, force=True) else: print("Exiting due to failed initiator creation") sys.exit(1) else: raise return initiator_obj
def run_fio_from_file(fiofile): print("Running FIO job") print(fiofile) exe("sudo fio {}".format(fiofile))
def main(args): if args.csi_yaml: udc_envs_from_csi_yaml(args.csi_yaml) api = scaffold.get_api() print('Using Config:') scaffold.print_config() if args.health: if not run_health(api): return FAILURE return SUCCESS if args.force_initiator_creation: resp = input( hf("Forcing initiator creation could result in I/O " "interruption for Volumes connected to the forced " "Initiator being created within this tenant. Are you " "Sure you want to proceed? Y/n") + "\n") if resp != "Y": print("Recieved negative confirmation, exiting") return FAILURE else: print("Recieved positive confirmation. Continuing") if args.show_at_url: for url in args.show_at_url: show.at_url(api, url) return SUCCESS for arg in args.list: detail = 'detail' in arg if 'volumes' in arg: print( "###### VOLUMES {}######".format("DETAIL " if detail else '')) for vol in args.volume: list_volumes('local', api, vol, detail=detail) if not args.volume: list_volumes('local', api, 'prefix=all', detail) elif 'templates' in arg: print("###### TEMPLATES {}######".format( "DETAIL " if detail else '')) list_templates(api, detail=detail) elif 'mounts' in arg: print("###### MOUNTS ######".format("DETAIL " if detail else '')) for vol in args.volume: list_mounts('local', api, vol, detail, not args.no_multipath) else: list_mounts('local', api, 'prefix=all', detail, not args.no_multipath) elif 'alerts' in arg: print("###### ALERTS ######") list_alerts(api) if 'events' in arg: print("###### EVENTS ######") if 'system' in arg: user = '******' if 'user' in arg: user = '******' if 'id' in arg: user = args.id list_events(api, user) if 'media-policy' in arg: print("###### MEDIA POLICIES ######") list_media_policies(api) if 'placement-policy' in arg: print("###### PLACEMENT POLICIES ######") list_placement_policies(api) if args.clear_alerts: clear_alerts(api) return SUCCESS if any((args.unmount, args.logout, args.clean)): for vol in args.volume: del_keys(vol) clean_mounts(api, vol, args.directory, args.workers) if args.unmount: return SUCCESS if args.clean: for vol in args.volume: clean_volumes(api, vol, args.workers) for pp in args.placement_policy: delete_placement_policy(api, pp) for mp in args.media_policy: delete_media_policy(api, mp) return SUCCESS if args.logout: return SUCCESS # Create placement_policy/media_policy for mp in args.media_policy: create_media_policy(api, mp) for pp in args.placement_policy: create_placement_policy(api, pp) # Create volumes vols = None for vol in args.volume: vols = create_volumes("local", api, vol, args.workers) if args.get_keys: for vol in args.volume: for n, keys in get_keys(vol): print(n, ":", ' '.join(map(str, keys))) # Login/mount volumes login_only = not args.mount and args.login if (args.mount or args.login) and vols: dev_or_folders = mount_volumes(api, vols, not args.no_multipath, args.fstype, args.fsargs, args.directory, args.workers, login_only, args.force_initiator_creation, args.initiator_path) # Generate fio/vdbench output if args.fio: try: exe("which fio") except EnvironmentError: print("FIO is not installed") if args.fio and (not args.mount and not args.login): print("--mount or --login MUST be specified when using --fio") elif args.fio: gen_fio(args.fio_workload, dev_or_folders) elif args.vdbench: gen_vdb(dev_or_folders) # Retrieve metrics if args.metrics: data = None try: interval, timeout = map(int, args.metrics.split(',')) if interval < 1 or timeout < 1: raise ValueError() mtypes = args.metrics_type if not args.metrics_type: mtypes = ['iops_write'] data = get_metrics(api, mtypes, args.volume, interval, timeout, args.metrics_op) except ValueError: print("--metrics argument must be in format '--metrics i,t' where" "'i' is the interval in seconds and 't' is the timeout in " "seconds. Both must be positive integers >= 1") return FAILURE if data: write_metrics(data, args.metrics_out_file) else: print("No data recieved from metrics") return FAILURE return SUCCESS
def _get_from_secret(entry): name = entry['valueFrom']['secretKeyRef']['name'] k = entry['valueFrom']['secretKeyRef']['key'] value = exe("kubectl get secrets --namespace kube-system {} --template " "{{{{.data.{}}}}} | base64 --decode".format(name, k)) return value
def main(args): api = scaffold.get_api() print('Using Config:') scaffold.print_config() if args.health: if not run_health(api): return FAILURE return SUCCESS if 'volumes' in args.list: for vol in args.volume: list_volumes(args.run_host, api, vol, detail='detail' in args.list) return SUCCESS elif 'templates' in args.list: list_templates(api, detail='detail' in args.list) elif 'mounts' in args.list: for vol in args.volume: list_mounts(args.run_host, api, vol, 'detail' in args.list, not args.no_multipath) return SUCCESS if any((args.unmount, args.logout, args.clean)): for vol in args.volume: if args.run_host == 'local': clean_mounts(api, vol, args.directory, args.workers) else: clean_mounts_remote(args.run_host, vol, args.directory, args.workers) if args.unmount: return SUCCESS if args.clean: for vol in args.volume: clean_volumes(api, vol, args.workers) return SUCCESS if args.logout: return SUCCESS vols = None for vol in args.volume: vols = create_volumes(args.run_host, api, vol, args.workers) login_only = not args.mount and args.login if (args.mount or args.login) and vols and args.run_host == 'local': dev_or_folders = mount_volumes(api, vols, not args.no_multipath, args.fstype, args.fsargs, args.directory, args.workers, login_only) elif (args.mount or args.login) and vols and args.run_host != 'local': dev_or_folders = mount_volumes_remote(args.run_host, vols, not args.no_multipath, args.fstype, args.fsargs, args.directory, args.workers, login_only) if args.fio: try: exe("which fio") except EnvironmentError: print("FIO is not installed") if args.fio and (not args.mount and not args.login): print("--mount or --login MUST be specified when using --fio") elif args.fio and args.run_host == 'local': gen_fio(args.fio_workload, dev_or_folders) elif args.fio and args.run_host != 'local': gen_fio_remote(args.run_host, args.fio_workload, dev_or_folders) if args.metrics: data = None try: interval, timeout = map(int, args.metrics.split(',')) if interval < 1 or timeout < 1: raise ValueError() mtypes = args.metrics_type if not args.metrics_type: mtypes = ['iops_write'] data = get_metrics(api, mtypes, args.volume, interval, timeout, args.metrics_op) except ValueError: print("--metrics argument must be in format '--metrics i,t' where" "'i' is the interval in seconds and 't' is the timeout in " "seconds. Both must be positive integers >= 1") return FAILURE if data: write_metrics(data, args.metrics_out_file) else: print("No data recieved from metrics") return FAILURE return SUCCESS