Commit 98b53f6a authored by Seblu's avatar Seblu
Browse files

New configuration style

parent 1700b532
Loading
Loading
Loading
Loading
+14 −13
Original line number Diff line number Diff line
@@ -49,7 +49,8 @@ def build(args):

# Top level argument parsing
p_main = argparse.ArgumentParser()
p_main.add_argument("-V", "--version", action="version", version=installsystems.version,
p_main.add_argument("-V", "--version", action = "version",
                    version = installsystems.version,
                    help="show installsystems version")
p_main.add_argument('-d', "--debug", action = ISAction, nargs = 0,
                    help="active debug mode")
@@ -68,7 +69,7 @@ p_build.add_argument('-f', "--force", action="store_true", dest="force", default
p_build.add_argument('-c', "--no-check", action = "store_false", dest = "check", default = True,
                     help = "do not check compilation before adding scripts")

p_build.add_argument("path", nargs="?", type=str, default=".")
p_build.add_argument("path", nargs = "?", default = ".")
p_build.set_defaults(func = build)
# Parse and run
args = p_main.parse_args()
+33 −27
Original line number Diff line number Diff line
@@ -15,10 +15,12 @@ import installsystems.argparse as argparse # To remove when default to python 2.
from installsystems.printer import *
from installsystems.repository import RepositoryManager, RepositoryConfig
from installsystems.image import PackageImage
from installsystems.config import ConfigFile
from installsystems.config import MainConfigFile, RepoConfigFile

class ISAction(argparse.Action):
    '''Set installsystems quiet/debug mode. Argparse callback'''
    '''
    Set installsystems quiet/debug mode. Argparse callback
    '''
    def __call__(self, parser, namespace, values, option_string=None):
        if option_string in ("-q", "--quiet"):
            installsystems.debug = False
@@ -28,7 +30,8 @@ class ISAction(argparse.Action):

# Argument parsing loading
p_main = argparse.ArgumentParser()
p_main.add_argument("-V", "--version", action="version", version=installsystems.version,
p_main.add_argument("-V", "--version", action = "version",
                    version = installsystems.version,
                    help = "show installsystems version")
p_main.add_argument('-d', "--debug", action = ISAction, nargs = 0,
                    help = "active debug mode")
@@ -36,21 +39,23 @@ p_main.add_argument('-q', "--quiet", action=ISAction, nargs=0,
                    help = "active quiet mode")
p_main.add_argument("--no-cache", action = "store_false", default = False,
                    help = "Not use persistent db caching")
p_main.add_argument("-c", "--config", dest="config", type=str, default=None,
p_main.add_argument("-c", "--config", dest = "config", default = "isinstall",
                    help = "config file path")
p_main.add_argument("-v", "--image-version", dest="image_version", type=int, default=None,
p_main.add_argument("-v", "--image-version", type = int, default = None,
                    help = "image version")
p_main.add_argument("-t", "--timeout", dest = "timeout", type = int, default = None,
                    help = "download timeout")
p_main.add_argument("-r", "--repo", dest="repos", action="append", default=[],
                    help="repository (can be specified more than one time)")
p_main.add_argument("image_name", type=str,
                    help="image to install (path or name)")
p_main.add_argument("-r", "--repo-path", action = "append", default = [],
                    help = "repository path")
p_main.add_argument("-R", "--repo-config", action = "append", default = ["repository"],
                    help = "repository config path (can be specified more than one time)")
p_main.add_argument("image_name", help = "image to install (path or name)")

try:
    # Partial parse
    args = p_main.parse_known_args()[0]
    # load config
    config = ConfigFile("isinstall", args.config)
    # load main config
    config = MainConfigFile(args.config)
    # looks if arguments is a file or image name
    if istools.pathtype(args.image_name) == "file" and os.path.isfile(args.image_name):
        pkg = PackageImage(istools.abspath(args.image_name))
@@ -60,12 +65,13 @@ try:
            config.cache = None
        # init repo cache object
        repoman = RepositoryManager(config.cache, timeout=args.timeout)
        # register config repositories
        for crepo in config.repos:
            repoman.register(crepo)
        # register command line repositories
        for rpath in args.repos:
        # register command line repositories (order matter)
        for rpath in args.repo_path:
            repoman.register(RepositoryConfig(None, path=rpath))
        # register config repositories
        for r_config in args.repo_config:
            for r_repo in RepoConfigFile(r_config).repos:
                repoman.register(r_repo)
        # get image package
        pkg = repoman.get(args.image_name, args.image_version)
    else:
+41 −26
Original line number Diff line number Diff line
@@ -8,14 +8,16 @@ InstallSystems Repository Manipulation Tool

import os
import installsystems
import installsystems.argparse as argparse # To remove when default to python 2.7
import installsystems.argparse as argparse # To Remove when python 2.7
from installsystems.printer import *
from installsystems.repository import Repository, RepositoryConfig
from installsystems.image import PackageImage
from installsystems.config import ConfigFile
from installsystems.config import MainConfigFile, RepoConfigFile

class ISAction(argparse.Action):
    '''Set installsystems quiet/debug mode. Argparse callback'''
    '''
    Set installsystems quiet/debug mode. Argparse callback
    '''
    def __call__(self, parser, namespace, values, option_string=None):
        if option_string in ("-q", "--quiet"):
            installsystems.quiet = True
@@ -24,7 +26,9 @@ class ISAction(argparse.Action):


def init(args):
    '''Create an empty fresh repo tree'''
    '''
    Create an empty fresh repo tree
    '''
    # call init from library
    try:
        Repository.create(args.repository)
@@ -32,7 +36,9 @@ def init(args):
        raise Exception("init failed: %s" % e)

def add(args):
    '''Add a package to repository'''
    '''
    Add a package to repository
    '''
    try:
        repo = Repository(args.repository)
        pkg = PackageImage(args.path)
@@ -41,7 +47,9 @@ def add(args):
        raise Exception("add failed: %s" % e)

def delete(args):
    '''Remove a package from repository'''
    '''
    Remove a package from repository
    '''
    try:
        repo = Repository(args.repository)
        repo.delete(args.image_name, args.image_version)
@@ -50,23 +58,27 @@ def delete(args):

# Top level argument parsing
p_main = argparse.ArgumentParser()
p_main.add_argument("-V", "--version", action="version", version=installsystems.version,
p_main.add_argument("-V", "--version", action = "version",
                    version = installsystems.version,
                    help = "show installsystems version")
p_main.add_argument('-d', "--debug", action = ISAction, nargs = 0,
                    help = "active debug mode")
p_main.add_argument('-q', "--quiet", action = ISAction, nargs = 0,
                    help = "active quiet mode")
p_main.add_argument("-c", "--config", dest="config", type=str, default=None,
p_main.add_argument("-c", "--config", default = "isrepo",
                    help = "config file path")
p_main.add_argument("-r", "--repo-name", dest="repo_name", type=str, default=None,
                    help="repository name in config file")
p_main.add_argument("-r", "--repo-name", default = None,
                    help = "select repository by name in config files")
p_main.add_argument("-R", "--repo-config", action = "append",
                    default = ["repository"],
                    help = "repository config (can be specified more than one time)")
subparsers = p_main.add_subparsers()
# Init command parser
p_init = subparsers.add_parser("init", help = init.__doc__.lower())
p_init.set_defaults(func = init)
# Add command parser
p_add =  subparsers.add_parser("add", help = add.__doc__.lower())
p_add.add_argument("path", type=str)
p_add.add_argument("path")
p_add.set_defaults(func = add)
# Del command parser
#p_del =  subparsers.add_parser("del", help=delete.__doc__.lower())
@@ -76,13 +88,16 @@ p_add.set_defaults(func=add)
try:
    # Parse and run
    args = p_main.parse_args()
    # load config
    config = ConfigFile("isrepo", args.config)
    # load isinstall config
    config = MainConfigFile(args.config)
    config.merge(args)
    # load repo configs
    repos = []
    for r_config in args.repo_config:
        repos += RepoConfigFile(r_config).repos
    # filtering on repository name if present
    if args.repo_name is not None:
        repos = filter(lambda x: x.name == args.repo_name, config.repos)
    else:
        repos = config.repos
        repos = filter(lambda x: x.name == args.repo_name, repos)
    if len(repos) == 1:
        args.repository = repos[0]
    elif len(repos) > 1:
+110 −42
Original line number Diff line number Diff line
@@ -11,59 +11,57 @@ from ConfigParser import RawConfigParser
from installsystems.printer import *
from installsystems.repository import RepositoryConfig


class ConfigFile(object):
    '''Configuration class'''
    '''
    Configuration File base class
    '''

    def __init__(self, prefix=None, filename=None):
        # prefix is config file indentifier (isinstall / isrepo)
        self.prefix = prefix
        self.path =  self._config_path() if filename is None else os.path.abspath(filename)
    def __init__(self, filename):
        '''
        filename can be name in config path
        '''
        #try to get filename in  default config dir
        if "/" not in filename:
            path = self._config_path(filename)
            if path is not None:
                self.path = path
        elif os.path.exists(filename):
            self.path = filename
        else:
            self.path = None
            debug("No config file found: %s" % filename)
        self.reload()

    def _config_path(self):
        '''Return path of the best config file'''
        for cf in [ os.path.join(os.path.expanduser("~/.config/installsystems/%s.conf" % self.prefix)),
                    "/etc/installsystems/%s.conf" % self.prefix ]:
    def reload():
        '''
        Reload configuration from file
        '''
        raise NotImplementedError

    def _config_path(self, name):
        '''
        Return path of the best config file
        '''
        for cf in [ os.path.join(os.path.expanduser("~/.config/installsystems/%s.conf" % name)),
                    "/etc/installsystems/%s.conf" % name ]:
            if (os.path.exists(cf) and os.path.isfile(cf) and os.access(cf, os.R_OK)):
                return cf
        return None

    def reload(self):
        '''Load/Reload config file'''
        # seting default config
        self._config = {}
        self._repos = []
        # loading config file if exists
        if self.path is not None:
            debug("Loading config file: %s" % self.path)
            try:
                cp = RawConfigParser()
                cp.read(self.path)
                # main configuration
                if cp.has_section(self.prefix):
                    self._config = dict(cp.items(self.prefix))
                    cp.remove_section(self.prefix)
                # each section is a repository
                for rep in cp.sections():
                    # check if its a repo section
                    if "path" not in cp.options(rep):
                        continue
                    # get all options in repo
                    self._repos.append(RepositoryConfig(rep, **dict(cp.items(rep))))
            except Exception as e:
                raise Exception("Unable load file %s: %s" % (self.path, e))
        else:
            debug("No config file found")

    def _cache_paths(self):
        '''List all candidates to cache directories. Alive or not'''
    def _cache_paths(self, name):
        '''
        List all candidates to cache directories. Alive or not
        '''
        dirs = [] # ["/var/tmp", "/tmp"]
        # we have a different behaviour if we are root
        dirs.insert(0, "/var/cache" if os.getuid() == 0 else os.path.expanduser("~/.cache"))
        return map(lambda x: os.path.join(x, self.prefix), dirs)
        return map(lambda x: os.path.join(x, name), dirs)

    def _cache_path(self):
        '''Return path of the best cache directory'''
        '''
        Return path of the best cache directory
        '''
        # find a good directory
        for di in self._cache_paths():
            if (os.path.exists(di)
@@ -72,9 +70,46 @@ class ConfigFile(object):
                return di
        return None


class MainConfigFile(ConfigFile):
    '''
    Program configuration file
    '''

    def reload(self):
        '''
        Load/Reload config file
        '''
        self._config = {}
        # loading config file if exists
        if self.path is None:
            return
        debug("Loading config file: %s" % self.path)
        try:
            cp = RawConfigParser()
            cp.read(self.path)
            # main configuration
            name = os.path.splitext(os.path.basename(self.path))[0]
            if cp.has_section(name):
                self._config = dict(cp.items(name))
        except Exception as e:
            raise Exception("Unable load file %s: %s" % (self.path, e))

    def merge(self, namespace):
        '''
        Merge current loaded option with a namespace from argparse
        '''
        for option, value in self._config.items():
            if not hasattr(namespace, option):
                setattr(namespace, option, value)
            elif getattr(namespace, option) == None:
                setattr(namespace, option, value)

    @property
    def cache(self):
        '''Find a cache directory'''
        '''
        Find a cache directory
        '''
        if "cache" in self._config:
            return self._config["cache"]
        if self._cache_path() is None:
@@ -86,8 +121,41 @@ class ConfigFile(object):
                    debug("Unable to create %s: %s" % (di, e))
        return self._cache_path()


class RepoConfigFile(ConfigFile):
    '''
    Repository Configuration class
    '''

    def reload(self):
        '''
        Load/Reload config file
        '''
        # seting default config
        self._config = {}
        self._repos = []
        # loading config file if exists
        if self.path is not None:
            debug("Loading config file: %s" % self.path)
            try:
                cp = RawConfigParser()
                cp.read(self.path)
                # each section is a repository
                for rep in cp.sections():
                    # check if its a repo section
                    if "path" not in cp.options(rep):
                        continue
                    # get all options in repo
                    self._repos.append(RepositoryConfig(rep, **dict(cp.items(rep))))
            except Exception as e:
                raise Exception("Unable load file %s: %s" % (self.path, e))
        else:
            debug("No config file found")

    @property
    def repos(self):
        '''Get a list of repository available'''
        '''
        Get a list of repository available
        '''
        # deep copy
        return list(self._repos)
+10 −9
Original line number Diff line number Diff line
# isinstall program configuration

[isinstall]
debug = False
# define a custom cache directory
#cache = /tmp/sex

# disable cache of remote repository
#no_cache = 1

# smartjog official installsystems repository
[smartjog]
image = http://installsystems.boot.wan/images
data = http://installsystems.boot.wan/data
# define connection timeout
#timeout = 30

# localhost testing repository
[localhost]
image = http://localhost/images
data = http://localhost/data
# custom repository config file
#repo_config =
Loading