All new accounts created on Gitlab now require administrator approval. If you invite any collaborators, please let Flux staff know so they can approve the accounts.

Commit 649a0107 authored by Jonathon Duerig's avatar Jonathon Duerig

Checkpoint. All the conversion is done, but I need to refactor the xpaths to...

Checkpoint. All the conversion is done, but I need to refactor the xpaths to account for brittleness in the xpath specification.
parent e25f7049
......@@ -17,7 +17,7 @@ LIB_SCRIPTS = GeniDB.pm GeniUser.pm \
GeniComponent.pm GeniCH.pm GeniEmulab.pm \
GeniAuthority.pm GeniCertificate.pm GeniAggregate.pm \
GeniUtil.pm GeniRegistry.pm GeniUsage.pm GeniHRN.pm \
GeniSES.pm GeniResource.pm
GeniSES.pm GeniResource.pm GeniXML.pm
SBIN_SCRIPTS = plabnodewrapper plabslicewrapper
SCRIPTS = addnode.pl genischemacheck.pl
......
......@@ -26,6 +26,7 @@ use GeniRegistry;
use GeniUtil;
use GeniUser;
use GeniHRN;
use GeniXML;
use emutil;
use Lan;
use Data::Dumper;
......@@ -646,29 +647,22 @@ sub GetManifest($$)
}
my ($xml) = $query_result->fetchrow_array();
my $manifest =
eval { XMLin($xml, KeyAttr => [],
ForceArray => ["node", "link", "interface",
"interface_ref", "linkendpoints"]) };
if ($@) {
print STDERR "XMLin error reading manifest: $@\n";
my $manifest = GeniXML::Parse($xml);
if (!defined($manifest)) {
return undef;
}
#
# Update the manifest ticket to reflect the current expiration time.
#
$manifest->{'valid_until'} =
POSIX::strftime("20%y-%m-%dT%H:%M:%S",
my $valid_date = POSIX::strftime("20%y-%m-%dT%H:%M:%S",
gmtime(str2time($slice->expires())));
GeniXML::SetText("valid_until", $manifest, $valid_date);
return $manifest
if (!$asxml);
$xml = eval { XMLout($manifest, "NoAttr" => 1, RootName => "manifest") };
if ($@) {
print STDERR "XMLout error on manifest: $@\n";
return undef;
}
$xml = $manifest->toString();
return $xml;
}
......@@ -1235,10 +1229,12 @@ sub Create($$$$$$)
$linkrspec, $node1rspec, $node2rspec) = @_;
my $clearinghouse;
my $linkname = $linkrspec->{"nickname"} || $linkrspec->{"virtual_id"};
my $linkname = GeniXML::GetText("./n:nickname | ".
"./n:virtual_id", $linkrspec);
return undef
if (!defined($linkname));
my @interfaces = @{ $linkrspec->{'interface_ref'} };
my @interfaces = GeniXML::FindNodes("./n:interface_ref",
$linkrspec)->get_nodelist();
my $experiment = Experiment->Lookup($slice->uuid());
if (!defined($experiment)) {
......@@ -1269,8 +1265,8 @@ sub Create($$$$$$)
my $iface2ref = $interfaces[1];
# These are the ips of the tunnel.
my $ip1 = $iface1ref->{'tunnel_ip'};
my $ip2 = $iface2ref->{'tunnel_ip'};
my $ip1 = GeniXML::GetText("./n:tunnel_ip", $iface1ref);
my $ip2 = GeniXML::GetText("./n:tunnel_ip", $iface2ref);
my $ctrlip1;
my $ctrlip2;
my $iface1;
......@@ -1295,7 +1291,8 @@ sub Create($$$$$$)
}
}
else {
my $component = GeniComponent->Lookup($node1rspec->{'component_uuid'});
my $component_name = GeniXML::GetNodeId($node1rspec);
my $component = GeniComponent->Lookup($component_name);
my $blob;
if (!defined($component)) {
......@@ -1304,10 +1301,10 @@ sub Create($$$$$$)
#
$clearinghouse = GeniRegistry::ClearingHouse->Create();
if ($clearinghouse->Resolve($node1rspec->{'component_uuid'},
if ($clearinghouse->Resolve($component_name,
"Component", \$blob) != 0) {
print STDERR "Could not lookup node at clearinghouse\n";
print STDERR Dumper($node1rspec);
print STDERR $node1rspec->toString();
goto bad;
}
my $certificate = GeniCertificate->LoadFromString($blob->{'gid'});
......@@ -1332,13 +1329,13 @@ sub Create($$$$$$)
print STDERR "Could not create a registry client for $component\n";
goto bad;
}
$registry->Resolve($node1rspec->{'component_uuid'}, "Node", \$blob);
$registry->Resolve($component_name, "Node", \$blob);
$ctrlip1 = $blob->{'physctrl'}
if (defined($blob) && exists($blob->{'physctrl'}));
if (!defined($ctrlip1)) {
print STDERR "Could not get control IP for ".
"$node1rspec->{'component_uuid'} at $component\n";
"$component_name at $component\n";
goto bad;
}
}
......@@ -1360,17 +1357,18 @@ sub Create($$$$$$)
}
else {
my $blob;
my $component = GeniComponent->Lookup($node2rspec->{'component_uuid'});
my $component_name = GeniXML::GetNodeId($node2rspec);
my $component = GeniComponent->Lookup($component_name);
if (!defined($component)) {
#
# Need to ask the clearinghouse where this node comes from.
#
$clearinghouse = GeniRegistry::ClearingHouse->Create();
if ($clearinghouse->Resolve($node2rspec->{'component_uuid'},
if ($clearinghouse->Resolve($component_name,
"Component", \$blob) != 0) {
print STDERR "Could not lookup node at clearinghouse\n";
print STDERR Dumper($node2rspec);
print STDERR $node2rspec->toString();
goto bad;
}
my $certificate = GeniCertificate->LoadFromString($blob->{'gid'});
......@@ -1395,13 +1393,13 @@ sub Create($$$$$$)
print STDERR "Could not create a registry client for $component\n";
goto bad;
}
$registry->Resolve($node2rspec->{'component_uuid'}, "Node", \$blob);
$registry->Resolve($component_name, "Node", \$blob);
$ctrlip2 = $blob->{'physctrl'}
if (defined($blob) && exists($blob->{'physctrl'}));
if (!defined($ctrlip2)) {
print STDERR "Could not get control IP for ".
"$node2rspec->{'component_uuid'} at $component\n";
"$component_name at $component\n";
goto bad;
}
}
......
This diff is collapsed.
......@@ -19,6 +19,7 @@ use vars qw(@ISA @EXPORT);
use GeniDB;
use GeniCertificate;
use GeniUtil;
use GeniXML;
use emutil qw(TBGetUniqueIndex);
use English;
use XML::Simple;
......@@ -122,7 +123,7 @@ sub Create($$$)
$self->{'owner_cert'} = $owner->GetCertificate();
$self->{'string'} = undef;
$self->{'capabilities'} = undef;
$self->{'extensions'} = undef;
$self->{'extensions'} = XML::LibXML::NodeList->new();
$self->{'idx'} = undef; # Only set when stored to DB.
bless($self, $class);
......@@ -184,11 +185,8 @@ sub AddExtension($$$)
return -1
if (!ref($self));
if (!defined($self->extensions())) {
$self->{'extensions'} = {};
}
$self->{'extensions'}->{$key} = $value;
my $newNode = XML::LibXML::Element->new($key);
$newNode->appendText($value);
return 0;
}
......@@ -249,7 +247,7 @@ sub CreateFromSigned($$;$)
unlink($filename);
}
# Use XML::Simple to convert to something we can mess with.
# Use XML::LibXML to convert to something we can mess with.
my $parser = XML::LibXML->new;
my $doc;
eval {
......@@ -259,28 +257,10 @@ sub CreateFromSigned($$;$)
print STDERR "Failed to parse credential string: $@\n";
return undef;
}
# Dig out the capabilities
my ($cap_node) = $doc->getElementsByTagName("privileges");
return undef
if (!defined($cap_node));
my $rawcapabilities =
eval { XMLin($cap_node->toString(),
ForceArray => [ "privilege" ] ) };
if ($@) {
print STDERR "XMLin error on capabilities: $@\n";
return undef;
}
my $capabilities = $rawcapabilities->{ "privilege" };
my $root = $doc->documentElement();
# Dig out the extensions
my ($extensions_node) = $doc->getElementsByTagName("extensions");
my $extensions = eval { XMLin($extensions_node->toString()) }
if (defined($extensions_node));
if ($@) {
print STDERR "XMLin error on extensions: $@\n";
return undef;
}
my $extensions = GeniXML::FindNodes('//n:extensions/*', $root);
# UUID of the credential.
my ($uuid_node) = $doc->getElementsByTagName("uuid");
......@@ -351,7 +331,7 @@ sub CreateFromSigned($$;$)
}
my $self = {};
$self->{'capabilities'} = $capabilities;
$self->{'capabilities'} = undef;
$self->{'extensions'} = $extensions;
$self->{'uuid'} = $this_uuid;
$self->{'valid_until'} = $expires;
......@@ -363,9 +343,44 @@ sub CreateFromSigned($$;$)
$self->{'idx'} = undef; # Only set when stored to DB.
bless($self, $class);
# Dig out the capabilities
foreach my $cap (GeniXML::FindNodes('.//n:privileges/n:privilege',
$root)->get_nodelist()) {
my $name = GeniXML::FindElement('./n:name', $cap);
my $delegate = GeniXML::FindElement('./n:can_delegate', $cap);
if (defined($name) && defined($delegate)) {
$self->AddCapability($name->textContent(),
$delegate->textContent());
}
}
return $self;
}
# Returns a NodeList for a given XPath using a given node as
# context. 'n' is defined to be the prefix for the namespace of the
# node.
#sub findnodes_n($$)
#{
# my ($path, $node) = @_;
# my $xc = XML::LibXML::XPathContext->new();
# my $ns = $node->namespaceURI();
# if (defined($ns)) {
# $xc->registerNs('ns', $node->namespaceURI());
# } else {
# $path =~ s/\bn://g;
# }
# return $xc->findnodes($path, $node);
#}
# Returns the first Node which matches a given XPath against a given
# node. Works like findnodes_n.
#sub findfirst_n($$)
#{
# my ($path, $node) = @_;
# return findnodes_n($path, $node)->pop();
#}
#
# Might have to delete this from the DB.
#
......@@ -413,11 +428,10 @@ sub Sign($$)
}
$cap_xml .= "</privileges>\n";
if (defined($self->extensions())) {
if ($self->extensions()->size() > 0) {
$cap_xml .= "<extensions>\n";
foreach my $key (keys(%{ $self->extensions() })) {
my $value = $self->extensions()->{$key};
$cap_xml .= "<$key>$value</$key>\n";
foreach my $node ($self->extensions()->get_nodelist()) {
$cap_xml .= $node->toString();
}
$cap_xml .= "</extensions>\n";
}
......
......@@ -31,6 +31,7 @@ use GeniSlice;
use GeniSliver;
use GeniUser;
use GeniHRN;
use GeniXML;
use libtestbed;
use User;
use Node;
......@@ -305,20 +306,26 @@ sub CreatePhysNode($)
}
}
elsif (exists($blob->{'rspec'})) {
my $rspec = XMLin($blob->{'rspec'}, KeyAttr => [],
ForceArray => ["interface"]);
foreach my $noderef (@{ $rspec->{'node'} }) {
my $rspec = GeniXML::Parse($blob->{'rspec'});
if (!defined($rspec)) {
goto bad;
}
foreach my $noderef (GeniXML::FindNodes("./n:node",
$rspec)->get_nodelist()) {
next
if ($noderef->{'component_uuid'} ne $node_urn);
if (GeniXML::GetNodeId($noderef) ne $node_urn);
next
if (! exists($noderef->{'interface'}));
if (! defined(GeniXML::FindFirst("./n:interface", $noderef)));
my $count = 0;
foreach my $ref (@{ $noderef->{'interface'} }) {
my $component_id = $ref->{'component_id'};
my $role = (exists($ref->{'role'}) ? $ref->{'role'} : "expt");
foreach my $ref (GeniXML::FindNodes("./n:interface",
$noderef)->get_nodelist()) {
my $component_id = GeniXML::GetText("./n:component_id", $ref);
my $role = GeniXML::GetText("./n:role", $ref);
if (! defined($role)) {
$role = "expt";
}
my $MAC = "00000000000" . $count;
my ($auth,$id,$iface) = GeniHRN::ParseInterface($component_id);
......
......@@ -26,6 +26,7 @@ use GeniAuthority;
use GeniComponent;
use GeniUser;
use GeniHRN;
use GeniXML;
use emutil qw(TBGetUniqueIndex);
use User;
use Project;
......@@ -303,9 +304,7 @@ sub Manifest($)
return undef;
}
my ($manifest_string) = $query_result->fetchrow_array();
my $manifest = XMLin($manifest_string, KeyAttr => [],
ForceArray => ["node", "link", "interface",
"interface_ref", "linkendpoints"]);
my $manifest = GeniXML::Parse($manifest_string);
$self->{'MANIFEST'} = $manifest;
$self->{'MANIFESTSTR'} = $manifest_string;
......@@ -321,13 +320,8 @@ 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 = $manifest->toString();
my $query_result =
DBQueryWarn("update geni_manifests set ".
" manifest=". DBQuoteSpecial($manifest_string) . ", " .
......@@ -362,13 +356,14 @@ sub GetTicket($$$$)
#
# Lets give it a reasonable default time.
#
if (!exists($rspec->{'valid_until'})) {
$rspec->{'valid_until'} =
POSIX::strftime("20%y-%m-%dT%H:%M:%S", gmtime(time() + (3600*6)));
my $valid_until = GeniXML::FindFirst("./n:valid_until", $rspec);
if (! defined($valid_until)) {
GeniXML::SetText("valid_until",
POSIX::strftime("20%y-%m-%dT%H:%M:%S",
gmtime(time() + (3600*6))));
}
my $rspec_string = XMLout($rspec, "NoAttr" => 1);
$rspec_string =~ s/opt\>/rspec\>/g;
my $rspec_string = $rspec_nodes->toString();
#
# Load the SA cert to act as caller context.
......
......@@ -22,6 +22,7 @@ use GeniCertificate;
use GeniAggregate;
use GeniUsage;
use GeniHRN;
use GeniXML;
use emutil;
use Experiment;
use OSinfo;
......@@ -105,12 +106,8 @@ sub Lookup($$)
my $rspec_string = $self->{'SLIVER'}->{'rspec_string'};
if (defined($rspec_string) && $rspec_string ne "") {
my $rspec =
eval { XMLin($rspec_string, KeyAttr => [],
ForceArray => ["node", "link", "interface",
"interface_ref", "linkendpoints"]) };
if ($@) {
print STDERR "XMLin error reading rspec: $@\n";
my $rspec = GeniXML::Parse($rspec_string);
if (!defined($rspec)) {
return undef;
}
$self->{'RSPEC'} = $rspec;
......@@ -200,7 +197,7 @@ sub Create($$$$$$$$$)
push(@insert_data, "slice_uuid='$slice_uuid'");
if (defined($rspec)) {
my $rspec_string = XMLout($rspec, RootName => "rspec");
my $rspec_string = $rspec->toString();
my $safe_rspec = DBQuoteSpecial($rspec_string);
push(@insert_data, "rspec_string=$safe_rspec");
......@@ -304,12 +301,7 @@ sub GetManifest($$)
return $manifest
if (!$asxml);
my $xml =
eval { XMLout($manifest, "NoAttr" => 1, RootName => "manifest") };
if ($@) {
print STDERR "XMLout error on manifest: $@\n";
return undef;
}
my $xml = $self->rspec()->toString();
return $xml;
}
......@@ -594,8 +586,14 @@ sub component_urn($)
sub Create($$$$$$)
{
# $rspec is a LibXML element representing a single node.
my ($class, $slice, $user, $resource_uuid, $rspec) = @_;
my $virtualization_type = $rspec->{'virtualization_type'};
my $virt_xml = GeniXML::FindFirst("./n:virtualization_type", $rspec);
if (!defined($virt_xml)) {
print STDERR "Node does not contain a virtualization_type\n";
return undef;
}
my $virtualization_type = $virt_xml->textContent();
my $experiment = $slice->GetExperiment();
if (!defined($experiment)) {
......@@ -631,7 +629,12 @@ sub Create($$$$$$)
return undef;
}
}
my $nickname = $rspec->{'virtual_id'};
my $virtual_id_xml = GeniXML::FindFirst("./n:virtual_id", $rspec);
if (!defined($virtual_id_xml)) {
print STDERR "Node does not contain a virtual_id\n";
return undef;
}
my $nickname = $virtual_id_xml->textContent();
my $hrn;
my $sshdport;
my $hostname;
......@@ -665,10 +668,10 @@ sub Create($$$$$$)
#
# Add this stuff to the rspec (which becomes the manifest).
#
$rspec->{'sliver_uuid'} = $sliver_uuid;
$rspec->{'hostname'} = $hostname;
$rspec->{'sshdport'} = $sshdport if (defined($sshdport));
$rspec->{'component_urn'} = $component_urn;
$rspec->setAttribute("sliver_uuid", $sliver_uuid);
$rspec->setAttribute("hostname", $hostname);
$rspec->setAttribute("sshdport", $sshdport) if (defined($sshdport));
$rspec->setAttribute("component_urn", $component_urn);
return GeniSliver->Create($slice, $user, $sliver_uuid, $resource_uuid,
"Node", $resource_id, $hrn, $nickname, $rspec);
......@@ -717,9 +720,11 @@ sub Provision($;$)
my $pid = $experiment->pid();
my $eid = $experiment->eid();
my $virt_type = GeniXML::FindFirst("./n:virtualization_type",
$self->rspec());
if (!$node->isremotenode() &&
exists($self->rspec()->{'virtualization_type'}) &&
$self->rspec()->{'virtualization_type'} eq "emulab-vnode") {
defined($virt_type) &&
$virt_type->textContent() eq "emulab-vnode") {
my $pnode = Node->Lookup($node->phys_nodeid());
if (!defined($pnode)) {
print STDERR "Could not get pnode object for $node\n";
......@@ -729,8 +734,10 @@ sub Provision($;$)
# Mark
$node->ModifyReservation({"genisliver_idx" => $self->idx()});
if (exists($self->rspec()->{'virtualization_subtype'})) {
my $subtype = $self->rspec()->{'virtualization_subtype'};
my $virt_subtype_xml = GeniXML::FindFirst("./n:virtualization_subtype",
$self->rspec());
if (defined($virt_subtype_xml)) {
my $subtype = $virt_subtype_xml->textContent();
if (!$pnode->sharing_mode()) {
$pnode->ModifyReservation({"genisliver_idx" => $self->idx()});
......@@ -808,8 +815,11 @@ sub UnProvision($;$)
}
}
my $virt_type = GeniXML::FindFirst("./n:virtualization_type",
$self->rspec());
if (!$node->isremotenode() &&
$self->rspec()->{'virtualization_type'} eq "emulab-vnode") {
defined($virt_type) &&
$virt_type->textContent() eq "emulab-vnode") {
my $pnode_id = $node->phys_nodeid();
my $pnode = Node->Lookup($pnode_id);
if (!defined($pnode)) {
......@@ -902,11 +912,14 @@ sub ProcessManifest($$)
#
# Find the corresponding node in the manifest.
#
foreach my $ref (@{$manifest->{'node'}}) {
if ($ref->{'sliver_uuid'} eq $uuid) {
foreach my $ref (GeniXML::FindNodes("./n:node",
$manifest)->get_nodelist()) {
my $sliver_xml = GeniXML::FindFirst("./n:sliver_uuid", $ref);
if (defined($sliver_xml) && $sliver_xml->textContent() eq $uuid) {
# startup command.
if (exists($ref->{'startup_command'})) {
my $startupcmd = $ref->{'startup_command'};
my $startup = GeniXML::FindFirst("./n:startup_command", $ref);
if (defined($startup)) {
my $startupcmd = $startup->textContent();
if (! TBcheck_dbslot($startupcmd, "virt_nodes",
"startupcmd",
......@@ -1127,8 +1140,8 @@ sub Create()
#
# Add this stuff to the rspec (which becomes the manifest).
#
$rspec->{'sliver_uuid'} = $interface_uuid;
$rspec->{'component_urn'} = $component_urn;
GeniXML::SetText("sliver_uuid", $rspec, $interface_uuid);
GeniXML::SetText("component_urn", $rspec, $component_urn);
return GeniSliver->Create($slice, $user, $interface_uuid,
$interface_uuid, "Interface", $resource_id,
......
......@@ -23,6 +23,7 @@ use GeniCertificate;
use emutil qw(TBGetUniqueIndex);
use GeniUtil;
use GeniHRN;
use GeniXML;
use English;
use XML::Simple;
use XML::LibXML;
......@@ -137,13 +138,24 @@ sub Lookup($$)
#
sub Create($$$$)
{
# $rspec is an XML string.
my ($class, $target, $owner, $rspec) = @_;
my $parser = XML::LibXML->new;
my $doc;
eval {
$doc = $parser->parse_string($rspec);
};
if ($@) {
print STDERR "Failed to parse ticket string: $@\n";
return undef;
}
# Every Ticket gets a new unique index (sequence number).
my $seqno = TBGetUniqueIndex('next_ticket', 1);
my $self = {};
$self->{'rspec'} = $rspec;
$self->{'rspec'} = $doc->documentElement();
$self->{'ticket_uuid'} = undef;
$self->{'owner_uuid'} = $owner->uuid();
$self->{'owner_hrn'} = $owner->hrn();
......@@ -282,21 +294,13 @@ sub CreateFromSignedTicket($$;$$)
}
# Dig out the rspec.
my ($rspec_node) = $doc->getElementsByTagName("rspec");
if (!defined($rspec_node)) {
my $rspec = GeniXML::FindFirst("//*[local-name()='rspec']",
$doc->documentElement());
if (!defined($rspec)) {
print STDERR "Ticket is missing rspec node\n";
return undef;
}
my $rspec =
eval { XMLin($rspec_node->toString(), KeyAttr => [],
ForceArray => ["node", "link", "interface",
"interface_ref", "linkendpoints"]) };
if ($@) {
print STDERR "XMLin error on ticket rspec: $@\n";
return undef;
}
# Dig out the ticket uuid.
my ($uuid_node) = $doc->getElementsByTagName("uuid");
if (!defined($uuid_node)) {
......@@ -573,14 +577,7 @@ sub rspecXML($)
return undef
if (!defined($self->rspec()));
my $rspec_xml =
eval { XMLout($self->rspec(),
"NoAttr" => 1, RootName => "rspec") };
if ($@) {
print STDERR "XMLout error on rspec: $@\n";
return undef;
}
return $rspec_xml;
return $self->rspec()->toString();
}
#
......@@ -712,18 +709,7 @@ sub RunSigner($$)
my $target_cert = $self->target_cert()->cert();
my $owner_cert = $self->owner_cert()->cert();
my $ticket_uuid = $self->{'ticket_uuid'};
my $rspec_xml = $self->rspec();
# Allow for the rspec to be in XML already.
if (ref($rspec_xml)) {