max / alloy
| 1 | #!/usr/bin/env bash |
| 2 | # |
| 3 | # host-recipe.sh — the per-machine mint recipe both image builders read. |
| 4 | # |
| 5 | # Sourced by build/build-image.sh and build/build-iso.sh alongside |
| 6 | # build/build-stamp.sh and build/privilege.sh. |
| 7 | # |
| 8 | # The dials that decide what a machine can do (PROFILE, LANGS, DB) all default |
| 9 | # to the smallest thing that boots. LANGS defaults to empty, so a default mint |
| 10 | # carries no compiler at all, and the C toolchain leaves with it. That is the |
| 11 | # right default for an image whose job is to run software, and it is a trap for |
| 12 | # the three machines in this tree that build it: a forgotten flag produces a |
| 13 | # build host that boots, looks healthy, and cannot compile. |
| 14 | # |
| 15 | # So the dials live in a file per machine. The difference between two machines |
| 16 | # is then a diff rather than a memory, and `--host fw13` is what a mint is |
| 17 | # asked for rather than four flags somebody has to remember in the right order. |
| 18 | # |
| 19 | # Format: KEY=VALUE, one per line. Blank lines and # comments are ignored, and |
| 20 | # so is trailing whitespace. Quotes are not stripped, because no dial takes a |
| 21 | # value that needs them. |
| 22 | # |
| 23 | # A value of the form @path reads the file instead. That exists for |
| 24 | # ALLOY_SSH_KEY: a machine that is reinstalled repeatedly should not need its |
| 25 | # key pasted in at each mint, and the recipe is committed to a public repo, so |
| 26 | # it names where the key lives rather than carrying it. ~ is expanded; a |
| 27 | # missing file is an error, since a medium minted with no key silently becomes |
| 28 | # one that needs somebody at the keyboard. |
| 29 | # |
| 30 | # Every key must name an ARG the Containerfile declares. That is checked here, |
| 31 | # against the Containerfile itself rather than a list kept in step by hand, |
| 32 | # because a typo'd key is silently dropped by podman and would mint exactly the |
| 33 | # image this file exists to prevent. |
| 34 | # |
| 35 | # Two reserved keys are not build args, because what they name is not something |
| 36 | # the Containerfile can be told. Both are consumed by build/build-iso.sh and |
| 37 | # ignored by build/build-image.sh. |
| 38 | # |
| 39 | # ARCH the medium's architecture. Not a cross-build: a machine builds its |
| 40 | # own medium, per the standing rule that nothing here cross-compiles. |
| 41 | # UPDATE_TARGET where `bootc upgrade` fetches from on a machine installed |
| 42 | # from this medium. Without one the installer writes the compiled-in |
| 43 | # public registry, which install/image.rs calls a deliberate dead |
| 44 | # end, and updates_scheduled() leaves the timer disabled because it |
| 45 | # reads the same absent kernel parameter. So a machine minted without |
| 46 | # it cannot be fixed without a `bootc switch` typed at the machine or |
| 47 | # a second medium, at the moment it is newest. It was a flag anyone |
| 48 | # could forget; a recipe key is a machine's own answer, kept. |
| 49 | # NVIDIA yes to install the derived alloy-nvidia image rather than Alloy |
| 50 | # itself. The NVIDIA module is not a package the shipped Containerfile |
| 51 | # can add: it has to be compiled against one exact kernel, so it lives |
| 52 | # in a thin image `FROM` that kernel's digest (build/build-nvidia.sh, |
| 53 | # ruled 2026-08-30 on alloy `2a382a75`). A dial would kernel-lock the |
| 54 | # shipped image; a recipe key says which machine's medium carries the |
| 55 | # derived one. |
| 56 | |
| 57 | # Read a recipe into a BUILD_ARGS array, and set HOST_ARCH from a recipe that |
| 58 | # names one. Recipe args go in before anything the caller typed, so an explicit |
| 59 | # `--build-arg` on the command line is the last value podman sees and wins. |
| 60 | # |
| 61 | # Usage: host_recipe_args NAME BUILD_ARGS (the array's NAME, not its contents) |
| 62 | |
| 63 | |
| 64 | |
| 65 | |
| 66 | |
| 67 | |
| 68 | [ || { |
| 69 | |
| 70 | |
| 71 | && | | )" >&2 |
| 72 | |
| 73 | } |
| 74 | |
| 75 | HOST_ARCH="" |
| 76 | HOST_NVIDIA="" |
| 77 | HOST_UPDATE_TARGET="" |
| 78 | |
| 79 | |
| 80 | while || [; do |
| 81 | line="" |
| 82 | line="" |
| 83 | [ || continue |
| 84 | case "" in |
| 85 | *=*) ;; |
| 86 | *) ; ;; |
| 87 | esac |
| 88 | key="" |
| 89 | value="" |
| 90 | case "" in |
| 91 | @*) |
| 92 | |
| 93 | case "" in "~/"*) path="/" ;; esac |
| 94 | [ || { |
| 95 | |
| 96 | |
| 97 | } |
| 98 | value="" |
| 99 | [ || { |
| 100 | |
| 101 | |
| 102 | } |
| 103 | ;; |
| 104 | esac |
| 105 | if [; then |
| 106 | HOST_ARCH="" |
| 107 | continue |
| 108 | fi |
| 109 | if [; then |
| 110 | HOST_UPDATE_TARGET="" |
| 111 | continue |
| 112 | fi |
| 113 | if [; then |
| 114 | case "" in |
| 115 | yes|no) HOST_NVIDIA="" ;; |
| 116 | *) ; ;; |
| 117 | esac |
| 118 | continue |
| 119 | fi |
| 120 | || { |
| 121 | |
| 122 | |
| 123 | } |
| 124 | recipe+=(--build-arg "=") |
| 125 | done |
| 126 | |
| 127 | out=("" "") |
| 128 | } |
| 129 |