diff --git a/.ci/oci_chectl_rollback.sh b/.ci/oci_chectl_rollback.sh index 2fb991c4f..6de34404c 100755 --- a/.ci/oci_chectl_rollback.sh +++ b/.ci/oci_chectl_rollback.sh @@ -32,7 +32,7 @@ init() { export SCRIPT=$(readlink -f "$0") export SCRIPT_DIR=$(dirname "$SCRIPT") - # Env necessary for openshift CI to put che logs inside + # Env necсessary for openshift CI to put che logs inside export ARTIFACTS_DIR="/tmp/artifacts" # Suggested namespace @@ -47,6 +47,8 @@ init() { } run() { + echo "[INFO] Environment:" + env # Before running the e2e tests we need to install all deps with yarn yarn --cwd ${CHECTL_REPO} export PLATFORM=openshift diff --git a/.github/workflows/e2e-minikube-operator-rollback.yml b/.github/workflows/e2e-minikube-operator-rollback.yml new file mode 100644 index 000000000..6667904fc --- /dev/null +++ b/.github/workflows/e2e-minikube-operator-rollback.yml @@ -0,0 +1,37 @@ +# +# Copyright (c) 2019-2021 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 +# + +name: Minikube E2E +on: pull_request +jobs: + minikube-e2e-operator-rollback: + name: Operator installer rollback update + runs-on: ubuntu-20.04 + steps: + - uses: actions/checkout@v1 + - name: Start minikube cluster + id: run-minikube + uses: che-incubator/setup-minikube-action@next + with: + minikube-version: v1.21.0 + - name: Install chectl dependencies + run: yarn + - name: Run e2e rollback tests for Operator installer + run: | + export PLATFORM=minikube + export INSTALLER=operator + yarn test --coverage=false --forceExit --testRegex=test/e2e/e2e-rollback.test.ts + - uses: actions/upload-artifact@v2 + if: ${{ always() }} + with: + name: test-artifacts + path: /tmp/logs/* diff --git a/src/api/kube.ts b/src/api/kube.ts index ad5cc394b..fcc6bded6 100644 --- a/src/api/kube.ts +++ b/src/api/kube.ts @@ -1687,7 +1687,7 @@ export class KubeHelper { cheClusterCR.spec.devWorkspace.enable = true } - if (cheClusterCR.spec.devWorkspace.enable) { + if (cheClusterCR.spec.devWorkspace && cheClusterCR.spec.devWorkspace.enable) { cheClusterCR.spec.auth.nativeUserMode = true } diff --git a/test/e2e/e2e-rollback.test.ts b/test/e2e/e2e-rollback.test.ts index 655ca6a4b..43f1b2941 100644 --- a/test/e2e/e2e-rollback.test.ts +++ b/test/e2e/e2e-rollback.test.ts @@ -18,10 +18,9 @@ jest.setTimeout(1000000) const binChectl = E2eHelper.getChectlBinaries() -const PLATFORM = process.env.PLATFORM || 'minikube' - -const INSTALLER = 'olm' -const OLM_CHANNEL = 'stable' +const PLATFORM = process.env.PLATFORM || 'openshift' +const INSTALLER = process.env.INSTALLER || 'olm' +const OLM_CHANNEL = process.env.OLM_CHANNEL || 'stable' const CHE_VERSION_TIMEOUT_MS = 12 * 60 * 1000 const CHE_BACKUP_TIMEOUT_MS = 2 * 60 * 1000 @@ -33,9 +32,12 @@ describe('Test rollback Che update', () => { describe('Prepare pre-latest stable Che', () => { it(`Deploy Che using ${INSTALLER} installer from ${OLM_CHANNEL} channel`, async () => { // Retrieve pre-latest and latest stable Che version - [previousCheVersion, latestCheVersion] = await helper.getTwoLatestReleasedVersions() + [previousCheVersion, latestCheVersion] = await helper.getTwoLatestReleasedVersions(INSTALLER) - const deployCommand = `${binChectl} server:deploy --batch --platform=${PLATFORM} --installer=${INSTALLER} --olm-channel=${OLM_CHANNEL} --version=${previousCheVersion} --chenamespace=${NAMESPACE} --telemetry=off --che-operator-cr-patch-yaml=test/e2e/resources/cr-patch.yaml` + let deployCommand = `${binChectl} server:deploy --batch --platform=${PLATFORM} --installer=${INSTALLER} --version=${previousCheVersion} --chenamespace=${NAMESPACE} --telemetry=off --che-operator-cr-patch-yaml=test/e2e/resources/cr-patch.yaml` + if (INSTALLER === 'olm') { + deployCommand += ` --olm-channel=${OLM_CHANNEL}` + } await helper.runCliCommand(deployCommand) await helper.waitForVersionInCheCR(previousCheVersion, CHE_VERSION_TIMEOUT_MS) @@ -46,7 +48,12 @@ describe('Test rollback Che update', () => { it('Update Eclipse Che Version to the latest', async () => { console.log(`Updating from ${previousCheVersion} to ${latestCheVersion}`) - await helper.runCliCommand(binChectl, ['server:update', '-y', `-n ${NAMESPACE}`, '--telemetry=off']) + let updateCommand = `${binChectl} server:update -y -n ${NAMESPACE} --telemetry=off` + if (INSTALLER === 'operator') { + // It is required to specify version for Operator installer, otherwise it will update Che to next as chectl is of next version + updateCommand += ` --version=${latestCheVersion}` + } + await helper.runCliCommand(updateCommand) }) it('Wait backup done', async () => { @@ -70,7 +77,7 @@ describe('Test rollback Che update', () => { it('Wait previous Che', async () => { // It is possible to reduce awaiting timeout, because rollback itself waits for the restore to complete. - await helper.waitForVersionInCheCR(previousCheVersion, 2 * 60 * 1000) + await helper.waitForVersionInCheCR(previousCheVersion, 5 * 60 * 1000) }) }) }) diff --git a/test/e2e/util.ts b/test/e2e/util.ts index e3e9c3aa6..d0d09301a 100644 --- a/test/e2e/util.ts +++ b/test/e2e/util.ts @@ -14,6 +14,7 @@ import { Octokit } from '@octokit/rest' import * as execa from 'execa' import { spawn } from 'child_process' import * as fs from 'fs-extra' +import * as semver from 'semver' import { CheHelper } from '../../src/api/che' import { CheGithubClient, TagInfo } from '../../src/api/github-client' @@ -286,6 +287,43 @@ export class E2eHelper { return tags } + /** + * Returns list of sorted CSVs in stable OLM channel of Che Operator published in community-operators repository. + * The CSVs are sorted from the latest to oldest. + */ + private async listOLMReleasedCSV(): Promise { + const response = await this.octokit.repos.getContent({ + owner: 'redhat-openshift-ecosystem', + repo: 'community-operators-prod', + path: 'operators/eclipse-che', + }) + // There is an array in the response as given path points to a directory + const data = response.data as {name: string}[] + const csvsNames: string[] = [] + data.map(item => csvsNames.push(item.name)) + const stableChannelCSVNames = csvsNames.filter(csvName => { + // Filter versions like 7.37.2-all-namespaces + if (csvName.indexOf('-') !== -1) { + return false + } + + // Filter non x.y.z + const versionParts = csvName.split('.') + if (versionParts.length !== 3) { + return false + } + // Ensure each part is a number + for (const versionPart of versionParts) { + if (!versionPart.match(/^[0-9]+$/)) { + return false + } + } + return true + }) + + return stableChannelCSVNames.sort((verA: string, verB: string) => semver.lt(verA, verB) ? 1 : -1) + } + /** * Get previous version from chectl repository */ @@ -298,10 +336,20 @@ export class E2eHelper { /** * Gets pre-latest and latest released version from chectl repository */ - async getTwoLatestReleasedVersions(): Promise<[string, string]> { - const githubClient = new CheGithubClient() - const latestTags = (githubClient as any).sortSemanticTags(await this.listLatestTags(CHECTL_REPONAME)) - return [latestTags[1].name, latestTags[0].name] + async getTwoLatestReleasedVersions(installer: string): Promise<[string, string]> { + if (installer === 'olm') { + // OLM installer uses community-operators marketplace. + // To list available versions see the following folder: + // https://github.com/redhat-openshift-ecosystem/community-operators-prod/tree/main/operators/eclipse-che + const csvs = await this.listOLMReleasedCSV() + return [csvs[1], csvs[0]] + } else if (installer === 'operator') { + // Operator installer uses templates from GitHub releases, which are marked with tags + const githubClient = new CheGithubClient() + const latestTags = (githubClient as any).sortSemanticTags(await this.listLatestTags(CHECTL_REPONAME)) + return [latestTags[1].name, latestTags[0].name] + } + throw new Error(`Failed to get latest versions: unknown installer '${installer}'`) } /**