This release is a pre-release and may not be stable for production use.
cyclo_manager CLI
PyPI package: cyclo-manager
Console commands: cyclo_manager (underscore), cyclo-manager (hyphen)
Host agent: cyclo_host_agent (installed by the package, run via systemd)
This package is the pip-installable launcher for the cyclo_manager stack on a robot host. It:
- Runs
docker composeagainst a bundledcyclo_manager_cli/docker/docker-compose.ymlto start the API and web UI containers. - Installs and maintains
cyclo_host_agentas a systemd service for host-level operations (git repo updates,cyclo_managerpackage update from the UI). - Can
pip install -Uitself and bring the Docker stack back up.
Implementation: cyclo_manager_cli/cli.py, cyclo_host_agent/.
For the full monorepo (API source, UI source, dev compose), see the repository root README.
Table of contents
- Prerequisites
- Install
- Commands
- What
cyclo_manager updoes - Host agent (
cyclo_host_agent) - Compose services
- Configuration
- Agent sockets on the host
- Environment variables
- URLs (packaged stack)
- Custom config and development
- Dependencies
- License
Prerequisites
- Docker with Compose v2 (
docker compose— the legacydocker-composebinary alone is not enough) - Python 3.10+
sudo— required on normal-user hosts to install the host agent systemd unit, socket directory permissions, and sudoers rules- For
cyclo_manager update:piporpip3onPATH - Root shell handling — root is rejected when a normal login user exists. On root-only devices, the host agent is installed as root.
- Agent sockets on the host under
/var/run/robotis/agent_sockets/(robot containers and host agent). The bundled Compose file bind-mounts this tree into the API container as/agents/.
Install
From PyPI:
pip install cyclo-manager
If cyclo_manager is not on PATH, add the user script directory:
export PATH="$HOME/.local/bin:$PATH"
cyclo_manager up
If the entry point is missing:
python3 -m cyclo_manager_cli.cli --help
python3 -m cyclo_manager_cli.cli up
Commands
| Command | Behavior |
|---|---|
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. |
cyclo_manager up --pull |
docker compose pull first, then the same as up. |
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. |
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). |
cyclo_manager update --no-pull |
Same as update, but skip image pull (use locally cached images). |
cyclo_manager --help |
Subcommand overview |
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.
What cyclo_manager up does
Three phases:
[1/3] Setting up host agent → systemd unit, socket ownership, sudoers
[2/3] Starting containers → cyclo_manager (API) + ui
[3/3] Creating (not starting) → zenoh_daemon + novnc-server
Open http://127.0.0.1:3000 (UI) and http://127.0.0.1:8081/docs (API).
Host agent (cyclo_host_agent)
The pip package installs a small FastAPI server that listens on a Unix domain socket on the host:
| Item | Path |
|---|---|
| Socket | /var/run/robotis/agent_sockets/host/host_agent.sock |
| systemd unit | cyclo_host_agent.service |
| sudoers | /etc/sudoers.d/cyclo_manager (cp, udevadm for container setup scripts; skipped on root-only devices) |
The API container reaches it at /agents/host/host_agent.sock (see bundled config.yml).
Responsibilities:
- List and update
~/ROBOTIS-GIT/*git repositories (Version Management in the UI) - Run
cyclo_manager updatewhen triggered from the UI (POST /host/update)
cyclo_manager up and cyclo_manager update both call _ensure_host_agent(), which is idempotent — safe to run after upgrades or user changes.
Repository scanning uses CYCLO_HOST_AGENT_WORKSPACE when set. Otherwise it uses the service user's home directory, except root-only devices with /data/docker, where /data/docker is used automatically.
Compose services
Defined in cyclo_manager_cli/docker/docker-compose.yml. All services use network_mode: host.
| Compose service | Container name | cyclo_manager up |
Image (example) |
|---|---|---|---|
cyclo_manager |
cyclo_manager |
Started | robotis/cyclo-manager:1.0.0 |
ui |
cyclo_manager_ui |
Started | robotis/cyclo-manager-ui:1.0.0 |
rmw_zenoh |
zenoh_daemon |
Created only | robotis/zenoh-daemon:latest |
novnc-server |
novnc-server |
Created only | robotis/novnc-server:latest |
Start optional containers from the UI or manually, e.g. docker start zenoh_daemon.
Configuration
The CLI always mounts the bundled config into the API container. There is no -c / --config flag on the pip CLI.
Bundled path: cyclo_manager_cli/config/config.yml
The API reads it as CONFIG_FILE=/app/config.yml inside the container.
Schema
| Key | Description |
|---|---|
supported_robot_containers |
Robot Docker container names that can open the System page (e.g. ai_worker, open_manipulator). Each must be a key in sockets and cannot be host_agent. |
sockets |
Map of logical name → agent Unix socket path as seen inside the API container (under /agents/...). Include robot/service containers and host_agent. |
s6 service names are not listed in config; each in-container agent reports them at runtime.
Example (bundled default)
supported_robot_containers:
- ai_worker
- open_manipulator
sockets:
ai_worker: "/agents/ai_worker/s6_agent.sock"
open_manipulator: "/agents/open_manipulator/s6_agent.sock"
cyclo_intelligence: "/agents/cyclo_intelligence/s6_agent.sock"
host_agent: "/agents/host/host_agent.sock"
To use a different config layout, mounts, or local source builds, use the repository’s docker-compose.dev.yml — see Custom config and development.
Agent sockets on the host
On the host, sockets typically live under:
/var/run/robotis/agent_sockets/
├── ai_worker/s6_agent.sock
├── cyclo_intelligence/s6_agent.sock
└── host/host_agent.sock ← created by cyclo_manager up
The bundled compose file mounts the parent directory:
- /var/run/robotis/agent_sockets:/agents
So /agents/ai_worker/s6_agent.sock in config corresponds to the host path above.
Environment variables
| Variable | Set by | Purpose |
|---|---|---|
CYCLO_MANAGER_CONFIG_FILE |
CLI (up, down, update) |
Absolute path to bundled config.yml on the host; mounted into the API container |
HOSTNAME |
CLI (default: machine hostname) | Passed to API as HOST_HOSTNAME |
CONFIG_FILE |
Compose (/app/config.yml) |
Path inside the API container |
ROS_DOMAIN_ID |
Not set by CLI | Set inside robot containers (e.g. ~/.bashrc) so DDS matches your fleet |
URLs (packaged stack)
With network_mode: host and default ports:
| What | URL |
|---|---|
| Web UI | http://127.0.0.1:3000 |
| cyclo_manager API | http://127.0.0.1:8081 |
| OpenAPI (Swagger) | http://127.0.0.1:8081/docs |
Custom config and development
The pip workflow is intended for production robots with pre-built images.
For development (local API/UI source, custom config.yml, hot reload):
# From repository root
docker compose -f docker-compose.dev.yml up
See the root README.
Dependencies
Python dependencies declared in pyproject.toml:
| Package | Used by |
|---|---|
| fastapi | cyclo_host_agent HTTP API |
| uvicorn | cyclo_host_agent server |
| psutil | Host agent / system utilities |
The cyclo_manager CLI itself uses only the Python standard library plus subprocess calls to docker compose, pip, systemctl, and sudo.
Runtime outside Python:
- Docker + Compose v2
- systemd (host agent service)
- Pre-built Docker images referenced in the bundled compose file
License
SPDX: Apache-2.0 (see pyproject.toml and the repository LICENSE).
Metadata
Release files for cyclo-manager 1.0.0.dev5
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| cyclo_manager-1.0.0.dev5.tar.gz | 19.1 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| cyclo_manager-1.0.0.dev5-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 39.9 kB
Release files / cyclo_manager-1.0.0.dev5.tar.gz
| Download URL | cyclo_manager-1.0.0.dev5.tar.gz |
|---|---|
| Size | 19.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
9cca48b88663a0f3a8a040d36ec5f7f74dc856eeca2ad47569fb91e75f350850
|
|
BLAKE2b-256 checksum How to use checksums |
ad962bdbdf44d42ac51d6f4752ca95d952de0cc0ddc957dbb68a4ae95d37bb0c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.10.12
|
Release files / cyclo_manager-1.0.0.dev5-py3-none-any.whl
| Download URL | cyclo_manager-1.0.0.dev5-py3-none-any.whl |
|---|---|
| Size | 20.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
61f5c10454ed8c5417d06d0ba0150278c2ccf5609d3586812fd9af7ef8c2842d
|
|
BLAKE2b-256 checksum How to use checksums |
a7f5a64da58becaa6ee15ac2d0223b9cfa2b39a9962e92eccdc3e5c6a9625344
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.10.12
|