From d039cd9f487bac52e598f6a715924c58315a1e0a Mon Sep 17 00:00:00 2001 From: tv Date: Tue, 5 Dec 2017 22:36:03 +0100 Subject: haskellPackages.nix-diff: init at 1.0.0 --- krebs/5pkgs/haskell/nix-diff.nix | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 krebs/5pkgs/haskell/nix-diff.nix (limited to 'krebs') diff --git a/krebs/5pkgs/haskell/nix-diff.nix b/krebs/5pkgs/haskell/nix-diff.nix new file mode 100644 index 00000000..2070dbd2 --- /dev/null +++ b/krebs/5pkgs/haskell/nix-diff.nix @@ -0,0 +1,22 @@ +{ mkDerivation, attoparsec, base, containers, Diff, fetchgit, mtl +, nix-derivation, optparse-generic, stdenv, system-filepath, text +, unix, vector +}: +mkDerivation { + pname = "nix-diff"; + version = "1.0.0"; + src = fetchgit { + url = "https://github.com/Gabriel439/nix-diff"; + sha256 = "1k00nx8pannqmpzadkwfrs6bf79yk22ynhd033z5rsyw0m8fcz9k"; + rev = "e32ffa2c7f38b47a71325a042c1d887fb46cdf7d"; + }; + isLibrary = false; + isExecutable = true; + executableHaskellDepends = [ + attoparsec base containers Diff mtl nix-derivation optparse-generic + system-filepath text unix vector + ]; + homepage = "https://github.com/Gabriel439/nix-diff"; + description = "Explain why two Nix derivations differ"; + license = stdenv.lib.licenses.bsd3; +} -- cgit v1.2.3 From d2de3e883ac0bb229ef45a15fcbf4feb31bb5b75 Mon Sep 17 00:00:00 2001 From: tv Date: Tue, 5 Dec 2017 23:08:36 +0100 Subject: stockholm: init --- krebs/5pkgs/simple/stockholm/default.nix | 279 +++++++++++++++++++++++++++++++ 1 file changed, 279 insertions(+) create mode 100644 krebs/5pkgs/simple/stockholm/default.nix (limited to 'krebs') diff --git a/krebs/5pkgs/simple/stockholm/default.nix b/krebs/5pkgs/simple/stockholm/default.nix new file mode 100644 index 00000000..3d41c49c --- /dev/null +++ b/krebs/5pkgs/simple/stockholm/default.nix @@ -0,0 +1,279 @@ +{ pkgs }: let + + stockholm-dir = ../../../..; + + lib = import (stockholm-dir + "/lib"); + + # + # high level commands + # + + cmds.deploy = pkgs.withGetopt { + diff = { default = /* sh */ "false"; switch = true; }; + force-populate = { default = /* sh */ "false"; switch = true; }; + quiet = { default = /* sh */ "false"; switch = true; }; + source_file = { + default = /* sh */ "$user/1systems/$system/source.nix"; + long = "source"; + }; + system = {}; + target.default = /* sh */ "$system"; + user.default = /* sh */ "$LOGNAME"; + } (opts: pkgs.writeDash "stockholm.deploy" '' + set -efu + + . ${init.env} + . ${init.proxy "deploy" opts} + + if \test ${opts.diff.ref} = true; then + + system_profile=/nix/var/nix/profiles/system + system_drv_cur=/etc/system.drv + + system_drv_new=$( + ${pkgs.nix}/bin/nix-instantiate \ + -Q \ + -I "$target_path" \ + -E ' + (import { + modules = [ ]; + }).config.system.build.toplevel + ' + ) + + if \test -e "$system_drv_cur"; then + + system_drv_cur_c=$(${pkgs.coreutils}/bin/readlink -f "$system_drv_cur") + system_drv_new_c=$(${pkgs.coreutils}/bin/readlink -f "$system_drv_new") + + if \test "$system_drv_cur_c" = "$system_drv_new_c"; then + echo "$0: system up to date" >&2 + exit 0 + fi + + system_drv_cur=$system_drv_cur_c \ + system_drv_new=$system_drv_new_c \ + ${pkgs.utillinux}/bin/script \ + --command ' + ${pkgs.haskellPackages.nix-diff}/bin/nix-diff \ + "$system_drv_cur" "$system_drv_new" + ' \ + --quiet \ + --return \ + /dev/null + + printf 'deploy? [N/y] ' >&2 + read -r REPLY + if \test "$REPLY" != y; then + echo "$0: abort!" >&2 + exit 1 + fi + else + echo "$0: --${opts.diff.long} has no effect because "$system_drv_cur" doesn't exist" >&2 + fi + + new_system=$(${pkgs.nix}/bin/nix-store --realize "$system_drv_new") + + ${pkgs.nix}/bin/nix-env -p "$system_profile" --set "$new_system" + PATH=${lib.makeBinPath [ + pkgs.systemd + ]} \ + "$system_profile"/bin/switch-to-configuration switch + + ${pkgs.coreutils}/bin/ln -fns "$system_drv_new" "$system_drv_cur" + exit + fi + + # Use system's nixos-rebuild, which is not self-contained + export PATH=/run/current-system/sw/bin + exec ${utils.with-whatsupnix} \ + nixos-rebuild switch \ + --show-trace \ + -I "$target_path" + ''); + + cmds.install = pkgs.withGetopt { + force-populate = { default = /* sh */ "false"; switch = true; }; + quiet = { default = /* sh */ "false"; switch = true; }; + source_file = { + default = /* sh */ "$user/1systems/$system/source.nix"; + long = "source"; + }; + system = {}; + target = {}; + user.default = /* sh */ "$LOGNAME"; + } (opts: pkgs.writeBash "stockholm.install" '' + set -efu + + . ${init.env} + + if \test "''${using_proxy-}" != true; then + ${pkgs.openssh}/bin/ssh \ + -o StrictHostKeyChecking=no \ + -o UserKnownHostsFile=/dev/null \ + "$target_user@$target_host" -p "$target_port" \ + env target_path=$(${pkgs.quote}/bin/quote "$target_path") \ + sh -s prepare \ + < ${stockholm-dir + "/krebs/4lib/infest/prepare.sh"} + # TODO inline prepare.sh? + fi + + . ${init.proxy "install" opts} + + # Reset PATH because we need access to nixos-install. + # TODO provide nixos-install instead of relying on prepare.sh + export PATH="$OLD_PATH" + + # these variables get defined by nix-shell (i.e. nix-build) from + # XDG_RUNTIME_DIR and reference the wrong directory (/run/user/0), + # which only exists on / and not at /mnt. + export NIX_BUILD_TOP=/tmp + export TEMPDIR=/tmp + export TEMP=/tmp + export TMPDIR=/tmp + export TMP=/tmp + export XDG_RUNTIME_DIR=/tmp + + export NIXOS_CONFIG="$target_path/nixos-config" + + cd + exec nixos-install + ''); + + cmds.test = pkgs.withGetopt { + force-populate = { default = /* sh */ "false"; switch = true; }; + quiet = { default = /* sh */ "false"; switch = true; }; + source_file = { + default = /* sh */ "$user/1systems/$system/source.nix"; + long = "source"; + }; + system = {}; + target = {}; + user.default = /* sh */ "$LOGNAME"; + } (opts: pkgs.writeDash "stockholm.test" /* sh */ '' + set -efu + + export dummy_secrets=true + + . ${init.env} + . ${init.proxy "test" opts} + + exec ${utils.build} config.system.build.toplevel + ''); + + # + # low level commands + # + + # usage: get-source SOURCE_FILE + cmds.get-source = pkgs.writeDash "stockholm.get-source" '' + set -efu + exec ${pkgs.nix}/bin/nix-instantiate \ + --eval \ + --json \ + --readonly-mode \ + --show-trace \ + --strict \ + "$1" + ''; + + # usage: parse-target [--default=TARGET] TARGET + # TARGET = [USER@]HOST[:PORT][/PATH] + cmds.parse-target = pkgs.withGetopt { + default_target = { + long = "default"; + short = "d"; + }; + } (opts: pkgs.writeDash "stockholm.parse-target" '' + set -efu + target=$1; shift + for arg; do echo "$0: bad argument: $arg" >&2; done + if \test $# != 0; then exit 2; fi + exec ${pkgs.jq}/bin/jq \ + -enr \ + --arg default_target "$default_target" \ + --arg target "$target" \ + -f ${pkgs.writeText "stockholm.parse-target.jq" '' + def parse: match("^(?:([^@]+)@)?([^:/]+)?(?::([0-9]+))?(/.*)?$") | { + user: .captures[0].string, + host: .captures[1].string, + port: .captures[2].string, + path: .captures[3].string, + }; + def sanitize: with_entries(select(.value != null)); + ($default_target | parse) + ($target | parse | sanitize) | + . + { local: (.user == env.LOGNAME and .host == env.HOSTNAME) } + ''} + ''); + + init.env = pkgs.writeText "init.env" /* sh */ '' + export quiet + export system + export target + export user + + default_target=root@$system:22/var/src + + export target_object="$(parse-target "$target" -d "$default_target")" + export target_user="$(echo $target_object | ${pkgs.jq}/bin/jq -r .user)" + export target_host="$(echo $target_object | ${pkgs.jq}/bin/jq -r .host)" + export target_port="$(echo $target_object | ${pkgs.jq}/bin/jq -r .port)" + export target_path="$(echo $target_object | ${pkgs.jq}/bin/jq -r .path)" + export target_local="$(echo $target_object | ${pkgs.jq}/bin/jq -r .local)" + ''; + + init.proxy = command: opts: pkgs.writeText "init.proxy" /* sh */ '' + if \test "''${using_proxy-}" != true; then + + source=$(get-source "$source_file") + qualified_target=$target_user@$target_host:$target_port$target_path + if \test "$force_populate" = true; then + echo "$source" | ${pkgs.populate}/bin/populate --force "$qualified_target" + else + echo "$source" | ${pkgs.populate}/bin/populate "$qualified_target" + fi + + if \test "$target_local" != true; then + exec ${pkgs.openssh}/bin/ssh \ + "$target_user@$target_host" -p "$target_port" \ + cd "$target_path/stockholm" \; \ + NIX_PATH=$(${pkgs.quote}/bin/quote "$target_path") \ + STOCKHOLM_VERSION=$(${pkgs.quote}/bin/quote "$STOCKHOLM_VERSION") \ + nix-shell --run "$(${pkgs.quote}/bin/quote " + ${lib.concatStringsSep " " (lib.mapAttrsToList + (name: opt: /* sh */ + "${opt.varname}=\$(${pkgs.quote}/bin/quote ${opt.ref})") + opts + )} \ + using_proxy=true \ + ${lib.shell.escape command} \ + $WITHGETOPT_ORIG_ARGS \ + ")" + fi + fi + ''; + + utils.build = pkgs.writeDash "utils.build" '' + set -efu + ${utils.with-whatsupnix} \ + ${pkgs.nix}/bin/nix-build \ + --no-out-link \ + --show-trace \ + -E "with import ; $1" \ + -I "$target_path" \ + ''; + + utils.with-whatsupnix = pkgs.writeDash "utils.with-whatsupnix" '' + set -efu + if \test "$quiet" = true; then + "$@" -Q 2>&1 | ${pkgs.whatsupnix}/bin/whatsupnix + else + exec "$@" + fi + ''; + +in + + pkgs.writeOut "stockholm" (lib.mapAttrs' (name: link: + lib.nameValuePair "/bin/${name}" { inherit link; } + ) cmds) -- cgit v1.2.3 From 3fb25717c5c7dbe69f56cea4c529cac398789c2b Mon Sep 17 00:00:00 2001 From: tv Date: Tue, 5 Dec 2017 23:20:50 +0100 Subject: stockholm: interpolate cmds.* --- krebs/5pkgs/simple/stockholm/default.nix | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'krebs') diff --git a/krebs/5pkgs/simple/stockholm/default.nix b/krebs/5pkgs/simple/stockholm/default.nix index 3d41c49c..3d9cea64 100644 --- a/krebs/5pkgs/simple/stockholm/default.nix +++ b/krebs/5pkgs/simple/stockholm/default.nix @@ -214,7 +214,9 @@ default_target=root@$system:22/var/src - export target_object="$(parse-target "$target" -d "$default_target")" + export target_object="$( + ${cmds.parse-target} "$target" -d "$default_target" + )" export target_user="$(echo $target_object | ${pkgs.jq}/bin/jq -r .user)" export target_host="$(echo $target_object | ${pkgs.jq}/bin/jq -r .host)" export target_port="$(echo $target_object | ${pkgs.jq}/bin/jq -r .port)" @@ -225,7 +227,7 @@ init.proxy = command: opts: pkgs.writeText "init.proxy" /* sh */ '' if \test "''${using_proxy-}" != true; then - source=$(get-source "$source_file") + source=$(${cmds.get-source} "$source_file") qualified_target=$target_user@$target_host:$target_port$target_path if \test "$force_populate" = true; then echo "$source" | ${pkgs.populate}/bin/populate --force "$qualified_target" -- cgit v1.2.3 From 289dd785e5bd5f3a628a7f0282ed4f8638277c5c Mon Sep 17 00:00:00 2001 From: tv Date: Tue, 5 Dec 2017 23:25:09 +0100 Subject: stockholm: export HOSTNAME and STOCKHOLM_VERSION --- krebs/5pkgs/simple/stockholm/default.nix | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'krebs') diff --git a/krebs/5pkgs/simple/stockholm/default.nix b/krebs/5pkgs/simple/stockholm/default.nix index 3d9cea64..da07c812 100644 --- a/krebs/5pkgs/simple/stockholm/default.nix +++ b/krebs/5pkgs/simple/stockholm/default.nix @@ -207,6 +207,10 @@ ''); init.env = pkgs.writeText "init.env" /* sh */ '' + + export HOSTNAME="$(${pkgs.nettools}/bin/hostname)" + export STOCKHOLM_VERSION="''${STOCKHOLM_VERSION-$(${shell.get-version})}" + export quiet export system export target @@ -274,6 +278,16 @@ fi ''; + shell.get-version = pkgs.writeDash "stockholm.get-version" '' + set -efu + version=git.$(${pkgs.git}/bin/git describe --always --dirty) + case $version in (*-dirty) + version=$version@$HOSTNAME + esac + date=$(${pkgs.coreutils}/bin/date +%y.%m) + echo "$date.$version" + ''; + in pkgs.writeOut "stockholm" (lib.mapAttrs' (name: link: -- cgit v1.2.3 From 3f8ae7bf425eb2addef7634a113197774fe3f76a Mon Sep 17 00:00:00 2001 From: lassulus Date: Tue, 5 Dec 2017 23:37:19 +0100 Subject: krebs.hosts: set default --- krebs/3modules/default.nix | 1 + 1 file changed, 1 insertion(+) (limited to 'krebs') diff --git a/krebs/3modules/default.nix b/krebs/3modules/default.nix index a8933e71..7cf02cd8 100644 --- a/krebs/3modules/default.nix +++ b/krebs/3modules/default.nix @@ -61,6 +61,7 @@ let hosts = mkOption { type = with types; attrsOf host; + default = {}; }; users = mkOption { -- cgit v1.2.3 From 7b38d1a8219ff7cfa39202ff17f1c92bd799c9b0 Mon Sep 17 00:00:00 2001 From: tv Date: Wed, 6 Dec 2017 00:02:17 +0100 Subject: stockholm: drop OLD_PATH --- krebs/5pkgs/simple/stockholm/default.nix | 4 ---- 1 file changed, 4 deletions(-) (limited to 'krebs') diff --git a/krebs/5pkgs/simple/stockholm/default.nix b/krebs/5pkgs/simple/stockholm/default.nix index da07c812..5705f086 100644 --- a/krebs/5pkgs/simple/stockholm/default.nix +++ b/krebs/5pkgs/simple/stockholm/default.nix @@ -120,10 +120,6 @@ . ${init.proxy "install" opts} - # Reset PATH because we need access to nixos-install. - # TODO provide nixos-install instead of relying on prepare.sh - export PATH="$OLD_PATH" - # these variables get defined by nix-shell (i.e. nix-build) from # XDG_RUNTIME_DIR and reference the wrong directory (/run/user/0), # which only exists on / and not at /mnt. -- cgit v1.2.3 From 19781ae7a4897c8f67e98ac6c57b75bb0c3d06b4 Mon Sep 17 00:00:00 2001 From: lassulus Date: Wed, 6 Dec 2017 00:08:11 +0100 Subject: krebs ci: stockholm=. --- krebs/3modules/ci.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'krebs') diff --git a/krebs/3modules/ci.nix b/krebs/3modules/ci.nix index adbc1ebe..b56f5c54 100644 --- a/krebs/3modules/ci.nix +++ b/krebs/3modules/ci.nix @@ -104,7 +104,7 @@ in "dummy_secrets": "true", }, command=[ - "nix-shell", "--run", " ".join(["test", + "nix-shell", "-I", "stockholm=.", "--run", " ".join(["test", "--user={}".format(user), "--system={}".format(host), "--force-populate", -- cgit v1.2.3