Commit f83ba977 authored by Leigh B. Stoller's avatar Leigh B. Stoller
Browse files

Checkpoint.

* More URN issues dealt with.

* Sliver registration and unregistraton (CM to SA).

* More V2 status stuff.

* Other fixes.
parent 5a431737
......@@ -24,6 +24,7 @@ use GeniSliver;
use GeniSlice;
use GeniRegistry;
use GeniUtil;
use GeniUser;
use GeniHRN;
use emutil;
use Lan;
......@@ -138,9 +139,10 @@ sub Stringify($)
my ($self) = @_;
my $uuid = $self->uuid();
my $hrn = $self->hrn();
my $idx = $self->idx();
return "[GeniAggregate: $uuid, IDX: $idx]";
return "[GeniAggregate: $hrn, IDX: $idx]";
}
#
......@@ -205,6 +207,7 @@ sub type($) { return field($_[0], "type"); }
sub slice_uuid($) { return field($_[0], "slice_uuid"); }
sub creator_uuid($) { return field($_[0], "creator_uuid"); }
sub created($) { return field($_[0], "created"); }
sub registered($) { return field($_[0], "registered"); }
sub credential_idx($) { return field($_[0], "credential_idx"); }
sub aggregate_idx($) { return field($_[0], "aggregate_idx"); }
sub status($) { return field($_[0], "status"); }
......@@ -509,6 +512,27 @@ sub SetState($$)
return 0;
}
#
# Set the registered datetime for the aggregate
#
sub SetRegistered($$)
{
my ($self, $yesno) = @_;
return undef
if (! ref($self));
my $idx = $self->idx();
my $val = ($yesno ? "now()" : "NULL");
return -1
if (!DBQueryWarn("update geni_aggregates set ".
" registered=$val ".
"where idx='$idx'"));
return 0;
}
#
# Get the slice for the aggregate.
#
......@@ -534,6 +558,23 @@ sub GetSlice($)
return $slice;
}
#
# Get the creator for the aggregate.
#
sub GetCreator($)
{
my ($self) = @_;
return undef
if (! ref($self));
if (!defined($self->creator_uuid())) {
print STDERR "No creator associated with $self\n";
return undef;
}
return GeniUser->Lookup($self->creator_uuid(), 1);
}
#
# Create a signed credential for this aggregate, issued to the provided user.
# The credential will grant all permissions for now.
......@@ -981,6 +1022,10 @@ sub ComputeState($)
my $started = 0;
my $stopped = 0;
my $unknown = 0;
my $ready = 0;
my $notready= 0;
my $failed = 0;
my $changing= 0;
my $count = 0;
return -1
......@@ -1018,6 +1063,19 @@ sub ComputeState($)
else {
$unknown++;
}
if ($status eq "ready") {
$ready++;
}
elsif ($status eq "notready") {
$notready++;
}
elsif ($status eq "failed" ||
$status eq "broken") {
$failed++;
}
elsif ($status eq "changing") {
$changing++;
}
$count++;
}
if ($stopped == $count) {
......@@ -1029,6 +1087,21 @@ sub ComputeState($)
else {
$self->SetState("mixed");
}
if ($ready == $count) {
$self->SetStatus("ready");
}
elsif ($notready == $count) {
$self->SetStatus("notready");
}
elsif ($changing == $count) {
$self->SetStatus("changing");
}
elsif ($failed) {
$self->SetStatus("failed");
}
else {
$self->SetStatus("mixed");
}
return 0;
}
......
......@@ -2150,6 +2150,7 @@ sub SliverWorkAux($$$$$$$)
}
$ticket->Redeem()
if (defined($ticket));
$aggregate->SetRegistered(0);
$slice->UnLock();
return GeniResponse->Create(GENIRESPONSE_SUCCESS, $manifest);
......@@ -2293,7 +2294,7 @@ sub RenewSliverAux($$)
#
my $diff = $when - time();
print STDERR "RenewSliver: $expires, $when, $diff\n";
# print STDERR "RenewSliver: $expires, $when, $diff\n";
if ($diff < (60 * 5) || $diff > (3600 * 24 * 100)) {
$message = "valid_until out of range";
......@@ -3534,14 +3535,9 @@ sub CreateSliceFromCertificate($)
my $certificate = $credential->target_cert();
my $owner_uuid = $credential->owner_uuid();
my $authority = GeniAuthority->LookupByPrefix($certificate->uuid());
if (!defined($authority)) {
$authority = CreateAuthorityFromRegistry($certificate->uuid());
if (!defined($authority)) {
print STDERR "Could not create new authority record\n";
return undef;
}
}
my $authority = CreateAuthorityFromRegistry($certificate);
return undef
if (!defined($authority));
#
# The problem with HRNs is that people will tend to reuse them.
......@@ -3591,14 +3587,9 @@ sub CreateUserFromCertificate($)
return $geniuser;
}
my $authority = GeniAuthority->LookupByPrefix($certificate->uuid());
if (!defined($authority)) {
$authority = CreateAuthorityFromRegistry($certificate->uuid());
if (!defined($authority)) {
print STDERR "Could not create new authority record\n";
return undef;
}
}
my $authority = CreateAuthorityFromRegistry($certificate);
return undef
if (!defined($authority));
return GeniUser->Create($certificate, $authority);
}
......@@ -3608,29 +3599,107 @@ sub CreateUserFromCertificate($)
#
sub CreateAuthorityFromRegistry($)
{
my ($uuid) = @_;
my ($certificate) = @_;
my ($prefix) = ($uuid =~ /^\w+\-\w+\-\w+\-\w+\-(\w+)$/);
# This prefix stuff will go away when fully converted to urns.
my ($prefix) = ($certificate->uuid() =~ /^\w+\-\w+\-\w+\-\w+\-(\w+)$/);
my $authority = GeniAuthority->LookupByPrefix($certificate->uuid());
if (!defined($authority)) {
$authority = GeniAuthority->CreateFromRegistry("SA", "P${prefix}");
if (!defined($authority)) {
print STDERR "Could not create authority from registry\n";
return undef;
}
}
else {
#
# Check for an out of date record; the certificate has a urn
# but the local authority object does not.
#
if (defined($certificate->urn()) &&
GeniHRN::IsValid($certificate->urn()) &&
(!defined($authority->urn()) || $authority->urn() eq "")) {
print STDERR "Reloading authority for prefix $prefix\n";
$authority = GeniAuthority->CreateFromRegistry("SA", "P${prefix}");
if (!defined($authority)) {
print STDERR "Could not recreate authority from registry\n";
return undef;
}
if (!defined($authority->urn()) || $authority->urn() eq "") {
print STDERR "Missing URN in authority $authority\n";
return undef;
}
}
}
return $authority;
}
my $clearinghouse = GeniRegistry::ClearingHouse->Create();
return undef
if (!defined($clearinghouse));
#
# Register/Unregister a local sliver at its slice authority.
#
sub RegisterSliver($)
{
my ($slice) = @_;
my $blob;
return undef
if ($clearinghouse->Resolve("P${prefix}", "SA", \$blob) != 0);
return RegisterAux($slice, 0);
}
sub UnRegisterSliver($)
{
my ($slice) = @_;
my $certificate = GeniCertificate->LoadFromString($blob->{'gid'});
return undef
if (!defined($certificate));
return RegisterAux($slice, 1);
}
sub RegisterAux($$)
{
my ($slice, $unregister) = @_;
my $authority = GeniAuthority->Create($certificate,
$blob->{'url'},
$blob->{'type'});
$certificate->Delete()
if (!defined($authority));
my $authority = $slice->SliceAuthority();
if (!defined($authority)) {
$authority =
GeniAuthority->CreateFromRegistry("SA", $slice->sa_uuid());
if (!defined($authority)) {
print STDERR "Could not find authority for $slice\n";
return -1;
}
}
my $credential = GeniRegistry::Client->CreateCredential($authority);
if (!defined($authority)) {
print STDERR "Could not create a credential for $authority\n";
return -1;
}
my $registry = GeniRegistry::Client->Create($authority, undef,$credential);
if (!defined($registry)) {
print STDERR "Could not create a registry client for $authority\n";
return -1;
}
if ($unregister) {
$registry->UnRegisterSliver($slice->urn());
}
else {
my $aggregate = GeniAggregate->SliceAggregate($slice);
if (!defined($aggregate)) {
print STDERR "Could not find aggregate for $slice\n";
return -1;
}
my $creator = $aggregate->GetCreator();
if (!defined($creator)) {
print STDERR "Could not find creator for $slice\n";
return -1;
}
my $blob = {
"urn" => $aggregate->urn(),
"creator_urn" => $creator->urn(),
"created" => $slice->created(),
"expires" => $slice->expires(),
"manifest" => $aggregate->GetManifest(1),
};
return $authority;
if ($registry->RegisterSliver($slice->urn(), $blob) == 0) {
$aggregate->SetRegistered(1);
}
}
return 0;
}
#
......@@ -3670,6 +3739,11 @@ sub CleanupDeadSlice($;$)
}
}
}
my $topaggregate = GeniAggregate->SliceAggregate($slice);
if (defined($topaggregate) && $topaggregate->registered()) {
# Unregister the slice at the SA.
UnRegisterSliver($slice);
}
#
# Find any aggregates and tear them down.
......
......@@ -479,7 +479,7 @@ sub DeleteSlice($)
if ($slice->Lock() != 0) {
return GeniResponse->BusyResponse();
}
if (GeniCM::CleanupDeadSlice($slice) != 0) {
if (GeniCM::CleanupDeadSlice($slice, 1) != 0) {
return GeniResponse->Create(GENIRESPONSE_ERROR, undef,
"Could not cleanup slice");
}
......@@ -670,6 +670,12 @@ sub SliverAction($$$$)
#
foreach my $urn (@{ $sliver_urns }) {
my $sliver = GeniSliver->Lookup($urn);
if (!defined($sliver)) {
$response = GeniResponse->Create(GENIRESPONSE_SEARCHFAILED,
undef,
"Nothing here by that name");
goto bad;
}
$response = &$CheckState($sliver, $action);
goto bad
......@@ -748,7 +754,7 @@ sub SliverStatus($)
my $blob = {
"state" => $aggregate->state(),
"status" => "ready",
"status" => $aggregate->status(),
"details" => {},
};
......@@ -760,20 +766,13 @@ sub SliverStatus($)
my $sliver_urn = $sliver->sliver_urn();
my $component_urn = $sliver->component_urn();
my $state = $sliver->state();
my $status = $sliver->status();
my $error = "";
my $state = $sliver->state();
my $status = $sliver->status();
my $error = "";
if ($status eq "failed") {
$blob->{'status'} = "failed";
$error = $sliver->ErrorLog();
}
elsif ($status eq "notready") {
$status = "notready";
# Set to notready unless something already failed.
$blob->{'status'} = "notready"
if ($blob->{'status'} ne "failed");
}
$blob->{'details'}->{$sliver_urn} = {
"component_urn" => $component_urn,
"state" => $state,
......
......@@ -255,6 +255,174 @@ sub Stringify($)
return "[GeniSlice: $hrn, IDX: $idx]";
}
##########################################################################
#
package GeniRegistry::ClientSliver;
use GeniDB;
use GeniSlice;
use GeniHRN;
use emutil qw(TBGetUniqueIndex);
use English;
use Data::Dumper;
use overload ('""' => 'Stringify');
#
# Lookup.
#
sub Lookup($$)
{
my ($class, $token) = @_;
my $query_result;
my $idx;
if( GeniHRN::IsValid( $token ) ) {
return undef if !GeniHRN::Authoritative($token, "@OURDOMAIN@");
my ($authority, $type, $id) = GeniHRN::Parse($token);
return undef if $type ne "sliver";
$query_result =
DBQueryWarn("select idx from client_slivers ".
"where urn='$token'");
return undef
if (! $query_result || !$query_result->numrows);
($idx) = $query_result->fetchrow_array();
}
elsif ($token =~ /^\d+$/) {
$idx = $token;
}
else {
return undef;
}
$query_result =
DBQueryWarn("select * from client_slivers where idx='$idx'");
return undef
if (!$query_result || !$query_result->numrows);
my $self = {};
$self->{'SLIVER'} = $query_result->fetchrow_hashref();
bless($self, $class);
#
# Grab the slice, since we will probably want it.
#
my $slice = GeniSlice->Lookup($self->slice_idx());
if (!defined($slice)) {
print STDERR "Could not find slice for slice $idx\n";
return undef;
}
return $self;
}
# accessors
sub field($$) { return ((! ref($_[0])) ? -1 : $_[0]->{'SLIVER'}->{$_[1]}); }
sub idx($) { return field($_[0], "idx"); }
sub urn($) { return field($_[0], "urn"); }
sub manager_urn($) { return field($_[0], "manager_urn"); }
sub slice_idx($) { return field($_[0], "slice_idx"); }
sub creator_idx($) { return field($_[0], "creator_idx"); }
sub created($) { return field($_[0], "created"); }
sub expires($) { return field($_[0], "expires"); }
sub manifest($) { return field($_[0], "manifest"); }
sub LOCKED($) { return $_[0]->{'LOCKED'}; }
sub LookupByAuthority($$$)
{
my ($class, $slice, $urn) = @_;
my $slice_idx = $slice->idx();
my $query_result;
my $idx;
if (GeniHRN::IsValid($urn)) {
my $safe_urn = DBQuoteSpecial($urn);
$query_result =
DBQueryWarn("select idx from client_slivers ".
"where manager_urn=$safe_urn and ".
"slice_idx='$slice_idx'");
return undef
if (! $query_result || !$query_result->numrows);
($idx) = $query_result->fetchrow_array();
}
else {
return undef;
}
return GeniRegistry::ClientSliver->Lookup($idx);
}
#
# Class function to create new Geni slice and return the object.
#
sub Create($$$$$)
{
my ($class, $slice, $manager_urn, $user, $blob) = @_;
my @insert_data = ();
# Every one gets a new unique index.
my $idx = TBGetUniqueIndex('next_clientsliver', 1);
my $slice_idx = $slice->idx();
my $user_idx = $user->idx();
my $safe_urn = DBQuoteSpecial($blob->{'urn'});
my $safe_created = DBQuoteSpecial($blob->{'created'});
my $safe_expires = DBQuoteSpecial($blob->{'expires'});
my $safe_manager = DBQuoteSpecial($manager_urn);
push(@insert_data, "idx='$idx'");
push(@insert_data, "slice_idx='$slice_idx'");
push(@insert_data, "creator_idx='$user_idx'");
push(@insert_data, "urn=$safe_urn");
push(@insert_data, "manager_urn=$safe_manager");
push(@insert_data, "created=$safe_created");
push(@insert_data, "expires=$safe_expires");
if (exists($blob->{'manifest'})) {
my $safe_manifest = DBQuoteSpecial($blob->{'manifest'});
push(@insert_data, "manifest=$safe_manifest");
}
# Insert into DB.
return undef
if (! DBQueryWarn("insert into client_slivers set " .
join(",", @insert_data)));
return GeniRegistry::ClientSliver->Lookup($idx);
}
#
# Delete it.
#
sub Delete($)
{
my ($self) = @_;
return -1
if (! ref($self));
my $idx = $self->idx();
DBQueryWarn("delete from client_slivers where idx='$idx'")
or return -1;
return 0;
}
#
# Stringify for output.
#
sub Stringify($)
{
my ($self) = @_;
my $urn = $self->urn();
my $idx = $self->idx();
return "[ClientSliver: $idx, $urn]";
}
##########################################################################
#
package GeniRegistry::Client;
......@@ -354,7 +522,13 @@ sub Resolve($$$$)
"type" => $type,
$which => $token });
return -1
if (!defined($response) || $response->code() != GENIRESPONSE_SUCCESS);
if (!defined($response));
if ($response->IsError()) {
print STDERR "Resolve: " . $response->Dump() . "\n"
if ($response->code() != GENIRESPONSE_SEARCHFAILED());
return -1;
}
$$pref = $response->value();
return 0;
......@@ -398,12 +572,13 @@ sub Register($$$$)
"gid" => $cert,
"info" => $info });
if (!defined($response) || $response->code() != GENIRESPONSE_SUCCESS) {
print STDERR "Could not register object: " .
$response->output() . "\n";
return -1
if (!defined($response));
if ($response->IsError()) {
print STDERR "Register: " . $response->Dump() . "\n";
return -1;
}
return 0;
}
......@@ -448,8 +623,13 @@ sub Remove($$$)
"type" => $type,
"uuid" => $uuid });
return -1
if (!defined($response) || $response->code() != GENIRESPONSE_SUCCESS);
if (!defined($response));
if ($response->IsError()) {
print STDERR "Remove: " . $response->Dump() . "\n"
if ($response->code() != GENIRESPONSE_SEARCHFAILED());
return -1;
}
return 0;
}
......@@ -478,8 +658,12 @@ sub Shutdown($$$)
"clear" => $clear,
"uuid" => $uuid });
return -1
if (!defined($response) || $response->code() != GENIRESPONSE_SUCCESS);
if (!defined($response));
if ($response->IsError()) {
print STDERR "Shutdown: " . $response->Dump() . "\n";
return -1;
}
return 0;
}
......@@ -499,9 +683,10 @@ sub ListComponents($$$)
return -1
if (!defined($response));
return -1
if ($response->code() != GENIRESPONSE_SUCCESS);
if ($response->IsError()) {
print STDERR "ListComponents: " . $response->Dump() . "\n";
return -1;