diff options
-rw-r--r-- | krebs/5pkgs/simple/withGetopt.nix | 106 | ||||
-rw-r--r-- | shell.nix | 122 | ||||
-rw-r--r-- | tv/3modules/charybdis/default.nix | 2 |
3 files changed, 154 insertions, 76 deletions
diff --git a/krebs/5pkgs/simple/withGetopt.nix b/krebs/5pkgs/simple/withGetopt.nix new file mode 100644 index 000000000..fd59adcaf --- /dev/null +++ b/krebs/5pkgs/simple/withGetopt.nix @@ -0,0 +1,106 @@ +with import <stockholm/lib>; +{ utillinux, writeDash }: + +opt-spec: cmd-spec: let + + cmd = cmd-spec opts; + + cmd-script = + if typeOf cmd == "set" + then "exec ${cmd}" + else cmd; + + opts = mapAttrs (name: value: value // rec { + long = value.long or (replaceStrings ["_"] ["-"] name); + ref = value.ref or "\"\$${varname}\""; + switch = value.switch or false; + varname = value.varname or (replaceStrings ["-"] ["_"] name); + }) opt-spec; + + # true if b requires a to define its default value + opts-before = a: b: + test ".*[$]${stringAsChars (c: "[${c}]") a.varname}\\>.*" (b.default or ""); + + opts-list = let + sort-out = toposort opts-before (attrValues opts); + in + if sort-out ? result + then sort-out.result + else throw "toposort output: ${toJSON sort-out}"; + + wrapper-name = + if typeOf cmd == "set" && cmd ? name + then "${cmd.name}-getopt" + else "getopt-wrapper"; + +in writeDash wrapper-name '' + set -efu + + wrapper_name=${shell.escape wrapper-name} + + ${concatStringsSep "\n" (mapAttrsToList (name: opt: /* sh */ '' + unset ${opt.varname} + '') opts)} + + args=$(${utillinux}/bin/getopt \ + -n "$wrapper_name" \ + -o "" \ + -l ${concatMapStringsSep "," + (opt: opt.long + optionalString (!opt.switch) ":") + (attrValues opts)} \ + -s sh \ + -- "$@") + if \test $? != 0; then exit 1; fi + eval set -- "$args" + + while :; do + case $1 in + ${concatStringsSep "\n" (mapAttrsToList (name: opt: /* sh */ '' + --${opt.long}) + ${if opt.switch then /* sh */ '' + ${opt.varname}=true + shift + '' else /* sh */ '' + ${opt.varname}=$2 + shift 2 + ''} + ;; + '') opts)} + --) + shift + break + esac + done + + ${concatMapStringsSep "\n" + (opt: /* sh */ '' + if \test "''${${opt.varname}+1}" != 1; then + printf '%s: missing mandatory option '--%s'\n' \ + "$wrapper_name" \ + ${shell.escape opt.long} + error=1 + fi + '') + (filter + (x: ! hasAttr "default" x) + (attrValues opts))} + if test "''${error+1}" = 1; then + exit 1 + fi + + ${concatMapStringsSep "\n" + (opt: /* sh */ '' + if \test "''${${opt.varname}+1}" != 1; then + ${opt.varname}=${opt.default} + fi + '') + (filter + (hasAttr "default") + opts-list)} + + ${concatStringsSep "\n" (mapAttrsToList (name: opt: /* sh */ '' + export ${opt.varname} + '') opts)} + + ${cmd-script} +'' @@ -6,43 +6,38 @@ let # high level commands # - # usage: deploy - # [--force-populate] - # [--quiet] - # [--source=PATH] - # --system=SYSTEM - # [--target=TARGET] - # [--user=USER] - cmds.deploy = pkgs.writeDash "cmds.deploy" '' + 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 - command=deploy - . ${init.args} - \test -n "''${quiet-}" || quiet=false - \test -n "''${target-}" || target=$system - \test -n "''${user-}" || user=$LOGNAME - \test -n "''${source_file}" || source_file=$user/1systems/$system/source.nix . ${init.env} - . ${init.proxy} + . ${init.proxy opts} exec ${utils.deploy} - ''; - - # usage: install - # [--force-populate] - # [--quiet] - # [--source=PATH] - # --system=SYSTEM - # --target=TARGET - # [--user=USER] - cmds.install = pkgs.writeBash "cmds.install" '' + ''); + + 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 - command=install - . ${init.args} - \test -n "''${quiet-}" || quiet=false - \test -n "''${user-}" || user=$LOGNAME - \test -n "''${source_file}" || source_file=$user/1systems/$system/source.nix . ${init.env} if \test "''${using_proxy-}" != true; then @@ -55,7 +50,7 @@ let # TODO inline prepare.sh? fi - . ${init.proxy} + . ${init.proxy opts} # Reset PATH because we need access to nixos-install. # TODO provide nixos-install instead of relying on prepare.sh @@ -75,30 +70,28 @@ let cd exec nixos-install - ''; - - # usage: test - # [--force-populate] - # [--quiet] - # [--source=PATH] - # --system=SYSTEM - # --target=TARGET - # [--user=USER] - cmds.test = pkgs.writeDash "cmds.test" /* sh */ '' + ''); + + 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 - command=test - . ${init.args} - \test -n "''${quiet-}" || quiet=false - \test -n "''${user-}" || user=$LOGNAME - \test -n "''${source_file}" || source_file=$user/1systems/$system/source.nix . ${init.env} - . ${init.proxy} + . ${init.proxy opts} exec ${utils.build} config.system.build.toplevel - ''; + ''); # # low level commands @@ -163,28 +156,6 @@ let echo ''; - init.args = pkgs.writeText "init.args" /* sh */ '' - args=$(${pkgs.utillinux}/bin/getopt -n "$command" -s sh \ - -o Qs:t:u: \ - -l force-populate,quiet,source:,system:,target:,user: \ - -- "$@") - if \test $? != 0; then exit 1; fi - eval set -- "$args" - force_populate=false - source_file= - while :; do case $1 in - --force-populate) force_populate=true; shift;; - -Q|--quiet) quiet=true; shift;; - --source) source_file=$2; shift 2;; - -s|--system) system=$2; shift 2;; - -t|--target) target=$2; shift 2;; - -u|--user) user=$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 */ '' export quiet export system @@ -201,7 +172,7 @@ let export target_local="$(echo $target_object | ${pkgs.jq}/bin/jq -r .local)" ''; - init.proxy = pkgs.writeText "init.proxy" /* sh */ '' + init.proxy = opts: pkgs.writeText "init.proxy" /* sh */ '' if \test "''${using_proxy-}" != true; then source=$(get-source "$source_file") @@ -219,11 +190,12 @@ let NIX_PATH=$(quote "$target_path") \ STOCKHOLM_VERSION=$(quote "$STOCKHOLM_VERSION") \ nix-shell --run "$(quote " - quiet=$(quote "$quiet") \ - system=$(quote "$system") \ - target=$(quote "$target") \ + ${lib.concatStringsSep " " (lib.mapAttrsToList + (name: opt: /* sh */ "${opt.varname}=\$(quote ${opt.ref})") + opts + )} \ using_proxy=true \ - $(quote "$command" "$@") + $(quote "$0" "$@") ")" fi fi diff --git a/tv/3modules/charybdis/default.nix b/tv/3modules/charybdis/default.nix index 859dc122c..e252f2e1d 100644 --- a/tv/3modules/charybdis/default.nix +++ b/tv/3modules/charybdis/default.nix @@ -52,7 +52,7 @@ in { systemd.services.charybdis = { wantedBy = [ "multi-user.target" ]; requires = [ "secret.service" ]; - after = [ "network.target" "secret.service" ]; + after = [ "network-online.target" "secret.service" ]; environment = { BANDB_DBPATH = "${cfg.user.home}/ban.db"; }; |