diff --git a/nix/nixos-module/server/lxc-containers.nix b/nix/nixos-module/server/lxc-containers.nix index 00c4cb8..c4c059c 100644 --- a/nix/nixos-module/server/lxc-containers.nix +++ b/nix/nixos-module/server/lxc-containers.nix @@ -2,14 +2,11 @@ let containers = - # TODO: remove 1 line - lib.filterAttrs (ctName: _: ctName == "upstream1") ( lib.filterAttrs (_: { role, model, location, ... }: role == "container" && model == "lxc" && location == hostName - ) config.site.hosts - ); + ) config.site.hosts; enabled = containers != {}; @@ -58,6 +55,44 @@ let else throw "Invalid data in lxc net config: ${lib.generators.toPretty {} x}"; in serialize "lxc.net" config; + + build-script = pkgs.writeScriptBin "build-container" '' + #! ${pkgs.runtimeShell} -e + + if [ -z "$1" ]; then + echo "Usage: $0 [containers ...]" + exit 1 + fi + + mkdir -p /nix/var/nix/gcroots/lxc + + for c in $@; do + echo Building $c + nix build -o /nix/var/nix/gcroots/lxc/$c zentralwerk-network#$c-rootfs + SYSTEM=$(readlink /nix/var/nix/gcroots/lxc/$c) + + echo Installing $c + for d in \ + bin dev etc home mnt \ + nix/store nix/var \ + proc root run sys tmp var usr ; \ + do + mkdir -p /var/lib/lxc/$c/rootfs/$d + done + ln -fs $SYSTEM/init /var/lib/lxc/$c/rootfs/init + + set +e + active=$(systemctl is-active lxc@$c) + if [[ "$active" = active ]] ; then + echo Activating $c + systemctl reload lxc@$c + else + echo Starting $c + systemctl start lxc@$c + fi + set -e + done + ''; in { virtualisation.lxc = lib.mkIf enabled { @@ -70,7 +105,7 @@ in ''; }; - environment.systemPackages = [ pkgs.lxc ]; + environment.systemPackages = [ pkgs.lxc build-script ]; environment.etc = builtins.foldl' (etc: ctName: etc // { @@ -113,30 +148,8 @@ in "lxc/common.conf".source = "${pkgs.lxc}/share/lxc/config/common.conf"; } (builtins.attrNames containers); - systemd.services."lxc-rootfs@" = { - description = "rootfs for '%i'"; - requires = [ "nix-daemon.service" ]; - after = [ "network.target" ]; - path = [ config.nix.package pkgs.util-linux pkgs.git ]; - scriptArgs = "%i"; - script = '' - mkdir -p /nix/var/nix/gcroots/lxc - - [ ! -e /nix/var/nix/gcroots/lxc/$1 ] && - flock /tmp/lxc-rootfs-build.lock -c \ - "nix build -o /nix/var/nix/gcroots/lxc/$1 zentralwerk-network#$1-rootfs" - - SYSTEM=$(readlink /nix/var/nix/gcroots/lxc/$1) - mkdir -p /var/lib/lxc/$1/rootfs/{bin,dev,etc,home,mnt,nix/store,nix/var,proc,root,run,sys,tmp,var,usr} - ln -fs $SYSTEM/init /var/lib/lxc/$1/rootfs/init - exit 0 - ''; - serviceConfig.Type = "oneshot"; - }; - systemd.services."lxc@" = { description = "LXC container '%i'"; - requires = [ "lxc-rootfs@%i.service" ]; after = [ "network.target" ]; serviceConfig = { Type = "simple"; @@ -145,7 +158,11 @@ in script = pkgs.writeScript "start-lxc-container.sh" '' #! ${pkgs.runtimeShell} -e - [ -e /var/lib/lxc/$1/rootfs ] + if [ ! -e /var/lib/lxc/$1/rootfs ]; then + echo "Container $1 does not exist. Run: build-container $1" + exit 1 + fi + exec ${pkgs.lxc}/bin/lxc-start -F -C -n $1 ''; in @@ -170,19 +187,7 @@ in systemd.targets.lxc-containers = { wantedBy = [ "multi-user.target" ]; - wants = builtins.concatMap (ctName: [ "lxc@${ctName}.service" "lxc-reload@${ctName}.path" ]) + wants = map (ctName: "lxc@${ctName}.service") (builtins.attrNames containers); }; - - systemd.paths."lxc-reload@" = { - pathConfig = { - PathChanged = "/var/lib/lxc/%i/rootfs/init"; - }; - }; - systemd.services."lxc-reload@" = { - requires = [ "lxc@%i.service" ]; - serviceConfig.Type = "oneshot"; - scriptArgs = "%i"; - script = "/run/current-system/systemd/bin/systemctl reload lxc@$1.service || true"; - }; }