flowmesh-cli-stack 0.1.8rc1__tar.gz → 0.1.10__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.
- {flowmesh_cli_stack-0.1.8rc1/src/flowmesh_cli_stack.egg-info → flowmesh_cli_stack-0.1.10}/PKG-INFO +3 -3
- {flowmesh_cli_stack-0.1.8rc1 → flowmesh_cli_stack-0.1.10}/pyproject.toml +3 -3
- {flowmesh_cli_stack-0.1.8rc1 → flowmesh_cli_stack-0.1.10}/src/flowmesh_cli_stack/assets/.env.example +28 -2
- {flowmesh_cli_stack-0.1.8rc1 → flowmesh_cli_stack-0.1.10}/src/flowmesh_cli_stack/env_schema.py +106 -2
- {flowmesh_cli_stack-0.1.8rc1 → flowmesh_cli_stack-0.1.10}/src/flowmesh_cli_stack/worker.py +21 -21
- {flowmesh_cli_stack-0.1.8rc1 → flowmesh_cli_stack-0.1.10/src/flowmesh_cli_stack.egg-info}/PKG-INFO +3 -3
- flowmesh_cli_stack-0.1.10/src/flowmesh_cli_stack.egg-info/requires.txt +5 -0
- flowmesh_cli_stack-0.1.8rc1/src/flowmesh_cli_stack.egg-info/requires.txt +0 -5
- {flowmesh_cli_stack-0.1.8rc1 → flowmesh_cli_stack-0.1.10}/LICENSE +0 -0
- {flowmesh_cli_stack-0.1.8rc1 → flowmesh_cli_stack-0.1.10}/README.md +0 -0
- {flowmesh_cli_stack-0.1.8rc1 → flowmesh_cli_stack-0.1.10}/setup.cfg +0 -0
- {flowmesh_cli_stack-0.1.8rc1 → flowmesh_cli_stack-0.1.10}/src/flowmesh_cli_stack/__init__.py +0 -0
- {flowmesh_cli_stack-0.1.8rc1 → flowmesh_cli_stack-0.1.10}/src/flowmesh_cli_stack/assets/compose.yml +0 -0
- {flowmesh_cli_stack-0.1.8rc1 → flowmesh_cli_stack-0.1.10}/src/flowmesh_cli_stack/assets/docker-bake.hcl +0 -0
- {flowmesh_cli_stack-0.1.8rc1 → flowmesh_cli_stack-0.1.10}/src/flowmesh_cli_stack/bundle.py +0 -0
- {flowmesh_cli_stack-0.1.8rc1 → flowmesh_cli_stack-0.1.10}/src/flowmesh_cli_stack/image.py +0 -0
- {flowmesh_cli_stack-0.1.8rc1 → flowmesh_cli_stack-0.1.10}/src/flowmesh_cli_stack/stack.py +0 -0
- {flowmesh_cli_stack-0.1.8rc1 → flowmesh_cli_stack-0.1.10}/src/flowmesh_cli_stack/utils.py +0 -0
- {flowmesh_cli_stack-0.1.8rc1 → flowmesh_cli_stack-0.1.10}/src/flowmesh_cli_stack.egg-info/SOURCES.txt +0 -0
- {flowmesh_cli_stack-0.1.8rc1 → flowmesh_cli_stack-0.1.10}/src/flowmesh_cli_stack.egg-info/dependency_links.txt +0 -0
- {flowmesh_cli_stack-0.1.8rc1 → flowmesh_cli_stack-0.1.10}/src/flowmesh_cli_stack.egg-info/top_level.txt +0 -0
{flowmesh_cli_stack-0.1.8rc1/src/flowmesh_cli_stack.egg-info → flowmesh_cli_stack-0.1.10}/PKG-INFO
RENAMED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: flowmesh-cli-stack
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.10
|
|
4
4
|
Summary: FlowMesh CLI stack commands
|
|
5
5
|
License-Expression: Apache-2.0
|
|
6
6
|
Requires-Python: >=3.12
|
|
7
7
|
Description-Content-Type: text/markdown
|
|
8
8
|
License-File: LICENSE
|
|
9
|
-
Requires-Dist: flowmesh-cli==0.1.
|
|
10
|
-
Requires-Dist: flowmesh-sdk-stack==0.1.
|
|
9
|
+
Requires-Dist: flowmesh-cli==0.1.10
|
|
10
|
+
Requires-Dist: flowmesh-sdk-stack==0.1.10
|
|
11
11
|
Requires-Dist: docker>=7.1.0
|
|
12
12
|
Requires-Dist: packaging>=24
|
|
13
13
|
Requires-Dist: pyyaml>=6.0.2
|
|
@@ -4,15 +4,15 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "flowmesh-cli-stack"
|
|
7
|
-
version = "0.1.
|
|
7
|
+
version = "0.1.10"
|
|
8
8
|
description = "FlowMesh CLI stack commands"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.12"
|
|
11
11
|
license = "Apache-2.0"
|
|
12
12
|
license-files = ["LICENSE"]
|
|
13
13
|
dependencies = [
|
|
14
|
-
"flowmesh-cli==0.1.
|
|
15
|
-
"flowmesh-sdk-stack==0.1.
|
|
14
|
+
"flowmesh-cli==0.1.10",
|
|
15
|
+
"flowmesh-sdk-stack==0.1.10",
|
|
16
16
|
"docker>=7.1.0",
|
|
17
17
|
"packaging>=24",
|
|
18
18
|
"pyyaml>=6.0.2",
|
{flowmesh_cli_stack-0.1.8rc1 → flowmesh_cli_stack-0.1.10}/src/flowmesh_cli_stack/assets/.env.example
RENAMED
|
@@ -43,6 +43,10 @@ SUPERVISOR_GRPC_KEEPALIVE_PERMIT_WITHOUT_CALLS=true
|
|
|
43
43
|
SUPERVISOR_GRPC_MIN_RECV_PING_INTERVAL_MS=60000
|
|
44
44
|
SUPERVISOR_GRPC_KEEPALIVE_TIME_MS=300000
|
|
45
45
|
SUPERVISOR_GRPC_KEEPALIVE_TIMEOUT_MS=10000
|
|
46
|
+
# Shared secret admitting `external` workers (empty disables them).
|
|
47
|
+
EXTERNAL_WORKER_TOKEN=
|
|
48
|
+
# File holding the secret; wins over EXTERNAL_WORKER_TOKEN.
|
|
49
|
+
EXTERNAL_WORKER_TOKEN_FILE=
|
|
46
50
|
|
|
47
51
|
# ==== Redis Connectivity ====
|
|
48
52
|
REDIS_CONTROL_URL=redis://localhost:6379/0
|
|
@@ -85,7 +89,7 @@ SERVER_PORT_FORWARD_PORT_END=32100
|
|
|
85
89
|
|
|
86
90
|
# ==== SSH Task Support ====
|
|
87
91
|
ENABLE_SERVER_SSH_PROXY=true
|
|
88
|
-
|
|
92
|
+
ENABLE_SERVER_SSH_CONNECTION_REGISTRY=true
|
|
89
93
|
|
|
90
94
|
# ==== Serve Task Support ====
|
|
91
95
|
ENABLE_SERVER_SERVE_PROXY=true
|
|
@@ -105,7 +109,19 @@ SSH_MAX_PIDS=
|
|
|
105
109
|
# Whether to apply requested GPU limits to SSH tasks.
|
|
106
110
|
# If false, SSH tasks are allocated all available GPUs
|
|
107
111
|
# regardless of their resource requests.
|
|
108
|
-
ENABLE_SSH_GPU_LIMIT=
|
|
112
|
+
ENABLE_SSH_GPU_LIMIT=true
|
|
113
|
+
# Whether a non-root worker may serve SSH sessions,
|
|
114
|
+
# which run as the worker and can read its credentials.
|
|
115
|
+
ENABLE_UNISOLATED_SSH_SESSION=false
|
|
116
|
+
# Sandbox an SSH session runs in. 'docker' creates a
|
|
117
|
+
# sibling container; 'process' runs sshd inside the
|
|
118
|
+
# worker. 'auto' picks docker, falling back to process
|
|
119
|
+
# on a root worker.
|
|
120
|
+
SSH_SESSION_BACKEND=auto
|
|
121
|
+
# Address a direct-mode session is advertised at.
|
|
122
|
+
# Defaults to the worker's tailnet address, else its
|
|
123
|
+
# FQDN.
|
|
124
|
+
SSH_DIRECT_HOST=
|
|
109
125
|
|
|
110
126
|
# ==== General Settings ====
|
|
111
127
|
TZ=Asia/Singapore
|
|
@@ -128,6 +144,8 @@ ENABLE_WORKER_WATCHDOG=true
|
|
|
128
144
|
WORKER_DEATH_CHECK_INTERVAL=30
|
|
129
145
|
WORKER_DEATH_GRACE_SEC=60
|
|
130
146
|
WORKER_REHYDRATION_GRACE_SEC=120
|
|
147
|
+
ENABLE_WORKER_REAPER=true
|
|
148
|
+
WORKER_REAP_GRACE_SEC=900
|
|
131
149
|
|
|
132
150
|
# ==== Server Heartbeat ====
|
|
133
151
|
SERVER_HEARTBEAT_INTERVAL=30
|
|
@@ -163,6 +181,14 @@ SERVER_CUDA_PROBE_IMAGE=nvidia/cuda:12.9.1-base-ubuntu24.04
|
|
|
163
181
|
# Optional Docker runtime name for GPU containers.
|
|
164
182
|
DOCKER_GPU_RUNTIME=nvidia
|
|
165
183
|
CUDA_VISIBLE_DEVICES=all
|
|
184
|
+
# Report a GPU as unavailable while a process outside FlowMesh uses it.
|
|
185
|
+
WORKER_FOREIGN_GPU_GATE=true
|
|
186
|
+
# Foreign GPU-memory threshold in MiB.
|
|
187
|
+
WORKER_FOREIGN_GPU_MEM_MIB=1024
|
|
188
|
+
# Consecutive occupancy readings required before a device changes availability.
|
|
189
|
+
WORKER_FOREIGN_GPU_CONSECUTIVE=2
|
|
190
|
+
# Delay occupancy checks after a worker task completes.
|
|
191
|
+
WORKER_FOREIGN_GPU_GRACE_SEC=90
|
|
166
192
|
WORKER_UPLOAD_RESULTS=false
|
|
167
193
|
WORKER_EXECUTOR_IDLE_CLEANUP_SEC=60
|
|
168
194
|
MODEL_CLEANUP_AFTER_UPLOAD=0
|
{flowmesh_cli_stack-0.1.8rc1 → flowmesh_cli_stack-0.1.10}/src/flowmesh_cli_stack/env_schema.py
RENAMED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"""Stack env schema."""
|
|
2
2
|
|
|
3
3
|
from flowmesh.models.nodes import NodeRole
|
|
4
|
+
from flowmesh_stack.env import parse_bool
|
|
4
5
|
from flowmesh_stack.env_schema import (
|
|
5
6
|
EnvSchema,
|
|
6
7
|
EnvSection,
|
|
@@ -10,6 +11,24 @@ from flowmesh_stack.env_schema import (
|
|
|
10
11
|
require_if_true,
|
|
11
12
|
)
|
|
12
13
|
|
|
14
|
+
|
|
15
|
+
def _warn_reaper_without_watchdog(
|
|
16
|
+
env: dict[str, str], errors: list[str], warnings: list[str]
|
|
17
|
+
) -> None:
|
|
18
|
+
"""Warn when the stale-worker reaper is enabled while the watchdog is off.
|
|
19
|
+
|
|
20
|
+
The reaper runs on the watchdog thread, so it never fires without it. An
|
|
21
|
+
unset or unparsable ENABLE_WORKER_WATCHDOG keeps its own default and is
|
|
22
|
+
left alone, so only an explicit false value warns.
|
|
23
|
+
"""
|
|
24
|
+
if parse_bool(env.get("ENABLE_WORKER_REAPER", "")) and (
|
|
25
|
+
parse_bool(env.get("ENABLE_WORKER_WATCHDOG", "")) is False
|
|
26
|
+
):
|
|
27
|
+
warnings.append(
|
|
28
|
+
"ENABLE_WORKER_REAPER has no effect while ENABLE_WORKER_WATCHDOG is false"
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
|
|
13
32
|
STACK_ENV_SCHEMA = EnvSchema(
|
|
14
33
|
name="stack",
|
|
15
34
|
header=[
|
|
@@ -147,6 +166,17 @@ STACK_ENV_SCHEMA = EnvSchema(
|
|
|
147
166
|
var_type=EnvVarType.INT,
|
|
148
167
|
min_value=0,
|
|
149
168
|
),
|
|
169
|
+
EnvVar(
|
|
170
|
+
"EXTERNAL_WORKER_TOKEN",
|
|
171
|
+
description="Shared secret admitting `external` workers "
|
|
172
|
+
"(empty disables them).",
|
|
173
|
+
),
|
|
174
|
+
EnvVar(
|
|
175
|
+
"EXTERNAL_WORKER_TOKEN_FILE",
|
|
176
|
+
description="File holding the secret; wins over "
|
|
177
|
+
"EXTERNAL_WORKER_TOKEN.",
|
|
178
|
+
var_type=EnvVarType.FILE_PATH,
|
|
179
|
+
),
|
|
150
180
|
],
|
|
151
181
|
),
|
|
152
182
|
EnvSection(
|
|
@@ -292,7 +322,7 @@ STACK_ENV_SCHEMA = EnvSchema(
|
|
|
292
322
|
vars=[
|
|
293
323
|
EnvVar("ENABLE_SERVER_SSH_PROXY", "true", var_type=EnvVarType.BOOL),
|
|
294
324
|
EnvVar(
|
|
295
|
-
"
|
|
325
|
+
"ENABLE_SERVER_SSH_CONNECTION_REGISTRY",
|
|
296
326
|
"true",
|
|
297
327
|
var_type=EnvVarType.BOOL,
|
|
298
328
|
),
|
|
@@ -325,7 +355,7 @@ STACK_ENV_SCHEMA = EnvSchema(
|
|
|
325
355
|
EnvVar("SSH_MAX_PIDS", var_type=EnvVarType.INT, min_value=1),
|
|
326
356
|
EnvVar(
|
|
327
357
|
"ENABLE_SSH_GPU_LIMIT",
|
|
328
|
-
"
|
|
358
|
+
"true",
|
|
329
359
|
var_type=EnvVarType.BOOL,
|
|
330
360
|
description=[
|
|
331
361
|
"Whether to apply requested GPU limits to SSH tasks.",
|
|
@@ -333,6 +363,35 @@ STACK_ENV_SCHEMA = EnvSchema(
|
|
|
333
363
|
"regardless of their resource requests.",
|
|
334
364
|
],
|
|
335
365
|
),
|
|
366
|
+
EnvVar(
|
|
367
|
+
"ENABLE_UNISOLATED_SSH_SESSION",
|
|
368
|
+
"false",
|
|
369
|
+
var_type=EnvVarType.BOOL,
|
|
370
|
+
description=[
|
|
371
|
+
"Whether a non-root worker may serve SSH sessions,",
|
|
372
|
+
"which run as the worker and can read its credentials.",
|
|
373
|
+
],
|
|
374
|
+
),
|
|
375
|
+
EnvVar(
|
|
376
|
+
"SSH_SESSION_BACKEND",
|
|
377
|
+
"auto",
|
|
378
|
+
var_type=EnvVarType.ENUM,
|
|
379
|
+
choices={"auto", "docker", "process"},
|
|
380
|
+
description=[
|
|
381
|
+
"Sandbox an SSH session runs in. 'docker' creates a",
|
|
382
|
+
"sibling container; 'process' runs sshd inside the",
|
|
383
|
+
"worker. 'auto' picks docker, falling back to process",
|
|
384
|
+
"on a root worker.",
|
|
385
|
+
],
|
|
386
|
+
),
|
|
387
|
+
EnvVar(
|
|
388
|
+
"SSH_DIRECT_HOST",
|
|
389
|
+
description=[
|
|
390
|
+
"Address a direct-mode session is advertised at.",
|
|
391
|
+
"Defaults to the worker's tailnet address, else its",
|
|
392
|
+
"FQDN.",
|
|
393
|
+
],
|
|
394
|
+
),
|
|
336
395
|
],
|
|
337
396
|
),
|
|
338
397
|
EnvSection(
|
|
@@ -427,6 +486,17 @@ STACK_ENV_SCHEMA = EnvSchema(
|
|
|
427
486
|
var_type=EnvVarType.INT,
|
|
428
487
|
min_value=0,
|
|
429
488
|
),
|
|
489
|
+
EnvVar(
|
|
490
|
+
"ENABLE_WORKER_REAPER",
|
|
491
|
+
"true",
|
|
492
|
+
var_type=EnvVarType.BOOL,
|
|
493
|
+
),
|
|
494
|
+
EnvVar(
|
|
495
|
+
"WORKER_REAP_GRACE_SEC",
|
|
496
|
+
"900",
|
|
497
|
+
var_type=EnvVarType.INT,
|
|
498
|
+
min_value=0,
|
|
499
|
+
),
|
|
430
500
|
],
|
|
431
501
|
),
|
|
432
502
|
EnvSection(
|
|
@@ -523,6 +593,39 @@ STACK_ENV_SCHEMA = EnvSchema(
|
|
|
523
593
|
EnvVar(
|
|
524
594
|
"CUDA_VISIBLE_DEVICES", "all", var_type=EnvVarType.CSV_INTS_OR_ALL
|
|
525
595
|
),
|
|
596
|
+
EnvVar(
|
|
597
|
+
"WORKER_FOREIGN_GPU_GATE",
|
|
598
|
+
"true",
|
|
599
|
+
description=[
|
|
600
|
+
"Report a GPU as unavailable while a process outside "
|
|
601
|
+
"FlowMesh uses it.",
|
|
602
|
+
],
|
|
603
|
+
var_type=EnvVarType.BOOL,
|
|
604
|
+
),
|
|
605
|
+
EnvVar(
|
|
606
|
+
"WORKER_FOREIGN_GPU_MEM_MIB",
|
|
607
|
+
"1024",
|
|
608
|
+
description="Foreign GPU-memory threshold in MiB.",
|
|
609
|
+
var_type=EnvVarType.INT,
|
|
610
|
+
min_value=1,
|
|
611
|
+
),
|
|
612
|
+
EnvVar(
|
|
613
|
+
"WORKER_FOREIGN_GPU_CONSECUTIVE",
|
|
614
|
+
"2",
|
|
615
|
+
description=[
|
|
616
|
+
"Consecutive occupancy readings required before a device "
|
|
617
|
+
"changes availability.",
|
|
618
|
+
],
|
|
619
|
+
var_type=EnvVarType.INT,
|
|
620
|
+
min_value=1,
|
|
621
|
+
),
|
|
622
|
+
EnvVar(
|
|
623
|
+
"WORKER_FOREIGN_GPU_GRACE_SEC",
|
|
624
|
+
"90",
|
|
625
|
+
description="Delay occupancy checks after a worker task completes.",
|
|
626
|
+
var_type=EnvVarType.FLOAT,
|
|
627
|
+
min_value=0,
|
|
628
|
+
),
|
|
526
629
|
EnvVar("WORKER_UPLOAD_RESULTS", "false", var_type=EnvVarType.BOOL),
|
|
527
630
|
EnvVar(
|
|
528
631
|
"WORKER_EXECUTOR_IDLE_CLEANUP_SEC",
|
|
@@ -693,6 +796,7 @@ STACK_ENV_SCHEMA = EnvSchema(
|
|
|
693
796
|
],
|
|
694
797
|
errors,
|
|
695
798
|
),
|
|
799
|
+
_warn_reaper_without_watchdog,
|
|
696
800
|
],
|
|
697
801
|
)
|
|
698
802
|
|
|
@@ -80,11 +80,11 @@ def worker_up(
|
|
|
80
80
|
"Repeat --config-raw to provide multiple configs."
|
|
81
81
|
),
|
|
82
82
|
),
|
|
83
|
-
|
|
83
|
+
alias_template: str | None = typer.Option(
|
|
84
84
|
None,
|
|
85
|
-
"--
|
|
85
|
+
"--alias-template",
|
|
86
86
|
help=(
|
|
87
|
-
"Worker
|
|
87
|
+
"Worker alias template for cpu/gpu presets. Placeholders: "
|
|
88
88
|
"{slug}, {kind}, {idx}, {gpu}. "
|
|
89
89
|
"Default: '{slug}_worker_{kind}_{idx|gpu}'."
|
|
90
90
|
),
|
|
@@ -113,21 +113,21 @@ def worker_up(
|
|
|
113
113
|
targets=targets,
|
|
114
114
|
config_paths=config,
|
|
115
115
|
config_raw=config_raw,
|
|
116
|
-
|
|
116
|
+
alias_template=alias_template,
|
|
117
117
|
slug=slug,
|
|
118
118
|
)
|
|
119
119
|
except FlowMeshError as exc:
|
|
120
120
|
logging.error(str(exc))
|
|
121
121
|
raise typer.Exit(code=1)
|
|
122
122
|
for label, worker_info in created:
|
|
123
|
-
|
|
124
|
-
logging.success(f"Created {label} '{
|
|
123
|
+
worker_alias = worker_info.get("alias", "<unknown>")
|
|
124
|
+
logging.success(f"Created {label} '{worker_alias}':")
|
|
125
125
|
logging.log(json.dumps(worker_info, indent=2))
|
|
126
126
|
|
|
127
127
|
|
|
128
128
|
@app.command("start")
|
|
129
129
|
def worker_start(
|
|
130
|
-
|
|
130
|
+
aliases: list[str] = typer.Argument(..., help="Worker alias(es) or 'all'"),
|
|
131
131
|
env_file: Path = typer.Option(
|
|
132
132
|
DEFAULT_ENV_FILE, "--env-file", help="Env file to load defaults"
|
|
133
133
|
),
|
|
@@ -139,20 +139,20 @@ def worker_start(
|
|
|
139
139
|
"""Start a stopped worker container."""
|
|
140
140
|
client = stack_node_client(env_file, base_url, token or None)
|
|
141
141
|
try:
|
|
142
|
-
started = operate_workers(client,
|
|
142
|
+
started = operate_workers(client, aliases, operation="start")
|
|
143
143
|
except FlowMeshError as exc:
|
|
144
144
|
logging.error(str(exc))
|
|
145
145
|
raise typer.Exit(code=1)
|
|
146
146
|
if not started:
|
|
147
147
|
logging.warning("No workers found.")
|
|
148
148
|
return
|
|
149
|
-
for
|
|
150
|
-
logging.success(f"Started worker {
|
|
149
|
+
for alias in started:
|
|
150
|
+
logging.success(f"Started worker {alias}")
|
|
151
151
|
|
|
152
152
|
|
|
153
153
|
@app.command("stop")
|
|
154
154
|
def worker_stop(
|
|
155
|
-
|
|
155
|
+
aliases: list[str] = typer.Argument(..., help="Worker alias(es) or 'all'"),
|
|
156
156
|
env_file: Path = typer.Option(
|
|
157
157
|
DEFAULT_ENV_FILE, "--env-file", help="Env file to load defaults"
|
|
158
158
|
),
|
|
@@ -164,20 +164,20 @@ def worker_stop(
|
|
|
164
164
|
"""Stop a running worker container without removing it."""
|
|
165
165
|
client = stack_node_client(env_file, base_url, token or None)
|
|
166
166
|
try:
|
|
167
|
-
stopped = operate_workers(client,
|
|
167
|
+
stopped = operate_workers(client, aliases, operation="stop")
|
|
168
168
|
except FlowMeshError as exc:
|
|
169
169
|
logging.error(str(exc))
|
|
170
170
|
raise typer.Exit(code=1)
|
|
171
171
|
if not stopped:
|
|
172
172
|
logging.warning("No workers found.")
|
|
173
173
|
return
|
|
174
|
-
for
|
|
175
|
-
logging.success(f"Stopped worker {
|
|
174
|
+
for alias in stopped:
|
|
175
|
+
logging.success(f"Stopped worker {alias}")
|
|
176
176
|
|
|
177
177
|
|
|
178
178
|
@app.command("down")
|
|
179
179
|
def worker_down(
|
|
180
|
-
|
|
180
|
+
aliases: list[str] = typer.Argument(..., help="Worker alias(es) or 'all'"),
|
|
181
181
|
env_file: Path = typer.Option(
|
|
182
182
|
DEFAULT_ENV_FILE, "--env-file", help="Env file to load defaults"
|
|
183
183
|
),
|
|
@@ -188,9 +188,9 @@ def worker_down(
|
|
|
188
188
|
) -> None:
|
|
189
189
|
"""Destroy a worker or all workers, removing containers and associated resources."""
|
|
190
190
|
client = stack_node_client(env_file, base_url, token or None)
|
|
191
|
-
if "all" in
|
|
192
|
-
if len(
|
|
193
|
-
logging.error("Use either 'all' or worker
|
|
191
|
+
if "all" in aliases:
|
|
192
|
+
if len(aliases) != 1:
|
|
193
|
+
logging.error("Use either 'all' or worker aliases, not both.")
|
|
194
194
|
raise typer.Exit(code=1)
|
|
195
195
|
try:
|
|
196
196
|
logging.info("Destroying all workers...")
|
|
@@ -202,15 +202,15 @@ def worker_down(
|
|
|
202
202
|
return
|
|
203
203
|
|
|
204
204
|
try:
|
|
205
|
-
destroyed = operate_workers(client,
|
|
205
|
+
destroyed = operate_workers(client, aliases, operation="destroy")
|
|
206
206
|
except FlowMeshError as exc:
|
|
207
207
|
logging.error(str(exc))
|
|
208
208
|
raise typer.Exit(code=1)
|
|
209
209
|
if not destroyed:
|
|
210
210
|
logging.warning("No workers found.")
|
|
211
211
|
return
|
|
212
|
-
for
|
|
213
|
-
logging.success(f"Destroyed worker {
|
|
212
|
+
for alias in destroyed:
|
|
213
|
+
logging.success(f"Destroyed worker {alias}")
|
|
214
214
|
|
|
215
215
|
|
|
216
216
|
@app.command("pull")
|
{flowmesh_cli_stack-0.1.8rc1 → flowmesh_cli_stack-0.1.10/src/flowmesh_cli_stack.egg-info}/PKG-INFO
RENAMED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: flowmesh-cli-stack
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.10
|
|
4
4
|
Summary: FlowMesh CLI stack commands
|
|
5
5
|
License-Expression: Apache-2.0
|
|
6
6
|
Requires-Python: >=3.12
|
|
7
7
|
Description-Content-Type: text/markdown
|
|
8
8
|
License-File: LICENSE
|
|
9
|
-
Requires-Dist: flowmesh-cli==0.1.
|
|
10
|
-
Requires-Dist: flowmesh-sdk-stack==0.1.
|
|
9
|
+
Requires-Dist: flowmesh-cli==0.1.10
|
|
10
|
+
Requires-Dist: flowmesh-sdk-stack==0.1.10
|
|
11
11
|
Requires-Dist: docker>=7.1.0
|
|
12
12
|
Requires-Dist: packaging>=24
|
|
13
13
|
Requires-Dist: pyyaml>=6.0.2
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{flowmesh_cli_stack-0.1.8rc1 → flowmesh_cli_stack-0.1.10}/src/flowmesh_cli_stack/__init__.py
RENAMED
|
File without changes
|
{flowmesh_cli_stack-0.1.8rc1 → flowmesh_cli_stack-0.1.10}/src/flowmesh_cli_stack/assets/compose.yml
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
|