iobroker.bee 0.2.3 → 0.2.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,134 @@
1
+ #!/bin/bash
2
+ # Changes Node.js to another major line for a job of the fleet management (ioBroker.bee).
3
+ # The agent starts it as root in a unit of its own (sudo systemd-run), so stopping ioBroker does not end it.
4
+ # Expects Node.js from the package nodejs of NodeSource, as the installer of ioBroker sets it up.
5
+ #
6
+ # Usage: node-update.sh <data directory of the agent> <major> <systemd service of ioBroker> <seconds>
7
+ #
8
+ # 1. stops ioBroker, points the NodeSource source to the new major and installs nodejs from it,
9
+ # with the capabilities the old binary had
10
+ # 2. starts ioBroker and waits up to <seconds> for the verdict of the agent (node-verdict.json), which it
11
+ # writes under the new Node.js once the instances that ran before run again
12
+ # 3. without a positive verdict: stops ioBroker, installs the old package again and starts ioBroker
13
+ #
14
+ # The agent follows node-status.json (state running, waiting, ok, restored or failed).
15
+ # The output goes to node-update.log in the data directory.
16
+
17
+ set -u
18
+
19
+ DIR=$1
20
+ TARGET=$2
21
+ SERVICE=$3
22
+ WAIT=$4
23
+
24
+ STATUS="$DIR/node-status.json"
25
+ VERDICT="$DIR/node-verdict.json"
26
+ LOG="$DIR/node-update.log"
27
+ SAVED="$DIR/nodesource.saved"
28
+
29
+ exec >>"$LOG" 2>&1
30
+ export DEBIAN_FRONTEND=noninteractive
31
+
32
+ say() {
33
+ echo "[$(date '+%F %T')] $*"
34
+ }
35
+
36
+ major() {
37
+ node -v 2>/dev/null | sed -E 's/^v([0-9]+).*/\1/'
38
+ }
39
+
40
+ # status <state> <detail>: for the agent
41
+ status() {
42
+ local detail
43
+ detail=$(printf '%s' "$2" | tr -d '"\\' | tr '\n\r\t' ' ' | cut -c1-500)
44
+ printf '{"state":"%s","detail":"%s","ts":%s000,"pid":%s,"node":"%s"}\n' \
45
+ "$1" "$detail" "$(date +%s)" "$$" "$(node -v 2>/dev/null)" >"$STATUS.tmp"
46
+ chown --reference="$DIR" "$STATUS.tmp" "$LOG" 2>/dev/null
47
+ mv -f "$STATUS.tmp" "$STATUS"
48
+ say "$1: $2"
49
+ }
50
+
51
+ SOURCE=""
52
+ # another directory only for the tests
53
+ SOURCES_DIR=${BEE_APT_SOURCES:-/etc/apt/sources.list.d}
54
+ for f in "$SOURCES_DIR/nodesource.sources" "$SOURCES_DIR/nodesource.list"; do
55
+ if [ -f "$f" ]; then
56
+ SOURCE=$f
57
+ break
58
+ fi
59
+ done
60
+ OLD_MAJOR=$(major)
61
+ OLD_PACKAGE=$(dpkg-query -W -f='${Version}' nodejs 2>/dev/null)
62
+ # getcap prints "<file> cap_a,cap_b=eip", older versions "<file> = cap_a,cap_b+eip"
63
+ CAPS=$(getcap "$(readlink -f /usr/bin/node)" 2>/dev/null | sed -E 's/^[^ ]+ (= )?//')
64
+
65
+ # install_node <major> [<package version>]: nodejs of this major from the source as it is now
66
+ install_node() {
67
+ local version=${2:-}
68
+ apt-get -q -o DPkg::Lock::Timeout=600 update || say "apt-get update meldet Fehler"
69
+ if [ -z "$version" ]; then
70
+ version=$(apt-cache madison nodejs | grep nodesource | awk '{print $3}' | grep -E "^$1\." | sort -V | tail -n 1)
71
+ fi
72
+ if [ -z "$version" ]; then
73
+ say "NodeSource bietet kein Node.js $1 an"
74
+ return 1
75
+ fi
76
+ apt-get install -y -q --allow-downgrades -o DPkg::Lock::Timeout=600 -o Dpkg::Options::=--force-confold \
77
+ "nodejs=$version" || return 1
78
+ if [ "$(major)" != "$1" ]; then
79
+ say "Nach der Installation meldet node -v: $(node -v 2>/dev/null)"
80
+ return 1
81
+ fi
82
+ # the new binary has lost the capabilities (ports below 1024, raw sockets)
83
+ if [ -n "$CAPS" ] && ! setcap "$CAPS" "$(readlink -f /usr/bin/node)"; then
84
+ say "Capabilities $CAPS nicht gesetzt"
85
+ fi
86
+ }
87
+
88
+ # restore <reason>: back to the old package, ioBroker runs again; ends the script
89
+ restore() {
90
+ status running "Zurück zu Node.js $OLD_MAJOR: $1"
91
+ systemctl stop "$SERVICE"
92
+ cp -f "$SAVED" "$SOURCE"
93
+ if [ "$(major)" != "$OLD_MAJOR" ] && ! install_node "$OLD_MAJOR" "$OLD_PACKAGE" && ! install_node "$OLD_MAJOR"; then
94
+ systemctl start "$SERVICE"
95
+ status failed "$1; Rückkehr zu Node.js $OLD_MAJOR gescheitert, siehe node-update.log"
96
+ exit 1
97
+ fi
98
+ systemctl start "$SERVICE"
99
+ rm -f "$SAVED"
100
+ status restored "$1"
101
+ exit 1
102
+ }
103
+
104
+ if [ -z "$SOURCE" ] || [ -z "$OLD_MAJOR" ] || [ -z "$OLD_PACKAGE" ]; then
105
+ status failed "Node.js stammt nicht aus dem Paket nodejs von NodeSource, nichts geändert"
106
+ exit 1
107
+ fi
108
+ rm -f "$VERDICT"
109
+ cp -f "$SOURCE" "$SAVED"
110
+ say "Node.js $(node -v) (Paket $OLD_PACKAGE) auf $TARGET, Dienst $SERVICE, Capabilities: ${CAPS:-keine}"
111
+
112
+ status running "ioBroker wird gestoppt"
113
+ systemctl stop "$SERVICE"
114
+ status running "Node.js $TARGET wird installiert"
115
+ sed -i -E "s#node_[0-9]+\.x#node_$TARGET.x#" "$SOURCE"
116
+ install_node "$TARGET" || restore "Installation von Node.js $TARGET fehlgeschlagen"
117
+
118
+ status running "ioBroker startet unter Node.js $(node -v)"
119
+ systemctl start "$SERVICE" || restore "ioBroker startet nicht unter Node.js $(node -v)"
120
+ status waiting "Warte auf die Rückmeldung des Agenten unter Node.js $(node -v)"
121
+
122
+ END=$(($(date +%s) + WAIT))
123
+ while [ "$(date +%s)" -lt "$END" ]; do
124
+ if [ -f "$VERDICT" ]; then
125
+ if grep -Eq '"ok" *: *true' "$VERDICT"; then
126
+ rm -f "$SAVED"
127
+ status ok "Node.js $(node -v)"
128
+ exit 0
129
+ fi
130
+ restore "$(sed -n -E 's/.*"reason" *: *"([^"]*)".*/\1/p' "$VERDICT")"
131
+ fi
132
+ sleep 5
133
+ done
134
+ restore "Keine Rückmeldung des Agenten unter Node.js $(node -v) nach $WAIT s"