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")
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")
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()
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()
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()