Subversion Repositories DevTools

Rev

Rev 5300 | Rev 5399 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 5300 Rev 5398
Line 43... Line 43...
43
#
43
#
44
my $logger = StdLogger->new();                  # Stdout logger. Only during config
44
my $logger = StdLogger->new();                  # Stdout logger. Only during config
45
my $name = basename( $ARGV[0]);
45
my $name = basename( $ARGV[0]);
46
   $name =~ s~.conf$~~;
46
   $name =~ s~.conf$~~;
47
my $now = 0;
47
my $now = 0;
-
 
48
my $startTime = 0;
48
my $tar = 'tar';
49
my $tar = 'tar';
49
my $gzip = 'gzip';
50
my $gzip = 'gzip';
50
my $tagDirTime = 0;
51
my $tagDirTime = 0;
51
my $lastDirScan = 0;
52
my $lastDirScan = 0;
52
my $lastReleaseScan = 0;
53
my $lastReleaseScan = 0;
Line 57... Line 58...
57
my $conf;
58
my $conf;
58
my $extraPkgs;
59
my $extraPkgs;
59
my $excludePkgs;
60
my $excludePkgs;
60
my %releaseData;
61
my %releaseData;
61
my $comError = 0;
62
my $comError = 0;
-
 
63
my $yday = -1;
62
 
64
 
63
#
65
#
-
 
66
#   Contain statisics maintained while operating
-
 
67
#       Can be dumped with a kill -USR2
-
 
68
#       List here for documentation
-
 
69
#  
-
 
70
 
-
 
71
my %statistics = (
-
 
72
    SeqNum => 0,                        # Bumped when $statistics are dumped
-
 
73
    timeStamp => 0,                     # DateTime when statistics are dumped
-
 
74
    upTime => 0,                        # Seconds since program start
-
 
75
    Cycle => 0,                         # Major process loop counter
-
 
76
    phase => 'Init',                    # Current phase of operation
-
 
77
    state => 'OK',                      # Nagios state
-
 
78
                                        # 
-
 
79
                                        # The following are reset each day
-
 
80
    dayStart => 0,                      # DateTime when daily data was reset
-
 
81
    txCount => 0,                       # Packages Transferred
-
 
82
    delCount => 0,                      # Packages marked for deletion
-
 
83
    staleTags => 0,                     # Stale Tags
-
 
84
    linkErrors => 0,                    # Transfer errors
-
 
85
                                        # 
-
 
86
                                        # Per Cycle Data - Calculated each processing Cycle
-
 
87
    total    => 0,                      # Packages on target machine
-
 
88
    delete   => 0,                      # Packages to delete
-
 
89
    excluded => 0,                      # Packages excluded    
-
 
90
    filtered => 0,                      # Packages filtered out
-
 
91
    missing  => 0,                      # Packages missing
-
 
92
    transfer => 0,                      # Packages to transfer
-
 
93
    writable => 0,                      # Packages still writable - thus not transferred
-
 
94
    tagCount => 0,                      # Packages tagged to be transferred
-
 
95
);
-
 
96
 
-
 
97
#
64
#   Describe config uration parameters
98
#   Describe configuration parameters
65
#
99
#
66
my %cdata = (
100
my %cdata = (
67
    '.ignore'         => {'pkg\.(.+)' => 'pkgs' },
101
    '.ignore'         => {'pkg\.(.+)' => 'pkgs' },
68
    'piddir'          => {'mandatory' => 1      , 'fmt' => 'dir'},
102
    'piddir'          => {'mandatory' => 1      , 'fmt' => 'dir'},
69
    'sleep'           => {'default'   => 5      , 'fmt' => 'period'},
103
    'sleep'           => {'default'   => 5      , 'fmt' => 'period'},
Line 103... Line 137...
103
#       Write a pidfile - thats not used
137
#       Write a pidfile - thats not used
104
readConfig();
138
readConfig();
105
Utils::writepid($conf);
139
Utils::writepid($conf);
106
$logger->logmsg("Starting...");
140
$logger->logmsg("Starting...");
107
sighandlers($conf);
141
sighandlers($conf);
-
 
142
$startTime = time();
108
 
143
 
109
#
144
#
110
#   Main processing loop
145
#   Main processing loop
111
#   Will exit when terminated by parent
146
#   Will exit when terminated by parent
112
#
147
#
113
while (1 )
148
while (1 )
114
{
149
{
115
    $logger->verbose3("Processing");
150
    $logger->verbose3("Processing");
-
 
151
    $statistics{Cycle}++;
116
    $now = time();
152
    $now = time();
117
 
153
 
118
    $transferred = {};
154
    $transferred = {};
-
 
155
    $statistics{phase} = 'ReadConfig';
119
    readConfig();
156
    readConfig();
120
    if ( $conf->{'active'} )
157
    if ( $conf->{'active'} )
121
    {
158
    {
-
 
159
        $statistics{phase} = 'ProcessReleaseList';
122
        processReleaseList();
160
        processReleaseList();
-
 
161
        $statistics{phase} = 'processTags';
123
        processTags();
162
        processTags();
-
 
163
        $statistics{phase} = 'maintainTagList';
124
        maintainTagList();
164
        maintainTagList();
125
    }
165
    }
126
    %releaseData = ();
166
    %releaseData = ();
127
 
167
 
-
 
168
    $statistics{phase} = 'Sleep';
128
    sleep( $conf->{'sleep'} );
169
    sleep( $conf->{'sleep'} );
129
 
170
 
130
    #
171
    #
131
    #   Reap any and all dead children
172
    #   Reap any and all dead children
132
    #
173
    #
-
 
174
    $statistics{phase} = 'Reaping';
133
    my $kid;
175
    my $kid;
134
    do {
176
    do {
135
        $kid = waitpid(-1, WNOHANG);
177
        $kid = waitpid(-1, WNOHANG);
136
    } while ( $kid > 0 );
178
    } while ( $kid > 0 );
137
 
179
 
Line 142... Line 184...
142
    {
184
    {
143
        $logger->logmsg("Terminate. Pid file removed");
185
        $logger->logmsg("Terminate. Pid file removed");
144
        last;
186
        last;
145
    }
187
    }
146
}
188
}
-
 
189
$statistics{phase} = 'Terminated';
147
$logger->logmsg("Child End");
190
$logger->logmsg("Child End");
148
exit 0;
191
exit 0;
149
 
192
 
150
#-------------------------------------------------------------------------------
193
#-------------------------------------------------------------------------------
151
# Function        : readConfig
194
# Function        : readConfig
Line 183... Line 226...
183
        $conf->{logger} = $logger;
226
        $conf->{logger} = $logger;
184
        $conf->{'pidfile'} = $conf->{'piddir'} . '/' . $name . '.pid';
227
        $conf->{'pidfile'} = $conf->{'piddir'} . '/' . $name . '.pid';
185
        $logger->verbose("Log Levl: $conf->{verbose}");
228
        $logger->verbose("Log Levl: $conf->{verbose}");
186
 
229
 
187
        #
230
        #
-
 
231
        #   Setup statistics filename
-
 
232
        $conf->{'statsfile'} = $conf->{'piddir'} . '/' . $name . '.stats';
-
 
233
        $conf->{'statsfiletmp'} = $conf->{'piddir'} . '/' . $name . '.stats.tmp';
-
 
234
 
-
 
235
        #
188
        #   Extract extra package config
236
        #   Extract extra package config
189
        #
237
        #
190
        $extraPkgs = {};
238
        $extraPkgs = {};
191
        $excludePkgs = {};
239
        $excludePkgs = {};
192
        while (my($key, $data) = each ( %{$conf->{pkgs}} ))
240
        while (my($key, $data) = each ( %{$conf->{pkgs}} ))
Line 301... Line 349...
301
    $logger->verbose("processReleaseList:End: $?");
349
    $logger->verbose("processReleaseList:End: $?");
302
    LogTxError ($?);
350
    LogTxError ($?);
303
    if ( $? != 0 )
351
    if ( $? != 0 )
304
    {
352
    {
305
        $logger->warn("Cannot retrieve package list: $?");
353
        $logger->warn("Cannot retrieve package list: $?");
-
 
354
        $statistics{state} = 'No Remote Package List';
306
        return;
355
        return;
307
    }
356
    }
308
 
357
 
309
#Utils::DebugDumpData ("remotePkgList", $remotePkgList);
358
#Utils::DebugDumpData ("remotePkgList", $remotePkgList);
310
   
359
   
Line 324... Line 373...
324
        #
373
        #
325
        my @rlist = getReleaseList();
374
        my @rlist = getReleaseList();
326
        unless ( @rlist )
375
        unless ( @rlist )
327
        {
376
        {
328
            $logger->verbose2("No Releases to Process");
377
            $logger->verbose2("No Releases to Process");
-
 
378
            $statistics{state} = 'No Releases found';
329
            return;
379
            return;
330
        }
380
        }
331
        $pkgList = getPkgList(@rlist);
381
        $pkgList = getPkgList(@rlist);
332
    }
382
    }
333
 
383
 
Line 376... Line 426...
376
    #
426
    #
377
    unless ( keys %{$pkgList} )
427
    unless ( keys %{$pkgList} )
378
    {
428
    {
379
 
429
 
380
        $logger->verbose2("No packages to process");
430
        $logger->verbose2("No packages to process");
-
 
431
        $statistics{state} = 'No Packages found';
381
        return;
432
        return;
382
    }
433
    }
383
 
434
 
384
#    while ( (my ($pname, $pvers)) = each %{$pkgList} )
435
#    while ( (my ($pname, $pvers)) = each %{$pkgList} )
385
#    {
436
#    {
Line 564... Line 615...
564
        $logger->verbose("Packages still writable: $writableCount");
615
        $logger->verbose("Packages still writable: $writableCount");
565
        $logger->verbose("Packages excluded: $excludeCount");
616
        $logger->verbose("Packages excluded: $excludeCount");
566
    }
617
    }
567
 
618
 
568
    #
619
    #
-
 
620
    #   Update stats
-
 
621
    #   At this point we are looking pretty good
-
 
622
    #   
-
 
623
    $statistics{state} = 'OK';
-
 
624
    $statistics{total} = scalar keys(%{$remotePkgList});
-
 
625
    $statistics{transfer} = $needPkgListCount;
-
 
626
    $statistics{delete} = $excessPkgListCount;
-
 
627
    $statistics{filtered} = $filteredCount;
-
 
628
    $statistics{missing} = $missingCount;
-
 
629
    $statistics{writable} = $writableCount;
-
 
630
    $statistics{excluded} = $excludeCount;
-
 
631
 
-
 
632
    #
569
    #   Time to do the real work
633
    #   Time to do the real work
570
    #   Transfer packages and delete excess packages
634
    #   Transfer packages and delete excess packages
571
    #   Note: Perform the transfers first
635
    #   Note: Perform the transfers first
572
    #         Limit the number of packages processed in one pass
636
    #         Limit the number of packages processed in one pass
573
    #
637
    #
Line 1027... Line 1091...
1027
    #   that the directory was last modified.
1091
    #   that the directory was last modified.
1028
    #
1092
    #
1029
    #   Allow for a forced scan to catch packages that did not transfer
1093
    #   Allow for a forced scan to catch packages that did not transfer
1030
    #   on the first attempt
1094
    #   on the first attempt
1031
    #
1095
    #
-
 
1096
    my $tagCount = 0;
1032
    my ($mtime) = Utils::mtime($conf->{'tagdir'} );
1097
    my ($mtime) = Utils::mtime($conf->{'tagdir'} );
1033
    if ( ($mtime > $tagDirTime) || ($now > ($lastDirScan + $conf->{'forcedirscan'})) )
1098
    if ( ($mtime > $tagDirTime) || ($now > ($lastDirScan + $conf->{'forcedirscan'})) )
1034
    {
1099
    {
1035
        $logger->verbose2("processTags: ",$conf->{'tagdir'}, $mtime - $tagDirTime, $now - $lastDirScan);
1100
        $logger->verbose2("processTags: ",$conf->{'tagdir'}, $mtime - $tagDirTime, $now - $lastDirScan);
1036
        $tagDirTime = $mtime;
1101
        $tagDirTime = $mtime;
Line 1058... Line 1123...
1058
 
1123
 
1059
            if ( $tag =~ m~(.+)::(.+)~  )
1124
            if ( $tag =~ m~(.+)::(.+)~  )
1060
            {
1125
            {
1061
                my $package = $1;
1126
                my $package = $1;
1062
                my $version = $2;
1127
                my $version = $2;
-
 
1128
                $tagCount++;
1063
                if ( transferPackage( $package, $version ))
1129
                if ( transferPackage( $package, $version ))
1064
                {
1130
                {
1065
                    unlink $file;
1131
                    unlink $file;
1066
                }
1132
                }
1067
                else
1133
                else
Line 1069... Line 1135...
1069
                    my ($mtime) = Utils::mtime( $file );
1135
                    my ($mtime) = Utils::mtime( $file );
1070
                    if ( $now - $mtime > $conf->{'tagage'} )
1136
                    if ( $now - $mtime > $conf->{'tagage'} )
1071
                    {
1137
                    {
1072
                        $logger->warn ("Delete unsatisfied tag: $tag");
1138
                        $logger->warn ("Delete unsatisfied tag: $tag");
1073
                        unlink $file;
1139
                        unlink $file;
-
 
1140
                        $statistics{staleTags}++;
1074
                    }
1141
                    }
1075
                }
1142
                }
1076
            }
1143
            }
1077
        }
1144
        }
1078
        closedir $dh;
1145
        closedir $dh;
1079
    }
1146
    }
-
 
1147
    $statistics{tagCount} = $tagCount;
1080
}
1148
}
1081
 
1149
 
1082
#-------------------------------------------------------------------------------
1150
#-------------------------------------------------------------------------------
1083
# Function        : transferPackage
1151
# Function        : transferPackage
1084
#
1152
#
Line 1169... Line 1237...
1169
        #
1237
        #
1170
        #   Mark has having been transferred in the current cycle
1238
        #   Mark has having been transferred in the current cycle
1171
        #
1239
        #
1172
        $transferred->{$pname}{$pver} = 1;
1240
        $transferred->{$pname}{$pver} = 1;
1173
        $rv = 1;
1241
        $rv = 1;
-
 
1242
        $statistics{txCount}++;
1174
    }
1243
    }
1175
    else
1244
    else
1176
    {
1245
    {
1177
        $logger->warn("transferPackage:Transfer Error: $pname, $pver, $?");
1246
        $logger->warn("transferPackage:Transfer Error: $pname, $pver, $?");
1178
    }
1247
    }
Line 1219... Line 1288...
1219
    close ($ph);
1288
    close ($ph);
1220
    $logger->verbose("deletePackage:End: $?");
1289
    $logger->verbose("deletePackage:End: $?");
1221
    if ( $? == 0 )
1290
    if ( $? == 0 )
1222
    {
1291
    {
1223
        $rv = 1;
1292
        $rv = 1;
-
 
1293
        $statistics{delCount}++;
1224
    }
1294
    }
1225
    else
1295
    else
1226
    {
1296
    {
1227
        $logger->warn("deletePackage:Error: $pname, $pver, $?");
1297
        $logger->warn("deletePackage:Error: $pname, $pver, $?");
1228
    }
1298
    }
Line 1283... Line 1353...
1283
 
1353
 
1284
    $hashp->{$pname}{$pver} = $rv;
1354
    $hashp->{$pname}{$pver} = $rv;
1285
    return $hashp;
1355
    return $hashp;
1286
}
1356
}
1287
 
1357
 
-
 
1358
#-------------------------------------------------------------------------------
-
 
1359
# Function        : resetDailyStatistics 
-
 
1360
#
-
 
1361
# Description     : Called periodically to reset the daily statistics
-
 
1362
#
-
 
1363
# Inputs          : $time       - Current time
-
 
1364
#
-
 
1365
# Returns         : 
-
 
1366
#
-
 
1367
sub resetDailyStatistics
-
 
1368
{
-
 
1369
    my ($time) = @_;
-
 
1370
 
-
 
1371
    #
-
 
1372
    #   Detect a new day
-
 
1373
    #
-
 
1374
    my $today = (localtime($time))[7];
-
 
1375
    if ($yday != $today)
-
 
1376
    {
-
 
1377
        $yday = $today;
-
 
1378
        $logger->logmsg('Resetting daily statistics' );
-
 
1379
 
-
 
1380
        $statistics{dayStart} = $time;
-
 
1381
        $statistics{txCount} = 0;
-
 
1382
        $statistics{delCount} = 0;
-
 
1383
        $statistics{staleTags} = 0;
-
 
1384
        $statistics{linkErrors} = 0;
-
 
1385
    }
-
 
1386
}
-
 
1387
 
-
 
1388
#-------------------------------------------------------------------------------
-
 
1389
# Function        : periodicStatistics 
-
 
1390
#
-
 
1391
# Description     : Called on a regular basis to write out statistics
-
 
1392
#                   Used to feed information into Nagios
-
 
1393
#                   
-
 
1394
#                   This function is called via an alarm and may be outside the normal
-
 
1395
#                   processing loop. Don't make assumptions on the value of $now
-
 
1396
#
-
 
1397
# Inputs          : 
-
 
1398
#
-
 
1399
# Returns         : 
-
 
1400
#
-
 
1401
sub periodicStatistics
-
 
1402
{
-
 
1403
    #
-
 
1404
    #   A few local stats
-
 
1405
    #
-
 
1406
    $statistics{SeqNum}++;
-
 
1407
    $statistics{timeStamp} = time();
-
 
1408
    $statistics{upTime} = $statistics{timeStamp} - $startTime;
-
 
1409
 
-
 
1410
    #   Reset daily accumulations - on first use each day
-
 
1411
    resetDailyStatistics($statistics{timeStamp});
-
 
1412
    
-
 
1413
    #
-
 
1414
    #   Write statistics to a file
-
 
1415
    #       Write to a tmp file, then rename.
-
 
1416
    #       Attempt to make the operation atomic - so that the file consumer
-
 
1417
    #       doesn't get a badly formed file.
-
 
1418
    #   
-
 
1419
    if ($conf->{'statsfiletmp'})
-
 
1420
    {
-
 
1421
        my $fh;
-
 
1422
        unless (open ($fh, '>', $conf->{'statsfiletmp'}))
-
 
1423
        {
-
 
1424
            $fh = undef;
-
 
1425
            $logger->warn("Cannot create temp stats file: $!");
-
 
1426
        }
-
 
1427
        else
-
 
1428
        {
-
 
1429
            foreach my $key ( keys %statistics)
-
 
1430
            {
-
 
1431
                print $fh $key . ':' . $statistics{$key} . "\n";
-
 
1432
                $logger->verbose2('Statistics:'. $key . ':' . $statistics{$key});
-
 
1433
            }
-
 
1434
            close $fh;
-
 
1435
 
-
 
1436
            # Rename temp to real file
-
 
1437
            rename  $conf->{'statsfiletmp'},  $conf->{'statsfile'} ;
-
 
1438
        }
-
 
1439
    }
-
 
1440
}
1288
 
1441
 
1289
#-------------------------------------------------------------------------------
1442
#-------------------------------------------------------------------------------
1290
# Function        : sighandlers
1443
# Function        : sighandlers
1291
#
1444
#
1292
# Description     : Install signal handlers
1445
# Description     : Install signal handlers
Line 1295... Line 1448...
1295
#
1448
#
1296
# Returns         : Nothing
1449
# Returns         : Nothing
1297
#
1450
#
1298
sub sighandlers
1451
sub sighandlers
1299
{
1452
{
1300
	my $conf = shift;
1453
    my $conf = shift;
1301
	my $logger = $conf->{logger};
1454
    my $logger = $conf->{logger};
1302
 
1455
 
1303
	$SIG{TERM} = sub {
1456
    $SIG{TERM} = sub {
1304
		# On shutdown
1457
        # On shutdown
1305
		$logger->logmsg('Received SIGTERM. Shutting down....' );
1458
        $logger->logmsg('Received SIGTERM. Shutting down....' );
1306
		unlink $conf->{'pidfile'} if (-f $conf->{'pidfile'});
1459
        unlink $conf->{'pidfile'} if (-f $conf->{'pidfile'});
-
 
1460
        unlink $conf->{'statsfile'} if (-f $conf->{'statsfile'});
-
 
1461
        unlink $conf->{'statsfiletmp'} if (-f $conf->{'statsfiletmp'});
1307
		exit 0;
1462
        exit 0;
1308
	};
1463
    };
1309
 
1464
 
1310
	$SIG{HUP} = sub {
1465
    $SIG{HUP} = sub {
1311
		# On logrotate
1466
        # On logrotate
1312
		$logger->logmsg('Received SIGHUP.');
1467
        $logger->logmsg('Received SIGHUP.');
1313
		$logger->rotatelog();
1468
        $logger->rotatelog();
1314
	};
1469
    };
1315
 
1470
 
1316
	$SIG{USR1} = sub {
1471
    $SIG{USR1} = sub {
1317
		# On Force Archive Sync
1472
        # On Force Archive Sync
1318
		$logger->logmsg('Received SIGUSR1.');
1473
        $logger->logmsg('Received SIGUSR1.');
1319
        $lastReleaseScan = 0;
1474
        $lastReleaseScan = 0;
1320
        $lastTagListScan = 0;
1475
        $lastTagListScan = 0;
1321
	};
1476
    };
-
 
1477
 
-
 
1478
    alarm 60;
-
 
1479
    $SIG{ALRM} = sub {
-
 
1480
        # On Dump Statistics
-
 
1481
        $logger->verbose2('Received SIGUSR2.');
-
 
1482
        periodicStatistics();
-
 
1483
        alarm 60;
-
 
1484
    };
1322
 
1485
 
1323
    $SIG{__WARN__} = sub { $logger->warn("@_") };
1486
    $SIG{__WARN__} = sub { $logger->warn("@_") };
1324
    $SIG{__DIE__} = sub { $logger->err("@_") };
1487
    $SIG{__DIE__} = sub { $logger->err("@_") };
1325
}
1488
}
1326
 
1489
 
Line 1338... Line 1501...
1338
sub LogTxError
1501
sub LogTxError
1339
{
1502
{
1340
    my ($state) = $@;
1503
    my ($state) = $@;
1341
    if ( $state )
1504
    if ( $state )
1342
    {
1505
    {
-
 
1506
        $statistics{linkErrors}++ unless($comError);
1343
        $comError++;
1507
        $comError++;
-
 
1508
        $statistics{state} = 'No Communication';
1344
    }
1509
    }
1345
    elsif ( $comError )
1510
    elsif ( $comError )
1346
    {
1511
    {
1347
        $logger->warn("Communication Restored");
1512
        $logger->warn("Communication Restored");
1348
        $comError = 0;
1513
        $comError = 0;
-
 
1514
        $statistics{state} = 'OK';
1349
    }
1515
    }
1350
}
1516
}
1351
 
1517
 
1352
 
1518
 
1353
#-------------------------------------------------------------------------------
1519
#-------------------------------------------------------------------------------