Moises Henriquez avatar Moises Henriquez committed ac7e5a5

Renamed backend modules to follow normal naming convention

Comments (0)

Files changed (49)

src/vasm/backend/BOOTLOADERS.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/>.
-
-#   Thanks to Jason Pierce (rxMokka) for the research that went into this.
-
-__author__ = "Moises Henriquez"
-__author_email__ = "moc.liamg@xnl.E0M"[::-1]
-__contributors__ = ["Jason Pierce (rxMokka)"]
-
-import parted
-import subprocess as sp
-import os
-import utils
-import shutil
-import psutil
-import logging
-
-DEFAULT_BOOTLOADER='GRUB2'
-logger = logging.getLogger('vasm')
-LOADER_CONFIGS={
-    "GRUB2": "/boot/grub/grub.cfg",
-    "LILO": "/etc/lilo.conf",
-    "GRUB": "/boot/grub/menu.lst"
-}
-
-# Boot loader action constants
-Install = -1
-Refresh = -2
-
-def get_current_bootsector():
-    """ Returns the current partition that is currently mounted in / """
-    fslist = psutil.disk_partitions()
-    for fs in fslist:
-        if fs.mountpoint == "/":
-            return fs.device
-    return None
-
-def get_linux_boot_info(root_partition):
-    """ Use linux-boot-prober to find out how to boot this OS 
-    linux-boot-prober produces multiple possible ways to boot the os, so we
-    must choose which one to implement.
-    
-    /dev/sdb1:/dev/sdb1::/boot/vmlinuz26:/boot/kernel26.img:root=/dev/sdb1
-    """
-    ret = {}
-    proc = sp.Popen(['linux-boot-prober', root_partition], stdout=sp.PIPE, stderr=sp.PIPE)
-    hits = proc.stdout.readlines()
-    if len(hits) == 0: return None
-    line = hits[0]
-    line = line.strip()
-    if ":" not in line:
-        return None
-    root,boot,trash,kernel,initrd,append = line.split(":")
-    ret["root"] = root.strip()
-    ret["kernel"] = kernel.strip()
-    ret["initrd"] = initrd.strip()
-    ret["append"] = append.strip()
-    return ret
-
-def find_operating_systems(include_own_root=False):
-    """ This function will use os-prober and linux-boot-prober to locate
-    existing operating systems.  This should only be used to generate a 
-    lilo.conf file 
-    
-    This produces a list of strings formatted like this:
-    root : Long description : Short description: os type
-    /dev/sda1:VectorLinux (7.0 STD RC 1):VectorLinux:linux
-    """
-    proc = sp.Popen(['os-prober'], stdout=sp.PIPE, stderr=sp.PIPE)
-    hits = proc.stdout.readlines()
-    ret = []
-    if include_own_root and os.path.exists('/boot/vmlinuz'):
-        # create an entry for the running linux.
-        own = Entry()
-        tuientry = Entry()
-        own.kernel = '/boot/vmlinuz'
-        tuientry.kernel = '/boot/vmlinuz'
-        own.label = "VectorLinux"
-        tuientry.label = 'VectorLinux-tui'
-        if os.path.exists('/boot/initrd'):
-            own.initrd = '/boot/initrd'
-            tuientry.initrd = '/boot/initrd'
-        own.root = get_current_bootsector()
-        tuientry.root = get_current_bootsector()
-        own.appendline = 'splash=silent'
-        tuientry.appendline = '2 splash=silent'
-        ret.append(own)
-        ret.append(tuientry)
-    # since we only need this for lilo, we only need to read the short description
-    for hit in hits:
-        rootpart, long_desc, short_desc, os_type = hit.strip().split(":")
-        OS = Entry()
-        if short_desc.strip().startswith("Vector"):
-            short_desc = "Vector-%s"% rootpart.split("/")[-1]
-        OS.label = short_desc.strip()
-        if os_type.strip().lower() in ("linux",):
-            os._ostype = "linux"
-            bootinfo = get_linux_boot_info(rootpart.strip())
-            if bootinfo is None: continue
-            OS.root = bootinfo["root"] or rootpart.strip()
-            OS.kernel = bootinfo["kernel"].strip()
-            OS.initrd = bootinfo["initrd"].strip()
-            OS.appendline = bootinfo["append"].strip()
-        elif "windows" or "microsoft" in os_type_strip().lower():
-            OS.root = rootpart.strip()
-            OS.label = "Windows-%s"% roorpart.strip().splir("/")[-1]
-            OS._ostype = "windows"
-            # FIXME: ^^ This needs testing.
-
-        ret.append(OS)
-
-    return ret
-    
-def get_vga_mode(resolution="800x600", quality="med", grub2=False):
-    """ Return a numeric vga mode that can be used in lilo.conf based on 
-    the values provided for resolution and quality"""
-    val = "nornal"
-    values = {
-        "640x480" : {
-            "low" : "769",
-            "med" : "784",
-            "high" : "785"},
-        "800x600" : {
-            "low" : "771",
-            "med" : "787",
-            "high" : "788"},
-        "1024x768" : {
-            "low" : "773",
-            "med" : "790", 
-            "high" : "791"},
-        "1280x1024": {
-            "high":"794",
-            "med":"793",
-            "low":"775"}
-        }
-    grub2values = {
-        "640x480":"640x480x16",
-        "800x600": "800x600x16",
-        "1024x768":"1024x768x16",
-        "1280x1024":"1280x1024x16",
-        }
-    if grub2 is False:
-        return values[resolution][quality] or val
-    else:
-        return grub2values[resolution] or grub2values["800x600"]
-    
-    
-
-class LiloDotConf(object):
-    """ represents a complete lilo.conf file. """
-    def __init__(self, target="", default="", 
-                timeout_value=0, vga_value="nornal", include_running_os=False):
-        self.timeout_value = timeout_value
-        self.vga_value = vga_value
-        self.target = target
-        self.boot_default = default
-        self._include_running_os = include_running_os
-    
-    def set_target(self, value):
-        """ Set the target value on the configuration file """
-        self.target = value
-        return
-    
-    def set_default_os(self, value):
-        """ set the default OS on the configuration file """
-        self.boot_default = value
-        return
-    
-    def getOsListing(self, oslist=None):
-        """ Returns the os listing for lilo.conf as a list of strings """
-        if oslist is None:
-            oslist = find_operating_systems(self._include_running_os)
-        lilo_root = get_current_bootsector() # this returns whatever partition is mounted @ /
-        ret = []
-        spacer = " "*4
-        
-        for entry in oslist:
-            ret.append("# -- %s on %s -- "% (entry.label, entry.root))
-            if entry._ostype == 'linux':
-                ret.append("image = %s"% entry.kernel)
-                ret.append("%s root = %s"% (spacer, entry.root))
-                if entry.root != lilo_root:
-                    ret.append("%s label = %s"% (spacer, entry.label))
-                else:
-                    if entry.label.endswith('-tui'):
-                        ret.append("%s label = %s"% (spacer, entry.label))
-                    else:
-                        ret.append("%s label = VectorLinux"% spacer)
-                if entry.initrd not in ("",None):
-                    ret.append("%s initrd = %s"% (spacer, entry.initrd))
-                if entry.appendline not in ("", None):
-                    if "splash" not in entry.appendline:
-                        ret.append("%s append = \"%s splash=silent\""% (spacer, entry.appendline))
-                    else:
-                        ret.append("%s append = \"%s\""% (spacer, entry.appendline))
-                ret.append("%s read-only"% spacer)
-                ret.append("#")
-                ret.append("#")
-                ret.append("# -- End of listing for %s on %s -- "% (entry.label, entry.root))
-                ret.append("#")
-            elif entry._ostype == 'windows':
-                ret.append("%s other = %s"% (spacer, entry.root))
-                ret.append("%s label = %s"% (spacer, entry.label))
-                ret.append("%s table = %s"% (spacer, entry.root))
-
-            
-        # Add some trailing text
-        ret.append("#")
-        ret.append("# ------------------------------------ #")
-        ret.append("# ------- END OF OS LISTING ---------- #")
-        ret.append("# ------------------------------------ #\n\n")
-        
-        return ret
-    
-    def getHeader(self):
-        """ Returns the header of the file as a list of strings """
-        ret = [
-        "# LILO configuration file.",
-        "# ",
-        "# Generated by VASM.",
-        "# ",
-        "boot = %s"% self.target,
-        "compact",
-        "prompt",
-        "timeout = %s"% str(self.timeout_value),
-        "# Override dangerous defaults that re-order the partition tables:",
-        "change-rules",
-        " reset",
-        "bitmap = /boot/bitmap/boot.bmp",
-        "# default vga mode",
-        "vga = %s"% str(self.vga_value),
-        "# ",
-        "# VGA mode definitions ",
-        "# -------------------------- #",
-        "# VESA framebuffer console @ 1024x768x64k",
-        "# vga=791",
-        "# VESA framebuffer console @ 1024x768x32k",
-        "# vga=790",
-        "# VESA framebuffer console @ 1024x768x256",
-        "# vga=773",
-        "# VESA framebuffer console @ 800x600x64k",
-        "# vga=788",
-        "# VESA framebuffer console @ 800x600x32k",
-        "# vga=787",
-        "# VESA framebuffer console @ 800x600x256",
-        "# vga=771",
-        "# VESA framebuffer console @ 640x480x64k",
-        "# vga=785",
-        "# VESA framebuffer console @ 640x480x32k",
-        "# vga=784",
-        "# VESA framebuffer console @ 640x480x256",
-        "# vga=769",
-        "# --------------------------------------- #",
-        "# --------- START OS LISTING ------------ #",
-        "# --------------------------------------- #",
-        ]
-        return ret
-
-    def set_timeout(self, value):
-        """ Set timeout value on the configuration file """
-        # lilo wants it in thenths of a second
-        self.timeout_value = int(value) * 10
-        return
-    
-    def set_vga_value(self, value):
-        self.vga_value = value
-        return
-    
-
-
-class MBR(object):
-    """ MBR object to be scanned for boot loaders """
-    def __init__(self, drive):
-        """ Arguments:
-            drive = some drive path like '/dev/sda' """
-        self.drive = drive
-
-    def read_bootloader(self):
-        """ Read the first 2 bytes to see what bootloader is there """
-        f = open(self.drive, 'r')
-        data = f.read(2)
-        f.close()
-        if not data:
-            return None
-        elif data == "\xEB\x63":
-            return "GRUB2"
-        elif data == "\xEB\x48":
-            return "GRUB"
-        elif data == "\xFA\xEB":
-            return "LILO"
-        
-        return None
-
-# we still dont know which bootloader is active.  we only know how to read what's in the MBR.
-def get_active_bootloader():
-    """ Reads each MBR to see what's in there, and if it finds a bootloader
-    it will test to see if a config file for that loader exists.  If both of these
-    are true, then we know which menu we are using. """
-    devs = [dev for dev in parted.getAllDevices() if dev.getSize() > 0]
-    for dev in devs:
-        mbr = MBR(dev.path)
-        loader = mbr.read_bootloader()
-        if loader is not None:
-            if LOADER_CONFIGS.has_key(loader):
-                if os.path.exists(LOADER_CONFIGS[loader]):
-                    return loader
-    # Return the default bootloader if nothing else.
-    return DEFAULT_BOOTLOADER
-
-class Entry(object):
-    def __init__(self):
-        self.label = ""
-        self._ostype = 'linux'
-
-class BootLoader(object):
-    def __init__(self,
-        target="", timeout=5, vga_size="800x600", vga_quality="med"):
-        self.timeout = timeout
-        self.target=target
-        self.vga_size = vga_size
-        self.vga_quality = vga_quality
-        self.vga_mode = ""
-        self.type = "undefined"
-    
-    def set_timeout(self, value):
-        self.timout = timeout
-    
-    def set_target(self, value):
-        self.target = value
-    
-    def set_vga_mode(self, value):
-        """ Method to set the vga mode """
-        pass
-    
-    def save_config(self):
-        """ Common method to save the configuration """
-        pass
-    
-    def refresh_menu(self):
-        """common method to refresh the bootloader boot menu """
-        pass
-    
-    def install(self):
-        """ common method to install the bootloader to the target """
-        pass
-
-class LILO(BootLoader):
-    def __init__(self, target, timeout, vga_size, vga_quality, include_running_os=False):
-        BootLoader.__init__(self,target, timeout, vga_size, vga_quality)
-        self.type = "LiLO"
-        self.config = LiloDotConf(include_running_os)
-        self._include_running_os=include_running_os
-
-    def set_vga_mode(self):
-        self.vga_mode = get_vga_mode(self.vga_size, self.vga_quality, False)
-    
-    def save_config(self):
-        """ save the lilo configuration.
-        lilo just saves the generated config file to /etc/lilo.conf"""
-        logger.info("Generating lilo.conf")
-        configpath = LOADER_CONFIGS["LILO"]
-        config = self.config
-        # we want to setup the variables in the config.
-        config.set_target(self.target)
-        config.set_timeout(self.timeout)
-        # set the correct vga mode
-        self.set_vga_mode()
-        config.set_vga_value(self.vga_mode)
-        
-        # generate the contents of the config file.
-        data = config.getHeader()
-        # Generate a list of Entry objects where we can check if the initrd
-        # and kernels exist.
-        OsList = find_operating_systems(self._include_running_os)
-        # we need to make sure the paths to the kernels and initrds are relative
-        # to lilo's /boot.  This may require some file copying.
-        data.extend(self.prepare_os_list(OsList))
-        #badOsList = config.getOsListing()
-        # fix the os listing
-        
-        # make a backup of the file
-        if os.path.exists(configpath):
-            bkfile = "%s.bak"%configpath
-            try:
-                shutil.copy2(configpath,bkfile)
-            except:
-                # exit if we can't make a backup copy of lilo.conf
-                return 1
-        f = open(configpath, "w")
-        f.writelines("\n".join(data))
-        f.close()
-        return 0
-
-    def _copy_kernel(self, root, mntpoint, kname):
-        """ copy kname from root/boot to /boot/tamu """
-        # root must be a mountpoint
-        oldpath = os.path.join(mntpoint, "boot", kname)
-        host = os.path.split(root)[-1]
-        fname = "%s_%s"% (kname, host)
-        newpath = os.path.join("/boot", "tamu", fname)
-        if os.path.exists(newpath):
-            return newpath            
-        try:
-            shutil.copy2(oldpath, newpath)
-            logger.debug("copied %s to %s "% (oldpath, newpath))
-            return newpath
-        except:
-            logger.warning("Unable to find initrd for %s on %s"% (kname, root))
-            return None
-
-    def _check_if_premounted(self, partition, premountlist):
-        """ Check if partition was part of the partitions that were
-        originally mounted (specified in premountlist)"""
-        for p in premountlist:
-            if p.device == partition:
-                return True
-        return False
-
-    def get_partition_mountpoint(self, device, mountlist):
-        for item in mountlist:
-            if item.device == device:
-                return item.mountpoint
-        return None
-    
-    def prepare_os_list(self, object_list):
-        """ Copy kernels and initrd's from other Os's /boot to lilos /boot/tamu """
-        # before we do anything, take a snapshot of the system to see
-        # which partitions are now mounted
-        mountlist = psutil.disk_partitions()
-        try:
-            os.makedirs("/boot/tamu")
-        except:
-            pass
-        lilo_root = utils.get_mounted("/").strip()
-        for entry in object_list:
-            has_initrd = False
-            entry.root = entry.root.strip()
-            kname = os.path.split(entry.kernel.strip())[-1]
-            if entry.initrd is not None and entry.initrd is not "":
-                has_initrd = True
-                rdname = os.path.split(entry.initrd.strip())[-1]
-            if entry.root != lilo_root:
-                # kernel should be in /boot/tamu.
-                mpoint = entry.root.replace("/dev/", "/mnt/")
-                kpath = os.path.join("/boot", "tamu", kname)
-                if not os.path.exists(kpath):
-                    if not self._check_if_premounted(entry.root, mountlist):
-                        # mount the partition
-                        mount = utils.mount(entry.root, mpoint)
-                    else:
-                        mpoint = self.get_partition_mountpoint(entry.root, mountlist)
-                        assert mpoint is not None, \
-                            "Unable to get mountpoint for mounted partition %s"% entry.root
-                    # copy the kernel now
-                    entry.kernel = self._copy_kernel(entry.root, mpoint, kname)
-                    
-                    # if the kernel was not there, the initrd is most likely not either.
-                    if has_initrd:
-                        entry.initrd = self._copy_kernel(entry.root, mpoint, rdname)
-                    # umount if necesssary
-                    if not self._check_if_premounted(entry.root, mountlist):
-                        utils.umount(mpoint)
-        return self.config.getOsListing(object_list)
-
-    def install(self):
-        """ lilo requires you to setup the config file before installation """
-        self.save_config()
-        return self._do_install()
-    
-    def _do_install(self):
-        """ install the boot loader.  Return the value ($?) of running `lilo` """
-        logger.info("Writing lilo to %s"% self.target)
-        proc = sp.Popen(["lilo"], stdout=sp.PIPE, stderr=sp.PIPE)
-        output = proc.communicate()[1]
-        code = proc.returncode
-        assert code == 0, output
-        logger.info("Lilo was installed to %s"% self.target)
-    
-    def refresh_menu(self):
-        """ Procedure to refresh the menu """
-        return self.install()
-    
-
-class GRUB2(BootLoader):
-    def __init__(self, target, timeout, vga_size, vga_quality):
-        BootLoader.__init__(self, target, timeout, vga_size, vga_quality)
-        self.configpath = "/etc/default/grub"
-        self.type = "GRUB2"
-        self.timeout = str(int(timeout))
-        self.set_vga_mode()
-    
-    def set_vga_mode(self):
-        self.vga_mode = get_vga_mode(self.vga_size, self.vga_quality, True)
-
-    def _do_install(self):
-        """ Install grub to the target and give it a menu """
-        logger.info("Installing grub2 to %s"% self.target)
-        proc = utils.get_popen(["grub-install", "--no-floppy", self.target])
-        err = proc.communicate()[1]
-        code = proc.returncode
-        assert code == 0, err
-        logger.info("Grub2 was installed to %s"% self.target)
-
-    def install(self):
-        """ install the bootloader and give it its configuration """
-        ret = self._do_install()
-        return ret
-
-    def refresh_menu(self):
-        """ Refresh the grub2 boot menu """
-        return self.save_config()
-    
-    def save_config(self):
-        """ The grub2 config file is automatically generated, so we use
-        this method to save the values to /etc/default/grub which is 
-        parsed while the config file is generated """
-        f = open(self.configpath, "r")
-        data = f.readlines()
-        f.close()
-        ndata = []
-        # set the correct vga_mode value
-        self.set_vga_mode()
-        
-        vgaline = False
-        timeoutline = False
-        # check to make sure the file has the variables we need to set
-        for line in data:
-            if "GRUB_GFXMODE=" in line:
-                vgaline = True
-            elif "GRUB_TIMEOUT=" in line:
-                timeoutline = True
-        
-        # Add the lines if we dont have them
-        if vgaline is False:
-            data.append("GRUB_GFXMODE=\n")
-        if timeoutline is False:
-            data.append("GRUB_TIMEOUT=\n")
-        # save the variables.
-        for line in data:
-            if "GRUB_GFXMODE=" in line:
-                line = "GRUB_GFXMODE=%s\n"% str(self.vga_mode)
-            elif "GRUB_TIMEOUT=" in line:
-                line = "GRUB_TIMEOUT=%s\n"% str(int(self.timeout))
-            ndata.append(line)
-        # make a backup copy of the file
-        bk = "%s.bak"% (self.configpath)
-        logger.debug("Saving backup copy of %s to %s"% (self.configpath, bk))
-        try:
-            shutil.copy2(self.configpath, bk)
-        except:
-            # exit with a 1 value if we can't save this file
-            logger.fatal("Unable to save backup copy of %s"% self.configpath)
-            return 1
-        # save the new file
-        logger.debug("Saving new changes to %s"% self.configpath)
-        f = open(self.configpath, "w")
-        f.writelines("".join(ndata))
-        f.close()
-        
-        # after these are set, we just need to run grub-mkconfig
-        logger.info("Updating grub2 boot menu.")
-        proc = utils.get_popen(["grub-mkconfig", "-o", LOADER_CONFIGS["GRUB2"]])
-        err = proc.communicate()[1]
-        code = proc.returncode
-        assert code == 0, err
-        logger.info("Grub2 menu was updated.")
-
-
-class GrubCFG(object):
-    """ Parse a grub.cfg file to expose the menu entries as objects """
-    def __init__(self):
-        fpath = LOADER_CONFIGS["GRUB2"]
-        f = open(fpath, 'r')
-        self.data = f.readlines()
-        f.close()
-    
-    def get_menu_entries(self):
-        res = []
-        i = 0
-        for line in self.data:
-            i = i + 1
-            if line.startswith("menuentry"):
-                # set the start marker
-                sm = i
-                entry = Entry()
-                start, label, garbage = line.split("\"")
-                entry.label = label
-                # Loop through the next 10 lines to find the rest of the data
-                for x in range(sm, (sm + 10)):
-                    _line = self.data[x].strip()
-                    if _line.startswith("linux"):
-                        start, kernel, rootdev, append = _line.replace("\t", " ").split(" ", 3)
-                        entry.kernel = kernel
-                        entry.root = rootdev.split('=')[1]
-                        entry.append = append
-                    elif _line.startswith("initrd"):
-                        start, initrdpath = _line.replace("\t", " ").split(" ", 1)
-                        entry.initrd = initrdpath
-                    elif _line.startswith("}"):
-                        break
-                res.append(entry)
-        return res

src/vasm/backend/BOOTMODE.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]
-
-""" Support module for bootmode.py.
-Contains methods for setting and checking the VL boot (/etc/inittab) settings
-"""
-
-class InitTab(object):
-    def __init__(self, fopath="/etc/inittab"):
-        self.path = fopath
-    
-    def getMode(self):
-        """ Return the current boot mode."""
-        with open(self.path) as f:
-            for line in f:
-                if self._line_sets_default_mode(line):
-                    return int(line.split(":")[1])
-    
-    def setMode(self, init_value):
-        """ Set the default boot mode to the new init_value.
-        Boot mode cannot be set to 0 or 6 because these values
-        will cause an endless boot loop."""
-        # avoid values 0 and 6
-        assert init_value not in (0, 6), "Default boot mode cannot be 0 or 6"
-        
-        newdata = []
-        with open(self.path) as fo:
-            for line in fo:
-                if self._line_sets_default_mode(line):
-                    line = "id:%s:initdefault:\n" % init_value
-                newdata.append(line)
-                
-        # write the changes to the file.
-        # DO NOT catch exceptions on this type of operations because
-        # we need to know what is going wrong (if anything)
-        fo = open(self.path, "w")
-        with fo as f:
-            f.writelines("".join(newdata))
-        fo.close()
-    
-    def _line_sets_default_mode(self, line):
-        """ Returns tru if line sets the default mode """
-        return line.startswith("id:") and "initdefault:" in line

src/vasm/backend/DATESET.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]
-
-
-"""Support module for the time/date setting vasm plugin
-
-"""
-
-
-from datetime import datetime
-import utils
-import logging
-import os
-
-log = logging.getLogger('vasm')
-
-class HWClock(object):
-    """ Interact with the hwclock """
-    def __init__(self, descriptor = "/etc/hardwareclock"):
-        self.descriptor = descriptor
-
-    def _line_sets_value(self, line):
-        """ Returns True if line is "localtime" or "UTC" """
-        return line.startswith("localtime") or line.startswith("UTC") \
-            or line.startswith('LocalTime') or line.startswith('LOCALTIME') \
-            or line.startswith("Localtime")
-
-    def get_value(self):
-        """ Read self.descriptor and return the current setting """
-        ret = ""
-        with open(self.descriptor) as f:
-            for line in f:
-                if self._line_sets_value(line):
-                    ret = line.strip()
-        # make sure we have a valid setting in there, otherwise, we wont be able
-        # to set the value later
-        assert ret != "", "Unable to get current hardware clock setting."
-        return ret
-
-    def set_value(self, value=""):
-        """ Save the provided value to /etc/hardwareclock """
-        # Raise exception if value is not valid
-        assert value in ("UTC",
-                         "LOCALTIME",
-            "utc",
-            "localtime",
-            "Utc",
-            "Localtime", 'LocalTime'), "Invalid hardware clock identifier"
-        newdata = []
-        with open(self.descriptor) as f:
-            for line in f:
-                if self._line_sets_value(line):
-                    line = "%s\n"% value
-                newdata.append(line)
-        f = open(self.descriptor, 'w')
-        f.writelines(''.join(newdata))
-        f.close()
-        
-class TimeZone(object):
-    """ Interact with the system timezone settings """
-    def __init__(self, zone=None):
-        self.zone = zone
-        self.tzlink = "/etc/localtime-copied-from"
-        self.timezones_base_dir = "/usr/share/zoneinfo/"
-
-    def get_zone(self):
-        """ Return a string representing the current timezone """
-        # To get the value, we must read /etc/localtime-copied-from.
-        # If this excepts, then no timezone is set.
-        if os.path.exists(self.tzlink):
-            tz = os.readlink(self.tzlink)
-            return tz.replace('/usr/share/zoneinfo/', '')
-        return 'US/Central'
-
-
-    def _remove_tz_link(self):
-        """ remove the symlink that sets the timezone """
-        if os.path.exists(self.tzlink):
-            return os.remove(self.tzlink)
-
-    def _check_faulty_rtcports(self):
-        """ Check /proc/ioports for unknown rtc ports """
-        # This comes from the old vasm scripts.
-        # Check for a broken motherboard rtc clock (where ioports for
-        # rtc are unknown) to prevent hwclock from causing a hang.
-        ret = True
-        proc = utils.get_popen(['cat', '/proc/ioports'])
-        output = proc.communicate()[0].split("\n")
-        for line in output:
-            if 'rtc' in line:
-                ret = False
-                break
-        return ret
-
-    def _activate_zone(self):
-        """ Active the selected zone """
-        if self._check_faulty_rtcports():
-            clock_opt = "--directisa"
-        else:
-            clock_opt = ""
-        ctype = HWClock().get_value().lower()
-        cm = ['/sbin/hwclock', clock_opt, '--%s'% ctype, '--hctosys']
-        proc = utils.get_popen(cm)
-        proc.communicate()
-        rval = proc.returncode
-        return rval > 0
-
-    def set_zone(self, zone=None):
-        """ Set the timezone to `zone` """
-        assert zone not in ("",None), "Empty values are not allowed for setting the time zone"
-        # first we remove the current setting
-        self._remove_tz_link()
-        
-        # we need to create a symlink to /usr/share/zoneinfo
-        src = os.path.join(self.timezones_base_dir, zone)
-        dest = self.tzlink
-        # We need to let this except
-        os.symlink(src, dest)
-        return self._activate_zone()
-
-    def list_zones(self):
-        """ Return a list of time zones to be presented in a UI """
-        lst = []
-
-        for zone in os.listdir(self.timezones_base_dir): # level 1
-            zonepath = os.path.join(self.timezones_base_dir, zone)
-            if os.path.isdir(zonepath): # level 2
-                for subzone in os.listdir(zonepath):
-                    subzonepath = os.path.join(zonepath, subzone)
-                    if os.path.isdir(subzonepath): # level 3
-                        for last in os.listdir(subzonepath):
-                            lastpath = os.path.join(subzonepath, last)
-                            if os.path.isdir(lastpath):
-                                for lastzone in os.listdir(lastpath):
-                                    lst.append("%s/%s/%s/%s"% ( zone, subzone, last, lastzone))
-                            else:
-                                lst.append("%s/%s/%s"% (zone,subzone,last))
-                    else:
-                        lst.append("%s/%s"% (zone,subzone))
-            else:
-                if not os.path.islink(zone) and '.' not in zone:
-                    lst.append(zone)
-        lst.sort()
-        return lst
-        
-
-
-class DateTime:
-    """Manage the system date and time.
-
-    """
-    def __init__(self, date_time=None):
-
-        if not date_time:
-            date_time = datetime.now()
-
-        self.year = date_time.year
-        self.month = date_time.month
-        self.day = date_time.day
-        self.hour = date_time.hour
-        self.minute = date_time.minute
-        self.second = date_time.second
-        self._date_time = date_time
-
-    def set_date(self):
-        """ Set the system date to the values specified.
-
-        """
-        if self.month < 10:
-            month = "0%s" % self.month
-        else:
-            month = self.month
-            
-        if self.day < 10:
-            day = "0%s" % self.day
-        else:
-            day = self.day
-            
-        datestr = "%s%s%s"% (self.year, month, day)
-        cmd = ["/bin/date", "+%Y%m%d", "-s", datestr]
-        proc = utils.get_popen(cmd)
-        out, err = proc.communicate()
-        rcode = proc.returncode
-
-        if rcode > 0:
-            _log = ("Command: %s said \"%s\""% (" ".join(cmd),
-                    err))
-            log.fatal("".join(_log))
-            raise DateTimeError(''.join(_log))
-        else:
-            log.debug("System date has been set to %s"% datestr)        
-
-    def set_time(self):
-        """ Set the system time to the specified value
-
-        """
-        timestr = "%s:%s:%s" % (self.hour, self.minute, self.second)
-        cmd = ["/bin/date", "+%T", "-s", timestr]
-        proc = utils.get_popen(cmd)
-        out, err = proc.communicate()
-        rcode = proc.returncode
-
-        if rcode > 0:
-            _log = ("Command: %s said \"%s\""% (" ".join(cmd), err))
-            log.fatal(_log)
-            raise DateTimeError(''.join(_log))
-        else:
-            log.debug("System time has been set to %s"% timestr)
-
-    def set_date_and_time(self):
-        """Set the system date and time.
-
-        """
-        self.set_date()
-        self.set_time()
-
-    def set_date_from_tuple(self, data):
-        """Update date attributes from a tuple. Convenience method for dealing
-        with UI widgets (gtk calendar returns a tuple, for example)
-        
-        """
-        self.year, self.month, self.day = data
-
-    def set_time_from_tuple(self, data):
-        """Update time attributes from a tuple. Convenience method for dealing
-        with UI widgets (gtk calendar returns a tuple, for example)
-        
-        """
-        self.hour, self.minute, self.second = data
-
-
-class DateTimeError(Exception):
-    """Raised when the system returns an error trying to set time or date
-
-    """
-    pass

src/vasm/backend/FSTAB.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]
-
-"""FSTAB.py
-Provides a data model for working with /etc/fstab."""
-
-import parted
-import os
-import utils
-
-def list_all_system_partitions():
-    """ return a list of all partition paths"""
-    partitions = []
-    for dev in parted.getAllDevices():
-        if not dev.readOnly and dev.getSize() > 0.0:
-           dsk = parted.Disk(dev)
-           for part in dsk.partitions:
-               # extended partitions are type 2 and have no fs
-               if part.type != 2:
-                   partitions.append(part.path)
-    return partitions
-
-def list_all_system_drives():
-    """ Return a list of all device drive paths """
-    drives = [dev.path for dev in parted.getAllDevices() if not dev.readOnly and dev.getSize() > 0.0]
-    return drives
-
-class FstabEntry(object):
-    """ Object representing an entry in /etc/fstab """
-    def __init__(self, device = None):
-        self.device = device
-        self.uuid = None
-        self.mountpoint = None
-        self.filesystem = None
-        self.options = None
-        self._mount_now = True
-    
-    def find_default_mountpoint(self):
-        assert self.device is not None, "device path must be set first."
-        assert self.filesystem is not None, "Unknown filesystem.  Set filesystem property first."
-        ret = None
-        if 'swap' in self.filesystem:
-            ret = 'swap'
-        else:
-            ret = self.device.replace('/dev/','/mnt/')
-        return ret
-
-    def find_default_options(self):
-        """ Returns the default fstab options for the partitions filesystem """
-        assert self.filesystem is not None, "Unknown filesystem."
-        opts = {
-            "ext2":"defaults 0 0",
-            "ext3":"defaults 0 0",
-            "ext4":"defaults 0 0",
-            "iso9660":"noauto,ro,user 0 0",
-            "msdos":"defaults 0 0",
-            "swap":"sw 0 0",
-            "linux-swap":"sw 0 0",
-            "linux-swap(v1)":"sw 0 0"
-        }
-        if opts.has_key(self.filesystem):
-            return opts[self.filesystem]
-        elif 'swap' in self.filesystem:
-            return opts['swap']
-        else:
-            return 'defaults 0 0'
-
-    def find_uuid(self):
-        """ Find the uuid for the specified device """
-        assert self.device is not None, "You must specify a device node first."
-        #assert "/" not in self.device, "Invalid device node."
-        uuiddir = "/dev/disk/by-uuid"
-        partition = os.path.split(self.device)[-1]
-        for entry in os.listdir(uuiddir):
-            lname = os.readlink(os.path.join(uuiddir, entry))
-            if lname.endswith(partition):
-                return entry
-        return None
-
-    def find_path(self):
-        """ Find the partition path.  This is useful if fstab provides UUID but not path """
-        assert self.uuid is not None, "Cannot find path if uuid is not known"
-        uuiddir = "/dev/disk/by-uuid"
-        for uid in os.listdir(uuiddir):
-            if uid == self.uuid:
-                lname = os.readlink(os.path.join(uuiddir, uid))
-                return os.path.join("/dev/", lname.split("/")[-1])
-        return None
-
-    def _activate_swap(self):
-        """ Activate a swap partition after it has been added """
-        return utils.activate_swap(self.device)
-
-    def mount(self):
-        """ Mount this entry to its mountpoint """
-        assert self.device not in ("",None), "No partition has been specified.  Cannot mount"
-        assert self.mountpoint not in ("",None), "No mountpoint has been specified for this partition."
-        assert self.options not in ("",None), "No mounting options specified"
-        assert self.filesystem not in ("",None), "No filesystem specified"
-        # We want to catch this exception, because the partition may already 
-        # be mounted.
-        if "swap" in self.filesystem:
-            try:
-                self._activate_swap()
-                return
-            except:
-                pass
-        try:
-            utils.mount(self.device, self.mountpoint)
-        except:
-            pass
-        return
-        
-    def find_filesystem(self):
-        """ Find the partition's filesystem as reported by parted """
-        assert self.device is not None, "You must specify a device node first."
-        devicename = self.device[:len("/dev/sda")]
-        pdev = parted.Device(devicename)
-        pdisk = parted.Disk(pdev)
-        ppart = [p for p in pdisk.partitions if p.path == self.device ][0]
-        if "swap" in ppart._fileSystem.type:
-            ret = "swap"
-        else:
-            ret = ppart._fileSystem.type
-
-        return ret
-
-class FstabModel(object):
-    """ Data model for working with /etc/fstab """
-    def __init__(self, dataobject = '/etc/fstab'):
-        self.observers = []
-        self.dataobject = dataobject
-    
-    def notify(self):
-        """ Notify all observers that there have been changes """
-        for f in self.observers:
-            f()
-    
-    def add_observer(self, method):
-        """ Add an observer to the model"""
-        self.observers.append(method)
-        return
-
-    def removeEntry(self, device_path=""):
-        """ Remove the fstab entry with the device_path. """
-        assert device_path not in ("", None), "Invalid device path"
-        assert self.hasEntry(device_path), "%s is not listed in %s"% (device_path, self.dataobject)
-        ndata = []
-        with open(self.dataobject) as data:
-            for line in data:
-                if len(line.strip()) == 0:
-                    continue
-                if not line.startswith("#"):
-                    entry = self.get_entry_from_line(line)
-                    if entry.device == device_path:
-                        continue
-                ndata.append(line)
-        f = open(self.dataobject, 'w')
-        f.writelines(''.join(ndata))
-        f.close()
-        return self.notify()
-
-    def addEntry(self, entry):
-        """ Add a new entry to fstab.
-        Arguments:
-            entry - An FstabEntry() object """
-        assert isinstance(entry, FstabEntry), "entry argument is of invalid type"
-        assert hasattr(entry, 'mountpoint'), "Missing mountpoint attribute."
-        sep = " "*4
-        if entry.uuid is None:
-            entry.uuid = entry.find_uuid()
-        if entry.filesystem is None:
-            entry.filesyatem = entry.find_filesystem()
-        # Use UUID when possible
-        if entry.uuid is None:
-            part = entry.device
-        else:
-            part = "UUID=%s"% entry.uuid
-
-        if entry.options is None:
-            options = entry.find_default_options()
-        else:
-            options = entry.options
-        data = []
-        with open(self.dataobject) as f:
-            for line in f:
-                data.append(line)
-        line = sep.join((
-            part,
-            entry.mountpoint,
-            entry.filesystem,
-            options
-            ))
-        data.append(line + "\n")
-        f = open(self.dataobject, 'w')
-        f.writelines(''.join(data))
-        f.close()
-        return self.notify()
-
-    def listEntries(self):
-        """ Return a list of FstabEntry objects representing each entry in fstab """
-        ret = []
-        sep = " "*4
-        with open(self.dataobject) as f:
-            for line in f:
-                if not line.strip():
-                    continue
-                if line.startswith("#"):
-                    continue
-                entry = self.get_entry_from_line(line)
-                ret.append(entry)
-        return ret
-
-    def getEntry(self, device_path=""):
-        """ Get an entry object for an existing fstab entry."""
-        assert device_path not in ('', None), \
-            "You must specify a device path to get the existing entry object."
-        for item in self.listEntries():
-            if item.device == device_path:
-                return item
-        return None
-
-    def get_entry_from_line(self, line):
-        """ Create a valid entry from the provide line """
-        sp = line.split()
-        sep = " "*4
-        entry = FstabEntry()
-        dev = sp[0].strip()
-        if dev.startswith("UUID="):
-            entry.uuid = dev.split("=")[-1].strip()
-            entry.device = entry.find_path()
-        else:
-            entry.device = dev.strip()
-            entry.uuid = entry.find_uuid()
-        entry.mountpoint = sp[1].strip()
-        entry.filesystem = sp[2].strip()
-        entry.options = sep.join(sp[3::]).strip()
-
-        return entry
-
-    def hasEntry(self, device_path=""):
-        """ Check if fstab has an entry for device_path """
-        assert device_path not in ("",None), "Invalid device path"
-        entries = self.listEntries()
-        for item in entries:
-            if item.device == device_path:
-                return True
-
-        return False

src/vasm/backend/GDMHELPER.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/>.
-
-
-import gdmconfigparser
-import os
-import logging
-
-__author__ = "Moises Henriquez"
-__author_email__ = "moc.liamg@xnl.E0M"[::-1]
-
-log = logging.getLogger('vasm')
-
-class SettingsModel(object):
-    """ Model to work with the gdm settings """
-    def __init__(self, tmpfile = '/tmp/gdmsettings', settingspath = '/etc/gdm/custom.conf'):
-        self.settingspath = settingspath
-        self._tmpfile = tmpfile
-        self.config = gdmconfigparser.ConfigHandler()
-        self.config.read(self.settingspath)
-
-    def get_current_autologin_setting(self):
-        """ Returns 'true' or 'false' """
-        if self.config.has_option('daemon', 'AutomaticLoginEnable'):
-            return self.config.get('daemon', 'AutomaticLoginEnable')
-        return 'false'
-    
-    def get_current_autologin_user(self):
-        """ return the value of the current autologin user.
-        
-        Returns None if nothing is available."""
-        if self.config.has_option('daemon', 'AutomaticLogin'):
-            return self.config.get('daemon', 'AutomaticLogin')
-        return None
-    
-    def _save_to_file(self):
-        """ Write the changes to the file """
-        # start by saving the options on the tempfile first. This is because
-        # Our helper module ignores all comments on the file, and we want to keep those
-        # in there. They're really helpful.
-        f = open(self.settingspath, 'r')
-        data = f.readlines()
-        f.close()
-        for key in ('AutomaticLoginEnable', 'AutomaticLogin'):
-            i = 0
-            for line in data:
-                if self._line_sets_setting(line, key):
-                    value = self.config.get('daemon', key)
-                    nline = "%s=%s\n"% (key, value)
-                    data[i] = nline
-                i += 1
-        f = open(self.settingspath, 'w')
-        f.writelines(''.join(data))
-        f.close()
-        return
-
-    def _line_sets_setting(self, line, setting):
-        """ Returns True if line sets setting"""
-        if "=" not in line:
-            return False
-        key, value = line.split('=')
-        return key.lower().strip() == setting.lower().strip()
-    
-    def save_settings(self, alsetting='false', aluser=''):
-        """ save the settings to the configuration (not yet written to file) """
-        self.config.set('daemon', 'AutomaticLoginEnable', alsetting)
-        self.config.set('daemon', 'AutomaticLogin', aluser)
-        f = open(self._tmpfile, 'w')
-        f.writelines([alsetting,'\n', aluser])
-        f.close()
-        return self._save_to_file()
-
-         
-        

src/vasm/backend/LOGINMANAGERS.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/>.
-
-
-import os
-import logging
-
-__author__ = "Moises Henriquez"
-__author_email__ = "moc.liamg@xnl.E0M"[::-1]
-
-log = logging.getLogger('vasm')
-
-class LoginManagers(object):
-    """ Methods for working with login managers """
-    def __init__(self, specfile = "/etc/rc.d/rc.X"):
-        self.specfile = specfile
-
-    def _describe_manager(self, manager):
-        """ Provide some descriptive text about the provided login manager """
-        managers = {
-            "gdm": "Gnome Login Manager.",
-            "kdm" : "KDE Login Manager.",
-            "lxdm": "LXDE login manager.",
-            "slim": "SLIM login manager.  Themeable and lightweight.",
-            "xdm" : "XLogin manager.  Simple, light weight.",
-            "wdm" : "WINGs display manager.  Ultra light weight."
-        }
-        return managers[manager] or manager
-
-    def list_existing(self):
-        ret = []
-        managers = {
-            "KDM": ("/usr/bin/kdm", "/usr/sbin/kdm", "/opt/kde/bin/kdm"),
-            "GDM": ("/usr/bin/gdm", "/usr/sbin/gdm", "/opt/gnome2/bin/gdm"),
-            "XDM": ("/usr/bin/xdm", "/usr/sbin/xdm", "/usr/X11R6/xdm"),
-            "WDM": ("/usr/bin/wdm", "/usr/sbin/wdm", "/usr/X11R6/wdm")
-            }
-        for _bin in managers.keys():
-            paths = managers[_bin]
-            for path in paths:
-                if os.path.exists(path):
-                    if not _bin in ret:
-                        ret.append(_bin)
-        return ret
-
-    def get_current(self):
-        """ return the current login manager """
-        f = open(self.specfile, "r")
-        data = f.readlines()
-        f.close()
-        for line in data:
-            if line.startswith("DISPLAY_MANAGER="):
-                return line.replace("DISPLAY_MANAGER=","").strip()
-        return None
-    
-    def _line_sets_manager(self, line):
-        """ Return true if line sets the login manager """
-        return line.startswith("DISPLAY_MANAGER=")
-
-    def set_manager(self, manager=None):
-        """ Set the login manager to the value provided in manager 
-        Will raise an exception if we cannot write to the file."""
-        assert manager is not None, "Invalid login manager specified"
-        f = open(self.specfile, "r")
-        data = f.readlines()
-        f.close()
-        newdata = []
-        
-        for line in data:
-            if self._line_sets_manager(line):
-                line = "DISPLAY_MANAGER=%s\n"% manager.upper()
-            newdata.append(line)
-        # Write the changes to the system.
-        f = open(self.specfile, 'w')
-        f.writelines(newdata)
-        f.close()
-        return
-

src/vasm/backend/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/>.
-
-#   Thanks to Jason Pierce (rxMokka) for the research that went into this.
-
-__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. """
-import netinfo
-import os
-import logging
-import shutil
-from utils import get_popen
-import SERVICES
-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.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. 
-    Arguments:
-        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, sessionscript = None):
-        self.name = name
-        self.bin_path = bin_path
-        self.init_script = init_script
-        self.service_script = service_script
-        self.sessionscript = sessionscript
-        
-        self.enabled_autostart = '/etc/xdg/autostart'
-        self.disabled_autostart = '/etc/xdg/autostart-disabled'
-        self.sessionfile = os.path.split(self.sessionscript)[-1]
-    
-    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 """
-        self.enable_session_script()
-        return self._run_command(['chmod','+x', self.init_stript])
-    
-    def disable(self):
-        """ Make the init_script not executable """
-        self.disable_session_script()
-        return self._run_command(['chmod', '-x', self.init_stript])
-    
-    def enable_session_script(self):
-        """ Enable the session startup script.  This will allow the desktop
-            to automatically start this daemons panel applets."""
-        dpath = os.path.join(self.disabled_autostart, self.sessionfile)
-        epath = os.path.join(self.enabled_autostart, self.sessionfile)
-        if os.path.exists(dpath):
-            shutil.move(dpath, epath)
-        return
-    
-    def disable_session_script(self):
-        """ Disable the session startup scripts.  This will avoid the desktop
-            showing error messages about not being able to connect to this
-            daemons backend."""
-        # Make sure the disabled dir exists
-        if not os.path.isdir(self.disabled_autostart):
-            os.makedirs(self.disabled_autostart)
-        dpath = os.path.join(self.disabled_autostart, self.sessionfile)
-        epath = os.path.join(self.enabled_autostart, self.sessionfile)
-        if os.path.exists(epath):
-            return shutil.move(epath, dpath)
-        return
-    
-    def check_status(self):
-        """ Return the status of the daemon. 
-        True = Daemon is enabled.
-        False = Daemon is disabled."""
-        if self._get_rcfile_status() or \
-            os.path.exists(os.path.join(self.enabled_autostart, self.sessionfile)):
-            return True
-        return False
-    
-    def _get_rcfile_status(self):
-        """ Returns True if self.init_script is executable.  False otherwise """
-        return os.access(self.init_script, os.X_OK)
-    
-    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)        
-        return
-    
-    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)
-        return
-
-class Nic(object):
-    """ Class representing a network interface. 
-    By using this class, we can access information about the network
-    
-    Arguments:
-        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 = '127.0.0.1',
-            netmask = '255.255.255.0',
-            bcast = '',
-            macaddr = None,
-            scripts_loc = '/etc/rc.d'):
-        self.devname = devname
-        self.ip_addr = ip_addr
-        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):
-            initpath = os.path.join(self.scripts_location,
-                'rc.inet%s'% x)
-            if not os.path.exists(initpath):
-                return initpath
-        # Should never return None unless the box has a ridiculous
-        # number of network adaptors.
-        return None
-    
-    def findConfig(self):
-        """ Locate the configuration file that configures this adaptor"""
-        for file in os.listdir(self.scripts_location):
-            if file.startswith('rc.inet') and \
-                '.conf' not in file and not file.endswith('.new'):
-                fpath = os.path.join(self.scripts_location, file)
-                #file.endswith('.conf') or file.endswith('.new'):
-                #fpath = os.path.join(self.scripts_location, file)
-                with open(fpath) as data:
-                    for line in data:
-                        if self.devname in line:
-                            return fpath
-        return self._get_next_available_config_file()
-    
-    def enable(self):
-        """ Enable this nic so it can be brought up automatically on boot """
-        return self.inet.enable()
-    
-    def disable(self):
-        """ Keep this nic from being brought up on boot """
-        return self.inet.disable()
-    
-    def check_status(self):
-        """ Check wether this Nic is being loaded @ startup """
-        return self.inet.check_status()
-
-class Inet(object):
-    """ Class used to represend an rc.inet configuration file
-        in a vectorlinux system.
-        Arguments:
-            fpath    -   Absolute path to the file we are working with
-            nmethod  -   Networking method. Must be one of DHCP or STATIC
-    
-    DO NOT USE THIS CLASS DIRECTLY.
-    Each Nic object gets an object of this class. It can be accessed
-    as the .inet attribute of the Nic object.
-    """
-    def __init__(self, fpath=None, nmethod=DHCP, nic=None):
-        self.fpath = fpath
-        self.nmethod = nmethod
-        self.nic = nic
-        try:
-            self.config = self._read_config_data()
-        except:
-            self.config = self._generate_new_config_data()
-    
-    def _run_command(self, cmd):
-        proc = get_popen(cmd)
-        stdout, stderr = proc.communicate()
-        code = proc.returncode
-        assert code == 0, stderr.strip()
-    
-    def enable(self):
-        """ Enable this inet by setting it's config file executable """
-        # First check to make sure the file exists
-        assert os.path.exists(self.fpath), \
-            "No such file %s in the system.  " % self.fpath + \
-            "  Has the configuration been saved yet?"
-        return self._run_command(['chmod', '+x', self.fpath])
-    
-    def disable(self):
-        """ Disable this inet by etting it's config file NOT executable """
-        assert os.path.exists(self.fpath), \
-            "No such file %s in the system."% self.fpath
-        return self._run_command(['chmod', '-x', self.fpath])
-    
-    def check_status(self):
-        """ Return True if inet is enabled.  False otherwise """
-        assert os.path.exists(self.fpath), \
-            "No such file %s in the system.  Cannot check its status"% self.fpath
-        return os.access(self.fpath, os.X_OK)
-
-    def _generate_new_config_data(self):
-        """ Generates new data for a config file.  Only
-        the config dictionary is generated here.  The header comments
-        and the script call are generated later. """
-        if self.nmethod is DHCP:
-            dhcpval = 'yes'
-        else:
-            dhcpval = 'no'
-        ret = {
-            'DEVICE':self.nic.devname,
-            'DHCP': dhcpval,
-            'IPADDR': '127.0.0.1',
-            'NETMASK': '255.255.255.0',
-            'GATEWAY': '',
-            'PROBE':'no'}
-        return ret
-    
-    def _generate_complete_config_file(self):
-        """ Returns a list with the data necessary to
-            write a complete new config file to the sysetem """
-        HEADER = [
-            "#!/bin/sh",
-            "# This file is created by vasm",
-            "# Avoid modifying it by hand.",
-            "# ",
-            "##################################",
-            "## The Settings. ",
-            ]
-        FOOTER = [
-            "# ",
-            "##################################",
-            "# ## The Script ## ",
-            "# Source the standard networking script.",
-            ". /etc/rc.d/functions-network \"$@\"","#",]
-        COMPLETE = []
-        # Add the header comments.
-        COMPLETE.extend(HEADER)
-        # Add the important data 
-        for comp in self.config:
-            _line = "%s='%s'"% (comp, self.config[comp])
-            COMPLETE.append(_line)
-        # Add the footer
-        COMPLETE.extend(FOOTER)
-        return COMPLETE
-
-    def _read_config_data(self):
-        """ Return a dictionary with the different options on
-            the config file. """
-        assert os.path.exists(self.fpath), \
-            "No such file %s.  %s represents a NEW unsaved rc.inet config file" % (
-                self.fpath, self.fpath)
-        ret = {}
-        with open(self.fpath) as data:
-            for line in data:
-                if self._line_sets_value(line):
-                    key, value = self._get_line_key_value(line)
-                    ret[key] = value
-        return ret
-    
-    def save_config(self):
-        """ Write the cofiguration to the filesystem.
-            Call this method after the differnt settings have
-            been modified """
-        # If the file doesn't exist, then we must write a new one
-        if not os.path.exists(self.fpath):
-            data = self._generate_complete_config_file()
-            f = open(self.fpath, 'w')
-            f.writelines('\n'.join(data))
-            f.close()
-            return
-        # The file already exists in the filesytem.  We must
-        # update it.
-        return self._do_write_changes()
-        
-    def _do_write_changes(self):
-        """ Only update the configuration data.  Leave the
-            file's comments alone """
-        ndata = []
-        with open(self.fpath) as data:
-            for line in data:
-                if self._line_sets_value(line):
-                    key, val = self._get_line_key_value(line)
-                    line = "%s='%s'"% (key, self.config[key])
-                ndata.append(line.strip())
-        # write the modified data to the filesystem
-        f = open(self.fpath, 'w')
-        f.writelines('\n'.join(ndata))
-        f.close()
-        return
-
-    def _line_sets_value(self, line):
-        """ Returns True if line sets a value.  False otherwise """
-        return "=" in line
-    
-    def _get_line_key_value(self, line):
-        """ Returns a tuple of (key, value) set by line """
-        key, val = line.split('=')
-        val = val.strip().replace("\'","").replace("\"","").strip()
-        return key, val
-
-class NetConfModel(object):
-    """ Global networking model. """
-    def __init__(self, host_file='/etc/HOSTNAME',
-        dns_file='/etc/resolve.conf',
-        hostname=None):
-        self.host_file = host_file
-        self.dns_file = dns_file
-        self.hostname = hostname
-    
-    def set_hostname(self):
-        """ Set the machine hostname to the value specified in self.hostname"""
-        assert self.hostname not in ('',None), \
-            "Empty hostname is not accepted.  Please set the .hostname attribute first"
-        f = open(self.host_file, 'w')
-        f.writelines("\n".join([self.hostname,]))
-        f.close()
-    
-    def get_hostname(self):
-        """ read the hostname from the file """
-        f = open(self.host_file, 'r')
-        data = f.readline()
-        f.close
-        return data.strip()
-
-    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',
-                '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,
-                'sessionscript' : '/etc/xdg/autostart/wicd-tray.desktop'}}
-        for netapp in DAEMONS:
-            if os.path.exists(DAEMONS[netapp]['path']):
-                ndaemon = NDaemon(
-                    name = DAEMONS[netapp]['name'],
-                    bin_path = DAEMONS[netapp]['path'],
-                    init_script = DAEMONS[netapp]['initscript'],
-                    service_script = DAEMONS[netapp]['service'],
-                    sessionscript = DAEMONS[netapp]['sessionscript'])
-                ret.append(ndaemon)
-        return ret
-    
-    def hasDaemon(self, daemon_name):
-        """ Check if the system has daemon_name available """
-        options = self.listNetworkingDaemons()
-        for item in options:
-            if item.name == daemon:
-                return True
-        return False
-    
-    def useDaemon(self, daemon):
-        """ Configure the system to use the specified networking daemon """
-        assert self.hasDaemon(daemon) is True, \
-            "The %s daemon is not available on this system."% daemon
-        # FIXME: Do we want to disable the manual setup? ie, run nic.disable()
-        #       on all of the system's adaptors?
-        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 useManualSetup(self, nic):
-        """ Do not use daemon for networking, but rather automatically 
-        bring up an interface as configured. """
-        # Turn off all daemons
-        for program in self.listNetworkingDaemons():
-            program.disable()
-        # Disable all interfaces except for the one specified
-        for iface in self.listNetworkAddapters():
-            if iface != nic:
-                iface.disable()        
-        return
-    
-    def useNoNetworking(self):
-        """ Disable all kinds of automatic networking configuration """
-        # Disable all kinds of automatic network configuration.
-        # Disable daemons
-        for program in self.listNetworkingDaemons():
-            program.disable()
-        # Disable adaptors
-        for _nic in self.listNetworkAddapters():
-            _nic.disable()
-        return
-
-    def listNetworkAdapters(self):
-        """ Return a list of Nic objects """
-        ret = []
-        for nic in netinfo.list_devs():
-            if nic == 'lo':
-                continue
-            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,
-                macaddr = macaddr,
-                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

src/vasm/backend/PASSWORDS.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/>.
-
-
-import pexpect
-from exceptions import Exception
-import os
-import crypt
-from utils import get_popen
-import logging
-
-log = logging.getLogger('vasm')
-
-__author__ = "Moises Henriquez"
-__author_email__ = "moc.liamg@xnl.E0M"[::-1]
-
-class BadPasswordException(Exception):
-    pass
-class BadNewPasswordException(Exception):
-    pass
-class UserModError(Exception):
-    pass
-
-def test_passwords_match(pass1, pass2):
-    """ Check if both passwords are the same """
-    return pass1 == pass2
-
-def test_password_length(passw):
-    """ Check if passw is suitable for system password """
-    return len(passw) >= 6    
-
-def change_password(user, oldpassword, newpassword):
-    """Proxy to decide how to change the user password.
-    If root is changing someone's password, tehre is no need to user pexpect"""
-    if os.geteuid() == 0:
-        # root can do anything !
-        if user == "own":
-            user = "root"
-        return change_password_usermod(user, newpassword)
-    else:
-        # Non-privileged accounts are not allowed to use usermod.
-        return change_password_pexpect(user, oldpassword, newpassword)    
-
-def change_password_usermod(login, password):
-    """ change the user password using usermod"""
-    salt = password[0] + password[-1]
-    epass = crypt.crypt(password, salt)
-    proc = get_popen(
-        ['/usr/sbin/usermod','-p', epass, login]
-        )
-    out, err = proc.communicate()
-    retv = proc.returncode
-    if retv > 0:
-        raise UserModError(err)
-    return
-    
-def change_password_pexpect(user, oldpassword, newpassword):
-    """ Change user password using pexpect
-    
-    The process is spawned via pexpect.
-    Returns:
-        0 = Success
-        raises exceptions when unsuccessful:
-            BadPasswordException
-    """
-    child = pexpect.spawn('/usr/bin/passwd')
-    i = child.expect('password: ')
-    child.sendline(oldpassword)
-    i = child.expect(["New password: ", pexpect.EOF])
-    if i == 0:
-        child.send("%s\n"%newpassword)
-        ii = child.expect(["-enter new password: ", "New password: "])
-        if ii == 0:
-            child.send("%s\n"% newpassword)
-            iii = child.expect([pexpect.EOF])
-            if iii == 0:
-                return 0
-        else:
-            #print "Bad new password", child.before
-            #return 2
-            msg = ("Unable to change password for user %s."% user,
-                "New password does not meet minimum requirements.")
-            log.error(" ".join(msg))
-            raise BadNewPasswordException("The provided password does not meet minimum requirements")
-    else:
-        msg = ("Unable to change password for user %s"% user,
-            " ", "The user failed to provide a correct current password.")
-        log.error(" ".join(msg))
-        raise BadPasswordException("Provided old password is wrong")
-        #print "Bad old passowrd"
-    log.debug("Password for user %s was successfully changed."% user)
-    return 0

src/vasm/backend/REPOS.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 shutil
-from string import capwords
-import logging
-
-log = logging.getLogger('vasm')
-
-""" REPOS.py
-provides methods for inteacting with /etc/slapt-get/slapt-getrc"""
-
-class SlaptgetRcModel(object):
-    """ data model for working with a slapt-getrc file """
-    def __init__(self, filepath="/etc/slapt-get/slapt-getrc"):
-        self.filepath = filepath
-        self.observers = []
-    
-    def add_observer(self, method):
-        """ Add an observer to the notification list """
-        self.observers.append(method)
-        return
-
-    def notify(self):
-        for method in self.observers:
-            method()
-    
-    def save_changes(self, changedlist):
-        """Save the changes to the actual file.
-        Arguments:
-            changedlist = a list of tuples indicating the following
-                (True, repo, priority)
-                where True means Enabled and False means Disabled.
-                
-        Returns False when successful.
-        """
-        newdata = []
-        f = open(self.filepath, "r")
-        fdata = f.readlines()
-        f.close()
-        for line in fdata:
-            if line.startswith("EXCLUDE=") or line.startswith("WORKINGDIR"):
-                newdata.append(line)
-            else:
-                continue
-        for entry in changedlist:
-            status = entry[0]
-            url = entry[1]
-            priority = entry[2]
-            if status == True:
-                state = "SOURCE"
-            else:
-                state = "#DISABLED"
-            if priority == "Default":
-                priotext = ""
-            else:
-                priotext = ":%s"% priority.upper()
-            line = "%s=%s%s\n"% (state, url, priotext)
-            newdata.append(line)
-            
-        # save a copy of the old file
-        shutil.copy(self.filepath, "%s.bak"%self.filepath)
-        # Write to the disk, DO NOT catch this exception
-        f = open(self.filepath, 'w')
-        f.writelines(''.join(newdata))
-        f.close()
-    
-    def get_current_active_repos(self):
-        """ Returns the list of currently active repos """
-        ret = []
-        f = open(self.filepath, "r")
-        data = f.readlines()
-        f.close()
-        for line in data:
-            if line.startswith("SOURCE="):
-                content = line.split("=")[-1]
-                if content.count(":") > 1:
-                    url = content.rsplit(":", 1)[0].strip()
-                    pri = capwords(content.rsplit(':',1)[-1])
-                else:
-                    url = content.strip()
-                    pri = "Default"
-                ret.append((url, pri))
-        return ret
-
-    def get_current_disabled_repos(self):
-        """ Returns a list of disabled repos """
-        ret = []
-        f = open(self.filepath, "r")
-        data = f.readlines()