Example #1
0
 def test_is_unit_running(self):
     running, state = yield is_unit_running(self.client,
                                            self.states["unit"])
     self.assertIdentical(running, False)
     self.assertIdentical(state, None)
     yield self.workflow.fire_transition("install")
     yield self.workflow.fire_transition("start")
     running, state = yield is_unit_running(self.client,
                                            self.states["unit"])
     self.assertIdentical(running, True)
     self.assertEqual(state, "started")
Example #2
0
 def test_is_unit_running(self):
     running, state = yield is_unit_running(
         self.client, self.states["unit"])
     self.assertIdentical(running, False)
     self.assertIdentical(state, None)
     yield self.workflow.fire_transition("install")
     yield self.workflow.fire_transition("start")
     running, state = yield is_unit_running(
         self.client, self.states["unit"])
     self.assertIdentical(running, True)
     self.assertEqual(state, "started")
Example #3
0
def upgrade_charm(
    config, environment, verbose, log, repository_path, service_name, dry_run):
    """Upgrades a service's charm.

    First determines if an upgrade is available, then updates the
    service charm reference, and marks the units as needing upgrades.
    """
    provider = environment.get_machine_provider()
    client = yield provider.connect()

    service_manager = ServiceStateManager(client)
    service_state = yield service_manager.get_service_state(service_name)
    old_charm_id = yield service_state.get_charm_id()

    old_charm_url = CharmURL.parse(old_charm_id)
    old_charm_url.assert_revision()
    repo, charm_url = resolve(
        str(old_charm_url.with_revision(None)),
        repository_path,
        environment.default_series)
    new_charm_url = charm_url.with_revision(
        (yield repo.latest(charm_url)))

    if charm_url.collection.schema == "local":
        if old_charm_url.revision >= new_charm_url.revision:
            new_revision = old_charm_url.revision + 1
            charm = yield repo.find(new_charm_url)
            if isinstance(charm, CharmDirectory):
                if dry_run:
                    log.info("%s would be set to revision %s",
                             charm.path, new_revision)
                else:
                    log.info("Setting %s to revision %s",
                             charm.path, new_revision)
                    charm.set_revision(new_revision)
                new_charm_url.revision = new_revision

    new_charm_id = str(new_charm_url)

    # Verify its newer than what's deployed
    if not new_charm_url.revision > old_charm_url.revision:
        if dry_run:
            log.info("Service already running latest charm %r", old_charm_id)
        else:
            raise NewerCharmNotFound(old_charm_id)
    elif dry_run:
        log.info("Service would be upgraded from charm %r to %r",
                 old_charm_id, new_charm_id)

    # On dry run, stop before modifying state.
    if not dry_run:
        # Publish the new charm
        storage = provider.get_file_storage()
        publisher = CharmPublisher(client, storage)
        charm = yield repo.find(new_charm_url)
        yield publisher.add_charm(new_charm_id, charm)
        result = yield publisher.publish()
        charm_state = result[0]

        # Update the service charm reference
        yield service_state.set_charm_id(charm_state.id)

    # Mark the units for upgrades
    units = yield service_state.get_all_unit_states()
    for unit in units:
        running, state = yield is_unit_running(client, unit)
        if not running:
            log.info(
                "Unit %r is not in a running state (state: %r), won't upgrade",
                unit.unit_name, state or "uninitialized")
            continue

        if not dry_run:
            yield unit.set_upgrade_flag()
Example #4
0
def resolved(config, environment, verbose, log, unit_name, relation_name,
             retry):
    """Mark an error as resolved in a unit or unit relation.

    If one of a unit's charm non-relation hooks returns a non-zero exit
    status, the entire unit can be considered to be in a non-running state.

    As a resolution, the the unit can be manually returned a running state
    via the juju resolved command. Optionally this command can also
    rerun the failed hook.

    This resolution also applies separately to each of the unit's relations.
    If one of the relation-hooks failed. In that case there is no
    notion of retrying (the change is gone), but resolving will allow
    additional relation hooks for that relation to proceed.
    """
    provider = environment.get_machine_provider()
    client = yield provider.connect()
    service_manager = ServiceStateManager(client)
    relation_manager = RelationStateManager(client)

    unit_state = yield service_manager.get_unit_state(unit_name)
    service_state = yield service_manager.get_service_state(
        unit_name.split("/")[0])

    retry = retry and RETRY_HOOKS or NO_HOOKS

    if not relation_name:
        running, workflow_state = yield is_unit_running(client, unit_state)
        if running:
            log.info("Unit %r already running: %s", unit_name, workflow_state)
            client.close()
            returnValue(False)

        yield unit_state.set_resolved(retry)
        log.info("Marked unit %r as resolved", unit_name)
        returnValue(True)

    # Check for the matching relations
    service_relations = yield relation_manager.get_relations_for_service(
        service_state)
    service_relations = [
        sr for sr in service_relations if sr.relation_name == relation_name
    ]
    if not service_relations:
        raise RelationStateNotFound()

    # Verify the relations are in need of resolution.
    resolved_relations = {}
    for service_relation in service_relations:
        unit_relation = yield service_relation.get_unit_state(unit_state)
        running, state = yield is_relation_running(client, unit_relation)
        if not running:
            resolved_relations[unit_relation.internal_relation_id] = retry

    if not resolved_relations:
        log.warning("Matched relations are all running")
        client.close()
        returnValue(False)

    # Mark the relations as resolved.
    yield unit_state.set_relation_resolved(resolved_relations)
    log.info("Marked unit %r relation %r as resolved", unit_name,
             relation_name)
    client.close()
Example #5
0
def resolved(
    config, environment, verbose, log, unit_name, relation_name, retry):
    """Mark an error as resolved in a unit or unit relation.

    If one of a unit's charm non-relation hooks returns a non-zero exit
    status, the entire unit can be considered to be in a non-running state.

    As a resolution, the the unit can be manually returned a running state
    via the juju resolved command. Optionally this command can also
    rerun the failed hook.

    This resolution also applies separately to each of the unit's relations.
    If one of the relation-hooks failed. In that case there is no
    notion of retrying (the change is gone), but resolving will allow
    additional relation hooks for that relation to proceed.
    """
    provider = environment.get_machine_provider()
    client = yield provider.connect()
    service_manager = ServiceStateManager(client)
    relation_manager = RelationStateManager(client)

    unit_state = yield service_manager.get_unit_state(unit_name)
    service_state = yield service_manager.get_service_state(
        unit_name.split("/")[0])

    retry = retry and RETRY_HOOKS or NO_HOOKS

    if not relation_name:
        running, workflow_state = yield is_unit_running(client, unit_state)
        if running:
            log.info("Unit %r already running: %s", unit_name, workflow_state)
            client.close()
            returnValue(False)

        yield unit_state.set_resolved(retry)
        log.info("Marked unit %r as resolved", unit_name)
        returnValue(True)

    # Check for the matching relations
    service_relations = yield relation_manager.get_relations_for_service(
        service_state)
    service_relations = [
        sr for sr in service_relations if sr.relation_name == relation_name]
    if not service_relations:
        raise RelationStateNotFound()

    # Verify the relations are in need of resolution.
    resolved_relations = {}
    for service_relation in service_relations:
        unit_relation = yield service_relation.get_unit_state(unit_state)
        running, state = yield is_relation_running(client, unit_relation)
        if not running:
            resolved_relations[unit_relation.internal_relation_id] = retry

    if not resolved_relations:
        log.warning("Matched relations are all running")
        client.close()
        returnValue(False)

    # Mark the relations as resolved.
    yield unit_state.set_relation_resolved(resolved_relations)
    log.info(
        "Marked unit %r relation %r as resolved", unit_name, relation_name)
    client.close()