From e4422212d4e40189ee23ede2b404006039035bc8 Mon Sep 17 00:00:00 2001 From: tv Date: Sun, 17 Apr 2016 02:04:52 +0200 Subject: krebs.on-failure: send journal since start of failed plan --- krebs/3modules/on-failure.nix | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'krebs/3modules') diff --git a/krebs/3modules/on-failure.nix b/krebs/3modules/on-failure.nix index 13d561b8..a471a4bc 100644 --- a/krebs/3modules/on-failure.nix +++ b/krebs/3modules/on-failure.nix @@ -84,6 +84,14 @@ ${pkgs.systemd}/bin/journalctl \ --lines=${toString plan.journalctl.lines} \ --output=${plan.journalctl.output} \ + --since="$( + ${pkgs.coreutils}/bin/date +'%F %T UTC' -ud "$( + ${pkgs.systemd}/bin/systemctl show \ + -p ExecMainStartTimestamp \ + ${shell.escape plan.name} \ + | ${pkgs.coreutils}/bin/cut -d= -f2- + )" + )" \ --unit=${shell.escape plan.name}.service } | ${shell.escape cfg.sendmail} -t ''; -- cgit v1.2.3 From 904d037bd704d9690b8a9a8e8338950931e3ccd1 Mon Sep 17 00:00:00 2001 From: tv Date: Sun, 17 Apr 2016 03:50:49 +0200 Subject: krebs.backup: allow injecting variables into dst shell --- krebs/3modules/backup.nix | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) (limited to 'krebs/3modules') diff --git a/krebs/3modules/backup.nix b/krebs/3modules/backup.nix index d22dd381..1cd851a4 100644 --- a/krebs/3modules/backup.nix +++ b/krebs/3modules/backup.nix @@ -103,7 +103,8 @@ let plan.method == method && config.krebs.build.host.name == plan.${side}.host.name; - start = plan: pkgs.writeDash "backup.${plan.name}" '' + start = plan: pkgs.writeScript "backup.${plan.name}" '' + #! ${pkgs.bash}/bin/bash set -efu ${getAttr plan.method { push = '' @@ -116,12 +117,12 @@ let dst_path=${shell.escape plan.dst.path} dst=$dst_user@$dst_host:$dst_path echo "update snapshot: current; $src -> $dst" >&2 - dst_shell() { + dst_exec() { exec ssh -F /dev/null \ -i "$identity" \ ''${dst_port:+-p $dst_port} \ "$dst_user@$dst_host" \ - -T "$with_dst_path_lock_script" + -T "exec$(printf ' %q' "$@")" } rsh="ssh -F /dev/null -i $identity ''${dst_port:+-p $dst_port}" local_rsync() { @@ -142,8 +143,8 @@ let dst_path=${shell.escape plan.dst.path} dst=$dst_path echo "update snapshot: current; $dst <- $src" >&2 - dst_shell() { - eval "$with_dst_path_lock_script" + dst_exec() { + exec "$@" } rsh="ssh -F /dev/null -i $identity ''${src_port:+-p $src_port}" local_rsync() { @@ -153,13 +154,7 @@ let remote_rsync=rsync ''; }} - # Note that this only works because we trust date +%s to produce output - # that doesn't need quoting when used to generate a command string. - # TODO relax this requirement by selectively allowing to inject variables - # e.g.: ''${shell.quote "exec env NOW=''${shell.unquote "$NOW"} ..."} - with_dst_path_lock_script="exec env start_date=$(date +%s) "${shell.escape - "flock -n ${shell.escape plan.dst.path} /bin/sh" - } + start_date=$(date +%s) local_rsync >&2 \ -aAXF --delete \ --rsh="$rsh" \ @@ -167,7 +162,10 @@ let --link-dest="$dst_path/current" \ "$src/" \ "$dst/.partial" - dst_shell < ${toFile "backup.${plan.name}.take-snapshots" '' + dst_exec env \ + start_date="$start_date" \ + flock -n "$dst_path" \ + /bin/sh < ${toFile "backup.${plan.name}.take-snapshots" '' set -efu : $start_date -- cgit v1.2.3 From 453384b60b628f97074c74940e88570aa8eab811 Mon Sep 17 00:00:00 2001 From: tv Date: Sun, 17 Apr 2016 03:51:55 +0200 Subject: krebs.backup: inject dst_path into dst shell --- krebs/3modules/backup.nix | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) (limited to 'krebs/3modules') diff --git a/krebs/3modules/backup.nix b/krebs/3modules/backup.nix index 1cd851a4..1e926429 100644 --- a/krebs/3modules/backup.nix +++ b/krebs/3modules/backup.nix @@ -163,41 +163,40 @@ let "$src/" \ "$dst/.partial" dst_exec env \ + dst_path="$dst_path" \ start_date="$start_date" \ flock -n "$dst_path" \ /bin/sh < ${toFile "backup.${plan.name}.take-snapshots" '' set -efu - : $start_date + : $dst_path $start_date - dst=${shell.escape plan.dst.path} - - mv "$dst/current" "$dst/.previous" - mv "$dst/.partial" "$dst/current" - rm -fR "$dst/.previous" + mv "$dst_path/current" "$dst_path/.previous" + mv "$dst_path/.partial" "$dst_path/current" + rm -fR "$dst_path/.previous" echo >&2 snapshot() {( : $ns $format $retain name=$(date --date="@$start_date" +"$format") - if ! test -e "$dst/$ns/$name"; then + if ! test -e "$dst_path/$ns/$name"; then echo >&2 "create snapshot: $ns/$name" - mkdir -m 0700 -p "$dst/$ns" + mkdir -m 0700 -p "$dst_path/$ns" rsync >&2 \ -aAXF --delete \ - --link-dest="$dst/current" \ - "$dst/current/" \ - "$dst/$ns/.partial.$name" - mv "$dst/$ns/.partial.$name" "$dst/$ns/$name" + --link-dest="$dst_path/current" \ + "$dst_path/current/" \ + "$dst_path/$ns/.partial.$name" + mv "$dst_path/$ns/.partial.$name" "$dst_path/$ns/$name" echo >&2 fi case $retain in ([0-9]*) delete_from=$(($retain + 1)) - ls -r "$dst/$ns" \ + ls -r "$dst_path/$ns" \ | sed -n "$delete_from,\$p" \ | while read old_name; do echo >&2 "delete snapshot: $ns/$old_name" - rm -fR "$dst/$ns/$old_name" + rm -fR "$dst_path/$ns/$old_name" done ;; (ALL) -- cgit v1.2.3 From affb69250d13f64d2be14327c1b47d23cadcb987 Mon Sep 17 00:00:00 2001 From: tv Date: Sun, 17 Apr 2016 04:13:32 +0200 Subject: krebs.backup network-ssh-port: fail if cannot find port --- krebs/3modules/backup.nix | 9 ++++++--- krebs/3modules/default.nix | 2 +- 2 files changed, 7 insertions(+), 4 deletions(-) (limited to 'krebs/3modules') diff --git a/krebs/3modules/backup.nix b/krebs/3modules/backup.nix index 1e926429..e85a3dfa 100644 --- a/krebs/3modules/backup.nix +++ b/krebs/3modules/backup.nix @@ -120,11 +120,11 @@ let dst_exec() { exec ssh -F /dev/null \ -i "$identity" \ - ''${dst_port:+-p $dst_port} \ + -p $dst_port \ "$dst_user@$dst_host" \ -T "exec$(printf ' %q' "$@")" } - rsh="ssh -F /dev/null -i $identity ''${dst_port:+-p $dst_port}" + rsh="ssh -F /dev/null -i $identity -p $dst_port" local_rsync() { rsync "$@" } @@ -146,7 +146,7 @@ let dst_exec() { exec "$@" } - rsh="ssh -F /dev/null -i $identity ''${src_port:+-p $src_port}" + rsh="ssh -F /dev/null -i $identity -p $src_port" local_rsync() { mkdir -m 0700 -p ${shell.escape plan.dst.path}/current flock -n ${shell.escape plan.dst.path} rsync "$@" @@ -231,6 +231,9 @@ let ${concatStringsSep ";;\n" (mapAttrsToList (_: net: "(${head net.aliases}) echo ${toString net.ssh.port}") host.nets)};; + (*) + echo network-ssh-port: unhandled case: ${word} >&2 + exit 1 esac ''; diff --git a/krebs/3modules/default.nix b/krebs/3modules/default.nix index be530d46..10c61b63 100644 --- a/krebs/3modules/default.nix +++ b/krebs/3modules/default.nix @@ -218,7 +218,7 @@ let (filter (hasSuffix ".${cfg.search-domain}") longs); add-port = a: - if net.ssh.port != null + if net.ssh.port != 22 then "[${a}]:${toString net.ssh.port}" else a; in -- cgit v1.2.3 From 6ec3d922a48ad6a583315a4433a7170e6850c676 Mon Sep 17 00:00:00 2001 From: tv Date: Sun, 17 Apr 2016 05:24:33 +0200 Subject: krebs.backup network-ssh-port -> pkgs.get-ssh-port --- krebs/3modules/backup.nix | 17 ++--------------- 1 file changed, 2 insertions(+), 15 deletions(-) (limited to 'krebs/3modules') diff --git a/krebs/3modules/backup.nix b/krebs/3modules/backup.nix index e85a3dfa..f9008150 100644 --- a/krebs/3modules/backup.nix +++ b/krebs/3modules/backup.nix @@ -113,7 +113,7 @@ let src=$src_path dst_user=root dst_host=$(${fastest-address plan.dst.host}) - dst_port=$(${network-ssh-port plan.dst.host "$dst_host"}) + dst_port=$(${pkgs.get-ssh-port}/bin/get-ssh-port "$dst_host") dst_path=${shell.escape plan.dst.path} dst=$dst_user@$dst_host:$dst_path echo "update snapshot: current; $src -> $dst" >&2 @@ -137,7 +137,7 @@ let identity=${shell.escape plan.dst.host.ssh.privkey.path} src_user=root src_host=$(${fastest-address plan.src.host}) - src_port=$(${network-ssh-port plan.src.host "$src_host"}) + src_port=$(${pkgs.get-ssh-port}/bin/get-ssh-port "$src_host") src_path=${shell.escape plan.src.path} src=$src_user@$src_host:$src_path dst_path=${shell.escape plan.dst.path} @@ -224,19 +224,6 @@ let | ${pkgs.coreutils}/bin/head -1; } ''; - # Note that we don't escape word on purpose, so we can deref shell vars. - # TODO type word - network-ssh-port = host: word: '' - case ${word} in - ${concatStringsSep ";;\n" (mapAttrsToList - (_: net: "(${head net.aliases}) echo ${toString net.ssh.port}") - host.nets)};; - (*) - echo network-ssh-port: unhandled case: ${word} >&2 - exit 1 - esac - ''; - in out # TODO ionice # TODO mail on failed push, pull -- cgit v1.2.3 From 70c27e21b1a31aac678a0a19127d86395e2b115e Mon Sep 17 00:00:00 2001 From: tv Date: Sun, 17 Apr 2016 05:26:02 +0200 Subject: krebs.backup: rm stale TODO Done in 13df24f8f09469c32077ded463d99033042e25ee --- krebs/3modules/backup.nix | 1 - 1 file changed, 1 deletion(-) (limited to 'krebs/3modules') diff --git a/krebs/3modules/backup.nix b/krebs/3modules/backup.nix index f9008150..22c860b8 100644 --- a/krebs/3modules/backup.nix +++ b/krebs/3modules/backup.nix @@ -226,7 +226,6 @@ let in out # TODO ionice -# TODO mail on failed push, pull # TODO mail on missing push # TODO don't cancel plans on activation # also, don't hang while deploying at: -- cgit v1.2.3 From 377b0dff1ca075a9b57660d8e2ec3596fd3e08e7 Mon Sep 17 00:00:00 2001 From: tv Date: Sun, 17 Apr 2016 06:00:48 +0200 Subject: krebs.backup: don't create plan.dst.path implicitly --- krebs/3modules/backup.nix | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'krebs/3modules') diff --git a/krebs/3modules/backup.nix b/krebs/3modules/backup.nix index 22c860b8..4172c980 100644 --- a/krebs/3modules/backup.nix +++ b/krebs/3modules/backup.nix @@ -129,6 +129,7 @@ let rsync "$@" } remote_rsync=${shell.escape (concatStringsSep " && " [ + "stat ${shell.escape plan.dst.path} >/dev/null" "mkdir -m 0700 -p ${shell.escape plan.dst.path}/current" "exec flock -n ${shell.escape plan.dst.path} rsync" ])} @@ -148,6 +149,7 @@ let } rsh="ssh -F /dev/null -i $identity -p $src_port" local_rsync() { + stat ${shell.escape plan.dst.path} >/dev/null mkdir -m 0700 -p ${shell.escape plan.dst.path}/current flock -n ${shell.escape plan.dst.path} rsync "$@" } @@ -230,7 +232,6 @@ in out # TODO don't cancel plans on activation # also, don't hang while deploying at: # starting the following units: backup.wu-home-xu.push.service, backup.wu-home-xu.push.timer -# TODO make sure /bku is properly mounted # TODO make sure that secure hosts cannot backup to insecure ones # TODO optionally only backup when src and dst are near enough :) # TODO try using btrfs for snapshots (configurable) -- cgit v1.2.3 From f5f7abce0d343c20a35bb12c49d03c5bf544d8a9 Mon Sep 17 00:00:00 2001 From: tv Date: Sun, 17 Apr 2016 10:23:01 +0200 Subject: krebs: programs.ssh.extraConfig += Host ... Port ... --- krebs/3modules/default.nix | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) (limited to 'krebs/3modules') diff --git a/krebs/3modules/default.nix b/krebs/3modules/default.nix index 10c61b63..9dac50d5 100644 --- a/krebs/3modules/default.nix +++ b/krebs/3modules/default.nix @@ -228,8 +228,25 @@ let publicKey = host.ssh.pubkey; }) (filterAttrs (_: host: host.ssh.pubkey != null) cfg.hosts); + + programs.ssh.extraConfig = concatMapStrings + (net: '' + Host ${toString (net.aliases ++ net.addrs)} + Port ${toString net.ssh.port} + '') + (filter + (net: net.ssh.port != 22) + (concatMap (host: attrValues host.nets) + (mapAttrsToList + (_: host: recursiveUpdate host + (optionalAttrs (hasAttr config.krebs.search-domain host.nets) { + nets."" = host.nets.${config.krebs.search-domain} // { + aliases = [host.name]; + addrs = []; + }; + })) + config.krebs.hosts))); } ]; -in -out +in out -- cgit v1.2.3 From 41ff57c6d6a7ed4d8562169c0d3fd9d6adb949e6 Mon Sep 17 00:00:00 2001 From: tv Date: Sun, 17 Apr 2016 10:25:59 +0200 Subject: krebs.backup: use globally configured ssh ports --- krebs/3modules/backup.nix | 99 +++++++++++++++++++++-------------------------- 1 file changed, 44 insertions(+), 55 deletions(-) (limited to 'krebs/3modules') diff --git a/krebs/3modules/backup.nix b/krebs/3modules/backup.nix index 4172c980..71b22d8c 100644 --- a/krebs/3modules/backup.nix +++ b/krebs/3modules/backup.nix @@ -103,74 +103,63 @@ let plan.method == method && config.krebs.build.host.name == plan.${side}.host.name; - start = plan: pkgs.writeScript "backup.${plan.name}" '' + start = plan: let + login-name = "root"; + identity = local.host.ssh.privkey.path; + ssh = "ssh -i ${shell.escape identity}"; + local = getAttr plan.method { + push = plan.src // { rsync = src-rsync; }; + pull = plan.dst // { rsync = dst-rsync; }; + }; + remote = getAttr plan.method { + push = plan.dst // { rsync = dst-rsync; }; + pull = plan.src // { rsync = src-rsync; }; + }; + src-rsync = "rsync"; + dst-rsync = concatStringsSep " && " [ + "stat ${shell.escape plan.dst.path} >/dev/null" + "mkdir -m 0700 -p ${shell.escape plan.dst.path}/current" + "flock -n ${shell.escape plan.dst.path} rsync" + ]; + in pkgs.writeScript "backup.${plan.name}" '' #! ${pkgs.bash}/bin/bash set -efu + start_date=$(date +%s) + ssh_target=${shell.escape login-name}@$(${fastest-address remote.host}) ${getAttr plan.method { push = '' - identity=${shell.escape plan.src.host.ssh.privkey.path} - src_path=${shell.escape plan.src.path} - src=$src_path - dst_user=root - dst_host=$(${fastest-address plan.dst.host}) - dst_port=$(${pkgs.get-ssh-port}/bin/get-ssh-port "$dst_host") - dst_path=${shell.escape plan.dst.path} - dst=$dst_user@$dst_host:$dst_path - echo "update snapshot: current; $src -> $dst" >&2 - dst_exec() { - exec ssh -F /dev/null \ - -i "$identity" \ - -p $dst_port \ - "$dst_user@$dst_host" \ - -T "exec$(printf ' %q' "$@")" - } - rsh="ssh -F /dev/null -i $identity -p $dst_port" - local_rsync() { - rsync "$@" - } - remote_rsync=${shell.escape (concatStringsSep " && " [ - "stat ${shell.escape plan.dst.path} >/dev/null" - "mkdir -m 0700 -p ${shell.escape plan.dst.path}/current" - "exec flock -n ${shell.escape plan.dst.path} rsync" - ])} + rsync_src=${shell.escape plan.src.path} + rsync_dst=$ssh_target:${shell.escape plan.dst.path} + echo >&2 "update snapshot current; $rsync_src -> $rsync_dst" ''; pull = '' - identity=${shell.escape plan.dst.host.ssh.privkey.path} - src_user=root - src_host=$(${fastest-address plan.src.host}) - src_port=$(${pkgs.get-ssh-port}/bin/get-ssh-port "$src_host") - src_path=${shell.escape plan.src.path} - src=$src_user@$src_host:$src_path - dst_path=${shell.escape plan.dst.path} - dst=$dst_path - echo "update snapshot: current; $dst <- $src" >&2 - dst_exec() { - exec "$@" - } - rsh="ssh -F /dev/null -i $identity -p $src_port" - local_rsync() { - stat ${shell.escape plan.dst.path} >/dev/null - mkdir -m 0700 -p ${shell.escape plan.dst.path}/current - flock -n ${shell.escape plan.dst.path} rsync "$@" - } - remote_rsync=rsync + rsync_src=$ssh_target:${shell.escape plan.src.path} + rsync_dst=${shell.escape plan.dst.path} + echo >&2 "update snapshot current; $rsync_dst <- $rsync_src" ''; }} - start_date=$(date +%s) - local_rsync >&2 \ + ${local.rsync} >&2 \ -aAXF --delete \ - --rsh="$rsh" \ - --rsync-path="$remote_rsync" \ - --link-dest="$dst_path/current" \ - "$src/" \ - "$dst/.partial" + --rsh=${shell.escape ssh} \ + --rsync-path=${shell.escape remote.rsync} \ + --link-dest=${shell.escape plan.dst.path}/current \ + "$rsync_src/" \ + "$rsync_dst/.partial" + + dst_exec() { + ${getAttr plan.method { + push = ''exec ${ssh} "$ssh_target" -T "exec$(printf ' %q' "$@")"''; + pull = ''exec "$@"''; + }} + } dst_exec env \ - dst_path="$dst_path" \ start_date="$start_date" \ - flock -n "$dst_path" \ + flock -n ${shell.escape plan.dst.path} \ /bin/sh < ${toFile "backup.${plan.name}.take-snapshots" '' set -efu - : $dst_path $start_date + : $start_date + + dst_path=${shell.escape plan.dst.path} mv "$dst_path/current" "$dst_path/.previous" mv "$dst_path/.partial" "$dst_path/current" -- cgit v1.2.3