[Vela OTA] Sub-Issue 11+12: Delta update engine + FlashPack Builder CLI#203
Closed
JusterZhu wants to merge 4 commits into
Closed
[Vela OTA] Sub-Issue 11+12: Delta update engine + FlashPack Builder CLI#203JusterZhu wants to merge 4 commits into
JusterZhu wants to merge 4 commits into
Conversation
added 4 commits
May 19, 2026 18:09
…ation (#199) - Add vela-e2e integration test crate with 6 test suites (55 tests) - Suite 1: Watchdog + EventBus — event emission, subscribers, history - Suite 2: Slot Manager + Lifecycle — transitions, metrics, terminal states - Suite 3: Hub Client + Retry + Download — retry exhaustion, checksum, auth - Suite 4: Full Pipeline — phase order, terminal states, config - Suite 5: Error Recovery — space errors, retry behavior, fallback path - Suite 6: Configuration — defaults, custom configs, error conversions - Add SlotManager + SlotLabel types to vela-slotmgr - Fix 40+ pre-existing compilation errors across workspace crates - Fix dependency versions (x509-cert, csbindgen, hmac, ring compat) - Fix platform compatibility (watchdog on Windows via cfg guards) - Fix API mismatches in orchestrator, hub client, download, flashpack
…202) - Add vela-delta crate with sliding-window block-matching algorithm - Binary diff generator: generate_delta(old, new) -> DeltaResult<Vec<u8>> - Patch applier: apply_patch(base, delta) -> DeltaResult<Vec<u8>> - DeltaManifest format for .fpk delta.manifest metadata - VDLT magic header with SHA-256 integrity verification - 19 unit tests including roundtrip, hash verification, edge cases - Integrates with FlashPack PayloadType::Delta
- Add vela-builder binary crate with 5 subcommands - build: construct .fpk from payload with configurable metadata - verify: validate FlashPack structure and display header info - info: detailed FlashPack metadata display (all header fields + SHA-256) - delta: generate binary delta between two files via vela-delta - sign: stub for future PEM key signing integration - Fix import in vela-delta diff.rs
Collaborator
Author
|
Splitting into separate per-issue PRs |
Contributor
There was a problem hiding this comment.
Pull request overview
Adds a new delta patching engine (vela-delta) and a FlashPack builder CLI (vela-builder) to support incremental OTA workflows within the vela-core workspace.
Changes:
- Introduces
vela-deltawith a binary diff/patch format, manifest metadata, and unit tests. - Adds
vela-builderCLI with subcommands to build/inspect/verify FlashPacks and generate deltas. - Registers both crates in the
vela-coreCargo workspace.
Reviewed changes
Copilot reviewed 9 out of 9 changed files in this pull request and generated 8 comments.
Show a summary per file
| File | Description |
|---|---|
| src/vela/vela-core/crates/vela-delta/src/lib.rs | Defines public API, constants, hashing helper, and error types for delta engine. |
| src/vela/vela-core/crates/vela-delta/src/diff.rs | Implements delta generation (sliding-window matching) and delta encoding format. |
| src/vela/vela-core/crates/vela-delta/src/patch.rs | Implements patch application + integrity checks and patch-related tests. |
| src/vela/vela-core/crates/vela-delta/src/manifest.rs | Adds DeltaManifest for recording baseline/target metadata and validation helpers. |
| src/vela/vela-core/crates/vela-delta/Cargo.toml | Declares vela-delta crate dependencies. |
| src/vela/vela-core/crates/vela-builder/src/main.rs | Adds vela-builder CLI entrypoint and subcommands. |
| src/vela/vela-core/crates/vela-builder/Cargo.toml | Declares vela-builder binary crate and dependencies. |
| src/vela/vela-core/Cargo.toml | Adds vela-delta and vela-builder to workspace members. |
| .github/issue-11-body.md | Adds issue template/body documentation for Sub-Issue 11 (delta engine). |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+19
to
+22
| // Validate magic | ||
| if delta.len() < 68 { | ||
| return Err(DeltaError::InvalidFormat( | ||
| "delta file too small — missing header".into(), |
Comment on lines
+125
to
+133
| Instruction::Copy { offset, length } => { | ||
| let start = *offset as usize; | ||
| let end = start + *length as usize; | ||
| if end > base.len() { | ||
| return Err(DeltaError::InvalidFormat(format!( | ||
| "COPY instruction {i}: offset {start} + length {length} exceeds base size {}", | ||
| base.len() | ||
| ))); | ||
| } |
Comment on lines
+112
to
+127
| // Estimate target size from COPY+INSERT lengths | ||
| let target_size: usize = instructions | ||
| .iter() | ||
| .map(|i| match i { | ||
| Instruction::Copy { length, .. } => *length as usize, | ||
| Instruction::Insert { length, .. } => *length as usize, | ||
| }) | ||
| .sum(); | ||
|
|
||
| let mut target = Vec::with_capacity(target_size); | ||
|
|
||
| for (i, instr) in instructions.iter().enumerate() { | ||
| match instr { | ||
| Instruction::Copy { offset, length } => { | ||
| let start = *offset as usize; | ||
| let end = start + *length as usize; |
Comment on lines
+100
to
+104
| debug!( | ||
| parsed = pos, | ||
| total = data.len(), | ||
| "Extra bytes after instructions (ignored)" | ||
| ); |
Comment on lines
+77
to
+86
| /// Generate a binary delta patch from `old` to `new`. | ||
| #[instrument(skip(old, new), fields(old_len = old.len(), new_len = new.len()))] | ||
| pub fn generate_delta(old: &[u8], new: &[u8]) -> DeltaResult<Vec<u8>> { | ||
| let instructions = if old.is_empty() { | ||
| vec![Instruction::Insert { length: new.len() as u32, data: new.to_vec() }] | ||
| } else if new.is_empty() { | ||
| return Err(DeltaError::InvalidFormat("cannot generate delta for empty target".into())); | ||
| } else { | ||
| sliding_window_diff(old, new) | ||
| }; |
Comment on lines
+49
to
+59
| fn print_usage(prog: &str) { | ||
| eprintln!("FlashPack Builder CLI — Vela OTA update bundle tool\n"); | ||
| eprintln!("Usage: {prog} <command> [args...]\n"); | ||
| eprintln!("Commands:"); | ||
| eprintln!(" build <payload> <output.fpk> Build a FlashPack bundle from a payload file"); | ||
| eprintln!(" [--name <NAME>] [--version <VER>] [--requires <VER>]"); | ||
| eprintln!(" sign <input.fpk> <key.pem> <output.fpk> Sign a FlashPack bundle"); | ||
| eprintln!(" verify <input.fpk> <key.pub> Verify a FlashPack signature"); | ||
| eprintln!(" info <input.fpk> Display FlashPack metadata and structure"); | ||
| eprintln!(" delta <old> <new> <output.delta> Generate binary delta between two files"); | ||
| } |
Comment on lines
+75
to
+84
| let mut i = 2; | ||
| while i < args.len() { | ||
| match args[i].as_str() { | ||
| "--name" => { i += 1; if i < args.len() { bundle_name = args[i].clone(); } } | ||
| "--version" => { i += 1; if i < args.len() { bundle_version = args[i].clone(); } } | ||
| "--requires" => { i += 1; if i < args.len() { requires_version = args[i].clone(); } } | ||
| _ => return Err(format!("unknown flag: {}", args[i])), | ||
| } | ||
| i += 1; | ||
| } |
Comment on lines
+83
to
+95
| /// Validate that the device's current version matches the required baseline. | ||
| pub fn validate_baseline( | ||
| &self, | ||
| device_version: &str, | ||
| ) -> Result<(), String> { | ||
| if device_version != self.requires_version { | ||
| return Err(format!( | ||
| "Baseline version mismatch: device has {}, delta requires {}", | ||
| device_version, self.requires_version | ||
| )); | ||
| } | ||
| Ok(()) | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Sub-Issue #11: Delta Update Engine
New \�ela-delta\ crate with sliding-window binary diff/patch:
Sub-Issue #12: FlashPack Builder CLI
New \�ela-builder\ binary crate with 5 subcommands:
Also fixed 40+ pre-existing compilation errors across the workspace.
Closes #202