Cleanup VM for exporting to appliance
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
#|Usage: <command> [OPTIONS] | |
#| | |
#|Clean development VM for exporting to appliance: | |
#| | |
#| - update system: apt-get update and upgrade | |
#| - install zerofree package | |
#| - remove user ssh keys | |
#| - stop foreman and django | |
#| - stop mongodb, compact database, purge journal | |
#| - purge /var/cache: <var-cache> | |
#| - purge /tmp | |
#| - disable, zero, recreate and reenable swap | |
#| - output steps to minify the vmdk disk image | |
#| | |
#|Options: | |
#| | |
#| -h, --help Show this help message and exit. | |
#| -n, --dry-run Preview, do not run anything. | |
#| -u, --no-update Do not update system. | |
#| | |
SSHKey="$HOME/.ssh/id_rsa" | |
VarCache= | |
# VarCache="apt apt-xapian-index cups man oracle-jdk-7-installer" | |
MongoDB=/var/lib/mongodb | |
main () { | |
local Name Base Force DryRun NoUpdate Output Swap Root | |
Name="${0##*/}" | |
# Base="`cd "${0%/*}"; pwd -P`" | |
if [ "$1" = -h -o "$1" = --help ]; then | |
usage "$0" command="$Name" var-cache="${VarCache:-*}" | |
return 2 | |
fi | |
[ "$1" = -f -o "$1" = --force ] && Force=$1 && shift 1 || Force= | |
[ "$1" = -n -o "$1" = --dry-run ] && DryRun=$1 && shift 1 || DryRun= | |
[ "$1" = -u -o "$1" = --no-update ] && NoUpdate=$1 && shift 1 || NoUpdate= | |
II "update system: apt-get update and upgrade" | |
if [ -z "$NoUpdate" ]; then | |
run sudo apt-get update || return $? | |
run sudo apt-get upgrade || return $? | |
else | |
skip "disabled with option $NoUpdate" | |
fi | |
II "install zerofree package" | |
if Output="`dpkg -l zerofree | grep -i 'ii *zerofree'`"; then | |
skip "zerofree already installed:" $Output | |
# dpkg output is outside quotes to shrink spaces | |
else | |
run sudo apt-get install -y zerofree || return $? | |
fi | |
II "remove user ssh keys" | |
if [ -f "$SSHKey" ]; then | |
run rm -f "$SSHKey" || return $? | |
[ ! -f "$SSHKey.pub" ] || run rm -f "$SSHKey.pub" || return $? | |
else | |
skip "not found: $SSHKey" | |
fi | |
II "stop foreman and django" | |
log pgrep -l foreman && { run pkill foreman || return $?; } | |
log pgrep -fl runserver && { run pkill -f runserver || return $?; } | |
II "stop mongodb, compact database, purge journal" | |
if Output="`status mongodb | grep -i stop`"; then | |
skip "mongodb already stopped: $Output" | |
else | |
run sudo stop mongodb || return $? | |
fi | |
if [ -d "$MongoDB" ]; then | |
log du -sh "$MongoDB" | |
run sudo mongod --repair --dbpath "$MongoDB" || return $? | |
run sudo chown -R mongodb:mongodb "$MongoDB"/* || return $? | |
log du -sh "$MongoDB" | |
log du -sh "$MongoDB"/journal | |
run sudo rm -rf "$MongoDB"/journal/* || return $? | |
log du -sh "$MongoDB"/journal | |
log du -sh "$MongoDB" | |
else | |
skip "mongodb database path not found: $MongoDB" | |
fi | |
II "purge /var/cache: ${VarCache:-*}" | |
if [ -z "$VarCache" ]; then | |
log sudo du -sh /var/cache | |
log sudo du -sh /var/cache/* | |
run sudo rm -rf /var/cache/* # || return $? | |
log sudo du -sh /var/cache | |
else | |
for dir in $VarCache; do | |
dir="/var/cache/$dir" | |
if [ -d "$dir" ]; then | |
log du -sh "$dir" | |
run sudo rm -rf "$dir" || return $? | |
else | |
skip "not found: $dir" | |
fi | |
done | |
fi | |
II "purge /tmp" | |
log sudo du -sh /tmp | |
run sudo rm -rf /tmp/* # || return $? | |
log sudo du -sh /tmp | |
II "disable, zero, recreate and reenable swap" | |
log swapon -s | |
Swap="`swapon -s | tail -1 | cut -f1 -d ' '`" | |
if [ "${Swap#/dev/}" != "$Swap" ]; then | |
log echo "detected swap on $Swap" | |
run sudo swapoff "$Swap" || return $? | |
run sudo dd "if=/dev/zero" "of=$Swap" # || return $? | |
run sudo mkswap "$Swap" || return $? | |
run sudo swapon "$Swap" || return $? | |
else | |
skip "no swap detected" | |
fi | |
II "steps to minify the vmdk disk image" | |
Root="`mount | grep ' on / type ' | cut -f1 -d ' '`" | |
log echo "detected root on ${Root:-<not-detected>}" | |
cat <<EOF | |
Steps to clean free space on root partition: | |
1. sudo telinit 1 | |
# switch to single user mode with / mounted readonly | |
# - if it hangs, then restart, press Esc to get into boot menu | |
# and boot to recovery mode | |
2. zerofree -v ${Root:-<root-partition>} | |
# run verbose /usr/sbin/zerofree on root partiton | |
# zerofree can only zero free space on ext2/3/4 partitions | |
3. shutdown -h now | |
Steps to minify the vmdk image (expects the VM to be stopped): | |
1. cd "<home>/Virtualbox VMs/<vm-folder>" | |
2. VBoxManage modifyhd --compact <vm-disk-image.vmdk> | |
EOF | |
} | |
II () { echo >&2; echo "=== $@" >&2; } | |
skip () { echo "--- $@" >&2; return 3; } | |
error () { echo "!!! $@" >&2; return 1; } | |
run () { echo ">>> $@" >&2; [ -n "$DryRun" ] || "$@"; } | |
log () { | |
## Usage: log command [OPTIONS] | |
## Runs command, and redirect indented output to stderr. | |
local O R; | |
[ "$1" = echo ] && shift && echo "... $@" >&2 && return | |
echo "... $@" >&2; O="`mktemp`" || { "$@"; return $?; } | |
"$@" >"$O" 2>&1; R=$?; sed 's/^/ /' "$O" >&2; rm "$O"; return $R | |
} | |
usage () { local R S I; S="${1:-$0}"; shift; R=; for I in "$@"; do I="${I//\\/\\}"; I="${I//\//\/}"; R="${R}s/<${I%%=*}>/${I#*=}/;"; done; sed -n "$R;/^#|/s/#|//p;" "$S"; } | |
## Usage: usage script [var=value] | |
## Extracts documentation from script. | |
is_sourced () { [ -z "$0" -o "$0" = "${SHELL##*/}" -o "$0" = 'sh' ] && [ $# = 0 ]; } | |
## Checks if current script is sourced from another script via '.' (command is empty or shell). | |
is_sourced || ! trap 'exit 10' 1 2 3 13 15 || main "$@" || exit $? |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment