File Coverage

blib/lib/MDV/Distribconf/Checks.pm
Criterion Covered Total %
statement 48 140 34.2
branch 15 70 21.4
condition 8 35 22.8
subroutine 11 17 64.7
pod 6 9 66.6
total 88 271 32.4


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   872 use strict;
  3         6  
  3         115  
18 3     3   18 use warnings;
  3         6  
  3         110  
19 3     3   1666 use MDV::Distribconf::MediaCFG;
  3         9  
  3         95  
20 3     3   1179 use MDV::Packdrakeng;
  3         15534  
  3         86  
21 3     3   25 use Digest::MD5;
  3         6  
  3         148  
22 3     3   1844 use MDV::Distribconf::Utils;
  3         9  
  3         108  
23 3     3   24 use base qw(MDV::Distribconf);
  3         7  
  3         5694  
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   607 my ($out, $err_code, $fmt, @args) = @_;
33 1         12 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       5 if (ref $out eq 'CODE') {
47 1   50     15 $out->(
      50        
48             errcode => $err_code || '?',
49             level => $errs{$err_code} || '?',
50             message => $message,
51             );
52             } else {
53 0   0     0 printf $out "%s: %s\n", $errs{$err_code} || '?', $message;
54             }
55 1 50 50     1225 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 0         0 my @er = MDV::Distribconf::MediaCFG::_valid_param(
71             'media_info',
72             $var,
73             $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 0         0 $error += _report_err(
102             $fhout,
103             'WRONG_CONFIG',
104             '%s and %s cannot be set together (media %s)',
105             $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 0         0 $error += _report_err(
126             $fhout,
127             'WRONG_CONFIG',
128             "`%s' has not `%s' as %s",
129             $sndmedia, $media, $varinfo->{cross},
130             );
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 0         0 $error += _report_err(
147             $fhout,
148             'WRONG_CONFIG',
149             "`%s' have same name (%s)",
150 0         0 join(', ', @{$foundname{$_}}),
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 0         0 $error += _report_err(
187             $fhout,
188             'SAME_INDEX',
189             "media `%s' have same %s (%s)",
190 0         0 join (", ", @{$e{$key}}),
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 does'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 foreach (qw/pubkey/) {
221 0 0       0 -f $distrib->getfullpath($media, $_) or $error += _report_err(
222             $fhout,
223             'MISSING_INFO', "$_ %s doesn't exist for media `%s'",
224             $distrib->getpath($media, $_),
225             $media
226             );
227             }
228              
229             }
230 0         0 return $error;
231             }
232              
233             =item $distrib->check_index_sync($media)
234              
235             Check the synchronisation between rpms contained by media $media
236             and its hdlist:
237              
238             - all rpms should be in the hdlist
239             - the hdlist should not contains rpms that does not exists
240              
241             Return 1 if no problem were found
242              
243             =cut
244              
245             sub check_index_sync {
246 2     2 1 9 return (get_index_sync_offset(@_))[0]
247             }
248              
249             sub get_index_sync_offset {
250 2     2 0 4 my ($self, $media, $submedia) = @_;
251 2         15 my $rpmspath = $self->getfullpath($media, 'path');
252 2 50 33     11 my $hdlist = ($submedia && -d $self->getfullpath($media, 'path') . '/media_info') ?
253             $self->getfullmediapath($media, 'hdlist') :
254             $self->getfullpath($media, 'hdlist');
255 2 50 33     10 my $synthesis = ($submedia && -d $self->getfullpath($media, 'path') . '/media_info') ?
256             $self->getfullmediapath($media, 'synthesis') :
257             $self->getfullpath($media, 'synthesis');
258              
259 2 50 33     91 -f $hdlist && -f $synthesis or return 0; # avoid warnings
260 2         10 my ($inp, $ind) = MDV::Distribconf::Utils::hdlist_vs_dir($hdlist, $rpmspath);
261 2 50 66     91 if (!defined($inp) || (@{$inp || []} + @{$ind || []})) {
  2 50       6  
  2 100       11  
262 1 50       2 return (0, (defined($inp) ? scalar(@{$inp || []}) : undef), scalar(@{$ind || []}));
  1 50       31  
  1 50       8  
263             }
264 1         12 return (1, 0, 0);
265             }
266              
267             =item $distrib->check_media_md5($media)
268              
269             Check md5sum for hdlist and synthesis for the media $media are the same
270             than value contains in the existing MD5SUM file.
271              
272             The function return an error also if the value is missing
273              
274             Return 1 if no error were found.
275              
276             =cut
277              
278             sub check_media_md5 {
279 2     2 1 3 my ($self, $media) = @_;
280 4         10 my ($unsync) = MDV::Distribconf::Utils::checkmd5(
281             $self->getfullmediapath($media, 'MD5SUM'),
282 2         13 map { $self->getfullmediapath($media, $_) } (qw(hdlist synthesis))
283             );
284 2 50       6 if (@{$unsync || []}) {
  2 100       9  
285 1         5 return 0;
286             } else {
287 1         4 return 1;
288             }
289             }
290              
291             sub check_global_md5 {
292 0     0 0   my ($self) = @_;
293 0           my @indexes;
294 0           foreach my $media ($self->listmedia()) {
295 0           push(@indexes, map { $self->getfullpath($media, $_) } (qw(hdlist synthesis)));
  0            
296             }
297 0           my ($unsync) = MDV::Distribconf::Utils::checkmd5(
298             $self->getfullpath(undef, 'MD5SUM'),
299             @indexes,
300             );
301 0 0         if (@{$unsync || []}) {
  0 0          
302 0           return 0;
303             } else {
304 0           return 1;
305             }
306             }
307              
308             =item $distrib->checkdistrib($fhout)
309              
310             Performs all light checks on the distribution and prints to $fhout (STDERR by
311             default) warnings and errors found. Returns the number of errors reported.
312              
313             =cut
314              
315             sub checkdistrib {
316 0     0 1   my ($self, $fhout) = @_;
317 0   0       $fhout ||= \*STDERR;
318              
319 0           my $error = 0;
320              
321 0           $error += $self->check_config($fhout);
322 0           $error += $self->check_media_coherency($fhout);
323              
324 0           foreach my $media ($self->listmedia) {
325 0           my ($e, $inhd, $indir) = $self->get_index_sync_offset($media);
326 0 0         if (!$e) {
327 0 0 0       $error += _report_err(
328             $fhout,
329             'UNSYNC_HDLIST',
330             "hdlist for media `%s' is not sync with its rpms" .
331             (defined($inhd) ? " (+%d -%d rpms)" : ' (missing or unreadable hdlist: +%d rpms)'),
332             $media, ($indir || 0), $inhd
333             );
334             }
335              
336 0 0         if(!$self->check_media_md5($media)) {
337 0           $error += _report_err(
338             $fhout,
339             'UNSYNC_MD5',
340             "md5sum for media `%s' is not ok",
341             $media,
342             );
343             }
344             }
345              
346 0 0         if (!$self->check_global_md5()) {
347 0           $error += _report_err(
348             $fhout,
349             'UNSYNC_MD5',
350             'Global md5sum file is not ok',
351             );
352             }
353            
354             $error
355 0           }
356              
357             =item $distrib->check($fhout)
358              
359             =cut
360              
361             sub check {
362 0     0 1   my ($self, $fhout) = @_;
363 0   0       $fhout ||= \*STDERR;
364              
365 0           my $error = $self->check_config($fhout);
366 0           $error += $self->check_media_coherency($fhout);
367              
368 0           $error
369             }
370              
371             1;
372              
373             __END__