cyclo-manager 1.1.0.dev3__tar.gz → 1.1.0.dev4__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-1.1.0.dev3 → cyclo_manager-1.1.0.dev4}/PKG-INFO +53 -8
- {cyclo_manager-1.1.0.dev3 → cyclo_manager-1.1.0.dev4}/README.md +52 -7
- {cyclo_manager-1.1.0.dev3 → cyclo_manager-1.1.0.dev4}/cyclo_manager.egg-info/PKG-INFO +53 -8
- {cyclo_manager-1.1.0.dev3 → cyclo_manager-1.1.0.dev4}/cyclo_manager_cli/docker/docker-compose.yml +2 -0
- {cyclo_manager-1.1.0.dev3 → cyclo_manager-1.1.0.dev4}/pyproject.toml +1 -1
- {cyclo_manager-1.1.0.dev3 → cyclo_manager-1.1.0.dev4}/cyclo_host_agent/__init__.py +0 -0
- {cyclo_manager-1.1.0.dev3 → cyclo_manager-1.1.0.dev4}/cyclo_host_agent/cpu_usage.py +0 -0
- {cyclo_manager-1.1.0.dev3 → cyclo_manager-1.1.0.dev4}/cyclo_host_agent/main.py +0 -0
- {cyclo_manager-1.1.0.dev3 → cyclo_manager-1.1.0.dev4}/cyclo_host_agent/models.py +0 -0
- {cyclo_manager-1.1.0.dev3 → cyclo_manager-1.1.0.dev4}/cyclo_host_agent/routers/__init__.py +0 -0
- {cyclo_manager-1.1.0.dev3 → cyclo_manager-1.1.0.dev4}/cyclo_host_agent/routers/files.py +0 -0
- {cyclo_manager-1.1.0.dev3 → cyclo_manager-1.1.0.dev4}/cyclo_host_agent/routers/repos.py +0 -0
- {cyclo_manager-1.1.0.dev3 → cyclo_manager-1.1.0.dev4}/cyclo_host_agent/routers/system_stats.py +0 -0
- {cyclo_manager-1.1.0.dev3 → cyclo_manager-1.1.0.dev4}/cyclo_host_agent/routers/update.py +0 -0
- {cyclo_manager-1.1.0.dev3 → cyclo_manager-1.1.0.dev4}/cyclo_manager.egg-info/SOURCES.txt +0 -0
- {cyclo_manager-1.1.0.dev3 → cyclo_manager-1.1.0.dev4}/cyclo_manager.egg-info/dependency_links.txt +0 -0
- {cyclo_manager-1.1.0.dev3 → cyclo_manager-1.1.0.dev4}/cyclo_manager.egg-info/entry_points.txt +0 -0
- {cyclo_manager-1.1.0.dev3 → cyclo_manager-1.1.0.dev4}/cyclo_manager.egg-info/requires.txt +0 -0
- {cyclo_manager-1.1.0.dev3 → cyclo_manager-1.1.0.dev4}/cyclo_manager.egg-info/top_level.txt +0 -0
- {cyclo_manager-1.1.0.dev3 → cyclo_manager-1.1.0.dev4}/cyclo_manager_cli/__init__.py +0 -0
- {cyclo_manager-1.1.0.dev3 → cyclo_manager-1.1.0.dev4}/cyclo_manager_cli/cli.py +0 -0
- {cyclo_manager-1.1.0.dev3 → cyclo_manager-1.1.0.dev4}/cyclo_manager_cli/config/config.yml +0 -0
- {cyclo_manager-1.1.0.dev3 → cyclo_manager-1.1.0.dev4}/setup.cfg +0 -0
- {cyclo_manager-1.1.0.dev3 → cyclo_manager-1.1.0.dev4}/tests/test_cpu_usage.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: cyclo-manager
|
|
3
|
-
Version: 1.1.0.
|
|
3
|
+
Version: 1.1.0.dev4
|
|
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
|
|
@@ -38,6 +38,7 @@ For the full monorepo (API source, UI source, dev compose), see the [repository
|
|
|
38
38
|
- [What `cyclo_manager up` does](#what-cyclo_manager-up-does)
|
|
39
39
|
- [Host agent (`cyclo_host_agent`)](#host-agent-cyclo_host_agent)
|
|
40
40
|
- [Compose services](#compose-services)
|
|
41
|
+
- [Recording storage](#recording-storage)
|
|
41
42
|
- [Configuration](#configuration)
|
|
42
43
|
- [Agent sockets on the host](#agent-sockets-on-the-host)
|
|
43
44
|
- [Environment variables](#environment-variables)
|
|
@@ -134,6 +135,10 @@ The API container reaches it at `/agents/host/host_agent.sock` (see bundled `con
|
|
|
134
135
|
- Update repos on allowed branches (`main`, `jazzy`) using stash or reset workflows.
|
|
135
136
|
- Stop/start a repo's `docker/container.sh` helper during an update when requested by the UI.
|
|
136
137
|
- Run Cyclo Manager package updates from the UI by delegating to `cyclo_manager update`.
|
|
138
|
+
- Provide host CPU/memory/disk statistics and process information. CPU summaries
|
|
139
|
+
share a background sampler's average of the latest three one-second samples.
|
|
140
|
+
- Serve the Files UI's browsing, filename search, upload, text editing, Git diff
|
|
141
|
+
and file/directory management operations under the configured workspace.
|
|
137
142
|
|
|
138
143
|
`cyclo_manager up` installs the `refresh-host-agent` CLI subcommand into sudoers. It is registered as `sys.executable -m cyclo_manager_cli.cli refresh-host-agent` with `SETENV`, so UI-triggered updates can pass the current `PYTHONPATH` to sudo and do not depend on `PATH`. The command is idempotent and refreshes the socket directory, sudoers file, systemd unit, and service state after package upgrades.
|
|
139
144
|
|
|
@@ -145,10 +150,10 @@ Repository scanning and the Files UI use `CYCLO_HOST_AGENT_WORKSPACE` when set.
|
|
|
145
150
|
|
|
146
151
|
Defined in [`cyclo_manager_cli/docker/docker-compose.yml`](cyclo_manager_cli/docker/docker-compose.yml). All services use **`network_mode: host`**.
|
|
147
152
|
|
|
148
|
-
| Compose service | Container name | `cyclo_manager up` | Image
|
|
153
|
+
| Compose service | Container name | `cyclo_manager up` | Image in this checkout |
|
|
149
154
|
|-----------------|----------------|--------------------|-----------------|
|
|
150
|
-
| `cyclo_manager` | `cyclo_manager` | **Started** | `robotis/cyclo-manager:1.0
|
|
151
|
-
| `ui` | `cyclo_manager_ui` | **Started** | `robotis/cyclo-manager-ui:1.0
|
|
155
|
+
| `cyclo_manager` | `cyclo_manager` | **Started** | `robotis/cyclo-manager:1.1.0` |
|
|
156
|
+
| `ui` | `cyclo_manager_ui` | **Started** | `robotis/cyclo-manager-ui:1.1.0` |
|
|
152
157
|
| `rmw_zenoh` | `zenoh_daemon` | **Created only** | `robotis/zenoh-daemon:latest` |
|
|
153
158
|
| `novnc-server` | `novnc-server` | **Created only** | `robotis/novnc-server:latest` |
|
|
154
159
|
|
|
@@ -156,6 +161,27 @@ Start optional containers from the UI or manually, e.g. `docker start zenoh_daem
|
|
|
156
161
|
|
|
157
162
|
---
|
|
158
163
|
|
|
164
|
+
## Recording storage
|
|
165
|
+
|
|
166
|
+
The packaged stack and dev compose both mount:
|
|
167
|
+
|
|
168
|
+
```yaml
|
|
169
|
+
- ${HOME}/cyclo_manager_ros_bags:/cyclo_manager_ros_bags
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
Compose resolves `${HOME}` on the host at invocation time. The API container uses
|
|
173
|
+
`RECORDINGS_DIR=/cyclo_manager_ros_bags`, which is also the server default when the
|
|
174
|
+
variable is absent. The host directory is independent of
|
|
175
|
+
`CYCLO_HOST_AGENT_WORKSPACE`; each recording stores its metadata and MCAP bag under
|
|
176
|
+
its generated ID. Container recreation, `down` and package updates preserve this
|
|
177
|
+
bind-mounted data. Applying a new mount requires container recreation.
|
|
178
|
+
|
|
179
|
+
Recording and playback run in the API container using `rosbag2_py` and the MCAP
|
|
180
|
+
storage plugin included in the manager image. They are not host-agent jobs.
|
|
181
|
+
See [Record & Play](../docs/record-play.md) for capture, repeat playback and stops.
|
|
182
|
+
|
|
183
|
+
---
|
|
184
|
+
|
|
159
185
|
## Configuration
|
|
160
186
|
|
|
161
187
|
The CLI always mounts the **bundled** config into the API container. There is **no** `-c` / `--config` flag on the pip CLI.
|
|
@@ -168,10 +194,13 @@ The API reads it as `CONFIG_FILE=/app/config.yml` inside the container.
|
|
|
168
194
|
|
|
169
195
|
| Key | Description |
|
|
170
196
|
|-----|-------------|
|
|
171
|
-
| **`supported_robot_containers`** |
|
|
197
|
+
| **`supported_robot_containers`** | Containers eligible for System navigation and server-side motion profile detection (e.g. `ai_worker`, `open_manipulator`). Each must be a key in `sockets` and cannot be `host_agent`. |
|
|
172
198
|
| **`sockets`** | Map of logical name → agent **Unix socket path as seen inside the API container** (under `/agents/...`). Include robot/service containers and `host_agent`. |
|
|
173
199
|
|
|
174
|
-
s6 **service names** are
|
|
200
|
+
s6 **service names** are defined in the manager's System/motion profiles, not in
|
|
201
|
+
this config. Motion detection checks the existing individual status endpoints for
|
|
202
|
+
`ai_worker_bringup` and `open_manipulator_bringup`, then reads `/run/robot_type`
|
|
203
|
+
inside the selected container through Docker. This needs no new s6-agent endpoint.
|
|
175
204
|
|
|
176
205
|
### Example (bundled default)
|
|
177
206
|
|
|
@@ -198,6 +227,7 @@ On the host, sockets typically live under:
|
|
|
198
227
|
```text
|
|
199
228
|
/var/run/robotis/agent_sockets/
|
|
200
229
|
├── ai_worker/s6_agent.sock
|
|
230
|
+
├── open_manipulator/s6_agent.sock
|
|
201
231
|
├── cyclo_intelligence/s6_agent.sock
|
|
202
232
|
└── host/host_agent.sock ← created by cyclo_manager up
|
|
203
233
|
```
|
|
@@ -220,7 +250,11 @@ So `/agents/ai_worker/s6_agent.sock` in config corresponds to the host path abov
|
|
|
220
250
|
| **`CYCLO_HOST_AGENT_WORKSPACE`** | User or CLI-generated systemd unit | Workspace scanned by `cyclo_host_agent` for managed git repositories and used as the Files UI/API root |
|
|
221
251
|
| **`HOSTNAME`** | CLI (default: machine hostname) | Passed to API as `HOST_HOSTNAME` |
|
|
222
252
|
| **`CONFIG_FILE`** | Compose (`/app/config.yml`) | Path inside the API container |
|
|
223
|
-
| **`
|
|
253
|
+
| **`HOME`** | Host environment used by Compose | Selects the host `${HOME}/cyclo_manager_ros_bags` bind-mount directory |
|
|
254
|
+
| **`RECORDINGS_DIR`** | Compose (`/cyclo_manager_ros_bags`) | Server-side recording directory inside the API container; same default without the variable |
|
|
255
|
+
| **`ROS_DOMAIN_ID`** | Manager image shell startup (`30`); not set by CLI | Must match the robot; the manager image configures it in `/root/.bashrc`, which the API startup sources |
|
|
256
|
+
| **`RMW_IMPLEMENTATION`** | Manager image shell startup (`rmw_zenoh_cpp`) | ROS middleware used by the manager; requires a reachable Zenoh router |
|
|
257
|
+
| **`NEXT_PUBLIC_API_URL`** | UI dev/build environment | Browser API address; production bundles embed it at build time, so a compose runtime value does not reconfigure a prebuilt UI |
|
|
224
258
|
|
|
225
259
|
---
|
|
226
260
|
|
|
@@ -234,6 +268,12 @@ With `network_mode: host` and default ports:
|
|
|
234
268
|
| cyclo_manager API | http://127.0.0.1:8081 |
|
|
235
269
|
| OpenAPI (Swagger) | http://127.0.0.1:8081/docs |
|
|
236
270
|
|
|
271
|
+
These loopback URLs apply on the robot host. From another device, use the robot's
|
|
272
|
+
hostname/IP and a browser-reachable API URL. Both compose files contain a UI
|
|
273
|
+
runtime value of `http://127.0.0.1:8081`; it takes effect in development, while a
|
|
274
|
+
production bundle uses its build-time value or hostname fallback. See the
|
|
275
|
+
[UI API address guide](../cyclo_manager_ui/README_UI.md#api-address).
|
|
276
|
+
|
|
237
277
|
---
|
|
238
278
|
|
|
239
279
|
## Custom config and development
|
|
@@ -247,6 +287,11 @@ For development (local API/UI source, custom `config.yml`, hot reload):
|
|
|
247
287
|
docker compose -f docker-compose.dev.yml up
|
|
248
288
|
```
|
|
249
289
|
|
|
290
|
+
The dev compose command starts all defined services and does not install the host
|
|
291
|
+
agent. API/UI source mounts do not update the Python code used by the separately
|
|
292
|
+
installed `cyclo_host_agent.service`; install the updated CLI package and refresh
|
|
293
|
+
that service when testing host-agent changes.
|
|
294
|
+
|
|
250
295
|
See the [root README](../README.md#development).
|
|
251
296
|
|
|
252
297
|
---
|
|
@@ -259,7 +304,7 @@ Python dependencies declared in [`pyproject.toml`](pyproject.toml):
|
|
|
259
304
|
|---------|---------|
|
|
260
305
|
| **fastapi** | `cyclo_host_agent` HTTP API |
|
|
261
306
|
| **uvicorn** | `cyclo_host_agent` server |
|
|
262
|
-
| **psutil** |
|
|
307
|
+
| **psutil** | Host CPU sampler, memory/disk statistics and process inspection |
|
|
263
308
|
|
|
264
309
|
The **`cyclo_manager`** CLI itself uses only the Python standard library plus **`subprocess`** calls to **`docker compose`**, **`pip`**, **`systemctl`**, and **`sudo`**.
|
|
265
310
|
|
|
@@ -24,6 +24,7 @@ For the full monorepo (API source, UI source, dev compose), see the [repository
|
|
|
24
24
|
- [What `cyclo_manager up` does](#what-cyclo_manager-up-does)
|
|
25
25
|
- [Host agent (`cyclo_host_agent`)](#host-agent-cyclo_host_agent)
|
|
26
26
|
- [Compose services](#compose-services)
|
|
27
|
+
- [Recording storage](#recording-storage)
|
|
27
28
|
- [Configuration](#configuration)
|
|
28
29
|
- [Agent sockets on the host](#agent-sockets-on-the-host)
|
|
29
30
|
- [Environment variables](#environment-variables)
|
|
@@ -120,6 +121,10 @@ The API container reaches it at `/agents/host/host_agent.sock` (see bundled `con
|
|
|
120
121
|
- Update repos on allowed branches (`main`, `jazzy`) using stash or reset workflows.
|
|
121
122
|
- Stop/start a repo's `docker/container.sh` helper during an update when requested by the UI.
|
|
122
123
|
- Run Cyclo Manager package updates from the UI by delegating to `cyclo_manager update`.
|
|
124
|
+
- Provide host CPU/memory/disk statistics and process information. CPU summaries
|
|
125
|
+
share a background sampler's average of the latest three one-second samples.
|
|
126
|
+
- Serve the Files UI's browsing, filename search, upload, text editing, Git diff
|
|
127
|
+
and file/directory management operations under the configured workspace.
|
|
123
128
|
|
|
124
129
|
`cyclo_manager up` installs the `refresh-host-agent` CLI subcommand into sudoers. It is registered as `sys.executable -m cyclo_manager_cli.cli refresh-host-agent` with `SETENV`, so UI-triggered updates can pass the current `PYTHONPATH` to sudo and do not depend on `PATH`. The command is idempotent and refreshes the socket directory, sudoers file, systemd unit, and service state after package upgrades.
|
|
125
130
|
|
|
@@ -131,10 +136,10 @@ Repository scanning and the Files UI use `CYCLO_HOST_AGENT_WORKSPACE` when set.
|
|
|
131
136
|
|
|
132
137
|
Defined in [`cyclo_manager_cli/docker/docker-compose.yml`](cyclo_manager_cli/docker/docker-compose.yml). All services use **`network_mode: host`**.
|
|
133
138
|
|
|
134
|
-
| Compose service | Container name | `cyclo_manager up` | Image
|
|
139
|
+
| Compose service | Container name | `cyclo_manager up` | Image in this checkout |
|
|
135
140
|
|-----------------|----------------|--------------------|-----------------|
|
|
136
|
-
| `cyclo_manager` | `cyclo_manager` | **Started** | `robotis/cyclo-manager:1.0
|
|
137
|
-
| `ui` | `cyclo_manager_ui` | **Started** | `robotis/cyclo-manager-ui:1.0
|
|
141
|
+
| `cyclo_manager` | `cyclo_manager` | **Started** | `robotis/cyclo-manager:1.1.0` |
|
|
142
|
+
| `ui` | `cyclo_manager_ui` | **Started** | `robotis/cyclo-manager-ui:1.1.0` |
|
|
138
143
|
| `rmw_zenoh` | `zenoh_daemon` | **Created only** | `robotis/zenoh-daemon:latest` |
|
|
139
144
|
| `novnc-server` | `novnc-server` | **Created only** | `robotis/novnc-server:latest` |
|
|
140
145
|
|
|
@@ -142,6 +147,27 @@ Start optional containers from the UI or manually, e.g. `docker start zenoh_daem
|
|
|
142
147
|
|
|
143
148
|
---
|
|
144
149
|
|
|
150
|
+
## Recording storage
|
|
151
|
+
|
|
152
|
+
The packaged stack and dev compose both mount:
|
|
153
|
+
|
|
154
|
+
```yaml
|
|
155
|
+
- ${HOME}/cyclo_manager_ros_bags:/cyclo_manager_ros_bags
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
Compose resolves `${HOME}` on the host at invocation time. The API container uses
|
|
159
|
+
`RECORDINGS_DIR=/cyclo_manager_ros_bags`, which is also the server default when the
|
|
160
|
+
variable is absent. The host directory is independent of
|
|
161
|
+
`CYCLO_HOST_AGENT_WORKSPACE`; each recording stores its metadata and MCAP bag under
|
|
162
|
+
its generated ID. Container recreation, `down` and package updates preserve this
|
|
163
|
+
bind-mounted data. Applying a new mount requires container recreation.
|
|
164
|
+
|
|
165
|
+
Recording and playback run in the API container using `rosbag2_py` and the MCAP
|
|
166
|
+
storage plugin included in the manager image. They are not host-agent jobs.
|
|
167
|
+
See [Record & Play](../docs/record-play.md) for capture, repeat playback and stops.
|
|
168
|
+
|
|
169
|
+
---
|
|
170
|
+
|
|
145
171
|
## Configuration
|
|
146
172
|
|
|
147
173
|
The CLI always mounts the **bundled** config into the API container. There is **no** `-c` / `--config` flag on the pip CLI.
|
|
@@ -154,10 +180,13 @@ The API reads it as `CONFIG_FILE=/app/config.yml` inside the container.
|
|
|
154
180
|
|
|
155
181
|
| Key | Description |
|
|
156
182
|
|-----|-------------|
|
|
157
|
-
| **`supported_robot_containers`** |
|
|
183
|
+
| **`supported_robot_containers`** | Containers eligible for System navigation and server-side motion profile detection (e.g. `ai_worker`, `open_manipulator`). Each must be a key in `sockets` and cannot be `host_agent`. |
|
|
158
184
|
| **`sockets`** | Map of logical name → agent **Unix socket path as seen inside the API container** (under `/agents/...`). Include robot/service containers and `host_agent`. |
|
|
159
185
|
|
|
160
|
-
s6 **service names** are
|
|
186
|
+
s6 **service names** are defined in the manager's System/motion profiles, not in
|
|
187
|
+
this config. Motion detection checks the existing individual status endpoints for
|
|
188
|
+
`ai_worker_bringup` and `open_manipulator_bringup`, then reads `/run/robot_type`
|
|
189
|
+
inside the selected container through Docker. This needs no new s6-agent endpoint.
|
|
161
190
|
|
|
162
191
|
### Example (bundled default)
|
|
163
192
|
|
|
@@ -184,6 +213,7 @@ On the host, sockets typically live under:
|
|
|
184
213
|
```text
|
|
185
214
|
/var/run/robotis/agent_sockets/
|
|
186
215
|
├── ai_worker/s6_agent.sock
|
|
216
|
+
├── open_manipulator/s6_agent.sock
|
|
187
217
|
├── cyclo_intelligence/s6_agent.sock
|
|
188
218
|
└── host/host_agent.sock ← created by cyclo_manager up
|
|
189
219
|
```
|
|
@@ -206,7 +236,11 @@ So `/agents/ai_worker/s6_agent.sock` in config corresponds to the host path abov
|
|
|
206
236
|
| **`CYCLO_HOST_AGENT_WORKSPACE`** | User or CLI-generated systemd unit | Workspace scanned by `cyclo_host_agent` for managed git repositories and used as the Files UI/API root |
|
|
207
237
|
| **`HOSTNAME`** | CLI (default: machine hostname) | Passed to API as `HOST_HOSTNAME` |
|
|
208
238
|
| **`CONFIG_FILE`** | Compose (`/app/config.yml`) | Path inside the API container |
|
|
209
|
-
| **`
|
|
239
|
+
| **`HOME`** | Host environment used by Compose | Selects the host `${HOME}/cyclo_manager_ros_bags` bind-mount directory |
|
|
240
|
+
| **`RECORDINGS_DIR`** | Compose (`/cyclo_manager_ros_bags`) | Server-side recording directory inside the API container; same default without the variable |
|
|
241
|
+
| **`ROS_DOMAIN_ID`** | Manager image shell startup (`30`); not set by CLI | Must match the robot; the manager image configures it in `/root/.bashrc`, which the API startup sources |
|
|
242
|
+
| **`RMW_IMPLEMENTATION`** | Manager image shell startup (`rmw_zenoh_cpp`) | ROS middleware used by the manager; requires a reachable Zenoh router |
|
|
243
|
+
| **`NEXT_PUBLIC_API_URL`** | UI dev/build environment | Browser API address; production bundles embed it at build time, so a compose runtime value does not reconfigure a prebuilt UI |
|
|
210
244
|
|
|
211
245
|
---
|
|
212
246
|
|
|
@@ -220,6 +254,12 @@ With `network_mode: host` and default ports:
|
|
|
220
254
|
| cyclo_manager API | http://127.0.0.1:8081 |
|
|
221
255
|
| OpenAPI (Swagger) | http://127.0.0.1:8081/docs |
|
|
222
256
|
|
|
257
|
+
These loopback URLs apply on the robot host. From another device, use the robot's
|
|
258
|
+
hostname/IP and a browser-reachable API URL. Both compose files contain a UI
|
|
259
|
+
runtime value of `http://127.0.0.1:8081`; it takes effect in development, while a
|
|
260
|
+
production bundle uses its build-time value or hostname fallback. See the
|
|
261
|
+
[UI API address guide](../cyclo_manager_ui/README_UI.md#api-address).
|
|
262
|
+
|
|
223
263
|
---
|
|
224
264
|
|
|
225
265
|
## Custom config and development
|
|
@@ -233,6 +273,11 @@ For development (local API/UI source, custom `config.yml`, hot reload):
|
|
|
233
273
|
docker compose -f docker-compose.dev.yml up
|
|
234
274
|
```
|
|
235
275
|
|
|
276
|
+
The dev compose command starts all defined services and does not install the host
|
|
277
|
+
agent. API/UI source mounts do not update the Python code used by the separately
|
|
278
|
+
installed `cyclo_host_agent.service`; install the updated CLI package and refresh
|
|
279
|
+
that service when testing host-agent changes.
|
|
280
|
+
|
|
236
281
|
See the [root README](../README.md#development).
|
|
237
282
|
|
|
238
283
|
---
|
|
@@ -245,7 +290,7 @@ Python dependencies declared in [`pyproject.toml`](pyproject.toml):
|
|
|
245
290
|
|---------|---------|
|
|
246
291
|
| **fastapi** | `cyclo_host_agent` HTTP API |
|
|
247
292
|
| **uvicorn** | `cyclo_host_agent` server |
|
|
248
|
-
| **psutil** |
|
|
293
|
+
| **psutil** | Host CPU sampler, memory/disk statistics and process inspection |
|
|
249
294
|
|
|
250
295
|
The **`cyclo_manager`** CLI itself uses only the Python standard library plus **`subprocess`** calls to **`docker compose`**, **`pip`**, **`systemctl`**, and **`sudo`**.
|
|
251
296
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: cyclo-manager
|
|
3
|
-
Version: 1.1.0.
|
|
3
|
+
Version: 1.1.0.dev4
|
|
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
|
|
@@ -38,6 +38,7 @@ For the full monorepo (API source, UI source, dev compose), see the [repository
|
|
|
38
38
|
- [What `cyclo_manager up` does](#what-cyclo_manager-up-does)
|
|
39
39
|
- [Host agent (`cyclo_host_agent`)](#host-agent-cyclo_host_agent)
|
|
40
40
|
- [Compose services](#compose-services)
|
|
41
|
+
- [Recording storage](#recording-storage)
|
|
41
42
|
- [Configuration](#configuration)
|
|
42
43
|
- [Agent sockets on the host](#agent-sockets-on-the-host)
|
|
43
44
|
- [Environment variables](#environment-variables)
|
|
@@ -134,6 +135,10 @@ The API container reaches it at `/agents/host/host_agent.sock` (see bundled `con
|
|
|
134
135
|
- Update repos on allowed branches (`main`, `jazzy`) using stash or reset workflows.
|
|
135
136
|
- Stop/start a repo's `docker/container.sh` helper during an update when requested by the UI.
|
|
136
137
|
- Run Cyclo Manager package updates from the UI by delegating to `cyclo_manager update`.
|
|
138
|
+
- Provide host CPU/memory/disk statistics and process information. CPU summaries
|
|
139
|
+
share a background sampler's average of the latest three one-second samples.
|
|
140
|
+
- Serve the Files UI's browsing, filename search, upload, text editing, Git diff
|
|
141
|
+
and file/directory management operations under the configured workspace.
|
|
137
142
|
|
|
138
143
|
`cyclo_manager up` installs the `refresh-host-agent` CLI subcommand into sudoers. It is registered as `sys.executable -m cyclo_manager_cli.cli refresh-host-agent` with `SETENV`, so UI-triggered updates can pass the current `PYTHONPATH` to sudo and do not depend on `PATH`. The command is idempotent and refreshes the socket directory, sudoers file, systemd unit, and service state after package upgrades.
|
|
139
144
|
|
|
@@ -145,10 +150,10 @@ Repository scanning and the Files UI use `CYCLO_HOST_AGENT_WORKSPACE` when set.
|
|
|
145
150
|
|
|
146
151
|
Defined in [`cyclo_manager_cli/docker/docker-compose.yml`](cyclo_manager_cli/docker/docker-compose.yml). All services use **`network_mode: host`**.
|
|
147
152
|
|
|
148
|
-
| Compose service | Container name | `cyclo_manager up` | Image
|
|
153
|
+
| Compose service | Container name | `cyclo_manager up` | Image in this checkout |
|
|
149
154
|
|-----------------|----------------|--------------------|-----------------|
|
|
150
|
-
| `cyclo_manager` | `cyclo_manager` | **Started** | `robotis/cyclo-manager:1.0
|
|
151
|
-
| `ui` | `cyclo_manager_ui` | **Started** | `robotis/cyclo-manager-ui:1.0
|
|
155
|
+
| `cyclo_manager` | `cyclo_manager` | **Started** | `robotis/cyclo-manager:1.1.0` |
|
|
156
|
+
| `ui` | `cyclo_manager_ui` | **Started** | `robotis/cyclo-manager-ui:1.1.0` |
|
|
152
157
|
| `rmw_zenoh` | `zenoh_daemon` | **Created only** | `robotis/zenoh-daemon:latest` |
|
|
153
158
|
| `novnc-server` | `novnc-server` | **Created only** | `robotis/novnc-server:latest` |
|
|
154
159
|
|
|
@@ -156,6 +161,27 @@ Start optional containers from the UI or manually, e.g. `docker start zenoh_daem
|
|
|
156
161
|
|
|
157
162
|
---
|
|
158
163
|
|
|
164
|
+
## Recording storage
|
|
165
|
+
|
|
166
|
+
The packaged stack and dev compose both mount:
|
|
167
|
+
|
|
168
|
+
```yaml
|
|
169
|
+
- ${HOME}/cyclo_manager_ros_bags:/cyclo_manager_ros_bags
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
Compose resolves `${HOME}` on the host at invocation time. The API container uses
|
|
173
|
+
`RECORDINGS_DIR=/cyclo_manager_ros_bags`, which is also the server default when the
|
|
174
|
+
variable is absent. The host directory is independent of
|
|
175
|
+
`CYCLO_HOST_AGENT_WORKSPACE`; each recording stores its metadata and MCAP bag under
|
|
176
|
+
its generated ID. Container recreation, `down` and package updates preserve this
|
|
177
|
+
bind-mounted data. Applying a new mount requires container recreation.
|
|
178
|
+
|
|
179
|
+
Recording and playback run in the API container using `rosbag2_py` and the MCAP
|
|
180
|
+
storage plugin included in the manager image. They are not host-agent jobs.
|
|
181
|
+
See [Record & Play](../docs/record-play.md) for capture, repeat playback and stops.
|
|
182
|
+
|
|
183
|
+
---
|
|
184
|
+
|
|
159
185
|
## Configuration
|
|
160
186
|
|
|
161
187
|
The CLI always mounts the **bundled** config into the API container. There is **no** `-c` / `--config` flag on the pip CLI.
|
|
@@ -168,10 +194,13 @@ The API reads it as `CONFIG_FILE=/app/config.yml` inside the container.
|
|
|
168
194
|
|
|
169
195
|
| Key | Description |
|
|
170
196
|
|-----|-------------|
|
|
171
|
-
| **`supported_robot_containers`** |
|
|
197
|
+
| **`supported_robot_containers`** | Containers eligible for System navigation and server-side motion profile detection (e.g. `ai_worker`, `open_manipulator`). Each must be a key in `sockets` and cannot be `host_agent`. |
|
|
172
198
|
| **`sockets`** | Map of logical name → agent **Unix socket path as seen inside the API container** (under `/agents/...`). Include robot/service containers and `host_agent`. |
|
|
173
199
|
|
|
174
|
-
s6 **service names** are
|
|
200
|
+
s6 **service names** are defined in the manager's System/motion profiles, not in
|
|
201
|
+
this config. Motion detection checks the existing individual status endpoints for
|
|
202
|
+
`ai_worker_bringup` and `open_manipulator_bringup`, then reads `/run/robot_type`
|
|
203
|
+
inside the selected container through Docker. This needs no new s6-agent endpoint.
|
|
175
204
|
|
|
176
205
|
### Example (bundled default)
|
|
177
206
|
|
|
@@ -198,6 +227,7 @@ On the host, sockets typically live under:
|
|
|
198
227
|
```text
|
|
199
228
|
/var/run/robotis/agent_sockets/
|
|
200
229
|
├── ai_worker/s6_agent.sock
|
|
230
|
+
├── open_manipulator/s6_agent.sock
|
|
201
231
|
├── cyclo_intelligence/s6_agent.sock
|
|
202
232
|
└── host/host_agent.sock ← created by cyclo_manager up
|
|
203
233
|
```
|
|
@@ -220,7 +250,11 @@ So `/agents/ai_worker/s6_agent.sock` in config corresponds to the host path abov
|
|
|
220
250
|
| **`CYCLO_HOST_AGENT_WORKSPACE`** | User or CLI-generated systemd unit | Workspace scanned by `cyclo_host_agent` for managed git repositories and used as the Files UI/API root |
|
|
221
251
|
| **`HOSTNAME`** | CLI (default: machine hostname) | Passed to API as `HOST_HOSTNAME` |
|
|
222
252
|
| **`CONFIG_FILE`** | Compose (`/app/config.yml`) | Path inside the API container |
|
|
223
|
-
| **`
|
|
253
|
+
| **`HOME`** | Host environment used by Compose | Selects the host `${HOME}/cyclo_manager_ros_bags` bind-mount directory |
|
|
254
|
+
| **`RECORDINGS_DIR`** | Compose (`/cyclo_manager_ros_bags`) | Server-side recording directory inside the API container; same default without the variable |
|
|
255
|
+
| **`ROS_DOMAIN_ID`** | Manager image shell startup (`30`); not set by CLI | Must match the robot; the manager image configures it in `/root/.bashrc`, which the API startup sources |
|
|
256
|
+
| **`RMW_IMPLEMENTATION`** | Manager image shell startup (`rmw_zenoh_cpp`) | ROS middleware used by the manager; requires a reachable Zenoh router |
|
|
257
|
+
| **`NEXT_PUBLIC_API_URL`** | UI dev/build environment | Browser API address; production bundles embed it at build time, so a compose runtime value does not reconfigure a prebuilt UI |
|
|
224
258
|
|
|
225
259
|
---
|
|
226
260
|
|
|
@@ -234,6 +268,12 @@ With `network_mode: host` and default ports:
|
|
|
234
268
|
| cyclo_manager API | http://127.0.0.1:8081 |
|
|
235
269
|
| OpenAPI (Swagger) | http://127.0.0.1:8081/docs |
|
|
236
270
|
|
|
271
|
+
These loopback URLs apply on the robot host. From another device, use the robot's
|
|
272
|
+
hostname/IP and a browser-reachable API URL. Both compose files contain a UI
|
|
273
|
+
runtime value of `http://127.0.0.1:8081`; it takes effect in development, while a
|
|
274
|
+
production bundle uses its build-time value or hostname fallback. See the
|
|
275
|
+
[UI API address guide](../cyclo_manager_ui/README_UI.md#api-address).
|
|
276
|
+
|
|
237
277
|
---
|
|
238
278
|
|
|
239
279
|
## Custom config and development
|
|
@@ -247,6 +287,11 @@ For development (local API/UI source, custom `config.yml`, hot reload):
|
|
|
247
287
|
docker compose -f docker-compose.dev.yml up
|
|
248
288
|
```
|
|
249
289
|
|
|
290
|
+
The dev compose command starts all defined services and does not install the host
|
|
291
|
+
agent. API/UI source mounts do not update the Python code used by the separately
|
|
292
|
+
installed `cyclo_host_agent.service`; install the updated CLI package and refresh
|
|
293
|
+
that service when testing host-agent changes.
|
|
294
|
+
|
|
250
295
|
See the [root README](../README.md#development).
|
|
251
296
|
|
|
252
297
|
---
|
|
@@ -259,7 +304,7 @@ Python dependencies declared in [`pyproject.toml`](pyproject.toml):
|
|
|
259
304
|
|---------|---------|
|
|
260
305
|
| **fastapi** | `cyclo_host_agent` HTTP API |
|
|
261
306
|
| **uvicorn** | `cyclo_host_agent` server |
|
|
262
|
-
| **psutil** |
|
|
307
|
+
| **psutil** | Host CPU sampler, memory/disk statistics and process inspection |
|
|
263
308
|
|
|
264
309
|
The **`cyclo_manager`** CLI itself uses only the Python standard library plus **`subprocess`** calls to **`docker compose`**, **`pip`**, **`systemctl`**, and **`sudo`**.
|
|
265
310
|
|
{cyclo_manager-1.1.0.dev3 → cyclo_manager-1.1.0.dev4}/cyclo_manager_cli/docker/docker-compose.yml
RENAMED
|
@@ -21,8 +21,10 @@ services:
|
|
|
21
21
|
- ${CYCLO_MANAGER_CONFIG_FILE}:/app/config.yml # For hot-reload on config changes
|
|
22
22
|
- /var/run/docker.sock:/var/run/docker.sock # For Docker API access
|
|
23
23
|
- /:/host_root:ro # For host disk usage and OS info
|
|
24
|
+
- ${HOME}/cyclo_manager_ros_bags:/cyclo_manager_ros_bags
|
|
24
25
|
environment:
|
|
25
26
|
- CONFIG_FILE=/app/config.yml
|
|
27
|
+
- RECORDINGS_DIR=/cyclo_manager_ros_bags
|
|
26
28
|
- HOST_HOSTNAME=${HOSTNAME}
|
|
27
29
|
|
|
28
30
|
ui:
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "cyclo-manager"
|
|
7
|
-
version = "1.1.0.
|
|
7
|
+
version = "1.1.0.dev4"
|
|
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
|
{cyclo_manager-1.1.0.dev3 → cyclo_manager-1.1.0.dev4}/cyclo_host_agent/routers/system_stats.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{cyclo_manager-1.1.0.dev3 → cyclo_manager-1.1.0.dev4}/cyclo_manager.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
{cyclo_manager-1.1.0.dev3 → cyclo_manager-1.1.0.dev4}/cyclo_manager.egg-info/entry_points.txt
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
|