From ccae74e71ef75d695ab34f79a412ba756da4c0b8 Mon Sep 17 00:00:00 2001 From: Anatolii Bazko Date: Wed, 15 May 2024 10:17:38 +0200 Subject: [PATCH] feat: Create editors definitions configmaps Signed-off-by: Anatolii Bazko --- Dockerfile | 3 +- Makefile | 8 +- api/v2/zz_generated.deepcopy.go | 2 +- build/scripts/release/editors-definitions.sh | 80 +++++++++ build/scripts/release/make-release.sh | 14 +- editors-definitions/che-code-insiders.yaml | 145 +++++++++++++++ editors-definitions/che-code-latest.yaml | 131 ++++++++++++++ editors-definitions/che-idea-latest.yaml | 166 ++++++++++++++++++ editors-definitions/che-idea-next.yaml | 166 ++++++++++++++++++ .../che-idea-server-latest.yaml | 126 +++++++++++++ editors-definitions/che-idea-server-next.yaml | 126 +++++++++++++ mocks/pkg/util/process_mock.go | 81 --------- pkg/common/constants/constants.go | 1 + pkg/common/utils/process.go | 51 ------ pkg/deploy/pluginregistry/init_test.go | 4 +- pkg/deploy/pluginregistry/pluginregistry.go | 26 ++- .../pluginregistry/pluginregistry_editors.go | 129 ++++++++++++++ .../pluginregistry_editors_test.go | 68 +++++++ .../pluginregistry/pluginregistry_test.go | 3 +- .../test-editors-definitions/devfile.yaml | 25 +++ 20 files changed, 1212 insertions(+), 143 deletions(-) create mode 100755 build/scripts/release/editors-definitions.sh create mode 100644 editors-definitions/che-code-insiders.yaml create mode 100644 editors-definitions/che-code-latest.yaml create mode 100644 editors-definitions/che-idea-latest.yaml create mode 100644 editors-definitions/che-idea-next.yaml create mode 100644 editors-definitions/che-idea-server-latest.yaml create mode 100644 editors-definitions/che-idea-server-next.yaml delete mode 100644 mocks/pkg/util/process_mock.go delete mode 100644 pkg/common/utils/process.go create mode 100644 pkg/deploy/pluginregistry/pluginregistry_editors.go create mode 100644 pkg/deploy/pluginregistry/pluginregistry_editors_test.go create mode 100644 pkg/deploy/pluginregistry/test-editors-definitions/devfile.yaml diff --git a/Dockerfile b/Dockerfile index e7e39d81d..eb52f6017 100644 --- a/Dockerfile +++ b/Dockerfile @@ -37,11 +37,11 @@ COPY go.sum go.sum # Copy the go source COPY main.go main.go COPY vendor/ vendor/ -COPY mocks/ mocks/ COPY api/ api/ COPY config/ config/ COPY controllers/ controllers/ COPY pkg/ pkg/ +COPY editors-definitions /tmp/editors-definitions # build operator # to test FIPS compliance, run https://github.com/openshift/check-payload#scan-a-container-or-operator-image against a built image @@ -53,6 +53,7 @@ RUN export ARCH="$(uname -m)" && if [[ ${ARCH} == "x86_64" ]]; then export ARCH= FROM registry.access.redhat.com/ubi8-minimal:8.9-1161 COPY --from=builder /tmp/header-rewrite-traefik-plugin /tmp/header-rewrite-traefik-plugin +COPY --from=builder /tmp/editors-definitions /tmp/editors-definitions COPY --from=builder /che-operator/che-operator /manager ENTRYPOINT ["/manager"] diff --git a/Makefile b/Makefile index 1fa7b687f..8200b666e 100644 --- a/Makefile +++ b/Makefile @@ -359,7 +359,7 @@ genenerate-env: cat $(BASH_ENV_FILE) install-che-operands: SHELL := /bin/bash -install-che-operands: generate manifests download-kustomize download-gateway-resources +install-che-operands: generate manifests download-kustomize download-gateway-resources copy-editors-definitions echo "[INFO] Running on $(PLATFORM)" if [[ ! "$$($(K8S_CLI) get checluster eclipse-che -n $(ECLIPSE_CHE_NAMESPACE) || false )" ]]; then [[ $(PLATFORM) == "kubernetes" ]] && $(MAKE) install-certmgr @@ -378,6 +378,12 @@ install-che-operands: generate manifests download-kustomize download-gateway-res $(MAKE) store_tls_cert $(MAKE) create-checluster-cr + +# Copy editors definitions to /tmp/editors-definitions +copy-editors-definitions: + mkdir -p /tmp/editors-definitions + cp -r $(PROJECT_DIR)/editors-definitions/* /tmp/editors-definitions + # Downloads Gateway resources download-gateway-resources: GATEWAY_RESOURCES=/tmp/header-rewrite-traefik-plugin diff --git a/api/v2/zz_generated.deepcopy.go b/api/v2/zz_generated.deepcopy.go index 981740202..2fa07b037 100644 --- a/api/v2/zz_generated.deepcopy.go +++ b/api/v2/zz_generated.deepcopy.go @@ -20,7 +20,7 @@ package v2 import ( "github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2" "github.com/devfile/devworkspace-operator/apis/controller/v1alpha1" - v1 "k8s.io/api/core/v1" + "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/runtime" ) diff --git a/build/scripts/release/editors-definitions.sh b/build/scripts/release/editors-definitions.sh new file mode 100755 index 000000000..bd684c7e0 --- /dev/null +++ b/build/scripts/release/editors-definitions.sh @@ -0,0 +1,80 @@ +#!/bin/bash +# +# Copyright (c) 2019-2024 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 +# + +set -e + +OPERATOR_REPO=$(dirname "$(dirname "$(dirname "$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")")")") +EDITORS_DEFINITIONS_DIR="${OPERATOR_REPO}/editors-definitions" +MANAGER_YAML="${OPERATOR_REPO}/config/manager/manager.yaml" + +init() { + unset VERSION + unset ENVS + + COMMAND=$1 + shift + + while [[ "$#" -gt 0 ]]; do + case $1 in + '--version') VERSION=$2; shift 1;; + esac + shift 1 + done +} + +usage () { + echo "Editor definitions utils." + echo + echo "Usage:" + echo -e "\t$0 release --version RELEASE_VERSION" + echo -e "\t$0 add-env-vars" +} + +release() { + if [[ ! ${VERSION} ]]; then usage; exit 1; fi + + yq -riY ".metadata.attributes.version = \"${VERSION}\"" "${EDITORS_DEFINITIONS_DIR}/che-code-latest.yaml" + yq -riY "(.components[] | select(.name==\"che-code-injector\") | .container.image) = \"quay.io/che-incubator/che-code:${VERSION}\"" "${EDITORS_DEFINITIONS_DIR}/che-code-latest.yaml" +} + +addEnvVars() { + for EDITOR_DEFINITION_FILE in $(find "${EDITORS_DEFINITIONS_DIR}" -name "*.yaml"); do + NAME=$(yq -r '.metadata.name' "${EDITOR_DEFINITION_FILE}") + VERSION=$(yq -r '.metadata.attributes.version' "${EDITOR_DEFINITION_FILE}") + for COMPONENT in $(yq -r '.components[] | .name' "${EDITOR_DEFINITION_FILE}"); do + ENV_VALUE=$(yq -r ".components[] | select(.name==\"${COMPONENT}\") | .container.image" "${EDITOR_DEFINITION_FILE}") + ENV_NAME=$(echo "RELATED_IMAGE_editor_definition_${NAME}_${VERSION}_${COMPONENT}" | sed 's|[-\.]|_|g') + + if [[ ! ${ENV_VALUE} == "null" ]]; then + ENV="{ name: \"${ENV_NAME}\", value: \"${ENV_VALUE}\"}" + if [[ -z ${ENVS} ]]; then + ENVS="${ENV}" + else + ENVS="${ENVS}, ${ENV}" + fi + fi + done + done + + yq -riY "(.spec.template.spec.containers[0].env ) += [${ENVS}]" "${MANAGER_YAML}" +} + +init "$@" + +pushd "${OPERATOR_REPO}" >/dev/null +case $COMMAND in + 'release') release;; + 'add-env-vars') release;; + *) usage; exit 1;; +esac +popd >/dev/null diff --git a/build/scripts/release/make-release.sh b/build/scripts/release/make-release.sh index 0508fe604..d5258e3f7 100755 --- a/build/scripts/release/make-release.sh +++ b/build/scripts/release/make-release.sh @@ -179,6 +179,17 @@ replaceTag() { echo "${1}" | sed -e "s/\(.*:\).*/\1${2}/" } +releaseEditorsDefinitions() { + echo "[INFO] Releasing editor definitions" + + . "${OPERATOR_REPO}/build/scripts/release/editors-definitions.sh" release --version "${RELEASE}" + . "${OPERATOR_REPO}/build/scripts/release/editors-definitions.sh" add-env-vars + + git add editors-definitions + git add "${OPERATOR_REPO}/config/manager/manager.yaml" + git commit -m "ci: Release editors definitions to $RELEASE" --signoff +} + updateVersionFile() { echo "[INFO] updating version.go file" # change version/version.go file @@ -268,7 +279,7 @@ createPRToMainBranch() { resetChanges main local tmpBranch="copy-csv-to-main" git checkout -B $tmpBranch - git diff refs/heads/${BRANCH}...refs/heads/${RELEASE_BRANCH} ':(exclude)config/manager/manager.yaml' ':(exclude)deploy' ':(exclude)Dockerfile' | git apply -3 + git diff refs/heads/${BRANCH}...refs/heads/${RELEASE_BRANCH} ':(exclude)config/manager/manager.yaml' ':(exclude)deploy' ':(exclude)editors-definitions' ':(exclude)Dockerfile' | git apply -3 if git status --porcelain; then git add -A || true # add new generated CSV files in olm/ folder git commit -am "ci: Copy "$RELEASE" csv to main" --signoff @@ -291,6 +302,7 @@ run() { checkoutToReleaseBranch updateVersionFile + releaseEditorsDefinitions releaseOperatorCode if [[ $RELEASE_OLM_FILES == "true" ]]; then releaseOlmFiles diff --git a/editors-definitions/che-code-insiders.yaml b/editors-definitions/che-code-insiders.yaml new file mode 100644 index 000000000..e57acd4b8 --- /dev/null +++ b/editors-definitions/che-code-insiders.yaml @@ -0,0 +1,145 @@ +# +# Copyright (c) 2019-2023 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 +# + +schemaVersion: 2.2.2 +metadata: + name: che-code + displayName: VS Code - Open Source + description: Microsoft Visual Studio Code - Open Source IDE for Eclipse Che - Insiders + build + tags: + - Tech-Preview + attributes: + publisher: che-incubator + version: insiders + title: Microsoft Visual Studio Code - Open Source IDE for Eclipse Che - Insiders + build + repository: https://github.com/che-incubator/che-code + firstPublicationDate: '2021-10-31' + icon-mediatype: image/svg+xml + icon-data: | + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +commands: + - id: init-container-command + apply: + component: che-code-injector + - id: init-che-code-command + exec: + component: che-code-runtime-description + commandLine: nohup /checode/entrypoint-volume.sh > /checode/entrypoint-logs.txt + 2>&1 & +events: + preStart: + - init-container-command + postStart: + - init-che-code-command +components: + - name: che-code-injector + container: + image: quay.io/che-incubator/che-code:insiders + command: + - /entrypoint-init-container.sh + volumeMounts: + - name: checode + path: /checode + memoryLimit: 256Mi + memoryRequest: 32Mi + cpuLimit: 500m + cpuRequest: 30m + - name: che-code-runtime-description + container: + image: quay.io/devfile/universal-developer-image:latest + memoryLimit: 1024Mi + memoryRequest: 256Mi + cpuLimit: 500m + cpuRequest: 30m + volumeMounts: + - name: checode + path: /checode + endpoints: + - name: che-code + attributes: + type: main + cookiesAuthEnabled: true + discoverable: false + urlRewriteSupported: true + targetPort: 3100 + exposure: public + secure: true + protocol: https + - name: code-redirect-1 + targetPort: 13131 + exposure: public + protocol: https + attributes: + discoverable: false + urlRewriteSupported: false + - name: code-redirect-2 + targetPort: 13132 + exposure: public + protocol: https + attributes: + discoverable: false + urlRewriteSupported: false + - name: code-redirect-3 + targetPort: 13133 + exposure: public + protocol: https + attributes: + discoverable: false + urlRewriteSupported: false + attributes: + app.kubernetes.io/component: che-code-runtime + app.kubernetes.io/part-of: che-code.eclipse.org + controller.devfile.io/container-contribution: true + - name: checode + volume: {} \ No newline at end of file diff --git a/editors-definitions/che-code-latest.yaml b/editors-definitions/che-code-latest.yaml new file mode 100644 index 000000000..e3b287dfc --- /dev/null +++ b/editors-definitions/che-code-latest.yaml @@ -0,0 +1,131 @@ +schemaVersion: 2.2.2 +metadata: + name: che-code + displayName: VS Code - Open Source + description: Microsoft Visual Studio Code - Open Source IDE for Eclipse Che + attributes: + publisher: che-incubator + version: latest + title: Microsoft Visual Studio Code - Open Source IDE for Eclipse Che + repository: https://github.com/che-incubator/che-code + firstPublicationDate: '2021-10-31' + icon-mediatype: image/svg+xml + icon-data: | + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +commands: + - id: init-container-command + apply: + component: che-code-injector + - id: init-che-code-command + exec: + component: che-code-runtime-description + commandLine: nohup /checode/entrypoint-volume.sh > /checode/entrypoint-logs.txt + 2>&1 & +events: + preStart: + - init-container-command + postStart: + - init-che-code-command +components: + - name: che-code-injector + container: + image: quay.io/che-incubator/che-code:latest + command: + - /entrypoint-init-container.sh + volumeMounts: + - name: checode + path: /checode + memoryLimit: 256Mi + memoryRequest: 32Mi + cpuLimit: 500m + cpuRequest: 30m + - name: che-code-runtime-description + container: + image: quay.io/devfile/universal-developer-image:latest + memoryLimit: 1024Mi + memoryRequest: 256Mi + cpuLimit: 500m + cpuRequest: 30m + volumeMounts: + - name: checode + path: /checode + endpoints: + - name: che-code + attributes: + type: main + cookiesAuthEnabled: true + discoverable: false + urlRewriteSupported: true + targetPort: 3100 + exposure: public + secure: true + protocol: https + - name: code-redirect-1 + targetPort: 13131 + exposure: public + protocol: https + attributes: + discoverable: false + urlRewriteSupported: false + - name: code-redirect-2 + targetPort: 13132 + exposure: public + protocol: https + attributes: + discoverable: false + urlRewriteSupported: false + - name: code-redirect-3 + targetPort: 13133 + exposure: public + protocol: https + attributes: + discoverable: false + urlRewriteSupported: false + attributes: + app.kubernetes.io/component: che-code-runtime + app.kubernetes.io/part-of: che-code.eclipse.org + controller.devfile.io/container-contribution: true + - name: checode + volume: {} +attributes: + version: null diff --git a/editors-definitions/che-idea-latest.yaml b/editors-definitions/che-idea-latest.yaml new file mode 100644 index 000000000..902f7a4e4 --- /dev/null +++ b/editors-definitions/che-idea-latest.yaml @@ -0,0 +1,166 @@ +# +# Copyright (c) 2019-2023 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 +# + +schemaVersion: 2.2.2 +metadata: + name: che-idea + displayName: IntelliJ IDEA Community + description: JetBrains IntelliJ IDEA Community IDE for Eclipse Che + tags: + - Tech-Preview + attributes: + publisher: che-incubator + version: latest + title: JetBrains IntelliJ IDEA Community IDE for Eclipse Che + repository: https://github.com/che-incubator/jetbrains-editor-images + firstPublicationDate: '2022-01-11' + icon-mediatype: image/svg+xml + icon-data: | + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +commands: + - id: init-container-command + apply: + component: che-idea-injector + - id: init-che-idea-command + exec: + component: che-idea-runtime-description + commandLine: nohup /projector/entrypoint-volume.sh > /projector/entrypoint-logs.txt + 2>&1 & +events: + preStart: + - init-container-command + postStart: + - init-che-idea-command +components: + - name: che-idea-runtime-description + container: + image: quay.io/devfile/universal-developer-image:latest + env: + - name: PROJECTOR_ASSEMBLY_DIR + value: /projector + - name: PROJECTOR_CONFIG_DIR + value: /home/user/.jetbrains + volumeMounts: + - name: projector-volume + path: /projector + - name: projector-configuration + path: /home/user/.jetbrains + - name: projector-java-configuration + path: /home/user/.java + memoryLimit: 6144Mi + memoryRequest: 2048Mi + cpuLimit: 2000m + cpuRequest: 1500m + endpoints: + - name: intellij + attributes: + type: main + cookiesAuthEnabled: true + discoverable: false + urlRewriteSupported: true + targetPort: 8887 + exposure: public + path: /?backgroundColor=434343&wss + secure: true + protocol: https + - name: intellij-redirect-1 + targetPort: 13131 + exposure: public + protocol: https + attributes: + discoverable: false + urlRewriteSupported: false + - name: intellij-redirect-2 + targetPort: 13132 + exposure: public + protocol: https + attributes: + discoverable: false + urlRewriteSupported: false + - name: intellij-redirect-3 + targetPort: 13133 + exposure: public + protocol: https + attributes: + discoverable: false + urlRewriteSupported: false + attributes: + app.kubernetes.io/component: che-idea-runtime + app.kubernetes.io/part-of: che-idea.eclipse.org + controller.devfile.io/container-contribution: true + - name: projector-volume + volume: {} + - name: projector-configuration + volume: {} + - name: projector-java-configuration + volume: {} + - name: che-idea-injector + container: + image: quay.io/che-incubator/che-idea:latest + command: + - /projector/entrypoint-init-container.sh + env: + - name: PROJECTOR_VOLUME_MOUNT + value: /projector-volume + - name: PROJECTOR_ASSEMBLY_DIR + value: /projector + volumeMounts: + - name: projector-volume + path: /projector-volume + memoryLimit: 128Mi + memoryRequest: 32Mi + cpuLimit: 500m + cpuRequest: 30m \ No newline at end of file diff --git a/editors-definitions/che-idea-next.yaml b/editors-definitions/che-idea-next.yaml new file mode 100644 index 000000000..255774244 --- /dev/null +++ b/editors-definitions/che-idea-next.yaml @@ -0,0 +1,166 @@ +# +# Copyright (c) 2019-2023 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 +# + +schemaVersion: 2.2.2 +metadata: + name: che-idea + displayName: IntelliJ IDEA Community + description: JetBrains IntelliJ IDEA Community IDE for Eclipse Che - next + tags: + - Tech-Preview + attributes: + publisher: che-incubator + version: next + title: JetBrains IntelliJ IDEA Community IDE for Eclipse Che - next + repository: https://github.com/che-incubator/jetbrains-editor-images + firstPublicationDate: '2022-01-11' + icon-mediatype: image/svg+xml + icon-data: | + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +commands: + - id: init-container-command + apply: + component: che-idea-injector + - id: init-che-idea-command + exec: + component: che-idea-runtime-description + commandLine: nohup /projector/entrypoint-volume.sh > /projector/entrypoint-logs.txt + 2>&1 & +events: + preStart: + - init-container-command + postStart: + - init-che-idea-command +components: + - name: che-idea-runtime-description + container: + image: quay.io/devfile/universal-developer-image:latest + env: + - name: PROJECTOR_ASSEMBLY_DIR + value: /projector + - name: PROJECTOR_CONFIG_DIR + value: /home/user/.jetbrains + volumeMounts: + - name: projector-volume + path: /projector + - name: projector-configuration + path: /home/user/.jetbrains + - name: projector-java-configuration + path: /home/user/.java + memoryLimit: 6144Mi + memoryRequest: 2048Mi + cpuLimit: 2000m + cpuRequest: 1500m + endpoints: + - name: intellij + attributes: + type: main + cookiesAuthEnabled: true + discoverable: false + urlRewriteSupported: true + targetPort: 8887 + exposure: public + path: /?backgroundColor=434343&wss + secure: true + protocol: https + - name: intellij-redirect-1 + targetPort: 13131 + exposure: public + protocol: https + attributes: + discoverable: false + urlRewriteSupported: false + - name: intellij-redirect-2 + targetPort: 13132 + exposure: public + protocol: https + attributes: + discoverable: false + urlRewriteSupported: false + - name: intellij-redirect-3 + targetPort: 13133 + exposure: public + protocol: https + attributes: + discoverable: false + urlRewriteSupported: false + attributes: + app.kubernetes.io/component: che-idea-runtime + app.kubernetes.io/part-of: che-idea.eclipse.org + controller.devfile.io/container-contribution: true + - name: projector-volume + volume: {} + - name: projector-configuration + volume: {} + - name: projector-java-configuration + volume: {} + - name: che-idea-injector + container: + image: quay.io/che-incubator/che-idea:next + command: + - /projector/entrypoint-init-container.sh + env: + - name: PROJECTOR_VOLUME_MOUNT + value: /projector-volume + - name: PROJECTOR_ASSEMBLY_DIR + value: /projector + volumeMounts: + - name: projector-volume + path: /projector-volume + memoryLimit: 128Mi + memoryRequest: 32Mi + cpuLimit: 500m + cpuRequest: 30m \ No newline at end of file diff --git a/editors-definitions/che-idea-server-latest.yaml b/editors-definitions/che-idea-server-latest.yaml new file mode 100644 index 000000000..6da8b67a5 --- /dev/null +++ b/editors-definitions/che-idea-server-latest.yaml @@ -0,0 +1,126 @@ +# +# Copyright (c) 2019-2023 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 +# + +schemaVersion: 2.2.2 +metadata: + name: che-idea-server + displayName: IntelliJ IDEA Ultimate (desktop) + description: JetBrains IntelliJ IDEA Ultimate dev server for Eclipse Che - latest + tags: + - Tech-Preview + attributes: + publisher: che-incubator + version: latest + title: JetBrains IntelliJ IDEA Ultimate dev server for Eclipse Che - latest + repository: https://github.com/che-incubator/che-idea-dev-server + firstPublicationDate: '2023-30-11' + icon-mediatype: image/svg+xml + icon-data: | + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +commands: + - id: inject-editor + apply: + component: editor-injector + - id: start-idea-server + exec: + component: editor-runtime + commandLine: nohup /idea-server/entrypoint-volume.sh > /idea-server/std.out + 2>&1 & +events: + preStart: + - inject-editor + postStart: + - start-idea-server +components: + - name: idea-server + volume: {} + - name: editor-injector + container: + image: quay.io/che-incubator/che-idea-dev-server:latest + command: + - /entrypoint-init-container.sh + volumeMounts: + - name: idea-server + path: /idea-server + memoryLimit: 256Mi + memoryRequest: 32Mi + cpuLimit: 500m + cpuRequest: 30m + - name: editor-runtime + container: + image: quay.io/devfile/universal-developer-image:latest + memoryLimit: 6144Mi + memoryRequest: 2048Mi + cpuLimit: 2000m + cpuRequest: 1500m + volumeMounts: + - name: idea-server + path: /idea-server + endpoints: + - name: idea-server + attributes: + type: main + cookiesAuthEnabled: true + discoverable: false + urlRewriteSupported: true + targetPort: 3400 + exposure: public + secure: true + protocol: https + attributes: + app.kubernetes.io/component: editor-runtime + app.kubernetes.io/part-of: idea-server.eclipse.org + controller.devfile.io/container-contribution: true \ No newline at end of file diff --git a/editors-definitions/che-idea-server-next.yaml b/editors-definitions/che-idea-server-next.yaml new file mode 100644 index 000000000..134ad1db1 --- /dev/null +++ b/editors-definitions/che-idea-server-next.yaml @@ -0,0 +1,126 @@ +# +# Copyright (c) 2019-2023 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 +# + +schemaVersion: 2.2.2 +metadata: + name: che-idea-server + displayName: IntelliJ IDEA Ultimate (desktop) + description: JetBrains IntelliJ IDEA Ultimate dev server for Eclipse Che - next + tags: + - Tech-Preview + attributes: + publisher: che-incubator + version: next + title: JetBrains IntelliJ IDEA Ultimate dev server for Eclipse Che - next + repository: https://github.com/che-incubator/che-idea-dev-server + firstPublicationDate: '2023-30-11' + icon-mediatype: image/svg+xml + icon-data: | + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +commands: + - id: inject-editor + apply: + component: editor-injector + - id: start-idea-server + exec: + component: editor-runtime + commandLine: nohup /idea-server/entrypoint-volume.sh > /idea-server/std.out + 2>&1 & +events: + preStart: + - inject-editor + postStart: + - start-idea-server +components: + - name: idea-server + volume: {} + - name: editor-injector + container: + image: quay.io/che-incubator/che-idea-dev-server:next + command: + - /entrypoint-init-container.sh + volumeMounts: + - name: idea-server + path: /idea-server + memoryLimit: 256Mi + memoryRequest: 32Mi + cpuLimit: 500m + cpuRequest: 30m + - name: editor-runtime + container: + image: quay.io/devfile/universal-developer-image:latest + memoryLimit: 6144Mi + memoryRequest: 2048Mi + cpuLimit: 2000m + cpuRequest: 1500m + volumeMounts: + - name: idea-server + path: /idea-server + endpoints: + - name: idea-server + attributes: + type: main + cookiesAuthEnabled: true + discoverable: false + urlRewriteSupported: true + targetPort: 3400 + exposure: public + secure: true + protocol: https + attributes: + app.kubernetes.io/component: editor-runtime + app.kubernetes.io/part-of: idea-server.eclipse.org + controller.devfile.io/container-contribution: true \ No newline at end of file diff --git a/mocks/pkg/util/process_mock.go b/mocks/pkg/util/process_mock.go deleted file mode 100644 index a668487c5..000000000 --- a/mocks/pkg/util/process_mock.go +++ /dev/null @@ -1,81 +0,0 @@ -// Code generated by MockGen. DO NOT EDIT. -// Source: pkg/util/process.go - -// Package mock_util is a generated GoMock package. -package mock_util - -import ( - reflect "reflect" - - gomock "github.com/golang/mock/gomock" -) - -// MockRunnable is a mock of Runnable interface -type MockRunnable struct { - ctrl *gomock.Controller - recorder *MockRunnableMockRecorder -} - -// MockRunnableMockRecorder is the mock recorder for MockRunnable -type MockRunnableMockRecorder struct { - mock *MockRunnable -} - -// NewMockRunnable creates a new mock instance -func NewMockRunnable(ctrl *gomock.Controller) *MockRunnable { - mock := &MockRunnable{ctrl: ctrl} - mock.recorder = &MockRunnableMockRecorder{mock} - return mock -} - -// EXPECT returns an object that allows the caller to indicate expected use -func (m *MockRunnable) EXPECT() *MockRunnableMockRecorder { - return m.recorder -} - -// Run mocks base method -func (m *MockRunnable) Run(name string, args ...string) error { - m.ctrl.T.Helper() - varargs := []interface{}{name} - for _, a := range args { - varargs = append(varargs, a) - } - ret := m.ctrl.Call(m, "Run", varargs...) - ret0, _ := ret[0].(error) - return ret0 -} - -// Run indicates an expected call of Run -func (mr *MockRunnableMockRecorder) Run(name interface{}, args ...interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - varargs := append([]interface{}{name}, args...) - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Run", reflect.TypeOf((*MockRunnable)(nil).Run), varargs...) -} - -// GetStdOut mocks base method -func (m *MockRunnable) GetStdOut() string { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetStdOut") - ret0, _ := ret[0].(string) - return ret0 -} - -// GetStdOut indicates an expected call of GetStdOut -func (mr *MockRunnableMockRecorder) GetStdOut() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetStdOut", reflect.TypeOf((*MockRunnable)(nil).GetStdOut)) -} - -// GetStdErr mocks base method -func (m *MockRunnable) GetStdErr() string { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetStdErr") - ret0, _ := ret[0].(string) - return ret0 -} - -// GetStdErr indicates an expected call of GetStdErr -func (mr *MockRunnableMockRecorder) GetStdErr() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetStdErr", reflect.TypeOf((*MockRunnable)(nil).GetStdErr)) -} diff --git a/pkg/common/constants/constants.go b/pkg/common/constants/constants.go index 17854d7be..c74afa7ec 100644 --- a/pkg/common/constants/constants.go +++ b/pkg/common/constants/constants.go @@ -124,6 +124,7 @@ const ( GatewayAuthenticationContainerName = "oauth-proxy" GatewayAuthorizationContainerName = "kube-rbac-proxy" KubernetesImagePullerComponentName = "kubernetes-image-puller" + EditorDefinitionComponentName = "editor-definition" // common CheFlavor = "che" diff --git a/pkg/common/utils/process.go b/pkg/common/utils/process.go deleted file mode 100644 index c2905f451..000000000 --- a/pkg/common/utils/process.go +++ /dev/null @@ -1,51 +0,0 @@ -// -// Copyright (c) 2019-2023 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 utils - -import ( - "bytes" - "os/exec" -) - -type Runnable interface { - Run(name string, args ...string) error - GetStdOut() string - GetStdErr() string -} - -type Process struct { - cmd *exec.Cmd - stdout bytes.Buffer - stderr bytes.Buffer -} - -func NewRunnable() Runnable { - return &Process{} -} - -func (p *Process) Run(name string, args ...string) error { - p.cmd = exec.Command(name, args...) - p.stderr.Reset() - p.stdout.Reset() - p.cmd.Stdout = &p.stdout - p.cmd.Stderr = &p.stderr - return p.cmd.Run() -} - -func (p *Process) GetStdOut() string { - return string(p.stdout.Bytes()) -} - -func (p *Process) GetStdErr() string { - return string(p.stderr.Bytes()) -} diff --git a/pkg/deploy/pluginregistry/init_test.go b/pkg/deploy/pluginregistry/init_test.go index 02fd09c04..d8d7e5f0b 100644 --- a/pkg/deploy/pluginregistry/init_test.go +++ b/pkg/deploy/pluginregistry/init_test.go @@ -1,5 +1,5 @@ // -// Copyright (c) 2019-2023 Red Hat, Inc. +// Copyright (c) 2019-2024 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/ @@ -23,4 +23,6 @@ func init() { infrastructure.InitializeForTesting(infrastructure.OpenShiftv4) defaults.InitializeForTesting("../../../config/manager/manager.yaml") + + editorsDefinitionsDir = "./test-editors-definitions" } diff --git a/pkg/deploy/pluginregistry/pluginregistry.go b/pkg/deploy/pluginregistry/pluginregistry.go index 097ee2b19..81893555c 100644 --- a/pkg/deploy/pluginregistry/pluginregistry.go +++ b/pkg/deploy/pluginregistry/pluginregistry.go @@ -1,5 +1,5 @@ // -// Copyright (c) 2019-2023 Red Hat, Inc. +// Copyright (c) 2019-2024 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/ @@ -16,6 +16,9 @@ import ( "fmt" "strings" + appsv1 "k8s.io/api/apps/v1" + corev1 "k8s.io/api/core/v1" + "github.com/eclipse-che/che-operator/pkg/common/chetypes" "github.com/eclipse-che/che-operator/pkg/common/constants" "github.com/eclipse-che/che-operator/pkg/deploy/gateway" @@ -35,12 +38,25 @@ func NewPluginRegistryReconciler() *PluginRegistryReconciler { func (p *PluginRegistryReconciler) Reconcile(ctx *chetypes.DeployContext) (reconcile.Result, bool, error) { if ctx.CheCluster.Spec.Components.PluginRegistry.DisableInternalRegistry { - ctx.CheCluster.Status.PluginRegistryURL = "" - err := deploy.UpdateCheCRStatus(ctx, "PluginRegistryURL", "") - return reconcile.Result{}, err == nil, err + _, _ = deploy.DeleteNamespacedObject(ctx, constants.PluginRegistryName, &corev1.Service{}) + _, _ = deploy.DeleteNamespacedObject(ctx, constants.PluginRegistryName, &corev1.ConfigMap{}) + _, _ = deploy.DeleteNamespacedObject(ctx, editorsDefinitionsConfigMapName, &corev1.ConfigMap{}) + _, _ = deploy.DeleteNamespacedObject(ctx, gateway.GatewayConfigMapNamePrefix+constants.PluginRegistryName, &corev1.ConfigMap{}) + _, _ = deploy.DeleteNamespacedObject(ctx, constants.PluginRegistryName, &appsv1.Deployment{}) + + if ctx.CheCluster.Status.PluginRegistryURL != "" { + ctx.CheCluster.Status.PluginRegistryURL = "" + err := deploy.UpdateCheCRStatus(ctx, "PluginRegistryURL", "") + return reconcile.Result{}, err == nil, err + } } - done, err := p.syncService(ctx) + done, err := p.syncEditors(ctx) + if !done { + return reconcile.Result{}, false, err + } + + done, err = p.syncService(ctx) if !done { return reconcile.Result{}, false, err } diff --git a/pkg/deploy/pluginregistry/pluginregistry_editors.go b/pkg/deploy/pluginregistry/pluginregistry_editors.go new file mode 100644 index 000000000..0c66453ee --- /dev/null +++ b/pkg/deploy/pluginregistry/pluginregistry_editors.go @@ -0,0 +1,129 @@ +// +// Copyright (c) 2019-2024 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 pluginregistry + +import ( + "fmt" + "os" + "path/filepath" + "regexp" + + "github.com/eclipse-che/che-operator/pkg/common/chetypes" + "github.com/eclipse-che/che-operator/pkg/common/constants" + "github.com/eclipse-che/che-operator/pkg/common/utils" + "github.com/eclipse-che/che-operator/pkg/deploy" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "sigs.k8s.io/yaml" +) + +var ( + editorsDefinitionsDir = "/tmp/editors-definitions" + editorsDefinitionsConfigMapName = "editors-definitions" +) + +func (p *PluginRegistryReconciler) syncEditors(ctx *chetypes.DeployContext) (bool, error) { + editorDefinitions, err := readEditorDefinitions() + if err != nil { + return false, err + } + + done, err := syncEditorDefinitions(ctx, editorDefinitions) + if !done { + return false, err + } + + return true, nil +} + +func readEditorDefinitions() (map[string][]byte, error) { + editorDefinitions := make(map[string][]byte) + + files, err := os.ReadDir(editorsDefinitionsDir) + if err != nil { + return editorDefinitions, err + } + + for _, file := range files { + if !file.IsDir() { + fileName := file.Name() + + editorContent, err := os.ReadFile(filepath.Join(editorsDefinitionsDir, fileName)) + if err != nil { + return editorDefinitions, err + } + + var devfile map[string]interface{} + err = yaml.Unmarshal(editorContent, &devfile) + if err != nil { + return editorDefinitions, err + } + + updateEditorDefinitionImageFromEnv(devfile) + + editorContent, err = yaml.Marshal(devfile) + if err != nil { + return editorDefinitions, err + } + + editorDefinitions[fileName] = editorContent + } + } + + return editorDefinitions, nil +} + +func updateEditorDefinitionImageFromEnv(devfile map[string]interface{}) { + notAllowedCharsReg, _ := regexp.Compile("[^a-zA-Z0-9]+") + + metadata := devfile["metadata"].(map[string]interface{}) + devfileName := metadata["name"].(string) + attributes := metadata["attributes"].(map[string]interface{}) + devfileVersion := attributes["version"].(string) + + components := devfile["components"].([]interface{}) + for _, component := range components { + componentName := component.(map[string]interface{})["name"].(string) + if container, ok := component.(map[string]interface{})["container"].(map[string]interface{}); ok { + imageEnvName := fmt.Sprintf("RELATED_IMAGE_%s_%s_%s", devfileName, devfileVersion, componentName) + imageEnvName = notAllowedCharsReg.ReplaceAllString(imageEnvName, "_") + imageEnvName = utils.GetArchitectureDependentEnvName(imageEnvName) + + if imageEnvValue, ok := os.LookupEnv(imageEnvName); ok { + container["image"] = imageEnvValue + } + } + } +} + +func syncEditorDefinitions(ctx *chetypes.DeployContext, editorDefinitions map[string][]byte) (bool, error) { + cm := &corev1.ConfigMap{ + TypeMeta: metav1.TypeMeta{ + Kind: "ConfigMap", + APIVersion: "v1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: editorsDefinitionsConfigMapName, + Namespace: ctx.CheCluster.Namespace, + Labels: deploy.GetLabels(constants.EditorDefinitionComponentName), + Annotations: map[string]string{}, + }, + Data: map[string]string{}, + } + + for fileName, content := range editorDefinitions { + cm.Data[fileName] = string(content) + } + + return deploy.Sync(ctx, cm, deploy.ConfigMapDiffOpts) +} diff --git a/pkg/deploy/pluginregistry/pluginregistry_editors_test.go b/pkg/deploy/pluginregistry/pluginregistry_editors_test.go new file mode 100644 index 000000000..a31f257cb --- /dev/null +++ b/pkg/deploy/pluginregistry/pluginregistry_editors_test.go @@ -0,0 +1,68 @@ +// +// Copyright (c) 2019-2024 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 pluginregistry + +import ( + "os" + "testing" + + "github.com/eclipse-che/che-operator/pkg/common/test" + "github.com/stretchr/testify/assert" + "k8s.io/apimachinery/pkg/runtime" + "sigs.k8s.io/yaml" +) + +func TestReadEditorDefinitions(t *testing.T) { + err := os.Setenv("RELATED_IMAGE_che_code_1_2_3_component_a", "image-new-a") + assert.NoError(t, err) + + defer func() { + _ = os.Setenv("RELATED_IMAGE_che_code_1_2_3_component_a", "") + }() + + editorDefinitions, err := readEditorDefinitions() + assert.NoError(t, err) + assert.NotEmpty(t, editorDefinitions) + assert.Equal(t, 1, len(editorDefinitions)) + assert.Contains(t, editorDefinitions, "devfile.yaml") + + var devfile map[string]interface{} + err = yaml.Unmarshal(editorDefinitions["devfile.yaml"], &devfile) + assert.NoError(t, err) + + components := devfile["components"].([]interface{}) + + component := components[0].(map[string]interface{}) + container := component["container"].(map[string]interface{}) + assert.Equal(t, "image-new-a", container["image"]) + + component = components[1].(map[string]interface{}) + container = component["container"].(map[string]interface{}) + assert.Equal(t, "image-b", container["image"]) + + component = components[2].(map[string]interface{}) + container, ok := component["container"].(map[string]interface{}) + assert.False(t, ok) +} + +func TestSyncEditorDefinitions(t *testing.T) { + ctx := test.GetDeployContext(nil, []runtime.Object{}) + + editorDefinitions, err := readEditorDefinitions() + assert.NoError(t, err) + assert.NotEmpty(t, editorDefinitions) + + done, err := syncEditorDefinitions(ctx, editorDefinitions) + assert.NoError(t, err) + assert.True(t, done) +} diff --git a/pkg/deploy/pluginregistry/pluginregistry_test.go b/pkg/deploy/pluginregistry/pluginregistry_test.go index ffe6cb7b4..266539bc9 100644 --- a/pkg/deploy/pluginregistry/pluginregistry_test.go +++ b/pkg/deploy/pluginregistry/pluginregistry_test.go @@ -1,5 +1,5 @@ // -// Copyright (c) 2019-2023 Red Hat, Inc. +// Copyright (c) 2019-2024 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/ @@ -37,6 +37,7 @@ func TestPluginRegistryReconcile(t *testing.T) { assert.True(t, test.IsObjectExists(ctx.ClusterAPI.Client, types.NamespacedName{Name: "plugin-registry", Namespace: "eclipse-che"}, &corev1.Service{})) assert.True(t, test.IsObjectExists(ctx.ClusterAPI.Client, types.NamespacedName{Name: "plugin-registry", Namespace: "eclipse-che"}, &corev1.ConfigMap{})) + assert.True(t, test.IsObjectExists(ctx.ClusterAPI.Client, types.NamespacedName{Name: "editors-definitions", Namespace: "eclipse-che"}, &corev1.ConfigMap{})) assert.True(t, test.IsObjectExists(ctx.ClusterAPI.Client, types.NamespacedName{Name: "plugin-registry", Namespace: "eclipse-che"}, &appsv1.Deployment{})) assert.NotEmpty(t, ctx.CheCluster.Status.PluginRegistryURL) } diff --git a/pkg/deploy/pluginregistry/test-editors-definitions/devfile.yaml b/pkg/deploy/pluginregistry/test-editors-definitions/devfile.yaml new file mode 100644 index 000000000..c2a766892 --- /dev/null +++ b/pkg/deploy/pluginregistry/test-editors-definitions/devfile.yaml @@ -0,0 +1,25 @@ +# +# Copyright (c) 2019-2024 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 +# + +schemaVersion: 2.2.2 +metadata: + name: che-code + attributes: + version: 1.2.3 +components: + - name: component-a + container: + image: image-a + - name: component-b + container: + image: image-b + - name: component-c