summaryrefslogtreecommitdiffstats
path: root/perl-install/do_pkgs.pm
diff options
context:
space:
mode:
Diffstat (limited to 'perl-install/do_pkgs.pm')
-rw-r--r--perl-install/do_pkgs.pm295
1 files changed, 236 insertions, 59 deletions
diff --git a/perl-install/do_pkgs.pm b/perl-install/do_pkgs.pm
index dd39c749e..ba9283000 100644
--- a/perl-install/do_pkgs.pm
+++ b/perl-install/do_pkgs.pm
@@ -1,4 +1,22 @@
-package do_pkgs; # $Id$
+package do_pkgs;
+
+=head1 SYNOPSYS
+
+B<do_pkgs> enables to install packages (through urpmi) from our tools.
+It works both during installer and in standalone tools by using dedicate sub packages (B<do_pkgs_standalone> and B<do_pkgs_during_install>), both relying onrelying on do_pkgs_common.
+
+
+=head1 Functions
+
+=over
+
+=cut
+
+=item do_pkgs($in)
+
+Returns a new B<do_pkgs> object from a L<interactive> object.
+
+=cut
sub do_pkgs {
my ($in) = @_;
@@ -9,60 +27,199 @@ sub do_pkgs {
package do_pkgs_common;
use common;
+=item ensure_is_installed($do, $pkg, $o_file, $b_auto)
+
+Makes sure that the $pkg package is installed.
+If $o_file is provided, the already installed check is I<way> faster.
+If $b_auto is set, (g)urpmi will not ask any questions.
+
+=cut
+
sub ensure_is_installed {
my ($do, $pkg, $o_file, $b_auto) = @_;
- if (! $o_file || ! -e "$::prefix$o_file") {
- $do->in->ask_okcancel('', N("The package %s needs to be installed. Do you want to install it?", $pkg), 1)
- or return if !$b_auto;
- $do->install($pkg) or return;
+ if ($do->is_installed($pkg, $o_file)) {
+ return 1;
}
+
+ $do->in->ask_okcancel(N("Warning"), N("The package %s needs to be installed. Do you want to install it?", $pkg), 1)
+ or return if !$b_auto && $do->in;
+
+ if (!$do->install($pkg)) {
+ $do->in->ask_warn(N("Error"), N("Could not install the %s package!", $pkg)) if $do->in;
+ return;
+ }
+
if ($o_file && ! -e "$::prefix$o_file") {
- $do->in->ask_warn('', N("Mandatory package %s is missing", $pkg));
+ $do->in->ask_warn(N("Error"), N("Mandatory package %s is missing", $pkg)) if $do->in;
return;
}
1;
}
+=item ensure_are_installed($do, $pkgs, $b_auto)
+
+Makes sure that the packages listed in $pkgs array ref are installed.
+If $b_auto is set, (g)urpmi will not ask any questions.
+
+It's quite costly, so it's better to use the B<ensure_files_are_installed> instead.
+
+=cut
+
+sub ensure_are_installed {
+ my ($do, $pkgs, $b_auto) = @_;
+
+ my @not_installed = difference2($pkgs, [ $do->are_installed(@$pkgs) ]) or return 1;
+
+ $do->in->ask_okcancel(N("Warning"), N("The following packages need to be installed:\n") . join(', ', @not_installed), 1)
+ or return if !$b_auto && $do->in;
+
+ if (!$do->install(@not_installed)) {
+ if ($do->in) {
+ $do->in->ask_warn(N("Error"), N("Could not install the %s package!", $not_installed[0]));
+ } else {
+ log::l("Could not install packages: " . join(' ', @not_installed));
+ }
+ return;
+ }
+ 1;
+}
+
+=item ensure_binary_is_installed($do, $pkg, $binary, $b_auto)
+
+Makes sure that the $pkg package is installed.
+$binary is looked for in $PATH. If not found, the package is installed.
+If $b_auto is set, (g)urpmi will not ask any questions.
+
+=cut
+
sub ensure_binary_is_installed {
my ($do, $pkg, $binary, $b_auto) = @_;
if (!whereis_binary($binary, $::prefix)) {
- $do->in->ask_okcancel('', N("The package %s needs to be installed. Do you want to install it?", $pkg), 1)
- or return if !$b_auto;
- $do->install($pkg) or return;
+ $do->in->ask_okcancel(N("Warning"), N("The package %s needs to be installed. Do you want to install it?", $pkg), 1)
+ or return if !$b_auto && $do->in;
+ if (!$do->install($pkg)) {
+ $do->in->ask_warn(N("Error"), N("Could not install the %s package!", $pkg)) if $do->in;
+ return;
+ }
}
if (!whereis_binary($binary, $::prefix)) {
- $do->in->ask_warn('', N("Mandatory package %s is missing", $pkg));
+ $do->in->ask_warn(N("Error"), N("Mandatory package %s is missing", $pkg)) if $do->in;
return;
}
1;
}
+sub _find_file {
+ my ($file) = @_;
+ if ($file =~ m!/!) {
+ -e "$::prefix$file";
+ } else {
+ # assume it's a binary to search in $PATH:
+ whereis_binary($file, $::prefix);
+ }
+}
+
+=item ensure_files_are_installed($do, $pkgs, $b_auto)
+
+Takes a list of [ "package", "file" ] and installs package if file is not there.
+If $b_auto is set, (g)urpmi will not ask any questions.
+
+=cut
+
+sub ensure_files_are_installed {
+ my ($do, $pkgs, $b_auto) = @_;
+
+ my @not_installed = map { my ($package, $file) = @$_; if_(!_find_file($file), $package) } @$pkgs;
+ return 1 if !@not_installed;
+
+ $do->in->ask_okcancel(N("Warning"), N("The following packages need to be installed:\n") . join(', ', @not_installed), 1)
+ or return if !$b_auto && $do->in;
+
+ if (!$do->install(@not_installed)) {
+ if ($do->in) {
+ $do->in->ask_warn(N("Error"), N("Could not install the %s package!", $not_installed[0]));
+ } else {
+ log::l("Could not install packages: " . join(' ', @not_installed));
+ }
+ return;
+ }
+ 1;
+}
+
+=item ensure_is_installed_if_available($do, $pkg, $file) = @_;
+
+Install $pkg if $file is not present and if $pkg is actually known to urpmi.
+
+=cut
+
sub ensure_is_installed_if_available {
my ($do, $pkg, $file) = @_;
- if (! -e "$::prefix$file" && !$::testing) {
- $do->what_provides($pkg) and $do->install($pkg);
+ if (-e "$::prefix$file" || $::testing) {
+ 1;
+ } else {
+ $do->what_provides($pkg) && $do->install($pkg);
}
}
-
-sub is_installed {
+
+=item is_available($do, $name)
+
+=item are_available($do, @names)
+
+Returns name(s) of package(s) that are available (aka known to urpmi).
+This is somewhat costly (needs to parse urpmi synthesis...)
+
+=cut
+
+sub is_available {
my ($do, $name) = @_;
- $do->are_installed($name);
+ $do->are_available($name);
}
+=item is_installed($do, $name)
+
+=item are_installed($do, @names)
+
+Returns name(s) of package(s) that are already installed on the system.
+This is less costly (needs to query RPM DB)
+
+=cut
+
+sub is_installed {
+ my ($do, $name, $o_file) = @_;
+ $o_file ? -e "$::prefix$o_file" : $do->are_installed($name);
+}
+
+=item check_kernel_module_packages($do, $base_name)
+
+Takes something like C<ati-kernel> and returns:
+
+=over 4
+
+=item * the various C<ati-kernel-3.Y.XX-ZZmga> available for the installed kernels
+
+=item * C<dkms-ati> if available
+
+=back
+
+=cut
+
sub check_kernel_module_packages {
- my ($do, $base_name, $o_ext_name) = @_;
+ my ($do, $base_name) = @_;
require bootloader;
- my @l = map { $base_name . '-' . bootloader::vmlinuz2version($_) } bootloader::installed_vmlinuz();
- my @ext = if_($o_ext_name, $o_ext_name);
- my @rpms = $do->are_available(@ext, @l);
+ my @test_rpms = (
+ 'dkms-' . $base_name,
+ map { $base_name . '-kernel-' . bootloader::vmlinuz2version($_) } bootloader::installed_vmlinuz()
+ );
+ my @rpms = $do->are_available(@test_rpms);
+ @rpms = $do->are_installed(@test_rpms) if !@rpms;
+ @rpms or return;
- log::l("found kernel module packages $_") foreach @rpms;
+ log::l("those kernel module packages can be installed: " . join(' ', @rpms));
- #- we want at least a kernel package and the ext package if specified
- @rpms > @ext && \@rpms;
+ \@rpms;
}
################################################################################
@@ -72,9 +229,18 @@ use common;
our @ISA = qw(do_pkgs_common);
+=item new($type, $in)
+
+Returns a C<do_pkg> object.
+
+=cut
+
sub new {
my ($type, $in) = @_;
- require pkgs;
+
+ $in->isa('interactive') or undef $in;
+
+ require install::pkgs;
bless { in => $in, o => $::o }, $type;
}
@@ -86,28 +252,29 @@ sub in {
sub install {
my ($do, @l) = @_;
log::l("do_pkgs_during_install::install");
- if ($::testing || $::globetrotter) {
+ if ($::testing) {
log::l("i would install packages " . join(' ', @l));
- return 1;
+ 1;
} else {
$do->{o}->pkg_install(@l);
+ 1; #- HACK, need better fix in install::steps::pkg_install()
}
}
sub what_provides {
my ($do, $name) = @_;
- map { $_->name } pkgs::packagesProviding($do->{o}{packages}, $name);
+ map { $_->name } install::pkgs::packagesProviding($do->{o}{packages}, $name);
}
sub are_available {
my ($do, @pkgs) = @_;
- grep { pkgs::packageByName($do->{o}{packages}, $_) } @pkgs;
+ grep { install::pkgs::packageByName($do->{o}{packages}, $_) } @pkgs;
}
sub are_installed {
my ($do, @l) = @_;
grep {
- my $p = pkgs::packageByName($do->{o}{packages}, $_);
+ my $p = install::pkgs::packageByName($do->{o}{packages}, $_);
$p && $p->flag_available;
} @l;
}
@@ -116,8 +283,8 @@ sub remove {
my ($do, @l) = @_;
@l = grep {
- my $p = pkgs::packageByName($do->{o}{packages}, $_);
- pkgs::unselectPackage($do->{o}{packages}, $p) if $p;
+ my $p = install::pkgs::packageByName($do->{o}{packages}, $_);
+ install::pkgs::unselectPackage($do->{o}{packages}, $p) if $p;
$p;
} @l;
run_program::rooted($::prefix, 'rpm', '-e', @l);
@@ -127,7 +294,7 @@ sub remove_nodeps {
my ($do, @l) = @_;
@l = grep {
- my $p = pkgs::packageByName($do->{o}{packages}, $_);
+ my $p = install::pkgs::packageByName($do->{o}{packages}, $_);
if ($p) {
$p->set_flag_requested(0);
$p->set_flag_required(0);
@@ -142,6 +309,7 @@ package do_pkgs_standalone;
use run_program;
use common;
use log;
+use feature qw(state);
our @ISA = qw(do_pkgs_common);
@@ -152,10 +320,6 @@ sub new {
sub in {
my ($do) = @_;
- $do->{in} ||= do {
- require interactive;
- interactive->vnew;
- };
$do->{in};
}
@@ -169,11 +333,18 @@ sub install {
return 1;
}
- my $_wait = $do->in->wait_message('', N("Installing packages..."));
- $do->in->suspend;
- log::explanations("installed packages @l");
- my $ret = system('urpmi', '--allow-medium-change', '--auto', '--best-output', '--no-verify-rpm', @l) == 0;
- $do->in->resume;
+ my @wrapper = $::isLiveInstall && $::prefix ? ('chroot', $::prefix) : ();
+ my @options = ('--allow-medium-change', '--auto', '--no-verify-rpm', '--expect-install', @l);
+ my $ret;
+ if (check_for_xserver() && -x '/usr/bin/gurpmi') {
+ $ret = system(@wrapper, 'gurpmi', @options) == 0;
+ } else {
+ my $_wait = $do->in && $do->in->wait_message(N("Please wait"), N("Installing packages..."));
+ $do->in->suspend if $do->in;
+ log::explanations("installing packages @l");
+ $ret = system(@wrapper, 'urpmi', @options) == 0;
+ $do->in->resume if $do->in;
+ }
$ret;
}
@@ -181,17 +352,19 @@ sub are_available {
my ($_do, @pkgs) = @_;
my %pkgs = map { $_ => 1 } @pkgs;
+ require urpm::media;
+ state $urpm;
eval {
- local *_;
- require urpm;
- my $urpm = urpm->new;
- $urpm->read_config(nocheck_access => 1);
- foreach (grep { !$_->{ignore} } @{$urpm->{media} || []}) {
- $urpm->parse_synthesis("$urpm->{statedir}/synthesis.$_->{hdlist}");
+ if (!$urpm) {
+ $urpm = urpm->new;
+ $urpm->{log} = \&log::l;
+ urpm::media::configure($urpm,
+ nocheck_access => 1,
+ no_skiplist => 1,
+ no_second_pass => 1);
}
map { $_->name } grep { $pkgs{$_->name} } @{$urpm->{depslist} || []};
};
-
}
sub what_provides {
@@ -199,25 +372,25 @@ sub what_provides {
split('\|', chomp_(run_program::get_stdout('urpmq', $name)));
}
-sub is_installed {
- my ($do, $name) = @_;
- are_installed($do, $name);
-}
-
sub are_installed {
my ($_do, @l) = @_;
+ @l or return;
+
my @l2;
- run_program::run('/bin/rpm', '>', \@l2, '-q', '--qf', "%{name}\n", @l); #- do not care about the return value
- intersection(\@l, [ chomp_(@l2) ]); #- can not return directly @l2 since it contains things like "package xxx is not installed"
+ my $query_all = (any { /\*/ } @l) ? 'a' : '';
+ my $rooted = $::isLiveInstall && $::prefix ? { root => $::prefix } : {};
+ run_program::raw($rooted, '/bin/rpm', '>', \@l2, '-q' . $query_all, '--qf', "%{name}\n", @l); #- do not care about the return value
+ $query_all ? chomp_(@l2) : intersection(\@l, [ chomp_(@l2) ]); #- cannot return directly @l2 since it contains things like "package xxx is not installed"
}
sub remove {
my ($do, @l) = @_;
- my $_wait = $do->in->wait_message('', N("Removing packages..."));
- $do->in->suspend;
- log::explanations("removed packages @l");
- my $ret = system('rpm', '-e', @l) == 0;
- $do->in->resume;
+ my $_wait = $do->in && $do->in->wait_message(N("Please wait"), N("Removing packages..."));
+ $do->in->suspend if $do->in;
+ log::explanations("removing packages @l");
+ my @wrapper = $::isLiveInstall && $::prefix ? ('chroot', $::prefix) : ();
+ my $ret = system(@wrapper, 'rpm', '-e', @l) == 0;
+ $do->in->resume if $do->in;
$ret;
}
@@ -225,3 +398,7 @@ sub remove_nodeps {
my ($do, @l) = @_;
remove($do, '--nodeps', @l) == 0;
}
+
+=back
+
+=cut