--- /dev/null
+#!/bin/sh
+
+
+USAGE="Usage: $(basename $0) <container operating system>"
+
+if [ $# -ne 1 ]
+then
+ echo "$USAGE" >&2
+ exit 1
+fi
+
+if [ ! -f /etc/lxc/lxc.conf ]
+then
+ echo "No lxc system configuration found" >&2
+ exit 1
+fi
+
+backup_old_container()
+{
+ if [ -z "$OLD_CONTAINER_NAME" ]
+ then
+ return 0
+ fi
+
+ if [ -d $OLD_CONTAINER_BACKUP_PATH ]
+ then
+ rm -Rf ${OLD_CONTAINER_BACKUP_PATH}.old
+ mv $OLD_CONTAINER_BACKUP_PATH ${OLD_CONTAINER_BACKUP_PATH}.old
+ fi
+
+ OLD_CONTAINER_STATE=$(lxc-info --name=$OLD_CONTAINER_NAME --state 2>/dev/null \
+ | cut -f 2 -d ':' | tr -d ' ')
+ case "$OLD_CONTAINER_STATE" in
+ "RUNNING")
+ echo "Stopping (the old) container $OLD_CONTAINER_NAME"
+ lxc-stop --name=$OLD_CONTAINER_NAME
+ echo "Stopped (the old) container $OLD_CONTAINER_NAME"
+ ;;
+ "STOPPED")
+ ;;
+ *)
+ echo "Unknown container state: $OLD_CONTAINER_STATE" >&2
+ exit 1
+ ;;
+ esac
+
+ mv $OLD_CONTAINER_PATH $OLD_CONTAINER_BACKUP_PATH
+}
+
+install_packages()
+{
+ case "$DISTRIBUTION" in
+ "CentOS")
+ YUM_CONFIG=$SCRIPT_PATH/yum.conf.centos
+ YUM_RELEASEVER=$DISTRIBUTION_VERSION
+ if [ -n "$ROOT_PACKAGES" ]
+ then
+ yum --assumeyes \
+ --config=$YUM_CONFIG \
+ --disablerepo=* \
+ --enablerepo=local-* \
+ --installroot=$CONTAINER_BUILDROOT \
+ --releasever=$YUM_RELEASEVER \
+ install $ROOT_PACKAGES
+ fi
+ if [ -n "$BASE_PACKAGES" ]
+ then
+ yum --assumeyes \
+ --config=$YUM_CONFIG \
+ --disablerepo=* \
+ --enablerepo=local-* \
+ --installroot=$CONTAINER_BUILDROOT \
+ --releasever=$YUM_RELEASEVER \
+ install $BASE_PACKAGES
+ fi
+ yum --assumeyes \
+ --config=$YUM_CONFIG \
+ --disablerepo=* \
+ --enablerepo=local-* \
+ --installroot=$CONTAINER_BUILDROOT \
+ --releasever=$YUM_RELEASEVER \
+ clean all
+ ;;
+ "Fedora")
+ DNF_CONFIG=$SCRIPT_PATH/dnf.conf.fedora
+ DNF_RELEASEVER=$DISTRIBUTION_VERSION
+ if [ -n "$ROOT_PACKAGES" ]
+ then
+ dnf --assumeyes \
+ --config=$DNF_CONFIG \
+ --disablerepo=* \
+ --enablerepo=local-* \
+ --installroot=$CONTAINER_BUILDROOT \
+ --releasever=$DNF_RELEASEVER \
+ install $ROOT_PACKAGES
+ fi
+ if [ -n "$BASE_PACKAGES" ]
+ then
+ dnf --assumeyes \
+ --config=$DNF_CONFIG \
+ --disablerepo=* \
+ --enablerepo=local-* \
+ --installroot=$CONTAINER_BUILDROOT \
+ --releasever=$DNF_RELEASEVER \
+ install $BASE_PACKAGES
+ fi
+ dnf --assumeyes \
+ --config=$DNF_CONFIG \
+ --disablerepo=* \
+ --enablerepo=local-* \
+ --installroot=$CONTAINER_BUILDROOT \
+ --releasever=$DNF_RELEASEVER \
+ clean all
+ ;;
+ "Rocky")
+ YUM_CONFIG=$SCRIPT_PATH/yum.conf.rocky
+ YUM_RELEASEVER=$DISTRIBUTION_VERSION
+ if [ -n "$ROOT_PACKAGES" ]
+ then
+ yum --assumeyes \
+ --config=$YUM_CONFIG \
+ --disablerepo=* \
+ --enablerepo=local-* \
+ --installroot=$CONTAINER_BUILDROOT \
+ --releasever=$YUM_RELEASEVER \
+ install $ROOT_PACKAGES
+ fi
+ if [ -n "$BASE_PACKAGES" ]
+ then
+ yum --assumeyes \
+ --config=$YUM_CONFIG \
+ --disablerepo=* \
+ --enablerepo=local-* \
+ --installroot=$CONTAINER_BUILDROOT \
+ --releasever=$YUM_RELEASEVER \
+ install $BASE_PACKAGES
+ fi
+ yum --assumeyes \
+ --config=$YUM_CONFIG \
+ --disablerepo=* \
+ --enablerepo=local-* \
+ --installroot=$CONTAINER_BUILDROOT \
+ --releasever=$YUM_RELEASEVER \
+ clean all
+ ;;
+ esac
+}
+
+create_build_path()
+{
+ echo "Creating and populating the container build directory."
+
+ mkdir --parents $CONTAINER_BUILDROOT
+
+ sed --expression="s|__CONTAINER_PATH__|$CONTAINER_PATH|" \
+ <$CONTAINER_SOURCE_PATH/config \
+ >$CONTAINER_BUILD_PATH/config
+ if [ -d $CONTAINER_SOURCE_PATH/hooks ]
+ then
+ cp --archive $CONTAINER_SOURCE_PATH/hooks $CONTAINER_BUILD_PATH
+ fi
+
+ echo "Created and populated the container build directory."
+}
+
+create_environment_file()
+{
+ ENV_FILE=$(mktemp)
+
+
+ echo "Creating environment file."
+
+ echo "SCRIPT_PATH=$SCRIPT_PATH" >>$ENV_FILE
+ echo "BASE_PATH=$BASE_PATH" >>$ENV_FILE
+ echo "BACKUPS_PATH=$BACKUPS_PATH" >>$ENV_FILE
+ echo "BUILD_PATH=$BUILD_PATH" >>$ENV_FILE
+ echo "FILESYSTEMS_PATH=$FILESYSTEMS_PATH" >>$ENV_FILE
+ echo "SOURCES_PATH=$SOURCES_PATH" >>$ENV_FILE
+ echo "SSH_KEYS_PATH=$SSH_KEYS_PATH" >>$ENV_FILE
+ echo >>$ENV_FILE
+ echo "CONTAINER_BASENAME=$CONTAINER_BASENAME" >>$ENV_FILE
+ echo "CONTAINER_NAME=$CONTAINER_NAME" >>$ENV_FILE
+ echo "CONTAINER_OS=$CONTAINER_OS" >>$ENV_FILE
+ echo "CONTAINER_PATH=$CONTAINER_PATH" >>$ENV_FILE
+ echo "CONTAINER_BUILD_PATH=$CONTAINER_BUILD_PATH" >>$ENV_FILE
+ echo "CONTAINER_FILESYSTEMS_PATH=$CONTAINER_FILESYSTEMS_PATH" >>$ENV_FILE
+ echo "CONTAINER_SOURCE_PATH=$CONTAINER_SOURCE_PATH" >>$ENV_FILE
+ echo "CONTAINER_BUILDROOT=$CONTAINER_BUILDROOT" >>$ENV_FILE
+ echo >>$ENV_FILE
+ echo "OLD_CONTAINER_NAME=$OLD_CONTAINER_NAME" >>$ENV_FILE
+ echo "OLD_CONTAINER_PATH=$OLD_CONTAINER_PATH" >>$ENV_FILE
+ echo "OLD_CONTAINER_BACKUP_PATH=$OLD_CONTAINER_BACKUP_PATH" >>$ENV_FILE
+
+ echo "Environment file created."
+}
+
+set_variables()
+{
+ CONTAINER_OS_PARAMETER=$1
+
+
+ echo "Setting variables."
+
+ CONTAINER_BASENAME="base"
+ CONTAINER_NAME_PARAMETER="${CONTAINER_BASENAME}.$CONTAINER_OS_PARAMETER"
+
+ LXC_PATH=$(grep '^lxc.lxcpath' /etc/lxc/lxc.conf \
+ | cut -f 2 -d '=' | tr -d ' ')
+
+ SCRIPT_PATH=$(dirname $(realpath $0))
+ BASE_PATH=$(dirname $SCRIPT_PATH)
+ BACKUPS_PATH=$BASE_PATH/backups
+ BUILD_PATH=$BASE_PATH/build
+ FILESYSTEMS_PATH=$BASE_PATH/filesystems
+ SOURCES_PATH=$BASE_PATH/sources
+ SSH_KEYS_PATH=$BASE_PATH/user-ssh
+
+ CONTAINER_SOURCE_PATH=$SOURCES_PATH/$CONTAINER_NAME_PARAMETER
+
+ if [ ! -d $CONTAINER_SOURCE_PATH ]
+ then
+ echo "No source found for $CONTAINER_NAME_PARAMETER" >&2
+ return 1
+ fi
+
+ if [ ! -f $CONTAINER_SOURCE_PATH/config ]
+ then
+ echo "No config file found for $CONTAINER_NAME_PARAMETER" >&2
+ return 2
+ fi
+
+ if [ ! -f $CONTAINER_SOURCE_PATH/envvars ]
+ then
+ echo "No envvars file found for $CONTAINER_NAME_PARAMETER" >&2
+ return 3
+ fi
+
+ source $CONTAINER_SOURCE_PATH/envvars
+ RC=$?
+ if [ $RC -ne 0 ]
+ then
+ echo "Could not source $CONTAINER_SOURCE_PATH/envvars, rc: $RC" >&2
+ return 4
+ fi
+
+ if [ -z "$DISTRIBUTION" ]
+ then
+ echo "No DISTRIBUTION variable set in envvars file" >&2
+ return 5
+ fi
+ if [ -z "$DISTRIBUTION_VERSION" ]
+ then
+ echo "No DISTRIBUTION_VERSION variable set in envvars file" >&2
+ return 6
+ fi
+
+ case "$DISTRIBUTION" in
+ "CentOS")
+ YUM_RELEASEVER=$DISTRIBUTION_VERSION
+ ;;
+ "Fedora")
+ DNF_RELEASEVER=$DISTRIBUTION_VERSION
+ ;;
+ "Rocky")
+ YUM_RELEASEVER=$DISTRIBUTION_VERSION
+ ;;
+ *)
+ echo "Unknown distribution: $DISTRIBUTION" >&2
+ return 7
+ ;;
+ esac
+
+ DISTRIBUTION_FIRST_CHAR=$(echo "$DISTRIBUTION" | cut -c 1 | tr '[A-Z]' '[a-z]')
+ CONTAINER_OS="${DISTRIBUTION_FIRST_CHAR}$DISTRIBUTION_VERSION"
+
+ if [ "$CONTAINER_OS_PARAMETER" != "$CONTAINER_OS" ]
+ then
+ echo "Container operating system mismatch." >&2
+ return 8
+ fi
+
+ CONTAINER_NAME="${CONTAINER_BASENAME}.$CONTAINER_OS"
+
+ CONTAINER_PATH=$LXC_PATH/$CONTAINER_NAME
+ CONTAINER_BUILD_PATH=$BUILD_PATH/$CONTAINER_NAME
+
+ if [ -d $CONTAINER_BUILD_PATH ]
+ then
+ echo "The build directory already exists." >&2
+ return 9
+ fi
+
+ CONTAINER_BUILDROOT=$CONTAINER_BUILD_PATH/rootfs
+
+ OLD_CONTAINER_NAME=$(lxc-ls -1 | grep "^${CONTAINER_NAME}$")
+ OLD_CONTAINER_PATH=$LXC_PATH/$OLD_CONTAINER_NAME
+ OLD_CONTAINER_BACKUP_PATH=$BACKUPS_PATH/$OLD_CONTAINER_NAME
+
+ echo "All variables set."
+}
+
+preinstall()
+{
+ if [ -d $CONTAINER_SOURCE_PATH/preinstall ]
+ then
+ cp --archive $CONTAINER_SOURCE_PATH/preinstall $CONTAINER_BUILDROOT
+ chmod 755 $CONTAINER_BUILDROOT/preinstall/*.sh
+ for SCRIPT in $CONTAINER_BUILDROOT/preinstall/*.sh
+ do
+ echo $SCRIPT $ENV_FILE
+ $SCRIPT $ENV_FILE
+ done
+ fi
+
+ mkdir $CONTAINER_BUILDROOT/dev
+ mkdir $CONTAINER_BUILDROOT/proc
+ mount -o bind /dev $CONTAINER_BUILDROOT/dev
+ mount -t proc proc $CONTAINER_BUILDROOT/proc
+}
+
+postinstall()
+{
+ if [ -d $CONTAINER_SOURCE_PATH/postinstall ]
+ then
+ cp --archive $CONTAINER_SOURCE_PATH/postinstall $CONTAINER_BUILDROOT
+ if [ -f $CONTAINER_SOURCE_PATH/postinstall/copy.list ]
+ then
+ grep -v '^#' $CONTAINER_SOURCE_PATH/postinstall/copy.list | while read LINE
+ do
+ SRC_HOST=$(echo "$LINE" | cut -f 1 -d ' ')
+ SRC_PATH=$(echo "$LINE" | cut -f 2 -d ' ')
+ TGT_PATH=$(echo "$LINE" | cut -f 3 -d ' ')
+ scp -pr -i $SSH_KEYS_PATH/scripts \
+ root@${SRC_HOST}:$SRC_PATH \
+ $CONTAINER_BUILDROOT/postinstall/install/$TGT_PATH
+ done
+ fi
+ fi
+ if [ -d $CONTAINER_BUILDROOT/postinstall ]
+ then
+ chmod 755 $CONTAINER_BUILDROOT/postinstall/*.sh
+ for SCRIPT in $CONTAINER_BUILDROOT/postinstall/*.sh
+ do
+ POSTINSTALL_SCRIPT=$(echo $SCRIPT | sed "s|^$CONTAINER_BUILDROOT||")
+ echo chroot $CONTAINER_BUILDROOT $POSTINSTALL_SCRIPT
+ chroot $CONTAINER_BUILDROOT $POSTINSTALL_SCRIPT
+ done
+ fi
+
+ umount $CONTAINER_BUILDROOT/dev
+ umount $CONTAINER_BUILDROOT/proc
+}
+
+firstboot()
+{
+ if [ -d $CONTAINER_SOURCE_PATH/firstboot ]
+ then
+ cp --archive $CONTAINER_SOURCE_PATH/firstboot $CONTAINER_BUILDROOT
+ chmod 755 $CONTAINER_BUILDROOT/firstboot/*.sh
+ for SCRIPT in $CONTAINER_BUILDROOT/firstboot/*.sh
+ do
+ FIRSTBOOT_SCRIPT=$(echo $SCRIPT | sed "s|^$CONTAINER_BUILDROOT||")
+ echo lxc-attach --name=$CONTAINER_NAME -- $FIRSTBOOT_SCRIPT
+ lxc-attach --name=$CONTAINER_NAME -- $FIRSTBOOT_SCRIPT
+ done
+ fi
+}
+
+set_variables $1
+RC=$?
+if [ $RC -ne 0 ]
+then
+ echo "Could not set variables, rc: $RC" >&2
+ exit $RC
+fi
+
+echo "Starting at $(date)"
+
+create_environment_file
+
+create_build_path
+
+preinstall
+
+install_packages
+
+postinstall
+
+backup_old_container
+
+################################################################
+# move the new container to its place #
+################################################################
+mv $CONTAINER_BUILD_PATH $CONTAINER_PATH
+
+################################################################
+# remove the environment file #
+################################################################
+rm -f $ENV_FILE
+
+echo "Finishing at $(date)"
exit 1
fi
-if [ -f /etc/lxc/lxc.conf ]
+if [ ! -f /etc/lxc/lxc.conf ]
then
- LXC_PATH=$(grep '^lxc.lxcpath' /etc/lxc/lxc.conf \
- | cut -f 2 -d '=' | tr -d ' ')
-else
echo "No lxc system configuration found" >&2
exit 1
fi
-SCRIPT_PATH=$(dirname $(realpath $0))
-BASE_PATH=$(dirname $SCRIPT_PATH)
-BACKUPS_PATH=$BASE_PATH/backups
-BUILD_PATH=$BASE_PATH/build
-FILESYSTEMS_PATH=$BASE_PATH/filesystems
-SOURCES_PATH=$BASE_PATH/sources
-SSH_KEYS_PATH=$BASE_PATH/user-ssh
-
-source $SCRIPT_PATH/functions
-RC=$?
-if [ $RC -ne 0 ]
-then
- echo "Could not source functions: $RC" >&2
- exit $RC
-fi
-
-CONTAINER_BASENAME=$(basename $1)
-CONTAINER_FILESYSTEMS_PATH=$FILESYSTEMS_PATH/$CONTAINER_BASENAME
-CONTAINER_SOURCE_PATH=$SOURCES_PATH/$CONTAINER_BASENAME
-
-################################################################
-# exit if no source exists for the container #
-################################################################
-if [ ! -d $CONTAINER_SOURCE_PATH ]
-then
- echo "No source found for $CONTAINER_BASENAME" >&2
- exit 1
-fi
-source $CONTAINER_SOURCE_PATH/envvars
-
-case "$DISTRIBUTION" in
- "CentOS")
- YUM_RELEASEVER=$DISTRIBUTION_VERSION
- ;;
- "Fedora")
- DNF_RELEASEVER=$DISTRIBUTION_VERSION
- ;;
- *)
- echo "Unknown distribution: $DISTRIBUTION" >&2
- exit 1
- ;;
-esac
-DISTRIBUTION_FIRST_CHAR=$(echo "$DISTRIBUTION" | cut -c 1 | tr '[A-Z]' '[a-z]')
-CONTAINER_OS="${DISTRIBUTION_FIRST_CHAR}$DISTRIBUTION_VERSION"
-PREV_DISTRIBUTION_VERSION=$(( $DISTRIBUTION_VERSION - 1 ))
-PREV_CONTAINER_OS="${DISTRIBUTION_FIRST_CHAR}$PREV_DISTRIBUTION_VERSION"
-
-CONTAINER_NAME="${CONTAINER_BASENAME}.$CONTAINER_OS"
-
-CONTAINER_PATH=$LXC_PATH/$CONTAINER_NAME
-CONTAINER_BUILD_PATH=$BUILD_PATH/$CONTAINER_NAME
-
-CONTAINER_START_ORDER=$(grep -w $CONTAINER_BASENAME $SOURCES_PATH/start-order.txt \
- | awk '{print $2}')
-
-################################################################
-# exit if the container does not have a start order #
-################################################################
-if [ -z "$CONTAINER_START_ORDER" ]
-then
- echo "The container does not have a start order." >&2
- exit 1
-fi
-
-################################################################
-# exit if the container build directory already exists #
-################################################################
-if [ -d $CONTAINER_BUILD_PATH ]
-then
- echo "The build directory already exists." >&2
- exit 1
-fi
-
-echo "Starting at $(date)"
-
-################################################################
-# find the old container if it exists #
-################################################################
-lxc-ls -1 | grep "^${CONTAINER_NAME}$" >/dev/null 2>&1
-if [ $? -eq 0 ]
-then
- OLD_CONTAINER_NAME=$CONTAINER_NAME
-else
- PREV_CONTAINER_NAME="${CONTAINER_BASENAME}.$PREV_CONTAINER_OS"
- lxc-ls -1 | grep "^${PREV_CONTAINER_NAME}$" >/dev/null 2>&1
- if [ $? -eq 0 ]
+backup_old_container()
+{
+ if [ -z "$OLD_CONTAINER_NAME" ]
then
- OLD_CONTAINER_NAME=$PREV_CONTAINER_NAME
+ return 0
fi
-fi
-OLD_CONTAINER_PATH=$LXC_PATH/$OLD_CONTAINER_NAME
-OLD_CONTAINER_BACKUP_PATH=$BACKUPS_PATH/$OLD_CONTAINER_NAME
-
-################################################################
-# create the environment file #
-################################################################
-ENV_FILE=$(mktemp)
-
-echo "SCRIPT_PATH=$SCRIPT_PATH" >>$ENV_FILE
-echo "BASE_PATH=$BASE_PATH" >>$ENV_FILE
-echo "BACKUPS_PATH=$BACKUPS_PATH" >>$ENV_FILE
-echo "BUILD_PATH=$BUILD_PATH" >>$ENV_FILE
-echo "FILESYSTEMS_PATH=$FILESYSTEMS_PATH" >>$ENV_FILE
-echo "SOURCES_PATH=$SOURCES_PATH" >>$ENV_FILE
-echo "SSH_KEYS_PATH=$SSH_KEYS_PATH" >>$ENV_FILE
-echo >>$ENV_FILE
-echo "CONTAINER_BASENAME=$CONTAINER_BASENAME" >>$ENV_FILE
-echo "CONTAINER_NAME=$CONTAINER_NAME" >>$ENV_FILE
-echo "CONTAINER_OS=$CONTAINER_OS" >>$ENV_FILE
-echo "CONTAINER_PATH=$CONTAINER_PATH" >>$ENV_FILE
-echo "CONTAINER_BUILD_PATH=$CONTAINER_BUILD_PATH" >>$ENV_FILE
-echo "CONTAINER_FILESYSTEMS_PATH=$CONTAINER_FILESYSTEMS_PATH" >>$ENV_FILE
-echo "CONTAINER_SOURCE_PATH=$CONTAINER_SOURCE_PATH" >>$ENV_FILE
-echo >>$ENV_FILE
-echo "OLD_CONTAINER_NAME=$OLD_CONTAINER_NAME" >>$ENV_FILE
-echo "OLD_CONTAINER_PATH=$OLD_CONTAINER_PATH" >>$ENV_FILE
-echo "OLD_CONTAINER_BACKUP_PATH=$OLD_CONTAINER_BACKUP_PATH" >>$ENV_FILE
-################################################################
-# create and populate the container build directory #
-################################################################
-echo "Creating the container build directory."
-mkdir --parents $CONTAINER_BUILD_PATH/rootfs
-
-echo "Creating container config and hooks."
-sed --expression="s|__CONTAINER_FILESYSTEMS_PATH__|$CONTAINER_FILESYSTEMS_PATH|" \
- --expression="s|__CONTAINER_PATH__|$CONTAINER_PATH|" \
- --expression="s|__CONTAINER_START_ORDER__|$CONTAINER_START_ORDER|" \
- <$CONTAINER_SOURCE_PATH/config \
- >$CONTAINER_BUILD_PATH/config
-if [ -d $CONTAINER_SOURCE_PATH/hooks ]
-then
- cp --archive $CONTAINER_SOURCE_PATH/hooks $CONTAINER_BUILD_PATH
-fi
+ if [ -d $OLD_CONTAINER_BACKUP_PATH ]
+ then
+ rm -Rf ${OLD_CONTAINER_BACKUP_PATH}.old
+ mv $OLD_CONTAINER_BACKUP_PATH ${OLD_CONTAINER_BACKUP_PATH}.old
+ fi
-################################################################
-# execute preinstall phase #
-################################################################
-echo "Executing preinstall phase."
-preinstall $ENV_FILE
+ OLD_CONTAINER_STATE=$(lxc-info --name=$OLD_CONTAINER_NAME --state 2>/dev/null \
+ | cut -f 2 -d ':' | tr -d ' ')
+ case "$OLD_CONTAINER_STATE" in
+ "RUNNING")
+ echo "Stopping (the old) container $OLD_CONTAINER_NAME"
+ lxc-stop --name=$OLD_CONTAINER_NAME
+ echo "Stopped (the old) container $OLD_CONTAINER_NAME"
+ ;;
+ "STOPPED")
+ ;;
+ *)
+ echo "Unknown container state: $OLD_CONTAINER_STATE" >&2
+ exit 1
+ ;;
+ esac
-################################################################
-# install packages into the container #
-################################################################
-case "$DISTRIBUTION" in
- "CentOS")
- YUM_CONFIG=$SCRIPT_PATH/yum.conf.centos
- yum --assumeyes \
- --config=$YUM_CONFIG \
- --disableplugin=fastestmirror \
- --disablerepo=* \
- --enablerepo=local-* \
- --installroot=$CONTAINER_BUILD_PATH/rootfs \
- --releasever=$YUM_RELEASEVER \
- install $BASE_PACKAGES
- if [ -n "$SPEC_PACKAGES" ]
- then
+ mv $OLD_CONTAINER_PATH $OLD_CONTAINER_BACKUP_PATH
+}
+
+copy_and_install()
+{
+ case "$DISTRIBUTION" in
+ "CentOS")
+ YUM_CONFIG=$SCRIPT_PATH/yum.conf.centos
+ YUM_RELEASEVER=$DISTRIBUTION_VERSION
+ cp --archive --link \
+ $LXC_PATH/base.$CONTAINER_OS/rootfs/* \
+ $CONTAINER_BUILDROOT
+ if [ -n "$SPEC_PACKAGES" ]
+ then
+ yum --assumeyes \
+ --config=$YUM_CONFIG \
+ --disablerepo=* \
+ --enablerepo=local-* \
+ --installroot=$CONTAINER_BUILDROOT \
+ --releasever=$YUM_RELEASEVER \
+ install $SPEC_PACKAGES
+ fi
yum --assumeyes \
--config=$YUM_CONFIG \
- --disableplugin=fastestmirror \
--disablerepo=* \
--enablerepo=local-* \
- --installroot=$CONTAINER_BUILD_PATH/rootfs \
+ --installroot=$CONTAINER_BUILDROOT \
--releasever=$YUM_RELEASEVER \
- install $SPEC_PACKAGES
- fi
- yum --assumeyes \
- --config=$YUM_CONFIG \
- --disableplugin=fastestmirror \
- --disablerepo=* \
- --enablerepo=local-* \
- --installroot=$CONTAINER_BUILD_PATH/rootfs \
- --releasever=$YUM_RELEASEVER \
- clean all
- ;;
- "Fedora")
- DNF_CONFIG=$SCRIPT_PATH/dnf.conf.fedora
- if [ -n "$ROOT_PACKAGES" ]
- then
+ clean all
+ ;;
+ "Fedora")
+ DNF_CONFIG=$SCRIPT_PATH/dnf.conf.fedora
+ DNF_RELEASEVER=$DISTRIBUTION_VERSION
+ cp --archive --link \
+ $LXC_PATH/base.$CONTAINER_OS/rootfs/* \
+ $CONTAINER_BUILDROOT
+ if [ -n "$SPEC_PACKAGES" ]
+ then
+ dnf --assumeyes \
+ --config=$DNF_CONFIG \
+ --disablerepo=* \
+ --enablerepo=local-* \
+ --installroot=$CONTAINER_BUILDROOT \
+ --releasever=$DNF_RELEASEVER \
+ install $SPEC_PACKAGES
+ fi
dnf --assumeyes \
--config=$DNF_CONFIG \
--disablerepo=* \
--enablerepo=local-* \
- --installroot=$CONTAINER_BUILD_PATH/rootfs \
+ --installroot=$CONTAINER_BUILDROOT \
--releasever=$DNF_RELEASEVER \
- install $ROOT_PACKAGES
- fi
- dnf --assumeyes \
- --config=$DNF_CONFIG \
- --disablerepo=* \
- --enablerepo=local-* \
- --installroot=$CONTAINER_BUILD_PATH/rootfs \
- --releasever=$DNF_RELEASEVER \
- install $BASE_PACKAGES
- dnf --assumeyes \
- --config=$DNF_CONFIG \
- --disablerepo=* \
- --enablerepo=local-* \
- --installroot=$CONTAINER_BUILD_PATH/rootfs \
- --releasever=$DNF_RELEASEVER \
- install $SPEC_PACKAGES
- dnf --assumeyes \
- --config=$DNF_CONFIG \
- --disablerepo=* \
- --enablerepo=local-* \
- --installroot=$CONTAINER_BUILD_PATH/rootfs \
- --releasever=$DNF_RELEASEVER \
- clean all
- ;;
-esac
+ clean all
+ ;;
+ "Rocky")
+ YUM_CONFIG=$SCRIPT_PATH/yum.conf.rocky
+ YUM_RELEASEVER=$DISTRIBUTION_VERSION
+ cp --archive --link \
+ $LXC_PATH/base.$CONTAINER_OS/rootfs/* \
+ $CONTAINER_BUILDROOT
+ if [ -n "$SPEC_PACKAGES" ]
+ then
+ yum --assumeyes \
+ --config=$YUM_CONFIG \
+ --disablerepo=* \
+ --enablerepo=local-* \
+ --installroot=$CONTAINER_BUILDROOT \
+ --releasever=$YUM_RELEASEVER \
+ install $SPEC_PACKAGES
+ fi
+ yum --assumeyes \
+ --config=$YUM_CONFIG \
+ --disablerepo=* \
+ --enablerepo=local-* \
+ --installroot=$CONTAINER_BUILDROOT \
+ --releasever=$YUM_RELEASEVER \
+ clean all
+ ;;
+ esac
+}
-################################################################
-# execute postinstall phase #
-################################################################
-echo "Executing postinstall phase."
-postinstall $ENV_FILE
+create_build_path()
+{
+ echo "Creating and populating the container build directory."
-################################################################
-# rename the backup of the old container if needed #
-################################################################
-if [ -n "$OLD_CONTAINER_NAME" ]
-then
- if [ -d $OLD_CONTAINER_BACKUP_PATH ]
+ mkdir --parents $CONTAINER_BUILDROOT
+
+ sed --expression="s|__CONTAINER_FILESYSTEMS_PATH__|$CONTAINER_FILESYSTEMS_PATH|" \
+ --expression="s|__CONTAINER_PATH__|$CONTAINER_PATH|" \
+ --expression="s|__CONTAINER_START_ORDER__|$CONTAINER_START_ORDER|" \
+ <$CONTAINER_SOURCE_PATH/config \
+ >$CONTAINER_BUILD_PATH/config
+ if [ -d $CONTAINER_SOURCE_PATH/hooks ]
then
- rm -Rf ${OLD_CONTAINER_BACKUP_PATH}.old
- mv $OLD_CONTAINER_BACKUP_PATH ${OLD_CONTAINER_BACKUP_PATH}.old
+ cp --archive $CONTAINER_SOURCE_PATH/hooks $CONTAINER_BUILD_PATH
fi
-fi
-################################################################
-# shut down the old container if needed #
-################################################################
-if [ -n "$OLD_CONTAINER_NAME" ]
-then
- OLD_CONTAINER_STATE=$(lxc-info --name=$OLD_CONTAINER_NAME --state 2>/dev/null | cut -f 2 -d ':' | tr -d ' ')
- case "$OLD_CONTAINER_STATE" in
- "RUNNING")
- echo "Stopping container $OLD_CONTAINER_NAME"
- lxc-stop --name=$OLD_CONTAINER_NAME
- echo "Stopped container $OLD_CONTAINER_NAME"
+ echo "Created and populated the container build directory."
+}
+
+create_environment_file()
+{
+ ENV_FILE=$(mktemp)
+
+
+ echo "Creating environment file."
+
+ echo "SCRIPT_PATH=$SCRIPT_PATH" >>$ENV_FILE
+ echo "BASE_PATH=$BASE_PATH" >>$ENV_FILE
+ echo "BACKUPS_PATH=$BACKUPS_PATH" >>$ENV_FILE
+ echo "BUILD_PATH=$BUILD_PATH" >>$ENV_FILE
+ echo "FILESYSTEMS_PATH=$FILESYSTEMS_PATH" >>$ENV_FILE
+ echo "SOURCES_PATH=$SOURCES_PATH" >>$ENV_FILE
+ echo "SSH_KEYS_PATH=$SSH_KEYS_PATH" >>$ENV_FILE
+ echo >>$ENV_FILE
+ echo "CONTAINER_BASENAME=$CONTAINER_BASENAME" >>$ENV_FILE
+ echo "CONTAINER_NAME=$CONTAINER_NAME" >>$ENV_FILE
+ echo "CONTAINER_OS=$CONTAINER_OS" >>$ENV_FILE
+ echo "CONTAINER_PATH=$CONTAINER_PATH" >>$ENV_FILE
+ echo "CONTAINER_BUILD_PATH=$CONTAINER_BUILD_PATH" >>$ENV_FILE
+ echo "CONTAINER_FILESYSTEMS_PATH=$CONTAINER_FILESYSTEMS_PATH" >>$ENV_FILE
+ echo "CONTAINER_SOURCE_PATH=$CONTAINER_SOURCE_PATH" >>$ENV_FILE
+ echo "CONTAINER_BUILDROOT=$CONTAINER_BUILDROOT" >>$ENV_FILE
+ echo >>$ENV_FILE
+ echo "OLD_CONTAINER_NAME=$OLD_CONTAINER_NAME" >>$ENV_FILE
+ echo "OLD_CONTAINER_PATH=$OLD_CONTAINER_PATH" >>$ENV_FILE
+ echo "OLD_CONTAINER_BACKUP_PATH=$OLD_CONTAINER_BACKUP_PATH" >>$ENV_FILE
+
+ echo "Environment file created."
+}
+
+set_variables()
+{
+ CONTAINER_NAME_PARAMETER=$1
+
+
+ echo "Setting variables."
+
+ CONTAINER_BASENAME=$(basename $CONTAINER_NAME_PARAMETER)
+
+ LXC_PATH=$(grep '^lxc.lxcpath' /etc/lxc/lxc.conf \
+ | cut -f 2 -d '=' | tr -d ' ')
+
+ SCRIPT_PATH=$(dirname $(realpath $0))
+ BASE_PATH=$(dirname $SCRIPT_PATH)
+ BACKUPS_PATH=$BASE_PATH/backups
+ BUILD_PATH=$BASE_PATH/build
+ FILESYSTEMS_PATH=$BASE_PATH/filesystems
+ SOURCES_PATH=$BASE_PATH/sources
+ SSH_KEYS_PATH=$BASE_PATH/user-ssh
+
+ CONTAINER_FILESYSTEMS_PATH=$FILESYSTEMS_PATH/$CONTAINER_BASENAME
+ CONTAINER_SOURCE_PATH=$SOURCES_PATH/$CONTAINER_BASENAME
+
+ if [ ! -d $CONTAINER_SOURCE_PATH ]
+ then
+ echo "No source found for $CONTAINER_BASENAME" >&2
+ return 1
+ fi
+
+ if [ ! -f $CONTAINER_SOURCE_PATH/config ]
+ then
+ echo "No config file found for $CONTAINER_BASENAME" >&2
+ return 2
+ fi
+
+ if [ ! -f $CONTAINER_SOURCE_PATH/envvars ]
+ then
+ echo "No envvars file found for $CONTAINER_BASENAME" >&2
+ return 3
+ fi
+
+ source $CONTAINER_SOURCE_PATH/envvars
+ RC=$?
+ if [ $RC -ne 0 ]
+ then
+ echo "Could not source $CONTAINER_SOURCE_PATH/envvars, rc: $RC" >&2
+ return 4
+ fi
+
+ if [ -z "$DISTRIBUTION" ]
+ then
+ echo "No DISTRIBUTION variable set in envvars file" >&2
+ return 5
+ fi
+ if [ -z "$DISTRIBUTION_VERSION" ]
+ then
+ echo "No DISTRIBUTION_VERSION variable set in envvars file" >&2
+ return 6
+ fi
+
+ case "$DISTRIBUTION" in
+ "CentOS")
+ YUM_RELEASEVER=$DISTRIBUTION_VERSION
;;
- "STOPPED")
+ "Fedora")
+ DNF_RELEASEVER=$DISTRIBUTION_VERSION
+ ;;
+ "Rocky")
+ YUM_RELEASEVER=$DISTRIBUTION_VERSION
;;
*)
- echo "Unknown container state: $OLD_CONTAINER_STATE" >&2
- exit 1
+ echo "Unknown distribution: $DISTRIBUTION" >&2
+ return 7
;;
esac
-fi
-################################################################
-# back up the old container if needed #
-################################################################
-if [ -n "$OLD_CONTAINER_NAME" ]
+ DISTRIBUTION_FIRST_CHAR=$(echo "$DISTRIBUTION" | cut -c 1 | tr '[A-Z]' '[a-z]')
+ CONTAINER_OS="${DISTRIBUTION_FIRST_CHAR}$DISTRIBUTION_VERSION"
+
+ if [ ! -d $LXC_PATH/base.$CONTAINER_OS ]
+ then
+ echo "The container does not have a base container." >&2
+ return 8
+ fi
+
+ CONTAINER_NAME="${CONTAINER_BASENAME}.$CONTAINER_OS"
+
+ CONTAINER_PATH=$LXC_PATH/$CONTAINER_NAME
+ CONTAINER_BUILD_PATH=$BUILD_PATH/$CONTAINER_NAME
+
+ if [ -d $CONTAINER_BUILD_PATH ]
+ then
+ echo "The build directory already exists." >&2
+ return 9
+ fi
+
+ CONTAINER_BUILDROOT=$CONTAINER_BUILD_PATH/rootfs
+
+ CONTAINER_START_ORDER=$(grep -w $CONTAINER_BASENAME $SOURCES_PATH/start-order.txt \
+ | awk '{print $2}')
+
+ if [ -z "$CONTAINER_START_ORDER" ]
+ then
+ echo "The container does not have a start order." >&2
+ return 10
+ fi
+
+ OLD_CONTAINER_NAME=$(lxc-ls -1 | grep -w "^$CONTAINER_BASENAME")
+ #OLD_CONTAINER_OS=$(echo $OLD_CONTAINER_NAME | sed 's/.*\.\([^\.]*\)$/\1/')
+ OLD_CONTAINER_PATH=$LXC_PATH/$OLD_CONTAINER_NAME
+ OLD_CONTAINER_BACKUP_PATH=$BACKUPS_PATH/$OLD_CONTAINER_NAME
+
+ echo "All variables set."
+}
+
+preinstall()
+{
+ if [ -d $CONTAINER_SOURCE_PATH/preinstall ]
+ then
+ cp --archive $CONTAINER_SOURCE_PATH/preinstall $CONTAINER_BUILDROOT
+ chmod 755 $CONTAINER_BUILDROOT/preinstall/*.sh
+ for SCRIPT in $CONTAINER_BUILDROOT/preinstall/*.sh
+ do
+ echo $SCRIPT $ENV_FILE
+ $SCRIPT $ENV_FILE
+ done
+ fi
+
+ mkdir $CONTAINER_BUILDROOT/dev
+ mkdir $CONTAINER_BUILDROOT/proc
+ mount -o bind /dev $CONTAINER_BUILDROOT/dev
+ mount -t proc proc $CONTAINER_BUILDROOT/proc
+}
+
+postinstall()
+{
+ if [ -d $CONTAINER_SOURCE_PATH/postinstall ]
+ then
+ cp --archive $CONTAINER_SOURCE_PATH/postinstall $CONTAINER_BUILDROOT
+ if [ -f $CONTAINER_SOURCE_PATH/postinstall/copy.list ]
+ then
+ grep -v '^#' $CONTAINER_SOURCE_PATH/postinstall/copy.list | while read LINE
+ do
+ SRC_HOST=$(echo "$LINE" | cut -f 1 -d ' ')
+ SRC_PATH=$(echo "$LINE" | cut -f 2 -d ' ')
+ TGT_PATH=$(echo "$LINE" | cut -f 3 -d ' ')
+ scp -pr -i $SSH_KEYS_PATH/scripts \
+ root@${SRC_HOST}:$SRC_PATH \
+ $CONTAINER_BUILDROOT/postinstall/install/$TGT_PATH
+ done
+ fi
+ fi
+ if [ -d $CONTAINER_BUILDROOT/postinstall ]
+ then
+ chmod 755 $CONTAINER_BUILDROOT/postinstall/*.sh
+ for SCRIPT in $CONTAINER_BUILDROOT/postinstall/*.sh
+ do
+ POSTINSTALL_SCRIPT=$(echo $SCRIPT | sed "s|^$CONTAINER_BUILDROOT||")
+ echo chroot $CONTAINER_BUILDROOT $POSTINSTALL_SCRIPT
+ chroot $CONTAINER_BUILDROOT $POSTINSTALL_SCRIPT
+ done
+ fi
+
+ umount $CONTAINER_BUILDROOT/dev
+ umount $CONTAINER_BUILDROOT/proc
+}
+
+firstboot()
+{
+ if [ -d $CONTAINER_SOURCE_PATH/firstboot ]
+ then
+ cp --archive $CONTAINER_SOURCE_PATH/firstboot $CONTAINER_BUILDROOT
+ chmod 755 $CONTAINER_BUILDROOT/firstboot/*.sh
+ for SCRIPT in $CONTAINER_BUILDROOT/firstboot/*.sh
+ do
+ FIRSTBOOT_SCRIPT=$(echo $SCRIPT | sed "s|^$CONTAINER_BUILDROOT||")
+ echo lxc-attach --name=$CONTAINER_NAME -- $FIRSTBOOT_SCRIPT
+ lxc-attach --name=$CONTAINER_NAME -- $FIRSTBOOT_SCRIPT
+ done
+ fi
+}
+
+set_variables $1
+RC=$?
+if [ $RC -ne 0 ]
then
- mv $OLD_CONTAINER_PATH $OLD_CONTAINER_BACKUP_PATH
+ echo "Could not set variables, rc: $RC" >&2
+ exit $RC
fi
+echo "Starting at $(date)"
+
+create_environment_file
+
+create_build_path
+
+preinstall
+
+copy_and_install
+
+postinstall
+
+backup_old_container
+
################################################################
# move the new container to its place #
################################################################
################################################################
# start up the new container #
################################################################
-echo "Starting container $CONTAINER_NAME"
+echo "Starting (the new) container $CONTAINER_NAME"
lxc-start --name=$CONTAINER_NAME --daemon
-echo "Waiting for container $CONTAINER_NAME to start up."
+echo "Waiting for (the new) container $CONTAINER_NAME to start up."
lxc-wait --name=$CONTAINER_NAME --state=RUNNING
################################################################
# execute firstboot phase #
################################################################
echo "Executing firstboot phase."
-firstboot $ENV_FILE
+firstboot
################################################################
# remove the environment file #