-# Copyright (c) Citrix Systems 2008. All rights reserved.
-# xsconsole is proprietary software.
+# Copyright (c) 2007-2011 Citrix Systems Inc.
+# Copyright (c) 2009,2010,2011,2012 Nicira, 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")
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 "<unknown>"
+ for line in output:
+ if self.processname in line:
+ return line.split()[-1]
+ return "<unknown>"
+
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 "<unknown>"
if len(output) == 0:
return "<unknown>"
- 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 "<unknown>"
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):
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, "--timeout=30", "-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 "<unknown>"
if len(output) == 0:
self.hostsInPool = 0
self.hostsUpdated = 0
+ self.xs_version = data.host.software_version.product_version('')
pool = data.GetPoolForThisHost()
if pool is not None:
- self.controller = pool.get("other_config", {}).get("vSwitchController", "")
+ self.controller = pool.get("vswitch_controller", "")
else:
self.controller = ""
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):
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)
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):
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:
@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", "<Unknown>")
- inPane.AddStatusField(Lang("Version", 20), versionStr)
+ inPane.AddStatusField(Lang("Version", 20),
+ VSwitchService.Inst("openvswitch", "ovs-vswitchd").version())
inPane.NewLine()
pool = data.GetPoolForThisHost()
if pool is not None:
- dbController = pool.get("other_config", {}).get("vSwitchController", "")
+ dbController = pool.get("vswitch_controller", "")
else:
dbController = ""
if dbController == "":
dbController = Lang("<None>")
inPane.AddStatusField(Lang("Controller (config)", 20), dbController)
- controller = VSwitchConfig.Get("mgmt.controller")
+ controller = VSwitchConfig.Get("get-manager")
+
if controller == "":
controller = Lang("<None>")
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("<Enter>") : Lang("Reconfigure"),
{
'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()