Files
Arch-R/scripts/mkimage
vpeter4 1edd8b4724 scripts/mkimage: show message when temp folder is full
If temporary folder is full error message can't be saved and shown to the user which doesn't know what the problem actually is. In this case file is empty and show other message.
2018-11-21 14:24:17 +01:00

341 lines
12 KiB
Bash
Executable File

#!/bin/bash
# SPDX-License-Identifier: GPL-2.0-or-later
# Copyright (C) 2009-2016 Stephan Raue (stephan@openelec.tv)
# Copyright (C) 2016-present Team LibreELEC (https://libreelec.tv)
################################################################################
# variables such as $ROOT $PATH etc... that are required for this
# script to work must be passed via env ... in scripts/image
################################################################################
# set variables
LE_TMP=$(mktemp -d)
SAVE_ERROR="${LE_TMP}/save_error"
if [ -z "${SYSTEM_SIZE}" -o -z "${SYSTEM_PART_START}" ]; then
echo "mkimage: SYSTEM_SIZE and SYSTEM_PART_START must be configured!"
exit 1
fi
if [ "${BOOTLOADER}" = "syslinux" ]; then
DISK_LABEL=gpt
else
DISK_LABEL=msdos
fi
STORAGE_SIZE=32 # STORAGE_SIZE must be >= 32 !
DISK_START_PADDING=$(( (${SYSTEM_PART_START} + 2048 - 1) / 2048 ))
DISK_GPT_PADDING=1
DISK_SIZE=$(( ${DISK_START_PADDING} + ${SYSTEM_SIZE} + ${STORAGE_SIZE} + ${DISK_GPT_PADDING} ))
DISK_BASENAME="${TARGET_IMG}/${IMAGE_NAME}"
DISK="${DISK_BASENAME}.img"
# functions
cleanup() {
echo -e "image: cleanup...\n"
rm -rf "${LE_TMP}"
}
show_error() {
echo "image: An error has occurred..."
echo
if [ -s "${SAVE_ERROR}" ]; then
cat "${SAVE_ERROR}"
else
echo "Folder $LE_TMP might be out of free space..."
fi
echo
cleanup
die
}
trap cleanup SIGINT
# generate volume id for fat partition
UUID_1=$(date '+%d%m')
UUID_2=$(date '+%M%S')
FAT_SERIAL_NUMBER="${UUID_1}${UUID_2}"
UUID_SYSTEM="${UUID_1}-${UUID_2}"
# create an image
echo -e "\nimage: creating file $(basename ${DISK})..."
dd if=/dev/zero of="${DISK}" bs=1M count="${DISK_SIZE}" conv=fsync >"${SAVE_ERROR}" 2>&1 || show_error
# write a disklabel
echo "image: creating ${DISK_LABEL} partition table..."
parted -s "${DISK}" mklabel ${DISK_LABEL}
sync
# create part1
echo "image: creating part1..."
SYSTEM_PART_END=$(( ${SYSTEM_PART_START} + (${SYSTEM_SIZE} * 1024 * 1024 / 512) - 1 ))
if [ "${DISK_LABEL}" = "gpt" ]; then
parted -s "${DISK}" -a min unit s mkpart system fat32 ${SYSTEM_PART_START} ${SYSTEM_PART_END}
parted -s "${DISK}" set 1 legacy_boot on
else
parted -s "${DISK}" -a min unit s mkpart primary fat32 ${SYSTEM_PART_START} ${SYSTEM_PART_END}
parted -s "${DISK}" set 1 boot on
fi
sync
# create part2
echo "image: creating part2..."
STORAGE_PART_START=$(( ${SYSTEM_PART_END} + 1 ))
STORAGE_PART_END=$(( ${STORAGE_PART_START} + (${STORAGE_SIZE} * 1024 * 1024 / 512) - 1 ))
if [ "${DISK_LABEL}" = "gpt" ]; then
parted -s "${DISK}" -a min unit s mkpart storage ext4 ${STORAGE_PART_START} ${STORAGE_PART_END}
else
parted -s "${DISK}" -a min unit s mkpart primary ext4 ${STORAGE_PART_START} ${STORAGE_PART_END}
fi
sync
if [ "${BOOTLOADER}" = "syslinux" ]; then
# write mbr
echo "image: writing mbr..."
MBR="${TOOLCHAIN}/share/syslinux/gptmbr.bin"
if [ -n "${MBR}" ]; then
dd bs=440 count=1 conv=fsync,notrunc if="${MBR}" of="${DISK}" >"${SAVE_ERROR}" 2>&1 || show_error
fi
fi
# create filesystem on part1
echo "image: creating filesystem on part1..."
OFFSET=$(( ${SYSTEM_PART_START} * 512 ))
HEADS=4
TRACKS=32
SECTORS=$(( ${SYSTEM_SIZE} * 1024 * 1024 / 512 / ${HEADS} / ${TRACKS} ))
shopt -s expand_aliases # enables alias expansion in script
alias mformat="mformat -i ${DISK}@@${OFFSET} -h ${HEADS} -t ${TRACKS} -s ${SECTORS}"
alias mcopy="mcopy -i ${DISK}@@${OFFSET}"
alias mmd="mmd -i ${DISK}@@${OFFSET}"
if [ "${BOOTLOADER}" = "syslinux" -o "${BOOTLOADER}" = "bcm2835-bootloader" -o "${BOOTLOADER}" = "u-boot" ]; then
mformat -v "${DISTRO_BOOTLABEL}" -N "${FAT_SERIAL_NUMBER}" ::
fi
sync
if [ "${BOOTLOADER}" = "syslinux" ]; then
# create bootloader configuration
echo "image: creating bootloader configuration..."
cat << EOF > "${LE_TMP}/syslinux.cfg"
SAY Wait for installer to start or press <TAB> for more options (live, run)
DEFAULT installer
TIMEOUT 50
PROMPT 1
LABEL installer
KERNEL /${KERNEL_NAME}
APPEND boot=UUID=${UUID_SYSTEM} installer quiet tty vga=current
LABEL live
KERNEL /${KERNEL_NAME}
APPEND boot=UUID=${UUID_SYSTEM} live quiet tty vga=current
LABEL run
KERNEL /${KERNEL_NAME}
APPEND boot=UUID=${UUID_SYSTEM} disk=UUID=${UUID_STORAGE} tty portable quiet
EOF
cat << EOF > "${LE_TMP}/grub.cfg"
set timeout="25"
set default="Installer"
menuentry "Installer" {
search --set -f /KERNEL
linux /KERNEL boot=UUID=${UUID_SYSTEM} installer quiet tty vga=current
}
menuentry "Live" {
search --set -f /KERNEL
linux /KERNEL boot=UUID=${UUID_SYSTEM} grub_live quiet tty vga=current
}
menuentry "Run" {
search --set -f /KERNEL
linux /KERNEL boot=UUID=${UUID_SYSTEM} disk=UUID=${UUID_STORAGE} tty grub_portable quiet
}
EOF
mcopy "${LE_TMP}/syslinux.cfg" ::
# install syslinux
echo "image: installing syslinux to part1..."
syslinux.mtools --offset "${OFFSET}" -i "${DISK}"
# copy files
echo "image: copying files to part1..."
mcopy "${TARGET_IMG}/${IMAGE_NAME}.kernel" "::/${KERNEL_NAME}"
mcopy "${TARGET_IMG}/${IMAGE_NAME}.system" ::/SYSTEM
mcopy "${RELEASE_DIR}/target/KERNEL.md5" "::/${KERNEL_NAME}.md5"
mcopy "${RELEASE_DIR}/target/SYSTEM.md5" ::/SYSTEM.md5
mmd EFI EFI/BOOT
mcopy "${TOOLCHAIN}/share/syslinux/bootx64.efi" ::/EFI/BOOT
mcopy "${TOOLCHAIN}/share/syslinux/ldlinux.e64" ::/EFI/BOOT
mcopy "${TOOLCHAIN}/share/grub/bootia32.efi" ::/EFI/BOOT
mcopy "${LE_TMP}/grub.cfg" ::/EFI/BOOT
elif [ "${BOOTLOADER}" = "bcm2835-bootloader" ]; then
# create bootloader configuration
echo "image: creating bootloader configuration..."
cat << EOF > "${LE_TMP}/cmdline.txt"
boot=UUID=${UUID_SYSTEM} disk=UUID=${UUID_STORAGE} quiet ${EXTRA_CMDLINE}
EOF
mcopy "${LE_TMP}/cmdline.txt" ::
# copy files
echo "image: copying files to part1..."
mcopy "${TARGET_IMG}/${IMAGE_NAME}.kernel" "::/${KERNEL_NAME}"
mcopy "${TARGET_IMG}/${IMAGE_NAME}.system" ::/SYSTEM
mcopy "${RELEASE_DIR}/target/KERNEL.md5" "::/${KERNEL_NAME}.md5"
mcopy "${RELEASE_DIR}/target/SYSTEM.md5" ::/SYSTEM.md5
mcopy "${RELEASE_DIR}/3rdparty/bootloader/bootcode.bin" ::
mcopy "${RELEASE_DIR}/3rdparty/bootloader/fixup.dat" ::
mcopy "${RELEASE_DIR}/3rdparty/bootloader/start.elf" ::
mcopy "${RELEASE_DIR}/3rdparty/bootloader/config.txt" ::
mcopy "${RELEASE_DIR}/3rdparty/bootloader/distroconfig.txt" ::
if [ -f "${RELEASE_DIR}/3rdparty/bootloader/dt-blob.bin" ]; then
mcopy "${RELEASE_DIR}/3rdparty/bootloader/dt-blob.bin" ::
fi
for dtb in "${RELEASE_DIR}/3rdparty/bootloader/"*.dtb ; do
if [ -f "${dtb}" ]; then
mcopy "${dtb}" ::/$(basename "${dtb}")
fi
done
if [ -d "${RELEASE_DIR}/3rdparty/bootloader/overlays" ]; then
mcopy -s "${RELEASE_DIR}/3rdparty/bootloader/overlays" ::
fi
elif [ "${BOOTLOADER}" = "u-boot" -a \( -n "${UBOOT_SYSTEM}" -o "${UBOOT_VERSION}" = "vendor" \) ]; then
# create bootloader configuration
echo "image: creating bootloader configuration..."
if [ "${UBOOT_VERSION}" != "vendor" ]; then
DTB="$(${SCRIPTS}/uboot_helper ${PROJECT} ${DEVICE} ${UBOOT_SYSTEM} dtb)"
if [ -f "${RELEASE_DIR}/3rdparty/bootloader/${DTB}" ]; then
mcopy "${RELEASE_DIR}/3rdparty/bootloader/${DTB}" ::
fi
mkdir -p "${LE_TMP}/extlinux"
cat << EOF > "${LE_TMP}/extlinux/extlinux.conf"
LABEL ${DISTRO}
LINUX /${KERNEL_NAME}
FDT /${DTB}
APPEND boot=UUID=${UUID_SYSTEM} disk=UUID=${UUID_STORAGE} quiet ${EXTRA_CMDLINE}
EOF
mcopy -s "${LE_TMP}/extlinux" ::
fi
if [ -f "${PROJECT_DIR}/${PROJECT}/devices/${DEVICE}/bootloader/mkimage" ]; then
. "${PROJECT_DIR}/${PROJECT}/devices/${DEVICE}/bootloader/mkimage"
elif [ -f "${PROJECT_DIR}/${PROJECT}/bootloader/mkimage" ]; then
. "${PROJECT_DIR}/${PROJECT}/bootloader/mkimage"
else
echo "image: skipping u-boot. no mkimage script found"
fi
echo "image: copying files to part1..."
mcopy "${TARGET_IMG}/${IMAGE_NAME}.kernel" "::/${KERNEL_NAME}"
mcopy "${TARGET_IMG}/${IMAGE_NAME}.system" ::/SYSTEM
mcopy "${RELEASE_DIR}/target/KERNEL.md5" "::/${KERNEL_NAME}.md5"
mcopy "${RELEASE_DIR}/target/SYSTEM.md5" ::/SYSTEM.md5
elif [ "${BOOTLOADER}" = "u-boot" ]; then
echo "to make an image using u-boot UBOOT_SYSTEM must be set"
cleanup
exit
fi # bootloader
# extract part2 from image to format and copy files
echo "image: extracting part2 from image..."
STORAGE_PART_COUNT=$(( ${STORAGE_PART_END} - ${STORAGE_PART_START} + 1 ))
sync
dd if="${DISK}" of="${LE_TMP}/part2.ext4" bs=512 skip="${STORAGE_PART_START}" count="${STORAGE_PART_COUNT}" conv=fsync >"${SAVE_ERROR}" 2>&1 || show_error
# create filesystem on part2
echo "image: creating filesystem on part2..."
mke2fs -F -q -t ext4 -m 0 "${LE_TMP}/part2.ext4"
tune2fs -L "${DISTRO_DISKLABEL}" -U ${UUID_STORAGE} "${LE_TMP}/part2.ext4" >"${SAVE_ERROR}" 2>&1 || show_error
e2fsck -n "${LE_TMP}/part2.ext4" >"${SAVE_ERROR}" 2>&1 || show_error
sync
# add resize mark
mkdir "${LE_TMP}/part2.fs"
touch "${LE_TMP}/part2.fs/.please_resize_me"
echo "image: populating filesystem on part2..."
populatefs -U -d "${LE_TMP}/part2.fs" "${LE_TMP}/part2.ext4" >"${SAVE_ERROR}" 2>&1 || show_error
sync
e2fsck -n "${LE_TMP}/part2.ext4" >"${SAVE_ERROR}" 2>&1 || show_error
# merge part2 back to disk image
echo "image: merging part2 back to image..."
dd if="${LE_TMP}/part2.ext4" of="${DISK}" bs=512 seek="${STORAGE_PART_START}" conv=fsync,notrunc >"${SAVE_ERROR}" 2>&1 || show_error
# extract part1 from image to run fsck
echo "image: extracting part1 from image..."
SYSTEM_PART_COUNT=$(( ${SYSTEM_PART_END} - ${SYSTEM_PART_START} + 1 ))
sync
dd if="${DISK}" of="${LE_TMP}/part1.fat" bs=512 skip="${SYSTEM_PART_START}" count="${SYSTEM_PART_COUNT}" conv=fsync >"${SAVE_ERROR}" 2>&1 || show_error
echo "image: checking filesystem on part1..."
fsck -n "${LE_TMP}/part1.fat" >"${SAVE_ERROR}" 2>&1 || show_error
# create virtual image
if [ "${PROJECT}" = "Generic" ]; then
echo "image: creating open virtual appliance..."
# duplicate $DISK so anything we do to it directly doesn't effect original
dd if="${DISK}" of="${DISK_BASENAME}.tmp" bs=1M >"${SAVE_ERROR}" 2>&1 || show_error
# change syslinux default to 'run'
echo "image: modifying fs on part1 for open virtual appliance..."
sed -e "/DEFAULT/ s/installer/run/" -i "${LE_TMP}/syslinux.cfg"
sed -e "/set default=/s/\"Installer\"/\"Run\"/" -i "${LE_TMP}/grub.cfg"
# FIXME: an unalias should work here, but it does not; call mcopy directly
"${TOOLCHAIN}"/bin/mcopy -i "${LE_TMP}/part1.fat" -o "${LE_TMP}/syslinux.cfg" ::
"${TOOLCHAIN}"/bin/mcopy -i "${LE_TMP}/part1.fat" -o "${LE_TMP}/grub.cfg" ::/EFI/BOOT
sync
# merge modified part1 back to tmp disk image
echo "image: merging part1 back to open virtual appliance..."
dd if="${LE_TMP}/part1.fat" of="${DISK_BASENAME}.tmp" bs=512 seek="${SYSTEM_PART_START}" conv=fsync,notrunc >"${SAVE_ERROR}" 2>&1 || show_error
# create vmdk from tmp $DISK
qemu-img convert -O vmdk -o subformat=streamOptimized "${DISK_BASENAME}.tmp" "${DISK_BASENAME}.vmdk"
# generate ovf from template
sed -e "s,@DISTRO@,${DISTRO},g" -e "s,@DISK@,${IMAGE_NAME},g" \
-e "s,@DISK_SIZE@,$((${DISK_SIZE}*1024*1024)),g" \
"${PROJECT_DIR}/${PROJECT}/config/ovf.template" > "${DISK_BASENAME}.ovf"
# combine ovf and vmdk into official ova
tar -C "${TARGET_IMG}" -cf "${DISK_BASENAME}.ova" "${IMAGE_NAME}.ovf" "${IMAGE_NAME}.vmdk"
# create sha256 checksum of ova image
( cd "${TARGET_IMG}"
sha256sum "${IMAGE_NAME}.ova" > "${IMAGE_NAME}.ova.sha256"
)
echo "image: cleaning up..."
# remove tmp $DISK, vmdk and ovf
rm "${DISK_BASENAME}.tmp" "${DISK_BASENAME}.vmdk" "${DISK_BASENAME}.ovf"
# set owner
[ -n "${SUDO_USER}" ] && chown "${SUDO_USER}:" "${DISK_BASENAME}.ova"
fi
# gzip
echo "image: compressing..."
gzip "${DISK}"
# set owner
if [ -n "${SUDO_USER}" ]; then
chown "${SUDO_USER}:" "${DISK}.gz"
fi
# create sha256 checksum of image
( cd "${TARGET_IMG}"
sha256sum $(basename "${DISK}").gz > $(basename "${DISK}").gz.sha256
)
# cleanup
cleanup
exit