vasm / src / vasm / backend /

#!/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
#    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 <>.

#   Thanks to Jason Pierce (rxMokka) for the research that went into this.

__author__ = "Moises Henriquez"
__author_email__ = "moc.liamg@xnl.E0M"[::-1]

Interact with network interfaces and general system networking settings. """
from netifaces import *
import os
import logging
from utils import get_popen

DHCP = -1
logger = logging.getLogger('vasm')

class MissingDaemonError(Exception):
    def __init__(self, message):
        self.message = message
    def __str__(self):
        return repr(self.message)

class NDaemon(object):
    """ Class representing a networking daemon available on the system. 
    Allows us to interact with this daemon, and perform tasks such as
    enabling it and disabling it. 
        bin_path    -   Path to the executable.
        init_script -   Path to the rc.daemon file in /etc/rc.d
        service_script - Path to the service handler for this daemon. 
                        Usually somewhere in /etc/rc.d/init.d """
    def __init__(self, name=None, bin_path=None, init_script=None, 
            service_script=None): = name
        self.bin_path = bin_path
        self.init_script = init_script
        self.service_script = service_script
    def _run_command(self, cmd):
        proc = get_popen(cmd)
        stdout, stderr = proc.communicate()
        code = proc.returncode
        assert code == 0, stderr.strip()
    def enable(self):
        """ Make the init_script executable """
        return self._run_command(['chmod','+x', self.init_stript])
    def disable(self):
        """ Make the init_script not executable """
        return self._run_command(['chmod', '-x', self.init_stript])
    def disable_service(self):
        """ disable the service for all runlevels """
        assert self.service_script is not None, \
            "No service script available for %s."% self.bin_path
        svcmodel = SERVICES.ServiceModel()
        assert svcmodel.hasService(self.service_script), \
            "No such service %s on the system."% self.service_script
        for x in range(3,5):
            svcmodel.disable_service(self.service_script, x)        
    def enable_service(self):
        """ enable service for runlevels 3-5 """
        assert self.service_script is not None, \
            "No service script available available for %s."% self.bin_path
        svcmodel = SERVICES.ServiceModel()
        assert svcmodel.hasService(self.service_script), \
            "No such service %s on the system."% self.service_script
        for x in range(3, 5):
            svcmodel.enable_service(self.service_script, x)

class Nic(object):
    """ Class representing a network interface. 
    By using this class, we can access information about the network
        devname - Device name. ie, 'eth0'
        ip_addr - IP Address for the adaptor.
        netmask - netmask address.
        bcast -   broadcast address.
        macaddr - hardware MAC address
    def __init__(self, devname=None,
            ip_addr = None,
            netmask = None,
            bcast = None,
            macaddr = None,
        self.devname = devname
        self.ip_addr = ip_addr
        self.netmask = netmask
        self.broadcast = bcast
        self.macaddr = macaddr

class Inet(object):
    """ Class used to represent an rc.inet entry in a vectorlinux system.
        nic     -   Interface to be used for this inet.  Must be an instance
                    of the class Nic.
        nmethod -   Networking Method.  Defines how the NIC is configured.
                    Must be one of STATIC or DHCP """
    def __init__(self, nic=None, nmethod=DHCP):
        assert isinstance(nic, Nic), 'Invalid nic argument.  Must use a Nic object'
        assert nmethod in (DHCP, STATIC), 'Invalid networking method argument'
        self.nic = nic
        self.nmethod = nmethod
    def _generate_config_data(self):
        """ Generate the inet script with the information provided. 
        Returns the data as a list"""
        if self.nmethod is DHCP:
            dhcpval = "yes"
            dhcpval = "no"
        ret = [
        " This file is created by vasm",
        " Avoid modifying it by hand",
        "## The settings",
        "DEVICE='%s'"% self.nic.devname,
        "DHCP='%s'"% dhcpval,
        "NETMASK='%s'"% self.nic.netmask,
        " ",
        "################## THE SCRIPT #########",
        "# Source the standard networking script.",
        ". /etc/rc.d/functions-network \"$@\""]
        return ret

class NetConfModel(object):
    """ Global networking model. """
    def __init__(self, host_file='/etc/hostname',
        hostname='vector.linux.vnet', nic_defs='/proc/net/dev'):
        self.nic_defs = nic_defs
        self.host_file = host_file
        self.dns_file = dns_file
        self.hostname = hostname

    def listNetworkingDaemons(self):
        """ Returns a list of known networking daemons available on 
        the system.  list contents are NDaemon objects """
        ret = []
        # Define some known daemons in a dictionary where the key
        # is the name of the daemon, and the key is another dictionary with
        # a 'path', 'initscript', and 'service' keys.
        DAEMONS = {'networkmanager':
            {'path': '/usr/sbin/NetworkManager',
                'initscript' : '/etc/rc.d/rc.networkmanager',
                'service' : None},
            '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,
                    bin_path = DAEMONS[netapp]['path'],
                    init_script = DAEMONS[netapp]['initscript'],
                    service_script = DAEMONS[netapp]['service'])
        return ret
    def useDaemon(self, daemon):
        """ Configure the system to use the specified networking daemon """
        options = self.lietNetworkingDaemons()
        valid = False
        for bin in options:
            if bin.lower() == daemon.lower():
                valid = True
        if not valid:
            raise MissingDaemonException(
            "Specified daemon is not available on this system.")
    def listNetworkAdapters(self):
        """ Return a list of Nic objects """
        ret = []
        for nic in interfaces():
            if nic == 'lo':
            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']
            _NIC = Nic(devname = nic,
                netmask = nmask,
                bcast = broadcast,
                macaddr = macaddr,
                ip_addr = ip)
        return ret