示例#1
0
def report(args):
    if os.getuid():
        raise CommandError('This command has to be run under the root user.')

    id = args.id or fetch_last_upgrade_context()[0]

    if not id:
        raise CommandError(
            'No previous Leapp upgrade run found. This command can only be run after "leapp upgrade" has been executed'
        )

    # FIXME: add proper default and choices parameters for the format option
    if args.format not in ('html', 'plaintext'):
        print(
            'No / not supported renderer provided as --format (available renderers: "html", "plaintext"). '
            'Defaulting to "plaintext"',
            file=sys.stdout,
            end='\n\n')
        renderer = 'plaintext'
    else:
        renderer = args.format

    messages = fetch_upgrade_report_messages(id, renderer)
    if not messages:
        raise CommandError(
            'No upgrade report messages found for context {}'.format(id))

    print(messages, file=sys.stdout)
示例#2
0
文件: __init__.py 项目: examon/leapp
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)
示例#3
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)
示例#4
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():
        workflow.run(context=context, skip_phases_until=skip_phases_until)

    report_errors(workflow.errors)

    if workflow.failure:
        sys.exit(1)
示例#5
0
def rerun(args):

    if os.environ.get('LEAPP_UNSUPPORTED') != '1':
        raise CommandError('This command requires the environment variable LEAPP_UNSUPPORTED="1" to be set!')

    if args.from_phase not in RERUN_SUPPORTED_PHASES:
        raise CommandError('This command is only supported for {}'.format(', '.join(RERUN_SUPPORTED_PHASES)))

    context = str(uuid.uuid4())
    last_context, configuration = util.fetch_last_upgrade_context()
    phases = [chkpt['phase'] for chkpt in util.get_checkpoints(context=last_context)]
    if args.from_phase not in set(phases):
        raise CommandError('Phase {} has not been executed in the last leapp upgrade execution. '
                           'Cannot rerun not executed phase'.format(args.from_phase))

    if not last_context:
        raise CommandError('No previous upgrade run to rerun - '
                           'leapp upgrade has to be run before leapp rerun can be used')

    with get_connection(None) as db:
        e = Execution(context=context, kind='rerun', configuration=configuration)

        e.store(db)

        clone_context(last_context, context, db)
        db.execute('''
            DELETE FROM audit WHERE id IN (
                SELECT
                    audit.id          AS id
                FROM
                    audit
                JOIN
                    data_source ON data_source.id = audit.data_source_id
                WHERE
                    audit.context = ? AND audit.event = 'checkpoint'
                    AND data_source.phase LIKE 'FirstBoot%'
            );
        ''', (context,))
        db.execute('''DELETE FROM message WHERE context = ? and type = 'ErrorModel';''', (context,))

    util.archive_logfiles()
    upgrade(Namespace(  # pylint: disable=no-value-for-parameter
        resume=True,
        resume_context=context,
        only_with_tags=args.only_actors_with_tag or [],
        debug=args.debug,
        verbose=args.verbose,
        reboot=False,
        no_rhsm=False,
        channel=None,
        whitelist_experimental=[],
        enablerepo=[]))
示例#6
0
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)
示例#7
0
def cli(args):
    model_name = args.model_name
    basedir = find_repository_basedir('.')

    basedir = os.path.join(basedir, 'models')
    if not os.path.isdir(basedir):
        os.mkdir(basedir)

    model_path = os.path.join(basedir, model_name.lower() + '.py')
    if os.path.exists(model_path):
        raise CommandError("File already exists: {}".format(model_path))
    topic_usage = 'None #  TODO: import appropriate topic and set it here'
    topic_import = ''
    if args.topic:
        topic_usage = args.topic
        topic_import = 'from leapp.topics import {}\n'.format(args.topic)

    with open(model_path, 'w') as f:
        f.write('''from leapp.models import Model, fields
{topic_import}

class {model_name}(Model):
    topic = {topic_usage}
'''.format(model_name=make_class_name(model_name), topic_import=topic_import, topic_usage=topic_usage))

    sys.stdout.write("New model {} has been created in {}\n".format(make_class_name(model_name),
                                                                    os.path.realpath(model_path)))
示例#8
0
    def impl(context=None):
        configure_logger()
        repository = find_and_scan_repositories(find_repository_basedir('.'),
                                                include_locals=True)
        try:
            repository.load()
        except LeappError as exc:
            sys.stderr.write(exc.message)
            sys.stderr.write('\n')
            sys.exit(1)

        wf = repository.lookup_workflow(params.name)
        if not wf:
            raise CommandError('Could not find any workflow named "{}"'.format(
                params.name))

        instance = wf()
        for actor_name in params.whitelist_experimental or ():
            actor = repository.lookup_actor(actor_name)
            if actor:
                instance.whitelist_experimental_actor(actor)

        with beautify_actor_exception():
            instance.run(context=context,
                         until_phase=params.until_phase,
                         until_actor=params.until_actor)

        report_errors(instance.errors)
示例#9
0
文件: run.py 项目: fellipeh/leapp
def cli(args):
    log = configure_logger()
    basedir = find_repository_basedir('.')
    repository = find_and_scan_repositories(basedir, include_locals=True)
    try:
        repository.load()
    except LeappError as exc:
        sys.stderr.write(exc.message)
        sys.stderr.write('\n')
        sys.exit(1)
    actor_logger = log.getChild('actors')
    actor = repository.lookup_actor(args.actor_name)
    if not actor:
        raise CommandError('Actor "{}" not found!'.format(args.actor_name))
    messaging = InProcessMessaging(stored=args.save_output)
    messaging.load(actor.consumes)

    failure = False
    with beautify_actor_exception():
        try:
            actor(messaging=messaging, logger=actor_logger).run()
        except BaseException:
            failure = True
            raise

    report_errors(messaging.errors())

    if failure or messaging.errors():
        sys.exit(1)

    if args.print_output:
        json.dump(messaging.messages(), sys.stdout, indent=2)
        sys.stdout.write('\n')
示例#10
0
def cli(args):
    topic_name = args.topic_name
    basedir = find_repository_basedir('.')

    basedir = os.path.join(basedir, 'topics')
    if not os.path.isdir(basedir):
        os.mkdir(basedir)

    topic_path = os.path.join(basedir, topic_name.lower() + '.py')
    if os.path.exists(topic_path):
        raise CommandError("File already exists: {}".format(topic_path))

    topic_path = os.path.join(basedir, topic_name.lower() + '.py')
    topic_class_name = make_class_name(topic_name)
    if not topic_class_name.endswith('Topic'):
        topic_class_name += 'Topic'
    with open(topic_path, 'w') as f:
        f.write('''from leapp.topics import Topic


class {topic_name}(Topic):
    name = '{topic}'
'''.format(topic_name=topic_class_name, topic=make_name(topic_name)))

    sys.stdout.write("New topic {} has been created in {}\n".format(topic_class_name, os.path.realpath(topic_path)))
示例#11
0
def process_report_schema(args, configuration):
    default_report_schema = configuration.get('report', 'schema')
    if args.report_schema and args.report_schema > default_report_schema:
        raise CommandError(
            '--report-schema version can not be greater that the '
            'actual {} one.'.format(default_report_schema))
    return args.report_schema or default_report_schema
示例#12
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)
示例#13
0
def list_runs(args):  # noqa; pylint: disable=unused-argument
    contexts = fetch_all_upgrade_contexts()
    if contexts:
        for context in contexts:
            print('Context ID: {} - time: {} - details: {}'.format(context[0], context[1], json.loads(context[2])),
                  file=sys.stdout)
    else:
        raise CommandError('No previous run found!')
示例#14
0
def cli(args):
    actor_name = args.actor_name
    basedir = find_repository_basedir('.')

    tag_imports = ''
    model_imports = ''
    if args.tag:
        tag_imports = '\nfrom leapp.tags import {}'.format(', '.join(
            tuple(map(lambda x: x.split('.')[0], args.tag))))
    if args.consumes or args.produces:
        models = set((args.produces or []) + (args.consumes or []))
        model_imports = '\nfrom leapp.models import {}'.format(
            ', '.join(models))

    tags_content = '({})'.format(as_quoted_tuple(args.tag))
    consumes_content = '({})'.format(as_quoted_tuple(args.consumes))
    produces_content = '({})'.format(as_quoted_tuple(args.produces))

    actors_dir = os.path.join(basedir, 'actors')
    if not os.path.isdir(actors_dir):
        os.mkdir(actors_dir)

    actor_dir = os.path.join(actors_dir, actor_name.lower())
    if not os.path.isdir(actor_dir):
        os.mkdir(actor_dir)

    actor_test_dir = os.path.join(actor_dir, 'tests')
    if not os.path.isdir(actor_test_dir):
        os.mkdir(actor_test_dir)

    actor_path = os.path.join(actor_dir, 'actor.py')
    if os.path.exists(actor_path):
        raise CommandError("File already exists: {}".format(actor_path))

    with open(actor_path, 'w') as f:
        f.write('''from leapp.actors import Actor{model_imports}{tag_imports}


class {actor_class}(Actor):
    name = '{actor_name}'
    description = 'No description has been provided for the {actor_name} actor.'
    consumes = {consumes_content}
    produces = {produces_content}
    tags = {tags_content}

    def process(self):
        pass
'''.format(actor_class=make_class_name(actor_name),
           actor_name=make_name(actor_name),
           tags_content=tags_content,
           produces_content=produces_content,
           consumes_content=consumes_content,
           model_imports=model_imports,
           tag_imports=tag_imports))

    sys.stdout.write("New actor {} has been created at {}\n".format(
        make_class_name(actor_name), os.path.realpath(actor_path)))
    return os.path.dirname(os.path.realpath(actor_path))
示例#15
0
def process_whitelist_experimental(repositories, workflow, configuration, logger=None):
    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)
            if logger:
                logger.error(msg)
            raise CommandError(msg)
示例#16
0
def check_version(version):
    """
    Versioning schema: MAJOR.MINOR
    In case version contains an invalid version string, an CommandError will be raised.

    :raises: CommandError
    :return: release tuple
    """
    if not re.match(VERSION_REGEX, version):
        raise CommandError('Unexpected format of target version: {}'.format(version))
    return version.split('.')[0]
示例#17
0
文件: run.py 项目: jmazanek/leapp
def cli(params):
    configure_logger()
    repository = find_and_scan_repositories(find_repository_basedir('.'), include_locals=True)
    try:
        repository.load()
    except LeappError as exc:
        sys.stderr.write(exc.message)
        sys.exit(1)

    wf = repository.lookup_workflow(params.name)
    if not wf:
        raise CommandError('Could not find any workflow named "{}"'.format(params.name))

    instance = wf()
    instance.run(until_phase=params.until_phase, until_actor=params.until_actor)
    report_errors(instance.errors)
示例#18
0
    def _load_ini(cls, inifile):
        """
        Loads an ini config file from the given location.

        :param inifile: Path to the answer file to load.
        :return: configparser.SafeConfigParser object
        :raises CommandError if any of the values are not in key=value format
        """
        conf = configparser.SafeConfigParser(allow_no_value=False)
        try:
            conf.read(inifile)
            return conf
        except configparser.ParsingError as exc:
            # Some of the sections were not in key = value format
            raise CommandError('Failed to load answer file {inifile} with the following errors: {errors}'.format(
                inifile=inifile, errors=exc.message))
示例#19
0
def new_repository(args):
    name = args.name
    basedir = os.path.join('.', name)
    if os.path.isdir(basedir):
        raise CommandError("Directory already exists: {}".format(basedir))

    os.mkdir(basedir)
    repository_dir = os.path.join(basedir, '.leapp')
    os.mkdir(repository_dir)
    with open(os.path.join(repository_dir, 'info'), 'w') as f:
        json.dump({'name': name}, f)
    with open(os.path.join(repository_dir, 'leapp.conf'), 'w') as f:
        f.write(_REPOSITORY_CONFIG)

    register_path(basedir)
    sys.stdout.write("New repository {} has been created in {}\n".format(
        name, os.path.realpath(name)))
示例#20
0
def cli(args):
    basedir = os.path.join(find_repository_basedir('.'), 'tags')
    if not os.path.isdir(basedir):
        os.mkdir(basedir)

    tag_path = os.path.join(basedir, args.tag_name.lower() + '.py')
    if os.path.exists(tag_path):
        raise CommandError("File already exists: {}".format(tag_path))

    with open(tag_path, 'w') as f:
        f.write('''from leapp.tags import Tag


class {tag_name}Tag(Tag):
    name = '{tag}'
'''.format(tag_name=make_class_name(args.tag_name),
           tag=make_name(args.tag_name)))

    sys.stdout.write("New tag {} has been created in {}\n".format(
        make_class_name(args.tag_name), os.path.realpath(tag_path)))
示例#21
0
文件: run.py 项目: vojtechsokol/leapp
def cli(args):
    start = datetime.datetime.utcnow()
    log = configure_logger()
    basedir = find_repository_basedir('.')
    repository = find_and_scan_repositories(basedir, include_locals=True)
    try:
        repository.load()
    except LeappError as exc:
        sys.stderr.write(exc.message)
        sys.stderr.write('\n')
        sys.exit(1)
    actor_logger = log.getChild('actors')
    actor = repository.lookup_actor(args.actor_name)
    if not actor:
        raise CommandError('Actor "{}" not found!'.format(args.actor_name))
    config_model = getattr(import_module('leapp.models'),
                           args.actor_config) if args.actor_config else None
    messaging = InProcessMessaging(stored=args.save_output,
                                   config_model=config_model)
    messaging.load(actor.consumes)

    failure = False
    with beautify_actor_exception():
        try:
            actor(messaging=messaging,
                  logger=actor_logger,
                  config_model=config_model).run()
        except BaseException:
            failure = True
            raise

    report_errors(messaging.errors())
    report_deprecations(os.getenv('LEAPP_EXECUTION_ID'), start=start)

    if failure or messaging.errors():
        sys.exit(1)

    if args.print_output:
        json.dump(messaging.messages(), sys.stdout, indent=2)
        sys.stdout.write('\n')
示例#22
0
def vet_upgrade_path(args):
    """
    Make sure the user requested upgrade_path is a supported one.
    If LEAPP_DEVEL_TARGET_RELEASE is set then it's value is not vetted against upgrade_paths_map but used as is.

    :raises: `CommandError` if the specified upgrade_path is not supported
    :return: `tuple` (target_release, flavor)
    """
    flavor = get_upgrade_flavour()
    env_version_override = os.getenv('LEAPP_DEVEL_TARGET_RELEASE')
    if env_version_override:
        check_version(env_version_override)
        return (env_version_override, flavor)
    target_release = args.target or get_target_version(flavor)
    supported_target_versions = get_supported_target_versions(flavor)
    if target_release not in supported_target_versions:
        raise CommandError(
            "Upgrade to {to} for {flavor} upgrade path is not supported, possible choices are {choices}"
            .format(to=target_release,
                    flavor=flavor,
                    choices=','.join(supported_target_versions)))
    return (target_release, flavor)
示例#23
0
def cli(params):
    configure_logger()
    repository = find_and_scan_repositories(find_repository_basedir('.'),
                                            include_locals=True)
    try:
        repository.load()
    except LeappError as exc:
        sys.stderr.write(exc.message)
        sys.stderr.write('\n')
        sys.exit(1)

    wf = repository.lookup_workflow(params.name)
    if not wf:
        raise CommandError('Could not find any workflow named "{}"'.format(
            params.name))

    instance = wf()
    produced_late = set(instance.initial).intersection(set(instance.produces))
    if produced_late:
        print_fail(
            _DESCRIPTION.format(' '.join([m.__name__ for m in produced_late])))
        sys.exit(1)
示例#24
0
    def run(self,
            context=None,
            until_phase=None,
            until_actor=None,
            skip_phases_until=None):
        """
        Executes the workflow

        :param context: Custom execution ID to be used instead of a randomly generated UUIDv4
        :type context: str
        :param until_phase: Specify until including which phase the execution should run - phase.stage can be used to
                            control it even more granularly. `phase` is any phase name where `stage` refers to `main`,
                            `before` or `after`. If no stage is defined, `after` is assumed to be the default value.
                            The execution ends when this phase (and stage, if specified) has been executed.
        :type until_phase: str
        :param until_actor: The execution finishes when this actor has been executed.
        :type until_actor: str
        :param skip_phases_until: Skips all phases until including the phase specified, and then continues the
               execution.
        :type skip_phases_until: str or None

        """
        context = context or str(uuid.uuid4())
        os.environ['LEAPP_EXECUTION_ID'] = context
        if not os.environ.get('LEAPP_HOSTNAME', None):
            os.environ['LEAPP_HOSTNAME'] = socket.getfqdn()

        self.log.info('Starting workflow execution: {name} - ID: {id}'.format(
            name=self.name, id=os.environ['LEAPP_EXECUTION_ID']))

        skip_phases_until = (skip_phases_until or '').lower()
        needle_phase = until_phase or ''
        needle_stage = None
        if '.' in needle_phase:
            needle_phase, needle_stage = needle_phase.split('.', 1)
        needle_phase = needle_phase.lower()
        needle_stage = (needle_stage or '').lower()
        needle_actor = (until_actor or '').lower()

        self._errors = get_errors(context)
        config_model = type(self).configuration

        for phase in skip_phases_until, needle_phase:
            if phase and not self.is_valid_phase(phase):
                raise CommandError(
                    'Phase {phase} does not exist in the workflow'.format(
                        phase=phase))

        for phase in self._phase_actors:
            os.environ['LEAPP_CURRENT_PHASE'] = phase[0].name
            if skip_phases_until:
                if skip_phases_until in phase_names(phase):
                    skip_phases_until = ''
                self.log.info(
                    'Skipping phase {name}'.format(name=phase[0].name))
                continue

            self.log.info('Starting phase {name}'.format(name=phase[0].name))
            current_logger = self.log.getChild(phase[0].name)

            early_finish = False
            for stage in phase[1:]:
                if early_finish:
                    return
                current_logger.info(
                    "Starting stage {stage} of phase {phase}".format(
                        phase=phase[0].name, stage=stage.stage))
                for actor in stage.actors:
                    if early_finish:
                        return
                    designation = ''
                    if ExperimentalTag in actor.tags:
                        designation = '[EXPERIMENTAL]'
                        if actor not in self.experimental_whitelist:
                            current_logger.info(
                                "Skipping experimental actor {actor}".format(
                                    actor=actor.name))
                            continue
                    current_logger.info(
                        "Executing actor {actor} {designation}".format(
                            designation=designation, actor=actor.name))
                    messaging = InProcessMessaging(config_model=config_model)
                    messaging.load(actor.consumes)
                    instance = actor(logger=current_logger,
                                     messaging=messaging,
                                     config_model=config_model)
                    try:
                        instance.run()
                    except BaseException:
                        self._unhandled_exception = True
                        raise

                    # Collect errors
                    if messaging.errors():
                        self._errors.extend(messaging.errors())

                        if phase[
                                0].policies.error is Policies.Errors.FailImmediately:
                            self.log.info(
                                'Workflow interrupted due to FailImmediately error policy'
                            )
                            early_finish = True
                            break

                    checkpoint(actor=actor.name,
                               phase=phase[0].name,
                               context=context,
                               hostname=os.environ['LEAPP_HOSTNAME'])
                    if needle_actor in actor_names(actor):
                        self.log.info(
                            'Workflow finished due to the until-actor flag')
                        early_finish = True
                        break
                if not stage.actors:
                    checkpoint(actor='',
                               phase=phase[0].name + '.' + stage.stage,
                               context=context,
                               hostname=os.environ['LEAPP_HOSTNAME'])

                if needle_phase in phase_names(
                        phase) and needle_stage == stage.stage.lower():
                    self.log.info(
                        'Workflow finished due to the until-phase flag')
                    early_finish = True
                    break

            checkpoint(actor='',
                       phase=phase[0].name,
                       context=context,
                       hostname=os.environ['LEAPP_HOSTNAME'])

            if self._errors and phase[
                    0].policies.error is Policies.Errors.FailPhase:
                self.log.info(
                    'Workflow interrupted due to the FailPhase error policy')
                early_finish = True

            elif needle_phase in phase_names(phase):
                self.log.info('Workflow finished due to the until-phase flag')
                early_finish = True

            elif phase[0].flags.request_restart_after_phase or phase[
                    0].flags.restart_after_phase:
                reboot = True
                if phase[
                        0].flags.request_restart_after_phase and not self._auto_reboot:
                    reboot = False
                    messaging.request_answers(
                        RawMessageDialog(
                            message=
                            'A reboot is required to continue. Please reboot your system.'
                        ))
                if reboot:
                    self.log.info(
                        'Initiating system reboot due to the restart_after_reboot flag'
                    )
                    reboot_system()
                early_finish = True
            elif phase[0].flags.is_checkpoint:
                self.log.info(
                    'Stopping the workflow execution due to the is_checkpoint flag'
                )
                early_finish = True

            if early_finish:
                return
示例#25
0
    def run(self,
            context=None,
            until_phase=None,
            until_actor=None,
            skip_phases_until=None,
            skip_dialogs=False,
            only_with_tags=None):
        """
        Executes the workflow

        :param context: Custom execution ID to be used instead of a randomly generated UUIDv4
        :type context: str
        :param until_phase: Specify until including which phase the execution should run - phase.stage can be used to
                            control it even more granularly. `phase` is any phase name where `stage` refers to `main`,
                            `before` or `after`. If no stage is defined, `after` is assumed to be the default value.
                            The execution ends when this phase (and stage, if specified) has been executed.
        :type until_phase: str
        :param until_actor: The execution finishes when this actor has been executed.
        :type until_actor: str
        :param skip_phases_until: Skips all phases until including the phase specified, and then continues the
               execution.
        :type skip_phases_until: str or None
        :param skip_dialogs: Inform actors about the mode of dialogs processing. If skip_dialogs is set to True it
                             means that dialogs can't be processed in the current workflow run interactively and
                             every attempted call of get_answers api method will be non-blocking, returning an empty
                             dict if no user choice was found in answerfile or a selected option otherwise.
                             If skip_dialogs is set to False then in case of absent recorded answer the dialog will
                             be rendered in a blocking user input requiring way.
                             The value of skip_dialogs will be passed to the actors that can theoretically use it for
                             their purposes.
        :type skip_dialogs: bool
        :param only_with_tags: Executes only actors with the given tag, any other actor is going to get skipped.
        :type only_with_tags: List[str]

        """
        context = context or str(uuid.uuid4())
        os.environ['LEAPP_EXECUTION_ID'] = context
        if not os.environ.get('LEAPP_HOSTNAME', None):
            os.environ['LEAPP_HOSTNAME'] = socket.getfqdn()

        self.log.info('Starting workflow execution: {name} - ID: {id}'.format(
            name=self.name, id=os.environ['LEAPP_EXECUTION_ID']))

        skip_phases_until = (skip_phases_until or '').lower()
        needle_phase = until_phase or ''
        needle_stage = None
        if '.' in needle_phase:
            needle_phase, needle_stage = needle_phase.split('.', 1)
        needle_phase = needle_phase.lower()
        needle_stage = (needle_stage or '').lower()
        needle_actor = (until_actor or '').lower()

        self._errors = get_errors(context)
        config_model = type(self).configuration

        for phase in skip_phases_until, needle_phase:
            if phase and not self.is_valid_phase(phase):
                raise CommandError(
                    'Phase {phase} does not exist in the workflow'.format(
                        phase=phase))

        self._stop_after_phase_requested = False
        for phase in self._phase_actors:
            os.environ['LEAPP_CURRENT_PHASE'] = phase[0].name
            if skip_phases_until:
                if skip_phases_until in phase_names(phase):
                    skip_phases_until = ''
                self.log.info(
                    'Skipping phase {name}'.format(name=phase[0].name))
                continue

            display_status_current_phase(phase)
            self.log.info('Starting phase {name}'.format(name=phase[0].name))
            current_logger = self.log.getChild(phase[0].name)

            early_finish = False
            for stage in phase[1:]:
                if early_finish:
                    return
                current_logger.info(
                    "Starting stage {stage} of phase {phase}".format(
                        phase=phase[0].name, stage=stage.stage))
                for actor in stage.actors:
                    if early_finish:
                        return
                    designation = ''
                    if ExperimentalTag in actor.tags:
                        designation = '[EXPERIMENTAL]'
                        if actor not in self.experimental_whitelist:
                            current_logger.info(
                                "Skipping experimental actor {actor}".format(
                                    actor=actor.name))
                            continue

                    if only_with_tags and not contains_tag(
                            only_with_tags, actor.tags):
                        current_logger.info(
                            "Actor {actor} does not contain any required tag. Skipping."
                            .format(actor=actor.name))
                        continue

                    display_status_current_actor(actor,
                                                 designation=designation)
                    current_logger.info(
                        "Executing actor {actor} {designation}".format(
                            designation=designation, actor=actor.name))
                    messaging = InProcessMessaging(
                        config_model=config_model,
                        answer_store=self._answer_store)
                    messaging.load(actor.consumes)
                    instance = actor(logger=current_logger,
                                     messaging=messaging,
                                     config_model=config_model,
                                     skip_dialogs=skip_dialogs)
                    try:
                        instance.run()
                    except BaseException:
                        self._unhandled_exception = True
                        raise

                    self._stop_after_phase_requested = messaging.stop_after_phase or self._stop_after_phase_requested

                    # Collect dialogs
                    self._dialogs.extend(messaging.dialogs())
                    # Collect errors
                    if messaging.errors():
                        self._errors.extend(messaging.errors())

                        if phase[
                                0].policies.error is Policies.Errors.FailImmediately:
                            self.log.info(
                                'Workflow interrupted due to FailImmediately error policy'
                            )
                            early_finish = True
                            break

                    for command in messaging.commands:
                        if command[
                                'command'] == SkipPhasesUntilCommand.COMMAND:
                            skip_phases_until = command['arguments'][
                                'until_phase']
                            self.log.info(
                                'SkipPhasesUntilCommand received. Skipping phases until {}'
                                .format(skip_phases_until))

                    checkpoint(actor=actor.name,
                               phase=phase[0].name,
                               context=context,
                               hostname=os.environ['LEAPP_HOSTNAME'])
                    if needle_actor in actor_names(actor):
                        self.log.info(
                            'Workflow finished due to the until-actor flag')
                        early_finish = True
                        break
                if not stage.actors:
                    checkpoint(actor='',
                               phase=phase[0].name + '.' + stage.stage,
                               context=context,
                               hostname=os.environ['LEAPP_HOSTNAME'])

                if needle_phase in phase_names(
                        phase) and needle_stage == stage.stage.lower():
                    self.log.info(
                        'Workflow finished due to the until-phase flag')
                    early_finish = True
                    break

            checkpoint(actor='',
                       phase=phase[0].name,
                       context=context,
                       hostname=os.environ['LEAPP_HOSTNAME'])

            if self._errors and phase[
                    0].policies.error is Policies.Errors.FailPhase:
                self.log.info(
                    'Workflow interrupted due to the FailPhase error policy')
                early_finish = True

            elif needle_phase in phase_names(phase):
                self.log.info('Workflow finished due to the until-phase flag')
                early_finish = True

            elif self._stop_after_phase_requested:
                self.log.info('Workflow received request to stop after phase.')
                early_finish = True

            elif phase[0].flags.request_restart_after_phase or phase[
                    0].flags.restart_after_phase:
                reboot = True
                if phase[
                        0].flags.request_restart_after_phase and not self._auto_reboot:
                    reboot = False
                    messaging.request_answers(
                        RawMessageDialog(
                            message=
                            'A reboot is required to continue. Please reboot your system.'
                        ))
                if reboot:
                    self.log.info(
                        'Initiating system reboot due to the restart_after_reboot flag'
                    )
                    reboot_system()
                early_finish = True

            elif phase[0].flags.is_checkpoint:
                self.log.info(
                    'Stopping the workflow execution due to the is_checkpoint flag'
                )
                early_finish = True

            if early_finish:
                return
示例#26
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)
示例#27
0
 def checker(*args, **kwargs):
     if not find_repository_basedir('.'):
         raise CommandError(
             'This command must be executed from the repository directory.')
     return f(*args, **kwargs)