diff --git a/elements/core-deps/accountsservice.bst b/elements/core-deps/accountsservice.bst index 00df3ac2f49fe44c7c772abb364366b258c31d49..31098e3a05b957ffd874c58901b6090e2dbccad0 100644 --- a/elements/core-deps/accountsservice.bst +++ b/elements/core-deps/accountsservice.bst @@ -5,6 +5,8 @@ sources: url: freedesktop:accountsservice/accountsservice.git track: refs/tags/* ref: 23.13.9-0-g57e491f5e6f3da2d5a949f4f8747c8f4e8ed799d +- kind: patch + path: patches/accountsservice/tmpfiles.patch build-depends: - sdk/gobject-introspection.bst diff --git a/elements/gnomeos/confext.bst b/elements/gnomeos/confext.bst new file mode 100644 index 0000000000000000000000000000000000000000..b8620f26e73320fded63ebf0aa7c74570706a89c --- /dev/null +++ b/elements/gnomeos/confext.bst @@ -0,0 +1,25 @@ +kind: manual + +sources: +- kind: local + path: files/gnomeos/confext + +build-depends: +- freedesktop-sdk.bst:components/gcc.bst +- freedesktop-sdk.bst:components/stripper.bst + +depends: +- freedesktop-sdk.bst:public-stacks/runtime-minimal.bst + +config: + build-commands: + - | + g++ -std=c++20 ${CFLAGS} ${LDFLAGS} migrate-confext.cpp -o migrate-confext + + install-commands: + - | + install -Dm644 -t '%{install-root}%{indep-libdir}/systemd/system' \ + initrd-confext.service \ + initrd-migrate-confext.service + install -Dm644 -t '%{install-root}%{indep-libdir}/systemd/system/systemd-confext.service.d' mutable.conf + install -Dm755 -t '%{install-root}%{indep-libdir}/gnomeos' migrate-confext diff --git a/elements/gnomeos/devel/layer.bst b/elements/gnomeos/devel/layer.bst index 230297aa0a57c0d18dfc878fd33360cf72d0e6a9..ca487f70e4086d1e8f02e491121d816fe8d53324 100644 --- a/elements/gnomeos/devel/layer.bst +++ b/elements/gnomeos/devel/layer.bst @@ -54,61 +54,29 @@ config: --noroot --noboot --nodepmod >/dev/null - | - mkdir -p output/etc - make-layer sysroot/etc sysroot-devel/etc output/etc/etc + mkdir -p sysroot-devel/etc/extension-release.d + case "%{branch}" in + master) + version_id=Nightly + ;; + *) + version_id="%{branch}" + ;; + esac - - | - cat >sysroot-devel/usr/lib/tmpfiles.d/extra-etc-devel.conf<sysroot-devel/etc/extension-release.d/extension-release.devel_%{image-version} + ID="org.gnome.os" + VERSION_ID="${version_id}" + CONFEXT_LEVEL="%{image-version}" + GNOMEOS_COMMIT="%{commit}" + GNOMEOS_COMMIT_DATE="%{commit-date-pretty}" + GNOMEOS_COMMITS_URL="${commits_url}" EOF - | - find output/etc - - - | - mkdir -p output/factory - for p in $(grep -v "^#" /dev/null - - | - cat >sysroot-snapd/usr/lib/tmpfiles.d/extra-etc-snapd.conf<sysroot-snapd/etc/extension-release.d/extension-release.snapd_%{image-version} + ID="org.gnome.os" + VERSION_ID="${version_id}" + CONFEXT_LEVEL="%{image-version}" + GNOMEOS_COMMIT="%{commit}" + GNOMEOS_COMMIT_DATE="%{commit-date-pretty}" + GNOMEOS_COMMITS_URL="${commits_url}" + EOF + - | mkdir -p output - make-layer sysroot/usr sysroot-snapd/usr output/usr - | - mkdir -p output/usr/share/factory/etc - cp -rT sysroot-snapd/etc/apparmor output/usr/share/factory/etc/apparmor - cp -rT sysroot-snapd/etc/apparmor.d output/usr/share/factory/etc/apparmor.d - mkdir -p output/usr/share/factory/etc/profile.d - cp -rT sysroot-snapd/etc/profile.d/snapd.sh output/usr/share/factory/etc/profile.d/snapd.sh - mkdir -p output/usr/share/factory/etc/xdg/autostart - cp -rT sysroot-snapd/etc/xdg/autostart/snap-userd-autostart.desktop output/usr/share/factory/etc/xdg/autostart/snap-userd-autostart.desktop + make-layer sysroot/usr sysroot-snapd/usr output/usr - | - mkdir -p output/etc - cp -T sysroot-snapd/usr/lib/os-release output/etc/os-release + make-layer sysroot/etc sysroot-snapd/etc output/etc - | mkdir -p tmp @@ -121,6 +125,25 @@ config: --copy-source=output \ snapd-%{systemd-arch}_%{image-version}.raw + - | + TMPDIR='%{build-root}/tmp' \ + SYSTEMD_LOG_LEVEL=debug \ + SYSTEMD_REPART_MKFS_OPTIONS_EROFS="${EROFS_OPTIONS} ${EROFS_WORKERS}" \ + systemd-repart \ + --empty=create \ + --make-ddi=sysext \ + --size=auto \ + --dry-run=no \ + --discard=no \ + --offline=true \ + --no-pager \ + --private-key=SYSEXT.key \ + --certificate=SYSEXT.crt \ + --seed %{repart-seed} \ + --copy-source=output \ + snapd-confext-%{systemd-arch}_%{image-version}.raw + install-commands: - | mv snapd-%{systemd-arch}_%{image-version}.raw %{install-root} + mv snapd-confext-%{systemd-arch}_%{image-version}.raw %{install-root} diff --git a/elements/gnomeos/usr/deps.bst b/elements/gnomeos/usr/deps.bst index 8c6c1c94d2759d9b45d6f41f0b892697ed2ebf71..a2780a7075907402e42e7159e5d85d4ecc13971f 100644 --- a/elements/gnomeos/usr/deps.bst +++ b/elements/gnomeos/usr/deps.bst @@ -16,6 +16,7 @@ depends: - gnomeos/public-keys.bst - gnomeos/signed-boot-common.bst - freedesktop-sdk.bst:vm/config/useradd-default.bst +- gnomeos/confext.bst (?): - arch in ["x86_64"]: diff --git a/elements/gnomeos/usr/image.bst b/elements/gnomeos/usr/image.bst index b791e30c0e6f3e76ee301cd9dcbaa6499f8a736a..c1268d9b51637c68759057ab9263b9b3b58daae9 100644 --- a/elements/gnomeos/usr/image.bst +++ b/elements/gnomeos/usr/image.bst @@ -73,11 +73,6 @@ config: rm /sysroot/etc/ssh/ssh_config.d/20-systemd-ssh-proxy.conf rm /sysroot/etc/ssh/sshd_config.d/20-systemd-userdb.conf - - | - cat >/sysroot/usr/lib/tmpfiles.d/extra-etc-symlinks.conf</sysroot/usr/lib/tmpfiles.d/extra-etc.conf<>/sysroot/usr/lib/tmpfiles.d/extra-etc.conf </sysroot/usr/lib/confexts/gnomeos-base-config/etc/extension-release.d/extension-release.gnomeos-base-config + ID="org.gnome.os" + CONFEXT_LEVEL="%{image-version}" EOF - ;; - esac - - - | - mkdir -p /sysroot/usr/share/factory - failures=() - for p in $(grep -v "^#" &2 - done - exit 1 - fi - - - | - find /sysroot/etc -depth -type d -empty -delete - - - | - unknown=() - for p in /sysroot/etc/*; do - rel="${p#/sysroot}" - case "${rel}" in - /etc/systemd) - # For those we copied the content instead - ;; - /etc/os-release|/etc/mtab|/etc/passwd|/etc/group|/etc/shadow|/etc/gshadow|/etc/ld.so.cache) - # Those are created another way - ;; - /etc/X11|/etc/dracut.conf.d) - # Those should not exist - ;; - *) - unknown+=("${rel}") - ;; - esac - done - if [ "${#unknown[*]}" -gt 0 ]; then - echo "Unknown paths:" "${unknown[@]}" >&2 - exit 1 - fi - | cat >/sysroot/usr/lib/tmpfiles.d/extensions.conf< +#include +#include +#include + +namespace fs = std::filesystem; + +void copy_with_dir(fs::path const& path, + fs::path const& source, + fs::path const& target) { + if (path.has_parent_path()) { + copy_with_dir(path.parent_path(), source, target); + } + + auto src_path = source / path; + if (is_symlink(src_path)) { + copy_symlink(src_path, target / path); + } else if (is_regular_file(src_path)) { + copy_file(src_path, target / path); + } else if (is_directory(src_path)) { + create_directory(target / path, src_path); + } +} + +int main() { + auto sysroot_etc = fs::path("/sysroot/etc"); + auto tmp_target = fs::path("/sysroot/var/lib/extensions.mutable/etc.creating"); + create_directories(tmp_target); + + for (auto& p : fs::recursive_directory_iterator(sysroot_etc)) { + auto path = fs::path(p); + auto rel = path.lexically_relative(sysroot_etc); + auto factory = "/usr/share/factory/etc" / rel; + auto confext = "/sysroot/usr/lib/confexts/gnomeos-base-config/etc" / rel; + if (p.is_symlink()) { + auto target = read_symlink(p); + if (target != factory) { + if (is_symlink(confext)) { + auto confext_target = read_symlink(confext); + if (target != confext_target) { + std::cerr << "different symlink " << rel << '\n'; + copy_with_dir(rel, sysroot_etc, tmp_target); + } + } else { + std::cerr << "new symlink " << rel << '\n'; + copy_with_dir(rel, sysroot_etc, tmp_target); + } + } + } else if (p.is_regular_file()) { + auto path_status = symlink_status(path); + auto confext_status = symlink_status(confext); + if (!is_regular_file(confext_status)) { + std::cerr << "added file " << rel << '\n'; + copy_with_dir(rel, sysroot_etc, tmp_target); + } else if (path_status.permissions() != confext_status.permissions()) { + std::cerr << "different perms " << rel << '\n'; + copy_with_dir(rel, sysroot_etc, tmp_target); + } else if (file_size(path) != file_size(confext)) { + std::cerr << "different size " << rel << '\n'; + copy_with_dir(rel, sysroot_etc, tmp_target); + } else { + std::ifstream f1(path); + std::ifstream f2(confext); + if (!std::ranges::equal(std::istreambuf_iterator(f1), + std::istreambuf_iterator(), + std::istreambuf_iterator(f2), + std::istreambuf_iterator())) { + std::cerr << "different content " << rel << '\n'; + copy_with_dir(rel, sysroot_etc, tmp_target); + } + } + } + } + rename(tmp_target, "/sysroot/var/lib/extensions.mutable/etc"); + return 0; +} diff --git a/files/gnomeos/confext/mutable.conf b/files/gnomeos/confext/mutable.conf new file mode 100644 index 0000000000000000000000000000000000000000..f05109c1fce4cf3bfc38e0b11720ce2511df35ff --- /dev/null +++ b/files/gnomeos/confext/mutable.conf @@ -0,0 +1,5 @@ +[Service] +ExecStart= +ExecStart=systemd-confext --mutable=auto refresh +ExecReload= +ExecReload=systemd-confext --mutable=auto refresh diff --git a/files/gnomeos/generate-initramfs/modules/50-confext/module.sh b/files/gnomeos/generate-initramfs/modules/50-confext/module.sh new file mode 100644 index 0000000000000000000000000000000000000000..87955690227e7e6d560681c85bb17fe63c89b9ff --- /dev/null +++ b/files/gnomeos/generate-initramfs/modules/50-confext/module.sh @@ -0,0 +1,11 @@ +install() { + install_files \ + "/usr/lib/systemd/system/initrd-confext.service" \ + "/usr/lib/systemd/system/initrd-migrate-confext.service" \ + "/usr/lib/gnomeos/migrate-confext" + + mkdir -p "${root}/usr/lib/systemd/system/initrd-fs.target.wants" + + ln -s ../initrd-confext.service "${root}/usr/lib/systemd/system/initrd.target.wants/initrd-confext.service" + ln -s ../initrd-migrate-confext.service "${root}/usr/lib/systemd/system/initrd.target.wants/initrd-migrate-confext.service" +} diff --git a/files/os-release/os-release.oci.in b/files/os-release/os-release.oci.in index 06bda857f3687355eeb00240b104307fa3b9356a..33a74bd351cde5042e07ca9d114ad8d930b2468d 100644 --- a/files/os-release/os-release.oci.in +++ b/files/os-release/os-release.oci.in @@ -8,6 +8,7 @@ BUG_REPORT_URL="https://gitlab.gnome.org/GNOME/gnome-build-meta/-/issues/new" HOME_URL="https://www.gnome.org/" IMAGE_VERSION="@IMAGE_VERSION@" SYSEXT_LEVEL="@IMAGE_VERSION@" +CONFEXT_LEVEL="@IMAGE_VERSION@" GNOMEOS_COMMIT="@GNOMEOS_COMMIT@" GNOMEOS_COMMIT_DATE="@GNOMEOS_COMMIT_DATE@" GNOMEOS_COMMITS_URL="@GNOMEOS_COMMITS_URL@" diff --git a/files/os-release/os-release.sysupdate.in b/files/os-release/os-release.sysupdate.in index 864195e57db7082cfef8bf6d8ffbd3d76c9d3e05..d81367ec62e45e1f07ed592b4228294b3164104a 100644 --- a/files/os-release/os-release.sysupdate.in +++ b/files/os-release/os-release.sysupdate.in @@ -10,6 +10,7 @@ VARIANT="@VARIANT@ (sysupdate)" VARIANT_ID="su-@VARIANT_ID@" IMAGE_VERSION="@IMAGE_VERSION@" SYSEXT_LEVEL="@IMAGE_VERSION@" +CONFEXT_LEVEL="@IMAGE_VERSION@" IMAGE_ID="@VARIANT_ID@" DEFAULT_HOSTNAME="gnomeos" GNOMEOS_COMMIT="@GNOMEOS_COMMIT@" diff --git a/files/sysupdate/40-gnomeos-devel-confext.transfer b/files/sysupdate/40-gnomeos-devel-confext.transfer new file mode 100644 index 0000000000000000000000000000000000000000..efe0588ad987ddd5e94ed5bdd22b99046d8e81b5 --- /dev/null +++ b/files/sysupdate/40-gnomeos-devel-confext.transfer @@ -0,0 +1,16 @@ +[Transfer] +ProtectVersion=%A +Features=devel + +[Source] +Type=url-file +Path=https://1270333429.rsc.cdn77.org/nightly/sysupdate/ +MatchPattern=devel-confext-%a_@v.raw \ + devel-confext-%a_@v.raw.xz \ + devel-confext-%a_@v.raw.zst + +[Target] +Type=regular-file +Path=/var/lib/confexts/ +MatchPattern=devel_@v.raw +InstancesMax=2 diff --git a/files/sysupdate/40-gnomeos-snapd-confext.transfer b/files/sysupdate/40-gnomeos-snapd-confext.transfer new file mode 100644 index 0000000000000000000000000000000000000000..451adcced19491c9de8d135ebfa679d87c8bb4b6 --- /dev/null +++ b/files/sysupdate/40-gnomeos-snapd-confext.transfer @@ -0,0 +1,16 @@ +[Transfer] +ProtectVersion=%A +Features=snapd + +[Source] +Type=url-file +Path=https://1270333429.rsc.cdn77.org/nightly/sysupdate/ +MatchPattern=snapd-confext-%a_@v.raw \ + snapd-confext-%a_@v.raw.xz \ + snapd-confext-%a_@v.raw.zst + +[Target] +Type=regular-file +Path=/var/lib/confexts/ +MatchPattern=snapd_@v.raw +InstancesMax=2 diff --git a/patches/accountsservice/tmpfiles.patch b/patches/accountsservice/tmpfiles.patch new file mode 100644 index 0000000000000000000000000000000000000000..ff4eecb31bc8b64224d49cfb66835a2f707e9cf1 --- /dev/null +++ b/patches/accountsservice/tmpfiles.patch @@ -0,0 +1,14 @@ +diff -ru accountsservice.old/data/accounts-daemon.service.in accountsservice/data/accounts-daemon.service.in +--- accountsservice.old/data/accounts-daemon.service.in 2026-01-31 18:44:32.698418179 +0100 ++++ accountsservice/data/accounts-daemon.service.in 2026-01-31 18:45:47.544478762 +0100 +@@ -7,6 +7,10 @@ + After=nss-user-lookup.target + Wants=nss-user-lookup.target + ++# For ProtectSystem=strict to work and /home to be writable ++# /home has to exist. So tmpfiles should have run first ++After=systemd-tmpfiles-setup.service ++ + [Service] + Type=dbus + BusName=org.freedesktop.Accounts