Subversion Repositories DevTools

Rev

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