mirror of
git://soft.sys114.com/odroid-stamper
synced 2025-12-19 01:48:42 +09:00
Currently the base image is downloaded everytime even if the same file is already downloaded and exist in the output directory. So this patch will check the SHA value of the file before downloading when the same file is required to build an OS image. Signed-off-by: Dongjin Kim <tobetter@gmail.com> Change-Id: I4581b4ddb990ef975d1c3a0008ed6b596ea627a1
756 lines
22 KiB
Bash
756 lines
22 KiB
Bash
boot_mnt=${build_dir}/boot
|
|
rootfs_mnt=${build_dir}/rootfs
|
|
fixups_dir=/host/fixups
|
|
|
|
do_unmount() {
|
|
echo "do_unmount()"
|
|
|
|
unmount_error=""
|
|
|
|
echo "I: unmounting pseudo directories in ${rootfs_mnt}..."
|
|
dirs="sys/firmware/efi/efivars sys proc dev/pts dev boot"
|
|
for dir in ${dirs}; do
|
|
mountpoint -q ${rootfs_mnt}/${dir} 2>/dev/null \
|
|
&& { umount ${rootfs_mnt}/${dir} \
|
|
|| { echo "umount ${dir} failed"; unmount_error=1; }; \
|
|
}
|
|
done
|
|
|
|
echo "I: cleanup loopback device ${LOOPBACK}..."
|
|
if [ ! -b ${TARGET_DEVICE} ]; then
|
|
losetup -d ${LOOPBACK} 2>/dev/null
|
|
fi
|
|
|
|
if [ -f ${TOPDIR}/custom/${CUSTOMOS}/hooks/umount ]; then
|
|
. ${TOPDIR}/custom/${CUSTOMOS}/hooks/umount
|
|
fi
|
|
|
|
if [ "$unmount_error" ] ; then
|
|
echo "an error occured during unmounting ressources, check mountpoints and losetup"
|
|
kill -9 $$
|
|
fi
|
|
}
|
|
|
|
cleanup() {
|
|
do_unmount
|
|
|
|
for dir in ${boot_mnt} ${rootfs_mnt}; do
|
|
mountpoint -q ${dir} 2>/dev/null \
|
|
&& umount ${dir} && rm -rf ${dir}
|
|
done
|
|
|
|
if [ "x${opt_keep_builddir}" != "xtrue" ]; then
|
|
rm -rf --one-file-system ${boot_mnt} ${rootfs_mnt}
|
|
fi
|
|
if [ "$(ls ${build_dir} 2>/dev/null | wc -l)" = "0" ]; then
|
|
rm -rf --one-file-system ${build_dir}
|
|
fi
|
|
}
|
|
|
|
trap_ctrlc() {
|
|
echo "<Ctrl-C> is detected..."
|
|
cleanup
|
|
exit 1
|
|
}
|
|
|
|
panic() {
|
|
echo "E: ${1}"
|
|
cleanup
|
|
exit 1
|
|
}
|
|
|
|
fixup_arch() {
|
|
case "${1}" in
|
|
arm64)
|
|
echo "aarch64"
|
|
;;
|
|
armhf)
|
|
echo "arm"
|
|
;;
|
|
*)
|
|
panic "Unknown architecture..."
|
|
;;
|
|
esac
|
|
}
|
|
|
|
qemu_binary() {
|
|
if [ "x$(fixup_arch ${1})" != "x$(uname -m)" ]; then
|
|
echo "/usr/bin/qemu-$(fixup_arch ${ARCH})-static"
|
|
fi
|
|
}
|
|
|
|
ask_password() {
|
|
printf '%s\n' "$(dialog --output-fd 1 \
|
|
--passwordbox "Enter your sudo password" 12 50)" | sudo -Svp ''
|
|
}
|
|
|
|
get_part_boot() {
|
|
if [ ! -b ${TARGET_DEVICE} ]; then
|
|
echo "${LOOPBACK}p1"
|
|
else
|
|
echo "${TARGET_DEVICE}-part1"
|
|
fi
|
|
}
|
|
|
|
get_part_root() {
|
|
if [ ! -b ${TARGET_DEVICE} ]; then
|
|
echo "${LOOPBACK}p2"
|
|
else
|
|
echo "${TARGET_DEVICE}-part2"
|
|
fi
|
|
}
|
|
|
|
get_part_ext() {
|
|
if [ ! -b ${TARGET_DEVICE} ]; then
|
|
echo "${LOOPBACK}p${1}"
|
|
else
|
|
echo "${TARGET_DEVICE}-part${1}"
|
|
fi
|
|
}
|
|
|
|
get_kernel_cmdline_defaults() {
|
|
echo ""
|
|
}
|
|
|
|
get_default_apt_options() {
|
|
echo "-y --no-install-recommends"
|
|
}
|
|
|
|
get_packages() {
|
|
[ -f ${1} ] && cat ${1} | awk -F '#|;' '{print $1}'
|
|
}
|
|
|
|
get_package_list() {
|
|
local pkgs=""
|
|
|
|
local dirs="distro/${DISTRO}/common"
|
|
dirs="${dirs} distro/${DISTRO}/${FLAVOUR}"
|
|
dirs="${dirs} boards/${BOARD}"
|
|
dirs="${dirs} boards/${BOARD}/distro/${DISTRO}/${FLAVOUR}"
|
|
dirs="${dirs} custom/${CUSTOMOS}"
|
|
|
|
for dir in ${dirs}; do
|
|
if [ -f ${dir}/${1} ]; then
|
|
list=$(cat ${dir}/${1} | awk -F '#|;' '{print $1}')
|
|
pkgs="${pkgs} ${list}"
|
|
fi
|
|
done
|
|
|
|
echo ${pkgs}
|
|
}
|
|
|
|
get_repo_components() {
|
|
local pkgs=$(get_package_list components)
|
|
|
|
echo ${pkgs} | tr " " "\n" | sort | uniq | tr "\n" " "
|
|
}
|
|
|
|
get_flavour_packages() {
|
|
local pkgs=$(get_package_list packages)
|
|
|
|
if [ "x${LIVESYSTEM}" = "xtrue" ]; then
|
|
pkgs="${pkgs} casper"
|
|
fi
|
|
|
|
if [ "x${WIFI}" = "xtrue" ]; then
|
|
pkgs="${pkgs} $(get_packages addon/wifi/packages)"
|
|
fi
|
|
|
|
echo ${pkgs} | tr " " "\n" | sort | uniq | tr "\n" " "
|
|
}
|
|
|
|
get_blacklist_packages() {
|
|
local pkgs=$(get_package_list blacklist)
|
|
|
|
echo ${pkgs} | tr " " "\n" | sort | uniq | tr "\n" " "
|
|
}
|
|
|
|
get_lookback_device() {
|
|
echo `losetup -a | grep ${1} | cut -d':' -f1`
|
|
}
|
|
|
|
oem_mount() {
|
|
local src=${TOPDIR}/custom/${CUSTOMOS}/part${1}
|
|
local dst=${rootfs_mnt}/${2}
|
|
|
|
mkdir -p ${src}
|
|
mkdir -p ${dst}
|
|
mount -o bind ${src} ${dst}
|
|
}
|
|
|
|
oem_umount() {
|
|
umount -f ${rootfs_mnt}/${1} 2>/dev/null
|
|
}
|
|
|
|
oem_mkfs_ext4() {
|
|
local src=${3}
|
|
local part=$(get_part_ext ${1})
|
|
local label=""
|
|
|
|
[ "x${2}" = "x" ] || label="-L ${2}"
|
|
|
|
# Build image with the file list
|
|
if [ -f ${TOPDIR}/custom/${CUSTOMOS}/${src} ]; then
|
|
local overlayfs_dir=${build_dir}/overlayfs
|
|
|
|
rm -rf ${overlayfs_dir} && mkdir -p ${overlayfs_dir}
|
|
|
|
while read line; do
|
|
file=$(echo "${line}" | awk -F '#|;' '{print $1}')
|
|
|
|
if [ ! -z "${file}" ]; then
|
|
if [ -d "${file}" ]; then
|
|
dir=$(dirname ${file})
|
|
mkdir -p ${overlayfs_dir}/${dir}
|
|
mv ${rootfs_mnt}/${file} ${overlayfs_dir}/${dir}/
|
|
else
|
|
for f in $(ls ${file} 1>/dev/null 2>&1); do
|
|
dir=$(dirname ${f})
|
|
mkdir -p ${overlayfs_dir}/${dir}
|
|
mv ${rootfs_mnt}/${f} ${overlayfs_dir}/${dir}/
|
|
done
|
|
fi
|
|
fi
|
|
done < ${TOPDIR}/custom/${CUSTOMOS}/${src}
|
|
|
|
# Copy file list to root of partition
|
|
cp -a ${TOPDIR}/custom/${CUSTOMOS}/${src} \
|
|
${overlayfs_dir}/.filesystem
|
|
|
|
src=${overlayfs_dir}
|
|
else
|
|
if [ "x${src}" = "x" ]; then
|
|
src=${TOPDIR}/custom/${CUSTOMOS}/part${1}
|
|
fi
|
|
fi
|
|
|
|
if [ -d ${src} ]; then
|
|
echo "* Creating ext4 file system to ${part} with ${src}"
|
|
sudo mkfs.ext4 -F ${label} -d ${src} ${part} 2>/dev/null \
|
|
|| panic "failed to create partition '${part}'"
|
|
fi
|
|
}
|
|
|
|
do_mount() {
|
|
echo "I: mounting to ${rootfs_mnt}"
|
|
|
|
mkdir -p ${rootfs_mnt}/boot
|
|
mkdir -p ${rootfs_mnt}/dev
|
|
mkdir -p ${rootfs_mnt}/dev/pts
|
|
mkdir -p ${rootfs_mnt}/proc
|
|
mkdir -p ${rootfs_mnt}/sys
|
|
|
|
mount -o bind ${boot_mnt} ${rootfs_mnt}/boot
|
|
mount -o bind /dev ${rootfs_mnt}/dev
|
|
mount -o bind /dev/pts ${rootfs_mnt}/dev/pts
|
|
mount -o bind /proc ${rootfs_mnt}/proc
|
|
mount -o bind /sys ${rootfs_mnt}/sys
|
|
|
|
if [ -f ${TOPDIR}/custom/${CUSTOMOS}/hooks/mount ]; then
|
|
. ${TOPDIR}/custom/${CUSTOMOS}/hooks/mount
|
|
fi
|
|
}
|
|
|
|
get_uuid_by_path() {
|
|
if [ -f ${rootfs_mnt}/etc/fstab ]; then
|
|
grep " ${1} " ${rootfs_mnt}/etc/fstab \
|
|
| cut -d' ' -f1 | cut -d'=' -f2 | tr -d '"'
|
|
fi
|
|
}
|
|
|
|
do_create_squashfs() {
|
|
local live_image=filesystem.squashfs
|
|
local disk=${1}
|
|
local boot_pstart=$(get_reserved_sectors)
|
|
[ "x${boot_pstart}" = "x" ] && boot_pstart=2048
|
|
|
|
sudo rm -f ${live_image}
|
|
sudo mksquashfs ${rootfs_mnt} ${live_image} -comp lzo || exit 1
|
|
|
|
mkdir -p ${boot_mnt}/casper
|
|
cp ${live_image} ${boot_mnt}/casper/ && rm -f ${live_image}
|
|
|
|
local boot_blk=$(($(du -s --block-size=512 ${boot_mnt} | cut -f1) * 12 / 10 - 1))
|
|
local blocks=$((${boot_pstart} + ${boot_blk}))
|
|
|
|
if [ -f ${TOPDIR}/custom/${CUSTOMOS}/partitions ]; then
|
|
. ${TOPDIR}/custom/${CUSTOMOS}/partitions
|
|
blocks=${TOTAL_SECTORS}
|
|
fi
|
|
|
|
echo "I: creating the disk image file '${disk}' ($((${blocks} * 512))KiB)"
|
|
dd if=/dev/zero bs=512 count=${blocks} \
|
|
| pv -s $((${blocks} * 512 * 1024))k \
|
|
| dd of=${disk} >/dev/null
|
|
|
|
[ "${BASH_VERSION}" = "" ] || BACKSLASH_ESCAPE="-e"
|
|
|
|
echo "I: creating a partition table to '${disk}'"
|
|
if [ -f ${TOPDIR}/custom/${CUSTOMOS}/partitions ]; then
|
|
echo ${BACKSLASH_ESCAPE} \
|
|
$(${TOPDIR}/fdiskcmd.sh ${TOPDIR}/custom/${CUSTOMOS}/partitions) \
|
|
| fdisk ${disk} >/dev/null
|
|
fi
|
|
|
|
echo ${BACKSLASH_ESCAPE} \
|
|
"n\np\n\n${boot_pstart}\n\n" \
|
|
"w\n" | fdisk ${disk} >/dev/null
|
|
partprobe
|
|
|
|
if [ ! -b ${disk} ]; then
|
|
losetup -fP ${disk} || panic "failed to setup loopback image"
|
|
LOOPBACK=$(get_lookback_device ${disk})
|
|
echo ${LOOPBACK}
|
|
fi
|
|
|
|
if [ -f ${TOPDIR}/custom/${CUSTOMOS}/hooks/partition ]; then
|
|
. ${TOPDIR}/custom/${CUSTOMOS}/hooks/partition
|
|
fi
|
|
|
|
UUID_BOOT=$(get_uuid_by_path "/boot")
|
|
|
|
sudo mkfs.ext2 -F -L BOOT -U ${UUID_BOOT} \
|
|
-d ${boot_mnt} $(get_part_boot) 2>/dev/null \
|
|
|| panic "failed to create partition '$(get_part_boot)'"
|
|
}
|
|
|
|
do_create_partition() {
|
|
local disk=${1}
|
|
local boot_blk=$((${2} * 1024 * 1024 / 512 - 1))
|
|
local root_blk=$(($(du -s --block-size=512 ${rootfs_mnt} | cut -f1) * 12 / 10))
|
|
local boot_pstart=$(get_reserved_sectors)
|
|
local fdiskcmd=""
|
|
|
|
[ "x${boot_pstart}" = "x" ] && boot_pstart=2048
|
|
|
|
if [ -f ${TOPDIR}/custom/${CUSTOMOS}/partitions ]; then
|
|
echo ${TOPDIR}/custom/${CUSTOMOS}/partitions
|
|
. ${TOPDIR}/custom/${CUSTOMOS}/partitions
|
|
|
|
if [ ! -z ${TOTAL_SECTORS} ]; then
|
|
fdiskcmd=$(${TOPDIR}/fdiskcmd.sh ${TOPDIR}/custom/${CUSTOMOS}/partitions)
|
|
fi
|
|
fi
|
|
|
|
if [ ! -z ${EXTRA_BOOT_SIZE} ]; then
|
|
blks=$((${EXTRA_BOOT_SIZE} * 1024 * 1024 / 512 - 1))
|
|
boot_blk=$((${boot_blk} + ${blks}))
|
|
fi
|
|
if [ ! -z ${EXTRA_ROOT_SIZE} ]; then
|
|
blks=$((${EXTRA_ROOT_SIZE} * 1024 * 1024 / 512 - 1))
|
|
root_blk=$((${root_blk} + ${blks}))
|
|
fi
|
|
|
|
local boot_size=$((${boot_pstart} + ${boot_blk}))
|
|
local blocks=$((${boot_pstart} + ${boot_blk} + ${root_blk}))
|
|
|
|
blocks=${TOTAL_SECTORS:-${blocks}}
|
|
|
|
if [ "x${fdiskcmd}" = "x" ]; then
|
|
fdiskcmd="n\np\n\n${boot_pstart}\n${boot_size}\nn\np\n\n$((${boot_size} + 1))\n\nw\n"
|
|
fi
|
|
|
|
if [ ! -b ${disk} ]; then
|
|
echo "I: creating the disk image file '${disk}' ($((${blocks} * 512))KiB)"
|
|
dd if=/dev/zero bs=512 count=${blocks} \
|
|
| pv -s $((${blocks} * 512 * 1024))k \
|
|
| dd of=${disk} >/dev/null
|
|
else
|
|
for d in `readlink -f ${disk}*`; do
|
|
mountpoint -q ${d} 2>/dev/null \
|
|
&& umount ${d}
|
|
done
|
|
|
|
echo "I: removing the current partition table in '${disk}'"
|
|
dd if=/dev/zero of=${disk} bs=512 count=1 >/dev/null
|
|
fi
|
|
|
|
[ "${BASH_VERSION}" = "" ] || BACKSLASH_ESCAPE="-e"
|
|
|
|
echo "I: creating a partition table to '${disk}'"
|
|
echo fdiskcmd=${fdiskcmd}
|
|
echo ${BACKSLASH_ESCAPE} ${fdiskcmd} | fdisk ${disk} \
|
|
|| panic "failed to create partition table" >/dev/null
|
|
partprobe
|
|
|
|
if [ ! -b ${disk} ]; then
|
|
losetup -fP ${disk} || panic "failed to setup loopback image"
|
|
LOOPBACK=$(get_lookback_device ${disk})
|
|
echo ${LOOPBACK}
|
|
fi
|
|
|
|
if [ -f ${TOPDIR}/custom/${CUSTOMOS}/hooks/partition ]; then
|
|
. ${TOPDIR}/custom/${CUSTOMOS}/hooks/partition
|
|
fi
|
|
|
|
UUID_BOOT=$(get_uuid_by_path "/boot")
|
|
UUID_ROOT=$(get_uuid_by_path "/")
|
|
|
|
sudo mkfs.ext2 -F -L BOOT -U ${UUID_BOOT} \
|
|
-d ${boot_mnt} $(get_part_boot) 2>/dev/null \
|
|
|| panic "failed to create partition '$(get_part_boot)'"
|
|
sudo mkfs.ext4 -F -L rootfs -U ${UUID_ROOT} \
|
|
-d ${rootfs_mnt} $(get_part_root) 2>/dev/null \
|
|
|| panic "failed to create partition '$(get_part_root)'"
|
|
}
|
|
|
|
do_copy_custom_files_by_dir() {
|
|
local dirs=""
|
|
|
|
[ "x${1}" = "x" ] && panic "E: missing source directory of custom files"
|
|
[ "x${2}" = "x" ] && panic "E: missing target directory for custom files"
|
|
|
|
dirs="${dirs} ${TOPDIR}"
|
|
dirs="${dirs} ${WORKDIR}"
|
|
dirs="${dirs} ${TOPDIR}/distro/${DISTRO}/common"
|
|
dirs="${dirs} ${TOPDIR}/distro/${DISTRO}/${FLAVOUR}"
|
|
dirs="${dirs} ${TOPDIR}/boards/${BOARD}"
|
|
dirs="${dirs} ${TOPDIR}/boards/${BOARD}/distro/${DISTRO}"
|
|
dirs="${dirs} ${TOPDIR}/boards/${BOARD}/distro/${DISTRO}/${FLAVOUR}"
|
|
dirs="${dirs} ${TOPDIR}/custom/${CUSTOMOS}"
|
|
|
|
for dir in ${dirs}; do
|
|
[ -d ${dir}/${1} ] && rsync -a ${dir}/${1}/ ${2}/
|
|
done
|
|
}
|
|
|
|
do_preinstall() {
|
|
local UUID_BOOT=$(uuidgen)
|
|
local UUID_ROOT=$(uuidgen)
|
|
|
|
echo "I: running preinstall scripts and copy default files..."
|
|
mkdir -p ${rootfs_mnt}${fixups_dir}
|
|
|
|
do_copy_custom_files_by_dir fixups ${rootfs_mnt}${fixups_dir}
|
|
|
|
case ${FLAVOUR} in
|
|
*-desktop*)
|
|
faceimage=${TOPDIR}/face.png
|
|
if [ -f ${TOPDIR}/boards/${BOARD}/face.png ]; then
|
|
faceimage=${TOPDIR}/boards/${BOARD}/face.png
|
|
elif [ -f ${TOPDIR}/custom/${CUSTOMOS}/face.png ]; then
|
|
faceimage=${TOPDIR}/custom/${CUSTOMOS}/face.png
|
|
fi
|
|
|
|
cp -a ${faceimage} ${rootfs_mnt}/tmp
|
|
;;
|
|
esac
|
|
|
|
DEFAULT_KERNEL_PACKAGE=$(get_kernel_package)
|
|
[ ! "x${opt_kernel_package}" = "x" ] && DEFAULT_KERNEL_PACKAGE=${opt_kernel_package}
|
|
|
|
[ ! "x${opt_linuxfactory}" = "x" ] && DEFAULT_LINUXFACTORY=${opt_linuxfactory}
|
|
|
|
FIXUPS=`ls -A1 ${rootfs_mnt}${fixups_dir}/*`
|
|
for fixup in ${FIXUPS}; do
|
|
sed -i \
|
|
-e "s,@@DEFAULT_BOARD@@,${BOARD},g" \
|
|
-e "s,@@DEFAULT_HOSTNAME@@,${FLAVOUR},g" \
|
|
-e "s,@@DEFAULT_APT_OPTIONS@@,$(get_default_apt_options ${FLAVOUR}),g" \
|
|
-e "s,@@DEFAULT_REPO_COMPONENTS@@,$(get_repo_components),g" \
|
|
-e "s,@@DEFAULT_FLAVOUR_PACKAGES@@,$(get_flavour_packages),g" \
|
|
-e "s,@@DEFAULT_BLACKLIST_PACKAGES@@,$(get_blacklist_packages),g" \
|
|
-e "s,@@DEFAULT_KERNEL_PACKAGE@@,${DEFAULT_KERNEL_PACKAGE},g" \
|
|
-e "s,@@DEFAULT_BOOTSCRIPT_PACKAGE@@,$(get_bootscript_package),g" \
|
|
-e "s,@@DEFAULT_MACHINE_NAME@@,$(get_machine_name),g" \
|
|
-e "s,@@DEFAULT_LINUXFACTORY@@,${DEFAULT_LINUXFACTORY},g" \
|
|
-e "s,@@LINUX_KERNEL_CMDLINE@@,root=UUID=${UUID_ROOT} rootwait ro quiet,g" \
|
|
-e "s,@@LINUX_KERNEL_CMDLINE_DEFAULTS@@,$(get_kernel_cmdline_defaults),g" \
|
|
-e "s,@@DEFAULT_DEV_BOOT@@,${UUID_BOOT},g" \
|
|
-e "s,@@DEFAULT_DEV_ROOTFS@@,${UUID_ROOT},g" \
|
|
-e "s,@@ALLOW_ROOT_LOGIN@@,$(allow_root_login),g" \
|
|
-e "s,@@DEFAULT_USER@@,$(default_user),g" \
|
|
-e "s,@@DEFAULT_USER_PASSWD@@,$(default_user_passwd),g" \
|
|
-e "s,@@DEFAULT_DISTRO@@,${DISTRO},g" \
|
|
-e "s,@@OSNAME@@,$(osname ${DISTRO}),g" \
|
|
-e "s,@@LIVESYSTEM@@,${LIVESYSTEM},g" \
|
|
-e "s,@@MACHINEID@@,$(dbus-uuidgen),g" \
|
|
-e "s,@@INTERNAL@@,${INTERNAL},g" \
|
|
-e "s,@@BUILD_DKMS@@,${BUILD_DKMS},g" \
|
|
${fixup}
|
|
done
|
|
|
|
QEMU_BINARY=$(qemu_binary ${ARCH})
|
|
|
|
if [ ! "x${QEMU_BINARY}" = "x" ]; then
|
|
cp ${QEMU_BINARY} ${rootfs_mnt}/${QEMU_BINARY} || panic "error"
|
|
fi
|
|
}
|
|
|
|
do_postinstall() {
|
|
echo "I: removing preinstall scripts..."
|
|
if [ ! "x${QEMU_BINARY}" = "x" ]; then
|
|
rm -f ${rootfs_mnt}/${QEMU_BINARY}
|
|
fi
|
|
rm -f ${rootfs_mnt}/tmp/face.png
|
|
rm -rf ${rootfs_mnt}/host
|
|
rm -rf ${rootfs_mnt}${fixups_dir}
|
|
rm -rf ${rootfs_mnt}/etc/apt/sources.list.d/ppa_linuxfactory_or_kr.list
|
|
}
|
|
|
|
do_cleanup() {
|
|
rm -f ${rootfs_mnt}/SHA256SUMS
|
|
rm -rf ${rootfs_mnt}/boot/filesystem.*
|
|
}
|
|
|
|
get_install_fixups() {
|
|
echo `ls -A1 ${rootfs_mnt}${fixups_dir}/S* | sort`
|
|
}
|
|
|
|
do_run_fixups() {
|
|
mkdir -p ${rootfs_mnt}/overlay
|
|
do_copy_custom_files_by_dir overlay ${rootfs_mnt}/overlay
|
|
|
|
for fixup in $(get_install_fixups); do
|
|
chroot ${rootfs_mnt} ${QEMU_BINARY} \
|
|
/bin/sh ${fixups_dir}/$(basename ${fixup}) || \
|
|
panic "error when running the fixup"
|
|
done
|
|
}
|
|
|
|
do_collect_uboot() {
|
|
if [ -e ${rootfs_mnt}/usr/lib/u-boot/${BOARD} ]; then
|
|
rm -rf ${TOPDIR}/u-boot
|
|
mkdir -p ${TOPDIR}/u-boot/sd_fuse && \
|
|
cp -a ${rootfs_mnt}/usr/lib/u-boot/${BOARD}/* ${TOPDIR}/u-boot/sd_fuse/
|
|
fi
|
|
}
|
|
|
|
do_url_of_cloudimage() {
|
|
local arch=${1}
|
|
local codename=${2}
|
|
local flavour=${3}
|
|
|
|
case ${flavour} in
|
|
*-desktop* | weston)
|
|
flavour="server"
|
|
;;
|
|
esac
|
|
|
|
case ${codename} in
|
|
# Debian Official Cloud Images
|
|
buster | bullseye | bookworm)
|
|
file=$(lynx -dump -listonly https://cloud.debian.org/images/cloud/${codename}/latest \
|
|
| grep generic-${arch}.tar.xz | awk '{print $2}' | uniq)
|
|
;;
|
|
|
|
# Ubuntu Cloud Images
|
|
focal | jammy | mantic | noble)
|
|
file="https://cloud-images.ubuntu.com/${codename}/current/${codename}-server-cloudimg-${arch}.squashfs"
|
|
;;
|
|
esac
|
|
|
|
echo ${file}
|
|
}
|
|
|
|
do_create_image() {
|
|
local target=${1}
|
|
local cloudimage=${2}
|
|
|
|
[ "x${target}" = "x" ] && panic "no given image file name"
|
|
[ -f ${cloudimage} ] || panic "E: missing cloudimage ${cloudimage}"
|
|
|
|
for dir in ${boot_mnt} ${rootfs_mnt}; do
|
|
mountpoint -q ${dir} 2>/dev/null \
|
|
&& umount ${dir} && rm -rf ${dir}
|
|
done
|
|
|
|
mkdir -p ${boot_mnt} ${rootfs_mnt} 2>/dev/null
|
|
|
|
#
|
|
# Expand orignal Cloud Image to raw file system before customizing
|
|
#
|
|
echo "I: extracting ${cloudimage} to ${rootfs_mnt}..."
|
|
case $(basename ${cloudimage}) in
|
|
*.squashfs)
|
|
sudo unsquashfs -f -d ${rootfs_mnt} ${cloudimage} || panic "unsquashfs failed"
|
|
;;
|
|
|
|
*.tar.gz)
|
|
pv ${cloudimage} \
|
|
| tar xzf - --strip-component=1 -C ${rootfs_mnt} \
|
|
|| panic "E: error while extracting"
|
|
;;
|
|
|
|
debian-*.raw)
|
|
tmpdir=$(mktemp -d) && mkdir -p ${tmpdir}
|
|
sudo losetup -fP ${cloudimage} \
|
|
&& LOOPBACK=$(get_lookback_device ${cloudimage}) \
|
|
&& sudo mount ${LOOPBACK}p1 ${tmpdir} \
|
|
&& sudo cp -a ${tmpdir}/* ${rootfs_mnt} \
|
|
&& sudo umount ${tmpdir} \
|
|
&& sudo losetup -D ${LOOPBACK}
|
|
rm -rf ${tmpdir} ${cloudimage}
|
|
;;
|
|
esac
|
|
|
|
do_mount
|
|
do_preinstall
|
|
do_run_fixups
|
|
do_collect_uboot
|
|
do_postinstall
|
|
do_cleanup
|
|
do_unmount
|
|
|
|
if [ "x${LIVESYSTEM}" = "xtrue" ]; then
|
|
do_create_squashfs ${target}
|
|
else
|
|
do_create_partition ${target} 512
|
|
fi
|
|
}
|
|
|
|
download_uboot() {
|
|
if [ -e ${TOPDIR}/u-boot/sd_fuse ]; then
|
|
(cd ${TOPDIR}/u-boot;
|
|
tar czvf ${1} sd_fuse/*
|
|
)
|
|
fi
|
|
}
|
|
|
|
do_flash_bootloader() {
|
|
local disk=${1}
|
|
local uboot_tarball=${download_dir}/u-boot.tar.gz
|
|
|
|
echo "I: Downloading U-boot binaries"
|
|
download_uboot ${uboot_tarball} \
|
|
|| panic "failed to download bootloader release"
|
|
if [ -f ${uboot_tarball} ]; then
|
|
rm -rf ${download_dir}/sd_fuse
|
|
tar xzvf ${uboot_tarball} -C ${download_dir} || false
|
|
if [ -f ${download_dir}/sd_fuse/sd_fusing.sh ]; then
|
|
(cd ${download_dir}/sd_fuse;
|
|
sed -i "/eject/d" ./sd_fusing.sh;
|
|
chmod +x ./sd_fusing.sh;
|
|
./sd_fusing.sh ${disk} 2>/dev/null
|
|
)
|
|
fi
|
|
rm -f ${uboot_tarball}
|
|
fi
|
|
|
|
rm -rf ${TOPDIR}/u-boot
|
|
}
|
|
|
|
do_finalize_image() {
|
|
local disk=${1}
|
|
local osimage=${2}.img
|
|
|
|
[ "x${PUBLISH}" = "xtrue" ] && COMPRESS=true
|
|
|
|
if [ -f ${disk} ]; then
|
|
echo "I: finalizing OS image - '${osimage}'"
|
|
mv -f ${disk} ${osimage} || panic "failed to target image file"
|
|
md5sum ${osimage} > ${osimage}.md5sum
|
|
if [ "x${COMPRESS}" = "xtrue" ]; then
|
|
echo "I: compressing OS image - '${osimage}'"
|
|
rm -f ${osimage}.xz
|
|
xz --verbose ${osimage} || panic "failed to create compressed image file"
|
|
md5sum ${osimage}.xz > ${osimage}.xz.md5sum
|
|
fi
|
|
|
|
if [ "x${ISOIMAGE}" = "xtrue" ]; then
|
|
mkisofs -R -relaxed-filenames -joliet-long -iso-level 3 -l \
|
|
-o ${2}.iso ${boot_mnt}
|
|
md5sum ${2}.iso > ${2}.iso.md5sum
|
|
fi
|
|
|
|
sed -i -r "s/ .*\/(.+)/ \1/g" ${osimage}*.md5sum
|
|
fi
|
|
}
|
|
|
|
do_custom_installer() {
|
|
local download_dir=${1}
|
|
local out_dir=${2}
|
|
|
|
mkdir -p ${download_dir} ${out_dir}
|
|
|
|
#
|
|
# Get URL of official Cloud Image for Debian/Ubuntu
|
|
#
|
|
echo "I: querying base official Cloud Image for ${ARCH}/${DISTRO}/${FLAVOUR}"
|
|
url=$(do_url_of_cloudimage ${ARCH} ${DISTRO} ${FLAVOUR})
|
|
[ "x${url}" = "x" ] && panic "E: invalid URL - ${url}"
|
|
|
|
local cloudimage=${download_dir}/$(basename ${url})
|
|
|
|
if [ -f ${cloudimage} ]; then
|
|
local hash_bits=256
|
|
|
|
case $(basename ${cloudimage}) in
|
|
debian-*.tar.xz)
|
|
hash_bits=512
|
|
esac
|
|
|
|
local hashurl=$(dirname ${url})/SHA${hash_bits}SUMS
|
|
local hash2=$(sha${hash_bits}sum ${cloudimage} | awk '{print $1}')
|
|
|
|
local hashfile=${download_dir}/hash
|
|
|
|
echo "I: Checking HASH value before downloading $(basename ${cloudimage})..."
|
|
wget --quiet ${hashurl} -O ${hashfile} \
|
|
|| panic "failed to download hash file '${hashurl}'"
|
|
|
|
local hash1=$(cat ${hashfile} | grep $(basename ${url})$ | awk '{print $1}')
|
|
|
|
if [ ${hash1} != ${hash2} ]; then
|
|
#
|
|
# Download official Cloud Image
|
|
#
|
|
echo "I: download official Cloud Image"
|
|
wget ${url} -O ${cloudimage} \
|
|
|| panic "failed to download cloudimage '${url}'"
|
|
fi
|
|
fi
|
|
|
|
#
|
|
# Extract raw Cloud Image
|
|
#
|
|
# Compressed Debian Cloud Image contains 'disk.raw' that is real Cloud
|
|
# Image, not compressing itself. So needs to extract it and rename it.
|
|
#
|
|
case $(basename ${cloudimage}) in
|
|
debian-*.tar.xz)
|
|
tar xf ${cloudimage} disk.raw || panic "E: cannot extract raw Debian Cloud Image"
|
|
cloudimage=${cloudimage%.tar.xz}.raw
|
|
mv disk.raw ${cloudimage}
|
|
;;
|
|
esac
|
|
|
|
do_create_image ${TARGET_DEVICE} ${cloudimage}
|
|
|
|
case $(readlink -f ${TARGET_DEVICE}) in
|
|
/dev/sd*)
|
|
echo "W: bootloader won't be flashed to USB storage"
|
|
;;
|
|
*)
|
|
if [ -b ${TARGET_DEVICE} ]; then
|
|
disk=${TARGET_DEVICE}
|
|
else
|
|
disk=${LOOPBACK}
|
|
fi
|
|
do_flash_bootloader ${disk}
|
|
do_finalize_image ${TARGET_DEVICE} ${OUTFILE}
|
|
|
|
if [ "x${PUBLISH}" = "xtrue" ]; then
|
|
do_publish "192.168.0.2" \
|
|
"/srv/ppa.linuxfactory.or.kr/html/images/raw" \
|
|
${OUTFILE}
|
|
fi
|
|
;;
|
|
esac
|
|
}
|
|
|
|
do_publish() {
|
|
local host=${1}
|
|
local dir=${2}/${ARCH}/${DISTRO}
|
|
local osimage=${3}
|
|
|
|
files=`ls ${osimage}.*`
|
|
if [ ! "x${files}" = "x" ]; then
|
|
ssh ${host} mkdir -p ${dir} && \
|
|
scp ${files} ${host}:/${dir} || \
|
|
panic "failed to connect to remote server"
|
|
fi
|
|
}
|
|
|
|
# vim: set ft=sh ts=4 sw=4 expandtab:
|