Skip to content

Comments

feat: software updates plugin system with 8 SOVD endpoints#231

Merged
bburda merged 15 commits intomainfrom
feat/update-endpoints
Feb 23, 2026
Merged

feat: software updates plugin system with 8 SOVD endpoints#231
bburda merged 15 commits intomainfrom
feat/update-endpoints

Conversation

@bburda
Copy link
Collaborator

@bburda bburda commented Feb 22, 2026

Pull Request

Summary

Add a plugin-based software updates subsystem implementing 8 SOVD-compliant REST endpoints for managing software update packages with async prepare/execute lifecycle.

  • Plugin architecture: UpdateBackend abstract interface loaded at runtime via dlopen/dlsym from .so shared libraries
  • 8 REST endpoints: GET/POST /updates, GET/DELETE /updates/{id}, PUT prepare/execute/automated, GET status - with async operations returning 202 + Location header for status polling
  • Production hardening: typed UpdateError with UpdateErrorCode enum replacing string-based errors, TOCTOU-safe deletion with Deleting sentinel phase, exception safety in async threads, thread-safety documentation
  • Full test coverage: 17 GTest unit tests for UpdateManager + 32 integration tests covering CRUD, async lifecycle, automated mode, error cases, failure/exception handling, and 501 no-backend mode
  • Documentation: API reference (8 endpoints), changelog, configuration guide, requirements traceability (REQ_INTEROP_082-094)
  • Verification script: enhanced to detect @verifies tags before test definitions and generate clickable GitHub links with line numbers

Issue


Type

  • Bug fix
  • New feature or tests
  • Breaking change
  • Documentation only

Testing

  • Unit tests: colcon test --ctest-args -R test_update_manager - 17 tests covering CRUD, prepare/execute workflow, automated mode, status polling, concurrent operations, deadlock-free destruction, backend failure/exception handling, and error codes
  • Integration tests: colcon test --packages-select ros2_medkit_integration_tests --ctest-args -R test_updates - 32 tests against running gateway with and without plugin backend
  • Linters: clang-format, flake8 pass on all new and modified files
  • Build: Clean build with no warnings on Jazzy
  • Docs: Sphinx build succeeds with 0 warnings, all GitHub links verified

Checklist

  • Breaking changes are clearly described (and announced in docs / changelog if needed)
  • Tests were added or updated if needed
  • Docs were updated if behavior or public API changed

Define OTA scenarios: no-plugin 501, CRUD lifecycle, prepare/execute
workflow, automated mode, error cases. All tests expected to fail
until implementation is complete.
Define abstract UpdateBackend class with CRUD + async operations,
UpdateProgressReporter for optional progress reporting, new
requirements REQ_INTEROP_091-094 for async update endpoints, and
vendor-specific error codes for update operations.
Stores metadata in memory, simulates prepare/execute with 4 steps
(100ms each) and progress reporting. Used as test fixture for
integration tests.
Background threads for prepare/execute/automated. Automatic status
tracking (Pending->InProgress->Completed/Failed) with optional
progress enrichment via UpdateProgressReporter. Uses unique_ptr
for PackageState pointer stability.
Uses dlopen/dlsym to load extern C create_update_backend() factory.
Returns backend + handle pair for UpdateManager ownership.
HTTP handler class for all SOVD software update REST endpoints:
- GET /updates (list with origin/target-version filters)
- POST /updates (register new package)
- GET /updates/{id} (get package details)
- DELETE /updates/{id} (remove package)
- PUT /updates/{id}/prepare (start prepare phase)
- PUT /updates/{id}/execute (start execute phase)
- PUT /updates/{id}/automated (prepare+execute in one)
- GET /updates/{id}/status (poll async operation status)

Includes check_backend() guard (501 if no plugin loaded) and
status_to_json() converter for UpdateStatusInfo.
Load updates config from parameters (updates.enabled, updates.backend,
updates.plugin_path), instantiate UpdateManager with plugin backend
(or nullptr for 501 mode), register 8 routes in REST server.
Add update_manager.cpp, plugin_loader.cpp, update_handlers.cpp to
gateway_lib. Build test_update_backend.so MODULE for integration
tests. Link dl library. Add updates config section to params YAML.
Unit tests cover CRUD, prepare/execute workflow, automated mode,
status polling, and error cases (no backend, not prepared, duplicate,
delete during operation).

Fix deadlock in ~UpdateManager: collect futures under lock, then
wait outside lock to avoid blocking async tasks that also need
the mutex.
…ception handling

Replace string-based error matching with typed UpdateErrorCode enum throughout
UpdateManager, handlers, and tests. Fix TOCTOU races by adding Deleting sentinel
phase and moving backend validation inside mutex. Wrap async prepare/execute/automated
in try-catch for exception safety. Add plugin loader exception safety to prevent
dlopen handle leaks. Validate entity IDs in all handlers, fix register response to
return JSON body with 201, and change state-conflict errors from 405 to 409.

Add 3 new unit tests (backend failure, exception, concurrent reject), integration
tests for malformed JSON and target-version filter, and complete REST API docs,
changelog, and config reference for software updates.
@bburda bburda self-assigned this Feb 22, 2026
@bburda bburda added the enhancement New feature or request label Feb 22, 2026
@bburda bburda added this to the MS5: Fleet & Advanced Features milestone Feb 22, 2026
@bburda bburda marked this pull request as ready for review February 22, 2026 15:38
@bburda bburda requested review from Copilot and mfaferek93 February 22, 2026 15:38
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR implements a comprehensive software updates management system for ros2_medkit with 8 SOVD-compliant REST endpoints, following a plugin-based architecture for maximum extensibility. The implementation adds async update lifecycle management (prepare/execute/automated) with status polling, full error handling, and comprehensive test coverage.

Changes:

  • Plugin-based UpdateBackend architecture with runtime loading via dlopen
  • 8 REST endpoints: list, register, get, delete, prepare, execute, automated, and status
  • Async operation management with thread-safe status tracking and progress reporting
  • Full test suite: 14 unit tests + comprehensive integration test scenarios
  • Documentation updates: API reference, configuration guide, roadmap, changelog, requirements

Reviewed changes

Copilot reviewed 24 out of 24 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
src/ros2_medkit_gateway/include/ros2_medkit_gateway/updates/update_backend.hpp Plugin interface with UpdateBackend base class and progress reporter
src/ros2_medkit_gateway/include/ros2_medkit_gateway/updates/update_manager.hpp Manager orchestrating async lifecycle and state tracking
src/ros2_medkit_gateway/include/ros2_medkit_gateway/updates/plugin_loader.hpp dlopen-based plugin loader with error handling
src/ros2_medkit_gateway/src/updates/update_manager.cpp Thread-safe async operations with deadlock-free destructor
src/ros2_medkit_gateway/src/updates/plugin_loader.cpp Plugin loading implementation with symbol resolution
src/ros2_medkit_gateway/src/http/handlers/update_handlers.cpp HTTP handlers for 8 update endpoints with proper error mapping
src/ros2_medkit_gateway/src/http/rest_server.cpp Route registration with correct ordering (specific before generic)
src/ros2_medkit_gateway/src/gateway_node.cpp Update manager initialization with plugin loading
src/ros2_medkit_gateway/test/test_update_manager.cpp 14 unit tests covering CRUD, lifecycle, concurrency, error cases
src/ros2_medkit_gateway/test/demo_nodes/test_update_backend.cpp Demo plugin implementation for integration testing
src/ros2_medkit_integration_tests/test/features/test_updates.test.py Integration tests covering all 8 endpoints with 501 mode and plugin mode
src/ros2_medkit_gateway/include/ros2_medkit_gateway/http/error_codes.hpp 5 new vendor-specific error codes with x-medkit- prefix
src/ros2_medkit_gateway/config/gateway_params.yaml Configuration parameters for updates feature
docs/api/rest.rst REST API documentation for all 8 endpoints
docs/config/server.rst Configuration guide for updates plugin system
docs/requirements/specs/updates.rst Requirements tracking with @verifies links
docs/roadmap.rst Roadmap update marking Updates as completed
docs/changelog.rst Changelog entry describing the feature
README.md Features table update showing Updates as Available
CMakeLists.txt Build configuration for UpdateManager, plugin loader, handlers, and test plugin

The verification script only scanned inside test bodies for @verifies
tags, missing tags placed as comments before def/TEST lines. Now scans
backwards from each test to find preceding @verifies comments. Also
generates clickable GitHub links with line numbers in verification.rst.
GitHub generates line anchors (#L123) dynamically via JavaScript, so
Sphinx linkcheck reports them as broken. Use
linkcheck_anchors_ignore_for_url to skip anchor checks while still
verifying the pages exist.
Copy link
Collaborator

@mfaferek93 mfaferek93 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review

Clean plugin system with good separation of concerns. Found a few thread-safety issues in UpdateManager and a validation ordering bug in the handler. Details in inline comments.

…lidation

Replace string-based backend error matching with typed UpdateBackendError enum
and UpdateBackendErrorInfo struct across UpdateBackend interface, UpdateManager,
and all mock/test backends. Fix TOCTOU race in delete_update by creating Deleting
sentinel when no PackageState exists. Move id validation and entity_id format
check before backend call in register handler. Remove dead Deleting phase check
in start_execute. Add stopped_ atomic flag to prevent new operations during
shutdown. Add execute failure/exception tests with dedicated mock backends. Fix
all polling loops to use deadline-based waits with explicit timeout assertions.
@bburda bburda requested a review from mfaferek93 February 23, 2026 07:27
Copy link
Collaborator

@mfaferek93 mfaferek93 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

@bburda bburda merged commit 9cf2ac4 into main Feb 23, 2026
6 checks passed
@bburda bburda deleted the feat/update-endpoints branch February 23, 2026 08:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Implement Software Updates management endpoints

2 participants