···101101 # tail can lag far behind the log when the reader (nom) is slow, so
102102 # it must not be killed on a timer: --pid makes it read the log to
103103 # the end once the waiter (unit finished) is gone, then exit, so
104104- # no line is cut off.
104104+ # no line is cut off. systemctl fails for a moment while a switch
105105+ # reexecutes systemd ("Failed to connect to system scope bus");
106106+ # that is retried, not taken for the unit having finished.
105107 follow() {
106108 ssh "''${ssh_opts[@]}" "$target" bash -s -- "$1" "$state" <<'EOF'
107109 unit=$1 log=$2/$1.log
108108- while case $(systemctl show -p ActiveState -p SubState "$unit") in
110110+ query() {
111111+ until systemctl show "$@" "$unit" 2>/dev/null; do sleep 1; done
112112+ }
113113+ while case $(query -p ActiveState -p SubState) in
109114 *ActiveState=activating* | *SubState=running*) true ;;
110115 *) false ;;
111116 esac; do
112117 sleep 1
113118 done &
114119 tail -n +1 -F --pid=$! "$log" 2>/dev/null
115115- [ "$(systemctl show -p Result --value "$unit")" = success ] && exit 0
116116- echo "deploy: $unit failed (exit status $(systemctl show -p ExecMainStatus --value "$unit")), log: $log" >&2
120120+ [ "$(query -p Result --value)" = success ] && exit 0
121121+ echo "deploy: $unit failed (exit status $(query -p ExecMainStatus --value)), log: $log" >&2
117122 exit 1
118123 EOF
119124 }