def constraints_set(env_config, environment, service_name, constraint_strs): """ Machine constraints allow you to pick the hardware to which your services will be deployed. Examples: $ juju set-constraints --service-name mysql mem=8G cpu=4 $ juju set-constraints instance-type=t1.micro Available constraints vary by provider type, and will be ignored if not understood by the current environment's provider. The current set of available constraints across all providers is: On Amazon EC2: * arch (CPU architecture: i386/amd64/arm; amd64 by default) * cpu (processing power in Amazon ECU; 1 by default) * mem (memory in [MGT]iB; 512M by default) * instance-type (unset by default) * ec2-zone (unset by default) On Orchestra: * orchestra-classes (unset by default) On MAAS: * maas-name (unset by default) Service settings, if specified, will override environment settings, which will in turn override the juju defaults of mem=512M, cpu=1, arch=amd64. New constraints set on an entity will completely replace that entity's pre-existing constraints. To override an environment constraint with the juju default when setting service constraints, just specify "name=" (rather than just not specifying the constraint at all, which will cause it to inherit the environment's value). To entirely unset a constraint, specify "name=any". """ provider = environment.get_machine_provider() constraint_set = yield provider.get_constraint_set() constraints = constraint_set.parse(constraint_strs) client = yield provider.connect() try: yield legacy.check_constraints(client, constraint_strs) yield sync_environment_state(client, env_config, environment.name) if service_name is None: esm = EnvironmentStateManager(client) yield esm.set_constraints(constraints) else: ssm = ServiceStateManager(client) service = yield ssm.get_service_state(service_name) yield service.set_constraints(constraints) finally: yield client.close()
def deploy(env_config, environment, repository_path, charm_name, service_name, log, constraint_strs, config_file=None, upgrade=False, num_units=1): """Deploy a charm within an environment. This will publish the charm to the environment, creating a service from the charm, and get it set to be launched on a new machine. If --repository is not specified, it will be taken from the environment variable JUJU_REPOSITORY. """ repo, charm_url = resolve( charm_name, repository_path, environment.default_series) log.info("Searching for charm %s in %s" % (charm_url, repo)) charm = yield repo.find(charm_url) if upgrade: if repo.type != "local" or charm.type != "dir": raise CharmError( charm.path, "Only local directory charms can be upgraded on deploy") charm.set_revision(charm.get_revision() + 1) charm_id = str(charm_url.with_revision(charm.get_revision())) # Validate config options prior to deployment attempt service_options = {} service_name = service_name or charm_url.name if config_file: service_options = parse_config_options( config_file, service_name, charm) charm = yield repo.find(charm_url) charm_id = str(charm_url.with_revision(charm.get_revision())) provider = environment.get_machine_provider() placement_policy = provider.get_placement_policy() constraint_set = yield provider.get_constraint_set() constraints = constraint_set.parse(constraint_strs) client = yield provider.connect() try: yield legacy.check_constraints(client, constraint_strs) yield legacy.check_environment( client, provider.get_legacy_config_keys()) yield sync_environment_state(client, env_config, environment.name) # Publish the charm to juju storage = yield provider.get_file_storage() publisher = CharmPublisher(client, storage) yield publisher.add_charm(charm_id, charm) result = yield publisher.publish() # In future we might have multiple charms be published at # the same time. For now, extract the charm_state from the # list. charm_state = result[0] # Create the service state service_manager = ServiceStateManager(client) service_state = yield service_manager.add_service_state( service_name, charm_state, constraints) # Use the charm's ConfigOptions instance to validate service # options.. Invalid options passed will thrown an exception # and prevent the deploy. state = yield service_state.get_config() charm_config = yield charm_state.get_config() # return the validated options with the defaults included service_options = charm_config.validate(service_options) state.update(service_options) yield state.write() # Create desired number of service units if (yield service_state.is_subordinate()): log.info("Subordinate %r awaiting relationship " "to principal for deployment.", service_name) else: for i in xrange(num_units): unit_state = yield service_state.add_unit_state() yield place_unit(client, placement_policy, unit_state) # Check if we have any peer relations to establish if charm.metadata.peers: relation_manager = RelationStateManager(client) for peer_name, peer_info in charm.metadata.peers.items(): yield relation_manager.add_relation_state( RelationEndpoint(service_name, peer_info["interface"], peer_name, "peer")) log.info("Charm deployed as service: %r", service_name) finally: yield client.close()