2014-05-18 17:52:33 -04:00
|
|
|
#!/bin/bash
|
|
|
|
# checks if run as root:
|
2019-11-07 01:11:16 -05:00
|
|
|
if [ "$(whoami)" != 'root' ]
|
2014-05-18 17:52:33 -04:00
|
|
|
then
|
2019-11-03 15:13:54 -05:00
|
|
|
echo "$(basename "$0"): must be root."
|
|
|
|
exit 1
|
2014-05-18 17:52:33 -04:00
|
|
|
fi
|
|
|
|
|
2014-05-20 03:07:01 -04:00
|
|
|
#set flag variables to null
|
|
|
|
EXCLUDE_BOOT=0
|
2020-03-24 22:43:25 -04:00
|
|
|
EXCLUDE_CONFIDENTIAL=0
|
2016-02-19 15:15:25 -05:00
|
|
|
EXCLUDE_LOST=0
|
2014-05-20 03:07:01 -04:00
|
|
|
QUIET=0
|
2019-11-03 12:25:01 -05:00
|
|
|
USER_EXCL=()
|
2020-04-02 22:10:09 -04:00
|
|
|
USER_INCL=()
|
2018-05-10 23:13:12 -04:00
|
|
|
S_KERNEL=0
|
2018-12-14 15:53:19 -05:00
|
|
|
PARALLEL=0
|
2019-08-05 08:18:24 -04:00
|
|
|
HAS_PORTAGEQ=0
|
|
|
|
|
2019-11-03 12:25:01 -05:00
|
|
|
if command -v portageq &>/dev/null
|
2019-08-05 08:18:24 -04:00
|
|
|
then
|
2019-11-03 15:13:54 -05:00
|
|
|
HAS_PORTAGEQ=1
|
2019-08-05 08:18:24 -04:00
|
|
|
fi
|
|
|
|
|
2016-02-11 01:51:15 -05:00
|
|
|
USAGE="usage:\n\
|
2020-04-02 22:10:09 -04:00
|
|
|
$(basename "$0") [-q -c -b -l -k -p] [-s || -t <target-mountpoint>] [-e <additional excludes dir*>] [-i <additional include target>] <archive-filename> [custom-tar-options]\n\
|
2019-11-03 15:13:54 -05:00
|
|
|
-q: activates quiet mode (no confirmation).\n\
|
2020-03-24 22:43:25 -04:00
|
|
|
-c: excludes some confidential files (currently only .bash_history and connman network lists).\n\
|
2019-11-03 15:13:54 -05:00
|
|
|
-b: excludes boot directory.\n\
|
|
|
|
-l: excludes lost+found directory.\n\
|
|
|
|
-p: compresses parallelly using pbzip2.\n\
|
|
|
|
-e: an additional excludes directory (one dir one -e, donot use it with *).\n\
|
2020-04-02 22:10:09 -04:00
|
|
|
-i: an additional target to include. This has higher precedence than -e, -t, and -s.\n\
|
2019-11-03 15:13:54 -05:00
|
|
|
-s: makes tarball of current system.\n\
|
|
|
|
-k: separately save current kernel modules and src (smaller & save decompression time).\n\
|
|
|
|
-t: makes tarball of system located at the <target-mountpoint>.\n\
|
|
|
|
-h: displays help message."
|
2014-05-20 03:07:01 -04:00
|
|
|
|
2014-05-18 17:52:33 -04:00
|
|
|
# reads options:
|
2020-04-02 22:10:09 -04:00
|
|
|
while getopts ":t:e:i:skqcblph" flag
|
2019-11-03 12:25:01 -05:00
|
|
|
do
|
2019-11-03 15:13:54 -05:00
|
|
|
case "$flag" in
|
|
|
|
t)
|
|
|
|
TARGET="$OPTARG"
|
|
|
|
;;
|
|
|
|
s)
|
|
|
|
TARGET="/"
|
|
|
|
;;
|
|
|
|
q)
|
|
|
|
QUIET=1
|
|
|
|
;;
|
|
|
|
k)
|
|
|
|
S_KERNEL=1
|
|
|
|
;;
|
|
|
|
c)
|
2020-03-24 22:43:25 -04:00
|
|
|
EXCLUDE_CONFIDENTIAL=1
|
2019-11-03 15:13:54 -05:00
|
|
|
;;
|
|
|
|
b)
|
|
|
|
EXCLUDE_BOOT=1
|
|
|
|
;;
|
|
|
|
l)
|
|
|
|
EXCLUDE_LOST=1
|
|
|
|
;;
|
|
|
|
e)
|
|
|
|
USER_EXCL+=("--exclude=${OPTARG}")
|
|
|
|
;;
|
2020-04-02 22:10:09 -04:00
|
|
|
i)
|
|
|
|
USER_INCL+=("${OPTARG}")
|
|
|
|
;;
|
2019-11-03 15:13:54 -05:00
|
|
|
p)
|
|
|
|
PARALLEL=1
|
|
|
|
;;
|
|
|
|
h)
|
|
|
|
echo -e "$USAGE"
|
|
|
|
exit 0
|
|
|
|
;;
|
|
|
|
\?)
|
|
|
|
echo "Invalid option: -$OPTARG" >&2
|
|
|
|
exit 1
|
|
|
|
;;
|
|
|
|
:)
|
|
|
|
echo "Option -$OPTARG requires an argument." >&2
|
|
|
|
exit 1
|
|
|
|
;;
|
|
|
|
esac
|
2014-05-18 17:52:33 -04:00
|
|
|
done
|
|
|
|
|
2019-11-03 12:25:01 -05:00
|
|
|
if [ -z "$TARGET" ]
|
2016-02-11 01:45:57 -05:00
|
|
|
then
|
2019-11-03 15:13:54 -05:00
|
|
|
echo "$(basename "$0"): no target specified."
|
|
|
|
echo -e "$USAGE"
|
|
|
|
exit 1
|
2016-02-11 01:45:57 -05:00
|
|
|
fi
|
|
|
|
|
2017-03-22 12:17:24 -04:00
|
|
|
# make sure TARGET path ends with slash
|
2019-11-07 01:11:16 -05:00
|
|
|
if [[ "$TARGET" != */ ]]
|
2017-03-22 12:17:24 -04:00
|
|
|
then
|
2019-11-03 15:13:54 -05:00
|
|
|
TARGET="${TARGET}/"
|
2017-03-22 12:17:24 -04:00
|
|
|
fi
|
|
|
|
|
2014-05-18 17:52:33 -04:00
|
|
|
# shifts pointer to read mandatory output file specification
|
2019-11-03 12:25:01 -05:00
|
|
|
shift $((OPTIND - 1))
|
2014-05-18 17:52:33 -04:00
|
|
|
ARCHIVE=$1
|
|
|
|
|
|
|
|
# checks for correct output file specification
|
2019-11-03 12:25:01 -05:00
|
|
|
if [ -z "$ARCHIVE" ]
|
2014-05-18 17:52:33 -04:00
|
|
|
then
|
2019-11-03 15:13:54 -05:00
|
|
|
echo "$(basename "$0"): no archive file name specified."
|
|
|
|
echo -e "$USAGE"
|
|
|
|
exit 1
|
2014-05-18 17:52:33 -04:00
|
|
|
fi
|
|
|
|
|
|
|
|
# checks for quiet mode (no confirmation)
|
2019-11-07 01:11:16 -05:00
|
|
|
if ((QUIET))
|
2014-05-18 17:52:33 -04:00
|
|
|
then
|
2019-11-03 15:13:54 -05:00
|
|
|
AGREE="yes"
|
2014-05-18 17:52:33 -04:00
|
|
|
fi
|
|
|
|
|
|
|
|
# determines if filename was given with relative or absolute path
|
2019-11-07 01:11:16 -05:00
|
|
|
if (($(grep -c '^/' <<< "$ARCHIVE") > 0))
|
2014-05-18 17:52:33 -04:00
|
|
|
then
|
2019-11-03 15:13:54 -05:00
|
|
|
STAGE4_FILENAME="${ARCHIVE}.tar.bz2"
|
2014-05-18 17:52:33 -04:00
|
|
|
else
|
2019-11-03 15:13:54 -05:00
|
|
|
STAGE4_FILENAME="$(pwd)/${ARCHIVE}.tar.bz2"
|
2014-05-18 17:52:33 -04:00
|
|
|
fi
|
|
|
|
|
|
|
|
#Shifts pointer to read custom tar options
|
2019-11-03 12:25:01 -05:00
|
|
|
shift
|
|
|
|
mapfile -t OPTIONS <<< "$@"
|
2019-11-07 01:11:16 -05:00
|
|
|
# Handle when no options are passed
|
|
|
|
((${#OPTIONS[@]} == 1)) && [ -z "${OPTIONS[0]}" ] && unset OPTIONS
|
2014-05-18 17:52:33 -04:00
|
|
|
|
2019-11-07 01:11:16 -05:00
|
|
|
if ((S_KERNEL))
|
2018-05-10 23:13:12 -04:00
|
|
|
then
|
2019-11-03 15:13:54 -05:00
|
|
|
USER_EXCL+=("--exclude=${TARGET}usr/src/*")
|
2020-02-04 22:45:04 -05:00
|
|
|
USER_EXCL+=("--exclude=${TARGET}lib*/modules/*")
|
2018-05-10 23:13:12 -04:00
|
|
|
fi
|
|
|
|
|
|
|
|
|
2014-05-18 17:52:33 -04:00
|
|
|
# Excludes:
|
2019-11-03 12:25:01 -05:00
|
|
|
EXCLUDES=(
|
2019-11-07 01:11:16 -05:00
|
|
|
"--exclude=${TARGET}dev/*"
|
|
|
|
"--exclude=${TARGET}var/tmp/*"
|
|
|
|
"--exclude=${TARGET}media/*"
|
|
|
|
"--exclude=${TARGET}mnt/*/*"
|
|
|
|
"--exclude=${TARGET}proc/*"
|
|
|
|
"--exclude=${TARGET}run/*"
|
|
|
|
"--exclude=${TARGET}sys/*"
|
|
|
|
"--exclude=${TARGET}tmp/*"
|
|
|
|
"--exclude=${TARGET}var/lock/*"
|
|
|
|
"--exclude=${TARGET}var/log/*"
|
|
|
|
"--exclude=${TARGET}var/run/*"
|
|
|
|
"--exclude=${TARGET}var/lib/docker/*"
|
2019-11-03 12:25:01 -05:00
|
|
|
)
|
2018-07-10 09:36:10 -04:00
|
|
|
|
2019-11-03 12:25:01 -05:00
|
|
|
EXCLUDES_DEFAULT_PORTAGE=(
|
2019-11-07 01:11:16 -05:00
|
|
|
"--exclude=${TARGET}var/db/repos/gentoo/*"
|
|
|
|
"--exclude=${TARGET}var/cache/distfiles/*"
|
|
|
|
"--exclude=${TARGET}usr/portage/*"
|
2019-11-03 12:25:01 -05:00
|
|
|
)
|
2014-05-18 17:52:33 -04:00
|
|
|
|
2019-11-03 12:25:01 -05:00
|
|
|
EXCLUDES+=("${USER_EXCL[@]}")
|
2018-05-10 23:13:12 -04:00
|
|
|
|
2020-04-02 22:10:09 -04:00
|
|
|
INCLUDES=(
|
|
|
|
)
|
|
|
|
|
|
|
|
INCLUDES+=("${USER_INCL[@]}")
|
|
|
|
|
2019-11-03 12:25:01 -05:00
|
|
|
if [ "$TARGET" == '/' ]
|
2014-05-18 17:52:33 -04:00
|
|
|
then
|
2019-11-07 01:11:16 -05:00
|
|
|
EXCLUDES+=("--exclude=$(realpath "$STAGE4_FILENAME")")
|
|
|
|
if ((HAS_PORTAGEQ))
|
2019-11-03 15:13:54 -05:00
|
|
|
then
|
|
|
|
EXCLUDES+=("--exclude=$(portageq get_repo_path / gentoo)/*")
|
|
|
|
EXCLUDES+=("--exclude=$(portageq distdir)/*")
|
|
|
|
else
|
|
|
|
EXCLUDES+=("${EXCLUDES_DEFAULT_PORTAGE[@]}")
|
|
|
|
fi
|
2019-08-05 08:18:24 -04:00
|
|
|
else
|
2019-11-07 01:11:16 -05:00
|
|
|
EXCLUDES+=("${EXCLUDES_DEFAULT_PORTAGE[@]}")
|
2014-05-18 17:52:33 -04:00
|
|
|
fi
|
|
|
|
|
2020-03-24 22:43:25 -04:00
|
|
|
if ((EXCLUDE_CONFIDENTIAL))
|
2014-05-18 17:52:33 -04:00
|
|
|
then
|
2020-03-24 22:43:25 -04:00
|
|
|
EXCLUDES+=("--exclude=${TARGET}home/*/.bash_history")
|
|
|
|
EXCLUDES+=("--exclude=${TARGET}root/.bash_history")
|
2019-11-03 15:13:54 -05:00
|
|
|
EXCLUDES+=("--exclude=${TARGET}var/lib/connman/*")
|
2014-05-18 17:52:33 -04:00
|
|
|
fi
|
|
|
|
|
2019-11-07 01:11:16 -05:00
|
|
|
if ((EXCLUDE_BOOT))
|
2014-05-18 17:52:33 -04:00
|
|
|
then
|
2019-11-03 15:13:54 -05:00
|
|
|
EXCLUDES+=("--exclude=${TARGET}boot/*")
|
2014-05-18 17:52:33 -04:00
|
|
|
fi
|
|
|
|
|
2019-11-07 01:11:16 -05:00
|
|
|
if ((EXCLUDE_LOST))
|
2016-02-18 00:45:51 -05:00
|
|
|
then
|
2019-11-03 15:13:54 -05:00
|
|
|
EXCLUDES+=("--exclude=lost+found")
|
2016-02-18 00:45:51 -05:00
|
|
|
fi
|
|
|
|
|
2014-05-18 17:52:33 -04:00
|
|
|
# Generic tar options:
|
2019-11-03 12:25:01 -05:00
|
|
|
TAR_OPTIONS=(-cpP --ignore-failed-read "--xattrs-include='*.*'" --numeric-owner)
|
2018-12-14 15:53:19 -05:00
|
|
|
|
2019-11-07 01:11:16 -05:00
|
|
|
if ((PARALLEL))
|
2018-12-14 15:53:19 -05:00
|
|
|
then
|
2019-11-03 15:13:54 -05:00
|
|
|
if command -v pbzip2 &>/dev/null; then
|
|
|
|
TAR_OPTIONS+=("--use-compress-prog=pbzip2")
|
|
|
|
else
|
|
|
|
echo "WARING: pbzip2 isn't installed, single-threaded compressing is used." >&2
|
|
|
|
TAR_OPTIONS+=("-j")
|
|
|
|
fi
|
2018-12-14 15:53:19 -05:00
|
|
|
else
|
2019-11-03 15:13:54 -05:00
|
|
|
TAR_OPTIONS+=("-j")
|
2018-12-14 15:53:19 -05:00
|
|
|
fi
|
2014-05-18 17:52:33 -04:00
|
|
|
|
|
|
|
# if not in quiet mode, this message will be displayed:
|
2019-11-07 01:11:16 -05:00
|
|
|
if [[ "$AGREE" != 'yes' ]]
|
2014-05-18 17:52:33 -04:00
|
|
|
then
|
2019-11-03 15:13:54 -05:00
|
|
|
echo "Are you sure that you want to make a stage 4 tarball of the system"
|
|
|
|
echo "located under the following directory?"
|
|
|
|
echo "$TARGET"
|
2019-11-07 01:11:16 -05:00
|
|
|
echo
|
2019-11-03 15:13:54 -05:00
|
|
|
echo "WARNING: since all data is saved by default the user should exclude all"
|
|
|
|
echo "security- or privacy-related files and directories, which are not"
|
|
|
|
echo "already excluded by mkstage4 options (such as -c), manually per cmdline."
|
|
|
|
echo "example: \$ $(basename "$0") -s /my-backup --exclude=/etc/ssh/ssh_host*"
|
2019-11-07 01:11:16 -05:00
|
|
|
echo
|
2019-11-03 15:13:54 -05:00
|
|
|
echo "COMMAND LINE PREVIEW:"
|
2020-04-02 22:10:09 -04:00
|
|
|
echo 'tar' "${TAR_OPTIONS[@]}" "${INCLUDES[@]}" "${EXCLUDES[@]}" "${OPTIONS[@]}" -f "$STAGE4_FILENAME" "${TARGET}"
|
2019-11-07 01:11:16 -05:00
|
|
|
if ((S_KERNEL))
|
2019-11-03 15:13:54 -05:00
|
|
|
then
|
2019-11-07 01:11:16 -05:00
|
|
|
echo
|
2020-03-24 22:46:32 -04:00
|
|
|
echo 'tar' "${TAR_OPTIONS[@]}" -f "$STAGE4_FILENAME.ksrc" "${TARGET}usr/src/linux-$(uname -r)"
|
|
|
|
echo 'tar' "${TAR_OPTIONS[@]}" -f "$STAGE4_FILENAME.kmod" "${TARGET}lib"*"/modules/$(uname -r)"
|
2019-11-03 15:13:54 -05:00
|
|
|
fi
|
2019-11-07 01:11:16 -05:00
|
|
|
echo
|
|
|
|
echo -n 'Type "yes" to continue or anything else to quit: '
|
2019-11-03 15:13:54 -05:00
|
|
|
read -r AGREE
|
2014-05-18 17:52:33 -04:00
|
|
|
fi
|
|
|
|
|
|
|
|
# start stage4 creation:
|
2019-11-07 01:11:16 -05:00
|
|
|
if [ "$AGREE" == 'yes' ]
|
2014-05-18 17:52:33 -04:00
|
|
|
then
|
2020-04-02 22:10:09 -04:00
|
|
|
tar "${TAR_OPTIONS[@]}" "${INCLUDES[@]}" "${EXCLUDES[@]}" "${OPTIONS[@]}" -f "$STAGE4_FILENAME" "${TARGET}"
|
2019-11-07 01:11:16 -05:00
|
|
|
if ((S_KERNEL))
|
2019-11-03 15:13:54 -05:00
|
|
|
then
|
2020-03-24 22:46:32 -04:00
|
|
|
tar "${TAR_OPTIONS[@]}" -f "$STAGE4_FILENAME.ksrc" "${TARGET}usr/src/linux-$(uname -r)"
|
|
|
|
tar "${TAR_OPTIONS[@]}" -f "$STAGE4_FILENAME.kmod" "${TARGET}lib"*"/modules/$(uname -r)"
|
2019-11-03 15:13:54 -05:00
|
|
|
fi
|
2014-05-18 17:52:33 -04:00
|
|
|
fi
|