NormalizeSnap.sh (Source)

#!/bin/sh

######################################################################
# ExtractCmd.sh
#
#  Copyright (c) 2016, Russell Adams <Russell.Adams@AdamsSystems.nl>
#  All rights reserved.
#
#  Redistribution and use in source and binary forms, with or without
#  modification, are permitted provided that the following conditions are
#  met:
#
#   - Redistributions of source code must retain the above copyright
#     notice, this list of conditions and the following disclaimer.
#
#   - Redistributions in binary form must reproduce the above copyright
#     notice, this list of conditions and the following disclaimer in the
#     documentation and/or other materials provided with the
#     distribution.
#
#   - Neither the name of Russell Adams, Adams Systems Consultancy,
#     nor the names of its contributors may be used to endorse or promote
#     products derived from this software without specific prior written
#     permission.
#
#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
#  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
#  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
#  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
#  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
#  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
#  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
#  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
#  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
#  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
#  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# This script uncompresses and unarchives an IBM AIX snap file stored
# in the PAX format. It create a new directory named by host, oslevel
# and date, performs recursive PAX unpacking (ie: HA snaps), and makes
# a final bzipped archive. The original .Z file can be removed
# afterward.

openpax () {

    # openpax DestinationDirectory Filename
    OLDDIR=$PWD
    cd "$1"

    pax $TAR_FLAGS -rvf "${OLDDIR}/${2}" 2>&1 | tail -n1

    cd "$OLDDIR"
}

fixperms () {

	# there's a frequent hiccup in hacmp snaps where the subsnap has no execute privs
	echo "Fixing perms."
	find $1 -type d -exec chmod 755 '{}' \;
	find $1 -type f -exec chmod 755 '{}' \;
	find $1 -type d -exec chmod 755 '{}' \;
	find $1 -type f -exec chmod 755 '{}' \;

}


for TARGET in "$@" ; do {

    [ -f "${TARGET}" ] || {
	    echo "Snap file does not exist"
	    exit 1
    }

    echo "${TARGET}" | egrep '\.(tar|pax)\.(Z|gz)$'   > /dev/null && TAR_FLAGS="-z"
    echo "${TARGET}" | egrep '\.(tar|pax)\.bz2$'      > /dev/null && TAR_FLAGS="-j"

    [ -z "$TAR_FLAGS" ] && {
	    echo "Unrecognized snap suffix, supports .{tar,pax}.{Z,gz,bz2}"
	    exit 1
    }

    TMPDIR=$(mktemp -d "./snapXXXXXXXX")

    # Untar into the scratch dir
    echo "========================================"
	echo -n "Untarring, # of files: "
	echo "${TARGET}" | grep '\.tar\.' && tar --no-same-permissions -C $TMPDIR $TAR_FLAGS -xvf "${TARGET}" | wc -l
    echo "${TARGET}" | grep '\.pax\.' && openpax "$TMPDIR" "${TARGET}"

	# Check is this a snap?
	echo "Checking general exists."
    find $TMPDIR -name general -type d | grep general || {
		echo "Not a snap file, aborting."
		exit 1
	}

    # Fix perms
	fixperms $TMPDIR

    # Find snap/general/... and move them into the base of the scratch dir
	echo "Moving subdirs."
	[ -d ${TMPDIR}/general ] || mv $(dirname $(find $TMPDIR -name general -type d | tail -n1))/* $TMPDIR

    # Check for sub-snaps
    echo "Opening subsnaps."
    find $TMPDIR -type f -name '*.pax.Z' | while read Z; do
        SUBTMP="$(echo ${Z} | sed 's/\.pax\.Z$//g')"
        mkdir "${SUBTMP}"
        echo "Opening subsnap $Z"
        openpax "${SUBTMP}" "${Z}"
        rm "${Z}"
    done
    find $TMPDIR -type f -name '*.pax' | while read Z; do
        SUBTMP="$(echo ${Z} | sed 's/\.pax$//g')"
        mkdir "${SUBTMP}"
        echo "Opening subsnap $Z"
        TAR_FLAGS="" openpax "${SUBTMP}" "${Z}"
        rm "${Z}"
    done
    find $TMPDIR -type f -name '*.tar.Z' | while read Z; do
        SUBTMP="$(echo ${Z} | sed 's/\.tar\.Z$//g')"
        mkdir "${SUBTMP}"
        echo "Opening subsnap $Z"
        tar --no-same-permissions -C $SUBTMP -zxvf "${TARGET}" | wc -l
        rm "${Z}"
    done

	# Fix perms
	fixperms $TMPDIR

    # Clean empty dirs
	echo "Cleaning empty dirs."
	find $TMPDIR -type d -empty -print0 | xargs -0t rmdir

    # Attributes
	echo "Collecting data."
	SYSTEM=$(awk   'BEGIN {RS="\n\n.....\n"} /lsattr -El sys0/  {print $0}' < ${TMPDIR}/general/general.snap | awk '/^modelname +/ {print $2}' | cut -f2 -d,)
	SERIAL=$(awk   'BEGIN {RS="\n\n.....\n"} /lsattr -El sys0/  {print $0}' < ${TMPDIR}/general/general.snap | awk '/^systemid +/  {print $2}' | cut -f2 -d,)

	OSLEVEL=$(tail -n1 $TMPDIR/general/oslevel.info \
				  || grep :bos.rte: ${TMPDIR}/general/lslpp.hac | sort | cut -f3 -d: | tail -n1)

	SNAPHOST=$(awk 'BEGIN {RS="\n\n.....\n"} /lsattr -El inet0/ {print $0}' < ${TMPDIR}/general/general.snap | awk '/^hostname +/  {print $2}' | tr -d _)
	SNAPDATE=$(date +%Y%m%d_%H%M%S -d "$(head -n1 $TMPDIR/general/general.snap)")

	NEWNAME="./${SYSTEM}_${SERIAL}_${SNAPHOST}_${OSLEVEL}_${SNAPDATE}.snap"

    # Cleanup
	echo "Cleaning dump and security."
	find $TMPDIR -name 'unix.Z'  -print0 | xargs -0 rm -f
	find $TMPDIR -name 'dump.Z'  -print0 | xargs -0 rm -f
	find $TMPDIR -name 'dump.BZ' -print0 | xargs -0 rm -f
	find $TMPDIR -name 'passwd'  -print0 | xargs -0 rm -f

    # Rename logically
    echo "Renaming to final destination"
	mv $TMPDIR $NEWNAME

    # Recompress
    echo "Retarring files into: ${NEWNAME}.tar.bzip2 "
    echo -n "Number of files compressed: "
	tar -jcvf "${NEWNAME}.tar.bzip2" "${NEWNAME}" | wc -l

    # Echo completion
    echo "Successfully extracted snap to: $NEWNAME"

} 2>&1 | tee -a ./NormalizeSnap.log

done