flowmesh-cli-stack 0.1.8__tar.gz → 0.1.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.
- {flowmesh_cli_stack-0.1.8/src/flowmesh_cli_stack.egg-info → flowmesh_cli_stack-0.1.9}/PKG-INFO +3 -3
- {flowmesh_cli_stack-0.1.8 → flowmesh_cli_stack-0.1.9}/pyproject.toml +3 -3
- {flowmesh_cli_stack-0.1.8 → flowmesh_cli_stack-0.1.9}/src/flowmesh_cli_stack/assets/.env.example +20 -2
- {flowmesh_cli_stack-0.1.8 → flowmesh_cli_stack-0.1.9}/src/flowmesh_cli_stack/env_schema.py +73 -2
- {flowmesh_cli_stack-0.1.8 → flowmesh_cli_stack-0.1.9/src/flowmesh_cli_stack.egg-info}/PKG-INFO +3 -3
- flowmesh_cli_stack-0.1.9/src/flowmesh_cli_stack.egg-info/requires.txt +5 -0
- flowmesh_cli_stack-0.1.8/src/flowmesh_cli_stack.egg-info/requires.txt +0 -5
- {flowmesh_cli_stack-0.1.8 → flowmesh_cli_stack-0.1.9}/LICENSE +0 -0
- {flowmesh_cli_stack-0.1.8 → flowmesh_cli_stack-0.1.9}/README.md +0 -0
- {flowmesh_cli_stack-0.1.8 → flowmesh_cli_stack-0.1.9}/setup.cfg +0 -0
- {flowmesh_cli_stack-0.1.8 → flowmesh_cli_stack-0.1.9}/src/flowmesh_cli_stack/__init__.py +0 -0
- {flowmesh_cli_stack-0.1.8 → flowmesh_cli_stack-0.1.9}/src/flowmesh_cli_stack/assets/compose.yml +0 -0
- {flowmesh_cli_stack-0.1.8 → flowmesh_cli_stack-0.1.9}/src/flowmesh_cli_stack/assets/docker-bake.hcl +0 -0
- {flowmesh_cli_stack-0.1.8 → flowmesh_cli_stack-0.1.9}/src/flowmesh_cli_stack/bundle.py +0 -0
- {flowmesh_cli_stack-0.1.8 → flowmesh_cli_stack-0.1.9}/src/flowmesh_cli_stack/image.py +0 -0
- {flowmesh_cli_stack-0.1.8 → flowmesh_cli_stack-0.1.9}/src/flowmesh_cli_stack/stack.py +0 -0
- {flowmesh_cli_stack-0.1.8 → flowmesh_cli_stack-0.1.9}/src/flowmesh_cli_stack/utils.py +0 -0
- {flowmesh_cli_stack-0.1.8 → flowmesh_cli_stack-0.1.9}/src/flowmesh_cli_stack/worker.py +0 -0
- {flowmesh_cli_stack-0.1.8 → flowmesh_cli_stack-0.1.9}/src/flowmesh_cli_stack.egg-info/SOURCES.txt +0 -0
- {flowmesh_cli_stack-0.1.8 → flowmesh_cli_stack-0.1.9}/src/flowmesh_cli_stack.egg-info/dependency_links.txt +0 -0
- {flowmesh_cli_stack-0.1.8 → flowmesh_cli_stack-0.1.9}/src/flowmesh_cli_stack.egg-info/top_level.txt +0 -0
{flowmesh_cli_stack-0.1.8/src/flowmesh_cli_stack.egg-info → flowmesh_cli_stack-0.1.9}/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.9
|
|
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.9
|
|
10
|
+
Requires-Dist: flowmesh-sdk-stack==0.1.9
|
|
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.9"
|
|
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.9",
|
|
15
|
+
"flowmesh-sdk-stack==0.1.9",
|
|
16
16
|
"docker>=7.1.0",
|
|
17
17
|
"packaging>=24",
|
|
18
18
|
"pyyaml>=6.0.2",
|
{flowmesh_cli_stack-0.1.8 → flowmesh_cli_stack-0.1.9}/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
|
|
@@ -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(
|
|
@@ -693,6 +763,7 @@ STACK_ENV_SCHEMA = EnvSchema(
|
|
|
693
763
|
],
|
|
694
764
|
errors,
|
|
695
765
|
),
|
|
766
|
+
_warn_reaper_without_watchdog,
|
|
696
767
|
],
|
|
697
768
|
)
|
|
698
769
|
|
{flowmesh_cli_stack-0.1.8 → flowmesh_cli_stack-0.1.9/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.9
|
|
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.9
|
|
10
|
+
Requires-Dist: flowmesh-sdk-stack==0.1.9
|
|
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
|
|
File without changes
|
{flowmesh_cli_stack-0.1.8 → flowmesh_cli_stack-0.1.9}/src/flowmesh_cli_stack/assets/compose.yml
RENAMED
|
File without changes
|
{flowmesh_cli_stack-0.1.8 → flowmesh_cli_stack-0.1.9}/src/flowmesh_cli_stack/assets/docker-bake.hcl
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{flowmesh_cli_stack-0.1.8 → flowmesh_cli_stack-0.1.9}/src/flowmesh_cli_stack.egg-info/SOURCES.txt
RENAMED
|
File without changes
|
|
File without changes
|
{flowmesh_cli_stack-0.1.8 → flowmesh_cli_stack-0.1.9}/src/flowmesh_cli_stack.egg-info/top_level.txt
RENAMED
|
File without changes
|