commit: 1111e063d87554087526b3f6ef43612125db9bfb Author: André Erdmann <dywi <AT> mailerd <DOT> de> AuthorDate: Mon Mar 31 15:44:49 2014 +0000 Commit: André Erdmann <dywi <AT> mailerd <DOT> de> CommitDate: Mon Mar 31 15:44:49 2014 +0000 URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=1111e063
let's run on debian #1: roverlay-setup This commit adds basic support for target-specific setup via the "--target-type <type>" switch. So far this affects config file creation only and there are 2 choices: * "gentoo": have portage and a PORTDIR * "foreign" a.k.a. "not gentoo": neither portage nor PORTDIR available --- roverlay/config/defconfig.py | 66 ++++++++++++------ roverlay/setupscript/runtime.py | 148 ++++++++++++++++++++++++++++------------ roverlay/static/targetenv.py | 51 ++++++++++++++ 3 files changed, 204 insertions(+), 61 deletions(-) diff --git a/roverlay/config/defconfig.py b/roverlay/config/defconfig.py index 4bff289..383bb96 100644 --- a/roverlay/config/defconfig.py +++ b/roverlay/config/defconfig.py @@ -148,7 +148,7 @@ class ConfigOption ( object ): class RoverlayConfigCreation ( object ): def __init__ ( self, - is_installed, + is_installed, target_type, work_root = '~/roverlay', data_root = '/usr/share/roverlay', conf_root = '/etc/roverlay', @@ -167,7 +167,7 @@ class RoverlayConfigCreation ( object ): self._ctree = tree.ConfigTree() self._cloader = self._ctree.get_loader() self._verify_value = self._cloader._make_and_verify_value - self.reset ( is_installed=is_installed ) + self.reset ( is_installed=is_installed, target_type=target_type ) # --- end of __init__ (...) --- def iter_options ( self ): @@ -189,6 +189,8 @@ class RoverlayConfigCreation ( object ): svalue = self.get_datadir ( value[2:] ) elif v == 'c': svalue = self.get_confdir ( value[2:] ) + elif v == 'a': + svalue = self.get_additions_dir ( value[2:] ) else: svalue = value else: @@ -215,7 +217,7 @@ class RoverlayConfigCreation ( object ): else: raise ConfigOptionMissing ( key ) - def reset ( self, is_installed ): + def reset ( self, is_installed, target_type ): workdir = self.get_workdir datadir = self.get_datadir confdir = self.get_confdir @@ -223,15 +225,21 @@ class RoverlayConfigCreation ( object ): cachedir = _fspath_prefix_func ( self.work_root, 'cache' ) + _NULLCONF = lambda *a, **b: None + _GET_A = lambda a, b: a + _GET_B = lambda a, b: b + _T_TRUE = ( ConfigOption, _NULLCONF, _GET_A ) + _T_FALSE = ( _NULLCONF, ConfigOption, _GET_B ) + _get_setup_triple = lambda cond: ( _T_TRUE if cond else _T_FALSE ) - UNLESS_INSTALLED = lambda *a, **b: ( - None if is_installed else ConfigOption ( *a, **b ) + IF_INSTALLED, UNLESS_INSTALLED, get_inst_val = ( + _get_setup_triple ( is_installed ) ) - IF_INSTALLED = lambda *a, **b: ( - ConfigOption ( *a, **b ) if is_installed else None + IF_PORTDIR, UNLESS_PORTDIR, get_portdir_val = ( + _get_setup_triple ( target_type.portdir ) ) - get_val = lambda v_inst, v_standalone: ( - v_inst if is_installed else v_standalone + IF_PORTAGE, UNLESS_PORTAGE, get_portage_val = ( + _get_setup_triple ( target_type.has_portage ) ) @@ -250,27 +258,35 @@ class RoverlayConfigCreation ( object ): use_default_desc=False ), ConfigOption ( 'CACHEDIR', cachedir() ), - ConfigOption ( - 'PORTDIR', '/usr/portage', use_default_desc=False, + IF_PORTDIR ( + 'PORTDIR', target_type.portdir, use_default_desc=False, description=( "portage directory", " used to scan for valid licenses", ), ), + UNLESS_PORTAGE ( + 'EBUILD_PROG', '/usr/bin/ebuild', + comment_default=True, required=False, recommended=None, + description=( + ' optional, but required for importing hand-written ebuilds' + ' and MANIFEST_IMPLEMENTATION=ebuild (see below)' + ), + ), '', '# --- Logging Configuration (optional) ---', '', ConfigOption ( - 'LOG_LEVEL', get_val ( 'WARNING', 'INFO' ), required=False, + 'LOG_LEVEL', get_inst_val ( 'WARNING', 'INFO' ), required=False, comment_default=is_installed, ), ConfigOption ( - 'LOG_LEVEL_CONSOLE', get_val ( 'INFO', 'WARNING' ), + 'LOG_LEVEL_CONSOLE', get_inst_val ( 'INFO', 'WARNING' ), required=False, comment_default=is_installed, use_default_desc=False, append_newline=False, ), ConfigOption ( - 'LOG_LEVEL_FILE', get_val ( 'ERROR', 'WARNING' ), + 'LOG_LEVEL_FILE', get_inst_val ( 'ERROR', 'WARNING' ), required=False, comment_default=is_installed, use_default_desc=False, append_newline=False, ), @@ -350,7 +366,10 @@ class RoverlayConfigCreation ( object ): ConfigOption ( 'OVERLAY_CATEGORY', 'sci-R', defaults_to=True, comment_default=True, required=False, use_default_desc=False, - description="default category for created ebuilds", + description=( + "default category for created ebuilds", + " (usually overridden by package rules)" + ) ), ConfigOption ( 'REPO_CONFIG', confdir ( 'repo.list' ), @@ -389,24 +408,33 @@ class RoverlayConfigCreation ( object ): ), ConfigOption ( 'USE_PORTAGE_LICENSES', 'no', required=False, - comment_default=True, defaults_to="yes" + comment_default=target_type.portdir, defaults_to="yes" + ), + UNLESS_PORTDIR ( + 'LICENSES_FILE', datadir ( 'licenses' ), required=True, + use_default_desc=False, defaults_to="<CACHEDIR>/licenses", + description=( + "file that lists all known licenses (one per line)" + ), ), ConfigOption ( 'CREATE_LICENSES_FILE', 'no', required=False, - comment_default=True, defaults_to="yes" + comment_default=target_type.portdir, defaults_to="yes" ), ConfigOption ( 'NOSYNC', 'yes', required=False, comment_default=True, defaults_to="no", ), ConfigOption ( - 'MANIFEST_IMPLEMENTATION', "ebuild", required=False, + 'MANIFEST_IMPLEMENTATION', 'ebuild', required=False, use_default_desc=False, comment_default=True, defaults_to="next", description=( "Manifest file creation", ' Available choices are \'next\' (internal, fast)', ' and \'ebuild\' (using ebuild(1), slow, but failsafe).', - ), + ) + get_portage_val ( + (), ( ' *** \'ebuild\' needs a valid EBUILD_PROG ***', ) + ) ), ] diff --git a/roverlay/setupscript/runtime.py b/roverlay/setupscript/runtime.py index 2afbc9f..afe9daa 100644 --- a/roverlay/setupscript/runtime.py +++ b/roverlay/setupscript/runtime.py @@ -17,10 +17,12 @@ import roverlay.fsutil import roverlay.runtime import roverlay.config.defconfig +import roverlay.config.entryutil import roverlay.setupscript.initenv import roverlay.setupscript.hookenv +import roverlay.static.targetenv if sys.hexversion >= 0x3000000: @@ -29,6 +31,12 @@ else: read_user_input = raw_input +CONFIG_FS_OPTIONS = frozenset ( + k for k, v in roverlay.config.entryutil.iter_entries_with_value_type ( + { 'fs_path', 'fs_abs', 'fs_dir', 'fs_file', } + ) +) + def setup_main_installed(): return setup_main ( True ) @@ -117,6 +125,25 @@ class SetupArgumentParser ( roverlay.argparser.RoverlayArgumentParser ): arg = self.setup_setup_minimal ( title='common options' ) arg ( + '--target-type', + dest = "target_type", + default = roverlay.static.targetenv.DEFAULT_TARGET, + metavar = "<type>", + choices = roverlay.static.targetenv.TARGET_INFO, + flags = self.ARG_WITH_DEFAULT, + help = ( + 'set the environment in which roverlay will be run' + ' (choose from %(choices)s)' + ) + ) + + arg ( + '--foreign', '--not-gentoo', dest="target_type", + flags=self.ARG_SHARED, action="store_const", const="foreign", + help="set target environment to \'foreign\'" + ) + + arg ( '--output', '-O', metavar="<file|dir|->", dest='output', default='-', type=arg_stdout_or_fs, flags=self.ARG_WITH_DEFAULT, @@ -348,6 +375,7 @@ class SetupEnvironment ( roverlay.runtime.IndependentRuntimeEnvironment ): self.additions_dir = None self.hook_overwrite = None + self.target_type = None # not used # COLUMNS = os.environ.get ( 'COLUMNS', 78 ) # should use termios/... @@ -359,9 +387,14 @@ class SetupEnvironment ( roverlay.runtime.IndependentRuntimeEnvironment ): # --- end of __init__ (...) --- def get_parser_defaults ( self ): + defaults = {} + + if 'ROVERLAY_TARGET_TYPE' in os.environ: + defaults ['target_type'] = os.environ ['ROVERLAY_TARGET_TYPE'] + if self.is_installed(): instinfo = self.INSTALLINFO - return { + defaults.update ({ 'work_root' : instinfo ['workroot'], 'data_root' : instinfo ['libexec'], 'conf_root' : instinfo ['confroot'], @@ -369,11 +402,11 @@ class SetupEnvironment ( roverlay.runtime.IndependentRuntimeEnvironment ): 'import_config' : 'symlink=root', 'additions_dir' : instinfo ['workroot'] + os.sep + 'files', 'hook_relpath' : False, - } + }) else: assert self.prjroot prjroot = self.prjroot + os.sep - return { + defaults.update ({ 'work_root' : prjroot + 'workdir', 'data_root' : prjroot + 'files', 'conf_root' : prjroot + 'config', @@ -381,7 +414,10 @@ class SetupEnvironment ( roverlay.runtime.IndependentRuntimeEnvironment ): 'import_config' : 'disable', 'additions_dir' : prjroot + 'files', 'hook_relpath' : True, - } + }) + # -- end if + + return defaults # --- end of get_parser_defaults (...) --- def create_argparser ( self ): @@ -425,53 +461,66 @@ class SetupEnvironment ( roverlay.runtime.IndependentRuntimeEnvironment ): ) # --- end of create_new_target_config (...) --- - def _expanduser_pwd ( self, fspath ): - return roverlay.fsutil.pwd_expanduser ( - fspath, self.options ['target_uid'] - ) + def _expanduser_pwd ( self, fspath, + _expand=roverlay.fsutil.pwd_expanduser + ): + return _expand ( fspath, self.options ['target_uid'] ) # --- end of _expanduser_pwd (...) --- def create_config_file ( self, expand_user=False ): - def _get_prjroot_relpath ( fspath ): - p = os.path.relpath ( fspath, self.prjroot ) - if p and ( p[0] != '.' or p == '.' ): - return p - else: - return fspath - # --- end of get_prjroot_relpath (...) --- + _IDENT = lambda x: x + _FS_OPTIONS = CONFIG_FS_OPTIONS - get_prjroot_relpath = ( - _get_prjroot_relpath - if ( self.options ['prjroot_relpath'] and self.prjroot ) - else (lambda p: p) - ) + def _unexpand ( fspath, + _unexpanduser_pwd = roverlay.fsutil.pwd_unexpanduser, + _target_uid = self.options ['target_uid'] + ): + return _unexpanduser_pwd ( fspath, _target_uid ) + # --- end of _unexpand (...) --- + + def _get_prjroot_relpath ( fspath, + _relpath=os.path.relpath, _prjroot=self.prjroot + ): + p = _relpath ( fspath, _prjroot ) + return p if ( p and ( p[0] != '.' or p == '.' ) ) else fspath + # --- end of _get_prjroot_relpath (...) --- + + def var_iter ( cmdline_vars ): + for kv in cmdline_vars: + key, sepa, value = kv.partition ( '=' ) + if key and sepa: + yield ( key, value ) + else: + raise ValueError ( "bad variable given: {!r}".format ( kv ) ) + # --- end of var_iter (...) --- + + if self.options ['prjroot_relpath'] and self.prjroot: + get_config_fspath = _get_prjroot_relpath + elif expand_user: + get_config_fspath = _IDENT + else: + get_config_fspath = _unexpand conf_creator = roverlay.config.defconfig.RoverlayConfigCreation ( is_installed = self.is_installed(), - work_root = get_prjroot_relpath ( - self.work_root if expand_user else self.options ['work_root'] - ), - data_root = get_prjroot_relpath ( - self.data_root if expand_user else self.options ['data_root'] - ), - conf_root = get_prjroot_relpath ( - self.user_conf_root if expand_user - else self.options ['private_conf_root'] - ), - additions_dir = get_prjroot_relpath ( - self.additions_dir if expand_user - else self.options ['additions_dir'] - ) + target_type = self.target_type, + work_root = get_config_fspath ( self.work_root ), + data_root = get_config_fspath ( self.data_root ), + conf_root = get_config_fspath ( self.user_conf_root ), + additions_dir = get_config_fspath ( self.additions_dir ), ) + set_option = conf_creator.set_option - for kv in self.options ['config_vars']: - key, sepa, value = kv.partition ( '=' ) - if not sepa: - raise Exception ( "bad variable given: {!r}".format ( kv ) ) - elif key in { 'ADDITIONS_DIR', 'OVERLAY_ADDITIONS_DIR', }: - conf_creator.set_option ( key, get_prjroot_relpath ( value ) ) - else: - conf_creator.set_option ( key, value ) + if get_config_fspath is _IDENT: + for key, value in var_iter ( self.options ['config_vars'] ): + set_option ( key, value ) + else: + for key, value in var_iter ( self.options ['config_vars'] ): + if key.lower() in _FS_OPTIONS: + set_option ( key, get_config_fspath ( value ) ) + else: + set_option ( key, value ) + # -- end if return conf_creator.get_str() # --- end of create_config_file (...) --- @@ -523,6 +572,21 @@ class SetupEnvironment ( roverlay.runtime.IndependentRuntimeEnvironment ): ) ) + target_type_str = options ['target_type'] + try: + self.target_type = ( + roverlay.static.targetenv.TARGET_INFO [target_type_str] + ) + except KeyError: + sys.stderr.write ( + "invalid $ROVERLAY_TARGET_TYPE/--target-type: {!r}\n".format ( + target_type_str + ) + ) + sys.exit ( os.EX_USAGE ) + # -- end try + del target_type_str + self.fs_private_virtual = roverlay.fsutil.VirtualFsOperations ( uid=target_uid, gid=target_gid, file_mode=self.PRIVATE_FILE_MODE, dir_mode=self.PRIVATE_DIR_MODE diff --git a/roverlay/static/targetenv.py b/roverlay/static/targetenv.py new file mode 100644 index 0000000..330c8ee --- /dev/null +++ b/roverlay/static/targetenv.py @@ -0,0 +1,51 @@ +# R overlay -- +# -*- coding: utf-8 -*- +# Copyright (C) 2014 André Erdmann <d...@mailerd.de> +# Distributed under the terms of the GNU General Public License; +# either version 2 of the License, or (at your option) any later version. + +import collections + + +# *** FIXME: doc *** +# gentoo means: +# * have PORTDIR +# * have ebuild(1) from portage +# and foreign -- "not gentoo": +# * don't use PORTDIR +# * don't use portage +# * use a hardcoded licenses file +# ... +# + +DEFAULT_TARGET = "gentoo" + +# dict: env_name(str) => defaults(TargetInfo) +TARGET_INFO = collections.OrderedDict() + +#TargetInfo = collections.namedtuple ( 'TargetInfo', 'name has_portage portdir' ) +class TargetInfo ( object ): + __instances = dict() + + @classmethod + def get_instance ( cls, *args ): + obj = cls.__instances.get ( args, None ) + if obj is None: + obj = cls ( *args ) + cls.__instances [args] = obj + return obj + + def __init__ ( self, name, has_portage, portdir ): + super ( TargetInfo, self ).__init__() + self.name = name + self.has_portage = has_portage + self.portdir = portdir +# --- end of TargetInfo --- + +def add_entry ( name, *args ): + TARGET_INFO [name] = TargetInfo.get_instance ( name, *args ) +# --- end of add_entry (...) --- + + +add_entry ( 'gentoo', True, "/usr/portage" ) +add_entry ( 'foreign', False, False )