summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--man/C/urpmi.addmedia.815
-rw-r--r--urpm.pm50
-rw-r--r--urpm/sys.pm20
3 files changed, 66 insertions, 19 deletions
diff --git a/man/C/urpmi.addmedia.8 b/man/C/urpmi.addmedia.8
index c6c6ff2f..75506d51 100644
--- a/man/C/urpmi.addmedia.8
+++ b/man/C/urpmi.addmedia.8
@@ -3,7 +3,7 @@
.SH NAME
urpmi.addmedia \- adds a new rpm medium to be used by urpmi
.SH SYNOPSIS
-.B urpmi.addmedia [\fIoptions\fP] <\fIname\fP> <\fIurl\fP>
+.B urpmi.addmedia [\fIoptions\fP] <\fIname\fP> <\fIurl\fP> [with <\fIhdlist\fP>]
.SH DESCRIPTION
urpmi.addmedia tells urpmi that it can find new rpms at the specified location.
Currently supported media types are: local drives, removable drives (such as
@@ -16,7 +16,8 @@ http:
Where <\fIname\fP> is your reference for the medium (e.g. "updates").
<\fIname\fP> is optional if \fB--distrib\fP is given in \fIoptions\fP.
.br
-<\fIhost\fP>/<\fIpath\fP> is the location of the rpm directory on the net.
+<\fIhost\fP>/<\fIpath\fP> is the location of the media directory on the net
+(e.g. media/main).
.br
<\fIrelative path of hdlist\fP> is the pathname where to find the hdlist of
the rpms. The location is given relative to <\fIpath\fP>.
@@ -56,13 +57,17 @@ Local drive or NFS:
.IP "\fB urpmi.addmedia [\fIoptions\fP] <\fIname\fP> file://<\fIpath\fP>\fP [with <\fIrelative path of synthesis|hdlist\fP>]\fP"
Where <\fIname\fP> is your reference for the medium (e.g. Myrpms).
.br
-<\fIpath\fP> is the location of the rpm directory on your machine.
+<\fIpath\fP> is the location of the media directory on your machine
+(e.g. media/main).
.PP
Removable device:
.br
.IP "\fB urpmi.addmedia [\fIoptions\fP] <\fIname\fP> removable://<\fIpath\fP>\fP [with <\fIrelative path of synthesis|hdlist\fP>]\fP"
-<\fIpath\fP> is the location of the rpm directory on your machine when the
-removable device is mounted.
+<\fIpath\fP> is the location of the media directory on your machine when the
+removable device is mounted. This works for removable drives, but also for ISO
+images mounted on a loop device. urpmi will then be able to re-mount the ISO
+image to the specified path (but the ISO image must be mounted when you run
+\fBurpmi.addmedia\fP).
.PP
.SH OPTIONS
.IP "\fB\--wget\fP"
diff --git a/urpm.pm b/urpm.pm
index 69a5c64e..fe98e80a 100644
--- a/urpm.pm
+++ b/urpm.pm
@@ -318,10 +318,17 @@ sub probe_medium {
$medium;
}
+#- returns the removable device name if it corresponds to an iso image, '' otherwise
+sub is_iso {
+ my ($removable_dev) = @_;
+ $removable_dev && $removable_dev =~ /\.iso$/i ? $removable_dev : '';
+}
+
#- probe device associated with a removable device.
sub probe_removable_device {
my ($urpm, $medium) = @_;
+ #- try to find device name in url scheme
if ($medium->{url} && $medium->{url} =~ /^removable_?([^_:]*)(?:_[^:]*)?:/) {
$medium->{removable} ||= $1 && "/dev/$1";
} else {
@@ -343,6 +350,8 @@ sub probe_removable_device {
$infos{$mntpoints[-1]}{device}, $medium->{name}));
}
$medium->{removable} = $infos{$mntpoints[-1]}{device};
+ } elsif (is_iso($medium->{removable})) {
+ $urpm->{log}(N("Medium \"%s\" is an ISO image, will be mounted on-the-fly", $medium->{name}));
} else {
$urpm->{error}(N("unable to retrieve pathname for removable medium \"%s\"", $medium->{name}));
}
@@ -1036,11 +1045,14 @@ sub update_media {
my $with_hdlist_dir = reduce_pathname($dir . ($medium->{with_hdlist} ? "/$medium->{with_hdlist}" : "/.."));
#- the directory given does not exist and may be accessible
- #- by mounting some other. try to figure out these directory and
- #- mount everything necessary.
- $urpm->try_mounting($options{force} < 2 && ($options{probe_with} || $medium->{with_hdlist}) ?
- $with_hdlist_dir : $dir) or
- $urpm->{error}(N("unable to access medium \"%s\",
+ #- by mounting some other directory. Try to figure it out and mount
+ #- mount everything that might be necessary.
+ $urpm->try_mounting(
+ $options{force} < 2 && ($options{probe_with} || $medium->{with_hdlist})
+ ? $with_hdlist_dir : $dir,
+ #- in case of an iso image, pass its name
+ is_iso($medium->{removable}),
+ ) or $urpm->{error}(N("unable to access medium \"%s\",
this could happen if you mounted manually the directory when creating the medium.", $medium->{name})), next;
#- try to probe for possible with_hdlist parameter, unless
@@ -1937,18 +1949,28 @@ sub clean {
}
}
-#- check for necessity of mounting some directory to get access
sub try_mounting {
my ($urpm, $dir, $removable) = @_;
my %infos;
- $dir = reduce_pathname($dir);
+ my $is_iso = is_iso($removable);
+ my @mntpoints = $is_iso
+ #- note: for isos, we don't parse the fstab because it might not be declared in it.
+ #- so we try to remove suffixes from the dir name until the dir exists
+ ? ($dir = urpm::sys::trim_until_d($dir))
+ : urpm::sys::find_mntpoints(($dir = reduce_pathname($dir)), \%infos);
foreach (grep {
! $infos{$_}{mounted} && $infos{$_}{fs} ne 'supermount';
- } urpm::sys::find_mntpoints($dir, \%infos))
+ } @mntpoints)
{
$urpm->{log}(N("mounting %s", $_));
- `mount '$_' 2>/dev/null`;
+ if ($is_iso) {
+ #- to mount an iso image, grab the first loop device
+ my $loopdev = urpm::sys::first_free_loopdev();
+ $loopdev and `mount '$removable' $_ -t iso9660 -o loop=$loopdev`;
+ } else {
+ `mount '$_' 2>/dev/null`;
+ }
$removable && $infos{$_}{fs} ne 'supermount' and $urpm->{removable_mounted}{$_} = undef;
}
-e $dir;
@@ -2550,14 +2572,14 @@ sub copy_packages_of_removable_media {
my ($id, $device, $copy) = @_;
my $medium = $urpm->{media}[$id];
if (my ($dir) = $medium->{url} =~ m!^(?:(?:removable[^:]*|file):/)?(/.*)!) {
- #- the directory given does not exist or may be accessible
- #- by mounting some other. Try to figure out these directories and
+ #- the directory given does not exist and may be accessible
+ #- by mounting some other directory. Try to figure it out and mount
#- mount everything that might be necessary.
- while ($check_notfound->($id, $dir, 'removable')) {
+ while ($check_notfound->($id, $dir, is_iso($medium->{removable}) || 'removable')) {
$options{ask_for_medium} or $urpm->{fatal}(4, N("medium \"%s\" is not selected", $medium->{name}));
$urpm->try_umounting($dir); system("eject", $device);
- $options{ask_for_medium}(remove_internal_name($medium->{name}), $medium->{removable}) or
- $urpm->{fatal}(4, N("medium \"%s\" is not selected", $medium->{name}));
+ $options{ask_for_medium}(remove_internal_name($medium->{name}), $medium->{removable})
+ or $urpm->{fatal}(4, N("medium \"%s\" is not selected", $medium->{name}));
}
if (-e $dir) {
while (my ($i, $url) = each %{$list->[$id]}) {
diff --git a/urpm/sys.pm b/urpm/sys.pm
index 1ccc3b6e..8a5e0739 100644
--- a/urpm/sys.pm
+++ b/urpm/sys.pm
@@ -107,6 +107,26 @@ sub find_mntpoints {
@mntpoints;
}
+#- returns the first unused loop device, or an empty string if none is found.
+sub first_free_loopdev () {
+ open my $mounts, '/proc/mounts' or do { warn "Can't read /proc/mounts: $!\n"; return 1 };
+ my %loopdevs = map { $_ => 1 } grep { ! -d $_ } glob('/dev/loop*');
+ local *_;
+ while (<$mounts>) {
+ (our $dev) = split ' ';
+ delete $loopdevs{$dev} if $dev =~ m!^/dev/loop!;
+ }
+ close $mounts;
+ my @l = keys %loopdevs;
+ @l ? $l[0] : '';
+}
+
+sub trim_until_d {
+ my ($dir) = @_;
+ while ($dir && !-d $dir) { $dir =~ s,/[^/]*$,, }
+ $dir;
+}
+
#- checks if the main filesystems are writeable for urpmi to install files in
sub check_fs_writable () {
open my $mounts, '/proc/mounts' or do { warn "Can't read /proc/mounts: $!\n"; return 1 };