package Scire::Job; sub new { my $proto = shift; my $class = ref($proto) || $proto; my $filename = shift; my $self = {}; bless ($self, $class); if(defined $filename) { $self->set_filename($filename); } return $self; } sub set_filename { my $self = shift; my $filename = shift; $self->{filename} = $filename; my $jobcontents; my $jobdata; open JOB, "< ${filename}" or die "Can't open file ${filename}"; $jobcontents = join("", ); close JOB; $jobdata = eval($jobcontents); ($@) and print "ERROR: Could not parse job file ${filename}!\n"; if(defined $jobdata->{script}) { for(keys %{$jobdata->{script}}) { $self->{$_} = $jobdata->{script}->{$_}; } } for(keys %{$jobdata}) { $self->{$_} = $jobdata->{$_} unless($_ eq "script"); } } package Scire::Communicator; use IPC::Open2; sub new { my $proto = shift; my $class = ref($proto) || $proto; my $self = { port => 22, user => scire, server_script => "/usr/bin/scireserver.pl", SERVER_STDOUT => undef, SERVER_STDIN => undef, @_ }; bless ($self, $class); $self->build_connection_command(); return $self; } sub send_command { my $self = shift; my $cmd = shift; my @args = @_; my $tosend = "${cmd}"; for my $arg (@args) { if($arg =~ /^[0-9]+$/) { $tosend .= " ${arg}"; } else { $arg =~ s/"/\\"/g; $tosend .= " \"${arg}\""; } } $tosend .= "\n"; my ($tmpin, $tmpout) = ($self->{SERVER_STDIN}, $self->{SERVER_STDOUT}); print $tmpin $tosend; #FIXME WE NEED A TIMEOUT HERE OF SOME SORT!! #if the server doesn't give you a newline this just hangs! my $response = <$tmpout>; return $self->parse_response($response); } sub parse_response { my $self = shift; my $response = shift; $response =~ /^(OK|ERROR)(?: (.+?))?\s*$/; my ($status, $message) = ($1, $2); return ($status, $message); } sub create_connection { my $self = shift; # XXX: How do we capture this error? $pid has a valid value even if the # process fails to run, since it just returns the PID of the forked perl # process. I tried adding 'or die' after it, but it didn't help since it # doesn't fail in the main process. When it fails, it outputs an error # to STDERR: # open2: exec of ../server/scireserver.pl failed at ./scireclient.pl line 116 $self->{connection_pid} = open2($self->{SERVER_STDOUT}, $self->{SERVER_STDIN}, $self->{connection_command}); } sub build_connection_command { my $self = shift; # This will eventually be something like "ssh scire@${scireserver} /usr/bin/scireserver.pl" my $connection_command = "ssh "; $connection_command .= "-o BatchMode yes "; $connection_command .= "-o SendEnv 'SCIRE_*' "; $connection_command .= "-o ServerAliveInterval 15 -o ServerAliveCountMax 4 "; if(defined($self->{port})) { $connection_command .= "-o Port=$conf{port} "; } $connection_command .= "$self->{user}\@$self->{host} $self->{server_script}"; if (-d ".svn") { # Overwrite $connection_command in the case of a dev environment for now $connection_command = "../server/scireserver.pl"; } $self->{connection_command} = $connection_command; } 1;