summaryrefslogtreecommitdiff
path: root/update-all.in
blob: 854e2a58a7927660b549ec3b2671e257cfaa9173 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
#!/bin/bash

# update-all version #VERSION#
# updates all clients defined in #ETCDIR#/update-all.conf via local versions of update-me

. #ETCDIR#/update-all.conf

usage() {
  >&2 printf 'usage:\n'
  >&2 printf '  %s\n' "${0##*/}"
  >&2 printf '  %s $id $tmpdir [cs]\n' "${0##*/}"
  exit 1
}

if [ "$#" -eq 3 ]; then
  system="${systems["$1"]}"
  if [ "${system}" == "localhost" ]
  then
    cmd=""
  else
    cmd="ssh -t -t ${system}"
  fi
  cmd="${cmd} update-me"
  case "$3" in
    'c')
      delay=1
      while sleep ${delay}; do
        ${cmd} -c </dev/null
        err=$?
        if [ "${err}" -ne 1 ]; then
          break
        fi
        if [ ${delay} -lt 10 ]; then
          delay=$((delay+1))
        fi
      done
    ;;
    's')
      ${cmd} -s
      err=$?
      if [ "${err}" -ne 0 ] \
      && [ -d "$2" ]; then
        printf '%s\n' "${err}" > "$2/$1"
      fi
    ;;
    *)
      usage
    ;;
  esac
  exit ${err}
fi

if [ "$#" -ne 0 ]; then
  usage
fi

tmp_dir=$(mktemp -d)
trap 'rm -rf --one-file-system "${tmp_dir}"' EXIT

pids=()

for system in "${!systems[@]}"; do
  if [ -z "${DISPLAY}" ]; then
    screen -S update-all -d -m "${0}" "${system}" "${tmp_dir}" 's'
    screen -S update-clear-all -d -m "${0}" "${system}" "${tmp_dir}" 'c'
  else
    urxvt -title "${systems["${system}"]}: update-me" -e "${0}" "${system}" "${tmp_dir}" 's' &
    pids+=($!)
    screen -S update-clear-all -d -m "${0}" "${system}" "${tmp_dir}" 'c'
  fi
done

if [ -z "${DISPLAY}" ]; then
  sleep 1
  pids=(
    $(
      screen -list \
      | sed '
        s/^\s\+\([0-9]\+\)\.update-all\s.*$/\1/
        t
        d
      '
    )
  )
fi

while [ -n "${pids[*]}" ]; do
  if [ -z "${DISPLAY}" ]; then
    for pid in "${pids[@]}"; do
      if ! kill -0 "${pid}" >/dev/null 2>&1; then
        continue
      fi
      npids+=("${pid}")
      screen -r "${pid}"
    done
    pids=("${npids[@]}")
  else
    sleep 1
  fi
  pids=(
    $(
      for pid in "${pids[@]}"; do
        if kill -0 "${pid}" >/dev/null 2>&1; then
          printf '%s\n' "${pid}"
        fi
      done
    )
  )
done

ls "${tmp_dir}" \
| while read -r system; do
  err=$(
    cat "${tmp_dir}/${system}"
  )
  if [ "${err}" -ne 0 ]; then
    printf 'update-me on "%s" failed: %s\n' \
      "${systems["${system}"]}" \
      "${err}"
  fi
done

exit $(
  find "${tmp_dir}" -type f \
    -exec grep -lxFv '0' {} + \
  | wc -l
)