From cf7dc9df504f70604f5dfea151dd41777c8636fa Mon Sep 17 00:00:00 2001 From: Lars Wikman Date: Wed, 8 Jan 2025 15:04:52 +0100 Subject: [PATCH] Add hook for post-processing filesystem Providing the config for :nerves, :firmware and the key `post_processing_script` will now allow `mix firmware` to pass a flag to rel2fw.sh that tells it what script to run when the filesystem is finalized. This is the hook required to do filesystem signing for dm-verity and any other similar schemes. Added some info about it to the advanced configuration guide. Ideally expanded to be a signing guide later when that has been more fully built out. --- guides/advanced/advanced-configuration.md | 22 ++++++++++++++++++++++ lib/mix/tasks/firmware.ex | 13 ++++++++++++- 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/guides/advanced/advanced-configuration.md b/guides/advanced/advanced-configuration.md index 39daeb7c..6a0daa8d 100644 --- a/guides/advanced/advanced-configuration.md +++ b/guides/advanced/advanced-configuration.md @@ -465,3 +465,25 @@ You can modify the kernel parameters for your application or custom Nerves system by copying the default `sysctl.conf` file to your `rootfs_overlay/etc` directory and making the desired changes. Use `System.cmd/3` to run `sysctl` to change settings after initialization. + +## Post-processing or signing the root filesystem + +When generating a Nerves firmware there is stage where `mix firmware` takes +your application code, makes a release and adds that release into the root +filesystem. After this the root filesystem is complete. This is the point where +you could generate signatures, hashes and such for a tool like dm-verity. To +allow this Nerves provides an entrypoint for a script that you can add to your +Nerves firmware config, such as `config/target.exs` or for the specific target. + +``` +config :nerves, + firmware: [ + post_processing_script: Path.expand("./scripts/sign.sh") + ] +``` + +Create your desired `sign.sh` in a `scripts` directory in your Nerves project +or put it wherever you prefer. The configuration file is not running with the +Nerves environment variables. The script will have access to them however. The +script will receive the filepath of the filesystem as the first argument and +this allows you to sign it or otherwise amend it. diff --git a/lib/mix/tasks/firmware.ex b/lib/mix/tasks/firmware.ex index 108f27c8..90d87fda 100644 --- a/lib/mix/tasks/firmware.ex +++ b/lib/mix/tasks/firmware.ex @@ -134,10 +134,21 @@ defmodule Mix.Tasks.Firmware do fwup_conf -> ["-c", Path.join(File.cwd!(), fwup_conf)] end + post_processing_script = + case firmware_config[:post_processing_script] do + nil -> [] + script when is_binary(script) -> ["-s", script] + end + fw = ["-f", fw_out] release_path = Path.join(Mix.Project.build_path(), "rel/#{otp_app}") output = [release_path] - args = args ++ fwup_conf ++ rootfs_overlays ++ fw ++ rootfs_priorities ++ output + + args = + args ++ + fwup_conf ++ + rootfs_overlays ++ fw ++ rootfs_priorities ++ post_processing_script ++ output + env = [{"MIX_BUILD_PATH", Mix.Project.build_path()} | standard_fwup_variables(config)] set_provisioning(firmware_config[:provisioning])