#!/usr/bin/perl -s
use Proc::Daemon;
use Proc::PID::File;
use POSIX;
use IO::File;
use Storable;
use File::Slurp qw/write_file/;
$| = 1;
my $fifo_path = '/var/run/sqdproc/sqd.fifo';
my $datafile = '/var/run/sqdproc/sqd.data';
my $workers;
$workers = retrieve $datafile if -e $datafile;
my $command = shift;
unless ($command) {
print "Syntax: sqd start|stop|status|create
|list|drop |submit \n";
exit;
}
if ($command eq 'create') {
my $dir = shift;
die unless $dir;
write_to_fifo("create $< $dir");
exit;
}
if ($command eq 'submit') {
my $dir = shift;
my $target = shift;
die unless ($dir and $target);
my $script = '';
while (<>) {
$script .= $_;
}
my $worker_exists = 0;
foreach (sort keys %$workers) {
$worker_exists = 1 if ($workers->{$_}->{'dir'} =~ m/$dir\/?/);
}
if ($worker_exists) {
write_file( "$dir/QUEUE/$target", {binmode => ':utf8'}, $script );
print STDERR "New job submitted as: $dir/QUEUE/$target\n";
}
else {
print STDERR "Worker for $dir not found\n";
}
exit;
}
if ($command eq 'drop') {
my $dir = shift;
die unless $dir;
my $kill = 0;
foreach (sort keys %$workers) {
$kill = $_ if ($workers->{$_}->{'dir'} eq $dir);
}
if ($kill) {
# $workers->{$_}->{'daemon'}->Kill_Daemon; # XXX
`sudo kill $kill`;
delete $workers->{$kill};
store $workers, $datafile;
print STDERR "Worker dropped.\n";
}
else {
print STDERR "Worker not found.\n";
}
exit;
}
if ($command eq 'list') {
print "Pid\tStatus\tDir\n";
foreach (sort keys %$workers) {
print "$_\t";
($_ eq $workers->{$_}->{'daemon'}->Status) ? print "Ok" : print "Nok";
print "\t$workers->{$_}->{'dir'}\n";
}
exit;
}
# handle pid
my $rundir = '/var/run/sqdproc';
mkdir $rundir unless -d $rundir;
if ($command eq 'stop') {
$pid = Proc::PID::File->running(name => "sqd", dir => $rundir);
print STDERR "Stopping process.. ";
store $workers, $datafile;
kill 2, $pid;
print "ok!\n" and exit;
}
if ($command eq 'status') {
$pid = Proc::PID::File->running(name => "sqd", dir => $rundir);
if ($pid) {
print STDERR "Process running, pid $pid\n" and exit;
}
else {
print STDERR "Not running\n" and exit;
}
}
$SIG{INT} = sub { $::exit = 1; close $::fifo };
print STDERR "Starting process.. \n";
Proc::Daemon::Init;
my $pid = Proc::PID::File->running(name => "sqd", dir => $rundir);
mkfifo($fifo_path, 0777) unless -e $fifo_path; # XXX mkfifo
open (my $fifo, "<", $fifo_path) or die $!;
while (1) {
exit if $::exit;
while (<$fifo>) {
chomp $_;
my ($c, $user, $dir) = split /\s+/, $_;
$user ||= 0;
my $tmp = "C $c USER $user DIR $dir\n";
`echo "$tmp" >> /tmp/sqd.log`;
if ($c =~ m/create/i) {
my $daemon = Proc::Daemon->new;
my $username = `getent passwd $user | awk -F: '{print \$1}'`;
chomp $username;
my $com= "su - $username -c 'perl -s /home/jj/svn/main/misc/queueproc/sqd-daemon.pl $dir'";
`echo "$com" > /tmp/u`;
my $dpid = $daemon->Init({
exec_command => "$com",
});
$workers->{$dpid} = {pid=>$dpid, daemon=>$daemon, dir=>$dir, uid=>$user};
store $workers, $datafile;
}
}
sleep 2;
}
close $fifo;
sub write_to_fifo {
my $str = shift;
open(my $fifo, ">", $fifo_path) or die $!;
print $fifo $str;
close $fifo;
}