Переглянути джерело

add script to check build

Helge Jung 9 роки тому
батько
коміт
60cc414ef9
1 змінених файлів з 146 додано та 0 видалено
  1. 146 0
      check.sh

+ 146 - 0
check.sh

@@ -0,0 +1,146 @@
+#!/bin/bash
+# (c) 2015 Helge Jung <hej@c3pb.de>
+#
+# This script is controlled by environment variables,
+# only the first being mandatory:
+#
+# CANDIDATE       = directory in which to find the to-be-checked firmware images
+# REFERENCE       = directory of your build firmware, defaults to './src/images'
+# MANIFEST        = if given, use files referenced in Gluon manifest file
+#                   if left empty (unset), 'find' is used to examine all '.bin' files
+# VERBOSE         = 0 (default) or 1, putting lots of debug output
+#
+
+MY_DIR=$(dirname $0)
+MY_DIR=$(readlink -f "$MY_DIR")
+
+pushd "$MY_DIR" > /dev/null
+. functions.sh
+
+# check for necessary tools
+for tool in bbe binwalk find gawk unsquashfs; do
+	[ -x "$(which $tool)" ] || abort "Missing necessary tool '$tool'."
+done
+
+# check that CANDIDATE dir is given and existing
+[ "_$CANDIDATE" == "_" ] && abort "Please specify CANDIDATE environment variable point to the directory of to-be-checked firmware images."
+[ ! -d "$CANDIDATE" ] && abort "The directory indicated by CANDIDATE was not found."
+CANDIDATE=$(readlink -f $CANDIDATE)
+
+# set defaults for environment variables
+[ -n "${REFERENCE}" ] || REFERENCE="./src/images"
+if [ "_$VERBOSE" == "_1" ]; then VERBOSE=1; else VERBOSE=0; fi
+
+# assemble file list
+declare -a FILELIST
+if [ -n "$MANIFEST" ]; then
+	progress "Assembling file list from manifest file ..."
+	FILELIST=()
+else
+	[ ! -d "$REFERENCE" ] && abort "The REFERENCE directory was not found. Have you built the firmware?"
+	REFERENCE=$(readlink -f $REFERENCE)
+
+	progress "Assembling file list ..."
+	FILELIST=($(find "$REFERENCE" -type f -name "*.bin"))
+fi
+
+COUNT=${#FILELIST[*]}
+[ "$COUNT" = 0 ] && abort "No firmware files found. Please check that you built software in the REFERENCE dir."
+
+info "Need to check $COUNT files."
+
+# setup temp dir for checking
+TEMPDIR=$(mktemp -d)
+debug "Temporary dir = $TEMPDIR"
+
+# check each file
+IDX=0
+declare -a ERRORS
+
+filter_timestamp() {
+	file=$1
+	cp "$file" "$file.orig"
+	egrep -ao '(Mon|Tue|Wed|Thu|Fri|Sat|Sun) (Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) [0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2} UTC [0-9]{4}' "$file" | sort -u | while read ts; do
+		debug "Normalizing timestamp: '$ts'"
+		bbe -e "s/$ts/Abc Def 12 34:56:78 UTC 9010/" -o "${file}" "${file}.orig"
+	done
+}
+
+for ref in ${FILELIST[*]}; do
+        IDX=$(($IDX + 1))
+        NAME=`basename "$ref"`
+	[ $VERBOSE -eq 1 ] && progress "[${IDX}/${COUNT}] $NAME"
+
+	if [ ! -r "$ref" ]; then
+		ERRORS=( "${ERRORS[@]}" "$NAME: missing reference file ($ref)" )
+		continue
+	fi
+
+        cand=$(readlink -f "${CANDIDATE}/${NAME}")
+	if [ ! -r "$cand" ]; then
+		ERRORS=( "${ERRORS[@]}" "$NAME: missing candidate file in $CANDIDATE" )
+		continue
+	fi
+
+	pushd "$TEMPDIR" > /dev/null
+
+	rm -Rf candidate ; mkdir candidate
+	rm -Rf reference ; mkdir reference
+
+	# TODO: check output of binwalk that there are only the two expected parts
+	cd candidate
+	binwalk -qe "$cand" 2>/dev/null
+	cd ../reference
+	binwalk -qe "$ref" 2>/dev/null
+	cd ..
+
+	# check ROM part
+	debug "Filtering timestamps in ROM part (uboot+kernel) ..."
+	filter_timestamp candidate/200
+	filter_timestamp reference/200
+
+	hash_rom_cand=$(sha512sum candidate/200)
+	hash_rom_ref=$(sha512sum reference/200)
+        if [ "$hash_rom_cand" != "$hash_rom_ref" ]; then
+		ERRORS=( "${ERRORS[@]}" "$NAME: ROM part mismatch" )
+
+		debug "Calling vbindiff for your visual pleasure."
+		vbindiff reference/200 candidate/200
+	fi
+
+	# extract root filesystem
+	for dir in candidate reference; do
+		cd $dir
+		unsquashfs -n -f *.squashfs > /dev/null
+		cd ..
+	done
+
+	fsdiff=$(diff -ur reference/squashfs-root candidate/squashfs-root 2>&1)
+	# TODO: intelligent diff statt 'diff -r', Verhalten abhängig vom Dateinamen
+	#   squashfs-root/usr/lib/opkg/info/*.list: erst sortieren, dann diffen
+	#   squashfs-root/usr/lib/opkg/info/*.control: Unterschied in "Installed Size" ignorieren (kommt vermutlich durch unterschiedliche Reihenfolge und Block-Alignments?)
+        #   squashfs-root/usr/lib/opkg/status: Delta in "Installed-Time: " Zeilen ignorieren
+	#   squashfs-root/usr/lib/lua/luci/version.lua: neoraider/openwrt hauen, die Änderung im luciversion-String kommt durch manuelles git patching
+	#   else: binary file compare, sha512sum
+	if [ "$?" -ne 0 ]; then
+		ERRORS=( "${ERRORS[@]}" "$NAME: Filesystems do not match" )
+		echo $fsdiff | less
+	fi
+
+	popd > /dev/null
+done
+rm -R "$TEMPDIR"
+
+# check if everything was fine - if yes, exit clean+smooth
+if [ ${#ERRORS[*]} -eq 0 ]; then
+	success "Everything OK, what a nice and lovely built firmware \o/"
+	exit 0
+fi
+
+# got some errors - output them
+for errmsg in "${ERRORS[@]}"; do
+    echo $errmsg
+done
+
+abort "Firmware check failed, see above :("
+