def handle_add_component(args):
    init_logger(args.verbose if 'verbose' in args else None)

    client = setup_client(args.product_url)

    with open(args.component_file, 'r',
              encoding="utf-8", errors="ignore") as component_file:
        value = component_file.read().strip()

    description = args.description if 'description' in args else None

    check_unicode_string(args.name, "Component name")

    if description:
        check_unicode_string(args.description, "Component description")

    # Check that the given source component is exists.
    source_component = client.getSourceComponents([args.name])

    if source_component:
        LOG.info("The source component '%s' already exist!", args.name)

        question = 'Do you want to update? Y(es)/n(o) '
        if not get_user_input(question):
            LOG.info("No source component update was done.")
            sys.exit(0)

    success = client.addSourceComponent(args.name, value, description)
    if success:
        LOG.info("Source component added.")
    else:
        LOG.error("An error occurred when adding source component.")
        sys.exit(1)
Beispiel #2
0
def handle_add_component(args):
    init_logger(args.verbose if 'verbose' in args else None)

    client = setup_client(args.product_url)

    if args.name == GEN_OTHER_COMPONENT_NAME:
        LOG.error(
            "'%s' is a special virtual component which can not be "
            "modified.", GEN_OTHER_COMPONENT_NAME)
        sys.exit(1)

    with open(args.component_file, 'r', encoding="utf-8",
              errors="ignore") as component_file:
        value = component_file.read().strip()

    description = args.description if 'description' in args else None

    # Check that the given source component is exists.
    source_component = client.getSourceComponents([args.name])

    if source_component:
        LOG.info("The source component '%s' already exist!", args.name)

        question = 'Do you want to update? Y(es)/n(o) '
        if not get_user_input(question):
            LOG.info("No source component update was done.")
            sys.exit(0)

    success = client.addSourceComponent(args.name, value, description)
    if success:
        LOG.info("Source component added.")
    else:
        LOG.error("An error occurred when adding source component.")
        sys.exit(1)
Beispiel #3
0
def server_init_start(args):
    """
    Start or manage a CodeChecker report server.
    """

    if 'list' in args or 'stop' in args or 'stop_all' in args:
        __instance_management(args)
        sys.exit(0)

    if 'reload' in args:
        __reload_config(args)
        sys.exit(0)

    # Actual server starting from this point.
    if not host_check.check_zlib():
        raise Exception("zlib is not available on the system!")

    # WARNING
    # In case of SQLite args.dbaddress default value is used
    # for which the is_localhost should return true.
    if is_localhost(args.dbaddress) and \
            not os.path.exists(args.config_directory):
        os.makedirs(args.config_directory)

    # Make sure the SQLite file can be created if it not exists.
    if 'sqlite' in args and \
            not os.path.isdir(os.path.dirname(args.sqlite)):
        os.makedirs(os.path.dirname(args.sqlite))

    if 'reset_root' in args:
        try:
            os.remove(os.path.join(args.config_directory, 'root.user'))
            LOG.info("Master superuser (root) credentials invalidated and "
                     "deleted. New ones will be generated...")
        except OSError:
            # File doesn't exist.
            pass

    if 'force_auth' in args:
        LOG.info("'--force-authentication' was passed as a command-line "
                 "option. The server will ask for users to authenticate!")

    context = webserver_context.get_context()
    context.codechecker_workspace = args.config_directory
    context.db_username = args.dbusername

    environ = env.extend(context.path_env_extra, context.ld_lib_path_extra)

    cfg_sql_server = database.SQLServer.from_cmdline_args(
        vars(args),
        CONFIG_META,
        context.config_migration_root,
        interactive=True,
        env=environ)

    LOG.info("Checking configuration database ...")
    db_status = cfg_sql_server.connect()
    db_status_msg = database_status.db_status_msg.get(db_status)
    LOG.info(db_status_msg)

    if db_status == DBStatus.SCHEMA_MISSING:
        LOG.debug("Config database schema is missing, initializing new.")
        db_status = cfg_sql_server.connect(init=True)
        if db_status != DBStatus.OK:
            LOG.error("Config database initialization failed!")
            LOG.error("Please check debug logs.")
            sys.exit(1)

    if db_status == DBStatus.SCHEMA_MISMATCH_NO:
        LOG.debug("Configuration database schema mismatch.")
        LOG.debug("No schema upgrade is possible.")
        sys.exit(1)

    force_upgrade = True if 'force_upgrade' in args else False

    if db_status == DBStatus.SCHEMA_MISMATCH_OK:
        LOG.debug("Configuration database schema mismatch.")
        LOG.debug("Schema upgrade is possible.")
        LOG.warning("Please note after migration only "
                    "newer CodeChecker versions can be used "
                    "to start the server")
        LOG.warning("It is advised to make a full backup of your "
                    "configuration database")

        LOG.warning(cfg_sql_server.get_db_location())

        question = 'Do you want to upgrade to the new schema?' \
                   ' Y(es)/n(o) '
        if force_upgrade or env.get_user_input(question):
            print("Upgrading schema ...")
            ret = cfg_sql_server.upgrade()
            msg = database_status.db_status_msg.get(ret,
                                                    'Unknown database status')
            print(msg)
            if ret != DBStatus.OK:
                LOG.error("Schema migration failed")
                sys.exit(ret)
        else:
            LOG.info("No schema migration was done.")
            sys.exit(0)

    if db_status == DBStatus.MISSING:
        LOG.error("Missing configuration database.")
        LOG.error("Server can not be started.")
        sys.exit(1)

    # Configuration database setup and check is needed before database
    # statuses can be checked.
    try:
        if args.status:
            ret = __db_status_check(cfg_sql_server, context.migration_root,
                                    environ, args.status)
            sys.exit(ret)
    except AttributeError:
        LOG.debug('Status was not in the arguments.')

    try:
        if args.product_to_upgrade:
            ret = __db_migration(cfg_sql_server, context.migration_root,
                                 environ, args.product_to_upgrade,
                                 force_upgrade)
            sys.exit(ret)
    except AttributeError:
        LOG.debug('Product upgrade was not in the arguments.')

    # Create the main database link from the arguments passed over the
    # command line.
    cfg_dir = os.path.abspath(args.config_directory)
    default_product_path = os.path.join(cfg_dir, 'Default.sqlite')
    create_default_product = 'sqlite' in args and \
                             not os.path.exists(default_product_path)

    if create_default_product:
        # Create a default product and add it to the configuration database.

        LOG.debug("Create default product...")
        LOG.debug("Configuring schema and migration...")

        prod_server = database.SQLiteDatabase(default_product_path, RUN_META,
                                              context.run_migration_root,
                                              environ)

        LOG.debug("Checking 'Default' product database.")
        db_status = prod_server.connect()
        if db_status != DBStatus.MISSING:
            db_status = prod_server.connect(init=True)
            LOG.debug(database_status.db_status_msg.get(db_status))
            if db_status != DBStatus.OK:
                LOG.error("Failed to configure default product")
                sys.exit(1)

        product_conn_string = prod_server.get_connection_string()

        server.add_initial_run_database(cfg_sql_server, product_conn_string)

        LOG.info("Product 'Default' at '%s' created and set up.",
                 default_product_path)

    prod_statuses = check_product_db_status(cfg_sql_server,
                                            context.run_migration_root,
                                            environ)

    upgrade_available = {}
    for k, v in prod_statuses.items():
        db_status, _, _, _ = v
        if db_status == DBStatus.SCHEMA_MISMATCH_OK or \
                db_status == DBStatus.SCHEMA_MISSING:
            upgrade_available[k] = v

    if upgrade_available:
        print_prod_status(prod_statuses)
        LOG.warning("Multiple products can be upgraded, make a backup!")
        __db_migration(cfg_sql_server, context.run_migration_root, environ,
                       'all', force_upgrade)

    prod_statuses = check_product_db_status(cfg_sql_server,
                                            context.run_migration_root,
                                            environ)
    print_prod_status(prod_statuses)

    non_ok_db = False
    for k, v in prod_statuses.items():
        db_status, _, _, _ = v
        if db_status != DBStatus.OK:
            non_ok_db = True
        break

    if non_ok_db:
        msg = "There are some database issues. " \
              "Do you want to start the " \
              "server? Y(es)/n(o) "
        if not env.get_user_input(msg):
            sys.exit(1)

    # Start database viewer.
    checker_md_docs = os.path.join(context.doc_root, 'checker_md_docs')
    checker_md_docs_map = os.path.join(checker_md_docs, 'checker_doc_map.json')
    checker_md_docs_map = util.load_json_or_empty(checker_md_docs_map, {})

    package_data = {
        'www_root': context.www_root,
        'doc_root': context.doc_root,
        'checker_md_docs': checker_md_docs,
        'checker_md_docs_map': checker_md_docs_map,
        'version': context.package_git_tag
    }

    try:
        server.start_server(args.config_directory, package_data,
                            args.view_port, cfg_sql_server,
                            args.listen_address, 'force_auth' in args,
                            args.skip_db_cleanup, context, environ)
    except socket.error as err:
        if err.errno == errno.EADDRINUSE:
            LOG.error(
                "Server can't be started, maybe the given port number "
                "(%s) is already used. Check the connection "
                "parameters.", args.view_port)
            sys.exit(1)
        else:
            raise
Beispiel #4
0
def __db_migration(cfg_sql_server,
                   migration_root,
                   environ,
                   product_to_upgrade='all',
                   force_upgrade=False):
    """
    Handle database management.
    Schema checking and migration.
    """
    LOG.info("Preparing schema upgrade for %s", str(product_to_upgrade))
    product_name = product_to_upgrade

    prod_statuses = check_product_db_status(cfg_sql_server, migration_root,
                                            environ)
    prod_to_upgrade = []

    if product_name != 'all':
        avail = prod_statuses.get(product_name)
        if not avail:
            LOG.error("No product was found with this endpoint: %s",
                      product_name)
            return 1
        prod_to_upgrade.append(product_name)
    else:
        prod_to_upgrade = list(prod_statuses.keys())

    LOG.warning("Please note after migration only "
                "newer CodeChecker versions can be used "
                "to start the server")
    LOG.warning("It is advised to make a full backup of your "
                "run databases.")

    for prod in prod_to_upgrade:
        LOG.info("========================")
        LOG.info("Checking: %s", prod)
        engine = cfg_sql_server.create_engine()
        config_session = sessionmaker(bind=engine)
        sess = config_session()

        product = sess.query(ORMProduct).filter(
            ORMProduct.endpoint == prod).first()
        db = database.SQLServer.from_connection_string(product.connection,
                                                       RUN_META,
                                                       migration_root,
                                                       interactive=False,
                                                       env=environ)

        db_status = db.connect()

        msg = database_status.db_status_msg.get(db_status,
                                                'Unknown database status')

        LOG.info(msg)
        if db_status == DBStatus.SCHEMA_MISSING:
            question = 'Do you want to initialize a new schema for ' \
                        + product.endpoint + '? Y(es)/n(o) '
            if force_upgrade or env.get_user_input(question):
                ret = db.connect(init=True)
                msg = database_status.db_status_msg.get(
                    ret, 'Unknown database status')
                LOG.info(msg)
            else:
                LOG.info("No schema initialization was done.")

        elif db_status == DBStatus.SCHEMA_MISMATCH_OK:
            question = 'Do you want to upgrade to new schema for ' \
                        + product.endpoint + '? Y(es)/n(o) '
            if force_upgrade or env.get_user_input(question):
                LOG.info("Upgrading schema ...")
                ret = db.upgrade()
                LOG.info("Done.")
                msg = database_status.db_status_msg.get(
                    ret, 'Unknown database status')
                LOG.info(msg)
            else:
                LOG.info("No schema migration was done.")

        sess.commit()
        sess.close()
        engine.dispose()
        LOG.info("========================")
    return 0