Example #1
0
 def run(self, args):
     from yams.diff import schema_diff
     from cubicweb import repoapi
     appid = args.pop(0)
     diff_tool = args.pop(0)
     config = ServerConfiguration.config_for(appid)
     config.repairing = True
     repo = repoapi.get_repository(config=config)
     fsschema = config.load_schema(expand_cubes=True)
     schema_diff(fsschema,
                 repo.schema,
                 permissionshandler,
                 diff_tool,
                 ignore=('eid', ))
Example #2
0
def repo_cnx(config):
    """return a in-memory repository and a repoapi connection to it"""
    from cubicweb import repoapi
    from cubicweb.server.utils import manager_userpasswd
    try:
        login = config.default_admin_config['login']
        pwd = config.default_admin_config['password']
    except KeyError:
        login, pwd = manager_userpasswd()
    while True:
        try:
            repo = repoapi.get_repository(config=config)
            cnx = repoapi.connect(repo, login, password=pwd)
            return repo, cnx
        except AuthenticationError:
            print('-> Error: wrong user/password.')
            # reset cubes else we'll have an assertion error on next retry
            config._cubes = None
        login, pwd = manager_userpasswd()
Example #3
0
    def run(self, args):
        from cubicweb import repoapi
        from cubicweb.cwctl import init_cmdline_log_threshold
        config = ServerConfiguration.config_for(args[0])
        config.global_set_option('log-file', None)
        config.log_format = '%(levelname)s %(name)s: %(message)s'
        init_cmdline_log_threshold(config, self['loglevel'])
        repo = repoapi.get_repository(config=config)
        repo.hm.call_hooks('server_maintenance', repo=repo)
        errors = False
        with repo.internal_cnx() as cnx:
            sources = []
            if len(args) >= 2:
                for name in args[1:]:
                    try:
                        source = repo.source_by_uri(name)
                    except ValueError:
                        cnx.error('no source named %r' % name)
                        errors = True
                    else:
                        sources.append(source)
            else:
                for uri, source in repo.sources_by_uri.items():
                    if (uri != 'system' and repo.config.source_enabled(source)
                            and source.config['synchronize']):
                        sources.append(source)

            for source in sources:
                try:
                    stats = source.pull_data(cnx,
                                             force=self['force'],
                                             raise_on_error=True)
                except Exception:
                    cnx.exception('while trying to update source %s', source)
                    errors = True
                else:
                    for key, val in stats.items():
                        if val:
                            print(key, ':', val)

        if errors:
            raise ExecutionError('All sources where not synced')
Example #4
0
def init_repository(config,
                    interactive=True,
                    drop=False,
                    vreg=None,
                    init_config=None):
    """Initialise a repository database by creating tables and filling them
    with the minimal set of entities (ie at least the schema, base groups and
    a initial user)
    """
    from cubicweb.repoapi import get_repository, connect
    from cubicweb.server.repository import Repository
    from cubicweb.server.utils import manager_userpasswd
    from cubicweb.server.sqlutils import sqlexec, sqlschema, sql_drop_all_user_tables
    from cubicweb.server.sqlutils import _SQL_DROP_ALL_USER_TABLES_FILTER_FUNCTION as drop_filter
    # configuration to avoid db schema loading and user'state checking
    # on connection
    config.creating = True
    config.consider_user_state = False
    config.cubicweb_appobject_path = set(('hooks', 'entities'))
    config.cube_appobject_path = set(('hooks', 'entities'))
    # only enable the system source at initialization time
    repo = Repository(config, vreg=vreg)
    repo.bootstrap()
    if init_config is not None:
        # further config initialization once it has been bootstrapped
        init_config(config)
    schema = repo.schema
    sourcescfg = config.read_sources_file()
    source = sourcescfg['system']
    driver = source['db-driver']
    with repo.internal_cnx() as cnx:
        sqlcnx = cnx.cnxset.cnx
        sqlcursor = cnx.cnxset.cu
        execute = sqlcursor.execute
        if drop:
            helper = database.get_db_helper(driver)
            dropsql = sql_drop_all_user_tables(helper, sqlcursor)
            # We may fail dropping some tables because of table dependencies, in a first pass.
            # So, we try a second drop sequence to drop remaining tables if needed.
            # Note that 2 passes is an arbitrary choice as it seems enough for our usecases
            # (looping may induce infinite recursion when user have no rights for example).
            # Here we try to keep code simple and backend independent. That's why we don't try to
            # distinguish remaining tables (missing privileges, dependencies, ...).
            failed = sqlexec(dropsql,
                             execute,
                             cnx=sqlcnx,
                             pbtitle='-> dropping tables (first pass)')
            if failed:
                failed = sqlexec(failed,
                                 execute,
                                 cnx=sqlcnx,
                                 pbtitle='-> dropping tables (second pass)')
                remainings = list(
                    filter(drop_filter, helper.list_tables(sqlcursor)))
                assert not remainings, 'Remaining tables: %s' % ', '.join(
                    remainings)
        handler = config.migration_handler(schema,
                                           interactive=False,
                                           repo=repo,
                                           cnx=cnx)
        # install additional driver specific sql files
        handler.cmd_install_custom_sql_scripts()
        for cube in reversed(config.cubes()):
            handler.cmd_install_custom_sql_scripts(cube)
        _title = '-> creating tables '
        print(_title, end=' ')
        # schema entities and relations tables
        # can't skip entities table even if system source doesn't support them,
        # they are used sometimes by generated sql. Keeping them empty is much
        # simpler than fixing this...
        schemasql = sqlschema(schema, driver)
        failed = sqlexec(schemasql, execute, pbtitle=_title)
        if failed:
            print(
                'The following SQL statements failed. You should check your schema.'
            )
            print(failed)
            raise Exception(
                'execution of the sql schema failed, you should check your schema'
            )
        sqlcursor.close()
        sqlcnx.commit()
    with repo.internal_cnx() as cnx:
        # insert entity representing the system source
        ssource = cnx.create_entity('CWSource', type=u'native', name=u'system')
        repo.system_source.eid = ssource.eid
        cnx.execute('SET X cw_source X WHERE X eid %(x)s', {'x': ssource.eid})
        # insert base groups and default admin
        print('-> inserting default user and default groups.')
        try:
            login = sourcescfg['admin']['login']
            pwd = sourcescfg['admin']['password']
        except KeyError:
            if interactive:
                msg = 'enter login and password of the initial manager account'
                login, pwd = manager_userpasswd(msg=msg, confirm=True)
            else:
                login, pwd = source['db-user'], source['db-password']
        # sort for eid predicatability as expected in some server tests
        for group in sorted(BASE_GROUPS):
            cnx.create_entity('CWGroup', name=group)
        admin = create_user(cnx, login, pwd, u'managers')
        cnx.execute(
            'SET X owned_by U WHERE X is IN (CWGroup,CWSource), U eid %(u)s',
            {'u': admin.eid})
        cnx.commit()
    repo.shutdown()
    # re-login using the admin user
    config._cubes = None  # avoid assertion error
    repo = get_repository(config=config)
    # replace previous schema by the new repo's one. This is necessary so that we give the proper
    # schema to `initialize_schema` above since it will initialize .eid attribute of schema elements
    schema = repo.schema
    with connect(repo, login, password=pwd) as cnx:
        with cnx.security_enabled(False, False):
            repo.system_source.eid = ssource.eid  # redo this manually
            handler = config.migration_handler(schema,
                                               interactive=False,
                                               cnx=cnx,
                                               repo=repo)
            # serialize the schema
            initialize_schema(config, schema, handler)
            # yoo !
            cnx.commit()
            repo.system_source.init_creating()
            cnx.commit()
    repo.shutdown()
    # restore initial configuration
    config.creating = False
    config.consider_user_state = True
    # (drop instance attribute to get back to class attribute)
    del config.cubicweb_appobject_path
    del config.cube_appobject_path
    print('-> database for instance %s initialized.' % config.appid)