-
Notifications
You must be signed in to change notification settings - Fork 24
/
Copy pathcheck-updates.sh
310 lines (270 loc) · 8.92 KB
/
check-updates.sh
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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
#!/bin/bash
#
# RESUME DOWNLOAD DETAILS
# swupdate can retry and resume a broken download. See -t and -r arguments
# in do_swupdate call at end of this file.
#
# Implementation in swupdate:
# https://github.com/sbabic/swupdate/blob/master/corelib/downloader.c
#
# Note that it only resumes the download when kept running: after the
# swupdate process has stopped, for example because of a reboot, it will
# restart. Improving this, without adding an intermediate scratchpad on disk,
# is not straightforward: the download is streamed straight into ubifs on the
# CCGX, and re-opening an unfinished ubifs volume is not a good idea.
#
# Resuming while online file has changed:
# When a new version is made available, the venus-swu-[machine].swu file on
# the webserver is replaced with the newer one. Devices busy starting a
# resume after that should not accidentally resume the download with the new
# file. A waste of bandwidth and possible leads to installing and booting
# into a corrupt rootfs. (What type of CRC or hash does swupdate on the swu
# file after download?)
#
# This is prevented this by dowloading the file that contains its version
# in the name. Therefore the webserver should always have the latest file
# available under two names:
# venus-swu-[machine].swu
# venus-swu-[machine]-[build-date-time].swu
#
# Best sequence of installing the files on the webserver is:
# 1. venus-swu-[machine]-[build-date-time].swu
# 2. venus-swu-[machine].swu
# 3. rename or remove the old build-date-time file: force the running
# downloads to cancel.
. $(dirname $0)/functions.sh
get_setting() {
dbus-send --print-reply=literal --system --type=method_call \
--dest=com.victronenergy.settings \
"/Settings/System/$1" \
com.victronenergy.BusItem.GetValue |
awk '{ print $3 }'
}
get_swu_version() {
if [ -f "$1" ]; then
# local file
cmd="head -n 10"
else
# url, probably
cmd="curl -s -r 0-999 -m 30 --retry 3"
fi
$cmd "$1" |
cpio --quiet -i --to-stdout sw-description 2>/dev/null |
sed -n '/venus-version/ {
s/.*"\(.*\)".*/\1/
p
q
}'
}
swu_status() {
if [ "$offline" = y ]; then
printf '%s\n' "$1" "" "$2" >$status_file
else
printf '%s\n' "$1" "$2" "" >$status_file
fi
}
status_file=/var/run/swupdate-status
start_log
echo "*** Checking for updates ***"
echo "arguments: $@"
feed=""
while [[ $# -gt 0 ]]; do
case "$1" in
-auto)
update=auto
auto=1
;;
-check) update=2 ;;
-update) update=1 ;;
-delay) delay=y ;;
-feed)
shift
feed="$1"
;;
-force) force=y ;;
-status-file)
shift
status_file="$1"
;;
-swu)
shift
force=y
forceswu="$1"
update="1"
;;
-swubase)
shift
swubase="$1"
;;
-offline)offline=y ;;
-help) help=y ;;
*) echo "Invalid option $arg"
exit 1
;;
esac
shift
done
if [ "$help" = y ]; then
echo "check-updates.sh: wrapper script around swupdate"
echo
echo "Arguments:"
echo "-auto script will check automatic update setting in localsettings."
echo " use this when calling from cron or after boot."
echo "-delay sleep for a random delay before starting the download of"
echo " new image (to prevent thousands of units starting the"
echo " download at the same time)."
echo " use this when calling from cron or after boot."
echo "-check (only) check if there is a new version available."
echo "-update check and, when necessary, update."
echo "-feed set the feed to check. venus OS setting will be used if omitted."
echo "-force force downloading and installing the new image, even if its"
echo " version is older or same as already installed version."
echo "-status-file use given file for status updates instead of /var/run/swupdate-status"
echo "-swu url forcefully install the swu from given url"
echo "-swubase url use given url as a base, rather than the default:"
echo " https://updates.victronenergy.com/feeds/venus/[feed]/"
echo "-offline search for updates on removable storage devices"
echo "-help this help"
echo
echo "Behaviour when called without any arguments is same as -update"
exit
fi
if [ "${update:-auto}" = auto ]; then
update=$(get_setting AutoUpdate)
case $update in
0) echo "Auto-update disabled, exit."
exit
;;
1) ;;
2) ;;
*) echo "Invalid AutoUpdate value $update, exit."
exit 1
;;
esac
fi
if [ "$delay" = y ]; then
DELAY=$[ $RANDOM % 3600 ]
echo "Sleeping for $DELAY seconds"
sleep $DELAY
fi
# note: to prevent unexpected state updates in the status file,
# make sure only one process is running.
if ! lock; then
echo "Can't get lock, other process already running? Exit."
exit 1
fi
trap unlock EXIT
machine=$(cat /etc/venus/machine)
swu_name=$(cat /etc/venus/swu-name)
swu_base=${swu_name}-${machine}
if [[ $forceswu ]]; then
echo "Updating to $forceswu"
SWU="$forceswu"
# The version is not known, since the stream might not support seeking,
# like stdin for example. So as a best effort, use the url instead.
swu_version="$forceswu"
elif [ "$offline" = y ]; then
echo "Searching for update on SD/USB..."
# use wildcard to allow image variants such as -large
swu_base="${swu_name}*-${machine}"
for dev in /media/*; do
# reverse order gives preference to an unversioned file
# followed by that with the most recent timestamp if
# multiple files exist
#
# MIND IT: There are ccgx and venusgx around which only check for
# venus-swu-${machine}*.swu so don't make an incompatible ccgxv2 or
# beaglebone-new MACHINE, since they are also accepted by the old ones.
SWU=$(ls -r $dev/${swu_base}-*.swu $dev/${swu_base}.swu 2>/dev/null | head -n1)
test -f "$SWU" && break
done
if [ -f "$SWU" ]; then
echo "Update found on $dev"
feed="$dev"
else
echo "Update not found. Exit."
swu_status -3
exit 1
fi
else
if [ -z "$feed" ]; then
feed=$(get_setting ReleaseType)
case $feed in
0) feed=release ;;
1) feed=candidate ;;
2) feed=testing ;;
3) feed=develop ;;
*) echo "Invalid release type, exit."
exit 1
;;
esac
fi
imgtype=$(get_setting ImageType)
case $imgtype in
0) imgtype= ;;
1) imgtype=large ;;
*) echo "Invalid image type."
exit 1
;;
esac
if [ ${imgtype:-normal} != $(cat /etc/venus/image-type) ]; then
force=y;
fi
swu_base=${swu_name}${imgtype:+-}${imgtype}-${machine}
if [ -z "$swubase" ]; then
swubase=https://updates.victronenergy.com/feeds/venus/${feed}/
fi
URL_BASE=${swubase}images/${machine}
SWU=${URL_BASE}/${swu_base}.swu
fi
if [[ -z $forceswu ]]; then
echo "Retrieving latest version... (from $SWU)"
swu_status 1
cur_version=$(get_version)
swu_version=$(get_swu_version "$SWU")
if [ -z "$swu_version" ]; then
echo "Unable to retrieve latest software version, exit."
swu_status -1
exit 1
fi
cur_build=${cur_version%% *}
swu_build=${swu_version%% *}
if [ "$offline" != y ]; then
# change SWU url into the full name
SWU=${URL_BASE}/${swu_base}-${swu_version// /-}.swu
fi
echo "installed: $cur_version"
echo "available: $swu_version"
if [ "$force" != y -a \( "${swu_build}" = "${cur_build}" -o "$auto" = "1" -a "${swu_build}" -le "${cur_build}" \) ]; then
echo "No newer version available, exit."
swu_status 0
exit
fi
if [ "$update" != 1 ]; then
swu_status 0 "$swu_version"
exit
fi
fi
altroot=$(get_altrootfs)
if [ -z "$altroot" ]; then
echo "Unable to determine rootfs. Exit."
swu_status -2 "$swu_version"
exit 1
fi
echo "Starting swupdate to install version $swu_version ..."
swu_status 2 "$swu_version"
# backup rootfs is about to be replaced, remove its version entry
get_version >/var/run/versions
if [ -f "$SWU" ]; then
swupdate_flags="-i"
else
swupdate_flags="-t 30 -r 3 -d"
fi
if do_swupdate -v $swupdate_flags "$SWU" -e "stable,copy$altroot"; then
echo "do_swupdate completed OK. Rebooting"
swu_status 3 "$swu_version"
reboot
else
echo "Error, do_swupdate stopped with exitcode $?, unlock and exit."
swu_status -2 "$swu_version"
fi