Writes a bundle a device installs from with no network:
Precompiled.install(:recon, source: "file:///media/usb/precompiled").
It plans on this host exactly as the device would, from the device's
facts, and copies only what that plan needs.
mix precompiled.bundle PKG[@REQ]... --out DIR (--system NAME@VSN | --pure) \
--otp N --elixir V [--cpu C] [--source URL] [--root FILE]
mix precompiled.bundle PKG[@REQ]... --out DIR --device-report FILE \
[--source URL] [--root FILE]DIR (new, or empty) gets the API's own layout:
root.json- the root the batch verified under: the source's served root when it chains from the trusted one, else the trusted root itself (--root, or the root this library ships);batch.json- the signed batch, byte for byte as verified;v2/manifests/<pkg>.json- for each planned package, the exact bytes the batch's hash names (manifests/<pkg>.jsonfor a format-1 one);files/<sha256>- every file of every planned build.
Every byte is checked against its signed hash before it is written, and
the bundle appears in DIR only once all of it has been. No key, and
nothing that is not in the plan, is ever written.
The device facts come from the flags: --system (or --pure for a
device with no Nerves system, which takes pure_elixir builds only),
--otp, --elixir and --cpu (default aarch64-unknown-linux-gnu),
with kernel, stdlib, elixir, logger and crypto present. Or they
come from --device-report FILE, the JSON that
Precompiled.install(..., dry_run: true, report: path) writes on the
device: its system, OTP, Elixir, CPU and present apps, so the bundle
holds what that device would fetch. With it, --system, --pure,
--otp, --elixir and --cpu are ignored. Apps the device has, by
name and exact version, are not bundled. The device checks everything
again when it installs.
--source is the API root (default the official one) and --root the
trust anchor (default the shipped root.json).
A bundle's batch.json expires 24 hours after it was issued. For a
device that stays offline longer, the holder of the root's offline key
signs the bundle with mix portal.precompiled.sign_offline, within a day
of the batch's issue, passing the current production root.json as
--root: the bundle's root.json must be that root.