comparison archiver.pl @ 11:b19df18aa19a

updated command line option parsing and logging
author casties
date Wed, 23 Mar 2005 13:12:08 +0100
parents 1a377102b1ce
children fdf4ceb36db1
comparison
equal deleted inserted replaced
10:4417be0e2f07 11:b19df18aa19a
14 ####################################################### 14 #######################################################
15 # internal parameters 15 # internal parameters
16 # 16 #
17 17
18 # program version 18 # program version
19 my $version = "0.5.2 (12.7.2004)"; 19 my $version = "0.6 (ROC 23.3.2005)";
20
21 # short help
22 my $shorthelp = "MPIWG archiver $version\nuse:\n archiver [options] docpath\noptions:\n -premigrate don't delete archived files\n";
23
24 # read command line parameters
25 my $args = MPIWGStor::parseargs;
26
27 # debug level
28 my $debug = (exists $$args{'debug'}) ? $$args{'debug'} : 0;
20 29
21 # rewrite XML file (necessary for archive date!) 30 # rewrite XML file (necessary for archive date!)
22 my $fix_xml = 1; 31 my $fix_xml = 1;
23 my $xml_changed = 0; 32 my $xml_changed = 0;
24 # XML namespace (not really implemented!) 33 # XML namespace (not really implemented!)
39 ####################################################### 48 #######################################################
40 # external programs 49 # external programs
41 # 50 #
42 my $archprog = "/opt/tivoli/tsm/client/ba/bin/dsmc"; 51 my $archprog = "/opt/tivoli/tsm/client/ba/bin/dsmc";
43 if (! -x $archprog) { 52 if (! -x $archprog) {
44 print "ABORT: TSM client program '$archprog' missing!!\n"; 53 logger('ABORT', "TSM client program '$archprog' missing!!\n");
45 exit 1; 54 exit 1;
46 } 55 }
47 my $checkprog = "/usr/local/mpiwg/archive/metacheck"; 56 my $checkprog = "/usr/local/mpiwg/archive/metacheck";
48 if (! -x $checkprog) { 57 if (! -x $checkprog) {
49 print "ABORT: meta data checking program '$checkprog' missing!!\n"; 58 logger('ABORT', "meta data checking program '$checkprog' missing!!\n");
50 exit 1; 59 exit 1;
51 } 60 }
52 # log file for archiver 61 # log file for archiver
53 my $log_file = "/var/log/mpiwg-archiver.log"; 62 my $log_file = "/var/log/mpiwg-archiver.log";
54 if (! open LOG, ">>$log_file") { 63 if (! open LOG, ">>$log_file") {
55 print "ABORT: unable to write log file '$log_file'!!\n"; 64 logger('ABORT', "unable to write log file '$log_file'!!\n");
56 exit 1; 65 exit 1;
57 } 66 }
58 67
59 ####################################################### 68 #######################################################
60 # check parameters that were passed to the program 69 # check parameters that were passed to the program
61 # 70 #
62 if ($#ARGV < 0) { 71 if ($#ARGV < 0) {
63 print "ABORT: no document directory given!\n"; 72 print $shorthelp;
64 exit 1; 73 exit 1;
65 } 74 }
66 my $docdir = $ARGV[0]; 75 my $docdir = $$args{'path'};
67 # strip double slashes 76 # strip double slashes
68 $docdir =~ s/\/\//\//; 77 $docdir =~ s/\/\//\//;
69 # strip trailing slashes 78 # strip trailing slashes
70 $docdir =~ s/\/+$//; 79 $docdir =~ s/\/+$//;
71 if (! -d $docdir) { 80 if (! -d $docdir) {
72 print "ABORT: document directory \'$docdir\' doesn't exist!\n"; 81 logger('ABORT', "document directory \'$docdir\' doesn't exist!\n");
73 exit 1; 82 exit 1;
74 } 83 }
75 if (($#ARGV > 0)&&($ARGV[1] eq "-premigrate")) { 84 # don't delete archived files with "-premigrate"
76 $delete_data_files = 0; 85 if (exists $$args{'premigrate'}) {
86 $delete_data_files = not $$args{'premigrate'};
87 }
88 if ($delete_data_files) {
89 logger('INFO', "going to remove successfully archived files from disk");
77 } 90 }
78 91
79 my $metafile = "$docdir/index.meta"; 92 my $metafile = "$docdir/index.meta";
80 if (! -f $metafile) { 93 if (! -f $metafile) {
81 print "ABORT: metadata index file \'$metafile\' doesn't exist!\n"; 94 logger('ABORT', "metadata index file \'$metafile\' doesn't exist!\n");
82 exit 1; 95 exit 1;
83 } 96 }
84 97
85 ####################################################### 98 #######################################################
86 # internal variables 99 # internal variables
107 # archive path 120 # archive path
108 # 121 #
109 # get archive-path 122 # get archive-path
110 $archname = MPIWGStor::sstrip($rootnode->findvalue('child::archive-path')); 123 $archname = MPIWGStor::sstrip($rootnode->findvalue('child::archive-path'));
111 if (! $archname) { 124 if (! $archname) {
112 print "ABORT: archive-name element missing!!\n"; 125 logger('ABORT', "archive-name element missing!!\n");
113 exit 1; 126 exit 1;
114 } 127 }
115 128
116 # 129 #
117 # files 130 # files
118 # 131 #
119 my @filenodes = $rootnode->findnodes('child::file'); 132 my @filenodes = $rootnode->findnodes('child::file');
120 foreach my $fn (@filenodes) { 133 foreach my $fn (@filenodes) {
121 my $name = MPIWGStor::sstrip($fn->findvalue('child::name')); 134 my $name = MPIWGStor::sstrip($fn->findvalue('child::name'));
122 my $path = MPIWGStor::sstrip($fn->findvalue('child::path')); 135 my $path = MPIWGStor::sstrip($fn->findvalue('child::path'));
123 print "FILE: ($path)$name\n"; 136 logger('DEBUG', "FILE ($path)$name\n");
124 my $f = ($path) ? "$path/$name" : "$name"; 137 my $f = ($path) ? "$path/$name" : "$name";
125 $files{$f} = $name; 138 $files{$f} = $name;
126 } 139 }
127 140
128 # 141 #
129 # archive-storage-date 142 # archive-storage-date
130 # 143 #
131 my $stordatenode = ($rootnode->find('child::archive-storage-date'))->get_node(1); 144 my $stordatenode = ($rootnode->find('child::archive-storage-date'))->get_node(1);
132 if ($stordatenode) { 145 if ($stordatenode) {
133 print "WARNING: archive storage date exists! Resource already archived?\n"; 146 logger('WARNING', "archive storage date exists! Resource already archived?\n");
134 $warncnt++; 147 $warncnt++;
135 # delete old date 148 # delete old date
136 $stordatenode->removeChildNodes; 149 $stordatenode->removeChildNodes;
137 } else { 150 } else {
138 # create new storage date node 151 # create new storage date node
171 if (/^Archive processing of .* finished without failure./) { 184 if (/^Archive processing of .* finished without failure./) {
172 print " ARCH: OK\n"; 185 print " ARCH: OK\n";
173 } 186 }
174 } 187 }
175 } else { 188 } else {
176 print "ABORT: unable to start archive command '$archcmd'!!\n"; 189 logger('ABORT', "unable to start archive command '$archcmd'!!\n");
177 exit 1; 190 exit 1;
178 } 191 }
179 192
180 return \%files; 193 return \%files;
181 } 194 }
194 207
195 foreach my $ft (sort keys %$to_archive) { 208 foreach my $ft (sort keys %$to_archive) {
196 my $fp = "$docdir/$ft"; 209 my $fp = "$docdir/$ft";
197 #print " fp: $fp\n"; 210 #print " fp: $fp\n";
198 if ($$archived{$fp}) { 211 if ($$archived{$fp}) {
199 print "DEBUG: $ft archived OK\n"; 212 logger('DEBUG', "$ft archived OK\n");
200 $$archived{$fp} = "OK"; 213 $$archived{$fp} = "OK";
201 } else { 214 } else {
202 print "ERROR: file '$ft' missing from archive!\n"; 215 logger('ERROR', "file '$ft' missing from archive!\n");
203 $errcnt++; 216 $errcnt++;
204 } 217 }
205 } 218 }
206 219
207 foreach my $fa (sort keys %$archived) { 220 foreach my $fa (sort keys %$archived) {
208 if ($$archived{$fa} ne "OK") { 221 if ($$archived{$fa} ne "OK") {
209 my ($fn, $fp) = MPIWGStor::split_file_path($fa); 222 my ($fn, $fp) = MPIWGStor::split_file_path($fa);
210 if ($MPIWGStor::index_files{$fn}) { 223 if ($MPIWGStor::index_files{$fn}) {
211 print "DEBUG: $fa ignored\n"; 224 logger('DEBUG', "$fa ignored\n");
212 $na--; 225 $na--;
213 } else { 226 } else {
214 print "WARNING: $fa archived but not in list!\n"; 227 logger('WARNING', "$fa archived but not in list!\n");
215 $warncnt++; 228 $warncnt++;
216 } 229 }
217 } 230 }
218 } 231 }
219 232
220 if ($nt > $na) { 233 if ($nt > $na) {
221 print "WARNING: less files were archived ($na vs. $nt)!\n"; 234 logger('WARNING', "less files were archived ($na vs. $nt)!\n");
222 } elsif ($na > $nt) { 235 } elsif ($na > $nt) {
223 print "WARNING: more files were archived ($na vs. $nt)!\n"; 236 logger('WARNING', "more files were archived ($na vs. $nt)!\n");
224 } 237 }
225 238
226 } 239 }
227 240
228 241
246 next if ($MPIWGStor::index_files{$fn}); 259 next if ($MPIWGStor::index_files{$fn});
247 # no file no delete 260 # no file no delete
248 next unless (-f $f); 261 next unless (-f $f);
249 # delete files 262 # delete files
250 if (unlink $f) { 263 if (unlink $f) {
251 print "INFO: remove $f ($fn)\n"; 264 logger('INFO', "remove $f ($fn)\n");
252 } else { 265 } else {
253 print "ERROR: unable to delete $f!\n"; 266 logger('ERROR', "unable to delete $f!\n");
254 $errcnt++; 267 $errcnt++;
255 } 268 }
256 } 269 }
257 # try to delete all empty directories 270 # try to delete all empty directories
258 my @dirkeys = sort keys %dirs; 271 my @dirkeys = sort keys %dirs;
260 for (my $i = $#dirkeys; $i >= 0; $i--) { 273 for (my $i = $#dirkeys; $i >= 0; $i--) {
261 my $d = $dirkeys[$i]; 274 my $d = $dirkeys[$i];
262 # dont't remove document dir (shouldn't be empty anyway) 275 # dont't remove document dir (shouldn't be empty anyway)
263 next if ($d eq $docdir); 276 next if ($d eq $docdir);
264 if (-d $d) { 277 if (-d $d) {
265 print "INFO: remove dir $d\n"; 278 logger('INFO', "remove dir $d\n");
266 rmdir $d; 279 rmdir $d;
267 } 280 }
268 } 281 }
269 } 282 }
270 283
277 # 290 #
278 sub delete_all_files { 291 sub delete_all_files {
279 my ($files, $dir) = @_; 292 my ($files, $dir) = @_;
280 293
281 if (! opendir DIR, $dir) { 294 if (! opendir DIR, $dir) {
282 print "ERROR: unable to read directory $dir!\n"; 295 logger('ERROR', "unable to read directory $dir!\n");
283 $errcnt++; 296 $errcnt++;
284 return; 297 return;
285 } 298 }
286 my @fl = readdir DIR; 299 my @fl = readdir DIR;
287 closedir DIR; 300 closedir DIR;
291 if ($$files{$f}) { 304 if ($$files{$f}) {
292 # $f is in the file list 305 # $f is in the file list
293 if (-f "$dir/$f") { 306 if (-f "$dir/$f") {
294 # $f is a file 307 # $f is a file
295 if (unlink "$dir/$f") { 308 if (unlink "$dir/$f") {
296 print "INFO: removed $f\n"; 309 logger('INFO', "removed $f\n");
297 } else { 310 } else {
298 print "ERROR: unable to delete $f!\n"; 311 logger('ERROR', "unable to delete $f!\n");
299 $errcnt++; 312 $errcnt++;
300 } 313 }
301 } elsif (-d _) { 314 } elsif (-d _) {
302 # $f is a directory (unlink won't work) 315 # $f is a directory (unlink won't work)
303 if ((system 'rm', '-r', "$dir/$f") == 0) { 316 if ((system 'rm', '-r', "$dir/$f") == 0) {
304 print "INFO: removed directory $f\n"; 317 logger('INFO', "removed directory $f\n");
305 } else { 318 } else {
306 print "ERROR: unable to delete directory $f!\n"; 319 logger('ERROR', "unable to delete directory $f!\n");
307 $errcnt++; 320 $errcnt++;
308 } 321 }
309 } else { 322 } else {
310 print "ERROR: funny object $dir/$f!\n"; 323 logger('ERROR', "funny object $dir/$f!\n");
311 $errcnt++; 324 $errcnt++;
312 } 325 }
313 } else { 326 } else {
314 # $f is not in the list 327 # $f is not in the list
315 if (-d "$dir/$f") { 328 if (-d "$dir/$f") {
316 # recurse into directories 329 # recurse into directories
317 print "DEBUG: enter $dir/$f\n"; 330 logger('DEBUG', "enter $dir/$f\n");
318 delete_all_files($files, "$dir/$f"); 331 delete_all_files($files, "$dir/$f");
319 } 332 }
320 } 333 }
321 } 334 }
322 } 335 }
324 337
325 ####################################################### 338 #######################################################
326 # main 339 # main
327 # 340 #
328 341
329 print "START: archiver $version at $archdate\n"; 342 logger('START', "archiver $version at $archdate\n");
330 343
331 # make shure the right user is running this program 344 # make shure the right user is running this program
332 my $user = getlogin; 345 my $user = getlogin;
333 #if (($user ne "archive")||($user ne "root")) { 346 #if (($user ne "archive")||($user ne "root")) {
334 # logger("ABORT", "you ($user) must be archive or root user to run this program!"); 347 # logger("ABORT", "you ($user) must be archive or root user to run this program!");
335 # exit 1; 348 # exit 1;
336 #} 349 #}
337 350
338 # use metacheck first 351 # use metacheck first
339 if (system("$checkprog $docdir >/dev/null") == 0) { 352 if (system("$checkprog $docdir >/dev/null") == 0) {
340 print "INFO: resource '$docdir' check OK\n"; 353 logger('INFO', "resource '$docdir' check OK\n");
341 } else { 354 } else {
342 print "ABORT: resource '$docdir' check failed!!\n"; 355 logger('ABORT', "resource '$docdir' check failed!!\n");
343 exit 1; 356 exit 1;
344 } 357 }
345 358
346 # read index.meta file 359 # read index.meta file
347 my ($document, $rootnode) = MPIWGStor::read_xml($metafile); 360 my ($document, $rootnode) = MPIWGStor::read_xml($metafile);
352 print "INFO: ", scalar keys %$files_to_archive, " files to archive\n"; 365 print "INFO: ", scalar keys %$files_to_archive, " files to archive\n";
353 366
354 # check for .archived file 367 # check for .archived file
355 if (-f "$docdir/.archived") { 368 if (-f "$docdir/.archived") {
356 if (unlink "$docdir/.archived") { 369 if (unlink "$docdir/.archived") {
357 print "WARNING: existing .archived file has been removed! Resource already archived?\n"; 370 logger('WARNING', "existing .archived file has been removed! Resource already archived?\n");
358 $warncnt++; 371 $warncnt++;
359 } else { 372 } else {
360 print "ERROR: unable to remove existing .archived file!\n"; 373 logger('ERROR', "unable to remove existing .archived file!\n");
361 $errcnt++; 374 $errcnt++;
362 } 375 }
363 } 376 }
364 377
365 # remove junk files 378 # remove junk files
367 delete_all_files(\%MPIWGStor::junk_files, $docdir); 380 delete_all_files(\%MPIWGStor::junk_files, $docdir);
368 } 381 }
369 382
370 # write new index.meta 383 # write new index.meta
371 if ($errcnt > 0) { 384 if ($errcnt > 0) {
372 print "ABORT: there were errors!\n"; 385 logger('ABORT', "there were errors!\n");
373 exit 1; 386 exit 1;
374 } else { 387 } else {
375 if ($fix_xml) { 388 if ($fix_xml) {
376 MPIWGStor::write_xml($document, $metafile); 389 MPIWGStor::write_xml($document, $metafile);
377 } 390 }
379 392
380 # start archiving 393 # start archiving
381 my $archived_files = run_archive(); 394 my $archived_files = run_archive();
382 my $num_archfiles = scalar keys %$archived_files; 395 my $num_archfiles = scalar keys %$archived_files;
383 396
384 print "INFO: $num_archfiles files archived\n"; 397 logger('INFO', "$num_archfiles files archived\n");
385 398
386 # check list of archived files 399 # check list of archived files
387 check_files($files_to_archive, $archived_files); 400 check_files($files_to_archive, $archived_files);
388 401
389 # delete files if all went OK 402 # delete files if all went OK
397 if ($delete_data_files) { 410 if ($delete_data_files) {
398 delete_files($archived_files); 411 delete_files($archived_files);
399 } 412 }
400 } 413 }
401 414
402 print "INFO: $warncnt warnings\n"; 415 logger('INFO', "$warncnt warnings\n");
403 print "INFO: $errcnt errors\n"; 416 logger('INFO', "$errcnt errors\n");
404 if ($errcnt > 0) { 417 if ($errcnt > 0) {
405 print "ABORT: there were errors! ($num_archfiles files archived) at ", stime(time), "\n"; 418 logger('ABORT', "there were errors! ($num_archfiles files archived) at " . stime(time));
406 exit 1; 419 exit 1;
407 } else { 420 } else {
408 print "DONE: $num_archfiles files archived at ", stime(time), "\n"; 421 logger('DONE', "$num_archfiles files archived at " . stime(time));
409 } 422 }