xen: xsconsole plugin cleanup based on Citrix feedback
authorJustin Pettit <jpettit@nicira.com>
Mon, 18 May 2009 15:45:56 +0000 (08:45 -0700)
committerJustin Pettit <jpettit@nicira.com>
Mon, 18 May 2009 15:45:56 +0000 (08:45 -0700)
Various cleanups to the vSwitch plugin for xsconsole based on feedback
from Citrix.  The changes include a cleaner way to pop-up temporary
messages, leaving a success or failure box after performing an action,
and safer subprocess calling.

xenserver/usr_lib_xsconsole_plugins-base_XSFeatureNiciraVSwitch.py [changed mode: 0644->0755]

old mode 100644 (file)
new mode 100755 (executable)
index 24ff6e4..9db5907
@@ -31,21 +31,15 @@ class NiciraService:
         if self.processname == None:
             self.processname = name
 
-    def _execCmd(self, cmd):
-        pipe = subprocess.PIPE
-        return subprocess.Popen(cmd, stdin=pipe, stdout=pipe, stderr=pipe)
-
     def status(self):
-        cmd = [ "service", self.name, "status" ]
         try:
-            p = self._execCmd(cmd)
-            output = p.communicate()[0]
+            output = ShellPipe(["service", self.name, "status"]).Stdout()
         except StandardError, e:
-            log.error("Subprocess error: " + str(e))
+            log.error("status retrieval error: " + str(e))
             return "<unknown>"
-        if output == None:
+        if len(output) == 0:
             return "<unknown>"
-        for l in output.split("\n"):
+        for l in output:
             if self.processname not in l:
                 continue
             elif "running" in l:
@@ -57,12 +51,10 @@ class NiciraService:
         return "<unknown>"
 
     def restart(self):
-        cmd = [ "service", self.name, "restart" ]
         try:
-            p = self._execCmd(cmd)
-            p.communicate()
+            ShellPipe(["service", self.name, "restart"]).Call()
         except StandardError, e:
-            log.error("Subprocess error: ", str(e))
+            log.error("restart error: " + str(e))
 
     @classmethod
     def Inst(cls, name, processname=None):
@@ -77,10 +69,14 @@ class VSwitchConfig:
 
     @staticmethod
     def Get(key):
-        cmd = [cfg_mod, "-vANY:console:emer", "-F", vswitchd_cfg_filename,
-               "-q", key]
-        output = subprocess.Popen(cmd, stdout=subprocess.PIPE).communicate()
-        if len(output) == 0 or output[0] == None:
+        try:
+            output = ShellPipe([cfg_mod, "-vANY:console:emer", "-F", 
+                    vswitchd_cfg_filename, "-q", key]).Stdout()
+        except StandardError, e:
+            log.error("config retrieval error: " + str(e))
+            return "<unknown>"
+
+        if len(output) == 0:
             output = ""
         else:
             output = output[0].strip()
@@ -94,12 +90,7 @@ class NiciraControllerDialogue(Dialogue):
 
         self.hostsInPool = 0
         self.hostsUpdated = 0
-
-        pool = data.pools().values()[0]
-        try:
-            self.controller = pool["other_config"]["niciraController"]
-        except KeyError, e:
-            self.controller = ""
+        self.controller = data.GetPoolForThisHost().get("other_config", {}).get("niciraController", "")
 
         choiceDefs = [
             ChoiceDef(Lang("Set pool-wide controller"),
@@ -113,13 +104,13 @@ class NiciraControllerDialogue(Dialogue):
 #             ChoiceDef(Lang("Restart brcompatd"),
 #                       lambda: self.restartService("vswitch-brcompatd"))
             ]
-        self.menu = Menu(self, None, Lang("Configure Nicira VSwitch"), choiceDefs)
+        self.menu = Menu(self, None, Lang("Configure Nicira vSwitch"), choiceDefs)
 
         self.ChangeState("INITIAL")
 
     def BuildPane(self):
         pane = self.NewPane(DialoguePane(self.parent))
-        pane.TitleSet(Lang("Configure Nicira VSwitch"))
+        pane.TitleSet(Lang("Configure Nicira vSwitch"))
         pane.AddBox()
 
     def ChangeState(self, inState):
@@ -147,13 +138,6 @@ class NiciraControllerDialogue(Dialogue):
         if pane.CurrentInput() is None:
             pane.InputIndexSet(0)
 
-    def UpdateFieldsCALLPLUGIN(self):
-        pane = self.Pane()
-        pane.ResetFields()
-        pane.AddTitleField(Lang("Updating members of pool"))
-        progress = "%d / %d" % (self.hostsUpdated, self.hostsInPool)
-        pane.AddWrappedTextField(Lang("Progress", 16) + progress)
-
     def HandleKey(self, inKey):
         handled = False
         if hasattr(self, "HandleKey" + self.state):
@@ -173,8 +157,14 @@ class NiciraControllerDialogue(Dialogue):
         if inKey == 'KEY_ENTER':
             inputValues = pane.GetFieldValues()
             self.controller = inputValues['address']
-            self.SetController(self.controller)
             Layout.Inst().PopDialogue()
+            Layout.Inst().TransientBanner(Lang("Setting controller..."))
+            try:
+                self.SetController(self.controller)
+                Layout.Inst().PushDialogue(InfoDialogue(Lang("Setting controller successful")))
+            except Exception, e:
+                Layout.Inst().PushDialogue(InfoDialogue(Lang("Setting controller failed")))
+
             self.ChangeState("INITIAL")
             return True
         else:
@@ -191,17 +181,26 @@ class NiciraControllerDialogue(Dialogue):
 
     def deleteController(self):
         self.controller = ""
-        self.SetController(None)
         Layout.Inst().PopDialogue()
+        Layout.Inst().TransientBanner(Lang("Deleting controller..."))
+        try:
+            self.SetController(None)
+            Layout.Inst().PushDialogue(InfoDialogue(Lang("Controller deletion successful")))
+        except Exception, e:
+            Layout.Inst().PushDialogue(InfoDialogue(Lang("Controller deletion failed")))
 
     def syncController(self):
-        Task.Sync(lambda s: self._updateThisServer(s))
         Layout.Inst().PopDialogue()
+        Layout.Inst().TransientBanner(Lang("Resyncing controller setting..."))
+        try:
+            Task.Sync(lambda s: self._updateThisServer(s))
+            Layout.Inst().PushDialogue(InfoDialogue(Lang("Resyncing controller config successful")))
+        except Exception, e:
+            Layout.Inst().PushDialogue(InfoDialogue(Lang("Resyncing controller config failed")))
 
     def SetController(self, ip):
         self.hostsInPool = 0
         self.hostsUpdated = 0
-        self.ChangeState("CALLPLUGIN")
         Task.Sync(lambda s: self._modifyPoolConfig(s, "niciraController", ip))
         # Should be done asynchronously, maybe with an external script?
         Task.Sync(lambda s: self._updateActiveServers(s))
@@ -229,9 +228,9 @@ class NiciraControllerDialogue(Dialogue):
         self.hostsInPool = len(hosts)
         self.UpdateFields()
         for host in hosts:
-            session.xenapi.host.call_plugin(host, "vswitch-cfg-update", "update", {})
+            Layout.Inst().TransientBanner("Updating host %d out of %d" 
+                    % (self.hostsUpdated + 1, self.hostsInPool))
             self.hostsUpdated = self.hostsUpdated + 1
-            self.UpdateFields()
 
     def _updateThisServer(self, session):
         data = Data.Inst()
@@ -245,23 +244,15 @@ class XSFeatureNiciraVSwitch:
     def StatusUpdateHandler(cls, inPane):
         data = Data.Inst()
 
-        inPane.AddTitleField(Lang("Nicira VSwitch"))
+        inPane.AddTitleField(Lang("Nicira vSwitch"))
 
         inPane.NewLine()
 
-        host = data.host()
-        try:
-            versionStr = host["other_config"]["niciraSwitchVersion"]
-        except KeyError, e:
-            versionStr = "<Unknown>"
+        versionStr = data.host.other_config({}).get("niciraSwitchVersion", "<Unknown>")
         inPane.AddStatusField(Lang("Version", 20), versionStr)
 
         inPane.NewLine()
-        pool = data.pools().values()[0]
-        try:
-            dbController = pool["other_config"]["niciraController"]
-        except KeyError, e:
-            dbController = ""
+        dbController = data.GetPoolForThisHost().get("other_config", {}).get("niciraController", "")
         if dbController == "":
             dbController = Lang("<None>")
         inPane.AddStatusField(Lang("Controller (config)", 20), dbController)
@@ -294,7 +285,7 @@ class XSFeatureNiciraVSwitch:
             {
                 'menuname' : 'MENU_NETWORK',
                 'menupriority' : 800,
-                'menutext' : Lang('Nicira VSwitch') ,
+                'menutext' : Lang('Nicira vSwitch') ,
                 'statusupdatehandler' : self.StatusUpdateHandler,
                 'activatehandler' : self.ActivateHandler
             }