parent
23c5fb2b47
commit
8a10b84875
|
|
@ -133,6 +133,7 @@ public class KubernetesInternalRuntime<E extends KubernetesEnvironment>
|
|||
private final PreviewUrlCommandProvisioner previewUrlCommandProvisioner;
|
||||
private final SecretAsContainerResourceProvisioner secretAsContainerResourceProvisioner;
|
||||
private final KubernetesServerResolverFactory serverResolverFactory;
|
||||
private final RuntimeCleaner runtimeCleaner;
|
||||
protected final CheNamespace cheNamespace;
|
||||
protected final Tracer tracer;
|
||||
|
||||
|
|
@ -158,6 +159,7 @@ public class KubernetesInternalRuntime<E extends KubernetesEnvironment>
|
|||
PreviewUrlCommandProvisioner previewUrlCommandProvisioner,
|
||||
SecretAsContainerResourceProvisioner secretAsContainerResourceProvisioner,
|
||||
KubernetesServerResolverFactory kubernetesServerResolverFactory,
|
||||
RuntimeCleaner runtimeCleaner,
|
||||
CheNamespace cheNamespace,
|
||||
Tracer tracer,
|
||||
@Assisted KubernetesRuntimeContext<E> context,
|
||||
|
|
@ -184,6 +186,7 @@ public class KubernetesInternalRuntime<E extends KubernetesEnvironment>
|
|||
this.previewUrlCommandProvisioner = previewUrlCommandProvisioner;
|
||||
this.secretAsContainerResourceProvisioner = secretAsContainerResourceProvisioner;
|
||||
this.serverResolverFactory = kubernetesServerResolverFactory;
|
||||
this.runtimeCleaner = runtimeCleaner;
|
||||
this.tracer = tracer;
|
||||
}
|
||||
|
||||
|
|
@ -195,7 +198,7 @@ public class KubernetesInternalRuntime<E extends KubernetesEnvironment>
|
|||
startSynchronizer.setStartThread();
|
||||
startSynchronizer.start();
|
||||
|
||||
cleanUp(workspaceId);
|
||||
runtimeCleaner.cleanUp(namespace, workspaceId);
|
||||
provisionWorkspace(startOptions, context, workspaceId);
|
||||
|
||||
volumesStrategy.prepare(
|
||||
|
|
@ -260,7 +263,7 @@ public class KubernetesInternalRuntime<E extends KubernetesEnvironment>
|
|||
// stop watching before namespace cleaning up
|
||||
namespace.deployments().stopWatch(true);
|
||||
try {
|
||||
cleanUp(workspaceId);
|
||||
runtimeCleaner.cleanUp(namespace, workspaceId);
|
||||
} catch (InfrastructureException cleanUppingEx) {
|
||||
LOG.warn(
|
||||
"Failed to clean up namespace after workspace '{}' start failing. Cause: {}",
|
||||
|
|
@ -277,11 +280,6 @@ public class KubernetesInternalRuntime<E extends KubernetesEnvironment>
|
|||
}
|
||||
}
|
||||
|
||||
private void cleanUp(String workspaceId) throws InfrastructureException {
|
||||
namespace.cleanUp();
|
||||
cheNamespace.cleanUp(workspaceId);
|
||||
}
|
||||
|
||||
protected void provisionWorkspace(
|
||||
Map<String, String> startOptions, KubernetesRuntimeContext<E> context, String workspaceId)
|
||||
throws InfrastructureException {
|
||||
|
|
@ -594,7 +592,7 @@ public class KubernetesInternalRuntime<E extends KubernetesEnvironment>
|
|||
// Che Server that is crashed so start is hung up in STOPPING phase.
|
||||
// Need to clean up runtime resources
|
||||
probeScheduler.cancel(identity.getWorkspaceId());
|
||||
cleanUp(identity.getWorkspaceId());
|
||||
runtimeCleaner.cleanUp(namespace, identity.getWorkspaceId());
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
throw new InfrastructureException(
|
||||
|
|
@ -604,7 +602,7 @@ public class KubernetesInternalRuntime<E extends KubernetesEnvironment>
|
|||
// runtime is RUNNING. Clean up used resources
|
||||
// Cancels workspace servers probes if any
|
||||
probeScheduler.cancel(identity.getWorkspaceId());
|
||||
cleanUp(identity.getWorkspaceId());
|
||||
runtimeCleaner.cleanUp(namespace, identity.getWorkspaceId());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* 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;
|
||||
|
||||
import static org.eclipse.che.workspace.infrastructure.kubernetes.server.external.SingleHostExternalServiceExposureStrategy.SINGLE_HOST_STRATEGY;
|
||||
|
||||
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.workspace.infrastructure.kubernetes.namespace.CheNamespace;
|
||||
import org.eclipse.che.workspace.infrastructure.kubernetes.namespace.KubernetesNamespace;
|
||||
import org.eclipse.che.workspace.infrastructure.kubernetes.server.WorkspaceExposureType;
|
||||
|
||||
/**
|
||||
* Little helper bean that decides what is needed to cleanup for given workspace. It does not delete
|
||||
* anything on it's own, but delegates the cleaning operations to provided {@link
|
||||
* KubernetesNamespace} and {@link CheNamespace}.
|
||||
*/
|
||||
@Singleton
|
||||
public class RuntimeCleaner {
|
||||
private final boolean cleanupCheNamespace;
|
||||
private final CheNamespace cheNamespace;
|
||||
|
||||
@Inject
|
||||
public RuntimeCleaner(
|
||||
@Named("che.infra.kubernetes.server_strategy") String exposureStrategy,
|
||||
@Named("che.infra.kubernetes.singlehost.workspace.exposure") String singleHostStrategy,
|
||||
CheNamespace cheNamespace) {
|
||||
this.cheNamespace = cheNamespace;
|
||||
|
||||
this.cleanupCheNamespace =
|
||||
SINGLE_HOST_STRATEGY.equals(exposureStrategy)
|
||||
&& WorkspaceExposureType.GATEWAY.getConfigValue().equals(singleHostStrategy);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove all workspace related k8s objects in both workspace's namespace and in Che namespace if
|
||||
* needed.
|
||||
*
|
||||
* @param namespace to cleanup
|
||||
* @param workspaceId to cleanup
|
||||
* @throws InfrastructureException when exception during cleaning occurs.
|
||||
*/
|
||||
public void cleanUp(KubernetesNamespace namespace, String workspaceId)
|
||||
throws InfrastructureException {
|
||||
namespace.cleanUp();
|
||||
if (cleanupCheNamespace) {
|
||||
cheNamespace.cleanUp(workspaceId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -216,6 +216,7 @@ public class KubernetesInternalRuntimeTest {
|
|||
@Mock private RuntimeHangingDetector runtimeHangingDetector;
|
||||
@Mock private KubernetesPreviewUrlCommandProvisioner previewUrlCommandProvisioner;
|
||||
@Mock private SecretAsContainerResourceProvisioner secretAsContainerResourceProvisioner;
|
||||
@Mock private RuntimeCleaner runtimeCleaner;
|
||||
private KubernetesServerResolverFactory serverResolverFactory;
|
||||
|
||||
@Mock
|
||||
|
|
@ -290,6 +291,7 @@ public class KubernetesInternalRuntimeTest {
|
|||
previewUrlCommandProvisioner,
|
||||
secretAsContainerResourceProvisioner,
|
||||
serverResolverFactory,
|
||||
runtimeCleaner,
|
||||
cheNamespace,
|
||||
tracer,
|
||||
context,
|
||||
|
|
@ -431,8 +433,7 @@ public class KubernetesInternalRuntimeTest {
|
|||
verify(services).create(any());
|
||||
verify(secrets).create(any());
|
||||
verify(configMaps).create(any());
|
||||
verify(namespace).cleanUp();
|
||||
verify(cheNamespace).cleanUp(WORKSPACE_ID);
|
||||
verify(runtimeCleaner).cleanUp(namespace, WORKSPACE_ID);
|
||||
verify(namespace.deployments(), times(1)).watchEvents(any());
|
||||
verify(eventService, times(4)).publish(any());
|
||||
verifyOrderedEventsChains(
|
||||
|
|
@ -449,9 +450,8 @@ public class KubernetesInternalRuntimeTest {
|
|||
internalRuntime.start(emptyMap());
|
||||
|
||||
InOrder cleanupInOrderExecutionVerification =
|
||||
Mockito.inOrder(namespace, cheNamespace, deployments, toolingProvisioner);
|
||||
cleanupInOrderExecutionVerification.verify(namespace).cleanUp();
|
||||
cleanupInOrderExecutionVerification.verify(cheNamespace).cleanUp(WORKSPACE_ID);
|
||||
Mockito.inOrder(runtimeCleaner, deployments, toolingProvisioner);
|
||||
cleanupInOrderExecutionVerification.verify(runtimeCleaner).cleanUp(namespace, WORKSPACE_ID);
|
||||
cleanupInOrderExecutionVerification
|
||||
.verify(toolingProvisioner)
|
||||
.provision(any(), any(), any(), any());
|
||||
|
|
@ -654,8 +654,7 @@ public class KubernetesInternalRuntimeTest {
|
|||
try {
|
||||
internalRuntime.start(emptyMap());
|
||||
} catch (Exception rethrow) {
|
||||
verify(namespace, times(2)).cleanUp();
|
||||
verify(cheNamespace, times(2)).cleanUp(WORKSPACE_ID);
|
||||
verify(runtimeCleaner, times(2)).cleanUp(namespace, WORKSPACE_ID);
|
||||
verify(namespace, never()).services();
|
||||
verify(namespace, never()).ingresses();
|
||||
throw rethrow;
|
||||
|
|
@ -693,7 +692,10 @@ public class KubernetesInternalRuntimeTest {
|
|||
|
||||
@Test(expectedExceptions = InfrastructureException.class)
|
||||
public void throwsInfrastructureExceptionWhenErrorOccursAndCleanupFailed() throws Exception {
|
||||
doNothing().doThrow(InfrastructureException.class).when(namespace).cleanUp();
|
||||
doNothing()
|
||||
.doThrow(InfrastructureException.class)
|
||||
.when(runtimeCleaner)
|
||||
.cleanUp(namespace, WORKSPACE_ID);
|
||||
when(k8sEnv.getServices()).thenReturn(singletonMap("testService", mock(Service.class)));
|
||||
when(services.create(any())).thenThrow(new InfrastructureException("service creation failed"));
|
||||
doThrow(IllegalStateException.class).when(namespace).services();
|
||||
|
|
@ -701,7 +703,7 @@ public class KubernetesInternalRuntimeTest {
|
|||
try {
|
||||
internalRuntime.start(emptyMap());
|
||||
} catch (Exception rethrow) {
|
||||
verify(namespace, times(2)).cleanUp();
|
||||
verify(runtimeCleaner, times(2)).cleanUp(namespace, WORKSPACE_ID);
|
||||
verify(namespace).services();
|
||||
verify(namespace, never()).ingresses();
|
||||
throw rethrow;
|
||||
|
|
@ -734,21 +736,12 @@ public class KubernetesInternalRuntimeTest {
|
|||
internalRuntime.internalStop(emptyMap());
|
||||
|
||||
verify(runtimeHangingDetector).stopTracking(IDENTITY);
|
||||
verify(namespace).cleanUp();
|
||||
verify(cheNamespace).cleanUp(WORKSPACE_ID);
|
||||
verify(runtimeCleaner).cleanUp(namespace, WORKSPACE_ID);
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = InfrastructureException.class)
|
||||
public void throwsInfrastructureExceptionWhenKubernetesNamespaceCleanupFailed() throws Exception {
|
||||
doThrow(InfrastructureException.class).when(namespace).cleanUp();
|
||||
|
||||
internalRuntime.internalStop(emptyMap());
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = InfrastructureException.class)
|
||||
public void throwsInfrastructureExceptionWhenKubernetesCheNamespaceCleanupFailed()
|
||||
throws Exception {
|
||||
doThrow(InfrastructureException.class).when(cheNamespace).cleanUp(WORKSPACE_ID);
|
||||
doThrow(InfrastructureException.class).when(runtimeCleaner).cleanUp(namespace, WORKSPACE_ID);
|
||||
|
||||
internalRuntime.internalStop(emptyMap());
|
||||
}
|
||||
|
|
@ -1161,7 +1154,7 @@ public class KubernetesInternalRuntimeTest {
|
|||
verify(cheNamespace)
|
||||
.createConfigMaps(
|
||||
expectedCreatedCheNamespaceConfigmaps, internalRuntime.getContext().getIdentity());
|
||||
verify(cheNamespace).cleanUp(WORKSPACE_ID);
|
||||
verify(runtimeCleaner).cleanUp(namespace, WORKSPACE_ID);
|
||||
}
|
||||
|
||||
private static MachineStatusEvent newEvent(String machineName, MachineStatus status) {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
* 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;
|
||||
|
||||
import static org.eclipse.che.workspace.infrastructure.kubernetes.server.WorkspaceExposureType.GATEWAY;
|
||||
import static org.eclipse.che.workspace.infrastructure.kubernetes.server.WorkspaceExposureType.NATIVE;
|
||||
import static org.eclipse.che.workspace.infrastructure.kubernetes.server.external.DefaultHostExternalServiceExposureStrategy.DEFAULT_HOST_STRATEGY;
|
||||
import static org.eclipse.che.workspace.infrastructure.kubernetes.server.external.MultiHostExternalServiceExposureStrategy.MULTI_HOST_STRATEGY;
|
||||
import static org.eclipse.che.workspace.infrastructure.kubernetes.server.external.SingleHostExternalServiceExposureStrategy.SINGLE_HOST_STRATEGY;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.testng.Assert.*;
|
||||
|
||||
import org.eclipse.che.api.workspace.server.spi.InfrastructureException;
|
||||
import org.eclipse.che.workspace.infrastructure.kubernetes.namespace.CheNamespace;
|
||||
import org.eclipse.che.workspace.infrastructure.kubernetes.namespace.KubernetesNamespace;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.testng.MockitoTestNGListener;
|
||||
import org.testng.annotations.DataProvider;
|
||||
import org.testng.annotations.Listeners;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
@Listeners(MockitoTestNGListener.class)
|
||||
public class RuntimeCleanerTest {
|
||||
private final String WS_ID = "123";
|
||||
|
||||
@Mock private CheNamespace cheNamespace;
|
||||
@Mock private KubernetesNamespace kubeNamespace;
|
||||
|
||||
@Test
|
||||
public void shouldCleanupEverythingIfSinglehostGateway() throws InfrastructureException {
|
||||
RuntimeCleaner runtimeCleaner =
|
||||
new RuntimeCleaner(SINGLE_HOST_STRATEGY, GATEWAY.getConfigValue(), cheNamespace);
|
||||
|
||||
runtimeCleaner.cleanUp(kubeNamespace, WS_ID);
|
||||
|
||||
verify(cheNamespace).cleanUp(WS_ID);
|
||||
verify(kubeNamespace).cleanUp();
|
||||
}
|
||||
|
||||
@Test(dataProvider = "notSinglehostGateway")
|
||||
public void shouldNotCleanupCheNamespaceIfNotSinglehostGateway(
|
||||
String serverStrategy, String singleHostStrategy) throws InfrastructureException {
|
||||
RuntimeCleaner runtimeCleaner =
|
||||
new RuntimeCleaner(serverStrategy, singleHostStrategy, cheNamespace);
|
||||
|
||||
runtimeCleaner.cleanUp(kubeNamespace, WS_ID);
|
||||
|
||||
verify(kubeNamespace).cleanUp();
|
||||
verify(cheNamespace, never()).cleanUp(any());
|
||||
}
|
||||
|
||||
@DataProvider
|
||||
public static Object[][] notSinglehostGateway() {
|
||||
return new Object[][] {
|
||||
{SINGLE_HOST_STRATEGY, NATIVE.getConfigValue()},
|
||||
{MULTI_HOST_STRATEGY, GATEWAY.getConfigValue()},
|
||||
{MULTI_HOST_STRATEGY, NATIVE.getConfigValue()},
|
||||
{DEFAULT_HOST_STRATEGY, GATEWAY.getConfigValue()},
|
||||
{DEFAULT_HOST_STRATEGY, NATIVE.getConfigValue()},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -34,6 +34,7 @@ import org.eclipse.che.commons.annotation.Traced;
|
|||
import org.eclipse.che.commons.tracing.TracingTags;
|
||||
import org.eclipse.che.workspace.infrastructure.kubernetes.KubernetesInternalRuntime;
|
||||
import org.eclipse.che.workspace.infrastructure.kubernetes.KubernetesRuntimeContext;
|
||||
import org.eclipse.che.workspace.infrastructure.kubernetes.RuntimeCleaner;
|
||||
import org.eclipse.che.workspace.infrastructure.kubernetes.RuntimeHangingDetector;
|
||||
import org.eclipse.che.workspace.infrastructure.kubernetes.StartSynchronizerFactory;
|
||||
import org.eclipse.che.workspace.infrastructure.kubernetes.cache.KubernetesMachineCache;
|
||||
|
|
@ -84,6 +85,7 @@ public class OpenShiftInternalRuntime extends KubernetesInternalRuntime<OpenShif
|
|||
SecretAsContainerResourceProvisioner<OpenShiftEnvironment>
|
||||
secretAsContainerResourceProvisioner,
|
||||
OpenShiftServerResolverFactory serverResolverFactory,
|
||||
RuntimeCleaner runtimeCleaner,
|
||||
CheNamespace cheNamespace,
|
||||
Tracer tracer,
|
||||
Openshift4TrustedCAProvisioner trustedCAProvisioner,
|
||||
|
|
@ -110,6 +112,7 @@ public class OpenShiftInternalRuntime extends KubernetesInternalRuntime<OpenShif
|
|||
previewUrlCommandProvisioner,
|
||||
secretAsContainerResourceProvisioner,
|
||||
null,
|
||||
runtimeCleaner,
|
||||
cheNamespace,
|
||||
tracer,
|
||||
context,
|
||||
|
|
|
|||
|
|
@ -66,6 +66,7 @@ import org.eclipse.che.api.workspace.server.model.impl.RuntimeIdentityImpl;
|
|||
import org.eclipse.che.api.workspace.server.spi.environment.InternalMachineConfig;
|
||||
import org.eclipse.che.api.workspace.server.spi.provision.InternalEnvironmentProvisioner;
|
||||
import org.eclipse.che.api.workspace.shared.dto.event.MachineStatusEvent;
|
||||
import org.eclipse.che.workspace.infrastructure.kubernetes.RuntimeCleaner;
|
||||
import org.eclipse.che.workspace.infrastructure.kubernetes.RuntimeHangingDetector;
|
||||
import org.eclipse.che.workspace.infrastructure.kubernetes.StartSynchronizer;
|
||||
import org.eclipse.che.workspace.infrastructure.kubernetes.StartSynchronizerFactory;
|
||||
|
|
@ -150,6 +151,7 @@ public class OpenShiftInternalRuntimeTest {
|
|||
@Mock private SecretAsContainerResourceProvisioner secretAsContainerResourceProvisioner;
|
||||
@Mock private Openshift4TrustedCAProvisioner trustedCAProvisioner;
|
||||
@Mock private CheNamespace cheNamespace;
|
||||
@Mock private RuntimeCleaner runtimeCleaner;
|
||||
private OpenShiftServerResolverFactory serverResolverFactory;
|
||||
|
||||
@Mock(answer = Answers.RETURNS_MOCKS)
|
||||
|
|
@ -194,6 +196,7 @@ public class OpenShiftInternalRuntimeTest {
|
|||
previewUrlCommandProvisioner,
|
||||
secretAsContainerResourceProvisioner,
|
||||
serverResolverFactory,
|
||||
runtimeCleaner,
|
||||
cheNamespace,
|
||||
tracer,
|
||||
trustedCAProvisioner,
|
||||
|
|
|
|||
Loading…
Reference in New Issue