first attempt

Signed-off-by: Xe <me@christine.website>
This commit is contained in:
Cadey Ratio 2022-02-27 11:06:53 +00:00
parent 92eb472d40
commit 043df13c1c
3 changed files with 124 additions and 0 deletions

35
build-rootfs.sh Executable file
View File

@ -0,0 +1,35 @@
source $stdenv/setup
set -o pipefail
# basic file system layout
mkdir -p $out/etc $out/proc $out/sys $out/dev $out/run $out/tmp $out/var/tmp $out/var/lib $out/var/log
# empty files to mount over with host's version
touch $out/etc/resolv.conf $out/etc/machine-id
# required for portable services
cp ${osRelease} $out/etc/os-release
# units must be copied to /etc/…
mkdir -p $out/etc/systemd/system
units=($units)
unitNames=($unitNames)
for ((n = 0; n < ${#units[*]}; n++)); do
unit=${units[$n]}
unitName=${unitNames[$n]}
cp $unit $out/etc/systemd/system/$unitName
done
# symlinks
objects=($objects)
targets=($targets)
for ((n = 0; n < ${#objects[*]}; n++)); do
object=${objects[$n]}
target=${targets[$n]}
mkdir -p $(dirname $out/$target)
ln -s $object $out/$target
done

82
default.nix Normal file
View File

@ -0,0 +1,82 @@
{ pkgs, lib, stdenv }:
/*
Create a systemd portable service image
https://systemd.io/PORTABLE_SERVICES/
Example:
pkgs.portableService {
name = "hello";
version = "2.4.3";
description = "hello portable";
units = [ hello-service ./files/hello.socket ];
symlinks = [
{ object = "${pkgs.cacert}/etc/ssl"; symlink = "/etc/ssl"; }
{ object = "${pkgs.bash}/bin/bash"; symlink = "/bin/sh"; }
];
}
*/
{ name
, version ? "dev"
, description ? null
, homepage ? null
, units ? [ ]
, symlinks ? [ ]
, contents ? [ ]
, squashfsTools ? pkgs.squashfsTools
, squash-compression ? "xz -Xdict-size 100%"
, squash-block-size ? "1M"
}:
let
image-name = "${name}_${version}";
os-release-params = lib.filterAttrs (n: v: v != null) {
PORTABLE_ID = name;
PORTABLE_PRETTY_NAME = description;
HOME_URL = homepage;
ID = "nixos";
PRETTY_NAME = "NixOS";
BUILD_ID = "rolling";
};
os-release = pkgs.writeText "os-release" (lib.generators.toKeyValue {} os-release-params);
getUnitName = u:
if lib.isDerivation u then u.name
else if builtins.isPath u then baseNameOf u
else throw "unit must be either derivation or path";
rootfs = stdenv.mkDerivation {
name = "rootfs";
builder = ./build-rootfs.sh;
inherit units;
unitNames = map getUnitName units;
osRelease = os-release;
objects = map (x: x.object) symlinks;
targets = map (x: x.symlink) symlinks;
};
in
stdenv.mkDerivation {
name = "${image-name}.raw";
nativeBuildInputs = [ squashfsTools ];
buildCommand = ''
closureInfo=${pkgs.closureInfo { rootPaths = contents ++ [rootfs]; }}
mkdir -p nix/store
for i in $(< $closureInfo/store-paths); do
cp -a "$i" "''${i:1}"
done
mksquashfs nix ${rootfs}/* $out \
-quiet -noappend \
-keep-as-directory \
-all-root -root-mode 755 \
-b ${squash-block-size} -comp ${squash-compression}
'';
}

7
flake.nix Normal file
View File

@ -0,0 +1,7 @@
{
description = "Nix tools to help you build portable services";
outputs = { self, nixpkgs, utils }: {
overlay = final: prev: prev.callPackage ./. { };
};
}