cyclo-manager 0.2.0.dev12__tar.gz → 0.2.1__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.dev12 → cyclo_manager-0.2.1}/PKG-INFO +7 -12
- {cyclo_manager-0.2.0.dev12 → cyclo_manager-0.2.1}/README.md +6 -11
- {cyclo_manager-0.2.0.dev12 → cyclo_manager-0.2.1}/cyclo_host_agent/main.py +4 -4
- {cyclo_manager-0.2.0.dev12 → cyclo_manager-0.2.1}/cyclo_host_agent/models.py +8 -0
- {cyclo_manager-0.2.0.dev12 → cyclo_manager-0.2.1}/cyclo_host_agent/routers/repos.py +23 -7
- {cyclo_manager-0.2.0.dev12 → cyclo_manager-0.2.1}/cyclo_host_agent/routers/update.py +4 -2
- {cyclo_manager-0.2.0.dev12 → cyclo_manager-0.2.1}/cyclo_manager.egg-info/PKG-INFO +7 -12
- {cyclo_manager-0.2.0.dev12 → cyclo_manager-0.2.1}/cyclo_manager_cli/__init__.py +1 -1
- {cyclo_manager-0.2.0.dev12 → cyclo_manager-0.2.1}/cyclo_manager_cli/cli.py +26 -10
- {cyclo_manager-0.2.0.dev12 → cyclo_manager-0.2.1}/cyclo_manager_cli/config/config.yml +1 -1
- {cyclo_manager-0.2.0.dev12 → cyclo_manager-0.2.1}/cyclo_manager_cli/docker/docker-compose.yml +2 -2
- {cyclo_manager-0.2.0.dev12 → cyclo_manager-0.2.1}/pyproject.toml +1 -1
- {cyclo_manager-0.2.0.dev12 → cyclo_manager-0.2.1}/setup.cfg +0 -1
- {cyclo_manager-0.2.0.dev12 → cyclo_manager-0.2.1}/cyclo_host_agent/__init__.py +0 -0
- {cyclo_manager-0.2.0.dev12 → cyclo_manager-0.2.1}/cyclo_host_agent/routers/__init__.py +0 -0
- {cyclo_manager-0.2.0.dev12 → cyclo_manager-0.2.1}/cyclo_manager.egg-info/SOURCES.txt +0 -0
- {cyclo_manager-0.2.0.dev12 → cyclo_manager-0.2.1}/cyclo_manager.egg-info/dependency_links.txt +0 -0
- {cyclo_manager-0.2.0.dev12 → cyclo_manager-0.2.1}/cyclo_manager.egg-info/entry_points.txt +0 -0
- {cyclo_manager-0.2.0.dev12 → cyclo_manager-0.2.1}/cyclo_manager.egg-info/requires.txt +0 -0
- {cyclo_manager-0.2.0.dev12 → cyclo_manager-0.2.1}/cyclo_manager.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: cyclo-manager
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.1
|
|
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
|
|
@@ -67,12 +67,6 @@ From **PyPI**:
|
|
|
67
67
|
pip install cyclo-manager
|
|
68
68
|
```
|
|
69
69
|
|
|
70
|
-
Pre-release versions:
|
|
71
|
-
|
|
72
|
-
```bash
|
|
73
|
-
pip install --pre cyclo-manager==0.2.0.dev0
|
|
74
|
-
```
|
|
75
|
-
|
|
76
70
|
If `cyclo_manager` is not on `PATH`, add the user script directory:
|
|
77
71
|
|
|
78
72
|
```bash
|
|
@@ -96,7 +90,8 @@ python3 -m cyclo_manager_cli.cli up
|
|
|
96
90
|
| `cyclo_manager up` | Install/refresh **cyclo_host_agent** (systemd unit, socket dir, sudoers), then `docker compose up -d` for **API + UI**, then `docker compose create --no-recreate` for **Zenoh** and **noVNC** (created but **not started**). Sets **`CYCLO_MANAGER_CONFIG_FILE`** to the bundled config. |
|
|
97
91
|
| `cyclo_manager up --pull` | `docker compose pull` first, then the same as `up`. |
|
|
98
92
|
| `cyclo_manager down` | **Tear down host agent** (stop/disable service, remove unit, sudoers, socket dir), then `docker compose down` for all services in the bundled compose file. |
|
|
99
|
-
| `cyclo_manager update` | `docker compose down` (containers only — **host agent stays installed**), `pip install -U cyclo-manager`, `docker compose up` + create optional services, then **refresh host agent** (unit, socket, sudoers).
|
|
93
|
+
| `cyclo_manager update` | `docker compose down` (containers only — **host agent stays installed**), `pip install -U cyclo-manager`, **`docker compose pull`**, then `docker compose up` + create optional services, then **refresh host agent** (unit, socket, sudoers). |
|
|
94
|
+
| `cyclo_manager update --no-pull` | Same as `update`, but skip image pull (use locally cached images). |
|
|
100
95
|
| `cyclo_manager --help` | Subcommand overview |
|
|
101
96
|
|
|
102
97
|
**`down` vs `update`:** `down` removes the host agent entirely. `update` only stops Docker containers, upgrades the pip package, restarts the stack, and refreshes the host agent — it does **not** call `cyclo_manager down`.
|
|
@@ -144,8 +139,8 @@ Defined in [`cyclo_manager_cli/docker/docker-compose.yml`](cyclo_manager_cli/doc
|
|
|
144
139
|
|
|
145
140
|
| Compose service | Container name | `cyclo_manager up` | Image (example) |
|
|
146
141
|
|-----------------|----------------|--------------------|-----------------|
|
|
147
|
-
| `cyclo_manager` | `cyclo_manager` | **Started** | `robotis/cyclo-manager:0.2.
|
|
148
|
-
| `ui` | `cyclo_manager_ui` | **Started** | `robotis/cyclo-manager-ui:0.2.
|
|
142
|
+
| `cyclo_manager` | `cyclo_manager` | **Started** | `robotis/cyclo-manager:0.2.1` |
|
|
143
|
+
| `ui` | `cyclo_manager_ui` | **Started** | `robotis/cyclo-manager-ui:0.2.1` |
|
|
149
144
|
| `rmw_zenoh` | `zenoh_daemon` | **Created only** | `robotis/zenoh-daemon:latest` |
|
|
150
145
|
| `novnc-server` | `novnc-server` | **Created only** | `robotis/novnc-server:latest` |
|
|
151
146
|
|
|
@@ -177,7 +172,7 @@ robot_container: ai_worker
|
|
|
177
172
|
|
|
178
173
|
sockets:
|
|
179
174
|
ai_worker: "/agents/ai_worker/s6_agent.sock"
|
|
180
|
-
|
|
175
|
+
cyclo_intelligence: "/agents/cyclo_intelligence/s6_agent.sock"
|
|
181
176
|
host_agent: "/agents/host/host_agent.sock"
|
|
182
177
|
```
|
|
183
178
|
|
|
@@ -198,7 +193,7 @@ On the host, sockets typically live under:
|
|
|
198
193
|
```text
|
|
199
194
|
/var/run/robotis/agent_sockets/
|
|
200
195
|
├── ai_worker/s6_agent.sock
|
|
201
|
-
├──
|
|
196
|
+
├── cyclo_intelligence/s6_agent.sock
|
|
202
197
|
└── host/host_agent.sock ← created by cyclo_manager up
|
|
203
198
|
```
|
|
204
199
|
|
|
@@ -53,12 +53,6 @@ From **PyPI**:
|
|
|
53
53
|
pip install cyclo-manager
|
|
54
54
|
```
|
|
55
55
|
|
|
56
|
-
Pre-release versions:
|
|
57
|
-
|
|
58
|
-
```bash
|
|
59
|
-
pip install --pre cyclo-manager==0.2.0.dev0
|
|
60
|
-
```
|
|
61
|
-
|
|
62
56
|
If `cyclo_manager` is not on `PATH`, add the user script directory:
|
|
63
57
|
|
|
64
58
|
```bash
|
|
@@ -82,7 +76,8 @@ python3 -m cyclo_manager_cli.cli up
|
|
|
82
76
|
| `cyclo_manager up` | Install/refresh **cyclo_host_agent** (systemd unit, socket dir, sudoers), then `docker compose up -d` for **API + UI**, then `docker compose create --no-recreate` for **Zenoh** and **noVNC** (created but **not started**). Sets **`CYCLO_MANAGER_CONFIG_FILE`** to the bundled config. |
|
|
83
77
|
| `cyclo_manager up --pull` | `docker compose pull` first, then the same as `up`. |
|
|
84
78
|
| `cyclo_manager down` | **Tear down host agent** (stop/disable service, remove unit, sudoers, socket dir), then `docker compose down` for all services in the bundled compose file. |
|
|
85
|
-
| `cyclo_manager update` | `docker compose down` (containers only — **host agent stays installed**), `pip install -U cyclo-manager`, `docker compose up` + create optional services, then **refresh host agent** (unit, socket, sudoers).
|
|
79
|
+
| `cyclo_manager update` | `docker compose down` (containers only — **host agent stays installed**), `pip install -U cyclo-manager`, **`docker compose pull`**, then `docker compose up` + create optional services, then **refresh host agent** (unit, socket, sudoers). |
|
|
80
|
+
| `cyclo_manager update --no-pull` | Same as `update`, but skip image pull (use locally cached images). |
|
|
86
81
|
| `cyclo_manager --help` | Subcommand overview |
|
|
87
82
|
|
|
88
83
|
**`down` vs `update`:** `down` removes the host agent entirely. `update` only stops Docker containers, upgrades the pip package, restarts the stack, and refreshes the host agent — it does **not** call `cyclo_manager down`.
|
|
@@ -130,8 +125,8 @@ Defined in [`cyclo_manager_cli/docker/docker-compose.yml`](cyclo_manager_cli/doc
|
|
|
130
125
|
|
|
131
126
|
| Compose service | Container name | `cyclo_manager up` | Image (example) |
|
|
132
127
|
|-----------------|----------------|--------------------|-----------------|
|
|
133
|
-
| `cyclo_manager` | `cyclo_manager` | **Started** | `robotis/cyclo-manager:0.2.
|
|
134
|
-
| `ui` | `cyclo_manager_ui` | **Started** | `robotis/cyclo-manager-ui:0.2.
|
|
128
|
+
| `cyclo_manager` | `cyclo_manager` | **Started** | `robotis/cyclo-manager:0.2.1` |
|
|
129
|
+
| `ui` | `cyclo_manager_ui` | **Started** | `robotis/cyclo-manager-ui:0.2.1` |
|
|
135
130
|
| `rmw_zenoh` | `zenoh_daemon` | **Created only** | `robotis/zenoh-daemon:latest` |
|
|
136
131
|
| `novnc-server` | `novnc-server` | **Created only** | `robotis/novnc-server:latest` |
|
|
137
132
|
|
|
@@ -163,7 +158,7 @@ robot_container: ai_worker
|
|
|
163
158
|
|
|
164
159
|
sockets:
|
|
165
160
|
ai_worker: "/agents/ai_worker/s6_agent.sock"
|
|
166
|
-
|
|
161
|
+
cyclo_intelligence: "/agents/cyclo_intelligence/s6_agent.sock"
|
|
167
162
|
host_agent: "/agents/host/host_agent.sock"
|
|
168
163
|
```
|
|
169
164
|
|
|
@@ -184,7 +179,7 @@ On the host, sockets typically live under:
|
|
|
184
179
|
```text
|
|
185
180
|
/var/run/robotis/agent_sockets/
|
|
186
181
|
├── ai_worker/s6_agent.sock
|
|
187
|
-
├──
|
|
182
|
+
├── cyclo_intelligence/s6_agent.sock
|
|
188
183
|
└── host/host_agent.sock ← created by cyclo_manager up
|
|
189
184
|
```
|
|
190
185
|
|
|
@@ -21,10 +21,10 @@
|
|
|
21
21
|
import logging
|
|
22
22
|
from pathlib import Path
|
|
23
23
|
|
|
24
|
-
import uvicorn
|
|
25
|
-
from fastapi import FastAPI
|
|
26
|
-
|
|
27
24
|
from cyclo_host_agent.routers import repos, update
|
|
25
|
+
from cyclo_manager_cli import __version__
|
|
26
|
+
from fastapi import FastAPI
|
|
27
|
+
import uvicorn
|
|
28
28
|
|
|
29
29
|
logging.basicConfig(
|
|
30
30
|
level=logging.INFO,
|
|
@@ -37,7 +37,7 @@ SOCKET_PATH = '/var/run/robotis/agent_sockets/host/host_agent.sock'
|
|
|
37
37
|
app = FastAPI(
|
|
38
38
|
title='cyclo_host_agent',
|
|
39
39
|
description='Host agent for Cyclo Manager: repo management.',
|
|
40
|
-
version=
|
|
40
|
+
version=__version__,
|
|
41
41
|
)
|
|
42
42
|
|
|
43
43
|
app.include_router(repos.router)
|
|
@@ -71,6 +71,14 @@ class RepoStatusResponse(BaseModel):
|
|
|
71
71
|
has_changes: bool
|
|
72
72
|
|
|
73
73
|
|
|
74
|
+
class RepoBranchCheckResponse(BaseModel):
|
|
75
|
+
"""Response for GET /repos/{name}/branch."""
|
|
76
|
+
|
|
77
|
+
name: str
|
|
78
|
+
branch: Optional[str] = None
|
|
79
|
+
allowed: bool
|
|
80
|
+
|
|
81
|
+
|
|
74
82
|
class UpdateRequest(BaseModel):
|
|
75
83
|
"""Request body for POST /repos/{name}/update."""
|
|
76
84
|
|
|
@@ -20,23 +20,23 @@
|
|
|
20
20
|
|
|
21
21
|
import asyncio
|
|
22
22
|
import os
|
|
23
|
-
import re
|
|
24
23
|
from pathlib import Path
|
|
24
|
+
import re
|
|
25
25
|
from typing import Optional
|
|
26
26
|
|
|
27
|
-
from fastapi import APIRouter, HTTPException, status
|
|
28
|
-
|
|
29
27
|
from cyclo_host_agent.models import (
|
|
30
28
|
ContainerScriptResponse,
|
|
31
29
|
FileChange,
|
|
30
|
+
RepoBranchCheckResponse,
|
|
32
31
|
RepoInfo,
|
|
33
32
|
RepoListResponse,
|
|
34
33
|
RepoStatusResponse,
|
|
35
|
-
RepoUpdateStatus,
|
|
36
34
|
RepoUpdatesResponse,
|
|
35
|
+
RepoUpdateStatus,
|
|
37
36
|
UpdateRequest,
|
|
38
37
|
UpdateResponse,
|
|
39
38
|
)
|
|
39
|
+
from fastapi import APIRouter, HTTPException, status
|
|
40
40
|
|
|
41
41
|
router = APIRouter(prefix='/repos', tags=['repos'])
|
|
42
42
|
|
|
@@ -109,12 +109,12 @@ async def _ensure_allowed_branch(repo_path: Path) -> None:
|
|
|
109
109
|
allowed = ', '.join(sorted(ALLOWED_UPDATE_BRANCHES))
|
|
110
110
|
if branch:
|
|
111
111
|
detail = (
|
|
112
|
-
f
|
|
112
|
+
f'Updates are only allowed on branches: {allowed}. '
|
|
113
113
|
f"Current branch is '{branch}'."
|
|
114
114
|
)
|
|
115
115
|
else:
|
|
116
116
|
detail = (
|
|
117
|
-
f
|
|
117
|
+
f'Updates are only allowed on branches: {allowed}. '
|
|
118
118
|
'Could not determine the current branch (detached HEAD?).'
|
|
119
119
|
)
|
|
120
120
|
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=detail)
|
|
@@ -221,7 +221,12 @@ async def _repo_update_status(repo_path: Path) -> Optional[RepoUpdateStatus]:
|
|
|
221
221
|
|
|
222
222
|
latest = await _fetch_latest_tag(remote_url)
|
|
223
223
|
if not latest:
|
|
224
|
-
return RepoUpdateStatus(
|
|
224
|
+
return RepoUpdateStatus(
|
|
225
|
+
name=repo_path.name,
|
|
226
|
+
branch=branch,
|
|
227
|
+
current_version=current,
|
|
228
|
+
has_update=False,
|
|
229
|
+
)
|
|
225
230
|
|
|
226
231
|
return RepoUpdateStatus(
|
|
227
232
|
name=repo_path.name,
|
|
@@ -356,6 +361,17 @@ async def list_repos() -> RepoListResponse:
|
|
|
356
361
|
return RepoListResponse(repos=repos, workspace_path=str(WORKSPACE_PATH))
|
|
357
362
|
|
|
358
363
|
|
|
364
|
+
@router.get('/{name}/branch', response_model=RepoBranchCheckResponse)
|
|
365
|
+
async def get_repo_branch(name: str) -> RepoBranchCheckResponse:
|
|
366
|
+
repo_path = _get_repo(name)
|
|
367
|
+
branch = await _current_branch(repo_path)
|
|
368
|
+
return RepoBranchCheckResponse(
|
|
369
|
+
name=name,
|
|
370
|
+
branch=branch,
|
|
371
|
+
allowed=branch in ALLOWED_UPDATE_BRANCHES,
|
|
372
|
+
)
|
|
373
|
+
|
|
374
|
+
|
|
359
375
|
@router.get('/{name}/status', response_model=RepoStatusResponse)
|
|
360
376
|
async def get_repo_status(name: str) -> RepoStatusResponse:
|
|
361
377
|
repo_path = _get_repo(name)
|
|
@@ -62,6 +62,10 @@ async def start_update() -> dict:
|
|
|
62
62
|
raise HTTPException(status_code=status.HTTP_503_SERVICE_UNAVAILABLE,
|
|
63
63
|
detail='cyclo_manager command not found')
|
|
64
64
|
|
|
65
|
+
if _update_status.get('phase') == 'updating':
|
|
66
|
+
raise HTTPException(status_code=status.HTTP_409_CONFLICT,
|
|
67
|
+
detail='Update already in progress')
|
|
68
|
+
|
|
65
69
|
_update_status = {'phase': 'updating', 'output': '', 'error': ''}
|
|
66
70
|
asyncio.create_task(_run_update(cyclo_exe))
|
|
67
71
|
return {'status': 'update started'}
|
|
@@ -71,5 +75,3 @@ async def start_update() -> dict:
|
|
|
71
75
|
async def get_update_status() -> dict:
|
|
72
76
|
"""Return the current update phase and stored outputs."""
|
|
73
77
|
return _update_status
|
|
74
|
-
|
|
75
|
-
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: cyclo-manager
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.1
|
|
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
|
|
@@ -67,12 +67,6 @@ From **PyPI**:
|
|
|
67
67
|
pip install cyclo-manager
|
|
68
68
|
```
|
|
69
69
|
|
|
70
|
-
Pre-release versions:
|
|
71
|
-
|
|
72
|
-
```bash
|
|
73
|
-
pip install --pre cyclo-manager==0.2.0.dev0
|
|
74
|
-
```
|
|
75
|
-
|
|
76
70
|
If `cyclo_manager` is not on `PATH`, add the user script directory:
|
|
77
71
|
|
|
78
72
|
```bash
|
|
@@ -96,7 +90,8 @@ python3 -m cyclo_manager_cli.cli up
|
|
|
96
90
|
| `cyclo_manager up` | Install/refresh **cyclo_host_agent** (systemd unit, socket dir, sudoers), then `docker compose up -d` for **API + UI**, then `docker compose create --no-recreate` for **Zenoh** and **noVNC** (created but **not started**). Sets **`CYCLO_MANAGER_CONFIG_FILE`** to the bundled config. |
|
|
97
91
|
| `cyclo_manager up --pull` | `docker compose pull` first, then the same as `up`. |
|
|
98
92
|
| `cyclo_manager down` | **Tear down host agent** (stop/disable service, remove unit, sudoers, socket dir), then `docker compose down` for all services in the bundled compose file. |
|
|
99
|
-
| `cyclo_manager update` | `docker compose down` (containers only — **host agent stays installed**), `pip install -U cyclo-manager`, `docker compose up` + create optional services, then **refresh host agent** (unit, socket, sudoers).
|
|
93
|
+
| `cyclo_manager update` | `docker compose down` (containers only — **host agent stays installed**), `pip install -U cyclo-manager`, **`docker compose pull`**, then `docker compose up` + create optional services, then **refresh host agent** (unit, socket, sudoers). |
|
|
94
|
+
| `cyclo_manager update --no-pull` | Same as `update`, but skip image pull (use locally cached images). |
|
|
100
95
|
| `cyclo_manager --help` | Subcommand overview |
|
|
101
96
|
|
|
102
97
|
**`down` vs `update`:** `down` removes the host agent entirely. `update` only stops Docker containers, upgrades the pip package, restarts the stack, and refreshes the host agent — it does **not** call `cyclo_manager down`.
|
|
@@ -144,8 +139,8 @@ Defined in [`cyclo_manager_cli/docker/docker-compose.yml`](cyclo_manager_cli/doc
|
|
|
144
139
|
|
|
145
140
|
| Compose service | Container name | `cyclo_manager up` | Image (example) |
|
|
146
141
|
|-----------------|----------------|--------------------|-----------------|
|
|
147
|
-
| `cyclo_manager` | `cyclo_manager` | **Started** | `robotis/cyclo-manager:0.2.
|
|
148
|
-
| `ui` | `cyclo_manager_ui` | **Started** | `robotis/cyclo-manager-ui:0.2.
|
|
142
|
+
| `cyclo_manager` | `cyclo_manager` | **Started** | `robotis/cyclo-manager:0.2.1` |
|
|
143
|
+
| `ui` | `cyclo_manager_ui` | **Started** | `robotis/cyclo-manager-ui:0.2.1` |
|
|
149
144
|
| `rmw_zenoh` | `zenoh_daemon` | **Created only** | `robotis/zenoh-daemon:latest` |
|
|
150
145
|
| `novnc-server` | `novnc-server` | **Created only** | `robotis/novnc-server:latest` |
|
|
151
146
|
|
|
@@ -177,7 +172,7 @@ robot_container: ai_worker
|
|
|
177
172
|
|
|
178
173
|
sockets:
|
|
179
174
|
ai_worker: "/agents/ai_worker/s6_agent.sock"
|
|
180
|
-
|
|
175
|
+
cyclo_intelligence: "/agents/cyclo_intelligence/s6_agent.sock"
|
|
181
176
|
host_agent: "/agents/host/host_agent.sock"
|
|
182
177
|
```
|
|
183
178
|
|
|
@@ -198,7 +193,7 @@ On the host, sockets typically live under:
|
|
|
198
193
|
```text
|
|
199
194
|
/var/run/robotis/agent_sockets/
|
|
200
195
|
├── ai_worker/s6_agent.sock
|
|
201
|
-
├──
|
|
196
|
+
├── cyclo_intelligence/s6_agent.sock
|
|
202
197
|
└── host/host_agent.sock ← created by cyclo_manager up
|
|
203
198
|
```
|
|
204
199
|
|
|
@@ -95,7 +95,7 @@ def _setup_socket_dir(user: str) -> bool:
|
|
|
95
95
|
check=True,
|
|
96
96
|
capture_output=True,
|
|
97
97
|
)
|
|
98
|
-
print(
|
|
98
|
+
print(' [3/3] Removing stale socket file (if any)...')
|
|
99
99
|
subprocess.run(
|
|
100
100
|
['sudo', 'rm', '-f', HOST_AGENT_SOCKET],
|
|
101
101
|
check=True,
|
|
@@ -109,8 +109,10 @@ def _setup_socket_dir(user: str) -> bool:
|
|
|
109
109
|
|
|
110
110
|
def _install_sudoers(user: str) -> bool:
|
|
111
111
|
"""
|
|
112
|
-
Write
|
|
113
|
-
|
|
112
|
+
Write sudoers rules for cyclo_manager.
|
|
113
|
+
|
|
114
|
+
Grant NOPASSWD for udev operations needed by container.sh
|
|
115
|
+
(cp to /etc/udev/rules.d/, udevadm control/trigger).
|
|
114
116
|
"""
|
|
115
117
|
print(' Installing sudoers rules (cp, udevadm)...')
|
|
116
118
|
sudoers_content = (
|
|
@@ -272,7 +274,10 @@ def _teardown_host_agent() -> None:
|
|
|
272
274
|
steps = [
|
|
273
275
|
(['sudo', 'systemctl', 'stop', f'{HOST_AGENT_SERVICE}.service'], 'stop service'),
|
|
274
276
|
(['sudo', 'systemctl', 'disable', f'{HOST_AGENT_SERVICE}.service'], 'disable service'),
|
|
275
|
-
(
|
|
277
|
+
(
|
|
278
|
+
['sudo', 'rm', '-f', f'/etc/systemd/system/{HOST_AGENT_SERVICE}.service'],
|
|
279
|
+
'remove unit file',
|
|
280
|
+
),
|
|
276
281
|
(['sudo', 'systemctl', 'daemon-reload'], 'daemon-reload'),
|
|
277
282
|
(['sudo', 'rm', '-f', '/etc/sudoers.d/cyclo_manager'], 'remove sudoers'),
|
|
278
283
|
(['sudo', 'rm', '-rf', HOST_AGENT_SOCKET_DIR], 'remove socket dir'),
|
|
@@ -356,10 +361,19 @@ def cmd_update(args: argparse.Namespace) -> int:
|
|
|
356
361
|
print('pip install timed out.', file=sys.stderr)
|
|
357
362
|
return 1
|
|
358
363
|
|
|
364
|
+
if not getattr(args, 'no_pull', False):
|
|
365
|
+
print('Pulling latest images...')
|
|
366
|
+
try:
|
|
367
|
+
subprocess.run([*base, 'pull'], env=env, check=True)
|
|
368
|
+
except subprocess.CalledProcessError as e:
|
|
369
|
+
print(
|
|
370
|
+
f'Warning: docker compose pull failed (exit {e.returncode}); '
|
|
371
|
+
'continuing with cached images.',
|
|
372
|
+
file=sys.stderr,
|
|
373
|
+
)
|
|
374
|
+
|
|
359
375
|
print('Starting containers...')
|
|
360
376
|
try:
|
|
361
|
-
if getattr(args, 'pull', False):
|
|
362
|
-
subprocess.run([*base, 'pull'], env=env, check=True)
|
|
363
377
|
subprocess.run([*base, 'up', '-d', *COMPOSE_SERVICES_UP], env=env, check=True)
|
|
364
378
|
subprocess.run(
|
|
365
379
|
[*base, 'create', '--no-recreate', *COMPOSE_SERVICES_CREATE_ONLY],
|
|
@@ -370,7 +384,9 @@ def cmd_update(args: argparse.Namespace) -> int:
|
|
|
370
384
|
return e.returncode
|
|
371
385
|
|
|
372
386
|
print('Refreshing host agent (unit, socket, sudoers)...')
|
|
373
|
-
_ensure_host_agent()
|
|
387
|
+
if _ensure_host_agent() != 0:
|
|
388
|
+
print('Warning: Failed to refresh host agent service.', file=sys.stderr)
|
|
389
|
+
return 1
|
|
374
390
|
|
|
375
391
|
print('cyclo_manager update completed.')
|
|
376
392
|
return 0
|
|
@@ -400,12 +416,12 @@ def main() -> int:
|
|
|
400
416
|
|
|
401
417
|
update_parser = sub.add_parser(
|
|
402
418
|
'update',
|
|
403
|
-
help='Down containers, pip install -U cyclo-manager, then up again',
|
|
419
|
+
help='Down containers, pip install -U cyclo-manager, pull images, then up again',
|
|
404
420
|
)
|
|
405
421
|
update_parser.add_argument(
|
|
406
|
-
'--pull',
|
|
422
|
+
'--no-pull',
|
|
407
423
|
action='store_true',
|
|
408
|
-
help='
|
|
424
|
+
help='Skip docker compose pull before starting containers (use cached images only)',
|
|
409
425
|
)
|
|
410
426
|
update_parser.set_defaults(func=cmd_update)
|
|
411
427
|
|
{cyclo_manager-0.2.0.dev12 → cyclo_manager-0.2.1}/cyclo_manager_cli/docker/docker-compose.yml
RENAMED
|
@@ -11,7 +11,7 @@ services:
|
|
|
11
11
|
|
|
12
12
|
cyclo_manager:
|
|
13
13
|
container_name: cyclo_manager
|
|
14
|
-
image: robotis/cyclo-manager:0.2.
|
|
14
|
+
image: robotis/cyclo-manager:0.2.1
|
|
15
15
|
restart: always
|
|
16
16
|
network_mode: host
|
|
17
17
|
volumes:
|
|
@@ -27,7 +27,7 @@ services:
|
|
|
27
27
|
|
|
28
28
|
ui:
|
|
29
29
|
container_name: cyclo_manager_ui
|
|
30
|
-
image: robotis/cyclo-manager-ui:0.2.
|
|
30
|
+
image: robotis/cyclo-manager-ui:0.2.1
|
|
31
31
|
restart: always
|
|
32
32
|
network_mode: host
|
|
33
33
|
environment:
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "cyclo-manager"
|
|
7
|
-
version = "0.2.
|
|
7
|
+
version = "0.2.1"
|
|
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
|
{cyclo_manager-0.2.0.dev12 → cyclo_manager-0.2.1}/cyclo_manager.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|