about summary refs log tree commit diff
path: root/pkgs/tools/misc/hetzner-nixops-installer
diff options
context:
space:
mode:
authoraszlig <aszlig@redmoonstudios.org>2013-07-09 07:37:39 +0200
committeraszlig <aszlig@redmoonstudios.org>2013-07-09 08:27:52 +0200
commit2fd13d8fcafdc9291c385787bb8ef4778d3d814d (patch)
treeb4d9a8e5a2fa57448214eadb23734c4e524e2cb8 /pkgs/tools/misc/hetzner-nixops-installer
parentf154735aefee5b73558cb7b298dfa7b08330d7fb (diff)
downloadnixlib-2fd13d8fcafdc9291c385787bb8ef4778d3d814d.tar
nixlib-2fd13d8fcafdc9291c385787bb8ef4778d3d814d.tar.gz
nixlib-2fd13d8fcafdc9291c385787bb8ef4778d3d814d.tar.bz2
nixlib-2fd13d8fcafdc9291c385787bb8ef4778d3d814d.tar.lz
nixlib-2fd13d8fcafdc9291c385787bb8ef4778d3d814d.tar.xz
nixlib-2fd13d8fcafdc9291c385787bb8ef4778d3d814d.tar.zst
nixlib-2fd13d8fcafdc9291c385787bb8ef4778d3d814d.zip
Add new hetzner-nixops-installer package.
This fixes a bunch of issues for the NixOps Hetzner backend, because over there,
it's quite difficult to export the references graph without either duplicaing
lots of code or make a bunch of workarounds.

A detailed description about how it works can be found in the
meta.longDescription attribute.

Signed-off-by: aszlig <aszlig@redmoonstudios.org>
Diffstat (limited to 'pkgs/tools/misc/hetzner-nixops-installer')
-rw-r--r--pkgs/tools/misc/hetzner-nixops-installer/default.nix99
1 files changed, 99 insertions, 0 deletions
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 000000000000..3322097ec778
--- /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;
+  };
+}