from copy import deepcopy from sfa.rspecs.version import RSpecVersion import sys from sfa.rspecs.elements.versions.iotlabv1Lease import Iotlabv1Lease from sfa.rspecs.elements.versions.iotlabv1Node import Iotlabv1Node from sfa.rspecs.elements.versions.iotlabv1Sliver import Iotlabv1Sliver from sfa.rspecs.elements.versions.sfav1Lease import SFAv1Lease from sfa.util.sfalogging import logger class Iotlabv1(RSpecVersion): #enabled = True type = 'Slab' content_type = 'ad' version = '1' #template = '' % type schema = 'http://senslab.info/resources/rspec/1/ad.xsd' namespace = 'http://www.geni.net/resources/rspec/3' extensions = { 'flack': "http://www.protogeni.net/resources/rspec/ext/flack/1", 'planetlab': "http://www.planet-lab.org/resources/sfa/ext/planetlab/1", } namespaces = dict(extensions.items() + [('default', namespace)]) elements = [] # Network def get_networks(self): #WARNING Added //default:network to the xpath #otherwise network element not detected 16/07/12 SA network_elems = self.xml.xpath('//network | //default:network') networks = [network_elem.get_instance(fields=['name', 'slice']) for \ network_elem in network_elems] return networks def add_network(self, network): network_tags = self.xml.xpath('//network[@name="%s"]' % network) if not network_tags: network_tag = self.xml.add_element('network', name=network) else: network_tag = network_tags[0] return network_tag # Nodes def get_nodes(self, filter=None): return Iotlabv1Node.get_nodes(self.xml, filter) def get_nodes_with_slivers(self): return Iotlabv1Node.get_nodes_with_slivers(self.xml) def get_slice_timeslot(self ): return Iotlabv1Timeslot.get_slice_timeslot(self.xml) def add_connection_information(self, ldap_username, sites_set): return Iotlabv1Node.add_connection_information(self.xml,ldap_username, sites_set) def add_nodes(self, nodes, check_for_dupes=False): return Iotlabv1Node.add_nodes(self.xml,nodes ) def merge_node(self, source_node_tag, network, no_dupes = False): logger.debug("SLABV1 merge_node") #if no_dupes and self.get_node_element(node['hostname']): ## node already exists #return network_tag = self.add_network(network) network_tag.append(deepcopy(source_node_tag)) # Slivers def get_sliver_attributes(self, hostname, node, network=None): print>>sys.stderr, "\r\n \r\n \r\n \t\t SLABV1.PY get_sliver_attributes hostname %s " %(hostname) nodes = self.get_nodes({'component_id': '*%s*' %hostname}) attribs = [] print>>sys.stderr, "\r\n \r\n \r\n \t\t SLABV1.PY get_sliver_attributes-----------------nodes %s " %(nodes) if nodes is not None and isinstance(nodes, list) and len(nodes) > 0: node = nodes[0] #if node : #sliver = node.xpath('./default:sliver | ./sliver') #sliver = node.xpath('./default:sliver', namespaces=self.namespaces) sliver = node['slivers'] if sliver is not None and isinstance(sliver, list) and len(sliver) > 0: sliver = sliver[0] attribs = sliver #attribs = self.attributes_list(sliver) print>>sys.stderr, "\r\n \r\n \r\n \t\t SLABV1.PY get_sliver_attributes----------NN------- sliver %s self.namespaces %s attribs %s " %(sliver, self.namespaces,attribs) return attribs def get_slice_attributes(self, network=None): slice_attributes = [] nodes_with_slivers = self.get_nodes_with_slivers() # TODO: default sliver attributes in the PG rspec? default_ns_prefix = self.namespaces['default'] for node in nodes_with_slivers: sliver_attributes = self.get_sliver_attributes(node['component_id'],node, network) for sliver_attribute in sliver_attributes: name = str(sliver_attribute[0]) text = str(sliver_attribute[1]) attribs = sliver_attribute[2] # we currently only suppor the and attributes #if 'info' in name: #attribute = {'name': 'flack_info', 'value': str(attribs), 'node_id': node} #slice_attributes.append(attribute) #elif 'initscript' in name: if 'initscript' in name: if attribs is not None and 'name' in attribs: value = attribs['name'] else: value = text attribute = {'name': 'initscript', 'value': value, 'node_id': node} slice_attributes.append(attribute) return slice_attributes def attributes_list(self, elem): opts = [] if elem is not None: for e in elem: opts.append((e.tag, str(e.text).strip(), e.attrib)) return opts def get_default_sliver_attributes(self, network=None): return [] def add_default_sliver_attribute(self, name, value, network=None): pass def add_slivers(self, hostnames, attributes=[], sliver_urn=None, append=False): # all nodes hould already be present in the rspec. Remove all # nodes that done have slivers print>>sys.stderr, "\r\n \r\n \r\n \t\t\t Iotlabv1.PY add_slivers ----->get_node " for hostname in hostnames: node_elems = self.get_nodes({'component_id': '*%s*' % hostname}) if not node_elems: continue node_elem = node_elems[0] # determine sliver types for this node #TODO : add_slivers valid type of sliver needs to be changed 13/07/12 SA valid_sliver_types = ['iotlab-node', 'emulab-openvz', 'raw-pc', 'plab-vserver', 'plab-vnode'] #valid_sliver_types = ['emulab-openvz', 'raw-pc', 'plab-vserver', 'plab-vnode'] requested_sliver_type = None for sliver_type in node_elem.get('slivers', []): if sliver_type.get('type') in valid_sliver_types: requested_sliver_type = sliver_type['type'] if not requested_sliver_type: continue sliver = {'type': requested_sliver_type, 'pl_tags': attributes} print>>sys.stderr, "\r\n \r\n \r\n \t\t\t Iotlabv1.PY add_slivers node_elem %s sliver_type %s \r\n \r\n " %(node_elem, sliver_type) # remove available element for available_elem in node_elem.xpath('./default:available | ./available'): node_elem.remove(available_elem) # remove interface elements for interface_elem in node_elem.xpath('./default:interface | ./interface'): node_elem.remove(interface_elem) # remove existing sliver_type elements for sliver_type in node_elem.get('slivers', []): node_elem.element.remove(sliver_type.element) # set the client id node_elem.element.set('client_id', hostname) if sliver_urn: pass # TODO # set the sliver id #slice_id = sliver_info.get('slice_id', -1) #node_id = sliver_info.get('node_id', -1) #sliver_id = urn_to_sliver_id(sliver_urn, slice_id, node_id) #node_elem.set('sliver_id', sliver_id) # add the sliver type elemnt Iotlabv1Sliver.add_slivers(node_elem.element, sliver) #Iotlabv1SliverType.add_slivers(node_elem.element, sliver) # remove all nodes without slivers if not append: for node_elem in self.get_nodes(): if not node_elem['client_id']: parent = node_elem.element.getparent() parent.remove(node_elem.element) def remove_slivers(self, slivers, network=None, no_dupes=False): Iotlabv1Node.remove_slivers(self.xml, slivers) # Utility def merge(self, in_rspec): """ Merge contents for specified rspec with current rspec """ if not in_rspec: return from sfa.rspecs.rspec import RSpec if isinstance(in_rspec, RSpec): rspec = in_rspec else: rspec = RSpec(in_rspec) if rspec.version.type.lower() == 'protogeni': from sfa.rspecs.rspec_converter import RSpecConverter in_rspec = RSpecConverter.to_sfa_rspec(rspec.toxml()) rspec = RSpec(in_rspec) # just copy over all networks #Attention special get_networks using //default:network xpath current_networks = self.get_networks() networks = rspec.version.get_networks() for network in networks: current_network = network.get('name') if current_network and current_network not in current_networks: self.xml.append(network.element) current_networks.append(current_network) # Leases def get_leases(self, lease_filter=None): return SFAv1Lease.get_leases(self.xml, lease_filter) #return Iotlabv1Lease.get_leases(self.xml, lease_filter) def add_leases(self, leases, network = None, no_dupes=False): SFAv1Lease.add_leases(self.xml, leases) #Iotlabv1Lease.add_leases(self.xml, leases) def cleanup(self): # remove unncecessary elements, attributes if self.type in ['request', 'manifest']: # remove 'available' element from remaining node elements self.xml.remove_element('//default:available | //available') class Iotlabv1Ad(Iotlabv1): enabled = True content_type = 'ad' schema = 'http://senslab.info/resources/rspec/1/ad.xsd' #http://www.geni.net/resources/rspec/3/ad.xsd' template = '' class Iotlabv1Request(Iotlabv1): enabled = True content_type = 'request' schema = 'http://senslab.info/resources/rspec/1/request.xsd' #http://www.geni.net/resources/rspec/3/request.xsd template = '' class Iotlabv1Manifest(Iotlabv1): enabled = True content_type = 'manifest' schema = 'http://senslab.info/resources/rspec/1/manifest.xsd' #http://www.geni.net/resources/rspec/3/manifest.xsd template = '' if __name__ == '__main__': from sfa.rspecs.rspec import RSpec from sfa.rspecs.rspec_elements import * r = RSpec('/tmp/iotlab.rspec') r.load_rspec_elements(Iotlabv1.elements) r.namespaces = Iotlabv1.namespaces print r.get(RSpecElements.NODE)