Advertisement
Guest User

Untitled

a guest
Jun 19th, 2018
71
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.54 KB | None | 0 0
  1. #!/bin/bash
  2. set -e
  3.  
  4. # Updater for the Shadow.
  5. #
  6. # Will flash the mmc partition not in use. Makes some effort not to
  7. # overwrite your data by mistake:
  8. #
  9. # * filesystem must have /etc/build and we must parse it
  10. # * dmidecode must identify board as one with a downloadable update
  11. # * /proc/cmdline must have "root=/dev/mmcblk0p[23]"
  12. # * alternate /dev/mmcblk0p[32] must exist and be a block device
  13. # * rootfs is squashfs
  14.  
  15. # Known problems:
  16. #
  17. # * when manually interrupted by ctrl-c or ctrl-\, dd finishes before
  18. # stopping, and grub config is not updated, and the system won't
  19. # boot on updated partition [low risk of occurence in the wild, and
  20. # auto-fixing on next attempt]
  21.  
  22.  
  23. # params
  24.  
  25. TIMEOUT=5
  26.  
  27. # identify platform
  28.  
  29. case $(dmidecode -s baseboard-product-name) in
  30. UP-CHT01) PLATFORM=up-board ;;
  31. BP-FP4-LC) PLATFORM=amdfalconx86 ;;
  32. *) PLATFORM=unknown ;;
  33. esac
  34.  
  35. SERVER=http://update.blade-group.fr/updates
  36. KEYRING=/usr/share/updater.keyring
  37.  
  38. DEFAULTBRANCH="prod"
  39. if [ -r /etc/blade/branch ]; then
  40. DEFAULTBRANCH=$(cat /etc/blade/branch)
  41. fi
  42.  
  43.  
  44. die() {
  45. echo >&2 "ERROR: $*"
  46. exit 1
  47. }
  48.  
  49. usage()
  50. {
  51. cat <<EOF
  52. Usage:
  53. $(basename $0) [options] [branch|version]
  54.  
  55. Options:
  56. --help, -h: This help
  57. --force, -f: Apply update even if already running same version.
  58. --fast: Don't rate-limit the download
  59. --reboot: Reboot if an update was applied
  60. --graphic Show graphical notification screens
  61. --imgdir <dir> Show graphical notification screens from <dir>
  62.  
  63. Example branches:
  64. prod Production image for real customers (default)
  65. preprod prod-candidate, for beta testers
  66. testing preprod-candidate, for internal testing
  67. <branch>-test <branch>-candidate for last checks before publication
  68.  
  69. EOF
  70. }
  71.  
  72. wrongusage()
  73. {
  74. echo >&2 "ERROR: $*"
  75. usage
  76. exit 1
  77. }
  78.  
  79. notify()
  80. {
  81. [ $GRAPHIC = 1 ] || return 0
  82. killall -9 feh || true
  83. feh --fullscreen "$IMGDIR"/"$1".png &
  84. }
  85.  
  86. check_squashfs()
  87. {
  88. if command -v unsquashfs >/dev/null; then
  89. unsquashfs -l "$1" >/dev/null
  90. else
  91. echo "WARNING: unsquashfs not found, NOT checking filesystem integrity"
  92. fi
  93. }
  94.  
  95. FORCE=0
  96. FEED="$DEFAULTBRANCH"
  97. REBOOT=0
  98. GRAPHIC=0
  99. IMGDIR=/usr/share/shadow/images
  100. # 100KB/s is below 1Mb/s
  101. MAYBELIMIT="--limit-rate 100k"
  102. while [ $# -gt 0 ]; do
  103. case "$1" in
  104. -h|--help) usage; exit 0 ;;
  105. -f|--force) FORCE=$((FORCE+1)) ;;
  106. --fast) MAYBELIMIT="" ;;
  107. --reboot) REBOOT=1 ;;
  108. --graphic) GRAPHIC=1 ;;
  109. --imgdir) GRAPHIC=1; IMGDIR="$2"; shift ;;
  110. -*) wrongusage "Unknown option '$1'" ;;
  111. *) break ;;
  112. esac
  113. shift
  114. done
  115. if [ $# -gt 0 ]; then
  116. FEED="$1"
  117. shift
  118. fi
  119. [ $# = 0 ] || wrongusage "Too many non-option arguments"
  120.  
  121. # locate this version's root partition
  122. for opt in $(cat /proc/cmdline); do
  123. case "$opt" in
  124. root=*) MYPART=${opt#*=}; break ;;
  125. esac
  126. done
  127.  
  128. if ! mount | grep -q ' / .* squashfs '; then
  129. echo "rootfs is not a squashfs, not updating"
  130. exit 0
  131. fi
  132.  
  133. if [[ "$FEED" =~ ^[0-9]+$ ]]; then
  134. FEEDVERSION="$FEED"
  135. else
  136. FEED="$PLATFORM/$FEED"
  137.  
  138. if [ $GRAPHIC = 1 ]; then
  139. trap "killall -9 feh || true" EXIT
  140. fi
  141.  
  142. notify checking-updates
  143.  
  144. FEEDFILE=$(mktemp -t "updater.XXXXXX")
  145. curl --silent --fail $MAYBELIMIT "$SERVER/$FEED" -o "$FEEDFILE" || die "failed to check for '$FEED' update"
  146.  
  147. FEEDVERSION=$(cat $FEEDFILE)
  148. rm $FEEDFILE
  149. [ -n "$FEEDVERSION" ] || die "no $FEED version!"
  150. echo "$FEED version is $FEEDVERSION"
  151. fi
  152.  
  153. # this partition's version
  154. [ -f /etc/build ] || die "Cannot find /etc/build for Shadow image version"
  155. CURRENT=$(grep "^DATETIME =" /etc/build | cut -d= -f2 | tr -d ' ')
  156. expr "$CURRENT" : "[0-9]*$" >/dev/null || die "Cannot understand rev '$CURRENT'"
  157. [ 14 -eq $(expr "$CURRENT" : "[0-9]*$") ] || die "Revision should have 14 digits: '$CURRENT'"
  158. echo "Current version is $CURRENT"
  159.  
  160. if [ "$FEEDVERSION" -eq "$CURRENT" ]; then
  161. echo "Shadow is uptodate"
  162. if [ $FORCE -ge 1 ]; then
  163. echo " --force given, proceeding anyway"
  164. else
  165. exit 0
  166. fi
  167. elif [ ! "$FEEDVERSION" -gt "$CURRENT" ]; then
  168. echo "Version inconsistency: $FEED '$FEEDVERSION' is older than '$CURRENT'"
  169. if [ $FORCE -ge 1 ]; then
  170. echo " --force given, proceeding anyway"
  171. else
  172. exit 3
  173. fi
  174. fi
  175.  
  176. # deduce other partition
  177. case "$MYPART" in
  178. /dev/mmcblk0p2) MYPARTNUM=2; NEWPARTNUM=3 ;;
  179. /dev/mmcblk0p3) MYPARTNUM=3; NEWPARTNUM=2 ;;
  180. *) die "unknown root partition '$MYPART'" ;;
  181. esac
  182. NEWPART=/dev/mmcblk0p$NEWPARTNUM
  183.  
  184. [ -b $NEWPART ] || die "partition $NEWPART does not exist"
  185.  
  186. # other partition's version
  187. while true; do # this is poor-man's do-while(0)
  188. # check the filesystem can be completely read
  189. if ! check_squashfs $NEWPART; then
  190. echo "Other partition's filesystem is bad, will reflash"
  191. break;
  192. fi
  193.  
  194. if ! mount -oro $NEWPART /mnt; then
  195. # this should never happen since we checked it, but old images
  196. # don't have unsquashfs
  197. echo "Could not mount other partition, will flash"
  198. break
  199. fi
  200.  
  201. OTHERVERS=$(grep "^DATETIME =" /mnt/etc/build | cut -d= -f2 | tr -d ' ')
  202. umount $NEWPART
  203. if ! [ "$OTHERVERS" -gt 0 ] 2>/dev/null; then
  204. echo "Cannot understand '$OTHERVERS' as numeric version, will reflash"
  205. break
  206. fi
  207.  
  208. echo "Other partition had $OTHERVERS"
  209.  
  210. break
  211. done
  212.  
  213. IMG=shadow-image-x11-${PLATFORM}-${FEEDVERSION}.rootfs.squashfs
  214.  
  215. notify "downloading-update"
  216.  
  217. echo "dowloading update..."
  218. wget -q $SERVER/$PLATFORM/$IMG.sig -O /tmp/$IMG.sig || die "failed to fetch update signature"
  219. wget $SERVER/$PLATFORM/$IMG -O /tmp/$IMG || die "failed to fetch update"
  220.  
  221. notify "applying-update"
  222.  
  223. echo "verifying update data..."
  224. gpgv --keyring $KEYRING /tmp/$IMG.sig /tmp/$IMG ||
  225. die "failed to verify update"
  226.  
  227. echo "flashing update..."
  228. dd if=/tmp/$IMG of=$NEWPART bs=4M || die "failed to flash update"
  229. sync
  230.  
  231. echo "verifying update..."
  232. check_squashfs $NEWPART
  233.  
  234. echo "updating bootentries..."
  235. mount /dev/mmcblk0p1 /mnt
  236. EFIDIR=/mnt/EFI/BOOT
  237. if [ "$FEED" = "master" ]; then
  238. QUIET=''
  239. else
  240. QUIET='quiet'
  241. fi
  242. cat > $EFIDIR/rootpart.cfg <<EOF
  243. timeout=$TIMEOUT
  244. timeout_style=countdown
  245.  
  246. #set prefix=(\${rootdsk},gpt$NEWPARTNUM)/usr/lib64/grub
  247.  
  248. if loadfont (\${rootdsk},gpt$NEWPARTNUM)/usr/share/grub/unicode.pf2
  249. then
  250. set gfxmode=1920x1080,2560x1440,1290x1200,1920x1080,1280x1024,1024x768,auto
  251. set gfxpayload=keep
  252. terminal_output gfxterm
  253. fi
  254.  
  255. menuentry 'Shadow (image $FEEDVERSION)' {
  256. linux (\${rootdsk},gpt$NEWPARTNUM)/boot/bzImage root=$NEWPART \${opts}
  257. }
  258. menuentry 'Shadow previous (image $CURRENT)' {
  259. linux (\${rootdsk},gpt$MYPARTNUM)/boot/bzImage root=$MYPART $QUIET \${opts}
  260. }
  261. EOF
  262. sync
  263. cat > $EFIDIR/oldrootpart.cfg <<EOF
  264. timeout=$TIMEOUT
  265. timeout_style=countdown
  266.  
  267. #set prefix=(\${rootdsk},gpt$NEWPARTNUM)/usr/lib64/grub
  268.  
  269. if loadfont (\${rootdsk},gpt$NEWPARTNUM)/usr/share/grub/unicode.pf2
  270. then
  271. set gfxmode=1920x1080,2560x1440,1290x1200,1920x1080,1280x1024,1024x768,auto
  272. set gfxpayload=keep
  273. terminal_output gfxterm
  274. fi
  275.  
  276. menuentry 'Shadow recovery (image $CURRENT)' {
  277. linux (\${rootdsk},gpt$MYPARTNUM)/boot/bzImage root=$MYPART $QUIET \${opts}
  278. }
  279. EOF
  280. umount /dev/mmcblk0p1
  281. sync
  282.  
  283. if [ $REBOOT = 1 ]; then
  284. notify "reboting"
  285. echo "Update finished, rebooting..."
  286. reboot
  287. else
  288. echo "Update finished."
  289. fi
  290.  
  291. # signal update to caller
  292. exit 2
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement