Skip to content

Commit c92ea4b

Browse files
committed
Switch the operator build to a shaded jar
* package the default operator with maven-shade-plugin so that META-INF/services files are merged correctly * deploy theia-cloud-base before theia-cloud-crds so the self-signed CA issuer exists when the conversion webhook certificate is created * add cert-manager installation step to the OpenShift setup docs * use K8SANNOTATION bandwidth limiter instead of WONDERSHAPER to avoid NET_ADMIN capability requirement on OpenShift * document how to push custom images to the CRC internal registry, including namespace/ImageStream creation and CA trust setup * add commented-out image override examples to theia_cloud.tf
1 parent 03db540 commit c92ea4b

7 files changed

Lines changed: 216 additions & 37 deletions

File tree

dockerfiles/operator/Dockerfile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ RUN mkdir /templates
1717
WORKDIR /log-config
1818
COPY java/operator/org.eclipse.theia.cloud.defaultoperator/log4j2.xml .
1919
WORKDIR /operator
20-
COPY --from=builder /operator/operator/org.eclipse.theia.cloud.defaultoperator/target/defaultoperator-1.2.0-jar-with-dependencies.jar .
20+
COPY --from=builder /operator/operator/org.eclipse.theia.cloud.defaultoperator/target/defaultoperator-1.2.0.jar .
2121
# to get more debug information from the kubernetes client itself, add -Dorg.slf4j.simpleLogger.defaultLogLevel=DEBUG below
22-
ENTRYPOINT [ "java", "-Dlog4j2.configurationFile=/log-config/log4j2.xml", "-jar", "./defaultoperator-1.2.0-jar-with-dependencies.jar" ]
22+
ENTRYPOINT [ "java", "-Dlog4j2.configurationFile=/log-config/log4j2.xml", "-jar", "./defaultoperator-1.2.0.jar" ]
2323
CMD [ "" ]

java/common/maven-conf/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
<quarkus.platform.group-id>io.quarkus.platform</quarkus.platform.group-id>
1919
<guice.version>7.0.0</guice.version>
2020
<log4j.version>2.25.1</log4j.version>
21-
<maven-assembly-plugin.version>3.7.1</maven-assembly-plugin.version>
21+
<maven-shade-plugin.version>3.6.0</maven-shade-plugin.version>
2222
<maven-compiler-plugin.version>3.14.0</maven-compiler-plugin.version>
2323
<surefire-plugin.version>3.5.3</surefire-plugin.version>
2424
<google.artifactregistry-maven-wagon-version>2.2.5</google.artifactregistry-maven-wagon-version>

java/operator/org.eclipse.theia.cloud.defaultoperator/pom.xml

Lines changed: 25 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -88,26 +88,36 @@
8888
</plugin>
8989

9090
<plugin>
91-
<artifactId>maven-assembly-plugin</artifactId>
92-
<version>${maven-assembly-plugin.version}</version>
93-
<configuration>
94-
<archive>
95-
<manifest>
96-
<mainClass>
97-
org.eclipse.theia.cloud.defaultoperator.DefaultTheiaCloudOperatorLauncher</mainClass>
98-
</manifest>
99-
</archive>
100-
<descriptorRefs>
101-
<descriptorRef>jar-with-dependencies</descriptorRef>
102-
</descriptorRefs>
103-
</configuration>
91+
<groupId>org.apache.maven.plugins</groupId>
92+
<artifactId>maven-shade-plugin</artifactId>
93+
<version>${maven-shade-plugin.version}</version>
10494
<executions>
10595
<execution>
106-
<id>make-assembly</id>
10796
<phase>package</phase>
10897
<goals>
109-
<goal>single</goal>
98+
<goal>shade</goal>
11099
</goals>
100+
<configuration>
101+
<transformers>
102+
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
103+
<mainClass>org.eclipse.theia.cloud.defaultoperator.DefaultTheiaCloudOperatorLauncher</mainClass>
104+
</transformer>
105+
<transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>
106+
<transformer implementation="org.apache.maven.plugins.shade.resource.ApacheLicenseResourceTransformer"/>
107+
<transformer implementation="org.apache.maven.plugins.shade.resource.ApacheNoticeResourceTransformer"/>
108+
</transformers>
109+
<filters>
110+
<filter>
111+
<artifact>*:*</artifact>
112+
<excludes>
113+
<exclude>META-INF/*.SF</exclude>
114+
<exclude>META-INF/*.DSA</exclude>
115+
<exclude>META-INF/*.RSA</exclude>
116+
</excludes>
117+
</filter>
118+
</filters>
119+
<createDependencyReducedPom>false</createDependencyReducedPom>
120+
</configuration>
111121
</execution>
112122
</executions>
113123
</plugin>

terraform/test-configurations/4-01_openshift_monitor/.terraform.lock.hcl

Lines changed: 22 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

terraform/test-configurations/4-01_openshift_monitor/theia_cloud.tf

Lines changed: 36 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -14,16 +14,7 @@ provider "helm" {
1414
}
1515
}
1616

17-
resource "helm_release" "theia-cloud-crds" {
18-
name = "theia-cloud-crds"
19-
chart = "../../../../theia-cloud-helm/charts/theia-cloud-crds"
20-
namespace = "theia-cloud"
21-
create_namespace = true
22-
}
23-
2417
resource "helm_release" "theia-cloud-base" {
25-
depends_on = [helm_release.theia-cloud-crds]
26-
2718
name = "theia-cloud-base"
2819
chart = "../../../../theia-cloud-helm/charts/theia-cloud-base"
2920
namespace = "theia-cloud"
@@ -34,20 +25,25 @@ resource "helm_release" "theia-cloud-base" {
3425
name = "operator.cloudProvider"
3526
value = "OPENSHIFT"
3627
},
37-
{
38-
name = "issuerca.enable"
39-
value = "false"
40-
},
4128
{
4229
name = "issuerprod.enable"
4330
value = "false"
4431
}
4532
]
4633
}
4734

48-
resource "helm_release" "theia-cloud" {
35+
resource "helm_release" "theia-cloud-crds" {
4936
depends_on = [helm_release.theia-cloud-base]
5037

38+
name = "theia-cloud-crds"
39+
chart = "../../../../theia-cloud-helm/charts/theia-cloud-crds"
40+
namespace = "theia-cloud"
41+
create_namespace = true
42+
}
43+
44+
resource "helm_release" "theia-cloud" {
45+
depends_on = [helm_release.theia-cloud-crds]
46+
5147
name = "theia-cloud"
5248
chart = "../../../../theia-cloud-helm/charts/theia-cloud"
5349
namespace = "theia-cloud"
@@ -65,6 +61,31 @@ resource "helm_release" "theia-cloud" {
6561
{
6662
name = "operator.cloudProvider"
6763
value = "OPENSHIFT"
68-
}
64+
},
65+
# Uncomment to use locally built images (see openshift.md)
66+
# {
67+
# name = "operator.image"
68+
# value = "image-registry.openshift-image-registry.svc:5000/theia-cloud/theia-cloud-operator:dev"
69+
# },
70+
# {
71+
# name = "operator.imagePullPolicy"
72+
# value = "Always"
73+
# },
74+
# {
75+
# name = "service.image"
76+
# value = "image-registry.openshift-image-registry.svc:5000/theia-cloud/theia-cloud-service:dev"
77+
# },
78+
# {
79+
# name = "service.imagePullPolicy"
80+
# value = "Always"
81+
# },
82+
# {
83+
# name = "landingPage.image"
84+
# value = "image-registry.openshift-image-registry.svc:5000/theia-cloud/theia-cloud-landing-page:dev"
85+
# },
86+
# {
87+
# name = "landingPage.imagePullPolicy"
88+
# value = "Always"
89+
# },
6990
]
7091
}

terraform/test-configurations/openshift.md

Lines changed: 129 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,123 @@ oc get routes -A # should show OpenShift console routes
5050
# OpenShift Local uses: apps-crc.testing
5151
```
5252

53+
## Building and Pushing Custom Images
54+
55+
When developing locally, you can build custom Theia Cloud images and push them to the CRC internal image registry. This avoids the need for an external registry.
56+
57+
### Registry Overview
58+
59+
OpenShift Local ships with an internal image registry. It is exposed externally via a Route at `default-route-openshift-image-registry.apps-crc.testing` (uses a self-signed certificate). Inside the cluster, pods pull from `image-registry.openshift-image-registry.svc:5000`.
60+
61+
There are two addresses to keep in mind:
62+
63+
| Address | Usage |
64+
| ------- | ----- |
65+
| `default-route-openshift-image-registry.apps-crc.testing` | External, used to push images from the host |
66+
| `image-registry.openshift-image-registry.svc:5000` | Internal, used by pods to pull images |
67+
68+
### Logging in to the Registry
69+
70+
The registry uses the CRC self-signed CA, so docker/podman needs to trust it or skip verification.
71+
72+
With podman:
73+
74+
```bash
75+
oc login -u kubeadmin https://api.crc.testing:6443
76+
podman login --tls-verify=false -u kubeadmin -p $(oc whoami -t) default-route-openshift-image-registry.apps-crc.testing
77+
```
78+
79+
With docker, you need to trust the CRC CA certificate. The `insecure-registries` daemon option alone is not sufficient because Docker's OAuth token exchange still verifies TLS. Extract the CRC CA and install it as a system-trusted certificate:
80+
81+
```bash
82+
# Extract the CRC ingress CA certificate
83+
oc extract secret/router-ca --keys=tls.crt -n openshift-ingress-operator --confirm
84+
sudo cp tls.crt /usr/local/share/ca-certificates/crc-ingress-ca.crt
85+
sudo update-ca-certificates
86+
sudo systemctl restart docker
87+
```
88+
89+
Then log in:
90+
91+
```bash
92+
docker login -u kubeadmin -p $(oc whoami -t) default-route-openshift-image-registry.apps-crc.testing
93+
```
94+
95+
### Building and Pushing Images
96+
97+
Make sure you have logged in to the registry first (see [Logging in to the Registry](#logging-in-to-the-registry)).
98+
99+
The OpenShift internal registry requires the target namespace and ImageStreams to exist before you can push images. Create them if they do not exist yet:
100+
101+
```bash
102+
oc new-project theia-cloud || true
103+
oc create imagestream theia-cloud-operator -n theia-cloud
104+
oc create imagestream theia-cloud-service -n theia-cloud
105+
oc create imagestream theia-cloud-landing-page -n theia-cloud
106+
```
107+
108+
All docker builds run from the `theia-cloud` repository root. The tag format is `default-route-openshift-image-registry.apps-crc.testing/<namespace>/<image>:<tag>`. Use the `theia-cloud` namespace to match the Helm deployment.
109+
110+
| Component | Dockerfile | Build context | Helm value to override |
111+
| ------------ | ------------------------------------- | ------------- | ---------------------- |
112+
| Operator | `dockerfiles/operator/Dockerfile` | repo root (`.`) | `operator.image` |
113+
| Service | `dockerfiles/service/Dockerfile` | repo root (`.`) | `service.image` |
114+
| Landing Page | `dockerfiles/landing-page/Dockerfile` | repo root (`.`) | `landingPage.image` |
115+
116+
All commands below assume you are in the `theia-cloud` repository root.
117+
118+
Operator:
119+
120+
```bash
121+
EXT_REG=default-route-openshift-image-registry.apps-crc.testing
122+
123+
docker build -f dockerfiles/operator/Dockerfile -t $EXT_REG/theia-cloud/theia-cloud-operator:dev .
124+
docker push $EXT_REG/theia-cloud/theia-cloud-operator:dev
125+
```
126+
127+
Service:
128+
129+
```bash
130+
docker build -f dockerfiles/service/Dockerfile -t $EXT_REG/theia-cloud/theia-cloud-service:dev .
131+
docker push $EXT_REG/theia-cloud/theia-cloud-service:dev
132+
```
133+
134+
Landing Page:
135+
136+
```bash
137+
docker build -f dockerfiles/landing-page/Dockerfile -t $EXT_REG/theia-cloud/theia-cloud-landing-page:dev .
138+
docker push $EXT_REG/theia-cloud/theia-cloud-landing-page:dev
139+
```
140+
141+
### Overriding Images in the Helm Deployment
142+
143+
When deploying via terraform (`4-01_openshift_monitor/theia_cloud.tf`), add `set` blocks to override the image. Inside the cluster, use the internal registry address (not the external route):
144+
145+
```hcl
146+
{
147+
name = "operator.image"
148+
value = "image-registry.openshift-image-registry.svc:5000/theia-cloud/theia-cloud-operator:dev"
149+
},
150+
{
151+
name = "operator.imagePullPolicy"
152+
value = "Always"
153+
}
154+
```
155+
156+
Set `imagePullPolicy` to `Always` during development so that new pushes with the same tag are picked up.
157+
158+
See the commented-out examples in `4-01_openshift_monitor/theia_cloud.tf` for all three images.
159+
160+
### Verifying the Image Was Pushed
161+
162+
```bash
163+
# List images in the theia-cloud namespace
164+
oc get imagestreams -n theia-cloud
165+
166+
# Check a specific image
167+
oc get imagestreamtag -n theia-cloud theia-cloud-operator:dev
168+
```
169+
53170
## Key Differences from Minikube
54171

55172
* No external DNS needed, OpenShift Local configures a local DNS resolver, routes are accessible from the host at `*.apps-crc.testing`
@@ -93,17 +210,26 @@ The configuration accepts the following variables:
93210

94211
## Step 4-01, Deploy Theia Cloud on OpenShift
95212

213+
Install cert-manager before deploying Theia Cloud. The CRDs chart uses cert-manager to generate the conversion webhook certificate. Wait for the cert-manager pods to be ready before proceeding.
214+
215+
```bash
216+
oc apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.17.2/cert-manager.yaml
217+
oc rollout status deployment/cert-manager-webhook -n cert-manager --timeout=120s
218+
```
219+
220+
Then deploy Theia Cloud:
221+
96222
```bash
97223
cd terraform/test-configurations/4-01_openshift_monitor
98224

99225
terraform init
100226
terraform apply
101227
```
102228

103-
This installs:
229+
This installs (in order):
104230

105-
* `theia-cloud-crds`, Custom Resource Definitions
106-
* `theia-cloud-base`, base RBAC and cluster roles
231+
* `theia-cloud-base`, RBAC, cluster roles, and cert-manager issuers
232+
* `theia-cloud-crds`, Custom Resource Definitions and conversion webhook
107233
* `theia-cloud`, operator, landing page, and service with OpenShift route configuration
108234

109235
## Verification

terraform/values/valuesOpenShiftMonitor.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ service:
3939

4040
operator:
4141
eagerStart: false
42-
bandwidthLimiter: "WONDERSHAPER"
42+
bandwidthLimiter: "K8SANNOTATION"
4343
sessionsPerUser: "3"
4444

4545
ingress:

0 commit comments

Comments
 (0)