summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md1
-rwxr-xr-xbuildlive51
-rw-r--r--distro/arch/meta20
-rw-r--r--distro/opensuse/meta20
-rw-r--r--distro/ubuntu/meta36
-rw-r--r--functions.sh85
6 files changed, 202 insertions, 11 deletions
diff --git a/README.md b/README.md
index 56804e4..18cbad2 100644
--- a/README.md
+++ b/README.md
@@ -138,7 +138,6 @@ $ ./buildlive --boot /media/boot --root /media/root arch fedora/32
I've made some experimental features that are not yet merged to the main source tree.
-- [metaiso](https://github.com/mytbk/liveusb-builder/tree/metaiso): support using a custom iso file for a certain distro
- [ia32efi-test](https://github.com/mytbk/liveusb-builder/commits/ia32efi-test): support IA32 EFI
## Status
diff --git a/buildlive b/buildlive
index ad607cb..120c14d 100755
--- a/buildlive
+++ b/buildlive
@@ -31,7 +31,7 @@ fatalerror() {
usage() {
>&2 cat << EOF
-$0 [--root <path>] [options] [distro 1] [distro 2] ...
+$0 [--root <path>] [options] [--distro=<metadist> <isofile>] [distro] ...
use $0 -L to list available distros
options:
--root <path>
@@ -103,6 +103,20 @@ do
--clean)
CLEAN_USB=1
;;
+ --distro=*)
+ metadist="${1/--distro=}"
+ if [ ! -f "distro/$metadist/meta" ]
+ then
+ fatalerror "distro/$metadist/meta not found"
+ fi
+ shift
+ isofn="$1"
+ if [ ! -f "$isofn" ]
+ then
+ fatalerror "File $isofn not found"
+ fi
+ DISTROLIST=(${DISTROLIST[@]} "/meta@$metadist@$isofn")
+ ;;
*=*|-*)
usage
exit 1
@@ -174,6 +188,17 @@ fi
for i in ${DISTROLIST[@]}
do
+ if [[ "$i" == /meta@* ]]
+ then
+ # FIXME: we assume the meta file path and the iso file name
+ # does not have '@' character
+ ISOFILE="$(echo "$i" | cut -d@ -f3)"
+ ISOLIST=("${ISOLIST[@]}" "$ISOFILE")
+ # TODO: we just use the file name as the ISO name
+ # can we do it better?
+ ISONAMELIST=("${ISONAMELIST[@]}" "$(basename "$ISOFILE")")
+ continue
+ fi
process_isoinfo "$i"
ISOLIST=("${ISOLIST[@]}" "$ISOFILE")
ISONAMELIST=("${ISONAMELIST[@]}" "$ISONAME")
@@ -199,16 +224,28 @@ do
DISTRO="${DISTROLIST[$i-1]}"
ISO_FILEPATH="$ISOPATH/$ISOFILE"
- set_distro "$DISTRO"
- export DISTRONAME KEYWORD # for grub and syslinux generation
-
- process_distro "$DISTRO"
+ if [[ "$DISTRO" == /meta@* ]]
+ then
+ metadir="$(echo "$DISTRO" | cut -d@ -f2)"
+ _meta=meta_
+ ISO_FILEPATH="$ISOFILE"
+ DISTRO="$metadir"
+ set_distro "$metadir"
+ KEYWORD="$ISONAME"
+ source "distro/$metadir/meta"
+ else
+ _meta=
+ ISO_FILEPATH="$ISOPATH/$ISOFILE"
+ set_distro "$DISTRO"
+ export DISTRONAME KEYWORD # for grub and syslinux generation
+ process_distro "$DISTRO"
+ fi
if [ "$GRUBCFG_ONLY" == 0 ]; then
install_live
fi
- gen_grubcfg "$DISTRO" >> "$GRUBCFG"
- gen_syslinux "$DISTRO" >> "$SYSLINUXCFG"
+ ${_meta}gen_grubcfg "$DISTRO" >> "$GRUBCFG"
+ ${_meta}gen_syslinux "$DISTRO" >> "$SYSLINUXCFG"
done
if [ "$GRUBCFG_ONLY" == 1 ]; then
diff --git a/distro/arch/meta b/distro/arch/meta
new file mode 100644
index 0000000..fcfe18f
--- /dev/null
+++ b/distro/arch/meta
@@ -0,0 +1,20 @@
+# SPDX-License-Identifier: GPL-3.0-or-later
+# TODO: detect kernel, initramfs, and ucode filenames
+
+entry() {
+ TITLE="$ISONAME"
+ prefix="/liveusb-kernel/$KEYWORD/arch/boot"
+ KERNEL="$prefix/x86_64/vmlinuz-linux"
+ INITRD=("$prefix/intel-ucode.img" "$prefix/amd-ucode.img"
+ "$prefix/x86_64/initramfs-linux.img")
+ OPTION="img_dev=/dev/disk/by-uuid/$UUID img_loop=liveusb-data/$KEYWORD/$ISONAME"
+ X64=y
+}
+
+install_live() {
+ install -d "$DATADIR/$KEYWORD" "$KERNELDIR/$KEYWORD"
+ iso_extract "${ISO_FILEPATH}" arch/boot/x86_64 'arch/boot/*.img' "$KERNELDIR/$KEYWORD/"
+ cp "${ISO_FILEPATH}" "$DATADIR/$KEYWORD/"
+}
+
+entries=(entry)
diff --git a/distro/opensuse/meta b/distro/opensuse/meta
new file mode 100644
index 0000000..87deffa
--- /dev/null
+++ b/distro/opensuse/meta
@@ -0,0 +1,20 @@
+entry() {
+ isofn="$(basename "$ISOFILE")"
+ label="$(get_iso_label "${ISO_FILEPATH}")"
+ TITLE="$label"
+ KERNEL=/liveusb-kernel/$KEYWORD/linux
+ INITRD=/liveusb-kernel/$KEYWORD/initrd
+ OPTION="root=live:CDLABEL=$label iso-scan/filename=liveusb-data/$KEYWORD/$isofn"
+ X64=y
+}
+
+install_live() {
+ mount_iso
+ install -d "$DATADIR/$KEYWORD" "$KERNELDIR/$KEYWORD"
+ cp "$ISOMNT/boot/x86_64/loader"/{linux,initrd} \
+ "$KERNELDIR/$KEYWORD"
+ umount_iso
+ cp "${ISO_FILEPATH}" "$DATADIR/$KEYWORD/"
+}
+
+entries=(entry)
diff --git a/distro/ubuntu/meta b/distro/ubuntu/meta
new file mode 100644
index 0000000..c051049
--- /dev/null
+++ b/distro/ubuntu/meta
@@ -0,0 +1,36 @@
+entry() {
+ if test -z "${ubt_kernel}" -o -z "${ubt_initrd}"
+ then
+ msg "warn: kernel image or initramfs not found."
+ msg " the Ubuntu based entry may not work."
+ fi
+ isofn="$(basename "$ISOFILE")"
+ TITLE="$ISONAME"
+ KERNEL="/liveusb-kernel/${KEYWORD}/${ubt_kernel}"
+ INITRD="/liveusb-kernel/${KEYWORD}/${ubt_initrd}"
+ OPTION="file=/cdrom/preseed/ubuntu.seed boot=casper iso-scan/filename=/liveusb-data/${KEYWORD}/${isofn}"
+ X64=y
+}
+
+install_live() {
+ install -d "$KERNELDIR/${KEYWORD}" "$DATADIR/${KEYWORD}"
+ mount_iso
+ ubt_kernel=($(find "$ISOMNT/casper/" -maxdepth 1 -name 'vmlinuz*'))
+ if [ "${#ubt_kernel[@]}" != 1 ]; then
+ fatalerror "panic: more than one kernel image found."
+ else
+ ubt_kernel="$(basename ${ubt_kernel[0]})"
+ fi
+ ubt_initrd=($(find "$ISOMNT/casper/" -maxdepth 1 -name 'initrd*'))
+ if [ "${#ubt_initrd[@]}" != 1 ]; then
+ fatalerror "panic: more than one initramfs image found."
+ else
+ ubt_initrd="$(basename ${ubt_initrd[0]})"
+ fi
+ cp "$ISOMNT/casper/${ubt_kernel}" "$ISOMNT/casper/${ubt_initrd}" \
+ "$KERNELDIR/${KEYWORD}/"
+ umount_iso
+ cp "$ISOFILE" "$DATADIR/${KEYWORD}/"
+}
+
+entries=(entry)
diff --git a/functions.sh b/functions.sh
index a3b3a8d..8f9db5f 100644
--- a/functions.sh
+++ b/functions.sh
@@ -61,6 +61,45 @@ process_distro() {
# ISOMNT="/media/$ISOFILE"
}
+# output_grub_entry
+# output_syslinux_entry
+# usage: first source the entry, then call this
+#
+# variables in entryfile:
+# - UUID: the UUID of the partition
+# - ISOFILE: the file name of iso
+#
+# parameters in entry file:
+# - TITLE: GRUB menu entry title
+# - KERNEL: path to kernel image
+# - INITRD: path to initramfs/initrd image
+# - OPTION: kernel command line
+# - X64: y/n, indicates whether it's 64-bit
+#
+output_grub_entry() {
+ cat << EOF
+menuentry '$TITLE' {
+ linux $KERNEL $OPTION
+ initrd ${INITRD[@]}
+}
+
+EOF
+}
+
+# we also need $LABEL when calling this
+output_syslinux_entry() {
+ _INITRD=$(echo ${INITRD[*]}|sed 's/ /,/g')
+
+ cat << EOF
+LABEL $LABEL
+MENU LABEL $TITLE
+LINUX $KERNEL
+INITRD $_INITRD
+APPEND $OPTION
+
+EOF
+}
+
gen_grubcfg() {
local entry allentries
allentries=("distro/$1/entry"*)
@@ -69,13 +108,50 @@ gen_grubcfg() {
fi
for entry in "${allentries[@]}"
do
- UUID="$UUID" ISOFILE="$ISOFILE" ./mkgrubcfg.sh "$entry"
+ unset INITRD # because it can be an array or just a string
+
+ source "$entry"
+ UUID="$UUID" ISOFILE="$ISOFILE" output_grub_entry
done
if [ ${#allentries[@]} -gt 1 ]; then
echo '}'
fi
}
+meta_gen_grubcfg() {
+ local entry
+ source "distro/$1/meta"
+ if [ ${#entries[@]} -gt 1 ]; then
+ echo "submenu '$ISONAME' {"
+ fi
+ for entry in "${entries[@]}"
+ do
+ unset INITRD # because it can be an array or just a string
+
+ "$entry"
+ UUID="$UUID" ISOFILE="$ISOFILE" output_grub_entry
+ done
+ if [ ${#entries[@]} -gt 1 ]; then
+ echo '}'
+ fi
+}
+
+meta_gen_syslinux() {
+ local entry count name
+ source "distro/$1/meta"
+ name=$(echo $1|sed 's/\//_/g')
+ count=0
+ for entry in "${entries[@]}"
+ do
+ unset INITRD # because it can be an array or just a string
+
+ "$entry"
+ UUID="$UUID" ISOFILE="$ISOFILE" LABEL="${name}_${count}" \
+ output_syslinux_entry
+ count=$(($count+1))
+ done
+}
+
gen_syslinux() {
local entry allentries count name
allentries=("distro/$1/entry"*)
@@ -83,8 +159,11 @@ gen_syslinux() {
count=0
for entry in "${allentries[@]}"
do
- UUID="$UUID" ISOFILE="$ISOFILE" LABEL="$name$count" \
- ./mksyslinux.sh "$entry"
+ unset INITRD # because it can be an array or just a string
+
+ source "$entry"
+ UUID="$UUID" ISOFILE="$ISOFILE" LABEL="${name}_${count}" \
+ output_syslinux_entry
count=$(($count+1))
done
}