Subversion Repositories DevTools

Rev

Rev 5212 | Rev 5231 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
5209 dpurdie 1
########################################################################
2
# Copyright (c) VIX TECHNOLOGY (AUST) LTD
3
#
4
# Module name   : jats_lxr.pl
5
# Module type   : JATS Utility
6
# Compiler(s)   : Perl
7
# Environment(s): jats
8
#
5213 dpurdie 9
# Description   : Tools to maintain LXR information
5209 dpurdie 10
#
5213 dpurdie 11
# Possible imporvements
12
#       Delete files we don't want to index
13
#           .DMP,.dmp,.so,.gz,.zip,.lib,.bz,.bz2,.tbz,.jar,.deb,.exe,.a,.msb
14
#
15
#       Merge ripples package versions
16
#           Just keep one
17
#
18
#       Cots packages
19
#           Use contents from dpkg_archive instead of the package
20
#
5209 dpurdie 21
# Usage         : See POD at the end of this file
22
#
23
#......................................................................#
24
 
25
require 5.008_002;
26
use strict;
27
use warnings;
28
 
29
use Pod::Usage;
30
use Getopt::Long;
31
use File::Path;
32
use FindBin;
33
use Socket;
5213 dpurdie 34
use Fcntl ':flock';
5209 dpurdie 35
 
36
use JatsError;
37
use JatsRmApi;
38
use DBI;
39
use JatsSystem;
40
use FileUtils;
41
 
42
#
43
#   Config Options
44
#
45
my $VERSION = "1.0.0";                      # Update this
46
my $opt_help = 0;
47
my $opt_verbose = $ENV{'GBE_VERBOSE'};      # Allow global verbose
48
my $opt_createVersions = 1;
49
my $opt_index = 1;
50
my $opt_purge = 1;
51
my $opt_extract = 1;
52
my $opt_logfile = 1;
5211 dpurdie 53
my $opt_config;
5209 dpurdie 54
 
55
 
56
#
57
#   Globals
58
#
59
my $scriptDir;
60
my $RM_DB;
5213 dpurdie 61
my $Config;
5209 dpurdie 62
my @addressList;
63
my %ReleaseData;
64
my %Packages;
65
my $PackageStore;
66
my $ReleaseStore;
5213 dpurdie 67
my $StampTime = time;
68
my $dateTag = localtime($StampTime);
69
my $lockFile = '/tmp/JATSLXR_LOCK';
5209 dpurdie 70
 
71
#-------------------------------------------------------------------------------
72
# Function        : Main
73
#
74
# Description     : Main entry point
75
#                   Parse user options
76
#
77
# Inputs          :
78
#
79
# Returns         :
80
#
81
 
82
my $result = GetOptions (
83
                "help:+"            => \$opt_help,              # flag, multiple use allowed
84
                "manual:3"          => \$opt_help,              # flag, multiple use allowed
85
                "verbose:+"         => \$opt_verbose,           # flag
86
                "createVersions!"   => \$opt_createVersions,
87
                "purge!"            => \$opt_purge,
88
                "index!"            => \$opt_index,
89
                "extract!"          => \$opt_extract,
5211 dpurdie 90
                "logfile!"          => \$opt_logfile,
91
                "config:s"          => \$opt_config,
5209 dpurdie 92
                );
93
 
94
#
95
#   Process help and manual options
96
#
97
pod2usage(-verbose => 0, -message => "Version: $VERSION")  if ($opt_help == 1  || ! $result);
98
pod2usage(-verbose => 1)  if ($opt_help == 2 );
99
pod2usage(-verbose => 2)  if ($opt_help > 2);
100
 
101
#
102
#   Capture all logging to a file
103
#   Could be done by the jats wrapper, but this way we can control its location
104
#
105
ErrorConfig( 'name'    => 'LXR',
106
             'verbose' => $opt_verbose );
107
 
108
#
109
#   Sanity test
110
#
111
 
112
$scriptDir = $FindBin::Bin;
113
InitFileUtils();
114
 
115
#
116
#   Read the tool configuration
5213 dpurdie 117
#   Sed with Default config
5209 dpurdie 118
#
5213 dpurdie 119
$Config->{'releaseAge'} = 0;
120
$Config->{'packageAge'} = 0;
121
$Config->{'logAge'} = 0;
122
$Config->{'verbose'} = 0;
5209 dpurdie 123
readConfig();
5213 dpurdie 124
Error ("No LXR Data directory defined", $Config->{lxrFiles}) unless( exists $Config->{lxrFiles});
125
Error ("No LXR Data directory found", $Config->{lxrFiles}) unless( -d $Config->{lxrFiles});
126
Error ("No LXR Install directory defined",$Config->{lxr}) unless( exists $Config->{lxr});
127
Error ("No LXR Install directory found",$Config->{lxr}) unless( -d $Config->{lxr});
128
ErrorConfig( 'verbose' => $Config->{'verbose'} );
5209 dpurdie 129
 
130
#
131
#   Start logging
132
#
133
startLogFile();
134
Message ("Start of LXR. " . localtime(time) ) if $opt_logfile;
135
Message("ScriptDir: $scriptDir");
136
 
137
#
5213 dpurdie 138
#   Prevent multiple instances of the program running
139
#
140
#   PerlMonks say to use $0 as the lock file, but that did not work.
141
#   Perhaps the file was open in an editor
142
#   Solution: Create my own file
143
#
144
open( FW, '>',$lockFile);
145
print FW '';
146
close FW;
147
 
148
open (my $self, '<', $lockFile)    || Error("Couldn't open self: $!");
149
flock ($self, (LOCK_EX | LOCK_NB)) || Error("This script is already running");
150
 
151
#
5209 dpurdie 152
#   Check required paths exist
153
#
5213 dpurdie 154
$PackageStore = catdir($Config->{lxrFiles}, 'Packages');
155
$ReleaseStore = catdir($Config->{lxrFiles}, 'Releases');
5209 dpurdie 156
mkpath($PackageStore);
157
mkpath($ReleaseStore);
158
Error ("Package Store not found ",$PackageStore) unless( -d $PackageStore);
159
Error ("Release Store not found ",$ReleaseStore) unless( -d $ReleaseStore);
160
 
161
#
162
#   Determine the various names for this machine
163
#   Include all the IP addresses too
164
#
165
my ($canonname, $aliases, $addrtype, $length, @addrs) = gethostbyname($ENV{GBE_HOSTNAME});
166
push @addressList, $canonname ;
167
push (@addressList, $aliases) if ($aliases) ;
168
push (@addressList, $ENV{GBE_HOSTNAME});
169
foreach ( @addrs) {
170
    push @addressList, inet_ntoa($_); 
171
}
172
Message("IpAddress: @addressList");
173
 
174
#
175
#   Perform the hard work
176
#
177
getReleaseData();
5213 dpurdie 178
updateReleaseViews() if $opt_createVersions;
5209 dpurdie 179
cleanReleaseViews();
5213 dpurdie 180
rebuildLxrConfig()  if $opt_index;
5209 dpurdie 181
buildIndexes() if $opt_index;
182
cleanPackageStore() if $opt_purge;
183
cleanupLogFiles() if $opt_purge;
184
 
185
#
186
#   All done
187
#
5213 dpurdie 188
unlink $lockFile;
5209 dpurdie 189
Message ("End of LXR. " . localtime(time) ) if $opt_logfile;
190
exit 0;
191
 
192
#-------------------------------------------------------------------------------
5212 dpurdie 193
# Function        : extractPackages 
5209 dpurdie 194
#
5212 dpurdie 195
# Description     : Extract Packages from VCS
5209 dpurdie 196
#                   Don't extract them if they already exist
5212 dpurdie 197
#   
198
#                   Kludge: Prevent extraction from MASS_Dev_Crypto Repo
5209 dpurdie 199
#
5213 dpurdie 200
# Inputs          : $rtagid         - Release To Process
201
#                                     Conatins PackageVersion data  
5209 dpurdie 202
#
203
# Returns         : 
204
#
5212 dpurdie 205
sub extractPackages
5209 dpurdie 206
{
5213 dpurdie 207
    my ($rtagid) = @_;
208
    foreach my $pvid (keys %{$ReleaseData{$rtagid}{data}})
5209 dpurdie 209
    {
210
        my $entry = $Packages{$pvid};
211
        #DebugDumpData("Entry", \$entry);
212
        my $fullName = join('_', $entry->{name}, $entry->{ver});
213
        my $fullPath = catfile($PackageStore , $fullName);
214
        next unless defined $entry->{vcs};
215
        next if ( $entry->{vcs} ) =~ m~^UC::~;
5211 dpurdie 216
        unless (-d $fullPath ) 
217
        {
5209 dpurdie 218
            Message("Need to extract: $entry->{name}, $entry->{ver}");
219
            if ($opt_extract)
220
            {
221
                Verbose0("Extracting into: $fullPath");
5212 dpurdie 222
                if ($entry->{vcs} =~ m~/MASS_Dev_Crypto/~)
5211 dpurdie 223
                {
224
                    print "$fullName : SUPPRESSED\n";
225
                }
226
                else
227
                {
228
                    my $rv = JatsCmd ('jats_vcsrelease', '-devmode=escrow', '-extractfiles', "-view=$fullName", "-label=$entry->{vcs}", "-root=$PackageStore", "-noprefix");
229
                    print "$fullName : SUCCESS\n" unless $rv;
230
                    print "$fullName : ERROR\n" if $rv;
231
                    $entry->{bad} = 1;
232
                }
5209 dpurdie 233
            }
234
        }
5211 dpurdie 235
        else
236
        {
237
            #   Package already extracted
238
            #   Ensure that it does not get aged out
239
            deleteAgeMarker($fullPath);
240
        }
5209 dpurdie 241
    }
242
}
243
 
244
#-------------------------------------------------------------------------------
5213 dpurdie 245
# Function        : updateReleaseViews 
5209 dpurdie 246
#
5213 dpurdie 247
# Description     : 
5209 dpurdie 248
#
249
# Inputs          : 
250
#
251
# Returns         : 
252
#
5213 dpurdie 253
sub updateReleaseViews
5209 dpurdie 254
{
255
    #
5213 dpurdie 256
    #   Process each known Release
5209 dpurdie 257
    #
5213 dpurdie 258
    foreach my $rtagid (sort keys \%ReleaseData)
5209 dpurdie 259
    {
5213 dpurdie 260
        if ($ReleaseData{$rtagid}{release}{ACTIVE})
5212 dpurdie 261
        {
5213 dpurdie 262
            #
263
            #   Determinte last created view in this Release
264
            #
265
            my ($latestView, $latestAge) = getLatestVersion(catdir($ReleaseStore, $rtagid ));
266
            if ( ! defined($latestView) || $latestAge > 1 )
5209 dpurdie 267
            {
268
                #
5213 dpurdie 269
                #   If there is no latest view, then we need to create a new view
270
                #   If there is a recent view, but its older than a day then we may need
271
                #   to refresh it.
5209 dpurdie 272
                #
5213 dpurdie 273
                getReleasePakageData($rtagid);
274
                if (checkViewDiffs($latestView,$rtagid) )
5209 dpurdie 275
                {
5213 dpurdie 276
                    #
277
                    #   Need to create a view
278
                    #       Either one does not exist
279
                    #       Content has changed
280
                    #
281
                    createReleaseView($rtagid);
5209 dpurdie 282
                }
5213 dpurdie 283
                else
284
                {
285
                    #   No need to create a new view
286
                    #   Do need to tag it so that we don't examine it again ( for a while )
287
                    Message("No Changes to LXR View: $rtagid");
288
                    if (defined $latestView)
289
                    {
290
                        my $rv = utime $StampTime,$StampTime, $latestView; 
291
                        Debug0("Utime $rv: $latestView");
292
                    }
293
                }
5209 dpurdie 294
            }
5213 dpurdie 295
            else
5209 dpurdie 296
            {
5213 dpurdie 297
                Message("Recent LXR View: $rtagid");
5209 dpurdie 298
            }
5213 dpurdie 299
        }
300
        else
301
        {
302
            Message("Inactive LXR View: $rtagid");
303
        }
304
    }
305
}
306
 
307
#-------------------------------------------------------------------------------
308
# Function        : checkViewDiffs 
309
#
310
# Description     : Check a view against the current package versions in the
311
#                   Release 
312
#
313
# Inputs          : $vdir       - View entry to process
314
#                   $rtagid     - RtagId
315
#
316
# Returns         : True, If we need to create a new view
317
#
318
sub checkViewDiffs
319
{
320
    my ($vdir, $rtagid) = @_;
321
 
322
    #   No entry to process, then we need to create a view
323
    return 1 if not defined $vdir;
324
 
325
    my %pkgsUsed;
326
    my $needNewView = 0;
327
 
328
    if (opendir (my $ldir, $vdir))
329
    {
330
        while (my $ldirEntry = readdir($ldir))
331
        {
332
            #   Skip hidden files
333
            next if ($ldirEntry =~ m~^\.~);
334
            my $dirName = catdir($vdir, $ldirEntry );
335
 
5209 dpurdie 336
            #
5213 dpurdie 337
            #   Process each entry within the Version
5209 dpurdie 338
            #
5213 dpurdie 339
            my $pkgName = $ldirEntry;
340
            if (-l $dirName)
5209 dpurdie 341
            {
5213 dpurdie 342
                $pkgName = readlink($dirName);
343
                $pkgName =~ s~.*/~~;
5209 dpurdie 344
            }
5213 dpurdie 345
            $pkgsUsed{$pkgName} = 2;
5209 dpurdie 346
        }
5213 dpurdie 347
        close ($ldir);
5209 dpurdie 348
 
5213 dpurdie 349
        #
350
        #   Compare Package-Versions against those we need
351
        # 
352
        foreach my $pvid (keys %{$ReleaseData{$rtagid}{data}})
5209 dpurdie 353
        {
5213 dpurdie 354
            my $entry = $Packages{$pvid};
355
            my $fullName = join('_', $entry->{name}, $entry->{ver});
356
            $pkgsUsed{$fullName}++;
5209 dpurdie 357
        }
5213 dpurdie 358
 
359
        #
360
        #   Scan the pkgUsed
361
        #   A value of 1 indicates that it is used only in the New Version
362
        #   A value of 2 indicates that it is only used on the Last Version
363
        #   A value of 3 indicates that its used in both
364
        #   Detect those that are not a 3
365
        #
366
        foreach ( keys %pkgsUsed)
5209 dpurdie 367
        {
5213 dpurdie 368
            if ($pkgsUsed{$_} != 3)
5209 dpurdie 369
            {
5213 dpurdie 370
                $needNewView = 1;
371
                last;
372
            }
373
        }
374
    }
375
    else
376
    {
377
        Warning ("Cannot open directory: $vdir", $!);
378
        $needNewView = 1;
379
    }
380
    #DebugDumpData("pkgsUsed",\%pkgsUsed);
381
    return $needNewView;
382
}
5209 dpurdie 383
 
5213 dpurdie 384
#-------------------------------------------------------------------------------
385
# Function        : createReleaseView 
386
#
387
# Description     : Create a new view for a single Release
388
#
389
# Inputs          : $rtagid     - RtagId
390
#
391
# Returns         : 
392
#
393
sub createReleaseView
394
{
395
    my ($rtagid) = @_;
396
 
397
    #
398
    #   Ensure that packages have been extracted
399
    #
400
    extractPackages($rtagid);
401
 
402
    #
403
    #   Create the actual view directory
404
    #   Its simply a bunch of symlinks back to the package store
405
    #
406
    Message("Creating LXR View: $rtagid, $dateTag");
407
    my $releaseDir = catdir($ReleaseStore, $rtagid, $dateTag);
408
    mkpath($releaseDir);
409
    if (-d $releaseDir)
410
    {
411
        foreach my $pvid (keys %{$ReleaseData{$rtagid}{data}})
412
        {
413
            my $entry = $Packages{$pvid};
414
            my $alias = join('', $entry->{name}, $entry->{ext});
415
            my $fullName = join('_', $entry->{name}, $entry->{ver});
416
            my $PackageStore = catdir($PackageStore , $fullName);
417
            my $releaseDir = catdir($releaseDir, $alias );
418
            next if -l $releaseDir;
419
 
420
            Verbose("Symlink $PackageStore, $releaseDir");
421
            my $rv = symlink ($PackageStore, $releaseDir);
422
            unless ($rv)
423
            {
424
                Warning("Could not link $PackageStore, $releaseDir")
5209 dpurdie 425
            }
426
        }
427
    }
428
}
429
 
430
#-------------------------------------------------------------------------------
431
# Function        : rebuildLxrConfig 
432
#
433
# Description     : Rebuild the LXR Configuration file
434
#                   This MAY be a bit LXR version specific, but since LXR doesn't
435
#                   provide a scriptable way to update configuration
436
#
437
#                   Uses template files that have been handcrafted after taken from
5211 dpurdie 438
#                   LXR. Basically we to a text replace and a glue together
5209 dpurdie 439
#
440
#                   For each release we need
441
#                       Long Release Name
442
#                       Short Release Name
443
#                       List of Versions
444
#
445
#
446
# Inputs          : Assumes Data has been added to %ReleaseData by other subroutines
447
#
448
# Returns         : 
449
#
450
sub rebuildLxrConfig
451
{
452
    my @lxrTreeText;
5211 dpurdie 453
 
5209 dpurdie 454
    #
5211 dpurdie 455
    #   Sort Sub
456
    #   Sort ReleaseData by Project and Name
457
    #   $a and $b are special to the sort
458
    #
459
    sub ReleaseDataSort
460
    {
461
        my $rv = lc($ReleaseData{$a}{release}{Project}) cmp lc($ReleaseData{$b}{release}{Project});
462
        if ($rv == 0)
463
        {
464
            $rv = lc($ReleaseData{$a}{release}{Name}) cmp lc($ReleaseData{$b}{release}{Name});
465
        }
466
        return $rv;
467
    }
468
 
469
    #
5209 dpurdie 470
    #   Process configured releases
5212 dpurdie 471
    #   Generate in the order we wish to display the Releases
5209 dpurdie 472
    #
473
    #DebugDumpData("ReleaseData", \%ReleaseData);
5211 dpurdie 474
    foreach my $rtagid ( sort ReleaseDataSort keys %ReleaseData )
5209 dpurdie 475
    {
476
        my $entry = $ReleaseData{$rtagid};
5211 dpurdie 477
        Information("Entry: $entry->{release}{Project}, $entry->{release}{Name}, $rtagid");
5209 dpurdie 478
        $entry->{release}{VersionsString} = join( ',', map { '"' . $_ .'"'} @{$entry->{Versions}} );
479
        $entry->{release}{dbName} = genDatabaseName($rtagid);
5213 dpurdie 480
        $entry->{release}{root} = catdir($ReleaseStore, $rtagid );
5209 dpurdie 481
        #DebugDumpData("ENTRY", \$entry);
482
 
483
        my $tfileName = 'lxr.tree.template';
484
        open( my $tf, '<', $tfileName) || Error ("Cannot open $tfileName. $!");
485
        while (my $line = <$tf>)
486
        {
487
            # Chomp trailing write space
488
            $line =~ s~\s+$~~;
489
 
490
            #   Replace known bits in the template
491
            $line =~ s~\@CAPTION\@~$entry->{release}{Project}::$entry->{release}{Name}~g;
492
            $line =~ s~\@SHORT_NAME\@~$rtagid~g;
493
            $line =~ s~\@RELEASE_ROOT\@~$entry->{release}{root}~g;
494
            $line =~ s~\@VERSIONS_LIST\@~$entry->{release}{VersionsString}~g;
495
            $line =~ s~\@DBNAME\@~$entry->{release}{dbName}~g;
496
            push @lxrTreeText, $line
497
        }
498
        close $tf;
499
    }
500
 
501
    #
502
    #   Insert tree sections into the main config file template
503
    #
504
    my $hostList = join( ',', map { '\'http://' . $_ .'\''} @addressList );
505
 
506
    my $tfileName = catfile($scriptDir, 'lxr.template');
5213 dpurdie 507
    my $lxrFileName = catfile($Config->{lxr}, 'lxr.new.conf');
5209 dpurdie 508
    unlink $lxrFileName;
509
    open( my $tf, '<', $tfileName) || Error ("Cannot open $tfileName. $!");
510
    open( my $to, '>', $lxrFileName) || Error ("Cannot open $lxrFileName. $!");
511
    while (my $line = <$tf>)
512
    {
513
        # Chomp trailing write space
514
        $line =~ s~\s+$~~;
515
 
516
        #   Replace known bits in the template
517
        if ($line =~ m~\@TREE_SECTIONS\@~)
518
        {
519
            foreach (@lxrTreeText)
520
            {
521
                print $to $_, "\n";
522
            }
523
        }
524
        else
525
        {
526
            $line =~ s~\@HOSTLIST\@~$hostList~g;
527
            print $to $line, "\n";
528
        }
529
    }
530
    close $tf;
531
    close $to;
532
 
533
    #
534
    #   Install the new config files
535
    #
5213 dpurdie 536
    my $lxrLive = catfile($Config->{lxr}, 'lxr.conf');
537
    my $lxrBackup = catfile($Config->{lxr}, 'lxr.conf.bak');
5209 dpurdie 538
    unlink $lxrBackup;
539
    rename ($lxrLive, $lxrBackup) || Warning("Renaming $lxrLive, $lxrBackup", $!);
540
    rename ($lxrFileName, $lxrLive) || Warning("Renaming $lxrFileName, $lxrLive", $!);
541
 
542
    #
543
    #   Create new database tables if required
544
    #   Use a customized shell script to do the hard work
545
    #
5213 dpurdie 546
    foreach my $rtagid ( sort keys %ReleaseData )
5209 dpurdie 547
    {
548
        my $entry = $ReleaseData{$rtagid};
5213 dpurdie 549
        Verbose("Database:$entry->{release}{Name}, $entry->{release}{dbName} ");
5209 dpurdie 550
        System('--NoExit', '--NoShell', catfile($scriptDir, 'lxr.initdb.sh'), $entry->{release}{dbName});
551
    }
552
}
553
 
554
#-------------------------------------------------------------------------------
555
# Function        : buildIndexes 
556
#
557
# Description     : Build (Generate) indexes for all versions of all releases
558
#                   that don't have an index
559
#                   
560
#                   Place a marker file in the 'version' directory when the
561
#                   index has been created
562
#
563
#                   Notes:
564
#                   The 'genxref' program needs to be run from the lxr insatll directory
565
#                   chdir to that directory for each invocation
566
#
567
#                   genxref uses DBI - and must find the proper PERL DBI and not the one
568
#                   within JATS.. Solution:
569
#                       Kill the PERL5LIB EnvVar
570
#
571
#
572
#
573
# Inputs          : 
574
#
575
# Returns         : 
576
#
577
sub buildIndexes
578
{
579
    #
580
    #   Prep envonment for calling genxref
581
    #   See notes above
582
    #
5213 dpurdie 583
    chdir ($Config->{lxr}) || Error ("Cannot chnage directory:$Config->{lxr}, $!");
5209 dpurdie 584
    delete $ENV{PERL5LIB};
585
 
586
    #
587
    #   Examine each Version in each Release
588
    #   Generate command line like:
589
    #   genxref --tree RTAGID --url http://HOSTNAME/lxr --version 'VERSION'
5213 dpurdie 590
    foreach my $rtagid ( sort keys %ReleaseData )
5209 dpurdie 591
    {
592
        my $entry = $ReleaseData{$rtagid};
593
        foreach my $version (@{$entry->{Versions}})
594
        {
5213 dpurdie 595
            my $markerFile = catfile(catdir($ReleaseStore, $rtagid ), $version, '.lxrIndexed');
5209 dpurdie 596
            unless (-f $markerFile) {
597
                Message("Must index: $rtagid, $version");
598
                my $rv = System('--NoExit', 
599
                       '--NoShell', 
5213 dpurdie 600
                       catfile($Config->{lxr}, 'genxref'),
5209 dpurdie 601
                       '--url', 'http://' . $ENV{GBE_HOSTNAME} . '/lxr',
602
                       '--tree', $rtagid,
603
                       '--version', $version
604
                       );
605
               Verbose("genxref exit: $rv");
606
               unless ($rv) {
607
                   TouchFile($markerFile);
608
               }
609
            }
610
            else
611
            {
612
                Verbose("Already indexed: $rtagid, $version");
613
            }
614
        }
615
    }
616
    #
617
    #   Restore current directory
618
    #
619
    chdir($FileUtils::CwdFull);
620
}
621
 
622
 
623
#-------------------------------------------------------------------------------
624
# Function        : cleanReleaseViews 
625
#
626
# Description     : Clean up unused Releases and Release Views
627
#                   Maintain the list of retained versions
628
#
629
#                   Two classes
630
#                   Active - Marked as having LXR support
631
#                       Retain the last 5 Versions
632
#
633
#                  InActive - Not having LXR support
634
#                       Retain for 10 days then delete all versions
635
#
636
# Inputs          : 
637
#
638
# Returns         : 
639
#
640
sub cleanReleaseViews
641
{
642
    #
643
    #   Scan Releases and delete all that are not currently configured
644
    #
645
    opendir (my $rdir, $ReleaseStore) || Error ("Cannot open directory: $ReleaseStore", $!);
646
    while (my $rdirEntry = readdir($rdir))
647
    {
648
        #   Skip hidden files and directories
649
        next if ($rdirEntry =~ m~^\.~);
650
        my $vdirName = catdir($ReleaseStore, $rdirEntry );
651
        next unless ( -d $vdirName );
5212 dpurdie 652
        unless(exists $ReleaseData{$rdirEntry} && $ReleaseData{$rdirEntry}{release}{ACTIVE} )
5209 dpurdie 653
        {
5211 dpurdie 654
            #   Release is no longer configured - age it out
5209 dpurdie 655
            #   Assume $rdirEntry is an rtag_id
5213 dpurdie 656
            if (processAgeMarker($vdirName, $Config->{'releaseAge'} ))
5211 dpurdie 657
            {
658
                Message("Delete Release: $rdirEntry");
659
                RmDirTree($vdirName);
660
                System('--NoExit', '--NoShell', catfile($scriptDir, 'lxr.dropdb.sh'), genDatabaseName($rdirEntry));
661
            }
5209 dpurdie 662
        }
663
        else
664
        {
5211 dpurdie 665
            deleteAgeMarker($vdirName);
5209 dpurdie 666
 
667
            #   Release is configured
668
            #   Keep the last x created
669
            #   Note: Create time is a kludge
670
            #
671
            #   Process each version within the Release
672
            #
673
            my @versionData;
674
            opendir (my $vdir, $vdirName) || Warning ("Cannot open directory: $vdirName", $!);
675
            while (my $vdirEntry = readdir($vdir))
676
            {
677
                #   Skip hidden files and directories
678
                next if ($vdirEntry =~ m~^\.~);
679
                my $ldirName = catdir($vdirName, $vdirEntry );
680
                next unless ( -d $ldirName );
681
                my $data;
682
                $data->{name} = $vdirEntry; 
683
                $data->{path} = $ldirName; 
684
                $data->{ctime} = (stat $ldirName)[9];
685
                push @versionData  , $data;
686
            }
687
            close ($vdir);
688
            #DebugDumpData("versionData",\@versionData);
689
 
690
            my $keepCount = 0;
691
            foreach my $entry ( sort { $b->{ctime} <=> $a->{ctime}} @versionData )
692
            {
693
                #DebugDumpData("Entry", $entry);
694
                $keepCount++;
695
                if ($keepCount > 5)
696
                {
697
                    #   Version is no longer needed - remove it
698
                    Message("Delete Version: $rdirEntry, $entry->{name}, $entry->{ctime}");
699
                    RmDirTree($entry->{path});
700
                }
701
                else
702
                {
703
                    #   Note which versions we have
704
                    push @{$ReleaseData{$rdirEntry}{Versions}}, $entry->{name};
705
                }
706
            }
707
        }
708
    }
709
    close ($rdir);
710
}
711
 
712
#-------------------------------------------------------------------------------
713
# Function        : getLatestVersion 
714
#
715
# Description     : For a specified directory return the newest subdir
716
#
717
#                   Used to determine the most recent version
718
#
5212 dpurdie 719
# Inputs          : $vdirName - Dir to process - expecting a Release directory
5209 dpurdie 720
#
5213 dpurdie 721
# Returns         : latestName  - Patch to the latest directory
722
#                   Age (days ) - Of the named directory
5209 dpurdie 723
#
724
sub getLatestVersion
725
{
726
    my  ($vdirName) = @_;
727
    my $latestName;
728
    my $latestAge = 0;
729
 
5213 dpurdie 730
    if (-d $vdirName )
5209 dpurdie 731
    {
5213 dpurdie 732
        opendir (my $vdir, $vdirName) || Warning ("Cannot open directory: $vdirName", $!);
733
        while (my $vdirEntry = readdir($vdir))
734
        {
735
            #   Skip hidden files and directories
736
            next if ($vdirEntry =~ m~^\.~);
5209 dpurdie 737
 
5213 dpurdie 738
            my $ldirName = catdir($vdirName, $vdirEntry );
739
            next unless ( -d $ldirName );
5209 dpurdie 740
 
5213 dpurdie 741
            my $age = (stat $ldirName)[9];
742
            Verbose3("Age: $ldirName, $age");
5209 dpurdie 743
 
5213 dpurdie 744
            if  ($age > $latestAge )
745
            {
746
                $latestAge = $age;
747
                $latestName = $ldirName;
748
            }
5209 dpurdie 749
        }
5213 dpurdie 750
        close ($vdir);
751
 
752
        #   Convert to Days ago
753
        $latestAge = ($StampTime - $latestAge) / (60*60*24);
754
        #DebugDumpData("versionDataSorted",\@versionDataSorted);
755
        Verbose("Latest: $latestName, $latestAge");
5209 dpurdie 756
    }
5213 dpurdie 757
    else
758
    {
759
        Verbose("Latest: No directory found: $vdirName");
760
    }
5209 dpurdie 761
 
5213 dpurdie 762
    return $latestName, $latestAge;
5209 dpurdie 763
}
764
 
765
#-------------------------------------------------------------------------------
766
# Function        : cleanPackageStore 
767
#
768
# Description     : Delete unused PAckages fromthe package store
769
#
770
# Inputs          : 
771
#
772
# Returns         : 
773
#
774
sub cleanPackageStore
775
{
776
    my %pkgsUsed;
777
    #
778
    #   Examime ALL versions in ALL Releases and build up a hash of
779
    #   Package Versions used
780
    #
781
    opendir (my $rdir, $ReleaseStore) || Error ("Cannot open directory: $ReleaseStore", $!);
782
    while (my $rdirEntry = readdir($rdir))
783
    {
784
        #   Skip hidden files and directories
785
        next if ($rdirEntry =~ m~^\.~);
786
        my $vdirName = catdir($ReleaseStore, $rdirEntry );
787
        next unless ( -d $vdirName );
788
 
789
        #
790
        #   Process each version within the Release
791
        #
792
        opendir (my $vdir, $vdirName) || Warning ("Cannot open directory: $vdirName", $!);
793
        while (my $vdirEntry = readdir($vdir))
794
        {
795
            #   Skip hidden files and directories
796
            next if ($vdirEntry =~ m~^\.~);
797
            my $ldirName = catdir($vdirName, $vdirEntry );
798
            next unless ( -d $ldirName );
799
 
800
            #
801
            #   Process each entry within the Version
802
            #
803
            opendir (my $ldir, $ldirName) || Warning ("Cannot open directory: $ldirName", $!);
804
            while (my $ldirEntry = readdir($ldir))
805
            {
806
                #   Skip hidden files and directories (also borken symlinks )
807
                next if ($ldirEntry =~ m~^\.~);
808
                my $dirName = catdir($ldirName, $ldirEntry );
809
                next unless ( -d $dirName );
810
 
811
                #
812
                #   Process each entry within the Version
813
                #
814
                my $pkgName = $ldirEntry;
815
                if (-l $dirName)
816
                {
817
                    $pkgName = readlink($dirName);
818
                    $pkgName =~ s~.*/~~;
819
                }
820
                $pkgsUsed{$pkgName}++;
821
            }
822
            close ($ldir);
823
        }
824
        close ($vdir);
825
    }
826
    close ($rdir);
827
 
828
    #
829
    #   Process the Packages directory and remove those not currently used
830
    #
831
    #
832
    #   Process each entry within the Version
833
    #
834
    opendir (my $pdir, $PackageStore) || Error ("Cannot open directory: $PackageStore", $!);
835
    while (my $pdirEntry = readdir($pdir))
836
    {
837
        #   Skip hidden files and directories
838
        next if ($pdirEntry =~ m~^\.~);
839
        my $pdirName = catdir($PackageStore, $pdirEntry );
840
        next unless ( -d $pdirName );
841
        next if (exists $pkgsUsed{$pdirEntry} );
842
 
5213 dpurdie 843
        if (processAgeMarker($pdirName, $Config->{packageAge})) 
5211 dpurdie 844
        {
845
            Message("Purge Package: $pdirEntry");
846
            RmDirTree($pdirName);
847
        }
5209 dpurdie 848
    }
849
    close ($pdir);
850
 
851
    #DebugDumpData("pkgsUsed", \%pkgsUsed);
852
}
853
 
854
 
855
#-------------------------------------------------------------------------------
856
# Function        : getReleaseData 
857
#
858
# Description     : Get all the required Release Data 
859
#
860
# Inputs          :  
861
#
862
# Returns         : 
863
#
864
sub getReleaseData
865
{
866
    my ($rtagid) = @_;
867
    my (@row);
5212 dpurdie 868
    my @releaseList;
869
    my $partSql = '';
5209 dpurdie 870
 
5213 dpurdie 871
    Verbose("getReleaseData");
5209 dpurdie 872
    connectRM(\$RM_DB) unless $RM_DB;
873
 
5212 dpurdie 874
    #
875
    #   Determine list of existing Releases
876
    #   Build up a Clause for the extraction SQL
877
    #   This is used to get data for Releases that exist in the Store but may have been
878
    #   deconfigured.
879
    #
880
    if ( opendir (my $rdir, $ReleaseStore) )
881
    {
882
        while (my $rdirEntry = readdir($rdir))
883
        {
884
            #   Skip hidden files and directories
885
            next if ($rdirEntry =~ m~^\.~);
886
            my $vdirName = catdir($ReleaseStore, $rdirEntry );
887
            next unless ( -d $vdirName );
888
            push @releaseList, $rdirEntry;
889
        }
890
        close $rdir;
891
    }
5209 dpurdie 892
 
5212 dpurdie 893
    if (@releaseList)
894
    {
895
        $partSql = ' OR rt.rtag_id in (' . join(',', @releaseList ) . ')' 
896
    }
897
 
898
 
5209 dpurdie 899
    #
900
    # Determine which Releases need LXR support
901
    #
902
    my $m_sqlstr = 
903
        "SELECT rtag_id, " .
904
        "  rt.proj_id, " .
905
        "  p.PROJ_NAME, " .
906
        "  rtag_name, " .
907
        "  official, " .
5212 dpurdie 908
        "  NVL(TRUNC (SYSDATE - rt.official_stamp),0) AS OFFICIAL_STAMP_DAYS, " .
909
        "  rt.lxr " .
5209 dpurdie 910
        "FROM release_tags rt, " .
911
        "  projects p " .
5212 dpurdie 912
        "WHERE ( rt.lxr  = 'Y'" . $partSql . ")" .
913
        " AND p.PROJ_ID = rt.proj_id ";
5209 dpurdie 914
 
915
    my $sth = $RM_DB->prepare($m_sqlstr);
916
    if ( defined($sth) )
917
    {
918
        if ( $sth->execute( ) )
919
        {
920
            if ( $sth->rows )
921
            {
922
                while ( @row = $sth->fetchrow_array )
923
                {
924
                    my $rtagid = $row[0];
925
                    my $data;
926
                    $data->{Project} = $row[2];
927
                    $data->{Name} = $row[3];
928
                    $data->{official} = substr($row[4],0,1);
929
                    $data->{official_stamp_days} = $row[5];
5212 dpurdie 930
                    $data->{lxr} = $row[6];
5209 dpurdie 931
 
932
                    #
933
                    #   Determine if this request for an LXR release is OK
934
                    #   Ok If the release is Open, CCB or Restricted
5212 dpurdie 935
                    #   Ok If closed and has been closed to < 10 days
5209 dpurdie 936
                    #
5212 dpurdie 937
                    if ($data->{lxr} eq 'Y')
5209 dpurdie 938
                    {
5212 dpurdie 939
                        if (index('NRC', $data->{official}) >= 0)
940
                        {
941
                            $data->{ACTIVE} = 1;
942
                        }
943
                        elsif ($data->{official} eq 'Y' && $data->{official_stamp_days} < 10 )
944
                        {
945
                            $data->{ACTIVE} = 2;
946
                        }
5209 dpurdie 947
                    }
948
 
949
                    $ReleaseData{$rtagid}{release} = $data;
950
                }
951
            }
952
            $sth->finish();
953
        }
954
    }
955
    else
956
    {
957
        Error("getReleaseData:Prepare failure" );
958
    }
959
 
5213 dpurdie 960
    if (IsVerbose(1))
961
    {
962
        DebugDumpData("ReleaseData", \%ReleaseData);
963
    }
5212 dpurdie 964
 
5213 dpurdie 965
    #
966
    #   Just a summary display for logging
967
    #
968
    foreach my $rtagid ( sort keys %ReleaseData)
5209 dpurdie 969
    {
5213 dpurdie 970
        my $state = $ReleaseData{$rtagid}{release}{ACTIVE} ? 'ACTIVE' : 'InActive';
971
        Information("Release: RtagId $rtagid, $state");
5209 dpurdie 972
    }
973
}
974
 
975
#-------------------------------------------------------------------------------
5213 dpurdie 976
# Function        : getReleasePakageData
5209 dpurdie 977
#
5212 dpurdie 978
# Description     : Get PackgeVersion information for one Release
5209 dpurdie 979
#
980
# Inputs          : rtagid
981
#
982
# Returns         : 
983
#
5213 dpurdie 984
sub getReleasePakageData
5209 dpurdie 985
{
986
    my ($rtagid) = @_;
987
    my (@row);
988
 
989
    connectRM(\$RM_DB) unless $RM_DB;
990
 
991
 
992
    # Get details for each package in the Release
993
    #   Don't worry about dependent packages
994
    #
995
    my $m_sqlstr = "SELECT pv.PV_ID, pkg.PKG_NAME, pv.PKG_VERSION, pv.V_EXT, release_manager.PK_RMAPI.return_vcs_tag(pv.PV_ID)".
996
                   " FROM RELEASE_MANAGER.RELEASE_CONTENT rc, RELEASE_MANAGER.PACKAGE_VERSIONS pv, RELEASE_MANAGER.PACKAGES pkg" .
997
                   " WHERE rc.RTAG_ID = $rtagid AND rc.PV_ID = pv.PV_ID AND pv.PKG_ID = pkg.PKG_ID";
998
    my $sth = $RM_DB->prepare($m_sqlstr);
999
    if ( defined($sth) )
1000
    {
1001
        if ( $sth->execute( ) )
1002
        {
1003
            if ( $sth->rows )
1004
            {
1005
                while ( @row = $sth->fetchrow_array )
1006
                {
1007
                    my $data;
1008
                    my $pvid = $row[0];
1009
                    unless (exists $Packages{$pvid}) {
1010
                        $data->{pv_id} = $row[0];
1011
                        $data->{name} = $row[1];
1012
                        $data->{ver} = $row[2];
1013
                        $data->{ext} = $row[3] || '';
1014
                        $data->{vcs} = $row[4] || '';
1015
                        $Packages{$pvid} = $data;
1016
                    }
5212 dpurdie 1017
                    $ReleaseData{$rtagid}{data}{$pvid} = 1;
5209 dpurdie 1018
                }
1019
            }
1020
            $sth->finish();
1021
        }
1022
    }
1023
    else
1024
    {
5213 dpurdie 1025
        Error("getReleasePakageData:Prepare failure" );
5209 dpurdie 1026
    }
1027
}
1028
 
1029
#-------------------------------------------------------------------------------
1030
# Function        : genDatabaseName 
1031
#
1032
# Description     : Genertate the name of a database
1033
#
1034
# Inputs          : rtag_id 
1035
#
1036
# Returns         : Text Name of the database
1037
#
1038
 
1039
sub genDatabaseName
1040
{
1041
    my ($rtag_id) = @_;
1042
    return 'LXR_' . $rtag_id;
1043
}
1044
 
1045
#-------------------------------------------------------------------------------
1046
# Function        : readConfig 
1047
#
1048
# Description     : Read the basic LXR config
1049
#                   This is held in a Perl structure 
1050
#
1051
# Inputs          : None 
1052
#
1053
# Returns         : Populate Global Data
1054
#
1055
sub readConfig
1056
{
1057
    my $cfile = catfile($scriptDir,'jats_lxr.conf');
5211 dpurdie 1058
    if ($opt_config)
1059
    {
1060
        Message ("Using alternate config: $opt_config");
1061
        $cfile = $opt_config;
1062
    }
5209 dpurdie 1063
 
5213 dpurdie 1064
    #
1065
    #   Slurp in the file and evaluate it as a perl expression
1066
    #
1067
    if (open(my $CONFIG, '<', $cfile))
1068
    {
1069
        local ($/) = undef;
1070
        my $config_contents = <$CONFIG>;
1071
        $config_contents =~ m/(.*)/s;
1072
        $config_contents = $1;    #untaint it
1073
        my $config = eval("\n#line 1 \"configuration file\"\n" . $config_contents);
1074
        Error($@) if $@;
1075
        close $CONFIG;
5209 dpurdie 1076
 
5213 dpurdie 1077
        #
1078
        #   Merge read data with defaults
1079
        #
1080
        @$Config{ keys %$config } = values %$config;
1081
    }
1082
    else
1083
    {
1084
        Error("Couldn't open configuration file \"$cfile\".", $!);
1085
    }
1086
 
1087
    if (IsVerbose(1))
1088
    {
1089
        DebugDumpData("Config", \$Config);
1090
    }
5209 dpurdie 1091
}
1092
 
1093
#-------------------------------------------------------------------------------
1094
# Function        : startLogFile 
1095
#
1096
# Description     : Start logging to a log file
1097
#                   Generate a nice name for the log file
1098
#
1099
# Inputs          : 
1100
#
1101
# Returns         : 
1102
#
1103
sub startLogFile
1104
{
1105
    if ( $opt_logfile )
1106
    {
5213 dpurdie 1107
        if (exists $Config->{lxrLogDir})
5209 dpurdie 1108
        {
5213 dpurdie 1109
            my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = gmtime($StampTime);
5209 dpurdie 1110
            my $name = sprintf("jats-lxr-%4.4d%2.2d%2.2d.%2.2d%2.2d%2.2d.log", 1900+$year, 1+$mon, $mday, $hour, $min, $sec);
5213 dpurdie 1111
            $name = catdir($Config->{lxrLogDir}, $name);
5209 dpurdie 1112
 
5213 dpurdie 1113
            mkpath($Config->{lxrLogDir}); 
1114
            if (-d $Config->{lxrLogDir} )
5209 dpurdie 1115
            {
1116
                open STDOUT, '>', $name  or die "Can't redirect STDOUT: $!";
1117
                open STDERR, ">&STDOUT"  or die "Can't dup STDOUT: $!";
1118
            }
1119
            else
1120
            {
5213 dpurdie 1121
                Warning("Can't create log dir: $Config->{lxrLogDir}. $!");
5209 dpurdie 1122
            }
1123
        }
1124
    }
1125
}
1126
 
1127
#-------------------------------------------------------------------------------
1128
# Function        : cleanupLogFiles 
1129
#
1130
# Description     : Remove old log files
1131
#
1132
# Inputs          : 
1133
#
1134
# Returns         : 
1135
#
1136
sub cleanupLogFiles
1137
{
5213 dpurdie 1138
    if (exists $Config->{lxrLogDir} && exists $Config->{logAge}  && $Config->{logAge} > 0 )
5209 dpurdie 1139
    {
5213 dpurdie 1140
        Verbose("cleanupLogFiles:$Config->{lxrLogDir}, $Config->{logAge}");
1141
        if ( opendir my $logDir, $Config->{lxrLogDir} )
5209 dpurdie 1142
        {
1143
            foreach my $fileName (readdir $logDir)
1144
            {
5213 dpurdie 1145
                my $file = catfile($Config->{lxrLogDir}, $fileName);
5209 dpurdie 1146
                next unless -f $file;
5213 dpurdie 1147
                next unless -M $file > $Config->{logAge};
5209 dpurdie 1148
                Verbose("Purge logfile: $fileName");
1149
                unlink $file;
1150
            }
1151
            closedir $logDir;
1152
        }
1153
    }
1154
}
1155
 
5211 dpurdie 1156
#-------------------------------------------------------------------------------
1157
# Function        : processAgeMarker 
1158
#
1159
# Description     : Age out directories
1160
#                   Will create age markers as required
1161
#
1162
# Inputs          : $tdir       - Target Directory
1163
#                   $age        - Configured age 
1164
#
1165
# Returns         : true        - Directory has reached age
1166
#
1167
sub processAgeMarker
1168
{
1169
    my ($tdir, $age) = @_;
1170
 
1171
    unless (-d $tdir) {
1172
        Warning ("Expected directory not found: $tdir");
1173
        return 0; 
1174
    }
5209 dpurdie 1175
 
5211 dpurdie 1176
    #   A configured age of 0 implies delete immediatly
1177
    if ($age == 0)
1178
    {
1179
        return 1;
1180
    }
1181
 
1182
    #
1183
    #   Create the file ONCE
1184
    #
1185
    my $markerfile = catfile($tdir, '.lxrAge');
1186
    unless (-f $markerfile)
1187
    {
1188
        TouchFile($markerfile);
1189
    }
1190
    else
1191
    {
5213 dpurdie 1192
        my $fileAge = -M $markerfile;
1193
        Verbose ("Age: $fileAge, $tdir");
1194
        if ($fileAge > $age)
5211 dpurdie 1195
        {
1196
            return 1
1197
        }
1198
    }
1199
    return 0;
1200
}
1201
 
1202
 
5209 dpurdie 1203
#-------------------------------------------------------------------------------
5211 dpurdie 1204
# Function        : deleteAgeMarker 
1205
#
1206
# Description     : Delete any age marker
1207
#                   Used when a (potentially) agable directory is used to remove
1208
#                   the aging marker
1209
#
1210
# Inputs          :  $tdir      - Directory
1211
#
1212
# Returns         : 
1213
#
1214
sub deleteAgeMarker
1215
{
1216
    my ($tdir) = @_;
1217
 
1218
    unless (-d $tdir) {
1219
        Warning ("Expected directory not found: $tdir");
1220
        return 0; 
1221
    }
1222
 
1223
    #
1224
    #   Use same file name as in processAgeMarker
1225
    #
1226
    my $markerfile = catfile($tdir, '.lxrAge');
1227
    unlink $markerfile;
1228
}
1229
 
1230
 
1231
#-------------------------------------------------------------------------------
5209 dpurdie 1232
#   Documentation
1233
#
1234
 
1235
=pod
1236
 
1237
=head1 NAME
1238
 
1239
jats_lxr - Maintain LXR Releases
1240
 
1241
=head1 SYNOPSIS
1242
 
1243
  jats jats_lxr [options]
1244
 
1245
 Options:
1246
    -help               - brief help message
1247
    -help -help         - Detailed help message
1248
    -man                - Full documentation
1249
    -[no]createVersions - Create new versions. Default:Create
1250
    -[no]extract        - Extract source code. Default:Extract
1251
    -[no]index          - Index new LXR versions. Default:Index
1252
    -[no]purge          - Purge unused packages. Default:Purge
1253
    -[no]logfile        - Capture out to a log file. Default:Log
5211 dpurdie 1254
    -config=file        - Alternate config file
5209 dpurdie 1255
 
1256
=head1 OPTIONS
1257
 
1258
=over 8
1259
 
1260
=item B<-help>
1261
 
1262
Print a brief help message and exits.
1263
 
1264
=item B<-help -help>
1265
 
1266
Print a detailed help message with an explanation for each option.
1267
 
1268
=item B<-man>
1269
 
1270
Prints the manual page and exits.
1271
 
1272
=item B<-verbose>
1273
 
1274
This option will display progress information as the program executes.
1275
 
1276
=item B<-[no]createVersions>
1277
 
1278
This option can be used to suppress the creation of new views.
1279
 
1280
=item B<-[no]extract>
1281
 
1282
This option can be used to suppress the extraction of source.
1283
 
1284
=item B<-[no]index>
1285
 
1286
This option can be used to suppress the indexing of newly created views.
1287
 
1288
=item B<-[no]purge>
1289
 
1290
This option can be used to suppress purging of packages that are no longer used by any of the LXR Trees.
1291
 
5211 dpurdie 1292
=item B<-config=file>
1293
 
1294
This option can be used to override the standard config file. Used in testing.
1295
 
5209 dpurdie 1296
=back
1297
 
1298
=head1 DESCRIPTION
1299
 
1300
This program is a tool for creating and maintaining an LXR instance within the VIX Build System.
1301
 
1302
The program can:
1303
 
1304
=over 8
1305
 
1306
=item * 
1307
 
1308
Examine the Release Manager Database and determine which Releases are a part of the set to have LXR Views created.
1309
 
1310
Releases that are Open (or Restricted or in CCB Mode) or that have been closed for less than 10 days will be processed.
1311
 
1312
=item *
1313
 
1314
Examine the Release Manager Database and determine the package-versions that are a part of the LXR Release Set.
1315
 
1316
The process will only examine the contents of a Release. It will not descend the version dependency tree.
1317
 
1318
The program will then extract new package-versions into it's Package Store. Multiple LXR Tree's will share the one 
1319
instance of the extracted source code.
1320
 
1321
=item *
1322
 
1323
Create a new 'Version' for each Release.
1324
 
1325
The Version Name is based on the date-time at which the process is run.
1326
 
1327
Each Version is a symlink to the required package-version held in the Package Store.
1328
 
1329
This step can be suppressed though a command line option.
1330
 
1331
=item *
1332
 
1333
Remove unused LXR Trees (Releases no longer being processed) and unused Versions within each Tree.
1334
 
1335
Releases that are no longer eligable for processing will be retained for 10 days and then deleted. 
1336
During this time the existing versions will not be aged out.
1337
 
1338
At the moment this tool simply retains the last 5 Versions of each Release. If the tool 
1339
is run nightly then this will translate into  5 days.
1340
 
1341
=item *
1342
 
1343
Regenerate the LXR Configuration file
1344
 
1345
Create new database tables for new Releases
1346
 
1347
=item *
1348
 
1349
Run the LXR indexer for each LXR Version that has not been processed. Once processed the Version will 
1350
be tagged to prevent further indexing.
1351
 
1352
=item *
1353
 
1354
Remove unused Package-Versions from the Package Store.
1355
 
1356
=back
1357
 
1358
=cut
1359