Subversion Repositories DevTools

Rev

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

Rev Author Line No. Line
1040 dpurdie 1
#! /usr/bin/perl
2
########################################################################
1044 dpurdie 3
# Copyright (C) 1998-2011 Vix Technology, All rights reserved
1040 dpurdie 4
#
5
# Module name   : blatPopulate
6
# Compiler(s)   : Perl
7
#
8
# Description   : Populate the blat tags directories with RM data
1044 dpurdie 9
#                 See POD at end of this file
1040 dpurdie 10
#
11
#......................................................................#
12
 
13
require 5.008_002;
14
use strict;
15
use warnings;
16
 
17
use Getopt::Long;                               # Option processing
18
use Pod::Usage;                                 # Required for help support
19
 
20
use File::Basename;
21
use File::Spec::Functions qw(catfile);
22
use FindBin;
23
 
24
use FindBin;                                    # Determine the current directory
25
use lib "$FindBin::Bin/lib";                    # Allow local libraries
26
use Utils;
1044 dpurdie 27
use StdLogger;                                  # Log to sdtout
1040 dpurdie 28
use Logger;
29
 
30
use Data::Dumper;
31
 
32
#
33
#   Globals
34
#
35
my $rootDir = $FindBin::Bin;
36
my $configPath = "config/blatPopulate.cfg";
37
my $conf;
38
my $errors;
39
my $logger;
40
my @args;
41
 
42
#
43
#   Options
44
#
45
my $opt_help = 0;
46
my $opt_verbose = 0;
47
my $opt_tagdir = 'tags';
1044 dpurdie 48
my $opt_nodaemonise;
1040 dpurdie 49
 
1044 dpurdie 50
my %pkginfo;
1040 dpurdie 51
 
1044 dpurdie 52
 
1040 dpurdie 53
#
1044 dpurdie 54
#   Describe configuration parameters
1040 dpurdie 55
#
56
my %cdata = (
57
    'logfile'         => {'mandatory' => 1    , 'fmt' => 'vfile'},
58
    'logfile.size'    => {'default' => '1M'   , 'fmt' => 'size'},
59
    'logfile.count'   => {'default' => 9      , 'fmt' => 'int'},
60
    'verbose'         => {'default' => 0      , 'fmt' => 'int'},
61
    'tagdir'          => {'mandatory' => 1    , 'fmt' => 'dir'},
1044 dpurdie 62
    'maxFileAge'      => {'default' => '24h'  , 'fmt' => 'period'},
1040 dpurdie 63
);
64
 
65
#-------------------------------------------------------------------------------
66
# Function        : Mainline Entry Point
67
#
68
# Description     :
69
#
70
# Inputs          :
71
#
72
@args = @ARGV;
1044 dpurdie 73
Getopt::Long::Configure('pass_through');
1040 dpurdie 74
my $result = GetOptions (
75
                "help|h:+"      => \$opt_help,
76
                "manual:3"      => \$opt_help,
77
                "verbose:+"     => \$opt_verbose,
78
                "tagdir=s"      => \$opt_tagdir,
1044 dpurdie 79
                "D"             => \$opt_nodaemonise,
1040 dpurdie 80
 
81
                );
82
 
83
                #
84
                #   UPDATE THE DOCUMENTATION AT THE END OF THIS FILE !!!
85
                #
86
 
87
#
88
#   Process help and manual options
89
#
1044 dpurdie 90
pod2usage(-verbose => 0, -message => "blatPopulate") if ($opt_help == 1 || ! $result );
1040 dpurdie 91
pod2usage(-verbose => 1) if ($opt_help == 2 );
92
pod2usage(-verbose => 2) if ($opt_help > 2);
93
 
1044 dpurdie 94
$logger = StdLogger->new();
95
 
1040 dpurdie 96
#
1044 dpurdie 97
#   Set the CWD as the directory of the script
1040 dpurdie 98
#   This simplifies configuration and use
99
#
100
chdir ($rootDir) || die ("Cannot 'cd' to $rootDir: $!\n");
101
 
102
#
103
#   Read in config
104
#
105
($conf, $errors) = Utils::readconf ( $configPath, \%cdata );
106
if ( scalar @{$errors} > 0 )
107
{
108
    warn "$_\n" foreach (@{$errors});
109
    die ("Config contained errors\n");
110
}
111
 
112
$conf->{verbose} = $opt_verbose if ( $opt_verbose > 0 );
1044 dpurdie 113
unless ( $opt_nodaemonise )
114
{
115
    $logger = Logger->new($conf);
116
    $conf->{logger} = $logger;
117
}
1040 dpurdie 118
$logger->verbose2("Args: @args");
119
 
120
#
1044 dpurdie 121
#   Porcess command line
4457 dpurdie 122
#   Arguments are of the form aaaa=bbbbm
1044 dpurdie 123
#
124
foreach ( @ARGV )
125
{
126
    next unless ( m~(.+)=(.+)~ );
127
    {
128
        my $tag = $1;
129
        my $value = $2;
130
        $value =~ s~^['"]~~;
131
        $value =~ s~['"]$~~;
132
        $pkginfo{$tag} = $value;
133
    }
134
}
135
 
136
#
1040 dpurdie 137
#   Sanity Test
1044 dpurdie 138
#   Ensure required arguments have been presented
1040 dpurdie 139
#
1044 dpurdie 140
foreach  ( qw(pkg_name pkg_version rtag_id pkg_id pv_id proj_id mode_id) )
141
{
142
    $logger->err ("$_ not provided")    unless ( exists $pkginfo{$_} );
1040 dpurdie 143
 
1044 dpurdie 144
}
145
 
1040 dpurdie 146
#
1044 dpurdie 147
#   Not interested in package deletions
148
#
149
if ( $pkginfo{mode_id} == 2 )
150
{
151
    $logger->verbose3 ("Ignore package deletion: $pkginfo{pkg_name},$pkginfo{pkg_version}");
152
    exit 0;
153
}
154
 
155
#
1040 dpurdie 156
#   Examine all the tag subdirectories
157
#   They will have a configuration file in them that has been created by the
158
#   consumer daemon.
159
#
160
 
161
    my $dh;
162
    unless (opendir($dh, $opt_tagdir) )
163
    {
164
        $logger->err ("Can't opendir $opt_tagdir: $!");
165
    }
166
 
167
    #
168
    #   Process each entry
169
    #       Ignore those that start with a .
170
    #       Only process subdirs
171
    #
172
    while (my $tag = readdir($dh) )
173
    {
174
        next if ( $tag =~ m~^\.~ );
1044 dpurdie 175
        $logger->verbose3 ("Processing: $tag");
1040 dpurdie 176
        my $tagfile = catfile($opt_tagdir, $tag, '.config');
177
        next unless ( -f $tagfile );
1044 dpurdie 178
        $logger->verbose3 ("Tag Dir: $tagfile");
1040 dpurdie 179
 
180
        my ($mtime) = Utils::mtime($tagfile);
181
        my $age = time() - $mtime;
182
        $logger->verbose3( "Config File Age: $age, $conf->{maxFileAge}");
183
        if ( $age > $conf->{maxFileAge} )
184
        {
185
            $logger->verbose ("File is OLD: $tagfile, $age");
186
            unlink $tagfile;
187
            next;
188
        }
189
 
190
        #
191
        #   Read in the config file
192
        #   Items of interest are:
193
        #       project
194
        #       release
195
        #       pkg.Name
196
        #
197
        my $data = ConfigReader::readConfig($tagfile);
1044 dpurdie 198
        if ( $conf->{verbose} > 2 )
199
        {
200
            $logger->verbose3 ("Config: " . Dumper($data));
201
        }
1040 dpurdie 202
        if ( $data )
203
        {
4457 dpurdie 204
            if (   ( exists $data->{allArchive} && $data->{allArchive} )
205
                || ( exists $data->{allProjects} && $data->{allProjects} ) 
206
                ||   exists $data->{projects}{$pkginfo{proj_id}}
207
                ||   exists $data->{releases}{$pkginfo{rtag_id}}
208
                ||   exists $data->{pkg}{$pkginfo{pkg_name}} )
1040 dpurdie 209
                {
1044 dpurdie 210
                    TouchFile( catfile( $opt_tagdir, $tag, $pkginfo{pkg_name} . '::' . $pkginfo{pkg_version} ));
1040 dpurdie 211
                }
212
        }
213
    }
214
    closedir $dh;
215
 
216
#-------------------------------------------------------------------------------
217
# Function        : TouchFile 
218
#
219
# Description     : touch a file
220
#                   Real use is to touch a marker file
221
#
222
# Inputs          : path        - path to the file
223
#
224
# Returns         : TRUE if an error occured in creating the file
225
#
226
sub TouchFile
227
{
228
    my ($path) = @_;
229
    my $result = 0;
230
    my $tfh;
231
    $logger->verbose( "Touching: $path" );
232
    if ( ! -f $path )
233
    {
234
        open ($tfh, ">>", $path) || ($result = 1);
235
        close $tfh;
236
    }
237
    else
238
    {
239
 
240
        #
241
        #   Modify the file
242
        #
243
        #   Need to physically modify the file
244
        #   Need to change the 'change time' on the file. Simply setting the
245
        #   last-mod and last-access is not enough to get past WIN32
246
        #   OR 'utime()' does not work as expected
247
        #
248
        #   Read in the first character of the file, rewind and write it
249
        #   out again.
250
        #
251
        my $data;
252
        open ($tfh , "+<", $path ) || return 1;
253
        if ( read ( $tfh, $data, 1 ) )
254
        {
255
            seek  ( $tfh, 0, 0 );
256
            print $tfh $data;
257
        }
258
        else
259
        {
260
            #
261
            #   File must have been of zero length
262
            #   Delete the file and create it
263
            #
264
            close ($tfh);
265
            unlink ( $path );
266
            open ($tfh, ">>", $path) || ($result = 1);
267
        }
268
        close ($tfh);
269
    }
1044 dpurdie 270
 
271
    #
272
    #   Ensure all can remove the file
273
    #   May be created by root and need to be deleted by the blatDaemon
274
    #
275
    chmod 0666, $path;
1040 dpurdie 276
    return $result;
277
}
278
 
279
package ConfigReader;
280
our %config;
281
 
282
#-------------------------------------------------------------------------------
283
# Function        : readConfig
284
#
285
# Description     : Read in a configuration file
286
#                   The file is a perl data structure and it can be
287
#                   required directly
288
#
289
# Inputs          : $fname              - Name of the file to read
290
#
291
# Returns         : Data component of the file
292
#
293
sub readConfig
294
{
295
    my ($fname) = @_;
296
#print "Reading: $fname\n";
297
    require $fname;
298
    return \%config;
299
}
300
 
301
#-------------------------------------------------------------------------------
302
#   Documentation
303
#
304
 
305
=pod
306
 
307
=head1 NAME
308
 
309
blatPopulate - Populate Blats tags directory to provide fast-transfer of packages
310
 
311
=head1 SYNOPSIS
312
 
1044 dpurdie 313
blatPopulate [options] pkg_data
1040 dpurdie 314
 
315
 
316
 Options:
317
    -help              - brief help message
318
    -help -help        - Detailed help message
319
    -man               - Full documentation
320
    -verbose           - A little bit of logging
321
    -tagdir=path       - Specify alternate tag base
1044 dpurdie 322
 PkgData
323
    tag=value          - A list of package information items
1040 dpurdie 324
 
325
=head1 OPTIONS
326
 
327
=over 8
328
 
329
=item B<-help>
330
 
331
Print a brief help message and exits.
332
 
333
=item B<-help -help>
334
 
335
Print a detailed help message with an explanation for each option.
336
 
337
=item B<-man>
338
 
339
Prints the manual page and exits.
340
 
341
=item B<-tagdir=path>
342
 
343
This provides an alternate tag directory root. The default value is a 'tags'
344
directory located below the directory in which the program is located.
345
 
1044 dpurdie 346
=item B<-tagdir=path>
347
 
348
A list of package information items. These include:
349
 
350
=over 4
351
 
352
=item * archive
353
 
354
=item * pkg_name
355
 
356
=item * pkg_version
357
 
358
=item * rtag_id
359
 
360
=item * pkg_id
361
 
362
=item * pv_id
363
 
364
=item * proj_id
365
 
366
=item * mode_id
367
 
1040 dpurdie 368
=back
369
 
1044 dpurdie 370
=back
371
 
1040 dpurdie 372
=head1 DESCRIPTION
373
 
374
This utility is designed to be invoked by Release Manager when a new package
375
has been added to a release.
376
 
377
The function of this program is to determine which Blat transfer targets
378
need to be notified of this event. This is done by
379
 
380
=over 8
381
 
382
=item * Scanning all tag directories for a .config file
383
 
384
=item * Examining the .config file and if the transfer target needs the current
385
        package then a tag file will be created.
386
 
387
=back
388
 
389
The .config file is created by the the consume BlatDaemon on a regular basis.
390
If the file is too old it will be deleted, on the assumption that the
391
blatDaemon is dead.
392
 
1044 dpurdie 393
=head2 EXAMPLE
394
 
395
    blatPopulate.pl  archive=dpkg_archive
396
                     pkg_name='h400sdk'
397
                     pkg_version='1.1.13-4.1000.cots'
398
                     rtag_id=11083
399
                     pkg_id=32885
400
                     pv_id=270088
401
                     proj_id=341
402
                     mode_id=2
403
                     -verbose=3
404
 
1040 dpurdie 405
=cut
406