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

Checkpoint multisite topology code. Work in progress.

parent 9f49096b
This diff is collapsed.
......@@ -781,85 +781,12 @@ sub UpdateDiskImage($$@)
return 0;
}
#
# We need to convert from using URNs to using URLs for disk images,
# since we want to support choosing the backend. This list is the
# list as of the conversion, at the APT. Before we instantiate, look
# at the rspec and update the URNs to URLs based on this list.
#
my %APTImages = (
'urn:publicid:IDN+utahddc.geniracks.net+image+emulab-net:demo-profile' => 'https://www.apt.emulab.net/image_metadata.php?uuid=39383c39-7b2f-11e4-9439-db9edc46fe2c',
'urn:publicid:IDN+utahddc.geniracks.net+image+emulab-net:docker' => 'https://www.apt.emulab.net/image_metadata.php?uuid=5ae53ff8-7b2f-11e4-9439-db9edc46fe2c',
'urn:publicid:IDN+utahddc.geniracks.net+image+emulab-net:docker-running-env' => 'https://www.apt.emulab.net/image_metadata.php?uuid=a1317423-7b2f-11e4-9439-db9edc46fe2c',
'urn:publicid:IDN+utahddc.geniracks.net+image+emulab-net:docker-running-env-02' => 'https://www.apt.emulab.net/image_metadata.php?uuid=f30e8657-7b2f-11e4-9439-db9edc46fe2c',
'urn:publicid:IDN+utahddc.geniracks.net+image+emulab-net:Docker1' => 'https://www.apt.emulab.net/image_metadata.php?uuid=31d9f5c1-7b30-11e4-9439-db9edc46fe2c',
'urn:publicid:IDN+utahddc.geniracks.net+image+emulab-net:ESA' => 'https://www.apt.emulab.net/image_metadata.php?uuid=72d94622-7b35-11e4-9439-db9edc46fe2c',
'urn:publicid:IDN+utahddc.geniracks.net+image+emulab-net:firstclone' => 'https://www.apt.emulab.net/image_metadata.php?uuid=d49e30a8-7b31-11e4-9439-db9edc46fe2c',
'urn:publicid:IDN+utahddc.geniracks.net+image+emulab-net:FPTaylorVM' => 'https://www.apt.emulab.net/image_metadata.php?uuid=f2e99dbe-7b31-11e4-9439-db9edc46fe2c',
'urn:publicid:IDN+utahddc.geniracks.net+image+emulab-net:FrequentDirection' => 'https://www.apt.emulab.net/image_metadata.php?uuid=1c6b4e98-7b32-11e4-9439-db9edc46fe2c',
'urn:publicid:IDN+utahddc.geniracks.net+image+emulab-net:geni-lib' => 'https://www.apt.emulab.net/image_metadata.php?uuid=441fc279-7b32-11e4-9439-db9edc46fe2c',
'urn:publicid:IDN+utahddc.geniracks.net+image+emulab-net:gimiovsomf6' => 'https://www.apt.emulab.net/image_metadata.php?uuid=626184be-7b32-11e4-9439-db9edc46fe2c',
'urn:publicid:IDN+utahddc.geniracks.net+image+emulab-net:hadoop' => 'https://www.apt.emulab.net/image_metadata.php?uuid=ffa8f859-3524-11e4-8944-81966d62745f',
'urn:publicid:IDN+utahddc.geniracks.net+image+emulab-net:hg' => 'https://www.apt.emulab.net/image_metadata.php?uuid=91dcd7d5-7b32-11e4-9439-db9edc46fe2c',
'urn:publicid:IDN+utahddc.geniracks.net+image+emulab-net:imageusage' => 'https://www.apt.emulab.net/image_metadata.php?uuid=adc61bad-7b32-11e4-9439-db9edc46fe2c',
'urn:publicid:IDN+utahddc.geniracks.net+image+emulab-net:Iperf' => 'https://www.apt.emulab.net/image_metadata.php?uuid=d0c8aba4-7b32-11e4-9439-db9edc46fe2c',
'urn:publicid:IDN+utahddc.geniracks.net+image+emulab-net:labwikiXORP' => 'https://www.apt.emulab.net/image_metadata.php?uuid=eee5f68d-7b32-11e4-9439-db9edc46fe2c',
'urn:publicid:IDN+utahddc.geniracks.net+image+emulab-net:myapt' => 'https://www.apt.emulab.net/image_metadata.php?uuid=13baa069-7b33-11e4-9439-db9edc46fe2c',
'urn:publicid:IDN+utahddc.geniracks.net+image+emulab-net:myclone' => 'https://www.apt.emulab.net/image_metadata.php?uuid=301d4978-7b33-11e4-9439-db9edc46fe2c',
'urn:publicid:IDN+utahddc.geniracks.net+image+emulab-net:myimage' => 'https://www.apt.emulab.net/image_metadata.php?uuid=03a342be-7b2c-11e4-9439-db9edc46fe2c',
'urn:publicid:IDN+utahddc.geniracks.net+image+emulab-net:myvm' => 'https://www.apt.emulab.net/image_metadata.php?uuid=6334cf1c-7a59-11e4-9439-db9edc46fe2c',
'urn:publicid:IDN+utahddc.geniracks.net+image+emulab-net:myvm2' => 'https://www.apt.emulab.net/image_metadata.php?uuid=aa8b3638-7a79-11e4-9439-db9edc46fe2c',
'urn:publicid:IDN+utahddc.geniracks.net+image+emulab-net:ricci-cav-2014' => 'https://www.apt.emulab.net/image_metadata.php?uuid=b3d6f6f7-7b35-11e4-9439-db9edc46fe2c',
'urn:publicid:IDN+utahddc.geniracks.net+image+emulab-net:rob-profile' => 'https://www.apt.emulab.net/image_metadata.php?uuid=31278fc7-7b34-11e4-9439-db9edc46fe2c',
'urn:publicid:IDN+utahddc.geniracks.net+image+emulab-net:robtestimage' => 'https://www.apt.emulab.net/image_metadata.php?uuid=4d43d6bb-7b34-11e4-9439-db9edc46fe2c',
'urn:publicid:IDN+utahddc.geniracks.net+image+emulab-net:singlenodelime' => 'https://www.apt.emulab.net/image_metadata.php?uuid=60905cf9-7b34-11e4-9439-db9edc46fe2c',
'urn:publicid:IDN+utahddc.geniracks.net+image+emulab-net:singlenodelime-2' => 'https://www.apt.emulab.net/image_metadata.php?uuid=8db24268-7b34-11e4-9439-db9edc46fe2c',
'urn:publicid:IDN+utahddc.geniracks.net+image+emulab-net:singlevmlime' => 'https://www.apt.emulab.net/image_metadata.php?uuid=b192a572-7b34-11e4-9439-db9edc46fe2c',
'urn:publicid:IDN+utahddc.geniracks.net+image+emulab-net:smack-cav2014-test' => 'https://www.apt.emulab.net/image_metadata.php?uuid=a4594b69-7b36-11e4-9439-db9edc46fe2c',
'urn:publicid:IDN+utahddc.geniracks.net+image+emulab-net:ubuntu1204maas' => 'https://www.apt.emulab.net/image_metadata.php?uuid=e532f26d-7b36-11e4-9439-db9edc46fe2c',
'urn:publicid:IDN+utahddc.geniracks.net+image+emulab-net:Ubuntu1404' => 'https://www.apt.emulab.net/image_metadata.php?uuid=0838c611-7b37-11e4-9439-db9edc46fe2c'
);
sub ConvertDiskImages($)
{
my ($self) = @_;
my $modified = 0;
my $rspec = GeniXML::Parse($self->rspec());
if (! defined($rspec)) {
print STDERR "Could not parse rspec\n";
return -1;
}
foreach my $ref (GeniXML::FindNodes("n:node", $rspec)->get_nodelist()) {
my $diskref = GeniXML::GetDiskImage($ref);
next
if (!defined($diskref));
my $imageurn = GeniXML::GetText("name", $diskref);
next
if (!defined($imageurn));
if (exists($APTImages{$imageurn})) {
GeniXML::SetDiskImage($ref, $APTImages{$imageurn});
$modified = 1;
}
}
if ($modified) {
$self->{'DBROW'}->{'rspec'} = GeniXML::Serialize($rspec);
my $profileid = $self->profileid();
my $version = $self->version();
my $safe_rspec = DBQuoteSpecial($self->rspec());
DBQueryWarn("update apt_profile_versions set rspec=$safe_rspec ".
"where profileid='$profileid' and version='$version'")
if (1);
}
return 0;
}
# Total nonsense, to be thrown away.
sub CheckNodeConstraints($$$)
{
my ($self, $iscloudlab, $pmsg) = @_;
my ($self, $default_aggregate_urn, $pmsg) = @_;
my $cloudwww = "www.utah.cloudlab.us";
my $cloudurn = "urn:publicid:IDN+utah.cloudlab.us+authority+cm";
require URI;
my $rspec = GeniXML::Parse($self->rspec());
......@@ -870,6 +797,11 @@ sub CheckNodeConstraints($$$)
foreach my $ref (GeniXML::FindNodes("n:node", $rspec)->get_nodelist()) {
my $client_id = GetVirtualId($ref);
my $virtualization_type = GeniXML::GetVirtualizationSubtype($ref);
my $manager_urn = GetManagerId($ref);
if (! defined($manager_urn)) {
$manager_urn = $default_aggregate_urn;
}
my $iscloudlab = ($manager_urn eq $cloudurn ? 1 : 0);
if (defined($virtualization_type) && $iscloudlab &&
$virtualization_type eq "emulab-xen") {
......@@ -1012,6 +944,38 @@ sub CheckDatasets($$$)
return 0;
}
#
# Set the component_manager_urn for the sites.
#
sub SetSites($$$)
{
my ($prspecstr, $sitemap, $perrmsg) = @_;
my $rspec = GeniXML::Parse($$prspecstr);
if (! defined($rspec)) {
$$perrmsg = "Could not parse rspec\n";
return -1;
}
foreach my $ref (GeniXML::FindNodes("n:node", $rspec)->get_nodelist()) {
my $client_id = GetVirtualId($ref);
my $site_id = GeniXML::GetJacksSiteId($ref);
if (!defined($site_id)) {
$$perrmsg = "No site ID for $client_id";
return -1;
}
my $site_mid = "site:" . $site_id;
if (!exists($sitemap->{$site_mid})) {
$$perrmsg = "No site mapping for $client_id ($site_id)";
return -1;
}
GeniXML::SetManagerId($ref, $sitemap->{$site_mid});
GeniXML::SetJacksSiteManagerId($ref, $sitemap->{$site_mid});
}
$$prspecstr = GeniXML::Serialize($rspec);
return 0;
}
sub IsHead($)
{
my ($self) = @_;
......
......@@ -29,7 +29,7 @@
#
use strict;
use English;
use Getopt::Std;
use Getopt::Long;
use XML::Simple;
use File::Temp qw(tempfile :POSIX );
use Data::Dumper;
......@@ -40,10 +40,10 @@ use Cwd qw(realpath);
#
sub usage()
{
print "Usage: quickvm [-u uuid] [-a aggregate] <xmlfile>\n";
print "Usage: quickvm [-u uuid] [--site site1=aggregate ...] <xmlfile>\n";
exit(1);
}
my $optlist = "dvu:a:t:f";
my @optlist = ('d', 'v', 'u=s', 't=s', 'a=s', 'f');
my $debug = 0;
my $verbose = 1;
my $DEFAULT_URN = "urn:publicid:IDN+apt.emulab.net+authority+cm";
......@@ -53,9 +53,16 @@ my $webtask_id;
my $foreground = 0;
my $localuser = 0;
my $quickuuid;
my $aggregate;
my $default_aggregate_urn = $DEFAULT_URN;
my $this_user;
my $xmlparse;
my $instance;
my $slice;
my $sitemap;
my @aggregate_urns = ();
# Debugging
my $usemydevtree = 0;
# Protos
sub fatal($);
......@@ -118,12 +125,13 @@ use WebTask;
# Parse command arguments. Once we return from getopts, all that should be
# left are the required arguments.
#
Getopt::Long::Configure("no_ignore_case");
my %options = ();
if (! getopts($optlist, \%options)) {
if (! GetOptions(\%options, @optlist, "site=s%" => \$sitemap)) {
usage();
}
if (defined($options{"a"})) {
$aggregate = $options{"a"};
$default_aggregate_urn = $options{"a"};
}
if (defined($options{"d"})) {
$debug = 1;
......@@ -199,8 +207,7 @@ if (!defined($sa_authority)) {
}
#
# We want to contact our local CM to create the sliver.
# We use the normal XMLRPC route.
# We use the normal XMLRPC route, so need a context.
#
my $context = Genixmlrpc->Context($sa_certificate);
if (!defined($context)) {
......@@ -208,30 +215,6 @@ if (!defined($context)) {
}
Genixmlrpc->SetContext($context);
#
# Load the CM authority, since that is who we talk to.
#
my $CMURN;
if (defined($aggregate)) {
$CMURN = $aggregate;
}
else {
$CMURN = $DEFAULT_URN;
}
my $cm_authority = GeniAuthority->Lookup($CMURN);
if (!defined($cm_authority)) {
$cm_authority = GeniAuthority->CreateFromRegistry("cm", $CMURN);
if (!defined($cm_authority)) {
fatal("Could not load CM authority object");
}
}
my $cmurl = $cm_authority->url();
#$cmurl =~ s/protogeni/protogeni\/stoller/;
my $iscloudlab =
($CMURN eq "urn:publicid:IDN+utah.cloudlab.us+authority+cm" ? 1 : 0);
#
# Must wrap the parser in eval since it exits on error.
#
......@@ -311,12 +294,6 @@ if (exists($xmlparse->{'attribute'}->{"rspec"})) {
else {
$rspecstr = $profile->CheckFirewall(!$localuser);
#
# Temp hack; replace URNs with URLs.
#
if (1 && $profile->ConvertDiskImages()) {
fatal("Not able to convert disk_image URNs to URLs.");
}
#
# Look for datasets; need to verify that the datasets being referenced
# still exist and are still permissible to use, and we have to generate
# credentials for those datasets (if not a global dataset). The tricky
......@@ -334,11 +311,28 @@ else {
# an x386 image on the Cloudlab cluster (ARMs). This will eventually
# get replaced with Jon's constraint checking code.
#
if ($profile->CheckNodeConstraints($iscloudlab, \$errmsg)) {
if ($profile->CheckNodeConstraints($default_aggregate_urn, \$errmsg)) {
UserError($errmsg);
}
}
#
# Update rspec with site aggregate urns.
#
if (keys(%{$sitemap}) > 1) {
if (APT_Profile::SetSites(\$rspecstr, $sitemap, \$errmsg)) {
fatal($errmsg);
}
}
if (keys(%{$sitemap})) {
foreach my $siteid (keys(%{$sitemap})) {
push(@aggregate_urns, $sitemap->{$siteid})
}
}
else {
push(@aggregate_urns, $default_aggregate_urn);
}
#
# Use ssh-keygen to see if the key is valid and convertable. We first
# try to get the fingerprint, which will tells us if its already in
......@@ -560,7 +554,9 @@ elsif (!$localuser) {
#
# Now we know where to send to logs.
#
AddAuditInfo("cc", $project->LogsEmailAddress());
if (!$debug) {
AddAuditInfo("cc", $project->LogsEmailAddress());
}
# There will be "internal" keys cause we pass the flag asking for them.
my @sshkeys;
......@@ -592,18 +588,6 @@ my $slice_urn = GeniHRN::Generate("${OURDOMAIN}:${pid}", "slice", $slice_id);
my $slice_hrn = "${PGENIDOMAIN}.${slice_id}";
my $SERVER_NAME = (exists($ENV{"SERVER_NAME"}) ? $ENV{"SERVER_NAME"} : "");
print STDERR "\n";
print STDERR "User: $user_urn\n";
print STDERR "Email: $user_email" . (!$localuser ? " (guest)" : "") . "\n";
if (defined($profile)) {
print STDERR "Profile: " . $profile->name() . ":${version}\n";
}
print STDERR "Slice: $slice_urn\n";
print STDERR "Server: $SERVER_NAME\n";
print STDERR "Cluster: $CMURN\n";
print STDERR "\n";
print STDERR "$rspecstr\n";
#
# Make sure slice is unique. Probably retry here at some point.
#
......@@ -624,15 +608,14 @@ if (!defined($slice_certificate)) {
fatal("Could not generate certificate for $slice_urn");
}
# Slice is created as locked.
my $slice = GeniSlice->Create($slice_certificate,
$geniuser, $sa_authority, undef, 1);
$slice = GeniSlice->Create($slice_certificate,
$geniuser, $sa_authority, undef, 1);
if (!defined($slice)) {
$slice_certificate->Delete();
fatal("Could not create new slice object for $slice_urn");
}
# These get quick expirations, unless it is a real user.
if ($slice->SetExpiration(time() + (($localuser ? 16 : 3) * 3600)) != 0) {
$slice->Delete();
fatal("Could not set the slice expiration for $slice_urn");
}
my $slice_uuid = $slice->uuid();
......@@ -644,7 +627,6 @@ my ($slice_credential, $speaksfor_credential) =
APT_Geni::GenCredentials($slice, $geniuser);
if (! (defined($speaksfor_credential) &&
defined($slice_credential))) {
$slice->Delete();
fatal("Could not generate credentials");
}
......@@ -663,7 +645,6 @@ my $blob = {'uuid' => $quickvm_uuid,
'creator' => $geniuser->uid(),
'creator_idx' => $geniuser->idx(),
'creator_uuid' => $geniuser->uuid(),
'aggregate_urn'=> $CMURN,
'status' => "created",
'servername' => $SERVER_NAME,
'rspec' => $rspecstr,
......@@ -673,19 +654,54 @@ if (defined($project)) {
$blob->{"pid_idx"} = $project->pid_idx();
}
$errmsg = undef;
my $instance = APT_Instance->Create($blob, \$errmsg);
$instance = APT_Instance->Create($blob, \$errmsg);
if (!defined($instance)) {
$slice->Delete();
fatal(defined($errmsg) ? $errmsg :
"Could not create instance record for $quickvm_uuid");
}
# To keep stuff happy until finished.
$instance->Update({'aggregate_urn' => $default_aggregate_urn});
# We use this list of references for ParRun below.
my @aggregate_list = ();
foreach my $aggregate_urn (@aggregate_urns) {
my $authority = GeniAuthority->Lookup($aggregate_urn);
if (!defined($authority)) {
$authority = GeniAuthority->CreateFromRegistry("cm", $aggregate_urn);
if (!defined($authority)) {
fatal("Could not load CM authority object for $aggregate_urn");
}
}
my $aggobj = $instance->AddAggregate($aggregate_urn);
if (!defined($aggobj)) {
fatal("Could not create aggregate object for $aggregate_urn");
}
$aggobj->_authority($authority);
push(@aggregate_list, $aggobj);
}
#
# Create a webtask so that we can store additional information about
# the sliver while we wait. No worries if this fails.
# the sliver while we wait.
#
$webtask = WebTask->Create($instance->uuid());
$webtask->AutoStore(1)
if (defined($webtask));
if (!defined($webtask)) {
fatal("Could not create a webtask!");
}
$webtask->AutoStore(1);
print STDERR "\n";
print STDERR "User: $user_urn\n";
print STDERR "Email: $user_email" . (!$localuser ? " (guest)" : "") . "\n";
if (defined($profile)) {
print STDERR "Profile: " . $profile->name() . ":${version}\n";
}
print STDERR "Slice: $slice_urn\n";
print STDERR "Server: $SERVER_NAME\n";
print STDERR "Cluster: ";
print STDERR join(",", map($_->aggregate_urn(), @aggregate_list)) . "\n";
print STDERR "\n";
print STDERR "$rspecstr\n";
#
# Exit and let caller poll for status.
......@@ -702,44 +718,60 @@ if (!$debug) {
libaudit::AuditFork();
}
# Bind the process id.
$webtask->SetProcessID($PID)
if (defined($webtask));
#
# This creates the sliver and starts it. We have to watch for the server
# being to busy.
#
my $tries = 15;
my $response;
while (1) {
$response =
Genixmlrpc::CallMethod($cmurl, undef,
"CreateSliver",
{ "slice_urn" => $slice_urn,
"rspec" => $rspecstr,
"keys" =>
[{'urn' => $user_urn,
'login' => $user_uid,
'keys' => \@sshkeys }],
"credentials" =>
[$slice_credential->asString(),
$speaksfor_credential->asString(),
@dataset_credentials
]});
if (!defined($response) || $response->code() != GENIRESPONSE_SUCCESS) {
if (defined($response) &&
$response->code() == GENIRESPONSE_SERVER_UNAVAILABLE &&
$tries >= 0) {
print STDERR "Server reports too busy, waiting a while ...\n";
sleep(int(rand(20)) + 10);
$tries--;
next;
}
$slice->Delete();
$instance->SetStatus("failed");
if (defined($webtask)) {
$webtask->SetProcessID($PID);
#
# Create a sliver at a single aggregate. This is called from parrun
# so it needs to return success or failure, we lookup the results
# in the DB.
#
sub CreateSliver($)
{
my ($ref) = @_;
my $aggobj = $ref;
$aggobj->Refresh();
my $webtask = $aggobj->webtask();
my $authority = $aggobj->_authority();
my $cmurl = $authority->url();
my $urn = $authority->urn();
$webtask->Refresh();
# Debugging
$cmurl =~ s/protogeni/protogeni\/stoller/ if ($usemydevtree);
#
# This creates the sliver and starts it. We have to watch for the
# server being too busy.
#
my $tries = 15;
my $response;
while (1) {
$response =
Genixmlrpc::CallMethod($cmurl, undef,
"CreateSliver",
{ "slice_urn" => $slice_urn,
"rspec" => $rspecstr,
"keys" =>
[{'urn' => $user_urn,
'login' => $user_uid,
'keys' => \@sshkeys }],
"credentials" =>
[$slice_credential->asString(),
$speaksfor_credential->asString(),
@dataset_credentials
]});
if (!defined($response) || $response->code() != GENIRESPONSE_SUCCESS) {
if (defined($response) &&
$response->code() == GENIRESPONSE_SERVER_UNAVAILABLE &&
$tries >= 0) {
print STDERR "Server for $urn reports too busy, ".
"waiting a while ...\n";
sleep(int(rand(20)) + 10);
$tries--;
next;
}
if (defined($response)) {
$webtask->output($response->output());
$webtask->Exited($response->code());
......@@ -747,65 +779,117 @@ while (1) {
else {
$webtask->Exited(1);
}
$aggobj->SetStatus("failed");
if (defined($response) && defined($response->logurl())) {
$aggobj->SetPublicURL($response->logurl());
}
print STDERR "CreateSliver failed on $urn: ".
(defined($response) ? $response->output() : "") . "\n";
return -1;
}
if (defined($response) && defined($response->logurl())) {
$instance->SetPublicURL($response->logurl());
}
fatal("CreateSliver failed: ".
(defined($response) ? $response->output() : "") . "\n");
last;
}
last;
}
# This will get overwritten later.
if (defined($response) && defined($response->logurl())) {
$instance->SetPublicURL($response->logurl());
# This will get overwritten later.
if (defined($response) && defined($response->logurl())) {
$aggobj->SetPublicURL($response->logurl());
}
my $manifest = $response->value()->[1];
if (!defined($manifest)) {
$webtask->Exited(1);
$aggobj->SetStatus("failed");
print STDERR "CreateSliver $urn: No manifest returned\n";
return -1;
}
$aggobj->SetStatus("provisioned");
$aggobj->SetManifest($manifest);
return 0;
}
#
# We are going to use the manifests table.
# Finally, do it.
#
my $manifest = $response->value()->[1];
if (!defined($manifest)) {
my @return_codes = ();
if (ParRun({"maxwaittime" => 99999, "maxchildren" => scalar(@aggregate_list)},
\@return_codes, \&CreateSliver, @aggregate_list)) {
#
# The parent caught a signal. Leave things intact so that we can
# kill things cleanly later.
#
$slice->UnLock();
$webtask->Exited(1) if (defined($webtask));
$instance->SetStatus("failed");
fatal("Could not find the manifest in the response!");
$webtask->Exited(1);
exit(-1);
}
#
# Check the exit codes; any failure is a total failure (for now).
#
foreach my $aggobj (@aggregate_list) {
#
# Have to refresh the sliver objects since they were updated in a fork.
# Need the manifests for the call to ComputeNodeCounts below.
#
$aggobj->Refresh();
my $code = shift(@return_codes);
if ($code) {
$slice->UnLock();
$instance->SetStatus("failed");
$webtask->output($aggobj->webtask()->output())
if (defined($aggobj->webtask()->output()));
$webtask->Exited(1);
exit(1);
}
}
$instance->SetStatus("provisioned");
$instance->SetManifest($manifest);
$instance->ComputeNodeCounts();
#
# but have to wait for the sliver to be ready, which means polling.
# Now wait for the sliver to be ready, which means polling.
#
# Shorten default timeout.
#
my $seconds = 1500;
my $interval = 15;
my $ready = 0;
my $failed = 0;
my $public_url;
# Shorten default timeout now.
Genixmlrpc->SetTimeout(60);
while ($seconds > 0) {
sleep($interval);
$seconds -= $interval;
sub WaitForSliver($)
{
my ($ref) = @_;
my $aggobj = $ref;
$aggobj->Refresh();
my $webtask = $aggobj->webtask();
my $authority = $aggobj->_authority();
my $cmurl = $authority->url();
my $urn = $authority->urn();
$webtask->Refresh();
# Debugging
$cmurl =~ s/protogeni/protogeni\/stoller/ if ($usemydevtree);
my $seconds = 1500;
my $interval = 15;
my $ready = 0;
my $failed = 0;
my $public_url;
my $repblob;
while ($seconds > 0) {
sleep($interval);
$seconds -= $interval;
my $response =
Genixmlrpc::CallMethod($cmurl, undef,
"SliverStatus",
{ "slice_urn" => $slice_urn,
"credentials" =>
[$slice_credential->asString(),
$speaksfor_credential->asString()]});
if (!defined($response) || !defined($response->value()) ||
($response->code() != GENIRESPONSE_SUCCESS &&
$response->code() != GENIRESPONSE_SERVER_UNAVAILABLE &&
$response->code() != GENIRESPONSE_BUSY)) {
print STDERR "SliverStatus failed";
if (defined($response)) {
print STDERR ": " . $response->output();
if (defined($webtask)) {
my $response =
Genixmlrpc::CallMethod($cmurl, undef,
"SliverStatus",