Subversion Repositories DevTools

Rev

Rev 1040 | Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1038 dpurdie 1
#! /usr/bin/perl
2
########################################################################
3
# Copyright (C) 2011 Vix-ERG Limited, All rights reserved
4
#
5
# Module name   : blatDaemon.pl
6
# Module type   :
7
# Compiler(s)   : Perl
8
# Environment(s):
9
#
10
# Description   :
11
#
12
# Usage         :   ARGV[0] - Path to config file for this instance
13
#
14
#......................................................................#
15
 
16
require 5.008_002;
17
use strict;
18
use warnings;
19
use Getopt::Long;
20
use File::Basename;
21
use POSIX ":sys_wait_h";
22
use File::Temp qw/tempfile/;
23
 
24
use FindBin;                                    # Determine the current directory
25
use lib "$FindBin::Bin/lib";                    # Allow local libraries
26
 
27
use Utils;
28
use StdLogger;                                  # Log to sdtout
29
use Logger;                                     # Log to file
30
 
31
#
32
#   Database interface
33
#   Pinched from jats and modified so that this software is not dependent on JATS
34
#
35
use IO::Handle;
36
use JatsRmApi;
37
use DBI;
38
 
39
#
40
#   Globals
41
#
42
my $logger = StdLogger->new();                  # Stdout logger. Only during config
43
my $name = basename( $ARGV[0]);
44
   $name =~ s~.conf$~~;
45
my $now = 0;
46
my $tagDirTime = 0;
47
my $lastDirScan = 0;
48
my $lastReleaseScan = 0;
49
my $transferred;
50
my $mtimeConfig = 0;
51
my $conf;
52
my $extraPkgs;
53
 
54
#
55
#   Describe config uration parameters
56
#
57
my %cdata = (
58
    '.ignore'         => {'pkg\.(.+)' => 'pkgs' },
59
    'piddir'          => {'mandatory' => 1    , 'fmt' => 'dir'},
60
    'sleep'           => {'default' => 5      , 'fmt' => 'period'},
61
    'dpkg_archive'    => {'mandatory' => 1    , 'fmt' => 'dir'},
62
    'logfile'         => {'mandatory' => 1    , 'fmt' => 'vfile'},
63
    'logfile.size'    => {'default' => '1M'   , 'fmt' => 'size'},
64
    'logfile.count'   => {'default' => 9      , 'fmt' => 'int'},
65
    'verbose'         => {'default' => 0      , 'fmt' => 'int'},
66
    'user'            => {'mandatory' => 1    , 'fmt' => 'text'},
67
    'hostname'        => {'mandatory' => 1    , 'fmt' => 'text'},
68
    'identity'        => {'mandatory' => 1    , 'fmt' => 'file'},
69
    'bindir'          => {'mandatory' => 1    , 'fmt' => 'text'},
70
    'tagdir'          => {'mandatory' => 1    , 'fmt' => 'dir'},
71
    'forcedirscan'    => {'default' => 100    , 'fmt' => 'period'},
72
    'tagage'          => {'default' => '10m'  , 'fmt' => 'period'},
73
    'synctime'        => {'default' => '2h'   , 'fmt' => 'period'},
74
    'project'         => {'mandatory' => 0    , 'fmt' => 'int_list'},
75
    'release'         => {'mandatory' => 0    , 'fmt' => 'int_list'},
76
    'writewindow'     => {'default' => '3h'   , 'fmt' => 'period'},
77
    'maxpackages'     => {'default' => 5      , 'fmt' => 'int'},
78
    'deletePackages'  => {'default' => 0      , 'fmt' => 'bool'},
79
);
80
 
81
 
82
#
83
#   Read in the configuration
84
#       Set up a logger
85
#       Write a pidfile - thats not used
86
readConfig();
87
Utils::writepid($conf);
88
$logger->logmsg("Starting...");
89
sighandlers($conf);
90
 
91
#
92
#   Main processing loop
93
#   Will exit when terminated by parent
94
#
95
while ( 1 )
96
{
97
    $logger->verbose3("Processing");
98
    $now = time();
99
    $transferred = {};
100
    readConfig();
101
    processReleaseList();
102
    processTags();
103
    sleep( $conf->{'sleep'} );
104
    waitpid(-1, WNOHANG);                           # Reap dead children
105
}
106
$logger->logmsg("Child End");
107
exit 0;
108
 
109
#-------------------------------------------------------------------------------
110
# Function        : readConfig
111
#
112
# Description     : Re read the config file if it modification time has changed
113
#
114
# Inputs          : Nothing
115
#
116
# Returns         : Nothing
117
#
118
sub readConfig
119
{
120
    my ($mtime) = Utils::mtime($ARGV[0]);
121
    if ( $mtimeConfig != $mtime )
122
    {
123
        $logger->logmsg("Reading config file: $ARGV[0]");
124
        $mtimeConfig = $mtime;
125
        my $errors;
126
        ($conf, $errors) = Utils::readconf ( $ARGV[0], \%cdata );
127
        if ( scalar @{$errors} > 0 )
128
        {
129
            warn "$_\n" foreach (@{$errors});
130
            die ("Config contained errors\n");
131
        }
132
 
133
        #
134
        #   Reset some information
135
        #   Create a new logger
136
        #
137
        $logger = Logger->new($conf);
138
        $conf->{logger} = $logger;
139
        $conf->{'pidfile'} = $conf->{'piddir'} . '/' . $name . '.pid';
140
        $logger->verbose("Log Levl: $conf->{verbose}");
141
 
142
        #
143
        #   Extract extra package config
144
        #
145
        $extraPkgs = {};
146
        while (my($key, $data) = each ( %{$conf->{pkgs}} ))
147
        {
148
            $extraPkgs->{$key}{$data} = 1;
149
            $logger->verbose("Extra Pkg: $key -> $data");
150
        }
151
    }
152
}
153
 
154
 
155
#-------------------------------------------------------------------------------
156
# Function        : processReleaseList
157
#
158
# Description     : Process the release list
159
#                       Determine if its time to process release list
160
#                       Determine release list
161
#                       Determine release content
162
#                       Determine new items
163
#
164
# Inputs          : None
165
#
166
# Returns         : Nothing
167
#
168
sub processReleaseList
169
{
170
    #
171
    #   Time to perform the scan
172
    #   Will do at startup and every time period there after
173
    #
174
    return unless ( $now > ($lastReleaseScan + $conf->{'synctime'} ));
175
    $logger->verbose("processReleaseList");
176
    $lastReleaseScan = $now;
177
    $tagDirTime = 0;                            # Force tag processing too
178
 
179
    #
180
    #   Get list of packages from Remote site
181
    #   Invoke a program on the remote site and parse the results
182
    #
183
    #     ssh  -i ./ssh/id_rsa_pkg_admin  pkg_admin@10.247.28.57 "./get_plist.pl"
184
    #
185
    #   Returned data looks like:
186
    #   1141792602 GMT(Wed Mar  8 04:36:42 2006) ishieldmodules/11.5.0.cots
187
    #   
188
    #
189
    my $remotePkgList;
190
    my $ph;
191
    my $tgt_cmd = "$conf->{'bindir'}/get_plist.pl 2>&1";
192
    my $ssh_cmd = "ssh -i $conf->{'identity'} $conf->{'user'}\@$conf->{'hostname'} \"$tgt_cmd\" 2>&1";
193
 
194
    $logger->verbose2("processReleaseList:ssh_cmd:$ssh_cmd");
195
    open ($ph, "$ssh_cmd |");
196
    while ( <$ph> )
197
    {
198
        chomp;
199
        if ( m~^(\d+)\s+GMT\(.*?\)\s+(.+)/(.+)~ )
200
        {
201
            $remotePkgList->{$2}{$3} = $1;
202
            $logger->verbose2("processReleaseList:Data: $_");
203
        }
204
        else
205
        {
206
            $logger->warn("processReleaseList:Bad Data: $_");
207
        }
208
    }
209
    close ($ph);
210
    $logger->verbose("processReleaseList:End: $?");
211
    if ( $? != 0 )
212
    {
213
        $logger->warn("Cannot retrieve package list: $?");
214
        return;
215
    }
216
 
217
    #
218
    #   Determine the set of packages in the releases to be transferred
219
    #   Examine
220
    #
221
    my @rlist = getReleaseList();
222
    return unless ( @rlist );
223
    my $pkgList = getPkgList(@rlist);
224
 
225
    #
226
    #   Append extra packages
227
    #   These are packages that are specifically named by the user
228
    #
229
    #   Note: If there are symbolic links, then the target of the
230
    #         link is treated used as the package name
231
    #
232
    #         Symlink MUST be within the same directory
233
    #
234
    #         Used to transfer jats2_current
235
    #
236
    my $pkgLink;
237
    while ( (my ($pname, $pvers)) = each %{$extraPkgs} ) {
238
        while ( (my ($pver, $pdata) ) = each %{$pvers} ) {
239
 
240
            my $epath = join ( '/', $conf->{'dpkg_archive'} , $pname, $pver );
241
            if ( -l $epath )
242
            {
243
                my $lver = readlink( $epath );
244
                if ( ! defined $lver )
245
                {
246
                    $logger->warn("Cant resolve symlink: $pname, $pver");
247
                    next;
248
                }
249
 
250
                if ( $lver =~ m ~/~ )
251
                {
252
                    $logger->warn("Won't resolve symlink: $pname, $pver, $lver");
253
                    next;
254
                }
255
                $pkgLink->{$pname}{$pver} = $lver;
256
                $pdata = $pver;
257
                $pver = $lver;
258
            }
259
 
260
            $logger->verbose2("Add extra package: $pname, $pver, $pdata");
261
            $pkgList->{$pname}{$pver} = $pdata;
262
        }
263
    }
264
 
265
#    while ( (my ($pname, $pvers)) = each %{$pkgList} )
266
#    {
267
#        while ( (my ($pver, $ptime) ) = each %{$pvers} )
268
#        {
269
#            print "L-- $pname, $pver, $ptime \n";
270
#
271
#        }
272
#    }
273
 
274
    #
275
    #   Display Excess Packages
276
    #       Packages not required on the target
277
    #       KLUDGE: Don't delete links to packages
278
    #
279
    my $excessPkgList;
280
    if ( $conf->{deletePackages} )
281
    {
282
        while ( (my ($pname, $pvers)) = each %{$remotePkgList} )
283
        {
284
            while ( (my ($pver, $pdata) ) = each %{$pvers} )
285
            {
286
                if ( !exists $pkgList->{$pname}{$pver} )
287
                {
288
                    if ( exists $pkgLink->{$pname}{$pver} )
289
                    {
290
                        $logger->verbose2("Keep Excess package-link: ${pname}/${pver}");
291
                        next;
292
                    }
293
                    $excessPkgList->{$pname}{$pver} = $pdata;
294
                    $logger->verbose("Excess package: ${pname}/${pver}");
295
                }
296
            }
297
        }
298
    }
299
 
300
    #
301
    #   Process the remote list and the local list
302
    #   The remote time-stamp is the modification time of the packages descpkg file
303
    #
304
    #   Mark for transfer packages that
305
    #       Are inthe local set but not the remote set
306
    #       Have a different time stamp
307
    #
308
    #   Ignore packages not in the local archive
309
    #   Ignore packages that don't have a descpkg
310
    #   Ignore packages that are writable - still being formed
311
    #
312
    my $needPkgList;
313
    while ( (my ($pname, $pvers)) = each %{$pkgList} )
314
    {
315
        while ( (my ($pver, $pdata) ) = each %{$pvers} )
316
        {
317
            my $tmtime = $remotePkgList->{$pname}{$pver} || 0;
318
 
319
            # Package is present in both list
320
            my ($mtime, $mode) = Utils::mtime(join ( '/', $conf->{'dpkg_archive'} , $pname, $pver, 'descpkg' ));
321
            if ( $mtime == 0 )
322
            {
323
                # PackageVersion not in local archive (at least the descpkg file is not)
324
                # Skip now - will pick it up later
325
                $logger->verbose("Package not in dpkg_archive: $pname, $pver");
326
                next;
327
            }
328
 
329
            if ( $mode & 0222 )
330
            {
331
                # Descpkg file is writable
332
                # Package may be in the process of being created
333
                # If the package has been wriatble for a long time, then
334
                # consider for transfer
335
                my $age = $now - $mtime;
336
                if ( $age < ($conf->{'writewindow '} || 600) )
337
                {
338
                    $logger->verbose("Package is writable: $pname, $pver, ", $now - $mtime);
339
                    next;
340
                }
341
            }
342
 
343
            if ( $mtime != $tmtime )
344
            {
345
                # Package not present on target, or timestamps differ
346
                $logger->verbose("Package Needs to be transferred: $pname, $pver, $mtime, $tmtime");
347
                $needPkgList->{$pname}{$pver} = $pdata;
348
                next;
349
            }
350
        }
351
    }
352
 
353
    #
354
    #   Debug output only
355
    #   Display what we need to transfer
356
    #
357
    if ( $conf->{verbose} > 2 )
358
    {
359
        while ( (my ($pname, $pvers)) = each %{$needPkgList} )
360
        {
361
            while ( (my ($pver, $pdata) ) = each %{$pvers} )
362
            {
363
                $logger->verbose("Need to transfer: $pname, $pver, $pdata");
364
            }
365
        }
366
    }
367
 
368
    #
369
    #   Time to do the real work
370
    #   Transfer packages and delete excess packages
371
    #   Note: Perform the transfers first
372
    #         Limit the number of packages processed in one pass
373
    #
374
    my $txcount = $conf->{maxpackages};
375
 
376
    #
377
    #   Transfer packages that we have identified
378
    #
379
    send_pkgs:
380
    while ( (my ($pname, $pvers)) = each %{$needPkgList} )
381
    {
382
        while ( (my ($pver, $pdata) ) = each %{$pvers} )
383
        {
384
            transferPackage ($pname, $pver, $pdata);
385
            if ( --$txcount <= 0 )
386
            {
387
                $logger->warn("Max transfer count exceeded");
388
                $lastReleaseScan = 0;
389
                last send_pkgs;
390
            }
391
        }
392
    }
393
 
394
    #
395
    #   Delete packages that have been identified as excess
396
    #
397
    delete_pkgs:
398
    while ( (my ($pname, $pvers)) = each %{$excessPkgList} )
399
    {
400
        while ( (my ($pver, $pdata) ) = each %{$pvers} )
401
        {
402
            deletePackage ($pname, $pver);
403
            if ( --$txcount <= 0 )
404
            {
405
                $logger->warn("Max transfer count exceeded");
406
                $lastReleaseScan = 0;
407
                last delete_pkgs;
408
            }
409
        }
410
    }
411
 
412
    #
413
    #   Send package list to the target
414
    #
415
    sendPackageList ($pkgList);
416
}
417
 
418
#-------------------------------------------------------------------------------
419
# Function        : sendPackageList
420
#
421
# Description     : Transfer package list to the target
422
#
423
# Inputs          : $pkgList            - Ref to hash of package names and versions
424
#
425
# Returns         : 
426
#
427
sub sendPackageList
428
{
429
    my ($pkgList) = @_;
430
    my ($fh, $filename) = tempfile( "/tmp/blat.$$.XXXX", SUFFIX => '.txt');
431
    $logger->verbose("sendPackageList:TmpFile: $filename");
432
 
433
    #
434
    #   Create a temp file with data
435
    #
436
    foreach my $pname ( sort keys %{$pkgList} )
437
    {
438
        foreach my $pver ( sort keys %{$pkgList->{$pname}} )
439
        {
440
            print $fh "$pname/$pver\n";
441
        }
442
    }
443
    close $fh;
444
 
445
    #
446
    #   Transfer to target
447
    #   Create the process pipe to transfer the file
448
    #   gzip the file and pipe the result through a ssh session to the target machine
449
    #   gzip -c filename |  ssh  -i $IDENTITY  pkg_admin@${TARGET_HOST} "./receive_file filename"
450
    #
451
    my $ph;
452
    my $gzip_cmd = "gzip --no-name -c \"$filename\"";
453
    my $tgt_cmd = "$conf->{'bindir'}/receive_file \"ArchiveList\" 2>&1";
454
    my $ssh_cmd = "ssh -i $conf->{'identity'} $conf->{'user'}\@$conf->{'hostname'} \"$tgt_cmd\"";
455
 
456
    $logger->verbose2("sendPackageList:gzip_cmd:$gzip_cmd");
457
    $logger->verbose2("sendPackageList:tgt_cmd:$tgt_cmd");
458
    $logger->verbose2("sendPackageList:ssh_cmd:$ssh_cmd");
459
 
460
    open ($ph, "$gzip_cmd | $ssh_cmd |");
461
    while ( <$ph> )
462
    {
463
        chomp;
464
        $logger->verbose2("sendPackageList:Data: $_");
465
    }
466
    close ($ph);
467
    $logger->verbose("sendPackageList:End: $?");
468
    unlink $filename;
469
}
470
 
471
 
472
#-------------------------------------------------------------------------------
473
# Function        : getPkgList
474
#
475
# Description     : Determine a set of package versions within the list
476
#                   of provided releases
477
#
478
# Inputs          : @rlist              - A list of releases to examine
479
#
480
# Returns         : Ref to a hask of package versions
481
#
482
sub getPkgList
483
{
484
    my %pdata;
485
    my $RM_DB;
486
    connectRM(\$RM_DB);
487
    $logger->verbose("getPkgList");
488
 
489
    #
490
    #   Determine the releases that are in this project
491
    #   Build up an sql query
492
    #
493
    my @m_rlist;
494
    push @m_rlist,"rc.RTAG_ID=$_" foreach ( @_ );
495
    my $m_rlist = join ' OR ', @m_rlist;
496
    my $m_sqlstr = "SELECT DISTINCT pv.PV_ID, pkg.PKG_NAME, pv.PKG_VERSION" .
497
                    " FROM RELEASE_MANAGER.RELEASE_CONTENT rc, RELEASE_MANAGER.PACKAGE_VERSIONS pv, RELEASE_MANAGER.PACKAGES pkg" .
498
                    " WHERE ( $m_rlist ) AND rc.PV_ID = pv.PV_ID AND pv.PKG_ID = pkg.PKG_ID" .
499
                    " ORDER by PKG_NAME DESC";
500
    $logger->verbose3("getPkgList:Sql:$m_sqlstr");
501
 
502
    my $sth = $RM_DB->prepare($m_sqlstr);
503
    if ( defined($sth) )
504
    {
505
        if ( $sth->execute( ) )
506
        {
507
            if ( $sth->rows )
508
            {
509
                while (my @row = $sth->fetchrow_array )
510
                {
511
                    $logger->verbose2("getPkgList:Data:@row");
512
                    $pdata{$row[1]}{$row[2]} = 1;
513
                }
514
            }
515
            $sth->finish();
516
        }
517
    }
518
    else
519
    {
520
        $logger->warn("getPkgList: SQL Prepare failure");
521
    }
522
   return \%pdata;
523
}
524
 
525
 
526
#-------------------------------------------------------------------------------
527
# Function        : getReleaseList
528
#
529
# Description     : Determine the list of releases to be proccessed
530
#
531
# Inputs          : None
532
#
533
# Returns         : A list of releases to be processed
534
#
535
sub getReleaseList
536
{
537
    my $RM_DB;
538
    my %rlist;
539
    $logger->verbose("getReleaseList");
540
 
541
    #
542
    #   Convert list of projects into a list of releases
543
    #
544
    my @plist = split /[,\s]+/, $conf->{'project'} || '';
545
    if ( @plist )
546
    {
547
        #
548
        #   Determine the releases that are in this project
549
        #   Build up an sql query
550
        #
551
        connectRM(\$RM_DB);
552
        my @m_plist;
553
        push @m_plist,"PROJ_ID=$_" foreach ( @plist );
554
        my $m_plist = join ' OR ', @m_plist;
555
        my $m_sqlstr = "SELECT rt.RTAG_ID" .
556
                    " FROM RELEASE_MANAGER.RELEASE_TAGS rt" .
557
                    " WHERE ( $m_plist ) AND rt.OFFICIAL != 'A' AND rt.OFFICIAL != 'Y'";
558
 
559
        $logger->verbose3("getReleaseList:Sql:$m_sqlstr");
560
        my $sth = $RM_DB->prepare($m_sqlstr);
561
        if ( defined($sth) )
562
        {
563
            if ( $sth->execute( ) )
564
            {
565
                if ( $sth->rows )
566
                {
567
                    while (my @row = $sth->fetchrow_array )
568
                    {
569
                        $logger->verbose2("getReleaseList:Data:@row");
570
                        $rlist{$row[0]} = 1;
571
                    }
572
                }
573
                $sth->finish();
574
            }
575
        }
576
        else
577
        {
578
            $logger->warn("getReleaseList: SQL Prepare failure");
579
        }
580
    }
581
 
582
    #
583
    #   Add in the user specified list of releases
584
    #
585
    my @rlist = split /[,\s]+/, $conf->{'release'} || '';
586
    $rlist{$_} = 1 foreach(@rlist);
587
 
588
    #
589
    #   Sort for pretty display only
590
    #
591
    return sort {$a <=> $b} keys %rlist;
592
}
593
 
594
 
595
#-------------------------------------------------------------------------------
596
# Function        : processTags
597
#
598
# Description     : Process tags and send marked package versions to the target
599
#                       Determine if new tags are present
600
#                       Process each tag
601
#
602
# Inputs          : None
603
#
604
# Returns         : Nothing
605
#
606
sub processTags
607
{
608
    #
609
    #   Determine if new tags are present by examining the time
610
    #   that the directory was last modified.
611
    #
612
    #   Allow for a forced scan to catch packages that did not transfer
613
    #   on the first attempt
614
    #
615
    my ($mtime) = Utils::mtime($conf->{'tagdir'} );
616
    if ( ($mtime > $tagDirTime) || ($now > ($lastDirScan + $conf->{'forcedirscan'})) )
617
    {
618
        $logger->verbose2("processTags: ", $mtime - $tagDirTime, $now - $lastDirScan);
619
        $tagDirTime = $mtime;
620
        $lastDirScan = $now;
621
 
622
        my $dh;
623
        unless (opendir($dh, $conf->{'tagdir'}))
624
        {
625
            $logger->warn ("can't opendir $conf->{'tagdir'}: $!");
626
            return;
627
        }
628
 
629
        #
630
        #   Process each entry
631
        #   Ignore those that start with a .
632
        #
633
        while (my $tag = readdir($dh) )
634
        {
635
            next if ( $tag =~ m~^\.~ );
636
            my $file = "$conf->{'tagdir'}/$tag";
637
            next unless ( -f $file );
638
            next if ( $tag  eq 'ReleaseList' );
639
 
640
            if ( $tag =~ m~(.+)::(.+)~  )
641
            {
642
                my $package = $1;
643
                my $version = $2;
644
                if ( transferPackage( $package, $version ))
645
                {
646
                    unlink $file;
647
                }
648
                else
649
                {
650
                    my ($mtime) = Utils::mtime( $file );
651
                    if ( $now - $mtime > $conf->{'tagage'} )
652
                    {
653
                        $logger->warn ("Delete unsatisfied tag: $tag");
654
                        unlink $file;
655
                    }
656
                }
657
            }
658
        }
659
        closedir $dh;
660
    }
661
}
662
 
663
#-------------------------------------------------------------------------------
664
# Function        : transferPackage
665
#
666
# Description     : Transfer specified package to target system
667
#
668
# Inputs          : $pname          - Name of the package
669
#                   $pver           - Package version
670
#                   $plink          - (optional) Symlink in same package
671
#
672
# Returns         : true    - Package transferred
673
#                   false   - Package not transferred
674
#
675
sub transferPackage
676
{
677
    my ($pname, $pver, $plink ) = @_;
678
    my $rv = 0;
679
    $logger->logmsg("transferPackage: @_");
680
 
681
    #
682
    #   plink of 1 is not a symlink
683
    #
684
    $plink = undef if ( defined($plink) && $plink eq '1' );
685
 
686
    #
687
    #   If its been transferred in the current scan, then
688
    #   indicate that all is well
689
    #
690
    if ( $transferred->{$pname}{$pver}  )
691
    {
692
        $logger->verbose("transferPackage: Already transferred");
693
        return 1;
694
    }
695
 
696
    my $sfile = join ( '/', $conf->{'dpkg_archive'} , $pname, $pver );
697
    unless ( -d $sfile )
698
    {
699
        $logger->warn("transferPackage:Package not found: $pname, $pver");
700
        return $rv;
701
    }
702
 
703
    #
704
    #   Create the process piple to transfer the package
705
    #   Tar the directory and pipe the result through a ssh session to
706
    #   the target machine
707
    #   gtar -czf - -C "$dpkg/${pname}/${pver}" . |  ssh  -i $IDENTITY  pkg_admin@${TARGET_HOST} "./receive_package ${rx_opts} \"$pname\" \"$pver\""
708
    #
709
    my $ph;
710
    my $tar_cmd = "gtar -czf - -C \"$sfile\" .";
711
    my $tgt_opts = defined($plink) ? "\"-L$plink\"" : '';
712
    my $tgt_cmd = "$conf->{'bindir'}/receive_package $tgt_opts \"$pname\" \"$pver\" 2>&1";
713
    my $ssh_cmd = "ssh -i $conf->{'identity'} $conf->{'user'}\@$conf->{'hostname'} \"$tgt_cmd\"";
714
 
715
    $logger->verbose2("transferPackage:tar_cmd:$tar_cmd");
716
    $logger->verbose2("transferPackage:tgt_cmd:$tgt_cmd");
717
    $logger->verbose2("transferPackage:ssh_cmd:$ssh_cmd");
718
 
719
    open ($ph, "$tar_cmd | $ssh_cmd |");
720
    while ( <$ph> )
721
    {
722
        chomp;
723
        $logger->verbose2("transferPackage:Data: $_");
724
    }
725
    close ($ph);
726
    $logger->verbose("transferPackage:End: $?");
727
    if ( $? == 0 )
728
    {
729
        #
730
        #   Mark has having been transferred in the current cycle
731
        #
732
        $transferred->{$pname}{$pver} = 1;
733
        $rv = 1;
734
    }
735
    else
736
    {
737
        $logger->warn("transferPackage:Transfer Error: $pname, $pver, $?");
738
    }
739
    return $rv;
740
}
741
 
742
#-------------------------------------------------------------------------------
743
# Function        : deletePackage
744
#
745
# Description     : Delete specified package to target system
746
#
747
# Inputs          : $pname          - Name of the package
748
#                   $pver           - Package version
749
#
750
# Returns         : true    - Package transferred
751
#                   false   - Package not transferred
752
#
753
sub deletePackage
754
{
755
    my ($pname, $pver ) = @_;
756
    my $rv = 0;
757
    $logger->logmsg("deletePackage: @_");
758
 
759
    #
760
    #   Create the process pipe to delete the package
761
    #   Tar the directory and pipe the result through a ssh session to
762
    #   the target machine
763
    #   gtar -czf - -C "$dpkg/${pname}/${pver}" . |  ssh  -i $IDENTITY  pkg_admin@${TARGET_HOST} "./receive_package ${rx_opts} \"$pname\" \"$pver\""
764
    #
765
    my $ph;
766
    my $tgt_cmd = "$conf->{'bindir'}/delete_package \"$pname\" \"$pver\" 2>&1";
767
    my $ssh_cmd = "ssh -i $conf->{'identity'} $conf->{'user'}\@$conf->{'hostname'} \"$tgt_cmd\"";
768
 
769
    $logger->verbose2("transferPackage:tgt_cmd:$tgt_cmd");
770
    $logger->verbose2("transferPackage:ssh_cmd:$ssh_cmd");
771
 
772
    open ($ph, "$ssh_cmd |");
773
    while ( <$ph> )
774
    {
775
        chomp;
776
        $logger->verbose2("deletePackage:Data: $_");
777
    }
778
    close ($ph);
779
    $logger->verbose("deletePackage:End: $?");
780
    if ( $? == 0 )
781
    {
782
        $rv = 1;
783
    }
784
    else
785
    {
786
        $logger->warn("deletePackage:Error: $pname, $pver, $?");
787
    }
788
    return $rv;
789
}
790
 
791
 
792
#-------------------------------------------------------------------------------
793
# Function        : sighandlers
794
#
795
# Description     : Install signal handlers
796
#
797
# Inputs          : $conf           - System config
798
#
799
# Returns         : Nothing
800
#
801
sub sighandlers
802
{
803
	my $conf = shift;
804
	my $logger = $conf->{logger};
805
 
806
	$SIG{TERM} = sub {
807
		# On shutdown
808
		$logger->logmsg('Received SIGTERM. Shutting down....' );
809
		unlink $conf->{'pidfile'} if (-f $conf->{'pidfile'});
810
		exit 0;
811
	};
812
 
813
	$SIG{HUP} = sub {
814
		# On logrotate
815
		$logger->logmsg('Received SIGHUP.');
816
		$logger->rotatelog();
817
	};
818
 
819
	$SIG{USR1} = sub {
820
		# On Force Archive Sync
821
		$logger->logmsg('Received SIGUSR1.');
822
        $lastReleaseScan = 0
823
	};
824
 
825
    $SIG{__WARN__} = sub { $logger->warn("@_") };
826
    $SIG{__DIE__} = sub { $logger->err("@_") };
827
 
828
 
829
}
830
 
831
#-------------------------------------------------------------------------------
832
# Function        : Error, Verbose, Warning
833
#
834
# Description     : Support for JatsRmApi
835
#
836
# Inputs          : Message
837
#
838
# Returns         : Nothing
839
#
840
sub Error
841
{
842
    $logger->err("@_");
843
}
844
 
845
sub Verbose
846
{
847
    $logger->verbose("@_");
848
}
849
 
850
sub Warning
851
{
852
    $logger->warn("@_");
853
}
854
 
855
 
856
 
857