]>
git.ipfire.org Git - people/ms/bricklayer.git/blob - src/bricklayer-master.in
2 ###############################################################################
4 # Bricklayer - An Installer for IPFire #
5 # Copyright (C) 2021 IPFire Development Team #
7 # This program is free software; you can redistribute it and/or #
8 # modify it under the terms of the GNU General Public License #
9 # as published by the Free Software Foundation; either version 2 #
10 # of the License, or (at your option) any later version. #
12 # This program is distributed in the hope that it will be useful, #
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of #
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
15 # GNU General Public License for more details. #
17 # You should have received a copy of the GNU General Public License #
18 # along with this program. If not, see <http://www.gnu.org/licenses/>. #
20 ###############################################################################
22 # Pakfire configuration file
23 PAKFIRE_CONFIG
="/etc/pakfire/distros/ipfire3.conf"
25 # Packages to install in the live system
28 "@PACKAGE@ >= @VERSION@"
36 BUILDSYSTEM_PACKAGES
=(
45 # Compress as best as we can
46 ZSTD_COMPRESSION_LEVEL
=22
48 # Grub modules to install
60 # The modules will only be installed for legacy boot
66 echo "BL_$(date -u "+%Y
%m
%d
%H
%M
")"
73 dd if=/dev
/zero of
="${path}" bs
=1k count
="${size}"
80 "${BUILDSYSTEM_PACKAGES[@]}"
84 if ! pakfire
--arch="${arch}" --config="${PAKFIRE_CONFIG}" --root="${path}" -y \
85 install --without-recommended "${packages[@]}"; then
86 echo "Could not install build system" >&2
92 if [ -z "${buildsystem}" ]; then
93 echo "Build system isn't set up" >&2
97 pakfire
--config="${PAKFIRE_CONFIG}" --root="${buildsystem}" execute
"$@"
100 make_live_system_image
() {
101 local filename
="${1}"
102 local os_release
="${2}"
105 local tempdir
="$(mktemp -d)"
107 # Install a very basic system
108 if ! pakfire
--arch="${arch}" --config="${PAKFIRE_CONFIG}" --root="${tempdir}" -y \
109 install --without-recommended "${PACKAGES[@]}" "$@"; then
110 echo "Could not install live system" >&2
115 # Copy /etc/os-release
116 if ! cat "${tempdir}/etc/os-release" > "${os_release}"; then
117 echo "Could not extract /etc/os-release" >&2
122 # Create a squashfs image
123 if ! mksquashfs
"${tempdir}" "${filename}" \
124 -comp zstd
-Xcompression-level "${ZSTD_COMPRESSION_LEVEL}"; then
134 make_boot_catalog
() {
137 allocate_file
"${path}" 2
140 make_grub_bios_image
() {
143 local tempdir
="$(mktemp -d)"
145 # Create a standalone image
146 if ! in_buildsystem
--bind="${tempdir}" \
148 --format="${grub_arch}-pc" \
149 --prefix="/boot/grub" \
150 --output="${tempdir}/core.img" \
151 "${GRUB_BIOS_MODULES[@]}" \
152 "${GRUB_MODULES[@]}"; then
157 # Append cdboot.img with the generated core.img
158 if ! cat "${buildsystem}/usr/lib/grub/${grub_arch}-pc/cdboot.img" "${tempdir}/core.img" \
160 unlink
"${tempdir}" "${path}"
177 # Make kernel commandline
179 # Tell dracut where to find the filesystem
180 "root=live:LABEL=${label}"
182 # Be less verbose during boot
186 cat > "${path}" <<EOF
187 # Bricklayer GRUB configuration
192 terminal_output gfxterm
195 # Try loading video output
198 # Select the first entry
201 # Wait for 60 seconds for the user to make a decision
204 menuentry 'Install ${name} (${arch})' --class ${class} --id install {
205 linux /boot/vmlinuz ${commandline[@]} installer
206 initrd /boot/initramfs.img
209 submenu 'Other Installation Options -->' {
210 menuentry 'Unattended installation' --class ${class} --id install.unattended {
211 linux /boot/vmlinuz ${commandline[@]} installer installer.unattended
212 initrd /boot/initramfs.img
218 make_grub_efi_config
() {
221 echo "search.fs_label \"${label}\" root"
222 echo "set prefix=(\$root)/boot/grub"
225 make_grub_efi_image
() {
230 local config
="$(mktemp)"
232 # Write early GRUB configuration
233 make_grub_efi_config
"${label}" > "${config}"
235 # Generate a GRUB image
236 if ! in_buildsystem
--bind="${tempdir}" --bind="${config}" \
238 --format="${arch}-efi" \
239 --prefix="/EFI/BOOT" \
241 --config="${config}" \
242 "${GRUB_MODULES[@]}"; then
243 echo "Could not generate GRUB EFI image" >&2
248 # Remove configuration
252 if ! allocate_file
"${efiboot}" 1440; then
257 if ! mkdosfs
-F 12 -n "BRICKLAYER" "${efiboot}"; then
258 echo "Could not format the EFI filesystem" >&2
263 local tempdir
="$(mktemp -d)"
266 if ! mount
-o loop
"${efiboot}" "${tempdir}"; then
267 echo "Could not mount EFI filesystem" >&2
268 rm -rf "${efiboot}" "${tempdir}"
272 mkdir
-p "${tempdir}/EFI/BOOT"
274 # Copy GRUB EFI image onto the FAT partition
275 if ! cp -- "${path}" "${tempdir}/EFI/BOOT/${path##*/}"; then
276 echo "Could not copy GRUB EFI image onto the FAT filesystem" >&2
277 rm -rf "${efiboot}" "${tempdir}"
281 # Umount the filesystem
282 if ! umount
"${tempdir}"; then
283 rm -rf "${efiboot}" "${tempdir}"
293 find_kernel_release
() {
295 for file in ${buildsystem}/usr
/lib
/modules
/*; do
296 if [ -d "${file}" ]; then
305 install_kernel_image
() {
306 local kernel_release
="${1}"
307 local filename
="${2}"
309 # Copy the kernel image
310 if ! cp -v "${buildsystem}/boot/vmlinuz-${kernel_release}" "${filename}"; then
311 echo "Could not install kernel image (release ${kernel_release})" >&2
318 install_initramfs
() {
319 local kernel_release
="${1}"
320 local filename
="${2}"
325 # Generate a ramdisk that can run on many hosts
328 --kmoddir "/usr/lib/modules/${kernel_release}"
330 # Add the live image module to mount our squashfs system
331 --add "dmsquash-live"
333 # Only enable these modules
334 --modules "base kernel-modules"
336 # Add support for squashfs
337 --filesystems "squashfs"
340 # The output is currently thrown away because dracut is broken and generates a lot
341 # of messages which slow down the build process...
342 if ! in_buildsystem
--bind="${tempdir}" \
343 dracut
"${args[@]}" "${filename}" "${kernel_release}"; then
352 local buildsystem
="${1}"
354 local filename
="${3}"
357 # Create a temporary working directory
358 local tempdir
="$(mktemp -d)"
360 # Create a directory for all the boot stuff
361 mkdir
-p "${tempdir}/boot"
363 # Create argument list for xorriso
365 # Emulate running as mkisofs
368 # Generate Joilet directory information
371 # Generate rationalized Rock Ridge directory information
377 # The name of the volume
380 # Set ISO9660 conformance level
383 # Where to write the output to?
384 -output "${filename}"
386 # What files to package?
390 # Determine GRUB architecture
391 local grub_arch
="${arch}"
402 # Find the kernel release
403 local kernel_release
="$(find_kernel_release)"
404 if [ -z "${kernel_release}" ]; then
405 echo "Could not find kernel release" >&2
409 # Install the kernel image
410 if ! install_kernel_image
"${kernel_release}" "${tempdir}/boot/vmlinuz"; then
415 # Create live ramdisk
416 if ! install_initramfs
"${kernel_release}" "${tempdir}/boot/initramfs.img"; then
421 # Generate GRUB BIOS image
422 if [ "${has_bios_boot}" = "true" ]; then
423 if ! make_grub_bios_image
"${tempdir}/boot/biosboot.img"; then
429 if ! make_boot_catalog
"${tempdir}/boot/boot.catalog"; then
434 # Append to xorriso command line
439 -b "boot/biosboot.img"
440 -c "boot/boot.catalog"
442 # Enable hybrid boot mode
444 --grub2-mbr "/usr/lib/grub/${grub_arch}-pc/boot_hybrid.img"
448 # Generate GRUB EFI image
449 if [ "${has_efi_boot}" = "true" ]; then
450 local grub_efi_arch
="${arch}"
461 # Create a directory for EFI stuff
462 mkdir
-p "${tempdir}/EFI/BOOT"
464 # Generate a GRUB EFI image
465 if ! make_grub_efi_image \
466 "${tempdir}/EFI/BOOT/boot${grub_efi_arch}.efi" \
467 "${tempdir}/boot/efiboot.img" \
473 # Append to xorriso command line
476 -e "boot/efiboot.img"
478 -isohybrid-gpt-basdat
482 local os_release
="$(mktemp)"
484 # Create the live system image
485 if ! make_live_system_image
"${tempdir}/squashfs.img" "${os_release}" \
486 "kernel = ${kernel_release}"; then
487 rm -rf "${tempdir}" "${os_release}"
491 # Source /etc/os-release
493 rm -f "${os_release}"
495 # Check if all necessary variables are set
497 for variable
in PRETTY_NAME ID
; do
498 if [ -n "${!variable}" ]; then
499 echo "WARNING: ${variable} is not set in /etc/os-release" >&2
503 mkdir
-p "${tempdir}/boot/grub"
505 # Generate GRUB configuration
506 if ! make_grub_config
"${tempdir}/boot/grub/grub.cfg" \
507 "${PRETTY_NAME}" "${ID}" "${arch}" "${label}"; then
508 echo "Could not generate GRUB configuration" >&2
513 mkdir
-p "${tempdir}/boot/grub/fonts"
517 for font
in unicode.pf2
; do
518 if ! cp -- "${buildsystem}/usr/share/grub/${font}" \
519 "${tempdir}/boot/grub/fonts/${font}"; then
520 echo "Could not install font '${font}'" >&2
526 # Master the ISO file
527 if ! xorriso
"${args[@]}"; then
532 rm -rf "${tempdir}" "${os_release}"
538 local arch
="$(uname -m)"
542 while [ $# -gt 0 ]; do
553 if [ -n "${filename}" ]; then
554 echo "Filename has already been set" >&2
562 echo "Unhandled argument: ${1}" >&2
570 if [ -z "${filename}" ]; then
571 echo "You have not specified a target filename" >&2
575 # Generate a random label if nothing was set
576 if [ -z "${label}" ]; then
577 label
="$(make_label)"
580 # Check if the label is < 16 characters
581 if [ "${#label}" -gt 16 ]; then
582 echo "The label cannot be longer than 16 characters" >&2
586 local has_bios_boot
="false"
587 local has_efi_boot
="false"
589 # Configure some architecture-dependent environment variables
600 # Throw an error on unhandled architectures
602 echo "Unknown architecture: ${arch}" >&2
607 local buildsystem
="$(mktemp -d)"
609 # Install a system with all tools we need
610 if ! make_buildsystem
"${buildsystem}"; then
614 # Make image and delete it if something went wrong
615 if ! mkimage
"${buildsystem}" "${label}" "${filename}"; then
616 rm -rf "${buildsystem}" "${filename}"
620 # Remove temporary system
621 rm -rf "${buildsystem}"