Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Provide conversion webhook for CRDs #283

Merged
merged 6 commits into from
Mar 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions .github/workflows/ci-conversion-webhook.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
name: conversion-webhook CI

on:
push:
branches:
- main
paths:
- "java/common/**"
- "java/conversion/**"
- "dockerfiles/conversion-webhook/**"
# Publish when a workflow has changed (this is needed to detect version updates)
- ".github/workflows/ci-conversion-webhook.yml"
- ".github/workflows/reusable-docker.yml"
pull_request:
branches:
- main
paths:
- "java/common/**"
- "java/conversion/**"
- "dockerfiles/conversion-webhook/**"
release:
types:
- published

jobs:
call-reusable-docker-workflow:
uses: ./.github/workflows/reusable-docker.yml
with:
docker_org: theiacloud
docker_image: theia-cloud-conversion-webhook
docker_file: dockerfiles/conversion-webhook/Dockerfile
secrets:
dockerhub_username: ${{ secrets.DOCKERHUB_USERNAME }}
dockerhub_token: ${{ secrets.DOCKERHUB_TOKEN }}
2 changes: 1 addition & 1 deletion .github/workflows/ci-landing-page.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ on:
- "dockerfiles/landing-page/**"
# Publish when a workflow has changed (this is needed to detect version updates)
- ".github/workflows/ci-landing-page.yml"
- ".github/workflows/reuseable-docker.yml"
- ".github/workflows/reusable-docker.yml"
pull_request:
branches:
- main
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/ci-monitor-theia.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ on:
- "node/monitor-theia/**"
# Publish when a workflow has changed (this is needed to detect version updates)
- ".github/workflows/ci-monitor-theia.yml"
- ".github/workflows/reuseable-npm.yml"
- ".github/workflows/reusable-npm.yml"
pull_request:
branches:
- main
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/ci-node-common.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ on:
- "node/common/**"
# Publish when a workflow has changed (this is needed to detect version updates)
- ".github/workflows/ci-node-common.yml"
- ".github/workflows/reuseable-npm.yml"
- ".github/workflows/reusable-npm.yml"
pull_request:
branches:
- main
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/ci-operator.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ on:
- "dockerfiles/operator/**"
# Publish when a workflow has changed (this is needed to detect version updates)
- ".github/workflows/ci-operator.yml"
- ".github/workflows/reuseable-docker.yml"
- ".github/workflows/reusable-docker.yml"
pull_request:
branches:
- main
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/ci-service.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ on:
- "dockerfiles/service/**"
# Publish when a workflow has changed (this is needed to detect version updates)
- ".github/workflows/ci-service.yml"
- ".github/workflows/reuseable-docker.yml"
- ".github/workflows/reusable-docker.yml"
pull_request:
branches:
- main
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/ci-try-now-page.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ on:
- "dockerfiles/try-now-page/**"
# Publish when a workflow has changed (this is needed to detect version updates)
- ".github/workflows/ci-try-now-page.yml"
- ".github/workflows/reuseable-docker.yml"
- ".github/workflows/reusable-docker.yml"
pull_request:
branches:
- main
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/ci-wondershaper.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ on:
- "dockerfiles/wondershaper/**"
# Publish when a workflow has changed (this is needed to detect version updates)
- ".github/workflows/ci-wondershaper.yml"
- ".github/workflows/reuseable-docker.yml"
- ".github/workflows/reusable-docker.yml"
pull_request:
branches:
- main
Expand Down
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,14 @@

- [.github/workflows] Improve version detection in workflows (do not build release commits, auto-detect version for demo publishing) [#280](https://github.com/eclipsesource/theia-cloud/pull/280) - contributed on behalf of STMicroelectronics
- [node] Separate `monitor` package from other workspaces to fix bundling the extension [#280](https://github.com/eclipsesource/theia-cloud/pull/280) - contributed on behalf of STMicroelectronics
- [conversion] Provide java conversion webhook for CRD updates [#283](https://github.com/eclipsesource/theia-cloud/pull/283) | [#49](https://github.com/eclipsesource/theia-cloud-helm/pull/49) - contributed on behalf of STMicroelectronics
- [.github/workflows] Add ci for `conversion-webhook` and fix typo to build on version bumps [#283](https://github.com/eclipsesource/theia-cloud/pull/283) | [#49](https://github.com/eclipsesource/theia-cloud-helm/pull/49) - contributed on behalf of STMicroelectronics
- [common] Update CRs, keep previous version and offer Hub (used by conversion-webhook) [#283](https://github.com/eclipsesource/theia-cloud/pull/283) | [#49](https://github.com/eclipsesource/theia-cloud-helm/pull/49) - contributed on behalf of STMicroelectronics
- Move status like fields to status
- `Session.v1beta7`: Move `url`, `lastActivity` and `error` fields from the spec to the status.
- `Workspace.v1beta4`: Move the `error` field from the spec to the status. Also add the `error` field to `Workspace.v1beta3` as it was missing
- Remove `timeout.strategy` from AppDefinition
- `AppDefinition.v1beta9`: Removed `timeout.strategy` and `timeout.limit` is now just `timeout`. This was done, as there is only one Strategy left.

## [0.9.0] - 2024-01-23

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ metadata:
name: placeholder-depname
namespace: placeholder-namespace
ownerReferences:
- apiVersion: theia.cloud/v1beta8
- apiVersion: theia.cloud/v1beta9
kind: AppDefinition
name: placeholder
uid: placeholder
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ metadata:
name: placeholder-depname
namespace: placeholder-namespace
ownerReferences:
- apiVersion: theia.cloud/v1beta8
- apiVersion: theia.cloud/v1beta9
kind: AppDefinition
name: placeholder
uid: placeholder
Expand Down
11 changes: 11 additions & 0 deletions dockerfiles/conversion-webhook/.project
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>conversion-docker</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
</buildSpec>
<natures>
</natures>
</projectDescription>
18 changes: 18 additions & 0 deletions dockerfiles/conversion-webhook/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
FROM eclipse-temurin:17-jdk AS builder
RUN apt-get update && apt-get install -y maven
WORKDIR /conversion
COPY java/common ./common
COPY java/conversion ./conversion
RUN cd /conversion/common/maven-conf && \
mvn clean install --no-transfer-progress && \
cd /conversion/common/org.eclipse.theia.cloud.common && \
mvn clean install --no-transfer-progress&& \
cd /conversion/conversion/org.eclipse.theia.cloud.conversion && \
mvn clean package -Dmaven.test.skip=true -Dquarkus.package.type=uber-jar --no-transfer-progress

FROM eclipse-temurin:17-jre-alpine
WORKDIR /conversion
COPY --from=builder /conversion/conversion/org.eclipse.theia.cloud.conversion/target/conversion-webhook-0.10.0-SNAPSHOT-runner.jar .

ENTRYPOINT java -jar ./conversion-webhook-0.10.0-SNAPSHOT-runner.jar
CMD [ "" ]
6 changes: 6 additions & 0 deletions documentation/Building.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,12 @@ docker build -t theia-cloud-try-now-page -f dockerfiles/try-now-page/Dockerfile
docker build -t theia-cloud-wondershaper -f dockerfiles/wondershaper/Dockerfile .
```

## CRD conversion webhook

```bash
docker build -t theia-cloud-conversion-webhook -f dockerfiles/conversion-webhook/Dockerfile .
```

## Demo applications

### Theia demo
Expand Down
2 changes: 1 addition & 1 deletion helm/theia.cloud/test/cdt.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
apiVersion: theia.cloud/v1beta8
apiVersion: theia.cloud/v1beta9
kind: AppDefinition
metadata:
name: cdt-cloud-demo
Expand Down
4 changes: 4 additions & 0 deletions java/common/maven-conf/.settings/org.eclipse.m2e.core.prefs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
activeProfiles=
eclipse.preferences.version=1
resolveWorkspaceProjects=true
version=1
9 changes: 6 additions & 3 deletions java/common/org.eclipse.theia.cloud.common/.classpath
Original file line number Diff line number Diff line change
Expand Up @@ -47,15 +47,18 @@
<attribute name="optional" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="src" path="target/generated-sources/annotations">
<classpathentry kind="src" output="target/test-classes" path="target/generated-test-sources/test-annotations">
<attributes>
<attribute name="optional" value="true"/>
<attribute name="test" value="true"/>
<attribute name="maven.pomderived" value="true"/>
<attribute name="ignore_optional_problems" value="true"/>
<attribute name="m2e-apt" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="src" output="target/test-classes" path="target/generated-test-sources/test-annotations">
<classpathentry kind="src" path="target/generated-sources/annotations">
<attributes>
<attribute name="optional" value="true"/>
<attribute name="test" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="output" path="target/classes"/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public DefaultSessionResourceClient(NamespacedKubernetesClient client) {
public Session create(String correlationId, SessionSpec spec) {
Session session = new Session();
session.setSpec(spec);
spec.setLastActivity(Instant.now().toEpochMilli());
session.getStatus().setLastActivity(Instant.now().toEpochMilli());
spec.setSessionSecret(UUID.randomUUID().toString());

ObjectMeta metadata = new ObjectMeta();
Expand All @@ -56,40 +56,39 @@ public Session create(String correlationId, SessionSpec spec) {
public Session launch(String correlationId, SessionSpec spec, long timeout, TimeUnit unit) {
// get or create session
Session session = get(spec.getName()).orElseGet(() -> create(correlationId, spec));
SessionSpec sessionSpec = session.getSpec();
SessionStatus sessionStatus = session.getStatus();

// if session is available and has already an url or error, return that session
if (sessionSpec.hasUrl()) {
if (sessionStatus.hasUrl()) {
return session;
}
if (sessionSpec.hasError()) {
if (sessionStatus.hasError()) {
delete(correlationId, spec.getName());
return session;
}

// wait for session url or error to be available
try {
watchUntil((action, changedSession) -> isSessionComplete(correlationId, sessionSpec, changedSession),
timeout, unit);
watchUntil((action, changedSession) -> isSessionComplete(correlationId, session, changedSession), timeout,
unit);
} catch (InterruptedException exception) {
error(correlationId, "Timeout while waiting for URL for " + spec.getName(), exception);
sessionSpec.setError(TheiaCloudError.SESSION_LAUNCH_TIMEOUT);
sessionStatus.setError(TheiaCloudError.SESSION_LAUNCH_TIMEOUT);
}
return session;
}

protected boolean isSessionComplete(String correlationId, SessionSpec sessionSpec,
Session changedSession) {
if (sessionSpec.getName().equals(changedSession.getSpec().getName())) {
if (changedSession.getSpec().hasUrl()) {
protected boolean isSessionComplete(String correlationId, Session session, Session changedSession) {
if (session.getSpec().getName().equals(changedSession.getSpec().getName())) {
if (changedSession.getStatus().hasUrl()) {
info(correlationId, "Received URL for " + changedSession);
sessionSpec.setUrl(changedSession.getSpec().getUrl());
session.getStatus().setUrl(changedSession.getStatus().getUrl());
return true;
}
if (changedSession.getSpec().hasError()) {
if (changedSession.getStatus().hasError()) {
info(correlationId, "Received Error for " + changedSession + ". Deleting session again.");
delete(correlationId, sessionSpec.getName());
sessionSpec.setError(changedSession.getSpec().getError());
delete(correlationId, session.getSpec().getName());
session.getStatus().setError(changedSession.getStatus().getError());
return true;
}
}
Expand All @@ -100,7 +99,7 @@ protected boolean isSessionComplete(String correlationId, SessionSpec sessionSpe
public boolean reportActivity(String correlationId, String name) {
return edit(correlationId, name, session -> {
trace(correlationId, "Updating activity for session {" + name + "}");
session.getSpec().setLastActivity(Instant.now().toEpochMilli());
session.getStatus().setLastActivity(Instant.now().toEpochMilli());
}) != null;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,40 +50,40 @@ public Workspace create(String correlationId, WorkspaceSpec spec) {
public Workspace launch(String correlationId, WorkspaceSpec spec, long timeout, TimeUnit unit) {
Workspace workspace = get(spec.getName()).orElseGet(() -> create(correlationId, spec));
WorkspaceSpec workspaceSpec = workspace.getSpec();
WorkspaceStatus workspaceStatus = workspace.getStatus();

if (workspaceSpec.hasStorage()) {
return workspace;
}

if (workspaceSpec.hasError()) {
if (workspaceStatus.hasError()) {
delete(correlationId, spec.getName());
return workspace;
}

try {
watchUntil(
(action, changedWorkspace) -> isWorkspaceComplete(correlationId, workspaceSpec, changedWorkspace),
watchUntil((action, changedWorkspace) -> isWorkspaceComplete(correlationId, workspace, changedWorkspace),
timeout, unit);
} catch (InterruptedException exception) {
error(correlationId, "Timeout while waiting for workspace storage " + workspaceSpec.getName()
+ ". Deleting workspace again.", exception);
workspaceSpec.setError(TheiaCloudError.WORKSPACE_LAUNCH_TIMEOUT);
workspaceStatus.setError(TheiaCloudError.WORKSPACE_LAUNCH_TIMEOUT);
}
return workspace;
}

protected boolean isWorkspaceComplete(String correlationId, WorkspaceSpec createdWorkspace,
protected boolean isWorkspaceComplete(String correlationId, Workspace createdWorkspace,
Workspace changedWorkspace) {
if (createdWorkspace.getName().equals(changedWorkspace.getSpec().getName())) {
if (createdWorkspace.getSpec().getName().equals(changedWorkspace.getSpec().getName())) {
if (changedWorkspace.getSpec().hasStorage()) {
info(correlationId, "Received URL for " + createdWorkspace);
createdWorkspace.setStorage(changedWorkspace.getSpec().getStorage());
createdWorkspace.getSpec().setStorage(changedWorkspace.getSpec().getStorage());
return true;
}
if (changedWorkspace.getSpec().hasError()) {
if (changedWorkspace.getStatus().hasError()) {
info(correlationId, "Received Error for " + changedWorkspace + ". Deleting workspace again.");
delete(correlationId, createdWorkspace.getName());
createdWorkspace.setError(changedWorkspace.getSpec().getError());
delete(correlationId, createdWorkspace.getSpec().getName());
createdWorkspace.getStatus().setError(changedWorkspace.getStatus().getError());
return true;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,15 @@
import io.fabric8.kubernetes.model.annotation.Singular;
import io.fabric8.kubernetes.model.annotation.Version;

@Version("v1beta8")
@Version("v1beta9")
@Group("theia.cloud")
@Kind("AppDefinition")
@Singular("appdefinition")
@Plural("appdefinitions")
public class AppDefinition extends CustomResource<AppDefinitionSpec, AppDefinitionStatus> implements Namespaced {

private static final long serialVersionUID = 8749670583218521755L;
public static final String API = "theia.cloud/v1beta8";
public static final String API = "theia.cloud/v1beta9";
public static final String KIND = "AppDefinition";
public static final String CRD_NAME = "appdefinitions.theia.cloud";

Expand All @@ -49,11 +49,11 @@ public AppDefinition() {
}

public AppDefinition(AppDefinitionHub fromHub) {
this.setMetadata(fromHub.getMetadata());
this.spec = new AppDefinitionSpec(fromHub.getSpec());
if (fromHub.getStatus() != null) {
this.status = new AppDefinitionStatus(fromHub.getStatus());
if (fromHub.getMetadata().isPresent()) {
this.setMetadata(fromHub.getMetadata().get());
}
this.spec = new AppDefinitionSpec(fromHub);
this.status = new AppDefinitionStatus(fromHub);
}

}
Loading
Loading