Skip to content

Commit

Permalink
Add the build option "--step-handlers" and related document improveme…
Browse files Browse the repository at this point in the history
…nts (#462)
  • Loading branch information
Nox-MSFT authored Apr 28, 2023
1 parent dd3d3a0 commit 5713d86
Show file tree
Hide file tree
Showing 51 changed files with 212 additions and 163 deletions.
21 changes: 15 additions & 6 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ set (
set (
ADUC_UPDATE_CONTENT_HANDLER_REG_FILENAME
"content_handler.json"
CACHE STRING "Content handler registration file name.")
CACHE STRING "Step handler registration file name.")

set (
ADUC_DOWNLOAD_HANDLER_REG_FILENAME
Expand All @@ -159,7 +159,7 @@ set (
set (
ADUC_EXTENSIONS_SUBDIR_UPDATE_CONTENT_HANDLERS
"update_content_handlers"
CACHE STRING "Sub folder for update content handler extensions.")
CACHE STRING "Sub folder for update step handler extensions.")

set (
ADUC_COMPONENT_ENUMERATOR_EXTENSION_DIR
Expand All @@ -174,7 +174,7 @@ set (
set (
ADUC_UPDATE_CONTENT_HANDLER_EXTENSION_DIR
"${ADUC_EXTENSIONS_FOLDER}/${ADUC_EXTENSIONS_SUBDIR_UPDATE_CONTENT_HANDLERS}"
CACHE STRING "Sub folder for update content handler extensions.")
CACHE STRING "Sub folder for update step handler extensions.")

set (
ADUC_EXTENSIONS_SUBDIR_DOWNLOAD_HANDLERS
Expand All @@ -191,10 +191,19 @@ set (
"${ADUC_DATA_FOLDER}/downloads"
CACHE STRING "Path to the folder containing downloaded update artifacts.")

# Define the mapping from step handler names to subdirectory names
set(ADUC_STEP_HANDLER_NAME_TO_DIRECOTRY_MAP
"microsoft/apt,apt_handler"
"microsoft/script,script_handler"
"microsoft/simulator,simulator_handler"
"microsoft/swupdate,swupdate_handler"
"microsoft/swupdate_v2,swupdate_handler_v2"
)

set (
ADUC_CONTENT_HANDLERS
"microsoft/swupdate"
CACHE STRING "The list of content handlers.")
ADUC_STEP_HANDLERS
"microsoft/swupdate_v2,microsoft/swupdate,microsoft/script,microsoft/apt,microsoft/simulator"
CACHE STRING "The list of step handlers.")

set (
ADUC_COMMANDS_FIFO_NAME
Expand Down
20 changes: 10 additions & 10 deletions docs/agent-reference/device-update-agent-extensibility-points.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,25 +23,25 @@ See the [Registering Device Update Extensions doc](./registering-device-update-e

There are currently 5 extension types:

1. Content Handler, also known as Step Handler (Note: singular Step, not plural Steps)
1. Step Handler, formerly known as Update Content Handler (Note: singular Step, not plural Steps)
- This is the "installer technology" for the update content type, but it actually handles all aspects of the update (Is the update installed? How to download it in addition to installing/applying the update).
2. Update Manifest Handler,
- Deals with how to handle one or more steps in the multi-step update.
- It is also a Content Handler.
- It is also a Step Handler.
3. Content Downloader,
- The wrapper for the "download technology" that will actually download update payload files and detached update manifests.
4. Download Handler,
- A pre-download hook that allows skipping of the update payload if the download handler can produce it by some other means (such as Delta Diffing technology, or "Delta Update").
5. and Component Enumerator
- Allows getting and querying of component hardware modules for proxy updates.

## Content Handler extension type
## Step Handler extension type

The agent defers the business logic for `IsInstalled`, `Download`, `Install`, `Apply`, `Backup`, `Rollback`, and `Cancel` actions to the content handler registered for the update type.
The agent defers the business logic for `IsInstalled`, `Download`, `Install`, `Apply`, `Backup`, `Rollback`, and `Cancel` actions to the step handler registered for the update type.

### List of 1st-Party Registered Content Handlers
### List of 1st-Party Registered Step Handlers

These are the content handlers that come pre-registered when installing the Debian package and can be found under [src/extensions/step_handlers/](../../src/extensions/step_handlers/):
These are the step handlers that come pre-registered when installing the Debian package and can be found under [src/extensions/step_handlers/](../../src/extensions/step_handlers/):

- apt handler ( [README.md](../../src/extensions/step_handlers/apt_handler/README.md) )
- limited example that can install/remove one or more APT package updates specified in an apt-manifest.json update payload,
Expand All @@ -53,7 +53,7 @@ These are the content handlers that come pre-registered when installing the Debi
- runs a script (specified as "scriptFileName" in the "handlerProperites") that's included as an update payload and that invokes swupdate command-line.
- Agent will also pass it the path to the downloaded .swu file included as "swuFileName" in the "handlerProperties"

### Implementing a custom content handler
### Implementing a custom step handler

See [How to implement custom update handler](./how-to-implement-custom-update-handler.md) and examples under [src/extensions/step_handlers](../../src/extensions/step_handlers/)

Expand All @@ -65,7 +65,7 @@ The update manifest handler handles the processing of steps in the instructions

The default Update Manifest Handler registered in deviceupdate-agent Debian package is the [Steps Handler](../../src/extensions/update_manifest_handlers/steps_handler/README.md) (Note: Plural Steps). The implementation is in [steps_handler.cpp](../../src/extensions/update_manifest_handlers/steps_handler/src/steps_handler.cpp).

[Steps Handler](../../src/extensions/update_manifest_handlers/steps_handler/README.md) is a content handler that applies each action aggregated across every step:
[Steps Handler](../../src/extensions/update_manifest_handlers/steps_handler/README.md) is a handler that applies each action aggregated across every step:

- IsInstalled() is true if every step has been installed (and recursively if there are children component updates),
- Download() downloads the update payloads for every step
Expand All @@ -74,11 +74,11 @@ The default Update Manifest Handler registered in deviceupdate-agent Debian pack

### Custom steps handling example

If, for example, not every update payload should be downloaded upfront, then a custom UpdateManifest Handler would need to be authored and registered to do the content handler actions for the first step, and then for the next step, and so on. Each step could decide to skip it's actions under certain conditions to avoid unnecessary downloads/processing.
If, for example, not every update payload should be downloaded upfront, then a custom UpdateManifest Handler would need to be authored and registered to do the step handler actions for the first step, and then for the next step, and so on. Each step could decide to skip it's actions under certain conditions to avoid unnecessary downloads/processing.

### Implementing a custom Update Manifest Handler

To implement a custom Update Manifest Handler, which is a Content Handler, export the function symbols with signatures defined in [extension_content_handler_export_symbols.h](../../src/extensions/inc/aduc/exports/extension_content_handler_export_symbols.h).
To implement a custom Update Manifest Handler, which is a Step Handler, export the function symbols with signatures defined in [extension_content_handler_export_symbols.h](../../src/extensions/inc/aduc/exports/extension_content_handler_export_symbols.h).

For detailed information, see:

Expand Down
2 changes: 1 addition & 1 deletion docs/agent-reference/extension-contract-versions.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ Every Extension Type shared library plugin includes a "GetContractInfo" function

The `GetContractInfo` symbol is defined in [extension_common_export_symbols.h](../../src/extensions/inc/aduc/exports/extension_common_export_symbols.h) but the signature is documented separately for each extension type--look for `GetContractInfo` in:

- [content handler and update manifest handler exports](../../src/extensions/inc/aduc/exports/extension_content_handler_export_symbols.h)
- [step handler and update manifest handler exports](../../src/extensions/inc/aduc/exports/extension_content_handler_export_symbols.h)
- [content download exports](../../src/extensions/inc/aduc/exports/extension_content_downloader_export_symbols.h)
- [download handler exports](../../src/extensions/inc/aduc/exports/extension_download_handler_export_symbols.h)
- [component enumerator exports](../../src/extensions/inc/aduc/exports/extension_component_enumerator_export_symbols.h)
Expand Down
24 changes: 12 additions & 12 deletions docs/agent-reference/goal-state-support.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,14 @@ Another change is the client only reports the status of workflow processing when
##### High-level summary
When the agent receives a property update from PnP either on agent process startup or when the desired action in the digital twin changes, the agent will:
- Parse the desired update metadata in the twin
- Load the appropriate content handler extension for the update type
- Call IsInstalled exported function on the content handler
- Load the appropriate step handler extension for the update type
- Call IsInstalled exported function on the step handler
- If not installed, the agent will:
- report the deployment is in progress
- initiate download, install, and apply operations in that order, which will invoke the corresponding exports on the content handler.
- initiate download, install, and apply operations in that order, which will invoke the corresponding exports on the step handler.
- it will report the final status to the cloud upon failure or success.

If an install or apply requires agent restart or system reboot (as dictated by return status from the content handler), then it will do so. Upon startup, the goal state in the twin is processed as before (it is treated idempotently). If the content handler deems that there is still more work to do, processing will continue from the beginning (it is up to the content handler to return success for any steps already done such as download); otherwise, it will report the results of workflow processing to the cloud.
If an install or apply requires agent restart or system reboot (as dictated by return status from the step handler), then it will do so. Upon startup, the goal state in the twin is processed as before (it is treated idempotently). If the step handler deems that there is still more work to do, processing will continue from the beginning (it is up to the step handler to return success for any steps already done such as download); otherwise, it will report the results of workflow processing to the cloud.

Processing of the goal state update workflow starts with the service updating the digital twin's desired section
with the `ProcessDeployment ( 3 )` ProcessWorkflow UpdateAction. See `ADUCITF_UpdateAction` enum in [update_content.h](../../src/adu_types/inc/aduc/types/update_content.h).
Expand All @@ -61,20 +61,20 @@ Here is each workflow step and what it does at a high-level:
- Auto-Transitions to `ADUCITF_WorkflowStep_Download`
- `ADUCITF_WorkflowStep_Download`
- Sets current state to `ADUCITF_State_DownloadStarted`
- Kicks off Download worker thread, which will call the content handler's `Download()` method to download the update content to the work folder download sandbox.
- Kicks off Download worker thread, which will call the step handler's `Download()` method to download the update content to the work folder download sandbox.
- On success, it will set the state to `ADUCITF_State_DownloadCompleted` and auto-transitions to `ADUCITF_WorkflowStep_Backup`
- On failure, it sets the state to `ADUCITF_State_Failed` and reports the failure.
- `ADUCITF_WorkflowStep_Backup`
- Sets current state to `ADUCITF_WorkflowStep_Backup`
- Kicks off Backup worker thread, which will call the content handler's `Backup()` method to backup the content needed to
- Kicks off Backup worker thread, which will call the step handler's `Backup()` method to backup the content needed to
be backed up
- On success, it will set the state to `ADUCITF_State_BackupCompleted` and auto-transitions to `ADUCITF_WorkflowStep_InstallStarted`
- On failure, it sets the state to `ADUCITF_State_Failed` and reports the failure.
Note: The default behavior of backup is that if Backup fails, the workflow will end and report failure immediately.
To opt out of this design, in the content handler, the owner of the content handler will need to persist the result of ADUC_Workflow_MethodCall_Backup and return ADUC_Result_Backup_Success to let the workflow continue.
To opt out of this design, in the step handler, the owner of the step handler will need to persist the result of ADUC_Workflow_MethodCall_Backup and return ADUC_Result_Backup_Success to let the workflow continue.
- `ADUCITF_WorkflowStep_Install`
- Sets the current state to `ADUCITF_State_InstallStarted`
- Kicks off Install worker thread, which will call the content handler's `Install()` method to install the content that is in the work folder
- Kicks off Install worker thread, which will call the step handler's `Install()` method to install the content that is in the work folder
- On success, it will:
- Reboot the system if the result code is either
- `ADUC_Result_Install_RequiredImmediateReboot` or
Expand All @@ -86,7 +86,7 @@ Here is each workflow step and what it does at a high-level:
- On failure, it will transit to `ADUCITF_WorkflowStep_Restore`
- `ADUCITF_WorkflowStep_Apply`
- Sets the current state to `ADUCITF_State_ApplyStarted`
- Kicks off Apply worker thread, which will call the content handler's `Apply()` method
- Kicks off Apply worker thread, which will call the step handler's `Apply()` method
- On success, it will:
- Reboot the system if the result code is either
- `ADUC_Result_Apply_RequiredImmediateReboot` or
Expand All @@ -99,7 +99,7 @@ Here is each workflow step and what it does at a high-level:

- `ADUCITF_WorkflowStep_Restore`
- Sets the current state to `ADUCITF_State_RestoreStarted`
- Kicks off Restore worker thread, which will call the content handler's `Restore()` method
- Kicks off Restore worker thread, which will call the step handler's `Restore()` method
- On success, it will:
- Reboot the system if the result code is either
- `ADUC_Result_Restore_RequiredImmediateReboot` or
Expand Down Expand Up @@ -129,7 +129,7 @@ Once processing is done, or cancel completes, it will start processing the new w

Note:

Ideally, the content handler's Cancel method should be able to send a cancel message/signal to the thread/process executing the current operation (e.g. install operation). If the cancellation is successful, the thread/process should still call `WorkCompletionCallback` so that the state machine can transition to the next state and report to the cloud as appropriate for final states (failure, cancellation, success).
Ideally, the step handler's Cancel method should be able to send a cancel message/signal to the thread/process executing the current operation (e.g. install operation). If the cancellation is successful, the thread/process should still call `WorkCompletionCallback` so that the state machine can transition to the next state and report to the cloud as appropriate for final states (failure, cancellation, success).

## Handling Service-Initiated Retry

Expand All @@ -139,6 +139,6 @@ Similarly, if the service operator issues a retry, the agent will cancel any cur

When a service operator issues a cancellation of the current workflow processing, the agent will attempt to cancel it. This leads to a call to the Cancel method of the ContentHandler that is registered for the update's update type.

The content handler should interupt the current in-progress operation (e.g. Download) so that the operation exits and calls WorkCompletionCallback to complete the current operation.
The step handler should interrupt the current in-progress operation (e.g. Download) so that the operation exits and calls WorkCompletionCallback to complete the current operation.

The agent will then report to the cloud a result code of ADUC_Result_Failure_Cancelled(-1) and transition to Idle state.
Loading

0 comments on commit 5713d86

Please sign in to comment.