cyclo-manager 0.2.0.dev9__tar.gz → 0.2.0.dev10__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.
- {cyclo_manager-0.2.0.dev9 → cyclo_manager-0.2.0.dev10}/PKG-INFO +1 -1
- {cyclo_manager-0.2.0.dev9 → cyclo_manager-0.2.0.dev10}/cyclo_manager.egg-info/PKG-INFO +1 -1
- {cyclo_manager-0.2.0.dev9 → cyclo_manager-0.2.0.dev10}/cyclo_manager_cli/cli.py +39 -8
- {cyclo_manager-0.2.0.dev9 → cyclo_manager-0.2.0.dev10}/pyproject.toml +1 -1
- {cyclo_manager-0.2.0.dev9 → cyclo_manager-0.2.0.dev10}/README.md +0 -0
- {cyclo_manager-0.2.0.dev9 → cyclo_manager-0.2.0.dev10}/cyclo_host_agent/__init__.py +0 -0
- {cyclo_manager-0.2.0.dev9 → cyclo_manager-0.2.0.dev10}/cyclo_host_agent/main.py +0 -0
- {cyclo_manager-0.2.0.dev9 → cyclo_manager-0.2.0.dev10}/cyclo_host_agent/models.py +0 -0
- {cyclo_manager-0.2.0.dev9 → cyclo_manager-0.2.0.dev10}/cyclo_host_agent/routers/__init__.py +0 -0
- {cyclo_manager-0.2.0.dev9 → cyclo_manager-0.2.0.dev10}/cyclo_host_agent/routers/repos.py +0 -0
- {cyclo_manager-0.2.0.dev9 → cyclo_manager-0.2.0.dev10}/cyclo_host_agent/routers/update.py +0 -0
- {cyclo_manager-0.2.0.dev9 → cyclo_manager-0.2.0.dev10}/cyclo_manager.egg-info/SOURCES.txt +0 -0
- {cyclo_manager-0.2.0.dev9 → cyclo_manager-0.2.0.dev10}/cyclo_manager.egg-info/dependency_links.txt +0 -0
- {cyclo_manager-0.2.0.dev9 → cyclo_manager-0.2.0.dev10}/cyclo_manager.egg-info/entry_points.txt +0 -0
- {cyclo_manager-0.2.0.dev9 → cyclo_manager-0.2.0.dev10}/cyclo_manager.egg-info/requires.txt +0 -0
- {cyclo_manager-0.2.0.dev9 → cyclo_manager-0.2.0.dev10}/cyclo_manager.egg-info/top_level.txt +0 -0
- {cyclo_manager-0.2.0.dev9 → cyclo_manager-0.2.0.dev10}/cyclo_manager_cli/__init__.py +0 -0
- {cyclo_manager-0.2.0.dev9 → cyclo_manager-0.2.0.dev10}/cyclo_manager_cli/config/config.yml +0 -0
- {cyclo_manager-0.2.0.dev9 → cyclo_manager-0.2.0.dev10}/cyclo_manager_cli/docker/docker-compose.yml +0 -0
- {cyclo_manager-0.2.0.dev9 → cyclo_manager-0.2.0.dev10}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: cyclo-manager
|
|
3
|
-
Version: 0.2.0.
|
|
3
|
+
Version: 0.2.0.dev10
|
|
4
4
|
Summary: cyclo_manager CLI: pip-installable launcher for cyclo_manager server and UI containers. Run 'cyclo_manager up' to start Docker stack.
|
|
5
5
|
License-Expression: Apache-2.0
|
|
6
6
|
Requires-Python: >=3.10
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: cyclo-manager
|
|
3
|
-
Version: 0.2.0.
|
|
3
|
+
Version: 0.2.0.dev10
|
|
4
4
|
Summary: cyclo_manager CLI: pip-installable launcher for cyclo_manager server and UI containers. Run 'cyclo_manager up' to start Docker stack.
|
|
5
5
|
License-Expression: Apache-2.0
|
|
6
6
|
Requires-Python: >=3.10
|
|
@@ -27,6 +27,7 @@ import argparse
|
|
|
27
27
|
import os
|
|
28
28
|
from pathlib import Path
|
|
29
29
|
import shutil
|
|
30
|
+
import socket
|
|
30
31
|
import subprocess
|
|
31
32
|
import sys
|
|
32
33
|
|
|
@@ -81,17 +82,20 @@ def _setup_socket_dir(user: str) -> bool:
|
|
|
81
82
|
Only host/ is chowned so other agent sockets under agent_sockets/ are untouched.
|
|
82
83
|
Removes a stale socket file (e.g. left by a previous root-owned service).
|
|
83
84
|
"""
|
|
85
|
+
print(f' [1/3] Creating socket directory {HOST_AGENT_SOCKET_DIR}...')
|
|
84
86
|
try:
|
|
85
87
|
subprocess.run(
|
|
86
88
|
['sudo', 'mkdir', '-p', HOST_AGENT_SOCKET_DIR],
|
|
87
89
|
check=True,
|
|
88
90
|
capture_output=True,
|
|
89
91
|
)
|
|
92
|
+
print(f' [2/3] Setting ownership to {user}:{user}...')
|
|
90
93
|
subprocess.run(
|
|
91
94
|
['sudo', 'chown', f'{user}:{user}', HOST_AGENT_SOCKET_DIR],
|
|
92
95
|
check=True,
|
|
93
96
|
capture_output=True,
|
|
94
97
|
)
|
|
98
|
+
print(f' [3/3] Removing stale socket file (if any)...')
|
|
95
99
|
subprocess.run(
|
|
96
100
|
['sudo', 'rm', '-f', HOST_AGENT_SOCKET],
|
|
97
101
|
check=True,
|
|
@@ -108,6 +112,7 @@ def _install_sudoers(user: str) -> bool:
|
|
|
108
112
|
Write /etc/sudoers.d/cyclo_manager granting NOPASSWD for udev operations
|
|
109
113
|
needed by container.sh (cp to /etc/udev/rules.d/, udevadm control/trigger).
|
|
110
114
|
"""
|
|
115
|
+
print(' Installing sudoers rules (cp, udevadm, reboot, poweroff)...')
|
|
111
116
|
sudoers_content = (
|
|
112
117
|
f'{user} ALL=(ALL) NOPASSWD: /usr/bin/cp, '
|
|
113
118
|
f'/usr/bin/udevadm control --reload-rules, '
|
|
@@ -181,18 +186,30 @@ WantedBy=multi-user.target
|
|
|
181
186
|
|
|
182
187
|
service_file = f'/etc/systemd/system/{HOST_AGENT_SERVICE}.service'
|
|
183
188
|
|
|
184
|
-
print(f'
|
|
189
|
+
print(f'Setting up {HOST_AGENT_SERVICE} systemd service (user={user})...')
|
|
185
190
|
try:
|
|
191
|
+
print(f' Writing unit file to {service_file}...')
|
|
186
192
|
subprocess.run(
|
|
187
193
|
['sudo', 'tee', service_file],
|
|
188
194
|
input=service_content.encode(),
|
|
189
195
|
capture_output=True,
|
|
190
196
|
check=True,
|
|
191
197
|
)
|
|
192
|
-
|
|
193
|
-
subprocess.run(['sudo', 'systemctl', '
|
|
194
|
-
|
|
195
|
-
|
|
198
|
+
print(' Running systemctl daemon-reload...')
|
|
199
|
+
subprocess.run(['sudo', 'systemctl', 'daemon-reload'], check=True, capture_output=True)
|
|
200
|
+
print(f' Enabling {HOST_AGENT_SERVICE}...')
|
|
201
|
+
subprocess.run(
|
|
202
|
+
['sudo', 'systemctl', 'enable', f'{HOST_AGENT_SERVICE}.service'],
|
|
203
|
+
check=True,
|
|
204
|
+
capture_output=True,
|
|
205
|
+
)
|
|
206
|
+
print(f' Starting {HOST_AGENT_SERVICE}...')
|
|
207
|
+
subprocess.run(
|
|
208
|
+
['sudo', 'systemctl', 'restart', f'{HOST_AGENT_SERVICE}.service'],
|
|
209
|
+
check=True,
|
|
210
|
+
capture_output=True,
|
|
211
|
+
)
|
|
212
|
+
print(f' {HOST_AGENT_SERVICE} is running.')
|
|
196
213
|
return 0
|
|
197
214
|
except subprocess.CalledProcessError as e:
|
|
198
215
|
print(f'Failed to install host agent service: {e}', file=sys.stderr)
|
|
@@ -204,6 +221,9 @@ WantedBy=multi-user.target
|
|
|
204
221
|
|
|
205
222
|
def cmd_up(args: argparse.Namespace) -> int:
|
|
206
223
|
"""Start API + UI; create zenoh and noVNC containers without starting them."""
|
|
224
|
+
print('--- cyclo_manager up ---')
|
|
225
|
+
|
|
226
|
+
print('[1/3] Setting up host agent...')
|
|
207
227
|
if _ensure_host_agent() != 0:
|
|
208
228
|
print('Warning: Failed to install host agent service.', file=sys.stderr)
|
|
209
229
|
|
|
@@ -217,11 +237,15 @@ def cmd_up(args: argparse.Namespace) -> int:
|
|
|
217
237
|
return 1
|
|
218
238
|
env = os.environ.copy()
|
|
219
239
|
env['CYCLO_MANAGER_CONFIG_FILE'] = str(config_path)
|
|
240
|
+
env.setdefault('HOSTNAME', socket.gethostname())
|
|
220
241
|
base = ['docker', 'compose', '-f', str(compose_path)]
|
|
221
242
|
try:
|
|
222
243
|
if args.pull:
|
|
244
|
+
print('[2/3] Pulling latest images...')
|
|
223
245
|
subprocess.run([*base, 'pull'], env=env, check=True)
|
|
246
|
+
print(f'[2/3] Starting containers: {", ".join(COMPOSE_SERVICES_UP)}...')
|
|
224
247
|
subprocess.run([*base, 'up', '-d', *COMPOSE_SERVICES_UP], env=env, check=True)
|
|
248
|
+
print(f'[3/3] Creating (not starting): {", ".join(COMPOSE_SERVICES_CREATE_ONLY)}...')
|
|
225
249
|
subprocess.run(
|
|
226
250
|
[*base, 'create', '--no-recreate', *COMPOSE_SERVICES_CREATE_ONLY],
|
|
227
251
|
env=env,
|
|
@@ -244,23 +268,27 @@ def cmd_up(args: argparse.Namespace) -> int:
|
|
|
244
268
|
|
|
245
269
|
def _teardown_host_agent() -> None:
|
|
246
270
|
"""Stop and remove the host agent service, unit file, sudoers, and socket dir."""
|
|
271
|
+
print(f'Tearing down {HOST_AGENT_SERVICE}...')
|
|
247
272
|
steps = [
|
|
248
273
|
(['sudo', 'systemctl', 'stop', f'{HOST_AGENT_SERVICE}.service'], 'stop service'),
|
|
249
274
|
(['sudo', 'systemctl', 'disable', f'{HOST_AGENT_SERVICE}.service'], 'disable service'),
|
|
250
275
|
(['sudo', 'rm', '-f', f'/etc/systemd/system/{HOST_AGENT_SERVICE}.service'], 'remove unit file'),
|
|
251
|
-
(['sudo', 'systemctl', 'daemon-reload'], 'reload
|
|
276
|
+
(['sudo', 'systemctl', 'daemon-reload'], 'daemon-reload'),
|
|
252
277
|
(['sudo', 'rm', '-f', '/etc/sudoers.d/cyclo_manager'], 'remove sudoers'),
|
|
253
278
|
(['sudo', 'rm', '-rf', HOST_AGENT_SOCKET_DIR], 'remove socket dir'),
|
|
254
279
|
]
|
|
255
280
|
for cmd, desc in steps:
|
|
281
|
+
print(f' {desc}...')
|
|
256
282
|
try:
|
|
257
283
|
subprocess.run(cmd, check=True, capture_output=True)
|
|
258
284
|
except subprocess.CalledProcessError:
|
|
259
|
-
print(f'Warning: failed to {desc}.', file=sys.stderr)
|
|
285
|
+
print(f' Warning: failed to {desc}.', file=sys.stderr)
|
|
260
286
|
|
|
261
287
|
|
|
262
288
|
def cmd_down(args: argparse.Namespace) -> int:
|
|
263
289
|
"""Stop cyclo_manager server, cyclo_manager_ui, and zenoh daemon (docker compose down)."""
|
|
290
|
+
print('--- cyclo_manager down ---')
|
|
291
|
+
|
|
264
292
|
_teardown_host_agent()
|
|
265
293
|
|
|
266
294
|
compose_path = _docker_dir() / 'docker-compose.yml'
|
|
@@ -269,6 +297,7 @@ def cmd_down(args: argparse.Namespace) -> int:
|
|
|
269
297
|
return 1
|
|
270
298
|
env = os.environ.copy()
|
|
271
299
|
env['CYCLO_MANAGER_CONFIG_FILE'] = str(_packaged_config_path())
|
|
300
|
+
env.setdefault('HOSTNAME', socket.gethostname())
|
|
272
301
|
cmd = [
|
|
273
302
|
'docker',
|
|
274
303
|
'compose',
|
|
@@ -276,6 +305,7 @@ def cmd_down(args: argparse.Namespace) -> int:
|
|
|
276
305
|
str(compose_path),
|
|
277
306
|
'down',
|
|
278
307
|
]
|
|
308
|
+
print('Stopping Docker containers (docker compose down)...')
|
|
279
309
|
try:
|
|
280
310
|
subprocess.run(cmd, env=env, check=True)
|
|
281
311
|
except subprocess.CalledProcessError as e:
|
|
@@ -287,7 +317,7 @@ def cmd_down(args: argparse.Namespace) -> int:
|
|
|
287
317
|
)
|
|
288
318
|
return 1
|
|
289
319
|
|
|
290
|
-
print('cyclo_manager
|
|
320
|
+
print('cyclo_manager is down.')
|
|
291
321
|
return 0
|
|
292
322
|
|
|
293
323
|
|
|
@@ -304,6 +334,7 @@ def cmd_update(args: argparse.Namespace) -> int:
|
|
|
304
334
|
return 1
|
|
305
335
|
env = os.environ.copy()
|
|
306
336
|
env['CYCLO_MANAGER_CONFIG_FILE'] = str(_packaged_config_path())
|
|
337
|
+
env.setdefault('HOSTNAME', socket.gethostname())
|
|
307
338
|
base = ['docker', 'compose', '-f', str(compose_path)]
|
|
308
339
|
|
|
309
340
|
print('Stopping containers...')
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "cyclo-manager"
|
|
7
|
-
version = "0.2.0.
|
|
7
|
+
version = "0.2.0.dev10"
|
|
8
8
|
description = "cyclo_manager CLI: pip-installable launcher for cyclo_manager server and UI containers. Run 'cyclo_manager up' to start Docker stack."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = "Apache-2.0"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{cyclo_manager-0.2.0.dev9 → cyclo_manager-0.2.0.dev10}/cyclo_manager.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
{cyclo_manager-0.2.0.dev9 → cyclo_manager-0.2.0.dev10}/cyclo_manager.egg-info/entry_points.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{cyclo_manager-0.2.0.dev9 → cyclo_manager-0.2.0.dev10}/cyclo_manager_cli/docker/docker-compose.yml
RENAMED
|
File without changes
|
|
File without changes
|