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', ))
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()
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')
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)