[interchange-cvs] interchange - heins modified 3 files
interchange-core@icdevgroup.org
interchange-core@icdevgroup.org
Fri Jul 19 01:14:00 2002
User: heins
Date: 2002-07-19 05:13:16 GMT
Modified: scripts interchange.PL
Modified: lib/Vend Server.pm Control.pm
Log:
* Add nascent "cron" capability. While we don't keep the time, and
a scheduler will have to set the execution time, it allows ITL
to be run without the hassles of having to deal with HTTP.
* Somewhat documented in pod for bin/interchange
* TODO: Add email of results.
* TODO: Add "Cron" directive to specify directory. Current practice
of picking a directory in PageDir or *TemplateDir is weak. Cron
directive could also specify email address and log file for results,
and possibly other things like write_control for databases, precursor
ITL, etc.
* TODO: Interchange-core discussion of this facility and its
features before it goes anywhere.
Revision Changes Path
2.41 +159 -44 interchange/scripts/interchange.PL
rev 2.41, prev_rev 2.40
Index: interchange.PL
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /anon_cvs/repository/interchange/scripts/interchange.PL,v
retrieving revision 2.40
retrieving revision 2.41
diff -u -r2.40 -r2.41
--- interchange.PL 7 Jul 2002 04:02:26 -0000 2.40
+++ interchange.PL 19 Jul 2002 05:13:16 -0000 2.41
@@ -3,7 +3,7 @@
#
# Interchange version 4.9.1
#
-# $Id: interchange.PL,v 2.40 2002/07/07 04:02:26 mheins Exp $
+# $Id: interchange.PL,v 2.41 2002/07/19 05:13:16 mheins Exp $
#
# Copyright (C) 1996-2002 Red Hat, Inc. <interchange@redhat.com>
#
@@ -235,6 +235,7 @@
use autouse 'Vend::Control' =3D> qw/
signal_reconfig
signal_add
+ signal_cron
signal_remove
control_interchange
remove_catalog
@@ -1445,6 +1446,69 @@
return $status;
}
=20
+sub run_in_catalog {
+ my ($cat_name, $directory, $itl) =3D @_;
+ my ($g,$c);
+
+#::logGlobal("running job in cat=3D$cat_name");
+ $g =3D $Global::Catalog{$cat_name};
+ unless (defined $g) {
+ logGlobal( "Can't find catalog '%s'" , $cat_name );
+ return undef;
+ }
+
+ #$Vend::Log_suppress =3D 1;
+
+ unless ($Vend::Quiet) {
+ logGlobal("Run cron group=3D%s", $directory || 'INTERNAL');
+ }
+ #undef $Vend::Log_suppress;
+
+ open_cat($cat_name);
+
+ my $dir;
+ my @itl;
+ if($directory) {
+ my $ct =3D $Vend::Cfg->{TemplateDir} || [];
+ my $gt =3D $Global::TemplateDir || [];
+
+ for my $d ($Vend::Cfg->{PageDir}, @$ct, @$gt) {
+#::logGlobal("check directory=3D$d for $directory");
+ $dir =3D "$d/$directory"
+ if -d "$d/$directory";
+ }
+ if($dir) {
+ my @f =3D glob("$dir/*");
+ @f =3D grep ! -d $_, @f;
+ @f =3D grep $_ !~ /$Vend::Cfg->{HTMLsuffix}$/, @f;
+ for(@f) {
+#::logGlobal("found cron piece file=3D$_");
+ push @itl, [$_, readfile($_)];
+ }
+ }
+ }
+
+ if ($itl) {
+ push @itl, ["Passed ITL", $itl];
+ }
+
+ if(! @itl) {
+ logGlobal("Empty cron job=3D%s", $directory);
+ }
+
+ my @out;
+ for(@itl) {
+ logError("Running cron task=3D%s", $_->[0]);
+ push @out, interpolate_html($_->[1]);
+ }
+
+ close_cat();
+ my $out =3D join "", @out;
+ $out =3D~ s/^\s+//;
+ $out =3D~ s/\s+$/\n/;
+ return $out;
+}
+
sub config_named_catalog {
my ($cat_name, $source, $db_only, $dbconfig) =3D @_;
my ($g,$c);
@@ -1730,28 +1794,32 @@
},
);
=20
-sub dispatch {
- my($http) =3D @_;
- $H =3D $http;
-
- adjust_cgi();
+sub open_cat {
+ my $cat =3D shift;
=20
- my($sessionid, $seed);
- my(@path);
- my($g, $action);
+ if($cat) {
+ %CGI::values =3D ();
+ if($Global::Catalog{$cat}) {
+ $CGI::script_path =3D $Global::Catalog{$cat}->{script};
+ $CGI::script_name =3D $CGI::script_path;
+ }
+ }
=20
unless (defined $Global::Selector{$CGI::script_name}) {
my $msg =3D get_locale_message(
404,
"Undefined catalog: %s",
- $CGI::script_name,
+ $CGI::script_name || $cat,
);
$Vend::StatusLine =3D <<EOF;
Status: 404 Not Found
Content-Type: text/plain
EOF
- ::response($msg);
+ if($H) {
+ ::response($msg);
+ }
logGlobal($msg);
+ # No close_cat() necessary
return;
}
=20
@@ -1764,25 +1832,6 @@
$Vend::Cfg =3D $Global::Selector{$CGI::script_name};
}
=20
-## Uncomment this to get global directive setting on a per-catalog basis
-## Probably only useful for:
-##
-## DebugFile
-## DisplayErrors
-## DomainTail
-## ErrorLog
-## FullUrl
-## GlobalSub
-## HitCount
-## IpHead
-## IpQuad
-## Locale
-## LockoutCommand
-## NoAbsolute
-## SafeUntrap
-## UserTag
-## Variable
-
$Vend::Cat =3D $Vend::Cfg->{CatalogName};
my $catref =3D $Global::Catalog{$Vend::Cat};
if(! $Global::Foreground and defined $catref->{directive}) {
@@ -1836,7 +1885,7 @@
if $Vend::Cfg->{ImageDirInternal};
}
=20
- if($Global::HitCount) {
+ if($Global::HitCount and ! $cat) {
my $ctr =3D new Vend::CounterFile
"$Global::ConfDir/hits.$Vend::Cat";
$ctr->inc();
@@ -1868,6 +1917,25 @@
#show_times("end cgi and config mapping") if $Global::ShowTimes;
open_database();
#show_times("end open_database") if $Global::ShowTimes;
+}
+
+sub close_cat {
+ put_session() if $Vend::HaveSession;
+ close_session() if $Vend::SessionOpen;
+ close_database();
+}
+
+sub dispatch {
+ my($http) =3D @_;
+ $H =3D $http;
+
+ adjust_cgi();
+
+ my($sessionid, $seed);
+ my(@path);
+ my($g, $action);
+
+ open_cat();
=20
$CGI::user =3D Vend::Util::check_authorization($CGI::authorization)
if defined $CGI::authorization;
@@ -1929,6 +1997,7 @@
EOF
::response($msg);
logGlobal($msg);
+ close_cat();
return;
}
=20
@@ -2023,6 +2092,7 @@
Content-Type: text/plain
EOF
::response($msg);
+ close_cat();
return;
}
}
@@ -2341,9 +2411,7 @@
$Vend::Track->filetrack();
# END TRACK
=20
- put_session() if $Vend::HaveSession;
- close_session() if $Vend::SessionOpen;
- close_database();
+ close_cat();
=20
undef $H;
=20
@@ -2442,6 +2510,30 @@
The information is in the form of a standard Interchange catalog line,
and must be in the single-line format.
=20
+=3Ditem --cron=3Dcatalog[=3Djob]
+
+Run a cron group which is a series of files in a directory with
+the name corresponding to the C<job>. For instance, if you=20
+set up a directory called "weekly" in your pages directory
+for the catalog C<foundation>, you can run those files with:
+
+ interchange --cron=3Dfoundation=3Dweekly
+
+Files ending in .html (or whatever HTMLsuffix is for that catalog)
+are skipped. It is not tree-recursive -- directories are ignored.
+
+Results can be emailed to an address if you specify --email=3Daddress,
+and they will be put in the cron log file.
+
+Alternatively jobs can be specified with --job=3Djobname B<before>
+the --cron option. In other words, this will work:
+
+ interchange --job=3Dweekly --cron=3Dfoundation
+
+This will NOT work:
+
+ interchange --cron=3Dfoundation --job=3Dweekly
+
=3Ditem -d dir, --dir=3Ddir
=20
Directory for VendRoot. This is where the Interchange configuration file
@@ -2452,6 +2544,10 @@
=20
Exclude catalog from this startup.
=20
+=3Ditem -email=3Daddress
+
+Email address to email cron job results to.
+
=3Ditem -f file, --config=3Dfile
=20
Configuration file to use (default is interchange.cfg in VendRoot).
@@ -2465,6 +2561,15 @@
Run with internet-domain socket only. Normally Interchange runs with
both UNIX- and internet-domain sockets (except on Windows).
=20
+=3Ditem --job=3Djob
+
+Sets the job for --cron if that is not included in the --cron
+call. MUST precede the --cron entry on the command line.
+
+ interchange --job=3Dweekly --cron=3Dfoundation
+
+See --cron for an explanation of what this does.
+
=3Ditem --kill [signal]
=20
By default, kills the server ungracefully with signal KILL (9, usually).
@@ -2555,14 +2660,18 @@
=20
--add=3Dcatalog add a catalog to operation; parms taken from =
the
standard input as a "Catalog ..." directive
+ --cron=3Dcatalog[=3Djob] run cron jobs for a particular catalog
+ (can use --job and -email)
-d dir, --dir=3Ddir directory for VendRoot (interchange.cfg, erro=
r.log, etc.)
-e name,
--exclude=3Dname exclude catalog
+ --email=3Demailaddr Send results of cron job to emailaddr
-f file,
--config=3Dfile configuration file (default interchange.cfg)
--files spec filespec (perl regexp OK) for static page tree
-h, --help display this message
-i, --inetmode run with Internet-domain socket (TCP)
+ --job=3Djobname cron jobs to run (hourly, daily, weekly, etc.)
--kill [signal] kill server ungracefully (9 or with optional si=
gnal)
-q, --quiet suppress informational messages on startup
--reconfig=3Dcatalog reconfig a particular catalog on the server
@@ -2671,6 +2780,9 @@
version =3D> sub { version(); exit 0 },
stop =3D> \&control_interchange,
add =3D> \&signal_add,
+ email =3D> \$Vend::CronEmail,
+ job =3D> \$Vend::CronJob,
+ cron =3D> \&signal_cron,
remove =3D> \&signal_remove,
kill =3D> \&control_interchange,
Ignore =3D> \$ignore,
@@ -2728,16 +2840,19 @@
DEBUG:i
Ignore
add|a=3Ds
- confdir=3Ds
- rundir=3Ds
- configfile|config|c|f=3Ds
- dir|vendroot|d=3Ds
- exclude|e=3Ds
- help|h
- inetmode|inet|i
- kill:s
- log|logfile|l=3Ds
- quiet|q
+ confdir=3Ds
+ configfile|config|c|f=3Ds
+ cron=3Ds
+ dir|vendroot|d=3Ds
+ email=3Ds
+ exclude|e=3Ds
+ help|h
+ inetmode|inet|i
+ job=3Ds
+ kill:s
+ log|logfile|l=3Ds
+ quiet|q
+ rundir=3Ds
pidfile=3Ds
reconfig=3Ds
remove=3Ds
2.9 +72 -2 interchange/lib/Vend/Server.pm
rev 2.9, prev_rev 2.8
Index: Server.pm
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /anon_cvs/repository/interchange/lib/Vend/Server.pm,v
retrieving revision 2.8
retrieving revision 2.9
diff -u -r2.8 -r2.9
--- Server.pm 27 Jun 2002 22:24:10 -0000 2.8
+++ Server.pm 19 Jul 2002 05:13:16 -0000 2.9
@@ -1,6 +1,6 @@
# Vend::Server - Listen for Interchange CGI requests as a background server
#
-# $Id: Server.pm,v 2.8 2002/06/27 22:24:10 jon Exp $
+# $Id: Server.pm,v 2.9 2002/07/19 05:13:16 mheins Exp $
#
# Copyright (C) 1996-2002 Red Hat, Inc. <interchange@redhat.com>
#
@@ -25,7 +25,7 @@
package Vend::Server;
=20
use vars qw($VERSION);
-$VERSION =3D substr(q$Revision: 2.8 $, 10);
+$VERSION =3D substr(q$Revision: 2.9 $, 10);
=20
use POSIX qw(setsid strftime);
use Vend::Util;
@@ -1114,6 +1114,11 @@
{
::remove_catalog($1);
}
+ elsif( $directive =3D~ /^cron$/i) {
+ my ($cat, @jobs) =3D grep /\S/, split /[\s,\0]+/, $value;
+#::logGlobal("restart line found value=3D'$value'");
+ run_cron($cat, @jobs);
+ }
else {
::change_global_directive($directive, $value);
}
@@ -2309,6 +2314,71 @@
or die "create PID file $$: $!\n";
lockfile(\*TEMPPID, 1, 0)
or die "PID $$ conflict: can't lock\n";
+}
+
+sub cron_job {
+ my ($cat, @jobs) =3D @_;
+ for my $job (@jobs) {
+ ::run_in_catalog($cat, $job);
+ }
+}
+
+sub run_cron {
+ my ($cat, @jobs) =3D @_;
+
+#::logGlobal("Vend::Server::run_cron: run cron cat=3Dcat jobs=3D@jobs");
+ my $pid;
+ if($Global::Foreground) {
+ $::Instance =3D {};
+ eval {
+ cron_job($cat, @jobs);
+ };
+ if($@) {
+ my $msg =3D $@;
+ ::logGlobal({ level =3D> 'error' }, "Runtime error: %s" , $msg);
+ logError("Runtime cron error: %s", $msg)
+ if defined $Vend::Cfg->{ErrorFile};
+ }
+ clean_up_after_fork();
+ undef $::Instance;
+ }
+ elsif(! defined ($pid =3D fork) ) {
+ my $msg =3D ::errmsg("Can't fork: %s", $!);
+ ::logGlobal({ level =3D> 'crit' }, $msg );
+ die ("$msg\n");
+ }
+ elsif (! $pid) {
+ #fork again
+ unless ($pid =3D fork) {
+
+ reset_per_fork();
+ $::Instance =3D {};
+ eval {=20
+ touch_pid() if $Global::PIDcheck;
+ &$Sig_inc;
+ cron_job($cat, @jobs);
+ };
+ if ($@) {
+ my $msg =3D $@;
+ ::logGlobal({ level =3D> 'error' }, "Runtime error: %s" , $msg);
+ logError("Runtime cron error: %s", $msg)
+ if defined $Vend::Cfg->{ErrorFile};
+ }
+ clean_up_after_fork();
+
+ undef $::Instance;
+ select(undef,undef,undef,0.050) until getppid =3D=3D 1;
+ if ($Global::PIDcheck) {
+ unlink_pid() and &$Sig_dec;
+ }
+ else {
+ &$Sig_dec;
+ }
+ exit(0);
+ }
+ exit(0);
+ }
+ wait unless $Global::Foreground;
}
=20
sub unlink_pid {
2.4 +38 -3 interchange/lib/Vend/Control.pm
rev 2.4, prev_rev 2.3
Index: Control.pm
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /anon_cvs/repository/interchange/lib/Vend/Control.pm,v
retrieving revision 2.3
retrieving revision 2.4
diff -u -r2.3 -r2.4
--- Control.pm 27 Jun 2002 22:24:10 -0000 2.3
+++ Control.pm 19 Jul 2002 05:13:16 -0000 2.4
@@ -1,6 +1,6 @@
# Vend::Control - Routines that alter the running Interchange daemon
#=20
-# $Id: Control.pm,v 2.3 2002/06/27 22:24:10 jon Exp $
+# $Id: Control.pm,v 2.4 2002/07/19 05:13:16 mheins Exp $
#
# Copyright (C) 1996-2002 Red Hat, Inc. <interchange@redhat.com>
#
@@ -29,6 +29,7 @@
@EXPORT =3D qw/
signal_reconfig
signal_add
+ signal_cron
signal_remove
control_interchange
change_catalog_directive
@@ -49,6 +50,22 @@
}
}
=20
+sub signal_cron {
+ shift;
+ $Vend::mode =3D 'cron';
+ my $arg =3D shift;
+ my ($cat, $job) =3D split /\s*=3D\s*/, $arg, 2;
+ $Vend::CronCat =3D $cat;
+#::logGlobal("signal_cron: called cron cat=3D$cat job=3D$job");
+ $job =3D join ",", $job, $Vend::CronJob;
+ $job =3D~ s/^,+//;
+ $job =3D~ s/,+$//;
+ $Vend::CronJob =3D $job;
+ Vend::Util::writefile("$Global::RunDir/restart", "cron $cat $job\n");
+#::logGlobal("signal_cron: wrote file, ready to control_interchange");
+ control_interchange('cron', 'HUP');
+}
+
sub signal_remove {
shift;
$Vend::mode =3D 'reconfig';
@@ -92,8 +109,26 @@
if(! $sig) {
$sig =3D $mode ne 'kill' ? 'TERM' : 'KILL';
}
- print "Killing Interchange server $pid with $sig.\n"
- unless $Vend::Quiet;
+ my $msg;
+ if($mode eq 'cron') {
+ $msg =3D ::errmsg(
+ "Dispatching jobs=3D%s for cat %s to Interchange server %s with %s.\n=
",
+ $Vend::CronJob,
+ $Vend::CronCat,
+ $pid,
+ $sig,
+ );
+ }
+ else {
+ $msg =3D ::errmsg(
+ "Killing Interchange server %s with %s.\n",
+ $pid,
+ $sig,
+ );
+ }=20
+
+ print $msg unless $Vend::Quiet;
+
kill $sig, $pid
or die errmsg("Interchange server would not stop.\n");
exit 0 unless $restart;