示例#1
0
def main(charm_class):
    """Setup the charm and dispatch the observed event.

    The event name is based on the way this executable was called (argv[0]).
    """
    charm_dir = _get_charm_dir()

    # Process the Juju event relevant to the current hook execution
    # JUJU_HOOK_NAME, JUJU_FUNCTION_NAME, and JUJU_ACTION_NAME are not used
    # in order to support simulation of events from debugging sessions.
    #
    # TODO: For Windows, when symlinks are used, this is not a valid
    #       method of getting an event name (see LP: #1854505).
    juju_exec_path = Path(sys.argv[0])
    juju_event_name = juju_exec_path.name.replace('-', '_')
    if juju_exec_path.parent.name == 'actions':
        juju_event_name = '{}_action'.format(juju_event_name)

    model_backend = ops.model.ModelBackend()
    debug = ('JUJU_DEBUG' in os.environ)
    setup_root_logging(model_backend, debug=debug)

    metadata, actions_metadata = _load_metadata(charm_dir)
    meta = ops.charm.CharmMeta(metadata, actions_metadata)
    unit_name = os.environ['JUJU_UNIT_NAME']
    model = ops.model.Model(unit_name, meta, model_backend)

    # TODO: If Juju unit agent crashes after exit(0) from the charm code
    # the framework will commit the snapshot but Juju will not commit its
    # operation.
    charm_state_path = charm_dir / CHARM_STATE_FILE
    framework = ops.framework.Framework(charm_state_path, charm_dir, meta, model)
    try:
        charm = charm_class(framework, None)

        # When a charm is force-upgraded and a unit is in an error state Juju
        # does not run upgrade-charm and instead runs the failed hook followed
        # by config-changed. Given the nature of force-upgrading the hook setup
        # code is not triggered on config-changed.
        #
        # 'start' event is included as Juju does not fire the install event for
        # K8s charms (see LP: #1854635).
        if (juju_event_name in ('install', 'start', 'upgrade_charm')
                or juju_event_name.endswith('_storage_attached')):
            _setup_event_links(charm_dir, charm)

        # TODO: Remove the collect_metrics check below as soon as the relevant
        #       Juju changes are made.
        #
        # Skip reemission of deferred events for collect-metrics events because
        # they do not have the full access to all hook tools.
        if juju_event_name != 'collect_metrics':
            framework.reemit()

        _emit_charm_event(charm, juju_event_name)

        framework.commit()
    finally:
        framework.close()
示例#2
0
文件: main.py 项目: mthaddon/operator
def main(charm_class):
    """Setup the charm and dispatch the observed event.

    The event name is based on the way this executable was called (argv[0]).
    """

    charm_dir = _get_charm_dir()

    # Process the Juju event relevant to the current hook execution
    # JUJU_HOOK_NAME, JUJU_FUNCTION_NAME, and JUJU_ACTION_NAME are not used
    # in order to support simulation of events from debugging sessions.
    # TODO: For Windows, when symlinks are used, this is not a valid method of getting an event name (see LP: #1854505).
    juju_exec_path = Path(sys.argv[0])
    juju_event_name = juju_exec_path.name.replace('-', '_')
    if juju_exec_path.parent.name in ('functions', 'actions'):
        juju_event_name = f'{juju_event_name}_function'

    metadata, functions_metadata, functions_dir = _load_metadata(charm_dir)
    meta = ops.charm.CharmMeta(metadata, functions_metadata)
    unit_name = os.environ['JUJU_UNIT_NAME']
    model = ops.model.Model(unit_name, meta, ops.model.ModelBackend())

    # TODO: If Juju unit agent crashes after exit(0) from the charm code
    # the framework will commit the snapshot but Juju will not commit its
    # operation.
    charm_state_path = charm_dir / CHARM_STATE_FILE
    framework = ops.framework.Framework(charm_state_path, charm_dir, meta,
                                        model)
    try:
        charm = charm_class(framework, None)

        # When a charm is force-upgraded and a unit is in an error state Juju does not run upgrade-charm and
        # instead runs the failed hook followed by config-changed. Given the nature of force-upgrading
        # the hook setup code is not triggered on config-changed.
        # 'start' event is included as Juju does not fire the install event for K8s charms (see LP: #1854635).
        if juju_event_name in ('install', 'start',
                               'upgrade_charm') or juju_event_name.endswith(
                                   '_storage_attached'):
            _setup_event_links(charm_dir, charm, functions_dir)

        framework.reemit()

        _emit_charm_event(charm, juju_event_name)

        framework.commit()
    finally:
        framework.close()
示例#3
0
文件: main.py 项目: xiryrg1/operator
def main(charm_class):
    """Setup the charm and dispatch the observed event.

    The event name is based on the way this executable was called (argv[0]).
    """
    charm_dir = _get_charm_dir()

    model_backend = ops.model._ModelBackend()
    debug = ('JUJU_DEBUG' in os.environ)
    setup_root_logging(model_backend, debug=debug)

    dispatcher = _Dispatcher(charm_dir)
    dispatcher.run_any_legacy_hook()

    metadata, actions_metadata = _load_metadata(charm_dir)
    meta = ops.charm.CharmMeta(metadata, actions_metadata)
    unit_name = os.environ['JUJU_UNIT_NAME']
    model_name = os.environ.get('JUJU_MODEL_NAME')
    model = ops.model.Model(unit_name,
                            meta,
                            model_backend,
                            model_name=model_name)

    # TODO: If Juju unit agent crashes after exit(0) from the charm code
    # the framework will commit the snapshot but Juju will not commit its
    # operation.
    charm_state_path = charm_dir / CHARM_STATE_FILE
    framework = ops.framework.Framework(charm_state_path, charm_dir, meta,
                                        model)
    try:
        charm = charm_class(framework, None)
        dispatcher.ensure_event_links(charm)

        # TODO: Remove the collect_metrics check below as soon as the relevant
        #       Juju changes are made.
        #
        # Skip reemission of deferred events for collect-metrics events because
        # they do not have the full access to all hook tools.
        if dispatcher.event_name != 'collect_metrics':
            framework.reemit()

        _emit_charm_event(charm, dispatcher.event_name)

        framework.commit()
    finally:
        framework.close()
示例#4
0
def main(charm_class: ops.charm.CharmBase, use_juju_for_storage: bool = None):
    """Setup the charm and dispatch the observed event.

    The event name is based on the way this executable was called (argv[0]).

    Args:
        charm_class: your charm class.
        use_juju_for_storage: whether to use controller-side storage. If not specified
            then kubernetes charms that haven't previously used local storage and that
            are running on a new enough Juju default to controller-side storage,
            otherwise local storage is used.
    """
    charm_dir = _get_charm_dir()

    model_backend = ops.model._ModelBackend()
    debug = ('JUJU_DEBUG' in os.environ)
    setup_root_logging(model_backend, debug=debug)
    logger.debug("Operator Framework %s up and running.", ops.__version__)

    dispatcher = _Dispatcher(charm_dir)
    dispatcher.run_any_legacy_hook()

    metadata = (charm_dir / 'metadata.yaml').read_text()
    actions_meta = charm_dir / 'actions.yaml'
    if actions_meta.exists():
        actions_metadata = actions_meta.read_text()
    else:
        actions_metadata = None

    if not yaml.__with_libyaml__:
        logger.debug(
            'yaml does not have libyaml extensions, using slower pure Python yaml loader'
        )
    meta = ops.charm.CharmMeta.from_yaml(metadata, actions_metadata)
    model = ops.model.Model(meta, model_backend)

    charm_state_path = charm_dir / CHARM_STATE_FILE

    if use_juju_for_storage and not ops.storage.juju_backend_available():
        # raise an exception; the charm is broken and needs fixing.
        msg = 'charm set use_juju_for_storage=True, but Juju version {} does not support it'
        raise RuntimeError(msg.format(JujuVersion.from_environ()))

    if use_juju_for_storage is None:
        use_juju_for_storage = _should_use_controller_storage(
            charm_state_path, meta)

    if use_juju_for_storage:
        if dispatcher.is_restricted_context():
            # TODO: jam 2020-06-30 This unconditionally avoids running a collect metrics event
            #  Though we eventually expect that juju will run collect-metrics in a
            #  non-restricted context. Once we can determine that we are running collect-metrics
            #  in a non-restricted context, we should fire the event as normal.
            logger.debug(
                '"%s" is not supported when using Juju for storage\n'
                'see: https://github.com/canonical/operator/issues/348',
                dispatcher.event_name)
            # Note that we don't exit nonzero, because that would cause Juju to rerun the hook
            return
        store = ops.storage.JujuStorage()
    else:
        store = ops.storage.SQLiteStorage(charm_state_path)
    framework = ops.framework.Framework(store, charm_dir, meta, model)
    framework.set_breakpointhook()
    try:
        sig = inspect.signature(charm_class)
        try:
            sig.bind(framework)
        except TypeError:
            msg = (
                "the second argument, 'key', has been deprecated and will be "
                "removed after the 0.7 release")
            warnings.warn(msg, DeprecationWarning)
            charm = charm_class(framework, None)
        else:
            charm = charm_class(framework)
        dispatcher.ensure_event_links(charm)

        # TODO: Remove the collect_metrics check below as soon as the relevant
        #       Juju changes are made. Also adjust the docstring on
        #       EventBase.defer().
        #
        # Skip reemission of deferred events for collect-metrics events because
        # they do not have the full access to all hook tools.
        if not dispatcher.is_restricted_context():
            framework.reemit()

        _emit_charm_event(charm, dispatcher.event_name)

        framework.commit()
    finally:
        framework.close()
示例#5
0
def main(charm_class, use_juju_for_storage=False):
    """Setup the charm and dispatch the observed event.

    The event name is based on the way this executable was called (argv[0]).
    """
    charm_dir = _get_charm_dir()

    model_backend = ops.model._ModelBackend()
    debug = ('JUJU_DEBUG' in os.environ)
    setup_root_logging(model_backend, debug=debug)
    logger.debug("Operator Framework %s up and running.", ops.__version__)

    dispatcher = _Dispatcher(charm_dir)
    dispatcher.run_any_legacy_hook()

    metadata = (charm_dir / 'metadata.yaml').read_text()
    actions_meta = charm_dir / 'actions.yaml'
    if actions_meta.exists():
        actions_metadata = actions_meta.read_text()
    else:
        actions_metadata = None

    if not yaml.__with_libyaml__:
        logger.debug(
            'yaml does not have libyaml extensions, using slower pure Python yaml loader'
        )
    meta = ops.charm.CharmMeta.from_yaml(metadata, actions_metadata)
    model = ops.model.Model(meta, model_backend)

    # TODO: If Juju unit agent crashes after exit(0) from the charm code
    # the framework will commit the snapshot but Juju will not commit its
    # operation.
    charm_state_path = charm_dir / CHARM_STATE_FILE
    if use_juju_for_storage:
        if dispatcher.is_restricted_context():
            # TODO: jam 2020-06-30 This unconditionally avoids running a collect metrics event
            #  Though we eventually expect that juju will run collect-metrics in a
            #  non-restricted context. Once we can determine that we are running collect-metrics
            #  in a non-restricted context, we should fire the event as normal.
            logger.debug(
                '"%s" is not supported when using Juju for storage\n'
                'see: https://github.com/canonical/operator/issues/348',
                dispatcher.event_name)
            # Note that we don't exit nonzero, because that would cause Juju to rerun the hook
            return
        store = ops.storage.JujuStorage()
    else:
        store = ops.storage.SQLiteStorage(charm_state_path)
    framework = ops.framework.Framework(store, charm_dir, meta, model)
    try:
        sig = inspect.signature(charm_class)
        try:
            sig.bind(framework)
        except TypeError:
            msg = (
                "the second argument, 'key', has been deprecated and will be "
                "removed after the 0.7 release")
            warnings.warn(msg, DeprecationWarning)
            charm = charm_class(framework, None)
        else:
            charm = charm_class(framework)
        dispatcher.ensure_event_links(charm)

        # TODO: Remove the collect_metrics check below as soon as the relevant
        #       Juju changes are made.
        #
        # Skip reemission of deferred events for collect-metrics events because
        # they do not have the full access to all hook tools.
        if not dispatcher.is_restricted_context():
            framework.reemit()

        _emit_charm_event(charm, dispatcher.event_name)

        framework.commit()
    finally:
        framework.close()
示例#6
0
def main(charm_class):
    """Setup the charm and dispatch the observed event.

    The event name is based on the way this executable was called (argv[0]).
    """
    charm_dir = _get_charm_dir()

    model_backend = ops.model._ModelBackend()
    debug = ('JUJU_DEBUG' in os.environ)
    setup_root_logging(model_backend, debug=debug)
    logger.debug("Operator Framework %s up and running.", ops.__version__)

    dispatcher = _Dispatcher(charm_dir)
    dispatcher.run_any_legacy_hook()

    metadata = (charm_dir / 'metadata.yaml').read_text()
    actions_meta = charm_dir / 'actions.yaml'
    if actions_meta.exists():
        actions_metadata = actions_meta.read_text()
    else:
        actions_metadata = None

    if not yaml.__with_libyaml__:
        logger.debug(
            'yaml does not have libyaml extensions, using slower pure Python yaml loader'
        )
    meta = ops.charm.CharmMeta.from_yaml(metadata, actions_metadata)
    model = ops.model.Model(meta, model_backend)

    # TODO: If Juju unit agent crashes after exit(0) from the charm code
    # the framework will commit the snapshot but Juju will not commit its
    # operation.
    charm_state_path = charm_dir / CHARM_STATE_FILE
    framework = ops.framework.Framework(charm_state_path, charm_dir, meta,
                                        model)
    try:
        sig = inspect.signature(charm_class)
        try:
            sig.bind(framework)
        except TypeError:
            msg = (
                "the second argument, 'key', has been deprecated and will be "
                "removed after the 0.7 release")
            warnings.warn(msg, DeprecationWarning)
            charm = charm_class(framework, None)
        else:
            charm = charm_class(framework)
        dispatcher.ensure_event_links(charm)

        # TODO: Remove the collect_metrics check below as soon as the relevant
        #       Juju changes are made.
        #
        # Skip reemission of deferred events for collect-metrics events because
        # they do not have the full access to all hook tools.
        if dispatcher.event_name != 'collect_metrics':
            framework.reemit()

        _emit_charm_event(charm, dispatcher.event_name)

        framework.commit()
    finally:
        framework.close()