Skip to content

Commit

Permalink
CHE-10561: Rework WS.NEXT flow to latest concept of plugin broker (#1…
Browse files Browse the repository at this point in the history
…0740)

* Move wsnext flow in Kubernetes infra implementation

Now we need to start a broker and pass meta.yaml files to it.
Starting a broker is infra-specific stuff, so it has to be done
on the infra implementation side because we don't have a part
in the infra SPI that would allow us to start a broker.
Passing Meta files using InternalEnvironment object is more
invasive than passing only attributes. So, this commit applies
less invasive scheme.

* CHE-10202,10561: Add fetching of Che editor, plugins meta from the registry

Add fetching of Che editor ID from workspace attributes.
Add fetching of Che plugins IDs from workspace attributes.
Use colon sign for separating editor/plugin ID and version
instead of the slash.
Remove old Workspace.Next model objects.

* CHE-10561: Share WS.NEXT between k8s and OS infras

Use WS.NEXT in both k8s and OS infrastructure implementations.

* CHE-10561: fix fetching meta.yaml files from che-plugin-registry

* CHE-10561: Fix sidecar model serialization

Fixes the fact that some fields in workspace sidecar tooling model
POJOs were incorrectly named or required custom serialization of
fields.

* CHE-10561: Add listening of che-plugin-broker

Add code that allows listening for events from Che plugin broker.
An event might contain workspace tooling config as a result if the broker
finished successfully or error otherwise.

* CHE-10561: Add PluginBrokerManager to control broker lifecycle

Adds PluginBrokerManager that configures/starts/waits Che plugin
broker.

Remove unused code.
Remove notion of Workspace next.

* Align plugin registry property between different components

* Fix extra  path in che plugin registry URL

Signed-off-by: Oleksandr Garagatyi <ogaragat@redhat.com>
  • Loading branch information
Oleksandr Garagatyi authored Sep 3, 2018
1 parent a70e621 commit 27bed82
Show file tree
Hide file tree
Showing 53 changed files with 1,545 additions and 1,789 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@
import org.eclipse.che.api.workspace.server.spi.provision.env.WorkspaceMavenServerJavaOptsEnvVariableProvider;
import org.eclipse.che.api.workspace.server.stack.StackLoader;
import org.eclipse.che.api.workspace.server.token.MachineTokenProvider;
import org.eclipse.che.api.workspace.server.wsnext.WorkspaceNextApplier;
import org.eclipse.che.api.workspace.server.wsplugins.ChePluginsApplier;
import org.eclipse.che.commons.auth.token.ChainedTokenExtractor;
import org.eclipse.che.commons.auth.token.RequestTokenExtractor;
import org.eclipse.che.core.db.DBTermination;
Expand Down Expand Up @@ -266,7 +266,7 @@ protected void configure() {

bind(org.eclipse.che.api.user.server.AppStatesPreferenceCleaner.class);

MapBinder.newMapBinder(binder(), String.class, WorkspaceNextApplier.class);
MapBinder.newMapBinder(binder(), String.class, ChePluginsApplier.class);
}

private void configureSingleUserMode(Map<String, String> persistenceProperties) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -484,9 +484,13 @@ che.singleport.wildcard_domain.ipless=false
### Experimental properties
# Next properties are subject to changes and removal, so do not rely on them in a stable Che assembly

# Workspace.Next feature API endpoint. Should be a valid HTTP URL that includes protocol, port etc.
# In case Workspace.Next is not needed value 'NULL' should be used
che.workspace.feature.api=NULL
# Workspace tooling plugins registry endpoint. Should be a valid HTTP URL that includes protocol, port etc.
# In case Che plugins tooling is not needed value 'NULL' should be used
che.workspace.plugin_registry_url=NULL

# Docker image of Che plugin broker app that resolves workspace tooling configuration and copies
# plugins dependencies to a workspace
che.workspace.plugin_broker.image=eclipse/che-plugin-broker:latest

# Configures in which way secure servers will be protected with authentication.
# Suitable values:
Expand Down
6 changes: 3 additions & 3 deletions deploy/kubernetes/kubectl/che-kubernetes.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ items:
CHE_LOGS_APPENDERS_IMPL: "plaintext"
CHE_INFRA_KUBERNETES_INGRESS_DOMAIN: "192.168.99.100.nip.io"
CHE_INFRA_KUBERNETES_SERVER__STRATEGY: "default-host"
CHE_WORKSPACE_FEATURE_API: "http://marketplace:80"
CHE_WORKSPACE_PLUGIN__REGISTRY__URL: "NULL"
- apiVersion: extensions/v1beta1
kind: Ingress
metadata:
Expand Down Expand Up @@ -253,10 +253,10 @@ items:
configMapKeyRef:
key: CHE_INFRA_KUBERNETES_SERVER__STRATEGY
name: che
- name: CHE_WORKSPACE_FEATURE_API
- name: CHE_WORKSPACE_PLUGIN__REGISTRY__URL
valueFrom:
configMapKeyRef:
key: CHE_WORKSPACE_FEATURE_API
key: CHE_WORKSPACE_PLUGIN__REGISTRY__URL
name: che
image: eclipse/che-server:nightly
imagePullPolicy: Always
Expand Down
8 changes: 4 additions & 4 deletions deploy/openshift/deploy_che.sh
Original file line number Diff line number Diff line change
Expand Up @@ -153,8 +153,8 @@ export PLUGIN_REGISTRY_IMAGE=${PLUGIN_REGISTRY_IMAGE:-${DEFAULT_PLUGIN_REGISTRY_
DEFAULT_PLUGIN_REGISTRY_IMAGE_PULL_POLICY="Always"
export PLUGIN_REGISTRY_IMAGE_PULL_POLICY=${PLUGIN_REGISTRY_IMAGE_PULL_POLICY:-${DEFAULT_PLUGIN_REGISTRY_IMAGE_PULL_POLICY}}

DEFAULT_PLUGIN_REGISTRY_URL="NULL"
export PLUGIN_REGISTRY_URL=${PLUGIN_REGISTRY_URL:-${DEFAULT_PLUGIN_REGISTRY_URL}}
DEFAULT_CHE_WORKSPACE_PLUGIN__REGISTRY__URL="NULL"
export CHE_WORKSPACE_PLUGIN__REGISTRY__URL=${CHE_WORKSPACE_PLUGIN__REGISTRY__URL:-${DEFAULT_CHE_WORKSPACE_PLUGIN__REGISTRY__URL}}

if [ "${ENABLE_SSL}" == "true" ]; then
HTTP_PROTOCOL="https"
Expand Down Expand Up @@ -437,7 +437,7 @@ ${CHE_VAR_ARRAY}"

if [ "${DEPLOY_CHE_PLUGIN_REGISTRY}" == "true" ]; then
PLUGIN_REGISTRY_ROUTE=$($OC_BINARY get route/che-plugin-registry --namespace=${CHE_OPENSHIFT_PROJECT} -o=jsonpath={'.spec.host'})
PLUGIN_REGISTRY_URL="${HTTP_PROTOCOL}://${PLUGIN_REGISTRY_ROUTE}/plugins/"
CHE_WORKSPACE_PLUGIN__REGISTRY__URL="${HTTP_PROTOCOL}://${PLUGIN_REGISTRY_ROUTE}/"
fi

${OC_BINARY} new-app -f ${BASE_DIR}/templates/che-server-template.yaml \
Expand All @@ -452,7 +452,7 @@ ${CHE_VAR_ARRAY}"
-p CHE_INFRA_OPENSHIFT_PROJECT=${CHE_INFRA_OPENSHIFT_PROJECT} \
-p CHE_INFRA_OPENSHIFT_OAUTH__IDENTITY__PROVIDER=${CHE_INFRA_OPENSHIFT_OAUTH__IDENTITY__PROVIDER} \
-p TLS=${TLS} \
-p CHE_PLUGIN_REGISTRY_URL=${PLUGIN_REGISTRY_URL} \
-p CHE_WORKSPACE_PLUGIN__REGISTRY__URL=${CHE_WORKSPACE_PLUGIN__REGISTRY__URL} \
${ENV}

if [ ${UPDATE_STRATEGY} == "Recreate" ]; then
Expand Down
6 changes: 3 additions & 3 deletions deploy/openshift/templates/che-server-template.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -145,8 +145,8 @@ objects:
key: ca.crt
name: openshift-identity-provider
optional: true
- name: CHE_PLUGIN_REGISTRY_URL
value: "${CHE_PLUGIN_REGISTRY_URL}"
- name: CHE_WORKSPACE_PLUGIN__REGISTRY__URL
value: "${CHE_WORKSPACE_PLUGIN__REGISTRY__URL}"
image: ${IMAGE_CHE}:${CHE_VERSION}
imagePullPolicy: "${PULL_POLICY}"
livenessProbe:
Expand Down Expand Up @@ -277,7 +277,7 @@ parameters:
displayName: GitHub Client Secret
description: GitHub oAuth app client servet. Applicable to Che single user only!
value: ''
- name: CHE_PLUGIN_REGISTRY_URL
- name: CHE_WORKSPACE_PLUGIN__REGISTRY__URL
displayName: Eclipse Che plugin registry URL
description: Url that used to get meta information about Eclipse Che tooling
value: 'NULL'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
import org.eclipse.che.api.workspace.server.spi.provision.env.CheApiExternalEnvVarProvider;
import org.eclipse.che.api.workspace.server.spi.provision.env.CheApiInternalEnvVarProvider;
import org.eclipse.che.api.workspace.server.spi.provision.env.EnvVarProvider;
import org.eclipse.che.api.workspace.server.wsnext.WorkspaceNextApplier;
import org.eclipse.che.api.workspace.server.wsplugins.ChePluginsApplier;
import org.eclipse.che.workspace.infrastructure.docker.environment.dockerimage.DockerImageEnvironment;
import org.eclipse.che.workspace.infrastructure.docker.environment.dockerimage.DockerImageEnvironmentFactory;
import org.eclipse.che.workspace.infrastructure.kubernetes.bootstrapper.KubernetesBootstrapperFactory;
Expand All @@ -55,7 +55,8 @@
import org.eclipse.che.workspace.infrastructure.kubernetes.server.secure.DefaultSecureServersFactory;
import org.eclipse.che.workspace.infrastructure.kubernetes.server.secure.SecureServerExposerFactory;
import org.eclipse.che.workspace.infrastructure.kubernetes.server.secure.SecureServerExposerFactoryProvider;
import org.eclipse.che.workspace.infrastructure.kubernetes.wsnext.KubernetesWorkspaceNextApplier;
import org.eclipse.che.workspace.infrastructure.kubernetes.wsplugins.KubernetesPluginsToolingApplier;
import org.eclipse.che.workspace.infrastructure.kubernetes.wsplugins.events.BrokerService;

/** @author Sergii Leshchenko */
public class KubernetesInfraModule extends AbstractModule {
Expand Down Expand Up @@ -121,9 +122,11 @@ protected void configure() {

install(new JpaKubernetesRuntimeCacheModule());

MapBinder<String, WorkspaceNextApplier> wsNext =
MapBinder.newMapBinder(binder(), String.class, WorkspaceNextApplier.class);
wsNext.addBinding(KubernetesEnvironment.TYPE).to(KubernetesWorkspaceNextApplier.class);
MapBinder<String, ChePluginsApplier> chePluginsAppliers =
MapBinder.newMapBinder(binder(), String.class, ChePluginsApplier.class);
chePluginsAppliers
.addBinding(KubernetesEnvironment.TYPE)
.to(KubernetesPluginsToolingApplier.class);

bind(new TypeLiteral<SecureServerExposerFactory<KubernetesEnvironment>>() {})
.toProvider(
Expand All @@ -139,5 +142,7 @@ protected void configure() {
secureServerExposerFactories
.addBinding("default")
.to(new TypeLiteral<DefaultSecureServersFactory<KubernetesEnvironment>>() {});

bind(BrokerService.class);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,20 @@
import java.util.Set;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.eclipse.che.api.core.ValidationException;
import org.eclipse.che.api.core.model.workspace.runtime.RuntimeIdentity;
import org.eclipse.che.api.core.notification.EventService;
import org.eclipse.che.api.workspace.server.spi.InfrastructureException;
import org.eclipse.che.api.workspace.server.spi.InternalInfrastructureException;
import org.eclipse.che.api.workspace.server.spi.RuntimeContext;
import org.eclipse.che.api.workspace.server.spi.RuntimeInfrastructure;
import org.eclipse.che.api.workspace.server.spi.environment.InternalEnvironment;
import org.eclipse.che.api.workspace.server.spi.provision.InternalEnvironmentProvisioner;
import org.eclipse.che.workspace.infrastructure.docker.environment.dockerimage.DockerImageEnvironment;
import org.eclipse.che.workspace.infrastructure.kubernetes.cache.KubernetesRuntimeStateCache;
import org.eclipse.che.workspace.infrastructure.kubernetes.environment.KubernetesEnvironment;
import org.eclipse.che.workspace.infrastructure.kubernetes.environment.convert.DockerImageEnvironmentConverter;
import org.eclipse.che.workspace.infrastructure.kubernetes.wsplugins.SidecarToolingProvisioner;

/** @author Sergii Leshchenko */
@Singleton
Expand All @@ -39,6 +42,7 @@ public class KubernetesInfrastructure extends RuntimeInfrastructure {
private final KubernetesRuntimeContextFactory runtimeContextFactory;
private final KubernetesEnvironmentProvisioner k8sEnvProvisioner;
private final KubernetesRuntimeStateCache runtimeStatusesCache;
private final SidecarToolingProvisioner toolingProvisioner;

@Inject
public KubernetesInfrastructure(
Expand All @@ -47,7 +51,8 @@ public KubernetesInfrastructure(
KubernetesEnvironmentProvisioner k8sEnvProvisioner,
Set<InternalEnvironmentProvisioner> internalEnvProvisioners,
DockerImageEnvironmentConverter dockerImageEnvConverter,
KubernetesRuntimeStateCache runtimeStatusesCache) {
KubernetesRuntimeStateCache runtimeStatusesCache,
SidecarToolingProvisioner toolingProvisioner) {
super(
NAME,
ImmutableSet.of(KubernetesEnvironment.TYPE, DockerImageEnvironment.TYPE),
Expand All @@ -57,13 +62,29 @@ public KubernetesInfrastructure(
this.k8sEnvProvisioner = k8sEnvProvisioner;
this.dockerImageEnvConverter = dockerImageEnvConverter;
this.runtimeStatusesCache = runtimeStatusesCache;
this.toolingProvisioner = toolingProvisioner;
}

@Override
public Set<RuntimeIdentity> getIdentities() throws InfrastructureException {
return runtimeStatusesCache.getIdentities();
}

@Override
public RuntimeContext prepare(RuntimeIdentity id, InternalEnvironment environment)
throws ValidationException, InfrastructureException {

// Sidecar-based tooling for now supports k8s/OS env only
// Convert other env types to a k8s type to use this tooling with other env types
final KubernetesEnvironment kubernetesEnvironment = asKubernetesEnv(environment);

// We need to provision development tooling here because there is environment variables
// provisioning in the superclass which might be important
toolingProvisioner.provision(id, kubernetesEnvironment);

return super.prepare(id, kubernetesEnvironment);
}

@Override
protected KubernetesRuntimeContext internalPrepare(
RuntimeIdentity id, InternalEnvironment environment) throws InfrastructureException {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ public void create(ConfigMap configMap) throws InfrastructureException {
}

/**
* Deletes all existing secrets.
* Deletes all existing config maps.
*
* @throws InfrastructureException when any exception occurs
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.che.workspace.infrastructure.kubernetes.wsnext;
package org.eclipse.che.workspace.infrastructure.kubernetes.wsplugins;

import static java.util.Collections.singletonList;
import static java.util.Collections.singletonMap;
Expand Down Expand Up @@ -41,29 +41,29 @@
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;
import org.eclipse.che.api.workspace.server.wsnext.WorkspaceNextApplier;
import org.eclipse.che.api.workspace.server.wsnext.model.CheContainer;
import org.eclipse.che.api.workspace.server.wsnext.model.CheContainerPort;
import org.eclipse.che.api.workspace.server.wsnext.model.ChePlugin;
import org.eclipse.che.api.workspace.server.wsnext.model.ChePluginEndpoint;
import org.eclipse.che.api.workspace.server.wsnext.model.EnvVar;
import org.eclipse.che.api.workspace.server.wsnext.model.Volume;
import org.eclipse.che.api.workspace.server.wsplugins.ChePluginsApplier;
import org.eclipse.che.api.workspace.server.wsplugins.model.CheContainer;
import org.eclipse.che.api.workspace.server.wsplugins.model.CheContainerPort;
import org.eclipse.che.api.workspace.server.wsplugins.model.ChePlugin;
import org.eclipse.che.api.workspace.server.wsplugins.model.ChePluginEndpoint;
import org.eclipse.che.api.workspace.server.wsplugins.model.EnvVar;
import org.eclipse.che.api.workspace.server.wsplugins.model.Volume;
import org.eclipse.che.workspace.infrastructure.kubernetes.Names;
import org.eclipse.che.workspace.infrastructure.kubernetes.environment.KubernetesEnvironment;
import org.eclipse.che.workspace.infrastructure.kubernetes.util.Containers;

/**
* Applies Workspace.Next configuration to a kubernetes internal runtime object.
* Applies Che plugins tooling configuration to a kubernetes internal runtime object.
*
* @author Oleksander Garagatyi
*/
@Beta
public class KubernetesWorkspaceNextApplier implements WorkspaceNextApplier {
public class KubernetesPluginsToolingApplier implements ChePluginsApplier {

private final String defaultMachineMemorySizeAttribute;

@Inject
public KubernetesWorkspaceNextApplier(
public KubernetesPluginsToolingApplier(
@Named("che.workspace.default_memory_mb") long defaultMachineMemorySizeMB) {
this.defaultMachineMemorySizeAttribute =
String.valueOf(defaultMachineMemorySizeMB * 1024 * 1024);
Expand All @@ -81,11 +81,14 @@ public void apply(InternalEnvironment internalEnvironment, Collection<ChePlugin>
Map<String, Pod> pods = kubernetesEnvironment.getPods();
if (pods.size() != 1) {
throw new InfrastructureException(
"Workspace.Next configuration can be applied to a workspace with one pod only");
"Che plugins tooling configuration can be applied to a workspace with one pod only");
}
Pod pod = pods.values().iterator().next();

for (ChePlugin chePlugin : chePlugins) {
if (chePlugin.getContainers() == null) {
continue;
}
for (CheContainer container : chePlugin.getContainers()) {
addMachine(pod, container, chePlugin, kubernetesEnvironment);
}
Expand Down Expand Up @@ -265,9 +268,11 @@ private ServerConfigImpl toServer(ChePluginEndpoint endpoint) {
private List<io.fabric8.kubernetes.api.model.EnvVar> toK8sEnv(List<EnvVar> env) {
List<io.fabric8.kubernetes.api.model.EnvVar> result = new ArrayList<>();

for (EnvVar envVar : env) {
result.add(
new io.fabric8.kubernetes.api.model.EnvVar(envVar.getName(), envVar.getValue(), null));
if (env != null) {
for (EnvVar envVar : env) {
result.add(
new io.fabric8.kubernetes.api.model.EnvVar(envVar.getName(), envVar.getValue(), null));
}
}

return result;
Expand Down
Loading

0 comments on commit 27bed82

Please sign in to comment.