]> git.ipfire.org Git - people/jschlag/ipfire-3.x-image.git/blobdiff - generate_image.sh
Improve how we execute commands in chroot
[people/jschlag/ipfire-3.x-image.git] / generate_image.sh
index 6cff68d319787f4c37e3bf0386780b0a028f445a..674cc2289204dde382f644e8a9b4e61c34440b8d 100755 (executable)
 # Copyright (C) - IPFire Development Team <info@ipfire.org>                   #
 ###############################################################################
 
-# Constants
+#Path of the script
 
-# Proper error codes
-EXIT_OK=0
-EXIT_ERROR=1
-EXIT_CONF_ERROR=2
-EXIT_NOT_SUPPORTED=3
-EXIT_NOT_HANDLED=4
-EXIT_COMMAND_NOT_FOUND=127
-EXIT_ERROR_ASSERT=128
+SCRIPT_PATH="$(dirname "$(readlink -f "$0")")"
 
-EXIT_TRUE=0
-EXIT_FALSE=1
-EXIT_UNKNOWN=2
 
-TRUE=0
-FALSE=1
-
-
-
-# Functions
-
-log() {
-       local level=${1}
-       local message=${2}
-       echo "[${level}] ${message}"
-}
-
-cmd() {
-       local cmd=$@
-       local ret
-
-       log DEBUG "Running command: ${cmd}"
-
-       ${cmd}
-       ret=$?
-
-       case "${ret}" in
-               ${EXIT_OK})
-                       return ${EXIT_OK}
-                       ;;
-               *)
-                       log DEBUG "Returned with code '${ret}'"
-                       return ${ret}
-                       ;;
-       esac
-}
-
-cleanup() {
-       # Unmount image
-       umount ${IMAGE_MOUNT_DIR}
-
-       # Remove partition from the kernel table.
-       partx -d ${outlo}p1
-
-       # Remove loopback device
-       losetup -d ${outlo}
-
-       # Drop working dir
-       if [ -d "${WORKING_DIR}" ]; then
-               rm -dfR "${WORKING_DIR}"
-       fi
-}
-
-generate_image_filename() {
-       local distro=${1}
-       local version=${2}
-       local arch=${3}
-
-       echo "${distro}-${version}-${arch}"
-}
-
-check_for_pakfire() {
-       local return_value=0
-
-       # TODO
-       # Check that pakfire-server binary is available
-       # Check that pakfire binary is available
-
-       # Check that repo files are installed. (pakfire need to know which repos exist)
-       local repo_dir="/etc/pakfire/repos"
-
-       if [ ! -d "${repo_dir}" ]; then
-               log ERROR "Could not find respository directory ${repo_dir}"
-               return_value=1
-       fi
-
-       return ${return_value}
-}
-
-compress_image() {
-       local compression=${1}
-       local image_file=${2}
-       local level=${3}
-
-       log debug "Compressing ${image_file} with ${compression}"
-
-       case "${compression}" in
-               "xz")
-                       # Check that the file does not exist yet
-                       if [ -f "${image_file}.xz" ]; then
-                               log ERROR "Failed to compress the image. The file already exists"
-                               return ${EXIT_ERROR}
-                       fi
-                       cmd xz "-${level}" "${image_file}"
-                       ;;
-               "zip")
-               # Check that the file does not exist yet
-                       if [ -f "${image_file}.zip" ]; then
-                               log ERROR "Failed to compress the image. The file already exists"
-                               return ${EXIT_ERROR}
-
-                       fi
-                       cmd zip "-${level}" "${image_file}.zip" "${image_file}"
-                       # Remove the file which we compressed+
-                       rm -f "${image_file}"
-                       ;;
-
-       esac
-}
-
-reset_root_password() {
-       local root_dir=${1}
-       # Backup passwd file
-       cp -avf ${root_dir}/etc/passwd ${root_dir}/etc/passwd.orig
-
-       # Drop root password.
-       sed -e "s/^\(root:\)[^:]*:/\1:/" ${root_dir}/etc/passwd.orig > ${root_dir}/etc/passwd
-
-       # Remove passwd backup file.
-       rm -rvf ${root_dir}/etc/passwd.orig
-}
-
-clone_git_repos() {
-       # Dir where the repos should be located
-       local dir=${1}
-       shift
-       local repos="$@"
-
-       local repo
-
-       mkdir -pv ${dir}
-
-       (
-               cd ${dir}
-               # Clone git repositories.
-               for repo in ${repos}; do
-                       git clone ${repo}
-               done
-       )
-}
-
-# This function is used to publish the produced images
-
-publish() {
-       local path=${1}
-       # The image we created usually a img. file
-       local image_base_file=${2}
-
-       local image_name_final="$(generate_image_filename "${DISTRO}" "${VERSION}" "${ARCH}")"
-
-       local image_type
-       local compression_type
-
-       # Do these steps for every image format we like to publish
-       for image_type in ${IMAGE_TYPES_PUBLISH}; do
-               # Get compressioon type
-               compression_type="$(get_compression_type ${image_type})"
-               # Convert images to the type specified in IMAGE_TYPES_PUBLISH
-               convert_image "${image_type}" "${image_base_file}" "${image_name_final}"
-
-               # compress image.
-               compress_image "${compression_type}" "${image_name_final}.${image_type}" "1"
-
-               # Move images to this path
-               mv -f "${image_name_final}.${image_type}.${compression_type}" ${path}
-
-               # point the latest links to these images
-               ln -s -f "${path}/${image_name_final}.${image_type}.${compression_type}" \
-                       "${path}/$(generate_image_filename "${DISTRO}" "latest" "${ARCH}").${image_type}.${compression_type}"
-
-       done
-
-}
-
-convert_image() {
-       local type=${1}
-       local from=${2}
-       local to=${3}
-
-       if [[ ${type} = "img" ]]; then
-               # We do not need to convert the image here but we need to rename
-               mv -f ${from} ${to}.${type}
-       fi
-
-       if [[ ${type} = "qcow2" ]]; then
-               local command="qemu-img convert -c -O ${type} ${from} ${to}.${type}"
-       else
-               local command="qemu-img convert -O ${type} ${from} ${to}.${type}"
-       fi
-
-       cmd ${command}
-}
-
-get_compression_type() {
-       local image_type=${1}
-
-       case "${image_type}" in
-               "qcow2" | "img")
-                       # These types can be used only under Unix so we use xz as compression
-                       echo "xz"
-                       ;;
-               "vmdk" | "vdi")
-                       # These types can be also under Windows so we use zip as compression
-                       echo "zip"
-                       ;;
-       esac
-
-}
-
-check_for_free_space() {
-               local space=${1}
-               local path=${2}
-
-               # Space needs to passed in MB
-               # df returns bytes so we multiple by 1024²
-               space=$(( ${space} * 1024 * 1024 ))
-
-               if [[ $(df --output=avail ${path} | tail -n 1) -lt ${space} ]]; then
-                       log error "Not enough free space available under ${path}"
-                       log error "Free space is $(df -h -B MB --output=avail ${path} | tail -n 1) but we need at least $(( ${space} / 1024 / 1024 ))MB"
-                       return ${EXIT_ERROR}
-               fi
-}
+# INCLUDE SETTINGS
+. "${SCRIPT_PATH}/settings.sh"
 
+# INCLUDE FUNCTIONS
+. "${SCRIPT_PATH}/functions.sh"
 #
-# General settings
+# Scripts starts here
 #
 
-ARCH="x86_64"
-DISTRO="ipfire3"
-VERSION="$(date +"%Y%m%d")"
-WORKING_DIR=$(mktemp -d /tmp/ipfire3_image.XXXXXXXX)
-
 log DEBUG "Working dir is ${WORKING_DIR}"
 
-#
-# Image
-#
-
-IMAGE_TYPE="img"
-IMAGE_BASE_FILE="$(mktemp -u ${WORKING_DIR}/image_base_file.XXXXXXX.img)"
-IMAGE_SIZE="8100"
-IMAGE_MOUNT_DIR="$(mktemp -d ${WORKING_DIR}/image.XXXXXXX)"
-
-IMAGE_TYPES_PUBLISH="qcow2 vmdk vdi img"
-
-# The used filesystem.
-FILESYSTEM="xfs"
-
-# Additional packages which should be installed.
-PACKAGES="xfsprogs kernel openssh-server wget htop tmux"
 
-# Use git network stack. ( When using the git network stack,
-# development tools and git automatically will be installed.)
-USE_GIT_NETWORK_STACK="True"
-
-# List of packages which are required to build the network stack.
-NETWORK_BUILD_DEPS="autoconf automake docbook-xsl libnl3-devel libxslt systemd-devel"
-
-# Install development tools.
-INSTALL_DEV_PACKAGES="False"
-
-# List of development tools which should be installed.
-DEVELOPMENT_PACKAGES="make gcc libtool git"
-
-
-# Git repositories which also should be checked, out.
-GIT_REPOS=""
-
-#
-# Stuff for the local repo
-#
-
-# Use local repository.
-USE_LOCAL_REPO="True"
-
-# Source path for the local repo packages.
-LOCAL_REPO_SOURCE_PATH="/var/lib/pakfire/local/"
-
-# Path were the local repo is created
-LOCAL_REPO_DIR="$(mktemp -d ${WORKING_DIR}/ipfire-repo.XXXXXXX)"
-
-# Config file for the local repo
-LOCAL_REPO_FILE="/etc/pakfire/repos/local.repo"
-
-
-#
-# Scripts starts here
-#
+#Parse cmdline
+parse_cmdline $@
 
 # Check that pakfire is working
 check_for_pakfire
@@ -331,11 +50,12 @@ cd ${WORKING_DIR} || exit ${EXIT_ERROR}
 #
 ## Create the disk image.
 #
-dd if=/dev/zero of=${IMAGE_BASE_FILE} seek=${IMAGE_SIZE}MB count=1k bs=1
+dd if=/dev/zero of=${IMAGE_BASE_FILE} seek=${IMAGE_SIZE}M count=1k bs=1
 
 # Setup the loopback device.
 outlo=`losetup -f --show ${IMAGE_BASE_FILE}`
 
+log INFO "Loop device is ${outlo}"
 log INFO "Create partions and filesystem"
 
 # Create and msdos compatible table on the image.
@@ -426,14 +146,7 @@ yes | pakfire --root=${IMAGE_MOUNT_DIR} ${ENABLE_LOCAL} install @Base ${PACKAGES
 
 #Hack to install a /etc/default/grub file
 
-cp -f grub "${IMAGE_MOUNT_DIR}/etc/default"
-
-#
-## Install grub2 if neccessary
-#
-if [ "${HAVE_GRUB}" == "True" ]; then
-       grub2-install --boot-directory=${IMAGE_MOUNT_DIR}/boot/ --modules="${FILESYSTEM} part_msdos" ${outlo}
-fi
+cmd cp -f "${SCRIPT_PATH}/grub" "${IMAGE_MOUNT_DIR}/etc/default"
 
 #
 ## Generate fstab
@@ -443,7 +156,9 @@ fi
 FS_UUID=$(blkid -o value -s UUID ${outlo}p1)
 
 # Write fstab.
-echo "UUID=${FS_UUID} / ${FILESYSTEM} defaults 0 0" > ${IMAGE_MOUNT_DIR}/etc/fstab
+echo "UUID=${FS_UUID} / ${FILESYSTEM} defaults 0 0" > "${IMAGE_MOUNT_DIR}/etc/fstab"
+
+cat  "${IMAGE_MOUNT_DIR}/etc/fstab"
 
 #
 ## Remove the password for user root.
@@ -457,47 +172,42 @@ reset_root_password "${IMAGE_MOUNT_DIR}"
 
 clone_git_repos "${IMAGE_MOUNT_DIR}/build" ${GIT_REPOS}
 
+
 #
 ## Prepare chrooting into the image.
 #
 
-# Check if the network stack should be build.
-if [ "${USE_GIT_NETWORK_STACK}" == "True" ]; then
-       BUILD_NETWORK_CMDS="cd network/ && ./autogen.sh && ./configure && make && make install"
-fi
-
-ENABLE_GETTY="/bin/systemctl enable getty@.service"
+chroot_script_init
 
-# Check if the arch uses grub
 if [ "${HAVE_GRUB}" == "True" ]; then
-       GENERATE_GRUB_CONF="grub-mkconfig -o /boot/grub2/grub.cfg"
+       chroot_script_add_cmd "grub-install --boot-directory=/boot/ ${outlo}" "grub-mkconfig -o /boot/grub/grub.cfg"
 fi
 
-# Use systemd-nspawn to spawn a chroot environment and execute
-# commands inside it.
-#
-# The first command enables the terminal on TTY1.
-# The second command generates the configuration file for grub2.
 
 
-systemd-nspawn -D ${IMAGE_MOUNT_DIR} --bind /dev --capability=CAP_SYS_ADMIN,CAP_SYS_RAWIO --bind /proc --bind /sys << END
-       echo "Execute commands inside chroot"
-       ${ENABLE_GETTY}
-       ${GENERATE_GRUB_CONF}
-       cd /git-repos/ && ls
-       ${BUILD_NETWORK_CMDS}
-       echo "All commands executed"
-END
+# ENABLE Serial Console
+chroot_script_add_cmd "/bin/systemctl enable getty@.service"
 
 
+# Check if the network stack should be build.
+if [ "${USE_GIT_NETWORK_STACK}" == "True" ]; then
+       chroot_script_add_cmd "cd /build/network" "./autogen.sh" "./configure" "make" "make install"
+fi
+
+chroot_script_exec
+
 
 # Insert the UUID because grub-mkconfig often fails to
 # detect that correctly
 
-sed -i "${IMAGE_MOUNT_DIR}/boot/grub2/grub.cfg" \
+sed -i "${IMAGE_MOUNT_DIR}/boot/grub/grub.cfg" \
                -e "s/root=[A-Za-z0-9\/=-]*/root=UUID=${FS_UUID}/g"
 
-cat "${IMAGE_MOUNT_DIR}/boot/grub2/grub.cfg"
+cat "${IMAGE_MOUNT_DIR}/boot/grub/grub.cfg"
+
+cat  "${IMAGE_MOUNT_DIR}/etc/fstab"
+
+
 #
 ## Tidy up.
 #
@@ -508,9 +218,9 @@ sleep 5
 # Check filesystem for damage.
 fsck.${FILESYSTEM} ${outlo}p1
 
-# Cleanup
-cleanup
+cleanup_stage_1
 
-publish "/home/jschlag/public/ipfire3-images" "${IMAGE_BASE_FILE}"
+publish "${IMAGE_DIR_PUBLISH}" "${IMAGE_BASE_FILE}"
 
-#compress_image "xz" "${IMAGE_BASE_FILE}"
+# Cleanup
+cleanup_stage_2