Define image pulling strategy for sidecars via configuration

6.19.x
Max Shaposhnik 2018-10-09 14:20:06 +03:00 committed by GitHub
parent f7ebd6e4fd
commit 127c433d8a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 73 additions and 6 deletions

View File

@ -100,6 +100,12 @@ che.workspace.default_memory_limit_mb=1024
# RAM limit default for each sidecar that has no RAM settings in Che plugin configuration.
che.workspace.sidecar.default_memory_limit_mb=128
# Define image pulling strategy for sidecars.
# Possible values are: Always, Never, IfNotPresent. Any other value
# will be interpreted as unspecified policy (Always if :latest tag is specified,
# or IfNotPresent otherwise.)
che.workspace.sidecar.image_pull_policy=Always
# RAM request default for each machine that has no explicit RAM settings in environment.
# this amount will be allocated on workspace container creation
# this property might not be supported by all infrastructure implementations:

View File

@ -40,11 +40,16 @@ public class K8sContainerResolver {
static final int MAX_CONTAINER_NAME_LENGTH = 63; // K8S container name limit
private final String pluginName;
private final String imagePullPolicy;
private final CheContainer cheContainer;
private final List<ChePluginEndpoint> containerEndpoints;
public K8sContainerResolver(
String pluginName, CheContainer container, List<ChePluginEndpoint> containerEndpoints) {
String pluginName,
String imagePullPolicy,
CheContainer container,
List<ChePluginEndpoint> containerEndpoints) {
this.imagePullPolicy = imagePullPolicy;
this.cheContainer = container;
this.pluginName = pluginName;
this.containerEndpoints = containerEndpoints;
@ -58,6 +63,7 @@ public class K8sContainerResolver {
Container container =
new ContainerBuilder()
.withImage(cheContainer.getImage())
.withImagePullPolicy(imagePullPolicy)
.withName(buildContainerName(pluginName, cheContainer.getName()))
.withEnv(toK8sEnv(cheContainer.getEnv()))
.withPorts(getContainerPorts())

View File

@ -22,6 +22,7 @@ import org.eclipse.che.api.workspace.server.wsplugins.model.ChePluginEndpoint;
public class K8sContainerResolverBuilder {
private String pluginName;
private String imagePullPolicy;
private CheContainer container;
private List<ChePluginEndpoint> pluginEndpoints;
@ -40,13 +41,18 @@ public class K8sContainerResolverBuilder {
return this;
}
public K8sContainerResolverBuilder setImagePullPolicy(String imagePullPolicy) {
this.imagePullPolicy = imagePullPolicy;
return this;
}
public K8sContainerResolver build() {
if (container == null || pluginEndpoints == null) {
throw new IllegalStateException();
}
List<ChePluginEndpoint> containerEndpoints =
getContainerEndpoints(container.getPorts(), pluginEndpoints);
return new K8sContainerResolver(pluginName, container, containerEndpoints);
return new K8sContainerResolver(pluginName, imagePullPolicy, container, containerEndpoints);
}
private List<ChePluginEndpoint> getContainerEndpoints(

View File

@ -14,14 +14,17 @@ package org.eclipse.che.workspace.infrastructure.kubernetes.wsplugins;
import static org.eclipse.che.workspace.infrastructure.kubernetes.server.secure.SecureServerExposerFactoryProvider.SECURE_EXPOSER_IMPL_PROPERTY;
import com.google.common.annotations.Beta;
import com.google.common.collect.Sets;
import io.fabric8.kubernetes.api.model.Container;
import io.fabric8.kubernetes.api.model.Pod;
import io.fabric8.kubernetes.api.model.Service;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
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;
@ -38,17 +41,24 @@ import org.eclipse.che.workspace.infrastructure.kubernetes.environment.Kubernete
* @author Oleksander Garagatyi
*/
@Beta
@Singleton
public class KubernetesPluginsToolingApplier implements ChePluginsApplier {
private static final Set<String> validImagePullPolicies =
Sets.newHashSet("Always", "Never", "IfNotPresent");
private final String defaultSidecarMemoryLimitBytes;
private final String sidecarImagePullPolicy;
private final boolean isAuthEnabled;
@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) {
this.defaultSidecarMemoryLimitBytes = String.valueOf(defaultSidecarMemoryLimitMB * 1024 * 1024);
this.isAuthEnabled = isAuthEnabled;
this.sidecarImagePullPolicy =
validImagePullPolicies.contains(sidecarImagePullPolicy) ? sidecarImagePullPolicy : null;
}
@Override
@ -98,6 +108,7 @@ public class KubernetesPluginsToolingApplier implements ChePluginsApplier {
K8sContainerResolver k8sContainerResolver =
new K8sContainerResolverBuilder()
.setContainer(container)
.setImagePullPolicy(sidecarImagePullPolicy)
.setPluginName(chePlugin.getName())
.setPluginEndpoints(chePlugin.getEndpoints())
.build();

View File

@ -47,7 +47,7 @@ public class K8sContainerResolverTest {
public void setUp() {
cheContainer = new CheContainer();
endpoints = new ArrayList<>();
resolver = new K8sContainerResolver(PLUGIN_NAME, cheContainer, endpoints);
resolver = new K8sContainerResolver(PLUGIN_NAME, "Always", cheContainer, endpoints);
}
@Test

View File

@ -68,6 +68,7 @@ import org.testng.annotations.Test;
@Listeners(MockitoTestNGListener.class)
public class KubernetesPluginsToolingApplierTest {
private static final String TEST_IMAGE = "testImage/test:test";
private static final String TEST_IMAGE_POLICY = "IfNotPresent";
private static final String ENV_VAR = "PLUGINS_ENV_VAR";
private static final String ENV_VAR_VALUE = "PLUGINS_ENV_VAR_VALUE";
private static final String POD_NAME = "pod12";
@ -88,7 +89,7 @@ public class KubernetesPluginsToolingApplierTest {
@BeforeMethod
public void setUp() {
applier = new KubernetesPluginsToolingApplier(MEMORY_LIMIT_MB, false);
applier = new KubernetesPluginsToolingApplier(TEST_IMAGE_POLICY, MEMORY_LIMIT_MB, false);
Map<String, InternalMachineConfig> machines = new HashMap<>();
List<Container> containers = new ArrayList<>();
@ -365,7 +366,7 @@ public class KubernetesPluginsToolingApplierTest {
@Test
public void shouldSetJWTServerExposerAttributeIfAuthEnabled() throws Exception {
applier = new KubernetesPluginsToolingApplier(MEMORY_LIMIT_MB, true);
applier = new KubernetesPluginsToolingApplier(TEST_IMAGE_POLICY, MEMORY_LIMIT_MB, true);
applier.apply(internalEnvironment, singletonList(createChePlugin()));
@ -375,7 +376,7 @@ public class KubernetesPluginsToolingApplierTest {
@Test
public void shouldNotSetJWTServerExposerAttributeIfAuthEnabledButAttributeIsPresent()
throws Exception {
applier = new KubernetesPluginsToolingApplier(MEMORY_LIMIT_MB, true);
applier = new KubernetesPluginsToolingApplier(TEST_IMAGE_POLICY, MEMORY_LIMIT_MB, true);
internalEnvironment.getAttributes().put(SECURE_EXPOSER_IMPL_PROPERTY, "somethingElse");
applier.apply(internalEnvironment, singletonList(createChePlugin()));
@ -384,6 +385,43 @@ public class KubernetesPluginsToolingApplierTest {
internalEnvironment.getAttributes().get(SECURE_EXPOSER_IMPL_PROPERTY), "somethingElse");
}
@Test
public void shouldSetSpecifiedImagePullPolicy() throws Exception {
applier = new KubernetesPluginsToolingApplier(TEST_IMAGE_POLICY, MEMORY_LIMIT_MB, true);
applier.apply(internalEnvironment, singletonList(createChePlugin()));
assertEquals(
internalEnvironment
.getPods()
.values()
.iterator()
.next()
.getSpec()
.getContainers()
.get(1)
.getImagePullPolicy(),
TEST_IMAGE_POLICY);
}
@Test
public void shouldSetNullImagePullPolicyIfValueIsNotStandard() throws Exception {
applier = new KubernetesPluginsToolingApplier("None", MEMORY_LIMIT_MB, true);
applier.apply(internalEnvironment, singletonList(createChePlugin()));
assertNull(
internalEnvironment
.getPods()
.values()
.iterator()
.next()
.getSpec()
.getContainers()
.get(1)
.getImagePullPolicy());
}
@Test
public void shouldNotSetJWTServerExposerAttributeIfAuthDisabled() throws Exception {
applier.apply(internalEnvironment, singletonList(createChePlugin()));