-
-
Notifications
You must be signed in to change notification settings - Fork 26
Provide a minimal firmware validator #381
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR introduces a minimal firmware validator called StartupGuard
that monitors system startup and automatically validates firmware for simple use cases. The validator waits for all OTP applications to start, then validates unvalidated firmware, with a 15-minute timeout and heart callback protection against hangs.
- Adds
Nerves.Runtime.StartupGuard
module with heart integration for automatic firmware validation - Enhances firmware validation status checking with new
firmware_validation_status/0
function - Improves KV module error handling to prevent crashes when the GenServer isn't running
Reviewed Changes
Copilot reviewed 9 out of 10 changed files in this pull request and generated 3 comments.
Show a summary per file
File | Description |
---|---|
lib/nerves_runtime/startup_guard.ex | New module implementing firmware validation with heart callbacks and application startup monitoring |
lib/nerves_runtime/application.ex | Conditionally starts StartupGuard based on configuration |
lib/nerves_runtime.ex | Adds firmware_validation_status/0 function and get_expected_started_apps/0 helper |
lib/nerves_runtime/kv.ex | Adds safe_call wrapper to handle GenServer crashes gracefully |
test/nerves_runtime/startup_guard_test.exs | Comprehensive test suite for StartupGuard functionality |
test/nerves_runtime_test.exs | Updates tests to use new firmware_validation_status/0 function |
test/test_helper.exs | Adds Mimic setup for mocking Erlang modules |
mix.exs | Adds Mimic dependency and custom test runner for Erlang module mocking |
README.md | Updates documentation to reflect new StartupGuard functionality and configuration |
|
||
defp get_uptime_minutes() do | ||
{total, _last_call} = :erlang.statistics(:wall_clock) | ||
div(total, 60_000) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[nitpick] The magic number 60_000 should be defined as a module attribute or constant to improve code clarity and maintainability.
div(total, 60_000) | |
div(total, @milliseconds_per_minute) |
Copilot uses AI. Check for mistakes.
8847978
to
da00524
Compare
Since it's going to be possible in the official Nerves systems to try out firmware that needs logic to validate it, there needs to be a simple way for new users to use it. This is a really basic startup guard that waits for all OTP applications in the start script to be running and then validates the running firmware. Applications not starting result in a reboot after 15 minutes which will either revert or go through the process again. A warning message is printed every minute to hopefully clue people into what's happening since it's guaranteed that 15 minutes won't work for everyone.
da00524
to
0fef454
Compare
This is draft since it's a little large for one PR and I may split up for easier review. However, since people are starting to try out auto fail-back with the Raspberry Pi (currently in branches too), it would be nice to start getting feedback on a trimmed down startup guard for automatically validating new firmware images.
The docs really contain everything to enable it and you'll need to use custom systems, so this takes a little work to actually use now. The TL;DR for this code is:
Add the following to your Nerves project's
target.exs
orconfig.exs
:Add then add the following to your project's
rel/vm.args.eex
: