summaryrefslogtreecommitdiffstats
path: root/lib/MDV/Distribconf/Checks.pm
diff options
context:
space:
mode:
Diffstat (limited to 'lib/MDV/Distribconf/Checks.pm')
-rw-r--r--lib/MDV/Distribconf/Checks.pm392
1 files changed, 392 insertions, 0 deletions
diff --git a/lib/MDV/Distribconf/Checks.pm b/lib/MDV/Distribconf/Checks.pm
new file mode 100644
index 0000000..57bae02
--- /dev/null
+++ b/lib/MDV/Distribconf/Checks.pm
@@ -0,0 +1,392 @@
+# $Id: Checks.pm 59285 2006-09-01 00:10:10Z nanardon $
+
+package MDV::Distribconf::Checks;
+
+our $VERSION = (qq$Revision: 59285 $ =~ /(\d+)/)[0];
+
+=head1 NAME
+
+MDV::Distribconf::Checks - A Subclass to MDV::Distribconf::Build to check distribution trees
+
+=head1 METHODS
+
+=over 4
+
+=cut
+
+use strict;
+use warnings;
+use MDV::Distribconf::MediaCFG;
+use MDV::Packdrakeng;
+use Digest::MD5;
+use MDV::Distribconf::Utils;
+use base qw(MDV::Distribconf);
+
+sub new {
+ my $class = shift;
+ my $self = $class->SUPER::new(@_);
+ bless $self, $class;
+}
+
+sub _report_err {
+ my ($out, $err_code, $fmt, @args) = @_;
+ my %errs = (
+ 'UNSYNC_HDLIST' => 'E',
+ 'UNSYNC_MD5' => 'E',
+ 'WRONG_CONFIG' => 'W',
+ 'MISSING_MEDIA' => 'W',
+ 'MISSING_MEDIADIR' => 'E',
+ 'SAME_INDEX' => 'E',
+ 'NOMEDIA' => 'E',
+ 'MISSING_INDEX' => 'E',
+ 'MISSING_INFO' => 'W',
+ );
+ my $message = sprintf($fmt, @args);
+
+ if (ref $out eq 'CODE') {
+ $out->(
+ errcode => $err_code || '?',
+ level => $errs{$err_code} || '?',
+ message => $message,
+ );
+ } else {
+ printf $out "%s: %s\n", $errs{$err_code} || '?', $message;
+ }
+ return($errs{$err_code} || '?' eq 'E' ? 1 : 0)
+}
+
+=item $distrib->check_config
+
+=cut
+
+sub check_config {
+ my ($self, $fhout) = @_;
+ $fhout ||= \*STDERR;
+
+ my $error = 0;
+
+ foreach my $var ($self->{cfg}->Parameters('media_info')) {
+ $self->{cfg}->val('media_info', $var) or next;
+ my @er = MDV::Distribconf::MediaCFG::_valid_param(
+ 'media_info',
+ $var,
+ $self->{cfg}->val('media_info', $var),
+ );
+ foreach (@er) {
+ $error += _report_err(
+ $fhout,
+ 'WRONG_CONFIG',
+ "%s %s: %s", 'media_info', $var, $_
+ );
+ }
+ }
+ foreach my $media ($self->listmedia()) {
+ foreach my $var ($self->{cfg}->Parameters($media)) {
+ $self->{cfg}->val($media, $var) or next;
+ my @er = MDV::Distribconf::MediaCFG::_valid_param(
+ 'media_info',
+ $var,
+ $self->getvalue($media, $var),
+ );
+ foreach (@er) {
+ $error += _report_err(
+ $fhout,
+ 'WRONG_CONFIG',
+ "%s %s: %s", $media, $var, $_
+ );
+ }
+ my $varinfo = MDV::Distribconf::MediaCFG::_value_info($var) || {};
+ if ($varinfo->{deny}) {
+ if ($self->getvalue($media, $varinfo->{deny})) {
+ $error += _report_err(
+ $fhout,
+ 'WRONG_CONFIG',
+ '%s and %s cannot be set together (media %s)',
+ $var, $varinfo->{deny}, $media
+ );
+ }
+ }
+ if ($varinfo->{ismedialist} || $varinfo->{cross}) {
+ foreach my $sndmedia (split(/ /, $self->getvalue($media, $var, ''))) {
+ if (!$self->mediaexists($sndmedia)) {
+ $error += _report_err(
+ $fhout,
+ 'MISSING_MEDIA',
+ "`%s' refer as %s to non existant `%s'",
+ $media,
+ $var,
+ $sndmedia,
+ );
+ } elsif($varinfo->{cross}) {
+ if(!grep { $media eq $_ }
+ split(/ /,
+ $self->getvalue($sndmedia, $varinfo->{cross})
+ )) {
+ $error += _report_err(
+ $fhout,
+ 'WRONG_CONFIG',
+ "`%s' has not `%s' as %s",
+ $sndmedia, $media, $varinfo->{cross},
+ );
+ }
+ }
+ }
+ }
+ }
+ }
+
+ # checking overlap
+ {
+ my %foundname;
+ push(@{$foundname{$self->getvalue($_, 'name')}}, $_)
+ foreach($self->listmedia());
+
+ foreach (keys %foundname) {
+ if (@{$foundname{$_}} > 1) {
+ $error += _report_err(
+ $fhout,
+ 'WRONG_CONFIG',
+ "`%s' have same name (%s)",
+ join(', ', @{$foundname{$_}}),
+ $_,
+ );
+ }
+ }
+ }
+
+ $error
+}
+=item $distrib->check_media_coherency($fhout)
+
+Performs basic checks on the distribution and prints to $fhout (STDERR by
+default) warnings and errors found. Returns the number of errors reported.
+
+=cut
+
+sub check_media_coherency {
+ my ($distrib, $fhout) = @_;
+ $fhout ||= \*STDERR;
+
+ my $error = 0;
+
+ $distrib->listmedia or $error += _report_err(
+ 'NOMEDIA', "No media found in this config"
+ );
+
+ # Checking no overlap
+ foreach my $var (qw/hdlist synthesis path/) {
+ my %e;
+ foreach ($distrib->listmedia) {
+ my $v = $distrib->getpath($_, $var);
+ push @{$e{$v}}, $_;
+ }
+
+ foreach my $key (keys %e) {
+ if (@{$e{$key}} > 1) {
+ $error += _report_err(
+ $fhout,
+ 'SAME_INDEX',
+ "media `%s' have same %s (%s)",
+ join (", ", @{$e{$key}}),
+ $var,
+ $key
+ );
+ }
+ }
+ }
+
+ foreach my $media ($distrib->listmedia) {
+ -d $distrib->getfullpath($media, 'path') or $error += _report_err(
+ $fhout,
+ 'MISSING_MEDIADIR', "dir %s does't exist for media `%s'",
+ $distrib->getpath($media, 'path'),
+ $media
+ );
+ foreach (qw/hdlist synthesis/) {
+ -f $distrib->getfullpath($media, $_) or $error += _report_err(
+ $fhout,
+ 'MISSING_INDEX', "$_ %s doesn't exist for media `%s'",
+ $distrib->getpath($media, $_),
+ $media
+ );
+ }
+ foreach (qw/pubkey/) {
+ -f $distrib->getfullpath($media, $_) or $error += _report_err(
+ $fhout,
+ 'MISSING_INFO', "$_ %s doesn't exist for media `%s'",
+ $distrib->getpath($media, $_),
+ $media
+ );
+ }
+
+ }
+ return $error;
+}
+
+=item $distrib->check_index_sync($media)
+
+Check the synchronisation between rpms contained by media $media
+and its hdlist:
+
+ - all rpms should be in the hdlist
+ - the hdlist should not contains rpms that does not exists
+
+Return 1 if no problem were found
+
+=cut
+
+
+sub check_index_sync {
+ my ($self, $media, $submedia) = @_;
+ my $rpmspath = $self->getfullpath($media, 'path');
+ my $hdlist = ($submedia && -d $self->getfullpath($media, 'path') . '/media_info') ?
+ $self->getfullmediapath($media, 'hdlist') :
+ $self->getfullpath($media, 'hdlist');
+ my $synthesis = ($submedia && -d $self->getfullpath($media, 'path') . '/media_info') ?
+ $self->getfullmediapath($media, 'synthesis') :
+ $self->getfullpath($media, 'synthesis');
+
+ -f $hdlist && -f $synthesis or return 0; # avoid warnings
+ my ($inp, $ind) = MDV::Distribconf::Utils::hdlist_vs_dir($hdlist, $rpmspath);
+ if (@{$inp || []} + @{$ind || []}) {
+ return 0;
+ }
+ return 1;
+}
+
+=item $distrib->check_media_md5($media)
+
+Check md5sum for hdlist and synthesis for the media $media are the same
+than value contains in the existing MD5SUM file.
+
+The function return an error also if the value is missing
+
+Return 1 if no error were found.
+
+=cut
+
+sub check_media_md5 {
+ my ($self, $media) = @_;
+ my ($unsync) = MDV::Distribconf::Utils::checkmd5(
+ $self->getfullmediapath($media, 'MD5SUM'),
+ map { $self->getfullmediapath($media, $_) } (qw(hdlist synthesis))
+ );
+ if (@{$unsync || []}) {
+ return 0;
+ } else {
+ return 1;
+ }
+}
+
+sub check_global_md5 {
+ my ($self) = @_;
+ my @indexes;
+ foreach my $media ($self->listmedia()) {
+ push(@indexes, map { $self->getfullpath($media, $_) } (qw(hdlist synthesis)));
+ }
+ my ($unsync) = MDV::Distribconf::Utils::checkmd5(
+ $self->getfullpath(undef, 'MD5SUM'),
+ @indexes,
+ );
+ if (@{$unsync || []}) {
+ return 0;
+ } else {
+ return 1;
+ }
+}
+
+=item $distrib->checkdistrib($fhout)
+
+Performs all light checks on the distribution and prints to $fhout (STDERR by
+default) warnings and errors found. Returns the number of errors reported.
+
+=cut
+
+sub checkdistrib {
+ my ($self, $fhout) = @_;
+ $fhout ||= \*STDERR;
+
+ my $error = 0;
+
+ $error += $self->check_config($fhout);
+ $error += $self->check_media_coherency($fhout);
+
+ foreach my $media ($self->listmedia) {
+ if(!$self->check_index_sync($media)) {
+ $error += _report_err(
+ $fhout,
+ 'UNSYNC_HDLIST',
+ "hdlist for media `%s' is not sync with its rpms",
+ $media,
+ );
+ }
+
+ if(!$self->check_media_md5($media)) {
+ $error += _report_err(
+ $fhout,
+ 'UNSYNC_MD5',
+ "md5sum for media `%s' is not ok",
+ $media,
+ );
+ }
+ }
+
+ if ($self->check_global_md5()) {
+ $error += _report_err(
+ $fhout,
+ 'UNSYNC_MD5',
+ 'Global md5sum file is not ok',
+ );
+ }
+
+ $error
+}
+
+=item $distrib->check($fhout)
+
+=cut
+
+sub check {
+ my ($self, $fhout) = @_;
+ $fhout ||= \*STDERR;
+
+ my $error = $self->check_config($fhout);
+ $error += $self->check_media_coherency($fhout);
+
+ $error
+}
+
+1;
+
+__END__
+
+=back
+
+=head1 SEE ALSO
+
+L<MDV::Distribconf>
+L<MDV::Distribconf::Build>
+
+=head1 AUTHOR
+
+Olivier Thauvin <nanardon@mandriva.org>
+
+=head1 LICENSE AND COPYRIGHT
+
+(c) 2005 Olivier Thauvin ; (c) 2005, 2006 Mandriva
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+=cut