mirror of
https://github.com/archr-linux/Arch-R.git
synced 2026-03-31 14:41:55 -07:00
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.
341 lines
12 KiB
Bash
Executable File
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
|