Skip to content

sensing: deploy the camera producer to an Orin with one script - #1440

Open
gareth-morgan-nv wants to merge 10 commits into
gmorgan/FastLiveKitfrom
gmorgan/OrinDeploy
Open

gareth-morgan-nv wants to merge 10 commits into
gmorgan/FastLiveKitfrom
gmorgan/OrinDeploy

Conversation

@gareth-morgan-nv

@gareth-morgan-nv gareth-morgan-nv commented Nov 5, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Adds src/plugins/sensing/scripts/deploy_orin.py, one script run on the desktop that builds the camera producer on an Orin from a git checkout and runs it as a systemd service.

  • Source-independent: it works for any checkout (--source DIR, --branch NAME), including trees that lack newer CMake components. It builds only camera_plugin_sensing and stages the release from the build tree: the binary, its platform configs, and liblivekit* only when the binary links them. Extra CMake options go through --cmake-arg.
  • Config: a JSON file with an explicit mode (direct, the default, or livekit), the producer's args, and an optional env map of extra unit environment variables (LD_LIBRARY_PATH is reserved). Install prefix, service groups and the ready timeout are fixed constants rather than flags.
  • Checks first: validates the ssh connection (reachable, python3, aarch64), then runs preflight on the target (L4T, CUDA, uv, SDK headers, disk) before uploading anything.
  • Incremental upload: one per-file hash manifest of the tracked source is compared with the Orin's record, and only the differing files are uploaded; the persistent build stays incremental.
  • Install: packages the release with checksums and installs it as a versioned directory behind an atomic current link, run by isaaccapture-producer.service. Refuses to replace a producer started by hand unless --replace-unmanaged, and then interrupts exactly the PIDs it listed. A failed build or transfer leaves the running producer alone; there is no automatic rollback.
  • Readiness: "up" means each configured sensor's latest status line since the producer's last Capturing. marker shows frames and, for a stream with a direct= destination, direct: HOST:PORT connected. A restart inside the unit cannot satisfy it, and a stream without a destination is reported as capture-only.
  • Failure report: when the producer does not come up, the deploy prints the causes from the journal with the cameras' driver chatter filtered out, and saves the full log on the Orin at ~/.cache/isaaccapture-deploy/last-start-failure.log.
  • Password from ORIN_PASSWORD (ssh via SSH_ASKPASS, sudo via stdin, never in argv), user from ORIN_USER; the LiveKit token file, when used, stays on the Orin and only its path is passed.

Validation

Run: the unit tests of the script (tests/python/ci/test_deploy_orin.py, mocked ssh/subprocess; registered in the pre-commit workflow) pass, including config validation and unit rendering for env; the pre-commit hooks (with SKIP=check-copyright-year) pass.

Run on a real Orin (SIPL, two cameras): repeated deploys of the video-stage branch built natively, installed, replaced the running producer, and reached readiness with both sensors capturing and connected to the PC.

Not verified: the livekit mode against a live LiveKit server in this revision; the Argus backend path.

Stacked on #1426 (the FastLiveKit branch).

🤖 Generated with Claude Code

@coderabbitai

coderabbitai Bot commented Nov 5, 2026 •

Copy link
Copy Markdown
Contributor

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

Run configuration

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • Trigger review
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

@ivany-nv ivany-nv added the NVIDIA label Nov 5, 2026
@gareth-morgan-nv
gareth-morgan-nv force-pushed the gmorgan/TimestampAlignment branch from ba2d1d7 to b7d8f99 Compare November 6, 2026 01:42
@gareth-morgan-nv
gareth-morgan-nv force-pushed the gmorgan/TimestampAlignment branch from b7d8f99 to be24085 Compare November 6, 2026 05:39
@gareth-morgan-nv
gareth-morgan-nv force-pushed the gmorgan/TimestampAlignment branch from be24085 to fbdc7e3 Compare November 6, 2026 05:42
@gareth-morgan-nv
gareth-morgan-nv force-pushed the gmorgan/OrinDeploy branch 2 times, most recently from 74a9341 to 214dfd6 Compare November 6, 2026 05:44
@gareth-morgan-nv
gareth-morgan-nv changed the base branch from gmorgan/TimestampAlignment to gmorgan/FastLiveKit November 6, 2026 05:44
gareth-morgan-nv and others added 9 commits November 6, 2026 14:37
scripts/deploy_orin.py copies a snapshot of the tracked files to the Orin, builds
only the producer there, packages the producer install component with
checksums, and installs it as a versioned release run by one systemd service.
It checks the ssh connection first, takes the password from ORIN_PASSWORD and the
user from ORIN_USER, refuses to replace an unmanaged producer unless told to, and
waits for the producer's own join and publish log lines before reporting ready.
A failed build or transfer leaves the running producer alone.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
Signed-off-by: Gareth Morgan <[email protected]>
…e build PATH

The deploy compares per-file hashes of the tracked source, grouped into files that
change often and files that rarely do, with the Orin's record and uploads only
the difference, keeping one source directory so the persistent build stays
incremental. The helper script is uploaded fresh and preflight runs before any
source transfer. The build PATH now includes ~/.local/bin and /usr/local/cuda/bin,
and preflight requires uv, which the build's Python setup needs.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
Signed-off-by: Gareth Morgan <[email protected]>
…t directory

FetchContent publishes <lowercased name>_SOURCE_DIR, so the uppercase LICENSE and
NOTICE lookups were empty and the install step looked for //LICENSE.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
Signed-off-by: Gareth Morgan <[email protected]>
Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
Signed-off-by: Gareth Morgan <[email protected]>
… Orin

--source DIR deploys a different git checkout (a worktree, say) and --branch NAME
deploys that branch's committed files from it, exported with git archive so the
working tree is ignored. The default is unchanged: the script's own checkout,
local edits included.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
Signed-off-by: Gareth Morgan <[email protected]>
…anch

Drop --backend and the SENSING_WITH_* flags: which capture SDK is built is the
deployed source's own CMake decision, so the same script deploys any branch.
Add a repeatable --cmake-arg for options only some trees define, and pass
-DSIPL_API_DIR only when that header tree exists. Remove the camera-backend
flag from the README example and fix a stale script name in a comment.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
Signed-off-by: Gareth Morgan <[email protected]>
…ploy options

The release is assembled from the build (binary, platform configs, the LiveKit
libraries the binary resolves, LiveKit licence files) instead of the source's
install rules, so any branch deploys. The service puts the release directory
first on LD_LIBRARY_PATH. Remove --prefix, --service-groups, --ready-timeout
and --fetch-archive; their values are constants.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
Signed-off-by: Gareth Morgan <[email protected]>
…eal failure report

The LiveKit settings are optional (both or neither). Readiness requires every
configured sensor to be producing (frames without LiveKit, published with it).
When the producer does not become ready the script prints the service state,
the producer's fault lines and the log with the driver's debug lines removed,
and saves the complete log on the Orin.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
Signed-off-by: Gareth Morgan <[email protected]>
…comparison

The config names its mode (direct or livekit). Readiness is each configured
sensor's latest status line since the producer's last start: frames captured
and, for a stream with a direct destination, that link connected. Progress
left over from an earlier attempt no longer counts. The file-grouping layer is
removed: one comparison of per-file hashes decides what to upload.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
Signed-off-by: Gareth Morgan <[email protected]>

This branch was successfully deployed

1 active deployment
dev — 90af995a Deployed Nov 6, 2026 by gareth-morgan-nv via publish-wheel #6602
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants