summaryrefslogtreecommitdiff
blob: 19c6119207548f772fa688137bda9f0c59a3784b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
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->load_jobfile($filename);
	}
	return $self;
}

sub load_jobfile {
	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("", <JOB>);
	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 (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;