Пример #1
0
def config_func(args: Namespace):
    try:
        dstack_config = get_config()
        # TODO: Support non-default profiles
        profile = dstack_config.get_profile("default")
        user_info = get_user_info(profile)
        data = {
            "aws_access_key_id": get_or_ask(args, None, "aws_access_key_id", "AWS Access Key ID: ", secure=True),
            "aws_secret_access_key": get_or_ask(args, None, "aws_secret_access_key", "AWS Secret Access Key: ",
                                                secure=True),
            "aws_region":
                get_or_ask(args, None, "aws_region",
                           f"Region name [{user_info['default_configuration']['aws_region']}]: ", secure=False,
                           required=False),
            "artifacts_s3_bucket": get_or_ask(args, None, "artifacts_s3_bucket", "Artifacts S3 bucket [None]: ",
                                              secure=False, required=False)
        }
        response = do_post("users/aws/info")
        if response.status_code == 200:
            response_json = response.json()
            if response_json.get("aws_access_key_id") is None \
                    and response_json.get("aws_secret_access_key") is None \
                    and response_json.get("aws_region") is None \
                    and response_json.get("artifacts_s3_bucket") is None:
                send_aws_config_request(data)
            else:
                if args.force or confirm(f"Do you want to override the previous configuration?"):
                    send_aws_config_request(data)
                else:
                    print(f"{colorama.Fore.RED}Cancelled{colorama.Fore.RESET}")
        else:
            response.raise_for_status()
    except ConfigurationError:
        sys.exit(f"Call 'dstack config' first")
Пример #2
0
def limit_func(args: Namespace):
    if args.delete:
        if args.force or confirm(f"Are you sure you want to delete the limit?"):
            try:
                data = {
                    "region_name": args.region,
                    "instance_type": args.instance_type,
                    "purchase_type": "spot" if args.spot else "on-demand"
                }
                response = do_post("on-demand/limits/delete", data)
                if response.status_code == 200:
                    print(f"{colorama.Fore.LIGHTBLACK_EX}OK{colorama.Fore.RESET}")
                if response.status_code == 400 and response.json().get("message") == "aws is not configured":
                    sys.exit(f"Call 'dstack aws config' first")
                if response.status_code == 404 and response.json().get("message") == "limit not found":
                    sys.exit(f"Limit doesn't exist")
                if response.status_code == 404 and response.json().get("message") == "region not found":
                    sys.exit(f"Region is not supported")
                if response.status_code == 404 and response.json().get("message") == "instance type not found":
                    sys.exit(f"Instance type is not supported")
                else:
                    response.raise_for_status()
            except ConfigurationError:
                sys.exit(f"Call 'dstack config' first")
        else:
            print(f"{colorama.Fore.RED}Cancelled{colorama.Fore.RESET}")
    else:
        try:
            data = {
                "region_name": args.region,
                "instance_type": args.instance_type,
                "purchase_type": "spot" if args.spot else "on-demand",
                "maximum": args.max,
            }
            response = do_post("on-demand/limits/set", data)
            if response.status_code == 200:
                print(f"{colorama.Fore.LIGHTBLACK_EX}OK{colorama.Fore.RESET}")
            if response.status_code == 400 and response.json().get("message") == "aws is not configured":
                sys.exit(f"Call 'dstack aws config' first")
            if response.status_code == 404 and response.json().get("message") == "region not found":
                sys.exit(f"Region is not supported")
            if response.status_code == 404 and response.json().get("message") == "instance type not found":
                sys.exit(f"Instance type is not supported")
            else:
                response.raise_for_status()
        except ConfigurationError:
            sys.exit(f"Call 'dstack config' first")
Пример #3
0
def do_clear_request():
    response = do_post("users/aws/clear")
    if response.status_code == 200:
        print(f"{colorama.Fore.LIGHTBLACK_EX}OK{colorama.Fore.RESET}")
    elif response.status_code == 400 and response.json().get("message") == "non-cancelled requests":
        sys.exit(f"Call 'dstack autoscale clear' first")
    else:
        response.raise_for_status()
Пример #4
0
def status_func(_: Namespace):
    try:
        response = do_post("on-demand/settings")
        if response.status_code == 200:
            response_json = response.json()
            print(f"{colorama.Fore.LIGHTMAGENTA_EX}Enabled{colorama.Fore.RESET}: " + (
                f"{colorama.Fore.LIGHTRED_EX}No{colorama.Fore.RESET}" if response_json.get(
                    "enabled") is False else f"{colorama.Fore.LIGHTGREEN_EX}Yes{colorama.Fore.RESET}"))
        else:
            response.raise_for_status()
    except ConfigurationError:
        sys.exit(f"Call 'dstack config' first")
Пример #5
0
def enable_func(_: Namespace):
    try:
        data = {
            "enabled": True
        }
        response = do_post("on-demand/settings/update", data)
        if response.status_code == 200:
            print(f"{colorama.Fore.LIGHTBLACK_EX}OK{colorama.Fore.RESET}")
        else:
            response.raise_for_status()
    except ConfigurationError:
        sys.exit(f"Call 'dstack config' first")
Пример #6
0
def disable_func(args: Namespace):
    if args.force or confirm(f"Are you sure you want to disable on-demand runners?"):
        try:
            data = {
                "enabled": False
            }
            response = do_post("on-demand/settings/update", data)
            if response.status_code == 200:
                print(f"{colorama.Fore.LIGHTBLACK_EX}OK{colorama.Fore.RESET}")
            else:
                response.raise_for_status()
        except ConfigurationError:
            sys.exit(f"Call 'dstack config' first")
    else:
        print(f"{colorama.Fore.RED}Cancelled{colorama.Fore.RESET}")
Пример #7
0
def limits_func(args: Namespace):
    if args.delete_all:
        if args.force or confirm(f"Are you sure you want to delete all limits?"):
            try:
                response = do_post("on-demand/limits/clear")
                if response.status_code == 200:
                    print(f"{colorama.Fore.LIGHTBLACK_EX}OK{colorama.Fore.RESET}")
                else:
                    response.raise_for_status()
            except ConfigurationError:
                sys.exit(f"Call 'dstack config' first")
        else:
            print(f"{colorama.Fore.RED}Cancelled{colorama.Fore.RESET}")
    else:
        try:
            response = do_get("on-demand/limits/query")
            if response.status_code == 200:
                table_headers = [
                    f"{colorama.Fore.LIGHTMAGENTA_EX}REGION{colorama.Fore.RESET}",
                    f"{colorama.Fore.LIGHTMAGENTA_EX}INSTANCE TYPE{colorama.Fore.RESET}",
                    f"{colorama.Fore.LIGHTMAGENTA_EX}CPU{colorama.Fore.RESET}",
                    f"{colorama.Fore.LIGHTMAGENTA_EX}MEMORY{colorama.Fore.RESET}",
                    f"{colorama.Fore.LIGHTMAGENTA_EX}GPU{colorama.Fore.RESET}",
                    f"{colorama.Fore.LIGHTMAGENTA_EX}PURCHASE TYPE{colorama.Fore.RESET}",
                    f"{colorama.Fore.LIGHTMAGENTA_EX}MAXIMUM{colorama.Fore.RESET}",
                    f"{colorama.Fore.LIGHTMAGENTA_EX}STATUS{colorama.Fore.RESET}"
                ]
                table_rows = []
                for limit in response.json()["limits"]:
                    availability_issues_at = pretty_date(
                        round(limit["availability_issues_at"] / 1000)) if limit.get("availability_issues_at") else ""
                    table_rows.append([
                        limit["region_name"],
                        limit["instance_type"],
                        limit["resources"]["cpu"]["count"] if limit.get("resources") else "",
                        str(int(limit["resources"]["memory_mib"] / 1024)) + "GiB" if limit.get("resources") else "",
                        __pretty_print_gpu_resources(limit["resources"]) if limit.get("resources") else "",
                        limit["purchase_type"],
                        limit["maximum"],
                        f"{colorama.Fore.RED}{'No capacity ' + availability_issues_at}{colorama.Fore.RESET}" if limit.get(
                            "availability_issues_message") else f"{colorama.Fore.GREEN}OK{colorama.Fore.RESET}"
                    ])
                print(tabulate(table_rows, headers=table_headers, tablefmt="plain"))
            else:
                response.raise_for_status()
        except ConfigurationError:
            sys.exit(f"Call 'dstack config' first")
Пример #8
0
def info_func(_: Namespace):
    try:
        response = do_post("users/aws/info")
        if response.status_code == 200:
            response_json = response.json()
            print(f"{colorama.Fore.LIGHTMAGENTA_EX}AWS Access Key ID{colorama.Fore.RESET}: " + (
                    sensitive(response_json.get("aws_access_key_id")) or "None"))
            print(f"{colorama.Fore.LIGHTMAGENTA_EX}AWS Secret Access Key{colorama.Fore.RESET}: " + (
                    sensitive(response_json.get("aws_secret_access_key")) or "None"))
            print(f"{colorama.Fore.LIGHTMAGENTA_EX}Region name{colorama.Fore.RESET}: " + (
                    response_json.get("aws_region") or "None"))
            print(f"{colorama.Fore.LIGHTMAGENTA_EX}Artifacts S3 bucket{colorama.Fore.RESET}: " + (
                    response_json.get("artifacts_s3_bucket") or "<none>"))
        else:
            response.raise_for_status()
    except ConfigurationError:
        sys.exit(f"Call 'dstack config' first")
Пример #9
0
def clear_func(args: Namespace):
    try:
        response = do_post("users/aws/info")
        if response.status_code == 200:
            response_json = response.json()
            if response_json.get("aws_access_key_id") is None \
                    and response_json.get("aws_secret_access_key") is None \
                    and response_json.get("aws_region") is None \
                    and response_json.get("artifacts_s3_bucket") is None:
                do_clear_request()
            else:
                if args.force or confirm(f"Do you want to override the previous configuration?"):
                    do_clear_request()
                else:
                    print(f"{colorama.Fore.RED}Cancelled{colorama.Fore.RESET}")
        else:
            response.raise_for_status()
    except ConfigurationError:
        sys.exit(f"Call 'dstack config' first")