Commit e9dedfc7 authored by Leigh Stoller's avatar Leigh Stoller

Another round of fixes and improvements to previous revision.

parent 0a06db53
......@@ -2660,19 +2660,19 @@ sub SliceResolve($)
sub Provision($$$$)
{
my ($self, $perrmsg, $users, $cert, $key) = @_;
my ($self, $users, $cert, $key) = @_;
my $authority = $self->GetGeniAuthority();
my $urn = $self->aggregate_urn();
my $geniuser = $self->instance()->GetGeniUser();
my $slice = $self->instance()->GetGeniSlice();
my $context = APT_Geni::GeniContext();
return -1
return ContextError()
if (! (defined($geniuser) && defined($authority) &&
defined($slice) && defined($context)));
my ($slice_credential, $speaksfor_credential) =
APT_Geni::GenCredentials($slice, $geniuser, undef, 0);
return -1
return CredentialError()
if (! (defined($speaksfor_credential) &&
defined($slice_credential)));
......@@ -2701,31 +2701,7 @@ sub Provision($$$$)
$cmurl = devurl($cmurl) if ($usemydevtree);
$cmurl .= "/3.0";
my $tries = 10;
while ($tries) {
my $response =
Genixmlrpc::CallMethod($cmurl, $context, "Provision", @params);
if (defined($response) && defined($response->logurl())) {
$self->SetPublicURL($response->logurl());
}
if (!defined($response) || $response->code() != GENIRESPONSE_SUCCESS) {
if (defined($response) &&
($response->code() == GENIRESPONSE_SERVER_UNAVAILABLE ||
$response->code() == GENIRESPONSE_BUSY) &&
$tries >= 0) {
print STDERR "Server for $urn reports too busy or slice busy, ".
"waiting a while ...\n";
sleep(int(rand(20)) + 10);
$tries--;
next;
}
$$perrmsg = $response->error();
return -1;
}
last;
}
return 0;
return Genixmlrpc::CallMethod($cmurl, $context, "Provision", @params);
}
#
......@@ -3141,8 +3117,8 @@ sub WaitForSliver($)
my $ready = 0;
my $failed = 0;
my $rpcfail = 0;
my $async_code;
my $async_output;
my $failure_code;
my $failure_output;
my $repblob;
my $laststatus;
......@@ -3158,7 +3134,8 @@ sub WaitForSliver($)
$response->code() != GENIRESPONSE_SERVER_UNAVAILABLE &&
$response->code() != GENIRESPONSE_BUSY &&
$response->code() != GENIRESPONSE_NETWORK_ERROR)) {
print STDERR "SliverStatus failed: " . $response->error() . "\n";
$failure_code = $response->code();
$failure_output = "SliverStatus failed: " . $response->error();
$failed = 1;
last;
}
......@@ -3251,8 +3228,8 @@ sub WaitForSliver($)
#
if (exists($repblob->{'async_code'})) {
# We are getting back async error status.
$async_code = $repblob->{'async_code'};
$async_output = $repblob->{'async_output'};
$failure_code = $repblob->{'async_code'};
$failure_output = $repblob->{'async_output'};
$failed = 1;
last;
}
......@@ -3261,13 +3238,20 @@ sub WaitForSliver($)
last;
}
elsif ($repblob->{'status'} eq "failed") {
print STDERR Dumper($repblob);
$failed = 1;
my $msg = $repblob->{'error'}
if (defined($repblob->{'error'}) && $repblob->{'error'} ne "");
print STDERR "*** $urn failed\n";
print STDERR " " . $repblob->{'error'} . "\n" if ($msg);
$webtask->output("Experiment setup on the $aggname cluster failed" .
($msg ? ": $msg" : "."));
$failure_code = GENIRESPONSE_SETUPFAILURE_BOOTFAILED();
# Backwards compat; boot_failure is new, and used to be only 1.
# If it is not set, that usually means node failure.
if (exists($repblob->{"boot_failure"})) {
if ($repblob->{"boot_failure"} > 1) {
$failure_code = $repblob->{"boot_failure"};
}
}
$failure_output = "Experiment setup on the $aggname cluster failed";
if (exists($repblob->{'error'}) && $repblob->{'error'} ne "") {
$failure_output .= ": " . $repblob->{'error'};
}
last;
}
elsif ($aggobj->instance()->IsCanceled()) {
......@@ -3281,23 +3265,22 @@ sub WaitForSliver($)
if ($failed || !$ready) {
$aggobj->SetStatus("failed");
if ($failed) {
if (defined($async_code)) {
$webtask->output($async_output);
$webtask->Exited($async_code);
}
else {
# Output set above.
$webtask->Exited(GENIRESPONSE_ERROR);
}
print STDERR "*** $urn failure\n";
print STDERR " $failure_output\n";
$webtask->output($failure_output);
$webtask->Exited($failure_code);
}
elsif (!$ready) {
# XXX Need better handling for timeout.
print STDERR "*** $urn timed out.\n";
$webtask->output("Experiment setup on $urn timed out");
$webtask->output("Experiment setup on the $aggobj cluster".
"timed out");
$webtask->Exited(GENIRESPONSE_TIMEDOUT);
}
else {
$webtask->Exited(1);
print STDERR "*** $urn unknown error\n";
$webtask->output("Unknown setup failure on the $aggobj cluster");
$webtask->Exited(GENIRESPONSE_ERROR);
}
return $webtask->exitcode();
}
......
This diff is collapsed.
......@@ -2722,9 +2722,8 @@ sub StartMonitorInternal(;$)
# going to ready, if we failed initially, the user can get
# themselves out of failure mode for the instance, say by
# reboot or reload.
$sliver->SetStatus("ready")
if ($sliver->status() eq "failed");
$sliver->SetStatus("ready");
return $response
if (!$executing || !$waitforstartup);
}
......@@ -2772,6 +2771,8 @@ sub StartMonitorInternal(;$)
foreach my $aggregate (@aggregates) {
my $response = shift(@{$response});
my $code = $response->code();
# Updated in the forked child, need to refresh.
$aggregate->Refresh();
next
if ($code == GENIRESPONSE_SUCCESS);
......@@ -4260,9 +4261,10 @@ sub CallMethodOnAggregates($$$@)
my $response;
if (0) {
# Need unblessed ref to store into webtask.
$response =
GeniResponse->new(GENIRESPONSE_SERVER_UNAVAILABLE,
undef, "Testing mode");
GeniResponse->Create(GENIRESPONSE_SERVER_UNAVAILABLE,
undef, "Testing mode");
$webtask->response($response);
return -1;
}
......@@ -4273,9 +4275,10 @@ sub CallMethodOnAggregates($$$@)
# the clusters that are up (say, terminate).
#
if ($aggregate->CheckStatus(\$errmsg)) {
# Need unblessed ref to store into webtask.
$response =
GeniResponse->new(GENIRESPONSE_SERVER_UNAVAILABLE,
undef, $errmsg);
GeniResponse->Create(GENIRESPONSE_SERVER_UNAVAILABLE,
undef, $errmsg);
$webtask->response($response);
return -1;
}
......@@ -4297,6 +4300,8 @@ sub CallMethodOnAggregates($$$@)
"$sliver");
last;
}
print Dumper($response);
# We can keep trying for these, but not an RPC error.
last
if (! ($response->code() == GENIRESPONSE_BUSY ||
......@@ -4312,7 +4317,8 @@ sub CallMethodOnAggregates($$$@)
sleep(15);
}
}
$webtask->response($response);
# Need unblessed ref to store into webtask.
$webtask->response($response->Unbless());
return ($response->code() == GENIRESPONSE_SUCCESS ? 0 : -1);
};
my @return_codes = ();
......@@ -4329,8 +4335,10 @@ sub CallMethodOnAggregates($$$@)
@return_codes = (&$coderef([$aggregate, $method, $webtask]));
}
else {
my @tmp = map { [$_, $method, $webtask] } @aggregates;
my @tmp = ();
for (my $i = 0; $i < scalar(@aggregates); $i++) {
push(@tmp, [$aggregates[$i], $method, $webtasks[$i]]);
}
if (ParRun({"maxwaittime" => 99999,
"maxchildren" => scalar(@aggregates)},
\@return_codes, $coderef, @tmp)) {
......@@ -4345,10 +4353,12 @@ sub CallMethodOnAggregates($$$@)
#
foreach my $agg (@aggregates) {
my $webtask = shift(@webtasks);
print "$agg\n";
# No need to refresh if we did not use ParRun above.
$webtask->Refresh() if (@aggregates > 1);
push(@return_values, $webtask->response());
push(@return_values, GeniResponse->Bless($webtask->response()));
}
$$prval = \@return_values;
map { $_->Delete(); } @webtasks;
......
......@@ -277,6 +277,10 @@ sub DoReserve()
$rpcargs{"reason"}= $reason if (defined($reason));
$rpcargs{"update"}= $update if (defined($update));
# We can check for disabled aggregate now, nothing below matters.
if ($aggregate->CheckStatus(\$errmsg, 1)) {
UserError($errmsg);
}
if ($this_user->IsAdmin()) {
#
# We do not have a very good notion of cross site admin.
......@@ -305,10 +309,6 @@ sub DoReserve()
$rpcargs{"credentials"} = $credentials;
$context = APT_Geni::GeniContext();
}
# We can check for disabled aggregate now, nothing below matters.
if ($aggregate->CheckStatus(\$errmsg, 1)) {
UserError($errmsg);
}
my $response =
APT_Geni::PortalRPC($authority, $context, "Reserve", \%rpcargs);
if (GeniResponse::IsError($response)) {
......@@ -805,7 +805,8 @@ sub DoPrediction()
my $optlist = "p:";
my $portal;
my $errmsg;
my @aggregates = ($authority);
my @aggregates = ($aggregate);
my @authorities = ($authority);
my @webtasks = ();
my @projlist = ();
my $blob = {};
......@@ -846,7 +847,8 @@ sub DoPrediction()
# all aggregates listed for the portal.
#
if (defined($portal)) {
@aggregates = ();
@authorities = ();
@aggregates = ();
my @list = APT_Aggregate->LookupForPortal($portal);
foreach my $agg (@list) {
......@@ -860,24 +862,30 @@ sub DoPrediction()
$errmsg = "Cannot lookup authority for $agg";
goto bad;
}
push(@aggregates, $authority);
push(@aggregates, $agg);
push(@authorities, $authority);
}
if (!@aggregates) {
UserError("No clusters are online, please try again later.");
}
}
else {
if ($aggregate->disabled()) {
UserError("The " . $aggregate->name() . " cluster ".
"is currently offline, please try again later.");
}
}
my $coderef = sub {
my ($blob) = @_;
my $authority = $blob->{"authority"};
my $aggregate = $blob->{"aggregate"};
my $webtask = $blob->{"webtask"};
my $errmsg;
if ($aggregate->CheckStatus(\$errmsg, 1)) {
# Need unblessed ref to store into webtask.
my $response =
GeniResponse->Create(GENIRESPONSE_SERVER_UNAVAILABLE,
undef, $errmsg);
$webtask->response($response);
print "$aggregate offline\n";
return 1;
}
# PortalRPC will use the root context in this case, which is
# essentially saying the caller is an admin. But thats okay
# for this call, it is just informational.
......@@ -885,6 +893,10 @@ sub DoPrediction()
APT_Geni::PortalRPC($authority, undef,
"ReservationPrediction",
{"projlist" => \@projlist});
# Need unblessed ref to store into webtask.
$response = GeniResponse->Create($response->code(),
$response->value(),
$response->output);
$webtask->response($response);
if (GeniResponse::IsError($response)) {
......@@ -898,11 +910,16 @@ sub DoPrediction()
# Do not bother with ParRun if only one aggregate.
#
if (@aggregates == 1) {
my $authority = $aggregates[0];
my $authority = $authorities[0];
my $aggregate = $aggregates[0];
my $temptask = WebTask->CreateAnonymous();
my $retval = &$coderef({"authority" => $authority,
my $retval = &$coderef({"aggregate" => $aggregate,
"authority" => $authority,
"webtask" => $temptask});
my $response = $temptask->response();
my $response = $temptask->response();
# No longer a blessed object (see above).
$response = GeniResponse->Bless($response);
$temptask->Delete();
if ($retval == 0) {
......@@ -920,12 +937,17 @@ sub DoPrediction()
my @return_codes = ();
my @agglist = ();
foreach my $auth (@aggregates) {
while (@aggregates) {
my $aggregate = shift(@aggregates);
my $authority = shift(@authorities);
my $temptask = WebTask->CreateAnonymous();
$temptask->AutoStore(1);
# For delete below.
push(@webtasks, $temptask);
push(@agglist, {"authority" => $auth,
push(@agglist, {"aggregate" => $aggregate,
"authority" => $authority,
"webtask" => $temptask});
}
if (ParRun({"maxwaittime" => 30,
......@@ -939,12 +961,16 @@ sub DoPrediction()
#
# Check the exit codes, create return structure for the web interface.
#
foreach my $agg (@agglist) {
foreach my $ref (@agglist) {
my $code = shift(@return_codes);
my $auth = $agg->{'authority'};
my $wtask = $agg->{'webtask'};
my $auth = $ref->{'authority'};
my $agg = $ref->{'aggregate'};
my $wtask = $ref->{'webtask'};
$wtask->Refresh();
my $response = $wtask->response();
# No longer a blessed object (see above).
$response = GeniResponse->Bless($response);
if ($code) {
#
......@@ -953,12 +979,12 @@ sub DoPrediction()
# server from operating normally.
#
my $msg = "Could not get reservation data: ".
$wtask->response()->error();
$response->error();
$blob->{$auth->urn()} = $msg;
print STDERR $msg . "\n";
}
$blob->{$auth->urn()} = $wtask->response()->value();
$blob->{$auth->urn()} = $response->value();
}
done:
if (defined($webtask)) {
......
#!/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
#
......@@ -71,7 +71,7 @@ sub Lookup($$)
$self->{'DATA'} =
eval { decode_json($self->{'DBROW'}->{'task_data'}); };
if ($@) {
print STDERR "Could not json decode task data\n";
print STDERR "Could not json decode task data: $@\n";
return undef
}
}
......@@ -236,7 +236,7 @@ sub Store($)
my $id = $self->{'DBROW'}->{'task_id'};
my $data = eval { encode_json($self->{'DATA'}); };
if ($@) {
print STDERR "Could not json encode task data\n";
print STDERR "Could not json encode task data: $@\n";
return -1;
}
$data = emdb::DBQuoteSpecial($data);
......@@ -274,7 +274,7 @@ sub Refresh($)
$self->{'DATA'} =
eval { decode_json($self->{'DBROW'}->{'task_data'}); };
if ($@) {
print STDERR "Could not json decode task data\n";
print STDERR "Could not json decode task data: $@\n";
return -1;
}
}
......
......@@ -51,6 +51,7 @@ use GeniUtil;
use GeniUser;
use GeniComponent;
use GeniHRN;
use GeniResponse;
use GeniEvent;
use GeniXML;
use GeniCM;
......@@ -732,9 +733,10 @@ sub SetErrorLog($$)
return 0;
}
sub SetBootFailure($)
sub SetBootFailure($;$)
{
my ($self) = @_;
my ($self, $code) = @_;
$code = GENIRESPONSE_SETUPFAILURE() if (!defined($code));
return undef
if (! ref($self));
......@@ -743,10 +745,10 @@ sub SetBootFailure($)
return -1
if (!DBQueryWarn("update geni_aggregates set ".
" boot_failure='1' ".
" boot_failure='$code' ".
"where idx='$idx'"));
$self->{'AGGREGATE'}->{'boot_failure'} = 1;
$self->{'AGGREGATE'}->{'boot_failure'} = $code;
return 0;
}
......@@ -1067,15 +1069,18 @@ sub Reload($$;$)
sub ActionStart($$;$)
{
my ($self, $version, $flags) = @_;
$self->ClearBootFailure();
my $msg = "Internal Error: ";
my $msg = "SliverStart: ";
my $bootfailure_code = GENIRESPONSE_SETUPFAILURE();
$flags = 0 if (!defined($flags));
require Lan;
require OSImage;
require libossetup;
#die("Yippie");
# Clear last error.
$self->SetErrorLog("");
$self->ClearBootFailure();
# Set new status so ComputeState() knows what is going on.
$self->SetStatus("working");
......@@ -1272,48 +1277,15 @@ sub ActionStart($$;$)
$msg .= "$NAMEDSETUP failed\n";
goto bad;
}
if (0) {
DebugTimeStamp("snmpit");
if ($flags & $ACTION_FLAGS_SYNCVLANS) {
if (Lan->CompareVlansWithSwitches2($experiment)) {
$msg .= "CompareVlansWithSwitches2 failed!\n";
goto bad;
}
system("$SNMPIT -X $pid $eid");
if ($?) {
$msg .= "Failed to synchronize vlans";
goto bad;
}
}
else {
my @diff = ();
my @same = ();
if (Lan->CompareVlansWithSwitches($experiment, \@diff, \@same)) {
print STDERR "CompareVlansWithSwitches failed!\n";
goto bad;
}
if (@diff) {
system("$SNMPIT -f ". join(" ", map("-o $_", @diff)));
if ($?) {
$msg .= "Failed to remove obsolete VLANs.";
goto bad;
}
}
system("$SNMPIT -t $pid $eid");
if ($?) {
$msg .= "Failed to setup vlans";
goto bad;
}
}
}
DebugTimeStamp("setuportvlans");
if ($experiment->SetupPortLans()) {
$bootfailure_code = GENIRESPONSE_SETUPFAILURE_NETWORK();
$msg .= "Failed to setup shared vlan ports";
goto bad;
}
DebugTimeStamp("syncportvlans");
if ($experiment->SyncPortLans()) {
$bootfailure_code = GENIRESPONSE_SETUPFAILURE_NETWORK();
$msg .= "Failed to add ports to shared vlans";
goto bad;
}
......@@ -1409,7 +1381,7 @@ sub ActionStart($$;$)
my $node = $nodes{$node_id};
$node->Refresh();
# os_setup will make failed nodes
# os_setup will set failed nodes to this state.
if ($node->allocstate() eq TBDB_ALLOCSTATE_DOWN()) {
push(@failed, $node);
$node->_sliver()->SetState("failed")
......@@ -1472,7 +1444,8 @@ sub ActionStart($$;$)
my $kid = waitpid($snmpit_child, 0);
if ($kid == $snmpit_child) {
if ($?) {
$msg = "Failed to set up networks\n";
$msg .= "Failed to set up experimental networks\n";
$bootfailure_code = GENIRESPONSE_SETUPFAILURE_NETWORK();
goto bad;
}
else {
......@@ -1480,11 +1453,15 @@ sub ActionStart($$;$)
}
}
else {
$msg = "Waitpid for snmpit process problem: $kid";
$bootfailure_code = GENIRESPONSE_SETUPFAILURE_NETWORK();
$msg .= "Waitpid for snmpit process problem: $kid";
goto bad;
}
}
if ($rval) {
if ($rval < 0) {
# More serious error. Otherwise if its just that some nodes
# failed, we will catch that below.
$bootfailure_code = GENIRESPONSE_SETUPFAILURE_OSSETUP();
$msg .= "Unable to OS setup nodes\n";
goto bad;
}
......@@ -1534,6 +1511,7 @@ sub ActionStart($$;$)
print STDERR "$msg\n";
}
else {
$bootfailure_code = GENIRESPONSE_SETUPFAILURE_EVENTSYS();
goto bad;
}
}
......@@ -1544,14 +1522,14 @@ sub ActionStart($$;$)
}
if (@failed) {
my @node_ids = map { $_->node_id() } @failed;
$self->SetBootFailure();
$self->SetBootFailure(GENIRESPONSE_SETUPFAILURE_BOOTFAILED());
$self->SetErrorLog("The following nodes failed to setup: " .
join(" ", @node_ids));
}
elsif (0) {
# Testing.
$self->SetBootFailure();
$self->SetErrorLog("Testing");
$self->SetBootFailure(GENIRESPONSE_SETUPFAILURE_NETWORK);
$self->SetErrorLog("Testing network failure");
}
# This has to be last so that SliverStatus() does not hand back a
# ready or failed state until we are fully done here.
......@@ -1560,7 +1538,7 @@ sub ActionStart($$;$)
return 0;
bad:
$self->SetBootFailure();
$self->SetBootFailure($bootfailure_code);
if (defined($msg)) {
$self->SetErrorLog($msg);
print STDERR "$msg\n";
......@@ -1648,8 +1626,8 @@ sub ActionRestart($$;$)
sub Action($$$;$)
{
my ($self, $version, $action, $flags) = @_;
$self->ClearBootFailure();
my $msg = "Internal Error: ";
my $bootfailure_code = GENIRESPONSE_SETUPFAILURE();
my $restart = ($action eq "restart" ? 1 : 0);
my $reload = ($action eq "reload" ? 1 : 0);
$flags = 0 if (!defined($flags));
......@@ -1661,6 +1639,7 @@ sub Action($$$;$)
# Clear last error.
$self->SetErrorLog("");
$self->ClearBootFailure();
# Set new status so ComputeState() knows what is going on.
$self->SetStatus("working");
......@@ -2112,7 +2091,7 @@ sub Action($$$;$)
$sliver = undef;
# Want to make sure we see fresh logs (and do not store the same log).
foreach my $node (@waitpnodes, @waitpnodes) {
foreach my $node (@waitpnodes, @waitvnodes) {
$node->ClearBootLog();
}
......@@ -2523,6 +2502,22 @@ sub Action($$$;$)
}
}
}
if (0) {
# Testing.
@failed = (@waitpnodes, @waitvnodes);
}
if (@failed) {
my @node_ids = map { $_->node_id() } @failed;
$self->SetBootFailure(GENIRESPONSE_SETUPFAILURE_BOOTFAILED());
$self->SetErrorLog("The following nodes failed to setup: " .
join(" ", @node_ids));
}
elsif (0) {
# Testing.
$self->SetBootFailure(GENIRESPONSE_SETUPFAILURE);
$self->SetErrorLog("Testing");
}
# Allow ComputeState to do its thing.
$self->SetStatus("mixed");
$self->ComputeState();
return 0;
......@@ -2536,7 +2531,7 @@ sub Action($$$;$)
$osload_object->osload_kill($childpid);
}
}
$self->SetBootFailure();
$self->SetBootFailure($bootfailure_code);
if (defined($msg)) {
$self->SetErrorLog($msg);
print STDERR "$msg\n";
......@@ -3007,13 +3002,13 @@ sub WaitForNodes($$$$@)
sub Stop($$;$)
{
my ($self, $version, $flags) = @_;
$self->ClearBootFailure();
my $msg = "Internal Error: ";
return -1
if (! ref($self));
# Clear last error.
$self->ClearBootFailure();
$self->SetErrorLog("");
my $experiment = Experiment->Lookup($self->slice_uuid());
......@@ -3163,11 +3158,15 @@ sub BatchAction($$@)
my $restart = ($action eq "restart" ? 1 : 0);
my $reload = ($action eq "reload" ? 1 : 0);
# Clear last error.
$self->SetErrorLog("");
$self->ClearBootFailure();
# Set new status so ComputeState() knows what is going on.
$self->SetStatus("working");
# Clear last error.
$self->SetErrorLog("");
# Clear boot failure but only if its for failed nodes. If the user
# gets all the nodes running, the state will flip to ready. We cannot
# clear other failures here.
$self->ClearBootFailure()
if ($self->boot_failure() == GENIRESPONSE_SETUPFAILURE_BOOTFAILED());
my $experiment = Experiment->Lookup($self->slice_uuid());
if (!defined($experiment)) {
......@@ -3620,7 +3619,7 @@ sub ComputeState($)
else {
$newstatus = "mixed";
}
if ($boot_failure == 1) {
if ($boot_failure) {
$newstatus = "failed";
}
$self->SetStateStatus($newstate, $newstatus);
......
......@@ -507,7 +507,8 @@ sub GetTicket($;$)
"ticket" => $ticket,
"speaksfor" => undef,
"morecreds" => [],
"async" => 0});
"async" => 0,
"slice" => undef});
}
sub GetTicketAux($)
......@@ -524,6 +525,8 @@ sub GetTicketAux($)
my $speaksfor = $argref->{"speaksfor"};
my $morecreds = $argref->{"morecreds"};
my $async = $argref->{"async"};
my $slice = $argref->{"slice"};
my $nolock = (defined($slice) ? 1 : 0);
defined($credential) &&
($credential->HasPrivilege( "pi" ) or
......@@ -548,22 +551,23 @@ sub GetTicketAux($)
#
# Create slice from the certificate.
#
my $slice = GeniSlice->Lookup($slice_urn);
if (!defined($slice)) {
if ($isupdate) {
print STDERR "Could not locate slice $slice_urn for Update\n";
return GeniResponse->Create(GENIRESPONSE_ERROR, undef,
"No slice found for UpdateTicket");
$slice = GeniSlice->Lookup($slice_urn);
if (!defined($slice)) {
if ($isupdate) {
print STDERR "Could not locate slice $slice_urn for Update\n";
return GeniResponse->Create(GENIRESPONSE_ERROR, undef,
"No slice found for UpdateTicket");
}
$slice = CreateSliceFromCertificate($credential, $user);
return $slice
if (GeniResponse::IsResponse($slice));
}
$slice = CreateSliceFromCertificate($credential, $user);
return $slice
if (GeniResponse::IsResponse($slice));