Commit 8b66840c authored by Gary Wong's avatar Gary Wong

Merge branch 'lbs-greatness'

parents 88dd5a80 33129222
#!/usr/bin/perl -wT #!/usr/bin/perl -wT
# #
# Copyright (c) 2007-2017 University of Utah and the Flux Group. # Copyright (c) 2007-2018 University of Utah and the Flux Group.
# #
# {{{EMULAB-LICENSE # {{{EMULAB-LICENSE
# #
...@@ -270,5 +270,34 @@ sub LookupByNickname($$) ...@@ -270,5 +270,34 @@ sub LookupByNickname($$)
return Lookup($class, $aggregate_urn); return Lookup($class, $aggregate_urn);
} }
#
# Check status of aggregate.
#
sub CheckStatus($$;$)
{
my ($self, $perrmsg, $portalrpc) = @_;
require APT_Geni;
if (0 || $self->disabled()) {
$$perrmsg = "The " . $self->name() . " cluster ".
"is currently offline, please try again later.";
return 1;
}
# Ping test. If we cannot get to the aggregate right now, bail.
my $retval = APT_Geni::PingAggregate($self, $perrmsg, $portalrpc);
if ($retval) {
if ($retval < 0) {
$$perrmsg = "Internal error contacting the ".
$self->name() . " cluster: " . $perrmsg;
}
else {
$$perrmsg = "The " . $self->name() . " cluster ".
"is currently unreachable, please try again later.";
}
return 1;
}
return 0;
}
# _Always_ make sure that this 1 is at the end of the file... # _Always_ make sure that this 1 is at the end of the file...
1; 1;
#!/usr/bin/perl -wT #!/usr/bin/perl -wT
# #
# Copyright (c) 2007-2017 University of Utah and the Flux Group. # Copyright (c) 2007-2018 University of Utah and the Flux Group.
# #
# {{{EMULAB-LICENSE # {{{EMULAB-LICENSE
# #
...@@ -574,6 +574,18 @@ sub GetCertificate($) ...@@ -574,6 +574,18 @@ sub GetCertificate($)
return $cert; return $cert;
} }
# Helper functions for below.
sub ContextError()
{
return GeniResponse->Create(GENIRESPONSE_ERROR(), undef,
"Could not generate context for RPC");
}
sub CredentialError()
{
return GeniResponse->Create(GENIRESPONSE_ERROR(), undef,
"Could not generate credentials for RPC");
}
# #
# Create a dataset on the remote aggregate. # Create a dataset on the remote aggregate.
# #
...@@ -584,13 +596,14 @@ sub CreateDataset($) ...@@ -584,13 +596,14 @@ sub CreateDataset($)
my $geniuser = $self->GetGeniUser(); my $geniuser = $self->GetGeniUser();
my $context = APT_Geni::GeniContext(); my $context = APT_Geni::GeniContext();
my $cert = $self->GetCertificate(); my $cert = $self->GetCertificate();
return undef return ContextError()
if (! (defined($geniuser) && defined($authority) && if (! (defined($geniuser) && defined($authority) &&
defined($context) && defined($cert))); defined($context) && defined($cert)));
my ($credential, $speaksfor_credential) = my ($credential, $speaksfor_credential) =
APT_Geni::GenCredentials($cert, $geniuser, ["blockstores"]); APT_Geni::GenCredentials($cert, $geniuser, ["blockstores"]);
return undef
return CredentialError
if (! (defined($speaksfor_credential) && if (! (defined($speaksfor_credential) &&
defined($credential))); defined($credential)));
...@@ -624,13 +637,13 @@ sub DeleteDataset($) ...@@ -624,13 +637,13 @@ sub DeleteDataset($)
my $geniuser = $self->GetGeniUser(); my $geniuser = $self->GetGeniUser();
my $context = APT_Geni::GeniContext(); my $context = APT_Geni::GeniContext();
my $cert = $self->GetCertificate(); my $cert = $self->GetCertificate();
return undef return ContextError()
if (! (defined($geniuser) && defined($authority) && if (! (defined($geniuser) && defined($authority) &&
defined($context) && defined($cert))); defined($context) && defined($cert)));
my ($credential, $speaksfor_credential) = my ($credential, $speaksfor_credential) =
APT_Geni::GenCredentials($cert, $geniuser, ["blockstores"], 1); APT_Geni::GenCredentials($cert, $geniuser, ["blockstores"], 1);
return undef return CredentialError()
if (!defined($credential)); if (!defined($credential));
my $credentials = [$credential->asString()]; my $credentials = [$credential->asString()];
...@@ -657,13 +670,13 @@ sub ModifyDataset($) ...@@ -657,13 +670,13 @@ sub ModifyDataset($)
my $geniuser = $self->GetGeniUser(); my $geniuser = $self->GetGeniUser();
my $context = APT_Geni::GeniContext(); my $context = APT_Geni::GeniContext();
my $cert = $self->GetCertificate(); my $cert = $self->GetCertificate();
return undef return ContextError()
if (! (defined($geniuser) && defined($authority) && if (! (defined($geniuser) && defined($authority) &&
defined($context) && defined($cert))); defined($context) && defined($cert)));
my ($credential, $speaksfor_credential) = my ($credential, $speaksfor_credential) =
APT_Geni::GenCredentials($cert, $geniuser, ["blockstores"], 1); APT_Geni::GenCredentials($cert, $geniuser, ["blockstores"], 1);
return undef return CredentialError()
if (!defined($credential)); if (!defined($credential));
my $credentials = [$credential->asString()]; my $credentials = [$credential->asString()];
...@@ -692,13 +705,13 @@ sub ExtendDataset($) ...@@ -692,13 +705,13 @@ sub ExtendDataset($)
my $geniuser = $self->GetGeniUser(); my $geniuser = $self->GetGeniUser();
my $context = APT_Geni::GeniContext(); my $context = APT_Geni::GeniContext();
my $cert = $self->GetCertificate(); my $cert = $self->GetCertificate();
return undef return ContextError()
if (! (defined($geniuser) && defined($authority) && if (! (defined($geniuser) && defined($authority) &&
defined($context) && defined($cert))); defined($context) && defined($cert)));
my ($credential, $speaksfor_credential) = my ($credential, $speaksfor_credential) =
APT_Geni::GenCredentials($cert, $geniuser, ["blockstores"], 1); APT_Geni::GenCredentials($cert, $geniuser, ["blockstores"], 1);
return undef return CredentialError()
if (!defined($credential)); if (!defined($credential));
my $credentials = [$credential->asString()]; my $credentials = [$credential->asString()];
...@@ -726,13 +739,13 @@ sub DescribeDataset($) ...@@ -726,13 +739,13 @@ sub DescribeDataset($)
my $geniuser = $self->GetGeniUser(); my $geniuser = $self->GetGeniUser();
my $context = APT_Geni::GeniContext(); my $context = APT_Geni::GeniContext();
my $cert = $self->GetCertificate(); my $cert = $self->GetCertificate();
return undef return ContextError()
if (! (defined($geniuser) && defined($authority) && if (! (defined($geniuser) && defined($authority) &&
defined($context) && defined($cert))); defined($context) && defined($cert)));
my ($credential, $speaksfor_credential) = my ($credential, $speaksfor_credential) =
APT_Geni::GenCredentials($cert, $geniuser, ["blockstores"], 1); APT_Geni::GenCredentials($cert, $geniuser, ["blockstores"], 1);
return undef return CredentialError()
if (!defined($credential)); if (!defined($credential));
my $credentials = [$credential->asString()]; my $credentials = [$credential->asString()];
...@@ -759,13 +772,13 @@ sub GetCredential($) ...@@ -759,13 +772,13 @@ sub GetCredential($)
my $geniuser = $self->GetGeniUser(); my $geniuser = $self->GetGeniUser();
my $context = APT_Geni::GeniContext(); my $context = APT_Geni::GeniContext();
my $cert = $self->GetCertificate(); my $cert = $self->GetCertificate();
return undef return ContextError()
if (! (defined($geniuser) && defined($authority) && if (! (defined($geniuser) && defined($authority) &&
defined($context) && defined($cert))); defined($context) && defined($cert)));
my ($credential) = my ($credential) =
APT_Geni::GenAuthCredential($cert, ["blockstores"]); APT_Geni::GenAuthCredential($cert, ["blockstores"]);
return undef return CredentialError()
if (!defined($credential)); if (!defined($credential));
my $args = { my $args = {
...@@ -789,13 +802,13 @@ sub ApproveDataset($) ...@@ -789,13 +802,13 @@ sub ApproveDataset($)
my $geniuser = $self->GetGeniUser(); my $geniuser = $self->GetGeniUser();
my $context = APT_Geni::GeniContext(); my $context = APT_Geni::GeniContext();
my $cert = $self->GetCertificate(); my $cert = $self->GetCertificate();
return undef return ContextError()
if (! (defined($geniuser) && defined($authority) && if (! (defined($geniuser) && defined($authority) &&
defined($context) && defined($cert))); defined($context) && defined($cert)));
my ($credential) = my ($credential) =
APT_Geni::GenAuthCredential($cert, ["admin"]); APT_Geni::GenAuthCredential($cert, ["admin"]);
return undef return CredentialError()
if (!defined($credential)); if (!defined($credential));
my $args = { my $args = {
......
#!/usr/bin/perl -wT #!/usr/bin/perl -wT
# #
# Copyright (c) 2007-2017 University of Utah and the Flux Group. # Copyright (c) 2007-2018 University of Utah and the Flux Group.
# #
# {{{EMULAB-LICENSE # {{{EMULAB-LICENSE
# #
...@@ -523,26 +523,62 @@ sub PortalRPC($$$@) ...@@ -523,26 +523,62 @@ sub PortalRPC($$$@)
if ($usemydevtree) { if ($usemydevtree) {
$cmurl =~ s/protogeni/protogeni\/stoller/; $cmurl =~ s/protogeni/protogeni\/stoller/;
} }
# #
# We use the root context to talk to the Cluster RPC server # We use the root context to talk to the Cluster RPC server
# #
if (!defined($context)) { if (!defined($context)) {
$context = RootContext(); $context = RootContext();
if (!defined($context)) { if (!defined($context)) {
return GeniResponse->Create(GENIRESPONSE_RPCERROR(), undef, return GeniResponse->Create(GENIRESPONSE_ERROR(), undef,
"Could not get root context for RPC"); "Could not get root context for RPC");
} }
} }
my $response = Genixmlrpc::CallMethod($cmurl, $context, $method, @args); my $response = Genixmlrpc::CallMethod($cmurl, $context, $method, @args);
if ($response->code() != GENIRESPONSE_SUCCESS()) { if ($response->code() != GENIRESPONSE_SUCCESS()) {
if (!defined($response->output())) { if (!defined($response->output())) {
$response->output("Operation failed, returned " . $response->output(GENIRESPONSE_STRING($response->code()));
$response->code());
} }
} }
return $response; return $response;
} }
#
# Ping an aggregate to see if its alive, using getversion.
#
sub PingAggregate($$;$)
{
my ($aggregate, $perrmsg, $portalrpc) = @_;
my $authority = GetAuthority($aggregate->urn());
my $context = RootContext();
if (!defined($authority)) {
$$perrmsg = "Could not lookup authority for $aggregate!";
return -1;
}
if (!defined($context)) {
$$perrmsg = "Could generate root context!";
return -1;
}
my $cmurl = $authority->url();
if (defined($portalrpc)) {
$cmurl =~ s/\/cm$/\/cluster/;
}
if ($usemydevtree) {
$cmurl =~ s/protogeni/protogeni\/stoller/;
}
my $oldto = Genixmlrpc->SetTimeout(10);
my $response = Genixmlrpc::CallMethod($cmurl, $context, "GetVersion");
Genixmlrpc->SetTimeout($oldto);
# Success is good!
return 0
if ($response->code() == GENIRESPONSE_SUCCESS());
#print STDERR Dumper($response);
$$perrmsg = $response->error();
return $response->code();
}
# _Always_ make sure that this 1 is at the end of the file... # _Always_ make sure that this 1 is at the end of the file...
1; 1;
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -81,12 +81,14 @@ use GeniXML; ...@@ -81,12 +81,14 @@ use GeniXML;
use GeniUser; use GeniUser;
use APT_Geni; use APT_Geni;
use APT_Profile; use APT_Profile;
use APT_Aggregate;
# Protos # Protos
sub fatal($); sub fatal($);
sub UserError($); sub UserError($);
sub DoListImages(); sub DoListImages();
sub DoDeleteImage(); sub DoDeleteImage();
sub ExitWithError($);
# #
# Parse command arguments. Once we return from getopts, all that should be # Parse command arguments. Once we return from getopts, all that should be
...@@ -162,9 +164,17 @@ sub DoListImages() ...@@ -162,9 +164,17 @@ sub DoListImages()
# Shorten default timeout. # Shorten default timeout.
Genixmlrpc->SetTimeout(90); Genixmlrpc->SetTimeout(90);
# Lets do a cluster check to make sure its reachable.
my $aggregate = APT_Aggregate->Lookup($aggregate_urn);
if (!defined($aggregate)) {
fatal("No such aggregate");
}
if ($aggregate->CheckStatus(\$errmsg)) {
UserError($errmsg);
}
my $authority = GeniAuthority->Lookup($aggregate_urn); my $authority = GeniAuthority->Lookup($aggregate_urn);
if (!defined($authority)) { if (!defined($authority)) {
fatal("No such aggregate"); fatal("No authority for aggregate");
} }
my $cmurl = $authority->url(); my $cmurl = $authority->url();
if ($usemydevtree) { if ($usemydevtree) {
...@@ -184,23 +194,8 @@ sub DoListImages() ...@@ -184,23 +194,8 @@ sub DoListImages()
my $response = Genixmlrpc::CallMethod($cmurl, undef, "ListImages", $args); my $response = Genixmlrpc::CallMethod($cmurl, undef, "ListImages", $args);
if ($response->code() != GENIRESPONSE_SUCCESS) { if ($response->code() != GENIRESPONSE_SUCCESS) {
if ($response->output()) { print STDERR $response->error() . "\n";
print STDERR $response->output() . "\n"; ExitWithError($response);
if (defined($webtask)) {
$webtask->output($response->output());
}
}
else {
print STDERR "Operation failed, returned " .
$response->code() . "\n";
if (defined($webtask)) {
$webtask->output("Operation failed");
}
}
if (defined($webtask)) {
$webtask->Exited($response->code());
}
exit($response->code());
} }
# #
# We get back a flat list, which can include mulitple versions of # We get back a flat list, which can include mulitple versions of
...@@ -526,9 +521,17 @@ sub DoDeleteImage() ...@@ -526,9 +521,17 @@ sub DoDeleteImage()
# Shorten default timeout. # Shorten default timeout.
Genixmlrpc->SetTimeout(90); Genixmlrpc->SetTimeout(90);
# Lets do a cluster check to make sure its reachable.
my $aggregate = APT_Aggregate->Lookup($aggregate_urn);
if (!defined($aggregate)) {
fatal("No such aggregate");
}
if ($aggregate->CheckStatus(\$errmsg)) {
UserError($errmsg);
}
my $authority = GeniAuthority->Lookup($aggregate_urn); my $authority = GeniAuthority->Lookup($aggregate_urn);
if (!defined($authority)) { if (!defined($authority)) {
fatal("No such aggregate"); fatal("No authority for aggregate");
} }
my $cmurl = $authority->url(); my $cmurl = $authority->url();
if ($usemydevtree) { if ($usemydevtree) {
...@@ -610,3 +613,33 @@ sub escapeshellarg($) ...@@ -610,3 +613,33 @@ sub escapeshellarg($)
return $str; return $str;
} }
#
# These are errors which the user might need to see. Some errors are
# exceptions though, and those we want to treat as internal errors.
#
sub ExitWithError($)
{
my ($response) = @_;
my $mesg = $response->error();
my $code = $response->code();
#
# In general, these errors are to be expected by the caller.
#
if ($code == GENIRESPONSE_REFUSED ||
$code == GENIRESPONSE_SEARCHFAILED ||
$code == GENIRESPONSE_SERVER_UNAVAILABLE ||
$code == GENIRESPONSE_NETWORK_ERROR ||
$code == GENIRESPONSE_BUSY) {
if (defined($webtask)) {
$webtask->output($mesg);
$webtask->Exited($code);
}
print STDERR "*** $0:\n".
" $mesg\n";
exit(1);
}
fatal($mesg);
}
This diff is collapsed.
This diff is collapsed.
#!/usr/bin/perl -w #!/usr/bin/perl -w
# #
# Copyright (c) 2008-2016 University of Utah and the Flux Group. # Copyright (c) 2008-2016, 2018 University of Utah and the Flux Group.
# #
# {{{GENIPUBLIC-LICENSE # {{{GENIPUBLIC-LICENSE
# #
...@@ -41,11 +41,9 @@ sub usage() ...@@ -41,11 +41,9 @@ sub usage()
} }
my $optlist = "da:"; my $optlist = "da:";
my $debug = 0; my $debug = 0;
my $errmsg;
my $aggurn; my $aggurn;
# For development.
my $usemydevtree = 0;
# #
# Configure variables # Configure variables
# #
...@@ -77,6 +75,8 @@ use GeniHRN; ...@@ -77,6 +75,8 @@ use GeniHRN;
use Genixmlrpc; use Genixmlrpc;
use GeniResponse; use GeniResponse;
use GeniAuthority; use GeniAuthority;
use APT_Aggregate;
use APT_Geni;
my %options = (); my %options = ();
if (! getopts($optlist, \%options)) { if (! getopts($optlist, \%options)) {
...@@ -103,15 +103,20 @@ Genixmlrpc->SetContext($context); ...@@ -103,15 +103,20 @@ Genixmlrpc->SetContext($context);
# Shorten default timeout. # Shorten default timeout.
Genixmlrpc->SetTimeout(15); Genixmlrpc->SetTimeout(15);
my $aggregate = APT_Aggregate->Lookup($aggurn);
if (!defined($aggregate)) {
fatal("No such aggregate: $aggurn");
}
my $authority = GeniAuthority->Lookup($aggurn); my $authority = GeniAuthority->Lookup($aggurn);
if (!defined($authority)) { if (!defined($authority)) {
fatal("No such aggregate: $aggurn"); fatal("No such aggregate authority: $aggurn");
} }
my $cmurl = $authority->url(); # Check online and reachable. Additional arg says to test Portal RPC.
$cmurl =~ s/\/cm$/\/cluster/; if ($aggregate->CheckStatus(\$errmsg, 1)) {
if ($usemydevtree) { print STDERR $errmsg . "\n";
$cmurl =~ s/protogeni/protogeni\/stoller/; exit(1);
} }
my @args = (); my @args = ();
if (@ARGV) { if (@ARGV) {
my $args = {}; my $args = {};
...@@ -128,16 +133,11 @@ if (@ARGV) { ...@@ -128,16 +133,11 @@ if (@ARGV) {
@args = ($args); @args = ($args);
} }
my $starttime = [gettimeofday()]; my $starttime = [gettimeofday()];
my $response = Genixmlrpc::CallMethod($cmurl, undef, $method, @args); my $response = APT_Geni::PortalRPC($authority, undef, $method, @args);
my $elapsed = tv_interval($starttime); my $elapsed = tv_interval($starttime);
if ($response->code() != GENIRESPONSE_SUCCESS) { if ($response->code() != GENIRESPONSE_SUCCESS) {
if ($response->output()) { print STDERR $response->error() . "\n";
print STDERR $response->output() . "\n";
}
else {
print STDERR "Operation failed, returned " . $response->code() . "\n";
}
exit($response->code()); exit($response->code());
} }
print encode_json($response->value()); print encode_json($response->value());
......
#!/usr/bin/perl -wT #!/usr/bin/perl -wT
# #
# Copyright (c) 2013-2017 University of Utah and the Flux Group. # Copyright (c) 2013-2018 University of Utah and the Flux Group.
# #
# {{{EMULAB-LICENSE # {{{EMULAB-LICENSE
# #
...@@ -71,7 +71,7 @@ sub Lookup($$) ...@@ -71,7 +71,7 @@ sub Lookup($$)
$self->{'DATA'} = $self->{'DATA'} =
eval { decode_json($self->{'DBROW'}->{'task_data'}); }; eval { decode_json($self->{'DBROW'}->{'task_data'}); };
if ($@) { if ($@) {
print STDERR "Could not json decode task data\n"; print STDERR "Could not json decode task data: $@\n";
return undef return undef
} }
} }
...@@ -236,7 +236,7 @@ sub Store($) ...@@ -236,7 +236,7 @@ sub Store($)
my $id = $self->{'DBROW'}->{'task_id'}; my $id = $self->{'DBROW'}->{'task_id'};
my $data = eval { encode_json($self->{'DATA'}); }; my $data = eval { encode_json($self->{'DATA'}); };
if ($@) {