1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
|
# 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA.
# SYNOPSIS
# --------
# This package provides a function to build the compressed images that will
# be mounted as loopback filesystems when booting a Live system.
package MGA::DrakISO::BuildLoop;
use strict;
use MDK::Common;
use common;
use File::Temp qw(tmpnam);
use MGA::DrakISO::LiveBuild;
use MGA::DrakISO::Loopback;
use MGA::DrakISO::Utils;
use Exporter;
our @ISA = qw(Exporter);
our @EXPORT = qw(build_live_loopback_files list_loopback_modules);
# This is the top-level function called to build the loopback images. The Live
# root filesystem must have been prepared before calling this function.
#
sub build_live_loopback_files {
my ($build) = @_;
my $root = $build->get_live_root;
# make sure no external filesystems are mounted before creating the loopback
umount_all_in_root($root);
my @excluded_files = expand_file_list($build, @{$build->{loopbacks}{exclude}{files} || []});
my @modules_files = expand_file_list($build, @{$build->{loopbacks}{modules} || []});
foreach (grep { exists $loop_types{$_->{type}}{build} } @{$build->{mount}{dirs} || []}) {
local $_->{exclude} = [ @excluded_files, @modules_files ];
$loop_types{$_->{type}}{build}->($build, $_);
}
foreach my $module (list_loopback_modules($build)) {
my $copy_tree = $root . "/tmp/draklive/loop/$module->{name}";
run_as_root('rm', '-rf', $copy_tree);
hardlink_filtered($root, $copy_tree, $module->{files});
my $loop = $loop_types{$module->{type}};
$loop->{build}->($build, { path => "/modules/$module->{name}", root => $copy_tree, exclude => \@excluded_files });
run_as_root('rm', '-rf', $copy_tree);
}
if (@excluded_files) {
my $excluded_tree = $root . "/tmp/draklive/excluded/all";
eval { rm_rf($excluded_tree) };
hardlink_filtered($root, $excluded_tree, \@excluded_files);
foreach my $module (list_loopback_modules($build)) {
my $copy_tree = $root . "/tmp/draklive/excluded/$module->{name}";
run_as_root('rm', '-rf', $copy_tree);
hardlink_filtered($excluded_tree, $copy_tree, $module->{files});
my $loop = $loop_types{$module->{type}};
$loop->{build}->($build, { path => "/modules/excluded-$module->{name}", root => $copy_tree });
run_as_root('rm', '-rf', $copy_tree);
}
my $loop = $loop_types{$build->{loopbacks}{exclude}{type}};
$loop->{build}->($build, { path => "/excluded", root => $excluded_tree, exclude => \@modules_files });
run_as_root('rm', '-rf', $excluded_tree);
}
}
sub expand_file_list {
my ($build, @files) = @_;
map {
$_->{path} ?
$_->{path} :
chomp_(cat_(glob(($_->{rooted} && $build->get_live_root) . $_->{source})));
} @files;
}
#- hardlink recursively file list to a directory
sub hardlink_filtered {
my ($src, $dest, $files) = @_;
mkdir_p($dest);
my $list_file = tmpnam();
output_p($list_file, map { "$_\n" } grep { -e $src . $_ } @$files);
#- cpio -pldm won't copy recursively, use rsync -r instead
run_as_root('rsync', '-ar', '--files-from=' . $list_file, '--link-dest=' . $src, $src, $dest);
unlink $list_file;
}
sub list_loopback_modules {
my ($build) = @_;
map {
my $l = $_;
map {
my $list = $_;
my $name = basename($list);
$name =~ s/\.[^.]+$//;
{ type => $l->{type}, name => $name, files => [ expand_file_list($build, { source => $list }) ] };
} glob(($_->{rooted} && $build->get_live_root) . $_->{source});
} @{$build->{loopbacks}{modules}};
}
1;
|