Merge branch 'master' of http://cgit.lassul.us/stockholm into klauen-von-lass
This commit is contained in:
commit
dc3723cf8f
@ -104,7 +104,7 @@ in
|
|||||||
"dummy_secrets": "true",
|
"dummy_secrets": "true",
|
||||||
},
|
},
|
||||||
command=[
|
command=[
|
||||||
"nix-shell", "--run", " ".join(["test",
|
"nix-shell", "-I", "stockholm=.", "--run", " ".join(["test",
|
||||||
"--user={}".format(user),
|
"--user={}".format(user),
|
||||||
"--system={}".format(host),
|
"--system={}".format(host),
|
||||||
"--force-populate",
|
"--force-populate",
|
||||||
|
@ -61,6 +61,7 @@ let
|
|||||||
|
|
||||||
hosts = mkOption {
|
hosts = mkOption {
|
||||||
type = with types; attrsOf host;
|
type = with types; attrsOf host;
|
||||||
|
default = {};
|
||||||
};
|
};
|
||||||
|
|
||||||
users = mkOption {
|
users = mkOption {
|
||||||
|
22
krebs/5pkgs/haskell/nix-diff.nix
Normal file
22
krebs/5pkgs/haskell/nix-diff.nix
Normal file
@ -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;
|
||||||
|
}
|
291
krebs/5pkgs/simple/stockholm/default.nix
Normal file
291
krebs/5pkgs/simple/stockholm/default.nix
Normal file
@ -0,0 +1,291 @@
|
|||||||
|
{ 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 <nixpkgs/nixos/lib/eval-config.nix> {
|
||||||
|
modules = [ <nixos-config> ];
|
||||||
|
}).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}
|
||||||
|
|
||||||
|
# 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 HOSTNAME="$(${pkgs.nettools}/bin/hostname)"
|
||||||
|
export STOCKHOLM_VERSION="''${STOCKHOLM_VERSION-$(${shell.get-version})}"
|
||||||
|
|
||||||
|
export quiet
|
||||||
|
export system
|
||||||
|
export target
|
||||||
|
export user
|
||||||
|
|
||||||
|
default_target=root@$system:22/var/src
|
||||||
|
|
||||||
|
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)"
|
||||||
|
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=$(${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"
|
||||||
|
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 <stockholm>; $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
|
||||||
|
'';
|
||||||
|
|
||||||
|
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:
|
||||||
|
lib.nameValuePair "/bin/${name}" { inherit link; }
|
||||||
|
) cmds)
|
@ -5,19 +5,23 @@ let
|
|||||||
|
|
||||||
mainUser = config.users.extraUsers.mainUser;
|
mainUser = config.users.extraUsers.mainUser;
|
||||||
|
|
||||||
browser-select = pkgs.writeScriptBin "browser-select" ''
|
browser-select = let
|
||||||
BROWSER=$(echo -e "${concatStringsSep "\\n" (attrNames config.lass.browser.paths)}" | ${pkgs.dmenu}/bin/dmenu)
|
sortedPaths = sort (a: b: a.value.precedence > b.value.precedence)
|
||||||
|
(mapAttrsToList (name: value: { inherit name value; })
|
||||||
|
config.lass.browser.paths);
|
||||||
|
in pkgs.writeScriptBin "browser-select" ''
|
||||||
|
BROWSER=$(echo -e "${concatStringsSep "\\n" (map (getAttr "name") sortedPaths)}" | ${pkgs.dmenu}/bin/dmenu)
|
||||||
case $BROWSER in
|
case $BROWSER in
|
||||||
${concatMapStringsSep "\n" (n: ''
|
${concatMapStringsSep "\n" (n: ''
|
||||||
${n})
|
${n.name})
|
||||||
export BIN=${config.lass.browser.paths.${n}}/bin/${n}
|
export BIN=${n.value.path}/bin/${n.name}
|
||||||
;;
|
;;
|
||||||
'') (attrNames config.lass.browser.paths)}
|
'') (sortedPaths)}
|
||||||
esac
|
esac
|
||||||
$BIN "$@"
|
$BIN "$@"
|
||||||
'';
|
'';
|
||||||
|
|
||||||
createChromiumUser = name: extraGroups:
|
createChromiumUser = name: extraGroups: precedence:
|
||||||
let
|
let
|
||||||
bin = pkgs.writeScriptBin name ''
|
bin = pkgs.writeScriptBin name ''
|
||||||
/var/run/wrappers/bin/sudo -u ${name} -i ${pkgs.chromium}/bin/chromium $@
|
/var/run/wrappers/bin/sudo -u ${name} -i ${pkgs.chromium}/bin/chromium $@
|
||||||
@ -31,7 +35,7 @@ let
|
|||||||
useDefaultShell = true;
|
useDefaultShell = true;
|
||||||
createHome = true;
|
createHome = true;
|
||||||
};
|
};
|
||||||
lass.browser.paths.${name} = bin;
|
lass.browser.paths.${name}.path = bin;
|
||||||
security.sudo.extraConfig = ''
|
security.sudo.extraConfig = ''
|
||||||
${mainUser.name} ALL=(${name}) NOPASSWD: ALL
|
${mainUser.name} ALL=(${name}) NOPASSWD: ALL
|
||||||
'';
|
'';
|
||||||
@ -40,7 +44,7 @@ let
|
|||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
createFirefoxUser = name: extraGroups:
|
createFirefoxUser = name: extraGroups: precedence:
|
||||||
let
|
let
|
||||||
bin = pkgs.writeScriptBin name ''
|
bin = pkgs.writeScriptBin name ''
|
||||||
/var/run/wrappers/bin/sudo -u ${name} -i ${pkgs.firefox}/bin/firefox $@
|
/var/run/wrappers/bin/sudo -u ${name} -i ${pkgs.firefox}/bin/firefox $@
|
||||||
@ -54,7 +58,10 @@ let
|
|||||||
useDefaultShell = true;
|
useDefaultShell = true;
|
||||||
createHome = true;
|
createHome = true;
|
||||||
};
|
};
|
||||||
lass.browser.paths.${name} = bin;
|
lass.browser.paths.${name} = {
|
||||||
|
path = bin;
|
||||||
|
inherit precedence;
|
||||||
|
};
|
||||||
security.sudo.extraConfig = ''
|
security.sudo.extraConfig = ''
|
||||||
${mainUser.name} ALL=(${name}) NOPASSWD: ALL
|
${mainUser.name} ALL=(${name}) NOPASSWD: ALL
|
||||||
'';
|
'';
|
||||||
@ -79,14 +86,24 @@ in {
|
|||||||
type = types.path;
|
type = types.path;
|
||||||
};
|
};
|
||||||
options.lass.browser.paths = mkOption {
|
options.lass.browser.paths = mkOption {
|
||||||
type = with types; attrsOf path;
|
type = types.attrsOf (types.submodule ({
|
||||||
|
options = {
|
||||||
|
path = mkOption {
|
||||||
|
type = types.path;
|
||||||
|
};
|
||||||
|
precedence = mkOption {
|
||||||
|
type = types.int;
|
||||||
|
default = 0;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}));
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
( createFirefoxUser "ff" [ "audio" ] )
|
( createFirefoxUser "ff" [ "audio" ] 10 )
|
||||||
( createChromiumUser "cr" [ "video" "audio" ] )
|
( createChromiumUser "cr" [ "video" "audio" ] 9 )
|
||||||
|
( createChromiumUser "gm" [ "video" "audio" ] 8 )
|
||||||
( createChromiumUser "wk" [ "video" "audio" ] )
|
( createChromiumUser "wk" [ "video" "audio" ] )
|
||||||
( createChromiumUser "fb" [ "video" "audio" ] )
|
( createChromiumUser "fb" [ "video" "audio" ] )
|
||||||
( createChromiumUser "gm" [ "video" "audio" ] )
|
|
||||||
( createChromiumUser "com" [ "video" "audio" ] )
|
( createChromiumUser "com" [ "video" "audio" ] )
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
230
shell.nix
230
shell.nix
@ -2,239 +2,16 @@ let
|
|||||||
lib = import ./lib;
|
lib = import ./lib;
|
||||||
pkgs = import <nixpkgs> { overlays = [(import ./krebs/5pkgs)]; };
|
pkgs = import <nixpkgs> { overlays = [(import ./krebs/5pkgs)]; };
|
||||||
|
|
||||||
#
|
|
||||||
# high level commands
|
|
||||||
#
|
|
||||||
|
|
||||||
cmds.deploy = 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.default = /* sh */ "$system";
|
|
||||||
user.default = /* sh */ "$LOGNAME";
|
|
||||||
} (opts: pkgs.writeDash "cmds.deploy" ''
|
|
||||||
set -efu
|
|
||||||
|
|
||||||
. ${init.env}
|
|
||||||
. ${init.proxy "deploy" opts}
|
|
||||||
|
|
||||||
# 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 "cmds.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=$(quote "$target_path") \
|
|
||||||
sh -s prepare < ${./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 "cmds.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 "cmds.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 "cmds.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 "cmds.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" | populate --force "$qualified_target"
|
|
||||||
else
|
|
||||||
echo "$source" | 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=$(quote "$target_path") \
|
|
||||||
STOCKHOLM_VERSION=$(quote "$STOCKHOLM_VERSION") \
|
|
||||||
nix-shell --run "$(quote "
|
|
||||||
${lib.concatStringsSep " " (lib.mapAttrsToList
|
|
||||||
(name: opt: /* sh */ "${opt.varname}=\$(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 <stockholm>; $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
|
|
||||||
'';
|
|
||||||
|
|
||||||
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 {
|
in pkgs.stdenv.mkDerivation {
|
||||||
name = "stockholm";
|
name = "stockholm";
|
||||||
shellHook = /* sh */ ''
|
shellHook = /* sh */ ''
|
||||||
export OLD_PATH="$PATH"
|
|
||||||
export NIX_PATH=stockholm=${toString ./.}:nixpkgs=${toString <nixpkgs>}
|
export NIX_PATH=stockholm=${toString ./.}:nixpkgs=${toString <nixpkgs>}
|
||||||
if test -e /nix/var/nix/daemon-socket/socket; then
|
if test -e /nix/var/nix/daemon-socket/socket; then
|
||||||
export NIX_REMOTE=daemon
|
export NIX_REMOTE=daemon
|
||||||
fi
|
fi
|
||||||
export PATH=${lib.makeBinPath [
|
export PATH=${lib.makeBinPath [
|
||||||
pkgs.populate
|
pkgs.stockholm
|
||||||
pkgs.quote
|
]}''${PATH+:$PATH}
|
||||||
shell.cmdspkg
|
|
||||||
]}
|
|
||||||
|
|
||||||
eval "$(declare -F | ${pkgs.gnused}/bin/sed s/declare/unset/)"
|
eval "$(declare -F | ${pkgs.gnused}/bin/sed s/declare/unset/)"
|
||||||
shopt -u no_empty_cmd_completion
|
shopt -u no_empty_cmd_completion
|
||||||
@ -251,9 +28,6 @@ in pkgs.stdenv.mkDerivation {
|
|||||||
:
|
:
|
||||||
}
|
}
|
||||||
|
|
||||||
export HOSTNAME="$(${pkgs.nettools}/bin/hostname)"
|
|
||||||
export STOCKHOLM_VERSION="''${STOCKHOLM_VERSION-$(${shell.get-version})}"
|
|
||||||
|
|
||||||
PS1='\[\e[38;5;162m\]\w\[\e[0m\] '
|
PS1='\[\e[38;5;162m\]\w\[\e[0m\] '
|
||||||
'';
|
'';
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user