summaryrefslogtreecommitdiffstats
path: root/lib/MGA/DrakISO/BuildLoop.pm
blob: d47b6e9cf81d09aea678801c24caa707463ea247 (plain)
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
# Copyright (C) 2005 Mandriva
#                    Olivier Blin <oblin@mandriva.com>
# Copyright (C) 2017-2020 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 image that will
# be mounted as a loopback filesystem when booting a Live system.

package MGA::DrakISO::BuildLoop;

use strict;

use MDK::Common;

use File::Temp qw(tmpnam);

use MGA::DrakISO::LiveBuild;
use MGA::DrakISO::Utils;

use Exporter;
our @ISA = qw(Exporter);
our @EXPORT = qw(build_live_loopback_file);

# This is the top-level function called to build the loopback image. The Live
# root filesystem must have been prepared before calling this function.
#
sub build_live_loopback_file {
    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 $total = directory_usage($root);
    print "Have to process " . int($total/1000000) . " MB\n" if $::verbose;

    my $dest = $build->get_build_dir('loopbacks') . '/distrib.sqfs';
    mkdir_p(dirname($dest));

    my $exclude_list = tmpnam();
    my @excluded_files = expand_file_list($build, @{$build->{loopbacks}{exclude} || []});
    output_p($exclude_list, map { $root . "$_\n" }  grep { run_as_root('test', '-e', $root . $_) } @excluded_files);

    my ($compress_type, $compress_level) = split(':', $build->{loopbacks}{compression} || 'zstd:18');

    my $sort = $build->{settings}{config_root} . '/config/distrib.sort';
    run_as_root(join(' ',
         'mksquashfs',
         $root, $dest,
         '-noappend',
         '-comp', $compress_type,
         if_($compress_type eq 'zstd' && $compress_level,
            '-Xcompression-level', $compress_level
         ),
         '-b', '1048576',
         '-ef', $exclude_list,
         if_(-f $sort, '-sort', $sort),
         if_($::verbose > 2, '-info', '-progress'),
         if_($::verbose < 2, '-no-progress'),
         # due to lack of a -quiet option
         if_($::verbose < 2, '> /dev/null'),
    )) or die "ERROR: unable to run mksquashfs\n";

    unlink $exclude_list;
}

sub expand_file_list {
    my ($build, @files) = @_;
    map {
        $_->{path} ?
          $_->{path} :
          chomp_(cat_(glob(($_->{rooted} && $build->get_live_root) . $_->{source})));
    } @files;
}

1;