mirror of
https://github.com/azaion/loader.git
synced 2026-04-22 08:26:32 +00:00
[AZ-187] Rules & cleanup
Made-with: Cursor
This commit is contained in:
@@ -2,9 +2,9 @@
|
||||
|
||||
**Task**: AZ-187_device_provisioning_script
|
||||
**Name**: Device Provisioning Script
|
||||
**Description**: Create a shell script that provisions a Jetson device identity (CompanionPC user) during the fuse/flash pipeline
|
||||
**Description**: Interactive shell script that provisions Jetson device identities (CompanionPC users) during the fuse/flash pipeline
|
||||
**Complexity**: 2 points
|
||||
**Dependencies**: None
|
||||
**Dependencies**: AZ-196 (POST /devices endpoint)
|
||||
**Component**: DevOps
|
||||
**Tracker**: AZ-187
|
||||
**Epic**: AZ-181
|
||||
@@ -15,48 +15,47 @@ Each Jetson needs a unique CompanionPC user account for API authentication. This
|
||||
|
||||
## Outcome
|
||||
|
||||
- Single script creates device identity and embeds credentials in the rootfs
|
||||
- Integrates into the fuse/flash pipeline between odmfuse.sh and flash.sh
|
||||
- Interactive `provision_devices.sh` detects connected Jetsons, registers identities via admin API, and runs fuse/flash pipeline
|
||||
- Serial numbers are auto-assigned server-side (azj-0000, azj-0001, ...)
|
||||
- Provisioning runbook documents the full end-to-end flow
|
||||
|
||||
## Scope
|
||||
|
||||
### Included
|
||||
- provision_device.sh: generate device email (azaion-jetson-{serial}@azaion.com), random 32-char password
|
||||
- Call admin API POST /users to create Users row with Role=CompanionPC
|
||||
- Write credentials config file to rootfs image (at known path, e.g., /etc/azaion/device.conf)
|
||||
- Idempotency: re-running for same serial doesn't create duplicate user
|
||||
- Provisioning runbook: step-by-step from unboxing through fusing, flashing, and first boot
|
||||
- `provision_devices.sh`: scan USB for Jetsons in recovery mode, interactive device selection, call admin API `POST /devices` for auto-generated serial/email/password, write credentials to rootfs, fuse, flash
|
||||
- Configuration via `scripts/.env` (git-ignored), template at `scripts/.env.example`
|
||||
- Dependency checks at startup (lsusb, curl, jq, L4T tools, sudo)
|
||||
- Provisioning runbook: step-by-step for multi-device manufacturing flow
|
||||
|
||||
### Excluded
|
||||
- fTPM provisioning (covered by NVIDIA's ftpm_provisioning.sh)
|
||||
- Secure Boot fusing (covered by solution_draft02 Phase 1-2)
|
||||
- OS hardening (covered by solution_draft02 Phase 3)
|
||||
- Admin API user creation endpoint (assumed to exist)
|
||||
- Admin API POST /devices endpoint implementation (AZ-196)
|
||||
|
||||
## Acceptance Criteria
|
||||
|
||||
**AC-1: Script creates CompanionPC user**
|
||||
Given a new device serial AZJN-0042
|
||||
When provision_device.sh is run with serial AZJN-0042
|
||||
Then admin API has a new user azaion-jetson-0042@azaion.com with Role=CompanionPC
|
||||
**AC-1: Script registers device via POST /devices**
|
||||
Given the admin API has the POST /devices endpoint deployed
|
||||
When provision_devices.sh is run and a device is selected
|
||||
Then the admin API creates a new user with auto-assigned serial (e.g. azj-0000) and Role=CompanionPC
|
||||
|
||||
**AC-2: Credentials written to rootfs**
|
||||
Given provision_device.sh completed successfully
|
||||
When the rootfs image is inspected
|
||||
Then /etc/azaion/device.conf contains the email and password
|
||||
Given POST /devices returned serial, email, and password
|
||||
When the provisioning step completes for a device
|
||||
Then `$ROOTFS_DIR/etc/azaion/device.conf` contains the email and password with mode 600
|
||||
|
||||
**AC-3: Device can log in after flash**
|
||||
Given a provisioned and flashed device boots for the first time
|
||||
When the loader reads /etc/azaion/device.conf and calls POST /login
|
||||
Then a valid JWT is returned
|
||||
|
||||
**AC-4: Idempotent re-run**
|
||||
Given provision_device.sh was already run for serial AZJN-0042
|
||||
When it is run again for the same serial
|
||||
Then no duplicate user is created (existing user is reused or updated)
|
||||
**AC-4: Multi-device support**
|
||||
Given multiple Jetsons connected in recovery mode
|
||||
When provision_devices.sh is run
|
||||
Then the user can select individual devices or all, and each is provisioned sequentially
|
||||
|
||||
**AC-5: Runbook complete**
|
||||
Given the provisioning runbook
|
||||
When followed step-by-step on a new Jetson Orin Nano
|
||||
Then the device is fully fused, flashed, provisioned, and can communicate with the admin API
|
||||
When followed step-by-step on new Jetson Orin Nano devices
|
||||
Then the devices are fully fused, flashed, provisioned, and can communicate with the admin API
|
||||
|
||||
@@ -1,66 +0,0 @@
|
||||
# Resources Table & Update Check API
|
||||
|
||||
**Task**: AZ-183_resources_table_update_api
|
||||
**Name**: Resources Table & Update Check API
|
||||
**Description**: Add Resources table to admin API PostgreSQL DB and implement POST /get-update endpoint for fleet OTA updates
|
||||
**Complexity**: 3 points
|
||||
**Dependencies**: None
|
||||
**Component**: Admin API
|
||||
**Tracker**: AZ-183
|
||||
**Epic**: AZ-181
|
||||
|
||||
## Problem
|
||||
|
||||
The fleet update system needs a server-side component that tracks published artifact versions and tells devices what needs updating. CI/CD publishes encrypted artifacts to CDN; the server must store metadata (version, URL, hash, encryption key) and serve it to devices on request.
|
||||
|
||||
## Outcome
|
||||
|
||||
- Resources table stores per-artifact metadata populated by CI/CD
|
||||
- Devices call POST /get-update with their current versions and get back only what's newer
|
||||
- Server-side memory cache handles 2000+ devices polling every 5 minutes without DB pressure
|
||||
|
||||
## Scope
|
||||
|
||||
### Included
|
||||
- Resources table migration (resource_name, dev_stage, architecture, version, cdn_url, sha256, encryption_key, size_bytes, created_at)
|
||||
- POST /get-update endpoint: accepts device's current versions + architecture + dev_stage, returns only newer resources
|
||||
- Server-side memory cache invalidated on CI/CD publish
|
||||
- Internal endpoint or direct DB write for CI/CD to publish new resource versions
|
||||
|
||||
### Excluded
|
||||
- CI/CD pipeline changes (AZ-186)
|
||||
- Loader-side update logic (AZ-185)
|
||||
- Device provisioning (AZ-187)
|
||||
|
||||
## Acceptance Criteria
|
||||
|
||||
**AC-1: Resources table created**
|
||||
Given the admin API database
|
||||
When the migration runs
|
||||
Then the Resources table exists with all required columns
|
||||
|
||||
**AC-2: Update check returns newer resources**
|
||||
Given Resources table has annotations version 2026-04-13
|
||||
When device sends POST /get-update with annotations version 2026-02-25
|
||||
Then response includes annotations with version, cdn_url, sha256, encryption_key, size_bytes
|
||||
|
||||
**AC-3: Current device gets empty response**
|
||||
Given device already has the latest version of all resources
|
||||
When POST /get-update is called
|
||||
Then response is an empty array
|
||||
|
||||
**AC-4: Memory cache avoids repeated DB queries**
|
||||
Given 2000 devices polling every 5 minutes
|
||||
When POST /get-update is called repeatedly
|
||||
Then the latest versions are served from memory cache, not from DB on every request
|
||||
|
||||
**AC-5: Cache invalidated on publish**
|
||||
Given a new resource version is published via CI/CD
|
||||
When the publish endpoint/function completes
|
||||
Then the next POST /get-update call returns the new version
|
||||
|
||||
## Constraints
|
||||
|
||||
- Must integrate with existing admin API (linq2db + PostgreSQL)
|
||||
- encryption_key column must be stored securely (encrypted at rest in DB or via application-level encryption)
|
||||
- Response must include encryption_key only over HTTPS with valid JWT
|
||||
Reference in New Issue
Block a user