X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=xenserver%2Fopt_xensource_libexec_interface-reconfigure;h=eae198b914823d23bdc819922b5e638efe4861d6;hb=5990cd46192920da5faedde84b6123b854ec0555;hp=301251f7623a640d5a9d0e3cbfc2a8c5c6341d1e;hpb=eeb569bf8ccb5760154205d0ccdef56ff0e9c5a7;p=openvswitch diff --git a/xenserver/opt_xensource_libexec_interface-reconfigure b/xenserver/opt_xensource_libexec_interface-reconfigure index 301251f7..eae198b9 100755 --- a/xenserver/opt_xensource_libexec_interface-reconfigure +++ b/xenserver/opt_xensource_libexec_interface-reconfigure @@ -5,22 +5,26 @@ # """Usage: - %(command-name)s --session --pif [up|down|rewrite] - %(command-name)s --force [up|down|rewrite ] + %(command-name)s up + %(command-name)s down + %(command-name)s [] rewrite + %(command-name)s --force up + %(command-name)s --force down + %(command-name)s --force rewrite --device= %(command-name)s --force all down - where, - = --device= --mode=dhcp - = --device= --mode=static --ip= --netmask= [--gateway=] + where is one of: + --session --pif + --pif-uuid + and is one of: + --mode=dhcp + --mode=static --ip= --netmask= [--gateway=] Options: --session A session reference to use to access the xapi DB - --pif A PIF reference. - --force-interface An interface name. Mutually exclusive with --session/--pif. - - Either both --session and --pif or just --pif-uuid. - - is either "up" or "down" or "rewrite" + --pif A PIF reference within the session. + --pif-uuid The UUID of a PIF. + --force An interface name. """ # @@ -28,7 +32,6 @@ # # --output-directory= Write configuration to . Also disables actually # raising/lowering the interfaces -# --pif-uuid A PIF UUID, use instead of --session/--pif. # # # @@ -38,40 +41,23 @@ # 3. A network may have an associated bridge, allowing vifs to be attached # 4. A network may be bridgeless (there's no point having a bridge over a storage pif) -# XXX: --force-interface=all down - -# XXX: --force-interface rewrite - -# XXX: Sometimes this leaves "orphaned" datapaths, e.g. a datapath whose -# only port is the local port. Should delete those. - -# XXX: This can leave crud in ovs-vswitchd.conf in this scenario: -# - Create bond in XenCenter. -# - Create VLAN on bond in XenCenter. -# - Attempt to delete bond in XenCenter (this will fail because there -# is a VLAN on the bond, although the error may not be reported -# until the next step) -# - Delete VLAN in XenCenter. -# - Delete bond in XenCenter. -# At this point there will still be some configuration data for the bond -# or the VLAN in ovs-vswitchd.conf. - import XenAPI import os, sys, getopt, time, signal import syslog import traceback import time import re -import pickle import random +from xml.dom.minidom import getDOMImplementation +from xml.dom.minidom import parse as parseXML output_directory = None db = None management_pif = None -dbcache_file = "/etc/ovs-vswitch.dbcache" -vswitch_config_dir = "/etc/openvswitch" +vswitch_state_dir = "/var/lib/openvswitch/" +dbcache_file = vswitch_state_dir + "dbcache" class Usage(Exception): def __init__(self, msg): @@ -272,11 +258,225 @@ def get_netdev_by_mac(mac): return device return None +# +# Helper functions for encoding/decoding database attributes to/from XML. +# +def str_to_xml(xml, parent, tag, val): + e = xml.createElement(tag) + parent.appendChild(e) + v = xml.createTextNode(val) + e.appendChild(v) +def str_from_xml(n): + def getText(nodelist): + rc = "" + for node in nodelist: + if node.nodeType == node.TEXT_NODE: + rc = rc + node.data + return rc + return getText(n.childNodes).strip() + + +def bool_to_xml(xml, parent, tag, val): + if val: + str_to_xml(xml, parent, tag, "True") + else: + str_to_xml(xml, parent, tag, "False") +def bool_from_xml(n): + s = str_from_xml(n) + if s == "True": + return True + elif s == "False": + return False + else: + raise Error("Unknown boolean value %s" % s); + +def strlist_to_xml(xml, parent, ltag, itag, val): + e = xml.createElement(ltag) + parent.appendChild(e) + for v in val: + c = xml.createElement(itag) + e.appendChild(c) + cv = xml.createTextNode(v) + c.appendChild(cv) +def strlist_from_xml(n, ltag, itag): + ret = [] + for n in n.childNodes: + if n.nodeName == itag: + ret.append(str_from_xml(n)) + return ret + +def otherconfig_to_xml(xml, parent, val, attrs): + otherconfig = xml.createElement("other_config") + parent.appendChild(otherconfig) + 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): + ret = {} + for n in n.childNodes: + if n.nodeName in attrs: + ret[n.nodeName] = str_from_xml(n) + return ret + +# +# Definitions of the database objects (and their attributes) used by interface-reconfigure. +# +# Each object is defined by a dictionary mapping an attribute name in +# the xapi database to a tuple containing two items: +# - a function which takes this attribute and encodes it as XML. +# - a function which takes XML and decocdes it into a value. +# +# other-config attributes are specified as a simple array of strings + +PIF_XML_TAG = "pif" +VLAN_XML_TAG = "vlan" +BOND_XML_TAG = "bond" +NETWORK_XML_TAG = "network" + +ETHTOOL_OTHERCONFIG_ATTRS = ['ethtool-%s' % x for x in 'autoneg', 'speed', 'duplex', 'rx', 'tx', 'sg', 'tso', 'ufo', 'gso' ] + +PIF_ATTRS = { 'uuid': (str_to_xml,str_from_xml), + 'management': (bool_to_xml,bool_from_xml), + 'network': (str_to_xml,str_from_xml), + 'device': (str_to_xml,str_from_xml), + 'bond_master_of': (lambda x, p, t, v: strlist_to_xml(x, p, 'bond_master_of', 'slave', v), + lambda n: strlist_from_xml(n, 'bond_master_of', 'slave')), + 'bond_slave_of': (str_to_xml,str_from_xml), + 'VLAN': (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')), + 'ip_configuration_mode': (str_to_xml,str_from_xml), + 'IP': (str_to_xml,str_from_xml), + 'netmask': (str_to_xml,str_from_xml), + 'gateway': (str_to_xml,str_from_xml), + 'DNS': (str_to_xml,str_from_xml), + 'MAC': (str_to_xml,str_from_xml), + 'other_config': (lambda x, p, t, v: otherconfig_to_xml(x, p, v, PIF_OTHERCONFIG_ATTRS), + lambda n: otherconfig_from_xml(n, PIF_OTHERCONFIG_ATTRS)), + + # Special case: We write the current value + # PIF.currently-attached to the cache but since it will + # not be valid when we come to use the cache later + # (i.e. after a reboot) we always read it as False. + 'currently_attached': (bool_to_xml, lambda n: False), + } + +PIF_OTHERCONFIG_ATTRS = [ 'domain', 'peerdns', 'defaultroute', 'mtu', 'static-routes' ] + \ + [ 'bond-%s' % x for x in 'mode', 'miimon', 'downdelay', 'updelay', 'use_carrier' ] + \ + ETHTOOL_OTHERCONFIG_ATTRS + +VLAN_ATTRS = { 'uuid': (str_to_xml,str_from_xml), + 'tagged_PIF': (str_to_xml,str_from_xml), + 'untagged_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_ATTRS = { 'uuid': (str_to_xml,str_from_xml), + 'bridge': (str_to_xml,str_from_xml), + 'PIFs': (lambda x, p, t, v: strlist_to_xml(x, p, 'PIFs', 'PIF', v), + lambda n: strlist_from_xml(n, 'PIFs', 'PIF')), + 'other_config': (lambda x, p, t, v: otherconfig_to_xml(x, p, v, NETWORK_OTHERCONFIG_ATTRS), + lambda n: otherconfig_from_xml(n, NETWORK_OTHERCONFIG_ATTRS)), + } + +NETWORK_OTHERCONFIG_ATTRS = [ 'mtu', 'static-routes' ] + ETHTOOL_OTHERCONFIG_ATTRS + class DatabaseCache(object): + def __read_xensource_inventory(self): + filename = "/etc/xensource-inventory" + f = open(filename, "r") + lines = [x.strip("\n") for x in f.readlines()] + f.close() + + defs = [ (l[:l.find("=")], l[(l.find("=") + 1):]) for l in lines ] + defs = [ (a, b.strip("'")) for (a,b) in defs ] + + return dict(defs) + def __pif_on_host(self,pif): + return self.__pifs.has_key(pif) + + def __get_pif_records_from_xapi(self, session, host): + self.__pifs = {} + for (p,rec) in session.xenapi.PIF.get_all_records().items(): + if rec['host'] != host: + continue + self.__pifs[p] = {} + for f in PIF_ATTRS: + self.__pifs[p][f] = rec[f] + self.__pifs[p]['other_config'] = {} + for f in PIF_OTHERCONFIG_ATTRS: + if not rec['other_config'].has_key(f): continue + self.__pifs[p]['other_config'][f] = rec['other_config'][f] + + 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) + 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_bond_records_from_xapi(self, session): + self.__bonds = {} + for b in session.xenapi.Bond.get_all(): + rec = session.xenapi.Bond.get_record(b) + if not self.__pif_on_host(rec['master']): + continue + self.__bonds[b] = {} + for f in BOND_ATTRS: + self.__bonds[b][f] = rec[f] + + 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) + self.__networks[n] = {} + for f in NETWORK_ATTRS: + if f == "PIFs": + # drop PIFs on other hosts + self.__networks[n][f] = [p for p in rec[f] if self.__pif_on_host(p)] + else: + self.__networks[n][f] = rec[f] + self.__networks[n]['other_config'] = {} + for f in NETWORK_OTHERCONFIG_ATTRS: + if not rec['other_config'].has_key(f): continue + self.__networks[n]['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) + parent.appendChild(e) + if ref: + e.setAttribute('ref', ref) + + for n,v in rec.items(): + if attrs.has_key(n): + h,_ = attrs[n] + h(xml, e, n, v) + else: + raise Error("Unknown attribute %s" % n) + def __from_xml(self, e, attrs): + """Decode a database object from XML""" + ref = e.attributes['ref'].value + rec = {} + for n in e.childNodes: + if n.nodeName in attrs: + _,h = attrs[n.nodeName] + rec[n.nodeName] = h(n) + return (ref,rec) + def __init__(self, session_ref=None, cache_file=None): if session_ref and cache_file: raise Error("can't specify session reference and cache file") - if cache_file == None: session = XenAPI.xapi_local() @@ -287,32 +487,70 @@ class DatabaseCache(object): session._session = session_ref try: - self.__vlans = session.xenapi.VLAN.get_all_records() - self.__bonds = session.xenapi.Bond.get_all_records() - self.__pifs = session.xenapi.PIF.get_all_records() - self.__networks = session.xenapi.network.get_all_records() + + inventory = self.__read_xensource_inventory() + assert(inventory.has_key('INSTALLATION_UUID')) + log("host uuid is %s" % inventory['INSTALLATION_UUID']) + + host = session.xenapi.host.get_by_uuid(inventory['INSTALLATION_UUID']) + + self.__get_pif_records_from_xapi(session, host) + + self.__get_vlan_records_from_xapi(session) + self.__get_bond_records_from_xapi(session) + self.__get_network_records_from_xapi(session) finally: if not session_ref: session.xenapi.session.logout() else: log("Loading xapi database cache from %s" % cache_file) - f = open(cache_file, 'r') - members = pickle.load(f) - self.extras = pickle.load(f) - f.close() - self.__vlans = members['vlans'] - self.__bonds = members['bonds'] - self.__pifs = members['pifs'] - self.__networks = members['networks'] + xml = parseXML(cache_file) - def save(self, cache_file, extras): + self.__pifs = {} + self.__bonds = {} + self.__vlans = {} + self.__networks = {} + + assert(len(xml.childNodes) == 1) + toplevel = xml.childNodes[0] + + assert(toplevel.nodeName == "xenserver-network-configuration") + + for n in toplevel.childNodes: + if n.nodeName == "#text": + pass + elif n.nodeName == PIF_XML_TAG: + (ref,rec) = self.__from_xml(n, PIF_ATTRS) + self.__pifs[ref] = rec + elif n.nodeName == BOND_XML_TAG: + (ref,rec) = self.__from_xml(n, BOND_ATTRS) + self.__bonds[ref] = rec + elif n.nodeName == VLAN_XML_TAG: + (ref,rec) = self.__from_xml(n, VLAN_ATTRS) + self.__vlans[ref] = rec + elif n.nodeName == NETWORK_XML_TAG: + (ref,rec) = self.__from_xml(n, NETWORK_ATTRS) + self.__networks[ref] = rec + else: + raise Error("Unknown XML element %s" % n.nodeName) + + def save(self, cache_file): + + xml = getDOMImplementation().createDocument( + None, "xenserver-network-configuration", None) + for (ref,rec) in self.__pifs.items(): + self.__to_xml(xml, xml.documentElement, PIF_XML_TAG, ref, rec, PIF_ATTRS) + for (ref,rec) in self.__bonds.items(): + 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.__networks.items(): + self.__to_xml(xml, xml.documentElement, NETWORK_XML_TAG, ref, rec, + NETWORK_ATTRS) + f = open(cache_file, 'w') - pickle.dump({'vlans': self.__vlans, - 'bonds': self.__bonds, - 'pifs': self.__pifs, - 'networks': self.__networks}, f) - pickle.dump(extras, f) + f.write(xml.toprettyxml()) f.close() def get_pif_by_uuid(self, uuid): @@ -326,33 +564,12 @@ class DatabaseCache(object): return pifs[0] - def get_pifs_by_record(self, record): - """record is partial pif record. - Get the pif(s) whose record matches. - """ - def match(pifrec): - for key in record: - if record[key] != pifrec[key]: - return False - return True - + def get_pifs_by_device(self, device): return map(lambda (ref,rec): ref, - filter(lambda (ref,rec): match(rec), + filter(lambda (ref,rec): rec['device'] == device, self.__pifs.items())) - def get_pif_by_record(self, record): - """record is partial pif record. - Get the pif whose record matches. - """ - pifs = self.get_pifs_by_record(record) - if len(pifs) == 0: - raise Error("No matching PIF \"%s\"" % str(record)) - elif len(pifs) > 1: - raise Error("Multiple matching PIFs \"%s\"" % str(record)) - - return pifs[0] - - def get_pif_by_bridge(self, host, bridge): + def get_pif_by_bridge(self, bridge): networks = map(lambda (ref,rec): ref, filter(lambda (ref,rec): rec['bridge'] == bridge, self.__networks.items())) @@ -364,32 +581,29 @@ class DatabaseCache(object): nwrec = self.get_network_record(network) for pif in nwrec['PIFs']: pifrec = self.get_pif_record(pif) - if pifrec['host'] != host: - continue if answer: - raise Error("Multiple PIFs on %s for network %s" % (host, bridge)) + raise Error("Multiple PIFs on host for network %s" % (bridge)) answer = pif if not answer: - raise Error("No PIF on %s for network %s" % (host, bridge)) + raise Error("No PIF on host for network %s" % (bridge)) return answer def get_pif_record(self, pif): if self.__pifs.has_key(pif): return self.__pifs[pif] - raise Error("Unknown PIF \"%s\"" % pif) + raise Error("Unknown PIF \"%s\" (get_pif_record)" % pif) def get_all_pifs(self): return self.__pifs def pif_exists(self, pif): return self.__pifs.has_key(pif) - def get_management_pif(self, host): + def get_management_pif(self): """ Returns the management pif on host """ all = self.get_all_pifs() for pif in all: pifrec = self.get_pif_record(pif) - if pifrec['management'] and pifrec['host'] == host : - return pif + if pifrec['management']: return pif return None def get_network_record(self, network): @@ -441,6 +655,7 @@ For a VLAN PIF, the datapath name is the bridge name for the PIF's VLAN slave. use it.) """ + pifrec = db.get_pif_record(pif) if pifrec['VLAN'] == '-1': @@ -463,7 +678,6 @@ For a VLAN PIF, this is the VLAN slave's physical device PIF. For a bond master PIF, these are the bond slave PIFs. For a non-VLAN, non-bond master PIF, the PIF is its own physical device PIF. """ - pifrec = db.get_pif_record(pif) if pifrec['VLAN'] != '-1': @@ -484,13 +698,13 @@ For a non-VLAN, non-bond master PIF, the physical device is the PIF itself. def log_pif_action(action, pif): pifrec = db.get_pif_record(pif) - pifrec['action'] = action - pifrec['interface-name'] = interface_name(pif) - if action == "rewrite": - pifrec['message'] = "Rewrite PIF %(uuid)s configuration" % pifrec - else: - pifrec['message'] = "Bring %(action)s PIF %(uuid)s" % pifrec - log("%(message)s: %(interface-name)s configured as %(ip_configuration_mode)s" % pifrec) + rec = {} + rec['uuid'] = pifrec['uuid'] + rec['ip_configuration_mode'] = pifrec['ip_configuration_mode'] + rec['action'] = action + rec['interface-name'] = interface_name(pif) + rec['message'] = "Bring %(action)s PIF %(uuid)s" % rec + log("%(message)s: %(interface-name)s configured as %(ip_configuration_mode)s" % rec) def get_bond_masters_of_pif(pif): """Returns a list of PIFs which are bond masters of this PIF""" @@ -516,7 +730,6 @@ def get_bond_slaves_of_pif(pif): """Returns a list of PIFs which make up the given bonded pif.""" pifrec = db.get_pif_record(pif) - host = pifrec['host'] bmo = pifrec['bond_master_of'] if len(bmo) > 1: @@ -657,10 +870,8 @@ This is because when we are called to bring up an interface with a bond master, we should bring down that master.""" pifrec = db.get_pif_record(pif) - host = pifrec['host'] - pifs_on_host = [ __pif for __pif in db.get_all_pifs() if - db.get_pif_record(__pif)['host'] == host and + pifs = [ __pif for __pif in db.get_all_pifs() if (not __pif in get_bond_masters_of_pif(pif)) ] peerdns_pif = None @@ -669,7 +880,7 @@ we should bring down that master.""" # loop through all the pifs on this host looking for one with # other-config:peerdns = true, and one with # other-config:default-route=true - for __pif in pifs_on_host: + for __pif in pifs: __pifrec = db.get_pif_record(__pif) __oc = __pifrec['other_config'] if __oc.has_key('peerdns') and __oc['peerdns'] == 'true': @@ -747,7 +958,6 @@ def configure_local_port(pif): datapath = datapath_name(pif) ipdev = ipdev_name(pif) - host = pifrec['host'] nw = pifrec['network'] nwrec = db.get_network_record(nw) @@ -820,7 +1030,7 @@ def configure_physdev(pif): run_ethtool(device, oc) def modify_config(commands): - run_command(['/root/vswitch/bin/ovs-cfg-mod', '-vANY:console:emer', + run_command(['/usr/bin/ovs-cfg-mod', '-vANY:console:emer', '-F', '/etc/ovs-vswitchd.conf'] + commands + ['-c']) run_command(['/sbin/service', 'vswitch', 'reload']) @@ -913,9 +1123,9 @@ def action_up(pif): # /etc/xensource/scripts/vif needs to know where to add VIFs. if vlan_slave: - if not os.path.exists(vswitch_config_dir): - os.mkdir(vswitch_config_dir) - br = ConfigurationFile("br-%s" % bridge, vswitch_config_dir) + if not os.path.exists(vswitch_state_dir): + os.mkdir(vswitch_state_dir) + br = ConfigurationFile("br-%s" % bridge, vswitch_state_dir) br.write("VLAN_SLAVE=%s\n" % datapath) br.write("VLAN_VID=%s\n" % pifrec['VLAN']) br.close() @@ -980,8 +1190,7 @@ def action_up(pif): # - The networks corresponding to any VLANs attached to the # datapath's PIF. network_uuids = [] - for nwpif in db.get_pifs_by_record({'device': pifrec['device'], - 'host': pifrec['host']}): + for nwpif in db.get_pifs_by_device(pifrec['device']): net = db.get_pif_record(nwpif)['network'] network_uuids += [db.get_network_record(net)['uuid']] @@ -1016,7 +1225,7 @@ def action_up(pif): argv += ['--add=iface.%s.fake-bridge=true' % (ipdev)] else: try: - os.unlink("%s/br-%s" % (vswitch_config_dir, bridge)) + os.unlink("%s/br-%s" % (vswitch_state_dir, bridge)) except OSError: pass argv += ['--del-match=bridge.%s.xs-network-uuids=*' % datapath] @@ -1028,6 +1237,8 @@ def action_up(pif): # Bring up VLAN slave, plus physical devices other than bond # slaves (which we brought up earlier). + # XXX need to bring up bond itself. + # XXX need to set MAC address on fake bridge if vlan_slave: up_netdev(ipdev_name(vlan_slave)) for physdev_pif in set(physdev_pifs) - set(bond_slave_physdev_pifs): @@ -1104,6 +1315,7 @@ def action_down(pif): log("VLAN masters of %s - %s" % (rec['device'], [interface_name(m) for m in vlan_masters])) for m in vlan_masters: if db.get_pif_record(m)['currently_attached']: + # XXX remove IP address log("Leaving %s up due to currently attached VLAN master %s" % (interface, interface_name(m))) return @@ -1159,6 +1371,9 @@ def action_rewrite(pif): # We have no code of our own to run here. pass +def action_force_rewrite(interface, config): + raise Error("Force rewrite is not implemented yet.") + def main(argv=None): global output_directory, management_pif @@ -1181,7 +1396,6 @@ def main(argv=None): "force=", "force-interface=", "management", - "test-mode", "device=", "mode=", "ip=", "netmask=", "gateway=", "help" ] arglist, args = getopt.gnu_getopt(argv[1:], shortops, longops) @@ -1218,6 +1432,10 @@ def main(argv=None): raise Usage("Too many arguments") action = args[0] + + if not action in ["up", "down", "rewrite", "rewrite-configuration"]: + raise Usage("Unknown action \"%s\"" % action) + # backwards compatibility if action == "rewrite-configuration": action = "rewrite" @@ -1229,6 +1447,8 @@ def main(argv=None): raise Usage("--session and --pif must be used together.") if force_interface and ( session or pif or pif_uuid ): raise Usage("--force is mutually exclusive with --session, --pif and --pif-uuid") + if force_interface == "all" and action != "down": + raise Usage("\"--force all\" only valid for down action") if len(force_rewrite_config) and not (force_interface and action == "rewrite"): raise Usage("\"--force rewrite\" needed for --device, --mode, --ip, --netmask, and --gateway") @@ -1238,54 +1458,57 @@ def main(argv=None): if action == "rewrite": action_force_rewrite(force_interface, force_rewrite_config) - else: + elif action in ["up", "down"]: + if action == "down" and force_interface == "all": + raise Error("Force all interfaces down not implemented yet") + db = DatabaseCache(cache_file=dbcache_file) - host = db.extras['host'] - pif = db.get_pif_by_bridge(host, force_interface) - management_pif = db.get_management_pif(host) + pif = db.get_pif_by_bridge(force_interface) + management_pif = db.get_management_pif() if action == "up": action_up(pif) elif action == "down": action_down(pif) - else: - raise Usage("Unknown action %s" % action) + else: + raise Error("Unknown action %s" % action) else: db = DatabaseCache(session_ref=session) if pif_uuid: pif = db.get_pif_by_uuid(pif_uuid) - - if not pif: - raise Usage("No PIF given") - if force_management: - # pif is going to be the management pif - management_pif = pif + if action == "rewrite" and not pif: + pass else: - # pif is not going to be the management pif. - # Search DB cache for pif on same host with management=true - pifrec = db.get_pif_record(pif) - host = pifrec['host'] - management_pif = db.get_management_pif(host) + if not pif: + raise Usage("No PIF given") - log_pif_action(action, pif) + if force_management: + # pif is going to be the management pif + management_pif = pif + else: + # pif is not going to be the management pif. + # Search DB cache for pif on same host with management=true + pifrec = db.get_pif_record(pif) + management_pif = db.get_management_pif() - if not check_allowed(pif): - return 0 + log_pif_action(action, pif) - if action == "up": - action_up(pif) - elif action == "down": - action_down(pif) - elif action == "rewrite": - action_rewrite(pif) - else: - raise Usage("Unknown action %s" % action) + if not check_allowed(pif): + return 0 + + if action == "up": + action_up(pif) + elif action == "down": + action_down(pif) + elif action == "rewrite": + action_rewrite(pif) + else: + raise Error("Unknown action %s" % action) # Save cache. - pifrec = db.get_pif_record(pif) - db.save(dbcache_file, {'host': pifrec['host']}) + db.save(dbcache_file) except Usage, err: print >>sys.stderr, err.msg @@ -1451,7 +1674,6 @@ def configure_network(pif, f): """ pifrec = db.get_pif_record(pif) - host = pifrec['host'] nw = pifrec['network'] nwrec = db.get_network_record(nw) oc = None @@ -1506,8 +1728,7 @@ def configure_network(pif, f): # This is because when we are called to bring up an interface with a bond master, it is implicit that # we should bring down that master. pifs_on_host = [ __pif for __pif in db.get_all_pifs() if - db.get_pif_record(__pif)['host'] == host and - (not __pif in get_bond_masters_of_pif(pif)) ] + not __pif in get_bond_masters_of_pif(pif) ] other_pifs_on_host = [ __pif for __pif in pifs_on_host if __pif != pif ] peerdns_pif = None