OpenWrt – Blame information for rev 2
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | office | 1 | #!/bin/sh |
2 | |||
3 | . /lib/functions.sh |
||
4 | . /lib/functions/system.sh |
||
5 | |||
6 | # initialize defaults |
||
7 | export MTD_ARGS="" |
||
8 | export MTD_CONFIG_ARGS="" |
||
9 | export INTERACTIVE=0 |
||
10 | export VERBOSE=1 |
||
11 | export SAVE_CONFIG=1 |
||
12 | export SAVE_OVERLAY=0 |
||
13 | export SAVE_OVERLAY_PATH= |
||
14 | export SAVE_PARTITIONS=1 |
||
15 | export SAVE_INSTALLED_PKGS=0 |
||
16 | export SKIP_UNCHANGED=0 |
||
17 | export CONF_IMAGE= |
||
18 | export CONF_BACKUP_LIST=0 |
||
19 | export CONF_BACKUP= |
||
20 | export CONF_RESTORE= |
||
21 | export NEED_IMAGE= |
||
22 | export HELP=0 |
||
23 | export FORCE=0 |
||
24 | export TEST=0 |
||
25 | export UMOUNT_ETCBACKUP_DIR=0 |
||
26 | |||
27 | # parse options |
||
28 | while [ -n "$1" ]; do |
||
29 | case "$1" in |
||
30 | -i) export INTERACTIVE=1;; |
||
31 | -v) export VERBOSE="$(($VERBOSE + 1))";; |
||
32 | -q) export VERBOSE="$(($VERBOSE - 1))";; |
||
33 | -n) export SAVE_CONFIG=0;; |
||
34 | -c) export SAVE_OVERLAY=1 SAVE_OVERLAY_PATH=/etc;; |
||
35 | -o) export SAVE_OVERLAY=1 SAVE_OVERLAY_PATH=/;; |
||
36 | -p) export SAVE_PARTITIONS=0;; |
||
37 | -k) export SAVE_INSTALLED_PKGS=1;; |
||
38 | -u) export SKIP_UNCHANGED=1;; |
||
39 | -b|--create-backup) export CONF_BACKUP="$2" NEED_IMAGE=1; shift;; |
||
40 | -r|--restore-backup) export CONF_RESTORE="$2" NEED_IMAGE=1; shift;; |
||
41 | -l|--list-backup) export CONF_BACKUP_LIST=1;; |
||
42 | -f) export CONF_IMAGE="$2"; shift;; |
||
43 | -F|--force) export FORCE=1;; |
||
44 | -T|--test) export TEST=1;; |
||
45 | -h|--help) export HELP=1; break;; |
||
46 | -*) |
||
47 | echo "Invalid option: $1" >&2 |
||
48 | exit 1 |
||
49 | ;; |
||
50 | *) break;; |
||
51 | esac |
||
52 | shift; |
||
53 | done |
||
54 | |||
55 | export CONFFILES=/tmp/sysupgrade.conffiles |
||
56 | export CONF_TAR=/tmp/sysupgrade.tgz |
||
57 | export ETCBACKUP_DIR=/etc/backup |
||
58 | export INSTALLED_PACKAGES=${ETCBACKUP_DIR}/installed_packages.txt |
||
59 | |||
60 | IMAGE="$1" |
||
61 | |||
62 | [ -z "$IMAGE" -a -z "$NEED_IMAGE" -a $CONF_BACKUP_LIST -eq 0 -o $HELP -gt 0 ] && { |
||
63 | cat <<EOF |
||
64 | Usage: $0 [<upgrade-option>...] <image file or URL> |
||
65 | $0 [-q] [-i] [-c] [-u] [-o] [-k] <backup-command> <file> |
||
66 | |||
67 | upgrade-option: |
||
68 | -f <config> restore configuration from .tar.gz (file or url) |
||
69 | -i interactive mode |
||
70 | -c attempt to preserve all changed files in /etc/ |
||
71 | -o attempt to preserve all changed files in /, except those |
||
72 | from packages but including changed confs. |
||
73 | -u skip from backup files that are equal to those in /rom |
||
74 | -n do not save configuration over reflash |
||
75 | -p do not attempt to restore the partition table after flash. |
||
76 | -k include in backup a list of current installed packages at |
||
77 | $INSTALLED_PACKAGES |
||
78 | -T | --test |
||
79 | Verify image and config .tar.gz but do not actually flash. |
||
80 | -F | --force |
||
81 | Flash image even if image checks fail, this is dangerous! |
||
82 | -q less verbose |
||
83 | -v more verbose |
||
84 | -h | --help display this help |
||
85 | |||
86 | backup-command: |
||
87 | -b | --create-backup <file> |
||
88 | create .tar.gz of files specified in sysupgrade.conf |
||
89 | then exit. Does not flash an image. If file is '-', |
||
90 | i.e. stdout, verbosity is set to 0 (i.e. quiet). |
||
91 | -r | --restore-backup <file> |
||
92 | restore a .tar.gz created with sysupgrade -b |
||
93 | then exit. Does not flash an image. If file is '-', |
||
94 | the archive is read from stdin. |
||
95 | -l | --list-backup |
||
96 | list the files that would be backed up when calling |
||
97 | sysupgrade -b. Does not create a backup file. |
||
98 | |||
99 | EOF |
||
100 | exit 1 |
||
101 | } |
||
102 | |||
103 | [ -n "$IMAGE" -a -n "$NEED_IMAGE" ] && { |
||
104 | cat <<-EOF |
||
105 | -b|--create-backup and -r|--restore-backup do not perform a firmware upgrade. |
||
106 | Do not specify both -b|-r and a firmware image. |
||
107 | EOF |
||
108 | exit 1 |
||
109 | } |
||
110 | |||
111 | # prevent messages from clobbering the tarball when using stdout |
||
112 | [ "$CONF_BACKUP" = "-" ] && export VERBOSE=0 |
||
113 | |||
114 | |||
115 | list_conffiles() { |
||
116 | awk ' |
||
117 | BEGIN { conffiles = 0 } |
||
118 | /^Conffiles:/ { conffiles = 1; next } |
||
119 | !/^ / { conffiles = 0; next } |
||
120 | conffiles == 1 { print } |
||
121 | ' /usr/lib/opkg/status |
||
122 | } |
||
123 | |||
124 | list_changed_conffiles() { |
||
125 | # Cannot handle spaces in filenames - but opkg cannot either... |
||
126 | list_conffiles | while read file csum; do |
||
127 | [ -r "$file" ] || continue |
||
128 | |||
129 | echo "${csum} ${file}" | sha256sum -sc - || echo "$file" |
||
130 | done |
||
131 | } |
||
132 | |||
133 | add_conffiles() { |
||
134 | local file="$1" |
||
135 | ( find $(sed -ne '/^[[:space:]]*$/d; /^#/d; p' \ |
||
136 | /etc/sysupgrade.conf /lib/upgrade/keep.d/* 2>/dev/null) \ |
||
137 | \( -type f -o -type l \) $find_filter 2>/dev/null; |
||
138 | list_changed_conffiles ) | sort -u > "$file" |
||
139 | return 0 |
||
140 | } |
||
141 | |||
142 | add_overlayfiles() { |
||
143 | local file="$1" |
||
144 | |||
145 | local packagesfiles=$1.packagesfiles |
||
146 | touch "$packagesfiles" |
||
147 | |||
148 | if [ "$SAVE_OVERLAY_PATH" = / ]; then |
||
149 | local conffiles=$1.conffiles |
||
150 | local keepfiles=$1.keepfiles |
||
151 | |||
152 | list_conffiles | cut -f2 -d ' ' | sort -u > "$conffiles" |
||
153 | |||
154 | # backup files from /etc/sysupgrade.conf and /lib/upgrade/keep.d, but |
||
155 | # ignore those aready controlled by opkg conffiles |
||
156 | find $(sed -ne '/^[[:space:]]*$/d; /^#/d; p' \ |
||
157 | /etc/sysupgrade.conf /lib/upgrade/keep.d/* 2>/dev/null) \ |
||
158 | \( -type f -o -type l \) 2>/dev/null | sort -u | |
||
159 | grep -h -v -x -F -f $conffiles > "$keepfiles" |
||
160 | |||
161 | # backup conffiles, but only those changed if '-u' |
||
162 | [ $SKIP_UNCHANGED = 1 ] && |
||
163 | list_changed_conffiles | sort -u > "$conffiles" |
||
164 | |||
165 | # do not backup files from packages, except those listed |
||
166 | # in conffiles and keep.d |
||
167 | { |
||
168 | find /usr/lib/opkg/info -type f -name "*.list" -exec cat {} \; |
||
169 | find /usr/lib/opkg/info -type f -name "*.control" -exec sed \ |
||
170 | -ne '/^Alternatives/{s/^Alternatives: //;s/, /\n/g;p}' {} \; | |
||
171 | cut -f2 -d: |
||
172 | } | grep -v -x -F -f $conffiles | |
||
173 | grep -v -x -F -f $keepfiles | sort -u > "$packagesfiles" |
||
174 | rm -f "$keepfiles" "$conffiles" |
||
175 | fi |
||
176 | |||
177 | # busybox grep bug when file is empty |
||
178 | [ -s "$packagesfiles" ] || echo > $packagesfiles |
||
179 | |||
180 | ( cd /overlay/upper/; find .$SAVE_OVERLAY_PATH \( -type f -o -type l \) $find_filter | sed \ |
||
181 | -e 's,^\.,,' \ |
||
182 | -e '\,^/etc/board.json$,d' \ |
||
183 | -e '\,/[^/]*-opkg$,d' \ |
||
184 | -e '\,^/etc/urandom.seed$,d' \ |
||
185 | -e "\,^$INSTALLED_PACKAGES$,d" \ |
||
186 | -e '\,^/usr/lib/opkg/.*,d' \ |
||
187 | ) | grep -v -x -F -f $packagesfiles > "$file" |
||
188 | |||
189 | rm -f "$packagesfiles" |
||
190 | |||
191 | return 0 |
||
192 | } |
||
193 | |||
194 | # hooks |
||
195 | sysupgrade_image_check="fwtool_check_signature fwtool_check_image platform_check_image" |
||
196 | |||
197 | if [ $SAVE_OVERLAY = 1 ]; then |
||
198 | [ ! -d /overlay/upper/etc ] && { |
||
199 | echo "Cannot find '/overlay/upper/etc', required for '-c'" >&2 |
||
200 | exit 1 |
||
201 | } |
||
202 | sysupgrade_init_conffiles="add_overlayfiles" |
||
203 | else |
||
204 | sysupgrade_init_conffiles="add_conffiles" |
||
205 | fi |
||
206 | |||
207 | find_filter="" |
||
208 | if [ $SKIP_UNCHANGED = 1 ]; then |
||
209 | [ ! -d /rom/ ] && { |
||
210 | echo "'/rom/' is required by '-u'" |
||
211 | exit 1 |
||
212 | } |
||
213 | find_filter='( ( -exec test -e /rom/{} ; -exec cmp -s /{} /rom/{} ; ) -o -print )' |
||
214 | fi |
||
215 | |||
216 | include /lib/upgrade |
||
217 | |||
218 | do_save_conffiles() { |
||
219 | local conf_tar="$1" |
||
220 | |||
221 | [ -z "$(rootfs_type)" ] && { |
||
222 | echo "Cannot save config while running from ramdisk." >&2 |
||
223 | ask_bool 0 "Abort" && exit |
||
224 | rm -f "$conf_tar" |
||
225 | return 0 |
||
226 | } |
||
227 | run_hooks "$CONFFILES" $sysupgrade_init_conffiles |
||
228 | ask_bool 0 "Edit config file list" && vi "$CONFFILES" |
||
229 | |||
230 | if [ "$SAVE_INSTALLED_PKGS" -eq 1 ]; then |
||
231 | echo "${INSTALLED_PACKAGES}" >> "$CONFFILES" |
||
232 | mkdir -p "$ETCBACKUP_DIR" |
||
233 | # Avoid touching filesystem on each backup |
||
234 | RAMFS="$(mktemp -d -t sysupgrade.XXXXXX)" |
||
235 | mkdir -p "$RAMFS/upper" "$RAMFS/work" |
||
236 | mount -t overlay overlay -o lowerdir=$ETCBACKUP_DIR,upperdir=$RAMFS/upper,workdir=$RAMFS/work $ETCBACKUP_DIR && |
||
237 | UMOUNT_ETCBACKUP_DIR=1 || { |
||
238 | echo "Cannot mount '$ETCBACKUP_DIR' as tmpfs to avoid touching disk while saving the list of installed packages." >&2 |
||
239 | ask_bool 0 "Abort" && exit |
||
240 | } |
||
241 | |||
242 | # Format: pkg-name<TAB>{rom,overlay,unkown} |
||
243 | # rom is used for pkgs in /rom, even if updated later |
||
244 | find /usr/lib/opkg/info -name "*.control" \( \ |
||
245 | \( -exec test -f /rom/{} \; -exec echo {} rom \; \) -o \ |
||
246 | \( -exec test -f /overlay/upper/{} \; -exec echo {} overlay \; \) -o \ |
||
247 | \( -exec echo {} unknown \; \) \ |
||
248 | \) | sed -e 's,.*/,,;s/\.control /\t/' > ${INSTALLED_PACKAGES} |
||
249 | fi |
||
250 | |||
251 | v "Saving config files..." |
||
252 | [ "$VERBOSE" -gt 1 ] && TAR_V="v" || TAR_V="" |
||
253 | tar c${TAR_V}zf "$conf_tar" -T "$CONFFILES" 2>/dev/null |
||
254 | if [ "$?" -ne 0 ]; then |
||
255 | echo "Failed to create the configuration backup." |
||
256 | rm -f "$conf_tar" |
||
257 | exit 1 |
||
258 | fi |
||
259 | |||
260 | [ "$UMOUNT_ETCBACKUP_DIR" -eq 1 ] && { |
||
261 | umount "$ETCBACKUP_DIR" |
||
262 | rm -rf "$RAMFS" |
||
263 | } |
||
264 | rm -f "$CONFFILES" |
||
265 | } |
||
266 | |||
267 | if [ $CONF_BACKUP_LIST -eq 1 ]; then |
||
268 | run_hooks "$CONFFILES" $sysupgrade_init_conffiles |
||
269 | [ "$SAVE_INSTALLED_PKGS" -eq 1 ] && echo ${INSTALLED_PACKAGES} >> "$CONFFILES" |
||
270 | cat "$CONFFILES" |
||
271 | rm -f "$CONFFILES" |
||
272 | exit 0 |
||
273 | fi |
||
274 | |||
275 | if [ -n "$CONF_BACKUP" ]; then |
||
276 | do_save_conffiles "$CONF_BACKUP" |
||
277 | exit $? |
||
278 | fi |
||
279 | |||
280 | if [ -n "$CONF_RESTORE" ]; then |
||
281 | if [ "$CONF_RESTORE" != "-" ] && [ ! -f "$CONF_RESTORE" ]; then |
||
282 | echo "Backup archive '$CONF_RESTORE' not found." >&2 |
||
283 | exit 1 |
||
284 | fi |
||
285 | |||
286 | [ "$VERBOSE" -gt 1 ] && TAR_V="v" || TAR_V="" |
||
287 | tar -C / -x${TAR_V}zf "$CONF_RESTORE" |
||
288 | exit $? |
||
289 | fi |
||
290 | |||
291 | type platform_check_image >/dev/null 2>/dev/null || { |
||
292 | echo "Firmware upgrade is not implemented for this platform." >&2 |
||
293 | exit 1 |
||
294 | } |
||
295 | |||
296 | case "$IMAGE" in |
||
297 | http://*|\ |
||
298 | https://*) |
||
299 | wget -O/tmp/sysupgrade.img "$IMAGE" |
||
300 | IMAGE=/tmp/sysupgrade.img |
||
301 | ;; |
||
302 | esac |
||
303 | |||
304 | IMAGE="$(readlink -f "$IMAGE")" |
||
305 | |||
306 | case "$IMAGE" in |
||
307 | '') |
||
308 | echo "Image file not found." >&2 |
||
309 | exit 1 |
||
310 | ;; |
||
311 | /tmp/*) ;; |
||
312 | *) |
||
313 | v "Image not in /tmp, copying..." |
||
314 | cp -f "$IMAGE" /tmp/sysupgrade.img |
||
315 | IMAGE=/tmp/sysupgrade.img |
||
316 | ;; |
||
317 | esac |
||
318 | |||
319 | export ARGV="$IMAGE" |
||
320 | export ARGC=1 |
||
321 | |||
322 | for check in $sysupgrade_image_check; do |
||
323 | ( $check "$IMAGE" ) || { |
||
324 | if [ $FORCE -eq 1 ]; then |
||
325 | echo "Image check '$check' failed but --force given - will update anyway!" >&2 |
||
326 | break |
||
327 | else |
||
328 | echo "Image check '$check' failed." >&2 |
||
329 | exit 1 |
||
330 | fi |
||
331 | } |
||
332 | done |
||
333 | |||
334 | if [ -n "$CONF_IMAGE" ]; then |
||
335 | case "$(get_magic_word $CONF_IMAGE cat)" in |
||
336 | # .gz files |
||
337 | 1f8b) ;; |
||
338 | *) |
||
339 | echo "Invalid config file. Please use only .tar.gz files" >&2 |
||
340 | exit 1 |
||
341 | ;; |
||
342 | esac |
||
343 | get_image "$CONF_IMAGE" "cat" > "$CONF_TAR" |
||
344 | export SAVE_CONFIG=1 |
||
345 | elif ask_bool $SAVE_CONFIG "Keep config files over reflash"; then |
||
346 | [ $TEST -eq 1 ] || do_save_conffiles "$CONF_TAR" |
||
347 | export SAVE_CONFIG=1 |
||
348 | else |
||
349 | [ $TEST -eq 1 ] || rm -f "$CONF_TAR" |
||
350 | export SAVE_CONFIG=0 |
||
351 | fi |
||
352 | |||
353 | if [ $TEST -eq 1 ]; then |
||
354 | exit 0 |
||
355 | fi |
||
356 | |||
357 | if [ $SAVE_PARTITIONS -eq 0 ]; then |
||
358 | touch /tmp/sysupgrade.always.overwrite.bootdisk.partmap |
||
359 | else |
||
360 | rm -f /tmp/sysupgrade.always.overwrite.bootdisk.partmap |
||
361 | fi |
||
362 | |||
363 | install_bin /sbin/upgraded |
||
364 | v "Commencing upgrade. Closing all shell sessions." |
||
365 | |||
366 | COMMAND='. /lib/functions.sh; include /lib/upgrade; do_upgrade_stage2' |
||
367 | |||
368 | if [ -n "$FAILSAFE" ]; then |
||
369 | printf '%s\x00%s\x00%s' "$RAM_ROOT" "$IMAGE" "$COMMAND" >/tmp/sysupgrade |
||
370 | lock -u /tmp/.failsafe |
||
371 | else |
||
372 | ubus call system sysupgrade "{ |
||
373 | \"prefix\": $(json_string "$RAM_ROOT"), |
||
374 | \"path\": $(json_string "$IMAGE"), |
||
375 | \"command\": $(json_string "$COMMAND") |
||
376 | }" |
||
377 | fi |