]>
git.proxmox.com Git - ovs.git/blob - xenserver/usr_lib_xsconsole_plugins-base_XSFeatureVSwitch.py
1 # Copyright (c) 2009,2010,2011,2012,2013 Nicira, Inc.
2 # Copyright (c) 2007-2011 Citrix Systems Inc.
4 # This program is free software; you can redistribute it and/or modify
5 # it under the terms of the GNU General Public License as published by
6 # the Free Software Foundation; version 2 only.
8 # This program is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # GNU General Public License for more details.
13 # You should have received a copy of the GNU General Public License along
14 # with this program; if not, write to the Free Software Foundation, Inc.,
15 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 from XSConsoleLog
import *
23 vsctl
="/usr/bin/ovs-vsctl"
25 if __name__
== "__main__":
26 raise Exception("This script is a plugin for xsconsole and cannot run independently")
28 from XSConsoleStandard
import *
33 def __init__(self
, name
, processname
=None):
35 self
.processname
= processname
36 if self
.processname
== None:
37 self
.processname
= name
41 output
= ShellPipe(["service", self
.name
, "version"]).Stdout()
42 except StandardError as e
:
43 XSLogError("vswitch version retrieval error: " + str(e
))
46 if self
.processname
in line
:
47 return line
.split()[-1]
52 output
= ShellPipe(["service", self
.name
, "status"]).Stdout()
53 except StandardError as e
:
54 XSLogError("vswitch status retrieval error: " + str(e
))
59 if self
.processname
not in line
:
61 elif "running" in line
:
71 ShellPipe(["service", self
.name
, "restart"]).Call()
72 except StandardError as e
:
73 XSLogError("vswitch restart error: " + str(e
))
76 def Inst(cls
, name
, processname
=None):
78 if processname
!= None:
79 key
= key
+ "-" + processname
80 if name
not in cls
.service
:
81 cls
.service
[key
] = VSwitchService(name
, processname
)
82 return cls
.service
[key
]
89 arg
= [vsctl
, "-vconsole:off"] + action
.split()
90 output
= ShellPipe(arg
).Stdout()
91 except StandardError as e
:
92 XSLogError("config retrieval error: " + str(e
))
98 output
= output
[0].strip()
102 class VSwitchControllerDialogue(Dialogue
):
104 Dialogue
.__init
__(self
)
108 self
.hostsUpdated
= 0
109 self
.xs_version
= data
.host
.software_version
.product_version('')
110 pool
= data
.GetPoolForThisHost()
112 self
.controller
= pool
.get("vswitch_controller", "")
117 ChoiceDef(Lang("Set pool-wide controller"),
118 lambda: self
.getController()),
119 ChoiceDef(Lang("Delete pool-wide controller"),
120 lambda: self
.deleteController()),
121 ChoiceDef(Lang("Resync server controller config"),
122 lambda: self
.syncController()),
123 # ChoiceDef(Lang("Restart ovs-vswitchd"),
124 # lambda: self.restartService("vswitch")),
126 self
.menu
= Menu(self
, None, Lang("Configure Open vSwitch"), choiceDefs
)
128 self
.ChangeState("INITIAL")
131 pane
= self
.NewPane(DialoguePane(self
.parent
))
132 pane
.TitleSet(Lang("Configure Open vSwitch"))
135 def ChangeState(self
, inState
):
140 def UpdateFields(self
):
141 self
.Pane().ResetPosition()
142 getattr(self
, "UpdateFields" + self
.state
)() # Dispatch method named 'UpdateFields'+self.state
144 def UpdateFieldsINITIAL(self
):
146 pane
.AddTitleField(Lang("Select an action"))
147 pane
.AddMenuField(self
.menu
)
148 pane
.AddKeyHelpField( { Lang("<Enter>") : Lang("OK"), Lang("<Esc>") : Lang("Cancel") } )
150 def UpdateFieldsGETCONTROLLER(self
):
154 pane
.AddTitleField(Lang("Enter IP address of controller"))
155 pane
.AddInputField(Lang("Address", 16), self
.controller
, "address")
156 pane
.AddKeyHelpField( { Lang("<Enter>") : Lang("OK"), Lang("<Esc>") : Lang("Exit") } )
157 if pane
.CurrentInput() is None:
158 pane
.InputIndexSet(0)
160 def HandleKey(self
, inKey
):
162 if hasattr(self
, "HandleKey" + self
.state
):
163 handled
= getattr(self
, "HandleKey" + self
.state
)(inKey
)
164 if not handled
and inKey
== 'KEY_ESCAPE':
165 Layout
.Inst().PopDialogue()
169 def HandleKeyINITIAL(self
, inKey
):
170 return self
.menu
.HandleKey(inKey
)
172 def HandleKeyGETCONTROLLER(self
, inKey
):
174 if pane
.CurrentInput() is None:
175 pane
.InputIndexSet(0)
176 if inKey
== 'KEY_ENTER':
177 inputValues
= pane
.GetFieldValues()
178 self
.controller
= inputValues
['address']
179 Layout
.Inst().PopDialogue()
181 # Make sure the controller is specified as a valid dotted quad
183 socket
.inet_aton(self
.controller
)
185 Layout
.Inst().PushDialogue(InfoDialogue(Lang("Please enter in dotted quad format")))
188 Layout
.Inst().TransientBanner(Lang("Setting controller..."))
190 self
.SetController(self
.controller
)
191 Layout
.Inst().PushDialogue(InfoDialogue(Lang("Setting controller successful")))
192 except Exception as e
:
193 Layout
.Inst().PushDialogue(InfoDialogue(Lang("Setting controller failed")))
195 self
.ChangeState("INITIAL")
198 return pane
.CurrentInput().HandleKey(inKey
)
200 def restartService(self
, name
):
201 s
= VSwitchService
.Inst(name
)
203 Layout
.Inst().PopDialogue()
205 def getController(self
):
206 self
.ChangeState("GETCONTROLLER")
207 self
.Pane().InputIndexSet(0)
209 def deleteController(self
):
211 Layout
.Inst().PopDialogue()
212 Layout
.Inst().TransientBanner(Lang("Deleting controller..."))
214 self
.SetController(None)
215 Layout
.Inst().PushDialogue(InfoDialogue(Lang("Controller deletion successful")))
216 except Exception as e
:
217 Layout
.Inst().PushDialogue(InfoDialogue(Lang("Controller deletion failed")))
219 def syncController(self
):
220 Layout
.Inst().PopDialogue()
221 Layout
.Inst().TransientBanner(Lang("Resyncing controller setting..."))
223 Task
.Sync(lambda s
: self
._updateThisServer
(s
))
224 Layout
.Inst().PushDialogue(InfoDialogue(Lang("Resyncing controller config successful")))
225 except Exception as e
:
226 Layout
.Inst().PushDialogue(InfoDialogue(Lang("Resyncing controller config failed")))
228 def SetController(self
, ip
):
230 self
.hostsUpdated
= 0
231 Task
.Sync(lambda s
: self
._modifyPoolConfig
(s
, ip
or ""))
232 # Should be done asynchronously, maybe with an external script?
233 Task
.Sync(lambda s
: self
._updateActiveServers
(s
))
235 def _modifyPoolConfig(self
, session
, value
):
236 """Modify pool configuration.
238 If value == "" then delete configuration, otherwise set to value.
240 pools
= session
.xenapi
.pool
.get_all()
241 # We assume there is only ever one pool...
243 XSLogFatal(Lang("No pool found for host."))
246 XSLogFatal(Lang("More than one pool for host."))
248 session
.xenapi
.pool
.set_vswitch_controller(value
)
251 def _updateActiveServers(self
, session
):
252 hosts
= session
.xenapi
.host
.get_all()
253 self
.hostsUpdated
= 0
254 self
.hostsInPool
= len(hosts
)
257 Layout
.Inst().TransientBanner("Updating host %d out of %d"
258 % (self
.hostsUpdated
+ 1, self
.hostsInPool
))
259 session
.xenapi
.host
.call_plugin(host
, "openvswitch-cfg-update", "update", {})
260 self
.hostsUpdated
= self
.hostsUpdated
+ 1
262 def _updateThisServer(self
, session
):
264 host
= data
.host
.opaqueref()
265 session
.xenapi
.host
.call_plugin(host
, "openvswitch-cfg-update", "update", {})
268 class XSFeatureVSwitch
:
271 def StatusUpdateHandler(cls
, inPane
):
273 xs_version
= data
.host
.software_version
.product_version('')
275 inPane
.AddTitleField(Lang("Open vSwitch"))
279 inPane
.AddStatusField(Lang("Version", 20),
280 VSwitchService
.Inst("openvswitch", "ovs-vswitchd").version())
284 pool
= data
.GetPoolForThisHost()
286 dbController
= pool
.get("vswitch_controller", "")
290 if dbController
== "":
291 dbController
= Lang("<None>")
292 inPane
.AddStatusField(Lang("Controller (config)", 20), dbController
)
293 controller
= VSwitchConfig
.Get("get-manager")
296 controller
= Lang("<None>")
297 elif controller
[0:4] == "ssl:":
298 controller
= controller
.split(':')[1]
299 inPane
.AddStatusField(Lang("Controller (in-use)", 20), controller
)
302 inPane
.AddStatusField(Lang("ovs-vswitchd status", 20),
303 VSwitchService
.Inst("openvswitch", "ovs-vswitchd").status())
304 inPane
.AddStatusField(Lang("ovsdb-server status", 20),
305 VSwitchService
.Inst("openvswitch", "ovsdb-server").status())
307 inPane
.AddKeyHelpField( {
308 Lang("<Enter>") : Lang("Reconfigure"),
309 Lang("<F5>") : Lang("Refresh")
313 def ActivateHandler(cls
):
314 DialogueUtils
.AuthenticatedOnly(lambda: Layout
.Inst().PushDialogue(VSwitchControllerDialogue()))
317 Importer
.RegisterNamedPlugIn(
319 'VSwitch', # Key of this plugin for replacement, etc.
321 'menuname' : 'MENU_NETWORK',
322 'menupriority' : 800,
323 'menutext' : Lang('Open vSwitch') ,
324 'statusupdatehandler' : self
.StatusUpdateHandler
,
325 'activatehandler' : self
.ActivateHandler
329 # Register this plugin when module is imported, IFF vswitchd is running
330 if os
.path
.exists('/var/run/openvswitch/ovs-vswitchd.pid'):
331 XSFeatureVSwitch().Register()