diff options
Diffstat (limited to 'lib/MGA/DrakISO/BuildLoop.pm')
-rwxr-xr-x | lib/MGA/DrakISO/BuildLoop.pm | 116 |
1 files changed, 116 insertions, 0 deletions
diff --git a/lib/MGA/DrakISO/BuildLoop.pm b/lib/MGA/DrakISO/BuildLoop.pm new file mode 100755 index 0000000..5e840d4 --- /dev/null +++ b/lib/MGA/DrakISO/BuildLoop.pm @@ -0,0 +1,116 @@ +# 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::BuildLoop; + +use strict; + +use MDK::Common; +use common; + +use File::Temp qw(tmpnam); + +use MGA::DrakISO::Live; +use MGA::DrakISO::Loopback; +use MGA::DrakISO::Utils; + +use Exporter; +our @ISA = qw(Exporter); +our @EXPORT = qw(build_live_loopback_files list_loopback_modules); + +sub build_live_loopback_files { + my ($live) = @_; + # make sure no external filesystems are mounted before creating the loopback + umount_external_fs($live); + + my @excluded_files = expand_file_list($live, @{$live->{loopbacks}{exclude}{files} || []}); + my @modules_files = expand_file_list($live, @{$live->{loopbacks}{modules} || []}); + + foreach (grep { exists $loop_types{$_->{type}}{build} } @{$live->{mount}{dirs} || []}) { + local $_->{exclude} = [ @excluded_files, @modules_files ]; + $loop_types{$_->{type}}{build}->($live, $_); + } + + foreach my $module (list_loopback_modules($live)) { + my $copy_tree = $live->get_system_root . "/tmp/draklive/loop/$module->{name}"; + eval { rm_rf($copy_tree) }; + hardlink_filtered($live->get_system_root, $copy_tree, $module->{files}); + my $loop = $loop_types{$module->{type}}; + $loop->{build}->($live, { path => "$live->{prefix}{build}{modules}/$module->{name}", root => $copy_tree, exclude => \@excluded_files }); + eval { rm_rf($copy_tree) }; + } + + if (@excluded_files) { + my $excluded_tree = $live->get_system_root . "/tmp/draklive/excluded/all"; + eval { rm_rf($excluded_tree) }; + hardlink_filtered($live->get_system_root, $excluded_tree, \@excluded_files); + + foreach my $module (list_loopback_modules($live)) { + my $copy_tree = $live->get_system_root . "/tmp/draklive/excluded/$module->{name}"; + eval { rm_rf($copy_tree) }; + hardlink_filtered($excluded_tree, $copy_tree, $module->{files}); + my $loop = $loop_types{$module->{type}}; + $loop->{build}->($live, { path => "$live->{prefix}{build}{modules}/excluded-$module->{name}", root => $copy_tree }); + eval { rm_rf($copy_tree) }; + } + + my $loop = $loop_types{$live->{loopbacks}{exclude}{type}}; + $loop->{build}->($live, { path => "/excluded", root => $excluded_tree, exclude => \@modules_files }); + + eval { rm_rf($excluded_tree) }; + } +} + +sub expand_file_list { + my ($live, @files) = @_; + map { + $_->{path} ? + $_->{path} : + chomp_(cat_(glob(($_->{rooted} && $live->get_system_root) . $_->{source}))); + } @files; +} + +#- hardlink recursively file list to a directory +sub hardlink_filtered { + my ($src, $dest, $files) = @_; + mkdir_p($dest); + my $pwd = $ENV{PWD}; + chdir($src); + my $list_file = tmpnam(); + output_p($list_file, map { "$_\n" } grep { -e $src . $_ } @$files); + #- cpio -pldm won't copy recursively, use rsync -r instead + system('rsync', '-ar', '--files-from=' . $list_file, '--link-dest=' . $src, $src, $dest); + unlink $list_file; + chdir($pwd); +} + +sub list_loopback_modules { + my ($live) = @_; + map { + my $l = $_; + map { + my $list = $_; + my $name = basename($list); + $name =~ s/\.[^.]+$//; + { type => $l->{type}, name => $name, files => [ expand_file_list($live, { source => $list }) ] }; + } glob(($_->{rooted} && $live->get_system_root) . $_->{source}); + } @{$live->{loopbacks}{modules}}; +} + +1; |