diff options
Diffstat (limited to 'perl-install/install/media.pm')
-rw-r--r-- | perl-install/install/media.pm | 321 |
1 files changed, 114 insertions, 207 deletions
diff --git a/perl-install/install/media.pm b/perl-install/install/media.pm index 5b6441b4c..149deffc3 100644 --- a/perl-install/install/media.pm +++ b/perl-install/install/media.pm @@ -1,4 +1,4 @@ -package install::media; # $Id$ +package install::media; use strict; @@ -6,6 +6,9 @@ our @ISA = qw(Exporter); our @EXPORT_OK = qw(getFile_ getAndSaveFile_ getAndSaveFile_media_info packageMedium); use common; +use Data::Dumper; +# Make sure report.bug are more easily comparable: +$Data::Dumper::Sortkeys = 1; use fs::type; use urpm::download; use urpm::media; @@ -25,7 +28,7 @@ use urpm::media; #- url #- list of fields for {media} : -#- end (last rpm id, undefined iff not selected) +#- end (last rpm id, undefined if not selected) #- fakemedium ("$name ($rpmsdir)", used locally by urpmi) #- rel_hdlist #- key-ids @@ -33,20 +36,15 @@ use urpm::media; #- pubkey (array containing all the keys to import) #- phys_medium #- rpmsdir -#- selected +#- ignore #- size (in MB) -#- start (first rpm id, undefined iff not selected) +#- start (first rpm id, undefined if ignored) #- update (for install_urpmi) our $postinstall_rpms = ''; my %mounted_media; -sub _free_medium_id { - my ($media) = @_; - int(@$media); -} - sub allMediums { my ($packages) = @_; @@ -63,6 +61,7 @@ sub packageMedium { my ($packages, $p) = @_; URPM::pkg2media($packages->{media}, $p) || {}; } + sub packagesOfMedium { my ($packages, $medium) = @_; @@ -80,16 +79,6 @@ sub path { ($phys_m->{real_mntpoint} || fs::get::mntpoint_prefixed($phys_m)) . $phys_m->{rel_path} . '/' . $f; } -sub rel_rpm_file { - my ($medium, $f) = @_; - if (my ($arch) = $f =~ m|\.([^\.]*)\.rpm$|) { - $f = "$medium->{rpmsdir}/$f"; - $f =~ s/%{ARCH}/$arch/g; - $f =~ s,^/+,,g; - } - $f; -} - sub umount_phys_medium { my ($phys_m) = @_; @@ -104,6 +93,7 @@ sub umount_phys_medium { } $ok; } + sub _mount_phys_medium { my ($phys_m, $o_rel_file, $b_force_change) = @_; @@ -170,7 +160,7 @@ sub stage2_phys_medium { my $user = $ENV{LOGIN} && ($ENV{LOGIN} . ($ENV{PASSWORD} && ":$ENV{PASSWORD}") . '@'); $ENV{URLPREFIX} = "ftp://$user$ENV{HOST}/$ENV{PREFIX}"; } - if ($method eq 'http' || $method eq 'ftp') { + if (member($method, qw(http ftp))) { { method => $method, url => $ENV{URLPREFIX} }; } elsif ($method =~ /(.*)-iso$/) { my $dir_method = $1; @@ -249,7 +239,7 @@ sub _associate_phys_media { log::l("setting medium $medium->{name} phys_medium to $phys_m->{url}"); $medium->{phys_medium} = $phys_m; } else { - $medium->{selected} = 0; + $medium->{ignore} = 1; log::l("deselecting missing medium $medium->{rpmsdir}"); } } @@ -284,6 +274,7 @@ sub _iso_phys_media { mntpoint => $mntpoint, rel_path => $rel_path, }; } + sub _get_phys_media_iso { my ($all_hds, $main_phys_m, $names) = @_; @@ -296,6 +287,7 @@ sub _get_phys_media_iso { $m; } @ISOs; } + sub _look_for_ISO_images { my ($main_iso) = @_; @@ -332,6 +324,7 @@ sub _open_file_and_size { my $fh = common::open_file($f) or return; $size, $fh; } + sub getFile_ { my ($phys_m, $f) = @_; log::l("getFile $f on " . phys_medium_to_string($phys_m) . ""); @@ -339,16 +332,14 @@ sub getFile_ { my ($_size, $fh) = get_file_and_size($phys_m, $f) or return; $fh; } + sub get_file_and_size { my ($phys_m, $f) = @_; - if ($f =~ m|^http://|) { + if ($f =~ m|^https?://|) { require install::http; install::http::get_file_and_size($f); - } elsif ($phys_m->{method} eq "ftp") { - require install::ftp; - install::ftp::get_file_and_size($f, $phys_m->{url}); - } elsif ($phys_m->{method} eq "http") { + } elsif (member($phys_m->{method}, qw(ftp http https))) { require install::http; install::http::get_file_and_size_($f, $phys_m->{url}); } elsif ($f =~ m!^/!) { @@ -370,6 +361,7 @@ sub getAndSaveFile_ { my $fh = getFile_($phys_m, $file) or return; _getAndSaveFile_raw($fh, $local); } + sub _getAndSaveFile_progress { my ($in_wait, $msg, $phys_m, $file, $local) = @_; my ($size, $fh) = get_file_and_size($phys_m, $file) or return; @@ -379,6 +371,7 @@ sub _getAndSaveFile_progress { _getAndSaveFile_raw($fh, $local); } } + sub _getAndSaveFile_raw { my ($fh, $local) = @_; @@ -389,6 +382,7 @@ sub _getAndSaveFile_raw { while (<$fh>) { syswrite($F, $_) or unlink($local), die("getAndSaveFile($local): $!") } 1; } + sub _getAndSaveFile_progress_raw { my ($in_wait, $msg, $size, $fh, $local) = @_; @@ -396,6 +390,7 @@ sub _getAndSaveFile_progress_raw { open(my $out, ">$local") or log::l("getAndSaveFile(opening $local): $!"), return; _print_with_progress($in_wait, $msg, $size, $fh, $out) or unlink($local), die("getAndSaveFile($local): $!"); } + sub _print_with_progress { my ($in_wait, $msg, $size, $in, $out) = @_; @@ -420,19 +415,12 @@ sub _print_with_progress { 1; } - sub urpmidir() { my $v = "$::prefix/var/lib/urpmi"; -l $v && !-e $v and unlink $v and mkdir $v, 0755; #- dangling symlink -w $v ? $v : '/tmp'; } -sub hdlist_on_disk { - my ($m) = @_; - - urpmidir() . "/hdlist.$m->{fakemedium}.cz"; -} - sub _allow_copy_rpms_on_disk { my ($medium, $hdlists) = @_; @@ -478,45 +466,42 @@ sub _parse_media_cfg { } sub select_only_some_media { - my ($packages, $selected_names) = @_; + my ($media_list, $selected_names) = @_; my @names = split(',', $selected_names); - foreach my $m (@{$packages->{media}}) { + foreach my $m (@$media_list) { my $bool = !member($m->{name}, @names); # workaround urpmi transforming "ignore => ''" or "ignore => 0" into "ignore => 1": undef $bool if !$bool; - log::l "disabling '$m->{name}' medium: " . to_bool($bool); + log::l("disabling '$m->{name}' medium: " . to_bool($bool)); urpm::media::_tempignore($m, $bool); # make sure we update un-ignored media (eg: */Testing and the like): $m->{modified} = 1 if !$bool; } } +sub update_media { + my ($packages) = @_; + urpm::media::update_media($packages, distrib => 1, callback => \&urpm::download::sync_logger) or + log::l('updating media failed'); +} + sub get_media { my ($o, $media, $packages) = @_; - my ($suppl_CDs, $copy_rpms_on_disk); + my ($suppl_CDs, $copy_rpms_on_disk, $phys_m); foreach (@$media) { if ($_->{type} eq 'media_cfg') { - my $phys_m = url2mounted_phys_medium($o, $_->{url}, 'media_info'); - my $uri = $o->{stage2_phys_medium}{url} =~ m!^(http|ftp)://! && $o->{stage2_phys_medium}{url} || - $phys_m->{method} =~ m!^(ftp|http)://! && $phys_m->{method} - || $phys_m->{real_mntpoint} || $phys_m->{url}; - urpm::media::add_distrib_media($packages, undef, $uri, ask_media => undef); #allmedia => 1 - - if (defined $_->{selected_names}) { - select_only_some_media($packages, $_->{selected_names}); - } - - _get_compsUsers_pl($phys_m, $_->{force_rpmsrate}); - ($suppl_CDs, $copy_rpms_on_disk) = eval { _get_media_cfg_options($o, $phys_m) }; + $phys_m = url2mounted_phys_medium($o, $_->{url}, 'media_info'); + local $phys_m->{is_suppl} = $_->{url} ne "drakx://media"; # so that _get_media_url() works + ($suppl_CDs, $copy_rpms_on_disk) = get_media_cfg($o, $phys_m, $packages, $_->{selected_names}, $_->{force_rpmsrate}); } elsif ($_->{type} eq 'media') { - my $phys_m = url2mounted_phys_medium($o, $_->{url}); + $phys_m = url2mounted_phys_medium($o, $_->{url}); get_standalone_medium($o, $phys_m, $packages, { name => $_->{id} =~ /media=(.*)/ && $1 }); } elsif ($_->{type} eq 'media_cfg_isos') { my ($dir_url, $iso, $rel_path) = $_->{url} =~ m!(.*)/(.*\.iso):(/.*)! or die "bad media_cfg_isos url $_->{url}"; my $dir_medium = url2mounted_phys_medium($o, $dir_url); $dir_medium->{options} =~ s/\bnoauto\b,?//; - my $phys_m = _iso_phys_media($dir_medium, $iso, $rel_path); + $phys_m = _iso_phys_media($dir_medium, $iso, $rel_path); push @{$o->{all_hds}{loopbacks}}, $phys_m; ($suppl_CDs, $copy_rpms_on_disk) = get_media_cfg($o, $phys_m, $packages, $_->{selected_names}, $_->{force_rpmsrate}); } else { @@ -524,16 +509,32 @@ sub get_media { } } - urpm::media::update_media($packages, distrib => 1, callback => \&urpm::download::sync_logger) or - log::l('updating media failed'); - - urpm::media::configure($packages); - log::l('urpmi completely set up'); - log::l("suppl_CDs=$suppl_CDs copy_rpms_on_disk=$copy_rpms_on_disk"); $suppl_CDs, $copy_rpms_on_disk; } +sub adjust_paths_in_urpmi_cfg { + my ($urpm) = @_; + + require Clone; + local $urpm->{media} = Clone::clone($urpm->{media}); + foreach my $medium (@{$urpm->{media}}) { + my $phys_m = $medium->{phys_medium}; + if ($phys_m->{method} eq 'cdrom') { + $medium->{url} =~ s!^.*?/media/!$phys_m->{url}/!; + } elsif (member($phys_m->{method}, qw(disk nfs))) { + # use the real mount point: + if ($medium->{url} =~ m!/tmp/image(/media)?!) { + $medium->{url} =~ s!/tmp/image(/media)?!$phys_m->{mntpoint}$phys_m->{rel_path}!; + } else { + # just remove $::prefix and we already have the real mount point: + $medium->{url} =~ s!^$::prefix!!; + } + } + } + urpm::media::write_config($urpm); +} + sub remove_from_fstab { my ($all_hds, $phys_m) = @_; @@ -616,52 +617,55 @@ sub _url2phys_medium { } } -# shrinked down get_media_cfg() in order to keep optins that urpmi discards: -sub _get_media_cfg_options { +sub _get_media_url { my ($o, $phys_medium) = @_; - - my ($distribconf); - if (getAndSaveFile_($phys_medium, 'media_info/media.cfg', '/tmp/media.cfg')) { - ($distribconf) = _parse_media_cfg('/tmp/media.cfg', $phys_medium); + my $uri; + if ($phys_medium->{is_suppl}) { + if (member($phys_medium->{method}, qw(ftp http https))) { + $uri = $phys_medium->{url}; + $uri =~ s!/media$!!; + } elsif (member($phys_medium->{method}, qw(cdrom nfs))) { + $uri = "$::prefix/$phys_medium->{mntpoint}"; + my $arch = arch() =~ /i.86/ ? $MDK::Common::System::compat_arch{arch()} : arch(); + $uri .= "/$arch" if -d "$uri/$arch"; + } } else { - die "media.cfg not found"; + $uri = $o->{stage2_phys_medium}{url} =~ m!^(https?|ftp)://! && $o->{stage2_phys_medium}{url} || + $phys_medium->{method} =~ m!^(ftp|https?)://! && $phys_medium->{method} || '/tmp/image'; } - - my $suppl_CDs = exists $o->{supplmedia} ? $o->{supplmedia} : $distribconf->{suppl} || 0; - - $suppl_CDs, $o->{copy_rpms_on_disk}; -} - + $uri; + } sub get_media_cfg { my ($o, $phys_medium, $packages, $selected_names, $force_rpmsrate) = @_; - my ($distribconf, $hdlists); + my @media = @{$packages->{media}}; + + my ($distribconf); if (getAndSaveFile_($phys_medium, 'media_info/media.cfg', '/tmp/media.cfg')) { - ($distribconf, $hdlists) = _parse_media_cfg('/tmp/media.cfg'); + ($distribconf) = _parse_media_cfg('/tmp/media.cfg'); } else { die "media.cfg not found"; } - if (defined $selected_names) { - my @names = split ',', $selected_names; - foreach my $h (@$hdlists) { - $h->{selected} = member($h->{name}, @names); - } - } - - my $suppl_CDs = exists $o->{supplmedia} ? $o->{supplmedia} : $distribconf->{suppl} || 0; + my $suppl_CDs = defined $o->{supplmedia} ? $o->{supplmedia} : $distribconf->{suppl} || 0; my $deselectionAllowed = $distribconf->{askmedia} || $o->{askmedia} || 0; - _associate_phys_media($o->{all_hds}, $phys_medium, $hdlists); + log::l(Data::Dumper->Dump([ $phys_medium ], [ 'phys_medium' ])); + log::l(Data::Dumper->Dump([ $o->{stage2_phys_medium} ], [ 'stage2_phys_medium' ])); + my $uri = _get_media_url($o, $phys_medium); + log::l("adding distrib media from $uri"); - if ($deselectionAllowed && !@{$packages->{media}}) { - my $allow = _allow_copy_rpms_on_disk($phys_medium, $hdlists); - $o->ask_deselect_media__copy_on_disk($hdlists, $allow && \$o->{copy_rpms_on_disk}) if $allow || @$hdlists > 1; - } + urpm::media::add_distrib_media($packages, undef, $uri, ask_media => undef); #allmedia => 1 - foreach my $h (@$hdlists) { - _get_medium($o, $phys_medium, $packages, $h); + my @new_media = difference2($packages->{media}, \@media); + _associate_phys_media($o->{all_hds}, $phys_medium, \@new_media); + + select_only_some_media(\@new_media, $selected_names) if defined $selected_names; + + if ($deselectionAllowed && !@{$packages->{media}}) { + my $allow = _allow_copy_rpms_on_disk($phys_medium, $packages->{media}); + $o->ask_deselect_media__copy_on_disk($packages->{media}, $allow && \$o->{copy_rpms_on_disk}) if $allow || @{$packages->{media}} > 1; } log::l("get_media_cfg read " . int(@{$packages->{depslist}}) . " headers"); @@ -685,79 +689,19 @@ sub _get_compsUsers_pl { sub get_standalone_medium { my ($in, $phys_m, $packages, $m) = @_; - add2hash($m, { phys_medium => $phys_m, selected => 1, rel_hdlist => 'media_info/hdlist.cz' }); + add2hash($m, { phys_medium => $phys_m, rel_hdlist => 'media_info/hdlist.cz' }); + local $phys_m->{is_suppl} = 1; # so that _get_media_url() works _get_medium($in, $phys_m, $packages, $m); } sub _get_medium { - my ($in_wait, $phys_m, $packages, $m) = @_; - - $m->{selected} or log::l("ignoring packages in $m->{rel_hdlist}"), return; - - my $medium_id = int @{$packages->{media}}; - $m->{fakemedium} = $m->{name} || $phys_m->{method}; - $m->{fakemedium} =~ s!/!_!g; #- remove "/" from name - if (find { $m->{fakemedium} eq $_->{fakemedium} } allMediums($packages)) { - $m->{fakemedium} .= " (" . ($m->{rpmsdir} || $medium_id) . ")"; - $m->{fakemedium} =~ s!/!_!g; #- remove "/" from rpmsdir - } + my ($_in_wait, $phys_m, $packages, $m) = @_; - log::l("trying to read $m->{rel_hdlist} for medium '$m->{fakemedium}'"); - - #- copy synthesis file directly to urpmi directory. - my $synthesis = urpmidir() . "/synthesis.hdlist.$m->{fakemedium}.cz"; - { - my $rel_synthesis = $m->{rel_hdlist}; - $rel_synthesis =~ s!/hdlist!/synthesis.hdlist! or internal_error("bad {rel_hdlist} $m->{rel_hdlist}"); - _getAndSaveFile_progress($in_wait, N("Downloading file %s...", $rel_synthesis), - $phys_m, $rel_synthesis, $synthesis); - } - - #- get all keys corresponding in the right pubkey file, - #- they will be added in rpmdb later if not found. - if (!$m->{pubkey}) { - my $rel_pubkey = $m->{rel_hdlist}; - $rel_pubkey =~ s!/hdlist(.*)\.cz!/pubkey$1! or internal_error("bad {rel_hdlist} $m->{rel_hdlist}"); - $m->{pubkey} = urpmidir() . "/pubkey_$m->{fakemedium}"; - getAndSaveFile_($phys_m, $rel_pubkey, $m->{pubkey}); - } - - #- for standalone medium not using media.cfg - $phys_m->{name} ||= $m->{name}; - - #- integrate medium in media list, only here to avoid download error (update) to be propagated. - push @{$packages->{media}}, $m; + !$m->{ignore} or log::l("ignoring packages in $m->{rel_hdlist}"), return; - #- parse synthesis (if available) of directly hdlist (with packing). - { - my $nb_suppl_pkg_skipped = 0; - my $callback = sub { - my (undef, $p) = @_; - my $uniq_pkg_seen = $packages->{uniq_pkg_seen} ||= {}; - if ($uniq_pkg_seen->{$p->fullname}++) { - log::l("skipping " . scalar $p->fullname); - ++$nb_suppl_pkg_skipped; - return 0; - } else { - return 1; - } - }; - my $error; - if (-s $synthesis) { - ($m->{start}, $m->{end}) = $packages->parse_synthesis($synthesis, callback => $callback) - or $error = "bad synthesis $synthesis for $m->{fakemedium}"; - } else { - $error = "fatal: no hdlist nor synthesis to read for $m->{fakemedium}"; - } - - if ($error) { - pop @{$packages->{media}}; - unlink $synthesis; - die $error; - } else { - log::l("medium " . phys_medium_to_string($phys_m) . ", read " . ($m->{end} - $m->{start} + 1) . " packages in $m->{rel_hdlist}, $nb_suppl_pkg_skipped skipped"); - } - } + my $url = _get_media_url({}, $phys_m); + log::l("trying '$url'\n"); + urpm::media::add_medium($packages, $m->{name} || 'Supplementary medium', $url, 0) or $packages->{fatal}(10, N("unable to add medium")); } @@ -832,7 +776,7 @@ sub clean_postinstall_rpms() { sub copy_rpms_on_disk { my ($o) = @_; - my $dest_dir = '/var/ftp/pub/Mandrivalinux/media'; + my $dest_dir = '/var/ftp/pub/Mageialinux/media'; #- don't be afraid, cleanup old RPMs if upgrade eval { rm_rf("$::prefix$dest_dir") if $o->{isUpgrade} }; mkdir_p("$::prefix$dest_dir"); @@ -857,7 +801,7 @@ sub copy_rpms_on_disk { #- keep in mind the asked medium has been refused. #- this means it is no longer selected. #- (but do not unselect supplementary CDs.) - $m->{selected} = 0; + $m->{ignore} = 1; } } my $dest_medium_dir = $dest_dir . '/' . basename($rpmsdir); @@ -880,29 +824,13 @@ sub copy_rpms_on_disk { our $copied_rpms_on_disk = 1; } -sub _install_urpmi__generate_names { - my ($packages, $medium) = @_; - - #- build a names file - output("$::prefix/var/lib/urpmi/names.$medium->{fakemedium}", - map { $packages->{depslist}[$_]->name . "\n" } $medium->{start} .. $medium->{end}); -} -sub _install_urpmi__generate_synthesis { - my ($packages, $medium) = @_; - - my $synthesis = "/var/lib/urpmi/synthesis.hdlist.$medium->{fakemedium}.cz"; - - #- build synthesis file if there are still not existing (ie not copied from mirror). - -s "$::prefix$synthesis" <= 32 or return; - - log::l("building $synthesis"); - - eval { $packages->build_synthesis( - start => $medium->{start}, - end => $medium->{end}, - synthesis => "$::prefix$synthesis", - ) }; - $@ and log::l("build_synthesis failed: $@"); +sub _get_medium_dir { + my ($phys_m) = @_; + if (member($phys_m->{method}, qw(ftp http https cdrom))) { + $phys_m->{url}; + } else { + "$phys_m->{mntpoint}$phys_m->{rel_path}"; + } } sub install_urpmi { @@ -914,38 +842,19 @@ sub install_urpmi { #- clean to avoid opening twice the rpm db. delete $packages->{rpmdb}; - #- import pubkey in rpmdb. - my $db = install::pkgs::open_rpm_db_rw(); - foreach my $medium (@media) { - URPM::import_needed_pubkeys_from_file($db, $medium->{pubkey}, sub { - my ($id, $imported) = @_; - if ($id) { - log::l(($imported ? "imported" : "found") . " key=$id for medium $medium->{name}"); - $medium->{'key-ids'} = $id; - } - }); - unlink $medium->{pubkey}; - } - my (@cfg, @netrc); foreach my $medium (@media) { - if ($medium->{selected}) { - my ($dir, $removable_device, $static); + if (!$medium->{ignore}) { + my ($dir, $removable_device); my $phys_m = $medium->{phys_medium}; - if ($phys_m->{method} eq 'ftp' || $phys_m->{method} eq 'http' || $phys_m->{method} eq 'cdrom') { - $dir = $phys_m->{url}; - } else { - $dir = "$phys_m->{mntpoint}$phys_m->{rel_path}"; - if ($phys_m->{method} eq 'iso') { - $removable_device = $phys_m->{loopback_device}{mntpoint} . $phys_m->{loopback_file}; - } - } + $dir = _get_medium_dir($phys_m); - $dir = MDK::Common::File::concat_symlink($dir, $medium->{rpmsdir}); + if ($phys_m->{method} eq 'iso') { + $removable_device = $phys_m->{loopback_device}{mntpoint} . $phys_m->{loopback_file}; + } - _install_urpmi__generate_names($packages, $medium); - _install_urpmi__generate_synthesis($packages, $medium); + $dir = MDK::Common::File::concat_symlink($dir, $medium->{rpmsdir}); my ($qname, $qdir) = ($medium->{fakemedium}, $dir); @@ -965,8 +874,6 @@ sub install_urpmi { " removable: $removable_device"), if_($medium->{update}, " update"), - if_($static, - " static"), "}"; } else { #- remove deselected media by removing copied hdlist and synthesis files |