let lib = import ./lib; pkgs = import { overlays = [(import ./krebs/5pkgs)]; }; # usage: deploy --system=SYSTEM [--target=TARGET] cmds.deploy = pkgs.writeDash "cmds.deploy" '' set -efu command=deploy . ${init.args} \test -n "''${target-}" || target=$system . ${init.env} exec ${utils.deploy} ''; # usage: test --system=SYSTEM --target=TARGET cmds.test = pkgs.writeDash "cmds.test" /* sh */ '' set -efu command=test . ${init.args} . ${init.env} export dummy_secrets=true exec ${utils.build} config.system.build.toplevel ''; init.args = pkgs.writeText "init.args" /* sh */ '' args=$(${pkgs.utillinux}/bin/getopt -n "$command" -s sh \ -o s:t: \ -l system:,target: \ -- "$@") if \test $? != 0; then exit 1; fi eval set -- "$args" while :; do case $1 in -s|--system) system=$2; shift 2;; -t|--target) target=$2; shift 2;; --) shift; break;; esac; done for arg; do echo "$command: bad argument: $arg" >&2; done if \test $# != 0; then exit 2; fi ''; init.env = pkgs.writeText "init.env" /* sh */ '' config=''${config-$LOGNAME/1systems/$system/config.nix} source=''${source-$LOGNAME/1systems/$system/source.nix} export config export source export system export target export target_object="$(${init.env.parsetarget} $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)" if \test "''${using_proxy-}" != true; then ${init.env.populate} if \test "$target_local" != true; then exec ${init.env.proxy} "$command" "$@" fi fi '' // { parsetarget = pkgs.writeDash "init.env.parsetarget" '' set -efu exec ${pkgs.jq}/bin/jq \ -enr \ --arg target "$1" \ -f ${init.env.parsetarget.jq} '' // { jq = pkgs.writeText "init.env.parsetarget.jq" '' def when(c; f): if c then f else . end; def capturesDef(i; v): .captures[i].string | when(. == null; v); $target | match("^(?:([^@]+)@)?([^:/]+)?(?::([0-9]+))?(/.*)?$") | { user: capturesDef(0; "root"), host: capturesDef(1; env.system), port: capturesDef(2; "22"), path: capturesDef(3; "/var/src"), } | . + { local: (.user == env.LOGNAME and .host == env.HOSTNAME), } ''; }; populate = pkgs.writeDash "init.env.populate" '' set -efu _source=$(${pkgs.nix}/bin/nix-instantiate \ --eval \ --json \ --readonly-mode \ --show-trace \ --strict \ -I nixos-config="$config" \ "$source") echo $_source | ${pkgs.populate}/bin/populate \ "$target_user@$target_host:$target_port$target_path" \ >&2 unset _source ''; proxy = pkgs.writeDash "init.env.proxy" '' set -efu q() { ${pkgs.jq}/bin/jq -nr --arg x "$*" '$x | @sh "\(.)"' } exec ${pkgs.openssh}/bin/ssh \ "$target_user@$target_host" -p "$target_port" \ cd "$target_path/stockholm" \; \ NIX_PATH=$(q "$target_path") \ STOCKHOLM_VERSION=$STOCKHOLM_VERSION \ nix-shell \ --run $(q \ config=$config \ system=$system \ target=$target \ using_proxy=true \ "$*" ) ''; }; utils.build = pkgs.writeDash "utils.build" '' set -efu ${pkgs.nix}/bin/nix-build \ -Q \ --no-out-link \ --show-trace \ -E "with import ; $1" \ -I "$target_path" \ 2>&1 | ${pkgs.whatsupnix}/bin/whatsupnix ''; utils.deploy = pkgs.writeDash "utils.deploy" '' set -efu PATH=/run/current-system/sw/bin nixos-rebuild switch \ -Q \ --show-trace \ -I "$target_path" \ 2>&1 | ${pkgs.whatsupnix}/bin/whatsupnix ''; shell.get-version = pkgs.writeDash "shell.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" ''; shell.cmdspkg = pkgs.writeOut "shell.cmdspkg" (lib.mapAttrs' (name: link: lib.nameValuePair "/bin/${name}" { inherit link; } ) cmds); in pkgs.stdenv.mkDerivation { name = "stockholm"; shellHook = /* sh */ '' export NIX_PATH="stockholm=$PWD''${NIX_PATH+:$NIX_PATH}" export PATH=${lib.makeBinPath [ shell.cmdspkg ]} eval "$(declare -F | ${pkgs.gnused}/bin/sed s/declare/unset/)" shopt -u no_empty_cmd_completion unalias -a enable -n \ . [ alias bg bind break builtin caller cd command compgen complete \ compopt continue dirs disown eval exec false fc fg getopts hash \ help history jobs kill let local logout mapfile popd printf pushd \ pwd read readarray readonly shift source suspend test times trap \ true typeset ulimit umask unalias wait exitHandler() { : } export HOSTNAME="$(${pkgs.nettools}/bin/hostname)" export STOCKHOLM_VERSION="''${STOCKHOLM_VERSION-$(${shell.get-version})}" PS1='\[\e[38;5;162m\]\w\[\e[0m\] ' ''; }