diff options
author | Martin Whitaker <mageia@martin-whitaker.me.uk> | 2017-12-18 10:54:01 +0000 |
---|---|---|
committer | Martin Whitaker <mageia@martin-whitaker.me.uk> | 2017-12-18 10:54:01 +0000 |
commit | 296dc5bb53c430c8842ab7327d8a76b5750c64b4 (patch) | |
tree | 5670e983d5d459466dac2b7a49b7ce14827c7e9d /lib/MGA/DrakISO/Loopback.pm | |
parent | 7e53518a7d8709998482eef1e9da21ee1a1886a9 (diff) | |
download | drakiso-296dc5bb53c430c8842ab7327d8a76b5750c64b4.tar drakiso-296dc5bb53c430c8842ab7327d8a76b5750c64b4.tar.gz drakiso-296dc5bb53c430c8842ab7327d8a76b5750c64b4.tar.bz2 drakiso-296dc5bb53c430c8842ab7327d8a76b5750c64b4.tar.xz drakiso-296dc5bb53c430c8842ab7327d8a76b5750c64b4.zip |
Start creating a new set of tools for generating Mageia ISO images.
The aim is to share as much code as possible between the tool used
to generate the Live ISOs and the tool used to generate the classic
installer ISOs.
This is derived from the user/martinw/use-grub2 branch of draklive.
Diffstat (limited to 'lib/MGA/DrakISO/Loopback.pm')
-rw-r--r-- | lib/MGA/DrakISO/Loopback.pm | 151 |
1 files changed, 151 insertions, 0 deletions
diff --git a/lib/MGA/DrakISO/Loopback.pm b/lib/MGA/DrakISO/Loopback.pm new file mode 100644 index 0000000..c48f2b6 --- /dev/null +++ b/lib/MGA/DrakISO/Loopback.pm @@ -0,0 +1,151 @@ +package MGA::DrakISO::Loopback; + +use MDK::Common; +use File::Temp; +use MGA::DrakISO::Progress; +use MGA::DrakISO::Utils; + +use Exporter; +our @ISA = qw(Exporter); +our @EXPORT = qw(%loop_types); + +my $loop_number = 0; +our %loop_types; +%loop_types = ( + squashfs => { + read_only => 1, + is_loopback => 1, + modules => sub { "loop", best_squashfs4_compression($_[0]) ? "squashfs" : "squashfs_lzma" }, + extension => '-lzma.sqfs', + build => sub { + my ($live, $dir) = @_; + my $dest = $live->get_builddir . $live->{prefix}{build}{loopbacks} . $dir->{path} . $loop_types{squashfs}{extension}; + mkdir_p(dirname($dest)); + my $root = $dir->{root} || $live->get_system_root; + my $src = $root . $dir->{build_from}; + my $total = directory_usage($src); + print "have to process " . int($total/1000000) . " MB\n"; + my $progress = MGA::DrakISO::Progress->new($total, time(), 6); + my $exclude_file = tmpnam(); + output_p($exclude_file, map { $root . "$_\n" } grep { -e $root . $_ } @{$dir->{exclude} || []}); + my $sort = $live->{settings}{config_root} . '/' . $dir->{sort}; + my $squashfs4_comp = best_squashfs4_compression($live); + run_foreach(sub { + if (/^mksquashfs: file .*, uncompressed size (\d+) bytes\s*(?:DUPLICATE|LINK)?$/) { + $progress->{current} += $1; + $progress->show(time()); + } + }, + $squashfs4_comp ? 'mksquashfs' : 'mksquashfs3', $src, $dest, + $squashfs4_comp ? ('-comp', $squashfs4_comp) : '-lzma', + '-noappend', '-no-progress', '-info', '-b', '1048576', + #'-processors', 1, + '-ef', $exclude_file, + if_(-f $sort, '-sort', $sort), + ) or die "unable to run mksquashfs\n"; + $progress->end; + unlink $exclude_file; + }, + mount => sub { + my ($live, $dir) = @_; + $dir->{loop} = "/dev/loop" . $loop_number++; + my $media_loopbacks = $live->get_media_prefix('loopbacks'); + ( + "/bin/losetup $dir->{loop} $live->{prefix}{live}{mnt}$live->{prefix}{media}{mnt}${media_loopbacks}$dir->{path}$loop_types{squashfs}{extension}", + "nash-mount -o ro -t squashfs $dir->{loop} $live->{prefix}{live}{mnt}$dir->{mountpoint}", + ); + }, + }, + modules => { + read_only => 1, + delay_mount => 1, + mount => sub { + my ($live, $dir) = @_; + my $media_loopbacks = $live->get_media_prefix('loopbacks'); + "sh -c 'modules=; for m in $live->{prefix}{live}{mnt}$live->{prefix}{media}{mnt}${media_loopbacks}$dir->{path}/*; do n=\$(basename \$m); n=\${n%.sqfs}; d=$live->{prefix}{live}{mnt}$dir->{mountpoint}/\$n; mkdir -p \$d; mount -n -o loop,ro -t squashfs \$m \$d && modules=\$modules\$d=ro:; done; echo \$modules | sed -e s/:\$// > $live->{prefix}{live}{mnt}/$dir->{list}'"; + }, + pivot_clean => sub { + my ($live, $dir, $initrdroot) = @_; + ( + "sh -c 'cd $initrdroot$live->{prefix}{live}{mnt}$dir->{mountpoint}; for i in `ls -1`; do mkdir -p $live->{prefix}{live}{mnt}$dir->{mountpoint}/\$i; mount -n --move \$i $live->{prefix}{live}{mnt}$dir->{mountpoint}/\$i; rmdir \$i; done; rmdir $initrdroot$live->{prefix}{live}{mnt}$dir->{mountpoint}'", + "sh -c 'mv $initrdroot$live->{prefix}{live}{mnt}/$dir->{list} $live->{prefix}{live}{mnt}/'", + ); + }, + }, + loopfs => { + is_loopback => 1, + modules => [], + extension => '.loop', + build => sub { + my ($live, $dir) = @_; + my $dest = $live->get_builddir . $live->{prefix}{build}{loopbacks} . $dir->{path} . $loop_types{loopfs}{extension}; + mkdir_p(dirname($dest)); + MGA::DrakISO::Utils::device_allocate_file($dest, $dir->{pre_allocate}); + MGA::DrakISO::Utils::device_mkfs($dest, $dir->{fs}) if !defined $dir->{min_size}; + }, + mount => sub { + my ($live, $dir) = @_; + $dir->{loop} = "/dev/loop" . $loop_number++; + my $fsck = "chroot </dev/tty1 $live->{prefix}{live}{mnt}$dir_distrib_sqfs->{mountpoint} /sbin/fsck $dir->{loop}"; + my $media_loopbacks = $live->get_media_prefix('loopbacks'); + ( + "losetup $dir->{loop} $live->{prefix}{live}{mnt}$live->{prefix}{media}{mnt}${media_loopbacks}$dir->{path}$loop_types{loopfs}{extension}", + qq(sh -c "$fsck -a || $fsck -y"), + "nash-mount -t $dir->{fs} $dir->{loop} $live->{prefix}{live}{mnt}$dir->{mountpoint}", + ); + }, + }, + plain => { + skip_mkdir => 1, + mount => sub { + my ($live, $dir) = @_; + qq(sh -c "mkdir -p $live->{prefix}{live}{mnt}$dir->{mountpoint}"); + }, + }, + partition => { + files => [ '/sbin/fsck', '/sbin/blkid' ], + mount => sub { + my ($live, $dir) = @_; + my $fsck = "/bin/fsck"; + ( + qq(sh -c 'dev=`blkid -l -t $dir->{path} -o device`; [ -z "\$dev" ] || $fsck -a \$dev || $fsck -y \$dev'), + "nash-mount -t $dir->{fs} $dir->{path} $live->{prefix}{live}{mnt}$dir->{mountpoint}", + ); + }, + }, + tmpfs => { + mount => sub { + my ($live, $dir) = @_; + my $mnt = $live->{prefix}{live}{mnt} . $dir->{mountpoint}; + my $mount_opts = $dir->{mount_opts} ? "-o $dir->{mount_opts}" : ""; + my $cmd = "mount -t tmpfs $mount_opts $mnt $mnt"; + $dir->{fallback} ? qq(sh -c 'if ! grep -q " $mnt " /proc/mounts; then $cmd; fi') : $cmd; + }, + }, +); + +sub get_loop_modules { + my ($live, $type) = @_; + my $modules = $loop_types{$_}{modules}; + my $type = ref $modules; + return $type eq 'CODE' ? $modules->($live) : + $type eq 'ARRAY' ? @$modules : + (); +} + +sub has_squashfs4_with { + my ($live, $comp) = @_; + my $ucomp = uc($comp); + cat_($live->get_system_root . "/boot/config-" . $live->find_kernel->{version}) =~ /^CONFIG_SQUASHFS_$ucomp=y$/m; +} + +sub mksquashfs4_compressors() { + map { /^Compressors available/ .. /^$/ ? if_(/^\t(\w+)/, chomp_($1)) : () } `mksquashfs 2>&1`; +} + +sub best_squashfs4_compression { + my ($live) = @_; + find { has_squashfs4_with($live, $_) } intersection([ mksquashfs4_compressors() ], [ qw(xz lzma) ]); +} + +1; |