summaryrefslogtreecommitdiffstats
path: root/packager
diff options
context:
space:
mode:
authorJonathan Bauer2015-06-03 12:42:18 +0200
committerJonathan Bauer2015-06-03 12:42:18 +0200
commitb760f7e9d8f601cf13d197fdd75e0a6546f49734 (patch)
tree3279c0fdfdb3c5075ad950195d6cd07bc8de350c /packager
parentfinally in a working state. See usage. (diff)
downloadsystemd-init-b760f7e9d8f601cf13d197fdd75e0a6546f49734.tar.gz
systemd-init-b760f7e9d8f601cf13d197fdd75e0a6546f49734.tar.xz
systemd-init-b760f7e9d8f601cf13d197fdd75e0a6546f49734.zip
trapped SIGINT/SIGTERM and implemented cleanup function
only rsync if we have a '.stage4' flag in the target sync dir
Diffstat (limited to 'packager')
-rwxr-xr-xpackager/openslx17
-rw-r--r--packager/openslx.functions142
2 files changed, 139 insertions, 20 deletions
diff --git a/packager/openslx b/packager/openslx
index a71a1db6..9613196b 100755
--- a/packager/openslx
+++ b/packager/openslx
@@ -10,21 +10,22 @@
#
# ------------------------------------------------------------------------------
#
-# OpenSLX-NG Main Code
+# Main Code
#
# ------------------------------------------------------------------------------
declare -rg ARG0="$0"
-declare -rg SELF="$(readlink -f "$ARG0")"
+declare -rg SELF="$(readlink -f "${ARG0}")"
declare -rg ROOT_DIR="$(dirname "${SELF}")"
declare -rg SELF_PID="$$"
# let's keep it simple for now, just source our config/functions file
-. "${ROOT_DIR}/$ARG0".functions || perror "Could not source functions."
-. "${ROOT_DIR}/$ARG0".config || perror "Could not source config."
+. "${ROOT_DIR}/${ARG0}".functions || perror "Could not source functions."
+. "${ROOT_DIR}/${ARG0}".config || perror "Could not source config."
# root check
if [ "$(id -u)" -ne 0 ]; then
+ banner
perror "ERROR: You need to be root to use this toolkit."
else
banner
@@ -32,11 +33,17 @@ fi
# do we even have tools?
for TOOL in qemu-img qemu-nbd mkfs.ext4; do
- which $TOOL &>/dev/null || perror "Could not find '$TOOL'."
+ which "${TOOL}" &>/dev/null || \
+ perror "Could not find '${TOOL}'. Please install it."
done
+# setup trap
+trap cleanexit SIGINT SIGTERM
+# read params
read_params $@
+
+# react to given action
if [ "x$ACTION" == "xCLONE" ]; then
clone_stage4 || perror "Cloning stage4 failed with: $?"
elif [ "x$ACTION" == "xPACKAGE" ]; then
diff --git a/packager/openslx.functions b/packager/openslx.functions
index 867e252d..8ecc1fdc 100644
--- a/packager/openslx.functions
+++ b/packager/openslx.functions
@@ -143,6 +143,88 @@ read_params() {
done
}
+# helper function trapped on SIGTERM/SIGINT
+# Usage: do not use as is
+cleanexit() {
+ trap '' SIGINT SIGTERM # from now on, ignore INT and TERM
+ pwarning "SIGINT/SIGTERM triggered - cleaning up ..."
+ [ -z "${_STATE}" ] && perror "'_STATE' not set, this is bad."
+
+ case "${_STATE}" in
+ SYNC_DONE|QCOW_DONE)
+ # we are happy
+ pwarning "SIGINT/SIGTERM received, but everything seems fine. Check it!"
+ exit 0
+ ;;
+ BLACKLISTING)
+ # creation of blacklists failed
+ # TODO do what?
+ ;;
+ SYNCING)
+ # error during rsync, create the .stage4 file again
+ [ -z "${RSYNC_TARGET}" ] && \
+ perror "RSYNC_TARGET not set, this should not happen."
+ if [ ! -e "${RSYNC_TARGET}/.stage4" ]; then
+ pwarning "'.stage4' flag was lost during rsync, restoring it."
+ touch "${RSYNC_TARGET}/.stage4"
+ fi
+ ;;
+ QCOW_CREATING)
+ # qemu-img failed. Just remove the container if its there
+ if [ -n "${CONTAINER_PATH}" -a -e "${CONTAINER_PATH}" ]; then
+ rm -f "${CONTAINER_PATH}" || \
+ pwarning "Could not remove '${CONTAINER_PATH}'."
+ fi
+ ;;
+ QCOW_NBD_CONNECTING)
+ # qemu-nbd failed
+ if [ -n "${NBD_DEV}" ]; then
+ qemu-nbd -d "${NBD_DEV}" && \
+ pwarning "Could not disconnect '${NBD_DEV}'."
+ fi
+ ;;
+ QCOW_FSING)
+ # mkfs failed, disconnect and remove container
+ if [ -n "${NBD_DEV}" ]; then
+ qemu-nbd -d "${NBD_DEV}" && \
+ pwarning "Could not disconnect '${NBD_DEV}'."
+ fi
+ if [ -n "${CONTAINER_PATH}" -a -e "${CONTAINER_PATH}" ]; then
+ rm -f "${CONTAINER_PATH}" || \
+ pwarning "Could not remove '${CONTAINER_PATH}'."
+ fi
+ ;;
+ QCOW_MOUNTING)
+ # mounting failed:
+ # umount, disconnect and remove container and mount point
+ if [ -n "${NBD_MNT}" ]; then
+ umount "${NBD_MNT}" || pwarning "Could not umount '${NBD_MNT}'."
+ rmdir "${NBD_MNT}" || pwarning "Could not rmdir '${NBD_MNT}'."
+ fi
+ if [ -n "${NBD_DEV}" ]; then
+ qemu-nbd -d "${NBD_DEV}" && \
+ perror "Could not disconnect '${NBD_DEV}'."
+ fi
+ if [ -n "${CONTAINER_PATH}" -a -e "${CONTAINER_PATH}" ]; then
+ rm -f "${CONTAINER_PATH}" || \
+ perror "Could not remove '${CONTAINER_PATH}'."
+ fi
+ ;;
+ QCOW_COPYING)
+ # rare case, should not happen
+ ;;
+ QCOW_CLEANING)
+ # should also not happen
+ ;;
+ *)
+ pwarning "Unknown state: ${_STATE}"
+ esac
+ # still here? then we ran into some error
+ exit 1
+}
+
+
+
# helper to validate an ip
# Usage:
# valid_ip <ip>
@@ -163,6 +245,20 @@ valid_ip() {
return $stat
}
+# helper to check whether a given host is valid
+# Usage:
+# check_host <hostname|ip>
+# Returns 0 if valid, 1 otherwise
+check_host() {
+ local HOST="$1"
+ [ -z "$HOST" ] && return 1
+ # check if its a valid IP or a valid hostname
+ valid_ip "$HOST" && return 0
+ host -W 2 "$HOST" && return 0
+ # still here? then fail
+ return 1
+}
+
# helper to check if a dir is empty or not
# Usage:
# dir_empty <dir>
@@ -186,19 +282,6 @@ user_confirm() {
[ "x${_input}" == "x" -o "x${_input}" == "xy" ] && return 0 || return 1
}
-# helper to check whether a given host is valid
-# Usage:
-# check_host <hostname|ip>
-# Returns 0 if valid, 1 otherwise
-check_host() {
- local HOST="$1"
- [ -z "$HOST" ] && return 1
- # check if its a valid IP or a valid hostname
- valid_ip "$HOST" && return 0
- host -W 2 "$HOST" && return 0
- # still here? then fail
- return 1
-}
# ------------------------------------------------------------------------------
#
# Stage4 related functions
@@ -225,12 +308,25 @@ clone_stage4() {
# RSYNC_TARGET set?
if [ -z "$RSYNC_TARGET" ]; then
- pwarning "RSYNC_TARGET not set. Assuming local mode"
+ pwarning "RSYNC_TARGET not set. Assuming local mode."
pinfo "Using '${BUILD_DIR}/stage4'"
declare -rg RSYNC_TARGET="${BUILD_DIR}/stage4"
fi
- mkdir -p "${RSYNC_TARGET}"
+ # check if RSYNC_TARGET is valid
+ if [ -d "${RSYNC_TARGET}" ]; then
+ # does it have the '.stage4' flag?
+ [ ! -e "${RSYNC_TARGET}/.stage4" ] && \
+ perror "'${RSYNC_TARGET}' exists, but no '.stage4' flag found." \
+ "Refusing to rsync there."
+ else
+ # not a directory, create it and set the .stage4 flag
+ mkdir -p "${RSYNC_TARGET}"
+ touch "${RSYNC_TARGET}/.stage4"
+ fi
+
+ # mark state
+ _STATE='BLACKLISTING'
local EXCLUDE="$BUILD_DIR/exclude-stage4"
local INCLUDE="$BUILD_DIR/include-stage4"
@@ -253,6 +349,7 @@ clone_stage4() {
fi
local RSYNC_SOURCE="root@$REMOTE_HOST:/"
+ _STATE='SYNCING'
# run rsync with the exclude/include lists created earlier
cat "$INCLUDE" "$EXCLUDE" | \
rsync --verbose \
@@ -267,6 +364,8 @@ clone_stage4() {
|| perror "rsync from '${RSYNC_SOURCE}' to '${RSYNC_TARGET}' failed."
## TODO real exit code handling
pinfo "Cloning '${REMOTE_HOST}' to '${RSYNC_TARGET}' succeeded."
+ _STATE='SYNC_DONE'
+ touch "${RSYNC_TARGET}/.stage4"
return 0
}
# helper to build a qcow2 container from a stage4 sync directory
@@ -317,6 +416,11 @@ pack_qcow2() {
[ ! -d "$RSYNC_TARGET" ] && perror "'$RSYNC_TARGET' not a directory!"
is_dir_empty "$RSYNC_TARGET" && \
perror "'$RSYNC_TARGET' appears to be empty. Did you clone?"
+ # the ultimative check
+ if [ ! -e "${RSYNC_TARGET}/.stage4" ]; then
+ perror "No '.stage4' flag found in '${RSYNC_TARGET}'." \
+ "Was this cloned properly?"
+ fi
# which size for the qcow2 container?
if [ -z "$DEFAULT_QCOW_SIZE" ]; then
@@ -326,6 +430,7 @@ pack_qcow2() {
fi
# so far so good
pinfo "Creating empty qcow2-container ..."
+ _STATE='QCOW_CREATING'
qemu-img create -f qcow2 "${CONTAINER_PATH}" "${QCOW_SIZE}" \
|| perror "qemu-img create failed with: $?"
pinfo "Done."
@@ -336,6 +441,7 @@ pack_qcow2() {
[ -z "${NBD_DEV}" ] && perror "Could not find usable NBD device."
[ -b "${NBD_DEV}" ] || perror "'${NBD_DEV}' is not a block device!"
pinfo "Exporting '${CONTAINER_PATH}' using '${NBD_DEV}'..."
+ _STATE='QCOW_NBD_CONNECTING'
qemu-nbd -c "${NBD_DEV}" "${CONTAINER_PATH}" || \
perror "qemu-nbd failed with: $?"
pinfo "Done."
@@ -350,9 +456,11 @@ pack_qcow2() {
local QCOW_FS="$DEFAULT_QCOW_FS"
fi
pinfo "Creating '${QCOW_FS}' filesystem on '${CONTAINER_PATH}'..."
+ _STATE='QCOW_FSING'
mkfs."${QCOW_FS}" "${NBD_DEV}" || perror "mkfs failed with: $?"
pinfo "Done."
+
# prepare NBD mount directory and check state to be safe
local NBD_MNT="$(mktemp -d)"
[ ! -d "${NBD_MNT}" ] && \
@@ -361,18 +469,22 @@ pack_qcow2() {
perror "'${NBD_MNT}' not empty. Refusing to mount ${NBD_DEV} to it."
pinfo "Mounting '${NBD_DEV}' to '${NBD_MNT}'..."
+ _STATE='QCOW_MOUNTING'
mount "${NBD_DEV}" "${NBD_MNT}" || perror "Mount failed with: $?"
pinfo "Done."
# copy files from the stage4 directory to the mounted qcow2-container
pinfo "Copying '${RSYNC_TARGET}' to '${NBD_MNT}'..."
+ _STATE='QCOW_COPYING'
cp -ra "${RSYNC_TARGET}"/* "${NBD_MNT}" || perror "Copying failed with: $?"
pinfo "Done."
pinfo "Cleaning up..."
+ _STATE='QCOW_CLEANING'
umount "${NBD_MNT}" || pwarning "Could not unmount '${NBD_MNT}'."
rmdir "${NBD_MNT}" || pwarning "Could not remove '${NBD_MNT}'."
qemu-nbd -d "${NBD_DEV}" || pwarning "Could not disconnect '${NBD_DEV}'."
+ _STATE='QCOW_DONE'
pinfo "Exporting '${RSYNC_TARGET}' to '${CONTAINER_PATH}' completed."
}