]> git.ipfire.org Git - thirdparty/lxc.git/commitdiff
lxc-local: Re-organize code to use more functions
authorZen <z@pyl.onl>
Thu, 16 Nov 2023 16:35:53 +0000 (10:35 -0600)
committerStéphane Graber <stgraber@stgraber.org>
Mon, 11 Dec 2023 22:04:41 +0000 (17:04 -0500)
Signed-off-by: Zen <z@pyl.onl>
templates/lxc-local.in

index 443c9601ea572bf0c148af83d43291dc49444f1b..f352bbfdc12d87e893b631ff0edf012ed304c669 100755 (executable)
@@ -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