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

feat: Add support to install che using stable-all-namespaces olm channel #1478

Merged
merged 3 commits into from
Aug 3, 2021
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
8 changes: 6 additions & 2 deletions src/api/context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import * as os from 'os'
import * as path from 'path'

import { CHE_OPERATOR_CR_PATCH_YAML_KEY, CHE_OPERATOR_CR_YAML_KEY, LOG_DIRECTORY_KEY } from '../common-flags'
import { CHECTL_PROJECT_NAME } from '../constants'
import { CHECTL_PROJECT_NAME, DEFAULT_CHE_NAMESPACE, DEFAULT_OPENSHIFT_OPERATORS_NS_NAME, STABLE_ALL_NAMESPACES_CHANNEL_NAME } from '../constants'
import { getProjectName, getProjectVersion, readCRFile } from '../util'

import { CHECTL_DEVELOPMENT_VERSION } from './version'
Expand Down Expand Up @@ -45,11 +45,15 @@ export namespace ChectlContext {
export async function init(flags: any, command: Command): Promise<void> {
ctx.isChectl = getProjectName() === CHECTL_PROJECT_NAME
ctx.isDevVersion = getProjectVersion().includes('next') || getProjectVersion() === CHECTL_DEVELOPMENT_VERSION

ctx.operatorNamespace = flags.chenamespace || DEFAULT_CHE_NAMESPACE
if (flags['listr-renderer'] as any) {
ctx.listrOptions = { renderer: (flags['listr-renderer'] as any), collapse: false } as Listr.ListrOptions
}

if (flags['olm-channel'] === STABLE_ALL_NAMESPACES_CHANNEL_NAME) {
ctx.operatorNamespace = DEFAULT_OPENSHIFT_OPERATORS_NS_NAME
}

ctx.highlightedMessages = [] as string[]
ctx[START_TIME] = Date.now()

Expand Down
5 changes: 3 additions & 2 deletions src/api/kube.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2033,9 +2033,10 @@ export class KubeHelper {
try {
await customObjectsApi.deleteNamespacedCustomObject('operators.coreos.com', 'v1alpha1', namespace, 'subscriptions', operatorSubscriptionName)
} catch (e) {
if (e.response.statusCode !== 404) {
throw this.wrapK8sClientError(e)
if (e.response.statusCode === 404) {
return
}
throw this.wrapK8sClientError(e)
}
}

Expand Down
6 changes: 5 additions & 1 deletion src/commands/server/deploy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import * as semver from 'semver'
import { ChectlContext } from '../../api/context'
import { KubeHelper } from '../../api/kube'
import { batch, cheDeployment, cheDeployVersion, cheNamespace, cheOperatorCRPatchYaml, cheOperatorCRYaml, CHE_OPERATOR_CR_PATCH_YAML_KEY, CHE_OPERATOR_CR_YAML_KEY, CHE_TELEMETRY, DEPLOY_VERSION_KEY, devWorkspaceControllerNamespace, k8sPodDownloadImageTimeout, K8SPODDOWNLOADIMAGETIMEOUT_KEY, k8sPodErrorRecheckTimeout, K8SPODERRORRECHECKTIMEOUT_KEY, k8sPodReadyTimeout, K8SPODREADYTIMEOUT_KEY, k8sPodWaitTimeout, K8SPODWAITTIMEOUT_KEY, listrRenderer, logsDirectory, LOG_DIRECTORY_KEY, skipKubeHealthzCheck as skipK8sHealthCheck } from '../../common-flags'
import { DEFAULT_ANALYTIC_HOOK_NAME, DEFAULT_CHE_NAMESPACE, DEFAULT_OLM_SUGGESTED_NAMESPACE, DOCS_LINK_INSTALL_RUNNING_CHE_LOCALLY, MIN_CHE_OPERATOR_INSTALLER_VERSION, MIN_HELM_INSTALLER_VERSION, MIN_OLM_INSTALLER_VERSION } from '../../constants'
import { DEFAULT_ANALYTIC_HOOK_NAME, DEFAULT_CHE_NAMESPACE, DEFAULT_OLM_SUGGESTED_NAMESPACE, DOCS_LINK_INSTALL_RUNNING_CHE_LOCALLY, MIN_CHE_OPERATOR_INSTALLER_VERSION, MIN_HELM_INSTALLER_VERSION, MIN_OLM_INSTALLER_VERSION, STABLE_ALL_NAMESPACES_CHANNEL_NAME } from '../../constants'
import { CheTasks } from '../../tasks/che'
import { DevWorkspaceTasks } from '../../tasks/component-installers/devfile-workspace-operator-installer'
import { checkChectlAndCheVersionCompatibility, downloadTemplates, getPrintHighlightedMessagesTask, getRetrieveKeycloakCredentialsTask, retrieveCheCaCertificateTask } from '../../tasks/installers/common-tasks'
Expand Down Expand Up @@ -296,6 +296,10 @@ export default class Deploy extends Command {
this.error(`🛑 The specified installer ${flags.installer} does not support Minishift`)
}

if (flags['olm-channel'] === STABLE_ALL_NAMESPACES_CHANNEL_NAME && isKubernetesPlatformFamily(flags.platform)) {
this.error('"stable-all-namespaces" channel is supported only in "openshift" platform')
}

if (flags['catalog-source-name'] && flags['catalog-source-yaml']) {
this.error('should be provided only one argument: "catalog-source-name" or "catalog-source-yaml"')
}
Expand Down
3 changes: 3 additions & 0 deletions src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,3 +90,6 @@ export const CHE_CLUSTER_BACKUP_CRD = 'checlusterbackups.org.eclipse.che'
export const CHE_CLUSTER_BACKUP_KIND_PLURAL = 'checlusterbackups'
export const CHE_CLUSTER_RESTORE_CRD = 'checlusterrestores.org.eclipse.che'
export const CHE_CLUSTER_RESTORE_KIND_PLURAL = 'checlusterrestores'

export const DEFAULT_OPENSHIFT_OPERATORS_NS_NAME = 'openshift-operators'
export const STABLE_ALL_NAMESPACES_CHANNEL_NAME = 'stable-all-namespaces'
65 changes: 41 additions & 24 deletions src/tasks/installers/olm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import * as path from 'path'
import { KubeHelper } from '../../api/kube'
import { CatalogSource, Subscription } from '../../api/typings/olm'
import { VersionHelper } from '../../api/version'
import { CUSTOM_CATALOG_SOURCE_NAME, CVS_PREFIX, DEFAULT_CHE_OLM_PACKAGE_NAME, DEFAULT_OLM_KUBERNETES_NAMESPACE, DEFAULT_OPENSHIFT_MARKET_PLACE_NAMESPACE, KUBERNETES_OLM_CATALOG, NIGHTLY_CATALOG_SOURCE_NAME, OLM_NIGHTLY_CHANNEL_NAME, OLM_STABLE_CHANNEL_NAME, OPENSHIFT_OLM_CATALOG, OPERATOR_GROUP_NAME, SUBSCRIPTION_NAME } from '../../constants'
import { CUSTOM_CATALOG_SOURCE_NAME, CVS_PREFIX, DEFAULT_CHE_NAMESPACE, DEFAULT_CHE_OLM_PACKAGE_NAME, DEFAULT_OLM_KUBERNETES_NAMESPACE, DEFAULT_OPENSHIFT_MARKET_PLACE_NAMESPACE, DEFAULT_OPENSHIFT_OPERATORS_NS_NAME, KUBERNETES_OLM_CATALOG, NIGHTLY_CATALOG_SOURCE_NAME, OLM_NIGHTLY_CHANNEL_NAME, OLM_STABLE_CHANNEL_NAME, OPENSHIFT_OLM_CATALOG, OPERATOR_GROUP_NAME, STABLE_ALL_NAMESPACES_CHANNEL_NAME, SUBSCRIPTION_NAME } from '../../constants'
import { isKubernetesPlatformFamily } from '../../util'

import { createEclipseCheCluster, createNamespaceTask, patchingEclipseCheCluster } from './common-tasks'
Expand Down Expand Up @@ -68,6 +68,8 @@ export class OLMTasks {
},
{
title: 'Create operator group',
// 'stable-all-namespaces' channel install the operator in openshift-operators namespace and there already exists a pre-created operator-group.
enabled: (ctx: any) => ctx.operatorNamespace !== DEFAULT_OPENSHIFT_OPERATORS_NS_NAME,
task: async (_ctx: any, task: any) => {
if (await kube.operatorGroupExists(OPERATOR_GROUP_NAME, flags.chenamespace)) {
task.title = `${task.title}...It already exists.`
Expand Down Expand Up @@ -142,20 +144,23 @@ export class OLMTasks {
{
title: 'Create operator subscription',
task: async (ctx: any, task: any) => {
if (await kube.operatorSubscriptionExists(SUBSCRIPTION_NAME, flags.chenamespace)) {
if (await kube.operatorSubscriptionExists(SUBSCRIPTION_NAME, ctx.operatorNamespace)) {
task.title = `${task.title}...It already exists.`
} else {
let subscription: Subscription
if (flags['catalog-source-yaml'] || flags['catalog-source-name']) {
// custom Che CatalogSource
const catalogSourceNamespace = flags['catalog-source-namespace'] || flags.chenamespace
subscription = this.constructSubscription(SUBSCRIPTION_NAME, flags['package-manifest-name'], flags.chenamespace, catalogSourceNamespace, flags['olm-channel'], ctx.sourceName, ctx.approvalStarategy, ctx.startingCSV)
const catalogSourceNamespace = flags['catalog-source-namespace'] || ctx.operatorNamespace
subscription = this.constructSubscription(SUBSCRIPTION_NAME, flags['package-manifest-name'], ctx.operatorNamespace, catalogSourceNamespace, flags['olm-channel'], ctx.sourceName, ctx.approvalStarategy, ctx.startingCSV)
} else if (VersionHelper.isDeployingStableVersion(flags) || flags['olm-channel'] === OLM_STABLE_CHANNEL_NAME) {
// stable Che CatalogSource
subscription = this.constructSubscription(SUBSCRIPTION_NAME, DEFAULT_CHE_OLM_PACKAGE_NAME, flags.chenamespace, ctx.defaultCatalogSourceNamespace, OLM_STABLE_CHANNEL_NAME, ctx.catalogSourceNameStable, ctx.approvalStarategy, ctx.startingCSV)
subscription = this.constructSubscription(SUBSCRIPTION_NAME, DEFAULT_CHE_OLM_PACKAGE_NAME, ctx.operatorNamespace, ctx.defaultCatalogSourceNamespace, OLM_STABLE_CHANNEL_NAME, ctx.catalogSourceNameStable, ctx.approvalStarategy, ctx.startingCSV)
} else if (flags['olm-channel'] === STABLE_ALL_NAMESPACES_CHANNEL_NAME) {
// stable Che CatalogSource
subscription = this.constructSubscription(SUBSCRIPTION_NAME, DEFAULT_CHE_OLM_PACKAGE_NAME, ctx.operatorNamespace, ctx.defaultCatalogSourceNamespace, STABLE_ALL_NAMESPACES_CHANNEL_NAME, ctx.catalogSourceNameStable, ctx.approvalStarategy, ctx.startingCSV)
} else {
// nightly Che CatalogSource
subscription = this.constructSubscription(SUBSCRIPTION_NAME, `eclipse-che-preview-${ctx.generalPlatformName}`, flags.chenamespace, flags.chenamespace, OLM_NIGHTLY_CHANNEL_NAME, NIGHTLY_CATALOG_SOURCE_NAME, ctx.approvalStarategy, ctx.startingCSV)
subscription = this.constructSubscription(SUBSCRIPTION_NAME, `eclipse-che-preview-${ctx.generalPlatformName}`, ctx.operatorNamespace, ctx.operatorNamespace, OLM_NIGHTLY_CHANNEL_NAME, NIGHTLY_CATALOG_SOURCE_NAME, ctx.approvalStarategy, ctx.startingCSV)
}
await kube.createOperatorSubscription(subscription)
task.title = `${task.title}...created new one.`
Expand All @@ -165,7 +170,7 @@ export class OLMTasks {
{
title: 'Wait while subscription is ready',
task: async (ctx: any, task: any) => {
const installPlan = await kube.waitOperatorSubscriptionReadyForApproval(flags.chenamespace, SUBSCRIPTION_NAME, 600)
const installPlan = await kube.waitOperatorSubscriptionReadyForApproval(ctx.operatorNamespace, SUBSCRIPTION_NAME, 600)
ctx.installPlanName = installPlan.name
task.title = `${task.title}...done.`
},
Expand All @@ -174,14 +179,14 @@ export class OLMTasks {
title: 'Approve installation',
enabled: ctx => ctx.approvalStarategy === 'Manual',
task: async (ctx: any, task: any) => {
await kube.approveOperatorInstallationPlan(ctx.installPlanName, flags.chenamespace)
await kube.approveOperatorInstallationPlan(ctx.installPlanName, ctx.operatorNamespace)
task.title = `${task.title}...done.`
},
},
{
title: 'Wait while operator installed',
task: async (ctx: any, task: any) => {
await kube.waitUntilOperatorIsInstalled(ctx.installPlanName, flags.chenamespace)
await kube.waitUntilOperatorIsInstalled(ctx.installPlanName, ctx.operatorNamespace)
task.title = `${task.title}...done.`
},
},
Expand Down Expand Up @@ -225,17 +230,17 @@ export class OLMTasks {
this.isOlmPreInstalledTask(command, kube),
{
title: 'Check if operator group exists',
task: async (_ctx: any, task: any) => {
if (!await kube.operatorGroupExists(OPERATOR_GROUP_NAME, flags.chenamespace)) {
task: async (ctx: any, task: any) => {
if (!await kube.operatorGroupExists(OPERATOR_GROUP_NAME, ctx.operatorNamespace)) {
command.error(`Unable to find operator group ${OPERATOR_GROUP_NAME}`)
}
task.title = `${task.title}...done.`
},
},
{
title: 'Check if operator subscription exists',
task: async (_ctx: any, task: any) => {
if (!await kube.operatorSubscriptionExists(SUBSCRIPTION_NAME, flags.chenamespace)) {
task: async (ctx: any, task: any) => {
if (!await kube.operatorSubscriptionExists(SUBSCRIPTION_NAME, ctx.operatorNamespace)) {
command.error(`Unable to find operator subscription ${SUBSCRIPTION_NAME}`)
}
task.title = `${task.title}...done.`
Expand All @@ -250,7 +255,7 @@ export class OLMTasks {
{
title: 'Get operator installation plan',
task: async (ctx: any, task: any) => {
const subscription: Subscription = await kube.getOperatorSubscription(SUBSCRIPTION_NAME, flags.chenamespace)
const subscription: Subscription = await kube.getOperatorSubscription(SUBSCRIPTION_NAME, ctx.operatorNamespace)

if (subscription.status) {
if (subscription.status.state === 'AtLatestKnown') {
Expand Down Expand Up @@ -286,15 +291,15 @@ export class OLMTasks {
title: 'Approve installation',
enabled: (ctx: any) => ctx.installPlanName,
task: async (ctx: any, task: any) => {
await kube.approveOperatorInstallationPlan(ctx.installPlanName, flags.chenamespace)
await kube.approveOperatorInstallationPlan(ctx.installPlanName, ctx.operatorNamespace)
task.title = `${task.title}...done.`
},
},
{
title: 'Wait while newer operator installed',
enabled: (ctx: any) => ctx.installPlanName,
task: async (ctx: any, task: any) => {
await kube.waitUntilOperatorIsInstalled(ctx.installPlanName, flags.chenamespace, 60)
await kube.waitUntilOperatorIsInstalled(ctx.installPlanName, ctx.operatorNamespace, 60)
ctx.highlightedMessages.push(`Operator is updated from ${ctx.currentVersion} to ${ctx.nextVersion} version`)
task.title = `${task.title}...done.`
},
Expand All @@ -313,11 +318,23 @@ export class OLMTasks {
task.title = `${task.title}: ${ctx.isPreInstalledOLM}...OK`
},
},
{
title: `Check if operator is installed in ${DEFAULT_OPENSHIFT_OPERATORS_NS_NAME} namespace`,
tolusha marked this conversation as resolved.
Show resolved Hide resolved
task: async (ctx: any, task: any) => {
if (await kube.operatorSubscriptionExists(SUBSCRIPTION_NAME, DEFAULT_OPENSHIFT_OPERATORS_NS_NAME)) {
ctx.operatorNamespace = DEFAULT_OPENSHIFT_OPERATORS_NS_NAME
task.title = `${task.title}...Found`
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

return or else

} else {
ctx.operatorNamespace = flags.chenamespace || DEFAULT_CHE_NAMESPACE
task.title = `${task.title}...Not Found`
}
},
},
{
title: `Delete(OLM) operator subscription ${SUBSCRIPTION_NAME}`,
enabled: ctx => ctx.isPreInstalledOLM,
task: async (_ctx: any, task: any) => {
await kube.deleteOperatorSubscription(SUBSCRIPTION_NAME, flags.chenamespace)
task: async (ctx: any, task: any) => {
await kube.deleteOperatorSubscription(SUBSCRIPTION_NAME, ctx.operatorNamespace)
task.title = `${task.title}...OK`
},
},
Expand All @@ -334,22 +351,22 @@ export class OLMTasks {
{
title: `Delete(OLM) operator group ${OPERATOR_GROUP_NAME}`,
enabled: ctx => ctx.isPreInstalledOLM,
task: async (_ctx: any, task: any) => {
await kube.deleteOperatorGroup(OPERATOR_GROUP_NAME, flags.chenamespace)
task: async (ctx: any, task: any) => {
await kube.deleteOperatorGroup(OPERATOR_GROUP_NAME, ctx.operatorNamespace)
task.title = `${task.title}...OK`
},
},
{
title: `Delete(OLM) custom catalog source ${CUSTOM_CATALOG_SOURCE_NAME}`,
task: async (_ctx: any, task: any) => {
await kube.deleteCatalogSource(flags.chenamespace, CUSTOM_CATALOG_SOURCE_NAME)
task: async (ctx: any, task: any) => {
await kube.deleteCatalogSource(ctx.operatorNamespace, CUSTOM_CATALOG_SOURCE_NAME)
task.title = `${task.title}...OK`
},
},
{
title: `Delete(OLM) nigthly catalog source ${NIGHTLY_CATALOG_SOURCE_NAME}`,
task: async (_ctx: any, task: any) => {
await kube.deleteCatalogSource(flags.chenamespace, NIGHTLY_CATALOG_SOURCE_NAME)
task: async (ctx: any, task: any) => {
await kube.deleteCatalogSource(ctx.operatorNamespace, NIGHTLY_CATALOG_SOURCE_NAME)
task.title = `${task.title}...OK`
},
},
Expand Down
2 changes: 1 addition & 1 deletion test/e2e/e2e-upgrade.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ const INSTALLER = 'operator'

const UPDATE_CHE_TIMEOUT_MS = 5 * 60 * 1000
const WORKSPACE_START_TIMEOUT_MS = 10 * 60 * 1000
const CHE_VERSION_TIMEOUT_MS = 3 * 60 * 1000
const CHE_VERSION_TIMEOUT_MS = 5 * 60 * 1000

describe('Test Che upgrade', () => {
let cheVersion: string
Expand Down