def __init__(conf: Configuration, image_name: str, sort_by_name: bool, all: bool): sort_keys = { True: lambda x: x.name, False: lambda x: (x.vcpus, x.ram, x.disk, x.ephemeral_disk) } ostack = OpenStack(conf) if image_name: images = list(ostack.get_image_by_alias(image_name)) if images and len(images) > 1: Console.print_error( f"Image '{image_name}' matches more than one image") return elif not images: Console.print_error(f"No image with name '{image_name}' found") return flavors = sorted(ostack.get_flavors(images[0]), key=sort_keys[sort_by_name]) else: flavors = sorted(ostack.flavors, key=sort_keys[sort_by_name]) table = TableOutput(TableColumn("Name", 20), TableColumn("vCPU", 5), TableColumn("RAM", 9), TableColumn("D+E Size", 15), TableColumn("Disk", 15), TableColumn("Ephemeral Disk", 15), TableColumn("Id", 36)) table.print_header() for flavor in flavors: if not all and flavor.ephemeral_disk == 0: continue table.print_row(flavor.name, flavor.vcpus, TableSizeColumn(flavor.ram).value, TableSizeColumn(flavor.sum_disk_size).value, TableSizeColumn(flavor.disk).value, TableSizeColumn(flavor.ephemeral_disk).value, flavor.id)
def __init__(conf: Configuration, name: str, count: int, flavor: str, image: str, key: str, password: str): def __work_unit(x: OpenStackVMInfo) -> bool: while True: if x.status == ServerState.active: return True if x.status not in [ ServerState.building, ServerState.build, ServerState.active ]: return False sleep(2) # ToDo: short term cache data by reservation_id x = ostack.get_server_by_id(x) # ====================================================================== ostack = OpenStack(conf) vh = ValueHolder(2) def __filter(vm: OpenStackVMInfo) -> bool: r = not str(vm.name).startswith(name) if not r: vh.set_if_bigger(0, len(vm.cluster_name)) vh.set_if_bigger(1, len(vm.flavor.name)) return r servers = ostack.get_server_by_cluster(name, True, filter_func=__filter) if len(servers) > 1: Console.print_warning( f"Cluster with name '{Colors.BRIGHT_WHITE.wrap(name)}' already exists, instance would be not be created" ) print_cluster(servers, vh) return elif len(servers) == 1: Console.print_info( f"The cluster already exists, will add requested amount of hosts to the cluster" ) with Console.status_context( f"Obtaining cluster information from existing {name}..."): cluster_name, hosts = next(iter(servers.items())) cluster_name: str = cluster_name hosts: List[OpenStackVMInfo] = hosts host: OpenStackVMInfo = hosts[0] # re-calculate host names last_host_name = hosts[-1:][0].name _, _, num = last_host_name.rpartition("-") _start_num: int = 1 if num and num.isnumeric(): _start_num: int = int(num) + 1 name: List[str] = [ f"{cluster_name}-{num}" for num in range(_start_num, _start_num + count) ] image: OSImageInfo = ostack.get_os_image(host.image) img_flavor: OSFlavor = host.flavor _default_key = ostack.get_keypairs()[0] if ostack.get_keypairs( ) else None _key = ostack.get_keypair(host.key_name, _default_key) _pass = conf.default_vm_password if not password else password print(f" |Image flavor to use: {img_flavor.name}") print(f" |Image to use : {image.alias}") print(f" |Key to use : {_key.name}") print(f" |Hosts to add : {', '.join(name)}") else: with Console.status_context("Resolving cluster configuration"): image: List[OSImageInfo] = list(ostack.get_image_by_alias(image)) if not image: raise RuntimeError("Cannot resolve image name for the request") image: OSImageInfo = image[0] img_flavor = ostack.get_flavor(image, flavor) _default_key = ostack.get_keypairs()[0] if ostack.get_keypairs( ) else None _key = _default_key if not key else ostack.get_keypair( key, _default_key) _pass = conf.default_vm_password if not password else password # == create nodes so = StatusOutput(__work_unit, pool_size=2, additional_errors=ostack.last_errors) with Console.status_context("Asking for node creation"): servers = ostack.create_instances(cluster_names=name, image=image, flavor=img_flavor, password=_pass, count=count, ssh_key=_key) if not servers: so.check_issues() return so.start("Creating nodes ", objects=servers) # == Configure nodes def __work_unit_waiter(x: OpenStackVMInfo) -> bool: tries: int = 0 while tries < 200: log = ostack.get_server_console_log(x.id) for l in log: if "finished" in l or "login:"******"Configure nodes", servers) console = ostack.get_server_console_log(servers[0], grep_by="cloud-init") to = TableOutput(TableColumn("Name", 15), TableColumn("Value", 30)) to.print_header(custom_header="SUMMARY") for line in console: if "@users@" in line: users = line.split("@users@:")[1].strip().split(" ") to.print_row("Accounts", ",".join(users)) to.print_row("Key", _key.name if _key else "Not used") to.print_row("Password", _pass)