filter['name'] = list(names)
if slice_ids:
filter['slice_id'] = list(slice_ids)
+ # get slices
slices = self.driver.shell.GetSlices(filter)
if not slices:
return []
- slice = slices[0]
+ slice = slices[0]
+
+ # get sliver users
+ persons = []
+ person_ids = []
+ for slice in slices:
+ person_ids.extend(slice['person_ids'])
+ if person_ids:
+ persons = self.driver.shell.GetPersons(person_ids)
+
+ # get user keys
+ keys = {}
+ key_ids = []
+ for person in persons:
+ key_ids.extend(person['key_ids'])
+
+ if key_ids:
+ key_list = self.driver.shell.GetKeys(key_ids)
+ for key in key_list:
+ keys[key['key_id']] = key
+
+ # construct user key info
+ users = []
+ for person in persons:
+ name = person['email'][0:person['email'].index('@')]
+ user = {
+ 'login': slice['name'],
+ 'user_urn': Xrn('%s.%s' % (self.driver.hrn, name), type='user').urn,
+ 'keys': [keys[k_id]['key'] for k_id in person['key_ids'] if k_id in keys]
+ }
+ users.append(user)
+
if node_ids:
node_ids = [node_id for node_id in node_ids if node_id in slice['node_ids']]
slice['node_ids'] = node_ids
sliver_hrn = '%s.%s-%s' % (self.driver.hrn, slice['slice_id'], node['node_id'])
node['sliver_id'] = Xrn(sliver_hrn, type='sliver').urn
node['urn'] = node['sliver_id']
+ node['services_user'] = users
slivers.append(node)
return slivers
rspec_node['slivers'] = [rspec_sliver]
# slivers always provide the ssh service
- login = Login({'authentication': 'ssh-keys', 'hostname': sliver['hostname'], 'port':'22', 'username': sliver['name']})
- service = Services({'login': login})
+ login = Login({'authentication': 'ssh-keys',
+ 'hostname': sliver['hostname'],
+ 'port':'22',
+ 'username': sliver['name'],
+ 'login': sliver['name']
+ })
+ service = Services({'login': login,
+ 'services_user': sliver['services_user']})
rspec_node['services'] = [service]
return rspec_node
'authentication',
'hostname',
'port',
- 'username'
+ 'username',
]
'install',
'execute',
'login',
+ 'services_user',
]
--- /dev/null
+from sfa.util.xrn import Xrn
+from sfa.util.xml import XpathFilter
+
+from sfa.rspecs.elements.node import Node
+from sfa.rspecs.elements.sliver import Sliver
+from sfa.rspecs.elements.location import Location
+from sfa.rspecs.elements.hardware_type import HardwareType
+from sfa.rspecs.elements.disk_image import DiskImage
+from sfa.rspecs.elements.interface import Interface
+from sfa.rspecs.elements.bwlimit import BWlimit
+from sfa.rspecs.elements.pltag import PLTag
+from sfa.rspecs.elements.v3.services import Services
+from sfa.rspecs.elements.versions.pgv2SliverType import PGv2SliverType
+from sfa.rspecs.elements.versions.pgv2Interface import PGv2Interface
+
+from sfa.planetlab.plxrn import xrn_to_hostname
+
+class Node:
+ @staticmethod
+ def add_nodes(xml, nodes):
+ node_elems = []
+ for node in nodes:
+ node_fields = ['component_manager_id', 'component_id', 'client_id', 'sliver_id', 'exclusive']
+ node_elem = xml.add_instance('node', node, node_fields)
+ node_elems.append(node_elem)
+ # set component name
+ if node.get('component_id'):
+ component_name = xrn_to_hostname(node['component_id'])
+ node_elem.set('component_name', component_name)
+ # set hardware types
+ if node.get('hardware_types'):
+ for hardware_type in node.get('hardware_types', []):
+ node_elem.add_instance('hardware_type', hardware_type, HardwareType.fields)
+ # set location
+ if node.get('location'):
+ node_elem.add_instance('location', node['location'], Location.fields)
+ # set interfaces
+ PGv2Interface.add_interfaces(node_elem, node.get('interfaces'))
+ #if node.get('interfaces'):
+ # for interface in node.get('interfaces', []):
+ # node_elem.add_instance('interface', interface, ['component_id', 'client_id'])
+ # set available element
+ if node.get('available'):
+ available_elem = node_elem.add_element('available', now=node['available'])
+ # add services
+ Services.add_services(node_elem, node.get('services', []))
+ # add slivers
+ slivers = node.get('slivers', [])
+ if not slivers:
+ # we must still advertise the available sliver types
+ slivers = Sliver({'type': 'plab-vserver'})
+ # we must also advertise the available initscripts
+ slivers['tags'] = []
+ if node.get('pl_initscripts'):
+ for initscript in node.get('pl_initscripts', []):
+ slivers['tags'].append({'name': 'initscript', 'value': initscript['name']})
+ PGv2SliverType.add_slivers(node_elem, slivers)
+
+ return node_elems
+
+ @staticmethod
+ def get_nodes(xml, filter={}):
+ xpath = '//node%s | //default:node%s' % (XpathFilter.xpath(filter), XpathFilter.xpath(filter))
+ node_elems = xml.xpath(xpath)
+ return Node.get_node_objs(node_elems)
+
+ @staticmethod
+ def get_nodes_with_slivers(xml, filter={}):
+ xpath = '//node[count(sliver_type)>0] | //default:node[count(default:sliver_type) > 0]'
+ node_elems = xml.xpath(xpath)
+ return Node.get_node_objs(node_elems)
+
+ @staticmethod
+ def get_node_objs(node_elems):
+ nodes = []
+ for node_elem in node_elems:
+ node = Node(node_elem.attrib, node_elem)
+ nodes.append(node)
+ if 'component_id' in node_elem.attrib:
+ node['authority_id'] = Xrn(node_elem.attrib['component_id']).get_authority_urn()
+
+ # get hardware types
+ hardware_type_elems = node_elem.xpath('./default:hardware_type | ./hardware_type')
+ node['hardware_types'] = [hw_type.get_instance(HardwareType) for hw_type in hardware_type_elems]
+
+ # get location
+ location_elems = node_elem.xpath('./default:location | ./location')
+ locations = [location_elem.get_instance(Location) for location_elem in location_elems]
+ if len(locations) > 0:
+ node['location'] = locations[0]
+
+ # get interfaces
+ iface_elems = node_elem.xpath('./default:interface | ./interface')
+ node['interfaces'] = [iface_elem.get_instance(Interface) for iface_elem in iface_elems]
+
+ # get services
+ node['services'] = Services.get_services(node_elem)
+
+ # get slivers
+ node['slivers'] = PGv2SliverType.get_slivers(node_elem)
+ available_elems = node_elem.xpath('./default:available | ./available')
+ if len(available_elems) > 0 and 'name' in available_elems[0].attrib:
+ if available_elems[0].attrib.get('now', '').lower() == 'true':
+ node['boot_state'] = 'boot'
+ else:
+ node['boot_state'] = 'disabled'
+ return nodes
+
+
+ @staticmethod
+ def add_slivers(xml, slivers):
+ component_ids = []
+ for sliver in slivers:
+ filter = {}
+ if isinstance(sliver, str):
+ filter['component_id'] = '*%s*' % sliver
+ sliver = {}
+ elif 'component_id' in sliver and sliver['component_id']:
+ filter['component_id'] = '*%s*' % sliver['component_id']
+ if not filter:
+ continue
+ nodes = Node.get_nodes(xml, filter)
+ if not nodes:
+ continue
+ node = nodes[0]
+ PGv2SliverType.add_slivers(node, sliver)
+
+ @staticmethod
+ def remove_slivers(xml, hostnames):
+ for hostname in hostnames:
+ nodes = Node.get_nodes(xml, {'component_id': '*%s*' % hostname})
+ for node in nodes:
+ slivers = PGv2SliverType.get_slivers(node.element)
+ for sliver in slivers:
+ node.element.remove(sliver.element)
+if __name__ == '__main__':
+ from sfa.rspecs.rspec import RSpec
+ import pdb
+ r = RSpec('/tmp/emulab.rspec')
+ r2 = RSpec(version = 'GENI')
+ nodes = Node.get_nodes(r.xml)
+ Node.add_nodes(r2.xml.root, nodes)
+ #pdb.set_trace()
+
+
--- /dev/null
+from sfa.rspecs.elements.element import Element
+from sfa.rspecs.elements.execute import Execute
+from sfa.rspecs.elements.install import Install
+from sfa.rspecs.elements.services import Services
+from sfa.rspecs.elements.login import Login
+
+class Services:
+ @staticmethod
+ def add_services(xml, services):
+ if not services:
+ return
+ for service in services:
+ service_elem = xml.add_element('services')
+ child_elements = {'install': Install.fields,
+ 'execute': Execute.fields,
+ 'login': Login.fields}
+ for (name, fields) in child_elements.items():
+ child = service.get(name)
+ if not child:
+ continue
+ if isinstance(child, dict):
+ service_elem.add_instance(name, child, fields)
+ elif isinstance(child, list):
+ for obj in child:
+ service_elem.add_instance(name, obj, fields)
+
+ # add ssh_users
+ if service['services_user']:
+ for ssh_user in service['services_user']:
+ ssh_user_elem = service_elem.add_element('{%s}services_user' % xml.namespaces['ssh-user'],
+ login=ssh_user['login'],
+ user_urn=ssh_user['user_urn'])
+ for key in ssh_user['keys']:
+ pkey_elem = ssh_user_elem.add_element('{%s}public_key' % xml.namespaces['ssh-user'])
+ pkey_elem.element.text=key
+
+
+ @staticmethod
+ def get_services(xml):
+ services = []
+ for services_elem in xml.xpath('./default:services | ./services'):
+ service = Services(services_elem.attrib, services_elem)
+ # get install
+ install_elems = xml.xpath('./default:install | ./install')
+ service['install'] = [install_elem.get_instance(Install) for install_elem in install_elems]
+ # get execute
+ execute_elems = xml.xpath('./default:execute | ./execute')
+ service['execute'] = [execute_elem.get_instance(Execute) for execute_elem in execute_elems]
+ # get login
+ login_elems = xml.xpath('./default:login | ./login')
+ service['login'] = [login_elem.get_instance(Login) for login_elem in login_elems]
+
+ ssh_user_elems = xml.xpath('./ssh-user:service_user | ./service_user')
+ service_users = []
+ for ssh_user_elem in ssh_user_elems:
+ service_user = ssh_user_elem.get_instance(None, fields=['login', 'user_urn'])
+ service['services_user'] = service_user
+ services.append(service)
+ return services
+
from sfa.rspecs.versions.pgv2 import PGv2
+from sfa.rspecs.elements.v3.node import Node
class GENIv3(PGv2):
type = 'GENI'
enabled = True
content_type = 'ad'
schema = 'http://www.geni.net/resources/rspec/3/ad.xsd'
- template = '<rspec type="advertisement" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.geni.net/resources/rspec/3" xmlns:plos="http://www.planet-lab.org/resources/sfa/ext/plos/1" xmlns:flack="http://www.protogeni.net/resources/rspec/ext/flack/1" xmlns:planetlab="http://www.planet-lab.org/resources/sfa/ext/planetlab/1" xsi:schemaLocation="http://www.geni.net/resources/rspec/3 http://www.geni.net/resources/rspec/3/ad.xsd http://www.planet-lab.org/resources/sfa/ext/planetlab/1 http://www.planet-lab.org/resources/sfa/ext/planetlab/1/planetlab.xsd http://www.planet-lab.org/resources/sfa/ext/plos/1 http://www.planet-lab.org/resources/sfa/ext/plos/1/plos.xsd http://www.geni.net/resources/rspec/ext/opstate/1 http://www.protogeni.net/resources/rspec/ext/opstate/1/ad.xsd"/>'
+ template = """<rspec type="advertisement" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.geni.net/resources/rspec/3" xmlns:plos="http://www.planet-lab.org/resources/sfa/ext/plos/1" xmlns:flack="http://www.protogeni.net/resources/rspec/ext/flack/1" xmlns:planetlab="http://www.planet-lab.org/resources/sfa/ext/planetlab/1" xmlns:opstate="http://www.geni.net/resources/rspec/ext/opstate/1" xsi:schemaLocation="http://www.geni.net/resources/rspec/3 http://www.geni.net/resources/rspec/3/ad.xsd http://www.planet-lab.org/resources/sfa/ext/planetlab/1 http://www.planet-lab.org/resources/sfa/ext/planetlab/1/planetlab.xsd http://www.planet-lab.org/resources/sfa/ext/plos/1 http://www.planet-lab.org/resources/sfa/ext/plos/1/plos.xsd http://www.geni.net/resources/rspec/ext/opstate/1 http://www.protogeni.net/resources/rspec/ext/opstate/1/ad.xsd">
+ <opstate:rspec_opstate aggregate_manager_id="urn:publicid:IDN+plc+authority+cm" start="geni_notready">
+ <opstate:sliver_type name="plab-vserver" />
+ <opstate:sliver_type name="plos-pc" />
+ <opstate:state name="geni_notready">
+ <opstate:action name="geni_start" next="geni_configuring">
+ <opstate:description>Boot the node</opstate:description>
+ </opstate:action>
+ <opstate:description>VMs begin powered down or inactive. They
+ must be explicitly booted before use.</opstate:description>
+ </opstate:state>
+ <opstate:state name="geni_configuring">
+ <opstate:wait type="geni_success" next="geni_ready" />
+ <opstate:wait type="geni_failure" next="geni_failed" />
+ <opstate:description>Booting takes a significant amount of time, so it
+ happens asynchronously while the node is in this
+ state.</opstate:description>
+ </opstate:state>
+ <opstate:state name="geni_ready">
+ <opstate:description>The node is up and ready to use.</opstate:description>
+ </opstate:state>
+ <opstate:state name="geni_failed">
+ <opstate:description>The node has failed and requires administrator
+ intervention before it can be used. Please contact support
+ for assistance.</opstate:description>
+ </opstate:state>
+ </opstate:rspec_opstate>
+</rspec>"""
class GENIv3Request(GENIv3):
enabled = True
enabled = True
content_type = 'manifest'
schema = 'http://www.geni.net/resources/rspec/3/manifest.xsd'
- template = '<rspec type="manifest" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.geni.net/resources/rspec/3" xmlns:plos="http://www.planet-lab.org/resources/sfa/ext/plos/1" xmlns:flack="http://www.protogeni.net/resources/rspec/ext/flack/1" xmlns:planetlab="http://www.planet-lab.org/resources/sfa/ext/planetlab/1" xsi:schemaLocation="http://www.geni.net/resources/rspec/3 http://www.geni.net/resources/rspec/3/manifest.xsd http://www.planet-lab.org/resources/sfa/ext/planetlab/1 http://www.planet-lab.org/resources/sfa/ext/planetlab/1/planetlab.xsd http://www.planet-lab.org/resources/sfa/ext/plos/1 http://www.planet-lab.org/resources/sfa/ext/plos/1/plos.xsd"/>'
-
+ template = '<rspec type="manifest" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.geni.net/resources/rspec/3" xmlns:plos="http://www.planet-lab.org/resources/sfa/ext/plos/1" xmlns:flack="http://www.protogeni.net/resources/rspec/ext/flack/1" xmlns:planetlab="http://www.planet-lab.org/resources/sfa/ext/planetlab/1" xmlns:ssh-user="http://www.geni.net/resources/rspec/ext/user/1" xsi:schemaLocation="http://www.geni.net/resources/rspec/3 http://www.geni.net/resources/rspec/3/manifest.xsd http://www.planet-lab.org/resources/sfa/ext/planetlab/1 http://www.planet-lab.org/resources/sfa/ext/planetlab/1/planetlab.xsd http://www.planet-lab.org/resources/sfa/ext/plos/1 http://www.planet-lab.org/resources/sfa/ext/plos/1/plos.xsd http://www.geni.net/resources/rspec/ext/user/1 http://www.geni.net/resources/rspec/ext/user/1/manifest.xsd"/>'
+
+
+ def add_nodes(self, nodes, check_for_dupes=False):
+ return Node.add_nodes(self.xml, nodes)
+
+ def get_nodes(self, filter=None):
+ return Node.get_nodes(self.xml, filter)