/
oupgrade.sh
executable file
·378 lines (303 loc) · 7.67 KB
/
oupgrade.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
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
#!/bin/sh
# include the Onion sh lib
. /usr/lib/onion/lib.sh
# setup variables
bUsage=0
bDeviceVersion=1
bRepoVersion=1
bCheck=1
bLatest=0
bUpgrade=0
bBuildMismatch=0
bJsonOutput=0
bCheckOnly=0
deviceVersion=""
deviceVersionMajor=""
deviceVersionMinor=""
deviceVersionRev=""
deviceBuildNum=""
repoVersion=""
repoVersionMajor=""
repoVersionMinor=""
repoVersionRev=""
repoBuildNum=""
repoBinary=""
binaryName=""
fileSize=""
tmpPath="/tmp"
# change repo url based on device type
urlBase="https://api.onioniot.com/firmware"
device=$(ubus call system board | jsonfilter -e '@.board_name')
repoUrl="$urlBase/$device"
repoStableFile="stable"
repoLatestFile="latest"
timeout=500
# function to print script usage
Usage () {
echo "Functionality:"
echo " Check if new Onion firmware is available and perform upgrade"
echo ""
echo "Usage: $0"
echo ""
echo "Arguments:"
echo " -h, --help Print this usage prompt"
echo " -v, --version Just print the current firmware version"
echo " -l, --latest Use latest repo version (instead of stable version)"
echo " -f, --force Force the upgrade, regardless of versions"
echo " -c, --check Only compare versions, do not actually update"
echo " -u, --ubus Script outputs only json"
echo ""
}
# print to stdout if not doing json output
# arg1 - the text to print
Print () {
if [ $bJsonOutput == 0 ]; then
echo "$1"
fi
}
## functions to parse version data
# parsing (x).y.z
GetVersionMajor () {
ret=${1%%.*}
echo "$ret"
}
# parsing x.(y).z
GetVersionMinor () {
tmp=${1#*.}
ret=${tmp%%.*}
echo "$ret"
}
# parsing x.y.(z)
GetVersionRevision () {
ret=${1##*.}
echo "$ret"
}
# function to read remote file size
GetFileSize () {
ret=$(wget --spider $1 2>&1 | grep Length | awk '{print $2}')
echo "$ret"
}
# function to read device firmware version
GetDeviceVersion () {
local ver=$(uci -q get onion.@onion[0].version)
if [ "$ver" != "" ]; then
# read the device version
deviceVersion=$ver
# read the sub-version info
deviceVersionMajor=$(GetVersionMajor "$deviceVersion")
deviceVersionMinor=$(GetVersionMinor "$deviceVersion")
deviceVersionRev=$(GetVersionRevision "$deviceVersion")
# read the build number
local build=$(uci -q get onion.@onion[0].build)
if [ "$build" != "" ]; then
deviceBuildNum=$build
else
deviceBuildNum=0
fi
else
deviceVersion="unknown"
fi
}
# function to read latest repo version
# arg1 - url of file to download
GetRepoVersion () {
local url="$1"
local outFile=$(mktemp)
# fetch the file
local resp=$(wget "$url" -O "$outFile" 2>&1)
local ret=$?
if [ $? -eq 0 ]; then
# parse the json file
local RESP="$(cat $outFile)"
# echo "response is $RESP"
json_load "$RESP"
# check the json file contents
json_get_var repoVersion version
# echo "repoVersion $repoVersion"
repoVersionMajor=$(GetVersionMajor "$repoVersion")
repoVersionMinor=$(GetVersionMinor "$repoVersion")
repoVersionRev=$(GetVersionRevision "$repoVersion")
json_get_var repoBuildNum build
# echo "repoBuildNum $repoBuildNum"
# parse the binary url
json_get_var repoBinary url
binaryName=${repoBinary##*/}
localBinary="$tmpPath/$binaryName"
fileSize=$(GetFileSize "$repoBinary")
# echo "repoVersionMajor $repoVersionMajor"
# echo "repoVersionMinor $repoVersionMinor"
# echo "repoVersionRev $repoVersionRev"
fi
# echo "$ret"
}
# function to add version info to json
JsonAddVersion () {
json_add_object "$1"
json_add_string "version" "$2"
json_add_int "major" "$3"
json_add_int "minor" "$4"
json_add_int "revision" "$5"
json_add_int "build" "$6"
json_close_object
}
########################
##### Main Program #####
# read arguments
while [ "$1" != "" ]
do
case "$1" in
-h|-help|--help)
bUsage=1
;;
-v|-version|--version)
bDeviceVersion=1
bRepoVersion=0
;;
-f|-force|--force)
bCheck=0
bUpgrade=1
;;
-c|-check|--check)
bCheckOnly=1
;;
-l|-latest|--latest)
bLatest=1
;;
-u|-ubus)
bJsonOutput=1
;;
*)
echo "ERROR: Invalid Argument"
echo ""
bUsage=1
;;
esac
shift
done
## print the script usage
if [ $bUsage == 1 ]
then
Usage
exit
fi
## get the current version
if [ $bDeviceVersion == 1 ]; then
# find the version
GetDeviceVersion
Print "> Device Firmware Version: $deviceVersion b$deviceBuildNum"
fi
## get the latest repo version
if [ $bRepoVersion == 1 ]; then
# find the remote version file to be used
if [ $bLatest == 0 ]; then
# use the stable version
repoFile="$repoUrl/$repoStableFile"
else
# use the latest version
repoFile="$repoUrl/$repoLatestFile"
fi
Print "> Checking latest version online..."
Print "url: $repoFile"
# fetch the repo version
GetRepoVersion $repoFile
if [ "$repoVersion" == "" ]; then
Print "> ERROR: Could not connect to Onion Firmware Server!"
exit
fi
Print "> Repo Firmware Version: $repoVersion b$repoBuildNum"
else
# optional exit here if just getting device version
if [ $bJsonOutput == 1 ]; then
json_init
JsonAddVersion "device" $deviceVersion $deviceVersionMajor $deviceVersionMinor $deviceVersionRev $deviceBuildNum
json_dump
fi
exit
fi
## compare the versions
if [ $bCheck == 1 ]
then
Print "> Comparing version numbers"
if [ $repoVersionMajor -gt $deviceVersionMajor ]
then
bUpgrade=1
elif [ $repoVersionMajor -eq $deviceVersionMajor ] &&
[ $repoVersionMinor -gt $deviceVersionMinor ];
then
bUpgrade=1
elif [ $repoVersionMajor -eq $deviceVersionMajor ] &&
[ $repoVersionMinor -eq $deviceVersionMinor ] &&
[ $repoVersionRev -gt $deviceVersionRev ];
then
bUpgrade=1
fi
fi
## compare the build numbers (only if versions are the same)
if [ $bUpgrade == 0 ]
then
if [ $repoBuildNum -gt $deviceBuildNum ]; then
bBuildMismatch=1
fi
fi
## generate script info output (json and stdout)
if [ $bJsonOutput == 1 ]
then
## json output
json_init
# upgrading firmware or not
json_add_boolean "upgrade" $bUpgrade
# version mismatch
json_add_boolean "build_mismatch" $bBuildMismatch
# image info
json_add_object "image"
json_add_string "binary" "$binaryName"
json_add_string "url" "$repoBinary"
json_add_string "local" "$localBinary"
json_add_string "size" "$fileSize"
json_close_object
# version info
JsonAddVersion "device" $deviceVersion $deviceVersionMajor $deviceVersionMinor $deviceVersionRev $deviceBuildNum
JsonAddVersion "repo" $repoVersion $repoVersionMajor $repoVersionMinor $repoVersionRev $repoBuildNum
json_dump
else
# stdout
if [ $bUpgrade == 1 ]; then
echo "> New firmware version available, need to upgrade device firmware"
elif [ $bBuildMismatch == 1 ]; then
echo "> New build of current firmware available, upgrade is optional, rerun with '-force' option to upgrade"
else
echo "> Device firmware is up to date!"
fi
fi
## exit route if only checking if upgrade is required
if [ $bCheckOnly == 1 ]
then
exit
fi
## perform the firmware upgrade
if [ $bUpgrade == 1 ]
then
Print "> Downloading new firmware ..."
# delete any local firmware with the same name
if [ -f $localBinary ]; then
eval rm -rf $localBinary
fi
# setup wget verbosity
verbosity="-q"
if [ $bJsonOutput == 0 ]; then
verbosity=""
fi
# download the new firmware
while [ ! -f $localBinary ]
do
wget $verbosity -O $localBinary "$repoBinary"
done
# start firmware upgrade
if [ $? -eq 0 ]; then
sleep 5 # wait 5 seconds before starting the firmware upgrade
Print "> Starting firmware upgrade...."
sysupgrade $localBinary
else
Print "> ERROR: Downloading firmware has failed! Try again!"
fi
fi