Repository navigation
Expand file tree
/
Copy pathContainerfile.el10
More file actions
291 lines (264 loc) · 14.2 KB
/
Copy pathContainerfile.el10
File metadata and controls
291 lines (264 loc) · 14.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
ARG BASE_IMAGE
# NOTE: ENABLE_HWE and ENABLE_NVIDIA are passed by the Justfile _build helper
# to every Containerfile for interface uniformity. The main Containerfile never
# gates on them — HWE/NVIDIA behavior is controlled by Containerfile selection
# (main vs Containerfile.hwe vs Containerfile.nvidia) and AKMODS_VERSION dispatch.
ARG ENABLE_HWE="${ENABLE_HWE:-0}"
ARG ENABLE_NVIDIA="${ENABLE_NVIDIA:-0}"
ARG ENABLE_SSHD="${ENABLE_SSHD:-0}"
ARG DESKTOP_FLAVOR="${DESKTOP_FLAVOR:-gnome}"
ARG TUNAOS_IMAGE_FLAVOR
ARG IMAGE_NAME_VARIANT
# SECURITY: Defaults use placeholder tags that MUST be overridden at build time.
# The Justfile and build engine always pin these to specific SHA256
# digests (e.g., ghcr.io/projectbluefin/common@sha256:...). Direct podman build
# without --build-arg overrides will fail with a clear error.
ARG COMMON_IMAGE_REF="ghcr.io/projectbluefin/common:unpinned-must-override"
ARG BREW_IMAGE_REF="ghcr.io/ublue-os/brew:unpinned-must-override"
# projectbluefin/utah-packages: Bluefin's GNOME 51 for Hummingbird as a dnf
# repository inside an OCI image (/repository, createrepo_c output; the image
# is cosign-signed and pinned by digest in image-versions.yaml). Only the
# gnome stage of a hummingbird build reads it -- bind-mounted, never copied,
# so no image carries 500 MB of RPMs -- through the file:// repo declared in
# manifests/desktops/gnome.yaml's hummingbird section
# (tuna-os/tunaos-packages#629).
ARG UTAH_PACKAGES_IMAGE_REF="ghcr.io/projectbluefin/utah-packages:unpinned-must-override"
# tuna-os/tunaos-packages: this project's own GNOME 50 for EL10, from the
# gnome50-el10-x86_64 build chain, in the same shape -- a createrepo_c
# repository inside an OCI image (/repository), pinned by digest in
# image-versions.yaml. Only the gnome stage of an EL10 build reads it, through
# the file:// repo declared in manifests/desktops/gnome.yaml's el10 section.
# Bind-mounted, never copied: EL10 images do not carry the RPMs they were
# built from.
ARG GNOME50_EL10_PACKAGES_IMAGE_REF="ghcr.io/tuna-os/tunaos-packages:unpinned-must-override"
FROM ${COMMON_IMAGE_REF} AS common
FROM ${BREW_IMAGE_REF} AS brew
FROM ${UTAH_PACKAGES_IMAGE_REF} AS utah-packages
FROM ${GNOME50_EL10_PACKAGES_IMAGE_REF} AS gnome50-el10-packages
# Context layer combines build-time dependencies and configuration files.
# NOTE: no zirconium content here — the context stage feeds EVERY desktop
# stage, and Zirconium (DMS/Niri) files belong only on niri images, the same
# way Aurora files inform kde and Bluefin files inform gnome. The zirconium
# payload is laid down by build_scripts/install-zirconium.sh in the niri
# stage (sourced from the zirconium source tarball, not an OCI stage).
FROM scratch as context
COPY system_files /files
COPY --from=brew /system_files /files
COPY --from=common /system_files/shared /files
COPY system_files_overrides /overrides
COPY build_scripts /build_scripts
COPY manifests /manifests
COPY tunaos.toml /tunaos.toml
# Only Tuna's curated files: install-desktop.sh applies experiences/<desktop>
# whenever it is present, and the other desktops' trees are not part of the
# RPM images today.
COPY experiences/tuna /experiences/tuna
COPY image-versions.yaml /image-versions.yaml
# ==============================================================================
# Base stage (no DE) - Shared layer for all variants
# ==============================================================================
FROM ${BASE_IMAGE} AS base-no-de
ARG BASE_IMAGE
ARG ENABLE_HWE
ARG ENABLE_NVIDIA
ARG ENABLE_SSHD
ARG DESKTOP_FLAVOR
ARG TUNAOS_IMAGE_FLAVOR
ENV TUNAOS_IMAGE_FLAVOR=${TUNAOS_IMAGE_FLAVOR}
ARG IMAGE_NAME
ARG IMAGE_VENDOR
ARG IMAGE_NAME_VARIANT
ARG IMAGE_REGISTRY="ghcr.io"
ARG TUNAOS_PUBLISHED_IMAGE_REF
# RHSM credentials are NOT declared as ARG here — they're passed via
# `--secret id=rhsm` from the Justfile and consumed in the
# install_base_packages_no_de RUN below. Keeping them out of ARG/ENV
# ensures they never appear in `podman history --no-trunc` or in the
# final image config (`podman inspect`).
ENV BASE_IMAGE=${BASE_IMAGE}
ENV IMAGE_NAME=${IMAGE_NAME}
ENV IMAGE_VENDOR=${IMAGE_VENDOR}
ENV IMAGE_NAME_VARIANT=${IMAGE_NAME_VARIANT}
ENV IMAGE_REGISTRY=${IMAGE_REGISTRY}
ENV TUNAOS_PUBLISHED_IMAGE_REF=${TUNAOS_PUBLISHED_IMAGE_REF}
ENV ENABLE_HWE=${ENABLE_HWE}
ENV ENABLE_NVIDIA=${ENABLE_NVIDIA}
ENV ENABLE_SSHD=${ENABLE_SSHD}
# Preserve desktop flavor so base-stage scripts don't fall back to GNOME defaults
ENV DESKTOP_FLAVOR=${DESKTOP_FLAVOR}
# Every build_scripts/*.sh RUN below uses
# `--mount=type=bind,from=context,source=/,target=/run/context` to invoke
# scripts without a COPY layer — but that bind mount's content is NOT part
# of buildah's cache-key hashing, so editing a script alone never
# invalidates the cached layer that ran it (confirmed: a runner reused a
# pre-fix cached layer for install_base_packages_no_de verbatim after the
# script changed, silently shipping the old package list). An ENV set here
# changes the cache key for every RUN after it, so hashing build_scripts/
# content into it forces correct invalidation — independent of
# SHA_HEAD_SHORT (declared much later, deliberately, so cache still hits
# across commits that don't touch these scripts at all).
ARG BUILD_SCRIPTS_HASH
ENV BUILD_SCRIPTS_HASH=${BUILD_SCRIPTS_HASH}
# Force layer cache invalidation when build scripts change
RUN echo "${BUILD_SCRIPTS_HASH}" > /dev/null
# Ensure /opt is a real directory so tmpfs mounts work in all subsequent stages
RUN rm -rf /opt && mkdir /opt
# Copy system files and apply TunaOS customizations
RUN --mount=type=tmpfs,dst=/opt --mount=type=tmpfs,dst=/tmp \
--mount=type=tmpfs,dst=/boot \
--mount=type=bind,from=context,source=/,target=/run/context \
/run/context/build_scripts/00-copy-files.sh
RUN --mount=type=tmpfs,dst=/opt --mount=type=tmpfs,dst=/tmp \
--mount=type=tmpfs,dst=/boot \
--mount=type=bind,from=context,source=/,target=/run/context \
/run/context/build_scripts/01-workarounds.sh
# Install base packages WITHOUT DE.
# The optional RHSM secret is mounted at /run/secrets/rhsm only inside this
# RUN. It contains `export RHSM_USER=…` etc.; install_base_packages_no_de
# sources it if present. The mount is also gated by `required=false` so
# non-RHEL builds (which never pass --secret) succeed unchanged.
RUN --mount=type=tmpfs,dst=/opt --mount=type=tmpfs,dst=/tmp \
--mount=type=tmpfs,dst=/boot \
--mount=type=bind,from=context,source=/,target=/run/context \
--mount=type=secret,id=rhsm,target=/run/secrets/rhsm,required=false \
/run/context/build_scripts/10-base-packages.sh
RUN --mount=type=tmpfs,dst=/opt --mount=type=tmpfs,dst=/tmp \
--mount=type=tmpfs,dst=/boot \
--mount=type=bind,from=context,source=/,target=/run/context \
/run/context/build_scripts/20-packages.sh && \
/run/context/build_scripts/30-image-packages.sh
RUN --mount=type=tmpfs,dst=/opt --mount=type=tmpfs,dst=/tmp \
--mount=type=tmpfs,dst=/boot \
--mount=type=bind,from=context,source=/,target=/run/context \
/run/context/build_scripts/26-packages-post.sh
RUN --mount=type=tmpfs,dst=/opt --mount=type=tmpfs,dst=/tmp \
--mount=type=tmpfs,dst=/boot \
--mount=type=bind,from=context,source=/,target=/run/context \
/run/context/build_scripts/40-services.sh
# SHA_HEAD_SHORT changes on every commit. Declared HERE (not at the top of
# the stage) so only the layers from this point down rebuild per commit —
# with it in the early ENV block, the layer cache could never hit across
# commits and the expensive dnf layers above rebuilt every time.
ARG SHA_HEAD_SHORT
ENV SHA_HEAD_SHORT=${SHA_HEAD_SHORT}
RUN --mount=type=tmpfs,dst=/opt --mount=type=tmpfs,dst=/tmp \
--mount=type=tmpfs,dst=/boot \
--mount=type=bind,from=context,source=/,target=/run/context \
/run/context/build_scripts/90-image-info.sh
# Per-variant overrides. This is what delivers system_files_overrides/<variant>/
# into the image -- notably hummingbird's 50-hummingbird.toml, without which
# `bootc install to-disk` aborts installing GRUB onto xfs.
RUN --mount=type=tmpfs,dst=/opt --mount=type=tmpfs,dst=/tmp \
--mount=type=tmpfs,dst=/boot \
--mount=type=bind,from=context,source=/,target=/run/context \
/run/context/build_scripts/92-variant-customizations.sh
RUN --mount=type=tmpfs,dst=/opt --mount=type=tmpfs,dst=/tmp \
--mount=type=tmpfs,dst=/boot \
--mount=type=bind,from=context,source=/,target=/run/context \
/run/context/build_scripts/99-cleanup.sh
# EL10 is meant to stay traditional ostree (bootupctl + GRUB), not composefs
# (tunaOS#748). Unlike the non-Fedora bases (see
# build_scripts/bootc/sandbox/usr/lib/ostree/prepare-root.conf, copied by
# Containerfile.ubuntu et al. to explicitly turn composefs ON), nothing in
# this Containerfile ever touched prepare-root.conf — so whatever
# quay.io/almalinuxorg/almalinux-bootc ships by default silently won any
# time upstream's default changed. Pin it explicitly instead of inheriting
# a default that already drifted once and broke wootc's Phase-2 boot
# (tuna-os/wootc#28: composefs images skip bootupctl/GRUB entirely, so a
# boot without the composefs karg drops to an emergency shell).
RUN printf '[composefs]\nenabled = no\n\n[sysroot]\nreadonly = true\n' > /usr/lib/ostree/prepare-root.conf
# ==============================================================================
# Desktop Variant Stages
# Each stage ends with the /opt symlink so chunkah can be run against them.
# ==============================================================================
FROM base-no-de AS base
# Base image with no DE - /opt made writeable via symlink
RUN rm -rf /opt && ln -s /var/opt /opt
FROM base-no-de AS gnome
# Bluefin LTS experience payload is scoped to GNOME images.
COPY --from=common /system_files/bluefin /
# /run/utah-packages and /run/gnome50-el10-packages are read only when the
# manifest's OS section declares a repo there -- hummingbird declares the
# first, el10 the second; on every other variant each is an unused read-only
# directory for the duration of this one RUN.
RUN --mount=type=tmpfs,dst=/opt --mount=type=tmpfs,dst=/tmp \
--mount=type=tmpfs,dst=/boot \
--mount=type=bind,from=context,source=/,target=/run/context \
--mount=type=bind,from=utah-packages,source=/repository,target=/run/utah-packages \
--mount=type=bind,from=gnome50-el10-packages,source=/repository,target=/run/gnome50-el10-packages \
/run/context/build_scripts/desktop/install-desktop.sh gnome
# Desktop packages (e.g. redhat-release / almalinux-release / centos-stream-release)
# can overwrite /usr/lib/os-release during install-desktop.sh, blowing away
# VERSION_CODENAME written by 90-image-info.sh in base-no-de. Re-run it here
# to ensure branding is preserved on standard desktop cells.
RUN --mount=type=tmpfs,dst=/opt --mount=type=tmpfs,dst=/tmp \
--mount=type=tmpfs,dst=/boot \
--mount=type=bind,from=context,source=/,target=/run/context \
/run/context/build_scripts/90-image-info.sh
RUN rm -rf /opt && ln -s /var/opt /opt
FROM base-no-de AS cosmic
RUN --mount=type=tmpfs,dst=/opt --mount=type=tmpfs,dst=/tmp \
--mount=type=tmpfs,dst=/boot \
--mount=type=bind,from=context,source=/,target=/run/context \
/run/context/build_scripts/desktop/install-desktop.sh cosmic
RUN --mount=type=tmpfs,dst=/opt --mount=type=tmpfs,dst=/tmp \
--mount=type=tmpfs,dst=/boot \
--mount=type=bind,from=context,source=/,target=/run/context \
/run/context/build_scripts/90-image-info.sh
RUN rm -rf /opt && ln -s /var/opt /opt
FROM base-no-de AS kde
# projectbluefin/common publishes shared and Bluefin payloads; it does not
# contain a /system_files/aurora tree on either architecture. The Aurora
# experience is assembled by the KDE manifest and validated below rather than
# relying on a nonexistent cross-image path.
RUN --mount=type=tmpfs,dst=/opt --mount=type=tmpfs,dst=/tmp \
--mount=type=tmpfs,dst=/boot \
--mount=type=bind,from=context,source=/,target=/run/context \
/run/context/build_scripts/desktop/install-desktop.sh kde
RUN --mount=type=tmpfs,dst=/opt --mount=type=tmpfs,dst=/tmp \
--mount=type=tmpfs,dst=/boot \
--mount=type=bind,from=context,source=/,target=/run/context \
/run/context/build_scripts/90-image-info.sh
RUN rm -rf /opt && ln -s /var/opt /opt
FROM base-no-de AS niri
# Zirconium (DMS/Niri upstream) config payload — niri images only. Sourced
# from the zirconium-dev/zirconium source tarball (mkosi.extra tree) rather
# than the published OCI image, pinned to the commit in image-versions.yaml
# (downloads.zirconium_src) so niri builds are reproducible.
RUN --mount=type=tmpfs,dst=/opt --mount=type=tmpfs,dst=/tmp \
--mount=type=tmpfs,dst=/boot \
--mount=type=bind,from=context,source=/,target=/run/context \
/run/context/build_scripts/install-zirconium.sh
RUN --mount=type=tmpfs,dst=/opt --mount=type=tmpfs,dst=/tmp \
--mount=type=tmpfs,dst=/boot \
--mount=type=bind,from=context,source=/,target=/run/context \
/run/context/build_scripts/desktop/install-desktop.sh niri
RUN --mount=type=tmpfs,dst=/opt --mount=type=tmpfs,dst=/tmp \
--mount=type=tmpfs,dst=/boot \
--mount=type=bind,from=context,source=/,target=/run/context \
/run/context/build_scripts/90-image-info.sh
RUN rm -rf /opt && ln -s /var/opt /opt
FROM base-no-de AS xfce
RUN --mount=type=tmpfs,dst=/opt --mount=type=tmpfs,dst=/tmp \
--mount=type=tmpfs,dst=/boot \
--mount=type=bind,from=context,source=/,target=/run/context \
/run/context/build_scripts/desktop/install-desktop.sh xfce
RUN --mount=type=tmpfs,dst=/opt --mount=type=tmpfs,dst=/tmp \
--mount=type=tmpfs,dst=/boot \
--mount=type=bind,from=context,source=/,target=/run/context \
/run/context/build_scripts/90-image-info.sh
RUN rm -rf /opt && ln -s /var/opt /opt
# Tuna Desktop on the RPM bases (tuna-os/tuna-desktop ADR 0008, epic #577):
# EL10 (yellowfin, albacore, skipjack), Fedora 44 (bonito) and ELN (wahoo).
# The package and the pieces their bases lack come from the TunaOS factory's
# signed repositories, declared per target in manifests/desktops/tuna.yaml.
FROM base-no-de AS tuna
RUN --mount=type=tmpfs,dst=/opt --mount=type=tmpfs,dst=/tmp \
--mount=type=tmpfs,dst=/boot \
--mount=type=bind,from=context,source=/,target=/run/context \
/run/context/build_scripts/desktop/install-desktop.sh tuna
RUN --mount=type=tmpfs,dst=/opt --mount=type=tmpfs,dst=/tmp \
--mount=type=tmpfs,dst=/boot \
--mount=type=bind,from=context,source=/,target=/run/context \
/run/context/build_scripts/90-image-info.sh
RUN rm -rf /opt && ln -s /var/opt /opt