summaryrefslogtreecommitdiffstats
path: root/packager
diff options
context:
space:
mode:
authorJonathan Bauer2016-04-18 15:41:44 +0200
committerJonathan Bauer2016-04-18 15:41:44 +0200
commita7abc3d120af436d3667f0cb819b24d4704fa831 (patch)
treec30263e0d2c4c91bfe35f40881d251a5675209bc /packager
parentupdate rebash (diff)
downloadsystemd-init-a7abc3d120af436d3667f0cb819b24d4704fa831.tar.gz
systemd-init-a7abc3d120af436d3667f0cb819b24d4704fa831.tar.xz
systemd-init-a7abc3d120af436d3667f0cb819b24d4704fa831.zip
reworked cleanup & stuff
Diffstat (limited to 'packager')
-rwxr-xr-xpackager/openslx3
-rw-r--r--packager/openslx.config4
-rw-r--r--packager/openslx.functions272
3 files changed, 133 insertions, 146 deletions
diff --git a/packager/openslx b/packager/openslx
index 69102564..6845f9ba 100755
--- a/packager/openslx
+++ b/packager/openslx
@@ -32,7 +32,7 @@ else
fi
# setup trap
-trap cleanexit SIGINT SIGTERM
+trap do_cleanup SIGINT SIGTERM SIGUSR1 EXIT
# read params
read_params $@
@@ -40,3 +40,4 @@ read_params $@
# react to given action
process_action
+exit 0
diff --git a/packager/openslx.config b/packager/openslx.config
index a02a608b..9c94226d 100644
--- a/packager/openslx.config
+++ b/packager/openslx.config
@@ -2,7 +2,7 @@
DEFAULT_RSYNC_OPTS="-e ssh -c arcfour -oStrictHostKeyChecking=no"
# default size for the qcow2-container (the one containing diffs)
-DEFAULT_QCOW_SIZE="25G"
+DEFAULT_CONTAINER_SIZE="25G"
# default filesystem type for the qcow2-container
-DEFAULT_QCOW_FS="ext4"
+DEFAULT_CONTAINER_FILESYSTEM="xfs"
diff --git a/packager/openslx.functions b/packager/openslx.functions
index e38f88c5..78208cd4 100644
--- a/packager/openslx.functions
+++ b/packager/openslx.functions
@@ -180,6 +180,7 @@ read_params() {
declare -rg CONTAINER_MNT="$(mktemp -d)"
[ -z "${CONTAINER_MNT}" ] && \
perror "Could not create temporary directory for mounting the container."
+ add_cleanup rmdir "${CONTAINER_MNT}"
# RSYNC_TARGET depends on the action at this point
if [ "x$ACTION" == "xPACKAGE" ]; then
# use default path when packaging
@@ -214,6 +215,32 @@ process_action() {
fi
return 0
}
+
+# wrapper to package a cloned stage4 as a qcow2 container
+# - creates empty container at CONTAINER_PATH
+# - mounts it to RSYNC_TARGET
+# - copy RSYNC_TARGET
+pack_clone() {
+ create_container
+ mount_container
+ copy_to_container
+}
+# wrapper to update an existing container
+# - mounts it to RSYNC_TARGET
+# - clone host there
+update_container() {
+ mount_container
+ clone_host
+}
+# wrapper to export a host directly to a container
+# - create en empty qcow2 container at CONTAINER_PATH
+# - mount it to RSYNC_TARGET
+# - clone host there
+export_host() {
+ create_container
+ mount_container
+ clone_host
+}
# ------------------------------------------------------------------------------
#
# Stage4 related functions
@@ -228,10 +255,10 @@ process_action() {
clone_host() {
# 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."
+ # does it have the '.stage4' flag? skip this check when exporting directly
+ [ "x$ACTION" != "xEXPORT" ] && [ ! -e "${RSYNC_TARGET}/.stage4" ] && \
+ perror "'${RSYNC_TARGET}' exists, but no '.stage4' flag found. Refusing to rsync there."
+ #touch $RSYNC_TARGET/.stage4 && exit 0
else
# not a directory, create it and set the .stage4 flag
mkdir -p "${RSYNC_TARGET}" || perror "Could not create '${RSYNC_TARGET}'."
@@ -251,14 +278,12 @@ clone_host() {
done
# prepare rsync's options
- if [ -z "$DEFAULT_RSYNC_OPTS" ]; then
- local RSYNC_OPTS="-e ssh -c arcfour -oStrictHostKeyChecking=no"
- else
- local RSYNC_OPTS="$DEFAULT_RSYNC_OPTS"
- fi
+ local RSYNC_OPTS="$DEFAULT_RSYNC_OPTS"
+ [ -z "$RSYNC_OPTS" ] && RSYNC_OPTS="-e ssh -c arcfour -oStrictHostKeyChecking=no"
local RSYNC_SOURCE="root@$REMOTE_HOST:/"
- _STATE='SYNCING'
+ # if something goes wrong during rsync, we need to recreate the .stage4 flag
+ add_cleanup touch ${RSYNC_TARGET}/.stage4
# run rsync with the exclude/include lists created earlier
cat "$INCLUDE" "$EXCLUDE" | \
rsync --verbose \
@@ -272,53 +297,52 @@ clone_host() {
--exclude-from=- \
"${RSYNC_OPTS}" \
"${RSYNC_SOURCE}" \
- "${RSYNC_TARGET}" \
- || perror "rsync from '${RSYNC_SOURCE}' to '${RSYNC_TARGET}' failed."
- ## TODO real exit code handling
- pinfo "Cloning '${REMOTE_HOST}' to '${RSYNC_TARGET}' succeeded."
+ "${RSYNC_TARGET}"
+
+ local -i rsync_ret=$?
+ if [ "x$rsync_ret" != "x0" ]; then
+ perror "rsync from '${RSYNC_SOURCE}' to '${RSYNC_TARGET}' failed."
+ fi
touch "${RSYNC_TARGET}/.stage4"
- _STATE='SYNCED'
- return 0
+ # make sure everything gets flushed
+ sync
+ pinfo "Cloning '${REMOTE_HOST}' to '${RSYNC_TARGET}' succeeded."
}
# Helper to create the empty container at CONTAINER_PATH
create_container() {
# CONTAINER_PATH valid?
- [ -d "$CONTAINER_PATH" ] && perror "Path to container can not be a directory!"
- if [ -f "$CONTAINER_PATH" ]; then
+ [ -d "${CONTAINER_PATH}" ] && perror "Path to container can not be a directory!"
+ if [ -f "${CONTAINER_PATH}" ]; then
if [ $FORCE -eq 0 ]; then
perror "Container file already exists. Use '--force' to overwrite it."
else
# force removal
- rm -f "$CONTAINER_PATH" || perror "Could not remove '$CONTAINER_PATH'"
- pinfo "Removed old '$CONTAINER_PATH'."
+ rm -f "${CONTAINER_PATH}" || perror "Could not remove '${CONTAINER_PATH}'"
+ pinfo "Removed old '${CONTAINER_PATH}'."
fi
fi
# which size for the qcow2 container?
- if [ -z "$DEFAULT_QCOW_SIZE" ]; then
- local QCOW_SIZE="25G"
- else
- local QCOW_SIZE="$DEFAULT_QCOW_SIZE"
- fi
+ local CONTAINER_SIZE="${DEFAULT_CONTAINER_SIZE}"
+ [ -z "${CONTAINER_SIZE}" ] && CONTAINER_SIZE="25G"
+
# so far so good
pinfo "Creating qcow2-container '${CONTAINER_PATH}'"
- qemu-img create -f qcow2 "${CONTAINER_PATH}" "${QCOW_SIZE}" || \
+ qemu-img create -f qcow2 "${CONTAINER_PATH}" "${CONTAINER_SIZE}" || \
perror "qemu-img create failed with: $?"
# now expose it as a loop device
- expose_container
- _STATE='QCOW_EXPOSED'
+ expose_container
# filesystem for the qcow2 container?
- if [ -z "$DEFAULT_QCOW_FS" ]; then
- local QCOW_FS="ext4"
- else
- # check if we have mkfs helper
- which "mkfs.$DEFAULT_QCOW_FS" &>/dev/null || \
- perror "Could not find 'mkfs.$DEFAULT_QCOW_FS'. Install it and retry."
- local QCOW_FS="$DEFAULT_QCOW_FS"
- fi
- pinfo "Creating '${QCOW_FS}' filesystem on '${CONTAINER_PATH}'..."
- mkfs."${QCOW_FS}" "${LOOPED_NBD_DEV}" || perror "mkfs failed with: $?"
+ local CONTAINER_FILESYSTEM="${DEFAULT_CONTAINER_FILESYSTEM}"
+ [ -z "${CONTAINER_FILESYSTEM}" ] && CONTAINER_FILESYSTEM="xfs"
+ # check if we have that mkfs helper
+ which "mkfs.${CONTAINER_FILESYSTEM}" || \
+ perror "Could not find 'mkfs.${CONTAINER_FILESYSTEM}'. Install it and retry."
+
+ pinfo "Creating '${CONTAINER_FILESYSTEM}' filesystem on '${CONTAINER_PATH}'..."
+ mkfs."${CONTAINER_FILESYSTEM}" "${LOOPED_NBD_DEV}" || perror "mkfs failed with: $?"
+ return 0
}
# Helper exposing the container as a loop device
@@ -334,11 +358,13 @@ expose_container() {
qemu-nbd -c "${NBD_DEV}" "${CONTAINER_PATH}" || \
perror "qemu-nbd failed with: $?"
- _STATE='QCOW_EXPOSED_NBD'
+ add_cleanup disconnect_nbd
# expose as a loop device
declare -rg LOOPED_NBD_DEV="$(losetup --find)"
losetup "${LOOPED_NBD_DEV}" "${NBD_DEV}" || \
perror "Loop device setup for '${NBD_DEV}' failed with: $?"
+ add_cleanup disconnect_loop
+ return 0
}
# Helper to mount CONTAINER_PATH to CONTAINER_MNT through expose_container
@@ -351,11 +377,13 @@ mount_container() {
# lets be safe...
[ -z "${LOOPED_NBD_DEV}" ] && \
perror "Internal error - LOOPED_NBD_DEV not set but should be! Check expose_container()"
-
+
# now we got everything, mount it
pinfo "Mounting '${LOOPED_NBD_DEV}' to '${CONTAINER_MNT}'..."
- mount "${LOOPED_NBD_DEV}" "${CONTAINER_MNT}" || perror "Mount failed with: $?"
- _STATE='QCOW_MOUNTED'
+ mount "${LOOPED_NBD_DEV}" "${CONTAINER_MNT}" \
+ || perror "Mount failed with: $?"
+ add_cleanup umount_container
+ return 0
}
# helper to copy the content of RSYNC_TARGET to CONTAINER_MNT
@@ -374,110 +402,18 @@ copy_to_container() {
fi
# copy files from the stage4 directory to the mounted qcow2-container
pinfo "Copying '${RSYNC_TARGET}' to '${CONTAINER_MNT}'..."
- rsync -avAHX "${RSYNC_TARGET}"/ "${CONTAINER_MNT}"/ || perror "Rsync failed with: $?"
-}
-
-# wrapper to package a cloned stage4 as a qcow2 container
-# - creates empty container at CONTAINER_PATH
-# - mounts it to RSYNC_TARGET
-# - copy RSYNC_TARGET
-pack_clone() {
- create_container
- mount_container
- copy_to_container
- umount_container
-}
-# wrapper to update an existing container
-# - mounts it to RSYNC_TARGET
-# - clone host there
-update_container() {
- mount_container
- clone_host
- umount_container
-}
-# wrapper to export a host directly to a container
-# - create en empty qcow2 container at CONTAINER_PATH
-# - mount it to RSYNC_TARGET
-# - clone host there
-export_host() {
- create_container
- mount_container
- clone_host
- umount_container
-}
-
-# 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 ..."
-
- case "${_STATE}" in
- 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
- break;
- ;;
- QCOW_MOUNTED)
- # container mounted
- [ -z "${CONTAINER_PATH}" ] && \
- perror "CONTAINER_PATH not set - should not be!"
- [ -z "${CONTAINER_MNT}" ] && \
- perror "CONTAINER_MNT not set - should not be!"
- umount_container || \
- perror "Could not umount '${CONTAINER_MNT}'."
- ;;
- QCOW_MOUNTED|QCOW_EXPOSED)
- disconnect_container
- break
- ;;
- # internal expose_container state
- QCOW_EXPOSED_NBD)
- disconnect_nbd
- break
- ;;
- *)
- [ -n "${_STATE}" ] && pwarning "Unknown state: ${_STATE}"
- ;;
- esac
- # still here? then we ran into some error
- exit 1
-}
-# Helper to umount + disconnect the container from all the devices
-umount_container() {
- [ -z "${CONTAINER_MNT}" ] && \
- perror "CONTAINER_MNT not set - is it really mounted?"
- umount "${CONTAINER_MNT}" || \
- perror "Failed to umount '${CONTAINER_MNT}'."
- rmdir "${CONTAINER_MNT}" || \
- pwarning "Could not remove '${CONTAINER_MNT}'."
+ rsync -avAHX "${RSYNC_TARGET}"/ "${CONTAINER_MNT}"/ \
+ || perror "Rsync failed with: $?"
+ #make sure everything is flushed
+ sync && return 0
}
-# Wrapper to disconnect the container from all the devices
-disconnect_container() {
- disconnect_loop
- disconnect_nbd
-}
-# Helper to disconnect from loop device
-disconnect_loop() {
- [ -z "${LOOPED_NBD_DEV}" ] && \
- perror "Container not connected to a loop device?"
- losetup -d "${LOOPED_NBD_DEV}" ||\
- perror "Could not disconnect loop device '${LOOPED_NBD_DEV}'."
-}
-# Helper to disconnect from nbd device
-disconnect_nbd() {
- [ -z "${NBD_DEV}" ] && \
- perror "Container does not seem to be connected to a NBD device?"
- qemu-nbd -d "${NBD_DEV}" || \
- perror "Could not disconnect '${CONTAINER_PATH}' from '${NBD_DEV}'."
-}
+###############################################################################
+#
+#
+#
+###############################################################################
# helper to find an unused nbd device
# Usage:
# find_free_nbd
@@ -550,4 +486,54 @@ user_confirm() {
[ "x${_input}" == "x" -o "x${_input}" == "xy" ] && return 0 || return 1
}
+###############################################################################
+#
+# CLEANUP FUNCTIONS
+#
+###############################################################################
+# indexed array for cleanup commands
+declare -ag cleanup_commands
+
+# function to add a cleanup command to be executed when the program exits
+add_cleanup() {
+ # get current command count
+ local -i count="${#cleanup_commands[*]}"
+ cleanup_commands[$count]="$*"
+}
+
+# function trapped to EXIT, SIGINT, SIGTERM
+# do the cleanup in FILO style
+do_cleanup() {
+ trap '' SIGINT SIGTERM EXIT # from now on, ignore INT and TERM
+ for i in $(seq $(( ${#cleanup_commands[*]} - 1 )) -1 0); do
+ pinfo "Running: ${cleanup_commands[$i]}"
+ eval ${cleanup_commands[$i]}
+ done
+}
+
+# Helper to umount + disconnect the container from all the devices
+umount_container() {
+ [ -z "${CONTAINER_MNT}" ] && \
+ perror "CONTAINER_MNT not set - is it really mounted?"
+ # sync?
+ umount -l "${CONTAINER_MNT}" || \
+ perror "Failed to umount '${CONTAINER_MNT}'."
+# rmdir "${CONTAINER_MNT}" || \
+# pwarning "Could not remove '${CONTAINER_MNT}'."
+}
+
+# Helper to disconnect from loop device
+disconnect_loop() {
+ [ -z "${LOOPED_NBD_DEV}" ] && \
+ perror "Container not connected to a loop device?"
+ losetup -d "${LOOPED_NBD_DEV}" ||\
+ perror "Could not disconnect loop device '${LOOPED_NBD_DEV}'."
+}
+# Helper to disconnect from nbd device
+disconnect_nbd() {
+ [ -z "${NBD_DEV}" ] && \
+ perror "Container does not seem to be connected to a NBD device?"
+ qemu-nbd -d "${NBD_DEV}" || \
+ perror "Could not disconnect '${CONTAINER_PATH}' from '${NBD_DEV}'."
+}