# 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
|