mirror of
https://github.com/ublue-os/titanoboa.git
synced 2026-11-03 21:49:46 -09:00
554 lines
20 KiB
Makefile
554 lines
20 KiB
Makefile
set unstable := true
|
|
PODMAN := which("podman") || require("podman-remote")
|
|
workdir := env("TITANOBOA_WORKDIR", "work")
|
|
isoroot := env("TITANOBOA_ISO_ROOT", "work/iso-root")
|
|
rootfs := workdir/"rootfs"
|
|
default_image := "ghcr.io/ublue-os/bluefin:lts"
|
|
arch := arch()
|
|
### BUILDER CONFIGURATION ###
|
|
# Distribution to use for the builder container (for tools and dependencies)
|
|
# Supported values: fedora, centos, almalinux
|
|
# Set via TITANOBOA_BUILDER_DISTRO environment variable (default: fedora)
|
|
builder_distro := env("TITANOBOA_BUILDER_DISTRO", "fedora")
|
|
##############################
|
|
|
|
### HOOKS SCRIPT PATHS ###
|
|
# Path to scripts used as hooks in between steps, used in 'hook-*' recipes.
|
|
# Must follow the naming convention HOOK_<recipe name without 'hook_' prefix>
|
|
|
|
# Hook used for custom operations done in the rootfs before it is squashed.
|
|
HOOK_post_rootfs := env("HOOK_post_rootfs", "")
|
|
|
|
# Hook used for custom operations done before the initramfs is generated.
|
|
HOOK_pre_initramfs := env("HOOK_pre_initramfs", "")
|
|
##########################
|
|
|
|
### UTILS ###
|
|
_ci_grouping := '''
|
|
if [[ -n "${CI:-}" ]]; then
|
|
echo "::group::${BASH_SOURCE[0]##*/} step"
|
|
trap 'echo ::endgroup::' EXIT
|
|
fi
|
|
'''
|
|
[private]
|
|
just := just_executable() + " -f " + source_file()
|
|
|
|
[private]
|
|
git_root := source_dir()
|
|
|
|
[private]
|
|
builder_image := if builder_distro == "fedora" { "quay.io/fedora/fedora:latest" } else if builder_distro == "centos" { "ghcr.io/hanthor/centos-anaconda-builder:main" } else if builder_distro == "almalinux-kitten" { "quay.io/almalinuxorg/almalinux:10-kitten" } else if builder_distro == "almalinux" { "quay.io/almalinuxorg/almalinux:10" } else { error("Unsupported builder distribution: " + builder_distro + ". Supported: fedora, centos, almalinux") }
|
|
|
|
|
|
[private]
|
|
chroot_function := '
|
|
function chroot(){
|
|
local command="$1"
|
|
shift
|
|
local args="$*"
|
|
' + PODMAN + ' run --rm -it \
|
|
--privileged \
|
|
--security-opt label=type:unconfined_t \
|
|
$args \
|
|
--tmpfs /tmp:rw \
|
|
--tmpfs /run:rw \
|
|
--volume ' + git_root + ':/app \
|
|
--rootfs ' + git_root/rootfs + ' \
|
|
/usr/bin/bash -c "$command"
|
|
}'
|
|
|
|
[private]
|
|
builder_function := '
|
|
function builder(){
|
|
local command="$1"
|
|
shift
|
|
local args="$*"
|
|
' + PODMAN + ' run --rm -it \
|
|
--privileged \
|
|
--security-opt label=disable \
|
|
--volume ' + git_root + ':/app \
|
|
' + builder_image + ' \
|
|
/usr/bin/bash -c "$command" $args
|
|
}'
|
|
|
|
[private]
|
|
compress_dependencies := '''
|
|
function compress_dependencies(){
|
|
local MISSING=()
|
|
local DEPS=(
|
|
mksquashfs
|
|
mkfs.erofs
|
|
)
|
|
for dep in "${DEPS[@]}"; do
|
|
if ! command -v $dep >/dev/null; then
|
|
MISSING+=($dep)
|
|
fi
|
|
done
|
|
echo "${#MISSING[@]}"
|
|
}
|
|
'''
|
|
|
|
[private]
|
|
iso_dependencies := '
|
|
function iso_dependencies(){
|
|
local MISSING=()
|
|
local RPMS=(
|
|
dosfstools
|
|
grub2
|
|
grub2-efi
|
|
grub2-tools
|
|
grub2-tools-extra
|
|
shim
|
|
xorriso
|
|
)
|
|
if [[ "' + arch + '" == "x86_64" ]]; then
|
|
RPMS+=(
|
|
grub2-efi-x64
|
|
grub2-efi-x64-cdboot
|
|
grub2-efi-x64-modules
|
|
)
|
|
elif [[ "' + arch + '" == "aarch64" ]]; then
|
|
RPMS+=(grub2-efi-aa64-modules)
|
|
fi
|
|
if ! command -v rpm >/dev/null; then
|
|
echo "1"
|
|
return
|
|
fi
|
|
for rpm in "${RPMS[@]}"; do
|
|
if ! rpm -q $rpm >/dev/null; then
|
|
MISSING+=($rpm)
|
|
fi
|
|
done
|
|
echo "${#MISSING[@]}"
|
|
}'
|
|
#############
|
|
|
|
# Default
|
|
@default:
|
|
{{ just }} --list
|
|
|
|
# Create Directories
|
|
init-work:
|
|
@echo "{{ style('command') }}Creating Work Directories...{{ NORMAL }}" >&2
|
|
mkdir -p {{ workdir }}
|
|
mkdir -p {{ isoroot }}
|
|
mkdir -p {{ rootfs }}
|
|
|
|
# Extract rootfs
|
|
rootfs image=default_image:
|
|
#!/usr/bin/env bash
|
|
{{ _ci_grouping }}
|
|
set -xeuo pipefail
|
|
# Pull and Extract Filesystem
|
|
{{ PODMAN }} pull {{ image }} # Pull newer image
|
|
ctr="$({{ PODMAN }} create --rm {{ image }} /usr/bin/bash)" && trap "{{ PODMAN }} rm $ctr" EXIT
|
|
{{ PODMAN }} export $ctr | tar --xattrs-include='*' -p -xf - -C {{ rootfs }}
|
|
|
|
# Make /var/tmp be a tmpfs by symlinking to /tmp,
|
|
# in order to make bootc work at runtime.
|
|
rm -rf {{ rootfs }}/var/tmp
|
|
ln -sr {{ rootfs }}/tmp {{ rootfs }}/var/tmp
|
|
|
|
# Generate initramfs with live modules
|
|
initramfs:
|
|
#!/usr/bin/env bash
|
|
{{ _ci_grouping }}
|
|
{{ chroot_function }}
|
|
set -euo pipefail
|
|
CMD='set -xeuo pipefail
|
|
dnf install -y dracut-live
|
|
INSTALLED_KERNEL=$(rpm -q kernel-core --queryformat "%{evr}.%{arch}" | tail -n 1)
|
|
mkdir -p $(realpath /root)
|
|
export DRACUT_NO_XATTR=1
|
|
dracut --zstd --reproducible --no-hostonly --kver "$INSTALLED_KERNEL" --add "dmsquash-live dmsquash-live-autooverlay" --force /app/{{ workdir }}/initramfs.img |& grep -v -e "Operation not supported"'
|
|
chroot "$CMD"
|
|
|
|
# Embed the container
|
|
rootfs-include-container container_image=default_image image=default_image:
|
|
#!/usr/bin/env bash
|
|
{{ _ci_grouping }}
|
|
{{ chroot_function }}
|
|
set -euo pipefail
|
|
CMD="set -xeuo pipefail
|
|
mkdir -p /var/lib/containers/storage
|
|
podman pull {{ container_image || image }}
|
|
dnf install -y fuse-overlayfs"
|
|
chroot "$CMD"
|
|
|
|
# Install Flatpaks into the live system
|
|
rootfs-include-flatpaks FLATPAKS_FILE="src/flatpaks.example.txt":
|
|
#!/usr/bin/env bash
|
|
{{ _ci_grouping }}
|
|
{{ if FLATPAKS_FILE =~ '(^$|^(?i)\bnone\b$)' { 'exit 0' } else if path_exists(FLATPAKS_FILE) == 'false' { error('Flatpak file inaccessible: ' + FLATPAKS_FILE) } else { '' } }}
|
|
{{ chroot_function }}
|
|
CMD='set -xeuo pipefail
|
|
mkdir -p /var/lib/flatpak
|
|
dnf install -y flatpak
|
|
|
|
# Get Flatpaks
|
|
flatpak remote-add --if-not-exists flathub "https://dl.flathub.org/repo/flathub.flatpakrepo"
|
|
grep -v "#.*" /flatpak-list/$(basename {{ FLATPAKS_FILE }}) | sort --reverse | xargs "-i{}" -d "\n" sh -c "flatpak remote-info --arch={{ arch }} --system flathub {} &>/dev/null && flatpak install --noninteractive -y {}" || true'
|
|
set -euo pipefail
|
|
chroot "$CMD" --volume "$(realpath "$(dirname {{ FLATPAKS_FILE }})")":/flatpak-list
|
|
|
|
# Install polkit rules
|
|
rootfs-include-polkit polkit="1":
|
|
#!/usr/bin/env bash
|
|
{{ _ci_grouping }}
|
|
{{ if polkit == "0" { 'exit 0' } else { '' } }}
|
|
set -euo pipefail
|
|
install -D -m 0644 {{ git_root }}/src/polkit-1/rules.d/*.rules -t {{ rootfs }}/etc/polkit-1/rules.d
|
|
|
|
# Install Livesys Scripts
|
|
rootfs-install-livesys-scripts livesys="1":
|
|
#!/usr/bin/env bash
|
|
{{ _ci_grouping }}
|
|
{{ if livesys == "0" { 'exit 0' } else { '' } }}
|
|
{{ chroot_function }}
|
|
set -euo pipefail
|
|
CMD='set -xeuo pipefail
|
|
dnf="$({ which dnf5 || which dnf; } 2>/dev/null)"
|
|
$dnf install -y livesys-scripts
|
|
|
|
# Determine desktop environment. Must match one of /usr/libexec/livesys/sessions.d/livesys-{desktop_env}
|
|
desktop_env=""
|
|
_session_file="$(find /usr/share/wayland-sessions/ /usr/share/xsessions \
|
|
-maxdepth 1 -type f -not -name '*gamescope*.desktop' -and -name '*.desktop' -printf '%P' -quit)"
|
|
case $_session_file in
|
|
budgie*) desktop_env=budgie ;;
|
|
cosmic*) desktop_env=cosmic ;;
|
|
gnome*) desktop_env=gnome ;;
|
|
plasma*) desktop_env=kde ;;
|
|
sway*) desktop_env=sway ;;
|
|
xfce*) desktop_env=xfce ;;
|
|
*) echo "\
|
|
{{ style('error') }}ERROR[rootfs-install-livesys-scripts]{{ NORMAL }}\
|
|
: No Livesys Environment Found"; exit 1 ;;
|
|
esac && unset -v _session_file
|
|
sed -i "s/^livesys_session=.*/livesys_session=${desktop_env}/" /etc/sysconfig/livesys
|
|
|
|
# Enable services
|
|
systemctl enable livesys.service livesys-late.service
|
|
|
|
# Set default time zone to prevent oddities with KDE clock
|
|
echo "C /var/lib/livesys/livesys-session-extra 0755 root root - /usr/share/factory/var/lib/livesys/livesys-session-extra" > \
|
|
/usr/lib/tmpfiles.d/livesys-session-extra.conf'
|
|
chroot "$CMD"
|
|
install -D -m 0644 {{ git_root }}/src/livesys-session-extra {{ rootfs }}/usr/share/factory/var/lib/livesys/livesys-session-extra
|
|
|
|
# Hook used for custom operations done in the rootfs before it is squashed.
|
|
# Meant to be used in a GH action.
|
|
hook-post-rootfs hook=HOOK_post_rootfs:
|
|
#!/usr/bin/env bash
|
|
{{ _ci_grouping }}
|
|
{{ if hook == '' { 'exit 0' } else { '' } }}
|
|
{{ chroot_function }}
|
|
set -euo pipefail
|
|
chroot "$(cat '{{ hook }}')"
|
|
|
|
# Hook used for custom operations done before the initramfs is generated.
|
|
# Meant to be used in a GH action.
|
|
hook-pre-initramfs hook=HOOK_pre_initramfs:
|
|
#!/usr/bin/env bash
|
|
{{ _ci_grouping }}
|
|
{{ if hook == '' { 'exit 0' } else { '' } }}
|
|
{{ chroot_function }}
|
|
set -euo pipefail
|
|
chroot "$(cat '{{ hook }}')"
|
|
|
|
# Remove the sysroot tree
|
|
rootfs-clean-sysroot:
|
|
#!/usr/bin/env bash
|
|
{{ _ci_grouping }}
|
|
{{ chroot_function }}
|
|
set -euo pipefail
|
|
CMD='set -xeuo pipefail
|
|
if [[ -d /app ]]; then
|
|
rm -rf /sysroot /ostree
|
|
dnf autoremove -y
|
|
dnf clean all -y
|
|
fi'
|
|
chroot "$CMD"
|
|
|
|
# Fix SELinux Permissions
|
|
rootfs-selinux-fix image=default_image:
|
|
#!/usr/bin/env bash
|
|
{{ _ci_grouping }}
|
|
set -euo pipefail
|
|
CMD='set -xeuo pipefail
|
|
cd /app/{{ rootfs }}
|
|
setfiles -F -r . /etc/selinux/targeted/contexts/files/file_contexts .
|
|
chcon --user=system_u --recursive .'
|
|
{{ PODMAN }} run --rm -it \
|
|
--volume {{ git_root }}:/app \
|
|
--workdir "/app" \
|
|
--security-opt label=disable \
|
|
--privileged \
|
|
{{ image }} \
|
|
/usr/bin/bash -c "$CMD"
|
|
rmdir {{ rootfs }}/app || true
|
|
|
|
# Compress rootfs into a compressed image
|
|
squash fs_type="squashfs":
|
|
#!/usr/bin/env bash
|
|
{{ _ci_grouping }}
|
|
CMD='{{ if fs_type == "squashfs" { "mksquashfs $0 $1/squashfs.img -all-root -noappend" } else if fs_type == "erofs" { "mkfs.erofs -d0 --quiet --all-root -zlz4hc,6 -Eall-fragments,fragdedupe=inode -C1048576 $1/squashfs.img $0" } else { error(style('error') + "ERROR[squash]" + NORMAL + ": Invalid Compression") } }}'
|
|
{{ compress_dependencies }}
|
|
{{ builder_function }}
|
|
set -euo pipefail
|
|
BUILDER="$(compress_dependencies)"
|
|
if ! (( BUILDER )); then
|
|
bash -c "$CMD" "$(realpath {{ rootfs }})" "$(realpath {{ workdir }})"
|
|
else
|
|
CMD="dnf install -y {{ if fs_type == 'squashfs' { 'squashfs-tools' } else if fs_type == 'erofs' { 'erofs-utils' } else { '' } }} ; $CMD"
|
|
builder "$CMD" "/app/{{ rootfs }}" "/app/{{ workdir }}"
|
|
fi
|
|
|
|
# Expand grub templace, according to the image os-release.
|
|
process-grub-template $extra_kargs="NONE":
|
|
#!/usr/bin/env bash
|
|
{{ _ci_grouping }}
|
|
set -xeuo pipefail
|
|
kargs=()
|
|
IFS=',' read -r -a kargs <<< "$extra_kargs"
|
|
if [[ "$extra_kargs" == "NONE" ]]; then
|
|
kargs=()
|
|
fi
|
|
|
|
OS_RELEASE="{{ rootfs }}/usr/lib/os-release"
|
|
TMPL="src/grub.cfg.tmpl"
|
|
DEST="{{ isoroot }}/boot/grub/grub.cfg"
|
|
# TODO figure out a better mechanism
|
|
PRETTY_NAME="$(source "$OS_RELEASE" >/dev/null && echo "${PRETTY_NAME/ (*)}")"
|
|
sed \
|
|
-e "s|@PRETTY_NAME@|${PRETTY_NAME}|g" \
|
|
-e "s|@EXTRA_KARGS@|${kargs[*]}|g" \
|
|
"$TMPL" >"$DEST"
|
|
|
|
# Prep the environment for the ISO
|
|
iso-organize extra_kargs: && (process-grub-template extra_kargs)
|
|
#!/usr/bin/env bash
|
|
{{ _ci_grouping }}
|
|
set -xeuo pipefail
|
|
mkdir -p {{ isoroot }}/boot/grub {{ isoroot }}/LiveOS
|
|
cp {{ rootfs }}/lib/modules/*/vmlinuz {{ isoroot }}/boot
|
|
cp {{ workdir }}/initramfs.img {{ isoroot }}/boot
|
|
# Hardcoded on the dmsquash-live source code unless specified otherwise via kargs
|
|
# https://github.com/dracut-ng/dracut-ng/blob/0ffc61e536d1193cb837917d6a283dd6094cb06d/modules.d/90dmsquash-live/dmsquash-live-root.sh#L23
|
|
{{ if env('CI', '') == '' { 'cp' } else { 'mv' } }} {{ workdir }}/squashfs.img {{ isoroot }}/LiveOS/squashfs.img
|
|
|
|
# Build the ISO from the compressed image
|
|
iso:
|
|
#!/usr/bin/env bash
|
|
{{ _ci_grouping }}
|
|
{{ if env('CI', '') != '' { "echo '" + style('warning') + "In CI - Deleting: " + rootfs + "...' " + NORMAL +"; rm -rf " + rootfs } else { '' } }}
|
|
{{ iso_dependencies }}
|
|
BUILDER="$(iso_dependencies)"
|
|
CMD='set -xeuo pipefail
|
|
ISOROOT="$0"
|
|
WORKDIR="$1"
|
|
|
|
mkdir -p $ISOROOT/EFI/BOOT
|
|
# ARCH_SHORT needs to be uppercase
|
|
ARCH_SHORT="$(echo {{ arch }} | sed 's/x86_64/x64/g' | sed 's/aarch64/aa64/g')"
|
|
ARCH_32="$(echo {{ arch }} | sed 's/x86_64/ia32/g' | sed 's/aarch64/arm/g')"
|
|
if [[ "$(rpm -E %centos)" -ge 10 ]]; then
|
|
cp -avf /boot/efi/EFI/centos/. $ISOROOT/EFI/BOOT
|
|
elif [[ "$(rpm -E %fedora)" -ge 41 ]]; then
|
|
cp -avf /boot/efi/EFI/fedora/. $ISOROOT/EFI/BOOT
|
|
fi
|
|
cp -avf $ISOROOT/boot/grub/grub.cfg $ISOROOT/EFI/BOOT/BOOT.conf
|
|
cp -avf $ISOROOT/boot/grub/grub.cfg $ISOROOT/EFI/BOOT/grub.cfg
|
|
cp -avf /boot/grub*/fonts/unicode.pf2 $ISOROOT/EFI/BOOT/fonts
|
|
cp -avf $ISOROOT/EFI/BOOT/shim${ARCH_SHORT}.efi "$ISOROOT/EFI/BOOT/BOOT${ARCH_SHORT^^}.efi"
|
|
cp -avf $ISOROOT/EFI/BOOT/shim.efi "$ISOROOT/EFI/BOOT/BOOT${ARCH_32}.efi"
|
|
|
|
ARCH_GRUB="$(echo {{ arch }} | sed 's/x86_64/i386-pc/g' | sed 's/aarch64/arm64-efi/g')"
|
|
ARCH_OUT="$(echo {{ arch }} | sed 's/x86_64/i386-pc-eltorito/g' | sed 's/aarch64/arm64-efi/g')"
|
|
ARCH_MODULES="$(echo {{ arch }} | sed 's/x86_64/biosdisk/g' | sed 's/aarch64/efi_gop/g')"
|
|
|
|
grub2-mkimage -O $ARCH_OUT -d /usr/lib/grub/$ARCH_GRUB -o $ISOROOT/boot/eltorito.img -p /boot/grub iso9660 $ARCH_MODULES
|
|
grub2-mkrescue -o $ISOROOT/../efiboot.img
|
|
|
|
EFI_BOOT_MOUNT=$(mktemp -d)
|
|
mount $ISOROOT/../efiboot.img $EFI_BOOT_MOUNT
|
|
cp -r $EFI_BOOT_MOUNT/boot/grub $ISOROOT/boot/
|
|
umount $EFI_BOOT_MOUNT
|
|
rm -rf $EFI_BOOT_MOUNT
|
|
|
|
# https://github.com/FyraLabs/katsu/blob/1e26ecf74164c90bc24299a66f8495eb2aef4845/src/builder.rs#L145
|
|
EFI_BOOT_PART=$(mktemp -d)
|
|
fallocate $WORKDIR/efiboot.img -l 25M
|
|
mkfs.msdos -v -n EFI $WORKDIR/efiboot.img
|
|
mount $WORKDIR/efiboot.img $EFI_BOOT_PART
|
|
mkdir -p $EFI_BOOT_PART/EFI/BOOT
|
|
cp -dRvf $ISOROOT/EFI/BOOT/. $EFI_BOOT_PART/EFI/BOOT
|
|
umount $EFI_BOOT_PART
|
|
|
|
ARCH_SPECIFIC=()
|
|
if [ "{{ arch }}" == "x86_64" ] ; then
|
|
ARCH_SPECIFIC=("--grub2-mbr" "/usr/lib/grub/i386-pc/boot_hybrid.img")
|
|
fi
|
|
|
|
xorrisofs \
|
|
-R \
|
|
-V titanoboa_boot \
|
|
-partition_offset 16 \
|
|
-appended_part_as_gpt \
|
|
-append_partition 2 C12A7328-F81F-11D2-BA4B-00A0C93EC93B \
|
|
$ISOROOT/../efiboot.img \
|
|
-iso_mbr_part_type EBD0A0A2-B9E5-4433-87C0-68B6B72699C7 \
|
|
-c boot.cat --boot-catalog-hide \
|
|
-b boot/eltorito.img \
|
|
-no-emul-boot \
|
|
-boot-load-size 4 \
|
|
-boot-info-table \
|
|
--grub2-boot-info \
|
|
-eltorito-alt-boot \
|
|
-e \
|
|
--interval:appended_partition_2:all:: \
|
|
-no-emul-boot \
|
|
-vvvvv \
|
|
-iso-level 3 \
|
|
-o /app/output.iso \
|
|
"${ARCH_SPECIFIC[@]}" \
|
|
$ISOROOT'
|
|
set -euo pipefail
|
|
if ! (( BUILDER )); then
|
|
bash -c "$CMD" "$(realpath {{ isoroot }})" "$(realpath {{ workdir }})"
|
|
else
|
|
{{ if `systemd-detect-virt -c || true` != 'none' { "echo '" + style('error') + "ERROR[iso]" + NORMAL + ": Cannot run in nested containers'; exit 1" } else { '' } }}
|
|
{{ builder_function }}
|
|
CMD="dnf install -y grub2 grub2-efi grub2-tools grub2-tools-extra xorriso shim dosfstools {{ if arch == "x86_64" { 'grub2-efi-x64-modules grub2-efi-x64-cdboot grub2-efi-x64' } else if arch == "aarch64" { 'grub2-efi-aa64-modules' } else { '' } }}; $CMD"
|
|
builder "$CMD" "/app/{{ isoroot }}" "/app/{{ workdir }}"
|
|
fi
|
|
|
|
# TODO update this recipe parameters. Make it actually usable
|
|
[no-exit-message]
|
|
[doc('Build a live-iso')]
|
|
@build image=default_image livesys="1" flatpaks_file="src/flatpaks.example.txt" compression="squashfs" extra_kargs="NONE" container_image=image polkit="1": \
|
|
checkroot \
|
|
(show-config image livesys flatpaks_file compression extra_kargs container_image polkit) \
|
|
clean \
|
|
init-work \
|
|
(rootfs image) \
|
|
(hook-pre-initramfs HOOK_pre_initramfs) \
|
|
initramfs \
|
|
(rootfs-include-flatpaks flatpaks_file) \
|
|
(rootfs-include-polkit polkit) \
|
|
(rootfs-install-livesys-scripts livesys) \
|
|
(rootfs-include-container container_image image) \
|
|
(hook-post-rootfs HOOK_post_rootfs) \
|
|
rootfs-clean-sysroot \
|
|
(rootfs-selinux-fix image) \
|
|
(ci-delete-image image) \
|
|
(squash compression) \
|
|
(iso-organize extra_kargs) \
|
|
iso
|
|
mv ./output.iso {{ justfile_dir() }} &>/dev/null
|
|
|
|
|
|
@show-config image livesys flatpaks_file compression extra_kargs container_image polkit:
|
|
echo "Using the following configuration:"
|
|
echo "{{ style('warning') }}################################################################################{{ NORMAL }}"
|
|
echo "PODMAN := {{ PODMAN }}"
|
|
echo "workdir := {{ workdir }}"
|
|
echo "isoroot := {{ isoroot }}"
|
|
echo "rootfs := {{ rootfs }}"
|
|
echo "builder_distro := {{ builder_distro }}"
|
|
echo "builder_image := {{ builder_image }}"
|
|
echo "HOOK_post_rootfs := {{ if HOOK_post_rootfs =~ '(^$|^(?i)\bnone\b$)' { '' } else { canonicalize(HOOK_post_rootfs) } }}"
|
|
echo "HOOK_pre_initramfs := {{ if HOOK_pre_initramfs =~ '(^$|^(?i)\bnone\b$)' { '' } else { canonicalize(HOOK_pre_initramfs) } }}"
|
|
echo "image := {{ image }}"
|
|
echo "livesys := {{ livesys }}"
|
|
echo "flatpaks_file := {{ if flatpaks_file =~ '(^$|^(?i)\bnone\b$)' { '' } else { canonicalize(flatpaks_file) } }}"
|
|
echo "compression := {{ compression }}"
|
|
echo "extra_kargs := {{ extra_kargs }}"
|
|
echo "container_image := {{ container_image || image }}"
|
|
echo "polkit := {{ polkit }}"
|
|
echo "CI := {{ env('CI', '') }}"
|
|
echo "ARCH := {{ arch }}"
|
|
echo "{{ style('warning') }}################################################################################{{ NORMAL }}"
|
|
sleep 1
|
|
|
|
|
|
[no-exit-message]
|
|
@checkroot:
|
|
if [ `id -u` -gt 0 ]; then echo '{{ style("error") }}ERROR[build]{{ NORMAL }}: Must be root to build ISO' >&2 && exit 1; fi
|
|
|
|
@clean:
|
|
echo "{{ style('command') }}cleaning {{ absolute_path(workdir) }}...{{ NORMAL }}" >&2
|
|
rm -rf {{ absolute_path(workdir) }}
|
|
|
|
[private]
|
|
delete-image image:
|
|
#!/usr/bin/env bash
|
|
set -xeuo pipefail
|
|
{{ PODMAN }} rmi --force "{{ image }}" || :
|
|
|
|
[private]
|
|
ci-delete-image image:
|
|
#!/usr/bin/env bash
|
|
set -xeuo pipefail
|
|
if [[ -n "${CI:-}" ]]; then
|
|
{{ PODMAN }} rmi --force {{ image }} || :
|
|
fi
|
|
|
|
# Run VM with qemu
|
|
vm ISO_FILE *ARGS:
|
|
#!/usr/bin/env bash
|
|
qemu="qemu-system-{{ arch }}"
|
|
if [[ ! $(type -P "$qemu") ]]; then
|
|
qemu="flatpak run --command=$qemu org.virt_manager.virt-manager"
|
|
fi
|
|
$qemu \
|
|
-enable-kvm \
|
|
-M q35 \
|
|
-cpu host \
|
|
-smp $(( $(nproc) / 2 > 0 ? $(nproc) / 2 : 1 )) \
|
|
-m 4G \
|
|
-net nic,model=virtio \
|
|
-net user,hostfwd=tcp::2222-:22 \
|
|
-display gtk,show-cursor=on \
|
|
-boot d \
|
|
-cdrom {{ ISO_FILE }} {{ ARGS }}
|
|
|
|
# Run VM with a container and web vnc
|
|
container-run-vm ISO_FILE:
|
|
#!/usr/bin/env bash
|
|
set -xeuo pipefail
|
|
# Determine an available port to use
|
|
port=8006
|
|
while grep -q :${port} <<< $(ss -tunalp); do
|
|
port=$(( port + 1 ))
|
|
done
|
|
echo "Using Port: ${port}"
|
|
echo "Connect to http://localhost:${port}"
|
|
|
|
# Ram Size
|
|
mem_free=$(awk '/MemAvailable/ { printf "%.0f\n", $2/1024/1024 - 1 }' /proc/meminfo)
|
|
ram_size=$(( mem_free > 64 ? mem_free / 2 : (mem_free > 8 ? 8 : (mem_free < 3 ? 3 : mem_free)) ))
|
|
|
|
# Set up the arguments for running the VM
|
|
run_args=()
|
|
run_args+=(--rm --privileged)
|
|
run_args+=(--pull=newer)
|
|
run_args+=(--publish "127.0.0.1:${port}:8006")
|
|
run_args+=(--env "CPU_CORES=$(( $(nproc) / 2 > 0 ? $(nproc) / 2 : 1 ))")
|
|
run_args+=(--env "RAM_SIZE=${ram_size}G")
|
|
run_args+=(--env "DISK_SIZE=64G")
|
|
run_args+=(--env "TPM=Y")
|
|
run_args+=(--env "GPU=Y")
|
|
run_args+=(--env "BOOT_MODE=windows_secure")
|
|
run_args+=(--device=/dev/kvm)
|
|
run_args+=(--volume "{{ canonicalize(ISO_FILE) }}":"/boot.iso")
|
|
run_args+=(ghcr.io/qemus/qemu)
|
|
|
|
# Run the VM and open the browser to connect
|
|
{{ PODMAN }} run "${run_args[@]}" &
|
|
xdg-open http://localhost:${port}
|
|
|
|
# Print the absolute of the files relative to the project dir.
|
|
[private]
|
|
whereis +FILE_PATHS:
|
|
@realpath -e {{ FILE_PATHS }}
|