Commit ac70e401 authored by Matt Strum's avatar Matt Strum Committed by Gary Wong

Additions and fixes for GEC15

parent aac3fc1d
......@@ -92,7 +92,7 @@ package com.flack.geni
if(user.authority == null || user.authority.type != GeniAuthority.TYPE_EMULAB)
SharedMain.tasker.add(new InitializeUserTaskGroup(user, true));
SharedMain.tasker.add(new GetResourcesTaskGroup(managers.length == 0));
SharedMain.tasker.add(new GetResourcesTaskGroup());
if(GeniMain.useSlice != null)
{
......
......@@ -51,7 +51,7 @@ package com.flack.geni
public static var clientNamespace:Namespace = new Namespace("client", "http://www.protogeni.net/resources/rspec/ext/client/1");
public static var historyNamespace:Namespace = new Namespace("history", "http://www.protogeni.net/resources/rspec/ext/history/1");
public static var emulabNamespace:Namespace = new Namespace("emulab", "http://www.protogeni.net/resources/rspec/ext/emulab/1");
public static var sharedVlanNamespace:Namespace = new Namespace("vlan", "http://www.protogeni.net/resources/rspec/ext/shared-vlan/1");
public static var sharedVlanNamespace:Namespace = new Namespace("vlan", "http://www.geni.net/resources/rspec/ext/shared-vlan/1");
public static var stitchingNamespace:Namespace = new Namespace("stitching", "http://hpn.east.isi.edu/rspec/ext/stitch/0.1/");
......
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (c) 2008-2012 University of Utah and the Flux Group.
{{{GENIPUBLIC-LICENSE
GENI Public License
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and/or hardware specification (the "Work") to
deal in the Work without restriction, including without limitation the
rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Work, and to permit persons to whom the Work
is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Work.
THE WORK IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE WORK OR THE USE OR OTHER DEALINGS
IN THE WORK.
}}}
-->
<s:GridItemEditor xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx" alpha="1">
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<fx:Script>
<![CDATA[
import com.flack.geni.resources.physical.PhysicalInterface;
import com.flack.geni.resources.physical.PhysicalInterfaceCollection;
import com.flack.geni.resources.physical.PhysicalNode;
import com.flack.geni.resources.virtual.VirtualInterface;
import com.flack.geni.resources.virtual.VirtualInterfaceCollection;
import com.flack.geni.resources.virtual.VirtualNode;
import com.flack.shared.resources.IdnUrn;
import mx.collections.ArrayCollection;
import mx.events.FlexEvent;
[Bindable]
private var interfaces:ArrayCollection = null;
override public function set value(newValue:Object):void {
// First, try to get the physical node info. If unbound, nothing to do.
var virtualInterface:VirtualInterface = data["source"];
var virtualNode:VirtualNode = virtualInterface.Owner;
var physicalNode:PhysicalNode = virtualNode.Physical;
if(physicalNode == null || newValue == null || newValue.physicalId.length == 0) {
valueDisplay.selectedItem = null;
boundCheckbox.selected = false;
controlsGroup.enabled = false;
return;
}
// Build up the physical interfaces once.
if(interfaces == null)
{
interfaces = new ArrayCollection();
for each(var nodeInterface:PhysicalInterface in physicalNode.interfaces.collection) {
if(nodeInterface.role == PhysicalInterface.ROLE_EXPERIMENTAL)
interfaces.addItem(nodeInterface.id.full);
}
}
boundCheckbox.selected = newValue.bound;
valueDisplay.selectedItem = newValue.physicalId;
controlsGroup.enabled = true;
}
override public function get value():Object {
// First, try to get the physicaln node information. If unbound, nothing to do.
var virtualInterface:VirtualInterface = data["source"];
var virtualNode:VirtualNode = virtualInterface.Owner;
var physicalNode:PhysicalNode = virtualNode.Physical;
if(physicalNode == null) {
return {physicalId: "", bound: false};
}
// If bound, make sure there aren't any physical interfaces used twice.
var candidateInterfaces:PhysicalInterfaceCollection = new PhysicalInterfaceCollection();
for each(var nodeInterface:PhysicalInterface in physicalNode.interfaces.collection) {
if(nodeInterface.role == PhysicalInterface.ROLE_EXPERIMENTAL && nodeInterface.id.full != valueDisplay.selectedItem)
candidateInterfaces.add(nodeInterface);
}
var checkInterfaces:VirtualInterfaceCollection = virtualNode.interfaces.Clone;
checkInterfaces.remove(virtualInterface);
// Go through the interfaces selected in the datagrid.
var replaceIdx:int = -1;
for(var i:int = 0; i < dataGrid.dataProviderLength; i++) {
if(i == rowIndex) continue;
var gridObject:Object = dataGrid.dataProvider.getItemAt(i);
var thisInterface:VirtualInterface = gridObject["source"];
if(thisInterface.Owner != virtualInterface.Owner) continue;
checkInterfaces.remove(thisInterface);
var selectedInterface:PhysicalInterface = candidateInterfaces.getById(gridObject["binding"].physicalId);
if(selectedInterface != null)
candidateInterfaces.remove(selectedInterface);
else
replaceIdx = i;
}
// Replace the interface with a remaining candidate interface if needed.
if(replaceIdx != -1)
{
var replaceInterface:PhysicalInterface = candidateInterfaces.collection[0];
dataGrid.dataProvider.getItemAt(replaceIdx)["binding"].physicalId = replaceInterface.id.full;
candidateInterfaces.remove(replaceInterface);
}
// Check interfaces which haven't been checked yet (which aren't in the datagrid).
var replaceExistingInterface:VirtualInterface = null;
for each(var checkInterface:VirtualInterface in checkInterfaces.collection)
{
if(checkInterface.physicalId.full == valueDisplay.selectedItem)
replaceExistingInterface = checkInterface;
else
candidateInterfaces.remove(checkInterface.Physical);
}
if(replaceExistingInterface != null)
replaceExistingInterface.physicalId.full = candidateInterfaces.collection[0].id.full;
return {physicalId: valueDisplay.selectedItem, bound:boundCheckbox.selected};
}
override public function setFocus():void {
valueDisplay.setFocus();
}
private function valueLabelFunction(value:Object):String {
return IdnUrn.getNameFrom(value as String);
}
]]>
</fx:Script>
<s:HGroup height="100%" width="100%"
id="controlsGroup"
verticalAlign="middle"
paddingLeft="2">
<s:CheckBox id="boundCheckbox"
label="Bound to" />
<s:DropDownList id="valueDisplay"
dataProvider="{interfaces}"
height="100%" width="100%"
change="boundCheckbox.selected = true;"
labelFunction="valueLabelFunction" />
</s:HGroup>
</s:GridItemEditor>
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (c) 2008-2012 University of Utah and the Flux Group.
{{{GENIPUBLIC-LICENSE
GENI Public License
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and/or hardware specification (the "Work") to
deal in the Work without restriction, including without limitation the
rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Work, and to permit persons to whom the Work
is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Work.
THE WORK IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE WORK OR THE USE OR OTHER DEALINGS
IN THE WORK.
}}}
-->
<s:GridItemRenderer
xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark" alpha="1">
<fx:Script>
<![CDATA[
import com.flack.geni.resources.physical.PhysicalInterface;
import com.flack.geni.resources.physical.PhysicalInterfaceCollection;
import com.flack.geni.resources.physical.PhysicalNode;
import com.flack.geni.resources.virtual.VirtualInterface;
import com.flack.geni.resources.virtual.VirtualInterfaceCollection;
import com.flack.geni.resources.virtual.VirtualNode;
import com.flack.shared.resources.IdnUrn;
import mx.collections.ArrayCollection;
[Bindable]
private var interfaces:ArrayCollection = null;
override public function prepare(hasBeenRecycled:Boolean):void
{
if(data && data[column.dataField])
{
// Just fake the drop down since the renderer doesn't need the whole list.
interfaces = new ArrayCollection();
interfaces.addItem(data[column.dataField].physicalId);
valueDisplay.selectedIndex = 0;
var virtualInterface:VirtualInterface = data["source"];
var virtualNode:VirtualNode = virtualInterface.Owner;
var physicalNode:PhysicalNode = virtualNode.Physical;
if(physicalNode == null || data[column.dataField].physicalId == "") {
boundCheckbox.selected = false;
return;
}
boundCheckbox.selected = data[column.dataField].bound;
}
else
valueDisplay.selectedItem = null;
}
private function valueLabelFunction(value:Object):String {
return IdnUrn.getNameFrom(value as String);
}
]]>
</fx:Script>
<s:HGroup height="100%" width="100%"
paddingLeft="2"
verticalAlign="middle"
enabled="false">
<s:CheckBox id="boundCheckbox"
label="Bound to" />
<s:DropDownList id="valueDisplay"
dataProvider="{interfaces}"
height="100%" width="100%"
labelFunction="valueLabelFunction" />
</s:HGroup>
</s:GridItemRenderer>
......@@ -37,7 +37,7 @@ IN THE WORK.
xmlns:areas="com.flack.geni.display.areas.*"
xmlns:components="com.flack.shared.display.components.*"
creationComplete="init()"
title="{link.clientId}" xmlns:areas1="com.flack.shared.display.areas.*">
title="{link.clientId}" xmlns:areas1="com.flack.shared.display.areas.*" xmlns:display="com.flack.geni.display.*">
<fx:Script>
<![CDATA[
import com.flack.geni.resources.Property;
......@@ -181,7 +181,7 @@ IN THE WORK.
owner: iface._owner,
clientId: iface.clientId,
macAddress: iface.macAddress,
physicalName: iface.physicalId.name,
binding: {physicalId: iface.physicalId.full, bound: iface.bound},
ipaddress: iface.ip.address,
ipnetmask: iface.ip.netmask,
iptype: iface.ip.type
......@@ -250,7 +250,10 @@ IN THE WORK.
{
var iface:VirtualInterface = ifaceObj.source;
iface.clientId = ifaceObj.clientId;
iface.ip.bound = iface.ip.address != ifaceObj.ipaddress;
iface.ip.address = ifaceObj.ipaddress;
iface.bound = ifaceObj.binding.bound;
iface.physicalId.full = ifaceObj.binding.physicalId;
iface.ip.netmask = ifaceObj.ipnetmask;
iface.ip.type = ifaceObj.iptype;
}
......@@ -416,23 +419,18 @@ IN THE WORK.
</fx:Component>
</s:itemRenderer>
</s:GridColumn>
<s:GridColumn dataField="physicalName"
headerText="Physical"
editable="false">
<s:GridColumn dataField="binding"
headerText="Physical">
<s:itemRenderer>
<fx:Component>
<s:DefaultGridItemRenderer />
<display:VirtualBoundInterfaceGridRenderer />
</fx:Component>
</s:itemRenderer>
</s:GridColumn>
<s:GridColumn dataField="macAddress"
headerText="MAC"
editable="false">
<s:itemRenderer>
<s:itemEditor>
<fx:Component>
<s:DefaultGridItemRenderer />
<display:VirtualBoundInterfaceEditor />
</fx:Component>
</s:itemRenderer>
</s:itemEditor>
</s:GridColumn>
<s:GridColumn dataField="ipaddress"
headerText="IP">
......
......@@ -86,6 +86,7 @@ IN THE WORK.
import com.flack.shared.utils.ColorUtil;
import com.flack.shared.utils.ImageUtil;
import com.flack.shared.utils.NetUtil;
import com.hurlant.math.bi_internal;
import mx.collections.ArrayCollection;
import mx.controls.Alert;
......@@ -202,6 +203,8 @@ IN THE WORK.
loginGroup.visible = true;
usernameText.text = node.services.loginServices[0].username;
hostnameText.text = node.services.loginServices[0].FullHostname;
visitButton.toolTip = "Click to launch http://" + node.services.loginServices[0].hostname;
sshButton.toolTip = "Click to launch ssh://" + node.services.loginServices[0].FullLogin;
}
managerList.selectedItem = node.manager;
......@@ -259,7 +262,7 @@ IN THE WORK.
source: iface,
clientId: iface.clientId,
macAddress: iface.macAddress,
physicalName: iface.physicalId.name,
binding: {physicalId: iface.physicalId.full, bound: iface.bound},
ipaddress: iface.ip.address,
ipnetmask: iface.ip.netmask,
iptype: iface.ip.type
......@@ -474,7 +477,7 @@ IN THE WORK.
protected function hardwareList_valueCommitHandler(event:FlexEvent):void
{
hardwareTypeCheckbox.selected = hardwareList.selectedItem != null
hardwareTypeCheckbox.selected = hardwareList.selectedItem != null;
if(!okButton.enabled)
okButton.enabled = node.hardwareType.name != hardwareList.selectedItem;
}
......@@ -663,11 +666,15 @@ IN THE WORK.
else
node.hardwareType.name = hardwareList.selectedItem.name;
node.physicalId.full = "";
node.flackInfo.unbound = true;
}
else
{
node.hardwareType.name = "";
node.physicalId.full = this.SelectedBoundNode.id.full;
var boundId:String = SelectedBoundNode.id.full;
if(node.physicalId.full != boundId)
node.flackInfo.unbound = false;
node.physicalId.full = boundId;
}
node.exclusive = exclusiveCheckbox.selected;
......@@ -727,7 +734,10 @@ IN THE WORK.
{
var iface:VirtualInterface = ifaceObj.source;
iface.clientId = ifaceObj.clientId;
iface.ip.bound = iface.ip.address != ifaceObj.ipaddress;
iface.ip.address = ifaceObj.ipaddress;
iface.bound = ifaceObj.binding.bound;
iface.physicalId.full = ifaceObj.binding.physicalId;
iface.ip.netmask = ifaceObj.ipnetmask;
iface.ip.type = ifaceObj.iptype;
}
......@@ -849,8 +859,8 @@ IN THE WORK.
<mx:Label id="usernameText" selectable="true" />
<s:Label text="Hostname" fontWeight="bold" />
<mx:Label id="hostnameText" selectable="true" />
<s:Button label="Visit" click="visitHost()" />
<s:Button label="SSH" click="openSsh()" />
<s:Button id="visitButton" label="Visit" click="visitHost()" />
<s:Button id="sshButton" label="SSH" click="openSsh()" />
</s:HGroup>
<s:ButtonBar dataProvider="{sectionViewstack}"
......@@ -922,6 +932,7 @@ IN THE WORK.
dataProvider="{physicalNodes}"
width="100%"
valueCommit="boundDropDownList_valueCommitHandler(event)"
change="if(!okButton.enabled) okButton.enabled = true;"
labelField="name" />
<components:ImageButton id="viewPhysicalNode"
icon="{ImageUtil.infoIcon}"
......@@ -1081,14 +1092,18 @@ IN THE WORK.
</fx:Component>
</s:itemRenderer>
</s:GridColumn>
<s:GridColumn dataField="physicalName"
headerText="Physical"
editable="false">
<s:GridColumn dataField="binding"
headerText="Physical">
<s:itemRenderer>
<fx:Component>
<s:DefaultGridItemRenderer />
<display:VirtualBoundInterfaceGridRenderer />
</fx:Component>
</s:itemRenderer>
<s:itemEditor>
<fx:Component>
<display:VirtualBoundInterfaceEditor />
</fx:Component>
</s:itemEditor>
</s:GridColumn>
<s:GridColumn dataField="macAddress"
headerText="MAC"
......
......@@ -31,7 +31,10 @@
package com.flack.geni.plugins.instools.instasks
{
import com.flack.geni.plugins.instools.SliceInstoolsDetails;
import com.flack.geni.resources.virtual.Sliver;
import com.flack.geni.tasks.groups.slice.RefreshSliceStatusTaskGroup;
import com.flack.shared.FlackEvent;
import com.flack.shared.SharedMain;
import com.flack.shared.tasks.SerialTaskGroup;
import com.flack.shared.tasks.Task;
......@@ -63,7 +66,12 @@ package com.flack.geni.plugins.instools.instasks
relatedTo.push(newDetails.slice);
details = newDetails;
details.slice.clearStatus();
details.slice.setSliverStatus(Sliver.STATUS_CHANGING);
SharedMain.sharedDispatcher.dispatchChanged(
FlackEvent.CHANGED_SLICE,
details.slice,
FlackEvent.ACTION_STATUS
);
add(new InstoolsVersionsTaskGroup(details));
}
......
......@@ -35,6 +35,8 @@ package com.flack.geni.plugins.instools.instasks
import com.flack.geni.resources.virtual.Sliver;
import com.flack.geni.tasks.xmlrpc.protogeni.ProtogeniXmlrpcTask;
import com.flack.geni.tasks.xmlrpc.protogeni.cm.StartSliverCmTask;
import com.flack.shared.FlackEvent;
import com.flack.shared.SharedMain;
import com.flack.shared.logging.LogMessage;
import com.flack.shared.tasks.TaskError;
import com.flack.shared.utils.MathUtil;
......@@ -81,6 +83,7 @@ package com.flack.geni.plugins.instools.instasks
case "INSTRUMENTIZE_COMPLETE": //instrumentize is finished, experiment is ready, etc.
details.portal_url[sliver.manager.id.full] = String(data.portal_url);
sliver.status = Sliver.STATUS_READY;
broadcastStatus();
var msg:String = details.creating ? "Instrumentizing complete!" : "INSTOOLS running!";
addMessage(
msg,
......@@ -162,6 +165,7 @@ package com.flack.geni.plugins.instools.instasks
break;
default:
sliver.status = Sliver.STATUS_FAILED;
broadcastStatus();
addMessage(
status + "!",
status + "!"
......@@ -178,7 +182,11 @@ package com.flack.geni.plugins.instools.instasks
}
// At this point, still changing and polling...
var wasChanging:Boolean = sliver.status != Sliver.STATUS_CHANGING;
sliver.status = Sliver.STATUS_CHANGING;
if(!wasChanging)
broadcastStatus();
broadcastStatus();
delay = MathUtil.randomNumberBetween(20, 60);
runCleanup();
start();
......@@ -198,6 +206,20 @@ package com.flack.geni.plugins.instools.instasks
failed();
}
private function broadcastStatus():void
{
SharedMain.sharedDispatcher.dispatchChanged(
FlackEvent.CHANGED_SLIVER,
sliver,
FlackEvent.ACTION_STATUS
);
SharedMain.sharedDispatcher.dispatchChanged(
FlackEvent.CHANGED_SLICE,
sliver.slice,
FlackEvent.ACTION_STATUS
);
}
public function failed():void
{
addMessage(
......
......@@ -67,7 +67,9 @@ package com.flack.geni.plugins.instools.instasks
for each(var sliver:Sliver in details.slice.slivers.collection)
{
if(details.MC_present[sliver.manager.id.full])
{
add(new SaveManifestTask(sliver, details, generate.resultRspec));
}
else
{
addMessage(
......
......@@ -42,7 +42,7 @@ package com.flack.geni.resources.virtual
public var address:String;
public var netmask:String = "";
public var type:String = "";
public var unset:Boolean = true;
public var bound:Boolean = false;
public var extensions:Extensions = new Extensions();
......
......@@ -454,10 +454,16 @@ package com.flack.geni.resources.virtual
return true;
}
public function clearStatus():void
public function clearStatus(sliversOnly:Boolean = false):void
{
for each(var sliver:Sliver in slivers.collection)
sliver.clearStatus();
sliver.clearStatus(sliversOnly);
}
public function setSliverStatus(sliverStatus:String):void
{
for each(var sliver:Sliver in slivers.collection)
sliver.status = sliverStatus;
}
/**
......
......@@ -105,10 +105,12 @@ package com.flack.geni.resources.virtual
|| status == STATUS_UNKNOWN
|| status == STATUS_STOPPED;
}
public function clearStatus():void
public function clearStatus(sliversOnly:Boolean = false):void
{
state = "";
status