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

Merge in my cooked mode changes

parent c3b4d6d3
#!/usr/bin/perl -wT #!/usr/bin/perl -wT
# #
# EMULAB-COPYRIGHT # 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. # All rights reserved.
# #
package Experiment; package Experiment;
...@@ -324,6 +324,8 @@ sub security_level($) { return field($_[0], 'security_level');} ...@@ -324,6 +324,8 @@ sub security_level($) { return field($_[0], 'security_level');}
sub linktest_pid($) { return field($_[0], 'linktest_pid');} sub linktest_pid($) { return field($_[0], 'linktest_pid');}
sub linktest_level($) { return field($_[0], 'linktest_level');} sub linktest_level($) { return field($_[0], 'linktest_level');}
sub logfile($) { return field($_[0], 'logfile');} 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 paniced($) { return field($_[0], 'paniced');}
sub cpu_usage($) { return field($_[0], 'cpu_usage');} sub cpu_usage($) { return field($_[0], 'cpu_usage');}
sub encap_style($) { return field($_[0], 'encap_style');} sub encap_style($) { return field($_[0], 'encap_style');}
......
...@@ -518,6 +518,29 @@ sub Update($$) ...@@ -518,6 +518,29 @@ sub Update($$)
return Refresh($self); 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; package Interface::VInterface;
use libdb; use libdb;
......
#!/usr/bin/perl -wT #!/usr/bin/perl -wT
# #
# EMULAB-COPYRIGHT # 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. # All rights reserved.
# #
package Node; package Node;
...@@ -2458,5 +2458,25 @@ sub GetOsids($) { ...@@ -2458,5 +2458,25 @@ sub GetOsids($) {
$self->{"DBROW"}{"next_boot_osid"}); $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... # _Always_ make sure that this 1 is at the end of the file...
1; 1;
#!/usr/bin/perl -w #!/usr/bin/perl -w
# #
# EMULAB-COPYRIGHT # 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. # All rights reserved.
# #
use strict; use strict;
...@@ -52,6 +52,7 @@ sub ClearAll(); ...@@ -52,6 +52,7 @@ sub ClearAll();
sub StartAll(); sub StartAll();
sub WaitAll(); sub WaitAll();
sub PurgeAll(); sub PurgeAll();
sub RenewAll();
# #
# Turn off line buffering on output # Turn off line buffering on output
...@@ -82,7 +83,8 @@ my $pid = shift; ...@@ -82,7 +83,8 @@ my $pid = shift;
my $eid = shift; my $eid = shift;
my $action = 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; $action = $1;
} }
else { else {
...@@ -166,6 +168,10 @@ SWITCH: for ($action) { ...@@ -166,6 +168,10 @@ SWITCH: for ($action) {
PurgeAll(); PurgeAll();
last SWITCH; last SWITCH;
}; };
/^renew$/ && do {
RenewAll();
last SWITCH;
};
fatal("Unknown action $action"); fatal("Unknown action $action");
} }
exit($exitval); exit($exitval);
...@@ -229,8 +235,10 @@ sub PurgeAll() ...@@ -229,8 +235,10 @@ sub PurgeAll()
foreach my $resource (@resources) { foreach my $resource (@resources) {
$resource->Purge($this_user) == 0 $resource->Purge($this_user) == 0
or fatal("Could not purge resources from $resource"); or fatal("Could not purge resources from $resource");
$resource->Delete() == 0
or fatal("Could not delete $resource");
} }
UnRegister();
return 0; return 0;
} }
...@@ -246,6 +254,12 @@ sub WaitAll() ...@@ -246,6 +254,12 @@ sub WaitAll()
fatal("Cannot wait on slivers!\n"); fatal("Cannot wait on slivers!\n");
} }
sub RenewAll()
{
libGeni::RenewSlivers($experiment, 1) == 0 or
fatal("Cannot renew resources");
}
# #
# Register. # Register.
# #
......
#!/usr/bin/perl -wT #!/usr/bin/perl -wT
# #
# EMULAB-COPYRIGHT # 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. # All rights reserved.
# #
package libGeni; package libGeni;
...@@ -50,23 +50,19 @@ sub UnRegister($) ...@@ -50,23 +50,19 @@ sub UnRegister($)
return GeniEmulab::UnRegisterExperiment($experiment); return GeniEmulab::UnRegisterExperiment($experiment);
} }
# sub RenewSlivers($;$)
# Quickie solution.
#
sub RenewAllSlivers()
{ {
# my ($experiment, $force) = @_;
# Hand this off ...
# return GeniResource::RenewExperimentResources($experiment, $force);
return GeniResource::RenewAll();
} }
# #
# Map rspec to resources using assign. # Map rspec to resources using assign.
# #
sub MapResources($$$) sub MapResources($$$$)
{ {
my ($experiment, $user, $rspec) = @_; my ($experiment, $user, $rspec, $verbose) = @_;
my %cm_urns = (); my %cm_urns = ();
my %fragments = (); my %fragments = ();
my %nodemap = (); my %nodemap = ();
...@@ -112,6 +108,7 @@ sub MapResources($$$) ...@@ -112,6 +108,7 @@ sub MapResources($$$)
$node_cms{$ref->{'virtual_id'}} = $cm; $node_cms{$ref->{'virtual_id'}} = $cm;
$nodemap{$ref->{'virtual_id'}} = $ref; $nodemap{$ref->{'virtual_id'}} = $ref;
} }
# #
# As above, need to split the interfaces into the correct fragments. # As above, need to split the interfaces into the correct fragments.
# #
...@@ -119,6 +116,15 @@ sub MapResources($$$) ...@@ -119,6 +116,15 @@ sub MapResources($$$)
foreach my $ref (@{ $rspec->{'link'} }) { foreach my $ref (@{ $rspec->{'link'} }) {
my $linkname = $ref->{'virtual_id'}; my $linkname = $ref->{'virtual_id'};
# Skip tunnels until rspec stitching in place.
next
if (exists($ref->{'link_type'}) &&
$ref->{'link_type'} eq "tunnel");
next
if (0 && exists($ref->{'link_type'}) &&
exists($ref->{'link_type'}->{'type_name'}) &&
$ref->{'link_type'}->{'type_name'} eq "tunnel");
foreach my $ifaceref (@{ $ref->{'interface_ref'} }) { foreach my $ifaceref (@{ $ref->{'interface_ref'} }) {
my $virtual_node_id = $ifaceref->{'virtual_node_id'}; my $virtual_node_id = $ifaceref->{'virtual_node_id'};
...@@ -206,12 +212,16 @@ sub MapResources($$$) ...@@ -206,12 +212,16 @@ sub MapResources($$$)
my $solution = my $solution =
eval { XMLin($soln, KeyAttr => [], eval { XMLin($soln, KeyAttr => [],
ForceArray => ["node", "link", "interface", ForceArray => ["node", "link", "interface",
"interface_ref", "linkendpoints"]) }; "interface_ref", "linkendpoints",
"component_manager"]) };
if ($@) { if ($@) {
print STDERR "XMLin error reading $soln: $@\n"; print STDERR "XMLin error reading $soln: $@\n";
return -1; return -1;
} }
# print STDERR Dumper($solution); if ($verbose) {
print STDERR "Solution for $resource\n";
print STDERR Dumper($solution);
}
foreach my $ref (@{ $solution->{'node'} }) { foreach my $ref (@{ $solution->{'node'} }) {
my $virtual_id = $ref->{'virtual_id'}; my $virtual_id = $ref->{'virtual_id'};
...@@ -233,6 +243,11 @@ sub MapResources($$$) ...@@ -233,6 +243,11 @@ sub MapResources($$$)
my $iface_id = $ifaceref->{'virtual_id'}; my $iface_id = $ifaceref->{'virtual_id'};
my $compid = $ifaceref->{'component_id'}; my $compid = $ifaceref->{'component_id'};
# Not supposed to happen, but does cause of issues
# with tunnels and rspec stitching.
next
if (!defined($compid));
foreach my $oref (@{ $noderef->{'interface'} }) { foreach my $oref (@{ $noderef->{'interface'} }) {
if ($oref->{'virtual_id'} eq $iface_id) { if ($oref->{'virtual_id'} eq $iface_id) {
# write the solution back into the original rspec. # write the solution back into the original rspec.
...@@ -244,7 +259,28 @@ sub MapResources($$$) ...@@ -244,7 +259,28 @@ sub MapResources($$$)
} }
} }
} }
# print STDERR Dumper($rspec); if (exists($rspec->{'link'})) {
foreach my $ref (@{ $rspec->{'link'} }) {
my %cms = ();
my @cms = ();
foreach my $ifaceref (@{ $ref->{'interface_ref'} }) {
my $virtual_node_id = $ifaceref->{'virtual_node_id'};
my $node_cm = $node_cms{$virtual_node_id};
if (!exists($cms{$node_cm})) {
push(@cms, {'id' => $node_cm});
$cms{$node_cm} = $node_cm;
}
}
$ref->{'component_manager'} = [@cms];
}
}
if ($verbose) {
print STDERR "Final rspec:\n";
print STDERR Dumper($rspec);
}
return 0; return 0;
} }
...@@ -252,6 +288,7 @@ sub GetTickets($$$$) ...@@ -252,6 +288,7 @@ sub GetTickets($$$$)
{ {
my ($experiment, $impotent, $user, $rspec) = @_; my ($experiment, $impotent, $user, $rspec) = @_;
my %cm_urns = (); my %cm_urns = ();
my %node_cms = ();
Register($experiment, $user) == 0 Register($experiment, $user) == 0
or return -1; or return -1;
...@@ -272,6 +309,7 @@ sub GetTickets($$$$) ...@@ -272,6 +309,7 @@ sub GetTickets($$$$)
my $cm = GeniHRN::Generate($auth, "authority", "cm"); my $cm = GeniHRN::Generate($auth, "authority", "cm");
$cm_urns{$cm} = $cm; $cm_urns{$cm} = $cm;
$node_cms{$ref->{'virtual_id'}} = $cm;
# #
# This is how we get the client side to do cooked mode properly. # This is how we get the client side to do cooked mode properly.
...@@ -279,7 +317,6 @@ sub GetTickets($$$$) ...@@ -279,7 +317,6 @@ sub GetTickets($$$$)
$ref->{'tarfiles'} = "/usr/local/etc/emulab ". $ref->{'tarfiles'} = "/usr/local/etc/emulab ".
"$TBDOCBASE/downloads/geniclient.tar"; "$TBDOCBASE/downloads/geniclient.tar";
} }
#print STDERR Dumper($rspec);
# #
# Get the resource objects. # Get the resource objects.
...@@ -295,6 +332,7 @@ sub GetTickets($$$$) ...@@ -295,6 +332,7 @@ sub GetTickets($$$$)
} }
$cm_urns{$cm} = $resource; $cm_urns{$cm} = $resource;
} }
# #
# Ask for tickets. # Ask for tickets.
# #
...@@ -343,9 +381,11 @@ sub RedeemTickets($$$) ...@@ -343,9 +381,11 @@ sub RedeemTickets($$$)
# Map the local nodes to the external nodes. This just sets some DB # Map the local nodes to the external nodes. This just sets some DB
# state for now. # state for now.
# #
sub MapNodes($) sub MapNodes($$)
{ {
my ($experiment) = @_; my ($experiment, $verbose) = @_;
my $eventkey = $experiment->eventkey();
my $keyhash = $experiment->keyhash();
my %ifacemap = (); my %ifacemap = ();
# #
...@@ -361,11 +401,21 @@ sub MapNodes($) ...@@ -361,11 +401,21 @@ sub MapNodes($)
return -1 return -1
if (!defined($manifest)); if (!defined($manifest));
print STDERR Dumper($manifest);
foreach my $ref (@{ $manifest->{'node'} }) { foreach my $ref (@{ $manifest->{'node'} }) {
my $sliver_urn = $ref->{'sliver_urn'}; my $sliver_urn = $ref->{'sliver_urn'};
my $vname = $ref->{'virtual_id'}; my $vname = $ref->{'virtual_id'};
my $node = $experiment->VnameToNode($vname);
#
# The manifest can include nodes from other CMs. There will not
# be a sliver urn in that case.
#
my $component_manager_urn = $ref->{'component_manager_urn'};
next
if (!defined($sliver_urn) && !defined($component_manager_urn));
my $node = $experiment->VnameToNode($vname);
if (!defined($node)) { if (!defined($node)) {
print STDERR print STDERR
"MapNodes: Could not locate node $vname in $experiment\n"; "MapNodes: Could not locate node $vname in $experiment\n";
...@@ -385,8 +435,9 @@ sub MapNodes($) ...@@ -385,8 +435,9 @@ sub MapNodes($)
# #
# This is how we get the client side to do cooked mode properly. # This is how we get the client side to do cooked mode properly.
# #
$ref->{'startup_command'} = "/usr/local/etc/emulab/rc.pgeni ". $ref->{'startup_command'} =
"-s $BOSSNODE -u '$sliver_urn' boot"; "sudo /usr/local/etc/emulab/rc/rc.pgeni ".
"-s $BOSSNODE -k $eventkey,$keyhash -u '$sliver_urn' boot";
# Interface map for loop below. # Interface map for loop below.
if (exists($ref->{'interface'})) { if (exists($ref->{'interface'})) {
...@@ -401,6 +452,20 @@ sub MapNodes($) ...@@ -401,6 +452,20 @@ sub MapNodes($)
foreach my $ref (@{ $manifest->{'link'} }) { foreach my $ref (@{ $manifest->{'link'} }) {
my $linkname = $ref->{"virtual_id"}; my $linkname = $ref->{"virtual_id"};
my $interfaces = $ref->{'interface_ref'}; my $interfaces = $ref->{'interface_ref'};
my %managers = map { $_->{'id'} => $_->{'id'} }
@{ $ref->{'component_manager'} };
# Skip tunnels in this loop for now.
next
if (exists($ref->{'link_type'}) &&
$ref->{'link_type'} eq "tunnel");
#
# The manifest can include links for other CMs. Skip those
# for now.
#
next
if (!exists($managers{$resource->manager_urn()}));
foreach my $ifaceref (@{ $interfaces }) { foreach my $ifaceref (@{ $interfaces }) {
my $vname = $ifaceref->{'virtual_node_id'}; my $vname = $ifaceref->{'virtual_node_id'};
...@@ -418,18 +483,18 @@ sub MapNodes($) ...@@ -418,18 +483,18 @@ sub MapNodes($)
if (!defined($iface)) { if (!defined($iface)) {
print STDERR "Could not determine iface for" . print STDERR "Could not determine iface for" .
"$vname,$iface_id\n"; "$vname,$iface_id\n";
print Dumper($manifest); print STDERR Dumper($manifest);
return -1; return -1;
} }
my $interface = Interface->LookupByIface($node,$iface); my $interface = Interface->LookupByIface($node,$iface);
if (!defined($interface)) { if (!defined($interface)) {
print STDERR "Could not map iface for $node,$iface\n"; print STDERR "Could not map iface for $node,$iface\n";
print Dumper($manifest); print STDERR Dumper($manifest);
return -1; return -1;
} }
if (! ($MAC =~ /^[\w]*$/)) { if (! ($MAC =~ /^[\w]*$/)) {
print STDERR "Bad mac '$MAC' for $node,$iface\n"; print STDERR "Bad mac '$MAC' for $node,$iface\n";
print Dumper($manifest); print STDERR Dumper($manifest);
return -1; return -1;
} }
if ($interface->Update({"mac" => "$MAC"})) { if ($interface->Update({"mac" => "$MAC"})) {
...@@ -439,6 +504,11 @@ sub MapNodes($) ...@@ -439,6 +504,11 @@ sub MapNodes($)
} }
} }
} }
# The manifest was changed above.
if ($resource->UpdateManifest($manifest)) {
print STDERR "Could not store manifest for $resource\n";
return -1;
}
} }
return 0; return 0;
} }
...@@ -511,17 +581,46 @@ sub WaitForSlivers($$@) ...@@ -511,17 +581,46 @@ sub WaitForSlivers($$@)
} }
# #
# Build a map of the nodes. # Build a map of the nodes. I made a real mess of this in Version 1.
#
foreach my $resource (@resources) {
my $manifest = $resource->Manifest();
return -1
if (!defined($manifest));
foreach my $ref (@{ $manifest->{'node'} }) {
my $vname = $ref->{'virtual_id'};
my $urn = $ref->{'component_urn'};
my $node = $experiment->VnameToNode($vname);
#
# The manifest can include nodes from other CMs. There will not
# be a sliver urn in that case.
# #
my @nodelist = $experiment->NodeList(0, 1); my $sliver_urn = $ref->{'sliver_urn'};
foreach my $node (@nodelist) { next
if (!defined($sliver_urn));
if (!defined($node)) {
print STDERR "WaitForSlivers: ".
"Could not locate node $vname in $experiment\n";
return -1;
}
if ($resource->ManagerVersion() == 1.0) {
my ($domain,undef,$node_id) = GeniHRN::Parse($urn);
$urn = GeniHRN::Generate($domain, "sliver", $node_id);
$nodemap{$urn} = $node;
}
else {
next next
if (!defined($node->external_resource_id()) || if (!defined($node->external_resource_id()) ||
$node->external_resource_id() eq ""); $node->external_resource_id() eq "");
$nodemap{$node->external_resource_id()} = $node; $nodemap{$node->external_resource_id()} = $node;
}
$node->Refresh(); $node->Refresh();
} }
}
# #
# Now we use parrun again to get the sliver status. We are waiting # Now we use parrun again to get the sliver status. We are waiting
...@@ -541,9 +640,23 @@ sub WaitForSlivers($$@) ...@@ -541,9 +640,23 @@ sub WaitForSlivers($$@)
} }
print STDERR Dumper($ref); print STDERR Dumper($ref);
foreach my $key (keys(%{ $ref->{'detailsNew'} })) { foreach my $key (keys(%{ $ref->{'details'} })) {
my $val = $ref->{'detailsNew'}->{$key}; my $val = $ref->{'details'}->{$key};
my $node = $nodemap{$key};