feat: add CreateLocalDeployment IPC support (C + C++ + Rust)#139
feat: add CreateLocalDeployment IPC support (C + C++ + Rust)#139xuchuwan wants to merge 1 commit into
Conversation
d4ead08 to
3aeada9
Compare
xuchuwan
left a comment
There was a problem hiding this comment.
feat: add CreateLocalDeployment IPC support (C + Rust)
Add CreateLocalDeployment IPC operation to the C SDK and Rust wrapper,
enabling components to create local deployments that merge configuration
into other components at runtime.
Use case: a proxy bridge component needs to set networkProxy on Nucleus
without requiring a cloud deployment. CreateLocalDeployment IPC is
supported by both Classic Nucleus (via aws.greengrass.Cli plugin) and
Nucleus Lite (via ggdeploymentd).
Testing:
Tested in local container in both classic and lite, see details in https://code.amazon.com/reviews/CR-270686792
3aeada9 to
e41ba1c
Compare
|
README and samples need updates |
|
No packet captures were used. All test data is hand-constructed according to the IPC protocol spec. The 4 unit tests use the same programmatic mock-packet-building infrastructure ( See also the companion PR on aws-greengrass-lite (PR #1108) which uses the same approach with GGL typed objects for its unit tests. |
|
The traces for other commands were pulled by capturing traffic between the device sdks and the Java nucleus. This is to ensure the IPC protocol remains compatible with them. The GG-IPC protocol is not well-specified, so cannot rely on documentation to match behavior. |
|
All commands have C++ wrappers too. All lang bindings should maintain full SDK functionality |
|
Good point — I'll capture real IPC traces from the Python/C++ SDK calling CreateLocalDeployment against Classic Java Nucleus and update the test fixtures to use those instead of hand-constructed packets. Will push an update. |
bda45f6 to
cdd98ab
Compare
|
Addressed all review feedback. Updated commit force-pushed. Changes made:
Verification:
|
cdd98ab to
a84630c
Compare
|
Re: How traces were captured Used GGLite-IPC-EventStream-Sniffer as a transparent proxy between SDK clients and Classic Nucleus v2.17.0:
Traces captured: CreateLocalDeployment (Java SDK, Python SDK, Rust SDK), GetConfiguration, SubscribeToConfigurationUpdate. |
dfdc9d6 to
709a6a0
Compare
|
Raw IPC wire traces — CreateLocalDeployment Captured via GGLite-IPC-EventStream-Sniffer between SDK clients and Classic Nucleus v2.17.0. Sniffer methodology documented in a prior comment. Java SDK (greengrass-cli)Python SDKRust SDK |
0cc9e7b to
4a90b53
Compare
e40c91a to
bf5ddeb
Compare
Add CreateLocalDeployment operation to the C, C++, and Rust SDK, enabling components to trigger local deployments via IPC without shelling out to greengrass-cli. Changes since initial review: - Full schema: GgCreateLocalDeploymentArgs struct exposes all 6 fields (componentToConfiguration, rootComponentVersionsToAdd, rootComponentsToRemove, recipeDirectoryPath, artifactsDirectoryPath, failureHandlingPolicy) - C++ wrapper: Client::create_local_deployment() added - README: CreateLocalDeployment section with C/C++/Rust examples - Mock packets: renamed ACCEPTED_HEADERS to RESPONSE_HEADERS per real IPC traces captured via GGLite-IPC-EventStream-Sniffer against Classic Nucleus v2.17.0 - Doc comments: clarified Classic vs Lite behavior (Lite has native support via ggdeploymentd, no Cli dep or ACL required) Testing: - nix flake check: 17/17 checks pass (formatting, namespacing, spelling, IWYU, C tests 45/45, Rust tests 28/28, cross-compile x86_64 + aarch64 + armv7l) - Integration: cache-proxy-bridge/server/common all compile and pass 172 tests with the updated SDK vendored in
bf5ddeb to
e57c7b4
Compare
Description
Add
CreateLocalDeploymentIPC operation to the C SDK and Rust wrapper,enabling components to programmatically create local deployments that merge
configuration into other components at runtime.
Motivating use case
A proxy bridge component that needs to set
networkProxyonaws.greengrass.Nucleus(or
aws.greengrass.NucleusLite) without going through a cloud deployment — soNucleus reconnects through a local (LAN) proxy. Today, the only way for a
component to push config into another component is to shell out to
greengrass-cli deployment create(Classic) or hand-roll the eventstream wireprotocol, since
CreateLocalDeploymentis not exposed in the C or Rust SDK.Compatibility
aws.greengrass.Cliplugin component. Callers must declare a dep on
aws.greengrass.Cliand anaccess-control policy allowing
aws.greengrass#CreateLocalDeployment.ggdeploymentdin recent versions.No plugin dependency, no ACL required. (See the companion PR in
aws-greengrass-litefor thecomponentToConfigurationwiring that makesthis IPC actually apply config merges to already-installed components on
Lite.)
Both target the same wire protocol; the Rust doc comment calls out the
difference explicitly.
Related Issue
N/A
Type of Change
src/ipc/client.cto avoid duplicating the marshaling logic for thenew operation)
Changes
C
src/ipc/client/create_local_deployment.c(new) — callsggipc_callwith
operation = "aws.greengrass#CreateLocalDeployment",service_model_type = "aws.greengrass#CreateLocalDeploymentRequest".Accepts the
componentToConfigurationmap and optionally returns thedeployment id. Validates the arg is a map; logs and returns
GG_ERR_INVALIDotherwise. Response validator extractsdeploymentIdfrom the accepted payload and copies it into a caller-provided arena.
include/gg/ipc/client.h— declareggipc_create_local_deployment().src/ipc/client.c— minor refactor of the shared IPC helpers to keepthe new file small.
Rust
rust/src/ipc.rs— addSdk::create_local_deployment()that takes animpl Into<Object<'a>>for the component-to-configuration map and acaller-owned
&mut [MaybeUninit<u8>]for the returned deployment id.rust/src/lib.rs—#![allow(clippy::ref_as_ptr)]for theptr::from_ref(&obj).cast::<c::GgObject>()pattern used throughout thecrate (pedantic lint).
Tests
test/client/create_local_deployment.c(new) — 4 unity tests usingthe existing fork + mock-IPC-server pattern:
networkProxymerge payload, deployment id returned)deployment_id = NULLcaller (no output buffer, server still receives request)UnauthorizedErrorresponse from server (client propagates failure)GG_ERR_INVALIDbefore IPC)mock/packets/component_packet_sequences.c— 4 new packet helpersparallel to the
RestartComponentones:gg_test_create_local_deployment_request_packetgg_test_create_local_deployment_response_packetgg_test_create_local_deployment_accepted_sequencegg_test_create_local_deployment_error_sequencemock/packets/packets.handmock/gg/ipc/packet_sequences.h—declarations.
No
CMakeLists.txtchange needed: the existingfile(GLOB_RECURSE ... test/client/*.c)picks up the new file intoc_client_tests.Checklist
nix flake check -L— not run locally (no nix in devenv); relying on CI.
cmake --build+ctestpass:44 Tests 0 Failures 0 Ignored(up from 40 on
main)///doc comment on the new function.aws-greengrass-testing— N/A, this is a pureSDK addition and is covered by the in-repo C unit tests.
Documentation Updates
create_local_deploymentexplains both Classic(
aws.greengrass.Clidep + ACL) and Lite (native inggdeploymentd,no dep / ACL) behavior, and links to the upstream GG IPC reference.
README.md— no change.docs/— no change.by GG; this PR only exposes it in the SDK).
Testing
c_client_tests,gg-sdk-testbuilds clean).a proxy-bridge component using
Sdk::create_local_deployment()successfully sets
networkProxyon Nucleus and traffic routes throughthe local proxy.
Additional Notes
This PR pairs with a companion PR in
aws-greengrass-lite(
feat(ggdeploymentd,ggl-cli): support componentToConfiguration in CreateLocalDeployment) that makes Lite'sggdeploymentdhonor thecomponentToConfigurationfield of the incoming deployment — required forthe SDK call to actually apply config merges to already-installed components
(notably
aws.greengrass.NucleusLite) on Lite.By submitting this pull request, I confirm that you can use, modify, copy,
and redistribute this contribution, under the terms of your choice.