Beispiel #1
0
 def run(self, args):
     """run the command with its specific arguments"""
     appid = args[0]
     configs = [
         cwcfg.config_for(appid, configname)
         for configname in cwcfg.possible_configurations(appid)
     ]
     if not configs:
         raise ExecutionError('unable to guess configuration for %s' %
                              appid)
     for config in configs:
         helper = self.config_helper(config, required=False)
         if helper:
             helper.cleanup()
     # remove home
     rm(config.apphome)
     # remove instance data directory
     try:
         rm(config.appdatahome)
     except OSError as ex:
         import errno
         if ex.errno != errno.ENOENT:
             raise
     confignames = ', '.join([config.name for config in configs])
     print('-> instance %s (%s) deleted.' % (appid, confignames))
Beispiel #2
0
    def setUp(self):
        self.CWCTL = CommandLine('cubicweb-ctl', 'The CubicWeb swiss-knife.',
                                 version=cw_version, check_duplicated_command=False)
        cwcfg.load_cwctl_plugins()
        self.CWCTL.register(_TestCommand)
        self.CWCTL.register(_TestFailCommand)

        # pretend that this instance exists
        patcher = patch.object(cwcfg, 'config_for', return_value=object())
        patcher.start()
        self.addCleanup(patcher.stop)
Beispiel #3
0
def run(args=sys.argv[1:]):
    """command line tool"""
    filterwarnings('default', category=DeprecationWarning)
    cwcfg.load_cwctl_plugins()
    try:
        CWCTL.run(args)
    except ConfigurationError as err:
        print('ERROR: ', err)
        sys.exit(1)
    except ExecutionError as err:
        print(err)
        sys.exit(2)
Beispiel #4
0
 def run(self, args):
     appid = args.pop(0)
     config = cwcfg.config_for(appid)
     dest = None
     if args:
         dest = args[0]
     self.generate_static_dir(config, dest)
Beispiel #5
0
def get_cw_option(instance_name, cw_option):
    """ Get a cw option.

    Parameters
    ----------
    instance_name: str (mandatory)
        the name of the cw instance we want to connect.
    cw_option: str (mandatory)
        the cw option name.

    Returns
    -------
    basedir: str
        part of the image path to hide in the virtual fs.
    """
    # Get the configuration file
    config = cwcfg.config_for(instance_name)
    config_file = os.path.join(os.path.dirname(config.sources_file()),
                               "all-in-one.conf")

    # Parse the configuration file and retrive the basedir
    with open(config_file) as open_file:
        for line in open_file.readlines():
            match = re.match(r"^([a-zA-Z0-9_-]+)=(\S*)$", line)
            if match:
                name, value = match.groups()
                if name == cw_option:
                    return value

    # If the basedir parameter is nor found raise an exception
    raise Exception("No '{0}' option has been declared in the '{1}' "
                    "configuration file.".format(cw_option, config_file))
def get_cw_option(instance_name, cw_option):
    """ Get a cw option.

    Parameters
    ----------
    instance_name: str (mandatory)
        the name of the cw instance we want to connect.
    cw_option: str (mandatory)
        the cw option name.

    Returns
    -------
    basedir: str
        part of the image path to hide in the virtual fs.
    """
    # Get the configuration file
    config = cwcfg.config_for(instance_name)
    config_file = os.path.join(
        os.path.dirname(config.sources_file()), "all-in-one.conf")

    # Parse the configuration file and retrive the basedir
    with open(config_file) as open_file:
        for line in open_file.readlines():
            match = re.match(r"^(\w+)=(\S*)$", line)
            if match:
                name, value = match.groups()
                if name == cw_option:
                    return value

    # If the basedir parameter is nor found raise an exception
    raise Exception("No '{0}' option has been declared in the '{1}' "
                    "configuration file.".format(cw_option, config_file))
Beispiel #7
0
 def upgrade_instance(self, appid):
     print('\n' + underline_title('Upgrading the instance %s' % appid))
     from logilab.common.changelog import Version
     config = cwcfg.config_for(appid)
     config.repairing = True  # notice we're not starting the server
     config.verbosity = self.config.verbosity
     set_sources_mode = getattr(config, 'set_sources_mode', None)
     if set_sources_mode is not None:
         set_sources_mode(self.config.ext_sources or ('migration', ))
     # get instance and installed versions for the server and the componants
     mih = config.migration_handler()
     repo = mih.repo
     vcconf = repo.get_versions()
     helper = self.config_helper(config, required=False)
     if self.config.force_cube_version:
         for cube, version in self.config.force_cube_version.items():
             vcconf[cube] = Version(version)
     toupgrade = []
     for cube in config.cubes():
         installedversion = config.cube_version(cube)
         try:
             applversion = vcconf[cube]
         except KeyError:
             config.error('no version information for %s' % cube)
             continue
         if installedversion > applversion:
             toupgrade.append((cube, applversion, installedversion))
     cubicwebversion = config.cubicweb_version()
     if self.config.force_cubicweb_version:
         applcubicwebversion = Version(self.config.force_cubicweb_version)
         vcconf['cubicweb'] = applcubicwebversion
     else:
         applcubicwebversion = vcconf.get('cubicweb')
     if cubicwebversion > applcubicwebversion:
         toupgrade.append(
             ('cubicweb', applcubicwebversion, cubicwebversion))
     # run cubicweb/componants migration scripts
     if self.config.fs_only or toupgrade:
         for cube, fromversion, toversion in toupgrade:
             print('-> migration needed from %s to %s for %s' %
                   (fromversion, toversion, cube))
         with mih.cnx:
             with mih.cnx.security_enabled(False, False):
                 mih.migrate(vcconf, reversed(toupgrade), self.config)
         clear_cache(config, 'instance_md5_version')
     else:
         print('-> no data migration needed for instance %s.' % appid)
     # rewrite main configuration file
     if not self.config.no_config_update:
         mih.rewrite_configuration()
     mih.shutdown()
     # handle i18n upgrade
     if not self.i18nupgrade(config):
         return
     print()
     if helper:
         helper.postupgrade(repo)
     print('-> instance migrated.')
     print()
 def test_filter_scripts_for_mode(self):
     config = CubicWebConfiguration('data', __file__)
     config.verbosity = 0
     config = self.config
     config.__class__.name = 'repository'
     self.assertListEqual(
         filter_scripts(config, TMIGRDIR, (0, 0, 4), (0, 1, 0)),
         [((0, 1, 0), TMIGRDIR + '0.1.0_Any.py'),
          ((0, 1, 0), TMIGRDIR + '0.1.0_common.py'),
          ((0, 1, 0), TMIGRDIR + '0.1.0_repository.py')])
     config.__class__.name = 'all-in-one'
     self.assertListEqual(
         filter_scripts(config, TMIGRDIR, (0, 0, 4), (0, 1, 0)),
         [((0, 1, 0), TMIGRDIR + '0.1.0_Any.py'),
          ((0, 1, 0), TMIGRDIR + '0.1.0_common.py'),
          ((0, 1, 0), TMIGRDIR + '0.1.0_repository.py')])
     config.__class__.name = 'repository'
def get_cw_cnx(endpoint):
    """ Get a cnx on a CubicWeb database
    """
    from cubicweb import dbapi
    from cubicweb.__pkginfo__ import numversion
    from cubicweb.cwconfig import CubicWebConfiguration
    from cubicweb.entities import AnyEntity
    CubicWebConfiguration.load_cwctl_plugins()
    config = CubicWebConfiguration.config_for(endpoint)
    if numversion < (3, 19):
        sourceinfo = config.sources()['admin']
    else:
        sourceinfo = config.default_admin_config
    login = sourceinfo['login']
    password = sourceinfo['password']
    _, cnx = dbapi.in_memory_repo_cnx(config, login, password=password)
    req = cnx.request()
    return req
Beispiel #10
0
def available_cube_names(cwcfg):
    """Return a list of available cube names, with 'cubicweb_' prefix dropped.
    """
    def drop_prefix(cube):
        prefix = 'cubicweb_'
        if cube.startswith(prefix):
            cube = cube[len(prefix):]
        return cube

    return [drop_prefix(cube) for cube in cwcfg.available_cubes()]
Beispiel #11
0
 def _datadirs(self, config, repo=None):
     if repo is None:
         repo = config.repository()
     if config._cubes is None:
         # web only config
         config.init_cubes(repo.get_cubes())
     for cube in repo.get_cubes():
         cube_datadir = osp.join(cwcfg.cube_dir(cube), 'data')
         if osp.isdir(cube_datadir):
             yield cube_datadir
     yield _DATA_DIR
Beispiel #12
0
 def configure_instance(self, appid):
     if self.config.param is not None:
         appcfg = cwcfg.config_for(appid)
         for key, value in self.config.param.items():
             try:
                 appcfg.global_set_option(key, value)
             except KeyError:
                 raise ConfigurationError(
                     'unknown configuration key "%s" for mode %s' %
                     (key, appcfg.name))
         appcfg.save()
Beispiel #13
0
 def i18ninstance_instance(appid):
     """recompile instance's messages catalogs"""
     config = cwcfg.config_for(appid)
     config.quick_start = True  # notify this is not a regular start
     repo = config.repository()
     if config._cubes is None:
         # web only config
         config.init_cubes(repo.get_cubes())
     errors = config.i18ncompile()
     if errors:
         print('\n'.join(errors))
Beispiel #14
0
 def versions_instance(self, appid):
     config = cwcfg.config_for(appid)
     # should not raise error if db versions don't match fs versions
     config.repairing = True
     # no need to load all appobjects and schema
     config.quick_start = True
     if hasattr(config, 'set_sources_mode'):
         config.set_sources_mode(('migration', ))
     vcconf = config.repository().get_versions()
     for key in sorted(vcconf):
         print(key + ': %s.%s.%s' % vcconf[key])
Beispiel #15
0
def admincnx(appid):
    from cubicweb import repoapi
    from cubicweb.cwconfig import CubicWebConfiguration
    from cubicweb.server.repository import Repository
    config = CubicWebConfiguration.config_for(appid)

    login = config.default_admin_config['login']
    password = config.default_admin_config['password']

    repo = Repository(config)
    repo.bootstrap()
    return repoapi.connect(repo, login, password=password)
Beispiel #16
0
 def _get_mih(self, appid):
     """ returns migration context handler & shutdown function """
     config = cwcfg.config_for(appid)
     if self.config.ext_sources:
         assert not self.config.system_only
         sources = self.config.ext_sources
     elif self.config.system_only:
         sources = ('system',)
     else:
         sources = ('all',)
     config.set_sources_mode(sources)
     config.repairing = self.config.force
     mih = config.migration_handler()
     return mih, lambda: mih.shutdown()
Beispiel #17
0
def get_cw_repo(instance_name):
    """ Connect to a local instance using an in memory connection.

    Parameters
    ----------
    instance_name: str (mandatory)
        the name of the cw instance we want to connect.

    Returns
    -------
    repo: cubicweb Repository
        a cubicweb Repository object.
    """
    config = cwcfg.config_for(instance_name)
    return Repository(config, TasksManager())
Beispiel #18
0
 def i18nupgrade(self, config):
     # handle i18n upgrade:
     # * install new languages
     # * recompile catalogs
     # XXX search available language in the first cube given
     from cubicweb import i18n
     templdir = cwcfg.cube_dir(config.cubes()[0])
     langs = [lang for lang, _ in i18n.available_catalogs(join(templdir, 'i18n'))]
     errors = config.i18ncompile(langs)
     if errors:
         print('\n'.join(errors))
         if not ASK.confirm('Error while compiling message catalogs, '
                            'continue anyway?'):
             print('-> migration not completed.')
             return False
     return True
Beispiel #19
0
def wsgi_application(instance_name=None, debug=None):
    """ Build a WSGI application from a cubicweb instance name

    :param instance_name: Name of the cubicweb instance (optional). If not
                          provided, :envvar:`CW_INSTANCE` must exists.
    :param debug: Enable/disable the debug mode. If defined to True or False,
                  overrides :envvar:`CW_DEBUG`.

    The following environment variables are used if they exist:

    .. envvar:: CW_INSTANCE

        A CubicWeb instance name.

    .. envvar:: CW_DEBUG

        If defined, the debugmode is enabled.

    The function can be used as an entry-point for third-party wsgi containers.
    Below is a sample uswgi configuration file:

    .. code-block:: ini

        [uwsgi]
        http = 127.0.1.1:8080
        env = CW_INSTANCE=myinstance
        env = CW_DEBUG=1
        module = cubicweb.pyramid:wsgi_application()
        virtualenv = /home/user/.virtualenvs/myvirtualenv
        processes = 1
        threads = 8
        stats = 127.0.0.1:9191
        plugins = http,python

    """
    if instance_name is None:
        instance_name = os.environ['CW_INSTANCE']
    if debug is None:
        debug = 'CW_DEBUG' in os.environ

    cwconfig = cwcfg.config_for(instance_name, debugmode=debug)

    return wsgi_application_from_cwconfig(cwconfig)
def get_cw_connection(instance_name):
    """ Connect to a local instance using an in memory connection.

    Parameters
    ----------
    instance_name: str (mandatory)
        the name of the cw instance we want to connect.

    Returns
    -------
    mih: cubicweb.server.migractions.ServerMigrationHelper
        the server migration object that contains a 'session' and 'shutdown'
        attributes.
    """
    # Parse/configure the all in one configuration
    config = cwcfg.config_for(instance_name)
    sources = ("all",)
    config.set_sources_mode(sources)
    config.repairing = False

    # Create server migration helper
    mih = config.migration_handler()

    return mih
Beispiel #21
0
def schema_image():
    options = [
        ('output-file', {
            'type': 'file',
            'default': None,
            'metavar': '<file>',
            'short': 'o',
            'help': 'output image file'
        }),
        ('viewer', {
            'type': 'string',
            'default': "rsvg-view",
            'short': "w",
            'metavar': '<cmd>',
            'help': 'command use to view the generated file (empty for none)'
        }),
        ('lib-dir', {
            'type': 'string',
            'short': "L",
            'metavar': '<dir>',
            'help': 'directory to look for schema dependancies'
        }),
    ]

    config = Configuration(
        options=options,
        usage="yams-view [-L <lib_dir> | [[[...] deps] deps]] apps",
        version=version)
    dirnames = config.load_command_line_configuration()

    lib_dir = config['lib-dir']
    assert lib_dir is not None
    if lib_dir is not None:
        app_dir = dirnames[-1]
        from cubicweb.cwconfig import CubicWebConfiguration as cwcfg
        packages = cwcfg.expand_cubes(dirnames)
        packages = cwcfg.reorder_cubes(packages)
        packages = [pkg for pkg in packages if pkg != app_dir]
    elif False:
        glob = globals().copy()
        execfile(join(app_dir, "__pkginfo__.py"), glob)
        #dirnames = [ join(lib_dir,dep) for dep in glob['__use__']]+dirnames
        packages = [dep for dep in glob['__use__']]

    for dir in dirnames:
        assert exists(dir), dir

    import cubicweb
    cubicweb_dir = dirname(cubicweb.__file__)

    schm_ldr = SchemaLoader()

    class MockConfig(object):
        def packages(self):
            return packages

        def packages_path(self):
            return packages

        def schemas_lib_dir(self):
            return join(cubicweb_dir, "schemas")

        #def apphome(self):
        #    return lib_dir
        apphome = dirnames[0]

        def appid(self):
            "bob"

    print(MockConfig().packages())

    schema = schm_ldr.load(MockConfig())

    out, viewer = config['output-file'], config['viewer']
    if out is None:
        tmp_file = NamedTemporaryFile(suffix=".svg")
        out = tmp_file.name
    schema2dot.schema2dot(
        schema,
        out,  #size=size,
        skiprels=("identity", ),
        skipentities=("Person", "AbstractPerson", "Card", "AbstractCompany",
                      "Company", "Division"))
    if viewer:
        p = Popen((viewer, out))
        p.wait()

    return 0
Beispiel #22
0
from os import unlink
from os.path import isfile, join
from cubicweb.cwconfig import CubicWebConfiguration as cwcfg

regdir = cwcfg.instances_dir()

if isfile(join(regdir, 'startorder')):
    if confirm('The startorder file is not used anymore in Cubicweb 3.22. '
               'Should I delete it?',
               shell=False, pdb=False):
        unlink(join(regdir, 'startorder'))

Beispiel #23
0
 def __init__(self, config):
     self.config = config
     self.cubes = {'cubicweb': cwcfg.cubicweb_version()}
Beispiel #24
0
def includeme(config):
    """Set-up a CubicWeb instance.

    The CubicWeb instance can be set in several ways:

    -   Provide an already loaded CubicWeb repository in the registry:

        .. code-block:: python

            config.registry['cubicweb.repository'] = your_repo_instance

    -   Provide an already loaded CubicWeb config instance in the registry:

        .. code-block:: python

            config.registry['cubicweb.config'] = your_config_instance

    -   Provide an instance name in the pyramid settings with
        :confval:`cubicweb.instance`.

    A CubicWeb repository is instantiated and attached in
    'cubicweb.repository' registry key if not already present.

    The CubicWeb instance registry is attached in 'cubicweb.registry' registry
    key.
    """
    cwconfig = config.registry.get('cubicweb.config')
    repo = config.registry.get('cubicweb.repository')

    if repo is not None:
        if cwconfig is None:
            config.registry['cubicweb.config'] = cwconfig = repo.config
        elif cwconfig is not repo.config:
            raise ConfigurationError(
                'CubicWeb config instance (found in "cubicweb.config" '
                'registry key) mismatches with that of the repository '
                '(registry["cubicweb.repository"])')

    if cwconfig is None:
        debugmode = asbool(
            config.registry.settings.get('cubicweb.debug', False))
        cwconfig = cwcfg.config_for(
            config.registry.settings['cubicweb.instance'], debugmode=debugmode)
        config.registry['cubicweb.config'] = cwconfig

    if repo is None:
        repo = config.registry['cubicweb.repository'] = cwconfig.repository()
    config.registry['cubicweb.registry'] = repo.vreg

    if cwconfig.mode != 'test':

        @atexit.register
        def shutdown_repo():
            if repo.shutting_down:
                return
            repo.shutdown

    if asbool(config.registry.settings.get('cubicweb.defaults', True)):
        config.include('cubicweb.pyramid.defaults')

    for name in aslist(config.registry.settings.get('cubicweb.includes', [])):
        config.include(name)

    config.include('cubicweb.pyramid.core')

    if asbool(
            config.registry.settings.get('cubicweb.bwcompat',
                                         cwconfig.name == 'all-in-one')):
        if cwconfig.name != 'all-in-one':
            warnings.warn(
                '"cubicweb.bwcompat" setting only applies to '
                '"all-in-one" instance configuration', UserWarning)
        else:
            config.include('cubicweb.pyramid.bwcompat')
Beispiel #25
0
 def run(self, args):
     """run the command with its specific arguments"""
     for cube in cwcfg.available_cubes():
         print(cube)
Beispiel #26
0
 def run(self, args):
     """run the command with its specific arguments"""
     regdir = cwcfg.instances_dir()
     for appid in sorted(listdir(regdir)):
         print(appid)
Beispiel #27
0
    def pyramid_instance(self, appid):
        self._needreload = False

        debugmode = self['debug-mode'] or self['debug']
        autoreload = self['reload'] or self['debug']
        daemonize = not (self['no-daemon'] or debugmode or autoreload)

        cwconfig = cwcfg.config_for(appid, debugmode=debugmode)
        filelist_path = os.path.join(cwconfig.apphome,
                                     '.pyramid-reload-files.list')

        pyramid_ini_path = os.path.join(cwconfig.apphome, "pyramid.ini")
        if not os.path.exists(pyramid_ini_path):
            _generate_pyramid_ini_file(pyramid_ini_path)

        if autoreload and not os.environ.get(self._reloader_environ_key):
            return self.restart_with_reloader(filelist_path)

        if autoreload:
            _turn_sigterm_into_systemexit()
            self.debug('Running reloading file monitor')
            extra_files = [sys.argv[0]]
            extra_files.extend(self.configfiles(cwconfig))
            extra_files.extend(self.i18nfiles(cwconfig))
            self.install_reloader(self['reload-interval'],
                                  extra_files,
                                  filelist_path=filelist_path)

        if daemonize:
            self.daemonize(cwconfig['pid-file'])
            self.record_pid(cwconfig['pid-file'])

        if self['dbglevel']:
            self['loglevel'] = 'debug'
            set_debug('|'.join('DBG_' + x.upper() for x in self['dbglevel']))
        init_cmdline_log_threshold(cwconfig, self['loglevel'])

        app = wsgi_application_from_cwconfig(
            cwconfig,
            profile=self['profile'],
            profile_output=self['profile-output'],
            profile_dump_every=self['profile-dump-every'])

        host = cwconfig['interface']
        port = cwconfig['port'] or 8080
        url_scheme = ('https'
                      if cwconfig['base-url'].startswith('https') else 'http')
        repo = app.application.registry['cubicweb.repository']
        warnings.warn(
            'the "pyramid" command does not start repository "looping tasks" '
            'anymore; use the standalone "scheduler" command if needed')
        try:
            waitress.serve(app,
                           host=host,
                           port=port,
                           url_scheme=url_scheme,
                           clear_untrusted_proxy_headers=True)
        finally:
            repo.shutdown()
        if self._needreload:
            return 3
        return 0
Beispiel #28
0
 def run(self, args):
     """run the command with its specific arguments"""
     from logilab.common.textutils import splitstrip
     check_options_consistency(self.config)
     configname = self.config.config
     cubes, appid = args
     cubes = splitstrip(cubes)
     # get the configuration and helper
     config = cwcfg.config_for(appid, configname, creating=True)
     cubes = config.expand_cubes(cubes)
     config.init_cubes(cubes)
     helper = self.config_helper(config)
     # check the cube exists
     try:
         templdirs = [cwcfg.cube_dir(cube)
                      for cube in cubes]
     except ConfigurationError as ex:
         print(ex)
         print('\navailable cubes:', end=' ')
         print(', '.join(available_cube_names(cwcfg)))
         return
     # create the registry directory for this instance
     print('\n' + underline_title('Creating the instance %s' % appid))
     create_dir(config.apphome)
     # cubicweb-ctl configuration
     if not self.config.automatic:
         print('\n' + underline_title('Configuring the instance (%s.conf)'
                                      % configname))
         config.input_config('main', self.config.config_level)
     # configuration'specific stuff
     print()
     helper.bootstrap(cubes, self.config.automatic, self.config.config_level)
     # input for cubes specific options
     if not self.config.automatic:
         sections = set(sect.lower() for sect, opt, odict in config.all_options()
                        if 'type' in odict
                        and odict.get('level', 0) <= self.config.config_level)
         for section in sections:
             if section not in ('main', 'email', 'web'):
                 print('\n' + underline_title('%s options' % section))
                 config.input_config(section, self.config.config_level)
     # write down configuration
     config.save()
     print('-> generated config %s' % config.main_config_file())
     # handle i18n files structure
     # in the first cube given
     from cubicweb import i18n
     langs = [lang for lang, _ in i18n.available_catalogs(join(templdirs[0], 'i18n'))]
     errors = config.i18ncompile(langs)
     if errors:
         print('\n'.join(errors))
         if self.config.automatic \
             or not ASK.confirm('error while compiling message catalogs, '
                                'continue anyway ?'):
             print('creation not completed')
             return
     # create the additional data directory for this instance
     if config.appdatahome != config.apphome:  # true in dev mode
         create_dir(config.appdatahome)
     create_dir(join(config.appdatahome, 'backup'))
     if config['uid']:
         from logilab.common.shellutils import chown
         # this directory should be owned by the uid of the server process
         print('set %s as owner of the data directory' % config['uid'])
         chown(config.appdatahome, config['uid'])
     print('\n-> creation done for %s\n' % repr(config.apphome)[1:-1])
     if not self.config.no_db_create:
         helper.postcreate(self.config.automatic, self.config.config_level)
Beispiel #29
0
    def run(self, args):
        """run the command with its specific arguments"""
        if not args:
            mode = 'all'
        elif len(args) == 1:
            mode = args[0]
        else:
            raise BadCommandUsage('Too many arguments')

        from cubicweb.migration import ConfigurationProblem

        if mode == 'all':
            print('CubicWeb %s (%s mode)' % (cwcfg.cubicweb_version(), cwcfg.mode))
            print()

        if mode in ('all', 'config', 'configurations'):
            cwcfg.load_available_configs()
            print('Available configurations:')
            for config in CONFIGURATIONS:
                print('*', config.name)
                for line in config.__doc__.splitlines():
                    line = line.strip()
                    if not line:
                        continue
                    print('   ', line)
            print()

        if mode in ('all', 'cubes'):
            cfgpb = ConfigurationProblem(cwcfg)
            try:
                cube_names = available_cube_names(cwcfg)
                namesize = max(len(x) for x in cube_names)
            except ConfigurationError as ex:
                print('No cubes available:', ex)
            except ValueError:
                print('No cubes available')
            else:
                print('Available cubes:')
                for cube in cube_names:
                    try:
                        tinfo = cwcfg.cube_pkginfo(cube)
                        tversion = tinfo.version
                        cfgpb.add_cube(cube, tversion)
                    except (ConfigurationError, AttributeError) as ex:
                        tinfo = None
                        tversion = '[missing cube information: %s]' % ex
                    print('* %s %s' % (cube.ljust(namesize), tversion))
                    if self.config.verbose:
                        if tinfo:
                            descr = getattr(tinfo, 'description', '')
                            if not descr:
                                descr = tinfo.__doc__
                            if descr:
                                print('    ' + '    \n'.join(descr.splitlines()))
                        modes = detect_available_modes(cwcfg.cube_dir(cube))
                        print('    available modes: %s' % ', '.join(modes))
            print()

        if mode in ('all', 'instances'):
            try:
                regdir = cwcfg.instances_dir()
            except ConfigurationError as ex:
                print('No instance available:', ex)
                print()
                return
            instances = list_instances(regdir)
            if instances:
                print('Available instances (%s):' % regdir)
                for appid in instances:
                    modes = cwcfg.possible_configurations(appid)
                    if not modes:
                        print('* %s (BROKEN instance, no configuration found)' % appid)
                        continue
                    print('* %s (%s)' % (appid, ', '.join(modes)))
                    try:
                        config = cwcfg.config_for(appid, modes[0])
                    except Exception as exc:
                        print('    (BROKEN instance, %s)' % exc)
                        continue
            else:
                print('No instance available in %s' % regdir)
            print()

        if mode == 'all':
            # configuration management problem solving
            cfgpb.solve()
            if cfgpb.warnings:
                print('Warnings:\n', '\n'.join('* ' + txt for txt in cfgpb.warnings))
            if cfgpb.errors:
                print('Errors:')
                for op, cube, version, src in cfgpb.errors:
                    if op == 'add':
                        print('* cube', cube, end=' ')
                        if version:
                            print(' version', version, end=' ')
                        print('is not installed, but required by %s' % src)
                    else:
                        print(
                            '* cube %s version %s is installed, but version %s is required by %s'
                            % (cube, cfgpb.cubes[cube], version, src)
                        )
Beispiel #30
0
    def run(self, args):
        """run the <command>_method on each argument (a list of instance
        identifiers)
        """
        if not args:
            if "CW_INSTANCE" in os.environ:
                appid = os.environ["CW_INSTANCE"]
            else:
                raise BadCommandUsage("Error: instance id is missing")
        else:
            appid = args[0]

        cmdmeth = getattr(self, '%s_instance' % self.name)

        traceback_ = None

        # debugmode=True is to force to have a StreamHandler used instead of
        # writting the logs into a file in /tmp
        self.cwconfig = cwcfg.config_for(appid, debugmode=True)

        # by default loglevel is 'error' but we keep the default value to None
        # because some subcommands (e.g: pyramid) can override the loglevel in
        # certain situations if it's not explicitly set by the user and we want
        # to detect that (the "None" case)
        if self['loglevel'] is None:
            # if no loglevel is set but dbglevel is here we want to set level to debug
            if self['dbglevel']:
                init_cmdline_log_threshold(self.cwconfig, 'debug')
            else:
                init_cmdline_log_threshold(self.cwconfig, 'error')
        else:
            init_cmdline_log_threshold(self.cwconfig, self['loglevel'])

        if self['dbglevel']:
            set_debug('|'.join('DBG_' + x.upper() for x in self['dbglevel']))

        try:
            status = cmdmeth(appid) or 0
        except (ExecutionError, ConfigurationError) as ex:
            # we need to do extract this information here for pdb since it is
            # now lost in python 3 once we exit the try/catch statement
            exception_type, exception, traceback_ = sys.exc_info()

            sys.stderr.write('instance %s not %s: %s\n' % (
                appid, self.actionverb, ex))
            status = 4
        except Exception as ex:
            # idem
            exception_type, exception, traceback_ = sys.exc_info()

            traceback.print_exc()

            sys.stderr.write('instance %s not %s: %s\n' % (
                appid, self.actionverb, ex))
            status = 8

        except (KeyboardInterrupt, SystemExit) as ex:
            # idem
            exception_type, exception, traceback_ = sys.exc_info()

            sys.stderr.write('%s aborted\n' % self.name)
            if isinstance(ex, KeyboardInterrupt):
                status = 2  # specific error code
            else:
                status = ex.code

        if status != 0 and self.config.pdb:
            pdb = utils.get_pdb()

            if traceback_ is not None:
                pdb.post_mortem(traceback_)
            else:
                print("WARNING: Could not access to the traceback because the command return "
                      "code is different than 0 but the command didn't raised an exception.")
                # we can't use "header=" of set_trace because ipdb doesn't supports it
                pdb.set_trace()

        sys.exit(status)