provide report of missing packages in xunit format for usage within e.g. Jenkins
[grml-live.git] / grml-live
index 3f42b78..b14320b 100755 (executable)
--- a/grml-live
+++ b/grml-live
@@ -59,6 +59,7 @@ Usage: $PN [options, see as follows]
    -r <release_name>       release name
    -s <suite>              Debian suite; values: etch, lenny, squeeze, sid
    -t <template_directory> place of the templates
+   -T <tar_name>           unpack chroot tar archive before starting
    -u                      update existing chroot instead of rebuilding it from scratch
    -U <username>           arrange output to be owned by specified username
    -v <version_number>     specify version number of the release
@@ -196,7 +197,7 @@ trap umount_all EXIT
 
 # log output:
 # usage: log "string to log"
-log() { echo "$*" >> $LOGFILE ; }
+log() { [ -n "$LOGFILE" ] && echo "$*" >> $LOGFILE ; }
 
 # cut string at character number int = $1
 # usage: cut_string 5 "1234567890" will output "12345"
@@ -298,7 +299,7 @@ fi
 # }}}
 
 # command line parsing {{{
-while getopts "a:C:c:d:D:g:i:I:o:r:s:t:U:v:AbBFnNquVz" opt; do
+while getopts "a:C:c:d:D:g:i:I:o:r:s:t:T:U:v:AbBFnNquVz" opt; do
   case "$opt" in
     a) ARCH="$OPTARG" ;;
     A) PACK_ARTIFACTS=1 ;;
@@ -318,6 +319,7 @@ while getopts "a:C:c:d:D:g:i:I:o:r:s:t:U:v:AbBFnNquVz" opt; do
     r) RELEASENAME="$OPTARG" ;;
     s) SUITE="$OPTARG" ;;
     t) TEMPLATE_DIRECTORY="$OPTARG";;
+    T) UNPACK_CHROOT="$(readlink -f $OPTARG)" ;;
     v) VERSION="$OPTARG" ;;
     F) FORCE=1 ;;
     u) UPDATE=1 ;;
@@ -358,6 +360,7 @@ shift $(($OPTIND - 1))  # set ARGV to the first not parsed commandline parameter
 [ -n "$CHROOT_ARCHIVE" ]   || CHROOT_ARCHIVE="$OUTPUT/$(basename $CHROOT_OUTPUT).tgz"
 [ -n "$ISO_OUTPUT" ]       || ISO_OUTPUT="$OUTPUT/grml_isos"
 [ -n "$LOG_OUTPUT" ]       || LOG_OUTPUT="$OUTPUT/grml_logs"
+[ -n "$REPORTS" ]          || REPORTS="${LOG_OUTPUT}/reports/"
 # }}}
 
 # some misc checks before executing FAI {{{
@@ -395,6 +398,7 @@ if [ -z "$FORCE" ] ; then
    [ -n "$CONFIG" ]              && echo "  Configuration:     $CONFIG"
    [ -n "$GRML_FAI_CONFIG" ]     && echo "  Config directory:  $GRML_FAI_CONFIG"
    echo "  main directory:    $OUTPUT"
+   [ -n "$UNPACK_CHROOT" ]       && echo "  Chroot from:       $UNPACK_CHROOT"
    [ -n "$CHROOT_OUTPUT" ]       && echo "  Chroot target:     $CHROOT_OUTPUT"
    [ -n "$BUILD_OUTPUT" ]        && echo "  Build target:      $BUILD_OUTPUT"
    [ -n "$ISO_OUTPUT" ]          && echo "  ISO target:        $ISO_OUTPUT"
@@ -444,7 +448,6 @@ if [ -n "${PACK_ARTIFACTS}" ]; then
   [ -n "${BUILD_OUTPUT}"   -a -d "${BUILD_OUTPUT}"   ] && rm -r "${BUILD_OUTPUT}"
   [ -n "${ISO_OUTPUT}"     -a -d "${ISO_OUTPUT}"     ] && rm -r "${ISO_OUTPUT}"
   [ -n "${LOG_OUTPUT}"     -a -d "${LOG_OUTPUT}"     ] && rm -r "${LOG_OUTPUT}"
-  [ -n "${CHROOT_ARCHIVE}" -a -f "${CHROOT_ARCHIVE}" ] && rm "${CHROOT_ARCHIVE}"
 fi
 # }}}
 
@@ -501,6 +504,28 @@ log "$CMDLINE"
 einfo "Logging actions to logfile $LOGFILE"
 # }}}
 
+# unpack chroot {{{
+if [ -n "${UNPACK_CHROOT}" ]; then
+  log "Unpacking chroot from ${UNPACK_CHROOT}"
+  einfo "Unpacking chroot from ${UNPACK_CHROOT}"
+  [ -d "$CHROOT_OUTPUT" ] || mkdir -p "${CHROOT_OUTPUT}"
+  tar -xf "${UNPACK_CHROOT}" -C "${CHROOT_OUTPUT}/" --strip-components 1 | RC=$?
+  echo $RC
+  if [ "$RC" != 0 ] ; then
+    eend 1
+    bailout 1
+  fi
+  eend 0
+fi
+# }}}
+
+# cleanup CHROOT_ARCHIVE now {{{
+if [ -n "${PACK_ARTIFACTS}" ]; then
+  # can't do this earlier, as UNPACK_CHROOT might point to CHROOT_ARCHIVE
+  [ -n "${CHROOT_ARCHIVE}" -a -f "${CHROOT_ARCHIVE}" ] && rm "${CHROOT_ARCHIVE}"
+fi
+# }}}
+
 # on-the-fly configuration {{{
 if [ -n "$FAI_DEBOOTSTRAP" ] ; then
   sed "s#^FAI_DEBOOTSTRAP=.*#FAI_DEBOOTSTRAP=\"$FAI_DEBOOTSTRAP\"#" "$NFSROOT_CONF" | sponge "$NFSROOT_CONF"
@@ -672,20 +697,78 @@ fi # BUILD_DIRTY?
 
 # package validator {{{
 CHECKLOG=/var/log/fai/$HOSTNAME/last
-# package validator
-if [ -r "$CHECKLOG/package_errors.log" ] && grep -q '[a-z]' "$CHECKLOG/package_errors.log" ; then
+if [ -r "$CHECKLOG/dpkg.selections" ] ; then
+  package_count=$(wc -l "$CHECKLOG/dpkg.selections" | awk '{print $1}')
+else
+  package_count="unknown"
+fi
 
-   if [ -n "$EXIT_ON_MISSING_PACKAGES" -a -z "$BUILD_DIRTY" ] ; then
-      eerror "The following packages were requested for installation but could not be processed:"
-      cat $CHECKLOG/package_errors.log
-      eerror "... exiting as requested via \$EXIT_ON_MISSING_PACKAGES."
-      eend 1
-      bailout 13
-   else
-      ewarn "The following packages were requested for installation but could not be processed:"
-      cat $CHECKLOG/package_errors.log
-      eend 0
-   fi
+mkdir -p "$REPORTS"
+REPORT_MISSING_PACKAGES="${REPORTS}/TEST-MissingPackages.xml"
+
+# check for missing packages
+if ! [ -s "$CHECKLOG/package_errors.log" ] ; then
+  einfo "No missing packages found, generating empty junit report."
+
+  cat > "${REPORT_MISSING_PACKAGES}" << EOF
+<?xml version="1.0" encoding="UTF-8"?>
+<testsuite name="grml-live-missing-packages" tests="${package_count}" time="1" failures="0" errors="0" skipped="0" assertions="0">
+  <testcase name="test_missing_packages" time="0" assertions="0">
+  </testcase>
+  <system-out>
+  </system-out>
+  <system-err>
+  </system-err>
+</testsuite>
+EOF
+  eend 0
+else
+  einfo "Missing packages found, generating junit report."
+
+  if [ -r "$CHECKLOG/package_errors.log" ] ; then
+    package_errors=$(wc -l "$CHECKLOG/package_errors.log" | awk '{print $1}')
+  else
+    package_errors="unknown"
+  fi
+
+  mkdir -p "$REPORTS"
+  REPORT_MISSING_PACKAGES="${REPORTS}/TEST-MissingPackages.xml"
+
+  cat > "${REPORT_MISSING_PACKAGES}" << EOF
+<?xml version="1.0" encoding="UTF-8"?>
+<testsuite name="grml-live-missing-packages" tests="${package_count}" time="1" failures="${package_errors}" errors="${package_errors}" skipped="0" assertions="0">
+EOF
+
+  for package in $(awk '{print $5}' "${CHECKLOG}/package_errors.log" | sed 's/\.$//') ; do
+    cat >> "${REPORT_MISSING_PACKAGES}" << EOF
+  <testcase name="test_missing_packages_${package}" time="0" assertions="0">
+    <failure type="RuntimeError" message="Package ${package} is missing">
+Package $package is missing in chroot
+  </failure>
+  </testcase>
+EOF
+  done
+
+  cat >> "${REPORT_MISSING_PACKAGES}" << EOF
+  <system-out>
+  </system-out>
+  <system-err>
+  </system-err>
+</testsuite>
+EOF
+  eend 0
+
+  if [ -n "$EXIT_ON_MISSING_PACKAGES" -a -z "$BUILD_DIRTY" ] ; then
+    eerror "The following packages were requested for installation but could not be processed:"
+    cat "$CHECKLOG/package_errors.log"
+    eerror "... exiting as requested via \$EXIT_ON_MISSING_PACKAGES."
+    eend 1
+    bailout 13
+  else
+    ewarn "The following packages were requested for installation but could not be processed:"
+    cat "$CHECKLOG/package_errors.log"
+    eend 0
+  fi
 fi
 # }}}