# Copyright (C) 2005 Mandriva # Olivier Blin # Copyright (C) 2017-2018 Mageia # Martin Whitaker # # 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 miscellaneous helper functions. package MGA::DrakISO::Utils; use strict; use MDK::Common; use Exporter; our @ISA = qw(Exporter); our @EXPORT = qw($sudo directory_usage glob__ run_ run_as_root run_in_root copy_or_link mk_dev_null rm_dev_null mount mount_system_fs umount_all_in_root); our $sudo = $> ? 'sudo' : ''; sub directory_usage { my ($dir, $o_apparent) = @_; my $apparent = $o_apparent && "--apparent-size"; first(split /\s/, `$sudo du -s -B 1 $apparent $dir`); } #- expand only if the pattern contains '*' #- and matches dot characters (like shell dotglob) sub glob__ { my ($pattern) = @_; $pattern =~ /\*/ ? glob_($pattern) : $pattern; } sub run_ { my @cmd = @_; print "@cmd\n" if $::verbose > 2; system(@cmd) == 0; } sub run_as_root { my @cmd = @_; if (@cmd > 1) { unshift @cmd, $sudo if $sudo; } else { $cmd[0] = join(' ', $sudo, $cmd[0]); } run_(@cmd); } sub run_in_root { my ($root, $arch, @cmd) = @_; if (@cmd > 1) { unshift @cmd, ('chroot', $root); unshift @cmd, ('setarch', $arch) if $arch; unshift @cmd, $sudo if $sudo; } else { $cmd[0] = join(' ', $sudo, if_($arch, 'setarch', $arch), 'chroot', $root, $cmd[0]); } print "@cmd\n" if $::verbose > 2; local %ENV = %ENV; $ENV{LC_ALL} = 'C'; system(@cmd) == 0; } sub copy_or_link { my ($src_file, $dst_file) = @_; mkdir_p(dirname($dst_file)); if ($src_file =~ m!^(ftp|https?)://!) { run_as_root('curl', '--silent', '-o', $dst_file, $src_file) or die "ERROR: couldn't copy $src_file to $dst_file\n"; } else { symlinkf($src_file, $dst_file) or die "ERROR: couldn't link $src_file to $dst_file\n"; } } sub mk_dev_null { my ($root) = @_; $root or die; return if -e $root . '/dev/null'; run_as_root('mkdir', '-p', $root . '/dev'); run_as_root('cp', '-a', '/dev/null', $root . '/dev'); } sub rm_dev_null { my ($root) = @_; $root or die; run_as_root('rm', $root . '/dev/null') if -e $root . '/dev/null'; } sub mount { my ($dst, $src, @o_options) = @_; mkdir_p($dst); run_as_root('mount', @o_options, $src, $dst) or die "ERROR: failed to mount $src on $dst\n"; } sub mount_system_fs { my ($root) = @_; $root or die; mount($root . '/dev', '/dev', '--bind', '-o', 'ro'); mount($root . '/proc', 'none', '-t', 'proc'); mount($root . '/sys', 'none', '-t', 'sysfs'); mount($root . '/run', 'none', '-t', 'tmpfs'); } sub umount_all_in_root { my ($root) = @_; $root or die; $root = Cwd::abs_path($root); my @mounts = grep { $_ =~ $root } split("\n", cat_('/proc/mounts')); foreach (reverse(@mounts)) { my @field = split(' ' , $_); run_as_root('umount', $field[1]); } } 1;