# Copyright (C) 2005 Mandriva # Olivier Blin # Copyright (C) 2017 Mageia # Martin Whitaker # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. package MGA::DrakISO::BuildISO; use strict; use MDK::Common; use common; use MGA::DrakISO::LiveBuild; use MGA::DrakISO::Loopback; use MGA::DrakISO::Utils; use MGA::DrakISO::BuildLoop; use Exporter; our @ISA = qw(Exporter); our @EXPORT = qw(build_live_iso); ############################################################################### # Live System ############################################################################### sub build_live_iso { my ($build) = @_; my $label = $build->{media}->get_media_label or die "the source device must be described by a label\n"; my $mbr_image = $build->get_absolute_path($build->{media}{mbr_boot_img}) // '/usr/lib/grub/i386-pc/boot_hybrid.img'; -e $mbr_image or die "cannot find MBR boot image $mbr_image\n"; my $esp_image = $build->get_builddir('images') . '/esp.img'; -e $esp_image or die "cannot find ESP image $esp_image\n"; my $dest = $build->get_builddir('dist') . '/' . $build->get_name . '.iso'; mkdir_p(dirname($dest)); build_iso_image( $build, $dest, $label, $mbr_image, $esp_image, '/boot=' . $build->get_builddir('boot'), if_($build->{settings}{arch} eq 'x86_64', '/EFI=' . $build->get_builddir('EFI'), ), ( map { '/loopbacks' . $_ . '=' . $build->get_builddir('loopbacks') . $_; } list_selected_loopbacks($build) ), if_($build->{media}{files}, map { $_ . '=' . $build->get_builddir('files') . '/' . $_; } all($build->get_builddir('files')) ), ); } sub list_selected_loopbacks { my ($build) = @_; my @pack = $build->{settings}{pack} ? @{$build->{packs}{$build->{settings}{pack}} || []} : (); my @pack_modules = grep { member($_->{name}, @pack) } list_loopback_modules($build); (map { $loop_types{$_->{type}}{is_loopback} && $_->{path} ? $_->{path} . $loop_types{$_->{type}}{extension} : () } @{$build->{mount}{dirs} || []}), (map { '/modules/' . $_->{name} . $loop_types{$_->{type}}{extension} } @pack_modules); } ############################################################################### # Generic ############################################################################### # This builds a hybrid ISO capable of both legacy and UEFI boot. The # ISO contains a primary iso9660 partition (which is the only thing # visible when booting from DVD) and a secondary ESP partition (which # is only used for USB UEFI boot). # # For legacy boot, the system boots the grub2 El Torito image. For DVD # boot, this is located via the El Torito catalogue. For USB boot, it # is located via the grub2 MBR hybrid boot image, which is stored in # the MBR. In both cases the initial grub2 root location is the iso9660 # partition, so the initial grub2 configuration file will be read from # that partition. # # For UEFI boot, the system boots the grub2 EFI image. For DVD boot, # this is located via the El Torito catalogue, and we store it in the # iso9660 partition. For USB boot, it must be located in the /EFI/BOOT # directory in the ESP. For DVD boot the initial grub2 root location is # the iso9660 partition, for USB boot it is the ESP partition, and the # initial grub2 configuration file will be located accordingly. # sub build_iso_image { my ($build, $dest, $label, $mbr_image, $esp_image, @opts) = @_; run_('xorrisofs', '-pad', '-l', '-R', '-J', '-V', $label, '-graft-points', '-hide-rr-moved', '--sort-weight', 0, '/', '--sort-weight', 1, '/boot', # for hybrid MBR boot '--grub2-mbr', $mbr_image, '-b', '/boot/grub2/eltorito.img', '-no-emul-boot', '-boot-load-size', 4, '-boot-info-table', '--grub2-boot-info', if_($build->{settings}{arch} eq 'x86_64', # for DVD UEFI boot '-eltorito-alt-boot', '-e', '/EFI/BOOT/bootx64.efi', '-no-emul-boot', # for USB UEFI boot '-part_like_isohybrid', '-iso_mbr_part_type', '0x00', '-append_partition', 2, '0xef', $esp_image, ), if_($dest, '-o', $dest), @opts, ) or die "unable to run xorrisofs\n"; if ($dest) { my $dir = dirname($dest); my $filename = basename($dest); run_('mgaiso-addmd5', '>', '/dev/null', '2>', '/dev/null', $dest); run_({ chdir => $dir }, 'md5sum', '>', $dest . '.md5', $filename); run_({ chdir => $dir }, 'sha1sum', '>', $dest . '.sha1', $filename); run_({ chdir => $dir }, 'sha512sum', '>', $dest . '.sha512', $filename); run_({ chdir => $dir }, 'date', '>', $dir . '/DATE.txt'); if (my $suffix = $build->get_set_suffix) { if (my ($prefix, $ext) = $dest =~ /(.*)(\.[^.]+)$/) { my $link = $prefix . $suffix . $ext; linkf($dest, $link); print "linked as $link\n"; } } } } 1;