protected DataStore getDataStore() { FabricService service = getFabricService(); if (service != null) { return service.getDataStore(); } return null; }
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(); } }
@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); }
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; }
@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; }
/** * 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; }
@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); } } } }
@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; } } }
@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")); }
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; }