| 967 |
967 |
|
# `host`. flatpak is the third and is client-only, since `sandboxed`
|
| 968 |
968 |
|
# exists to run desktop applications through portals.
|
| 969 |
969 |
|
podman \
|
| 970 |
|
- |
# gopass is the password manager, on its age backend, synced by git
|
| 971 |
|
- |
# (decided 2026-07-30). Fedora main carries it at 1.16.1; no COPR.
|
| 972 |
|
- |
# It needs no gpg on the age backend, and the git half is the `git`
|
| 973 |
|
- |
# already named below. A CLI with no graphical half, so it is base.
|
|
970 |
+ |
# gopass is NOT here. It moved to the client block on 2026-08-17,
|
|
971 |
+ |
# with gnome-keyring, which it always should have sat beside: a
|
|
972 |
+ |
# personal password store is for the person at the machine, and a
|
|
973 |
+ |
# headless build host has no use for one. It took `fish` with it,
|
|
974 |
+ |
# which is 39.3 MiB gopass hard-requires and nothing else in the
|
|
975 |
+ |
# image wants — see the note beside it there.
|
| 974 |
976 |
|
#
|
| 975 |
|
- |
# gnome-keyring, its Secret Service counterpart, is client-only: it
|
| 976 |
|
- |
# is the D-Bus provider desktop applications resolve to, and there is
|
| 977 |
|
- |
# no session bus to hold it on a headless box.
|
| 978 |
|
- |
gopass \
|
| 979 |
977 |
|
# git. Not in the base. aliases.nu ships six git aliases, helix's
|
| 980 |
978 |
|
# diff gutters need it, docs/STACK.md sells EDITOR=hx on git commit
|
| 981 |
979 |
|
# messages, and the stated audience is developers. The full package
|
| 1170 |
1168 |
|
# credentials for daemons, no interactive component.
|
| 1171 |
1169 |
|
gnome-keyring \
|
| 1172 |
1170 |
|
gnome-keyring-pam \
|
|
1171 |
+ |
# gopass is the other half of that sentence: gnome-keyring is the
|
|
1172 |
+ |
# API programs call, gopass is where a person keeps their own
|
|
1173 |
+ |
# logins (docs/STACK.md#secrets). age backend, synced by git,
|
|
1174 |
+ |
# decided 2026-07-30 and re-taken 2026-08-17 on the question of
|
|
1175 |
+ |
# what to build a house GUI over: a directory of age-encrypted
|
|
1176 |
+ |
# files is git-native, so a concurrent edit is a conflict on one
|
|
1177 |
+ |
# secret with a diff, and it reuses the age identity the sops
|
|
1178 |
+ |
# migration already requires. A single-blob vault (KDBX) syncs as
|
|
1179 |
+ |
# two silent copies, which is the failure this stack keeps
|
|
1180 |
+ |
# rejecting.
|
|
1181 |
+ |
#
|
|
1182 |
+ |
# HERE RATHER THAN IN THE BASE, moved 2026-08-17. It is a personal
|
|
1183 |
+ |
# store for the person at the machine, and it costs `fish`: Fedora's
|
|
1184 |
+ |
# gopass hard-requires /usr/bin/fish for one completion file, 39.3
|
|
1185 |
+ |
# MiB of a shell nothing in this image runs, and no flag touches a
|
|
1186 |
+ |
# hard dependency. Two Terra completion packages then follow fish in
|
|
1187 |
+ |
# by conditional dependency. Client pays it because gopass is worth
|
|
1188 |
+ |
# it there; server no longer pays it at all.
|
|
1189 |
+ |
#
|
|
1190 |
+ |
# The comment this replaced said gopass "needs no gpg on the age
|
|
1191 |
+ |
# backend". True of the backend and false of the package: it
|
|
1192 |
+ |
# requires gnupg2 regardless, and gnupg2 is installed.
|
|
1193 |
+ |
gopass \
|
| 1173 |
1194 |
|
# -----------------------------------------------------------------
|
| 1174 |
1195 |
|
# Session prerequisites — not curated picks. See the header above.
|
| 1175 |
1196 |
|
# fedora-bootc is a server base; everything in this group is
|
| 1203 |
1224 |
|
wl-clipboard \
|
| 1204 |
1225 |
|
&& dnf clean all; \
|
| 1205 |
1226 |
|
else \
|
| 1206 |
|
- |
# The asserting else. Three sentinels, one per reason a package could
|
|
1227 |
+ |
# The asserting else. Five sentinels, one per reason a package could
|
| 1207 |
1228 |
|
# have landed here anyway: sway is a direct name in the `then` branch,
|
| 1208 |
1229 |
|
# pipewire is the group most likely to arrive as somebody's weak
|
| 1209 |
1230 |
|
# dependency, and greetd is what would silently turn a headless box
|
| 1210 |
1231 |
|
# into one waiting at a login prompt on a VT nobody can see.
|
| 1211 |
|
- |
for unwanted in sway pipewire greetd; do \
|
|
1232 |
+ |
#
|
|
1233 |
+ |
# gopass and fish joined them 2026-08-17, when gopass moved out of the
|
|
1234 |
+ |
# base block. fish is the interesting one: nothing in the image runs
|
|
1235 |
+ |
# it, it is here only as gopass's hard dependency, and it is 39.3 MiB.
|
|
1236 |
+ |
# If either reappears on a server image, the move has been undone by
|
|
1237 |
+ |
# something and the 64 MiB is back without anyone deciding it.
|
|
1238 |
+ |
for unwanted in sway pipewire greetd gopass fish; do \
|
| 1212 |
1239 |
|
rpm -q "$unwanted" >/dev/null 2>&1 \
|
| 1213 |
1240 |
|
&& { echo "profile=server but $unwanted is installed; the client branch ran or something pulled it in" >&2; exit 1; }; \
|
| 1214 |
1241 |
|
done; \
|
| 1829 |
1856 |
|
else \
|
| 1830 |
1857 |
|
[ ! -f "$service" ] \
|
| 1831 |
1858 |
|
|| { echo "profile=server but something claims org.freedesktop.secrets; gnome-keyring got installed" >&2; exit 1; }; \
|
| 1832 |
|
- |
echo "secret service: none on this profile; gopass is the store here"; \
|
|
1859 |
+ |
echo "secret service: none on this profile, and no gopass either since 2026-08-17"; \
|
| 1833 |
1860 |
|
fi
|
| 1834 |
1861 |
|
|
| 1835 |
1862 |
|
# gopass, and the one thing about it that can be wrong without saying so.
|
| 1847 |
1874 |
|
# an account with no store, authored by a build step, sitting where the
|
| 1848 |
1875 |
|
# real one would go the first time anyone runs gopass as root. A guard
|
| 1849 |
1876 |
|
# that leaves state behind is a guard that changes what it was checking.
|
| 1850 |
|
- |
RUN command -v gopass >/dev/null \
|
| 1851 |
|
- |
|| { echo "gopass is missing; docs/STACK.md names it as the password manager" >&2; exit 1; }
|
| 1852 |
|
- |
RUN set -eux; \
|
| 1853 |
|
- |
probe=$(mktemp -d); \
|
| 1854 |
|
- |
HOME="$probe" gopass age --help >/dev/null 2>&1 \
|
| 1855 |
|
- |
|| { rm -rf "$probe"; echo "this gopass build has no age backend; the whole reason it was picked over pass is gone" >&2; exit 1; }; \
|
| 1856 |
|
- |
rm -rf "$probe"; \
|
| 1857 |
|
- |
[ ! -e /root/.config/gopass ] \
|
| 1858 |
|
- |
|| { echo "the gopass probe wrote into /root anyway; it would ship in the image" >&2; exit 1; }
|
|
1877 |
+ |
# CONDITIONAL SINCE 2026-08-17, when gopass moved to the client block. Both
|
|
1878 |
+ |
# of these ran unconditionally and both failed the first server build after
|
|
1879 |
+ |
# the move, which is the third instance of the shape subtask 825465e0 named:
|
|
1880 |
+ |
# not a conditional with a silent half, but an assertion with no conditional
|
|
1881 |
+ |
# at all, written when every profile carried the thing it checks. Kept as two
|
|
1882 |
+ |
# RUNs rather than merged, because the second is the expensive one and the
|
|
1883 |
+ |
# first is what makes its failure legible.
|
|
1884 |
+ |
RUN if [ "$PROFILE" = client ]; then \
|
|
1885 |
+ |
command -v gopass >/dev/null \
|
|
1886 |
+ |
|| { echo "gopass is missing; docs/STACK.md names it as the password manager" >&2; exit 1; }; \
|
|
1887 |
+ |
else \
|
|
1888 |
+ |
! command -v gopass >/dev/null \
|
|
1889 |
+ |
|| { echo "profile=server but gopass is installed; it moved to the client block and takes fish with it" >&2; exit 1; }; \
|
|
1890 |
+ |
! command -v fish >/dev/null \
|
|
1891 |
+ |
|| { echo "profile=server but fish is installed; nothing here runs it and only gopass wanted it" >&2; exit 1; }; \
|
|
1892 |
+ |
echo "password store: none on this profile, and no fish behind it"; \
|
|
1893 |
+ |
fi
|
|
1894 |
+ |
RUN if [ "$PROFILE" = client ]; then \
|
|
1895 |
+ |
set -eux; \
|
|
1896 |
+ |
probe=$(mktemp -d); \
|
|
1897 |
+ |
HOME="$probe" gopass age --help >/dev/null 2>&1 \
|
|
1898 |
+ |
|| { rm -rf "$probe"; echo "this gopass build has no age backend; the whole reason it was picked over pass is gone" >&2; exit 1; }; \
|
|
1899 |
+ |
rm -rf "$probe"; \
|
|
1900 |
+ |
[ ! -e /root/.config/gopass ] \
|
|
1901 |
+ |
|| { echo "the gopass probe wrote into /root anyway; it would ship in the image" >&2; exit 1; }; \
|
|
1902 |
+ |
else \
|
|
1903 |
+ |
[ ! -e /root/.config/gopass ] \
|
|
1904 |
+ |
|| { echo "profile=server has a gopass config; something ran it during the build" >&2; exit 1; }; \
|
|
1905 |
+ |
echo "no gopass on this profile, so no age-backend probe and nothing to leave behind"; \
|
|
1906 |
+ |
fi
|
| 1859 |
1907 |
|
|
| 1860 |
1908 |
|
# =====================================================================
|
| 1861 |
1909 |
|
# The screenshot helper — assert the binds reach it.
|