3 Create a systemd portable service image
4 https://systemd.io/PORTABLE_SERVICES/
10 units = [ demo-service demo-socket ];
14 # The name and version of the portable service. The resulting image will be
15 # created in result/$pname_$version.raw
19 # Units is a list of derivations for systemd unit files. Those files will be
20 # copied to /etc/systemd/system in the resulting image. Note that the unit
21 # names must be prefixed with the name of the portable service.
24 # Basic info about the portable service image, used for the generated
29 # A list of attribute sets {object, symlink}. Symlinks will be created
30 # in the root filesystem of the image to objects in the nix store.
33 # A list of additional derivations to be included in the image as-is.
37 , squashfsTools ? pkgs.squashfsTools
38 , squash-compression ? "xz -Xdict-size 100%"
39 , squash-block-size ? "1M"
43 filterNull = lib.filterAttrs (_: v: v != null);
44 envFileGenerator = lib.generators.toKeyValue { };
50 PORTABLE_PRETTY_NAME = description;
53 PRETTY_NAME = "NixOS";
56 os-release = pkgs.writeText "os-release"
57 (envFileGenerator (filterNull os-release-params));
61 pname = "root-fs-scaffold";
65 # scaffold a file system layout
66 mkdir -p $out/etc/systemd/system $out/proc $out/sys $out/dev $out/run \
67 $out/tmp $out/var/tmp $out/var/lib $out/var/cache $out/var/log
69 # empty files to mount over with host's version
70 touch $out/etc/resolv.conf $out/etc/machine-id
72 # required for portable services
73 cp ${os-release} $out/etc/os-release
75 # units **must** be copied to /etc/systemd/system/
76 + (lib.concatMapStringsSep "\n" (u: "cp ${u} $out/etc/systemd/system/${u.name};") units)
77 + (lib.concatMapStringsSep "\n"
78 ({ object, symlink }: ''
79 mkdir -p $(dirname $out/${symlink});
80 ln -s ${object} $out/${symlink};
87 assert lib.assertMsg (lib.all (u: lib.hasPrefix pname u.name) units) "Unit names must be prefixed with the service name";
90 pname = "${pname}-img";
93 nativeBuildInputs = [ squashfsTools ];
94 closureInfo = pkgs.closureInfo { rootPaths = [ rootFsScaffold ] ++ contents; };
98 for i in $(< $closureInfo/store-paths); do
103 # the '.raw' suffix is mandatory by the portable service spec
104 mksquashfs nix ${rootFsScaffold}/* $out/"${pname}_${version}.raw" \
108 -all-root -root-mode 755 \
109 -b ${squash-block-size} -comp ${squash-compression}