diff --git a/pkgs/tools/misc/hetzner-nixops-installer/default.nix b/pkgs/tools/misc/hetzner-nixops-installer/default.nix new file mode 100644 index 00000000000..3322097ec77 --- /dev/null +++ b/pkgs/tools/misc/hetzner-nixops-installer/default.nix @@ -0,0 +1,99 @@ +{ stdenv, perl, gnutar, pathsFromGraph, nix, pythonPackages }: + +let + base = stdenv.mkDerivation { + name = "hetzner-nixops-base"; + + buildCommand = '' + ensureDir "$out/bin" + ln -s "${nix}"/bin/* "$out/bin/" + ln -s "${stdenv.shell}" "$out/bin/sh" + ''; + }; +in stdenv.mkDerivation { + name = "hetzner-nixops-installer"; + + exportReferencesGraph = [ + "refs-base" base + "refs-nixpart" pythonPackages.nixpartHetzner + ]; + + buildCommand = '' + ensureDir "usr/bin" + + # Create the chroot wrappers for Nix + for path in "${nix}"/bin/*; do + base="$(basename "$path")" + wrapper="usr/bin/$base" + echo "#!/bin/sh" > "$wrapper" + echo "chroot /mnt \"$path\" \$@" >> "$wrapper" + chmod +x "$wrapper" + done + + # Only a symlink that is goint to be put into the Tar file. + ln -ns "${pythonPackages.nixpartHetzner}/bin/nixpart" usr/bin/nixpart + + base_storepaths="$("${perl}/bin/perl" "${pathsFromGraph}" refs-base)" + base_registration="$(printRegistration=1 \ + "${perl}/bin/perl" "${pathsFromGraph}" refs-base)" + + ( # Don't use stdenv.shell here, we're NOT on NixOS! + echo "#!/bin/sh" + # Do not quote because we want to inline the paths! + echo 'mkdir -m 1777 -p "/mnt/nix/store"' + echo "cp -a" $base_storepaths "/mnt/nix/store/" + echo "chroot /mnt \"${base}/bin/nix-store\" --load-db <<'REGINFO'" + echo "$base_registration" + echo "REGINFO" + echo 'ln -sn "${stdenv.shell}" /mnt/bin/sh' + ) > "usr/bin/activate-remote" + chmod +x "usr/bin/activate-remote" + + full_storepaths="$("${perl}/bin/perl" "${pathsFromGraph}" refs-*)" + stripped_full_storepaths="$(echo "$full_storepaths" | sed 's|/*||')" + + ( echo "#!${stdenv.shell}" + echo 'tarfile="$(mktemp)"' + echo 'trap "rm -f $tarfile" EXIT' + echo "lnum=\"\$(grep -m1 -an '^EXISTING_TAR${"\$"}' \"$out\")\"" + echo 'tail -n +$((''${lnum%%:*} + 1)) "'"$out"'" > "$tarfile"' + # As before, don't quote here! + echo '${gnutar}/bin/tar rf "$tarfile" -C /' $stripped_full_storepaths + echo 'cat "$tarfile"' + echo "exit 0" + echo EXISTING_TAR + tar c usr + ) > "$out" + chmod +x "$out" + ''; + + meta = { + description = "Basic Nix bootstrap installer for NixOps"; + longDescription = '' + It works like this: + + Preapare a base image with reference graph, which is to be copied over to + the mount point and contains wrappers for the system outside the mount + point. Those wrappers basically just chroot into the mountpoint path and + execute the corresponding counterparts over there. The base derivation + itself only contains everything necessary in order to get a Nix + bootstrapped, like Nix itself and a shell linked to /mnt/bin/sh. + + From outside the mountpoint, we just provide a small derivation which + contains a partitioner, an activate-remote and a script which is the + output of this derivation. In detail: + + $out: Creates a tarball of of the full closure of the base derivation and + its reference information, the partitioner and activate-remote. The + script outputs the tarball on stdout, so it's easy for NixOps to + pipe it to the remote system. + + activate-remote: Copies the base derivation into /mnt and registers it + with the Nix database. Afterwards, it creates the + mentioned chroot wrappers and puts them into /usr/bin + (remember, we're on a non-NixOS system here), together + with the partitioner. + ''; + maintainer = stdenv.lib.maintainers.aszlig; + }; +} diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix index bf546a23b09..027172935ae 100644 --- a/pkgs/top-level/all-packages.nix +++ b/pkgs/top-level/all-packages.nix @@ -7683,6 +7683,9 @@ let hexedit = callPackage ../applications/editors/hexedit { }; + hetznerNixOpsInstaller = + callPackage ../tools/misc/hetzner-nixops-installer { }; + hipchat = callPackage_i686 ../applications/networking/instant-messengers/hipchat { }; homebank = callPackage ../applications/office/homebank { };