protected void runStopProcessAndRestart(Effector<?> restartEffector, Map<String, ?> args)
      throws Exception {
    LocalhostMachineProvisioningLocation loc = app.newLocalhostProvisioningLocation();
    SoftwareProcess entity = app.createAndManageChild(newEntitySpec());

    // Start the app
    app.start(ImmutableList.of(loc));
    EntityTestUtils.assertAttributeEqualsEventually(entity, SoftwareProcess.SERVICE_UP, true);
    EntityTestUtils.assertAttributeEqualsEventually(app, SoftwareProcess.SERVICE_UP, true);

    // Stop the process
    Entities.invokeEffector(
            app,
            entity,
            SoftwareProcess.STOP,
            ImmutableMap.of(
                StopSoftwareParameters.STOP_MACHINE_MODE.getName(),
                StopSoftwareParameters.StopMode.NEVER))
        .get();
    EntityTestUtils.assertAttributeEqualsEventually(entity, SoftwareProcess.SERVICE_UP, false);
    EntityTestUtils.assertAttributeEqualsEventually(
        entity, SoftwareProcess.SERVICE_STATE_ACTUAL, Lifecycle.STOPPED);
    EntityTestUtils.assertAttributeEqualsEventually(
        entity, SoftwareProcess.SERVICE_PROCESS_IS_RUNNING, false);
    EntityTestUtils.assertAttributeEventually(
        entity,
        ServiceStateLogic.SERVICE_NOT_UP_INDICATORS,
        CollectionFunctionals.<String>mapSizeEquals(1));

    // Restart the process
    Entities.invokeEffector(app, entity, restartEffector, args).get();
    EntityTestUtils.assertAttributeEqualsEventually(entity, SoftwareProcess.SERVICE_UP, true);
    EntityTestUtils.assertAttributeEqualsEventually(
        entity, SoftwareProcess.SERVICE_STATE_ACTUAL, Lifecycle.RUNNING);
    EntityTestUtils.assertAttributeEqualsEventually(
        entity, SoftwareProcess.SERVICE_PROCESS_IS_RUNNING, true);
    EntityTestUtils.assertAttributeEqualsEventually(
        entity, ServiceStateLogic.SERVICE_NOT_UP_INDICATORS, ImmutableMap.<String, Object>of());

    EntityTestUtils.assertAttributeEqualsEventually(app, SoftwareProcess.SERVICE_UP, true);
    EntityTestUtils.assertAttributeEqualsEventually(
        app, SoftwareProcess.SERVICE_STATE_ACTUAL, Lifecycle.RUNNING);
  }
Beispiel #2
0
  @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();
    }
  }