116 lines
4.1 KiB
Markdown
116 lines
4.1 KiB
Markdown
# Local Installer Agent
|
|
|
|
FastAPI service that runs on each Linux client and listens on `127.0.0.1:5010`.
|
|
|
|
It accepts install, update, remove, task, log, installed-app, and service-control requests from `robot.installer`. It stores state in local SQLite and installs trusted `.deb` components downloaded from `robot.package`, allowlisted Ubuntu APT packages, plus Docker image components from allowed registries when Docker support is enabled.
|
|
|
|
## Development
|
|
|
|
```bash
|
|
cd agent
|
|
python3 -m venv .venv
|
|
source .venv/bin/activate
|
|
pip install -r requirements.txt
|
|
uvicorn app.main:app --host 127.0.0.1 --port 5010
|
|
```
|
|
|
|
## Install script URL
|
|
|
|
Client machines should keep using the stable installer command:
|
|
|
|
```bash
|
|
curl -fsSL https://robot.package/install-agent.sh | sudo bash
|
|
```
|
|
|
|
The web server resolves `https://robot.package/packages/agent/latest.deb?arch=<dpkg-arch>`
|
|
to the newest uploaded `local-installer-agent_<version>_<arch>.deb`, so updating the Agent does not require editing the install command.
|
|
|
|
Agent packages are uploaded from the web server Admin page at `/agent`. The default storage folder is
|
|
`web-server/uploads/packages/agent`, and it can be changed with `AGENT_PACKAGE_DIR`.
|
|
|
|
## Important API
|
|
|
|
```text
|
|
GET /health
|
|
GET /system-info
|
|
GET /apps/installed
|
|
POST /apps/install
|
|
POST /apps/update
|
|
POST /apps/remove
|
|
GET /tasks/{taskId}
|
|
GET /tasks/{taskId}/logs
|
|
GET /tasks/{taskId}/components
|
|
POST /services/start
|
|
POST /services/stop
|
|
POST /services/restart
|
|
GET /services/{serviceName}/status
|
|
```
|
|
|
|
`POST /apps/install` supports both:
|
|
|
|
```json
|
|
{
|
|
"appId": "robot-suite",
|
|
"version": "1.0.0"
|
|
}
|
|
```
|
|
|
|
and a direct single `.deb` payload:
|
|
|
|
```json
|
|
{
|
|
"appId": "robot-web-app",
|
|
"appName": "Robot Web App",
|
|
"packageName": "robot-web-app",
|
|
"serviceName": "robot-web-app.service",
|
|
"version": "1.0.0",
|
|
"downloadUrl": "https://robot.package/packages/robot-web-app_1.0.0_amd64.deb",
|
|
"checksum": "sha256_hash_here"
|
|
}
|
|
```
|
|
|
|
For manifest mode, the Agent fetches:
|
|
|
|
```text
|
|
{ROBOT_PACKAGE_BASE_URL}/api/apps/{appId}/versions/{version}/manifest
|
|
```
|
|
|
|
Docker image components require Docker Engine on the client machine. By default `AUTO_INSTALL_DOCKER=true`, so the agent will install the trusted distro package `docker.io` with `apt-get` when a Docker app is installed and Docker is missing. Set `AUTO_INSTALL_DOCKER=false` if Docker must be provisioned by your own fleet policy. The agent validates `image` against `ALLOWED_DOCKER_REGISTRIES`, then runs a managed container using the manifest fields `containerName`, `restartPolicy`, `ports`, `volumes`, and `env`.
|
|
|
|
APT components use a fixed manifest contract and never accept shell commands:
|
|
|
|
```json
|
|
{
|
|
"componentId": "postgresql",
|
|
"type": "apt",
|
|
"packageName": "postgresql",
|
|
"version": "16"
|
|
}
|
|
```
|
|
|
|
The package name must be present in `ALLOWED_APT_PACKAGES` (default: `postgresql`). After installation, the Agent discovers concrete systemd `.service` units shipped by the trusted package and reads their state with a fixed `systemctl show` argv (no shell command is accepted from the manifest or Web Client). The structured result is returned as `serviceCheckStatus` and `serviceChecks` from the task component API and is retained with the installed app for the UI.
|
|
|
|
PostgreSQL keeps an additional trusted policy: the Agent enables and starts `postgresql.service`, verifies that it is active, and waits for `pg_isready`. Other discovered package services are checked read-only; they are not blindly enabled or started because packages can ship optional or one-shot units.
|
|
|
|
`GET /apps/installed` refreshes the current systemd state for retained service names. For the trusted PostgreSQL policy it also re-runs `pg_isready`, so the UI does not report a healthy meta-service while the database is unavailable.
|
|
|
|
Example task component service result:
|
|
|
|
```json
|
|
{
|
|
"serviceCheckStatus": "healthy",
|
|
"serviceChecks": [
|
|
{
|
|
"serviceName": "postgresql.service",
|
|
"loadState": "loaded",
|
|
"activeState": "active",
|
|
"subState": "running",
|
|
"unitFileState": "enabled",
|
|
"healthy": true,
|
|
"readinessStatus": "ready",
|
|
"checkedAt": "2026-07-20T00:00:00Z"
|
|
}
|
|
]
|
|
}
|
|
```
|