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

Fix bitrot in protogeni cooked mode. Mostly XML and rspec issues.

parent 3911298f
......@@ -31,6 +31,7 @@ use Lan;
use GeniEmulab;
use GeniResource;
use GeniResponse;
use GeniXML;
use English;
use Socket;
use XML::Simple;
......@@ -103,7 +104,12 @@ sub MapResources($$$$)
$fragments{$cm} = {
'generated_by' => 'libvtop',
'type' => 'request',
'xmlns' => 'http://www.protogeni.net/resources/rspec/0.1',
'xmlns' => 'http://www.protogeni.net/resources/rspec/0.2',
# Assign now wants this stuff. I have no clue what it means!
'xmlns:xsi' => "http://www.w3.org/2001/XMLSchema-instance",
'xsi:schemaLocation' =>
"http://www.protogeni.net/resources/rspec/0.2 ".
"http://www.protogeni.net/resources/rspec/0.2/request.xsd",
'node' => [] };
}
push(@{ $fragments{$cm}->{'node'} }, $copy);
......@@ -204,7 +210,7 @@ sub MapResources($$$$)
$ptopfh->close();
system("nice $ASSIGN -uod -c .75 ".
"-q $ptop -w $vtop -W $soln > $log 2>&1");
"-f rspec/rspec -W $soln $ptop $vtop > $log 2>&1");
if ($?) {
print STDERR "Could not map to physical resources on $resource\n";
......@@ -284,13 +290,20 @@ sub MapResources($$$$)
if ($verbose) {
print STDERR "Final rspec:\n";
print STDERR Dumper($rspec);
if (1) {
my $rspecdoc = GeniResource::ConvertRspec($rspec);
my $rspecstr = GeniXML::Serialize($rspecdoc);
print STDERR "In XML:\n";
print STDERR "$rspecstr\n";
}
}
return 0;
}
sub GetTickets($$$$)
{
my ($experiment, $impotent, $user, $rspec) = @_;
my ($experiment, $verbose, $user, $rspec) = @_;
my %cm_urns = ();
Register($experiment, $user) == 0
......@@ -335,6 +348,17 @@ sub GetTickets($$$$)
$cm_urns{$cm} = $resource;
}
#
# XXX Convert to a proper XML looking thing. This is just a temporay
# hack for now.
#
my $rspecdoc = GeniResource::ConvertRspec($rspec);
my $rspecstr = GeniXML::Serialize($rspecdoc);
if ($verbose) {
print STDERR "In XML:\n";
print STDERR "$rspecstr\n";
}
#
# Get Tickets in parallel.
#
......@@ -344,7 +368,7 @@ sub GetTickets($$$$)
my ($resource) = @_;
print STDERR "Asking for ticket from $resource\n";
if ($resource->GetTicket($user, $rspec, $impotent)) {
if ($resource->GetTicket($user, $rspecstr, 0)) {
#
# Print this here since we do not save this in the
# DB, and the parent side of the fork will not have
......@@ -487,19 +511,22 @@ sub MapNodes($$)
my $manifest = $resource->Manifest();
return -1
if (!defined($manifest));
my $manifest_string = $resource->manifest_string();
print STDERR Dumper($manifest)
print STDERR "$manifest_string\n"
if ($verbose);
foreach my $ref (@{ $manifest->{'node'} }) {
my $sliver_urn = $ref->{'sliver_urn'};
my $vname = $ref->{'virtual_id'};
foreach my $ref (GeniXML::FindNodes("n:node",
$manifest)->get_nodelist()) {
my $sliver_urn = GeniXML::GetSliverId($ref);
my $vname = GeniXML::GetVirtualId($ref);
my $sshdport = GeniXML::GetText("sshdport", $ref);
#
# 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'};
my $component_manager_urn = GeniXML::GetManagerId($ref);
next
if (!defined($sliver_urn) && !defined($component_manager_urn));
......@@ -515,9 +542,7 @@ sub MapNodes($$)
$sliver_urn})
== 0 or return -1;
if (exists($ref->{'sshdport'})) {
my $sshdport = $ref->{'sshdport'};
if (defined($sshdport)) {
$node->Update({'sshdport' => $sshdport});
}
#
......@@ -527,29 +552,38 @@ sub MapNodes($$)
"-s $BOSSNODE -k $eventkey,$keyhash -u '$sliver_urn'";
$cmd .= " -j " . $node->node_id()
if ($node->isvirtnode());
$ref->{'startup_command'} = "$cmd boot";
GeniXML::SetText("startup_command", $ref, "$cmd boot");
# Interface map for loop below.
if (exists($ref->{'interface'})) {
foreach my $ifaceref (@{ $ref->{'interface'} }) {
my $virtid = $ifaceref->{'virtual_id'};
my $compid = $ifaceref->{'component_id'};
if (defined(GeniXML::FindFirst("n:interface", $ref))) {
foreach my $ifaceref (GeniXML::FindNodes("n:interface",
$ref)->get_nodelist()) {
my $virtid = GeniXML::GetText("virtual_id", $ifaceref);
my $compid = GeniXML::GetText("component_id", $ifaceref);
$ifacemap{$virtid} = [$node, $compid];
}
}
}
foreach my $ref (@{ $manifest->{'link'} }) {
my $linkname = $ref->{"virtual_id"};
my $interfaces = $ref->{'interface_ref'};
my %managers = map { $_->{'id'} => $_->{'id'} }
@{ $ref->{'component_manager'} };
foreach my $ref (GeniXML::FindNodes("n:link",
$manifest)->get_nodelist()) {
my $linkname = GeniXML::GetVirtualId($ref);
my $link_type = GeniXML::GetText("link_type", $ref);
my $vlantag = GeniXML::GetText("vlantag", $ref);
my @ifacerefs = GeniXML::FindNodes("n:interface_ref",
$ref)->get_nodelist();
my %managers = ();
if (GeniXML::FindNodes("n:component_manager", $ref)) {
%managers = map { GeniXML::GetText("id", $_) => $_ }
GeniXML::FindNodes("n:component_manager",
$ref)->get_nodelist();
}
# Skip tunnels in this loop for now.
next
if (exists($ref->{'link_type'}) &&
$ref->{'link_type'} eq "tunnel");
if (defined($link_type) && $link_type eq "tunnel");
#
# The manifest can include links for other CMs. Skip those
......@@ -558,13 +592,13 @@ sub MapNodes($$)
next
if (!exists($managers{$resource->manager_urn()}));
if (exists($ref->{'vlantag'})) {
my $TAG = $ref->{'vlantag'};
if (defined($vlantag)) {
my $TAG = $vlantag;
if (defined($TAG)) {
if (!($TAG =~ /^[\w]*$/)) {
print STDERR "Bad vlantag '$TAG' for $linkname\n";
print STDERR Dumper($manifest);
print STDERR "$manifest_string\n";
return -1;
}
my $lan = Lan->Lookup($experiment, $linkname, 1);
......@@ -590,11 +624,12 @@ sub MapNodes($$)
}
}
foreach my $ifaceref (@{ $interfaces }) {
my $vname = $ifaceref->{'virtual_node_id'};
my $iface_id = $ifaceref->{'virtual_interface_id'};
my $MAC = $ifaceref->{'MAC'};
my $VMAC = $ifaceref->{'VMAC'};
foreach my $ifaceref (@ifacerefs) {
my $vname = GeniXML::GetText("virtual_node_id", $ifaceref);
my $iface_id = GeniXML::GetText("virtual_interface_id",
$ifaceref);
my $MAC = GeniXML::GetText("MAC", $ifaceref);
my $VMAC = GeniXML::GetText("VMAC", $ifaceref);
my ($node, $compid) = @{ $ifacemap{$iface_id} };
my $iface;
......@@ -607,7 +642,7 @@ sub MapNodes($$)
if (!defined($iface)) {
print STDERR "Could not determine iface for" .
"$vname,$iface_id\n";
print STDERR Dumper($manifest);
print STDERR "$manifest_string\n";
return -1;
}
#
......@@ -619,7 +654,7 @@ sub MapNodes($$)
my $pnode = $node->GetPhysHost();
if (!defined($pnode)) {
print STDERR "Could not physical node for $node\n";
print STDERR Dumper($manifest);
print STDERR "$manifest_string\n";
return -1;
}
$node = $pnode;
......@@ -628,22 +663,22 @@ sub MapNodes($$)
my $interface = Interface->LookupByIface($node,$iface);
if (!defined($interface)) {
print STDERR "Could not map iface for $node,$iface\n";
print STDERR Dumper($manifest);
print STDERR "$manifest_string\n";
return -1;
}
if (!defined($MAC)) {
print STDERR "No mac (or vmac) for $node,$iface\n";
print STDERR Dumper($manifest);
print STDERR "$manifest_string\n";
return -1;
}
if (! ($MAC =~ /^[\w]*$/)) {
print STDERR "Bad mac '$MAC' for $node,$iface\n";
print STDERR Dumper($manifest);
print STDERR "$manifest_string\n";
return -1;
}
if ($interface->Update({"mac" => "$MAC"})) {
print STDERR "Could not update $node,$iface\n";
print Dumper($manifest);
print STDERR "$manifest_string\n";
return -1;
}
if (defined($VMAC)) {
......@@ -659,12 +694,12 @@ sub MapNodes($$)
}
if (! ($VMAC =~ /^[\w]*$/)) {
print STDERR "Bad vmac '$VMAC' for $linkname,$vname\n";
print STDERR Dumper($manifest);
print STDERR "$manifest_string\n";
return -1;
}
if ($vinterface->Update({"mac" => "$VMAC"})) {
print STDERR "Could not update $linkname,$vname\n";
print Dumper($manifest);
print STDERR "$manifest_string\n";
return -1;
}
}
......@@ -797,16 +832,17 @@ sub WaitForSlivers($$$@)
return -1
if (!defined($manifest));
foreach my $ref (@{ $manifest->{'node'} }) {
my $vname = $ref->{'virtual_id'};
my $urn = $ref->{'component_urn'};
foreach my $ref (GeniXML::FindNodes("n:node",
$manifest)->get_nodelist()) {
my $vname = GeniXML::GetVirtualId($ref);
my $urn = GeniXML::GetNodeId($ref);
my $node = $experiment->VnameToNode($vname);
#
# The manifest can include nodes from other CMs. There will not
# be a sliver urn in that case.
#
my $sliver_urn = $ref->{'sliver_urn'};
my $sliver_urn = GeniXML::GetSliverId($ref);
next
if (!defined($sliver_urn));
......@@ -945,8 +981,9 @@ sub WaitForSlivers($$$@)
next
if (!defined($manifest));
foreach my $ref (@{ $manifest->{'node'} }) {
my $vname = $ref->{'virtual_id'};
foreach my $ref (GeniXML::FindNodes("n:node",
$manifest)->get_nodelist()) {
my $vname = GeniXML::GetVirtualId($ref);
my $node = $experiment->VnameToNode($vname);
next
if (!defined($node));
......
......@@ -26,6 +26,7 @@ use GeniAuthority;
use GeniComponent;
use GeniUser;
use GeniHRN;
use GeniXML;
use emutil qw(TBGetUniqueIndex);
use User;
use Project;
......@@ -218,6 +219,7 @@ sub manager_version($) { return $_[0]->{'manager_version'}; }
sub last_rpc_error($) { return $_[0]->{'last_rpc_error'}; }
sub last_rpc_output($) { return $_[0]->{'last_rpc_output'}; }
sub last_rpc_value($) { return $_[0]->{'last_rpc_value'}; }
sub manifest_string($) { return $_[0]->{'MANIFESTSTR'}; }
#
# Delete a resource record from the DB.
......@@ -378,11 +380,11 @@ sub Manifest($)
return undef;
}
my ($manifest_string) = $query_result->fetchrow_array();
my $manifest = XMLin($manifest_string, KeyAttr => [],
ForceArray => ["node", "link", "interface",
"interface_ref", "linkendpoints",
"component_manager"]);
my $manifest = GeniXML::Parse($manifest_string);
if (!defined($manifest)) {
print STDERR "Could not getmanifest for $self\n";
return undef;
}
$self->{'MANIFEST'} = $manifest;
$self->{'MANIFESTSTR'} = $manifest_string;
return $manifest;
......@@ -397,14 +399,7 @@ sub UpdateManifest($$)
return -1;
}
my $manifest_idx = $self->manifest_idx();
my $manifest_string =
eval { XMLout($manifest, "NoAttr" => 1, RootName => "manifest") };
if ($@) {
print STDERR "UpdateManifest: XMLout error: $@\n";
print STDERR Dumper($manifest);
return -1;
}
my $manifest_string = GeniXML::Serialize($manifest);
my $query_result =
DBQueryWarn("update geni_manifests set ".
......@@ -461,13 +456,81 @@ sub ManagerVersion($)
return $self->{'manager_version'};
}
#
# Convert an rspec structure (as from libvtop) into proper format.
# This is horrible.
#
sub ConvertRspec($)
{
my ($rspec) = @_;
my $template =
"<rspec xmlns=\"http://protogeni.net/resources/rspec/0.2\" ".
" type=\"request\" generated_by=\"libvtop\">".
"</rspec>";
my $new = GeniXML::Parse($template);
if (!defined($new)) {
print STDERR "ConvertRspec: Could not create new document\n";
return undef;
}
# ???
my $root = $new;
foreach my $ref (@{ $rspec->{'node'} }) {
my $node = GeniXML::AddElement("node", $root);
foreach my $key ('virtual_id', 'component_urn', 'exclusive',
'virtualization_type', 'virtualization_subtype',
'startup_command', 'tarfiles') {
GeniXML::SetText($key, $node, $ref->{$key})
if (exists($ref->{$key}));
}
foreach my $ifaceref (@{ $ref->{'interface'} }) {
my $iface = GeniXML::AddElement("interface", $node);
foreach my $key ('virtual_id', 'component_id') {
GeniXML::SetText($key, $iface, $ifaceref->{$key})
if (exists($ifaceref->{$key}));
}
}
}
if (exists($rspec->{'link'})) {
foreach my $linkref (@{ $rspec->{'link'} }) {
my $link = GeniXML::AddElement("link", $root);
foreach my $key ('virtual_id', 'link_type',
'virtualization_type') {
GeniXML::SetText($key, $link, $linkref->{$key})
if (exists($linkref->{$key}));
}
# These are special; see libvtop.
foreach my $key ('bandwidth', 'latency', 'packet_loss') {
if (exists($linkref->{$key})) {
my ($val) = @{ $linkref->{$key} };
GeniXML::SetText($key, $link, $val);
}
}
foreach my $ifaceref (@{ $linkref->{'interface_ref'} }) {
my $iface = GeniXML::AddElement("interface_ref", $link);
foreach my $key ('virtual_node_id', 'virtual_interface_id',
'tunnel_ip') {
GeniXML::SetText($key, $iface, $ifaceref->{$key})
if (exists($ifaceref->{$key}));
}
}
}
}
return $new;
}
#
# Add Resources. We get an rspec to replace the current rspec.
# Ask for a ticket, and then redeem it.
#
sub GetTicket($$$$)
{
my ($self, $user, $rspec, $impotent) = @_;
my ($self, $user, $rspec_string, $impotent) = @_;
my $ticket;
my $response;
......@@ -483,15 +546,6 @@ sub GetTicket($$$$)
}
my $manager_urn = $self->manager_urn();
my $rspec_string = eval { XMLout($rspec, "NoAttr" => 1) };
if ($@) {
print STDERR "GetTicket: XMLout error: $@\n";
print STDERR Dumper($rspec);
return -1;
}
$rspec_string =~ s/opt\>/rspec\>/g;
#
# Load the SA cert to act as caller context.
#
......
......@@ -204,6 +204,12 @@ sub GetVirtualId($)
GetText("nickname", $node);
}
sub GetSliverId($)
{
my ($node) = @_;
return GetText("sliver_urn", $node);
}
sub GetManagerId($)
{
my ($node) = @_;
......
......@@ -1263,13 +1263,12 @@ sub GenVirtNodes($)
$self->{'RSPEC'} = {
'generated_by' => 'libvtop',
'type' => 'request',
'xmlns' => 'http://www.protogeni.net/resources/rspec/0.1',
'xmlns' => 'http://www.protogeni.net/resources/rspec/0.2',
'node' => [] };
}
push(@{ $self->rspec()->{'node'} }, $ref);
next;
}
my $subnodestr = "";
if ($vnode->_issubnode()) {
my $parent = $vnode->_parent();
......@@ -3310,7 +3309,7 @@ sub ReadRspecSolution($$)
$self->printdb("Nodes:\n");
foreach my $ref (@{ $self->rspec()->{'node'} }) {
my $node_urn = $ref->{'component_urn'};
my $node_urn = $ref->{'component_urn'} || $ref->{'component_uuid'};
my $virtual = $ref->{'virtual_id'};
# Skip LAN/Fake nodes.
......@@ -3769,7 +3768,7 @@ sub AllocNodes($)
if (defined($self->rspec()) && !$self->impotent()) {
$self->printdb("Requesting geni tickets ...\n");
if (libGeni::GetTickets($self->experiment(), $self->impotent(),
if (libGeni::GetTickets($self->experiment(), $self->verbose(),
$self->user(), $self->rspec())) {
tberror("Could not allocate Geni Tickets\n");
return -1;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment