diff options
Diffstat (limited to 'lib/MDV/Distribconf/Checks.pm')
-rw-r--r-- | lib/MDV/Distribconf/Checks.pm | 392 |
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 |