Esempio n. 1
0
 def __setXenHost(self, ip, username, password, slave):
     try:
         self.__xenHost = ManagedXenPool(ip, username, password, slave)
     except LoginError as error:
          raise LoginError(error.message)
     finally:
          pass
Esempio n. 2
0
class MainWindow():
    def __init__(self, parent): 
        self.__vmFrame = None                 #GUI frame for the VMs
        self.__menuBar = None                 #menubar for app
        self.__dropdown = None                #dropdown box for the VMs
        self.__session = None                 #stores the session
        self.__mainFrame = None               #main frame for the app
        self.__bottomFrame = None             #bottom frame that holds the actions drop down box and the output box
        
        self.__xenHost = None                 #store XenServer Pool
        self.__selectedVM = None              #currently selected VM
        self.__selectedAction = None          #currently selected action
        self.__toggleLoginSlaveVal = 0        #toggle value for 'Login to slave host' option
        self.__toggleVMNetMonitorVal = 0      #toggle for monitoring VM option
        self.__connected = 0                  #used to see is the client is already connected to a host
        
        
        #create the balloon for Pmw
        self.balloon = Pmw.Balloon(parent)
        
                  
        frame = Tkinter.Frame(parent)
        frame.pack(fill = 'both', expand = 1)
        self.__mainFrame = frame
        
        #create the menu bar
        self.menuBar = Pmw.MenuBar(frame, hull_relief = 'raised', hull_borderwidth = 1, balloon = self.balloon)  
        self.menuBar.pack(fill = 'x')
        
        inputFrame = Tkinter.Frame(frame)
        inputFrame.pack()
        
        buttonFrame = Tkinter.Frame(frame)
        buttonFrame.pack()
               

        inputFrame.grid_size()
        # parent.configure(background = 'gray')
        
        
        #add items to the menu bar
        self.menuBar.addmenu('File', 'Exit options')
        self.menuBar.addmenuitem('File', 'separator')
        self.menuBar.addmenuitem('File', 'command', 'Exit the application',
                            command = self.__exit, label = 'Exit')


        self.menuBar.addmenu('Options', 'Set user preferences/options')
        self.menuBar.addmenuitem('Options', 'command', 'Change system password',
                            command = self.__changeSysPass, label = 'Change system password')
    
        #checkbutton menu item for 'Login to slave host' option
        self.__toggleLoginSlave = Tkinter.IntVar()
        
        #checkbutton menu item for monitoring VM option
        self.__toggleVMNetMonitor = Tkinter.IntVar()
        
        #initialize the checkbutton items to 0:
        self.__toggleLoginSlave.set(0)
        self.__toggleVMNetMonitor.set(0)
        
        self.menuBar.addmenuitem('Options', 'checkbutton', 'Login to slave host',
                label = 'Login to slave host',
                command = self.__toggleSlaveLogin,
                variable = self.__toggleLoginSlave)
        
        self.menuBar.addmenuitem('Options', 'checkbutton', 'Start network monitoring on VM',
                label = 'Start network monitoring on VM',
                command = self.__toggleStartVMNetMonitor,
                variable = self.__toggleVMNetMonitor)
        
        self.menuBar.component('Options-menu').entryconfig(2,state='disabled')

        self.menuBar.addcascademenu('Options', 'Filter powered-on VMs by host', 'Filter powered-on VMs by host', traverseSpec = 'z', tearoff = 1)
        

        self.menuBar.addmenu('Help', 'Help', side = 'right')
        self.menuBar.addmenuitem('Help', 'command', 'About this application', command = ShowDialog('About'), label = 'About')
    
        self.menuBar.label_ip = Tkinter.Label(inputFrame, text="IP Address:")
        self.menuBar.label_ip.grid(row=0, column=0, sticky='nw', padx='5')

        self.text_ip = Tkinter.Entry(inputFrame, name="ip")
        self.text_ip.grid(row=1, column=0, sticky='nw', padx='5')  
 
        self.label_username = Tkinter.Label(inputFrame, text="Username:"******"username")
        self.text_username.grid(row=1, column=1, sticky='nw', padx='5')
        
        self.label_password = Tkinter.Label(inputFrame, text="Password:"******"password", show="*")
        self.text_password.grid(row=1, column=2, sticky='nw', padx='5')
        
        buttonBox = Pmw.ButtonBox(buttonFrame)
        buttonBox.pack()
        buttonBox.add('connect', text = 'Connect', command = self.__connectButton)
        buttonBox.add('disconnect', text = 'Disconnect', command = self.__disconnectButton)

        self.menuBar.component('Options-menu').entryconfig(0,state='disabled')
        self.menuBar.component('Options-menu').entryconfig(3,state='disabled')


    #initialize bottom part of the main frame
    def __setBottomFrame(self, frame):
        self.__bottomFrame = Tkinter.Frame(frame)
        self.__bottomFrame.pack()
        
        
    #initialize part of the main frame that holds the VM drop down box    
    def __setVMFrame(self, frame):
        self.__vmFrame = Tkinter.Frame(frame)
        self.__vmFrame.pack()
        
        
    #initialize dropdown box with VMs
    def __setDropdown(self, vmFrame, label_text2, labelpos2, vms):
        self.__dropdown = Pmw.ComboBox(vmFrame, label_text = label_text2, labelpos = labelpos2, selectioncommand = self.__selectVM, scrolledlist_items = sorted(vms.keys(), cmp=self.__numeric_compare))
        self.__dropdown.pack()
             
        
    #return the bottom frame or bottom part of the main frame
    def __getBottomFrame(self):
        return self.__bottomFrame


    #return the dropdown box with VMs
    def __getDropdown(self):
        return self.__dropdown
    
        
    #function used to toggle value used to determine if to login to slave host 
    def __toggleSlaveLogin(self):
        if self.__toggleLoginSlaveVal:
            self.__toggleLoginSlaveVal = 0
            
        else:
            self.__toggleLoginSlaveVal = 1
            
            
    #function used to toggle starting and stopping VM monitoring of a VM
    def __toggleStartVMNetMonitor(self):
        session = self.__xenHost.getSession()        
        tempVM = self.__xenHost.getFilteredVMS()[self.__selectedVM]
        
        
        if tempVM.getMonitorState():
            tempVM.getVMMonitor().stopMonitor()
            tempVM.toggleMonitorState()
            self.__updateOutputText("VM monitoring successfully stopped")
        else:
            try:
                tempVM.getVMMonitor().startMonitor()
                tempVM.toggleMonitorState()
                self.__updateOutputText("VM monitoring successfully started")
            except VMNetMonitorError as error:
                self.__toggleVMNetMonitorVal = 0
                self.__toggleVMNetMonitor.set(0)
                command = ShowDialog("Error Monitoring VM")
                command.__call__()
            finally:
                pass
                        
            
    #called when a VM is selected from the VM dropdown box
    def __selectVM(self, vm):       
        self.__selectedVM = vm
        
        if self.__selectedVM and self.__toggleLoginSlaveVal == 0:
            self.menuBar.component('Options-menu').entryconfig(2,state='normal')
            
            
        ManagedVMObject = self.__xenHost.getFilteredVMS().get(self.__selectedVM)
        
        if ManagedVMObject.getMonitorState():
            self.__toggleVMNetMonitor.set(1)
        else:
            self.__toggleVMNetMonitor.set(0)
                        

    #called to update the results output box at the bottom of the main frame - passed-in parameter is the message to display
    def __updateOutputText(self, new_text):
        self.st.configure(text_state = 'normal') 
        self.st.component('text').delete('0.0', '20.0')
        self.st.component('text').insert('0.0', new_text + "\n")
        self.st.configure(text_state = 'disabled')


       
    #from 'actions' dropdown, select operation to perform on VM - called when dropdown is used to select action
    def __selectAction(self, action):        
        self.__selectedAction = action
        
        ManagedVMObject = self.__xenHost.getFilteredVMS().get(self.__selectedVM)
        
        if self.__selectedVM:        
            if self.__selectedAction == "Clean Shutdown VM":
                try:
                    ManagedVMObject.vmCleanShutdown()
                    self.__updateOutputText("VM clean shutdown request sent:\n\nXenTools must be installed on the VM\nfor this request to succeed.")                  
                except VMXenToolsActionError as error:
                    command = ShowDialog("VM XenTools Action Error")
                    command.__call__()
                    
            elif self.__selectedAction == "Start VM":
                try:
                    ManagedVMObject.startVM()
                    self.__updateOutputText("VM start request sent")                   
                except VMActionError as error:
                    command = ShowDialog("VM Action Error")
                    command.__call__()
                               
            elif self.__selectedAction == "Hard Reboot VM":
                try:
                    ManagedVMObject.hardRebootVM()
                    self.__updateOutputText('VM hard reboot request sent')                 
                except VMActionError as error:
                    command = ShowDialog("VM Action Error")
                    command.__call__()
                    
            elif self.__selectedAction == "Suspend VM":
                try:
                    ManagedVMObject.suspendVM()
                    self.__updateOutputText('VM suspend request sent:\n\nXenTools must be installed on the VM\nfor this request to succeed.')                  
                except VMXenToolsActionError as error:
                    command = ShowDialog("VM XenTools Action Error")
                    command.__call__()
                
            elif self.__selectedAction == "Resume VM":
                try:
                    ManagedVMObject.resumeVM()
                    self.__updateOutputText('VM resume request sent:\n\nXenTools must be installed on the VM\nfor this request to succeed.')                
                except VMXenToolsActionError as error:
                    command = ShowDialog("VM XenTools Action Error")
                    command.__call__()
                
            elif self.__selectedAction == "Create Snapshot":
                try:
                    root.update()
                    d = InputDialog(root, "Enter Snapshot Name")
                    root.wait_window(d.top)
            
                    snapshot_name = d.var.strip()
            
                    if snapshot_name:
                        if(re.match("^[A-Za-z0-9_-]{1,20}$", snapshot_name) != None): #validate snapshot name               
                            ManagedVMObject.vmCreateSnapshot(snapshot_name)
                            d.clearVar()
                            
                            self.__updateOutputText("Snapshot request sent")
                        else:
                            command = ShowDialog("Invalid Snapshot Name Error")
                            command.__call__()
                    else:
                        command = ShowDialog("No Snapshot Name Error")
                        command.__call__()                
                except VMActionError as error:
                    command = ShowDialog("VM Action Error")
                    command.__call__()
                    

            elif self.__selectedAction == "Live Migrate VM":
                #ManagedVMObject.migrateVM()
                #print 'VM successfully migrated'
                command = ShowDialog('Not Yet Implemented')
                command.__call__()
            else:
                pass
        else:
           command = ShowDialog('No VM Selected')
           command.__call__()


    #connect to the server
    def __connectButton(self):
        ip = self.text_ip.get()
        username = self.text_username.get()
        password = self.text_password.get()
        
        if(self.__connected == 0): #if not already connected
            if ip:
                if username:
                    if password:
                        try:
                            self.__xenHost = None
                            self.__setXenHost(ip, username, password, self.__toggleLoginSlaveVal) #login and set ManagedXenPool instance variables
                            self.__session = session = self.__xenHost.getSession() #get the current session
                        except LoginError as error:
                            command = ShowDialog("Login Error")
                            command.__call__()
                            root.destroy()
                            sys.exit()
                        finally:
                            pass
                        
                        self.__connected = 1    
                        self.__dropdown = None
                        self.__vmFrame = None
                        
                        self.__bottomFrame = None
                        self.__selectedVM = None
                        self.__selectedAction = None
                        self.__toggleVMNetMonitorVal = 0
                        
                        self.__setVMFrame(self.__mainFrame) 
                        self.__setBottomFrame(self.__mainFrame)   
                        
                        #get all hosts
                        hosts = self.__xenHost.getHosts()
                                           
                        self.__loadVMS(self.__vmFrame)
                        self.__loadActions()
                        self.__loadOutput()
        
                        for currHost in hosts.keys():
                            self.menuBar.addmenuitem('Filter powered-on VMs by host', 'command', 'Filter by ' + currHost, command = PrintVMs(currHost), label = currHost)
                        
                        if(self.__toggleLoginSlaveVal == 0):    
                            self.menuBar.component('Options-menu').entryconfig(0,state='normal')
                        self.menuBar.component('Options-menu').entryconfig(3,state='normal')
                        self.menuBar.component('Options-menu').entryconfig(1,state='disabled')
                    else:
                        command = ShowDialog("Missing Password")
                        command.__call__()
                else:
                    command = ShowDialog("Missing Username")
                    command.__call__()
            else:
                    command = ShowDialog("Missing IP Address")
                    command.__call__()
        else:
            command = ShowDialog('Already Connected')
            command.__call__()
                
        
    #disconnect from the server    
    def __disconnectButton(self):
        if(self.__connected == 1):
            session = self.__xenHost.getSession()
            session.xenapi.session.logout()
            self.__connected = 0
            
            self.__toggleLoginSlave.set(0)
            self.__toggleLoginSlaveVal = 0
            
            self.__toggleVMNetMonitor.set(0)
            self.__toggleVMNetMonitorVal = 0            
            
            #reinitialize respective menu items to logged-off defaults
            self.menuBar.component('Options-menu').entryconfig(0,state='disabled')
            self.menuBar.component('Options-menu').entryconfig(2,state='disabled')
            self.menuBar.component('Options-menu').entryconfig(3,state='disabled')
            self.menuBar.component('Options-menu').entryconfig(1,state='normal')
            
            
            #loop through all the VMs, and, if needed, get its monitoring object and shut it down  
            vms = self.__xenHost.getFilteredVMS()
            
            for vm in vms.values():                
                monitor = vm.getVMMonitor()
                pinger = monitor.getPinger()
                
                if pinger != None:
                    vm.getVMMonitor().stopMonitor()
            
            
            self.__vmFrame.destroy()
            self.__getBottomFrame().destroy()
            self.menuBar.deletemenuitems('Filter powered-on VMs by host', 0, self.__xenHost.getHostCount())
            
        else:
            command = ShowDialog('Already Disconnected')
            command.__call__()
  
    
    #load vms into respective dropdown box    
    def __loadVMS(self, vmFrame, hostFilter = False):       
        vms = {}      
            
        if(hostFilter):
            self.__getDropdown().destroy()
            vms = self.__xenHost.getFilteredVMS()
        else:  
            vms = self.__xenHost.getVMS()
 
        
        self.__setDropdown(vmFrame, 'Virtual Machines:', 'nw', vms)
        
                                       
     
    #regex to strip out the number in front and sort based off of it --- also used as the key to determine what vm was selected
    #since some vms may have the same name  
    def __numeric_compare(self,x,y):
        regexp = re.compile(r"(?P<the_x>^[\d]+)")
        result_x = regexp.search(x)
        
        regexp = re.compile(r"(?P<the_y>^[\d]+)")
        result_y = regexp.search(y)
        
        x_value = result_x.group('the_x')
        y_value = result_y.group('the_y')
        
        return int(x_value) - int(y_value)

        
        
    #load the 'actions' drop down box with operations that can be performed on VMs    
    def __loadActions(self):        
        vmActions = ('','Start VM', 'Clean Shutdown VM', "Hard Reboot VM", "Suspend VM", "Resume VM", "Create Snapshot", "Live Migrate VM")

        actionLabel = "Actions:"
        
        if self.__toggleLoginSlaveVal:
            actionLabel= "Actions: (Disabled - connected to slave!)"
        
        dropdownVmAction = Pmw.ComboBox(self.__getBottomFrame(), label_text = actionLabel, labelpos = 'nw', selectioncommand = self.__selectAction, scrolledlist_items = vmActions,)
        dropdownVmAction.pack()
        
        if self.__toggleLoginSlaveVal:
            dropdownVmAction.component('entry').config(state='disabled')
            dropdownVmAction.component('listbox').config(state='disabled')
            
        
        #display the first VM action which will be ''
        firstAction = vmActions[0]
        dropdownVmAction.selectitem(firstAction)
            
           
    #load the output scrolled text box and set initial values        
    def __loadOutput(self):
        
        #Create the ScrolledText with headers
        fixedFont = Pmw.logicalfont('Fixed')
        self.st = Pmw.ScrolledText(self.__getBottomFrame(),
        labelpos = 'n',
        label_text='',
        columnheader = 1,
        rowcolumnheader = 0,
        usehullsize = 1,
        hull_width = 400,
        hull_height = 300,
        text_wrap='none',
        text_font = fixedFont,
        Header_font = fixedFont,
        Header_foreground = 'blue',
        text_padx = 4,
        text_pady = 4,
        )
        
        headerLine="               Connected!                    "
        
        self.st.pack()
        self.st.component('columnheader').insert('0.0', headerLine)
        self.st.component('text').insert('0.0', "# of VMs in Cluster: " + str(self.__xenHost.getVMCount()) + "\n")
        self.st.component('text').insert('0.0', "# of Host Servers in Cluster: " + str(self.__xenHost.getHostCount()) + "\n")

        self.st.configure(
            text_state = 'disabled',
            Header_state = 'disabled',
        )          
            
            
    
    #filter VMs based on selected host
    def filterByHost(self, host):
        self.__toggleVMNetMonitor.set(0)
        self.menuBar.component('Options-menu').entryconfig(2,state='disabled')
        self.__xenHost.filterByHost(host)
        self.__loadVMS(self.__vmFrame, hostFilter = True)
                                    


    #change the system password of the master host of the pool
    def __changeSysPass(self):
        session = self.__xenHost.getSession()
        sessionID = self.__xenHost.getSessionID()
        
        d = InputDialog(root, "New system password:"******"^[A-Za-z0-9_-]{1,20}$", newPassword) != None):                
                session.xenapi.session.change_password(self.__xenHost.getPassword(), newPassword)
                self.__xenHost.setPassword(newPassword)
                d.clearVar() 
                self.__updateOutputText("Password successfully changed")
            else:
                command = ShowDialog("Invalid Password Error")
                command.__call__()
        else:
                command = ShowDialog("No Password Error")
                command.__call__()

     
       
    #login to host and save respective info into ManagedXenPool object    
    def __setXenHost(self, ip, username, password, slave):
        try:
            self.__xenHost = ManagedXenPool(ip, username, password, slave)
        except LoginError as error:
             raise LoginError(error.message)
        finally:
             pass

       
    #loop through all the VMs, and, if needed, get its monitoring object and shut it down   
    def __exit(self):
        if(self.__connected):
            vms = self.__xenHost.getFilteredVMS()
            
            for vm in vms.values():                
                monitor = vm.getVMMonitor()
                pinger = monitor.getPinger()
                
                if pinger != None:
                    vm.getVMMonitor().stopMonitor()
        
        root.destroy()
        sys.exit()