ret.append(_str_from_xml(n))
return ret
-def _otherconfig_to_xml(xml, parent, val, attrs):
- otherconfig = xml.createElement("other_config")
- parent.appendChild(otherconfig)
+def _map_to_xml(xml, parent, tag, val, attrs):
+ e = xml.createElement(tag)
+ parent.appendChild(e)
for n,v in val.items():
- if not n in attrs:
- raise Error("Unknown other-config attribute: %s" % n)
- _str_to_xml(xml, otherconfig, n, v)
-def _otherconfig_from_xml(n, attrs):
+ if n in attrs:
+ _str_to_xml(xml, e, n, v)
+ else:
+ log("Unknown other-config attribute: %s" % n)
+
+def _map_from_xml(n, attrs):
ret = {}
for n in n.childNodes:
if n.nodeName in attrs:
ret[n.nodeName] = _str_from_xml(n)
return ret
+def _otherconfig_to_xml(xml, parent, val, attrs):
+ return _map_to_xml(xml, parent, "other_config", val, attrs)
+def _otherconfig_from_xml(n, attrs):
+ return _map_from_xml(n, attrs)
+
#
# Definitions of the database objects (and their attributes) used by interface-reconfigure.
#
_PIF_XML_TAG = "pif"
_VLAN_XML_TAG = "vlan"
+_TUNNEL_XML_TAG = "tunnel"
_BOND_XML_TAG = "bond"
_NETWORK_XML_TAG = "network"
+_POOL_XML_TAG = "pool"
-_ETHTOOL_OTHERCONFIG_ATTRS = ['ethtool-%s' % x for x in 'autoneg', 'speed', 'duplex', 'rx', 'tx', 'sg', 'tso', 'ufo', 'gso' ]
+_ETHTOOL_OTHERCONFIG_ATTRS = ['ethtool-%s' % x for x in 'autoneg', 'speed', 'duplex', 'rx', 'tx', 'sg', 'tso', 'ufo', 'gso', 'gro', 'lro' ]
_PIF_OTHERCONFIG_ATTRS = [ 'domain', 'peerdns', 'defaultroute', 'mtu', 'static-routes' ] + \
- [ 'bond-%s' % x for x in 'mode', 'miimon', 'downdelay', 'updelay', 'use_carrier' ] + \
+ [ 'bond-%s' % x for x in 'mode', 'miimon', 'downdelay',
+ 'updelay', 'use_carrier', 'hashing-algorithm' ] + \
+ [ 'vlan-bug-workaround' ] + \
_ETHTOOL_OTHERCONFIG_ATTRS
_PIF_ATTRS = { 'uuid': (_str_to_xml,_str_from_xml),
'VLAN_master_of': (_str_to_xml,_str_from_xml),
'VLAN_slave_of': (lambda x, p, t, v: _strlist_to_xml(x, p, 'VLAN_slave_of', 'master', v),
lambda n: _strlist_from_xml(n, 'VLAN_slave_Of', 'master')),
+ 'tunnel_access_PIF_of': (lambda x, p, t, v: _strlist_to_xml(x, p, 'tunnel_access_PIF_of', 'pif', v),
+ lambda n: _strlist_from_xml(n, 'tunnel_access_PIF_of', 'pif')),
+ 'tunnel_transport_PIF_of': (lambda x, p, t, v: _strlist_to_xml(x, p, 'tunnel_transport_PIF_of', 'pif', v),
+ lambda n: _strlist_from_xml(n, 'tunnel_transport_PIF_of', 'pif')),
'ip_configuration_mode': (_str_to_xml,_str_from_xml),
'IP': (_str_to_xml,_str_from_xml),
'netmask': (_str_to_xml,_str_from_xml),
'untagged_PIF': (_str_to_xml,_str_from_xml),
}
+_TUNNEL_ATTRS = { 'uuid': (_str_to_xml,_str_from_xml),
+ 'access_PIF': (_str_to_xml,_str_from_xml),
+ 'transport_PIF': (_str_to_xml,_str_from_xml),
+ }
_BOND_ATTRS = { 'uuid': (_str_to_xml,_str_from_xml),
'master': (_str_to_xml,_str_from_xml),
'slaves': (lambda x, p, t, v: _strlist_to_xml(x, p, 'slaves', 'slave', v),
lambda n: _strlist_from_xml(n, 'slaves', 'slave')),
}
-_NETWORK_OTHERCONFIG_ATTRS = [ 'mtu', 'static-routes' ] + _ETHTOOL_OTHERCONFIG_ATTRS
+_NETWORK_OTHERCONFIG_ATTRS = [ 'mtu',
+ 'static-routes',
+ 'vswitch-controller-fail-mode',
+ 'vswitch-disable-in-band' ] \
+ + _ETHTOOL_OTHERCONFIG_ATTRS
_NETWORK_ATTRS = { 'uuid': (_str_to_xml,_str_from_xml),
'bridge': (_str_to_xml,_str_from_xml),
lambda n: _otherconfig_from_xml(n, _NETWORK_OTHERCONFIG_ATTRS)),
}
+_POOL_OTHERCONFIG_ATTRS = ['vswitch-controller-fail-mode']
+
+_POOL_ATTRS = { 'other_config': (lambda x, p, t, v: _otherconfig_to_xml(x, p, v, _POOL_OTHERCONFIG_ATTRS),
+ lambda n: _otherconfig_from_xml(n, _POOL_OTHERCONFIG_ATTRS)),
+ }
+
#
# Database Cache object
#
def __get_vlan_records_from_xapi(self, session):
self.__vlans = {}
- for v in session.xenapi.VLAN.get_all():
- rec = session.xenapi.VLAN.get_record(v)
+ for (v,rec) in session.xenapi.VLAN.get_all_records().items():
if not self.__pif_on_host(rec['untagged_PIF']):
continue
self.__vlans[v] = {}
for f in _VLAN_ATTRS:
self.__vlans[v][f] = rec[f]
+ def __get_tunnel_records_from_xapi(self, session):
+ self.__tunnels = {}
+ for t in session.xenapi.tunnel.get_all():
+ rec = session.xenapi.tunnel.get_record(t)
+ if not self.__pif_on_host(rec['transport_PIF']):
+ continue
+ self.__tunnels[t] = {}
+ for f in _TUNNEL_ATTRS:
+ self.__tunnels[t][f] = rec[f]
+
def __get_bond_records_from_xapi(self, session):
self.__bonds = {}
- for b in session.xenapi.Bond.get_all():
- rec = session.xenapi.Bond.get_record(b)
+ for (b,rec) in session.xenapi.Bond.get_all_records().items():
if not self.__pif_on_host(rec['master']):
continue
self.__bonds[b] = {}
def __get_network_records_from_xapi(self, session):
self.__networks = {}
- for n in session.xenapi.network.get_all():
- rec = session.xenapi.network.get_record(n)
+ for (n,rec) in session.xenapi.network.get_all_records().items():
self.__networks[n] = {}
for f in _NETWORK_ATTRS:
if f == "PIFs":
if not rec['other_config'].has_key(f): continue
self.__networks[n]['other_config'][f] = rec['other_config'][f]
+ def __get_pool_records_from_xapi(self, session):
+ self.__pools = {}
+ for p in session.xenapi.pool.get_all():
+ rec = session.xenapi.pool.get_record(p)
+
+ self.__pools[p] = {}
+
+ for f in _POOL_ATTRS:
+ self.__pools[p][f] = rec[f]
+
+ for f in _POOL_OTHERCONFIG_ATTRS:
+ if rec['other_config'].has_key(f):
+ self.__pools[p]['other_config'][f] = rec['other_config'][f]
+
def __to_xml(self, xml, parent, key, ref, rec, attrs):
"""Encode a database object as XML"""
e = xml.createElement(key)
host = session.xenapi.host.get_by_uuid(inventory['INSTALLATION_UUID'])
self.__get_pif_records_from_xapi(session, host)
-
+ self.__get_pool_records_from_xapi(session)
+ self.__get_tunnel_records_from_xapi(session)
self.__get_vlan_records_from_xapi(session)
self.__get_bond_records_from_xapi(session)
self.__get_network_records_from_xapi(session)
self.__pifs = {}
self.__bonds = {}
self.__vlans = {}
+ self.__pools = {}
+ self.__tunnels = {}
self.__networks = {}
assert(len(xml.childNodes) == 1)
elif n.nodeName == _VLAN_XML_TAG:
(ref,rec) = self.__from_xml(n, _VLAN_ATTRS)
self.__vlans[ref] = rec
+ elif n.nodeName == _TUNNEL_XML_TAG:
+ (ref,rec) = self.__from_xml(n, _TUNNEL_ATTRS)
+ self.__vlans[ref] = rec
elif n.nodeName == _NETWORK_XML_TAG:
(ref,rec) = self.__from_xml(n, _NETWORK_ATTRS)
self.__networks[ref] = rec
+ elif n.nodeName == _POOL_XML_TAG:
+ (ref,rec) = self.__from_xml(n, _POOL_ATTRS)
+ self.__pools[ref] = rec
else:
raise Error("Unknown XML element %s" % n.nodeName)
self.__to_xml(xml, xml.documentElement, _BOND_XML_TAG, ref, rec, _BOND_ATTRS)
for (ref,rec) in self.__vlans.items():
self.__to_xml(xml, xml.documentElement, _VLAN_XML_TAG, ref, rec, _VLAN_ATTRS)
+ for (ref,rec) in self.__tunnels.items():
+ self.__to_xml(xml, xml.documentElement, _TUNNEL_XML_TAG, ref, rec, _TUNNEL_ATTRS)
for (ref,rec) in self.__networks.items():
self.__to_xml(xml, xml.documentElement, _NETWORK_XML_TAG, ref, rec,
_NETWORK_ATTRS)
+ for (ref,rec) in self.__pools.items():
+ self.__to_xml(xml, xml.documentElement, _POOL_XML_TAG, ref, rec, _POOL_ATTRS)
- f = open(cache_file, 'w')
+ temp_file = cache_file + ".%d" % os.getpid()
+ f = open(temp_file, 'w')
f.write(xml.toprettyxml())
f.close()
+ os.rename(temp_file, cache_file)
def get_pif_by_uuid(self, uuid):
pifs = map(lambda (ref,rec): ref,
filter(lambda (ref,rec): rec['device'] == device,
self.__pifs.items()))
+ def get_networks_with_bridge(self, bridge):
+ return map(lambda (ref,rec): ref,
+ filter(lambda (ref,rec): rec['bridge'] == bridge,
+ self.__networks.items()))
+
+ def get_network_by_bridge(self, bridge):
+ #Assumes one network has bridge.
+ try:
+ return self.get_networks_with_bridge(bridge)[0]
+ except KeyError:
+ return None
+
def get_pif_by_bridge(self, bridge):
- networks = map(lambda (ref,rec): ref,
- filter(lambda (ref,rec): rec['bridge'] == bridge,
- self.__networks.items()))
+ networks = self.get_networks_with_bridge(bridge)
+
if len(networks) == 0:
raise Error("No matching network \"%s\"" % bridge)
else:
return None
+ def get_pool_record(self):
+ if len(self.__pools) > 0:
+ return self.__pools.values()[0]
+
#
#
#
+PIF_OTHERCONFIG_DEFAULTS = {'gro': 'off', 'lro': 'off'}
-def ethtool_settings(oc):
+def ethtool_settings(oc, defaults = {}):
settings = []
if oc.has_key('ethtool-speed'):
val = oc['ethtool-speed']
log("Invalid value for ethtool-speed = %s. Must be 10|100|1000." % val)
if oc.has_key('ethtool-duplex'):
val = oc['ethtool-duplex']
- if val in ["10", "100", "1000"]:
- settings += ['duplex', 'val']
+ if val in ["half", "full"]:
+ settings += ['duplex', val]
else:
log("Invalid value for ethtool-duplex = %s. Must be half|full." % val)
if oc.has_key('ethtool-autoneg'):
else:
log("Invalid value for ethtool-autoneg = %s. Must be on|true|off|false." % val)
offload = []
- for opt in ("rx", "tx", "sg", "tso", "ufo", "gso"):
+ for opt in ("rx", "tx", "sg", "tso", "ufo", "gso", "gro", "lro"):
if oc.has_key("ethtool-" + opt):
val = oc["ethtool-" + opt]
if val in ["true", "on"]:
offload += [opt, 'off']
else:
log("Invalid value for ethtool-%s = %s. Must be on|true|off|false." % (opt, val))
+ elif opt in defaults:
+ offload += [opt, defaults[opt]]
return settings,offload
# By default the MTU is taken from the Network.MTU setting for VIF,
vlans = [db().get_vlan_record(v) for v in pifrec['VLAN_slave_of']]
return [v['untagged_PIF'] for v in vlans if v and db().pif_exists(v['untagged_PIF'])]
+#
+# Tunnel PIFs
+#
+def pif_is_tunnel(pif):
+ return len(db().get_pif_record(pif)['tunnel_access_PIF_of']) > 0
+
#
# Datapath base class
#
Should assume any configuration files changed attached in
the preconfigure stage are applied and bring up the
- necesary devices to provide the datapath for the
+ necessary devices to provide the datapath for the
PIF.
Should not bring up the IPdev.