wip: sys extensions and versioning thinkering

This commit is contained in:
Lars Sjöström 2025-06-27 08:10:37 +02:00
commit 6e691c41d2
No known key found for this signature in database
9 changed files with 165 additions and 34 deletions

View file

@ -16,9 +16,13 @@
system:
let
buildParams = {
arch = {
"x86_64-linux" = "x86-64";
"aarch64-linux" = "arm64";
};
revision = self.shortRev or self.dirtyShortRev or "dirty";
updateUrl = builtins.getEnv "PATOS_UPDATE_URL";
secureBoot = builtins.getEnv "PATOS_ENABLE_SECURE_BOOT";
updateUrl = "http://10.0.2.2:8000/";
secureBoot = "false";
version = "0.0.1";
};

View file

@ -8,6 +8,8 @@
services ? [],
osId ? "patos",
version ? null,
arch ? "x86-64",
updateUrl ? null,
}:
@ -17,12 +19,15 @@ let
VERSION_ID = osId;
IMAGE_ID = name;
IMAGE_VERSION = version;
ARCHITECTURE = arch;
} // lib.optionalAttrs (services != []) { EXTENSION_RELOAD_MANAGER = "1"; };
metadataFile = lib.concatStringsSep "\n" (
lib.mapAttrsToList (k: v: "${k}=${v}") (lib.filterAttrs (_: v: v != null) metadata)
);
versionString = "${version}-${arch}";
doCopy =
{
drv,
@ -40,6 +45,10 @@ runCommand name
inherit metadataFile;
passAsFile = [ "metadataFile" ];
env = {
SYSTEMD_REPART_MKFS_OPTIONS_EROFS = "--all-root -zlz4hc,12 -C1048576 -Efragments,dedupe,ztailpacking";
};
nativeBuildInputs = [
pkgs.erofs-utils
pkgs.cryptsetup
@ -135,26 +144,76 @@ runCommand name
cat "$metadataFilePath" > $out/tree/usr/lib/extension-release.d/extension-release."${name}"
fi
if [ -n "${updateUrl}" ]; then
mkdir -p $out/tree/usr/lib/sysupdate.d
ft=(raw)
for i in "''${!ft[@]}"; do
cat << EOF > $out/tree/usr/lib/sysupdate.d/9"$i"-"${name}".transfer
[Source]
Type=url-file
Path=${updateUrl}
MatchPattern=${name}-@v-%a.''${ft[i]}
[Target]
InstancesMax=3
Type=regular-file
MatchPattern=extensions.d/${name}-@v-%a.''${ft[i]}
Path=/var/lib/
CurrentSymlink=extensions/${name}.''${ft[i]}
[Transfer]
Verify=no
EOF
done
fi
pushd $out
find tree -type d -exec chmod 0755 {} \;
mkfs.erofs -zlz4hc,12 -C1048576 -Efragments,dedupe,ztailpacking --all-root $name.raw tree/
veritysetup format --root-hash-file $name.roothash $name.raw $name.verity
mkdir $out/sysext.repart.d
cat << EOF > $out/sysext.repart.d/10-root.conf
[Partition]
Type=root
Format=erofs
CopyFiles=/usr/
CopyFiles=/opt/
AddValidateFS=false
Verity=data
VerityMatchKey=root
Minimize=best
EOF
cat << EOF > $out/sysext.repart.d/20-root-verity.conf
[Partition]
Type=root-verity
AddValidateFS=false
Verity=hash
VerityMatchKey=root
Minimize=best
EOF
${pkgs.patos.systemd}/usr/bin/systemd-repart \
--make-ddi=sysext \
--definitions=$out/sysext.repart.d \
--copy-source=./tree \
--pretty=no \
"$name"-${versionString}.raw
ln -s "$name"-${versionString}.raw "$name".raw
# TODO: pcks7 signature
# openssl smime -sign -nocerts -noattr -binary -in ${name}.roothash \
# -inkey key.pem -signer cert.pem -outform der -out ${name}.roothash.p7s
# create contents list
pushd tree
find . -ls > $out/"$name"_contents.txt
find . -ls > $out/"$name"-${versionString}_contents.txt
popd
# create nixpkgs packages list
sort -u $out/.tmp-pkgs.txt > $out/"$name"_packages.txt
sort -u $out/.tmp-pkgs.txt > $out/"$name"-${versionString}_packages.txt
rm -f $out/.tmp-pkgs.txt
jq -R -s 'split("\n") | map(select(length > 0)) | map(capture("pkgname=\"(?<name>[^\"]*)\",licenses=\"(?<licenses>[^\"]*)\"") | .licenses |= split(",")) | map(select(. != null))' $out/"$name"_packages.txt > $out/"$name"_packages.json
jq -R -s 'split("\n") | map(select(length > 0)) | map(capture("pkgname=\"(?<name>[^\"]*)\",licenses=\"(?<licenses>[^\"]*)\"") | .licenses |= split(",")) | map(select(. != null))' $out/"$name"-${versionString}_packages.txt > $out/"$name"-${versionString}_packages.json
rm -rf tree
rm -rf $out/sysext.repart.d
sha256sum * > SHA256SUMS
ln -s SHA256SUMS SHA256SUMS.asc
# TODO: add gpg signature

View file

@ -3,17 +3,19 @@
stdenv,
pkgs,
version,
revision,
runCommand,
updateUrl,
microcode ? "",
secureBoot ? "false"
secureBoot ? "false",
arch,
...
}:
let
pname = "patos-image";
in
runCommand pname {
versionString = "${version}+${revision}-${stdenv.system}";
versionString = "${version}-"+ arch.${stdenv.hostPlatform.system};
mcode = lib.optionalString (microcode == "amd") "--microcode ${pkgs.microcode-amd}/amd-ucode.img"
+ lib.optionalString (microcode == "intel") "--microcode ${pkgs.microcode-intel}/intel-ucode.img";
@ -47,11 +49,6 @@ mkdir rootfs
cp -prP ${pkgs.patos.rootfs}/* rootfs/
find rootfs/ -type d -exec chmod 755 {} \;
# package kernel modules as sysext (will reduce the image size a little bit (~3MB))
mkdir rootfs/etc/extensions
rm -rf rootfs/usr/lib/modules
cp ${pkgs.patos.kernel}/patos-kernel-modules* rootfs/etc/extensions/
# set default target to multi-user
ln -sf multi-user.target rootfs/usr/lib/systemd/system/default.target
@ -113,12 +110,12 @@ mkdir -p rootfs/etc/sysupdate.d
cat <<EOF > rootfs/etc/sysupdate.d/10-uki.transfer
[Source]
Path=${updateUrl}
MatchPattern=patos_@v.efi
MatchPattern=patos_@v-%a.efi
Type=url-file
[Target]
InstancesMax=2
MatchPattern=patos_@v+@l-@d.efi patos_@v+@l.efi patos_@v.efi
MatchPattern=patos_@v-%a+@l-@d.efi patos_@v-%a+@l.efi patos_@v-%a.efi
Mode=0444
Path=/EFI/Linux
PathRelativeTo=esp
@ -134,7 +131,7 @@ cat <<EOF > rootfs/etc/sysupdate.d/20-root-verity.transfer
[Source]
Type=url-file
Path=${updateUrl}
MatchPattern=patos_@v_@u.verity
MatchPattern=patos_@v-%a_@u.verity
[Target]
Type=partition
@ -151,7 +148,7 @@ cat <<EOF > rootfs/etc/sysupdate.d/22-root.transfer
[Source]
Type=url-file
Path=${updateUrl}
MatchPattern=patos_@v_@u.root
MatchPattern=patos_@v-%a_@u.root
[Target]
Type=partition
@ -208,8 +205,8 @@ rootUuid=$(jq -r '.[0].uuid' init-repart-output.json)
verityPart=$(jq -r '.[1].split_path' init-repart-output.json)
verityUuid=$(jq -r '.[1].uuid' init-repart-output.json)
ln -sf patos_$versionString.verity.raw patos_$versionString_$verityUuid.verity
ln -sf patos_$versionString.root.raw patos_$versionString_$rootUuid.root
ln -sf patos_$versionString.verity.raw patos_"$versionString"_"$verityUuid".verity
ln -sf patos_$versionString.root.raw patos_"$versionString"_"$rootUuid".root
${pkgs.patos.systemd}/usr/bin/ukify build \
--linux ${pkgs.patos.kernel}/$kernelImage \
@ -256,7 +253,7 @@ EOF
cat <<EOF > final.repart.d/20-root.conf
[Partition]
Type=root
Label=root-$versionString
Label=root-${version}
CopyBlocks=$out/$rootPart
UUID=$rootUuid
SizeMinBytes=64M
@ -267,7 +264,7 @@ EOF
cat <<EOF > final.repart.d/22-root-verity.conf
[Partition]
Type=root-verity
Label=verity-$versionString
Label=verity-${version}
CopyBlocks=$out/$verityPart
UUID=$verityUuid
ReadOnly=1

View file

@ -112,15 +112,16 @@ cat <<EOF > $out/etc/repart.d/40-var.conf
[Partition]
Type=var
Format=btrfs
MakeDirectories=/var/lib/confexts /var/lib/extensions /var/lib/portables /var/.snapshots
MakeDirectories=/var/lib/confexts /var/lib/extensions /var/lib/portables /var/lib/extensions.d /var/.snapshots
MountPoint=/var
Label=patos-state
Encrypt=tpm2
EncryptedVolume=patos-state:none:tpm2-device=auto,luks,discard
Subvolumes=/var/lib/confexts /var/lib/extensions /var/lib/portables /var/.snapshots
Subvolumes=/var/lib/confexts /var/lib/extensions /var/lib/portables /var/lib/extensions.d /var/.snapshots
MountPoint=/var/lib/confexts:subvol=/var/lib/confexts
MountPoint=/var/lib/extensions:subvol=/var/lib/extensions
MountPoint=/var/lib/portables:subvol=/var/lib/portables
MountPoint=/var/lib/extensions.d:subvol=/var/lib/extensions.d
MountPoint=/var/.snapshots:subvol=/var/.snapshots
SizeMinBytes=1G
Minimize=off

View file

@ -1,16 +1,20 @@
{
pkgs,
stdenv,
version,
revision,
arch,
updateUrl,
...
}:
let
versionString = "${version}-${revision}";
cpu_arch = arch.${stdenv.hostPlatform.system};
in
pkgs.callPackage ../../lib/make-sysext.nix {
name = "patos-debug-tools";
version = versionString;
version = version;
arch = cpu_arch;
updateUrl = updateUrl;
packages = [
{ drv = pkgs.curl; path = "bin/"; }

View file

@ -1,7 +1,20 @@
{ pkgs, version, revision, ... }:
{
pkgs,
version,
arch,
stdenv,
updateUrl,
...
}:
let
cpu_arch = arch.${stdenv.hostPlatform.system};
in
pkgs.callPackage ../../lib/make-sysext.nix {
name = "patos-firewall-tools";
version = "${version}-${revision}";
version = version;
arch = cpu_arch;
updateUrl = updateUrl;
packages = [
# network/firewalling
{ drv = pkgs.iproute2; path = "bin/"; }

View file

@ -26,11 +26,15 @@ stdenv.mkDerivation (finalAttrs: {
src = fetchFromGitHub {
owner = "systemd";
repo = "systemd";
rev = "959d7f1759d67994e3bed7b9d2f23e063475a872"; # main
hash = "sha256-IxGg0t/0GEllU4EPHqY2bwMDYwrQ5KWyE2QhwhTxqGs=";
rev = "2e5e17a5707ad6538d67e4d43088a6eb33f2d852"; # main
hash = "sha256-xPwGuS/vaA3/oe8szzI1bNadVHt623ZBz+HSj7x/4cM=";
};
patches = [ ./skip-verify-esp.patch ];
patches = [
./skip-verify-esp.patch
./enable-sysext-repart.patch
./sysupdate-fix.patch
];
dontCheckForBrokenSymlinks = true;

View file

@ -0,0 +1,36 @@
diff --git a/src/repart/repart.c b/src/repart/repart.c
index 352384bfc0..e3e8bcae5f 100644
--- a/src/repart/repart.c
+++ b/src/repart/repart.c
@@ -9076,8 +9076,6 @@ static int parse_argv(int argc, char *argv[], X509 **ret_certificate, EVP_PKEY *
"Expected at most one argument, the path to the block device or image file.");
if (arg_make_ddi) {
- if (arg_definitions)
- return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Combination of --make-ddi= and --definitions= is not supported.");
if (!IN_SET(arg_empty, EMPTY_UNSET, EMPTY_CREATE))
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Combination of --make-ddi= and --empty=%s is not supported.", empty_mode_to_string(arg_empty));
@@ -9744,21 +9742,7 @@ static int run(int argc, char *argv[]) {
if (r < 0)
return r;
- if (arg_make_ddi) {
- _cleanup_free_ char *d = NULL, *dp = NULL;
- assert(!arg_definitions);
-
- d = strjoin(arg_make_ddi, ".repart.d/");
- if (!d)
- return log_oom();
-
- r = search_and_access(d, F_OK, NULL, CONF_PATHS_STRV("systemd/repart/definitions"), &dp);
- if (r < 0)
- return log_error_errno(r, "DDI type '%s' is not defined: %m", arg_make_ddi);
-
- if (strv_consume(&arg_definitions, TAKE_PTR(dp)) < 0)
- return log_oom();
- } else
+ if (arg_make_ddi)
strv_uniq(arg_definitions);
r = context_read_definitions(context);

View file

@ -0,0 +1,13 @@
diff --git a/src/sysupdate/sysupdate-transfer.c b/src/sysupdate/sysupdate-transfer.c
index d3e71bb21e..ba3747dead 100644
--- a/src/sysupdate/sysupdate-transfer.c
+++ b/src/sysupdate/sysupdate-transfer.c
@@ -684,7 +684,7 @@ int transfer_resolve_paths(
return r;
r = resource_resolve_path(&t->target, root, /*relative_to_directory=*/ NULL, node);
- if (r < 0)
+ if (r < 0 && !RESOURCE_IS_FILESYSTEM((&t->target)->type))
return r;
return 0;