X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=xenserver%2Fusr_lib_xsconsole_plugins-base_XSFeatureVSwitch.py;h=fdbbc0ed4c8923a6ba987f18985476e3c9b334f1;hb=HEAD;hp=8f4be3139b2a1d2b258f477b8f6b27152baf1db5;hpb=064af42167bf4fc9aaea2702d80ce08074b889c0;p=sliver-openvswitch.git diff --git a/xenserver/usr_lib_xsconsole_plugins-base_XSFeatureVSwitch.py b/xenserver/usr_lib_xsconsole_plugins-base_XSFeatureVSwitch.py index 8f4be3139..fdbbc0ed4 100644 --- a/xenserver/usr_lib_xsconsole_plugins-base_XSFeatureVSwitch.py +++ b/xenserver/usr_lib_xsconsole_plugins-base_XSFeatureVSwitch.py @@ -1,21 +1,26 @@ -# Copyright (c) Citrix Systems 2008. All rights reserved. -# xsconsole is proprietary software. +# Copyright (c) 2009,2010,2011,2012,2013 Nicira, Inc. +# Copyright (c) 2007-2011 Citrix Systems Inc. # -# Xen, the Xen logo, XenCenter, XenMotion are trademarks or registered -# trademarks of Citrix Systems, Inc., in the United States and other -# countries. - -# Copyright (c) 2009 Nicira Networks. +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; version 2 only. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -import logging -log = logging.getLogger("vswitch-cfg-update") -logging.basicConfig(filename="/var/log/vswitch-xsplugin.log", level=logging.DEBUG) +from XSConsoleLog import * import os +import socket import subprocess -cfg_mod="/root/vswitch/bin/ovs-cfg-mod" -vswitchd_cfg_filename="/etc/ovs-vswitchd.conf" +vsctl="/usr/bin/ovs-vsctl" if __name__ == "__main__": raise Exception("This script is a plugin for xsconsole and cannot run independently") @@ -31,20 +36,31 @@ class VSwitchService: if self.processname == None: self.processname = name + def version(self): + try: + output = ShellPipe(["service", self.name, "version"]).Stdout() + except StandardError, e: + XSLogError("vswitch version retrieval error: " + str(e)) + return "" + for line in output: + if self.processname in line: + return line.split()[-1] + return "" + def status(self): try: output = ShellPipe(["service", self.name, "status"]).Stdout() except StandardError, e: - log.error("status retrieval error: " + str(e)) + XSLogError("vswitch status retrieval error: " + str(e)) return "" if len(output) == 0: return "" - for l in output: - if self.processname not in l: + for line in output: + if self.processname not in line: continue - elif "running" in l: + elif "running" in line: return "Running" - elif "stop" in l: + elif "stop" in line: return "Stopped" else: return "" @@ -54,7 +70,7 @@ class VSwitchService: try: ShellPipe(["service", self.name, "restart"]).Call() except StandardError, e: - log.error("restart error: " + str(e)) + XSLogError("vswitch restart error: " + str(e)) @classmethod def Inst(cls, name, processname=None): @@ -68,12 +84,12 @@ class VSwitchService: class VSwitchConfig: @staticmethod - def Get(key): + def Get(action): try: - output = ShellPipe([cfg_mod, "-vANY:console:emer", "-F", - vswitchd_cfg_filename, "-q", key]).Stdout() + arg = [vsctl, "-vconsole:off"] + action.split() + output = ShellPipe(arg).Stdout() except StandardError, e: - log.error("config retrieval error: " + str(e)) + XSLogError("config retrieval error: " + str(e)) return "" if len(output) == 0: @@ -90,7 +106,12 @@ class VSwitchControllerDialogue(Dialogue): self.hostsInPool = 0 self.hostsUpdated = 0 - self.controller = data.GetPoolForThisHost().get("other_config", {}).get("vSwitchController", "") + self.xs_version = data.host.software_version.product_version('') + pool = data.GetPoolForThisHost() + if pool is not None: + self.controller = pool.get("vswitch_controller", "") + else: + self.controller = "" choiceDefs = [ ChoiceDef(Lang("Set pool-wide controller"), @@ -101,16 +122,14 @@ class VSwitchControllerDialogue(Dialogue): lambda: self.syncController()), # ChoiceDef(Lang("Restart ovs-vswitchd"), # lambda: self.restartService("vswitch")), -# ChoiceDef(Lang("Restart ovs-brcompatd"), -# lambda: self.restartService("vswitch-brcompatd")) ] - self.menu = Menu(self, None, Lang("Configure vSwitch"), choiceDefs) + self.menu = Menu(self, None, Lang("Configure Open vSwitch"), choiceDefs) self.ChangeState("INITIAL") def BuildPane(self): pane = self.NewPane(DialoguePane(self.parent)) - pane.TitleSet(Lang("Configure vSwitch")) + pane.TitleSet(Lang("Configure Open vSwitch")) pane.AddBox() def ChangeState(self, inState): @@ -158,6 +177,14 @@ class VSwitchControllerDialogue(Dialogue): inputValues = pane.GetFieldValues() self.controller = inputValues['address'] Layout.Inst().PopDialogue() + + # Make sure the controller is specified as a valid dotted quad + try: + socket.inet_aton(self.controller) + except socket.error: + Layout.Inst().PushDialogue(InfoDialogue(Lang("Please enter in dotted quad format"))) + return True + Layout.Inst().TransientBanner(Lang("Setting controller...")) try: self.SetController(self.controller) @@ -201,25 +228,24 @@ class VSwitchControllerDialogue(Dialogue): def SetController(self, ip): self.hostsInPool = 0 self.hostsUpdated = 0 - Task.Sync(lambda s: self._modifyPoolConfig(s, "vSwitchController", ip)) + Task.Sync(lambda s: self._modifyPoolConfig(s, ip or "")) # Should be done asynchronously, maybe with an external script? Task.Sync(lambda s: self._updateActiveServers(s)) - def _modifyPoolConfig(self, session, key, value): + def _modifyPoolConfig(self, session, value): """Modify pool configuration. - If value == None then delete key, otherwise set key to value.""" + If value == "" then delete configuration, otherwise set to value. + """ pools = session.xenapi.pool.get_all() # We assume there is only ever one pool... if len(pools) == 0: - log.error("No pool for host.") - raise XenAPIPlugin.Failure("NO_POOL_FOR_HOST", []) + XSLogFatal(Lang("No pool found for host.")) + return if len(pools) > 1: - log.error("More than one pool for host.") - raise XenAPIPlugin.Failure("MORE_THAN_ONE_POOL_FOR_HOST", []) - session.xenapi.pool.remove_from_other_config(pools[0], key) - if value != None: - session.xenapi.pool.add_to_other_config(pools[0], key, value) + XSLogFatal(Lang("More than one pool for host.")) + return + session.xenapi.pool.set_vswitch_controller(value) Data.Inst().Update() def _updateActiveServers(self, session): @@ -230,13 +256,13 @@ class VSwitchControllerDialogue(Dialogue): for host in hosts: Layout.Inst().TransientBanner("Updating host %d out of %d" % (self.hostsUpdated + 1, self.hostsInPool)) - session.xenapi.host.call_plugin(host, "vswitch-cfg-update", "update", {}) + session.xenapi.host.call_plugin(host, "openvswitch-cfg-update", "update", {}) self.hostsUpdated = self.hostsUpdated + 1 def _updateThisServer(self, session): data = Data.Inst() host = data.host.opaqueref() - session.xenapi.host.call_plugin(host, "vswitch-cfg-update", "update", {}) + session.xenapi.host.call_plugin(host, "openvswitch-cfg-update", "update", {}) class XSFeatureVSwitch: @@ -244,31 +270,39 @@ class XSFeatureVSwitch: @classmethod def StatusUpdateHandler(cls, inPane): data = Data.Inst() + xs_version = data.host.software_version.product_version('') - inPane.AddTitleField(Lang("vSwitch")) + inPane.AddTitleField(Lang("Open vSwitch")) inPane.NewLine() - versionStr = data.host.other_config({}).get("vSwitchVersion", "") - inPane.AddStatusField(Lang("Version", 20), versionStr) + inPane.AddStatusField(Lang("Version", 20), + VSwitchService.Inst("openvswitch", "ovs-vswitchd").version()) inPane.NewLine() - dbController = data.GetPoolForThisHost().get("other_config", {}).get("vSwitchController", "") + + pool = data.GetPoolForThisHost() + if pool is not None: + dbController = pool.get("vswitch_controller", "") + else: + dbController = "" + if dbController == "": dbController = Lang("") inPane.AddStatusField(Lang("Controller (config)", 20), dbController) - controller = VSwitchConfig.Get("mgmt.controller") + controller = VSwitchConfig.Get("get-manager") + if controller == "": controller = Lang("") elif controller[0:4] == "ssl:": - controller = controller[4:] + controller = controller.split(':')[1] inPane.AddStatusField(Lang("Controller (in-use)", 20), controller) inPane.NewLine() inPane.AddStatusField(Lang("ovs-vswitchd status", 20), - VSwitchService.Inst("vswitch", "ovs-vswitchd").status()) - inPane.AddStatusField(Lang("ovs-brcompatd status", 20), - VSwitchService.Inst("vswitch", "ovs-brcompatd").status()) + VSwitchService.Inst("openvswitch", "ovs-vswitchd").status()) + inPane.AddStatusField(Lang("ovsdb-server status", 20), + VSwitchService.Inst("openvswitch", "ovsdb-server").status()) inPane.AddKeyHelpField( { Lang("") : Lang("Reconfigure"), @@ -286,11 +320,12 @@ class XSFeatureVSwitch: { 'menuname' : 'MENU_NETWORK', 'menupriority' : 800, - 'menutext' : Lang('vSwitch') , + 'menutext' : Lang('Open vSwitch') , 'statusupdatehandler' : self.StatusUpdateHandler, 'activatehandler' : self.ActivateHandler } ) -# Register this plugin when module is imported -XSFeatureVSwitch().Register() +# Register this plugin when module is imported, IFF vswitchd is running +if os.path.exists('/var/run/openvswitch/ovs-vswitchd.pid'): + XSFeatureVSwitch().Register()