Commit 4bf3c2bf authored by Leigh Stoller's avatar Leigh Stoller

Merge in my cooked mode changes

parent c3b4d6d3
#!/usr/bin/perl -wT
#
# EMULAB-COPYRIGHT
# Copyright (c) 2005-2009 University of Utah and the Flux Group.
# Copyright (c) 2005-2010 University of Utah and the Flux Group.
# All rights reserved.
#
package Experiment;
......@@ -324,6 +324,8 @@ sub security_level($) { return field($_[0], 'security_level');}
sub linktest_pid($) { return field($_[0], 'linktest_pid');}
sub linktest_level($) { return field($_[0], 'linktest_level');}
sub logfile($) { return field($_[0], 'logfile');}
sub eventkey($) { return field($_[0], 'eventkey');}
sub keyhash($) { return field($_[0], 'keyhash');}
sub paniced($) { return field($_[0], 'paniced');}
sub cpu_usage($) { return field($_[0], 'cpu_usage');}
sub encap_style($) { return field($_[0], 'encap_style');}
......
......@@ -518,6 +518,29 @@ sub Update($$)
return Refresh($self);
}
#
# Lookup a specific attribute in the type capabilities table.
#
sub TypeCapability($$$)
{
my ($self, $capkey, $pcapval) = @_;
return -1
if (!ref($self));
my $itype = $self->interface_type();
my $query_result =
DBQueryWarn("select capval from interface_capabilities ".
"where type='$itype' and capkey=$capkey");
return -1
if (!$query_result || !$query_result->numrows());
my ($capval) = $query_result->fetchrow_array();
$pcapval = $capval;
return 0;
}
##############################################################################
package Interface::VInterface;
use libdb;
......
#!/usr/bin/perl -wT
#
# EMULAB-COPYRIGHT
# Copyright (c) 2005-2009 University of Utah and the Flux Group.
# Copyright (c) 2005-2010 University of Utah and the Flux Group.
# All rights reserved.
#
package Node;
......@@ -2458,5 +2458,25 @@ sub GetOsids($) {
$self->{"DBROW"}{"next_boot_osid"});
}
#
# Look for a widearea node by its external node id.
#
sub LookupWideArea($$)
{
my ($class, $external_node_id) = @_;
my $safe_id = DBQuoteSpecial($external_node_id);
my $query_result =
DBQueryWarn("select node_id from widearea_nodeinfo ".
"where external_node_id=$safe_id");
return undef
if (!defined($query_result) || !$query_result->numrows);
my ($node_id) = $query_result->fetchrow_array();
return Node->Lookup($node_id);
}
# _Always_ make sure that this 1 is at the end of the file...
1;
#!/usr/bin/perl -w
#
# EMULAB-COPYRIGHT
# Copyright (c) 2009 University of Utah and the Flux Group.
# Copyright (c) 2009, 2010 University of Utah and the Flux Group.
# All rights reserved.
#
use strict;
......@@ -52,6 +52,7 @@ sub ClearAll();
sub StartAll();
sub WaitAll();
sub PurgeAll();
sub RenewAll();
#
# Turn off line buffering on output
......@@ -82,7 +83,8 @@ my $pid = shift;
my $eid = shift;
my $action = shift;
if ($action =~ /^(alloc|free|clear|wait|purge|start|register|unregister)$/) {
if ($action =~
/^(alloc|free|clear|wait|purge|start|register|unregister|renew)$/) {
$action = $1;
}
else {
......@@ -166,6 +168,10 @@ SWITCH: for ($action) {
PurgeAll();
last SWITCH;
};
/^renew$/ && do {
RenewAll();
last SWITCH;
};
fatal("Unknown action $action");
}
exit($exitval);
......@@ -229,8 +235,10 @@ sub PurgeAll()
foreach my $resource (@resources) {
$resource->Purge($this_user) == 0
or fatal("Could not purge resources from $resource");
$resource->Delete() == 0
or fatal("Could not delete $resource");
}
UnRegister();
return 0;
}
......@@ -246,6 +254,12 @@ sub WaitAll()
fatal("Cannot wait on slivers!\n");
}
sub RenewAll()
{
libGeni::RenewSlivers($experiment, 1) == 0 or
fatal("Cannot renew resources");
}
#
# Register.
#
......
This diff is collapsed.
This diff is collapsed.
/*
* EMULAB-COPYRIGHT
* Copyright (c) 2000-2008 University of Utah and the Flux Group.
* Copyright (c) 2000-2010 University of Utah and the Flux Group.
* All rights reserved.
*/
......@@ -135,6 +135,20 @@ int address_tuple_free(address_tuple_t);
event_notification_put_string(handle, note, "___SENDER___", buf)
#define event_notification_clr_sender(handle, note) \
event_notification_remove(handle, note, "___SENDER___")
#define event_notification_get_version(handle, note, buf, len) \
event_notification_get_string(handle, note, "___VERSION___", buf, len)
#define event_notification_set_version(handle, note, buf) \
event_notification_put_string(handle, note, "___VERSION___", buf)
#define event_notification_clr_version(handle, note) \
event_notification_remove(handle, note, "___VERSION___")
#define event_notification_get_elvincompat(handle, note, buf) \
event_notification_get_int32(handle, note, "___ELVIN___", buf)
#define event_notification_set_elvincompat(handle, note) \
event_notification_put_int32(handle, note, "___ELVIN___", 1)
#define event_notification_clr_elvincompat(handle, note) \
event_notification_remove(handle, note, "___ELVIN___")
#endif /* ifndef NO_EVENT_MACROS */
#endif /* ifndef SWIG */
......
#!/usr/bin/perl -wT
#!/usr/bin/perl -w
#
# EMULAB-COPYRIGHT
# Copyright (c) 2000-2005 University of Utah and the Flux Group.
# Copyright (c) 2000-2010 University of Utah and the Flux Group.
# All rights reserved.
#
use English;
......
#!/usr/bin/perl -wT
#!/usr/bin/perl -w
#
# EMULAB-COPYRIGHT
# Copyright (c) 2000-2005 University of Utah and the Flux Group.
# Copyright (c) 2000-2010 University of Utah and the Flux Group.
# All rights reserved.
#
use English;
......
......@@ -197,6 +197,7 @@ CREATE TABLE `geni_resources` (
`idx` mediumint(8) unsigned NOT NULL default '0',
`manager_urn` tinytext,
`created` datetime default NULL,
`expires` datetime default NULL,
`updated` datetime default NULL,
`slice_idx` mediumint(8) unsigned NOT NULL default '0',
`credential_idx` mediumint(8) unsigned NOT NULL default '0',
......
#!/usr/bin/perl -wT
#
# GENIPUBLIC-COPYRIGHT
# Copyright (c) 2008-2009 University of Utah and the Flux Group.
# Copyright (c) 2008-2010 University of Utah and the Flux Group.
# All rights reserved.
#
package GeniCredential;
......@@ -586,7 +586,7 @@ sub Store($)
if (defined($expires)) {
my $safe_expires = DBQuoteSpecial($expires);
push(@insert_data, "expires=$safe_expires");
push(@insert_data, "valid_until=$safe_expires");
}
# Insert into DB.
......
......@@ -42,6 +42,8 @@ use XML::Simple;
use Data::Dumper;
use Experiment;
use libdb qw(TBDB_IFACEROLE_CONTROL TBDB_IFACEROLE_EXPERIMENT);
use POSIX qw(strftime);
use Carp;
# Configure variables
my $TB = "@prefix@";
......@@ -96,7 +98,7 @@ sub RegisterExperiment($$)
}
#
# Create and register the slice.
# Create and register the slice. Slice is returned locked
#
print STDERR "Creating new slice for $experiment\n";
$slice = GeniSlice->CreateFromLocal($experiment, $user);
......@@ -104,12 +106,28 @@ sub RegisterExperiment($$)
print STDERR "Could not create local slice from $experiment\n";
return -1;
}
#
# We want this slice to have a long expiration and let Emulab
# deal with aging it out.
#
my $expires = time() + (3600 * 24 * 90);
if ($slice->SetExpiration($expires)) {
print STDERR "Could not set expiration for $slice\n";
if ($slice->UnRegister() != 0) {
print STDERR "Could not unregister $slice for $experiment\n";
return -1;
}
$slice->Delete();
return -1;
}
print STDERR "Registering $slice at the ClearingHouse.\n";
if ($slice->Register() != 0) {
$slice->Delete();
print STDERR "Could not register slice for $experiment\n";
print STDERR "Could not register slice $slice\n";
return -1;
}
$slice->UnLock();
return 0;
}
......@@ -135,17 +153,28 @@ sub UnRegisterExperiment($)
my $context = Genixmlrpc->Context($certificate);
if (!defined($context)) {
print STDERR "Could not create context to talk to clearinghouse\n";
return -1;
}
#
# Set the default RPC context.
#
Genixmlrpc->SetContext($context);
#
# Its possible the sa_daemon has the slice locked.
#
if ($slice->Lock() != 0) {
print STDERR "Could not lock slice\n";
return -1;
}
print STDERR "Unregistering $slice at the ClearingHouse.\n";
if ($slice->UnRegister() != 0) {
print STDERR "Could not unregister $slice for $experiment\n";
return -1;
}
# Needs to move.
GeniRegistry::ClientSliver->SliceDelete($slice);
if ($slice->Delete()) {
print STDERR "Could not delete $slice for $experiment\n";
return -1;
......@@ -159,15 +188,18 @@ sub UnRegisterExperiment($)
sub CreatePhysNode($)
{
my ($node_urn) = @_;
my $blob;
my @ifaces;
my $ctrliface;
if (!defined($node_urn) || ! GeniHRN::IsValid($node_urn)) {
carp("Not a proper node urn: $node_urn\n");
return -1;
}
print STDERR "$node_urn\n";
my ($auth,$type,$node_id) = GeniHRN::Parse($node_urn);
my $manager_urn = GeniHRN::Generate($auth, "authority", "cm");
# print STDERR "$node_urn\n";
#
# Load the SA cert to act as caller context.
#
......@@ -191,40 +223,24 @@ sub CreatePhysNode($)
print STDERR "Could not lookup $manager_urn at ClearingHouse\n";
return undef;
}
#
# Until this urn stuff is done.
#
my ($translated) = $authority->hrn() =~ /^([-\w]+)\..*/;
my $node_hrn = $translated . "." . $node_id;
# print STDERR "$node_hrn\n";
my $manager_version = $authority->Version();
return undef
if (!defined($manager_version));
my $component = GeniComponent->CreateFromRegistry($node_urn);
if (!defined($component)) {
print STDERR "Could not lookup $node_urn at ClearingHouse\n";
return undef;
}
my $node = Node->Lookup($component->uuid());
my $node = Node->LookupWideArea($node_urn);
return $node
if (defined($node));
print STDERR "Creating local node for $node_urn\n";
my $credential = GeniRegistry::Client->CreateCredential($component);
if (!defined($credential)) {
print STDERR "Could not create a credential for $component\n";
return undef;
}
my $registry = GeniRegistry::Client->Create($component,undef,$credential);
if (!defined($registry)) {
print STDERR "Could not create a registry client for $component\n";
return undef;
}
if ($registry->Resolve($component->uuid(), "Node", \$blob)) {
print STDERR "Could not resolve $component at $registry\n";
return undef;
}
my $blob = $component->Resolve();
return undef
if (!defined($blob));
my $hrn = $blob->{'hrn'};
my $IP = $blob->{'physctrl'};
......@@ -315,8 +331,16 @@ sub CreatePhysNode($)
$noderef)->get_nodelist()) {
my $component_id = GeniXML::GetText("component_id", $ref);
my $role = GeniXML::GetText("role", $ref);
if (! defined($role)) {
$role = "expt";
if (!defined($role) ||
$role eq "experimental" || $role eq "expt") {
$role = TBDB_IFACEROLE_EXPERIMENT();
}
elsif ($role eq "ctrl" || $role eq "control") {
$role = TBDB_IFACEROLE_CONTROL();
}
else {
print STDERR "Unknown role $role for $node_urn!\n";
goto bad;
}
my $MAC = "00000000000" . $count;
......@@ -332,10 +356,10 @@ sub CreatePhysNode($)
};
push(@ifaces, $ifaceargs);
if ($role eq "control") {
if ($role eq TBDB_IFACEROLE_CONTROL()) {
my $ipv4 = GeniXML::GetText("public_ipv4", $ref);
$ctrliface = $ifaceargs;
$ifaceargs->{'IP'} = $ref->{'public_ipv4'};
$ifaceargs->{'role'} = TBDB_IFACEROLE_CONTROL();
$ifaceargs->{'IP'} = $ipv4;
}
$count++;
#print Dumper($ifaceargs);
......@@ -353,7 +377,6 @@ sub CreatePhysNode($)
my $newnode = Node->Create($node_id, undef,
{"role" => "testnode",
"type" => "pcfedphys",
"uuid" => $uuid,
"hostname" => $hostname,
"external_node_id" => $node_urn,
"IP" => $IP});
......
......@@ -129,9 +129,9 @@ sub LOCKED($) { return $_[0]->{'LOCKED'}; }
#
# Class function to create new Geni slice and return the object.
#
sub Create($$$$;$)
sub Create($$$$;$$)
{
my ($class, $certificate, $creator_uuid, $authority, $exptidx) = @_;
my ($class, $certificate, $creator_uuid, $authority, $exptidx, $lock) = @_;
my @insert_data = ();
# Every slice gets a new unique index.
......@@ -150,6 +150,8 @@ sub Create($$$$;$)
push(@insert_data, "sa_uuid='$sa_uuid'");
push(@insert_data, "exptidx=$exptidx")
if (defined($exptidx));
push(@insert_data, "locked=now()")
if (defined($lock) && $lock);
my $safe_hrn = DBQuoteSpecial($certificate->hrn());
my $safe_uuid = DBQuoteSpecial($certificate->uuid());
......@@ -410,6 +412,24 @@ sub Delete($)
return 0;
}
#
# Delete all for a slice.
#
sub SliceDelete($$)
{
my ($self, $slice) = @_;
return -1
if (! ref($self));
my $slice_idx = $self->slice_idx();
DBQueryWarn("delete from client_slivers where slice_idx='$slice_idx'")
or return -1;
return 0;
}
#
# Stringify for output.
#
......
This diff is collapsed.
......@@ -159,14 +159,19 @@ sub GetCredential($)
#
if ($type eq "Slice") {
my $slice = GeniSlice->Lookup( defined( $urn ) ? $urn : $uuid );
return GeniResponse->Create(GENIRESPONSE_SEARCHFAILED, undef,
"No such Slice")
if (!defined($slice));
return GeniResponse->Create(GENIRESPONSE_FORBIDDEN, undef,
"Not your slice!")
if ($slice->Lock() != 0) {
return GeniResponse->BusyResponse("slice");
}
if ($slice->creator_uuid() ne $this_user->uuid() &&
!$slice->IsBound($this_user));
!$slice->IsBound($this_user)) {
$slice->UnLock();
return GeniResponse->Create(GENIRESPONSE_FORBIDDEN, undef,
"Not your slice!");
}
#
# Return a credential for the slice.
#
......@@ -174,9 +179,11 @@ sub GetCredential($)
GeniCredential->CreateSigned($slice,
$this_user,
$GeniCredential::LOCALSA_FLAG);
return GeniResponse->Create(GENIRESPONSE_ERROR)
if (!defined($slice_credential));
if (!defined($slice_credential)) {
$slice->UnLock();
return GeniResponse->Create(GENIRESPONSE_ERROR);
}
$slice->UnLock();
return GeniResponse->Create(GENIRESPONSE_SUCCESS,
$slice_credential->asString());
}
......@@ -317,7 +324,9 @@ sub Resolve($)
return GeniResponse->Create(GENIRESPONSE_SEARCHFAILED, undef,
"No such slice registered here");
}
if ($slice->Lock() != 0) {
return GeniResponse->BusyResponse("slice");
}
# Return a blob.
my $blob = { "hrn" => $slice->hrn(),
"uuid" => $slice->uuid(),
......@@ -327,6 +336,7 @@ sub Resolve($)
"slice",
$slice->slicename() )
};
$slice->UnLock();
return GeniResponse->Create(GENIRESPONSE_SUCCESS, $blob);
}
......@@ -504,16 +514,19 @@ sub Register($)
return GeniResponse->Create(GENIRESPONSE_ERROR, undef,
"$hrn or $uuid already registered");
}
# Slice is created as locked.
my $slice = GeniSlice->Create($certificate,
$credential->owner_uuid(),
$authority);
$authority, undef, 1);
if (!defined($slice)) {
$certificate->Delete();
print STDERR "Could not create new slice object\n";
return GeniResponse->Create(GENIRESPONSE_ERROR);
}
if (defined($expires) && $slice->SetExpiration($expires) != 0) {
print STDERR "Could not set slice expiration to $expires\n";
$slice->Delete();
return GeniResponse->Create(GENIRESPONSE_ERROR);
}
......@@ -529,16 +542,6 @@ sub Register($)
return GeniResponse->Create(GENIRESPONSE_ERROR);
}
#
# Add the bindings locally before registration.
#
if (0 && defined($userbindings)) {
foreach my $binding_uuid (@{ $userbindings }) {
my $binding_user = GeniUser->Lookup($binding_uuid, 1);
$slice->BindUser($binding_user);
}
}
#
# Register new slice at the clearinghouse.
#
......@@ -549,7 +552,7 @@ sub Register($)
return GeniResponse->Create(GENIRESPONSE_ERROR, undef,
"Could not register new slice at clearinghouse");
}
$slice->UnLock();
return GeniResponse->Create(GENIRESPONSE_SUCCESS,
$slice_credential->asString());
}
......@@ -662,21 +665,37 @@ sub Remove($)
return GeniResponse->Create(GENIRESPONSE_SEARCHFAILED, undef,
"No such slice");
}
if ($slice->Lock() != 0) {
return GeniResponse->BusyResponse("slice");
}
#
# Not allowed to delete a cooked mode slice via this interface.
#
if ($slice->exptidx()) {
$slice->UnLock();
return GeniResponse->Create(GENIRESPONSE_REFUSED, undef,
"Cooked mode Slice");
}
#
# Not allowed to delete a slice that has not expired since
# that would make it impossible to control any existing
# slivers.
#
if (! $slice->IsExpired()) {
$slice->UnLock();
return GeniResponse->Create(GENIRESPONSE_REFUSED, undef,
"Slice has not expired");
}
# Needs to move.
GeniRegistry::ClientSliver->SliceDelete($slice);
#
# Remove from the clearing house.
#
if ($slice->UnRegister()) {
print STDERR "Could not delete $slice from clearinghouse!\n";
$slice->UnLock();
return GeniResponse->Create(GENIRESPONSE_ERROR, undef,
(defined($uuid)?$uuid:$hrn)
. " could not be unregistered");
......@@ -693,60 +712,6 @@ sub Remove($)
return GeniResponse->Create(GENIRESPONSE_UNSUPPORTED);
}
#
# Discover resources for one of our slices. Just return the list of
# components that the clearinghouse gives us. Ug.
#
sub DiscoverResources($)
{
my ($argref) = @_;
my $cred = $argref->{'credential'};
my $rspec = $argref->{'rspec'};
if (! defined($cred)) {
return GeniResponse->MalformedArgsResponse();
}
if (! (defined($rspec) && ($rspec =~ /^[-\w]+$/))) {
GeniResponse->Create(GENIRESPONSE_BADARGS, undef,
"Improper rspec");
}
my $credential = GeniCredential->CreateFromSigned($cred);
if (!defined($credential)) {
return GeniResponse->Create(GENIRESPONSE_ERROR, undef,
"Could not create GeniCredential object");
}
#
# Make sure the credential was issued to the caller.
#
if ($credential->owner_uuid() ne $ENV{'GENIUUID'}) {
return GeniResponse->Create(GENIRESPONSE_ERROR, undef,
"This is not your credential!");
}
my $slice = GeniSlice->Lookup($credential->target_uuid());
if (!defined($slice)) {
return GeniResponse->Create(GENIRESPONSE_ERROR, undef,
"Unknown slice for this credential");
}
$credential->HasPrivilege( "authority" ) or
$credential->HasPrivilege( "resolve" ) or
return GeniResponse->Create( GENIRESPONSE_FORBIDDEN, undef,
"Insufficient privilege" );
#
# Ask clearing house for a list of components.
#
my @components;
if ($slice->DiscoverResources(\@components)) {
print STDERR "Could not DiscoverResources for $slice\n";
return GeniResponse->Create(GENIRESPONSE_ERROR, undef,
"Could not discover resources at clearinghouse");
}
return GeniResponse->Create(GENIRESPONSE_SUCCESS, 0);
}
#
# Return ssh keys.
#
......@@ -856,10 +821,15 @@ sub BindToSlice($)
return GeniResponse->Create(GENIRESPONSE_SEARCHFAILED,
undef, "No such user here");
}
if ($slice->Lock() != 0) {
return GeniResponse->BusyResponse("slice");
}
if ($slice->BindUser($target_user) != 0) {
print STDERR "Could not bind $target_user to $slice\n";
$slice->UnLock();
return GeniResponse->Create(GENIRESPONSE_ERROR);
}
$slice->UnLock();
return GeniResponse->Create(GENIRESPONSE_SUCCESS);
}
......@@ -938,6 +908,13 @@ sub RenewSlice($)
return GeniResponse->Create(GENIRESPONSE_ERROR, undef,
"Unknown slice for this credential");
}
#
# Not allowed to renew a cooked mode slice via this interface.
#
if ($slice->exptidx()) {
return GeniResponse->Create(GENIRESPONSE_REFUSED, undef,
"Cooked mode Slice");
}
$credential->HasPrivilege( "pi" ) or
$credential->HasPrivilege( "bind" ) or
......@@ -971,10 +948,15 @@ sub RenewSlice($)
$message = "Expiration is in the past";
goto bad;
}
if ($slice->Lock() != 0) {
return GeniResponse->BusyResponse("slice");
}
if ($slice->SetExpiration($when) != 0) {
$message = "Could not set expiration time";
$slice->UnLock();
goto bad;
}
$slice->UnLock();
return GeniResponse->Create(GENIRESPONSE_SUCCESS);
bad:
......@@ -1049,7 +1031,9 @@ sub RegisterSliver($)
print STDERR "No URN in $credential\n";
return GeniResponse->Create(GENIRESPONSE_ERROR);
}
if ($slice->Lock() != 0) {
return GeniResponse->BusyResponse("slice");
}
#
# See if one already exists; overwrite it.
#
......@@ -1063,8 +1047,10 @@ sub RegisterSliver($)
if (!defined($clientsliver)) {
print STDERR "Could not register sliver for $slice_urn\n";
print STDERR Dumper($blob);
$slice->UnLock();
return GeniResponse->Create(GENIRESPONSE_ERROR);
}
$slice->UnLock();
return GeniResponse->Create(GENIRESPONSE_SUCCESS);
}
......@@ -1124,7 +1110,9 @@ sub UnRegisterSliver($)
print STDERR "No URN in $credential\n";
return GeniResponse->Create(GENIRESPONSE_ERROR);
}
if ($slice->Lock() != 0) {
return GeniResponse->BusyResponse("slice");
}
#
# See if one already exists; overwrite it.
#
......@@ -1134,6 +1122,7 @@ sub UnRegisterSliver($)
$clientsliver->Delete()
if (defined($clientsliver));