Пример #1
0
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)
Пример #2
0
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)