From: Zen Date: Thu, 16 Nov 2023 16:35:53 +0000 (-0600) Subject: lxc-local: Re-organize code to use more functions X-Git-Tag: v6.0.0~33^2~1 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=f885a3c56047a05436ec4466833465b25e406474;p=thirdparty%2Flxc.git lxc-local: Re-organize code to use more functions Signed-off-by: Zen --- diff --git a/templates/lxc-local.in b/templates/lxc-local.in index 443c9601e..f352bbfdc 100755 --- a/templates/lxc-local.in +++ b/templates/lxc-local.in @@ -32,6 +32,10 @@ LXC_METADATA= MODE="system" COMPAT_LEVEL=5 +EXCLUDES="" +TEMPLATE_FILES="${LXC_PATH}/config" + + # Make sure the usual locations are in PATH export PATH="$PATH:/usr/sbin:/usr/bin:/sbin:/bin" @@ -134,6 +138,13 @@ if [ "${USERNS}" != "no" ]; then fi relevant_file() { + # Reads the supplied file name from LOCAL_TEMP.. + # If the file exists in $LOCAL_TEMP/$FILENAME.$COMPAT_LEVEL, it will be used. + # The default COMPAT_LEVEL is 5. + # If the file exists in $LOCAL_TEMP/$FILENAME-$MODE, it will be used. + # The default MODE is "system". + # If a mode or compatibility level specific file does not exist, the + # passed file name will be used. FILE_PATH="${LOCAL_TEMP}/$1" if [ -e "${FILE_PATH}-${MODE}" ]; then @@ -147,130 +158,206 @@ relevant_file() { echo "${FILE_PATH}" } +create_build_dir() { + # Create temporary build directory. + # If mktemp is not available, use /tmp/lxc-local.$$ + if ! command -V mktemp >/dev/null 2>&1; then + LOCAL_TEMP=/tmp/lxc-local.$$ + mkdir -p "${LOCAL_TEMP}" + else + LOCAL_TEMP=$(mktemp -d) + fi -# Unpack the rootfs -echo "Unpacking the rootfs" - -# Create temporary directory to -if ! command -V mktemp >/dev/null 2>&1; then - LOCAL_TEMP=/tmp/lxc-local.$$ - mkdir -p "${LOCAL_TEMP}" -else - LOCAL_TEMP=$(mktemp -d) -fi - -# Unpack file that contains meta.tar.xz -if ! tar Jxf "${LXC_METADATA}" -C "${LOCAL_TEMP}"; then - echo "ERROR: Invalid metadata file" 2>&1 - exit 1 -fi + echo "Using local temporary directory ${LOCAL_TEMP}" +} -EXCLUDES="" -excludelist=$(relevant_file excludes) -if [ -f "${excludelist}" ]; then +process_excludes() { + # If the file ${LXC_PATH}/excludes exists, it will be used as a list of + # files to exclude from the tarball. + excludelist=$(relevant_file excludes) + if [ -f "${excludelist}" ]; then while read -r line; do - EXCLUDES="${EXCLUDES} --exclude=${line}" + EXCLUDES="${EXCLUDES} --exclude=${line}" done < "${excludelist}" -fi + fi +} -# Do not surround ${EXCLUDES} by quotes. This does not work. The solution could -# use array but this is not POSIX compliant. The only POSIX compliant solution -# is to use a function wrapper, but the latter can't be used here as the args -# are dynamic. We thus need to ignore the warning brought by shellcheck. -# shellcheck disable=SC2086 -tar --anchored ${EXCLUDES} --numeric-owner -xpJf "${LXC_FSTREE}" -C "${LXC_ROOTFS}" +extract_config() { + # lxc-create will automatically create a config file at ${LXC_PATH}/config. + # This function extracts the network config, and any remaining lxc config + # The extracted config is stored in ${LXC_PATH}/config-network and ${LXC_PATH}/config-extra + # The config will be merged later. -mkdir -p "${LXC_ROOTFS}/dev/pts/" + # Extract all the network config entries + sed -i -e "/lxc.net.0/{w ${LXC_PATH}/config-network" -e "d}" "${LXC_PATH}/config" -# Setup the configuration -# Setup the configuration -configfile="$(relevant_file config)" -if [ ! -e "${configfile}" ]; then - echo "ERROR: meta tarball is missing the configuration file" 1>&2 - exit 1 -fi + if [ -e "${LXC_PATH}/config-network" ]; then + echo "Extracted network config to: ${LXC_PATH}/config-network" + cat "${LXC_PATH}/config-network" + fi + + # Extract any other config entry + sed -i -e "/lxc./{w ${LXC_PATH}/config-extra" -e "d}" "${LXC_PATH}/config" -## Extract all the network config entries -sed -i -e "/lxc.net.0/{w ${LXC_PATH}/config-network" -e "d}" "${LXC_PATH}/config" - -## Extract any other config entry -sed -i -e "/lxc./{w ${LXC_PATH}/config-auto" -e "d}" "${LXC_PATH}/config" - -## Append the defaults -{ - echo "" - echo "# Distribution configuration" - cat "$configfile" -} >> "${LXC_PATH}/config" - -## Add the container-specific config -{ - echo "" - echo "# Container specific configuration" - if [ -e "${LXC_PATH}/config-auto" ]; then - cat "${LXC_PATH}/config-auto" - rm "${LXC_PATH}/config-auto" + if [ -e "${LXC_PATH}/config-extra" ]; then + echo "Extracted additional config to: ${LXC_PATH}/config-extra" + cat "${LXC_PATH}/config-extra" fi -} >> "${LXC_PATH}/config" +} -fstab="$(relevant_file fstab)" -if [ -e "${fstab}" ]; then - echo "lxc.mount.fstab = ${LXC_PATH}/fstab" >> "${LXC_PATH}/config" -fi -echo "lxc.uts.name = ${LXC_NAME}" >> "${LXC_PATH}/config" +add_container_config() { + # Adds the contents of the supplied metadata config to the container config + { + echo "" + echo "# Distribution configuration" + cat "$configfile" + } >> "${LXC_PATH}/config" +} -## Re-add the previously removed network config -if [ -e "${LXC_PATH}/config-network" ]; then +add_extra_config() { + # Add the container-specific config { echo "" - echo "# Network configuration" - cat "${LXC_PATH}/config-network" - rm "${LXC_PATH}/config-network" + echo "# Container specific configuration" + if [ -e "${LXC_PATH}/config-extra" ]; then + cat "${LXC_PATH}/config-extra" + rm "${LXC_PATH}/config-extra" + fi } >> "${LXC_PATH}/config" -fi +} -TEMPLATE_FILES="${LXC_PATH}/config" +add_network_config() { + # Re-add the previously removed network config + if [ -e "${LXC_PATH}/config-network" ]; then + { + echo "" + echo "# Network configuration" + cat "${LXC_PATH}/config-network" + rm "${LXC_PATH}/config-network" + } >> "${LXC_PATH}/config" + fi +} -# Setup the fstab -if [ -e "${fstab}" ]; then - cp "${fstab}" "${LXC_PATH}/fstab" - TEMPLATE_FILES="${TEMPLATE_FILES};${LXC_PATH}/fstab" -fi +process_config() { + # Process the supplied config file if it exists. + configfile="$(relevant_file config)" + if [ ! -e "${configfile}" ]; then + echo "ERROR: metadata tarball is missing the configuration file" 1>&2 + return + fi -# Look for extra templates -if [ -e "$(relevant_file templates)" ]; then - while read -r line; do - fullpath="${LXC_ROOTFS}/${line}" - [ ! -e "${fullpath}" ] && continue - TEMPLATE_FILES="${TEMPLATE_FILES};${fullpath}" - done < "$(relevant_file templates)" -fi + extract_config + add_container_config + add_extra_config + add_network_config +} +process_fstab() { + # Process the supplied fstab file if it exists. + # Add the fstab file to template files so substitions can be made. + fstab="$(relevant_file fstab)" + if [ -e "${fstab}" ]; then + echo "lxc.mount.fstab = ${LXC_PATH}/fstab" >> "${LXC_PATH}/config" + cp "${fstab}" "${LXC_PATH}/fstab" + TEMPLATE_FILES="${TEMPLATE_FILES};${LXC_PATH}/fstab" + fi +} -# Replace variables in all templates -OLD_IFS=${IFS} -IFS=";" -for file in ${TEMPLATE_FILES}; do - [ ! -f "${file}" ] && continue +process_templates() { + # Look for extra templates + template="$(relevant_file template)" + if [ -e "${template}" ]; then + while read -r line; do + fullpath="${LXC_ROOTFS}/${line}" + [ ! -e "${fullpath}" ] && continue + TEMPLATE_FILES="${TEMPLATE_FILES};${fullpath}" + done < "${template}" + fi +} - sed -i "s#LXC_NAME#${LXC_NAME}#g" "${file}" - sed -i "s#LXC_PATH#${LXC_PATH}#g" "${file}" - sed -i "s#LXC_ROOTFS#${LXC_ROOTFS}#g" "${file}" - sed -i "s#LXC_TEMPLATE_CONFIG#${LXC_TEMPLATE_CONFIG}#g" "${file}" - sed -i "s#LXC_HOOK_DIR#${LXC_HOOK_DIR}#g" "${file}" -done -IFS=${OLD_IFS} +unpack_metadata() { + # Unpack file that contains the container metadata + # If the file does not exist, just warn and continue. + if [ -n "${LXC_METADATA}" ] && [ -f "${LXC_METADATA}" ]; then + if tar Jxf "${LXC_METADATA}" -C "${LOCAL_TEMP}"; then + echo "Unpacked metadata file: ${LXC_METADATA}" + process_excludes + process_config + process_fstab + process_templates + else + echo "Unable to unpack metadata file: ${LXC_METADATA}" 2>&1 + exit 1 + fi + fi +} -# prevent mingetty from calling vhangup(2) since it fails with userns on CentOS / Oracle -if [ -f "${LXC_ROOTFS}/etc/init/tty.conf" ]; then - sed -i 's|mingetty|mingetty --nohangup|' "${LXC_ROOTFS}/etc/init/tty.conf" -fi +set_utsname() { + # Set the container's hostname + echo "lxc.uts.name = ${LXC_NAME}" >> "${LXC_PATH}/config" +} + +prepare_rootfs() { + # Additional configuration that must be done on the rootfs. + # Always add /dev/pts as /dev may be excluded. + mkdir -p "${LXC_ROOTFS}/dev/pts/" +} +unpack_rootfs() { + # Unpack the rootfs + echo "Unpacking the rootfs to: ${LXC_ROOTFS}" -if [ -e "$(relevant_file create-message)" ]; then - echo "" - echo "---" - cat "$(relevant_file create-message)" -fi + # Do not surround ${EXCLUDES} by quotes. This does not work. The solution could + # use array but this is not POSIX compliant. The only POSIX compliant solution + # is to use a function wrapper, but the latter can't be used here as the args + # are dynamic. We thus need to ignore the warning brought by shellcheck. + # shellcheck disable=SC2086 + tar --anchored ${EXCLUDES} --numeric-owner -xpJf "${LXC_FSTREE}" -C "${LXC_ROOTFS}" + + prepare_rootfs +} + +replace_template_vars() { + # Replace variables in all templates + OLD_IFS=${IFS} + IFS=";" + for file in ${TEMPLATE_FILES}; do + [ ! -f "${file}" ] && continue + + sed -i "s#LXC_NAME#${LXC_NAME}#g" "${file}" + sed -i "s#LXC_PATH#${LXC_PATH}#g" "${file}" + sed -i "s#LXC_ROOTFS#${LXC_ROOTFS}#g" "${file}" + sed -i "s#LXC_TEMPLATE_CONFIG#${LXC_TEMPLATE_CONFIG}#g" "${file}" + sed -i "s#LXC_HOOK_DIR#${LXC_HOOK_DIR}#g" "${file}" + done + IFS=${OLD_IFS} +} + +fix_tty() { + # prevent mingetty from calling vhangup(2) since it fails with userns on CentOS / Oracle + if [ -f "${LXC_ROOTFS}/etc/init/tty.conf" ]; then + echo "Patching ${LXC_ROOTFS}/etc/init/tty.conf to prevent mingetty from calling vhangup." + sed -i 's|mingetty|mingetty --nohangup|' "${LXC_ROOTFS}/etc/init/tty.conf" + fi +} + +display_creation_message() { + if [ -e "$(relevant_file create-message)" ]; then + echo "" + echo "---" + cat "$(relevant_file create-message)" + fi +} + + +create_build_dir +unpack_metadata +unpack_rootfs + +set_utsname +replace_template_vars +fix_tty + +display_creation_message exit 0