oak-cli 0.2.8__tar.gz → 0.2.9__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {oak_cli-0.2.8 → oak_cli-0.2.9}/PKG-INFO +2 -1
- {oak_cli-0.2.8 → oak_cli-0.2.9}/oak_cli/args_parser/apps/delete.py +1 -1
- oak_cli-0.2.9/oak_cli/args_parser/docker/main.py +25 -0
- oak_cli-0.2.9/oak_cli/args_parser/docker/rebuild.py +66 -0
- {oak_cli-0.2.8 → oak_cli-0.2.9}/oak_cli/args_parser/main.py +1 -1
- {oak_cli-0.2.8 → oak_cli-0.2.9}/oak_cli/args_parser/plugins/flops/create.py +1 -1
- {oak_cli-0.2.8 → oak_cli-0.2.9}/oak_cli/commands/apps/main.py +5 -0
- oak_cli-0.2.9/oak_cli/commands/docker/aux_dockers/node_engine_log_observer.docker-compose.yml +18 -0
- oak_cli-0.2.9/oak_cli/commands/docker/common.py +29 -0
- oak_cli-0.2.9/oak_cli/commands/docker/enums.py +30 -0
- oak_cli-0.2.9/oak_cli/commands/docker/rebuild.py +38 -0
- oak_cli-0.2.9/oak_cli/commands/docker/restart.py +17 -0
- {oak_cli-0.2.8 → oak_cli-0.2.9}/oak_cli/commands/plugins/flops/main.py +3 -1
- {oak_cli-0.2.8 → oak_cli-0.2.9}/oak_cli/commands/services/deployment.py +3 -0
- {oak_cli-0.2.8 → oak_cli-0.2.9}/oak_cli/commands/services/get.py +3 -0
- {oak_cli-0.2.8 → oak_cli-0.2.9}/oak_cli/main.py +3 -3
- {oak_cli-0.2.8 → oak_cli-0.2.9}/oak_cli/utils/SLAs/default_app_with_services.SLA.json +1 -1
- oak_cli-0.2.9/oak_cli/utils/__init__.py +0 -0
- oak_cli-0.2.9/oak_cli/utils/api/__init__.py +0 -0
- {oak_cli-0.2.8 → oak_cli-0.2.9}/oak_cli/utils/api/custom_requests.py +19 -11
- {oak_cli-0.2.8 → oak_cli-0.2.9}/oak_cli/utils/api/login.py +2 -2
- oak_cli-0.2.9/oak_cli/utils/exceptions/__init__.py +0 -0
- oak_cli-0.2.9/oak_cli/utils/exceptions/main.py +17 -0
- oak_cli-0.2.9/oak_cli/utils/exceptions/types.py +12 -0
- {oak_cli-0.2.8 → oak_cli-0.2.9}/pyproject.toml +2 -1
- {oak_cli-0.2.8 → oak_cli-0.2.9}/README.md +0 -0
- {oak_cli-0.2.8 → oak_cli-0.2.9}/oak_cli/__init__.py +0 -0
- {oak_cli-0.2.8 → oak_cli-0.2.9}/oak_cli/args_parser/__init__.py +0 -0
- {oak_cli-0.2.8 → oak_cli-0.2.9}/oak_cli/args_parser/apps/__init__.py +0 -0
- {oak_cli-0.2.8 → oak_cli-0.2.9}/oak_cli/args_parser/apps/create.py +0 -0
- {oak_cli-0.2.8 → oak_cli-0.2.9}/oak_cli/args_parser/apps/main.py +0 -0
- {oak_cli-0.2.8 → oak_cli-0.2.9}/oak_cli/args_parser/apps/status.py +0 -0
- {oak_cli-0.2.8/oak_cli/args_parser/plugins → oak_cli-0.2.9/oak_cli/args_parser/docker}/__init__.py +0 -0
- {oak_cli-0.2.8/oak_cli/args_parser/plugins/flops → oak_cli-0.2.9/oak_cli/args_parser/plugins}/__init__.py +0 -0
- {oak_cli-0.2.8/oak_cli/args_parser/services → oak_cli-0.2.9/oak_cli/args_parser/plugins/flops}/__init__.py +0 -0
- {oak_cli-0.2.8 → oak_cli-0.2.9}/oak_cli/args_parser/plugins/flops/main.py +0 -0
- {oak_cli-0.2.8 → oak_cli-0.2.9}/oak_cli/args_parser/plugins/main.py +0 -0
- {oak_cli-0.2.8/oak_cli/commands/apps → oak_cli-0.2.9/oak_cli/args_parser/services}/__init__.py +0 -0
- {oak_cli-0.2.8 → oak_cli-0.2.9}/oak_cli/args_parser/services/deployment.py +0 -0
- {oak_cli-0.2.8 → oak_cli-0.2.9}/oak_cli/args_parser/services/main.py +0 -0
- {oak_cli-0.2.8 → oak_cli-0.2.9}/oak_cli/args_parser/services/status.py +0 -0
- {oak_cli-0.2.8/oak_cli/commands/plugins → oak_cli-0.2.9/oak_cli/commands/apps}/__init__.py +0 -0
- {oak_cli-0.2.8 → oak_cli-0.2.9}/oak_cli/commands/apps/status.py +0 -0
- {oak_cli-0.2.8/oak_cli/commands/plugins/flops → oak_cli-0.2.9/oak_cli/commands/docker}/__init__.py +0 -0
- {oak_cli-0.2.8/oak_cli/commands/services → oak_cli-0.2.9/oak_cli/commands/plugins}/__init__.py +0 -0
- {oak_cli-0.2.8/oak_cli/utils/SLAs → oak_cli-0.2.9/oak_cli/commands/plugins/flops}/__init__.py +0 -0
- {oak_cli-0.2.8 → oak_cli-0.2.9}/oak_cli/commands/plugins/flops/flops.SLA.json +0 -0
- {oak_cli-0.2.8/oak_cli/utils → oak_cli-0.2.9/oak_cli/commands/services}/__init__.py +0 -0
- {oak_cli-0.2.8 → oak_cli-0.2.9}/oak_cli/commands/services/status.py +0 -0
- {oak_cli-0.2.8/oak_cli/utils/api → oak_cli-0.2.9/oak_cli/utils/SLAs}/__init__.py +0 -0
- {oak_cli-0.2.8 → oak_cli-0.2.9}/oak_cli/utils/SLAs/blank_app_without_services.SLA.json +0 -0
- {oak_cli-0.2.8 → oak_cli-0.2.9}/oak_cli/utils/SLAs/common.py +0 -0
- {oak_cli-0.2.8 → oak_cli-0.2.9}/oak_cli/utils/api/common.py +0 -0
- {oak_cli-0.2.8 → oak_cli-0.2.9}/oak_cli/utils/api/custom_http.py +0 -0
- {oak_cli-0.2.8 → oak_cli-0.2.9}/oak_cli/utils/argcomplete.py +0 -0
- {oak_cli-0.2.8 → oak_cli-0.2.9}/oak_cli/utils/common.py +0 -0
- {oak_cli-0.2.8 → oak_cli-0.2.9}/oak_cli/utils/exceptions.py +0 -0
- {oak_cli-0.2.8 → oak_cli-0.2.9}/oak_cli/utils/logging.py +0 -0
- {oak_cli-0.2.8 → oak_cli-0.2.9}/oak_cli/utils/types.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: oak_cli
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.9
|
|
4
4
|
Summary:
|
|
5
5
|
Author: Alexander Malyuk
|
|
6
6
|
Author-email: malyuk.alexander1999@gmail.com
|
|
@@ -11,6 +11,7 @@ Classifier: Programming Language :: Python :: 3.11
|
|
|
11
11
|
Classifier: Programming Language :: Python :: 3.12
|
|
12
12
|
Requires-Dist: argcomplete (>=3.2.3,<4.0.0)
|
|
13
13
|
Requires-Dist: icecream (>=2.1.3,<3.0.0)
|
|
14
|
+
Requires-Dist: pydantic (>=2.6.4,<3.0.0)
|
|
14
15
|
Description-Content-Type: text/markdown
|
|
15
16
|
|
|
16
17
|
# [Oakestra CLI](https://github.com/oakestra/oakestra-cli)
|
|
@@ -15,7 +15,7 @@ def prepare_applications_deletion_argparser(
|
|
|
15
15
|
applications_subparsers: Subparsers,
|
|
16
16
|
) -> None:
|
|
17
17
|
def aux_delete_applications(args: Any):
|
|
18
|
-
if args.all:
|
|
18
|
+
if args.all or not args.app_id:
|
|
19
19
|
delete_all_applications()
|
|
20
20
|
else:
|
|
21
21
|
delete_application(args.app_id)
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import argparse
|
|
2
|
+
from typing import Any
|
|
3
|
+
|
|
4
|
+
from oak_cli.args_parser.docker.rebuild import prepare_docker_rebuild_argparser
|
|
5
|
+
from oak_cli.utils.types import Subparsers
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def prepare_docker_argparsers(subparsers: Subparsers) -> None:
|
|
9
|
+
docker_parser = subparsers.add_parser(
|
|
10
|
+
"docker",
|
|
11
|
+
aliases=["d"],
|
|
12
|
+
help="command for docker(compose) related activities",
|
|
13
|
+
formatter_class=argparse.RawTextHelpFormatter,
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
def docker_parser_print_help(_: Any) -> None:
|
|
17
|
+
docker_parser.print_help()
|
|
18
|
+
|
|
19
|
+
docker_parser.set_defaults(func=docker_parser_print_help)
|
|
20
|
+
|
|
21
|
+
docker_subparsers = docker_parser.add_subparsers(
|
|
22
|
+
dest="services commands",
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
prepare_docker_rebuild_argparser(docker_subparsers)
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import argparse
|
|
2
|
+
from typing import Any
|
|
3
|
+
|
|
4
|
+
from oak_cli.commands.docker.enums import ClusterOrchestratorService, RootOrchestratorService
|
|
5
|
+
from oak_cli.commands.docker.rebuild import rebuild_docker_service
|
|
6
|
+
from oak_cli.commands.docker.restart import restart_docker_service
|
|
7
|
+
from oak_cli.utils.types import Subparsers
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def aux_rebuild_docker_service(args: Any):
|
|
11
|
+
if args.only_restart:
|
|
12
|
+
restart_docker_service(args.service)
|
|
13
|
+
else:
|
|
14
|
+
rebuild_docker_service(args.service)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def prepare_docker_rebuild_root_orchestrator_service_parser(
|
|
18
|
+
docker_rebuild_subparser: Subparsers,
|
|
19
|
+
) -> None:
|
|
20
|
+
docker_rebuild_root_orchestrator_service_parser = docker_rebuild_subparser.add_parser(
|
|
21
|
+
"root_orchestrator",
|
|
22
|
+
aliases=["ro"],
|
|
23
|
+
)
|
|
24
|
+
docker_rebuild_root_orchestrator_service_parser.add_argument(
|
|
25
|
+
"service",
|
|
26
|
+
help="testing",
|
|
27
|
+
type=RootOrchestratorService,
|
|
28
|
+
choices=RootOrchestratorService,
|
|
29
|
+
)
|
|
30
|
+
docker_rebuild_root_orchestrator_service_parser.set_defaults(func=aux_rebuild_docker_service)
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def prepare_docker_rebuild_cluster_orchestrator_service_parser(
|
|
34
|
+
docker_rebuild_subparser: Subparsers,
|
|
35
|
+
) -> None:
|
|
36
|
+
docker_rebuild_cluster_orchestrator_service_parser = docker_rebuild_subparser.add_parser(
|
|
37
|
+
"cluster_orchestrator",
|
|
38
|
+
aliases=["co"],
|
|
39
|
+
)
|
|
40
|
+
docker_rebuild_cluster_orchestrator_service_parser.add_argument(
|
|
41
|
+
"service",
|
|
42
|
+
help="testing",
|
|
43
|
+
type=ClusterOrchestratorService,
|
|
44
|
+
choices=ClusterOrchestratorService,
|
|
45
|
+
)
|
|
46
|
+
docker_rebuild_cluster_orchestrator_service_parser.set_defaults(func=aux_rebuild_docker_service)
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def prepare_docker_rebuild_argparser(docker_subparsers: Subparsers) -> None:
|
|
50
|
+
HELP_TEXT = "rebuilds a docker compose service"
|
|
51
|
+
docker_restart_parser = docker_subparsers.add_parser(
|
|
52
|
+
"rebuilds",
|
|
53
|
+
aliases=["r"],
|
|
54
|
+
help=HELP_TEXT,
|
|
55
|
+
description=HELP_TEXT,
|
|
56
|
+
formatter_class=argparse.RawTextHelpFormatter,
|
|
57
|
+
)
|
|
58
|
+
docker_restart_parser.add_argument(
|
|
59
|
+
"-o",
|
|
60
|
+
"--only-restart",
|
|
61
|
+
help="only restart without rebuilding the service",
|
|
62
|
+
action="store_true",
|
|
63
|
+
)
|
|
64
|
+
docker_restart_subparsers = docker_restart_parser.add_subparsers()
|
|
65
|
+
prepare_docker_rebuild_root_orchestrator_service_parser(docker_restart_subparsers)
|
|
66
|
+
prepare_docker_rebuild_cluster_orchestrator_service_parser(docker_restart_subparsers)
|
|
@@ -23,7 +23,7 @@ def parse_arguments_and_execute() -> None:
|
|
|
23
23
|
prepare_applications_argparsers(subparsers)
|
|
24
24
|
prepare_services_argparsers(subparsers)
|
|
25
25
|
prepare_plugins_argparsers(subparsers)
|
|
26
|
-
#
|
|
26
|
+
# prepare_docker_argparsers(subparsers) # WIP
|
|
27
27
|
|
|
28
28
|
argcomplete.autocomplete(parser)
|
|
29
29
|
args = parser.parse_args()
|
|
@@ -5,7 +5,7 @@ from oak_cli.utils.types import Subparsers
|
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
def prepare_flops_create_argparser(flops_subparser: Subparsers) -> None:
|
|
8
|
-
HELP_TEXT = "creates a new FLOps
|
|
8
|
+
HELP_TEXT = "creates a new FLOps project - i.e. triggers the init FLOps API"
|
|
9
9
|
flops_create_parser = flops_subparser.add_parser(
|
|
10
10
|
"create",
|
|
11
11
|
aliases=["c"],
|
|
@@ -5,6 +5,7 @@ from typing import List
|
|
|
5
5
|
import oak_cli.utils.api.custom_requests as custom_requests
|
|
6
6
|
from oak_cli.utils.api.common import SYSTEM_MANAGER_URL
|
|
7
7
|
from oak_cli.utils.api.custom_http import HttpMethod
|
|
8
|
+
from oak_cli.utils.exceptions.types import OakCLIExceptionTypes
|
|
8
9
|
from oak_cli.utils.logging import logger
|
|
9
10
|
from oak_cli.utils.SLAs.common import get_SLAs_path
|
|
10
11
|
from oak_cli.utils.types import Application, ApplicationId
|
|
@@ -18,6 +19,7 @@ def get_application(app_id: ApplicationId) -> Application:
|
|
|
18
19
|
),
|
|
19
20
|
custom_requests.RequestAuxiliaries(
|
|
20
21
|
what_should_happen=f"Get application '{app_id}'",
|
|
22
|
+
oak_cli_exception_type=OakCLIExceptionTypes.APP_GET,
|
|
21
23
|
),
|
|
22
24
|
).execute()
|
|
23
25
|
|
|
@@ -30,6 +32,7 @@ def get_applications() -> List[Application]:
|
|
|
30
32
|
),
|
|
31
33
|
custom_requests.RequestAuxiliaries(
|
|
32
34
|
what_should_happen="Get all applications",
|
|
35
|
+
oak_cli_exception_type=OakCLIExceptionTypes.APP_GET,
|
|
33
36
|
),
|
|
34
37
|
).execute()
|
|
35
38
|
if not apps:
|
|
@@ -55,6 +58,7 @@ def send_sla(sla_enum: enum) -> List[Application]:
|
|
|
55
58
|
custom_requests.RequestAuxiliaries(
|
|
56
59
|
what_should_happen=f"Create new application based on '{sla_enum}'",
|
|
57
60
|
show_msg_on_success=True,
|
|
61
|
+
oak_cli_exception_type=OakCLIExceptionTypes.APP_CREATE,
|
|
58
62
|
),
|
|
59
63
|
).execute()
|
|
60
64
|
|
|
@@ -72,6 +76,7 @@ def delete_application(app_id: ApplicationId) -> None:
|
|
|
72
76
|
custom_requests.RequestAuxiliaries(
|
|
73
77
|
what_should_happen=f"Delete application '{app_id}'",
|
|
74
78
|
show_msg_on_success=True,
|
|
79
|
+
oak_cli_exception_type=OakCLIExceptionTypes.APP_DELETE,
|
|
75
80
|
),
|
|
76
81
|
).execute()
|
|
77
82
|
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
version: "3.3"
|
|
2
|
+
|
|
3
|
+
services:
|
|
4
|
+
|
|
5
|
+
node_engine_log_observer:
|
|
6
|
+
image: node_engine_log_observer
|
|
7
|
+
build:
|
|
8
|
+
context: .
|
|
9
|
+
dockerfile_inline: |
|
|
10
|
+
FROM alpine
|
|
11
|
+
CMD tail -f node_engine_logs
|
|
12
|
+
hostname: node_engine_log_observer
|
|
13
|
+
container_name: node_engine_log_observer
|
|
14
|
+
volumes:
|
|
15
|
+
- /tmp/node_engine_logs:/node_engine_logs
|
|
16
|
+
|
|
17
|
+
volumes:
|
|
18
|
+
node_engine_logs:
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import json
|
|
2
|
+
import shlex
|
|
3
|
+
import subprocess
|
|
4
|
+
|
|
5
|
+
from oak_cli.commands.docker.enums import OakestraDockerComposeService
|
|
6
|
+
from oak_cli.utils.logging import logger
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def check_docker_service_status(
|
|
10
|
+
docker_service: OakestraDockerComposeService, docker_operation: str
|
|
11
|
+
):
|
|
12
|
+
inspect_cmd = 'docker inspect -f "{{ json .State }}" ' + str(docker_service)
|
|
13
|
+
result = subprocess.run(
|
|
14
|
+
shlex.split(inspect_cmd),
|
|
15
|
+
check=True,
|
|
16
|
+
stderr=subprocess.PIPE,
|
|
17
|
+
stdout=subprocess.PIPE,
|
|
18
|
+
text=True,
|
|
19
|
+
)
|
|
20
|
+
result_output = json.loads(result.stdout)
|
|
21
|
+
service_status = result_output["Status"]
|
|
22
|
+
if service_status == "running":
|
|
23
|
+
logger.info(
|
|
24
|
+
f"'{docker_service}' successfully '{docker_operation}' - status: '{service_status}'"
|
|
25
|
+
)
|
|
26
|
+
else:
|
|
27
|
+
logger.error(
|
|
28
|
+
f"'{docker_service}' failed to '{docker_operation}' - status: '{service_status}'"
|
|
29
|
+
)
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
from enum import EnumMeta
|
|
2
|
+
|
|
3
|
+
from oak_cli.utils.types import CustomEnum
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class OakestraDockerComposeService(CustomEnum, metaclass=EnumMeta):
|
|
7
|
+
pass
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class RootOrchestratorService(OakestraDockerComposeService):
|
|
11
|
+
SYSTEM_MANAGER = "system_manager"
|
|
12
|
+
MONGO_ROOT = "mongo_root"
|
|
13
|
+
MONGO_ROOTNET = "mongo_rootnet"
|
|
14
|
+
ROOT_SERVICE_MANAGER = "root_service_manager"
|
|
15
|
+
REDIS = "redis"
|
|
16
|
+
GRAFANA = "grafana"
|
|
17
|
+
DASHBOARD = "dashboard"
|
|
18
|
+
CLOUD_SCHEDULER = "cloud_scheduler"
|
|
19
|
+
RESOURCE_ABSTRACTOR = "resource_abstractor"
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class ClusterOrchestratorService(OakestraDockerComposeService):
|
|
23
|
+
MQTT = "mqtt"
|
|
24
|
+
MONGO_CLUSTER = "mongo_cluster"
|
|
25
|
+
MONGO_CLUSTERNET = "mongo_clusternet"
|
|
26
|
+
CLUSTER_SERVICE_MANAGER = "cluster_service_manager"
|
|
27
|
+
CLUSTER_MANAGER = "cluster_manager"
|
|
28
|
+
CLUSTER_SCHEDULER = "cluster_scheduler"
|
|
29
|
+
CLUSTER_REDIS = "cluster_redis"
|
|
30
|
+
PROMETHEUS = "prometheus"
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import pathlib
|
|
2
|
+
import shlex
|
|
3
|
+
import subprocess
|
|
4
|
+
import sys
|
|
5
|
+
|
|
6
|
+
from oak_cli.commands.docker.common import check_docker_service_status
|
|
7
|
+
from oak_cli.commands.docker.enums import OakestraDockerComposeService, RootOrchestratorService
|
|
8
|
+
from oak_cli.utils.logging import logger
|
|
9
|
+
|
|
10
|
+
ROOT_ORCHESTRATOR_DOCKER_COMPOSE_FILE_PATH = pathlib.Path(
|
|
11
|
+
"/home/alex/oakestra/root_orchestrator/docker-compose.yml"
|
|
12
|
+
)
|
|
13
|
+
CLUSTER_ORCHESTRATOR_DOCKER_COMPOSE_FILE_PATH = pathlib.Path(
|
|
14
|
+
"/home/alex/oakestra/cluster_orchestrator/docker-compose.yml"
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def rebuild_docker_service(docker_service: OakestraDockerComposeService) -> None:
|
|
19
|
+
rebuild_flags = "-d --build --no-deps --force-recreate"
|
|
20
|
+
if isinstance(docker_service, RootOrchestratorService):
|
|
21
|
+
compose_path = ROOT_ORCHESTRATOR_DOCKER_COMPOSE_FILE_PATH
|
|
22
|
+
else:
|
|
23
|
+
compose_path = CLUSTER_ORCHESTRATOR_DOCKER_COMPOSE_FILE_PATH
|
|
24
|
+
|
|
25
|
+
final_cmd = f"docker compose -f {compose_path} up {rebuild_flags} {docker_service}"
|
|
26
|
+
|
|
27
|
+
result = subprocess.run(
|
|
28
|
+
shlex.split(final_cmd),
|
|
29
|
+
check=False,
|
|
30
|
+
stderr=subprocess.PIPE,
|
|
31
|
+
stdout=subprocess.PIPE,
|
|
32
|
+
text=True,
|
|
33
|
+
)
|
|
34
|
+
if result.returncode != 0:
|
|
35
|
+
logger.critical(f"Docker service '{docker_service}' rebuild failed due to: '{result}")
|
|
36
|
+
sys.exit(1)
|
|
37
|
+
|
|
38
|
+
check_docker_service_status(docker_service, "rebuild")
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import shlex
|
|
2
|
+
import subprocess
|
|
3
|
+
|
|
4
|
+
from oak_cli.commands.docker.common import check_docker_service_status
|
|
5
|
+
from oak_cli.commands.docker.enums import OakestraDockerComposeService
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def restart_docker_service(docker_service: OakestraDockerComposeService) -> None:
|
|
9
|
+
docker_cmd = f"docker restart {docker_service}"
|
|
10
|
+
subprocess.run(
|
|
11
|
+
shlex.split(docker_cmd),
|
|
12
|
+
check=True,
|
|
13
|
+
stderr=subprocess.PIPE,
|
|
14
|
+
stdout=subprocess.PIPE,
|
|
15
|
+
text=True,
|
|
16
|
+
)
|
|
17
|
+
check_docker_service_status(docker_service, "restarted")
|
|
@@ -4,6 +4,7 @@ import pathlib
|
|
|
4
4
|
|
|
5
5
|
import oak_cli.utils.api.custom_requests as custom_requests
|
|
6
6
|
from oak_cli.utils.api.custom_http import HttpMethod
|
|
7
|
+
from oak_cli.utils.exceptions.types import OakCLIExceptionTypes
|
|
7
8
|
|
|
8
9
|
ROOT_FL_MANAGER_URL = f"http://{os.environ.get('SYSTEM_MANAGER_URL')}:5072"
|
|
9
10
|
|
|
@@ -23,7 +24,8 @@ def create_new_fl_service() -> None:
|
|
|
23
24
|
data=SLA,
|
|
24
25
|
),
|
|
25
26
|
custom_requests.RequestAuxiliaries(
|
|
26
|
-
what_should_happen="Init new FLOps
|
|
27
|
+
what_should_happen="Init new FLOps project",
|
|
27
28
|
show_msg_on_success=True,
|
|
29
|
+
oak_cli_exception_type=OakCLIExceptionTypes.FLOPS_PLUGIN,
|
|
28
30
|
),
|
|
29
31
|
).execute()
|
|
@@ -2,6 +2,7 @@ import oak_cli.utils.api.custom_requests as custom_requests
|
|
|
2
2
|
from oak_cli.commands.services.get import get_single_service
|
|
3
3
|
from oak_cli.utils.api.common import SYSTEM_MANAGER_URL
|
|
4
4
|
from oak_cli.utils.api.custom_http import HttpMethod
|
|
5
|
+
from oak_cli.utils.exceptions.types import OakCLIExceptionTypes
|
|
5
6
|
from oak_cli.utils.types import Id, ServiceId
|
|
6
7
|
|
|
7
8
|
|
|
@@ -15,6 +16,7 @@ def deploy_new_instance(service_id: ServiceId) -> None:
|
|
|
15
16
|
custom_requests.RequestAuxiliaries(
|
|
16
17
|
what_should_happen=f"Deploy a new instance for the service '{service_id}'",
|
|
17
18
|
show_msg_on_success=True,
|
|
19
|
+
oak_cli_exception_type=OakCLIExceptionTypes.SERVICE_DEPLOYMENT,
|
|
18
20
|
),
|
|
19
21
|
).execute()
|
|
20
22
|
|
|
@@ -29,6 +31,7 @@ def undeploy_instance(service_id: ServiceId, instance_id: Id = None) -> None:
|
|
|
29
31
|
custom_requests.RequestAuxiliaries(
|
|
30
32
|
what_should_happen=f"Undeploy instance '{instance_id or 0}' for service '{service_id}'",
|
|
31
33
|
show_msg_on_success=True,
|
|
34
|
+
oak_cli_exception_type=OakCLIExceptionTypes.SERVICE_UNDEPLOYMENT,
|
|
32
35
|
),
|
|
33
36
|
).execute()
|
|
34
37
|
|
|
@@ -2,6 +2,7 @@ from typing import List
|
|
|
2
2
|
|
|
3
3
|
import oak_cli.utils.api.custom_requests as custom_requests
|
|
4
4
|
from oak_cli.utils.api.common import SYSTEM_MANAGER_URL
|
|
5
|
+
from oak_cli.utils.exceptions.types import OakCLIExceptionTypes
|
|
5
6
|
from oak_cli.utils.logging import logger
|
|
6
7
|
from oak_cli.utils.types import Service, ServiceId
|
|
7
8
|
|
|
@@ -14,6 +15,7 @@ def get_single_service(service_id: ServiceId) -> Service:
|
|
|
14
15
|
),
|
|
15
16
|
custom_requests.RequestAuxiliaries(
|
|
16
17
|
what_should_happen=f"Get single service '{service_id}'",
|
|
18
|
+
oak_cli_exception_type=OakCLIExceptionTypes.SERVICE_GET,
|
|
17
19
|
),
|
|
18
20
|
).execute()
|
|
19
21
|
|
|
@@ -30,6 +32,7 @@ def get_all_services(app_id: ServiceId = None) -> List[Service]:
|
|
|
30
32
|
),
|
|
31
33
|
custom_requests.RequestAuxiliaries(
|
|
32
34
|
what_should_happen=what_should_happen,
|
|
35
|
+
oak_cli_exception_type=OakCLIExceptionTypes.SERVICE_GET,
|
|
33
36
|
),
|
|
34
37
|
).execute()
|
|
35
38
|
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
|
|
4
4
|
from oak_cli.args_parser.main import parse_arguments_and_execute
|
|
5
5
|
from oak_cli.utils.argcomplete import handle_argcomplete
|
|
6
|
-
from oak_cli.utils.exceptions import
|
|
6
|
+
from oak_cli.utils.exceptions.main import OakCLIException
|
|
7
7
|
from oak_cli.utils.logging import logger
|
|
8
8
|
|
|
9
9
|
|
|
@@ -17,8 +17,8 @@ def main():
|
|
|
17
17
|
|
|
18
18
|
try:
|
|
19
19
|
parse_arguments_and_execute()
|
|
20
|
-
except
|
|
21
|
-
logger.fatal(f"{e.
|
|
20
|
+
except OakCLIException as e:
|
|
21
|
+
logger.fatal(f"{e.message}, {e.http_status}")
|
|
22
22
|
except Exception as e:
|
|
23
23
|
err_msg = f"Unexpected error occured: {e}"
|
|
24
24
|
logger.fatal(err_msg)
|
|
File without changes
|
|
File without changes
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import json
|
|
2
|
+
from dataclasses import dataclass, field
|
|
2
3
|
from http import HTTPStatus
|
|
3
4
|
from typing import NamedTuple
|
|
4
5
|
|
|
@@ -6,7 +7,8 @@ import requests
|
|
|
6
7
|
|
|
7
8
|
from oak_cli.utils.api.custom_http import HttpMethod
|
|
8
9
|
from oak_cli.utils.api.login import get_login_token
|
|
9
|
-
from oak_cli.utils.exceptions import
|
|
10
|
+
from oak_cli.utils.exceptions.main import OakCLIException
|
|
11
|
+
from oak_cli.utils.exceptions.types import OakCLIExceptionTypes
|
|
10
12
|
from oak_cli.utils.logging import logger
|
|
11
13
|
|
|
12
14
|
|
|
@@ -21,19 +23,23 @@ class RequestCore(NamedTuple):
|
|
|
21
23
|
|
|
22
24
|
class RequestAuxiliaries(NamedTuple):
|
|
23
25
|
what_should_happen: str
|
|
24
|
-
|
|
26
|
+
oak_cli_exception_type: OakCLIExceptionTypes
|
|
25
27
|
show_msg_on_success: bool = False
|
|
26
28
|
is_oakestra_api: bool = True
|
|
27
29
|
|
|
28
30
|
|
|
31
|
+
# Note: The use of Pydantic here leads to strange validation errors.
|
|
32
|
+
@dataclass
|
|
29
33
|
class CustomRequest:
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
34
|
+
core: RequestCore
|
|
35
|
+
aux: RequestAuxiliaries
|
|
36
|
+
|
|
37
|
+
headers: dict = field(default=None, init=False)
|
|
38
|
+
url: str = field(default=None, init=False)
|
|
39
|
+
args: dict = field(default=None, init=False)
|
|
40
|
+
response: requests.Response = field(default=None, init=False)
|
|
41
|
+
|
|
42
|
+
def __post_init__(self):
|
|
37
43
|
self._prepare()
|
|
38
44
|
|
|
39
45
|
def _prepare(self) -> None:
|
|
@@ -88,7 +94,9 @@ class CustomRequest:
|
|
|
88
94
|
|
|
89
95
|
error_msg += self._create_failure_msg()
|
|
90
96
|
|
|
91
|
-
raise
|
|
92
|
-
|
|
97
|
+
raise OakCLIException(
|
|
98
|
+
flops_exception_type=self.aux.flops_exception_type,
|
|
99
|
+
text=error_msg,
|
|
93
100
|
http_status=self.response.status if self.response else None,
|
|
101
|
+
flops_project_id=self.aux.flops_project_id,
|
|
94
102
|
)
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import oak_cli.utils.api.custom_requests as custom_requests
|
|
2
2
|
from oak_cli.utils.api.common import SYSTEM_MANAGER_URL
|
|
3
3
|
from oak_cli.utils.api.custom_http import HttpMethod
|
|
4
|
-
from oak_cli.utils.exceptions import
|
|
4
|
+
from oak_cli.utils.exceptions.types import OakCLIExceptionTypes
|
|
5
5
|
|
|
6
6
|
_login_token = ""
|
|
7
7
|
|
|
@@ -21,7 +21,7 @@ def _login_and_set_token() -> str:
|
|
|
21
21
|
),
|
|
22
22
|
custom_requests.RequestAuxiliaries(
|
|
23
23
|
what_should_happen="Login",
|
|
24
|
-
|
|
24
|
+
oak_cli_exception_type=OakCLIExceptionTypes.LOGIN,
|
|
25
25
|
),
|
|
26
26
|
).execute()
|
|
27
27
|
|
|
File without changes
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
from dataclasses import dataclass, field
|
|
2
|
+
from http import HTTPStatus
|
|
3
|
+
|
|
4
|
+
from oak_cli.utils.exceptions.types import OakCLIExceptionTypes
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
# Note: Pydantic.BaseModel and Exception do not seem to work well if inherited together.
|
|
8
|
+
@dataclass
|
|
9
|
+
class OakCLIException(Exception):
|
|
10
|
+
oak_cli_exception_type: OakCLIExceptionTypes
|
|
11
|
+
text: str
|
|
12
|
+
http_status: HTTPStatus = None
|
|
13
|
+
|
|
14
|
+
message: str = field(init=False)
|
|
15
|
+
|
|
16
|
+
def model_post_init(self, _) -> None:
|
|
17
|
+
self.message = f"'{self.oak_cli_exception_type}' exception occured: {self.text}"
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
from oak_cli.utils.types import CustomEnum
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class OakCLIExceptionTypes(CustomEnum):
|
|
5
|
+
LOGIN = "Login"
|
|
6
|
+
APP_CREATE = "Application Creation"
|
|
7
|
+
APP_DELETE = "Application Deletion"
|
|
8
|
+
APP_GET = "GET Application"
|
|
9
|
+
SERVICE_GET = "GET Service"
|
|
10
|
+
SERVICE_DEPLOYMENT = "Deploying Service"
|
|
11
|
+
SERVICE_UNDEPLOYMENT = "Undeploying Service"
|
|
12
|
+
FLOPS_PLUGIN = "FLOps Plugin"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[tool.poetry]
|
|
2
2
|
name = "oak_cli"
|
|
3
|
-
version = "0.2.
|
|
3
|
+
version = "0.2.9"
|
|
4
4
|
description = ""
|
|
5
5
|
authors = ["Alexander Malyuk <malyuk.alexander1999@gmail.com>"]
|
|
6
6
|
readme = "README.md"
|
|
@@ -8,6 +8,7 @@ readme = "README.md"
|
|
|
8
8
|
[tool.poetry.dependencies]
|
|
9
9
|
python = "^3.10"
|
|
10
10
|
argcomplete = "^3.2.3"
|
|
11
|
+
pydantic = "^2.6.4"
|
|
11
12
|
icecream = "^2.1.3"
|
|
12
13
|
|
|
13
14
|
[build-system]
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{oak_cli-0.2.8/oak_cli/args_parser/plugins → oak_cli-0.2.9/oak_cli/args_parser/docker}/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{oak_cli-0.2.8/oak_cli/commands/apps → oak_cli-0.2.9/oak_cli/args_parser/services}/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{oak_cli-0.2.8/oak_cli/commands/plugins/flops → oak_cli-0.2.9/oak_cli/commands/docker}/__init__.py
RENAMED
|
File without changes
|
{oak_cli-0.2.8/oak_cli/commands/services → oak_cli-0.2.9/oak_cli/commands/plugins}/__init__.py
RENAMED
|
File without changes
|
{oak_cli-0.2.8/oak_cli/utils/SLAs → oak_cli-0.2.9/oak_cli/commands/plugins/flops}/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|