Skip to content

Implement Software Updates management endpoints #206

@bburda

Description

@bburda

Summary

Software updates endpoints provide a standardized interface for managing update packages at the server level (not per-entity). The workflow covers: listing available updates, registering new packages, preparing (download + verify), executing (install), and monitoring progress.

This is a server-level feature - all endpoints are under /updates, not under /{entity-path}/updates.


Proposed solution

1. GET /api/v1/updates

List all available/registered software update packages.

Query parameters:

Parameter Type Required Description
origin string No Filter by origin: remote or proximity
target-version string No Filter by target version string

Response 200 OK:

{
  "items": ["autonomous", "ADAS-v2-03-2154", "CAM-v1-18-8643"]
}

Returns a string array of update package identifiers.


2. GET /api/v1/updates/{update-package-id}

Read full metadata for a specific update package.

Path parameters:

Parameter Type Required Description
{update-package-id} string Yes Update package identifier

Response 200 OK:

{
  "id": "ADAS-v2-03-2154",
  "update_name": "ADAS System Update v2.03",
  "automated": true,
  "origins": ["remote", "proximity"],
  "notes": "Fixes lane-keeping edge case in heavy rain",
  "preconditions": "Vehicle must be stationary",
  "execution_conditions": "Engine off, battery > 80%",
  "duration": 1800,
  "size": 524288,
  "updated_components": ["adas_controller", "camera_front"],
  "affected_components": ["adas_controller", "camera_front", "lidar_top"]
}
Field Type Required Description
id string Yes Update package identifier
update_name string Yes Human-readable name
update_translation_id string No Translation key
automated boolean Yes Whether this update can run fully automatically
origins string[] Yes Supported origins: remote (from OTA server), proximity (from local diagnostic tester)
notes string No Additional description
user_activity string No What the user needs to do during the update
preconditions string No Requirements before update can start
execution_conditions string No Conditions that must hold during execution
duration integer No Estimated duration in seconds
size integer No Package size in kilobytes
added_components string[] No New components introduced by this update
removed_components string[] No Components removed by this update
updated_components string[] No Components that will be updated
affected_components string[] No Components affected during the update process (may experience downtime)

Error: 404 if update package doesn't exist.


3. POST /api/v1/updates

Register a new update package.

Request body: Manufacturer-specific content type (e.g., JSON metadata or binary package).

For a ROS 2 implementation, a JSON body is practical:

{
  "id": "gateway-v1.5.0",
  "update_name": "Gateway Update v1.5.0",
  "automated": false,
  "origins": ["proximity"],
  "notes": "Adds cyclic subscription support",
  "updated_components": ["ros2_medkit_gateway"]
}

Response 201 Created with Location header pointing to the new update resource.

Error: 400 if required fields are missing or ID already exists.


4. PUT /api/v1/updates/{update-package-id}/prepare

Trigger preparation phase: download package, verify integrity, check dependencies.

Response 202 Accepted with Location header pointing to the status resource.


5. PUT /api/v1/updates/{update-package-id}/execute

Begin the actual update installation. Should only be called after preparation succeeds.

Response 202 Accepted with Location header pointing to the status resource.


6. PUT /api/v1/updates/{update-package-id}/automated

Trigger a fully automated update (prepare + execute in one step). Only available for packages where automated: true.

Response 202 Accepted with Location header.

Error: 400 if the update doesn't support automated execution.


7. GET /api/v1/updates/{update-package-id}/status

Poll the current status of an update.

Response 200 OK:

{
  "status": "inProgress",
  "progress": 45,
  "sub_progress": [
    { "name": "Downloading package", "progress": 90 },
    { "name": "Flashing ECU", "progress": 0 }
  ]
}
Field Type Required Description
status string Yes See status values below
progress integer No Overall percentage 0–100
sub_progress object[] No Detailed per-step progress
error GenericError No Error details when status is failed

Status values:

Status Description
pending Queued, not yet started
inProgress Update is running
completed Successfully finished
failed Error occurred

8. DELETE /api/v1/updates/{update-package-id}

Remove an update package.

Response 204 No Content

Error responses:

Status Error Code When
404 resource-not-found Package doesn't exist
405 invalid-request Cannot delete - update is currently executing or was automatically triggered

Additional context

ROS 2 context

Updates could map to different deployment models:

  • Docker deployments: Pull new container image, restart container
  • Native deployments: apt/snap package upgrade, colcon workspace rebuild
  • Initial implementation: Store metadata only, delegate execution to shell scripts

Architecture

  • Create an UpdateManager class at the gateway level (not per-entity)
  • Store update metadata in memory or SQLite (for persistence across restarts)
  • Execution delegates to a pluggable backend (strategy pattern)
  • Progress tracking via polling

Route registration

srv->Get(api_path("/updates"), handler);
srv->Get((api_path("/updates") + R"(/([^/]+)$)"), handler);
srv->Post(api_path("/updates"), handler);
srv->Put((api_path("/updates") + R"(/([^/]+)/prepare$)"), handler);
srv->Put((api_path("/updates") + R"(/([^/]+)/execute$)"), handler);
srv->Put((api_path("/updates") + R"(/([^/]+)/automated$)"), handler);
srv->Get((api_path("/updates") + R"(/([^/]+)/status$)"), handler);
srv->Delete((api_path("/updates") + R"(/([^/]+)$)"), handler);

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