Automation Engine
Server-side script automation: a versioned saved-script library, multi-host execution with per-host result tracking, multi-shell support, cron-style scheduling, and approval workflows for privileged scripts. Migrates ~328 lines of agent-side script orchestration to a Cython engine so the agent retains only a thin execution shim.
Overview
The Automation Engine owns every aspect of script execution: storing the script, tracking its version history, validating typed parameters, picking the right shell per host, dispatching to many hosts in one call, and capturing the per-host stdout/stderr. The agent's role shrinks to "run the deploy plan the server hands me" via the existing apply_deployment_plan handler.
Open Source vs Professional+
- Community Edition: ad-hoc one-shot script runs against a single host via
backend/services/script_plan_builder.py - Professional+: persisted, versioned saved-script library (every edit snapshots the prior body for audit / rollback)
- Professional+: queue one execution against many hosts; per-host result rolls up into an aggregate status
- Professional+: cron-triggered scheduled executions with last-run / next-run tracking
- Professional+: scripts flagged
requires_approvalqueue anApprovalRequestreviewers must clear before the execution dispatches - Professional+: typed parameter declarations (string / integer / boolean / float / secret) with validation +
${name}substitution
Deploy Plan Shape
Every execution produces a deploy plan that the agent runs step-by-step: write the rendered script body to a tempfile, invoke the right interpreter, then clean up. The plan is wire-compatible with apply_deployment_plan so the same agent handler runs both Pro+ and ad-hoc paths:
{
"files": [
{"path": "/tmp/sysmanage_script_.sh", "content": "", "mode": 0o700}
],
"commands": [
{"argv": ["/bin/bash", ""], "timeout": N, "ignore_errors": false, "description": "..."},
{"argv": ["rm", "-f", ""], "timeout": 10, "ignore_errors": true, "description": "..."}
]
}
Saved Scripts & Versioning
A SavedScript bundles a name, shell, body, typed parameter declarations, timeout, and an optional requires_approval flag. Updating an existing script bumps its version and snapshots the previous body into the version-history table; older versions remain executable for rollback / audit replays.
Endpoints
GET /api/v1/automation/scripts— list current versionsPOST /api/v1/automation/scripts— create or update; auto-bumps version and snapshots historyGET /api/v1/automation/scripts/{id}— fetch the current versionGET /api/v1/automation/scripts/{id}/versions— full version history newest-firstDELETE /api/v1/automation/scripts/{id}— remove script + all version history
Multi-host Execution
A single POST dispatches one rendered script body to many hosts. Each host gets its own ScriptExecutionHostResult tuple tracking start / completion timestamps, return code, and captured output. The overall ScriptExecution.status rolls up from the per-host states (all-succeeded → succeeded; any-failed → failed; etc.).
POST /api/v1/automation/scripts/{id}/execute
{
"host_ids": ["..uuid-a..", "..uuid-b..", "..uuid-c.."],
"parameter_values": {"target_dir": "/var/www", "dry_run": false}
}
Approval Workflows
Scripts marked requires_approval dispatch into the pending_approval state and create a paired ApprovalRequest. An authorized reviewer either approves (the linked execution promotes to queued and dispatches) or rejects with an optional reason (the linked execution flips to rejected). Approvals are scoped per-execution, not per-script, so reuse is explicit.
GET /api/v1/automation/approvals?status=pending— pending approval queuePOST /api/v1/automation/approvals/{id}/approve— promote linked execution to queuedPOST /api/v1/automation/approvals/{id}/reject?reason=...— reject with optional reason
Scheduled Execution
A ScheduledExecution binds a saved script + a host list + a cron expression. The engine validates the 5-field cron form on insert; the dispatcher polls and fires matching schedules, recording last_run and last_status. Schedules can be disabled in place without deleting the record.
Parameters & Substitution
Each script declares a list of ScriptParameter entries with a typed signature (string, integer, boolean, float, secret), a required flag, and an optional default. Submitted values are type-coerced and required-checked before the script body's ${name} placeholders are substituted left-to-right. Unknown parameter names are rejected; unknown placeholders are left untouched.
Multi-shell Support
Supported shells: bash, zsh, sh, ksh, powershell, cmd. The engine validates the script's declared shell against each target host's advertised shells (or per-platform defaults) before queueing; hosts that don't support the script's shell appear in the execution's skipped_hosts list rather than being dispatched and failing at the agent.
Feature Codes
Endpoints in this engine are gated by these feature codes (returned 402 by the open-source server when the module isn't loaded):
automation_script_library— saved-script CRUD + version historyautomation_script_exec— execute / list / cancel executionsautomation_script_schedule— scheduled executions CRUDautomation_script_approval— approvals queue + decisions
Architecture
The engine is a Cython-compiled binary (automation_engine.so) loaded by the open-source server's module_loader at startup. It exports the same get_module_info() + get_automation_router() contract as the other Pro+ modules, so mount_automation_routes() wires it under /api/v1/automation alongside the 402 stub routes.