vantage6 5.0.0a22__py3-none-any.whl → 5.0.0a29__py3-none-any.whl
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.
Potentially problematic release.
This version of vantage6 might be problematic. Click here for more details.
- tests_cli/test_client_script.py +23 -0
- tests_cli/test_server_cli.py +7 -6
- tests_cli/test_wizard.py +7 -7
- vantage6/cli/__build__ +1 -1
- vantage6/cli/algorithm/generate_algorithm_json.py +531 -0
- vantage6/cli/algostore/list.py +2 -1
- vantage6/cli/algostore/start.py +6 -6
- vantage6/cli/algostore/stop.py +3 -2
- vantage6/cli/cli.py +25 -0
- vantage6/cli/common/decorator.py +3 -1
- vantage6/cli/common/start.py +221 -12
- vantage6/cli/common/stop.py +90 -0
- vantage6/cli/common/utils.py +15 -20
- vantage6/cli/config.py +260 -0
- vantage6/cli/configuration_manager.py +8 -14
- vantage6/cli/configuration_wizard.py +66 -111
- vantage6/cli/context/__init__.py +2 -1
- vantage6/cli/context/algorithm_store.py +10 -7
- vantage6/cli/context/node.py +38 -54
- vantage6/cli/context/server.py +36 -5
- vantage6/cli/dev/create.py +88 -29
- vantage6/cli/dev/data/km_dataset.csv +2401 -0
- vantage6/cli/dev/remove.py +99 -98
- vantage6/cli/globals.py +24 -4
- vantage6/cli/node/common/__init__.py +6 -5
- vantage6/cli/node/new.py +4 -3
- vantage6/cli/node/remove.py +4 -2
- vantage6/cli/node/start.py +33 -42
- vantage6/cli/prometheus/monitoring_manager.py +146 -0
- vantage6/cli/prometheus/prometheus.yml +5 -0
- vantage6/cli/server/files.py +4 -2
- vantage6/cli/server/import_.py +7 -7
- vantage6/cli/server/list.py +2 -1
- vantage6/cli/server/new.py +25 -6
- vantage6/cli/server/shell.py +5 -4
- vantage6/cli/server/start.py +44 -213
- vantage6/cli/server/stop.py +36 -105
- vantage6/cli/server/version.py +5 -4
- vantage6/cli/template/algo_store_config.j2 +0 -1
- vantage6/cli/template/node_config.j2 +3 -1
- vantage6/cli/template/server_import_config.j2 +0 -2
- vantage6/cli/test/algo_test_scripts/algo_test_arguments.py +29 -0
- vantage6/cli/test/algo_test_scripts/algo_test_script.py +92 -0
- vantage6/cli/test/client_script.py +151 -0
- vantage6/cli/test/common/diagnostic_runner.py +2 -2
- vantage6/cli/test/feature_tester.py +5 -2
- vantage6/cli/use/context.py +46 -0
- vantage6/cli/use/namespace.py +55 -0
- vantage6/cli/utils.py +70 -4
- {vantage6-5.0.0a22.dist-info → vantage6-5.0.0a29.dist-info}/METADATA +15 -11
- vantage6-5.0.0a29.dist-info/RECORD +84 -0
- {vantage6-5.0.0a22.dist-info → vantage6-5.0.0a29.dist-info}/WHEEL +1 -1
- vantage6-5.0.0a22.dist-info/RECORD +0 -72
- {vantage6-5.0.0a22.dist-info → vantage6-5.0.0a29.dist-info}/entry_points.txt +0 -0
- {vantage6-5.0.0a22.dist-info → vantage6-5.0.0a29.dist-info}/top_level.txt +0 -0
vantage6/cli/algostore/stop.py
CHANGED
|
@@ -2,12 +2,13 @@ import click
|
|
|
2
2
|
import docker
|
|
3
3
|
from colorama import Fore, Style
|
|
4
4
|
|
|
5
|
-
from vantage6.common import info, warning
|
|
5
|
+
from vantage6.common import error, info, warning
|
|
6
6
|
from vantage6.common.docker.addons import (
|
|
7
7
|
check_docker_running,
|
|
8
8
|
remove_container_if_exists,
|
|
9
9
|
)
|
|
10
10
|
from vantage6.common.globals import APPNAME, InstanceType
|
|
11
|
+
|
|
11
12
|
from vantage6.cli.common.decorator import click_insert_context
|
|
12
13
|
from vantage6.cli.context.algorithm_store import AlgorithmStoreContext
|
|
13
14
|
|
|
@@ -23,7 +24,7 @@ def cli_algo_store_stop(ctx: AlgorithmStoreContext, all_stores: bool):
|
|
|
23
24
|
client = docker.from_env()
|
|
24
25
|
|
|
25
26
|
running_stores = client.containers.list(
|
|
26
|
-
filters={"label": f"{APPNAME}-type={InstanceType.ALGORITHM_STORE
|
|
27
|
+
filters={"label": f"{APPNAME}-type={InstanceType.ALGORITHM_STORE}"}
|
|
27
28
|
)
|
|
28
29
|
|
|
29
30
|
if not running_stores:
|
vantage6/cli/cli.py
CHANGED
|
@@ -24,6 +24,11 @@ from vantage6.cli.node.stop import cli_node_stop
|
|
|
24
24
|
from vantage6.cli.node.version import cli_node_version
|
|
25
25
|
from vantage6.cli.algorithm.create import cli_algorithm_create
|
|
26
26
|
from vantage6.cli.algorithm.update import cli_algorithm_update
|
|
27
|
+
from vantage6.cli.algorithm.generate_algorithm_json import (
|
|
28
|
+
cli_algorithm_generate_algorithm_json,
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
# from vantage6.cli.test.client_script import cli_test_client_script
|
|
27
32
|
from vantage6.cli.test.feature_tester import cli_test_features
|
|
28
33
|
|
|
29
34
|
# from vantage6.cli.test.integration_test import cli_test_integration
|
|
@@ -34,6 +39,8 @@ from vantage6.cli.algostore.stop import cli_algo_store_stop
|
|
|
34
39
|
from vantage6.cli.algostore.files import cli_algo_store_files
|
|
35
40
|
from vantage6.cli.algostore.list import cli_algo_store_configuration_list
|
|
36
41
|
from vantage6.cli.algostore.remove import cli_algo_store_remove
|
|
42
|
+
from vantage6.cli.use.context import cli_use_context
|
|
43
|
+
from vantage6.cli.use.namespace import cli_use_namespace
|
|
37
44
|
|
|
38
45
|
|
|
39
46
|
# Define the server group
|
|
@@ -104,6 +111,9 @@ def cli_algorithm() -> None:
|
|
|
104
111
|
# Define the commands for the algorithm group
|
|
105
112
|
cli_algorithm.add_command(cli_algorithm_create, name="create")
|
|
106
113
|
cli_algorithm.add_command(cli_algorithm_update, name="update")
|
|
114
|
+
cli_algorithm.add_command(
|
|
115
|
+
cli_algorithm_generate_algorithm_json, name="generate-algorithm-json"
|
|
116
|
+
)
|
|
107
117
|
|
|
108
118
|
|
|
109
119
|
# Define the test group
|
|
@@ -117,6 +127,7 @@ def cli_test() -> None:
|
|
|
117
127
|
# Define the commands for the test group
|
|
118
128
|
cli_test.add_command(cli_test_features, name="feature-test")
|
|
119
129
|
# cli_test.add_command(cli_test_integration, name="integration-test")
|
|
130
|
+
# cli_test.add_command(cli_test_client_script, name="client-script")
|
|
120
131
|
|
|
121
132
|
|
|
122
133
|
# Define the algorithm-store group
|
|
@@ -137,6 +148,19 @@ cli_algo_store.add_command(cli_algo_store_configuration_list, name="list")
|
|
|
137
148
|
cli_algo_store.add_command(cli_algo_store_remove, name="remove")
|
|
138
149
|
|
|
139
150
|
|
|
151
|
+
# Add the use group
|
|
152
|
+
@click.group(name="use")
|
|
153
|
+
def cli_use() -> None:
|
|
154
|
+
"""
|
|
155
|
+
Manage Kubernetes context and namespace.
|
|
156
|
+
"""
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
# Define the commands for the use group
|
|
160
|
+
cli_use.add_command(cli_use_context, name="context")
|
|
161
|
+
cli_use.add_command(cli_use_namespace, name="namespace")
|
|
162
|
+
|
|
163
|
+
|
|
140
164
|
# Define the overall group
|
|
141
165
|
@click.group(name="cli", context_settings={"show_default": True})
|
|
142
166
|
def cli_complete() -> None:
|
|
@@ -155,3 +179,4 @@ cli_complete.add_command(cli_dev)
|
|
|
155
179
|
cli_complete.add_command(cli_algorithm)
|
|
156
180
|
cli_complete.add_command(cli_test)
|
|
157
181
|
cli_complete.add_command(cli_algo_store)
|
|
182
|
+
cli_complete.add_command(cli_use)
|
vantage6/cli/common/decorator.py
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
from functools import wraps
|
|
2
2
|
from pathlib import Path
|
|
3
|
+
|
|
3
4
|
import click
|
|
4
5
|
|
|
5
6
|
from vantage6.common import error
|
|
6
7
|
from vantage6.common.globals import InstanceType
|
|
8
|
+
|
|
7
9
|
from vantage6.cli.configuration_wizard import select_configuration_questionaire
|
|
8
|
-
from vantage6.cli.context import
|
|
10
|
+
from vantage6.cli.context import get_context, select_context_class
|
|
9
11
|
|
|
10
12
|
|
|
11
13
|
def click_insert_context(
|
vantage6/cli/common/start.py
CHANGED
|
@@ -1,29 +1,41 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import enum
|
|
1
4
|
import os
|
|
2
|
-
|
|
5
|
+
import re
|
|
6
|
+
import subprocess
|
|
3
7
|
import time
|
|
8
|
+
from os import PathLike
|
|
9
|
+
from pathlib import Path
|
|
10
|
+
from threading import Thread
|
|
11
|
+
|
|
4
12
|
import docker
|
|
5
|
-
import
|
|
13
|
+
from colorama import Fore, Style
|
|
6
14
|
from docker.client import DockerClient
|
|
7
15
|
from docker.models.containers import Container
|
|
8
|
-
from colorama import Fore, Style
|
|
9
16
|
from sqlalchemy.engine.url import make_url
|
|
10
17
|
|
|
11
18
|
from vantage6.common import error, info, warning
|
|
12
19
|
from vantage6.common.context import AppContext
|
|
20
|
+
from vantage6.common.docker.addons import check_docker_running, pull_image
|
|
13
21
|
from vantage6.common.globals import (
|
|
22
|
+
APPNAME,
|
|
14
23
|
DEFAULT_ALGO_STORE_IMAGE,
|
|
24
|
+
DEFAULT_CHART_REPO,
|
|
25
|
+
DEFAULT_DOCKER_REGISTRY,
|
|
15
26
|
DEFAULT_NODE_IMAGE,
|
|
16
27
|
DEFAULT_SERVER_IMAGE,
|
|
17
28
|
DEFAULT_UI_IMAGE,
|
|
18
29
|
InstanceType,
|
|
19
|
-
APPNAME,
|
|
20
|
-
DEFAULT_DOCKER_REGISTRY,
|
|
21
30
|
)
|
|
22
|
-
|
|
23
|
-
from vantage6.cli.context import AlgorithmStoreContext, ServerContext
|
|
31
|
+
|
|
24
32
|
from vantage6.cli.common.utils import print_log_worker
|
|
25
|
-
from vantage6.cli.
|
|
26
|
-
from vantage6.cli.globals import
|
|
33
|
+
from vantage6.cli.context import AlgorithmStoreContext, ServerContext
|
|
34
|
+
from vantage6.cli.globals import AlgoStoreGlobals, ServerGlobals
|
|
35
|
+
from vantage6.cli.utils import (
|
|
36
|
+
check_config_name_allowed,
|
|
37
|
+
validate_input_cmd_args,
|
|
38
|
+
)
|
|
27
39
|
|
|
28
40
|
|
|
29
41
|
def check_for_start(ctx: AppContext, type_: InstanceType) -> DockerClient:
|
|
@@ -57,7 +69,7 @@ def check_for_start(ctx: AppContext, type_: InstanceType) -> DockerClient:
|
|
|
57
69
|
)
|
|
58
70
|
for server in running_servers:
|
|
59
71
|
if server.name == f"{APPNAME}-{ctx.name}-{ctx.scope}-{type_}":
|
|
60
|
-
error(f"Server {Fore.RED}{ctx.name}{Style.RESET_ALL}
|
|
72
|
+
error(f"Server {Fore.RED}{ctx.name}{Style.RESET_ALL} is already running")
|
|
61
73
|
exit(1)
|
|
62
74
|
return docker_client
|
|
63
75
|
|
|
@@ -279,6 +291,8 @@ def mount_database(
|
|
|
279
291
|
return mount, environment_vars
|
|
280
292
|
|
|
281
293
|
|
|
294
|
+
# TODO v5+ remove this function, it is replaced by the `attach_logs` function in
|
|
295
|
+
# `vantage6.cli.common.utils`
|
|
282
296
|
def attach_logs(container: Container, type_: InstanceType) -> None:
|
|
283
297
|
"""
|
|
284
298
|
Attach container logs to the console if specified.
|
|
@@ -290,8 +304,6 @@ def attach_logs(container: Container, type_: InstanceType) -> None:
|
|
|
290
304
|
type_ : InstanceType
|
|
291
305
|
The type of instance to attach the logs for
|
|
292
306
|
"""
|
|
293
|
-
if isinstance(type_, enum.Enum):
|
|
294
|
-
type_ = type_.value
|
|
295
307
|
logs = container.attach(stream=True, logs=True, stdout=True)
|
|
296
308
|
Thread(target=print_log_worker, args=(logs,), daemon=True).start()
|
|
297
309
|
while True:
|
|
@@ -304,3 +316,200 @@ def attach_logs(container: Container, type_: InstanceType) -> None:
|
|
|
304
316
|
f"with {Fore.RED}v6 {type_} stop{Style.RESET_ALL}"
|
|
305
317
|
)
|
|
306
318
|
exit(0)
|
|
319
|
+
|
|
320
|
+
|
|
321
|
+
def helm_install(
|
|
322
|
+
release_name: str,
|
|
323
|
+
chart_name: str,
|
|
324
|
+
values_file: str | PathLike | None = None,
|
|
325
|
+
context: str | None = None,
|
|
326
|
+
namespace: str | None = None,
|
|
327
|
+
) -> None:
|
|
328
|
+
"""
|
|
329
|
+
Manage the `helm install` command.
|
|
330
|
+
|
|
331
|
+
Parameters
|
|
332
|
+
----------
|
|
333
|
+
release_name : str
|
|
334
|
+
The name of the Helm release.
|
|
335
|
+
chart_name : str
|
|
336
|
+
The name of the Helm chart.
|
|
337
|
+
values_file : str, optional
|
|
338
|
+
A single values file to use with the `-f` flag.
|
|
339
|
+
context : str, optional
|
|
340
|
+
The Kubernetes context to use.
|
|
341
|
+
namespace : str, optional
|
|
342
|
+
The Kubernetes namespace to use.
|
|
343
|
+
"""
|
|
344
|
+
# Input validation
|
|
345
|
+
validate_input_cmd_args(release_name, "release name")
|
|
346
|
+
validate_input_cmd_args(chart_name, "chart name")
|
|
347
|
+
|
|
348
|
+
values_file = Path(values_file) if values_file else None
|
|
349
|
+
if values_file and not values_file.is_file():
|
|
350
|
+
error(f"Helm chart values file does not exist: {values_file}")
|
|
351
|
+
return
|
|
352
|
+
|
|
353
|
+
validate_input_cmd_args(context, "context name", allow_none=True)
|
|
354
|
+
validate_input_cmd_args(namespace, "namespace name", allow_none=True)
|
|
355
|
+
|
|
356
|
+
# Create the command
|
|
357
|
+
command = [
|
|
358
|
+
"helm",
|
|
359
|
+
"install",
|
|
360
|
+
release_name,
|
|
361
|
+
chart_name,
|
|
362
|
+
"--repo",
|
|
363
|
+
DEFAULT_CHART_REPO,
|
|
364
|
+
"--devel", # ensure using latest version including pre-releases
|
|
365
|
+
]
|
|
366
|
+
|
|
367
|
+
if values_file:
|
|
368
|
+
command.extend(["-f", str(values_file)])
|
|
369
|
+
|
|
370
|
+
if context:
|
|
371
|
+
command.extend(["--kube-context", context])
|
|
372
|
+
|
|
373
|
+
if namespace:
|
|
374
|
+
command.extend(["--namespace", namespace])
|
|
375
|
+
|
|
376
|
+
try:
|
|
377
|
+
subprocess.run(
|
|
378
|
+
command,
|
|
379
|
+
stdout=subprocess.DEVNULL,
|
|
380
|
+
check=True,
|
|
381
|
+
)
|
|
382
|
+
info(
|
|
383
|
+
f"Successfully installed release '{release_name}' using chart '{chart_name}'."
|
|
384
|
+
)
|
|
385
|
+
except subprocess.CalledProcessError as e:
|
|
386
|
+
error(f"Failed to install release '{release_name}': {e.stderr}")
|
|
387
|
+
except FileNotFoundError:
|
|
388
|
+
error(
|
|
389
|
+
"Helm command not found. Please ensure Helm is installed and available in the PATH."
|
|
390
|
+
)
|
|
391
|
+
|
|
392
|
+
|
|
393
|
+
def start_port_forward(
|
|
394
|
+
service_name: str,
|
|
395
|
+
service_port: int,
|
|
396
|
+
port: int,
|
|
397
|
+
ip: str | None,
|
|
398
|
+
context: str | None = None,
|
|
399
|
+
namespace: str | None = None,
|
|
400
|
+
) -> None:
|
|
401
|
+
"""
|
|
402
|
+
Port forward a kubernetes service.
|
|
403
|
+
|
|
404
|
+
Parameters
|
|
405
|
+
----------
|
|
406
|
+
service_name : str
|
|
407
|
+
The name of the Kubernetes service to port forward.
|
|
408
|
+
service_port : int
|
|
409
|
+
The port on the service to forward.
|
|
410
|
+
port : int
|
|
411
|
+
The port to listen on.
|
|
412
|
+
ip : str | None
|
|
413
|
+
The IP address to listen on. If None, defaults to localhost.
|
|
414
|
+
context : str | None
|
|
415
|
+
The Kubernetes context to use.
|
|
416
|
+
namespace : str | None
|
|
417
|
+
The Kubernetes namespace to use.
|
|
418
|
+
"""
|
|
419
|
+
# Input validation
|
|
420
|
+
validate_input_cmd_args(service_name, "service name")
|
|
421
|
+
if not isinstance(service_port, int) or service_port <= 0:
|
|
422
|
+
error(f"Invalid service port: {service_port}. Must be a positive integer.")
|
|
423
|
+
return
|
|
424
|
+
|
|
425
|
+
if not isinstance(port, int) or port <= 0:
|
|
426
|
+
error(f"Invalid local port: {port}. Must be a positive integer.")
|
|
427
|
+
return
|
|
428
|
+
|
|
429
|
+
if ip and not re.match(
|
|
430
|
+
r"^(localhost|[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3})$", ip
|
|
431
|
+
):
|
|
432
|
+
error(f"Invalid IP address: {ip}. Must be a valid IPv4 address or 'localhost'.")
|
|
433
|
+
return
|
|
434
|
+
|
|
435
|
+
validate_input_cmd_args(context, "context name", allow_none=True)
|
|
436
|
+
validate_input_cmd_args(namespace, "namespace name", allow_none=True)
|
|
437
|
+
|
|
438
|
+
# Check if the service is ready before starting port forwarding
|
|
439
|
+
info(f"Waiting for service '{service_name}' to become ready...")
|
|
440
|
+
start_time = time.time()
|
|
441
|
+
timeout = 300 # seconds
|
|
442
|
+
while time.time() - start_time < timeout:
|
|
443
|
+
try:
|
|
444
|
+
result = (
|
|
445
|
+
subprocess.check_output(
|
|
446
|
+
[
|
|
447
|
+
"kubectl",
|
|
448
|
+
"get",
|
|
449
|
+
"endpoints",
|
|
450
|
+
service_name,
|
|
451
|
+
"-o",
|
|
452
|
+
"jsonpath={.subsets[*].addresses[*].ip}",
|
|
453
|
+
]
|
|
454
|
+
)
|
|
455
|
+
.decode()
|
|
456
|
+
.strip()
|
|
457
|
+
)
|
|
458
|
+
|
|
459
|
+
if result:
|
|
460
|
+
info(f"Service '{service_name}' is ready.")
|
|
461
|
+
break
|
|
462
|
+
except subprocess.CalledProcessError:
|
|
463
|
+
pass # ignore and retry
|
|
464
|
+
|
|
465
|
+
time.sleep(2)
|
|
466
|
+
else:
|
|
467
|
+
error(
|
|
468
|
+
f"Timeout: Service '{service_name}' has no ready endpoints after {timeout} seconds."
|
|
469
|
+
)
|
|
470
|
+
return
|
|
471
|
+
|
|
472
|
+
# Create the port forwarding command
|
|
473
|
+
if not ip:
|
|
474
|
+
ip = "localhost"
|
|
475
|
+
|
|
476
|
+
command = [
|
|
477
|
+
"kubectl",
|
|
478
|
+
"port-forward",
|
|
479
|
+
"--address",
|
|
480
|
+
ip,
|
|
481
|
+
f"service/{service_name}",
|
|
482
|
+
f"{port}:{service_port}",
|
|
483
|
+
]
|
|
484
|
+
|
|
485
|
+
if context:
|
|
486
|
+
command.extend(["--context", context])
|
|
487
|
+
|
|
488
|
+
if namespace:
|
|
489
|
+
command.extend(["--namespace", namespace])
|
|
490
|
+
|
|
491
|
+
# Start the port forwarding process
|
|
492
|
+
try:
|
|
493
|
+
process = subprocess.Popen(
|
|
494
|
+
command,
|
|
495
|
+
stdout=subprocess.DEVNULL,
|
|
496
|
+
stderr=subprocess.PIPE,
|
|
497
|
+
start_new_session=True, # Start in new session to detach from parent
|
|
498
|
+
)
|
|
499
|
+
|
|
500
|
+
# Give the process a moment to start and check if it's still running
|
|
501
|
+
time.sleep(1)
|
|
502
|
+
if process.poll() is not None:
|
|
503
|
+
# Process has already terminated
|
|
504
|
+
e = process.stderr.read().decode() if process.stderr else "Unknown error"
|
|
505
|
+
error(f"Failed to start port forwarding: {e}")
|
|
506
|
+
return
|
|
507
|
+
|
|
508
|
+
info(
|
|
509
|
+
f"Port forwarding started: {ip}:{port} -> {service_name}:{service_port} "
|
|
510
|
+
f"(PID: {str(process.pid)})"
|
|
511
|
+
)
|
|
512
|
+
return
|
|
513
|
+
except Exception as e:
|
|
514
|
+
error(f"Failed to start port forwarding: {e}")
|
|
515
|
+
return
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import subprocess
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
from vantage6.common import error, info, warning
|
|
7
|
+
from vantage6.cli.utils import validate_input_cmd_args
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def stop_port_forward(service_name: str) -> None:
|
|
11
|
+
"""
|
|
12
|
+
Stop the port forwarding process for a given service name.
|
|
13
|
+
|
|
14
|
+
Parameters
|
|
15
|
+
----------
|
|
16
|
+
service_name : str
|
|
17
|
+
The name of the service whose port forwarding process should be terminated.
|
|
18
|
+
"""
|
|
19
|
+
# Input validation
|
|
20
|
+
validate_input_cmd_args(service_name, "service name")
|
|
21
|
+
|
|
22
|
+
try:
|
|
23
|
+
# Find the process ID (PID) of the port forwarding command
|
|
24
|
+
result = subprocess.run(
|
|
25
|
+
["pgrep", "-f", f"kubectl port-forward.*{service_name}"],
|
|
26
|
+
check=True,
|
|
27
|
+
text=True,
|
|
28
|
+
capture_output=True,
|
|
29
|
+
)
|
|
30
|
+
pids = result.stdout.strip().splitlines()
|
|
31
|
+
|
|
32
|
+
if not pids:
|
|
33
|
+
warning(f"No port forwarding process found for service '{service_name}'.")
|
|
34
|
+
return
|
|
35
|
+
|
|
36
|
+
for pid in pids:
|
|
37
|
+
subprocess.run(["kill", "-9", pid], check=True)
|
|
38
|
+
info(
|
|
39
|
+
f"Terminated port forwarding process for service '{service_name}' "
|
|
40
|
+
f"(PID: {pid})"
|
|
41
|
+
)
|
|
42
|
+
except subprocess.CalledProcessError as e:
|
|
43
|
+
error(f"Failed to terminate port forwarding: {e}")
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def helm_uninstall(
|
|
47
|
+
release_name: str,
|
|
48
|
+
context: str | None = None,
|
|
49
|
+
namespace: str | None = None,
|
|
50
|
+
) -> None:
|
|
51
|
+
"""
|
|
52
|
+
Manage the `helm uninstall` command.
|
|
53
|
+
|
|
54
|
+
Parameters
|
|
55
|
+
----------
|
|
56
|
+
release_name : str
|
|
57
|
+
The name of the Helm release to uninstall.
|
|
58
|
+
context : str, optional
|
|
59
|
+
The Kubernetes context to use.
|
|
60
|
+
namespace : str, optional
|
|
61
|
+
The Kubernetes namespace to use.
|
|
62
|
+
"""
|
|
63
|
+
# Input validation
|
|
64
|
+
validate_input_cmd_args(release_name, "release name")
|
|
65
|
+
validate_input_cmd_args(context, "context name", allow_none=True)
|
|
66
|
+
validate_input_cmd_args(namespace, "namespace name", allow_none=True)
|
|
67
|
+
|
|
68
|
+
# Create the command
|
|
69
|
+
command = ["helm", "uninstall", release_name]
|
|
70
|
+
|
|
71
|
+
if context:
|
|
72
|
+
command.extend(["--kube-context", context])
|
|
73
|
+
|
|
74
|
+
if namespace:
|
|
75
|
+
command.extend(["--namespace", namespace])
|
|
76
|
+
|
|
77
|
+
try:
|
|
78
|
+
subprocess.run(
|
|
79
|
+
command,
|
|
80
|
+
stdout=subprocess.DEVNULL,
|
|
81
|
+
check=True,
|
|
82
|
+
)
|
|
83
|
+
info(f"Successfully uninstalled release '{release_name}'.")
|
|
84
|
+
except subprocess.CalledProcessError as e:
|
|
85
|
+
error(f"Failed to uninstall release '{release_name}': {e.stderr}")
|
|
86
|
+
except FileNotFoundError:
|
|
87
|
+
error(
|
|
88
|
+
"Helm command not found. Please ensure Helm is installed and available in "
|
|
89
|
+
"the PATH."
|
|
90
|
+
)
|
vantage6/cli/common/utils.py
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
import enum
|
|
2
|
-
|
|
3
|
-
from colorama import Fore, Style
|
|
4
|
-
import click
|
|
2
|
+
from subprocess import Popen
|
|
5
3
|
from typing import Iterable
|
|
4
|
+
|
|
5
|
+
import click
|
|
6
6
|
import docker
|
|
7
|
-
|
|
7
|
+
import questionary as q
|
|
8
|
+
from colorama import Fore, Style
|
|
8
9
|
|
|
10
|
+
from vantage6.common import error, warning
|
|
11
|
+
from vantage6.common.globals import APPNAME, STRING_ENCODING, InstanceType
|
|
9
12
|
|
|
10
|
-
from vantage6.common import warning, error
|
|
11
|
-
from vantage6.common.globals import APPNAME, InstanceType, STRING_ENCODING
|
|
12
13
|
from vantage6.cli.context import select_context_class
|
|
13
14
|
|
|
14
15
|
|
|
@@ -77,7 +78,7 @@ def get_running_servers(
|
|
|
77
78
|
return [server.name for server in running_servers]
|
|
78
79
|
|
|
79
80
|
|
|
80
|
-
def get_server_configuration_list(instance_type: InstanceType
|
|
81
|
+
def get_server_configuration_list(instance_type: InstanceType) -> None:
|
|
81
82
|
"""
|
|
82
83
|
Print list of available server configurations.
|
|
83
84
|
|
|
@@ -89,11 +90,7 @@ def get_server_configuration_list(instance_type: InstanceType.SERVER) -> None:
|
|
|
89
90
|
client = docker.from_env()
|
|
90
91
|
ctx_class = select_context_class(instance_type)
|
|
91
92
|
|
|
92
|
-
|
|
93
|
-
instance_type.value if isinstance(instance_type, enum.Enum) else instance_type
|
|
94
|
-
)
|
|
95
|
-
|
|
96
|
-
running_server_names = get_running_servers(client, instance_type_value)
|
|
93
|
+
running_server_names = get_running_servers(client, instance_type)
|
|
97
94
|
header = "\nName" + (21 * " ") + "Status" + (10 * " ") + "System/User"
|
|
98
95
|
|
|
99
96
|
click.echo(header)
|
|
@@ -107,26 +104,24 @@ def get_server_configuration_list(instance_type: InstanceType.SERVER) -> None:
|
|
|
107
104
|
for config in configs:
|
|
108
105
|
status = (
|
|
109
106
|
running
|
|
110
|
-
if f"{APPNAME}-{config.name}-system-{
|
|
111
|
-
in running_server_names
|
|
107
|
+
if f"{APPNAME}-{config.name}-system-{instance_type}" in running_server_names
|
|
112
108
|
else stopped
|
|
113
109
|
)
|
|
114
|
-
click.echo(f"{config.name:25}
|
|
110
|
+
click.echo(f"{config.name:25}{status:25} System ")
|
|
115
111
|
|
|
116
112
|
# user folders
|
|
117
113
|
configs, f2 = ctx_class.available_configurations(system_folders=False)
|
|
118
114
|
for config in configs:
|
|
119
115
|
status = (
|
|
120
116
|
running
|
|
121
|
-
if f"{APPNAME}-{config.name}-user-{
|
|
122
|
-
in running_server_names
|
|
117
|
+
if f"{APPNAME}-{config.name}-user-{instance_type}" in running_server_names
|
|
123
118
|
else stopped
|
|
124
119
|
)
|
|
125
|
-
click.echo(f"{config.name:25}
|
|
120
|
+
click.echo(f"{config.name:25}{status:25} User ")
|
|
126
121
|
|
|
127
122
|
click.echo("-" * 85)
|
|
128
123
|
if len(f1) + len(f2):
|
|
129
|
-
warning(f"{Fore.RED}Failed imports: {len(f1)+len(f2)}{Style.RESET_ALL}")
|
|
124
|
+
warning(f"{Fore.RED}Failed imports: {len(f1) + len(f2)}{Style.RESET_ALL}")
|
|
130
125
|
|
|
131
126
|
|
|
132
127
|
def print_log_worker(logs_stream: Iterable[bytes]) -> None:
|
|
@@ -177,6 +172,6 @@ def attach_logs(*labels: list[str]) -> None:
|
|
|
177
172
|
labels : list[str]
|
|
178
173
|
The labels to attach to
|
|
179
174
|
"""
|
|
180
|
-
command = ["
|
|
175
|
+
command = ["kubectl", "logs", "--follow", "--selector", ",".join(labels)]
|
|
181
176
|
process = Popen(command, stdout=None, stderr=None)
|
|
182
177
|
process.wait()
|