summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.perl_checker1
-rw-r--r--NEWS2
-rw-r--r--t/helper.pm26
-rw-r--r--t/superuser--addmedia.t22
-rw-r--r--urpm.pm1
-rw-r--r--urpm/cfg.pm63
-rw-r--r--urpm/media.pm40
7 files changed, 151 insertions, 4 deletions
diff --git a/.perl_checker b/.perl_checker
index 5f46df51..c97dff1e 100644
--- a/.perl_checker
+++ b/.perl_checker
@@ -17,3 +17,4 @@ Time::HiRes
open
encoding
XML::LibXML::Reader
+Config::IniFiles
diff --git a/NEWS b/NEWS
index b3b70e91..3b0673f2 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,5 @@
+- urpmi handles /etc/urpmi/media.d/*.cfg
+ as an alternative to using urpmi.addmedia
- urpmi.update, urpmi.addmedia:
o handle --virtual for remote media
(a better name would be "auto-update", a la yum)
diff --git a/t/helper.pm b/t/helper.pm
index 870baa2b..edf787d3 100644
--- a/t/helper.pm
+++ b/t/helper.pm
@@ -7,6 +7,7 @@ our @EXPORT = qw(need_root_and_prepare
urpmi_addmedia urpmi_removemedia urpmi_update
urpm_cmd run_urpm_cmd urpmi_cmd urpmi test_urpmi_fail urpme
urpmi_cfg set_urpmi_cfg_global_options
+ create_media_d_cfg media_d_cfg
system_ system_should_fail
rpm_is_jbj_version
check_installed_fullnames check_installed_names check_nothing_installed
@@ -101,6 +102,31 @@ sub set_urpmi_cfg_global_options {
ok(urpm::cfg::dump_config(urpmi_cfg(), $config), 'set_urpmi_cfg_global_options');
}
+sub media_d_dir {
+ "$::pwd/root/etc/urpmi/media.d";
+}
+sub media_d_cfg {
+ my ($name) = @_;
+ media_d_dir() . "/$name.cfg";
+}
+sub create_media_d_cfg {
+ my ($name, @l) = @_;
+
+ system("install -d " . media_d_dir());
+ my $cfg = media_d_cfg($name);
+ -e $cfg and die "$cfg already exists\n";
+ open(my $F, '>', $cfg);
+
+ my $cnt = 1;
+ foreach my $h (@l) {
+ my %h = %$h;
+ my $section = delete $h{conf_file__rel_media} || $cnt++;
+ print $F "[$section]\n";
+ print $F "$_ = $h->{$_}\n" foreach keys %$h;
+ }
+}
+
+
sub system_ {
my ($cmd) = @_;
system($cmd);
diff --git a/t/superuser--addmedia.t b/t/superuser--addmedia.t
index 63b9fb34..f6701a3e 100644
--- a/t/superuser--addmedia.t
+++ b/t/superuser--addmedia.t
@@ -14,6 +14,9 @@ my $name3 = 'various3';
my @fields = qw(hdlist synthesis with_synthesis media_info_dir no-media-info list virtual ignore);
+try_media_d_1();
+try_media_d_2();
+
try_medium({}, '');
@@ -150,3 +153,22 @@ sub check_urpmi {
urpmi(join(' ', @names));
check_installed_and_remove(@names);
}
+
+sub try_media_d_1 {
+ create_media_d_cfg($name, { name => $name, url => "$::pwd/media/$name" });
+ check_urpmi($name);
+
+ create_media_d_cfg($name2, { name => $name2, url => "$::pwd/media/$name2" });
+ check_urpmi($name2);
+
+ ok(unlink media_d_cfg($name));
+ ok(unlink media_d_cfg($name2));
+}
+sub try_media_d_2 {
+ create_media_d_cfg($name,
+ { name => $name, url => "$::pwd/media/$name" },
+ { name => $name2, url => "$::pwd/media/$name2" });
+ check_urpmi($name, $name2);
+
+ ok(unlink media_d_cfg($name));
+}
diff --git a/urpm.pm b/urpm.pm
index 66702b33..88f0946c 100644
--- a/urpm.pm
+++ b/urpm.pm
@@ -123,6 +123,7 @@ sub set_files {
my ($urpm, $urpmi_root) = @_;
my %h = (
config => "$urpmi_root/etc/urpmi/urpmi.cfg",
+ configs_dir => "$urpmi_root/etc/urpmi/media.d",
skiplist => prefer_rooted($urpmi_root, '/etc/urpmi/skip.list'),
instlist => prefer_rooted($urpmi_root, '/etc/urpmi/inst.list'),
prefer_list => prefer_rooted($urpmi_root, '/etc/urpmi/prefer.list'),
diff --git a/urpm/cfg.pm b/urpm/cfg.pm
index a1c24d3f..634a188d 100644
--- a/urpm/cfg.pm
+++ b/urpm/cfg.pm
@@ -252,6 +252,69 @@ sub dump_config_raw {
1;
}
+sub load_ini_config_file_raw {
+ my ($file, $b_norewrite) = @_;
+
+ require Config::IniFiles;
+ my $cfg = Config::IniFiles->new('-file' => $file);
+ [ map {
+ my $section = $_;
+ my %h = map {
+ my $v = $cfg->val($section, $_);
+ $v = expand_line($v) if !$b_norewrite;
+ $_ => $v;
+ } $cfg->Parameters($section);
+ { conf_file__rel_media => $section, %h };
+ } $cfg->Sections ];
+}
+
+sub write_ini_config {
+ my ($file, $blocks) = @_;
+
+ if (@$blocks == 0) {
+ unlink $file;
+ return;
+ }
+ my $modified;
+
+ require Config::IniFiles;
+ my $cfg = Config::IniFiles->new('-file' => $file);
+ if ($cfg) {
+ # remove dropped blocks
+ foreach (difference2([ $cfg->Sections ], [ map { $_->{name} } @$blocks ])) {
+ $cfg->DeleteSection($_);
+ $modified = 1;
+ }
+ } else {
+ $cfg = Config::IniFiles->new;
+ }
+
+ my %uniq;
+
+ foreach (@$blocks) {
+ my %h = %$_;
+ my $section = delete $h{conf_file__rel_media} || '_';
+ $uniq{$section}++ or die "conflicting conf_file__rel_media value\n";
+
+ foreach (difference2([ $cfg->Parameters($section) ], [ keys %h ])) {
+ # remove those options which are no more wanted
+ $cfg->delval($section, $_);
+ $modified = 1;
+ }
+ foreach (keys %h) {
+ my $old_v = $cfg->getval($section, $_);
+ my $v = substitute_back($h{$_}, $old_v);
+ if ($old_v ne $v) {
+ $cfg->setval($section, $_, $v);
+ $modified = 1;
+ }
+ }
+ }
+ if ($modified) {
+ $cfg->RewriteConfig;
+ }
+}
+
#- routines to handle mirror list location
#- Default mirror list
diff --git a/urpm/media.pm b/urpm/media.pm
index ac66c3b2..0e056c63 100644
--- a/urpm/media.pm
+++ b/urpm/media.pm
@@ -11,6 +11,7 @@ use MDV::Distribconf;
our @PER_MEDIA_OPT = qw(
+ conf_file__rel_media
downloader
ignore
key-ids
@@ -144,6 +145,7 @@ sub read_config {
#- per-media options
read_config_add_passwords($urpm, $config);
+ my @media;
foreach my $m (@{$config->{media}}) {
my $medium = _only_media_opts_read($m);
@@ -154,9 +156,22 @@ sub read_config {
$medium->{url} or $urpm->{error}("unable to find url in list file $medium->{name}, medium ignored");
}
- add_existing_medium($urpm, $medium);
+ push @media, $medium;
}
+ require File::Glob;
+ # we can't use perl's glob() because we allow spaces in filename
+ foreach my $conf_file (File::Glob::bsd_glob("$urpm->{configs_dir}/*.cfg")) {
+ $urpm->{debug} and $urpm->{debug}("parsing: $conf_file");
+ my $conf = urpm::cfg::load_ini_config_file_raw($conf_file);
+ foreach my $medium (map { _only_media_opts_read($_) } @$conf) {
+ $medium->{conf_file} = $conf_file;
+ push @media, $medium;
+ }
+ }
+
+ add_existing_medium($urpm, $_) foreach @media;
+
eval { require urpm::ldap; urpm::ldap::load_ldap_media($urpm) };
}
@@ -172,7 +187,12 @@ sub check_existing_medium {
N("unable to access list file of \"%s\", medium ignored", $medium->{name});
} elsif (!$medium->{ignore}
&& !-r any_synthesis($urpm, $medium)) {
- $err = N("unable to access synthesis file of \"%s\", medium ignored", $medium->{name});
+ if ($medium->{conf_file} && $< == 0) {
+ # no pb, we create on the fly
+ $medium->{force_auto_update} = 1;
+ } else {
+ $err = N("unable to access synthesis file of \"%s\", medium ignored", $medium->{name});
+ }
}
if ($err) {
$medium->{ignore} = 1;
@@ -406,11 +426,16 @@ sub write_urpmi_cfg {
#- avoid trashing exiting configuration if it wasn't loaded
$urpm->{media} or return;
+ my %media_per_cfg;
+ foreach (grep { !$_->{external} } @{$urpm->{media}}) {
+ push @{$media_per_cfg{$_->{conf_file} || ''}}, _only_media_opts_write($_);
+ }
+
my $config = {
#- global config options found in the config file, without the ones
#- set from the command-line
global => $urpm->{global_config},
- media => [ map { _only_media_opts_write($_) } grep { !$_->{external} } @{$urpm->{media}} ],
+ media => delete $media_per_cfg{''},
};
remove_passwords_and_write_private_netrc($urpm, $config);
@@ -419,6 +444,13 @@ sub write_urpmi_cfg {
$urpm->{log}(N("wrote config file [%s]", $urpm->{config}));
+ foreach my $conf_file (sort keys %media_per_cfg) {
+ urpm::cfg::write_ini_config($conf_file, $media_per_cfg{$conf_file})
+ or $urpm->{fatal}(6, N("unable to write config file [%s]", $conf_file));
+
+ $urpm->{log}(N("wrote config file [%s]", $conf_file));
+ }
+
#- everything should be synced now.
delete $urpm->{modified};
}
@@ -552,7 +584,7 @@ sub _auto_update_media {
my $errors;
foreach (grep { !$_->{ignore} && (!$options{update} || $_->{update}) &&
- _is_remote_virtual($_) } @{$urpm->{media} || []}) {
+ ($_->{force_auto_update} || _is_remote_virtual($_)) } @{$urpm->{media} || []}) {
_update_medium($urpm, $_, %options) or $errors++;
}
!$errors;