@Override public Map<String, String> getShellEnvironment() { return MutableMap.<String, String>builder() .putAll(super.getShellEnvironment()) .put("PORT", Integer.toString(getHttpPort())) .build(); }
/** * Given an enricher, extracts its state for serialization. * * @deprecated since 0.7.0, see {@link #newBasicMemento(BrooklynObject)} */ @Deprecated public static EnricherMemento newEnricherMemento(Enricher enricher) { BasicEnricherMemento.Builder builder = BasicEnricherMemento.builder(); populateBrooklynObjectMementoBuilder(enricher, builder); // TODO persist config keys as well? Or only support those defined on policy class; // current code will lose the ConfigKey type on rebind for anything not defined on class. // Whereas entities support that. // TODO Do we need the "nonPersistableFlagNames" that locations use? Map<ConfigKey<?>, Object> config = ((AbstractEnricher) enricher).getConfigMap().getAllConfig(); for (Map.Entry<ConfigKey<?>, Object> entry : config.entrySet()) { ConfigKey<?> key = checkNotNull(entry.getKey(), "config=%s", config); Object value = configValueToPersistable(entry.getValue()); builder.config.put(key.getName(), value); } Map<String, Object> persistableFlags = MutableMap.<String, Object>builder() .putAll( FlagUtils.getFieldsWithFlagsExcludingModifiers( enricher, Modifier.STATIC ^ Modifier.TRANSIENT)) .remove("id") .remove("name") .build(); builder.config.putAll(persistableFlags); return builder.build(); }
protected void runTest(Map<String, ?> flags) throws Exception { String tag = getClass().getSimpleName().toLowerCase(); Map<String, ?> allFlags = MutableMap.<String, Object>builder() .put("tags", ImmutableList.of(tag)) .putAll(flags) .build(); jcloudsLocation = ctx.getLocationRegistry().getLocationManaged(PROVIDER, allFlags); doTest(jcloudsLocation); }
/** @deprecated since 0.7.0; use {@link #newBasicMemento(BrooklynObject)} instead */ @Deprecated public static BasicLocationMemento.Builder newLocationMementoBuilder(Location location) { BasicLocationMemento.Builder builder = BasicLocationMemento.builder(); populateBrooklynObjectMementoBuilder(location, builder); Set<String> nonPersistableFlagNames = MutableMap.<String, Object>builder() .putAll(FlagUtils.getFieldsWithFlagsWithModifiers(location, Modifier.TRANSIENT)) .putAll(FlagUtils.getFieldsWithFlagsWithModifiers(location, Modifier.STATIC)) .put("id", String.class) .filterValues(Predicates.not(Predicates.instanceOf(ConfigKey.class))) .build() .keySet(); Map<String, Object> persistableFlags = MutableMap.<String, Object>builder() .putAll( FlagUtils.getFieldsWithFlagsExcludingModifiers( location, Modifier.STATIC ^ Modifier.TRANSIENT)) .removeAll(nonPersistableFlagNames) .build(); ConfigBag persistableConfig = new ConfigBag() .copy(((LocationInternal) location).config().getLocalBag()) .removeAll(nonPersistableFlagNames); builder.copyConfig(persistableConfig); builder.locationConfig.putAll(persistableFlags); Location parentLocation = location.getParent(); builder.parent = (parentLocation != null) ? parentLocation.getId() : null; for (Location child : location.getChildren()) { builder.children.add(child.getId()); } return builder; }
@Override public ComputeService findComputeService(ConfigBag conf, boolean allowReuse) { String provider = checkNotNull(conf.get(CLOUD_PROVIDER), "provider must not be null"); String identity = checkNotNull(conf.get(CloudLocationConfig.ACCESS_IDENTITY), "identity must not be null"); String credential = checkNotNull( conf.get(CloudLocationConfig.ACCESS_CREDENTIAL), "credential must not be null"); Properties properties = new Properties(); properties.setProperty(Constants.PROPERTY_TRUST_ALL_CERTS, Boolean.toString(true)); properties.setProperty(Constants.PROPERTY_RELAX_HOSTNAME, Boolean.toString(true)); properties.setProperty( "jclouds.ssh.max-retries", conf.getStringKey("jclouds.ssh.max-retries") != null ? conf.getStringKey("jclouds.ssh.max-retries").toString() : "50"); // Enable aws-ec2 lazy image fetching, if given a specific imageId; otherwise customize for // specific owners; or all as a last resort // See https://issues.apache.org/jira/browse/WHIRR-416 if ("aws-ec2".equals(provider)) { // TODO convert AWS-only flags to config keys if (groovyTruth(conf.get(IMAGE_ID))) { properties.setProperty(PROPERTY_EC2_AMI_QUERY, ""); properties.setProperty(PROPERTY_EC2_CC_AMI_QUERY, ""); } else if (groovyTruth(conf.getStringKey("imageOwner"))) { properties.setProperty( PROPERTY_EC2_AMI_QUERY, "owner-id=" + conf.getStringKey("imageOwner") + ";state=available;image-type=machine"); } else if (groovyTruth(conf.getStringKey("anyOwner"))) { // set `anyOwner: true` to override the default query (which is restricted to certain owners // as per below), // allowing the AMI query to bind to any machine // (note however, we sometimes pick defaults in JcloudsLocationFactory); // (and be careful, this can give a LOT of data back, taking several minutes, // and requiring extra memory allocated on the command-line) properties.setProperty(PROPERTY_EC2_AMI_QUERY, "state=available;image-type=machine"); /* * by default the following filters are applied: * Filter.1.Name=owner-id&Filter.1.Value.1=137112412989& * Filter.1.Value.2=063491364108& * Filter.1.Value.3=099720109477& * Filter.1.Value.4=411009282317& * Filter.2.Name=state&Filter.2.Value.1=available& * Filter.3.Name=image-type&Filter.3.Value.1=machine& */ } // occasionally can get com.google.common.util.concurrent.UncheckedExecutionException: // java.lang.RuntimeException: // security group eu-central-1/jclouds#brooklyn-bxza-alex-eu-central-shoul-u2jy-nginx-ielm // is not available after creating // the default timeout was 500ms so let's raise it in case that helps properties.setProperty( EC2Constants.PROPERTY_EC2_TIMEOUT_SECURITYGROUP_PRESENT, "" + Duration.seconds(30).toMilliseconds()); } // FIXME Deprecated mechanism, should have a ConfigKey for overrides Map<String, Object> extra = Maps.filterKeys(conf.getAllConfig(), Predicates.containsPattern("^jclouds\\.")); if (extra.size() > 0) { LOG.warn("Jclouds using deprecated property overrides: " + Sanitizer.sanitize(extra)); } properties.putAll(extra); String endpoint = conf.get(CloudLocationConfig.CLOUD_ENDPOINT); if (!groovyTruth(endpoint)) endpoint = getDeprecatedProperty(conf, Constants.PROPERTY_ENDPOINT); if (groovyTruth(endpoint)) properties.setProperty(Constants.PROPERTY_ENDPOINT, endpoint); Map<?, ?> cacheKey = MutableMap.builder() .putAll(properties) .put("provider", provider) .put("identity", identity) .put("credential", credential) .putIfNotNull("endpoint", endpoint) .build() .asUnmodifiable(); if (allowReuse) { ComputeService result = cachedComputeServices.get(cacheKey); if (result != null) { LOG.trace( "jclouds ComputeService cache hit for compute service, for " + Sanitizer.sanitize(properties)); return result; } LOG.debug( "jclouds ComputeService cache miss for compute service, creating, for " + Sanitizer.sanitize(properties)); } Iterable<Module> modules = getCommonModules(); // Synchronizing to avoid deadlock from sun.reflect.annotation.AnnotationType. // See https://github.com/brooklyncentral/brooklyn/issues/974 ComputeServiceContext computeServiceContext; synchronized (createComputeServicesMutex) { computeServiceContext = ContextBuilder.newBuilder(provider) .modules(modules) .credentials(identity, credential) .overrides(properties) .build(ComputeServiceContext.class); } final ComputeService computeService = computeServiceContext.getComputeService(); if (allowReuse) { synchronized (cachedComputeServices) { ComputeService result = cachedComputeServices.get(cacheKey); if (result != null) { LOG.debug( "jclouds ComputeService cache recovery for compute service, for " + Sanitizer.sanitize(cacheKey)); // keep the old one, discard the new one computeService.getContext().close(); return result; } LOG.debug( "jclouds ComputeService created " + computeService + ", adding to cache, for " + Sanitizer.sanitize(properties)); cachedComputeServices.put(cacheKey, computeService); } } return computeService; }
@Override public DockerContainerLocation obtain(Map<?, ?> flags) throws NoMachinesAvailableException { lock.readLock().lock(); try { // Lookup entity from context or flags Object context = flags.get(LocationConfigKeys.CALLER_CONTEXT.getName()); if (context == null || !(context instanceof Entity)) { throw new IllegalStateException("Invalid location context: " + context); } Entity entity = (Entity) context; // Flag to configure adding SSHable layer boolean useSsh = entity.config().get(DockerContainer.DOCKER_USE_SSH) && dockerHost.config().get(DockerContainer.DOCKER_USE_SSH); // Configure the entity LOG.info("Configuring entity {} via subnet {}", entity, dockerHost.getSubnetTier()); entity .config() .set( SubnetTier.PORT_FORWARDING_MANAGER, dockerHost.getSubnetTier().getPortForwardManager()); entity.config().set(SubnetTier.PORT_FORWARDER, portForwarder); if (getOwner().config().get(SdnAttributes.SDN_ENABLE)) { SdnAgent agent = getOwner().sensors().get(SdnAgent.SDN_AGENT); if (agent == null) { throw new IllegalStateException("SDN agent entity on " + getOwner() + " is null"); } Map<String, Cidr> networks = agent.sensors().get(SdnAgent.SDN_PROVIDER).sensors().get(SdnProvider.SUBNETS); entity.config().set(SubnetTier.SUBNET_CIDR, networks.get(entity.getApplicationId())); } else { entity.config().set(SubnetTier.SUBNET_CIDR, Cidr.UNIVERSAL); } configureEnrichers(entity); // Add the entity Dockerfile if configured String dockerfile = entity.config().get(DockerAttributes.DOCKERFILE_URL); String entrypoint = entity.config().get(DockerAttributes.DOCKERFILE_ENTRYPOINT_URL); String contextArchive = entity.config().get(DockerAttributes.DOCKERFILE_CONTEXT_URL); String imageId = entity.config().get(DockerAttributes.DOCKER_IMAGE_ID); Optional<String> baseImage = Optional.fromNullable(entity.config().get(DockerAttributes.DOCKER_IMAGE_NAME)); String imageTag = Optional.fromNullable(entity.config().get(DockerAttributes.DOCKER_IMAGE_TAG)) .or("latest"); // TODO incorporate more info final String imageName = DockerUtils.imageName(entity, dockerfile); // Lookup image ID or build new image from Dockerfile LOG.info("ImageName for entity {}: {}", entity, imageName); if (dockerHost.getImageNamed(imageName, imageTag).isPresent()) { // Wait until committed before continuing - Brooklyn may be midway through its creation. waitForImage(imageName); // Look up imageId again imageId = dockerHost.getImageNamed(imageName, imageTag).get(); LOG.info("Found image {} for entity: {}", imageName, imageId); // Skip install phase entity.config().set(SoftwareProcess.SKIP_INSTALLATION, true); } else if (baseImage.isPresent()) { if (useSsh) { // Create an SSHable image from the one configured imageId = dockerHost.layerSshableImageOn(baseImage.get(), imageTag); LOG.info("Created SSHable image from {}: {}", baseImage.get(), imageId); } else { dockerHost.runDockerCommand(String.format("pull %s:%s", baseImage.get(), imageTag)); imageId = dockerHost.getImageNamed(baseImage.get(), imageTag).get(); } entity.config().set(SoftwareProcess.SKIP_INSTALLATION, true); } else { // Otherwise Clocker is going to make an image for the entity once it is installed. insertCallback(entity, SoftwareProcess.POST_INSTALL_COMMAND, DockerCallbacks.commit()); if (Strings.isNonBlank(dockerfile)) { if (imageId != null) { LOG.warn( "Ignoring container imageId {} as dockerfile URL is set: {}", imageId, dockerfile); } Map<String, Object> substitutions = getExtraTemplateSubstitutions(imageName, entity); imageId = dockerHost.buildImage( dockerfile, entrypoint, contextArchive, imageName, useSsh, substitutions); } if (Strings.isBlank(imageId)) { imageId = getOwner().sensors().get(DockerHost.DOCKER_IMAGE_ID); } // Tag the image name and create its latch images.putIfAbsent(imageName, new CountDownLatch(1)); dockerHost.runDockerCommand(String.format("tag -f %s %s:latest", imageId, imageName)); } // Look up hardware ID String hardwareId = entity.config().get(DockerAttributes.DOCKER_HARDWARE_ID); if (Strings.isEmpty(hardwareId)) { hardwareId = getOwner().config().get(DockerAttributes.DOCKER_HARDWARE_ID); } // Create new Docker container in the host cluster LOG.info( "Starting container with imageId {} and hardwareId {} at {}", new Object[] {imageId, hardwareId, machine}); Map<Object, Object> containerFlags = MutableMap.builder() .putAll(flags) .put("useSsh", useSsh) .put("entity", entity) .putIfNotNull("imageId", imageId) .putIfNotNull("hardwareId", hardwareId) .build(); DynamicCluster cluster = dockerHost.getDockerContainerCluster(); Entity added = cluster.addNode(machine, containerFlags); if (added == null) { throw new NoMachinesAvailableException( String.format("Failed to create container at %s", dockerHost.getDockerHostName())); } else { Entities.invokeEffector( (EntityLocal) entity, added, Startable.START, MutableMap.of("locations", ImmutableList.of(machine))) .getUnchecked(); } DockerContainer dockerContainer = (DockerContainer) added; // Save the container attributes dockerContainer.sensors().set(DockerContainer.IMAGE_ID, imageId); dockerContainer.sensors().set(DockerContainer.IMAGE_NAME, imageName); dockerContainer.sensors().set(DockerContainer.HARDWARE_ID, hardwareId); // record SDN application network details if (getOwner().config().get(SdnAttributes.SDN_ENABLE)) { SdnAgent agent = getOwner().sensors().get(SdnAgent.SDN_AGENT); Cidr applicationCidr = agent.sensors().get(SdnAgent.SDN_PROVIDER).getSubnetCidr(entity.getApplicationId()); entity.sensors().set(SdnProvider.APPLICATION_CIDR, applicationCidr); dockerContainer.sensors().set(SdnProvider.APPLICATION_CIDR, applicationCidr); } return dockerContainer.getDynamicLocation(); } finally { lock.readLock().unlock(); } }