Current section

Files

Jump to
nerves lib mix tasks firmware.unpack.ex
Raw

lib/mix/tasks/firmware.unpack.ex

defmodule Mix.Tasks.Firmware.Unpack do
use Mix.Task
import Mix.Nerves.Utils
alias Mix.Nerves.Preflight
@shortdoc "Unpack a firmware bundle for inspection"
@moduledoc """
Unpack the firmware so that its contents can be inspected locally.
## Usage
mix firmware.unpack [output directory]
If not supplied, the output directory will be based off the OTP application
name.
## Examples
```
# Create a firmware bundle. It will be under the _build directory
mix firmware
# Unpack it
mix firmware.unpack firmware_contents
# Inspect it
ls firmware_contents
```
"""
@impl true
def run([output_path]) do
Preflight.check!()
debug_info("Nerves Firmware Unpack")
config = Mix.Project.config()
otp_app = config[:app]
target = mix_target()
images_path =
(config[:images_path] || Path.join([Mix.Project.build_path(), "nerves", "images"]))
|> Path.expand()
_ = check_nerves_system_is_set!()
_ = check_nerves_toolchain_is_set!()
fw = "#{images_path}/#{otp_app}.fw"
unless File.exists?(fw) do
Mix.raise("Firmware for target #{target} not found at #{fw} run `mix firmware` to build")
end
unpack(fw, output_path)
end
def run([]) do
config = Mix.Project.config()
otp_app = config[:app]
target = mix_target()
file = "#{otp_app}-#{target}"
run([file])
end
def run(_args) do
Mix.raise("""
mix firmware.unpack [output path]
See mix help firmware.unpack for more info
""")
Mix.Task.run("help", ["firmware.unpack"])
end
defp unpack(fw, output_path) do
abs_output_path = Path.expand(output_path)
rootfs_output_path = Path.join(abs_output_path, "rootfs")
rootfs_image = Path.join([abs_output_path, "data", "rootfs.img"])
Mix.shell().info("Unpacking to #{output_path}...")
_ = File.rm_rf!(abs_output_path)
File.mkdir_p!(abs_output_path)
{_, 0} = shell("unzip", [fw, "-d", abs_output_path])
{_, 0} = shell("unsquashfs", ["-d", rootfs_output_path, rootfs_image])
:ok
end
end