diff --git a/assembly/assembly-wsmaster-war/src/main/webapp/WEB-INF/classes/che/che.properties b/assembly/assembly-wsmaster-war/src/main/webapp/WEB-INF/classes/che/che.properties index fcc7217cc1f..dbffa35cf1d 100644 --- a/assembly/assembly-wsmaster-war/src/main/webapp/WEB-INF/classes/che/che.properties +++ b/assembly/assembly-wsmaster-war/src/main/webapp/WEB-INF/classes/che/che.properties @@ -607,8 +607,8 @@ che.singleport.wildcard_domain.ipless=false # Docker image of Che plugin broker app that resolves workspace tooling configuration and copies # plugins dependencies to a workspace -che.workspace.plugin_broker.init.image=eclipse/che-init-plugin-broker:v0.20 -che.workspace.plugin_broker.unified.image=eclipse/che-unified-plugin-broker:v0.20 +che.workspace.plugin_broker.init.image=eclipse/che-init-plugin-broker:v0.21 +che.workspace.plugin_broker.unified.image=eclipse/che-unified-plugin-broker:v0.21 # Docker image of Che plugin broker app that resolves workspace tooling configuration and copies # plugins dependencies to a workspace diff --git a/infrastructures/kubernetes/src/main/java/org/eclipse/che/workspace/infrastructure/kubernetes/wsplugins/ChePluginsVolumeApplier.java b/infrastructures/kubernetes/src/main/java/org/eclipse/che/workspace/infrastructure/kubernetes/wsplugins/ChePluginsVolumeApplier.java new file mode 100644 index 00000000000..8f62c43ef66 --- /dev/null +++ b/infrastructures/kubernetes/src/main/java/org/eclipse/che/workspace/infrastructure/kubernetes/wsplugins/ChePluginsVolumeApplier.java @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2012-2018 Red Hat, Inc. + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Red Hat, Inc. - initial API and implementation + */ + +package org.eclipse.che.workspace.infrastructure.kubernetes.wsplugins; + +import static org.eclipse.che.workspace.infrastructure.kubernetes.namespace.KubernetesObjectUtil.newPVC; +import static org.eclipse.che.workspace.infrastructure.kubernetes.namespace.KubernetesObjectUtil.newVolume; +import static org.eclipse.che.workspace.infrastructure.kubernetes.namespace.KubernetesObjectUtil.newVolumeMount; + +import io.fabric8.kubernetes.api.model.Container; +import io.fabric8.kubernetes.api.model.PersistentVolumeClaim; +import io.fabric8.kubernetes.api.model.PodSpec; +import io.fabric8.kubernetes.api.model.VolumeBuilder; +import java.util.Collection; +import java.util.Optional; +import javax.inject.Inject; +import javax.inject.Named; +import javax.inject.Singleton; +import org.eclipse.che.api.workspace.server.wsplugins.model.Volume; +import org.eclipse.che.workspace.infrastructure.kubernetes.environment.KubernetesEnvironment; + +/** + * Components for applying workspace plugin volumes to the kubernetes {@link + * io.fabric8.kubernetes.api.model.Container}. + */ +@Singleton +public class ChePluginsVolumeApplier { + + private final String pvcQuantity; + private final String pvcAccessMode; + private final String pvcStorageClassName; + + @Inject + public ChePluginsVolumeApplier( + @Named("che.infra.kubernetes.pvc.quantity") String pvcQuantity, + @Named("che.infra.kubernetes.pvc.access_mode") String pvcAccessMode, + @Named("che.infra.kubernetes.pvc.storage_class_name") String pvcStorageClassName) { + this.pvcQuantity = pvcQuantity; + this.pvcAccessMode = pvcAccessMode; + this.pvcStorageClassName = pvcStorageClassName; + } + + public void applyVolumes( + KubernetesEnvironment.PodData pod, + Container container, + Collection volumes, + KubernetesEnvironment k8sEnv) { + for (Volume volume : volumes) { + String podVolumeName = provisionPodVolume(volume, pod, k8sEnv); + + container.getVolumeMounts().add(newVolumeMount(podVolumeName, volume.getMountPath(), "")); + } + } + + private String provisionPodVolume( + Volume volume, KubernetesEnvironment.PodData pod, KubernetesEnvironment k8sEnv) { + if (volume.isEphemeral()) { + addEmptyDirVolumeIfAbsent(pod.getSpec(), volume.getName()); + return volume.getName(); + } else { + return provisionPVCPodVolume(volume, pod, k8sEnv).getName(); + } + } + + private io.fabric8.kubernetes.api.model.Volume provisionPVCPodVolume( + Volume volume, KubernetesEnvironment.PodData pod, KubernetesEnvironment k8sEnv) { + String pvcName = volume.getName(); + + if (!k8sEnv.getPersistentVolumeClaims().containsKey(pvcName)) { + final PersistentVolumeClaim pvc = + newPVC(pvcName, pvcAccessMode, pvcQuantity, pvcStorageClassName); + k8sEnv.getPersistentVolumeClaims().put(pvcName, pvc); + } + + PodSpec podSpec = pod.getSpec(); + Optional volumeOpt = + podSpec + .getVolumes() + .stream() + .filter( + vm -> + vm.getPersistentVolumeClaim() != null + && pvcName.equals(vm.getPersistentVolumeClaim().getClaimName())) + .findAny(); + io.fabric8.kubernetes.api.model.Volume podVolume; + if (volumeOpt.isPresent()) { + podVolume = volumeOpt.get(); + } else { + podVolume = newVolume(pvcName, pvcName); + podSpec.getVolumes().add(podVolume); + } + return podVolume; + } + + private void addEmptyDirVolumeIfAbsent(PodSpec podSpec, String uniqueVolumeName) { + if (podSpec + .getVolumes() + .stream() + .noneMatch(volume -> volume.getName().equals(uniqueVolumeName))) { + podSpec + .getVolumes() + .add( + new VolumeBuilder() + .withName(uniqueVolumeName) + .withNewEmptyDir() + .endEmptyDir() + .build()); + } + } +} diff --git a/infrastructures/kubernetes/src/main/java/org/eclipse/che/workspace/infrastructure/kubernetes/wsplugins/KubernetesPluginsToolingApplier.java b/infrastructures/kubernetes/src/main/java/org/eclipse/che/workspace/infrastructure/kubernetes/wsplugins/KubernetesPluginsToolingApplier.java index efb02d23dea..3a5656218ab 100644 --- a/infrastructures/kubernetes/src/main/java/org/eclipse/che/workspace/infrastructure/kubernetes/wsplugins/KubernetesPluginsToolingApplier.java +++ b/infrastructures/kubernetes/src/main/java/org/eclipse/che/workspace/infrastructure/kubernetes/wsplugins/KubernetesPluginsToolingApplier.java @@ -71,18 +71,21 @@ public class KubernetesPluginsToolingApplier implements ChePluginsApplier { private final String sidecarImagePullPolicy; private final boolean isAuthEnabled; private final ProjectsRootEnvVariableProvider projectsRootEnvVariableProvider; + private final ChePluginsVolumeApplier chePluginsVolumeApplier; @Inject public KubernetesPluginsToolingApplier( @Named("che.workspace.sidecar.image_pull_policy") String sidecarImagePullPolicy, @Named("che.workspace.sidecar.default_memory_limit_mb") long defaultSidecarMemoryLimitMB, @Named("che.agents.auth_enabled") boolean isAuthEnabled, - ProjectsRootEnvVariableProvider projectsRootEnvVariableProvider) { + ProjectsRootEnvVariableProvider projectsRootEnvVariableProvider, + ChePluginsVolumeApplier chePluginsVolumeApplier) { this.defaultSidecarMemoryLimitBytes = String.valueOf(defaultSidecarMemoryLimitMB * 1024 * 1024); this.isAuthEnabled = isAuthEnabled; this.sidecarImagePullPolicy = validImagePullPolicies.contains(sidecarImagePullPolicy) ? sidecarImagePullPolicy : null; this.projectsRootEnvVariableProvider = projectsRootEnvVariableProvider; + this.chePluginsVolumeApplier = chePluginsVolumeApplier; } @Override @@ -95,13 +98,13 @@ public void apply( return; } - KubernetesEnvironment kubernetesEnvironment = (KubernetesEnvironment) internalEnvironment; + KubernetesEnvironment k8sEnv = (KubernetesEnvironment) internalEnvironment; - Map pods = kubernetesEnvironment.getPodsData(); + Map pods = k8sEnv.getPodsData(); switch (pods.size()) { case 0: - addToolingPod(kubernetesEnvironment); - pods = kubernetesEnvironment.getPodsData(); + addToolingPod(k8sEnv); + pods = k8sEnv.getPodsData(); break; case 1: break; @@ -111,31 +114,27 @@ public void apply( } PodData pod = pods.values().iterator().next(); - CommandsResolver commandsResolver = new CommandsResolver(kubernetesEnvironment); + CommandsResolver commandsResolver = new CommandsResolver(k8sEnv); for (ChePlugin chePlugin : chePlugins) { for (CheContainer container : chePlugin.getInitContainers()) { - pod.getSpec().getInitContainers().add(toK8sContainer(container)); + Container k8sInitContainer = toK8sContainer(container); + pod.getSpec().getInitContainers().add(k8sInitContainer); + chePluginsVolumeApplier.applyVolumes(pod, k8sInitContainer, container.getVolumes(), k8sEnv); } Collection pluginRelatedCommands = commandsResolver.resolve(chePlugin); for (CheContainer container : chePlugin.getContainers()) { - addSidecar( - pod, - container, - chePlugin, - kubernetesEnvironment, - pluginRelatedCommands, - runtimeIdentity); + addSidecar(pod, container, chePlugin, k8sEnv, pluginRelatedCommands, runtimeIdentity); } } - chePlugins.forEach(chePlugin -> populateWorkspaceEnvVars(chePlugin, kubernetesEnvironment)); + chePlugins.forEach(chePlugin -> populateWorkspaceEnvVars(chePlugin, k8sEnv)); if (isAuthEnabled) { // enable per-workspace security with JWT proxy for sidecar based workspaces // because it is the only workspace security implementation supported for now - kubernetesEnvironment.getAttributes().putIfAbsent(SECURE_EXPOSER_IMPL_PROPERTY, "jwtproxy"); + k8sEnv.getAttributes().putIfAbsent(SECURE_EXPOSER_IMPL_PROPERTY, "jwtproxy"); } } @@ -201,7 +200,7 @@ private void addSidecar( PodData pod, CheContainer container, ChePlugin chePlugin, - KubernetesEnvironment kubernetesEnvironment, + KubernetesEnvironment k8sEnv, Collection sidecarRelatedCommands, RuntimeIdentity runtimeIdentity) throws InfrastructureException { @@ -211,6 +210,7 @@ private void addSidecar( List containerEndpoints = k8sContainerResolver.getEndpoints(); Container k8sContainer = k8sContainerResolver.resolve(); + chePluginsVolumeApplier.applyVolumes(pod, k8sContainer, container.getVolumes(), k8sEnv); String machineName = k8sContainer.getName(); Names.putMachineName(pod.getMetadata(), k8sContainer.getName(), machineName); @@ -222,7 +222,7 @@ private void addSidecar( .setContainer(k8sContainer) .setContainerEndpoints(containerEndpoints) .setDefaultSidecarMemorySizeAttribute(defaultSidecarMemoryLimitBytes) - .setAttributes(kubernetesEnvironment.getAttributes()) + .setAttributes(k8sEnv.getAttributes()) .setProjectsRootPathEnvVar(projectsRootEnvVariableProvider.get(runtimeIdentity)) .setPluginPublisher(chePlugin.getPublisher()) .setPluginName(chePlugin.getName()) @@ -232,7 +232,7 @@ private void addSidecar( InternalMachineConfig machineConfig = machineResolver.resolve(); machineConfig.getAttributes().put(CONTAINER_SOURCE_ATTRIBUTE, TOOL_CONTAINER_SOURCE); machineConfig.getAttributes().put(PLUGIN_MACHINE_ATTRIBUTE, chePlugin.getId()); - kubernetesEnvironment.getMachines().put(machineName, machineConfig); + k8sEnv.getMachines().put(machineName, machineConfig); sidecarRelatedCommands.forEach( c -> @@ -245,11 +245,11 @@ private void addSidecar( .getCommands() .stream() .map(c -> asCommand(machineName, c)) - .forEach(c -> kubernetesEnvironment.getCommands().add(c)); + .forEach(c -> k8sEnv.getCommands().add(c)); SidecarServicesProvisioner sidecarServicesProvisioner = new SidecarServicesProvisioner(containerEndpoints, pod.getMetadata().getName()); - sidecarServicesProvisioner.provision(kubernetesEnvironment); + sidecarServicesProvisioner.provision(k8sEnv); } private CommandImpl asCommand(String machineName, Command command) { diff --git a/infrastructures/kubernetes/src/main/java/org/eclipse/che/workspace/infrastructure/kubernetes/wsplugins/MachineResolver.java b/infrastructures/kubernetes/src/main/java/org/eclipse/che/workspace/infrastructure/kubernetes/wsplugins/MachineResolver.java index b2d68e0109c..b15f1d1e453 100644 --- a/infrastructures/kubernetes/src/main/java/org/eclipse/che/workspace/infrastructure/kubernetes/wsplugins/MachineResolver.java +++ b/infrastructures/kubernetes/src/main/java/org/eclipse/che/workspace/infrastructure/kubernetes/wsplugins/MachineResolver.java @@ -167,7 +167,6 @@ private void normalizeMemory(Container container, InternalMachineConfig machineC projectsRootPathEnvVar.second, projectsRootPathEnvVar.first)); } - result.put(volume.getName(), new VolumeImpl().withPath(volume.getMountPath())); } return result; } diff --git a/infrastructures/kubernetes/src/test/java/org/eclipse/che/workspace/infrastructure/kubernetes/wsplugins/KubernetesPluginsToolingApplierTest.java b/infrastructures/kubernetes/src/test/java/org/eclipse/che/workspace/infrastructure/kubernetes/wsplugins/KubernetesPluginsToolingApplierTest.java index dfc60c8c3a0..c7c7ec6993c 100644 --- a/infrastructures/kubernetes/src/test/java/org/eclipse/che/workspace/infrastructure/kubernetes/wsplugins/KubernetesPluginsToolingApplierTest.java +++ b/infrastructures/kubernetes/src/test/java/org/eclipse/che/workspace/infrastructure/kubernetes/wsplugins/KubernetesPluginsToolingApplierTest.java @@ -27,8 +27,10 @@ import static org.eclipse.che.workspace.infrastructure.kubernetes.Constants.CHE_ORIGINAL_NAME_LABEL; import static org.eclipse.che.workspace.infrastructure.kubernetes.server.secure.SecureServerExposerFactoryProvider.SECURE_EXPOSER_IMPL_PROPERTY; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.lenient; import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertNull; @@ -59,7 +61,6 @@ import org.eclipse.che.api.core.model.workspace.runtime.RuntimeIdentity; import org.eclipse.che.api.workspace.server.model.impl.CommandImpl; import org.eclipse.che.api.workspace.server.model.impl.ServerConfigImpl; -import org.eclipse.che.api.workspace.server.model.impl.VolumeImpl; import org.eclipse.che.api.workspace.server.spi.InfrastructureException; import org.eclipse.che.api.workspace.server.spi.environment.InternalEnvironment; import org.eclipse.che.api.workspace.server.spi.environment.InternalMachineConfig; @@ -103,6 +104,7 @@ public class KubernetesPluginsToolingApplierTest { @Mock private InternalMachineConfig userMachineConfig; @Mock private RuntimeIdentity runtimeIdentity; @Mock private ProjectsRootEnvVariableProvider projectsRootEnvVariableProvider; + @Mock private ChePluginsVolumeApplier chePluginsVolumeApplier; private KubernetesEnvironment internalEnvironment; private KubernetesPluginsToolingApplier applier; @@ -112,7 +114,11 @@ public void setUp() { internalEnvironment = spy(KubernetesEnvironment.builder().build()); applier = new KubernetesPluginsToolingApplier( - TEST_IMAGE_POLICY, MEMORY_LIMIT_MB, false, projectsRootEnvVariableProvider); + TEST_IMAGE_POLICY, + MEMORY_LIMIT_MB, + false, + projectsRootEnvVariableProvider, + chePluginsVolumeApplier); Map machines = new HashMap<>(); List containers = new ArrayList<>(); @@ -451,11 +457,46 @@ public void canAddMultipleToolingContainersToAPodFromSeveralPlugins() throws Exc } @Test - public void addsMachineWithVolumeToAToolingContainer() throws Exception { - applier.apply(runtimeIdentity, internalEnvironment, singletonList(createChePlugin())); + public void applyPluginContainerWithOneVolume() throws InfrastructureException { + lenient().when(podSpec.getContainers()).thenReturn(new ArrayList<>()); - InternalMachineConfig machineConfig = getOneAndOnlyNonUserMachine(internalEnvironment); - verifyOneAndOnlyVolume(machineConfig, VOLUME_NAME, VOLUME_MOUNT_PATH); + ChePlugin chePlugin = createChePlugin(); + CheContainer cheContainer = chePlugin.getContainers().get(0); + + applier.apply(runtimeIdentity, internalEnvironment, singletonList(chePlugin)); + + verifyPodAndContainersNumber(1); + Container container = getOneAndOnlyNonUserContainer(internalEnvironment); + verifyContainer(container); + + verify(chePluginsVolumeApplier) + .applyVolumes( + any(PodData.class), + eq(container), + eq(cheContainer.getVolumes()), + eq(internalEnvironment)); + } + + @Test + public void applyPluginInitContainerWithOneVolume() throws InfrastructureException { + lenient().when(podSpec.getInitContainers()).thenReturn(new ArrayList<>()); + + ChePlugin chePlugin = createChePlugin(); + CheContainer initContainer = createContainer(); + chePlugin.setInitContainers(singletonList(initContainer)); + + applier.apply(runtimeIdentity, internalEnvironment, singletonList(chePlugin)); + + verifyPodAndInitContainersNumber(1); + Container toolingInitContainer = getOnlyOneInitContainerFromPod(internalEnvironment); + verifyContainer(toolingInitContainer); + + verify(chePluginsVolumeApplier) + .applyVolumes( + any(PodData.class), + eq(toolingInitContainer), + eq(initContainer.getVolumes()), + eq(internalEnvironment)); } @Test @@ -464,24 +505,27 @@ public void addsMachinesWithVolumesToAllToolingContainer() throws Exception { ChePlugin chePluginWithNonDefaultVolume = createChePlugin(); String anotherVolumeName = VOLUME_NAME + "1"; String anotherVolumeMountPath = VOLUME_MOUNT_PATH + "/something"; - chePluginWithNonDefaultVolume - .getContainers() - .get(0) - .setVolumes( - singletonList(new Volume().name(anotherVolumeName).mountPath(anotherVolumeMountPath))); + List volumes = + singletonList(new Volume().name(anotherVolumeName).mountPath(anotherVolumeMountPath)); + CheContainer toolingContainer = chePluginWithNonDefaultVolume.getContainers().get(0); + toolingContainer.setVolumes(volumes); + + ChePlugin chePlugin = createChePlugin(); // when applier.apply( - runtimeIdentity, - internalEnvironment, - asList(createChePlugin(), chePluginWithNonDefaultVolume)); + runtimeIdentity, internalEnvironment, asList(chePlugin, chePluginWithNonDefaultVolume)); // then Collection machineConfigs = getNonUserMachines(internalEnvironment); assertEquals(machineConfigs.size(), 2); - verifyNumberOfMachinesWithSpecificVolume(machineConfigs, 1, VOLUME_NAME, VOLUME_MOUNT_PATH); - verifyNumberOfMachinesWithSpecificVolume( - machineConfigs, 1, anotherVolumeName, anotherVolumeMountPath); + + verify(chePluginsVolumeApplier) + .applyVolumes( + any(PodData.class), + any(Container.class), + eq(chePlugin.getContainers().get(0).getVolumes()), + eq(internalEnvironment)); } @Test @@ -497,8 +541,7 @@ public void addsMachineWithVolumeFromChePlugin() throws Exception { // then Collection machineConfigs = getNonUserMachines(internalEnvironment); assertEquals(machineConfigs.size(), 2); - verifyNumberOfMachinesWithSpecificNumberOfVolumes(machineConfigs, 1, 0); - verifyNumberOfMachinesWithSpecificNumberOfVolumes(machineConfigs, 1, 1); + verifyNumberOfMachinesWithSpecificNumberOfVolumes(machineConfigs, 2, 0); } @Test @@ -681,7 +724,11 @@ public void throwsExceptionOnAddingChePluginEndpointServiceIfServiceExists() thr public void shouldSetJWTServerExposerAttributeIfAuthEnabled() throws Exception { applier = new KubernetesPluginsToolingApplier( - TEST_IMAGE_POLICY, MEMORY_LIMIT_MB, true, projectsRootEnvVariableProvider); + TEST_IMAGE_POLICY, + MEMORY_LIMIT_MB, + true, + projectsRootEnvVariableProvider, + chePluginsVolumeApplier); applier.apply(runtimeIdentity, internalEnvironment, singletonList(createChePlugin())); @@ -693,7 +740,11 @@ public void shouldNotSetJWTServerExposerAttributeIfAuthEnabledButAttributeIsPres throws Exception { applier = new KubernetesPluginsToolingApplier( - TEST_IMAGE_POLICY, MEMORY_LIMIT_MB, true, projectsRootEnvVariableProvider); + TEST_IMAGE_POLICY, + MEMORY_LIMIT_MB, + true, + projectsRootEnvVariableProvider, + chePluginsVolumeApplier); internalEnvironment.getAttributes().put(SECURE_EXPOSER_IMPL_PROPERTY, "somethingElse"); applier.apply(runtimeIdentity, internalEnvironment, singletonList(createChePlugin())); @@ -706,7 +757,11 @@ public void shouldNotSetJWTServerExposerAttributeIfAuthEnabledButAttributeIsPres public void shouldSetSpecifiedImagePullPolicy() throws Exception { applier = new KubernetesPluginsToolingApplier( - TEST_IMAGE_POLICY, MEMORY_LIMIT_MB, true, projectsRootEnvVariableProvider); + TEST_IMAGE_POLICY, + MEMORY_LIMIT_MB, + true, + projectsRootEnvVariableProvider, + chePluginsVolumeApplier); applier.apply(runtimeIdentity, internalEnvironment, singletonList(createChePlugin())); @@ -727,7 +782,11 @@ public void shouldSetSpecifiedImagePullPolicy() throws Exception { public void shouldSetNullImagePullPolicyIfValueIsNotStandard() throws Exception { applier = new KubernetesPluginsToolingApplier( - "None", MEMORY_LIMIT_MB, true, projectsRootEnvVariableProvider); + "None", + MEMORY_LIMIT_MB, + true, + projectsRootEnvVariableProvider, + chePluginsVolumeApplier); applier.apply(runtimeIdentity, internalEnvironment, singletonList(createChePlugin())); @@ -826,15 +885,6 @@ private void verifyContainers(List containers) { } } - @SuppressWarnings("SameParameterValue") - private void verifyOneAndOnlyVolume( - InternalMachineConfig machineConfig, String volumeName, String volumeMountPath) { - Map volumes = - machineConfig.getVolumes(); - assertEquals(volumes.size(), 1); - assertEquals(ImmutableMap.of(volumeName, new VolumeImpl().withPath(volumeMountPath)), volumes); - } - @SuppressWarnings("SameParameterValue") private void verifyNumberOfMachinesWithSpecificNumberOfVolumes( Collection machineConfigs, int numberOfMachines, int numberOfVolumes) { @@ -847,25 +897,6 @@ private void verifyNumberOfMachinesWithSpecificNumberOfVolumes( assertEquals(numberOfMatchingMachines, numberOfMachines); } - @SuppressWarnings("SameParameterValue") - private void verifyNumberOfMachinesWithSpecificVolume( - Collection machineConfigs, - int numberOfMachines, - String volumeName, - String volumeMountPath) { - - long numberOfMatchingMachines = - machineConfigs - .stream() - .filter(machineConfig -> machineConfig.getVolumes().size() == 1) - .filter(machineConfig -> machineConfig.getVolumes().get(volumeName) != null) - .filter( - machineConfig -> - volumeMountPath.equals(machineConfig.getVolumes().get(volumeName).getPath())) - .count(); - assertEquals(numberOfMatchingMachines, numberOfMachines); - } - private void verifyPortsExposed(Container container, int... ports) { List actualPorts = container.getPorts(); List expectedPorts = new ArrayList<>(); @@ -928,8 +959,7 @@ private Container getOneAndOnlyNonUserContainer(KubernetesEnvironment kubernetes private Container getOnlyOneInitContainerFromPod(KubernetesEnvironment kubernetesEnvironment) { Pod pod = kubernetesEnvironment.getPodsCopy().values().iterator().next(); - List initContainer = - pod.getSpec().getInitContainers().stream().collect(Collectors.toList()); + List initContainer = pod.getSpec().getInitContainers(); assertEquals(initContainer.size(), 1); return initContainer.get(0); } diff --git a/infrastructures/kubernetes/src/test/java/org/eclipse/che/workspace/infrastructure/kubernetes/wsplugins/MachineResolverTest.java b/infrastructures/kubernetes/src/test/java/org/eclipse/che/workspace/infrastructure/kubernetes/wsplugins/MachineResolverTest.java index 806bc6662ae..80291ca72b2 100644 --- a/infrastructures/kubernetes/src/test/java/org/eclipse/che/workspace/infrastructure/kubernetes/wsplugins/MachineResolverTest.java +++ b/infrastructures/kubernetes/src/test/java/org/eclipse/che/workspace/infrastructure/kubernetes/wsplugins/MachineResolverTest.java @@ -81,20 +81,6 @@ public void setUp() { wsAttributes); } - @Test - public void shouldSetVolumesInMachineConfig() throws InfrastructureException { - List sidecarVolumes = - asList( - new Volume().name("vol1").mountPath("/path1"), - new Volume().name("vol2").mountPath("/path2")); - cheContainer.setVolumes(sidecarVolumes); - Map expected = of("vol1", volume("/path1"), "vol2", volume("/path2")); - - InternalMachineConfig machineConfig = resolver.resolve(); - - assertEquals(machineConfig.getVolumes(), expected); - } - @Test public void shouldSetComponentAliasAttributeInMachineConfig() throws InfrastructureException { String componentAlias = "mycomponent"; diff --git a/wsmaster/che-core-api-workspace/src/main/java/org/eclipse/che/api/workspace/server/wsplugins/model/Volume.java b/wsmaster/che-core-api-workspace/src/main/java/org/eclipse/che/api/workspace/server/wsplugins/model/Volume.java index 6918dd083ea..cba28dd711f 100644 --- a/wsmaster/che-core-api-workspace/src/main/java/org/eclipse/che/api/workspace/server/wsplugins/model/Volume.java +++ b/wsmaster/che-core-api-workspace/src/main/java/org/eclipse/che/api/workspace/server/wsplugins/model/Volume.java @@ -17,6 +17,7 @@ public class Volume { private String name = null; private String mountPath = null; + private boolean ephemeral; /** */ public Volume name(String name) { @@ -46,6 +47,19 @@ public void setMountPath(String mountPath) { this.mountPath = mountPath; } + public Volume ephemeral(boolean ephemeral) { + this.ephemeral = ephemeral; + return this; + } + + public boolean isEphemeral() { + return ephemeral; + } + + public void setEphemeral(boolean ephemeral) { + this.ephemeral = ephemeral; + } + @Override public boolean equals(java.lang.Object o) { if (this == o) { @@ -55,21 +69,23 @@ public boolean equals(java.lang.Object o) { return false; } Volume volume = (Volume) o; - return Objects.equals(name, volume.name) && Objects.equals(mountPath, volume.mountPath); + return Objects.equals(name, volume.name) + && Objects.equals(mountPath, volume.mountPath) + && Objects.equals(ephemeral, volume.ephemeral); } @Override public int hashCode() { - return Objects.hash(name, mountPath); + return Objects.hash(name, mountPath, ephemeral); } @Override public String toString() { StringBuilder sb = new StringBuilder(); sb.append("class Volume {\n"); - sb.append(" name: ").append(toIndentedString(name)).append("\n"); sb.append(" mountPath: ").append(toIndentedString(mountPath)).append("\n"); + sb.append(" ephemeral: ").append(toIndentedString(ephemeral)).append("\n"); sb.append("}"); return sb.toString(); }