Commit 6737a38b authored by Leigh Stoller's avatar Leigh Stoller

Fixes for Mike's mesh topology that binds Xen VMs to other physical

nodes in the topology. Instead of binding with a component_id, implement
new variant of the "relation" element, called "instantiate_on" that
specifies the client_id of the parent node. This becomes the "fixed"
slot of the virt_nodes table entry for the Xen VM.
parent 203bcda4
......@@ -36,7 +36,7 @@ TB = "@prefix@";
OURDOMAIN = "@OURDOMAIN@";
# Testbed specific stuff
if True:
if False:
sys.path.append(TB + "/opsdir/lib/geni-lib")
else:
sys.path.append("/usr/local/lib/geni-lib")
......@@ -137,8 +137,6 @@ for child in tree.getroot():
osname = osname.replace("/", "//");
pass
node.disk_image = "urn:publicid:IDN+" + OURDOMAIN + "+image+" + osname
elif element.tag == "fixed" and element.text != None:
node.component_id = URN.Node(OURDOMAIN, element.text)
elif element.tag == "ips" and element.text != None:
ips = element.text.split()
for token in ips:
......@@ -261,6 +259,18 @@ for child in tree.getroot():
# record that these links are bridged by bridge
bridged[vlink] = {"bridge" : vname, "vport" : vport}
pass
if child.tag == "virt_nodes":
row = child.find("row")
vname = row.find("vname").text
for element in row:
if element.tag == "fixed" and element.text != None:
#
# Watch for binding to another node in the topology.
#
if vname in nodes:
nodes[vname].InstantiateOn(nodes[element.text])
else:
node.component_id = URN.Node(OURDOMAIN, element.text)
pass
#
......
......@@ -270,6 +270,11 @@ foreach my $noderef (GeniXML::FindNodes("n:node", $rspec)->get_nodelist()) {
my $ptype = GeniXML::XenPtype($noderef);
AddNodeStatement($client_id, "xen_ptype = '$ptype'");
}
if (defined(GeniXML::GetInstantiateOn($noderef))) {
my $vhost = GeniXML::GetInstantiateOn($noderef);
AddNodeStatement($client_id, "InstantiateOn('$vhost')");
}
}
elsif ($sliver_type eq "emulab-blockstore") {
AddNode($client_id, "emulab-blockstore");
......@@ -573,7 +578,7 @@ foreach my $noderef (GeniXML::FindNodes("n:node", $rspec)->get_nodelist()) {
my @code = ("# Node $client_id");
if ($node->{'type'} eq "emulab-xen") {
push(@code, "$ntag = emulab.XenVM('$client_id')");
push(@code, "$ntag = request.XenVM('$client_id')");
}
elsif ($node->{'type'} eq "emulab-blockstore") {
my $mount = $node->{'blockstores'}->{$client_id}->{'mount'};
......
......@@ -916,6 +916,7 @@ sub GetTicketAuxAux($$$$$$$$$$$)
my %bridgemap= ();
my @nodeids = ();
my %lannodes = ();
my %allnodes = ();
# For stitching, keep track of external nodes and links.
my %external_nodemap = ();
my %external_linkmap = ();
......@@ -926,6 +927,31 @@ sub GetTicketAuxAux($$$$$$$$$$$)
# Always do this to avoid buildup.
$slice_experiment->ClearBackupState();
#
# Find all the node client ids, so we can support binding VMs to other
# nodes in the topology. We could enforce that the rspec has to put
# those nodes first, but that would be annoying to users. And me.
#
foreach my $ref (GeniXML::FindNodes("n:node", $rspec)->get_nodelist()) {
# Let remote nodes pass through.
next
if (!GeniXML::IsLocalNode($ref));
# Skip lan nodes; they are fake.
next
if (GeniXML::IsLanNode($ref));
my $node_nickname = GeniXML::GetVirtualId($ref);
# Might as well do a duplicate check while we are here.
if (exists($allnodes{lc($node_nickname)})) {
$response = GeniResponse->Create(GENIRESPONSE_BADARGS, undef,
"Duplicate node $node_nickname");
goto bad;
}
$allnodes{lc($node_nickname)} = 1;
}
#
# If this is a ticket update, we want to seed the namemap with
......@@ -1002,8 +1028,6 @@ sub GetTicketAuxAux($$$$$$$$$$$)
print GeniXML::Serialize($rspec);
my %nodeexistsmap = ();
foreach my $ref (GeniXML::FindNodes("n:node", $rspec)->get_nodelist()) {
my $component_id = GeniXML::GetNodeId($ref);
my $vnode_id = GeniXML::GetVnodeId($ref);
......@@ -1011,6 +1035,7 @@ sub GetTicketAuxAux($$$$$$$$$$$)
my $node_nickname = GeniXML::GetVirtualId($ref);
my $colocate = GeniXML::GetColocate($ref);
my $subnode_of = GeniXML::GetSubnodeOf($ref);
my $instantiate_on= GeniXML::GetInstantiateOn($ref);
my $virtualization_type = GeniXML::GetVirtualizationType($ref);
my $virtualization_subtype
......@@ -1026,14 +1051,6 @@ sub GetTicketAuxAux($$$$$$$$$$$)
my $xensettings;
my $fwsettings;
if (exists($nodeexistsmap{lc($node_nickname)})) {
$response =
GeniResponse->Create(GENIRESPONSE_BADARGS, undef,
"Duplicate node $node_nickname");
goto bad;
}
$nodeexistsmap{lc($node_nickname)} = 1;
# Always populate iface2node mapping, even if we let the node
# pass through.
foreach my $linkref (GeniXML::FindNodes("n:interface",
......@@ -1416,6 +1433,30 @@ sub GetTicketAuxAux($$$$$$$$$$$)
if (!defined($pctype));
}
#
# Check to see if a XEN pcvm is bound to another node in the
# virtual topology (not a testbed physical node). This becomes
# the "fixed" slot in the virt_nodes table, even on an update
# (we bound $node above) cause this is how libvtop wants it.
#
if (defined($instantiate_on)) {
if (defined($virtualization_subtype) &&
$virtualization_subtype eq "emulab-xen") {
if (!exists($allnodes{$instantiate_on})) {
$response =
GeniResponse->Create(GENIRESPONSE_BADARGS, undef,
"Bad binding of $node_nickname to $subnode_of");
goto bad;
}
}
else {
$response =
GeniResponse->Create(GENIRESPONSE_BADARGS, undef,
"Only Xen nodes can use 'instantiate_on'");
goto bad;
}
}
#
# If no osname, check for protogeni default osname
#
......@@ -1452,9 +1493,10 @@ sub GetTicketAuxAux($$$$$$$$$$$)
"ips" => '', # deprecated
"cmd_line"=> '', # bogus
"routertype" => $routertype,
"fixed" => (defined($subnode_of) ? $subnode_of :
defined($node) ? $node->node_id() : ""),
"fixed" =>
(defined($subnode_of) ? $subnode_of :
defined($instantiate_on) ? $instantiate_on :
defined($node) ? $node->node_id() : ""),
};
if (defined($parent_osname)) {
......@@ -2984,6 +3026,7 @@ sub GetTicketAuxAux($$$$$$$$$$$)
my $node = GeniUtil::LookupNode($vnode_id);
my $colocate = GeniXML::GetColocate($rspec);
my $subnode_of = GeniXML::GetSubnodeOf($rspec);
my $instantiate_on = GeniXML::GetInstantiateOn($rspec);
# Need to do this after the mapper has run.
$node->Refresh();
......@@ -3028,7 +3071,7 @@ sub GetTicketAuxAux($$$$$$$$$$$)
# Also update the virtexperiment table row.
# Do not update subnodes; they are fixed to the parent,
# while the parent is fixed to an actual node.
if (!defined($subnode_of)) {
if (! (defined($subnode_of) || defined($instantiate_on))) {
# Remember, we fix to the physnode not the virtual.
$virtnode->fixed(($node->isvirtnode() ?
$node->phys_nodeid() : $node->node_id()));
......
......@@ -588,6 +588,23 @@ sub GetSubnodeOf($)
}
return $result;
}
sub GetInstantiateOn($)
{
my ($node) = @_;
my $result = undef;
if (IsVersion0($node)) {
$result = GetText("instantiate_on", $node);
} else {
my @relations = FindNodes("n:relation", $node)->get_nodelist();
foreach my $current (@relations) {
if (GetText("type", $current) == "instantiate_on") {
$result = GetText("client_id", $current);
last;
}
}
}
return $result;
}
sub GetServices($)
{
......
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