From d4913d113477795127bf71c9ae397085368f0f89 Mon Sep 17 00:00:00 2001 From: udeved Date: Mon, 11 May 2015 12:47:02 +0200 Subject: [PATCH] [buildiso] integrate mkiso; WIP --- bin/buildiso.in | 8 +- conf/manjaro-tools.conf | 6 ++ lib/util-iso-image.sh | 21 +++++ lib/util-iso-log.sh | 46 ++++++++++ lib/util-iso.sh | 199 +++++++++++++++++++++++++--------------- lib/util.sh | 81 ++++++++++++++-- 6 files changed, 278 insertions(+), 83 deletions(-) create mode 100644 lib/util-iso-log.sh diff --git a/bin/buildiso.in b/bin/buildiso.in index fe99cc6..0559d1a 100755 --- a/bin/buildiso.in +++ b/bin/buildiso.in @@ -27,7 +27,7 @@ show_profile(){ msg2 "iso_file: ${iso_file}" #msg2 "pacman_conf: ${pacman_conf}" msg2 "is_custom_pac_conf: ${is_custom_pac_conf}" - + msg2 "initsys: ${initsys}" msg2 "displaymanager: ${displaymanager}" msg2 "kernel: ${kernel}" @@ -190,11 +190,11 @@ cache_dir_iso="${cache_dir}/iso" mirrors_conf="${PKGDATADIR}/pacman-mirrors-${branch}.conf" -create_args+=(-v -a ${arch} -D ${iso_name} -M ${mirrors_conf}) +# create_args+=(-v -a ${arch} -D ${iso_name} -M ${mirrors_conf}) -iso_args+=(-v -x -a ${arch} -D ${iso_name} -L ${iso_label} -c ${iso_compression}) +# iso_args+=(-v -x -a ${arch} -D ${iso_name} -L ${iso_label} -c ${iso_compression}) -${clean_cache_iso} && iso_args+=(-f) +# ${clean_cache_iso} && iso_args+=(-f) check_root "$0" "${orig_argv[@]}" diff --git a/conf/manjaro-tools.conf b/conf/manjaro-tools.conf index c20214e..d1d5197 100644 --- a/conf/manjaro-tools.conf +++ b/conf/manjaro-tools.conf @@ -71,6 +71,12 @@ # unset defaults to given value # iso_name=manjaro +# publisher +# iso_publisher="Manjaro Linux " + +# iso_app_id +# iso_app_id="Manjaro Linux Live/Rescue CD" + # unset defaults to given value # iso_compression=xz diff --git a/lib/util-iso-image.sh b/lib/util-iso-image.sh index af1fb39..c5a099e 100644 --- a/lib/util-iso-image.sh +++ b/lib/util-iso-image.sh @@ -338,3 +338,24 @@ configure_xorg_drivers(){ touch $1/var/lib/mhwd/db/pci/graphic_drivers/nvidia-340xx/MHWDCONFIG fi } + +# $1: image path +clean_up_image(){ + msg2 "Cleaning up [$1]" + if [ -d "$1/boot/" ]; then + # remove the initcpio images that were generated for the host system + find "$1/boot" -name 'initramfs*.img' -delete &>/dev/null + fi + + [[ -f "$1/etc/locale.gen.bak" ]] \ + && mv "$1/etc/locale.gen.bak" "$1/etc/locale.gen" + [[ -f "$1/etc/locale.conf.bak" ]] \ + && mv "$1/etc/locale.conf.bak" "$1/etc/locale.conf" + + find "$1/var/lib/pacman" -maxdepth 1 -type f -delete &>/dev/null + find "$1/var/lib/pacman/sync" -delete &>/dev/null + find "$1/var/cache/pacman/pkg" -type f -delete &>/dev/null + find "$1/var/log" -type f -delete &>/dev/null + find "$1/var/tmp" -mindepth 1 -delete &>/dev/null + find "$1/tmp" -mindepth 1 -delete &>/dev/null +} diff --git a/lib/util-iso-log.sh b/lib/util-iso-log.sh new file mode 100644 index 0000000..9d95264 --- /dev/null +++ b/lib/util-iso-log.sh @@ -0,0 +1,46 @@ +#!/bin/bash +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; version 2 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +error_function() { + if [[ -p $logpipe ]]; then + rm "$logpipe" + fi + # first exit all subshells, then print the error + if (( ! BASH_SUBSHELL )); then + error "A failure occurred in %s()." "$1" + plain "Aborting..." + fi + exit 2 +} + +run_safe() { + local restoretrap + set -e + set -E + restoretrap=$(trap -p ERR) + trap 'error_function $1' ERR + run_log "$1" + eval $restoretrap + set +E + set +e +} + +# $1: function +run_log(){ + local logfile=${work_dir}/${imgname}.log + logpipe=$(mktemp -u "/tmp/logpipe.XXXXXXXX") + mkfifo "$logpipe" + tee "$logfile" < "$logpipe" & + local teepid=$! + $1 &> "$logpipe" + wait $teepid + rm "$logpipe" +} diff --git a/lib/util-iso.sh b/lib/util-iso.sh index ae69e24..64312ae 100644 --- a/lib/util-iso.sh +++ b/lib/util-iso.sh @@ -148,11 +148,128 @@ download_to_cache(){ --cache $2 -Syw $3 --noconfirm } +# $1: image path +# $2: packages +make_chroot(){ + #set locale.gen + local flag + if [ "$1" == "${work_dir}/root-image" ]; then + flag="-L" + fi + + setarch "${ARCH}" \ + mkchroot -C ${pacman_conf} \ + -S ${mirrors_conf} \ + ${flag} \ + "$1" $2 || die "Failed to retrieve one or more packages!" + fi + + # Cleanup + find "${work_dir}" -name *.pacnew -name *.pacsave -name *.pacorig -delete +} + + +# $1: image path +squash_image_dir() { + if [ ! -d "$1" ]; then + error "$1 is not a directory" + return 1 + fi + + local sq_img="${work_dir}/iso/${INSTALL_DIR}/${ARCH}/$(basename ${1}).sqfs" + msg "Generating SquashFS image for '${1}'" + if [ -e "${sq_img}" ]; then + dirhaschanged=$(find ${1} -newer ${sqimg}) + msg2 "Possible changes for ${1}..." >> /tmp/buildiso.debug + msg2 "${dirhaschanged}" >> /tmp/buildiso.debug + if [ ! -z "${dirhaschanged}" ]; then + msg2 "SquashFS image '${sq_img}' is not up to date, rebuilding..." + rm "${sqimg}" + else + msg2 "SquashFS image '${sq_img}' is up to date, skipping." + return + fi + fi + + msg2 "Creating SquashFS image. This may take some time..." + start=$(date +%s) + + mksquashfs "${1}" "${sqimg}" -noappend -comp "${COMPRESSION}" ${HIGHCOMP} + + minutes=$(echo $start $(date +%s) | awk '{ printf "%0.2f",($2-$1)/60 }') + msg "Image creation done in $minutes minutes." +} + # Build ISO make_iso() { msg "Start [Build ISO]" - touch "${work_dir}/iso/.miso" - mkiso ${iso_args[*]} iso "${work_dir}" "${cache_dir_iso}/${iso_file}" || mkiso_error_handler + touch "${work_dir}/iso/.buildiso" +# mkiso ${iso_args[*]} iso "${work_dir}" "${cache_dir_iso}/${iso_file}" || mkiso_error_handler + + for d in $(find "${work_dir}" -maxdepth 1 -type d -name '[^.]*'); do + if [ "$d" != "${work_dir}/iso" -a \ + "$(basename "$d")" != "iso" -a \ + "$(basename "$d")" != "efiboot" -a \ + "$d" != "${work_dir}" ]; then + squash_image_dir "$d" + fi + done + + msg "Making bootable image" + + # Sanity checks + [[ ! -d "${work_dir}/iso" ]] && die "${work_dir}/iso doesn't exist. What did you do?!" + + if [[ -f "${cache_dir_iso}/${iso_file}" ]]; then + msg2 "Removing existing bootable image..." + rm -rf "${cache_dir_iso}/${iso_file}" + fi + +# if [[ ! -f ${work_dir}/iso/isolinux/isolinux.cfg ]]; then +# die "${work_dir}/iso/isolinux/isolinux.cfg, doesn't exist." +# fi +# +# if [ ! -f "${work_dir}/iso/isolinux/isolinux.bin" ]; then +# die "${work_dir}/iso/isolinux/isolinux.bin, doesn't exist." +# fi +# if [ ! -f "${work_dir}/iso/isolinux/isohdpfx.bin" ]; then +# die "${work_dir}/iso/isolinux/isohdpfx.bin, doesn't exist." +# fi + + local efi_boot_args="" + + # If exists, add an EFI "El Torito" boot image (FAT filesystem) to ISO-9660 image. + if [[ -f "${work_dir}/iso/EFI/miso/${iso_name}.img" ]]; then + msg2 "Setting efi args. El Torito detected." + efi_boot_args=("-eltorito-alt-boot" \ + "-e EFI/miso/${iso_name}.img" \ + "-isohybrid-gpt-basdat" \ + "-no-emul-boot") + fi + + msg "Creating ISO image..." + ## Generate the BIOS+ISOHYBRID CD image using xorriso (extra/libisoburn package) in mkisofs emulation mode + #_qflag="" +# if ${QUIET}; then +# _qflag="-quiet" +# fi + xorriso -as mkisofs \ + -iso-level 3 -rock -joliet \ + -max-iso9660-filenames -omit-period \ + -omit-version-number \ + -relaxed-filenames -allow-lowercase \ + -volid "${iso_label}" \ + -appid "${iso_app_id}" \ + -publisher "${iso_publisher}" \ + -preparer "Prepared by manjaro-tools/${0##*/}" \ + -eltorito-boot isolinux/isolinux.bin \ + -eltorito-catalog isolinux/boot.cat \ + -no-emul-boot -boot-load-size 4 -boot-info-table \ + -isohybrid-mbr "${work_dir}/iso/isolinux/isohdpfx.bin" \ + ${efi_boot_args[@]} \ + -output "${cache_dir_iso}/${iso_file}" \ + "${work_dir}/iso/" + chown -R "${OWNER}:users" "${cache_dir_iso}" msg "Done [Build ISO]" } @@ -203,17 +320,17 @@ umount_image_handler(){ aufs_remove_image "${work_dir}/boot-image" } -mkiso_error_handler(){ - umount_image_handler - die "Exiting..." -} +# mkiso_error_handler(){ +# umount_image_handler +# die "Exiting..." +# } # Base installation (root-image) make_image_root() { if [[ ! -e ${work_dir}/build.${FUNCNAME} ]]; then msg "Prepare [Base installation] (root-image)" local path="${work_dir}/root-image" - mkiso ${create_args[*]} -p "${packages}" -i "root-image" create "${work_dir}" || mkiso_error_handler +# mkiso ${create_args[*]} -p "${packages}" -i "root-image" create "${work_dir}" || mkiso_error_handler pacman -Qr "${path}" > "${path}/root-image-pkgs.txt" configure_lsb "${path}" copy_overlay_root "${path}" @@ -230,7 +347,7 @@ make_image_custom() { mkdir -p ${path} umount_image_handler aufs_mount_root_image "${path}" - mkiso ${create_args[*]} -i "${custom}-image" -p "${packages}" create "${work_dir}" || mkiso_error_handler +# mkiso ${create_args[*]} -i "${custom}-image" -p "${packages}" create "${work_dir}" || mkiso_error_handler pacman -Qr "${path}" > "${path}/${custom}-image-pkgs.txt" cp "${path}/${custom}-image-pkgs.txt" ${cache_dir_iso}/${iso_name}-${custom}-${dist_release}-${arch}-pkgs.txt [[ -d ${custom}-overlay ]] && copy_overlay_custom @@ -255,7 +372,7 @@ make_image_livecd() { else aufs_mount_root_image "${path}" fi - mkiso ${create_args[*]} -i "livecd-image" -p "${packages}" create "${work_dir}" || mkiso_error_handler +# mkiso ${create_args[*]} -i "livecd-image" -p "${packages}" create "${work_dir}" || mkiso_error_handler pacman -Qr "${path}" > "${path}/livecd-image-pkgs.txt" copy_overlay_livecd "${path}" # copy over setup helpers and config loader @@ -535,70 +652,6 @@ compress_images(){ msg3 "Time ${FUNCNAME}: $(elapsed_time ${timer}) minutes" } -# $1: section -parse_section() { - local is_section=0 - while read line; do - [[ $line =~ ^\ {0,}# ]] && continue - [[ -z "$line" ]] && continue - if [ $is_section == 0 ]; then - if [[ $line =~ ^\[.*?\] ]]; then - line=${line:1:$((${#line}-2))} - section=${line// /} - if [[ $section == $1 ]]; then - is_section=1 - continue - fi - continue - fi - elif [[ $line =~ ^\[.*?\] && $is_section == 1 ]]; then - break - else - pc_key=${line%%=*} - pc_key=${pc_key// /} - pc_value=${line##*=} - pc_value=${pc_value## } - eval "$pc_key='$pc_value'" - fi - done < "${pacman_conf}" -} - -get_repos() { - local section repos=() filter='^\ {0,}#' - while read line; do - [[ $line =~ "${filter}" ]] && continue - [[ -z "$line" ]] && continue - if [[ $line =~ ^\[.*?\] ]]; then - line=${line:1:$((${#line}-2))} - section=${line// /} - case ${section} in - "options") continue ;; - *) repos+=("${section}") ;; - esac - fi - done < "${pacman_conf}" - echo ${repos[@]} -} - -clean_pacman_conf(){ - local repositories=$(get_repos) uri='file://' - msg "Cleaning [$1/etc/pacman.conf] ..." - for repo in ${repositories[@]}; do - case ${repo} in - 'options'|'core'|'extra'|'community'|'multilib') continue ;; - *) - msg2 "parsing [${repo}] ..." - parse_section ${repo} - if [[ ${pc_value} == $uri* ]]; then - msg2 "Removing local repo [${repo}] ..." - sed -i "/^\[${repo}/,/^Server/d" $1/etc/pacman.conf - fi - ;; - esac - done - msg "Done cleaning [$1/etc/pacman.conf]" -} - build_images(){ local timer=$(get_timer) load_pkgs "Packages" diff --git a/lib/util.sh b/lib/util.sh index 2ba49cb..5c90f7f 100644 --- a/lib/util.sh +++ b/lib/util.sh @@ -162,6 +162,71 @@ check_root() { fi } + +# $1: section +parse_section() { + local is_section=0 + while read line; do + [[ $line =~ ^\ {0,}# ]] && continue + [[ -z "$line" ]] && continue + if [ $is_section == 0 ]; then + if [[ $line =~ ^\[.*?\] ]]; then + line=${line:1:$((${#line}-2))} + section=${line// /} + if [[ $section == $1 ]]; then + is_section=1 + continue + fi + continue + fi + elif [[ $line =~ ^\[.*?\] && $is_section == 1 ]]; then + break + else + pc_key=${line%%=*} + pc_key=${pc_key// /} + pc_value=${line##*=} + pc_value=${pc_value## } + eval "$pc_key='$pc_value'" + fi + done < "${pacman_conf}" +} + +get_repos() { + local section repos=() filter='^\ {0,}#' + while read line; do + [[ $line =~ "${filter}" ]] && continue + [[ -z "$line" ]] && continue + if [[ $line =~ ^\[.*?\] ]]; then + line=${line:1:$((${#line}-2))} + section=${line// /} + case ${section} in + "options") continue ;; + *) repos+=("${section}") ;; + esac + fi + done < "${pacman_conf}" + echo ${repos[@]} +} + +clean_pacman_conf(){ + local repositories=$(get_repos) uri='file://' + msg "Cleaning [$1/etc/pacman.conf] ..." + for repo in ${repositories[@]}; do + case ${repo} in + 'options'|'core'|'extra'|'community'|'multilib') continue ;; + *) + msg2 "parsing [${repo}] ..." + parse_section ${repo} + if [[ ${pc_value} == $uri* ]]; then + msg2 "Removing local repo [${repo}] ..." + sed -i "/^\[${repo}/,/^Server/d" $1/etc/pacman.conf + fi + ;; + esac + done + msg "Done cleaning [$1/etc/pacman.conf]" +} + load_vars() { local var @@ -203,7 +268,7 @@ load_config(){ ################### if [[ -z ${repo_tree} ]];then - repo_tree=(core extra community multilib openrc) + repo_tree=('core' 'extra' 'community' 'multilib' 'openrc') fi if [[ -z ${host_tree} ]];then @@ -300,8 +365,16 @@ load_config(){ iso_label="${iso_label^^}" # all uppercase iso_label="${iso_label::8}" # limit to 8 characters + if [[ -z ${iso_publisher} ]];then + iso_publisher='Manjaro Linux ' + fi + + if [[ -z ${iso_app_id} ]];then + iso_app_id='Manjaro Linux Live/Rescue CD' + fi + if [[ -z ${iso_compression} ]];then - iso_compression=xz + iso_compression='xz' fi if [[ -z ${iso_checksum} ]];then @@ -375,10 +448,6 @@ load_profile_config(){ displaymanager="none" fi - if [[ -z ${keep_repos} ]];then - keep_repos=() - fi - return 0 }