diff options
-rw-r--r-- | README.md | 2 | ||||
-rw-r--r-- | lib/default.nix | 3 | ||||
-rw-r--r-- | pkgs/krops/default.nix | 29 | ||||
-rw-r--r-- | pkgs/populate/default.nix | 23 |
4 files changed, 31 insertions, 26 deletions
@@ -71,7 +71,7 @@ If specified as string, the format could be described as: [[USER]@]HOST[:PORT][/SOME/PATH] ``` -Portions in square brakets are optional. +Portions in square brackets are optional. If the `USER` is the empty string, as in e.g. `@somehost`, then the username will be obtained by ssh from its configuration files. diff --git a/lib/default.nix b/lib/default.nix index 5829250..f1f0007 100644 --- a/lib/default.nix +++ b/lib/default.nix @@ -36,6 +36,9 @@ let { if lib.length y != 1 then throw "malformed /etc/hostname" else lib.elemAt y 0; + firstWord = s: + lib.head (lib.match "^([^[:space:]]*).*" s); + isLocalTarget = let origin = lib.mkTarget ""; in target: diff --git a/pkgs/krops/default.nix b/pkgs/krops/default.nix index 4760287..ab74bc3 100644 --- a/pkgs/krops/default.nix +++ b/pkgs/krops/default.nix @@ -5,7 +5,7 @@ in { nix, openssh, populate, writers }: rec { build = target: - remoteCommand target (lib.concatStringsSep " " [ + runShell target (lib.concatStringsSep " " [ "nix build" "-I ${lib.escapeShellArg target.path}" "--no-link -f '<nixpkgs/nixos>'" @@ -13,20 +13,23 @@ in ]); rebuild = args: target: - remoteCommand target "nixos-rebuild -I ${lib.escapeShellArg target.path} ${ + runShell target "nixos-rebuild -I ${lib.escapeShellArg target.path} ${ lib.concatMapStringsSep " " lib.escapeShellArg args }"; - remoteCommand = target: command: - writers.writeDash "build.${target.host}" '' - exec ${openssh}/bin/ssh ${lib.escapeShellArgs (lib.flatten [ - (lib.optionals (target.user != "") ["-l" target.user]) - "-p" target.port - "-t" - target.extraOptions - target.host - (if target.sudo then "sudo ${command}" else command)])} - ''; + runShell = target: command: + if lib.isLocalTarget target + then command + else + writers.writeDash "krops.${target.host}.${lib.firstWord command}" '' + exec ${openssh}/bin/ssh ${lib.escapeShellArgs (lib.flatten [ + (lib.optionals (target.user != "") ["-l" target.user]) + "-p" target.port + "-T" + target.extraOptions + target.host + (if target.sudo then "sudo ${command}" else command)])} + ''; writeCommand = name: { command ? (targetPath: "echo ${targetPath}"), @@ -40,7 +43,7 @@ in writers.writeDash name '' set -efu ${populate { inherit backup force source; target = target'; }} - ${remoteCommand target' (command target'.path)} + ${runShell target' (command target'.path)} ''; writeDeploy = name: { diff --git a/pkgs/populate/default.nix b/pkgs/populate/default.nix index 36a97b3..40c37e3 100644 --- a/pkgs/populate/default.nix +++ b/pkgs/populate/default.nix @@ -6,7 +6,7 @@ with shell; let check = { force, target }: let sentinelFile = "${target.path}/.populate"; - in shell' target /* sh */ '' + in runShell target /* sh */ '' ${optionalString force /* sh */ '' mkdir -vp ${quote (dirOf sentinelFile)} >&2 touch ${quote sentinelFile} @@ -23,7 +23,7 @@ let do-backup = { target }: let sentinelFile = "${target.path}/.populate"; in - shell' target /* sh */ '' + runShell target /* sh */ '' if ! test -d ${quote sentinelFile}; then >&2 printf 'error" sentinel file is not a directory: %s\n' ${quote ( optionalString (!isLocalTarget target) "${target.host}:" + @@ -40,7 +40,7 @@ let ${target.path}/.populate/backup/ ''; - pop.derivation = target: source: shell' target /* sh */ '' + pop.derivation = target: source: runShell target /* sh */ '' nix-build -E ${quote source.text} -o ${quote target.path} >&2 ''; @@ -50,7 +50,7 @@ let in rsync' target config (quote source.path); - pop.git = target: source: shell' target /* sh */ '' + pop.git = target: source: runShell target /* sh */ '' set -efu if ! test -e ${quote target.path}; then git clone --recurse-submodules ${quote source.url} ${quote target.path} @@ -92,7 +92,7 @@ let if test -e ${quote source.dir}/.git; then local_pass_info=${quote source.name}\ $(${git}/bin/git -C ${quote source.dir} log -1 --format=%H ${quote source.name}) - remote_pass_info=$(${shell' target /* sh */ '' + remote_pass_info=$(${runShell target /* sh */ '' cat ${quote target.path}/.pass_info || : ''}) @@ -133,12 +133,12 @@ let pop.pipe = target: source: /* sh */ '' ${quote source.command} | { - ${shell' target /* sh */ "cat > ${quote target.path}"} + ${runShell target /* sh */ "cat > ${quote target.path}"} } ''; # TODO rm -fR instead of ln -f? - pop.symlink = target: source: shell' target /* sh */ '' + pop.symlink = target: source: runShell target /* sh */ '' ln -fnsT ${quote source.target} ${quote target.path} ''; @@ -178,20 +178,19 @@ let >&2 ''; - shell' = target: script: + runShell = target: command: if isLocalTarget target - then script + then command else if target.sudo then /* sh */ '' - ${ssh' target} ${quote target.host} ${quote "sudo bash -c ${quote script}"} + ${ssh' target} ${quote target.host} ${quote "sudo bash -c ${quote command}"} '' else '' - ${ssh' target} ${quote target.host} ${quote script} + ${ssh' target} ${quote target.host} ${quote command} ''; ssh' = target: concatMapStringsSep " " quote (flatten [ "${openssh}/bin/ssh" (optionals (target.user != "") ["-l" target.user]) - "-o" "ControlPersist=no" "-p" target.port "-T" target.extraOptions |