Commit adbfc56d authored by Leigh B Stoller's avatar Leigh B Stoller

Initial support requesting the new RRD idle data for a slice.

parent f6962901
......@@ -2578,5 +2578,32 @@ sub Utilization($)
return undef;
}
#
# IdleData
#
sub IdleData($)
{
my ($self) = @_;
my $authority = $self->GetGeniAuthority();
my $context = APT_Geni::RootContext();
my $slice = $self->instance()->GetGeniSlice();
return undef
if (! (defined($authority) && defined($context) &&
defined($slice)));
my $args = {
"slice_urn" => $slice->urn(),
};
my $cmurl = $authority->url();
$cmurl =~ s/\/cm$/\/cluster/;
$cmurl = devurl($cmurl) if ($usemydevtree);
my $response = Genixmlrpc::CallMethod($cmurl, $context,
"SliceIdleData", $args);
return $response;
bad:
return undef;
}
# _Always_ make sure that this 1 is at the end of the file...
1;
......@@ -54,6 +54,7 @@ sub usage()
print("Usage: manage_instance denyextension instance [-m message] [filename]\n");
print("Usage: manage_instance extendold instance [-f] seconds\n");
print("Usage: manage_instance utilization instance\n");
print("Usage: manage_instance idledata instance\n");
exit(-1);
}
my $optlist = "dt:s";
......@@ -125,6 +126,7 @@ sub DoLinktest();
sub DoUpdateKeys();
sub DoDeleteNodes();
sub DoUtilization();
sub DoIdleData();
sub WriteCredentials();
sub StartMonitor();
sub StartMonitorInternal(;$@);
......@@ -226,6 +228,9 @@ elsif ($action eq "deletenodes") {
elsif ($action eq "utilization") {
DoUtilization()
}
elsif ($action eq "idledata") {
DoIdleData()
}
else {
usage();
}
......@@ -3247,6 +3252,95 @@ sub DoUtilization()
exit($errcode);
}
#
# Get idledata info from the clusters.
#
sub DoIdleData()
{
my $errmsg;
my $errcode = 1;
#
# Create the webtask object; the web interface gave us an anonymous
# webtask, so we can use it before lock.
#
if (defined($webtask_id)) {
$webtask = WebTask->Lookup($webtask_id);
fatal("Could not lookup webtask object")
if (!defined($webtask));
# Convenient.
$webtask->AutoStore(1);
}
#
# And ask the backend clusters for the data.
#
my $coderef = sub {
my ($sliver) = @_;
my $webtask = $sliver->webtask();
my $response = $sliver->IdleData();
if (!defined($response)) {
print STDERR "RPC Error calling idledata on $sliver\n";
return -1;
}
if ($response->code() != GENIRESPONSE_SUCCESS) {
print STDERR "Could not get idledata for sliver: ".
$response->output() . "\n";
$webtask->output($response->output());
$webtask->Exited($response->code());
return $response->code();
}
if ($debug) {
print Dumper($response->value());
}
$webtask->idledata($response->value());
return 0;
};
my @return_codes = ();
my @agglist = ();
#
# Cull out any aggregates with no nodes.
#
foreach my $agg ($instance->AggregateList()) {
push(@agglist, $agg)
if ($agg->physnode_count() || $agg->virtnode_count());
}
if (ParRun({"maxwaittime" => 99999,
"maxchildren" => scalar(@agglist)},
\@return_codes, $coderef, @agglist)) {
$errmsg = "Internal error calling IdleData()";
goto bad;
}
#
# Check the exit codes.
#
foreach my $agg (@agglist) {
my $code = shift(@return_codes);
$agg->webtask()->Refresh();
if ($code) {
$errmsg = "Could not get idledata from some slivers";
if ($agg->webtask()->output()) {
$errmsg .= ": " . $agg->webtask()->output();
$errcode = $agg->webtask()->output();
}
goto bad;
}
if ($debug) {
print Dumper($agg->webtask()->idledata());
}
}
exit(0);
bad:
print STDERR $errmsg . "\n";
if (defined($webtask)) {
$webtask->output($errmsg);
$webtask->Exited($errcode);
}
exit($errcode);
}
#
# Write instance credentials to files.
#
......
......@@ -47,6 +47,7 @@ use libEmulab;
use GeniResponse;
use GeniSlice;
use GeniHRN;
use GeniUtil;
use English;
use Data::Dumper;
use Date::Parse;
......@@ -60,6 +61,9 @@ my $TB = "@prefix@";
my $TBOPS = "@TBOPSEMAIL@";
my $MAINSITE = @TBMAINSITE@;
my $OURDOMAIN = "@OURDOMAIN@";
my $IDLESTATS = "$TB/bin/idlestats";
my $SUDO = "/usr/local/bin/sudo";
my $WAP = "$TB/sbin/withadminprivs";
my $API_VERSION = 1.0;
#
......@@ -383,5 +387,57 @@ sub SliceUtilizationData($)
return GeniResponse->Create(GENIRESPONSE_SUCCESS, $results);
}
#
# Return utilization data for the nodes in a slice.
#
sub SliceIdleData($)
{
my ($argref) = @_;
my $slice_urn = $argref->{'slice_urn'};
my %blob = ();
my $hasperm = CheckPermission();
return $hasperm
if (GeniResponse::IsError($hasperm));
my $slice = GeniSlice->Lookup($slice_urn);
return GeniResponse->Create(GENIRESPONSE_SEARCHFAILED)
if (!defined($slice));
my $experiment = $slice->GetExperiment();
return GeniResponse->Create(GENIRESPONSE_ERROR, undef,
"No experiment for $slice")
if (!defined($experiment));
my $pid = $experiment->pid();
my $eid = $experiment->eid();
my $swapped = str2time($experiment->swapin_last());
my $limit = time() - (3600 * 24 * 3);
if ($limit < $swapped) {
$limit = $swapped;
}
$limit = emutil::TBDateStringLocal($limit);
GeniUtil::FlipToElabMan();
if (! open(IDLE, "$WAP $IDLESTATS -S '$limit' -e $pid,$eid |")) {
return GeniResponse->Create(GENIRESPONSE_ERROR, undef,
"Could not start idlestats")
}
my $output = "";
while (<IDLE>) {
$output .= $_;
}
if (! close(IDLE)) {
return GeniResponse->Create(GENIRESPONSE_ERROR, undef,
($! ? "Pipe error running idlestats: $!" :
"idlestats exited with $?") .
"\n" . $output);
}
#
# We get a giant json encoded string back.
#
return GeniResponse->Create(GENIRESPONSE_SUCCESS, $output);
}
# _Always_ make sure that this 1 is at the end of the file...
1;
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment