Commit e6c90969 authored by Leigh B. Stoller's avatar Leigh B. Stoller

Two big changes

1. Allow use of the shared nodes via the "exclusive" tag in the rspec.

2. Switch to using the mapper in GetTicket() and in RedeemTicket() as
   per this email I sent:

* GetTicket(): New rspec comes in and I build a virtual topology as I
 parse the rspec. Basically, virt_nodes and virt_lans table entries,
 which are stored into the DB. The rspec can include wildcards or
 specific nodes; I use the "fixed" slot of the virt_nodes table. Note
 that I am not yet handling fixed ifaces. Nice thing about this is
 that all of the show exp tools work.

 I run the (new) mapper on it in "solution" mode. This does two
 things; wildcards are mapped, and 2) it verifies that the rspec is
 mappable on the local hardware. Solution mode does not actually
 change the DB, but rather it spits out an XML file that I parse
 (note, we eventually will pass the rspec through, but I am not ready
 for that yet). I then allocate the nodes to the holding area, update
 the rspec, create a ticket, and return it.

* RedeemTicket(): I run the new mapper again, only this time in real
 mode with -update. This is basically a redo of the run above since
 all the nodes are reserved already, but the DB is actually filled
 out this time. I then create the slivers and such.

 The other difference is that instead of creating the vlans by hand,
 I can now run snmpit -t to do the work for me. Ditto for tear down
 with snmpit -r.

 Another bonus is that I can add (missing) IP addressess during the
 initial rspec parse, and the nodes now boot and have their
 interfaces configured. Virtual interfaces too, including the ones
 inside of virtual nodes.

* All of the above works with shared nodes too:

"<rspec xmlns=\"http://protogeni.net/resources/rspec/0.1\"> " +\
" <node virtual_id=\"geni1\" "+\
"       virtualization_type=\"emulab-vnode\" " +\
"       virtualization_subtype=\"emulab-openvz\" " +\
"       exclusive=\"0\"> " +\
"   <interface virtual_id=\"virt0\"/> " +\
" </node>" +\
" <node virtual_id=\"geni2\" "+\
"       virtualization_type=\"emulab-vnode\" " +\
"       virtualization_subtype=\"emulab-openvz\" " +\
"       exclusive=\"0\"> " +\
"   <interface virtual_id=\"virt0\"/> " +\
" </node>" +\
" <link virtual_id=\"link0\"> " +\
"  <interface_ref " +\
"            virtual_interface_id=\"virt0\" " +\
"            virtual_node_id=\"geni1\" " +\
"            /> " +\
"  <interface_ref " +\
"            virtual_interface_id=\"virt0\" " +\
"            virtual_node_id=\"geni2\" " +\
"            /> " +\
" </link> " +\
"</rspec>"

The shared nodes boot, and you can ping on the experimental networks.

Caveats:

* UpdateTicket and UpdateSliver need work as per the mail I sent the
 other day about the state of the sliver between the ticket and the
 sliver operations.

* Collocation specifications are ignored since we do not have any way
 to specify this to assign when wildcards are used. Rob, I am
 wondering if assign has any tricks we can take advantage of.

* Still need to commit all the snmpit changes and get that hooked into
 the CM.
parent 4a295eed
......@@ -545,9 +545,12 @@ sub Start($)
return -1;
}
# Remote nodes are handled special.
if ($node->isremotenode()) {
$sliver->Start();
# Remote/shared nodes are handled special.
if ($node->isremotenode() ||
($node->isvirtnode() && $node->sharing_mode())) {
$sliver->Start() == 0
or return -1;
next;
}
# We assume local nodes are not shared, so reboot pnode; this
......@@ -678,7 +681,8 @@ sub Create($$$)
}
#
# Provision all the slivers in the aggregate.
# Provision all the slivers in the aggregate. For links, this is done
# for the entire aggregate (experiment) at once.
#
sub Provision($;$)
{
......@@ -687,52 +691,16 @@ sub Provision($;$)
return -1
if (! ref($self));
my @slivers = ();
if ($self->SliverList(\@slivers) != 0) {
print STDERR "Could not get sliver list for $self\n";
return -1;
}
my $experiment = Experiment->Lookup($self->slice_uuid());
if (!defined($experiment)) {
print STDERR "Could not map $self to its experiment\n";
return -1;
}
my $vlan = VLan->Create($experiment, $self->uuid());
if (!defined($vlan)) {
print STDERR "Could not create vlan for $self\n";
goto bad;
}
foreach my $sliver (@slivers) {
my $interface = Interface->LookupByUUID($sliver->uuid());
if (! defined($interface)) {
print STDERR "Could not map $sliver to its interface object\n";
goto bad;
}
if (! $vlan->AddMember($interface->node_id(), $interface->iface())) {
print STDERR "$self: Could not add $interface to $vlan\n";
goto bad;
}
}
if ($vlan->Instantiate(1) != 0) {
print STDERR "$self: Could not instantiate $vlan on switches\n";
goto bad;
}
$self->SetStatus("ready");
return 0;
bad:
$vlan->UnInstantiate(1)
if (defined($vlan));
$vlan->Destroy()
if (defined($vlan));
return -1
}
#
# Unprovision all the slivers in the aggregate.
# Unprovision all the slivers in the aggregate. For links, this is done
# for the entire aggregate (experiment) at once.
#
sub UnProvision($)
{
......@@ -741,30 +709,6 @@ sub UnProvision($)
return -1
if (! ref($self));
my @slivers = ();
if ($self->SliverList(\@slivers) != 0) {
print STDERR "Could not get sliver list for $self\n";
return -1;
}
my $experiment = Experiment->Lookup($self->slice_uuid());
if (!defined($experiment)) {
print STDERR "Could not map $self to its experiment\n";
return -1;
}
my $vlan = VLan->Lookup($experiment, $self->uuid());
if (! defined($vlan)) {
print STDERR "No vlan associated with $self\n";
return 0;
}
if ($vlan->UnInstantiate(1) != 0) {
print STDERR "Could not uninstantiate $vlan\n";
return -1;
}
if ($vlan->Destroy() != 0) {
print STDERR "Could not destroy $vlan\n";
return -1;
}
return 0;
}
......
This diff is collapsed.
......@@ -690,7 +690,7 @@ use GeniCertificate;
use GeniUtil;
use Experiment;
use XML::Simple;
use libdb qw(TBDB_ALLOCSTATE_RES_INIT_DIRTY);
use libdb qw(TBDB_ALLOCSTATE_RES_INIT_DIRTY TBDB_NODESTATE_SHUTDOWN);
sub Create($$$$$$)
{
......@@ -702,12 +702,6 @@ sub Create($$$$$$)
print STDERR "Could not map $slice to its experiment\n";
return undef;
}
$sliver_uuid = GeniUtil::NewUUID()
if (!defined($sliver_uuid));
if (!defined($sliver_uuid)) {
print STDERR "Could not generate a sliver UUID for node in $slice\n";
return undef;
}
#
# the node is already allocated to the sliver, but still need to enter
......@@ -719,7 +713,7 @@ sub Create($$$$$$)
print STDERR "Could not map node $resource_uuid to its object\n";
return undef;
}
if (! $node->isremotenode()) {
if (! ($node->isremotenode() || $node->sharing_mode())) {
my $reservation = $node->Reservation();
if (!defined($reservation)) {
print STDERR "$node was already released from $slice\n";
......@@ -733,48 +727,20 @@ sub Create($$$$$$)
}
my $hrn = "${PGENIDOMAIN}." . $node->node_id();
my $nickname = $rspec->{'virtual_id'};
$sliver_uuid = $node->uuid();
#
# The resource UUID refers to the physical node, but the virtualization
# type might require a vnode.
#
if ($virtualization_type eq "emulab-vnode") {
my $vtype = "pcfake";
if ($node->isplabphysnode()) {
if ($node->type() =~ /^(\w*)phys$/) {
$vtype = $1;
}
else {
print STDERR "Could not determine vtype for $node\n";
return undef;
}
}
elsif (exists($rspec->{'virtualization_subtype'})) {
#
# See if a jail node is requested.
#
if ($rspec->{'virtualization_subtype'} eq "emulab-jail") {
$vtype = "pcvm";
}
}
#
# Create a virtual node on the physnode.
#
my @vnodes = ($sliver_uuid);
if (Node::CreateVnodes(\@vnodes,
{"pid" => $experiment->pid(),
"eid" => $experiment->eid(),
"count" => 1,
"vtype" => "$vtype",
"nodeid" => $node->node_id(),
"verbose" => 0 }) < 0) {
print STDERR "Could not create new virtual node on $node\n";
my $vnode = $experiment->VnameToNode($nickname);
if (!defined($vnode)) {
print STDERR "Could not lookup node $nickname in $experiment\n";
return undef;
}
my $vnode = Node->Lookup($vnodes[0]);
$hrn = "${PGENIDOMAIN}." . $vnode->node_id()
$hrn = "${PGENIDOMAIN}." . $vnode->node_id();
$sliver_uuid = $vnode->uuid();
}
return GeniSliver->Create($slice, $user, $sliver_uuid, $resource_uuid,
"Node", $hrn, $nickname, $rspec);
......@@ -823,11 +789,6 @@ sub Provision($;$)
my $pid = $experiment->pid();
my $eid = $experiment->eid();
if ($experiment->InsertVirtNode($node) != 0) {
print STDERR "Could not add virtnode entry for $node to $self\n";
return -1;
}
my $redirected = 0;
if (exists($self->rspec()->{'tmcd_server'}) &&
exists($self->rspec()->{'tmcd_nodeid'})) {
......@@ -856,55 +817,16 @@ sub Provision($;$)
return -1;
}
# Do this early.
#
# XXX This is the wrong place to do this.
my $osid = undef;
if (exists($self->rspec()->{'virtualization_subtype'}) &&
$self->rspec()->{'virtualization_subtype'} eq "emulab-jail") {
my $osinfo = OSinfo->LookupByName("FBSD-STD");
if (!defined($osinfo)) {
print STDERR "Could not find osinfo for FBSD-STD\n";
return -1;
}
# Need to resolve to the specfic OSID.
my $nextosinfo = $osinfo->ResolveNextOSID();
if (!defined($nextosinfo)) {
print STDERR "Could not resolve nextosid for $osinfo\n";
return -1;
}
$osid = $nextosinfo->osid();
#
# Gack.
#
my $cmdline = "/kernel.jail";
if ($nextosinfo->OSBootCmd("vnodehost", \$cmdline) != 0) {
print STDERR "Could not resolve cmdline for $nextosinfo\n";
return -1;
}
$pnode->Update({"def_boot_cmd_line" => $cmdline});
$pnode->ModifyReservation({"sharing_mode" => "shared"});
}
# The pnode might have multiple vnodes on it ... only insert once.
if (! $experiment->HasVirtNode($pnode)) {
if ($experiment->InsertVirtNode($pnode) != 0) {
print STDERR "Could not add virtnode for $pnode to $self\n";
return -1;
}
$pnode->ModifyReservation({"genisliver_idx" => $self->idx()});
}
# Not redirected. Use local tmcd anyway.
$node->ModifyReservation({"genisliver_idx" => $self->idx()})
if (!$redirected);
# Set it to boot the proper os.
if ($pnode->SelectOS($osid) != 0) {
return -1;
if (exists($self->rspec()->{'virtualization_subtype'})) {
my $subtype = $self->rspec()->{'virtualization_subtype'};
if (!$pnode->sharing_mode()) {
$pnode->ModifyReservation({"genisliver_idx" => $self->idx()});
}
}
}
else {
......@@ -961,14 +883,16 @@ sub UnProvision($;$)
if ($node->isremotenode()) {
system("$VNODESETUP -p -q -m -k $pid $eid $node_id");
if ($?) {
print STDERR "$VNODESETUP failed\n";
print STDERR "$VNODESETUP -k failed on $node_id\n";
return -1;
}
}
if ($experiment->DeleteVirtNode($node) != 0) {
print STDERR "Could remove virtnode entry for $node from $self\n";
return -1;
elsif ($node->sharing_mode()) {
system("$VNODESETUP -j -q -m -k $pid $eid $node_id");
if ($?) {
print STDERR "$VNODESETUP -k failed on $node_id\n";
return -1;
}
}
if (!$node->isremotenode() &&
......@@ -982,10 +906,15 @@ sub UnProvision($;$)
#
# If this is the last virtnode on the physnode, release the
# physnode too.
# physnode too. Unless its a shared host, in which case just
# deallocate the virtnode.
#
my @vnodes;
if ($pnode->VirtualNodes(\@vnodes) != 0) {
my @vnodes = ();
if ($pnode->sharing_mode()) {
$nophysfree = 1;
}
elsif ($pnode->VirtualNodes(\@vnodes) != 0) {
print STDERR "Could not get vnode list for $pnode\n";
return -1;
}
......@@ -994,18 +923,13 @@ sub UnProvision($;$)
system("$NFREE -q $pid $eid $node_id");
}
else {
if ($experiment->DeleteVirtNode($pnode) != 0) {
print STDERR
"Could remove virtnode entry for $pnode from $self\n";
return -1;
}
system("$NFREE -x -q $pid $eid $pnode_id");
$pnode->Refresh();
}
}
else {
goto skip
if (!$nophysfree);
if ($nophysfree);
system("$NFREE -q $pid $eid $node_id");
}
if ($?) {
......@@ -1039,6 +963,9 @@ sub Start($)
print STDERR "Could not map $self to its experiment\n";
return -1;
}
my $pid = $experiment->pid();
my $eid = $experiment->eid();
my $uuid = $self->uuid();
return 0
if (!defined($uuid));
......@@ -1064,7 +991,14 @@ sub Start($)
#
# Reboot and wait?
#
system("$NODEREBOOT -s $node_id");
if ($node->isvirtnode() && $node->sharing_mode()) {
if ($node->eventstate() eq TBDB_NODESTATE_SHUTDOWN()) {
system("$VNODESETUP -j -q -m $pid $eid $node_id");
}
}
else {
system("$NODEREBOOT -s $node_id");
}
return -1
if ($?);
}
......
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