protected DataStore getDataStore() {
   FabricService service = getFabricService();
   if (service != null) {
     return service.getDataStore();
   }
   return null;
 }
Example #2
0
 protected CreateChildContainerOptions.Builder createAutoScaleOptions(
     AutoScaleRequest request, FabricService fabricService) {
   CreateChildContainerOptions.Builder builder = CreateChildContainerOptions.builder();
   Container[] containers = fabricService.getContainers();
   if (containers != null) {
     List<String> containerIds = Containers.rootContainerIds(containers);
     // allow the requirements to customise which root to use...
     if (containerIds.isEmpty()) {
       throw new IllegalStateException("No root containers are available!");
     }
     String rootContainer = null;
     if (containerIds.size() == 1) {
       rootContainer = containerIds.get(0);
     } else {
       rootContainer = chooseRootContainer(request, containerIds);
     }
     if (Strings.isNullOrBlank(rootContainer)) {
       throw new IllegalStateException(
           "Could not choose a root container from the possible IDs: "
               + containerIds
               + " with requirements: "
               + getChildScalingRequirements(request));
     } else {
       builder = builder.parent(rootContainer);
     }
   }
   String zookeeperUrl = fabricService.getZookeeperUrl();
   String zookeeperPassword = fabricService.getZookeeperPassword();
   return builder
       .jmxUser("admin")
       .jmxPassword(zookeeperPassword)
       .zookeeperUrl(zookeeperUrl)
       .zookeeperPassword(zookeeperPassword);
 }
 protected void onConfigurationChanged() {
   ProcessManager manager = getProcessManager();
   FabricService fabric = getFabricService();
   if (manager != null && fabric != null) {
     ImmutableMap<String, Installation> map = manager.listInstallationMap();
     ImmutableSet<Map.Entry<String, Installation>> entries = map.entrySet();
     for (Map.Entry<String, Installation> entry : entries) {
       String id = entry.getKey();
       Installation installation = entry.getValue();
       try {
         Container container = null;
         try {
           container = fabric.getContainer(id);
         } catch (Exception e) {
           LOG.debug("No container for id: " + id + ". " + e, e);
         }
         if (container != null && installation != null) {
           ChildContainerController controllerForContainer = getControllerForContainer(container);
           if (controllerForContainer instanceof ProcessManagerController) {
             ProcessManagerController processManagerController =
                 (ProcessManagerController) controllerForContainer;
             processManagerController.updateInstallation(container, installation);
           }
         }
       } catch (Exception e) {
         LOG.warn("Failed to get PID for process " + id + ". " + e, e);
       }
     }
   }
 }
  @Test
  public void testFeatures() throws Exception {
    System.out.println(executeCommand("fabric:create -n --wait-for-provisioning"));
    // System.out.println(executeCommand("shell:info"));
    // System.out.println(executeCommand("fabric:info"));
    // System.out.println(executeCommand("fabric:profile-list"));

    ServiceProxy<FabricService> fabricProxy =
        ServiceProxy.createServiceProxy(bundleContext, FabricService.class);
    try {
      FabricService fabricService = fabricProxy.getService();

      Set<ContainerProxy> containers =
          ContainerBuilder.create(fabricProxy)
              .withName("feature-camel")
              .withProfiles("feature-camel")
              .assertProvisioningResult()
              .build();
      try {
        CuratorFramework curator = fabricService.adapt(CuratorFramework.class);
        assertProvisionedFeature(
            fabricService,
            curator,
            containers,
            "camel-script-javascript",
            "feature-camel",
            "scriptengines-javascript");
      } finally {
        ContainerBuilder.destroy(containers);
      }
    } finally {
      fabricProxy.close();
    }
  }
Example #5
0
  @Test
  public void testProfileScaling() throws Exception {
    System.err.println(executeCommand("fabric:create -n"));
    FabricService fabricService = getFabricService();
    assertNotNull(fabricService);
    waitForFabricCommands();
    String profile = "mq-amq";
    Integer expected = 1;
    boolean changed = fabricService.scaleProfile(profile, expected);
    assertProfileMinimumSize(profile, expected);

    // lets call the scale method again, should have no effect as already requirements are updated
    // and we've not started an auto-scaler yet
    changed = fabricService.scaleProfile(profile, expected);
    assertProfileMinimumSize(profile, expected);
    Assert.assertEquals("should not have changed!", false, changed);

    changed = fabricService.scaleProfile(profile, 2);
    assertProfileMinimumSize(profile, 2);

    // now lets scale down
    changed = fabricService.scaleProfile(profile, -1);

    // since we have no instances right now, scaling down just removes the minimumInstances
    // requirements ;)
    assertProfileMinimumSize(profile, null);
  }
Example #6
0
 protected Profile getProcessProfile(ProcessRequirements requirements, boolean includeController) {
   Container container = fabricService.getCurrentContainer();
   Profile processProfile =
       new ProfileOverlayImpl(
           new ProcessProfile(container, requirements, fabricService, includeController),
           true,
           fabricService.getDataStore(),
           fabricService.getEnvironment());
   return processProfile;
 }
Example #7
0
 @Override
 public boolean isValidProvider() {
   // docker provider isn't valid in openshift/kubernetes environment
   FabricService service = getFabricService();
   if (service != null) {
     // lets disable child if in docker or openshift environments
     String environment = service.getEnvironment();
     if (Objects.equal(environment, "openshift") || Objects.equal(environment, "kubernetes")) {
       return false;
     }
   }
   return true;
 }
Example #8
0
  /**
   * Creates the environment variables for the given container options using the profiles specified
   * in the options to figure out what environment variables to use.
   */
  public static Map<String, String> getEnvironmentVariables(
      FabricService service, CreateContainerBasicOptions options) {
    Set<String> profileIds = options.getProfiles();
    String versionId = options.getVersion();
    String zookeeperUrl = service.getZookeeperUrl();
    String zookeeperUser = service.getZooKeeperUser();
    String zookeeperPasswordRaw = service.getZookeeperPassword();
    String zookeeperPassword = zookeeperPasswordRaw;
    if (zookeeperPassword != null) {
      zookeeperPassword = PasswordEncoder.encode(zookeeperPassword);
    }
    String localIp = service.getCurrentContainer().getLocalIp();
    if (!Strings.isNullOrBlank(localIp)) {
      int idx = zookeeperUrl.lastIndexOf(':');
      if (idx > 0) {
        localIp += zookeeperUrl.substring(idx);
      }
      zookeeperUrl = localIp;
    }

    Map<String, String> envVarsOverlay =
        Profiles.getOverlayConfiguration(
            service, profileIds, versionId, EnvironmentVariables.ENVIRONMENT_VARIABLES_PID);
    String containerName = options.getName();
    envVarsOverlay.put(EnvironmentVariables.KARAF_NAME, containerName);
    envVarsOverlay.put(EnvironmentVariables.CONTAINER_NAME, containerName);
    if (!options.isEnsembleServer()) {
      if (!envVarsOverlay.containsKey(EnvironmentVariables.ZOOKEEPER_URL)) {
        envVarsOverlay.put(EnvironmentVariables.ZOOKEEPER_URL, zookeeperUrl);
      }
      if (!envVarsOverlay.containsKey(EnvironmentVariables.ZOOKEEPER_USER)) {
        envVarsOverlay.put(EnvironmentVariables.ZOOKEEPER_USER, zookeeperUser);
      }
      if (!envVarsOverlay.containsKey(EnvironmentVariables.ZOOKEEPER_PASSWORD)) {
        envVarsOverlay.put(EnvironmentVariables.ZOOKEEPER_PASSWORD, zookeeperPassword);
      }
      if (!envVarsOverlay.containsKey(EnvironmentVariables.ZOOKEEPER_PASSWORD_RAW)) {
        envVarsOverlay.put(EnvironmentVariables.ZOOKEEPER_PASSWORD_RAW, zookeeperPasswordRaw);
      }
      if (!envVarsOverlay.containsKey(EnvironmentVariables.ZOOKEEPER_PASSWORD_ENCODE)) {
        String zkPasswordEncode = System.getProperty("zookeeper.password.encode", "true");
        envVarsOverlay.put(EnvironmentVariables.ZOOKEEPER_PASSWORD_ENCODE, zkPasswordEncode);
      }
    }
    return envVarsOverlay;
  }
Example #9
0
  @Override
  public void createContainers(AutoScaleRequest request) throws Exception {
    int count = request.getDelta();
    String profile = request.getProfile();
    String version = request.getVersion();
    FabricService fabricService = request.getFabricService();
    CreateChildContainerOptions.Builder builder = null;
    if (fabricService != null) {
      builder = createAutoScaleOptions(request, fabricService);
    }
    if (builder != null) {
      Set<String> ignoreContainerNames = new HashSet<>();
      for (int i = 0; i < count; i++) {
        final CreateChildContainerOptions.Builder configuredBuilder =
            builder.number(1).version(version).profiles(profile);

        Container[] containers = fabricService.getContainers();
        NameValidator nameValidator = Containers.createNameValidator(containers);
        String name =
            Containers.createContainerName(
                containers, profile, containerProvider.getScheme(), nameValidator);
        ignoreContainerNames.add(name);

        CreateChildContainerOptions options = configuredBuilder.name(name).build();
        LOG.info(
            "Creating container name "
                + name
                + " version "
                + version
                + " profile "
                + profile
                + " "
                + count
                + " container(s)");
        fabricService.createContainers(options);
      }
    } else {
      LOG.warn(
          "Could not create version "
              + version
              + " profile "
              + profile
              + " due to missing autoscale configuration");
    }
  }
    protected void recompile() {
        LOG.debug("Looking for XSDs to recompile");

        Set<String> urls = new TreeSet<String>();
        FabricService fabric = getFabricService();
        Container container = fabric.getCurrentContainer();
        String version = container.getVersion().getId();
        List<Profile> profiles = Containers.overlayProfiles(container);
        List<String> profileIds = Profiles.profileIds(profiles);
        Collection<String> names = fabric.getDataStore().listFiles(version, profileIds, schemaPath);
        for (String name : names) {
            if (name.endsWith(".xsd")) {
                String prefix = schemaPath;
                if (Strings.isNotBlank(prefix)) {
                    prefix += "/";
                }
                urls.add("profile:" + prefix + name);
            }
        }

        LOG.info("Recompiling XSDs at URLs: " + urls);
        startedFlag.set(false);

        ClassLoader classLoader = AriesFrameworkUtil.getClassLoader(bundleContext.getBundle());
        if (classLoader == null) {
            classLoader = getClass().getClassLoader();
        }
        DynamicXJC xjc = new DynamicXJC(classLoader);
        xjc.setSchemaUrls(new ArrayList<String>(urls));
        compileResults = xjc.compileSchemas();
        if (handler != null) {
            handler.onCompileResults(compileResults);
        }
        if (introspector != null) {
            introspector.setClassLoaderProvider("dynamic.jaxb", new ClassLoaderProvider() {
                @Override
                public ClassLoader getClassLoader() {
                    return compileResults.getClassLoader();
                }
            });
        }
    }
  protected void checkProcessesStatus() {
    ProcessManager manager = getProcessManager();
    FabricService fabric = getFabricService();
    if (manager != null && fabric != null) {
      ImmutableMap<String, Installation> map = manager.listInstallationMap();
      ImmutableSet<Map.Entry<String, Installation>> entries = map.entrySet();
      for (Map.Entry<String, Installation> entry : entries) {
        String id = entry.getKey();
        Installation installation = entry.getValue();
        try {
          Container container = null;
          try {
            container = fabric.getContainer(id);
          } catch (Exception e) {
            LOG.debug("No container for id: " + id + ". " + e, e);
          }
          if (container != null) {
            Long pid = installation.getActivePid();
            if (LOG.isDebugEnabled()) {
              LOG.debug("Polling container " + id + " for its PID");
            }
            if (pid == null) {
              if (container.isAlive()) {
                container.setAlive(false);
              }
            } else if (pid != null && pid != 0) {
              if (!container.isAlive()) {
                container.setAlive(true);
              }
              if (!Objects.equal(container.getProvisionResult(), Container.PROVISION_SUCCESS)) {
                container.setProvisionResult(Container.PROVISION_SUCCESS);
              }

              JolokiaAgentHelper.jolokiaKeepAliveCheck(fabric, container);
            }
          }
        } catch (Exception e) {
          LOG.warn("Failed to get PID for process " + id + ". " + e, e);
        }
      }
    }
  }
Example #12
0
 @Override
 protected Set<Integer> findUsedPortByHostAndDocker() {
   try {
     FabricService fabric = getFabricService();
     Container currentContainer = fabric.getCurrentContainer();
     Set<Integer> usedPorts;
     Set<Integer> dockerPorts;
     synchronized (portLock) {
       usedPorts = fabric.getPortService().findUsedPortByHost(currentContainer);
       dockerPorts = Dockers.getUsedPorts(docker);
     }
     usedPorts.addAll(dockerPorts);
     return usedPorts;
   } catch (DockerApiConnectionException e) {
     String suggestion =
         String.format(
             "Can't connect to the Docker server. Are you sure a Docker server is running at %s?",
             dockerFactory.getAddress());
     throw new DockerApiConnectionException(suggestion, e.getCause());
   }
 }
  /**
   * Allocates a new jolokia port for the given container ID
   *
   * @param containerId
   * @return
   */
  public synchronized int createJolokiaPort(String containerId) {
    FabricService fabricService = getFabricService();
    Container currentContainer = fabricService.getCurrentContainer();
    Set<Integer> usedPortByHost =
        fabricService.getPortService().findUsedPortByHost(currentContainer);

    while (true) {
      if (externalJolokiaPort <= 0) {
        externalJolokiaPort = JolokiaAgentHelper.DEFAULT_JOLOKIA_PORT;
      } else {
        externalJolokiaPort++;
      }
      if (!usedPortByHost.contains(externalJolokiaPort)) {
        Container container = fabricService.getCurrentContainer();
        String pid = JolokiaAgentHelper.JOLOKIA_PORTS_PID;
        String key = containerId;
        fabricService.getPortService().registerPort(container, pid, key, externalJolokiaPort);
        return externalJolokiaPort;
      }
    }
  }
Example #14
0
 @Override
 public int complete(String buffer, int cursor, List<String> candidates) {
   StringsCompleter delegate = new StringsCompleter();
   String versionName = null;
   try {
     Version version = fabricService.getDefaultVersion();
     Profile[] profiles = version.getProfiles();
     for (Profile profile : profiles) {
       delegate.getStrings().add(profile.getId());
     }
   } catch (Exception ex) {
     // Ignore Exceptions
   }
   return delegate.complete(buffer, cursor, candidates);
 }
  @Test
  public void testLocalFabricCluster() throws Exception {
    fabricService = getFabricService();
    // Test autostartup.
    assertNotNull(fabricService);
    CuratorFramework curator = getCurator();
    curator.getZookeeperClient().blockUntilConnectedOrTimedOut();
    Provision.containerAlive(
        Arrays.<Container>asList(new ContainerImpl(null, "root", fabricService)),
        PROVISION_TIMEOUT);
    Container[] containers = fabricService.getContainers();
    assertNotNull(containers);
    assertEquals("Expected to find 1 container", 1, containers.length);
    assertEquals("Expected to find the root container", "root", containers[0].getId());

    // Test that a generated password exists
    // We don't inject the configuration admin as it causes issues when the tracker gets closed.
    ConfigurationAdmin configurationAdmin = getOsgiService(ConfigurationAdmin.class);
    org.osgi.service.cm.Configuration configuration =
        configurationAdmin.getConfiguration(Constants.ZOOKEEPER_CLIENT_PID);
    Dictionary<String, Object> dictionary = configuration.getProperties();
    assertNotNull("Expected a generated zookeeper password", dictionary.get("zookeeper.password"));
    assertTrue(String.valueOf(dictionary.get("zookeeper.url")).endsWith("2182"));
  }
Example #16
0
  protected Object doExecute() throws Exception {

    // prevent creating fabric if already created
    ServiceReference<FabricService> sref = bundleContext.getServiceReference(FabricService.class);
    FabricService fabricService = sref != null ? bundleContext.getService(sref) : null;
    if (!force
        && (fabricService != null && fabricService.getCurrentContainer().isEnsembleServer())) {
      System.out.println(
          "Current container "
              + fabricService.getCurrentContainerName()
              + " is already in the current fabric ensemble. Cannot create fabric.");
      System.out.println(
          "You can use the --force option, if you want to force re-create the fabric.");
      return null;
    }

    Configuration bootConfiguration =
        configAdmin.getConfiguration(BootstrapConfiguration.COMPONENT_PID, null);
    Dictionary<String, Object> bootProperties = bootConfiguration.getProperties();
    if (bootProperties == null) {
      bootProperties = new Hashtable<>();
    }

    String runtimeIdentity = runtimeProperties.getRuntimeIdentity();
    CreateEnsembleOptions.Builder<?> builder =
        CreateEnsembleOptions.builder()
            .zooKeeperServerTickTime(zooKeeperTickTime)
            .zooKeeperServerInitLimit(zooKeeperInitLimit)
            .zooKeeperServerSyncLimit(zooKeeperSyncLimit)
            .zooKeeperServerDataDir(zooKeeperDataDir)
            .fromRuntimeProperties(runtimeProperties)
            .bootstrapTimeout(bootstrapTimeout)
            .waitForProvision(waitForProvisioning)
            .clean(clean);

    builder.version(version);

    if (containers == null || containers.isEmpty()) {
      containers = Arrays.asList(runtimeIdentity);
    }

    if (!noImport && importDir != null) {
      builder.autoImportEnabled(true);
      builder.importPath(importDir);
    }

    if (globalResolver != null) {
      builder.globalResolver(globalResolver);
      bootProperties.put(ZkDefs.GLOBAL_RESOLVER_PROPERTY, globalResolver);
    }

    if (resolver != null) {
      builder.resolver(resolver);
      bootProperties.put(ZkDefs.LOCAL_RESOLVER_PROPERTY, resolver);
    }

    if (manualIp != null) {
      builder.manualIp(manualIp);
      bootProperties.put(ZkDefs.MANUAL_IP, manualIp);
    }

    if (bindAddress != null) {
      if (!bindAddress.contains(":")) {
        builder.bindAddress(bindAddress);
        bootProperties.put(ZkDefs.BIND_ADDRESS, bindAddress);
      } else {
        String[] parts = bindAddress.split(":");
        builder.bindAddress(parts[0]);
        builder.zooKeeperServerPort(Integer.parseInt(parts[1]));
        bootProperties.put(ZkDefs.BIND_ADDRESS, parts[0]);
      }
    }

    if (zooKeeperServerPort > 0) {
      // --zookeeper-server-port option has higher priority than
      // CreateEnsembleOptions.ZOOKEEPER_SERVER_PORT and
      // CreateEnsembleOptions.ZOOKEEPER_SERVER_CONNECTION_PORT
      // system/runtime properties
      builder.setZooKeeperServerPort(zooKeeperServerPort);
      builder.setZooKeeperServerConnectionPort(zooKeeperServerPort);
    }

    // Configure External Git Repository.
    if (externalGitUrl != null) {
      builder.dataStoreProperty(GIT_REMOTE_URL, externalGitUrl);
    }
    if (externalGitUser != null) {
      builder.dataStoreProperty(GIT_REMOTE_USER, externalGitUser);
    }
    if (externalGitPassword != null) {
      builder.dataStoreProperty(GIT_REMOTE_PASSWORD, externalGitPassword);
    }

    if (profiles != null && profiles.size() > 0) {
      builder.profiles(profiles);
    }

    if (nonManaged) {
      builder.agentEnabled(false);
    } else {
      builder.agentEnabled(true);
    }

    builder.minimumPort(minimumPort);
    builder.minimumPort(maximumPort);
    bootProperties.put(ZkDefs.MINIMUM_PORT, String.valueOf(minimumPort));
    bootProperties.put(ZkDefs.MAXIMUM_PORT, String.valueOf(maximumPort));

    newUser = newUser != null ? newUser : ShellUtils.retrieveFabricUser(session);
    newUserPassword =
        newUserPassword != null ? newUserPassword : ShellUtils.retrieveFabricUserPassword(session);

    Path propsPath = runtimeProperties.getConfPath().resolve("users.properties");
    Properties userProps = new Properties(propsPath.toFile());

    if (userProps.isEmpty()) {
      String[] credentials = promptForNewUser(newUser, newUserPassword);
      newUser = credentials[0];
      newUserPassword = credentials[1];
    } else {
      if (newUser == null || newUserPassword == null) {
        newUser = "" + userProps.keySet().iterator().next();
        newUserPassword = "" + userProps.get(newUser);
        if (newUserPassword.contains(ROLE_DELIMITER)) {
          newUserPassword = newUserPassword.substring(0, newUserPassword.indexOf(ROLE_DELIMITER));
        }
      }
      String passwordWithroles = userProps.get(newUser);
      if (passwordWithroles != null && passwordWithroles.contains(ROLE_DELIMITER)) {
        String[] infos = passwordWithroles.split(",");
        String oldUserRole = newUserRole;
        for (int i = 1; i < infos.length; i++) {
          if (infos[i].trim().startsWith(BackingEngine.GROUP_PREFIX)) {
            // it's a group reference
            String groupInfo = (String) userProps.get(infos[i].trim());
            if (groupInfo != null) {
              String[] roles = groupInfo.split(",");
              for (int j = 1; j < roles.length; j++) {
                if (!roles[j].trim().equals(oldUserRole)) {
                  newUserRole = newUserRole + ROLE_DELIMITER + roles[j].trim();
                }
              }
            }
          } else {
            // it's an user reference
            if (!infos[i].trim().equals(oldUserRole)) {
              newUserRole = newUserRole + ROLE_DELIMITER + infos[i].trim();
            }
          }
        }
      }
    }

    if (Strings.isNullOrEmpty(newUser)) {
      System.out.println("No user specified. Cannot create a new fabric ensemble.");
      return null;
    }

    StringBuilder sb = new StringBuilder();

    // session is unset when this is called from FMC
    if (session != null) {
      ShellUtils.storeFabricCredentials(session, newUser, newUserPassword);
    }

    if (generateZookeeperPassword) {
      // do nothing use the generated password.
    } else if (zookeeperPassword == null) {
      zookeeperPassword =
          PasswordEncoder.decode(
              runtimeProperties.getProperty(
                  CreateEnsembleOptions.ZOOKEEPER_PASSWORD,
                  PasswordEncoder.encode(newUserPassword)));
      builder.zookeeperPassword(zookeeperPassword);
    } else {
      builder.zookeeperPassword(zookeeperPassword);
    }

    bootConfiguration.update(bootProperties);
    CreateEnsembleOptions options =
        builder.users(userProps).withUser(newUser, newUserPassword, newUserRole).build();

    if (containers.size() == 1 && containers.contains(runtimeIdentity)) {
      bootstrap.create(options);
    } else {
      ServiceProxy<ZooKeeperClusterService> serviceProxy =
          ServiceProxy.createServiceProxy(bundleContext, ZooKeeperClusterService.class);
      try {
        serviceProxy.getService().createCluster(containers, options);
      } finally {
        serviceProxy.close();
      }
    }

    ShellUtils.storeZookeeperPassword(session, options.getZookeeperPassword());
    if (zookeeperPassword == null && !generateZookeeperPassword) {
      sb.append("Zookeeper password: (reusing users ")
          .append(newUser)
          .append(" password:"******")\n");
      sb.append(
          "(You can use the --zookeeper-password / --generate-zookeeper-password option to specify one.)\n");
    } else if (generateZookeeperPassword) {
      sb.append("Generated zookeeper password:"******"Using specified zookeeper password:"******"It may take a couple of seconds for the container to provision...");
      System.out.println(
          "You can use the --wait-for-provisioning option, if you want this command to block until the container is provisioned.");
    }

    return null;
  }
  public String generateContainerImage(
      FabricService fabric,
      Container container,
      List<Profile> profileList,
      Docker docker,
      JavaContainerOptions options,
      JavaContainerConfig javaConfig,
      CreateDockerContainerOptions containerOptions,
      ExecutorService downloadExecutor,
      Map<String, String> envVars)
      throws Exception {
    String libDirAndSeparator = ensureEndsWithFileSeparator(options.getJavaLibraryPath());
    String homeDirAndSeparator = ensureEndsWithFileSeparator(options.getHomePath());
    Map<String, Parser> artifacts =
        JavaContainers.getJavaContainerArtifacts(fabric, profileList, downloadExecutor);

    URI mavenRepoURI = fabric.getMavenRepoURI();
    String repoTextPrefix = mavenRepoURI.toString();
    int idx = repoTextPrefix.indexOf("://");
    if (idx > 0) {
      repoTextPrefix = repoTextPrefix.substring(idx + 3);
    }
    repoTextPrefix =
        "http://"
            + fabric.getZooKeeperUser()
            + ":"
            + fabric.getZookeeperPassword()
            + "@"
            + repoTextPrefix;

    String baseImage = options.getBaseImage();
    String tag = options.getNewImageTag();

    DockerFileBuilder dockerFile = DockerFileBuilder.from(baseImage);

    Set<Map.Entry<String, Parser>> entries = artifacts.entrySet();
    for (Map.Entry<String, Parser> entry : entries) {
      Parser parser = entry.getValue();
      String path = parser.getArtifactPath();
      String url = repoTextPrefix + path;
      String version = parser.getVersion();
      String snapshotModifier = "";
      // avoid the use of the docker cache for snapshot dependencies
      if (version != null && version.contains("SNAPSHOT")) {
        long time = new Date().getTime();
        url += "?t=" + time;
        snapshotModifier = "-" + time;
      }
      String fileName =
          parser.getArtifact() + "-" + version + snapshotModifier + "." + parser.getType();
      String filePath = libDirAndSeparator + fileName;

      dockerFile.add(url, filePath);
    }

    if (container != null) {
      List<String> bundles = new ArrayList<String>();
      for (String name : artifacts.keySet()) {
        if (name.startsWith("fab:")) {
          name = name.substring(4);
        }
        bundles.add(name);
      }
      Collections.sort(bundles);
      container.setProvisionList(bundles);
    }

    String restAPI = fabric.getRestAPI();
    if (Strings.isNotBlank(restAPI)) {
      addContainerOverlays(
          dockerFile,
          restAPI,
          fabric,
          container,
          profileList,
          docker,
          options,
          javaConfig,
          containerOptions,
          envVars,
          homeDirAndSeparator);
    } else {
      LOGGER.error("Cannot perform container overlays as there is no REST API for fabric8!");
    }

    String[] copiedEnvVars = JavaContainerEnvironmentVariables.ALL_ENV_VARS;
    for (String envVarName : copiedEnvVars) {
      String value = envVars.get(envVarName);
      if (value != null) {
        dockerFile.env(envVarName, value);
      }
    }

    String entryPoint = options.getEntryPoint();
    if (Strings.isNotBlank(entryPoint)) {
      dockerFile.cmd(entryPoint);
    }

    // TODO we should keep a cache of the Dockerfile text for each profile so we don't create it
    // each time

    // lets use the command line for now....
    File tmpFile = File.createTempFile("fabric-", ".dockerfiledir");
    tmpFile.delete();
    tmpFile.mkdirs();

    dockerFile.writeTo(new File(tmpFile, "Dockerfile"));

    // lets use the docker command line for now...
    String[] commands = new String[] {"docker", "build", "-t", tag, tmpFile.getCanonicalPath()};

    String message = join(asList(commands), " ");
    LOGGER.info("Executing commands: " + message);
    String answer = null;
    String errors = null;
    String dockerHost = resolveDockerHost();
    try {
      ProcessBuilder dockerBuild = new ProcessBuilder().command(commands);
      Map<String, String> env = dockerBuild.environment();
      env.put("DOCKER_HOST", dockerHost);
      Process process = dockerBuild.start();
      answer = parseCreatedImage(process.getInputStream(), message);
      errors = processErrors(process.getErrorStream(), message);
    } catch (Exception e) {
      LOGGER.error("Failed to execute process " + "stdin" + " for " + message + ": " + e, e);
      throw e;
    }
    if (answer == null) {
      LOGGER.error("Failed to create image " + errors);
      throw new CreateDockerImageFailedException("Failed to create docker image: " + errors);
    } else {
      LOGGER.info("Created Image: " + answer);
      return answer;
    }
  }
  protected void addContainerOverlays(
      DockerFileBuilder dockerFile,
      String restAPI,
      FabricService fabricService,
      Container container,
      List<Profile> profiles,
      Docker docker,
      JavaContainerOptions options,
      JavaContainerConfig javaConfig,
      CreateDockerContainerOptions containerOptions,
      Map<String, String> environmentVariables,
      String homeDirAndSeparator)
      throws Exception {
    Set<String> profileIds = containerOptions.getProfiles();
    String versionId = containerOptions.getVersion();
    String layout = javaConfig.getOverlayFolder();
    if (layout != null) {
      for (Profile profile : profiles) {
        Map<String, String> configuration = ProcessUtils.getProcessLayout(profile, layout);
        if (configuration != null && !configuration.isEmpty()) {
          String profileRestApi =
              restAPI
                  + "/version/"
                  + profile.getVersion()
                  + "/profile/"
                  + profile.getId()
                  + "/overlay/file/"
                  + layout
                  + (layout.endsWith("/") ? "" : "/");
          Map variables =
              Profiles.getOverlayConfiguration(
                  fabricService, profileIds, versionId, ChildConstants.TEMPLATE_VARIABLES_PID);
          if (variables == null) {
            variables = new HashMap();
          } else {
            CuratorFramework curator = fabricService.adapt(CuratorFramework.class);
            JolokiaAgentHelper.substituteEnvironmentVariableExpressions(
                variables, environmentVariables, fabricService, curator);
          }
          variables.putAll(environmentVariables);
          LOGGER.info("Using template variables for MVEL: " + variables);
          new ApplyConfigurationStep(
                  dockerFile,
                  profileRestApi,
                  configuration,
                  variables,
                  getTempDirectory(),
                  homeDirAndSeparator)
              .install();
        }
      }
    }
    Map<String, String> overlayResources =
        Profiles.getOverlayConfiguration(
            fabricService,
            profileIds,
            versionId,
            ChildConstants.PROCESS_CONTAINER_OVERLAY_RESOURCES_PID);
    if (overlayResources != null && !overlayResources.isEmpty()) {
      File baseDir = getTempDirectory();
      Set<Map.Entry<String, String>> entries = overlayResources.entrySet();
      for (Map.Entry<String, String> entry : entries) {
        String localPath = entry.getKey();
        String urlText = entry.getValue();
        if (Strings.isNotBlank(urlText)) {
          URL url = null;
          try {
            url = new URL(urlText);
          } catch (MalformedURLException e) {
            LOGGER.warn(
                "Ignoring invalid URL '"
                    + urlText
                    + "' for overlay resource "
                    + localPath
                    + ". "
                    + e,
                e);
          }
          if (url != null) {
            // TODO find the URL of the resource in the maven repo and add it like we do with maven
            // dependencies above
            LOGGER.warn("TODO - add overlay resources into a docker file for URL: " + url);
            /*
                                    File newFile = new File(baseDir, localPath);
                                    newFile.getParentFile().mkdirs();
                                    InputStream stream = url.openStream();
                                    if (stream != null) {
                                        Files.copy(stream, new BufferedOutputStream(new FileOutputStream(newFile)));

                                        // now lets add to the Dockerfile
                                        dockerFile.add(newFile.getAbsolutePath(), localPath);
                                    }
            */
          }
        }
      }
    }
  }
  @Test
  public void testRegistryEntries() throws Exception {
    System.out.println(executeCommand("fabric:create -n root"));
    System.out.println(executeCommand("fabric:profile-list"));

    ServiceProxy<FabricService> fabricProxy =
        ServiceProxy.createServiceProxy(bundleContext, FabricService.class);
    try {
      FabricService fabricService = fabricProxy.getService();
      CuratorFramework curator = fabricService.adapt(CuratorFramework.class);

      Set<ContainerProxy> containers =
          ContainerBuilder.create(fabricProxy, 3)
              .withName("fabric-camel")
              .withProfiles("feature-camel")
              .assertProvisioningResult()
              .build();
      try {
        // We will use the first container as a client and the rest as servers.
        LinkedList<Container> containerList = new LinkedList<Container>(containers);
        Container client = containerList.removeLast();

        LinkedList<Container> servers = new LinkedList<Container>(containerList);

        for (Container c : servers) {
          Profile p = c.getVersion().getProfile("example-camel-cluster.server");
          c.setProfiles(new Profile[] {p});
        }

        Provision.provisioningSuccess(servers, PROVISION_TIMEOUT);

        Profile p = client.getVersion().getProfile("example-camel-cluster.client");
        client.setProfiles(new Profile[] {p});

        Provision.provisioningSuccess(Arrays.asList(new Container[] {client}), PROVISION_TIMEOUT);

        System.out.println(executeCommand("fabric:container-list"));
        System.out.println(executeCommand("fabric:profile-display --overlay fabric-camel-server"));

        // Check that the entries have been properly propagated.
        Assert.assertNotNull(exists(curator, "/fabric/registry/camel/endpoints"));
        Assert.assertEquals(1, getChildren(curator, "/fabric/registry/camel/endpoints").size());

        Assert.assertTrue(
            Provision.waitForCondition(
                Arrays.asList(client),
                new ContainerCondition() {
                  @Override
                  public Boolean checkConditionOnContainer(final Container c) {
                    return getCompletedExchangesCount(c) > 0;
                  }
                },
                60000L));

        // We want to kill all but one server, so we take out the first and keep it to the end.
        Container lastActiveServerContainer = servers.removeLast();

        for (Container c : servers) {
          try {
            c.destroy(true);
          } catch (Exception ex) {
            // ignore.
          }
          // Get the number of exchanges completed before we kill the server.
          final int completed = getCompletedExchangesCount(client);

          // Ensure that we still have messages flowing
          Assert.assertTrue(
              Provision.waitForCondition(
                  Arrays.asList(client),
                  new ContainerCondition() {
                    @Override
                    public Boolean checkConditionOnContainer(final Container c) {
                      return getCompletedExchangesCount(c) > completed + 3;
                    }
                  },
                  60000L));
        }
        System.out.println(
            new AnsiString(
                    executeCommand(
                        "fabric:container-connect -u admin -p admin "
                            + client.getId()
                            + " camel:route-info fabric-client"))
                .getPlain()
                .toString());
      } finally {
        ContainerBuilder.destroy(containers);
      }
    } finally {
      fabricProxy.close();
    }
  }
    public DockerCreateContainerParameters invoke() throws Exception {
      assertValid();

      String containerId = options.getName();
      containerConfig = createContainerConfig(options);

      // allow values to be extracted from the profile configuration
      // such as the image
      Set<String> profileIds = options.getProfiles();
      String versionId = options.getVersion();
      FabricService service = getFabricService();
      Map<String, String> configOverlay = new HashMap<>();
      Map<String, String> ports = null;
      Map<String, String> dockerProviderConfig = new HashMap<>();

      List<Profile> profileOverlays = new ArrayList<>();
      Version version = null;
      if (profileIds != null && versionId != null) {
        ProfileService profileService = service.adapt(ProfileService.class);
        version = profileService.getVersion(versionId);
        if (version != null) {
          for (String profileId : profileIds) {
            Profile profile = version.getRequiredProfile(profileId);
            if (profile != null) {
              Profile overlay = profileService.getOverlayProfile(profile);
              profileOverlays.add(overlay);
              Map<String, String> dockerConfig =
                  overlay.getConfiguration(DockerConstants.DOCKER_PROVIDER_PID);
              if (dockerConfig != null) {
                configOverlay.putAll(dockerConfig);
              }
              if (ports == null || ports.size() == 0) {
                ports = overlay.getConfiguration(Constants.PORTS_PID);
              }
            }
          }
          if (version.hasProfile(DockerConstants.DOCKER_PROVIDER_PROFILE_ID)) {
            Profile profile =
                version.getRequiredProfile(DockerConstants.DOCKER_PROVIDER_PROFILE_ID);
            if (profile != null) {
              Profile overlay = profileService.getOverlayProfile(profile);
              Map<String, String> dockerConfig =
                  overlay.getConfiguration(DockerConstants.DOCKER_PROVIDER_PID);
              if (dockerConfig != null) {
                dockerProviderConfig.putAll(dockerConfig);
              }
            }
          }
        }
      }
      if (ports == null || ports.size() == 0) {
        // lets find the defaults from the docker profile
        if (version == null) {
          version = service.getRequiredDefaultVersion();
        }
        Profile dockerProfile = version.getRequiredProfile("docker");
        ports = dockerProfile.getConfiguration(Constants.PORTS_PID);
        if (ports == null || ports.size() == 0) {
          LOG.warn("Could not a docker ports configuration for: " + Constants.PORTS_PID);
          ports = new HashMap<String, String>();
        }
      }
      LOG.info("Got port configuration: " + ports);

      environmentVariables =
          ChildContainers.getEnvironmentVariables(service, options, DockerConstants.SCHEME);

      DockerProviderConfig configOverlayDockerProvider =
          createDockerProviderConfig(configOverlay, environmentVariables);

      CuratorFramework curatorOptional = getCuratorFramework();
      String image =
          JolokiaAgentHelper.substituteVariableExpression(
              containerConfig.getImage(), environmentVariables, service, curatorOptional, true);

      if (Strings.isNullOrBlank(image)) {
        image = configOverlayDockerProvider.getImage();
        if (Strings.isNullOrBlank(image)) {
          DockerProviderConfig dockerProviderConfigObject =
              createDockerProviderConfig(dockerProviderConfig, environmentVariables);
          image = dockerProviderConfigObject.getImage();
        }
        if (Strings.isNullOrBlank(image)) {
          image = System.getenv(DockerConstants.EnvironmentVariables.FABRIC8_DOCKER_DEFAULT_IMAGE);
        }
        if (Strings.isNullOrBlank(image)) {
          image = DockerConstants.DEFAULT_IMAGE;
        }
        containerConfig.setImage(image);
      }
      containerType = "docker " + image;
      Container container = service.getContainer(containerId);
      if (container != null) {
        container.setType(containerType);
      }

      String[] cmd = containerConfig.getCmd();
      if (cmd == null || cmd.length == 0) {
        String value = configOverlayDockerProvider.getCmd();
        if (Strings.isNullOrBlank(value)) {
          cmd = null;
        } else {
          cmd = new String[] {value};
        }
        containerConfig.setCmd(cmd);
      }

      Map<String, Integer> internalPorts = options.getInternalPorts();
      Map<String, Integer> externalPorts = options.getExternalPorts();

      Map<String, Object> exposedPorts = new HashMap<>();
      Set<Integer> usedPortByHost = findUsedPortByHostAndDocker();
      Map<String, String> emptyMap = new HashMap<>();

      SortedMap<Integer, String> sortedInternalPorts = new TreeMap<>();
      for (Map.Entry<String, String> portEntry : ports.entrySet()) {
        String portName = portEntry.getKey();
        String portText = portEntry.getValue();
        if (portText != null && !Strings.isNullOrBlank(portText)) {
          Integer port = null;
          try {
            port = Integer.parseInt(portText);
          } catch (NumberFormatException e) {
            LOG.warn(
                "Ignoring bad port number for "
                    + portName
                    + " value '"
                    + portText
                    + "' in PID: "
                    + Constants.PORTS_PID);
          }
          if (port != null) {
            sortedInternalPorts.put(port, portName);
            internalPorts.put(portName, port);
            exposedPorts.put(portText + "/tcp", emptyMap);
          } else {
            LOG.info("No port for " + portName);
          }
        }
      }

      String dockerHost = dockerFactory.getDockerHost();
      jolokiaUrl = null;

      Map<String, String> javaContainerConfig =
          Profiles.getOverlayConfiguration(
              service, profileIds, versionId, Constants.JAVA_CONTAINER_PID);
      JavaContainerConfig javaConfig = new JavaContainerConfig();
      getConfigurer().configure(javaContainerConfig, javaConfig);

      boolean isJavaContainer = ChildContainers.isJavaContainer(getFabricService(), options);

      // lets create the ports in sorted order
      for (Map.Entry<Integer, String> entry : sortedInternalPorts.entrySet()) {
        Integer port = entry.getKey();
        String portName = entry.getValue();
        int externalPort = createExternalPort(containerId, portName, usedPortByHost, options);
        externalPorts.put(portName, externalPort);
        environmentVariables.put("FABRIC8_" + portName + "_PORT", "" + port);
        environmentVariables.put("FABRIC8_" + portName + "_PROXY_PORT", "" + externalPort);

        if (portName.equals(JolokiaAgentHelper.JOLOKIA_PORT_NAME)) {
          jolokiaUrl = "http://" + dockerHost + ":" + externalPort + "/jolokia/";
          LOG.info("Found Jolokia URL: " + jolokiaUrl);

          JolokiaAgentHelper.substituteEnvironmentVariables(
              javaConfig,
              environmentVariables,
              isJavaContainer,
              JolokiaAgentHelper.getJolokiaPortOverride(port),
              JolokiaAgentHelper.getJolokiaAgentIdOverride(getFabricService().getEnvironment()));
        } else {
          JolokiaAgentHelper.substituteEnvironmentVariables(
              javaConfig,
              environmentVariables,
              isJavaContainer,
              JolokiaAgentHelper.getJolokiaAgentIdOverride(getFabricService().getEnvironment()));
        }
      }
      javaConfig.updateEnvironmentVariables(environmentVariables, isJavaContainer);

      LOG.info("Passing in manual ip: " + dockerHost);
      environmentVariables.put(EnvironmentVariables.FABRIC8_MANUALIP, dockerHost);
      if (container != null) {
        container.setManualIp(dockerHost);
      }
      if (!environmentVariables.containsKey(EnvironmentVariables.FABRIC8_LISTEN_ADDRESS)) {
        environmentVariables.put(EnvironmentVariables.FABRIC8_LISTEN_ADDRESS, dockerHost);
      }
      environmentVariables.put(EnvironmentVariables.FABRIC8_GLOBAL_RESOLVER, ZkDefs.MANUAL_IP);
      environmentVariables.put(
          EnvironmentVariables.FABRIC8_FABRIC_ENVIRONMENT, DockerConstants.SCHEME);

      // now the environment variables are all set lets see if we need to make a custom image
      String libDir = configOverlayDockerProvider.getJavaLibraryPath();
      String deployDir = configOverlayDockerProvider.getJavaDeployPath();
      String homeDir = configOverlayDockerProvider.getHomePath();
      if (Strings.isNotBlank(libDir) || Strings.isNotBlank(deployDir)) {
        if (container != null) {
          container.setProvisionResult("preparing");
          container.setAlive(true);
        }
        String imageRepository = configOverlayDockerProvider.getImageRepository();
        String entryPoint = configOverlayDockerProvider.getImageEntryPoint();
        List<String> names = new ArrayList<String>(profileIds);
        names.add(versionId);
        String newImageName = "fabric8-" + Strings.join(names, "-").replace('.', '-');
        String customImageUserName = configOverlayDockerProvider.getCustomImageUserName();

        DockerProviderConfig currentContainerDockerProviderConfig = null;
        Container currentContainer = service.getCurrentContainer();
        if (currentContainer != null) {
          Map<String, String> configuration =
              currentContainer
                  .getOverlayProfile()
                  .getConfiguration(DockerConstants.DOCKER_PROVIDER_PID);
          if (configuration != null && !configuration.isEmpty()) {
            Map<String, Map<String, String>> configurations = new HashMap<>();
            configurations.put(DockerConstants.DOCKER_PROVIDER_PID, configuration);
            service.substituteConfigurations(configurations);
            configuration = configurations.get(DockerConstants.DOCKER_PROVIDER_PID);
            configuration =
                JolokiaAgentHelper.substituteEnvironmentVariableExpressionKeysAndValues(
                    configuration, System.getenv());
            currentContainerDockerProviderConfig = createDockerProviderConfig(configuration);
          }
        }
        if (Strings.isNullOrBlank(customImageUserName)
            && currentContainerDockerProviderConfig != null) {
          customImageUserName = currentContainerDockerProviderConfig.getCustomImageUserName();
        }
        Boolean customImagePushValue = configOverlayDockerProvider.getCustomImagePush();
        if (customImagePushValue == null && currentContainerDockerProviderConfig != null) {
          customImagePushValue = currentContainerDockerProviderConfig.getCustomImagePush();
        }
        boolean customImagePush =
            customImagePushValue != null && customImagePushValue.booleanValue();
        if (Strings.isNotBlank(customImageUserName)) {
          newImageName = customImageUserName + "/" + newImageName;
        } else {
          customImagePush = false;
        }

        CustomDockerContainerImageBuilder builder = new CustomDockerContainerImageBuilder();
        CustomDockerContainerImageOptions customDockerContainerImageOptions =
            new CustomDockerContainerImageOptions(
                image,
                imageRepository,
                newImageName,
                libDir,
                deployDir,
                homeDir,
                entryPoint,
                configOverlayDockerProvider.getOverlayFolder(),
                configOverlayDockerProvider.isMavenJavaLibraryPathLayout());

        String actualImage =
            builder.generateContainerImage(
                service,
                container,
                profileOverlays,
                docker,
                customDockerContainerImageOptions,
                options,
                downloadExecutor,
                environmentVariables);
        if (actualImage != null) {
          containerConfig.setImage(actualImage);

          if (customImagePush) {
            LOG.info(
                "Pushing image to repository " + newImageName + " actualImage: " + actualImage);
            Auth authConfig = new Auth();
            authConfig.setEmail("*****@*****.**");
            authConfig.setUsername(service.getZooKeeperUser());
            authConfig.setPassword(service.getZookeeperPassword());
            try {
              docker.imagePush(newImageName, "latest", authConfig);
              LOG.info("Image pushed to repository " + newImageName);
            } catch (Exception e) {
              LOG.info(
                  "Failed to push image " + newImageName + ": " + e + Dockers.dockerErrorMessage(e),
                  e);
              throw e;
            }
          }
        }
      }

      JolokiaAgentHelper.substituteEnvironmentVariableExpressions(
          environmentVariables, environmentVariables, service, curatorOptional, false);

      List<String> env = containerConfig.getEnv();
      if (env == null) {
        env = new ArrayList<>();
      }
      Dockers.addEnvironmentVariablesToList(env, environmentVariables);
      containerConfig.setExposedPorts(exposedPorts);
      containerConfig.setEnv(env);

      String name = options.getName();

      LOG.info(
          "Creating container on docker: "
              + getDockerAddress()
              + " name: "
              + name
              + " env vars: "
              + env);
      LOG.info("Creating container with config: " + containerConfig);
      return this;
    }