File Coverage

blib/lib/MDV/Distribconf/Checks.pm
Criterion Covered Total %
statement 50 150 33.3
branch 16 78 20.5
condition 9 41 21.9
subroutine 11 17 64.7
pod 6 9 66.6
total 92 295 31.1


line stmt bran cond sub pod time code
1             # $Id: Checks.pm 59285 2006-09-01 00:10:10Z nanardon $
2              
3             package MDV::Distribconf::Checks;
4              
5             our $VERSION = (qq$Revision: 59285 $ =~ /(\d+)/)[0];
6              
7             =head1 NAME
8              
9             MDV::Distribconf::Checks - A Subclass to MDV::Distribconf::Build to check distribution trees
10              
11             =head1 METHODS
12              
13             =over 4
14              
15             =cut
16              
17 3     3   823 use strict;
  3         8  
  3         112  
18 3     3   16 use warnings;
  3         5  
  3         79  
19 3     3   1351 use MDV::Distribconf::MediaCFG;
  3         8  
  3         105  
20 3     3   670 use MDV::Packdrakeng;
  3         14021  
  3         77  
21 3     3   17 use Digest::MD5;
  3         6  
  3         110  
22 3     3   1402 use MDV::Distribconf::Utils;
  3         8  
  3         111  
23 3     3   22 use base qw(MDV::Distribconf);
  3         6  
  3         6076  
24              
25             sub new {
26 0     0 1 0 my $class = shift;
27 0         0 my $self = $class->SUPER::new(@_);
28 0         0 bless $self, $class;
29             }
30              
31             sub _report_err {
32 1     1   561 my ($out, $err_code, $fmt, @args) = @_;
33 1         8 my %errs = (
34             'UNSYNC_HDLIST' => 'E',
35             'UNSYNC_MD5' => 'E',
36             'WRONG_CONFIG' => 'W',
37             'MISSING_MEDIA' => 'W',
38             'MISSING_MEDIADIR' => 'E',
39             'SAME_INDEX' => 'E',
40             'NOMEDIA' => 'E',
41             'MISSING_INDEX' => 'E',
42             'MISSING_INFO' => 'W',
43             );
44 1         4 my $message = sprintf($fmt, @args);
45              
46 1 50       4 if (ref $out eq 'CODE') {
47             $out->(
48             errcode => $err_code || '?',
49 1   50     8 level => $errs{$err_code} || '?',
      50        
50             message => $message,
51             );
52             } else {
53 0   0     0 printf $out "%s: %s\n", $errs{$err_code} || '?', $message;
54             }
55 1 50 50     1606 return($errs{$err_code} || '?' eq 'E' ? 1 : 0)
56             }
57              
58             =item $distrib->check_config
59              
60             =cut
61              
62             sub check_config {
63 0     0 1 0 my ($self, $fhout) = @_;
64 0   0     0 $fhout ||= \*STDERR;
65              
66 0         0 my $error = 0;
67              
68 0         0 foreach my $var ($self->{cfg}->Parameters('media_info')) {
69 0 0       0 $self->{cfg}->val('media_info', $var) or next;
70             my @er = MDV::Distribconf::MediaCFG::_valid_param(
71             'media_info',
72             $var,
73 0         0 $self->{cfg}->val('media_info', $var),
74             );
75 0         0 foreach (@er) {
76 0         0 $error += _report_err(
77             $fhout,
78             'WRONG_CONFIG',
79             "%s %s: %s", 'media_info', $var, $_
80             );
81             }
82             }
83 0         0 foreach my $media ($self->listmedia()) {
84 0         0 foreach my $var ($self->{cfg}->Parameters($media)) {
85 0 0       0 $self->{cfg}->val($media, $var) or next;
86 0         0 my @er = MDV::Distribconf::MediaCFG::_valid_param(
87             'media_info',
88             $var,
89             $self->getvalue($media, $var),
90             );
91 0         0 foreach (@er) {
92 0         0 $error += _report_err(
93             $fhout,
94             'WRONG_CONFIG',
95             "%s %s: %s", $media, $var, $_
96             );
97             }
98 0   0     0 my $varinfo = MDV::Distribconf::MediaCFG::_value_info($var) || {};
99 0 0       0 if ($varinfo->{deny}) {
100 0 0       0 if ($self->getvalue($media, $varinfo->{deny})) {
101             $error += _report_err(
102             $fhout,
103             'WRONG_CONFIG',
104             '%s and %s cannot be set together (media %s)',
105 0         0 $var, $varinfo->{deny}, $media
106             );
107             }
108             }
109 0 0 0     0 if ($varinfo->{ismedialist} || $varinfo->{cross}) {
110 0         0 foreach my $sndmedia (split(/ /, $self->getvalue($media, $var, ''))) {
111 0 0       0 if (!$self->mediaexists($sndmedia)) {
    0          
112 0         0 $error += _report_err(
113             $fhout,
114             'MISSING_MEDIA',
115             "`%s' refer as %s to non existant `%s'",
116             $media,
117             $var,
118             $sndmedia,
119             );
120             } elsif($varinfo->{cross}) {
121 0 0       0 if(!grep { $media eq $_ }
  0         0  
122             split(/ /,
123             $self->getvalue($sndmedia, $varinfo->{cross})
124             )) {
125             $error += _report_err(
126             $fhout,
127             'WRONG_CONFIG',
128             "`%s' has not `%s' as %s",
129             $sndmedia, $media, $varinfo->{cross},
130 0         0 );
131             }
132             }
133             }
134             }
135             }
136             }
137              
138             # checking overlap
139             {
140 0         0 my %foundname;
  0         0  
141 0         0 push(@{$foundname{$self->getvalue($_, 'name')}}, $_)
142 0         0 foreach($self->listmedia());
143              
144 0         0 foreach (keys %foundname) {
145 0 0       0 if (@{$foundname{$_}} > 1) {
  0         0  
146             $error += _report_err(
147             $fhout,
148             'WRONG_CONFIG',
149             "`%s' have same name (%s)",
150 0         0 join(', ', @{$foundname{$_}}),
  0         0  
151             $_,
152             );
153             }
154             }
155             }
156              
157             $error
158 0         0 }
159             =item $distrib->check_media_coherency($fhout)
160              
161             Performs basic checks on the distribution and prints to $fhout (STDERR by
162             default) warnings and errors found. Returns the number of errors reported.
163              
164             =cut
165              
166             sub check_media_coherency {
167 0     0 0 0 my ($distrib, $fhout) = @_;
168 0   0     0 $fhout ||= \*STDERR;
169              
170 0         0 my $error = 0;
171              
172 0 0       0 $distrib->listmedia or $error += _report_err(
173             'NOMEDIA', "No media found in this config"
174             );
175              
176             # Checking no overlap
177 0         0 foreach my $var (qw/hdlist synthesis path/) {
178 0         0 my %e;
179 0         0 foreach ($distrib->listmedia) {
180 0         0 my $v = $distrib->getpath($_, $var);
181 0         0 push @{$e{$v}}, $_;
  0         0  
182             }
183              
184 0         0 foreach my $key (keys %e) {
185 0 0       0 if (@{$e{$key}} > 1) {
  0         0  
186             $error += _report_err(
187             $fhout,
188             'SAME_INDEX',
189             "media `%s' have same %s (%s)",
190 0         0 join (", ", @{$e{$key}}),
  0         0  
191             $var,
192             $key
193             );
194             }
195             }
196             }
197              
198 0         0 foreach my $media ($distrib->listmedia) {
199 0 0       0 -d $distrib->getfullpath($media, 'path') or $error += _report_err(
200             $fhout,
201             'MISSING_MEDIADIR', "dir %s doesn't exist for media `%s'",
202             $distrib->getpath($media, 'path'),
203             $media
204             );
205 0         0 foreach (qw/hdlist synthesis MD5SUM/) {
206 0 0       0 -f $distrib->getfullmediapath($media, $_) or $error += _report_err(
207             $fhout,
208             'MISSING_INDEX', "$_ %s doesn't exist for media `%s'",
209             $distrib->getmediapath($media, $_),
210             $media
211             );
212 0 0       0 /^MD5SUM$/ and next;
213 0 0       0 -f $distrib->getfullpath($media, $_) or $error += _report_err(
214             $fhout,
215             'MISSING_INDEX', "$_ %s doesn't exist for media `%s'",
216             $distrib->getpath($media, $_),
217             $media
218             );
219             }
220 0 0       0 if ($distrib->getvalue($media, 'xml-info')) {
221 0         0 foreach (qw/info files changelog/) {
222 0 0       0 -f $distrib->getfulldpath($media, $_) or $error += _report_err(
223             $fhout,
224             'MISSING_INDEX', "$_ %s doesn't exist for media `%s'",
225             $distrib->getfulldpath($media, $_),
226             $media
227             );
228             }
229             }
230 0         0 foreach (qw/pubkey/) {
231 0 0       0 -f $distrib->getfullpath($media, $_) or $error += _report_err(
232             $fhout,
233             'MISSING_INFO', "$_ %s doesn't exist for media `%s'",
234             $distrib->getpath($media, $_),
235             $media
236             );
237             }
238              
239             }
240 0         0 return $error;
241             }
242              
243             =item $distrib->check_index_sync($media)
244              
245             Check the synchronisation between rpms contained by media $media
246             and its hdlist:
247              
248             - all rpms should be in the hdlist
249             - the hdlist should not contains rpms that does not exists
250              
251             Return 1 if no problem were found
252              
253             =cut
254              
255             sub check_index_sync {
256 2     2 1 11 return (get_index_sync_offset(@_))[0]
257             }
258              
259             sub get_index_sync_offset {
260 2     2 0 7 my ($self, $media, $submedia) = @_;
261 2         16 my $rpmspath = $self->getfullpath($media, 'path');
262 2 50 33     13 my $hdlist = ($submedia && -d $self->getfullpath($media, 'path') . '/media_info') ?
263             $self->getfullmediapath($media, 'hdlist') :
264             $self->getfullpath($media, 'hdlist');
265 2 50 33     13 my $synthesis = ($submedia && -d $self->getfullpath($media, 'path') . '/media_info') ?
266             $self->getfullmediapath($media, 'synthesis') :
267             $self->getfullpath($media, 'synthesis');
268              
269 2 50 33     79 -f $hdlist && -f $synthesis or return 0; # avoid warnings
270 2         23 my ($inp, $ind) = MDV::Distribconf::Utils::hdlist_vs_dir($hdlist, $rpmspath);
271 2 50 66     122 if (!defined($inp) || (@{$inp || []} + @{$ind || []})) {
  2 50       8  
  2 100       10  
272 1 50       5 return (0, (defined($inp) ? scalar(@{$inp || []}) : undef), scalar(@{$ind || []}));
  1 50       5  
  1 50       8  
273             }
274 1         13 return (1, 0, 0);
275             }
276              
277             =item $distrib->check_media_md5($media)
278              
279             Check md5sum for hdlist and synthesis for the media $media are the same
280             than value contains in the existing MD5SUM file.
281              
282             The function return an error also if the value is missing
283              
284             Return 1 if no error were found.
285              
286             =cut
287              
288             sub check_media_md5 {
289 2     2 1 7 my ($self, $media) = @_;
290 2         6 my @indexes = map { $self->getfullmediapath($media, $_) } (qw(hdlist synthesis));
  4         17  
291 2 50 33     7 if ($self->getvalue($media, 'xml-info') && !$self->getvalue($media, 'cdmode')) {
292 0         0 push(@indexes, map { $self->getfullmediapath($media, $_) }
  0         0  
293             (qw(info files changelog)));
294             }
295 2         8 my ($unsync) = MDV::Distribconf::Utils::checkmd5(
296             $self->getfullmediapath($media, 'MD5SUM'),
297             @indexes
298             );
299 2 50       7 if (@{$unsync || []}) {
  2 100       11  
300 1         7 return 0;
301             } else {
302 1         7 return 1;
303             }
304             }
305              
306             sub check_global_md5 {
307 0     0 0   my ($self) = @_;
308 0           my @indexes;
309 0           foreach my $media ($self->listmedia()) {
310             push(
311             @indexes,
312 0           map { $self->getfulldpath($media, $_) } (qw(hdlist synthesis))
  0            
313             );
314 0 0 0       if ($self->getvalue($media, 'xml-info') && $self->getvalue($media, 'cdmode')) {
315             push(
316             @indexes,
317 0           map { $self->getfulldpath($media, $_) } (qw(info files changelog))
  0            
318             );
319             }
320             }
321            
322 0           my ($unsync) = MDV::Distribconf::Utils::checkmd5(
323             $self->getfullpath(undef, 'MD5SUM'),
324             @indexes,
325             );
326 0 0         if (@{$unsync || []}) {
  0 0          
327 0           return 0;
328             } else {
329 0           return 1;
330             }
331             }
332              
333             =item $distrib->checkdistrib($fhout)
334              
335             Performs all light checks on the distribution and prints to $fhout (STDERR by
336             default) warnings and errors found. Returns the number of errors reported.
337              
338             =cut
339              
340             sub checkdistrib {
341 0     0 1   my ($self, $fhout) = @_;
342 0   0       $fhout ||= \*STDERR;
343              
344 0           my $error = 0;
345              
346 0           $error += $self->check_config($fhout);
347 0           $error += $self->check_media_coherency($fhout);
348              
349 0           foreach my $media ($self->listmedia) {
350 0           my ($e, $inhd, $indir) = $self->get_index_sync_offset($media);
351 0 0         if (!$e) {
352 0 0 0       $error += _report_err(
353             $fhout,
354             'UNSYNC_HDLIST',
355             "hdlist for media `%s' is not sync with its rpms" .
356             (defined($inhd) ? " (+%d -%d rpms)" : ' (missing or unreadable hdlist: +%d rpms)'),
357             $media, ($indir || 0), $inhd
358             );
359             }
360              
361 0 0         if(!$self->check_media_md5($media)) {
362 0           $error += _report_err(
363             $fhout,
364             'UNSYNC_MD5',
365             "md5sum for media `%s' is not ok",
366             $media,
367             );
368             }
369             }
370              
371 0 0         if (!$self->check_global_md5()) {
372 0           $error += _report_err(
373             $fhout,
374             'UNSYNC_MD5',
375             'Global md5sum file is not ok',
376             );
377             }
378            
379             $error
380 0           }
381              
382             =item $distrib->check($fhout)
383              
384             =cut
385              
386             sub check {
387 0     0 1   my ($self, $fhout) = @_;
388 0   0       $fhout ||= \*STDERR;
389              
390 0           my $error = $self->check_config($fhout);
391 0           $error += $self->check_media_coherency($fhout);
392              
393 0           $error
394             }
395              
396             1;
397              
398             __END__