Commits

Moises Henriquez  committed 557d0d3

Begin coding initial networking ui ideas [gui]

  • Participants
  • Parent commits 7ff839c

Comments (0)

Files changed (3)

File src/vasm/backend/NETWORKING.py

 
 __author__ = "Moises Henriquez"
 __author_email__ = "moc.liamg@xnl.E0M"[::-1]
+__contributors__ = ["Uel Archuletta", 
+    "Jason Pierce",
+    "Rodrigo Bistolfi"]
 
 """ NETWORKING.py
 Interact with network interfaces and general system networking settings. """
-from netifaces import *
+import netinfo
 import os
 import logging
 import shutil
 from utils import get_popen
 import SERVICES
+logger = logging.getLogger('vasm')
 
-DHCP = -1
-STATIC = -2
-logger = logging.getLogger('vasm')
+# Networking Constants
+NET_NONE = -1
+NET_DAEMON = -2
+NET_INET = -3
+NET_INET_DHCP = -4
+NET_INET_STATIC = -5
+DHCP = NET_INET_DHCP
+STATIC = NET_INET_STATIC
 
 class MissingDaemonError(Exception):
     def __init__(self, message):
         self.netmask = netmask
         self.broadcast = bcast
         self.macaddr = macaddr
+        self.livedata = self._get_live_data()
         self.scripts_location = scripts_loc
         self.inet = Inet(
             fpath = self.findConfig(), nic = self)
     
+    def _get_live_data(self):
+        """ Returns a dictionary of the current information on this nic """
+        ldata = netinfo.get_routes(self.devname)
+        data = {
+            'IPADDR': netinfo.get_ip(self.devname),
+            'NETMASK': netinfo.get_netmask(self.devname),
+            'BROADCAST': netinfo.get_broadcast(self.devname)}
+        gw = None
+        for part in ldata:
+            if part['dest'] == '0.0.0.0' and \
+                    part['dev'] == self.devname and \
+                    part['netmask'] == '0.0.0.0':
+                gw = part['gateway']
+                break
+        if gw:
+            data['GATEWAY'] = gw
+        else:
+            data['GATEWAY'] = ''
+        return data
+
     def _get_next_available_config_file(self):
         """ Return a path to the next available config file """
         for x in range(1,10):
         # a 'path', 'initscript', and 'service' keys.
         DAEMONS = {'networkmanager':
             {'path': '/usr/sbin/NetworkManager',
+                'name': 'NetworkManager',
                 'initscript' : '/etc/rc.d/rc.networkmanager',
                 'service' : None,
                 'sessionscript' : '/etc/xdg/autostart/nm-applet.desktop'},
             'wicd' : {
+                'name': 'Wicd',
                 'path': '/usr/sbin/wicd',
                 'initscript' : '/etc/rc.d/rc.wicd',
                 'service': None,
         for netapp in DAEMONS:
             if os.path.exists(DAEMONS[netapp]['path']):
                 ndaemon = NDaemon(
-                    name = netapp,
+                    name = DAEMONS[netapp]['name'],
                     bin_path = DAEMONS[netapp]['path'],
                     init_script = DAEMONS[netapp]['initscript'],
                     service_script = DAEMONS[netapp]['service'],
     def listNetworkAdapters(self):
         """ Return a list of Nic objects """
         ret = []
-        for nic in interfaces():
+        for nic in netinfo.list_devs():
             if nic == 'lo':
                 continue
-            nicdata = ifaddresses(nic)
-            ip = nicdata[AF_INET][0]['addr']
-            broadcast = nicdata[AF_INET][0]['broadcast']
-            nmask = nicdata[AF_INET][0]['netmask']
-            macaddr = nicdata[AF_LINK][0]['addr']
-            # Create the Nic objet.
-            # The new Nic object will get it's own Inet object.
+            ip = netinfo.get_ip(nic)
+            broadcast = netinfo.get_broadcast(nic)
+            nmask = netinfo.get_netmask(nic)
+            macaddr = netinfo.get_hwaddr(nic)
+            # Create the Nic object.
+            # The new Nic object will get its own inet object
             _NIC = Nic(devname = nic,
                 netmask = nmask,
                 bcast = broadcast,
                 ip_addr = ip)
             ret.append(_NIC)
         return ret
+    
+    def getNic(self, devname):
+        """ Return a Nic object for the device name provided """
+        all = self.listNetworkAddapters()
+        for item in all:
+            if item.devname == devname:
+                return item
+        return None
+    
+    def getCurrentMethod(self):
+        """ Returns which networking method is currently being used. """
+        # look for active daemons
+        for app in self.listNetworkingDaemons():
+            if app.check_status():
+                return (NET_DAEMON, app.name)
+        # look for active inets
+        for inet in self.listNetworkAdapters():
+            if inet.check_status():
+                return (NET_INET, inet.devname)
+        # Nothig was found
+        return (NET_NONE, None)
+    
+    def getActiveNics(self):
+        """ Returns a list of active network interfaces """
+        ret = []
+        for inet in self.listNetworkAdapters():
+            if inet.check_status():
+                ret.append(inet)
+        return ret

File src/vasm/ui/gtk2/modules/networking.py

+#!/usr/bin/env python
+
+#    This file is part of VASM.
+#
+#    VASM is free software: you can redistribute it and/or modify
+#    it under the terms of the GNU General Public License v3 as published by
+#    the Free Software Foundation.
+#
+#    VASM 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 VASM.  If not, see <http://www.gnu.org/licenses/>.
+
+__author__ = "Moises Henriquez"
+__author_email__ = "moc.liamg@xnl.E0M"[::-1]
+
+import gtk
+import os
+from vasm.ui.gtk2.support import widgets, dialogs
+from vasm.backend import NETWORKING
+from vasm.backend.utils import _, get_popen, datapath
+import logging
+
+logger = logging.getLogger('vasm')
+
+class NetworkingUI(widgets.VasmModule):
+    def __init__(self, parent):
+        self.netmodel = NETWORKING.NetConfModel()
+        widgets.VasmModule.__init__(self, parent,
+            _("Networking"), _("Network settings"))
+        
+        netchoice = widgets.OptionsBox(
+            label=_("Select how this computer networks."),
+            options = (
+                ("None", NETWORKING.NET_NONE),
+                ("Automatic", NETWORKING.NET_DAEMON)),
+                #("Manual", NETWORKING.NET_INET)),
+            orientation=widgets.vertical)
+        if not self.netmodel.hostname: self.netmodel.hostname = 'vector.linux.vnet'
+        netchoice.add_observer(self.netchoice_observer)
+        hostnamebox = widgets.TextEntry("Hostname", entry_fill_box=False)
+        hostnamebox.set_text(self.netmodel.hostname)
+        
+        # daemon mode
+        self.frmdaemon = gtk.Frame(label=_("Preferred Network Managing Application"))
+        _daemons = [("None", NETWORKING.NET_INET)]
+        for app in self.netmodel.listNetworkingDaemons():
+            _daemons.append((app.name, app.name))
+        dpicker = widgets.OptionsBox(
+            label = None,
+            options = _daemons,
+            orientation = widgets.horizontal)
+        dpicker.add_observer(self.daemon_observer)
+        self.dpicker = dpicker
+        self.frmdaemon.add(dpicker)
+        # inet mode
+        self.inetpicker = gtk.Frame(
+            label = _("Automatic networking - INET based")
+            )
+        hbox = gtk.VBox()
+        inets = self.netmodel.listNetworkAdapters()
+        self.nicpicker = widgets.OptionsBox(
+            label = _("Network Adaptor"),
+            orientation=widgets.horizontal,
+            options = [(nic.devname, nic.devname) for nic in inets])
+        hbox.pack_start(self.nicpicker, True, True, 2)
+        self.inetpicker.add(hbox)
+        self.nmethodpicker = widgets.OptionsBox(
+            label = _("Networking Method"),
+            options = [("DHCP", NETWORKING.NET_INET_DHCP), 
+                        ("STATIC", NETWORKING.NET_INET_STATIC)],
+            orientation = widgets.horizontal)
+        self.nmethodpicker.add_observer(self.inet_adaptor_observer)
+        hbox.pack_start(self.nmethodpicker, True, True, 2)
+        self.staticsettings = gtk.Frame(_("Static networking settings."))
+        hbox.pack_start(self.staticsettings, False, True, 4)
+        sthbox = gtk.VBox()
+        sthbox.pack_start(gtk.Label())
+        self.entry_IP = widgets.TextEntry(_("IP Address") + ":", 
+            entry_fill_box=False,
+            label_width_chars=10)
+        sthbox.pack_start(self.entry_IP, False, True, 2)
+        self.entry_GW = widgets.TextEntry(_("Gateway") + ":",
+            entry_fill_box=False, label_width_chars=10)
+        self.entry_NM = widgets.TextEntry(_("Netmask") + ":",
+            entry_fill_box=False, label_width_chars=10)
+        sthbox.pack_start(self.entry_GW, False, True, 2)
+        sthbox.pack_start(self.entry_NM, False, True, 2)
+        self.staticsettings.add(sthbox)
+        self.staticsettings.set_property('sensitive', False)
+        
+        
+        # pack the widgets on the module
+        self.pack_start(hostnamebox, False, True, 4)
+        self.pack_start(netchoice, False, True, 4)
+        self.pack_start(self.frmdaemon, False, True, 4)
+        self.pack_start(self.inetpicker, False, True, 4)
+        self.add_button((gtk.Button(stock=gtk.STOCK_CLOSE), self.close_module))
+        self.add_button((gtk.Button(stock=gtk.STOCK_APPLY),
+            self._save_changes))
+        
+        # Read the current status
+        method, _nobject = self.netmodel.getCurrentMethod()
+        for wid in netchoice._options:
+            if wid.user_data == method:
+                wid.set_active(True)
+
+    def _save_changes(self, caller=None):
+        print "Saaving"
+    
+    def _set_ui_for_no_network(self, caller=None):
+        self.frmdaemon.set_property('sensitive', False)
+        self.inetpicker.set_property('sensitive', False)
+    
+    def _set_ui_for_daemon_networking(self, caller=None):
+        self.frmdaemon.set_property('sensitive', True)
+        self.inetpicker.set_property('sensitive', False)
+    
+    def _set_ui_for_inet_networking(self, caller=None):
+        self.inetpicker.set_property('sensitive', True)
+        method, adaptor = self.netmodel.getCurrentMethod()
+        for nic in self.nicpicker._options:
+            if nic.user_data == adaptor:
+                # toggle the active NIC
+                nic.set_active(True)
+                return self._display_nic_settings(nic)                
+
+    def _display_nic_settings(self, nic):
+        """ Display the settings details on how this nic is setup """
+        # See if we are using dhcp
+        dhcp = nic.inet.config['DHCP'] == 'yes'
+        self.staticsettings.set_property('sensitive', not dhcp)
+        # Display the rest of the information here.
+        # If it is using dhcp, read the live data on the nic
+    
+        if dhcp:
+            _ip = nic.livedata['IPADDR']
+            _gw = nic.livedata['GATEWAY']
+            _nm = nic.livedata['NETMASK']
+            _bc = nic.livedata['BROADCAST']
+        else:
+            _ip = nic.inet.config['IPADDR']
+            _gw = nic.inet.config['GATEWAY']
+            _nm = nic.inet.config['NETMASK']
+            _bc = nic.inet.config['BROADCAST']
+        self.entry_IP.set_text(_ip)
+        self.entry_GW.set_text(_gw)
+        self.entry_NM.set_text(_nm)
+    
+    def daemon_observer(self, data):
+        """ Trigger events when the networking daemon is selected """
+        seld = data.user_data
+        if seld == NETWORKING.NET_INET:
+            self._set_ui_for_inet_networking()
+            # get the active nic
+            niclist = self.netmodel.getActiveNics()
+            # FIXME:  ^^ will return more than one value if more than one
+            #           rc.inet script is set +x
+            #           We use the first one here.
+            if len(niclist) == 0: return
+            anic = niclist[0]
+            return self._display_nic_settings(anic)
+                
+        else:
+            self._set_ui_for_daemon_networking()
+
+    def inet_adaptor_observer(self, data):
+        nmethod = data.user_data
+        if nmethod == NETWORKING.NET_INET_DHCP:
+            self.staticsettings.set_property('sensitive', False)
+        else:
+            self.staticsettings.set_property('sensitive', True)
+        #print data.user_data
+    
+    def netchoice_observer(self, data):
+        nval =  data.user_data
+        self.networkingmethod = nval
+        if nval == NETWORKING.NET_NONE:
+            return self._set_ui_for_no_network()
+        elif nval == NETWORKING.NET_DAEMON:
+            self._set_ui_for_daemon_networking()
+            method, _object = self.netmodel.getCurrentMethod()
+            for wid in self.dpicker._options:
+                # Select the current selected object from the method
+                if wid.user_data == _object:
+                    wid.set_active(True)
+                    return
+                if method == NETWORKING.NET_INET:
+                    active_nic = self.netmodel.getNic(_object)
+                    if active_nic.config['DHCP'] == 'yes':
+                        for radio in self.nmethodpicker._options:
+                            if radio.user_data == NETWORKING.NET_INET_DHCP:
+                                return radio.set_active(True)
+                        METHOD = NETWORKING.NET_INET_DHCP
+                    else:
+                        for radio in self.netchoice_observer._options:
+                            if radio.user_data == NETWORKING.NET_INET_STATIC:
+                                return radio.set_active(True)
+                    # Set the radio to either dhcp or static """
+
+    
+def __vasm_test__():
+    return True
+    return os.geteuid() == 0
+
+def __run__(parent=None):
+    w = NetworkingUI(parent)
+    return w.launch()
+
+VASM_CATEGORY = _("Networking")
+VASM_LABEL=_("Networking")
+VASM_ICON = os.path.join(datapath, 'category_networking.png')

File src/vasm/ui/gtk2/support/widgets.py

 horizontal = gtk.HBox
 vertical = gtk.VBox
 
-class VasmEmbedder(object):
-    def __init__(self, parent=None, command="", window_title=""):
-        self.command = command
-        self.window_title = window_title
-        self._parent = parent
-        self.end_flag = Event()
     
-    def launch(self):
-        """ Launch the application and find the created window """
-        # we need to execute the thread and get the gtk.gdk.window that we will
-        # reparent on the main ui.
-        mthread = MonitoredExternalGui(self.command, self.end_flag).start()
-        
-        # get the window id so we can find the window object
-        wid = self._get_window_id()
-        wobj = None
-        if wid > 0:
-            print "Got window ID of", wid, "getting window object"
-            wobj = self._get_window_object(wid)
-        if wobj is not None:
-            print "Got window object", wobj
-            return self._parent.embed_external(wobj, self.end_flag)
-        # else, it will just run externally.
 
-    def _get_window_object(self, windowid):
-        """ return the gtk.gdk.window object needed to embed in the app """
-        ret = None
-        for x in range(5):
-            ret = gtk.gdk.window_foreign_new(int(windowid))
-            if ret:
-                break
-            time.sleep(1)
-        return ret
-    
-    def _get_window_id(self):
-        #cmd = "xwininfo -name '%s'"% self.window_title
-        cmd = ["xwininfo", "-name", self.window_title]
-        for x in range(5):
-            wid = 0
-            proc = get_popen(cmd)
-            output = proc.communicate()[0].split('\n')
-            for line in output:
-                line = line.strip()
-                if line.startswith("xwininfo:") and line.endswith('\"' + self.window_title + '\"'):
-                    raw = line.rsplit(":")[-1].strip()
-                    strid = raw.split()[0].strip()
-                    if strid.startswith("0x"):
-                        strid = strid[2::]
-                        wid=int(long(str(strid), 16))
-                    else:
-                        wid = int(lont(strid))
-            if wid > 0:
-                break
-            time.sleep(1)
-        return wid
 
-class HOptionsBox(gtk.HBox):
-    def __init__(self, label=None, options=[]):
+class OptionsBox(gtk.HBox):
+    """ Box used to present a group of options to the user.
+    Arguments:
+        title   Title for the options.
+        orientation     Orientation method can be horizontal or vertical.
+        options     Iterrable collection of options to be presented.
+        """
+    def __init__(self, label=None, orientation=horizontal, options = []):
         gtk.HBox.__init__(self)
+        self._body = orientation()
         self._options = []
+        self.observers = []
         if label is not None:
             self.label = gtk.Label()
             self.label.set_use_markup(True)
             self.label.set_markup(label)
             self.label.set_property('xalign', 0.0)
-            self.pack_start(self.label, False, False, 4)
-        for choice in options:
+            self._body.pack_start(self.label, False, False, 4)
+        # Add the options
+        for item in options:
+            choice, data = item
             grp = self._get_rb_group()
             wid = gtk.RadioButton(grp, choice)
+            wid.user_data = data
+            wid.connect('toggled', self.radio_toggle)
             self._options.append(wid)
-            self.pack_start(wid, False, False, 4)
-
-    def set_label(self, txt):
-        return self.label.set_markup(txt)
-
-    def set_value(self, value):
-            for wid in self._options:
-                if wid.get_label() == value or wid.get_label().lower() == value.lower():
-                    wid.set_active(True)
-                    return
-            return
-
-    def get_value(self):
-        for wid in self._options:
-            if wid.get_active():
-                return wid.get_label()
-        return None
-
+            self._body.pack_start(wid, False, False, 2)
+        self.pack_start(self._body, True, True, 0)
+    
     def _get_rb_group(self):
         if len(self._options) > 0:
             return self._options[0]
         return None
-            
+    
+    def add_observer(self, method):
+        return self.observers.append(method)
+    
+    def notify(self, data):
+        for f in self.observers:
+            f(data)
+    def radio_toggle(self, radio):
+        if radio.get_active():
+            return self.notify(radio)
+
+class HOptionsBox(OptionsBox):
+    def __init__(self, label=None, options=[]):
+        OptionsBox.__init__(self, label, options, orientation=horizontal)
+    
+class VOptionsBox(OptionsBox):
+    def __init__(self, label=None, options=[]):
+        OptionsBox.__init__(self, label, options, orientation=vertical)
 
 class VasmSubModule(gtk.VBox):
     """ Submodule widget to be used as a sub-category display """
     def get_text(self):
         return self.entry.get_text()
     
+    def set_text(self, value):
+        return self.entry.set_text(value)
+    
     def set_label(self, markup):
         return self.label.set_markup(markup)