Browse Source

add initial fwupdate application

Waldemar Brodkorb 7 years ago
parent
commit
cd539adc4a

+ 28 - 0
package/fwupdate/Makefile

@@ -0,0 +1,28 @@
+# This file is part of the OpenADK project. OpenADK is copyrighted
+# material, please see the LICENCE file in the top-level directory.
+
+include $(ADK_TOPDIR)/rules.mk
+
+PKG_NAME:=		fwupdate
+PKG_VERSION:=		1.0
+PKG_RELEASE:=		1
+PKG_DESCR:=		update firmware
+PKG_SECTION:=		sys/misc
+PKG_URL:=		http://www.openadk.org
+
+NO_DISTFILES:=          1
+
+include $(ADK_TOPDIR)/mk/package.mk
+
+$(eval $(call PKG_template,FWUPDATE,fwupdate,$(PKG_VERSION)-${PKG_RELEASE},${PKG_DEPENDS},${PKG_DESCR},${PKG_SECTION}))
+
+CONFIG_STYLE:=          manual
+BUILD_STYLE:=           manual
+INSTALL_STYLE:=         manual
+
+fwupdate-install:
+	$(INSTALL_DIR) $(IDIR_FWUPDATE)/usr/sbin
+	$(INSTALL_BIN) $(WRKBUILD)/fwupdate $(IDIR_FWUPDATE)/usr/sbin
+	$(INSTALL_BIN) $(WRKBUILD)/fwvalidate $(IDIR_FWUPDATE)/usr/sbin
+
+include ${ADK_TOPDIR}/mk/pkg-bottom.mk

+ 27 - 0
package/fwupdate/files/fwupdate.init

@@ -0,0 +1,27 @@
+#!/bin/sh
+#PKG fwupdate
+#INIT 99
+
+. /etc/rc.conf
+
+case $1 in
+autostop) ;;
+autostart)
+        test x"${fwupdate:-NO}" = x"NO" && exit 0
+        test x"$fwupdate" = x"DAEMON" && test -x /bin/mksh && exec mksh -T- $0 start
+        exec sh $0 start
+        ;;
+start)
+        /usr/sbin/fwvalidate
+        ;;
+stop)
+        ;;
+restart)
+        sh $0 stop
+        sh $0 start
+        ;;
+*)
+        echo "usage: $0 (start|stop|restart)"
+        exit 1
+esac
+exit $?

+ 9 - 0
package/fwupdate/files/fwupdate.service

@@ -0,0 +1,9 @@
+[Unit]
+Description=Firmware Update Validation
+After=dropbear.service
+
+[Service]
+ExecStart=/usr/sbin/fwvalidate
+
+[Install]
+WantedBy=multi-user.target

+ 137 - 0
package/fwupdate/src/fwupdate

@@ -0,0 +1,137 @@
+#!/bin/sh
+# This file is part of the OpenADK project.
+# Do update.
+
+PART0="/dev/sda2"
+PART1="/dev/sda3"
+
+# Name of the archive, which is the firmware. For this file is the checksum calculated and
+# checked against the one from the tar archive.
+FW_NAME="openadk.tar.xz"
+CHECK_SUM_FILE="sha256.txt"
+TMP_MOUNT="/mnt"
+
+if [ -z $1 ]; then
+  echo "Usage: $0 <full path to update filename>"
+  exit 1
+fi
+if [ ! -f $1 ]; then
+  echo "File $1 not found"
+  exit 1
+fi
+FIRMWARE=$1
+
+echo "Validate new firmware $FIRMWARE"
+echo "Extract checksum file ..."
+cmd="tar -xf $FIRMWARE $CHECK_SUM_FILE"
+$cmd
+if [ ! -f $CHECK_SUM_FILE ];then
+  echo "No checksum file found! $CHECK_SUM_FILE"
+  exit 3
+fi
+
+if [ $(wc -m $CHECK_SUM_FILE | cut -d\  -f1) -eq 65 ];then
+  echo "Found a checksum in file $CHECK_SUM_FILE"
+else
+  echo "No checksum found in archive! $(wc -m $CHECK_SUM_FILE | cut -d\  -f1)"
+  exit 4
+fi
+
+CHECK_SUM_UPDATE_FILE="$(cat $CHECK_SUM_FILE)"
+
+echo "Calculate the checksum of the new firmware ..."
+CHECK_SUM_NEW_SYSTEM=$(tar -xf $FIRMWARE $FW_NAME -O | sha256sum - |cut -d\  -f1)
+
+echo "Compare the checksums ..."
+if [ "X$CHECK_SUM_NEW_SYSTEM" = "X$CHECK_SUM_UPDATE_FILE" ]; then
+    echo "Checksum verified (they match): "
+else
+    echo "Checksum does not match!"
+    echo "${CHECK_SUM_UPDATE_FILE} "
+    echo "${CHECK_SUM_NEW_SYSTEM}"
+fi
+
+echo "First unmount $TMP_MOUNT the spare partition just in case ..."
+umount $TMP_MOUNT 2>/dev/null
+
+# create the mkfs options depending on which is the active partition
+CURRENT_SYS="$(rdev /|awk '{ print $1 }')"
+case "$CURRENT_SYS" in
+  "$PART0")
+    MOUNTPART="$PART1"
+    OS=OpenADK2
+    ;;
+  "$PART1")
+    MOUNTPART="$PART0"
+    OS=OpenADK1
+    ;;
+  *)
+    echo "Current partition $CURRENT_SYS not recognized"
+    exit 5
+    ;;
+esac
+echo "Currently the system is running on $CURRENT_SYS"
+
+# Create filesystem on inactive partition
+echo "The partition $MOUNTPART is going to be prepared for the new system."
+echo "Creating the filesystem ..."
+
+mkfs.ext2 -j -q -F $MOUNTPART
+if [ $? -ne 0 ];then
+  echo "It was not possible to create the new filesystem on $MOUNTPART"
+  exit 6
+fi
+
+echo "Mount the new partition $MOUNTPART ..."
+mount -t ext4 $MOUNTPART $TMP_MOUNT
+if [ $? -ne 0 ];then
+  echo "It was not possible to mount the partition for the new system!"
+  echo "Please reboot the system and try to update again."
+  exit 7
+fi
+
+cd $TMP_MOUNT
+echo "The new system is going to be extracted into the partition $MOUNTPART ..."
+tar -xf $FIRMWARE $FW_NAME -O|tar -xJf -
+if [ $? -ne 0 ]; then
+  echo "The extraction of the new system failed!"
+  echo "Please reboot the system and try to update again."
+  cd /
+  umount $MOUNTPART
+  exit 8
+fi
+
+echo "Checking the new system on next boot"
+touch $TMP_MOUNT/firmware_check
+if [ $? -ne 0 ]; then
+  echo "General ERROR"
+  echo "Please reboot the system and try to update again."
+  cd /
+  umount $MOUNTPART
+  exit 9
+fi
+# echo "DD.MM.YYYY hh:mm:hh\n$(date '+%d.%m.%Y %H:%M:%S')" > install_date.txt
+date '+%d.%B.%Y %H:%M:%S' > $TMP_MOUNT/installation_date.txt
+if [ $? -ne 0 ]; then
+  echo "General ERROR"
+  echo "Please reboot the system and try to update again."
+  cd /
+  umount $MOUNTPART
+  exit 9
+fi
+echo "$CHECK_SUM_NEW_FW" >> $TMP_MOUNT/installation_date.txt
+if [ $? -ne 0 ]; then
+  echo "General ERROR"
+  echo "Please reboot the system and try to update again."
+  cd /
+  umount $MOUNTPART
+  exit 9
+fi
+
+cd /
+umount $MOUNTPART
+mount -o remount,rw /boot
+grub-reboot $OS
+mount -o remount,ro /boot
+sync
+echo "Reboot now to the updated system $OS"

+ 132 - 0
package/fwupdate/src/fwvalidate

@@ -0,0 +1,132 @@
+#!/bin/sh
+# This file is part of the OpenADK project.
+# Validate update.
+
+PART0="/dev/sda2"
+PART1="/dev/sda3"
+
+APPLIANCE_NAME=OpenADK
+
+BOOT0_NAME="OpenADK1"
+BOOT1_NAME="OpenADK2"
+
+CURRENT_SYS="$(rdev /|awk '{ print $1 }' )"
+TIMEOUT=45
+STAT_FILE="/tmp/update_status"
+
+SSH_KEY_FOLDER=/etc/dropbear/
+SSH_KEYS=("dropbear_dss_host_key" "dropbear_ecdsa_host_key" "dropbear_rsa_host_key")
+
+DEBUG=1
+
+if [ "x$1" == "xtest" ];then
+  TIMEOUT=1
+fi
+
+get_interface(){
+  ip route list | grep '^default' | cut -d\  -f 5
+}
+get_nw_mask(){
+  # This function will get the NW Mask in the form /x e.g. /16
+  local BIT=$(ip a s $(get_interface)| grep inet\ | cut -d/ -f2| cut -d\  -f1)
+  echo $BIT
+}
+
+getip() {
+  DEFDEVICE=$(ip route list | grep ^default | cut -d\  -f5)
+  IPADDR=$(ip a s $(ip route list | grep ^default | cut -d\  -f5) | grep inet\ | grep 'inet' | cut -d\  -f 6 | cut -d/ -f1)
+  echo $IPADDR
+}
+
+chk_initial_save(){
+  if [ $(cfgfs status | wc -l) -gt 0 ];then
+    echo "please save configuration"
+  fi
+}
+updategrub(){
+  
+  mount -o remount,rw /boot
+
+  case "$CURRENT_SYS" in
+    "$PART1")
+      grub-set-default OpenADK2
+      ;;
+    "$PART0")
+      grub-set-default OpenADK1
+      ;;
+    *)
+      echo "Current partition $CURRENT_SYS not recognized"
+      exit 1
+      ;;
+  esac
+
+  sync
+  mount -o remount,ro /boot
+
+}
+
+base_check() {
+  NET_PROGS="$(netstat -tulpn 2>/dev/null)"
+  TESTS=0
+  TESTSUM=0
+
+  #test start: check if dropbear is running
+  T_NAME=dropbear
+  if [[ $NET_PROGS = *"/dropbear"* ]];then
+    logger -t update "check $T_NAME  OK"
+    TESTS=$(( $TESTS + 1 ))
+  else
+    logger -t update "check $T_NAME  FAILURE"
+  fi
+  ((TESTSUM = TESTSUM +1))
+  #test end
+}
+
+if [ -f /installation_date.txt ];then
+  echo "Update was applied at:" > $STAT_FILE
+  echo "$(head -n1 /installation_date.txt)" >> $STAT_FILE
+else
+  rm -f $STAT_FILE
+fi
+
+# Do some checks before setting the new partiton as default boot partition.
+if ( [ -f /firmware_check ] || [ "x$1" = "xtest" ] );then 
+  logger -t update "check now!"
+  base_check
+  i=0
+  while [ $TESTS -lt $TESTSUM ];do
+      base_check
+      [ $DEBUG -gt 0 ] && echo "$i Only $TESTS from $TESTSUM are passed wait until $TIMEOUT"
+      sleep 1
+      i=$(( $i + 1 ))
+      if [ $i -ge $TIMEOUT ];then
+	  break
+      fi
+  done
+else
+  logger -t update "$APPLIANCE_NAME validate nothing to do..."
+  if [ -f $STAT_FILE ];then
+    echo "Last update was successful" >> $STAT_FILE
+  else
+    echo "Firmware check was successful" >> $STAT_FILE
+  fi
+
+  n=0
+  chk_initial_save
+  exit 0
+fi
+
+if [ $TESTS -eq $TESTSUM ]; then
+    logger -t update "All Tests passed."
+    if [ "x$1" = "x" ]; then
+      logger -t update "Set default boot partition for bootloader."
+      rm /firmware_check
+      echo "System check was successful" >> $STAT_FILE
+      updategrub
+    fi
+else
+    logger -t update "Not all tests passed. The the default system remains on the current partition."
+    logger -t update "Please try to reboot the system and repeat the update."
+    echo "ERROR last system update failed, please reboot and try again." >> $STAT_FILE
+    exit 1
+fi