Skip to content

Implement Script Execution lifecycle endpoints #201

@bburda

Description

@bburda

Summary

Script execution endpoints allow clients to start, monitor, control, and clean up diagnostic script runs. This is separate from script management (upload/list/delete) - execution requires a script to already be uploaded.


Proposed solution

1. POST /api/v1/{entity-path}/scripts/{script-id}/executions

Start a new execution of an uploaded script.

Applies to entity types: Components, Apps

Path parameters:

Parameter Type Required Description
{entity-path} URL segment Yes e.g., apps/temp_sensor
{script-id} string Yes ID of the uploaded script to execute

Request body:

{
  "execution_type": "now",
  "parameters": {
    "threshold": 0.1,
    "timeout": 30
  },
  "proximity_response": "optional-proof-token"
}
Field Type Required Description
execution_type string Yes When to run. See values below.
parameters object No Input parameters for the script (must match parameters_schema if defined)
proximity_response string No Co-location proof token (if script requires proximity)

execution_type values:

Value Description
now Execute immediately
now_and_on_restart Execute now and also schedule for server restart
on_restart Schedule for next server restart only
once_on_restart Execute once on next restart, then remove schedule

Response 202 Accepted:

{
  "id": "exec_001",
  "status": "prepared",
  "href": "/api/v1/apps/temp_sensor/scripts/script_001/executions/exec_001"
}

The Location header also points to the execution status resource.

Error responses:

Status Error Code When
400 invalid-parameter Invalid execution_type, parameters don't match schema
404 resource-not-found Script doesn't exist
409 invalid-request Script already has a running execution (if single-execution only)

2. GET /api/v1/{entity-path}/scripts/{script-id}/executions/{execution-id}

Poll the status of a script execution.

Path parameters:

Parameter Type Required Description
{script-id} string Yes Script identifier
{execution-id} string Yes Execution identifier

Response 200 OK:

{
  "id": "exec_001",
  "status": "running",
  "progress": 45,
  "started_at": "2026-02-14T10:30:00Z"
}
Field Type Required Description
id string Yes Execution identifier
status string Yes Current status (see values below)
progress integer No Percentage 0–100
started_at string (ISO 8601) No When execution started
completed_at string (ISO 8601) No When execution completed/failed/terminated
parameters object No Output parameters (when completed)
error GenericError No Error details (when failed)

status values:

Status Description
prepared Created but not yet running
running Currently executing
completed Successfully finished (output in parameters)
failed Execution failed (details in error)
terminated Manually stopped by client

Error responses:

Status Error Code When
404 resource-not-found Execution doesn't exist

3. PUT /api/v1/{entity-path}/scripts/{script-id}/executions/{execution-id}

Send a termination action to a running script execution.

Request body:

{
  "action": "stop"
}
Value Description
stop Request graceful termination (SIGTERM equivalent)
forced_termination Force immediate termination (SIGKILL equivalent)

Response 200 OK: Returns updated execution status.

Error responses:

Status Error Code When
400 invalid-parameter Unknown action value
404 resource-not-found Execution doesn't exist
409 invalid-request Execution is not in a state that can be terminated (already completed/failed/terminated)

4. DELETE /api/v1/{entity-path}/scripts/{script-id}/executions/{execution-id}

Remove a completed, failed, or terminated execution resource. Cannot remove a running execution.

Response 204 No Content

Error responses:

Status Error Code When
404 resource-not-found Execution doesn't exist
409 invalid-request Execution is still running

Additional context

Architecture

  • The ScriptManager (from issue Add basic folder struct and initial gateway node #6) should have an ExecutionManager component
  • Script execution spawns a subprocess (e.g., Python interpreter) with configurable timeout
  • Track execution status in memory; clean up terminated processes
  • Consider resource limits: max concurrent executions per entity, CPU/memory limits

ROS 2 context

In a ROS 2 environment, scripts could be:

  • Python scripts using rclpy to interact with the ROS 2 graph
  • Shell scripts for system diagnostics
  • Launch file fragments for diagnostic sequences

Route registration

srv->Post((api_path("/apps") + R"(/([^/]+)/scripts/([^/]+)/executions$)"), handler);
srv->Get((api_path("/apps") + R"(/([^/]+)/scripts/([^/]+)/executions/([^/]+)$)"), handler);
srv->Put((api_path("/apps") + R"(/([^/]+)/scripts/([^/]+)/executions/([^/]+)$)"), handler);
srv->Delete((api_path("/apps") + R"(/([^/]+)/scripts/([^/]+)/executions/([^/]+)$)"), handler);
// Same for /components/

Tests

  • Unit test: start execution → 202
  • Unit test: poll status → transitions through prepared → running → completed
  • Unit test: terminate running execution → terminated
  • Unit test: delete completed execution → 204
  • Unit test: delete running execution → 409
  • Unit test: start execution for nonexistent script → 404

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions