eventsys_control.in 5.67 KB
Newer Older
1
#!/usr/bin/perl -wT
Leigh B. Stoller's avatar
Leigh B. Stoller committed
2 3

#
Mike Hibler's avatar
Mike Hibler committed
4
# Copyright (c) 2000-2015 University of Utah and the Flux Group.
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
# 
# {{{EMULAB-LICENSE
# 
# This file is part of the Emulab network testbed software.
# 
# This file is free software: you can redistribute it and/or modify it
# under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or (at
# your option) any later version.
# 
# This file is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public
# License for more details.
# 
# You should have received a copy of the GNU Affero General Public License
# along with this file.  If not, see <http://www.gnu.org/licenses/>.
# 
# }}}
Leigh B. Stoller's avatar
Leigh B. Stoller committed
24 25
#

26 27 28 29 30 31 32 33 34 35 36 37 38
use English;
use Getopt::Std;
use POSIX ":sys_wait_h";

#
# Start/Stop the event scheduler for an experiment. This script is
# setuid so that the stop function can send a signal regardless of
# who is running the script (must have appropriate permission of course).
# This is temporary; we eventually want to use the event system to control
# the event system, but lets see how well this event stuff works first.
#
sub usage()
{
39
    print STDOUT
Mike Hibler's avatar
Mike Hibler committed
40
	"Usage: eventsys_control [-f] <start|stop|replay> <pid>,<eid>\n";
41 42
    exit(-1);
}
43
my  $optlist = "dfa";
44 45 46 47 48 49

#
# Configure variables
#
my $TB		= "@prefix@";
my $TBOPS       = "@TBOPSEMAIL@";
50
my $CONTROL     = "@USERNODE@";
51
my $EVENTSYS    = @EVENTSYS@;
52
my $TESTMODE    = @TESTMODE@;
53 54
my $UNIFIED     = @UNIFIED_BOSS_AND_OPS@;
my $DBIFACE     = 0;
55 56 57 58 59 60 61 62

#
# The event system is currently optional.
#
if (! $EVENTSYS) {
    exit(0);
}

63 64 65 66
#
# Do nothing when testing.
#
if ($TESTMODE) {
67 68 69 70 71
#    print "Testing run - no event system.\n";
#    exit(0);
}

if ($EUID != 0) {
72
    die("Must be root! Maybe its a development version?\n");
73 74
}

75 76 77 78 79 80
#
# Testbed Support libraries
#
use lib "@prefix@/lib";
use libdb;
use libtestbed;
Kevin Atkinson's avatar
Kevin Atkinson committed
81
use libtblog;
82 83
use Experiment;
use User;
Ryan Jackson's avatar
Ryan Jackson committed
84
use EmulabFeatures;
85 86 87 88 89 90 91

#
# Turn off line buffering on output
#
$| = 1;

# un-taint path
92
$ENV{'PATH'} = "/bin:/usr/bin:/usr/local/bin:$TB/bin";
93 94
delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV'};

95 96
my $proxy	= "$TB/sbin/eventsys.proxy";
my $debug	= 1;
97
my $force       = 0;
98
my $agent       = 0;
99 100 101 102 103 104 105 106 107

#
# Parse command arguments. Once we return from getopts, all that should be
# left are the required arguments.
#
%options = ();
if (! getopts($optlist, \%options)) {
    usage();
}
108
if (@ARGV != 2) {
109 110 111 112 113
    usage();
}
if (defined($options{"d"})) {
    $debug = 1;
}
114 115 116
if (defined($options{"f"})) {
    $force = 1;
}
117 118 119
if (defined($options{"a"})) {
    $agent = 1;
}
120 121 122 123 124
my $action = $ARGV[0];

#
# Untaint args.
#
125 126 127 128
if ($action =~ /^(start|stop|replay)$/) {
    $action = $1;
}
else {
129 130 131
    usage();
}

132 133 134 135 136 137
#
# Verify user and get his DB uid and other info for later.
#
my $this_user = User->ThisUser();
if (! defined($this_user)) {
    tbdie("You ($UID) do not exist!");
138
}
139 140
my $user_uid = $this_user->uid();
my $isadmin  = TBAdmin();
141

142 143 144 145 146 147 148
#
# Grab the experiment.
#
my $experiment = Experiment->Lookup($ARGV[1]);
if (! $experiment) {
    die("*** $0:\n".
	"    No such experiment in the Emulab Database.\n");
149
}
150 151 152
my $pid = $experiment->pid();
my $eid = $experiment->eid();
my $expstate = $experiment->state();
153
my $project  = $experiment->GetProject();
154

155
#
156 157
# Check permission. Only people with permission to destroy the experiment
# can do this.
158
#
159
if (! $experiment->AccessCheck($this_user, TB_EXPT_DESTROY)) {
160
    tbdie("You do not have permission to control the event system!");
161 162
}

163
#
164 165
# Do not allow an event system to be controlled if the experiment is not
# active (or swapping).
166
#
167 168
if ($expstate ne EXPTSTATE_ACTIVE &&
    $expstate ne EXPTSTATE_ACTIVATING &&
169
    $expstate ne EXPTSTATE_MODIFY_RESWAP &&
170
    $expstate ne EXPTSTATE_SWAPPING) {
171
    tbdie("$experiment must be active (or swapping), not $expstate!");
172 173 174
}

#
175 176
# If being asked to start the event system, but there are no nodes in
# the experiment, balk unless force mode is on.
177
#
178
if ($action eq "start" && !$force && !ExpNodes($pid, $eid)) {
179
    tbnotice("There are no nodes in $experiment. Not starting a scheduler.");
180 181 182
    exit(0);
}

183 184 185 186 187 188 189 190
#
# Delete the TIME START event.
#
if ($action eq "replay" || $action eq "stop") {
    DBQueryFatal("DELETE FROM eventlist WHERE " .
		 "pid='$pid' and eid='$eid' and objecttype=3 and eventtype=1");
}

191 192 193 194 195 196 197 198 199 200 201 202
#
# Do we need a program agent on ops?
#
if ($action ne "stop" && ! $agent) {
    my $query_result =
	DBQueryFatal("select vname from virt_agents as v ".
		     "left join event_objecttypes as o on o.idx=v.objecttype ".
		     "where v.pid='$pid' and v.eid='$eid' and ".
		     "      o.type='PROGRAM' and v.vnode='ops'");
    $agent = $query_result->numrows;
}

203
# Need the unix_gid info to pass to boss.
204 205 206
my $group = $experiment->GetGroup();
if (!defined($group)) {
    tbdie("Could not get unix group info for $experiment!");
207 208
}

209
#
210 211 212
# Pase the whole thing off to the proxy, which might be local when running
# in UNIFIED_BOSS_AND_OPS mode. Become real root either way; the proxy will
# flip back. 
213
#
214
my $cmd = $proxy;
Ryan Jackson's avatar
Ryan Jackson committed
215

216
if (EmulabFeatures->FeatureEnabled("NewEventScheduler", $this_user, $group,
Ryan Jackson's avatar
Ryan Jackson committed
217 218 219 220
                                   $experiment)) {
	$cmd .= " -N ";
}

221 222
$cmd .= " -d"
    if ($debug);
223 224
$cmd .= " -a"
    if ($agent);
225 226 227 228 229
$cmd .= " -t " . $experiment->UserDir() . "/logs/events"
    if ($experiment->IsInstance());
$cmd .= " -l " . $experiment->UserDir() . "/logs/event-sched.log";
$cmd .= " -k " . $experiment->EventKeyPath();
$cmd .= " -g " . $group->unix_name();
230
$cmd .= " -p " . $project->unix_name();
231
$cmd .= " -e $pid/$eid";
232
$cmd .= " -u $user_uid";
233
$cmd .= " $action";
234

235 236 237
$UID=0;
if ($UNIFIED || $DBIFACE) {
    exec($cmd);
238
}
239 240
else {
    exec("sshtb -host $CONTROL $cmd");
241
}
242
tbdie("Could not exec '$cmd'");