]> 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 756615f154672ede3557356c8afd15d41a9eae9f..674cc2289204dde382f644e8a9b4e61c34440b8d 100755 (executable)
 
 SCRIPT_PATH="$(dirname "$(readlink -f "$0")")"
 
-# Constants
 
-# 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
-
-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_stage_1() {
-       # Unmount image
-       umount ${IMAGE_MOUNT_DIR}
-
-       # Remove partition from the kernel table.
-       partx -d ${outlo}p1
-
-       # Remove loopback device
-       losetup -d ${outlo}
-}
-
-cleanup_stage_2() {
-       # 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
-       local compression_level=1
-
-       if [[ ${IMAGE_RELEASE} -eq ${TRUE} ]]; then
-               compression_level=1
-       fi
-
-       # 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}" ${compression_level}
-
-               # 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}
-               return $?
-       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 ))
-
-               log debug $(df --output=avail ${path} | tail -n 1)
-               log debug ${space}
-
-               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
-}
-
-parse_cmdline() {
-       while [ $# -gt 0 ]; do
-               case "${1}" in
-                       "--release")
-                                       IMAGE_RELEASE=${TRUE}
-                               ;;
-
-                       *)
-                               error "Invalid argument: ${1}"
-                               return ${EXIT_CONF_ERROR}
-                               ;;
-               esac
-               shift
-       done
-}
+# 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_BASE_FILE="$(mktemp -u ${WORKING_DIR}/image_base_file.XXXXXXX.img)"
-IMAGE_SIZE="7500"
-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="True"
-
-# 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 $@
@@ -369,6 +55,7 @@ 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.
@@ -461,13 +148,6 @@ yes | pakfire --root=${IMAGE_MOUNT_DIR} ${ENABLE_LOCAL} install @Base ${PACKAGES
 
 cmd cp -f "${SCRIPT_PATH}/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
-
 #
 ## Generate fstab
 #
@@ -492,47 +172,38 @@ 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 /build/ && 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"
 
@@ -549,7 +220,7 @@ fsck.${FILESYSTEM} ${outlo}p1
 
 cleanup_stage_1
 
-publish "/home/jschlag/public/ipfire3-images" "${IMAGE_BASE_FILE}"
+publish "${IMAGE_DIR_PUBLISH}" "${IMAGE_BASE_FILE}"
 
 # Cleanup
 cleanup_stage_2