summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--NEWS2
-rw-r--r--README.zeroconf30
-rw-r--r--pod/urpmi.addmedia.8.pod6
-rw-r--r--urpm/args.pm1
-rw-r--r--urpm/media.pm57
-rw-r--r--urpmi-repository-http.service16
-rwxr-xr-xurpmi.addmedia5
7 files changed, 115 insertions, 2 deletions
diff --git a/NEWS b/NEWS
index f63a5913..927b6590 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,5 @@
+- add --zeroconf support in urpmi.addmedia
+
Version 6.37 - 28 May 2010
- urpmq
o fix listing of groups when listing all packages (also fixes #59321)
diff --git a/README.zeroconf b/README.zeroconf
new file mode 100644
index 00000000..4df14066
--- /dev/null
+++ b/README.zeroconf
@@ -0,0 +1,30 @@
+urpmi can automatically find the media repository path using DNS-SD
+(Zeroconf), with the "--zeroconf" option:
+ urpmi.addmedia --distrib --zeroconf
+ urpmi.addmedia --zeroconf main media/main/release
+
+This option can also be used together with the "--mirrorlist" option,
+in which case the repositories are configured using Zeroconf if found,
+and mirrorlist is used as a fallback:
+ urpmi.addmedia --distrib --zeroconf --mirrorlist
+
+When searching for the repository using Zeroconf, the request timeouts
+after a delay of 10 seconds, to avoid hanging urpmi if some hosts are
+unresolvable.
+
+If a repository is found using DNS-SD, urpmi.addmedia will build a
+complete repository path using fields from /etc/product.id, this way:
+<advertised repository path>/lowercase(<branch>)/<version>/<arch>
+
+To advertise an urpmi repository using DNS-SD, a service record with
+the instance "_mdv_urpmi" has to be created, specifying the target
+host and target port where the service is located.
+In addition, two DNS-SD TXT records must be specified, in the form of
+key/value pairs: protocol (http, ftp or rsync) and path (repository root).
+
+The path value should be the full path to the media repository root,
+for example /dis if the distribution repository is reachable on
+http://host:port/dis/official/2010.1/i586
+
+See the urpmi-repository-http.service file for an example of urpmi
+repository advertising using Avahi.
diff --git a/pod/urpmi.addmedia.8.pod b/pod/urpmi.addmedia.8.pod
index c7d223a6..6d404716 100644
--- a/pod/urpmi.addmedia.8.pod
+++ b/pod/urpmi.addmedia.8.pod
@@ -156,6 +156,12 @@ available.
nb: $MIRRORLIST is a special variable which gives the default URL for the
current distribution/arch. $MIRRORLIST is the default mirrorlist.
+=item B<--zeroconf>
+
+Find a media repository for the current distribution using zeroconf (DNS-SD).
+It can be used together with B<--distrib> or by specifying a media name and a
+path to the media directory, relative to the repository root.
+
=item B<--distrib>
Retrieve a set of media from a distribution. Typically, the URL provided
diff --git a/urpm/args.pm b/urpm/args.pm
index 71902b36..d5e584cc 100644
--- a/urpm/args.pm
+++ b/urpm/args.pm
@@ -344,6 +344,7 @@ my %options_spec = (
'no-probe' => sub { $options{probe_with} = undef },
distrib => sub { $options{distrib} = 1 },
'mirrorlist:s' => sub { $options{mirrorlist} = $_[1] || '$MIRRORLIST' },
+ zeroconf => sub { $options{zeroconf} = 1 },
interactive => sub { $options{interactive} = 1 },
'all-media' => sub { $options{allmedia} = 1 },
virtual => \$options{virtual},
diff --git a/urpm/media.pm b/urpm/media.pm
index b7b7f6cb..9f8c138c 100644
--- a/urpm/media.pm
+++ b/urpm/media.pm
@@ -755,10 +755,61 @@ sub _compute_flags_for_instlist {
}
+sub maybe_find_zeroconf {
+ my ($urpm, $url, $options) = @_;
+ if (delete $options->{zeroconf}) {
+ $url and die "unexpected url $url together with zeroconf\n";
+ $url = find_zeroconf_repository($urpm);
+ if ($url) {
+ $url = urpm::mirrors::_add__with_dir($url, delete $options->{"with-dir"});
+ delete $options->{mirrorlist};
+ }
+ }
+ return $url;
+}
+
+sub find_zeroconf_repository {
+ my ($urpm) = @_;
+
+ my $zeroconf_timeout = 10;
+ my $res;
+ eval {
+ local $SIG{ALRM} = sub { die "timeout" };
+ alarm($zeroconf_timeout);
+
+ $urpm->{debug} and $urpm->{debug}("trying to find a zeroconf repository");
+ require Net::Bonjour;
+ $res = Net::Bonjour->new('mdv_urpmi');
+
+ alarm(0);
+ };
+
+ if ($@) {
+ $urpm->{error}("zeroconf error: $@"), return;
+ }
+
+ require urpm::mirrors;
+ my $product_id = urpm::mirrors::parse_LDAP_namespace_structure(cat_('/etc/product.id'));
+ my $path_suffix = join('/', lc($product_id->{branch}), $product_id->{version}, $product_id->{arch});
+
+ foreach my $entry ($res->entries) {
+ my $base_url = $entry->attribute('protocol') . '://' .$entry->address . ':' . $entry->port . $entry->attribute('path');
+ my $url = $base_url . '/' . $path_suffix;
+ my $distribconf = _new_distribconf_and_download($urpm, { url => $url });
+ if ($distribconf) {
+ $urpm->{log}(sprintf("found zeroconf repository: %s", $url));
+ return $url;
+ };
+ }
+
+ $urpm->{debug} and $urpm->{debug}("unable to find zeroconf repository");
+ return;
+}
+
#- add a new medium, sync the config file accordingly.
#- returns the new medium's name. (might be different from the requested
#- name if index_name was specified)
-#- options: ignore, index_name, nolock, update, virtual, media_info_dir, mirrorlist, with-dir, xml-info, on_the_fly
+#- options: ignore, index_name, nolock, update, virtual, media_info_dir, mirrorlist, zeroconf, with-dir, xml-info, on_the_fly
sub add_medium {
my ($urpm, $name, $url, $with_synthesis, %options) = @_;
@@ -777,6 +828,8 @@ sub add_medium {
name2medium($urpm, $name) and $urpm->{fatal}(5, N("medium \"%s\" already exists", $name));
}
+ $url = maybe_find_zeroconf($urpm, $url, \%options);
+
$url =~ s,/*$,,; #- clear URLs for trailing /es.
#- creating the medium info.
@@ -878,6 +931,7 @@ sub _register_media_cfg {
#- - ask_media : callback to know whether each media should be added
#- - only_updates : only add "update" media (used by rpmdrake)
#- - mirrorlist
+#- - zeroconf
#- other options are passed to add_medium(): ignore, nolock, virtual
sub add_distrib_media {
my ($urpm, $name, $url, %options) = @_;
@@ -903,6 +957,7 @@ sub add_distrib_media {
_register_media_cfg($urpm, $dir, undef, $distribconf, $media_cfg);
}
} else {
+ $url = maybe_find_zeroconf($urpm, $url, \%options);
if ($options{mirrorlist}) {
$url and die "unexpected url $url together with mirrorlist $options{mirrorlist}\n";
}
diff --git a/urpmi-repository-http.service b/urpmi-repository-http.service
new file mode 100644
index 00000000..735d30bc
--- /dev/null
+++ b/urpmi-repository-http.service
@@ -0,0 +1,16 @@
+<?xml version="1.0" standalone='no'?><!--*-nxml-*-->
+<!DOCTYPE service-group SYSTEM "avahi-service.dtd">
+
+<service-group>
+ <name replace-wildcards="yes">Mandriva urpmi repository on %h (HTTP)</name>
+
+ <service>
+ <type>_mdv_urpmi._tcp</type>
+ <subtype>_http._sub._mdv_urpmi._tcp</subtype>
+ <host-name>distro.local</host-name>
+ <port>80</port>
+ <txt-record>protocol=http</txt-record>
+ <txt-record>path=/dis</txt-record>
+ </service>
+
+</service-group>
diff --git a/urpmi.addmedia b/urpmi.addmedia
index 872e93b4..415d1e4a 100755
--- a/urpmi.addmedia
+++ b/urpmi.addmedia
@@ -48,6 +48,7 @@ examples:
urpmi.addmedia --distrib --mirrorlist '\$MIRRORLIST'
urpmi.addmedia --mirrorlist '\$MIRRORLIST' backports media/main/backports
+ urpmi.addmedia --distrib --zeroconf
and [options] are from
@@ -101,7 +102,7 @@ my $with_dir;
$options{quiet} = 1 if $options{verbose} < 0;
$url or ($url, $name) = ($name, '');
-if ($options{mirrorlist}) {
+if ($options{mirrorlist} || $options{zeroconf}) {
if ($options{distrib}) {
$url and die N("no argument needed for --distrib --mirrorlist <url>") . "\n";
} else {
@@ -144,6 +145,7 @@ if ($options{distrib}) {
$name,
$url,
mirrorlist => $options{mirrorlist},
+ zeroconf => $options{zeroconf},
virtual => $options{virtual},
only_updates => $options{update},
probe_with => $options{probe_with},
@@ -167,6 +169,7 @@ if ($options{distrib}) {
urpm::media::add_medium($urpm,
$name, $url, $relative_synthesis,
mirrorlist => $options{mirrorlist},
+ zeroconf => $options{zeroconf},
'with-dir' => $with_dir,
virtual => $options{virtual},
update => $options{update},