Exemple #1
0
def archive_logfiles():
    """ Archive log files from a previous run of Leapp """
    cfg = get_config()

    if not os.path.isdir(cfg.get('logs', 'dir')):
        os.makedirs(cfg.get('logs', 'dir'))

    files_to_archive = [os.path.join(cfg.get('logs', 'dir'), f)
                        for f in cfg.get('logs', 'files').split(',')
                        if os.path.isfile(os.path.join(cfg.get('logs', 'dir'), f))]

    if not os.path.isdir(cfg.get('archive', 'dir')):
        os.makedirs(cfg.get('archive', 'dir'))

    if files_to_archive:
        if os.path.isdir(cfg.get('debug', 'dir')):
            files_to_archive.append(cfg.get('debug', 'dir'))

        now = datetime.now().strftime('%Y%m%d%H%M%S')
        archive_file = os.path.join(cfg.get('archive', 'dir'), 'leapp-{}-logs.tar.gz'.format(now))

        with tarfile.open(archive_file, "w:gz") as tar:
            for file_to_add in files_to_archive:
                tar.add(file_to_add)
                if os.path.isdir(file_to_add):
                    shutil.rmtree(file_to_add, ignore_errors=True)
                try:
                    os.remove(file_to_add)
                except OSError:
                    pass
            # leapp_db is not in files_to_archive to not have it removed
            if os.path.isfile(cfg.get('database', 'path')):
                tar.add(cfg.get('database', 'path'))
Exemple #2
0
def answer(args):
    """A command to record user choices to the questions in the answerfile.
       Saves user answer between leapp preupgrade runs.
    """
    cfg = get_config()
    if args.section:
        args.section = list(
            itertools.chain(*[i.split(',') for i in args.section]))
    else:
        raise UsageError(
            'At least one dialog section must be specified, ex. --section dialog.option=mychoice'
        )
    try:
        sections = [
            tuple((dialog_option.split('.', 2) + [value])) for dialog_option,
            value in [s.split('=', 2) for s in args.section]
        ]
    except ValueError:
        raise UsageError(
            "A bad formatted section has been passed. Expected format is dialog.option=mychoice"
        )
    answerfile_path = cfg.get('report', 'answerfile')
    answerstore = AnswerStore()
    answerstore.load(answerfile_path)
    for dialog, option, value in sections:
        answerstore.answer(dialog, option, value)
    not_updated = answerstore.update(answerfile_path, allow_missing=args.add)
    if not_updated:
        sys.stderr.write(
            "WARNING: Only sections found in original userfile can be updated, ignoring {}\n"
            .format(",".join(not_updated)))
Exemple #3
0
def test_migrations_are_applied():
    con = sqlite3.connect(get_config().get('database', 'path'))
    con.executescript(_ORIGINAL_DB_SCHEMA)
    assert con.execute("PRAGMA user_version").fetchone()[0] == 0
    con.close()

    with get_connection(None) as db:
        assert db.execute("PRAGMA user_version").fetchone()[0] > 0
Exemple #4
0
def upgrade(args):
    skip_phases_until = None
    context = str(uuid.uuid4())
    cfg = get_config()
    configuration = prepare_configuration(args)
    answerfile_path = cfg.get('report', 'answerfile')
    userchoices_path = cfg.get('report', 'userchoices')

    if os.getuid():
        raise CommandError('This command has to be run under the root user.')
    handle_output_level(args)

    if args.resume:
        context, configuration = fetch_last_upgrade_context()
        if not context:
            raise CommandError('No previous upgrade run to continue, remove `--resume` from leapp invocation to'
                               'start a new upgrade flow')
        os.environ['LEAPP_DEBUG'] = '1' if check_env_and_conf('LEAPP_DEBUG', 'debug', configuration) else '0'

        if os.environ['LEAPP_DEBUG'] == '1' or check_env_and_conf('LEAPP_VERBOSE', 'verbose', configuration):
            os.environ['LEAPP_VERBOSE'] = '1'
        else:
            os.environ['LEAPP_VERBOSE'] = '0'

        skip_phases_until = get_last_phase(context)
        logger = configure_logger()
    else:
        e = Execution(context=context, kind='upgrade', configuration=configuration)
        e.store()
        archive_logfiles()
        logger = configure_logger('leapp-upgrade.log')
    os.environ['LEAPP_EXECUTION_ID'] = context

    if args.resume:
        logger.info("Resuming execution after phase: %s", skip_phases_until)
    try:
        repositories = load_repositories()
    except LeappError as exc:
        raise CommandError(exc.message)
    workflow = repositories.lookup_workflow('IPUWorkflow')(auto_reboot=args.reboot)
    process_whitelist_experimental(repositories, workflow, configuration, logger)
    warn_if_unsupported(configuration)
    with beautify_actor_exception():
        logger.info("Using answerfile at %s", answerfile_path)
        workflow.load_answers(answerfile_path, userchoices_path)
        workflow.run(context=context, skip_phases_until=skip_phases_until, skip_dialogs=True)

    logger.info("Answerfile will be created at %s", answerfile_path)
    workflow.save_answers(answerfile_path, userchoices_path)
    report_errors(workflow.errors)
    report_inhibitors(context)
    generate_report_files(context)
    report_files = get_cfg_files('report', cfg)
    log_files = get_cfg_files('logs', cfg)
    report_info(report_files, log_files, answerfile_path, fail=workflow.failure)

    if workflow.failure:
        sys.exit(1)
Exemple #5
0
def preupgrade(args):
    if os.getuid():
        raise CommandError('This command has to be run under the root user.')

    if args.whitelist_experimental:
        args.whitelist_experimental = list(
            itertools.chain(
                *[i.split(',') for i in args.whitelist_experimental]))
    context = str(uuid.uuid4())
    configuration = {
        'debug': os.getenv('LEAPP_DEBUG', '0'),
        'verbose': os.getenv('LEAPP_VERBOSE', '0'),
        'whitelist_experimental': args.whitelist_experimental or ()
    }
    e = Execution(context=context,
                  kind='preupgrade',
                  configuration=configuration)
    e.store()
    archive_logfiles()
    logger = configure_logger('leapp-preupgrade.log')
    os.environ['LEAPP_EXECUTION_ID'] = context

    try:
        repositories = load_repositories()
    except LeappError as exc:
        raise CommandError(exc.message)
    workflow = repositories.lookup_workflow('IPUWorkflow')()
    for actor_name in configuration.get('whitelist_experimental', ()):
        actor = repositories.lookup_actor(actor_name)
        if actor:
            workflow.whitelist_experimental_actor(actor)
        else:
            msg = 'No such Actor: {}'.format(actor_name)
            logger.error(msg)
            raise CommandError(msg)
    with beautify_actor_exception():
        until_phase = 'ReportsPhase'
        logger.info('Executing workflow until phase: %s', until_phase)
        workflow.run(context=context,
                     until_phase=until_phase,
                     skip_dialogs=True)

    cfg = get_config()
    answerfile = args.save_answerfile or cfg.get('report', 'answerfile')
    logger.info("Answerfile will be created at %s", answerfile)
    workflow._answer_store.generate_for_workflow(workflow, answerfile)
    generate_report_files(context)
    report_errors(workflow.errors)

    report_files = [
        os.path.join(cfg.get('report', 'dir'), r)
        for r in cfg.get('report', 'files').split(',')
    ]
    report_info([rf for rf in report_files if os.path.isfile(rf)],
                fail=workflow.failure)
    if workflow.failure:
        sys.exit(1)
Exemple #6
0
def generate_report_files(context):
    """
    Generates all report files for specific leapp run (txt and json format)
    """
    cfg = get_config()
    report_txt, report_json = [os.path.join(cfg.get('report', 'dir'),
                                            'leapp-report.{}'.format(f)) for f in ['txt', 'json']]
    # fetch all report messages as a list of dicts
    messages = fetch_upgrade_report_messages(context)
    generate_report_file(messages, context, report_json)
    generate_report_file(messages, context, report_txt)
Exemple #7
0
def get_connection(db):
    """
    Get the database connection or passes it through if it is already set

    :param db: Database connection to be passed through in case it exists already
    :return: database object initialized and migrated to the latest schema version
    """
    if db:
        return db
    cfg = get_config()
    return create_connection(cfg.get('database', 'path'))
def preupgrade(args, breadcrumbs):
    context = str(uuid.uuid4())
    cfg = get_config()
    util.handle_output_level(args)
    configuration = util.prepare_configuration(args)
    answerfile_path = cfg.get('report', 'answerfile')
    userchoices_path = cfg.get('report', 'userchoices')

    if os.getuid():
        raise CommandError('This command has to be run under the root user.')
    e = Execution(context=context,
                  kind='preupgrade',
                  configuration=configuration)
    e.store()
    util.archive_logfiles()
    logger = configure_logger('leapp-preupgrade.log')
    os.environ['LEAPP_EXECUTION_ID'] = context

    try:
        repositories = util.load_repositories()
    except LeappError as exc:
        raise CommandError(exc.message)
    workflow = repositories.lookup_workflow('IPUWorkflow')()
    util.warn_if_unsupported(configuration)
    util.process_whitelist_experimental(repositories, workflow, configuration,
                                        logger)
    with beautify_actor_exception():
        workflow.load_answers(answerfile_path, userchoices_path)
        until_phase = 'ReportsPhase'
        logger.info('Executing workflow until phase: %s', until_phase)

        # Set the locale, so that the actors parsing command outputs that might be localized will not fail
        os.environ['LC_ALL'] = 'en_US.UTF-8'
        os.environ['LANG'] = 'en_US.UTF-8'
        workflow.run(context=context,
                     until_phase=until_phase,
                     skip_dialogs=True)

    logger.info("Answerfile will be created at %s", answerfile_path)
    workflow.save_answers(answerfile_path, userchoices_path)
    util.generate_report_files(context)
    report_errors(workflow.errors)
    report_inhibitors(context)
    report_files = util.get_cfg_files('report', cfg)
    log_files = util.get_cfg_files('logs', cfg)
    report_info(report_files,
                log_files,
                answerfile_path,
                fail=workflow.failure)
    if workflow.failure:
        sys.exit(1)
Exemple #9
0
def preupgrade(args):
    if os.getuid():
        raise CommandError('This command has to be run under the root user.')

    if args.whitelist_experimental:
        args.whitelist_experimental = list(itertools.chain(*[i.split(',') for i in args.whitelist_experimental]))
    context = str(uuid.uuid4())
    configuration = {
        'debug': os.getenv('LEAPP_DEBUG', '0'),
        'verbose': os.getenv('LEAPP_VERBOSE', '0'),
        'whitelist_experimental': args.whitelist_experimental or ()
    }
    e = Execution(context=context, kind='preupgrade', configuration=configuration)
    e.store()
    archive_logfiles()
    logger = configure_logger('leapp-preupgrade.log')
    os.environ['LEAPP_EXECUTION_ID'] = context

    try:
        repositories = load_repositories()
    except LeappError as exc:
        raise CommandError(exc.message)
    workflow = repositories.lookup_workflow('IPUWorkflow')()
    for actor_name in configuration.get('whitelist_experimental', ()):
        actor = repositories.lookup_actor(actor_name)
        if actor:
            workflow.whitelist_experimental_actor(actor)
        else:
            msg = 'No such Actor: {}'.format(actor_name)
            logger.error(msg)
            raise CommandError(msg)
    with beautify_actor_exception():
        until_phase = 'ReportsPhase'
        logger.info('Executing workflow until phase: %s', until_phase)
        workflow.run(context=context, until_phase=until_phase)

    report_errors(workflow.errors)

    report_txt, report_json = [os.path.join(get_config().get('report', 'dir'),
                                            'leapp-report.{}'.format(f)) for f in ['txt', 'json']]
    report_info([report_txt, report_json], fail=workflow.errors)
    # fetch all report messages as a list of dicts
    messages = fetch_upgrade_report_raw(context, renderers=False)
    with open(report_json, 'w+') as f:
        json.dump({'entries': messages}, f, indent=2)
    if workflow.failure:
        sys.exit(1)
Exemple #10
0
def configure_logger(log_file=None):
    global _logger
    if not _logger:
        log_format = '%(asctime)s.%(msecs)-3d %(levelname)-8s PID: %(process)d %(name)s: %(message)s'
        log_date_format = '%Y-%m-%d %H:%M:%S'
        path = os.getenv('LEAPP_LOGGER_CONFIG', '/etc/leapp/logger.conf')

        if path and os.path.isfile(path):
            logging.config.fileConfig(path)
        else:  # Fall back logging configuration
            logging.Formatter.converter = time.gmtime
            logging.basicConfig(
                level=logging.ERROR,
                format=log_format,
                datefmt=log_date_format,
                stream=sys.stderr,
            )
            logging.getLogger('urllib3').setLevel(logging.WARN)
            handler = LeappAuditHandler()
            handler.setFormatter(
                logging.Formatter(fmt=log_format, datefmt=log_date_format))
            logging.getLogger('leapp').addHandler(handler)

        if log_file:
            file_handler = logging.FileHandler(
                os.path.join(get_config().get('logs', 'dir'), log_file))
            file_handler.setFormatter(
                logging.Formatter(fmt=log_format, datefmt=log_date_format))
            file_handler.setLevel(logging.DEBUG)
            logging.getLogger('leapp').addHandler(file_handler)

        if is_verbose():
            for handler in logging.getLogger().handlers:
                if isinstance(handler, logging.StreamHandler):
                    handler.setLevel(
                        logging.DEBUG if is_debug() else logging.INFO)

        _logger = logging.getLogger('leapp')
        _logger.info('Logging has been initialized')

    return _logger
Exemple #11
0
def setup():
    path = get_config().get('database', 'path')
    if os.path.isfile(path):
        os.unlink(path)
Exemple #12
0
def setup_module():
    get_config().set('database', 'path', '/tmp/leapp-test.db')
Exemple #13
0
def load_repositories_from(name, repo_path, manager=None):
    if get_config().has_option('repositories', name):
        repo_path = get_config().get('repositories', name)
    return find_and_scan_repositories(repo_path, manager=manager)
Exemple #14
0
def upgrade(args, breadcrumbs):
    skip_phases_until = None
    context = str(uuid.uuid4())
    cfg = get_config()
    util.handle_output_level(args)
    answerfile_path = cfg.get('report', 'answerfile')
    userchoices_path = cfg.get('report', 'userchoices')

    # Processing of parameters passed by the rerun call, these aren't actually command line arguments
    # therefore we have to assume that they aren't even in `args` as they are added only by rerun.
    only_with_tags = args.only_with_tags if 'only_with_tags' in args else None
    resume_context = args.resume_context if 'resume_context' in args else None

    report_schema = util.process_report_schema(args, cfg)

    if os.getuid():
        raise CommandError('This command has to be run under the root user.')

    if args.resume:
        context, configuration = util.fetch_last_upgrade_context(resume_context)
        if not context:
            raise CommandError('No previous upgrade run to continue, remove `--resume` from leapp invocation to'
                               ' start a new upgrade flow')
        os.environ['LEAPP_DEBUG'] = '1' if util.check_env_and_conf('LEAPP_DEBUG', 'debug', configuration) else '0'

        if os.environ['LEAPP_DEBUG'] == '1' or util.check_env_and_conf('LEAPP_VERBOSE', 'verbose', configuration):
            os.environ['LEAPP_VERBOSE'] = '1'
        else:
            os.environ['LEAPP_VERBOSE'] = '0'
        util.restore_leapp_env_vars(context)
        skip_phases_until = util.get_last_phase(context)
    else:
        util.disable_database_sync()
        configuration = util.prepare_configuration(args)
        e = Execution(context=context, kind='upgrade', configuration=configuration)
        e.store()
        util.archive_logfiles()

    logger = configure_logger('leapp-upgrade.log')
    os.environ['LEAPP_EXECUTION_ID'] = context

    if args.resume:
        logger.info("Resuming execution after phase: %s", skip_phases_until)
    try:
        repositories = util.load_repositories()
    except LeappError as exc:
        raise CommandError(exc.message)
    workflow = repositories.lookup_workflow('IPUWorkflow')(auto_reboot=args.reboot)
    util.process_whitelist_experimental(repositories, workflow, configuration, logger)
    util.warn_if_unsupported(configuration)
    with beautify_actor_exception():
        logger.info("Using answerfile at %s", answerfile_path)
        workflow.load_answers(answerfile_path, userchoices_path)

        # Set the locale, so that the actors parsing command outputs that might be localized will not fail
        os.environ['LC_ALL'] = 'en_US.UTF-8'
        os.environ['LANG'] = 'en_US.UTF-8'
        workflow.run(context=context, skip_phases_until=skip_phases_until, skip_dialogs=True,
                     only_with_tags=only_with_tags)

    logger.info("Answerfile will be created at %s", answerfile_path)
    workflow.save_answers(answerfile_path, userchoices_path)
    report_errors(workflow.errors)
    report_inhibitors(context)
    util.generate_report_files(context, report_schema)
    report_files = util.get_cfg_files('report', cfg)
    log_files = util.get_cfg_files('logs', cfg)
    report_info(report_files, log_files, answerfile_path, fail=workflow.failure)

    if workflow.failure:
        sys.exit(1)
Exemple #15
0
@command_opt('whitelist-experimental', action='append', metavar='ActorName', help='Enable experimental actors')
@command_opt('debug', is_flag=True, help='Enable debug mode', inherit=False)
@command_opt('verbose', is_flag=True, help='Enable verbose logging', inherit=False)
@command_opt('no-rhsm', is_flag=True, help='Use only custom repositories and skip actions'
                                           ' with Red Hat Subscription Manager')
@command_opt('enablerepo', action='append', metavar='<repoid>',
             help='Enable specified repository. Can be used multiple times.')
@command_opt('channel',
             help='Set preferred channel for the IPU target.',
             choices=['ga', 'tuv', 'e4s', 'eus', 'aus'],
             value_type=str.lower)  # This allows the choices to be case insensitive
@command_opt('target', choices=command_utils.get_supported_target_versions(),
             help='Specify RHEL version to upgrade to for {} detected upgrade flavour'.format(
                 command_utils.get_upgrade_flavour()))
@command_opt('report-schema', help='Specify report schema version for leapp-report.json', choices=['1.0.0', '1.1.0'],
             default=get_config().get('report', 'schema'))
@breadcrumbs.produces_breadcrumbs
def upgrade(args, breadcrumbs):
    skip_phases_until = None
    context = str(uuid.uuid4())
    cfg = get_config()
    util.handle_output_level(args)
    answerfile_path = cfg.get('report', 'answerfile')
    userchoices_path = cfg.get('report', 'userchoices')

    # Processing of parameters passed by the rerun call, these aren't actually command line arguments
    # therefore we have to assume that they aren't even in `args` as they are added only by rerun.
    only_with_tags = args.only_with_tags if 'only_with_tags' in args else None
    resume_context = args.resume_context if 'resume_context' in args else None

    report_schema = util.process_report_schema(args, cfg)
Exemple #16
0
def upgrade(args):
    if os.getuid():
        raise CommandError('This command has to be run under the root user.')

    if args.whitelist_experimental:
        args.whitelist_experimental = list(
            itertools.chain(
                *[i.split(',') for i in args.whitelist_experimental]))
    skip_phases_until = None
    context = str(uuid.uuid4())
    configuration = {
        'debug': os.getenv('LEAPP_DEBUG', '0'),
        'verbose': os.getenv('LEAPP_VERBOSE', '0'),
        'whitelist_experimental': args.whitelist_experimental or ()
    }
    if args.resume:
        context, configuration = fetch_last_upgrade_context()
        if not context:
            raise CommandError(
                'No previous upgrade run to continue, remove `--resume` from leapp invocation to'
                'start a new upgrade flow')
        os.environ['LEAPP_DEBUG'] = '1' if check_env_and_conf(
            'LEAPP_DEBUG', 'debug', configuration) else '0'

        if os.environ['LEAPP_DEBUG'] == '1' or check_env_and_conf(
                'LEAPP_VERBOSE', 'verbose', configuration):
            os.environ['LEAPP_VERBOSE'] = '1'
        else:
            os.environ['LEAPP_VERBOSE'] = '0'

        skip_phases_until = get_last_phase(context)
        logger = configure_logger()
    else:
        e = Execution(context=context,
                      kind='upgrade',
                      configuration=configuration)
        e.store()
        archive_logfiles()
        logger = configure_logger('leapp-upgrade.log')
    os.environ['LEAPP_EXECUTION_ID'] = context

    if args.resume:
        logger.info("Resuming execution after phase: %s", skip_phases_until)
    try:
        repositories = load_repositories()
    except LeappError as exc:
        raise CommandError(exc.message)
    workflow = repositories.lookup_workflow('IPUWorkflow')(
        auto_reboot=args.reboot)
    for actor_name in configuration.get('whitelist_experimental', ()):
        actor = repositories.lookup_actor(actor_name)
        if actor:
            workflow.whitelist_experimental_actor(actor)
        else:
            msg = 'No such Actor: {}'.format(actor_name)
            logger.error(msg)
            raise CommandError(msg)
    with beautify_actor_exception():
        answerfile_path = args.load_answerfile or get_config().get(
            'report', 'answerfile')
        logger.info("Using answerfile at %s", answerfile_path)
        workflow.load_answerfile(answerfile_path)
        workflow.run(context=context, skip_phases_until=skip_phases_until)

    report_errors(workflow.errors)
    generate_report_files(context)

    if workflow.failure:
        sys.exit(1)