[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen-3.0.5-testing] [XEND] Fully implement XenAPI network and PIF classes.



# HG changeset patch
# User Tom Wilkie <tom.wilkie@xxxxxxxxx>
# Date 1177514271 -3600
# Node ID 0bbc44c0b6e335bb08fc74b0dc1ec4ae6ed39b4b
# Parent  31f6f85778e5b8c8612e1712886cdef566284e1f
[XEND] Fully implement XenAPI network and PIF classes.

Now support creation of Networks and PIFs.  Auto discover current network 
settings.

signed-off-by: Tom Wilkie <tom.wilkie@xxxxxxxxx>
---
 tools/python/xen/xend/XendNetwork.py |  158 +++++++++++++---
 tools/python/xen/xend/XendNode.py    |  260 ++++++++++++---------------
 tools/python/xen/xend/XendPIF.py     |  332 ++++++++++++++++++++++++-----------
 3 files changed, 480 insertions(+), 270 deletions(-)

diff -r 31f6f85778e5 -r 0bbc44c0b6e3 tools/python/xen/xend/XendNetwork.py
--- a/tools/python/xen/xend/XendNetwork.py      Wed Apr 25 16:16:21 2007 +0100
+++ b/tools/python/xen/xend/XendNetwork.py      Wed Apr 25 16:17:51 2007 +0100
@@ -24,15 +24,122 @@ import XendDomain
 import XendDomain
 import XendNode
 from XendLogging import log
+from xen.xend import uuid as genuuid
+from xen.xend.XendBase import XendBase
+from xen.xend.XendError import *
+from xen.util import Brctl
+from xen.xend import XendAPIStore
 
 IP_ROUTE_RE = r'^default via ([\d\.]+) dev (\w+)'
 
-class XendNetwork:
-    def __init__(self, uuid, record):
-        self.uuid = uuid
-        self.name_label = record.get('name_label', '')
-        self.name_description = record.get('name_description', '')
-        self.other_config = record.get('other_config', {})
+def bridge_exists(name):
+    return name in Brctl.get_state().keys()
+
+class XendNetwork(XendBase):
+    """We're going to assert that the name_label of this
+    network is just the name of the bridge"""
+
+    def getClass(self):
+        return "network"
+
+    def getAttrRW(self):
+        attrRW = ['name_label',
+                  'name_description',
+                  'other_config',
+                  'default_gateway',
+                  'default_netmask']
+        return XendBase.getAttrRW() + attrRW
+
+    def getAttrRO(self):
+        attrRO =  ['VIFs',
+                   'PIFs']
+        return XendBase.getAttrRO() + attrRO
+
+    def getAttrInst(self):
+        return XendBase.getAttrInst() + self.getAttrRW()
+
+    def getMethods(self):
+        methods = ['add_to_other_config',
+                   'remove_from_other_config']
+        return XendBase.getMethods() + methods
+
+    def getFuncs(self):
+        funcs = ['create']
+        return XendBase.getFuncs() + funcs
+
+    getClass    = classmethod(getClass)
+    getAttrRO   = classmethod(getAttrRO)
+    getAttrRW   = classmethod(getAttrRW)
+    getAttrInst = classmethod(getAttrInst)
+    getMethods  = classmethod(getMethods)
+    getFuncs    = classmethod(getFuncs)
+
+    def create_phy(self, name):
+        """
+        Called when a new bridge is found on xend start
+        """
+        # Create new uuids
+        uuid = genuuid.createString()
+
+        # Create instance
+        record = {
+                'name_label':       name,
+                'name_description': '',
+                'other_config':     {},
+                'default_gateway':  '',
+                'default_netmask':  ''
+            }
+        network = XendNetwork(record, uuid)
+
+        return uuid
+        
+    def recreate(self, record, uuid):
+        """
+        Called on xend start / restart, or machine
+        restart, when read from saved config.
+        Needs to check network exists, create it otherwise
+        """
+
+        # Create instance (do this first, to check record)
+        network = XendNetwork(record, uuid)
+
+        # Create network if it doesn't already exist
+        if not bridge_exists(network.name_label):
+            Brctl.bridge_create(network.name_label)
+
+        return uuid
+
+    def create(self, record):
+        """
+        Called from API, to create a new network
+        """
+        # Create new uuids
+        uuid = genuuid.createString()
+
+        # Create instance (do this first, to check record)
+        network = XendNetwork(record, uuid)
+
+        # Check network doesn't already exist
+        name_label = network.name_label
+        if bridge_exists(name_label):
+            del network
+            raise UniqueNameError(name_label, "network")
+
+        # Create the bridge
+        Brctl.bridge_create(network.name_label)
+
+        return uuid
+
+    create_phy  = classmethod(create_phy)
+    recreate    = classmethod(recreate)
+    create      = classmethod(create)
+        
+    def __init__(self, record, uuid):       
+        XendBase.__init__(self, uuid, record)
+        
+    #
+    # XenAPI Mehtods
+    #
 
     def get_name_label(self):
         return self.name_label
@@ -41,9 +148,8 @@ class XendNetwork:
         return self.name_description
 
     def set_name_label(self, new_name):
-        self.name_label = new_name
-        XendNode.instance().save_networks()
-
+        pass
+        
     def set_name_description(self, new_desc):
         self.name_description = new_desc
         XendNode.instance().save_networks()
@@ -55,13 +161,14 @@ class XendNetwork:
             vifs = vm.get_vifs()
             for vif in vifs:
                 vif_cfg = vm.get_dev_xenapi_config('vif', vif)
-                if vif_cfg.get('network') == self.uuid:
+                if vif_cfg.get('network') == self.get_uuid():
                     result.append(vif)
         return result
 
     def get_PIFs(self):
-        return [x.uuid for x in XendNode.instance().pifs.values()
-                if x.network == self]
+        pifs = XendAPIStore.get_all("PIF")
+        return [pif.get_uuid() for pif in pifs
+                if pif.get_network() == self.get_uuid()]
 
     def get_other_config(self):
         return self.other_config
@@ -79,17 +186,16 @@ class XendNetwork:
             del self.other_config[key]
         XendNode.instance().save_networks()
 
-    def get_record(self):
-        return self.get_record_internal(True)
-
-    def get_record_internal(self, transient):
-        result = {
-            'uuid': self.uuid,
-            'name_label': self.name_label,
-            'name_description': self.name_description,
-            'other_config' : self.other_config,
-        }
-        if transient:
-            result['VIFs'] = self.get_VIFs()
-            result['PIFs'] = self.get_PIFs()
-        return result
+    def get_default_gateway(self):
+        return self.default_gateway
+
+    def set_default_gateway(self, gateway):
+        self.default_gateway = gateway
+        XendNode.instance().save_networks()
+
+    def get_default_netmask(self):
+        return self.default_netmask
+
+    def set_default_netmask(self, netmask):
+        self.default_netmask = netmask
+        XendNode.instance().save_networks()
diff -r 31f6f85778e5 -r 0bbc44c0b6e3 tools/python/xen/xend/XendNode.py
--- a/tools/python/xen/xend/XendNode.py Wed Apr 25 16:16:21 2007 +0100
+++ b/tools/python/xen/xend/XendNode.py Wed Apr 25 16:17:51 2007 +0100
@@ -21,9 +21,10 @@ import xen.lowlevel.xc
 import xen.lowlevel.xc
 
 from xen.util import Brctl
+from xen.xend import XendAPIStore
 
 import uuid, arch
-import XendPBD
+from XendPBD import XendPBD
 from XendError import *
 from XendOptions import instance as xendoptions
 from XendQCoWStorageRepo import XendQCoWStorageRepo
@@ -34,7 +35,7 @@ from XendNetwork import *
 from XendNetwork import *
 from XendStateStore import XendStateStore
 from XendMonitor import XendMonitor
-
+     
 class XendNode:
     """XendNode - Represents a Domain 0 Host."""
     
@@ -133,70 +134,72 @@ class XendNode:
                       'features' : cpu_features,
                     })
 
-        self.pifs = {}
-        self.pif_metrics = {}
-        self.networks = {}
         self.srs = {}
-        
-        # initialise networks
+
+        # Initialise networks
+        # First configure ones off disk
         saved_networks = self.state_store.load_state('network')
         if saved_networks:
             for net_uuid, network in saved_networks.items():
-                self.network_create(network, False, net_uuid)
-        else:
-            bridges = Brctl.get_state().keys()
-            for bridge in bridges:
-                self.network_create({'name_label' : bridge }, False)
+                XendNetwork.recreate(network, net_uuid)
                 
-        # Get a mapping from interface to bridge
-
-        if_to_br = dict([(i,b)
-                         for (b,ifs) in Brctl.get_state().items()
-                         for i in ifs])
-
-        # initialise PIFs
+        # Next discover any existing bridges and check
+        # they are not already configured
+        bridges = Brctl.get_state().keys()
+        configured_bridges = [XendAPIStore.get(
+                                  network_uuid, "network")
+                                      .get_name_label()
+                              for network_uuid in XendNetwork.get_all()]
+        unconfigured_bridges = [bridge
+                                for bridge in bridges
+                                if bridge not in configured_bridges]
+        for unconfigured_bridge in unconfigured_bridges:
+            XendNetwork.create_phy(unconfigured_bridge)
+
+        # Initialise PIFs
+        # First configure ones off disk
         saved_pifs = self.state_store.load_state('pif')
         if saved_pifs:
             for pif_uuid, pif in saved_pifs.items():
-                if pif.get('network') in self.networks:
-                    network = self.networks[pif['network']]
-                    try:
-                        if 'device' not in pif and 'name' in pif:
-                            # Compatibility hack, can go pretty soon.
-                            pif['device'] = pif['name']
-                        if 'metrics' not in pif:
-                            # Compatibility hack, can go pretty soon.
-                            pif['metrics'] = uuid.createString()
-
-                        try:
-                            pif['VLAN'] = int(pif.get('VLAN', -1))
-                        except (ValueError, TypeError):
-                            pif['VLAN'] = -1
-
-                        self._PIF_create(pif['device'], pif['MTU'],
-                                         pif['VLAN'],
-                                         pif['MAC'], network, False, pif_uuid,
-                                         pif['metrics'])
-                    except NetworkAlreadyConnected, exn:
-                        log.error('Cannot load saved PIF %s, as network %s ' +
-                                  'is already connected to PIF %s',
-                                  pif_uuid, pif['network'], exn.pif_uuid)
-        else:
-            for name, mtu, mac in linux_get_phy_ifaces():
-                bridge_name = if_to_br.get(name, None)
-                if bridge_name is not None:
-                    networks = [network for
-                                network in self.networks.values()
-                                if network.get_name_label() == bridge_name]
-                    if len(networks) > 0:
-                        network = networks[0]
-                        self._PIF_create(name, mtu, -1, mac, network, False)
-
+                XendPIF.recreate(pif, pif_uuid)
+ 
+        # Next discover any existing PIFs and check
+        # they are not already configured
+        configured_pifs = [XendAPIStore.get(
+                               pif_uuid, "PIF")
+                                   .get_interface_name()
+                           for pif_uuid in XendPIF.get_all()]
+        unconfigured_pifs = [(name, mtu, mac)
+                             for name, mtu, mac in linux_get_phy_ifaces()
+                             if name not in configured_pifs]
+
+        # Get a mapping from interface to bridge          
+        if_to_br = dict([(i,b)
+                         for (b,ifs) in Brctl.get_state().items()
+                             for i in ifs])
+
+        for name, mtu, mac in unconfigured_pifs:
+            # Check PIF is on bridge
+            # if not, ignore
+            bridge_name = if_to_br.get(name, None)
+            if bridge_name is not None:
+                # Translate bridge name to network uuid
+                for network_uuid in XendNetwork.get_all():
+                    network = XendAPIStore.get(
+                        network_uuid, 'network')
+                    if network.get_name_label() == bridge_name:
+                        XendPIF.create_phy(network_uuid, name,
+                                           mtu, mac)
+                        break
+                else:
+                    log.debug("Cannot find network for bridge %s "
+                              "when configuring PIF %s",
+                              (bridge_name, name))     
+        
         # initialise storage
         saved_srs = self.state_store.load_state('sr')
         if saved_srs:
             for sr_uuid, sr_cfg in saved_srs.items():
-                log.error("SAved SRS %s %s", sr_uuid, sr_cfg['type'])
                 if sr_cfg['type'] == 'qcow_file':
                     self.srs[sr_uuid] = XendQCoWStorageRepo(sr_uuid)
                 elif sr_cfg['type'] == 'local':
@@ -214,69 +217,47 @@ class XendNode:
         saved_pbds = self.state_store.load_state('pbd')
         if saved_pbds:
             for pbd_uuid, pbd_cfg in saved_pbds.items():
-                pbd_cfg['uuid'] = pbd_uuid
-                XendPBD.XendPBD(pbd_cfg)
-
-
-    def network_create(self, record, persist = True, net_uuid = None):
-        if net_uuid is None:
-            net_uuid = uuid.createString()
-        self.networks[net_uuid] = XendNetwork(net_uuid, record)
-        if persist:
-            self.save_networks()
-        return net_uuid
-
-
-    def network_destroy(self, net_uuid):
-        del self.networks[net_uuid]
-        self.save_networks()
-
-
-    def get_PIF_refs(self):
-        return self.pifs.keys()
-
-
-    def _PIF_create(self, name, mtu, vlan, mac, network, persist = True,
-                    pif_uuid = None, metrics_uuid = None):
-        for pif in self.pifs.values():
-            if pif.network == network:
-                raise NetworkAlreadyConnected(pif.uuid)
-
-        if pif_uuid is None:
-            pif_uuid = uuid.createString()
-        if metrics_uuid is None:
-            metrics_uuid = uuid.createString()
-
-        metrics = XendPIFMetrics(metrics_uuid)
-        pif = XendPIF(pif_uuid, metrics, name, mtu, vlan, mac, network, self)
-        metrics.set_PIF(pif)
-
-        self.pif_metrics[metrics_uuid] = metrics
-        self.pifs[pif_uuid] = pif
-
-        if persist:
-            self.save_PIFs()
-            self.refreshBridges()
-        return pif_uuid
-
-
-    def PIF_create_VLAN(self, pif_uuid, network_uuid, vlan):
-        if vlan < 0 or vlan >= 4096:
-            raise VLANTagInvalid()
-            
-        pif = self.pifs[pif_uuid]
-        network = self.networks[network_uuid]
-        return self._PIF_create(pif.device, pif.mtu, vlan, pif.mac, network)
-
-
-    def PIF_destroy(self, pif_uuid):
-        pif = self.pifs[pif_uuid]
-
-        if pif.vlan == -1:
-            raise PIFIsPhysical()
-
-        del self.pifs[pif_uuid]
-        self.save_PIFs()
+                XendPBD.recreate(pbd_uuid, pbd_cfg)
+
+##    def network_destroy(self, net_uuid):
+ ##       del self.networks[net_uuid]
+  ##      self.save_networks()
+
+
+##    def get_PIF_refs(self):
+##       return self.pifs[:]
+
+##   def _PIF_create(self, name, mtu, vlan, mac, network, persist = True,
+##                     pif_uuid = None, metrics_uuid = None):
+##         for pif in self.pifs.values():
+##             if pif.network == network:
+##                 raise NetworkAlreadyConnected(pif.uuid)
+
+##         if pif_uuid is None:
+##             pif_uuid = uuid.createString()
+##         if metrics_uuid is None:
+##             metrics_uuid = uuid.createString()
+
+##         metrics = XendPIFMetrics(metrics_uuid)
+##         pif = XendPIF(pif_uuid, metrics, name, mtu, vlan, mac, network, 
self)
+##         metrics.set_PIF(pif)
+
+##         self.pif_metrics[metrics_uuid] = metrics
+##         self.pifs[pif_uuid] = pif
+
+##         if persist:
+##             self.save_PIFs()
+##             self.refreshBridges()
+##         return pif_uuid
+
+##     def PIF_destroy(self, pif_uuid):
+##         pif = self.pifs[pif_uuid]
+
+##         if pif.vlan == -1:
+##             raise PIFIsPhysical()
+
+##         del self.pifs[pif_uuid]
+##         self.save_PIFs()
 
 
     def save(self):
@@ -284,7 +265,7 @@ class XendNode:
         host_record = {self.uuid: {'name_label':self.name,
                                    'name_description':self.desc,
                                    'metrics_uuid': self.host_metrics_uuid,
-                                   'other_config': repr(self.other_config)}}
+                                   'other_config': self.other_config}}
         self.state_store.save_state('host',host_record)
         self.state_store.save_state('cpu', self.cpus)
         self.save_PIFs()
@@ -293,18 +274,21 @@ class XendNode:
         self.save_SRs()
 
     def save_PIFs(self):
-        pif_records = dict([(k, v.get_record())
-                            for k, v in self.pifs.items()])
+        pif_records = dict([(pif_uuid, XendAPIStore.get(
+                                 pif_uuid, "PIF").get_record())
+                            for pif_uuid in XendPIF.get_all()])
         self.state_store.save_state('pif', pif_records)
 
     def save_networks(self):
-        net_records = dict([(k, v.get_record_internal(False))
-                            for k, v in self.networks.items()])
+        net_records = dict([(network_uuid, XendAPIStore.get(
+                                 network_uuid, "network").get_record())
+                            for network_uuid in XendNetwork.get_all()])
         self.state_store.save_state('network', net_records)
 
     def save_PBDs(self):
-        pbd_records = dict([(v.get_uuid(), v.get_record())
-                            for v in XendPBD.get_all()])
+        pbd_records = dict([(pbd_uuid, XendAPIStore.get(
+                                 pbd_uuid, "PBD").get_record())
+                            for pbd_uuid in XendPBD.get_all()])
         self.state_store.save_state('pbd', pbd_records)
 
     def save_SRs(self):
@@ -330,9 +314,6 @@ class XendNode:
 
     def is_valid_cpu(self, cpu_ref):
         return (cpu_ref in self.cpus)
-
-    def is_valid_network(self, network_ref):
-        return (network_ref in self.networks)
 
     def is_valid_sr(self, sr_ref):
         return (sr_ref in self.srs)
@@ -495,12 +476,6 @@ class XendNode:
     # Network Functions
     #
     
-    def get_network_refs(self):
-        return self.networks.keys()
-
-    def get_network(self, network_ref):
-        return self.networks[network_ref]
-
     def bridge_to_network(self, bridge):
         """
         Determine which network a particular bridge is attached to.
@@ -518,13 +493,12 @@ class XendNode:
                 raise Exception(
                     'Could not find default bridge, and none was specified')
 
-        bridges = Brctl.get_state()
-        if bridge not in bridges:
-            raise Exception('Bridge %s is not up' % bridge)
-        for pif in self.pifs.values():
-            if pif.interface_name() in bridges[bridge]:
-                return pif.network
-        raise Exception('Bridge %s is not connected to a network' % bridge)
+        for network_uuid in XendNetwork.get_all():
+            network = XendAPIStore.get(network_uuid, "network")
+            if network.get_name_label() == bridge:
+                return network
+        else:
+            raise Exception('Cannot find network for bridge %s' % bridge)
 
     #
     # Debug keys.
@@ -641,12 +615,6 @@ class XendNode:
         return dict(self.physinfo())
     def info_dict(self):
         return dict(self.info())
-
-
-    def refreshBridges(self):
-        for pif in self.pifs.values():
-            pif.refresh(Brctl.get_state())
-
 
 def parse_proc_cpuinfo():
     cpuinfo = {}
diff -r 31f6f85778e5 -r 0bbc44c0b6e3 tools/python/xen/xend/XendPIF.py
--- a/tools/python/xen/xend/XendPIF.py  Wed Apr 25 16:16:21 2007 +0100
+++ b/tools/python/xen/xend/XendPIF.py  Wed Apr 25 16:17:51 2007 +0100
@@ -19,11 +19,14 @@ import logging
 import logging
 import os
 import re
-
+from xen.xend import uuid as genuuid
+from xen.xend import XendAPIStore
+from xen.xend.XendBase import XendBase
+from xen.xend.XendPIFMetrics import XendPIFMetrics
+from xen.xend.XendError import *
 
 log = logging.getLogger("xend.XendPIF")
 log.setLevel(logging.TRACE)
-
 
 MAC_RE = re.compile(':'.join(['[0-9a-f]{2}'] * 6))
 IP_IFACE_RE = re.compile(r'^\d+: (\w+):.*mtu (\d+) .* link/\w+ ([0-9a-f:]+)')
@@ -87,106 +90,239 @@ def linux_set_mtu(iface, mtu):
     except ValueError:
         return False
 
-class XendPIF:
+def _create_VLAN(dev, vlan):
+    rc, _ = commands.getstatusoutput('vconfig add %s %d' %
+                                     (dev, vlan))
+    return rc == 0   
+
+class XendPIF(XendBase):
     """Representation of a Physical Network Interface."""
-    
-    def __init__(self, uuid, metrics, device, mtu, vlan, mac, network,
-                 host):
-        self.uuid = uuid
-        self.metrics = metrics
-        self.device = device
-        self.mac = mac
-        self.mtu = mtu
-        self.vlan = vlan
-        self.network = network
-        self.host = host
-
-    def set_device(self, new_device):
-        self.device = new_device
-
-    def set_mac(self, new_mac):
-        success = linux_set_mac(new_mac)
+
+    def getClass(self):
+        return "PIF"
+
+    def getAttrRO(self):
+        attrRO = ['network',
+                  'host',
+                  'metrics',
+                  'device']
+        return XendBase.getAttrRO() + attrRO
+    
+    def getAttrRW(self):
+        attrRW = ['MAC',
+                  'MTU',
+                  'VLAN']
+        return XendBase.getAttrRW() + attrRW
+
+    def getAttrInst(self):
+        attrInst = ['network',
+                    'device',
+                    'MAC',
+                    'MTU',
+                    'VLAN']
+        return attrInst
+
+    def getMethods(self):
+        methods = ['plug',
+                   'unplug']
+        return XendBase.getMethods() + methods
+
+    def getFuncs(self):
+        funcs = ['create_VLAN']
+        return XendBase.getFuncs() + funcs
+
+    getClass    = classmethod(getClass)
+    getAttrRO   = classmethod(getAttrRO)
+    getAttrRW   = classmethod(getAttrRW)
+    getAttrInst = classmethod(getAttrInst)
+    getMethods  = classmethod(getMethods)
+    getFuncs    = classmethod(getFuncs)
+    
+    def create_phy(self, network_uuid, device,
+                   MAC, MTU):
+        """
+        Called when a new physical PIF is found
+        Could be a VLAN...
+        """
+        # Create new uuids
+        pif_uuid = genuuid.createString()
+        metrics_uuid = genuuid.createString()
+
+        # Create instances
+        metrics = XendPIFMetrics(metrics_uuid, pif_uuid)
+
+        # Is this a VLAN?
+        VLANdot = device.split(".")
+        VLANcolon = device.split(":")
+
+        if len(VLANdot) > 1:
+            VLAN = VLANdot[1]
+            device = VLANdot[0]
+        elif len(VLANcolon) > 1:
+            VLAN = VLANcolon[1]
+            device = VLANcolon[0] 
+        else:
+            VLAN = -1
+            
+        record = {
+            'network': network_uuid,
+            'device':  device,
+            'MAC':     MAC,
+            'MTU':     MTU,
+            'VLAN':    VLAN
+            }
+        pif = XendPIF(record, pif_uuid, metrics_uuid)
+
+        return pif_uuid
+
+    def recreate(self, record, uuid):
+        """Called on xend start / restart"""        
+        pif_uuid = uuid
+        metrics_uuid = record['metrics']
+
+        # Create instances
+        metrics = XendPIFMetrics(metrics_uuid, pif_uuid)
+        pif = XendPIF(record, pif_uuid, metrics_uuid)
+
+        # If physical PIF, check exists
+        # If VLAN, create if not exist
+        ifs = [dev for dev, _1, _2 in linux_get_phy_ifaces()]
+        if pif.get_VLAN() == -1:
+            if pif.get_device() not in ifs:
+                del pif
+                del metrics
+                return None
+        else:
+            if pif.get_interface_name() not in ifs:
+                _create_VLAN(pif.get_device(), pif.get_VLAN())
+
+        return pif_uuid
+
+    def create_VLAN(self, device, network_uuid, host_ref, vlan):
+        """Exposed via API - create a new VLAN from existing VIF"""
+        
+        ifs = [name for name, _, _ in linux_get_phy_ifaces()]
+
+        vlan = int(vlan)
+
+        # Check VLAN tag is valid
+        if vlan < 0 or vlan >= 4096:
+            raise VLANTagInvalid(vlan)
+        
+        # Check device exists
+        if device not in ifs:
+            raise InvalidDeviceError(device)
+
+        # Check VLAN doesn't already exist
+        if "%s.%d" % (device, vlan) in ifs:
+            raise DeviceExistsError("%s.%d" % (device, vlan))
+
+        # Check network ref is valid
+        from xen.xend import XendNode
+        network_uuids = XendNode.instance().networks
+        if network_uuid in network_uuids:
+            raise InvalidHandleError("Network", network_ref)
+
+        # Check host_ref is this host
+        if host_ref != XendNode.instance().get_uuid():
+            raise InvalidHandleError("Host", host_ref)
+
+        # Create the VLAN
+        _create_VLAN(device, vlan)
+
+        # Create new uuids
+        pif_uuid = genuuid.createString()
+        metrics_uuid = genuuid.createString()
+
+        # Create the record
+        record = {
+            "device":  device,
+            "MAC":     '',
+            "MTU":     '',
+            "network": network_ref,
+            "VLAN":    vlan
+            }
+
+        # Create instances
+        metrics = XendPIFMetrics(metrics_uuid, pif_uuid)
+        pif = XendPIF(record, pif_uuid, metrics_uuid)
+        
+        # Add it to list of PIFs
+        XendNode.instance().pifs.append(pif_ref)        
+
+        # Add it to network
+        network.add_pif(pif_ref)
+
+        return pif_uuid
+
+    create_phy  = classmethod(create_phy)
+    recreate    = classmethod(recreate)
+    create_VLAN = classmethod(create_VLAN)
+    
+    def __init__(self, record, uuid, metrics_uuid):
+        XendBase.__init__(self, uuid, record)
+        self.metrics = metrics_uuid
+
+    def plug(self):
+        """Plug the PIF into the network"""
+        network = XendAPIStore.get(self.network,
+                                   "network")
+        bridge_name = network.get_name_label()
+
+        Brctl.vif_bridge_add({
+            "bridge": bridge_name,
+            "vif":    self.get_interface_name()
+            })
+
+    def unplug(self):
+        """Unplug the PIF from the network"""
+        pass
+
+    def get_interface_name(self):
+        if self.get_VLAN() == -1:
+            return self.get_device()
+        else:
+            return "%s.%d" % (self.get_device(), self.get_VLAN())
+        
+    def get_device(self):
+        """
+        This is the base interface.
+        For phy if (VLAN == -1) this is same as
+        if name.
+        For VLANs, this it the bit before the period
+        """
+        return self.device
+
+    def get_network(self):
+        return self.network
+
+    def get_host(self):
+        from xen.xend import XendNode
+        return XendNode.instance().get_uuid()
+
+    def get_metrics(self):
+        return self.metrics
+
+    def get_MAC(self):
+        return self.MAC
+
+    def set_MAC(self, new_mac):
+        success = linux_set_mac(self.device, new_mac)
         if success:
-            self.mac = new_mac
+            self.MAC = new_mac
         return success
 
-    def set_mtu(self, new_mtu):
-        success = linux_set_mtu(new_mtu)
+    def get_MTU(self):
+        return self.MTU
+
+    def set_MTU(self, new_mtu):
+        success = linux_set_mtu(self.device, new_mtu)
         if success:
-            self.mtu = new_mtu
+            self.MTU = new_mtu
         return success
 
-    def get_record(self):
-        return {'uuid': self.uuid,
-                'device': self.device,
-                'MAC': self.mac,
-                'MTU': self.mtu,
-                'VLAN': self.vlan,
-                'host': self.host.uuid,
-                'network': self.network.uuid,
-                'metrics': self.metrics.uuid}
-
-    def refresh(self, bridges):
-        ifname = self.interface_name()
-        rc, _ = _cmd('ip link show %s', ifname)
-        if rc != 0:
-            # Interface does not exist.  If it's a physical interface, then
-            # there's nothing we can do -- this should have been set up with
-            # the network script.  Otherwise, we can use vconfig to derive
-            # a subinterface.
-            if self.vlan == -1:
-                return
-            
-            rc, _ = _cmd('vconfig add %s %d', self.device, self.vlan)
-            if rc != 0:
-                log.error('Could not refresh VLAN for interface %s', ifname)
-                return
-            
-            log.info('Created network interface %s', ifname)
-
-        for brname, nics in bridges.items():
-            if ifname in nics:
-                log.debug('%s is already attached to %s', ifname, brname)
-                return
-
-        # The interface is not attached to a bridge.  Create one, and attach
-        # the interface to it.
-        brname = _new_bridge_name(bridges)
-        rc, _ = _cmd('brctl addbr %s', brname)
-        if rc != 0:
-            log.error('Could not create bridge %s for interface %s', brname,
-                      ifname)
-            return
-        log.info('Created network bridge %s', brname)
-        
-        rc, _ = _cmd('brctl addif %s %s', brname, ifname)
-        if rc != 0:
-            log.error('Could not add %s to %s', ifname, brname)
-            return
-        log.info('Added network interface %s to bridge %s', ifname, brname)
-
-
-    def interface_name(self):
-        if self.vlan != -1:
-            return '%s.%d' % (self.device, self.vlan)
-        else:
-            return self.device
-
-
-def _cmd(cmd, *args):
-    if len(args) > 0:
-        cmd = cmd % args
-    rc, output = commands.getstatusoutput(cmd)
-    if rc != 0:
-        log.debug('%s failed with code %d' % (cmd, rc))
-    log.trace('%s: %s' % (cmd, output))
-    return rc, output
-
-
-def _new_bridge_name(bridges):
-    n = 0
-    while True:
-        brname = 'xenbr%d' % n
-        if brname not in bridges:
-            return brname
-        n += 1
+    def get_VLAN(self):
+        return self.VLAN
+
+    def set_VLAN(self, VLAN):
+        pass

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.