From 2372c15947a76022284fdb3d80a8da8c00a00582 Mon Sep 17 00:00:00 2001 From: Seblu <sebastien.luttringer@smartjog.com> Date: Tue, 31 May 2011 12:57:35 +0200 Subject: [PATCH] Add config file --- bin/isimage | 2 +- bin/isinstall | 23 +++----- bin/isrepo | 55 ++++++++++++------ installsystems/config.py | 105 +++++++++++++++++++++++++++++++++++ installsystems/repository.py | 11 ++-- 5 files changed, 159 insertions(+), 37 deletions(-) create mode 100644 installsystems/config.py diff --git a/bin/isimage b/bin/isimage index 29f901b..1445eb8 100755 --- a/bin/isimage +++ b/bin/isimage @@ -33,7 +33,7 @@ def init(args): def build(args): '''Create a package image''' try: - # start time + # build start time t0 = time.time() # load source image simg = SourceImage(args.path) diff --git a/bin/isinstall b/bin/isinstall index b3227bd..c1ec467 100755 --- a/bin/isinstall +++ b/bin/isinstall @@ -15,6 +15,7 @@ import installsystems.tools as istools from installsystems.printer import * from installsystems.repository import RepositoryCache from installsystems.image import PackageImage +from installsystems.config import ConfigFile class DebugAction(argparse.Action): '''Set installsystems in debug mode. Argparse callback''' @@ -24,7 +25,7 @@ class DebugAction(argparse.Action): debug("Debug on") -# Top level argument parsing +# Argument parsing loading p_main = argparse.ArgumentParser() p_main.add_argument("-V", "--version", action="version", version=installsystems.version, help="show installsystems version") @@ -32,32 +33,26 @@ p_main.add_argument('-d', "--debug", action=DebugAction, nargs=0, help="active debug mode") p_main.add_argument('-q', "--quiet", action="store_false", dest="verbose", default=True, help="active quiet mode") -p_main.add_argument("-I", "--image-repo", dest="image_path", type=str, default=None, - help="remote image repository path") -p_main.add_argument("-D", "--data-repo", dest="data_path", type=str, default=None, - help="remote data repository path") -p_main.add_argument("-C", "--cache-path", dest="cache_path", type=str, - default="/var/cache/isinstall", - help="local cache repository path") +p_main.add_argument("-c", "--config", dest="config", type=str, default=None, + help="config file path") p_main.add_argument("-v", "--image-version", dest="image_version", type=int, default=None, help="specific image version") p_main.add_argument("image_name", type=str, help="image to install (path or name)") - -# program entry point try: # Partial parse args = p_main.parse_known_args()[0] + # load config + config = ConfigFile("isinstall", args.config) # looks if arguments is a file or image name image_name_type = istools.get_path_type(args.image_name) if image_name_type == "file": pkg = PackageImage(istools.complete_path(args.image_name)) elif image_name_type == "name": # init repo cache object - repocache = RepositoryCache(args.cache_path, verbose=args.verbose) - # register command ligne repo - if args.image_path is not None: - repocache.register("cmdline", args.image_path, args.data_path) + repocache = RepositoryCache(config.cache, verbose=args.verbose) + # register repositories + repocache.register(config.repos) # update remote info repocache.update() # get image package diff --git a/bin/isrepo b/bin/isrepo index 3900a8f..c864932 100755 --- a/bin/isrepo +++ b/bin/isrepo @@ -12,7 +12,7 @@ import installsystems from installsystems.printer import * from installsystems.repository import Repository from installsystems.image import PackageImage - +from installsystems.config import ConfigFile class DebugAction(argparse.Action): '''Set installsystems in debug mode. Argparse callback''' @@ -26,14 +26,14 @@ def init(args): '''Create an empty fresh repo tree''' # call init from library try: - Repository.create(args.image_path, args.data_path, args.verbose) + Repository.create(args.repo_image, args.repo_data, args.verbose) except Exception as e: error("init failed: %s." % e) def add(args): '''Add a package to repository''' try: - repo = Repository(args.image_path, args.data_path, args.verbose) + repo = Repository(args.repo_image, args.repo_data, args.verbose) pkg = PackageImage(args.path, args.verbose) pkg.check_md5() repo.add(pkg) @@ -43,7 +43,7 @@ def add(args): def delete(args): '''Remove a package from repository''' try: - repo = Repository(args.image_path, args.data_path, args.verbose) + repo = Repository(args.repo_image, args.repo_data, args.verbose) repo.delete(args.image_name, args.image_version) except Exception as e: error("del failed: %s." % e) @@ -56,17 +56,20 @@ p_main.add_argument('-d', "--debug", action=DebugAction, nargs=0, help="active debug mode") p_main.add_argument('-q', "--quiet", action="store_false", dest="verbose", default=True, help="active quiet mode") -p_main.add_argument("-I", "--image-path", dest="image_path", type=str, +p_main.add_argument("-c", "--config", dest="config", type=str, default=None, + help="config file path") +p_main.add_argument("-r", "--repo-name", dest="repo_name", type=str, default=None, + help="repository name") +p_main.add_argument("-I", "--repo-image", dest="repo_image", type=str, help="image repository path") -p_main.add_argument("-D", "--data-path", dest="data_path", type=str, +p_main.add_argument("-D", "--repo-data", dest="repo_data", type=str, help="data repository path") - subparsers = p_main.add_subparsers() # Init command parser p_init = subparsers.add_parser("init", help=init.__doc__.lower()) -p_init.add_argument("image_path", nargs="?", default=argparse.SUPPRESS, +p_init.add_argument("repo_image", nargs="?", default=argparse.SUPPRESS, help="Path of the new image directory") -p_init.add_argument("data_path", nargs="?", default=argparse.SUPPRESS, +p_init.add_argument("repo_data", nargs="?", default=argparse.SUPPRESS, help="Path of the new data directory") p_init.set_defaults(func=init) # Add command parser @@ -78,13 +81,29 @@ p_del = subparsers.add_parser("del", help=delete.__doc__.lower()) p_del.add_argument("image_name", type=str) p_del.add_argument("image_version", type=str) p_del.set_defaults(func=delete) -# Parse and run -args = p_main.parse_args() -# Check global args -if args.image_path is None: - p_main.print_usage() - error("image path missing") -elif args.data_path is None: +try: + # Parse and run + args = p_main.parse_args() + # load config + config = ConfigFile("isrepo", args.config) + # get config repository + c_repo = config.repo(args.repo_name) + # looks for image repository in config, if needed + if args.repo_image is None and c_repo is not None: + args.repo_image = c_repo[0] + # looks for data repository in config, if needed + if args.repo_data is None and c_repo is not None: + args.repo_data = c_repo[1] + # final check of existance + if args.repo_image is None: + raise Exception("image repository missing") + elif args.repo_data is None: + raise Exception("data repository missing") + debug("Image repo: %s" % args.repo_image) + debug("Data repo: %s" % args.repo_data) + args.func(args) +except Exception as e: p_main.print_usage() - error("data path missing") -args.func(args) + error(e) +except KeyboardInterrupt: + warn("Keyboard Interrupted") diff --git a/installsystems/config.py b/installsystems/config.py new file mode 100644 index 0000000..e8cba0d --- /dev/null +++ b/installsystems/config.py @@ -0,0 +1,105 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# Started 30/05/2011 by Seblu <seblu@seblu.net> + +''' +InstallSystems Configuration files class +''' + +import os +from ConfigParser import RawConfigParser +from xdg import BaseDirectory +from installsystems.printer import * + +class ConfigFile(object): + '''Configuration 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) + 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 ]: + 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) + if cp.has_section(self.prefix): + self._config = dict(cp.items(self.prefix)) + cp.remove_section(self.prefix) + for rep in cp.sections(): + img = data = None + if cp.has_option(rep, "image"): + img = cp.get(rep, "image") + if cp.has_option(rep, "data"): + data = cp.get(rep, "data") + self._repos[rep]= (img, data) + 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''' + 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) + + def _cache_path(self): + '''Return path of the best cache directory''' + # find a good directory + for di in self._cache_paths(): + if (os.path.exists(di) + and os.path.isdir(di) + and os.access(di, os.R_OK|os.W_OK|os.X_OK)): + return di + return None + + @property + def cache(self): + '''Find a cache directory''' + if "cache" in self._config: + return self._config["cache"] + if self._cache_path() is None: + for di in self._cache_paths(): + try: + os.mkdir(di) + break + except Exception as e: + debug("Unable to create %s: %s" % (di, e)) + return self._cache_path() + + @property + def repos(self): + '''Get a list of repository available''' + for r in self._repos: + yield (r, self._repos[r][0], self._repos[r][1]) + + def repo(self, name): + ''' + Return a reposiory by its name + name can be None if there is only one repository + ''' + if name is None and len(self._repos) == 1: + return self._repos[self._repos.keys()[0]] + elif name is not None: + if name in self._repos.keys(): + return self._repos[name] + return None + diff --git a/installsystems/repository.py b/installsystems/repository.py index fa095de..69d5d90 100644 --- a/installsystems/repository.py +++ b/installsystems/repository.py @@ -119,12 +119,15 @@ class RepositoryCache(object): raise Exception("%s is not writable or executable" % path) self.verbose = verbose self.repos = dict() + debug("Repository cache is in %s" % self.base_path) - def register(self, name, image, data): + def register(self, iterepo): '''Register a repository to track''' - self.repos[name] = Repository(istools.complete_path(image), - istools.complete_path(data), - verbose=self.verbose) + for r in iterepo: + print r + self.repos[r[0]] = Repository(istools.complete_path(r[1]), + istools.complete_path(r[2]), + verbose=self.verbose) def update(self): '''Update cache info''' -- GitLab