def __init__(conf: Configuration, search_pattern: str, own: bool): ostack = OpenStack(conf) image_id_ref: Dict[str, DiskImageInfo] = {img.id: img for img in ostack.images} images: List[tuple[DiskImageInfo, str, DiskImageInfo]] = [ ] # Snap Image, Base Image Name, Base Image user_id = conf.user_id _search_pattern = search_pattern.lower() if search_pattern else None max_name_len: TableMaxValue[int] = TableMaxValue(0) max_base_name: TableMaxValue[int] = TableMaxValue(0) for image in ostack.images: if own and image.user_id != user_id: continue if not image.image_type: continue if search_pattern and _search_pattern not in image.name.lower(): continue base_image: DiskImageInfo = image_id_ref[ image. base_image_ref] if image.base_image_ref in image_id_ref else None base_os_image: OSImageInfo = ostack.get_os_image( base_image) if base_image else None base_image_name: str = base_os_image.name if base_os_image else\ base_image.name if base_image else "unknown" max_name_len.process(len(image.name)) max_base_name.process(len(base_image_name)) images.append(( image, base_image_name, base_image, )) table = TableOutput(TableColumn("Name", max_name_len.value), TableColumn("Status", 10), TableColumn("Base Image Name", max_base_name.value), TableColumn("Snap Size | Base Sise | Total Size", 36), TableColumn("Visibility", 10)) table.print_header() for image, base_name, base_image in images: snap_size = TableSizeColumn(image.size) base_image_size = TableSizeColumn( base_image.size) if base_image else snap_size table.print_row( image.name, image.status, base_name, f"{(snap_size-base_image_size).value:>10} | {base_image_size.value:>10} | {snap_size.value:>10}", image.visibility)
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)