b4da22f2cf
This change makes it so that the ARM image creation script uses DNF instead of urpmi. This affords several advantages: 1. Mageia images can be created from non-Mageia systems 2. Mageia images can be created from within Mock 3. ARM images can be created from x86_64 hosts 4. Image building can rely on pre-installed repo configurations This also brings us in line with the Docker image creation process, which also uses DNF.
1014 lines
32 KiB
Bash
Executable File
1014 lines
32 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
# Copyright (C) 2017-2018 Daniel Tartavel-jeannot <contact@librepc.com>
|
|
# Jean-Baptiste Biernacki <j.biernacki@free.fr>
|
|
#
|
|
# 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; either version 2 of the License, or
|
|
# (at your option) any later version.
|
|
#
|
|
# 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.
|
|
#
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
#Change the local to the most global
|
|
export LC_ALL=C
|
|
|
|
function WaitToContinue() {
|
|
read -p "Break... Press [ENTER] to continue." GARBAGE
|
|
}
|
|
|
|
function title() {
|
|
echo -e "\e[1;32m${1}\e[0m"
|
|
}
|
|
|
|
function info() {
|
|
echo -e "\e[36m${1}\e[0m"
|
|
}
|
|
|
|
function warning() {
|
|
echo -e "\e[1;35m${1}\e[0m"
|
|
}
|
|
|
|
function error() {
|
|
echo -e "\e[1;31m${1}\e[0m"
|
|
}
|
|
|
|
function help() {
|
|
echo -e "${CMDNAME} [option] [size of image in Go]"
|
|
echo -e "Options:"
|
|
echo -e "--all create ready to burn image of Mageia ${MAGEIA_VERSION}"
|
|
echo -e "--clean Clean all (suppress all) to make a new image"
|
|
echo -e "--size size of image default: 7Go"
|
|
echo -e "--build-path Path to the build directory of the image of Mageia ${MAGEIA_VERSION}"
|
|
echo -e "--target target system (for now rpi, odroid)"
|
|
echo -e "--target-version version of the target (0, 1, 2, 3 for rpi, 3 or 4 for odroid)"
|
|
echo -e "--config Path to config files"
|
|
echo -e "--bootfs filesystem of boot partition (ext4 or vfat) default: ext4"
|
|
echo -e "--nonfree activate nonfree repos"
|
|
echo -e "--tainted activate tainted repos"
|
|
|
|
echo -e "\nBuild levels:"
|
|
echo -e "--create-chroot Create the chroot directory"
|
|
echo -e "--install-basesystem install base system"
|
|
echo -e "--add-urpmimedia add mirrors for urpmi"
|
|
echo -e "--chroot chroot to arm directory and launch packages installation"
|
|
echo -e "--create-image Create the image of Mageia ${MAGEIA_VERSION}"
|
|
echo "--config Path to config files (rpi1 rpi2 rpi3 rpi3+ xu4)"
|
|
|
|
echo -e "\nFor image size, make sure it fit on physical support. (Default size is 7 Go)"
|
|
}
|
|
|
|
|
|
function verify_disk_space()
|
|
{
|
|
title "Verifying if there is enough space on disk to make the image"
|
|
DISK_SPACE=$(/usr/bin/df -BG --output=avail "${INSTALL_PATH}" | sed '1d;s/[^0-9]//g')
|
|
info "Free disk space: ${DISK_SPACE}G"
|
|
if [ ${DISK_SPACE} -lt ${IMAGE_SIZE} ]; then
|
|
warning "image size is greater than disk space"
|
|
info "correct the problem and relaunch the script with parameter --create-rpi-image"
|
|
info "${0} --size ${IMAGE_SIZE} --create-rpi-image"
|
|
return 1
|
|
fi
|
|
return 0
|
|
}
|
|
|
|
|
|
# creation of install path and copy of qemu ( installing it if not yet installed )
|
|
function createchroot()
|
|
{
|
|
title "Making chroot"
|
|
if ! [ -f /bin/qemu-arm-static ]; then
|
|
title "Qemu package not present : installing qemu packages"
|
|
/usr/bin/dnf --assumeyes --setopt=install_weak_deps=False install qemu-user-static
|
|
if [ ${?} -ne 0 ]; then
|
|
error "line ${LINENO} can't install qemu-user-static : exiting"
|
|
exit ${ERR_1}
|
|
fi
|
|
fi
|
|
# Starting qemu service if not started
|
|
/bin/systemctl is-active systemd-binfmt.service
|
|
if [ ${?} -ne 0 ]; then
|
|
title "Starting systemd-binfmt.service"
|
|
/bin/systemctl start systemd-binfmt.service
|
|
if [ ${?} -ne 0 ]; then
|
|
error "line ${LINENO} can't start qemu-user-static : exiting"
|
|
exit ${ERR_1}
|
|
fi
|
|
fi
|
|
return 0
|
|
}
|
|
|
|
# enabling extra Mageia repositories
|
|
function genusemirroroptions()
|
|
{
|
|
DNF_MIRROROPTS="--nogpgcheck --releasever=${MAGEIA_VERSION}"
|
|
if [ ! -z "${MIRROR}" ]; then
|
|
DNF_MIRROROPTS="${DNF_MIRROROPTS} --disablerepo=\* --repofrompath=mgarel,${MIRROR}/media/core/release/ --repofrompath=mgaup,${MIRROR}/media/core/updates/ --enablerepo=mgarel --enablerepo=mgaup"
|
|
if [ ${NONFREE} -eq 1 ]; then
|
|
DNF_MIRROROPTS="${DNF_MIRROROPTS} --repofrompath=mgarel-nonfree,${MIRROR}/media/nonfree/release/ --repofrompath=mgaup-nonfree,${MIRROR}/media/nonfree/updates/ --enablerepo=mgarel-nonfree --enablerepo=mgaup-nonfree"
|
|
fi
|
|
if [ ${TAINTED} -eq 1 ]; then
|
|
DNF_MIRROROPTS="${DNF_MIRROROPTS} --repofrompath=mgarel-tainted,${MIRROR}/media/tainted/release/ --repofrompath=mgaup-tainted,${MIRROR}/media/tainted/updates/ --enablerepo=mgarel-tainted --enablerepo=mgaup-tainted"
|
|
fi
|
|
fi
|
|
export DNF_MIRROROPTS
|
|
return 0
|
|
}
|
|
|
|
# enabling extra Mageia repositories
|
|
function enableextrarepos()
|
|
{
|
|
if [ "${MAGEIA_VERSION}" = "cauldron" ]; then
|
|
extrasect_baseprefix="cauldron"
|
|
extrasect_updatesprefix="cauldron-updates"
|
|
else
|
|
extrasect_baseprefix="mageia"
|
|
extrasect_updatesprefix="updates"
|
|
fi
|
|
if [ ${NONFREE} -eq 1 ]; then
|
|
title "activating non-free repos"
|
|
/usr/bin/dnf --installroot="${BUILD_PATH}" config-manager --set-enabled "${extrasect_baseprefix}-${ARM_VERSION}-nonfree" --set-enabled "${extrasect_updatesprefix}-${ARM_VERSION}-nonfree"
|
|
err=${?}
|
|
if [ ${err} -ne 0 ]; then
|
|
error "line ${LINENO} error ${err} - can't activate nonfree repositories : exiting"
|
|
exit ${ERR_1}
|
|
fi
|
|
fi
|
|
if [ ${TAINTED} -eq 1 ]; then
|
|
title "activating tainted repos"
|
|
/usr/bin/dnf --installroot="${BUILD_PATH}" config-manager --set-enabled "${extrasect_baseprefix}-${ARM_VERSION}-tainted" --set-enabled "${extrasect_updatesprefix}-${ARM_VERSION}-tainted"
|
|
err=${?}
|
|
if [ ${err} -ne 0 ]; then
|
|
error "line ${LINENO} error ${err} - can't activate tainted repositories : exiting"
|
|
exit ${ERR_1}
|
|
fi
|
|
fi
|
|
return 0
|
|
}
|
|
|
|
# adding Mageia urpmi repositories
|
|
function addurpmimedia()
|
|
{
|
|
title "Creating media ${MIRROR}"
|
|
|
|
info "Removing old media"
|
|
/sbin/urpmi.removemedia --urpmi-root "${BUILD_PATH}" -a
|
|
|
|
info "Adding media"
|
|
if [ ! -z "${MIRROR}" ] ; then
|
|
/sbin/urpmi.addmedia --urpmi-root "${BUILD_PATH}" --distrib "${MIRROR}"
|
|
else
|
|
info "MIRROR variable not set, using mirrorlist."
|
|
/sbin/urpmi.addmedia --urpmi-root "${BUILD_PATH}" --distrib --mirrorlist "http://mirrors.mageia.org/api/mageia.${MAGEIA_VERSION}.${ARM_VERSION}.list"
|
|
fi
|
|
|
|
err=${?}
|
|
if [ ${err} -ne 0 ]; then
|
|
error "line ${LINENO} error ${err} - can't add medias from ${MIRROR} : exiting"
|
|
exit ${ERR_1}
|
|
fi
|
|
if [ ${NONFREE} -eq 1 ]; then
|
|
title "activating non-free repos"
|
|
/sbin/urpmi.update --urpmi-root "${BUILD_PATH}" --no-ignore Nonfree\ Release Nonfree\ Updates
|
|
err=${?}
|
|
if [ ${err} -ne 0 ]; then
|
|
error "line ${LINENO} error ${err} - can't activate medias nonfree : exiting"
|
|
exit ${ERR_1}
|
|
fi
|
|
fi
|
|
if [ ${TAINTED} -eq 1 ]; then
|
|
title "activating tainted repos"
|
|
/sbin/urpmi.update --urpmi-root "${BUILD_PATH}" --no-ignore Tainted\ Release Tainted\ Updates
|
|
err=${?}
|
|
if [ ${err} -ne 0 ]; then
|
|
error "line ${LINENO} error ${err} - can't activate medias tainted : exiting"
|
|
exit ${ERR_1}
|
|
fi
|
|
fi
|
|
return 0
|
|
}
|
|
|
|
|
|
function installbasesystem()
|
|
{
|
|
# Create Build path
|
|
if ! [ -d "${BUILD_PATH}" ]; then
|
|
warning "Build path ( ${BUILD_PATH} ) does not exist, do you want to create it ? [Y|n] "
|
|
read yn
|
|
if [ -z ${yn} ] || [ ${yn} = "Y" ] || [ ${yn} = "y" ]; then
|
|
title "Creating ${BUILD_PATH}"
|
|
/bin/mkdir -p "${BUILD_PATH}/usr/bin" "${BUILD_PATH}/usr/lib/binfmt.d"
|
|
if [ ${?} -ne 0 ]; then
|
|
error "line ${LINENO} can't create ${BUILD_PATH} : exiting"
|
|
exit ${ERR_1}
|
|
fi
|
|
else
|
|
exit ${ERR_1}
|
|
fi
|
|
else
|
|
info "Build path exists"
|
|
fi
|
|
|
|
title "installing basesystem"
|
|
/usr/bin/dnf --installroot="${BUILD_PATH}" --setopt=ignorearch=True ${DNF_MIRROROPTS} --assumeyes install shadow-utils basesystem-minimal
|
|
if [ ${?} -ne 0 ]; then
|
|
error "line ${LINENO} error installing shadow-utils or basesystem-minimal : exiting"
|
|
exit ${ERR_1}
|
|
fi
|
|
#/usr/bin/dnf --installroot="${BUILD_PATH}" --setopt=ignorearch=True ${DNF_MIRROROPTS} --assumeyes install basesystem-minimal
|
|
#if [ ${?} -ne 0 ]; then
|
|
# error "line ${LINENO} error installing basesystem-minimal : exiting"
|
|
# exit ${ERR_1}
|
|
#fi
|
|
/usr/bin/dnf --installroot="${BUILD_PATH}" --setopt=ignorearch=True ${DNF_MIRROROPTS} --assumeyes install dnf dnf-plugins-core locales u-boot
|
|
if [ ${?} -ne 0 ]; then
|
|
error "line ${LINENO} error installing dnf or locales : exiting"
|
|
exit ${ERR_1}
|
|
fi
|
|
/usr/bin/dnf --installroot="${BUILD_PATH}" --setopt=ignorearch=True ${DNF_MIRROROPTS} --assumeyes install urpmi
|
|
if [ ${?} -ne 0 ]; then
|
|
error "line ${LINENO} error installing urpmi : exiting"
|
|
exit ${ERR_1}
|
|
fi
|
|
return 0
|
|
}
|
|
|
|
|
|
function preparechroot()
|
|
{
|
|
title "Preparing chrooting in ${BUILD_PATH}"
|
|
|
|
#Copying qemu
|
|
|
|
/bin/cp /bin/qemu-arm-static "${BUILD_PATH}/usr/bin/"
|
|
if [ ${?} -ne 0 ]; then
|
|
error "line ${LINENO} can't copy /bin/qemu-user-static to ${BUILD_PATH}/usr/bin/ : exiting"
|
|
exit ${ERR_1}
|
|
fi
|
|
/bin/cp /usr/lib/binfmt.d/qemu-arm-static.conf "${BUILD_PATH}/usr/lib/binfmt.d"
|
|
if [ ${?} -ne 0 ]; then
|
|
error "line ${LINENO} can't copy /usr/lib/binfmt.d/qemu-arm-static.conf to ${BUILD_PATH}/usr/lib/binfmt.d : exiting"
|
|
exit ${ERR_1}
|
|
fi
|
|
|
|
|
|
info "making /etc/hostname"
|
|
echo "${HOSTNAME}" > "${BUILD_PATH}/etc/hostname"
|
|
|
|
info "copying second stage script in ${BUILD_PATH}"
|
|
#echo "/bin/cp ${CONFIG_PATH}/second_stage_install.sh ${BUILD_PATH}/"
|
|
cp --preserve=mode "${CONFIG_PATH}/second_stage_install.sh" "${BUILD_PATH}/second_stage_install.sh"
|
|
if [ ${?} -ne 0 ]; then
|
|
error "line ${LINENO} error copying ${CONFIG_PATH}/second_stage_install.sh : exiting"
|
|
exit ${ERR_1}
|
|
fi
|
|
|
|
info "Preparation for setting root and user account"
|
|
if [ -n "${ROOT_PWD}" ]; then #If root password defined, it will be setted at the end of the chroot of the second_stage_install.sh script
|
|
echo -e " /bin/passwd << EOF\n${ROOT_PWD}\n${ROOT_PWD}\nEOF\n" >>"${BUILD_PATH}/second_stage_install.sh"
|
|
else
|
|
info "No root password... One password will be set at the first login."
|
|
echo -e " /bin/passwd -d root\n /bin/passwd -e root\n" >>"${BUILD_PATH}/second_stage_install.sh"
|
|
fi
|
|
|
|
if [ -n "${ID_USER}" ]; then #If user ID defined, it will be setted at the end of the chroot of the second_stage_install.sh script
|
|
echo -e " /sbin/useradd ${ID_USER}\n" >>"${BUILD_PATH}/second_stage_install.sh"
|
|
if [ -n "${PASSWORD}" ]; then
|
|
echo -e " /bin/passwd ${ID_USER} << EOF\n${PASSWORD}\n${PASSWORD}\nEOF" >>"${BUILD_PATH}/second_stage_install.sh"
|
|
else
|
|
echo -e " /bin/passwd -d ${ID_USER}\n" >>"${BUILD_PATH}/second_stage_install.sh"
|
|
fi
|
|
else
|
|
info "No user defined, no user account created."
|
|
fi
|
|
|
|
|
|
# info "Copying skel in root directory"
|
|
# /bin/rsync -rlptH "${BUILD_PATH}/etc/skel/" "${BUILD_PATH}/root/"
|
|
#This line break the default .bashrc file from the package "rootfiles" and the values as PATH (and /usr/sbin programs).
|
|
|
|
postPrepareChroot
|
|
if [ ${?} -ne 0 ]; then
|
|
error "line ${LINENO} error in postPrepareChroot function."
|
|
exit ${ERR_1}
|
|
fi
|
|
return 0
|
|
}
|
|
|
|
|
|
function jumpchroot()
|
|
{
|
|
title "chrooting to ${BUILD_PATH}"
|
|
info "mounting dev, sys, proc directories in chroot"
|
|
/bin/mount -B /dev "${BUILD_PATH}/dev"
|
|
if [ ${?} -ne 0 ]; then
|
|
error "line ${LINENO} error mounting ${BUILD_PATH}/dev : exiting"
|
|
exit ${ERR_1}
|
|
fi
|
|
/bin/mount -B /sys "${BUILD_PATH}/sys"
|
|
if [ ${?} -ne 0 ]; then
|
|
error "line ${LINENO} error mounting ${BUILD_PATH}/sys : exiting"
|
|
exit ${ERR_1}
|
|
fi
|
|
/bin/mount -B /proc "${BUILD_PATH}/proc"
|
|
if [ ${?} -ne 0 ]; then
|
|
error "line ${LINENO} error mounting ${BUILD_PATH}/proc : exiting"
|
|
exit ${ERR_1}
|
|
fi
|
|
info "Copying resolv.conf"
|
|
/bin/cp -v --preserve=mode /etc/resolv.conf "${BUILD_PATH}/etc/"
|
|
if [ ${?} -ne 0 ]; then
|
|
error "line ${LINENO} error copying ${BUILD_PATH}/etc/resolv.conf : exiting"
|
|
exit ${ERR_1}
|
|
fi
|
|
if [ "$OPT" = "chroot" ]; then
|
|
/sbin/chroot "${BUILD_PATH}"
|
|
else
|
|
/sbin/chroot --userspec root:root "${BUILD_PATH}" /bin/bash -v -c 'bash /second_stage_install.sh 2>&1'
|
|
fi
|
|
RET=${?}
|
|
if [ ${RET} -ne 0 ]; then
|
|
error "line ${LINENO} Warning : chrooting to ${BUILD_PATH} retrurn an error ${RET}"
|
|
ERRORN=$((${ERRORN}+1))
|
|
fi
|
|
info "unmounting dev, sys, proc"
|
|
/bin/umount -lf "${BUILD_PATH}/dev"
|
|
if [ ${?} -ne 0 ]; then
|
|
warning "line ${LINENO} Warning : error unmounting ${BUILD_PATH}/dev, continuing anyway"
|
|
ERRORN=$((${ERRORN}+1))
|
|
fi
|
|
/bin/umount -lf "${BUILD_PATH}/sys"
|
|
if [ ${?} -ne 0 ]; then
|
|
warning "line ${LINENO} Warning : error unmounting ${BUILD_PATH}/sys, continuing anyway"
|
|
ERRORN=$((${ERRORN}+1))
|
|
fi
|
|
/bin/umount -lf "${BUILD_PATH}/proc"
|
|
if [ ${?} -ne 0 ]; then
|
|
warning "line ${LINENO} Warning : error unmounting ${BUILD_PATH}/proc, continuing anyway"
|
|
ERRORN=$((${ERRORN}+1))
|
|
fi
|
|
return 0
|
|
}
|
|
|
|
|
|
function createImageWrap()
|
|
{
|
|
title "Wrap image creation"
|
|
preImgCreation
|
|
if [ ${?} -ne 0 ]; then
|
|
error "line ${LINENO} error in the process ${CONFIG_PATH}/specialFunctions.sh ."
|
|
exit ${ERR_1}
|
|
fi
|
|
createimage
|
|
if [ -z "${BOOTFS}" ]; then
|
|
BOOTFS="ext4"
|
|
fi
|
|
formatpartitions ${BOOTFS} ext4
|
|
|
|
return 0
|
|
}
|
|
|
|
|
|
function createimage()
|
|
{
|
|
title " in ${IMAGE}"
|
|
if [ -f "${INSTALL_PATH}/${IMAGE}" ]; then
|
|
warning "Deleting previous image"
|
|
/bin/rm -f "${INSTALL_PATH}/${IMAGE}"
|
|
if [ ${?} -ne 0 ]; then
|
|
error "line ${LINENO} error can't remove previous image at ${INSTALL_PATH}/${IMAGE} : exiting"
|
|
exit ${ERR_1}
|
|
fi
|
|
fi
|
|
|
|
warning "please wait until end of image creation"
|
|
/bin/dd if=/dev/zero of="${INSTALL_PATH}/${IMAGE}" bs=1MB count=$(( ${IMAGE_SIZE} * 1024 ))
|
|
if [ ${?} -ne 0 ]; then
|
|
error "line ${LINENO} can't make image at ${INSTALL_PATH}/${IMAGE} : exiting"
|
|
exit ${ERR_1}
|
|
fi
|
|
|
|
loopingImage
|
|
|
|
bunrningBootloader
|
|
if [ ${?} -ne 0 ]; then
|
|
error "line ${LINENO} error in the process ${CONFIG_PATH}/specialFunctions.sh ."
|
|
exit ${ERR_1}
|
|
fi
|
|
|
|
info "making partitions"
|
|
echo -e "${FDISK_SCRIPT}" | /sbin/fdisk ${DEVICE}
|
|
|
|
#Activate 'pY' : /dev/loopXpY
|
|
partx -vu "${DEVICE}"
|
|
#Previous function give us a list of partition. It is easy to get it and define prior this list the partition.
|
|
#But... How to distinguish between the boot p1 and the root p2 if both are empty and ext4 ? ...
|
|
|
|
if [ 1 -eq ${SEPARATE_BOOT_PARTITION} ]; then
|
|
BOOTP="${DEVICE}p1"
|
|
ROOTP="${DEVICE}p2"
|
|
else
|
|
ROOTP="${DEVICE}p1"
|
|
fi
|
|
return 0
|
|
}
|
|
|
|
|
|
function loopingImage()
|
|
{
|
|
title "Looping image ..."
|
|
|
|
# Mettre en place et contrôler des périphériques boucle.
|
|
# -f, --find trouver le premier périphérique inutilisé
|
|
# --show afficher le nom du périphérique après configuration (avec -f)
|
|
DEVICE=$(/sbin/losetup -f --show "${INSTALL_PATH}/${IMAGE}")
|
|
|
|
return 0
|
|
}
|
|
|
|
|
|
function formatpartitions()
|
|
{
|
|
info "Formatting partitions"
|
|
if [ 1 -eq ${SEPARATE_BOOT_PARTITION} ]; then
|
|
info "Boot : ${BOOTP} as ${1}"
|
|
"/sbin/mkfs.${1}" "${BOOTP}"
|
|
if [ ${?} -ne 0 ]; then
|
|
error "line ${LINENO} error formating ${BOOTP} : exiting"
|
|
/sbin/losetup -d "${DEVICE}"
|
|
exit ${ERR_1}
|
|
fi
|
|
BOOT_UUID=$(blkid -s UUID -o value UUID "${BOOTP}")
|
|
info "Boot UUID: ${BOOT_UUID}"
|
|
fi
|
|
|
|
info "Root : ${ROOTP} as ${2}"
|
|
"/sbin/mkfs.${2}" "${ROOTP}"
|
|
if [ ${?} -ne 0 ]; then
|
|
error "line ${LINENO} error formating ${ROOTP} : exiting"
|
|
/sbin/losetup -d "${DEVICE}"
|
|
exit ${ERR_1}
|
|
fi
|
|
ROOT_UUID=$(blkid -s UUID -o value UUID "${ROOTP}")
|
|
info "Root UUID: ${ROOT_UUID}"
|
|
|
|
return 0
|
|
}
|
|
|
|
function generateExtlinux()
|
|
{
|
|
info "Generate extlinux if extlinux.conf exists."
|
|
if [ -e "${CONFIG_PATH}/extlinux.conf" ]; then
|
|
info "\tFound extlinux.conf"
|
|
if [ ! -d "${BUILD_PATH}/boot/extlinux" ]; then
|
|
info "making /boot/extlinux/extlinux.conf"
|
|
/bin/rm -rf "${BUILD_PATH}/boot/extlinux"
|
|
mkdir -p "${BUILD_PATH}/boot/extlinux"
|
|
fi
|
|
if [ ! -f "${BUILD_PATH}/boot/extlinux/extlinux.conf" ]; then
|
|
info "\tTuning extlinux.conf"
|
|
cp "${CONFIG_PATH}/extlinux.conf" "${BUILD_PATH}/boot/extlinux/extlinux.conf"
|
|
#In order to use the UUID, a initrd file is necessary.
|
|
sed -i -e "s/<UUID>/${ROOT_UUID}/g" "${BUILD_PATH}/boot/extlinux/extlinux.conf"
|
|
sed -i -e "s/<BOOT_ARGS>/${BOOT_ARGS}/g" "${BUILD_PATH}/boot/extlinux/extlinux.conf"
|
|
KERNEL_ID=$(basename ${BUILD_PATH}/usr/lib/linux-*)
|
|
sed -i -e "s/<FDTDIR>/${KERNEL_ID}/g" "${BUILD_PATH}/boot/extlinux/extlinux.conf"
|
|
fi
|
|
fi
|
|
}
|
|
|
|
function copyingsystem()
|
|
{
|
|
generateExtlinux
|
|
|
|
info "Remove second_stage_install.sh"
|
|
/bin/rm -f "${BUILD_PATH}/second_stage_install.sh"
|
|
|
|
if [ 1 -eq ${SEPARATE_BOOT_PARTITION} ]; then
|
|
ARM_BOOT="${BUILD_PATH}/mnt/arm_boot"
|
|
if ! [ -d "${ARM_BOOT}" ]; then
|
|
rm -rf "${ARM_BOOT}"
|
|
mkdir -p "${ARM_BOOT}"
|
|
fi
|
|
info "copying Mageia image to root partition"
|
|
/bin/rsync -rlptogDH --exclude "${ARM_BOOT}/" --exclude "qemu-arm-static*" "${BUILD_PATH}/" "${ROOT}/"
|
|
/bin/rsync -rlptogDH "${ARM_BOOT}/" "${BOOT}/"
|
|
/bin/rsync -rlptogDH "${BUILD_PATH}/boot/" "${BOOT}/"
|
|
else
|
|
info "copying Mageia image to root partition"
|
|
/bin/rsync -rlptogDH --exclude "qemu-arm-static*" "${BUILD_PATH}/" "${ROOT}/"
|
|
fi
|
|
|
|
copyingCustomSystem
|
|
if [ ${?} -ne 0 ]; then
|
|
error "line ${LINENO} error in the process ${CONFIG_PATH}/specialFunctions.sh ."
|
|
exit ${ERR_1}
|
|
fi
|
|
|
|
copyingcommon
|
|
|
|
sync
|
|
warning "You can now burn the image ( ${INSTALL_PATH}/${IMAGE} ) on SD card"
|
|
return 0
|
|
}
|
|
|
|
|
|
function mountPartitions(){
|
|
info "mounting partitions, making mountpoint if necessary"
|
|
|
|
if [ 1 -eq ${SEPARATE_BOOT_PARTITION} ]; then
|
|
if ! [ -d "${BOOT}" ]; then
|
|
/bin/mkdir "${BOOT}"
|
|
if [ ${?} -ne 0 ]; then
|
|
error "line ${LINENO} error making directory ${BOOT} : exiting"
|
|
exit ${ERR_1}
|
|
fi
|
|
fi
|
|
/bin/mount "${BOOTP}" "${BOOT}"
|
|
if [ ${?} -ne 0 ]; then
|
|
error "line ${LINENO} error mounting ${BOOTP} : exiting"
|
|
exit ${ERR_1}
|
|
fi
|
|
fi
|
|
|
|
if ! [ -d "${ROOT}" ]; then
|
|
/bin/mkdir "${ROOT}"
|
|
if [ ${?} -ne 0 ]; then
|
|
error "line ${LINENO} error making directory ${ROOT} : exiting"
|
|
exit ${ERR_1}
|
|
fi
|
|
fi
|
|
/bin/mount "${ROOTP}" "${ROOT}"
|
|
if [ ${?} -ne 0 ]; then
|
|
error "line ${LINENO} error mounting ${ROOTP} : exiting"
|
|
exit ${ERR_1}
|
|
fi
|
|
}
|
|
|
|
|
|
function unmountingPartitions()
|
|
{
|
|
title "Unmounting partitions..."
|
|
|
|
# Syncing devices before unmounting
|
|
/usr/bin/sync
|
|
|
|
if [ -z "${BOOTP}" ] && [ -z "${ROOTP}" ] ; then
|
|
warning "Root partition and Boot partition not defined !"
|
|
|
|
for LOOP in $(losetup -l -O NAME,BACK-FILE -n | grep "${IMAGE}" | cut -d ' ' -f 1 ) ; do
|
|
IFS=$'\n'
|
|
for PARTITION in $(mount -l | grep ${LOOP}); do
|
|
MOUNTPOINT=$(echo "$PARTITION" | cut -d ' ' -f 3)
|
|
PARTITION=$(echo "$PARTITION" | cut -d ' ' -f 1)
|
|
info "unmount ${PARTITION} and remove ${MOUNTPOINT}"
|
|
/usr/bin/umount "${PARTITION}"
|
|
if [ ${?} -eq 0 ]; then
|
|
/bin/rmdir "${MOUNTPOINT}"
|
|
else
|
|
error "line ${LINENO} error unmounting ${BOOT}..."
|
|
fi
|
|
done
|
|
unset IFS
|
|
done
|
|
else
|
|
if [ ! -z "${BOOTP}" ]; then
|
|
/usr/bin/umount "${BOOTP}"
|
|
if [ ${?} -eq 0 ]; then
|
|
/bin/rmdir "${BOOT}"
|
|
else
|
|
error "line ${LINENO} error unmounting ${BOOT}..."
|
|
fi
|
|
fi
|
|
/usr/bin/umount "${ROOTP}"
|
|
if [ ${?} -eq 0 ]; then
|
|
/bin/rmdir "${ROOT}"
|
|
else
|
|
error "line ${LINENO} error unmounting ${ROOT}..."
|
|
fi
|
|
fi
|
|
return 0
|
|
}
|
|
|
|
|
|
function unloopingImage(){
|
|
title "Unlooping image..."
|
|
# Syncing devices before unmounting
|
|
/usr/bin/sync
|
|
|
|
# [root@jabztop mageia4arm (master)]# losetup -l -O NAME,BACK-FILE -n
|
|
# /dev/loop0 /home/jibz/workspaces/mageia4arm/build/Mageia-7-bananaPro1.img (deleted)
|
|
info "Looped devices to unmount : $(losetup -l -O NAME,BACK-FILE -n | grep "${IMAGE}" | cut -d ' ' -f 1 ) "
|
|
|
|
for LOOP in $(losetup -l -O NAME,BACK-FILE -n | grep "${IMAGE}" | cut -d ' ' -f 1 ) ; do
|
|
info "removing ${LOOP}"
|
|
for PARTITION in ${LOOP}p* ; do
|
|
partx -dv "${PARTITION}"
|
|
done
|
|
# losetup -d "${LOOP}"
|
|
kpartx -d "${INSTALL_PATH}/${IMAGE}"
|
|
done
|
|
|
|
return 0
|
|
}
|
|
|
|
|
|
# Copying files common to all systems
|
|
function copyingcommon()
|
|
{
|
|
title "Copying common files and configuration"
|
|
rsync -rlptDH "${SOURCE_PATH}/common/" "${ROOT}/"
|
|
rsync -rlptDH "${SOURCE_PATH}/tools/"*.sh "${ROOT}/usr/local/bin/"
|
|
chown root:root "${ROOT}/usr/local/bin/"
|
|
return 0
|
|
}
|
|
|
|
|
|
function mkfstab()
|
|
{
|
|
title "making /etc/fstab"
|
|
### BUG : /mnt/arm_boot is set to vfat for all plateforms, odroid configuration says ext4.
|
|
#echo -e "proc /proc proc defaults 0 0\nUUID=${BOOT_UUID} /mnt/arm_boot vfat defaults 0 0\nUUID=${ROOT_UUID} / ext4 defaults 0 0" > "${BUILD_PATH}/etc/fstab"
|
|
#echo -e "proc\t/proc\tproc\tdefaults\t0\t0\nUUID=${BOOT_UUID}\t/mnt/arm_boot\t${BOOTFS}\tdefaults\t0\t0\nUUID=${ROOT_UUID}\t/\text4\tdefaults\t0\t0" > "${BUILD_PATH}/etc/fstab"
|
|
if [ 1 -eq ${SEPARATE_BOOT_PARTITION} ]; then
|
|
echo -e "proc\t/proc\tproc\tdefaults\t0\t0\nUUID=${BOOT_UUID}\t/mnt/arm_boot\t${BOOTFS}\tdefaults\t0\t0\nUUID=${ROOT_UUID}\t/\text4\tdefaults\t0\t0" > "${BUILD_PATH}/etc/fstab"
|
|
else
|
|
echo -e "proc\t/proc\tproc\tdefaults\t0\t0\nUUID=${ROOT_UUID}\t/\text4\tdefaults\t0\t0" > "${BUILD_PATH}/etc/fstab"
|
|
fi
|
|
return 0
|
|
}
|
|
|
|
|
|
# cleaning build space
|
|
function clean()
|
|
{
|
|
title "Cleaning"
|
|
|
|
unmountingPartitions
|
|
unloopingImage
|
|
|
|
# Removing old Build directory
|
|
if [ -d "${BUILD_PATH}" ]; then
|
|
info "Removing ${BUILD_PATH}"
|
|
/bin/rm -Rf "${BUILD_PATH}"
|
|
else
|
|
warning "${BUILD_PATH} does not exists"
|
|
fi
|
|
# removing old image
|
|
if [ -e "${INSTALL_PATH}/${IMAGE}" ]; then
|
|
info "Removing ${IMAGE}"
|
|
/bin/rm -f "${INSTALL_PATH}/${IMAGE}"
|
|
else
|
|
warning "${IMAGE} does not exists"
|
|
fi
|
|
|
|
return 0
|
|
}
|
|
|
|
|
|
function preImgCreation()
|
|
{
|
|
error "This function is called if no sourced file about fdisk was lauched."
|
|
return 1
|
|
}
|
|
|
|
function postPrepareChroot()
|
|
{
|
|
error "This function is called if no sourced file is containing postPrepareChroot function."
|
|
return 1
|
|
}
|
|
|
|
function bunrningBootloader()
|
|
{
|
|
error "This function is called if no sourced file is containing bunrningBootloader function."
|
|
return 1
|
|
}
|
|
|
|
function copyingCustomSystem()
|
|
{
|
|
error "This function is called if no sourced file is containing bunrningBootloader function."
|
|
return 1
|
|
}
|
|
|
|
|
|
|
|
ERRORN=0
|
|
ERR_1=1
|
|
ERR_DEFAULT_CONFIG=2
|
|
ERR_NO_CONFIG_FILE=3
|
|
ERR_NOT_ROOT=4
|
|
ERR_DEPENDENCY_MISSING=5
|
|
ERR_NO_SPACE=6
|
|
ERR_7=7
|
|
ERR_8=8
|
|
ERR_9=9
|
|
|
|
SEPARATE_BOOT_PARTITION=1
|
|
|
|
#######################
|
|
# PROGRAMM START HERE #
|
|
#######################
|
|
|
|
|
|
info ${0}
|
|
|
|
#Check dependencies :
|
|
#if [ -e /usr/bin/qemu-arm-static ]; then
|
|
# error "qemu-user-static package is needed."
|
|
# exit ${ERR_DEPENDENCY_MISSING}
|
|
#fi
|
|
#if [ 0 -ne $(id -u) ]; then
|
|
# error "Script need to be run as root."
|
|
# exit ${ERR_NOT_ROOT}
|
|
#fi
|
|
|
|
SOURCE_PATH="$(/bin/dirname "$(readlink -f "${0}")")"
|
|
INSTALL_PATH="$(pwd)/build"
|
|
# FILES_PATH="${SOURCE_PATH}/files"
|
|
PLATFORMS_PATH="${SOURCE_PATH}/platforms"
|
|
|
|
CMDNAME=$(/bin/basename "${0}")
|
|
|
|
|
|
if [ ${#} == 0 ]; then
|
|
help
|
|
exit
|
|
fi
|
|
|
|
|
|
# parsing commandline
|
|
TEMP=$(getopt -o h,a --long all,help,clean,create-chroot,add-urpmimedia,create-image,,config:,target:,target-version:,chroot,bootfs:,install-basesystem,update-mirror,build-path:,size:,nonfree,tainted -n ${CMDNAME} -- "${@}")
|
|
if [ ${?} -ne 0 ] ; then error "line ${LINENO} Failed parsing options." >&2 ; exit ${ERR_1} ; fi
|
|
eval set -- "${TEMP}"
|
|
|
|
echo "${TEMP}"
|
|
# Note the quotes around `$TEMP': they are essential! Or not, $( ) do the same as ` `. But there are the ` ' used ?
|
|
while true; do
|
|
case "${1}" in
|
|
-h|--help)
|
|
help
|
|
exit 0
|
|
;;
|
|
-a|--all)
|
|
OPT="all"
|
|
shift 1
|
|
;;
|
|
--clean)
|
|
OPT="clean"
|
|
shift
|
|
;;
|
|
--size)
|
|
IMAGE_SIZE_P=${2}
|
|
shift 2
|
|
;;
|
|
--build-path)
|
|
INSTALL_PATH_P=$(readlink -f "${2}")
|
|
shift 2
|
|
;;
|
|
--chroot)
|
|
if [ -z ${OPT} ]; then
|
|
OPT="chroot"
|
|
fi
|
|
shift
|
|
;;
|
|
--create-chroot)
|
|
if [ -z ${OPT} ]; then
|
|
OPT="createchroot"
|
|
fi
|
|
shift
|
|
;;
|
|
--add-urpmimedia)
|
|
if [ -z ${OPT} ]; then
|
|
OPT="addurpmimedia"
|
|
fi
|
|
shift
|
|
;;
|
|
--update-mirror)
|
|
if [ -z ${OPT} ]; then
|
|
OPT="updatemirror"
|
|
fi
|
|
shift
|
|
;;
|
|
--install-basesystem)
|
|
if [ -z ${OPT} ]; then
|
|
OPT="installbasesystem"
|
|
fi
|
|
shift
|
|
;;
|
|
--create-image)
|
|
if [ -z ${OPT} ]; then
|
|
CREATEIMAGE=true
|
|
OPT="createimage"
|
|
fi
|
|
shift
|
|
;;
|
|
--target)
|
|
TARGET_P=${2}
|
|
shift 2
|
|
;;
|
|
--target-version)
|
|
TARGET_VERSION_P=${2}
|
|
shift 2
|
|
;;
|
|
--config)
|
|
CONFIG_PATH="${PLATFORMS_PATH}/${2}"
|
|
shift 2
|
|
;;
|
|
--bootfs)
|
|
BOOTFS_P=${2}
|
|
shift 2
|
|
;;
|
|
--nonfree)
|
|
NONFREE_P=1
|
|
shift
|
|
;;
|
|
--tainted)
|
|
TAINTED_P=1
|
|
shift
|
|
;;
|
|
--)
|
|
shift
|
|
break;;
|
|
*)
|
|
error "Parameter ${1} does not exists "
|
|
exit ${ERR_1};;
|
|
esac
|
|
done
|
|
|
|
|
|
# path of config file
|
|
if ! [ -d "${CONFIG_PATH}" ]; then
|
|
info " Config path does not exists, defaulting to ./platforms/${TARGET}"
|
|
CONFIG_PATH="${PLATFORMS_PATH}/${TARGET}"
|
|
warning "Do you want to create it and to copy the template file in? [Y|n] "
|
|
read yn
|
|
if [ -z ${yn} ] || [ ${yn} = "Y" ] || [ ${yn} = "y" ]; then
|
|
/usr/bin/mkdir "${CONFIG_PATH}/"
|
|
/usr/bin/cp --preserve=mode "${SOURCE_PATH}/mageia4arm.cfg.template" "${CONFIG_PATH}/mageia4arm.cfg"
|
|
warning "You need now to modify the config file (${CONFIG_PATH}/mageia4arm.cfg) and relaunch the script"
|
|
exit ${ERR_DEFAULT_CONFIG}
|
|
else
|
|
error "Error: Can't continue without config file, exiting"
|
|
exit ${ERR_NO_CONFIG_FILE}
|
|
fi
|
|
fi
|
|
|
|
if [ -e "${CONFIG_PATH}/mageia4arm.cfg" ]; then
|
|
info "using ${CONFIG_PATH}/mageia4arm.cfg as config"
|
|
source "${CONFIG_PATH}/mageia4arm.cfg" #NOTE1 : Here is sourced a file with variables.
|
|
else
|
|
warning "Config file does not exists, do you want to copy template ? [Y|n] "
|
|
read yn
|
|
if [ -z ${yn} ] || [ ${yn} = "Y" ] || [ ${yn} = "y" ]; then
|
|
/usr/bin/cp --preserve=mode "${SOURCE_PATH}/mageia4arm.cfg.template" "${CONFIG_PATH}/mageia4arm.cfg"
|
|
warning "You need now to modify the config file (${CONFIG_PATH}/mageia4arm.cfg) and relaunch the script"
|
|
exit ${ERR_DEFAULT_CONFIG}
|
|
fi
|
|
fi
|
|
|
|
if ! [ -z "${IMAGE_SIZE_P}" ]; then
|
|
IMAGE_SIZE=${IMAGE_SIZE_P}
|
|
fi
|
|
if ! [ -z "${INSTALL_PATH_P}" ]; then
|
|
INSTALL_PATH=${INSTALL_PATH_P}
|
|
fi
|
|
if ! [ -z "${TARGET_P}" ]; then
|
|
TARGET=${TARGET_P}
|
|
fi
|
|
if ! [ -z "${TARGET_VERSION_P}" ]; then
|
|
TARGET_VERSION=${TARGET_VERSION_P}
|
|
fi
|
|
if ! [ -z "${BOOTFS_P}" ]; then
|
|
BOOTFS=${BOOTFS_P}
|
|
fi
|
|
if ! [ -z "${NONFREE_P}" ]; then
|
|
NONFREE=${NONFREE_P}
|
|
else
|
|
NONFREE=0
|
|
fi
|
|
if ! [ -z "${TAINTED_P}" ]; then
|
|
TAINTED=${TAINTED_P}
|
|
else
|
|
TAINTED=0
|
|
fi
|
|
|
|
info "Option: "${OPT}
|
|
|
|
IMAGE="Mageia-${MAGEIA_VERSION}-${TARGET}${TARGET_VERSION}.img"
|
|
BOOT="/mnt/boot"
|
|
ROOT="/mnt/root"
|
|
BUILD_PATH="${INSTALL_PATH}/build-${TARGET}${TARGET_VERSION}"
|
|
ARM_VERSION="armv7hl"
|
|
|
|
# Assigne a script for creating a particular target image (rpi, odroid, ...)
|
|
if [ -e "${CONFIG_PATH}/specialFunctions.sh" ]; then
|
|
source "${CONFIG_PATH}/specialFunctions.sh"
|
|
fi
|
|
|
|
info "target : ${TARGET}"
|
|
info "target_version : ${TARGET_VERSION}"
|
|
info "source path: ${SOURCE_PATH}"
|
|
info "Install path: ${INSTALL_PATH}"
|
|
info "Build path: ${BUILD_PATH}"
|
|
info "Commande : ${CMDNAME}"
|
|
info "Firmware path : ${FIRMWARE_PATH}"
|
|
info "Firmware dir : ${FIRMWARE_DIR}"
|
|
|
|
# Defining default image size to 7 go
|
|
if [[ "${IMAGE_SIZE}" -lt 2 ]] || [[ "${IMAGE_SIZE}" -gt 128 ]]; then
|
|
IMAGE_SIZE=7
|
|
fi
|
|
|
|
# change dir to install path and create it if not existing
|
|
if [ "${OPT}" != "clean" ]; then
|
|
info "cd ${INSTALL_PATH}"
|
|
if ! [ -e "${INSTALL_PATH}" ]; then
|
|
/bin/mkdir -p "${INSTALL_PATH}"
|
|
if [ -z ${?} ]; then
|
|
error "line ${LINENO} can't make directory ${INSTALL_PATH} , exiting"
|
|
exit ${ERR_1}
|
|
fi
|
|
fi
|
|
cd "${INSTALL_PATH}"
|
|
if [ -z ${?} ]; then
|
|
error "line ${LINENO} can't change to directory ${INSTALL_PATH} , exiting"
|
|
exit ${ERR_1}
|
|
fi
|
|
fi
|
|
|
|
#if no parameters then display help message
|
|
if [ -z ${OPT} ]; then
|
|
OPT="--help"
|
|
fi
|
|
|
|
info "Image size is: ${IMAGE_SIZE} GB"
|
|
|
|
case ${OPT} in
|
|
"clean")
|
|
clean
|
|
;;
|
|
"all")
|
|
verify_disk_space
|
|
if [ ${?} -ne 0 ]; then
|
|
echo -e "Not enough space on disk\nDo you want to continue anyway ? [Y,n]"
|
|
read yn
|
|
if [ ${yn} = "n" ]; then
|
|
exit ${ERR_NO_SPACE}
|
|
fi
|
|
fi
|
|
createImageWrap #Create the empty .img
|
|
createchroot #Check qemu and activate it
|
|
genusemirroroptions #Generate mirror options, if needed
|
|
installbasesystem #Generate the rootfs, rootfiles, ...
|
|
enableextrarepos
|
|
addurpmimedia
|
|
mkfstab
|
|
preparechroot
|
|
jumpchroot
|
|
#Check before is useless (with $MIRROR
|
|
info "Use mirrorlist to light one server."
|
|
MIRROR=
|
|
genusemirroroptions
|
|
enableextrarepos
|
|
addurpmimedia
|
|
mountPartitions
|
|
copyingsystem
|
|
unmountingPartitions
|
|
unloopingImage
|
|
;;
|
|
"createchroot")
|
|
createchroot
|
|
;;
|
|
"chroot")
|
|
jumpchroot
|
|
;;
|
|
"addurpmimedia")
|
|
addurpmimedia
|
|
;;
|
|
"createimage")
|
|
verify_disk_space
|
|
if [ ${?} -ne 0 ]; then
|
|
warning "Not enough space on disk"
|
|
exit ${ERR_NO_SPACE}
|
|
fi
|
|
createImageWrap
|
|
;;
|
|
"installbasesystem")
|
|
installbasesystem
|
|
;;
|
|
esac
|
|
|
|
|
|
if [ ${ERRORN} -ne 0 ]; then
|
|
warning "Some errors occurs : ${ERRORN} errors"
|
|
fi
|
|
|
|
exit ${ERRORN}
|