diff options
Diffstat (limited to 'lib/MGA/DrakISO/BuildISO.pm')
-rwxr-xr-x | lib/MGA/DrakISO/BuildISO.pm | 163 |
1 files changed, 163 insertions, 0 deletions
diff --git a/lib/MGA/DrakISO/BuildISO.pm b/lib/MGA/DrakISO/BuildISO.pm new file mode 100755 index 0000000..9b7e503 --- /dev/null +++ b/lib/MGA/DrakISO/BuildISO.pm @@ -0,0 +1,163 @@ +# Copyright (C) 2005 Mandriva +# Olivier Blin <oblin@mandriva.com> +# Copyright (C) 2017 Mageia +# Martin Whitaker <mageia@martin-whitaker.me.uk> +# +# 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::Live; +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 ($live) = @_; + + my $label = $live->{media}->get_media_label or die "the source device must be described by a label\n"; + + my $mbr_image = $live->get_absolute_path($live->{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 = $live->get_builddir . $live->{prefix}{build}{images} . '/esp.img'; + -e $esp_image or die "cannot find ESP image $esp_image\n"; + + my $dest = $live->get_builddir . $live->{prefix}{build}{dist} . '/' . $live->get_name . '.iso'; + mkdir_p(dirname($dest)); + + build_iso_image( + $live, + $dest, + $label, + $mbr_image, + $esp_image, + $live->get_media_prefix('boot') . '=' . $live->get_builddir . $live->{prefix}{build}{boot}, + if_($live->{settings}{arch} eq 'x86_64', + $live->get_media_prefix('EFI') . '=' . $live->get_builddir . $live->{prefix}{build}{EFI}, + ), + ( + map { + $live->get_media_prefix('loopbacks') . $_ . + '=' . + $live->get_builddir . $live->{prefix}{build}{loopbacks} . $_; + } list_selected_loopbacks($live) + ), + if_($live->{media}{files}, + map { + $_ . '=' . $live->get_builddir . $live->{prefix}{build}{files} . '/' . $_; + } all($live->get_builddir . $live->{prefix}{build}{files}) + ), + ); +} + +sub list_selected_loopbacks { + my ($live) = @_; + my @pack = $live->{settings}{pack} ? @{$live->{packs}{$live->{settings}{pack}} || []} : (); + my @pack_modules = grep { member($_->{name}, @pack) } list_loopback_modules($live); + (map { $loop_types{$_->{type}}{is_loopback} && $_->{path} ? $_->{path} . $loop_types{$_->{type}}{extension} : () } @{$live->{mount}{dirs} || []}), + (map { $live->{prefix}{build}{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 ($live, $dest, $label, $mbr_image, $esp_image, @opts) = @_; + + my $boot = $live->get_media_prefix('boot'); # normally '/boot' + my $EFI = $live->get_media_prefix('EFI'); # normally '/EFI' + + 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_($live->{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 = $live->get_set_suffix) { + if (my ($prefix, $ext) = $dest =~ /(.*)(\.[^.]+)$/) { + my $link = $prefix . $suffix . $ext; + linkf($dest, $link); + print "linked as $link\n"; + } + } + } +} + +1; |