# Copyright (C) 2005 Mandriva # Olivier Blin # Copyright (C) 2017-2018 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA. # SYNOPSIS # -------- # This package provides a function to finally build the ISO image. package MGA::DrakISO::BuildISO; use strict; use MDK::Common; use MGA::DrakISO::ISOBuild; use MGA::DrakISO::Utils; use Exporter; our @ISA = qw(Exporter); our @EXPORT = qw(build_iso); # This is the top-level function called to build an ISO image. It generates # the list of file assignments before calling build_iso_image() to do the # actual work. All the files to go on the ISO should be stored in or linked # into the build directory before calling this function. # sub build_iso { my ($build) = @_; my $efi_type = $build->{media}{efi_type} || 'none'; my $loopbacks = $build->get_build_dir('loopbacks'); my $files = $build->get_build_dir('files'); build_iso_image( $build, '/boot=' . $build->get_build_dir('boot'), if_($efi_type ne 'none', '/EFI=' . $build->get_build_dir('EFI'), ), if_(-d $loopbacks, '/loopbacks=' . $loopbacks ), if_(-d $files, map { $_ . '=' . $files . '/' . $_; } all($files) ), ); } # This function builds a hybrid ISO capable of both legacy and EFI 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 EFI 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 EFI 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, @opts) = @_; my $efi_type = $build->{media}{efi_type} || 'none'; 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 "ERROR: cannot find MBR boot image $mbr_image\n"; my $esp_image = $build->get_build_dir('images') . '/esp.img'; my $build_dir = $build->get_build_dir('dist'); mkdir_p($build_dir); my $iso_name = $build->get_name . '.iso'; my $iso_part_start = $build->{media}{iso_part_start} || 0; $iso_part_start == 0 || $iso_part_start == 1 or die "ERROR: unsupported start sector for ISO protective partition\n"; my $iso_part_type = $build->{media}{iso_part_type} || '0x00'; my $dest = $build_dir . '/' . $iso_name; my $xorriso_version = `xorriso -version 2> /dev/null | head -1`; chomp($xorriso_version); my $date_file = $build_dir . '/DATE.txt'; run_("date > $date_file"); run_('xorrisofs', if_($::verbose < 2, '-quiet'), '-pad', '-l', '-R', '-J', '-publisher', $build->{settings}{vendor}, '-preparer', 'drakiso', '-sysid', 'Linux', '-appid', $xorriso_version, '-volid', $build->{media}{label}, '-follow-links', '-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_($efi_type ne 'none', # for DVD EFI boot '--efi-boot', '--interval:appended_partition_2:all::', # for USB EFI boot '-part_like_isohybrid', '-iso_mbr_part_type', $iso_part_type, if_($build->{media}{iso_part_start} == 1, '--protective-msdos-label', ), '-append_partition', 2, '0xef', $esp_image, ), '-o', $dest, @opts, '/DATE.txt=' . $date_file, ) or die "ERROR: unable to run xorrisofs\n"; run_("mgaiso-addmd5 $dest > /dev/null 2> /dev/null"); run_("cd $build_dir && md5sum $iso_name > $iso_name.md5"); run_("cd $build_dir && sha1sum $iso_name > $iso_name.sha1"); run_("cd $build_dir && sha512sum $iso_name > $iso_name.sha512"); 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"; } } print "Created ISO $dest\n" if $::verbose; } 1;