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 1 commit
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'
69 changes: 44 additions & 25 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_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: () => flags['olm-channel'] !== STABLE_ALL_NAMESPACES_CHANNEL_NAME,
Copy link
Collaborator

@tolusha tolusha Aug 2, 2021

Choose a reason for hiding this comment

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

check operator namespace (adjust comment as well)

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,22 +179,22 @@ 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.`
},
},
{
title: 'Set custom operator image',
enabled: () => flags['che-operator-image'],
task: async (_ctx: any, task: any) => {
const csvList = await kube.getClusterServiceVersions(flags.chenamespace)
const csvList = await kube.getClusterServiceVersions(flags.chenamespaces)
Copy link
Collaborator

Choose a reason for hiding this comment

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

Typo ?

if (csvList.items.length < 1) {
throw new Error('Failed to get CSV for Che operator')
}
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,25 @@ 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

}
ctx.operatorNamespace = flags.chenamespace
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
ctx.operatorNamespace = flags.chenamespace
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) => {
const checlusters = await kube.getAllCheClusters()
if (kube.operatorSubscriptionExists(SUBSCRIPTION_NAME, DEFAULT_OPENSHIFT_OPERATORS_NS_NAME) && checlusters.length === 0) {
Copy link
Contributor

Choose a reason for hiding this comment

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

kube.operatorSubscriptionExists(SUBSCRIPTION_NAME, DEFAULT_OPENSHIFT_OPERATORS_NS_NAME) && checlusters.length === 0

Maybe this check should be moved to the separated method, cause it was used not once?

Copy link
Collaborator

Choose a reason for hiding this comment

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

pls revert

await kube.deleteOperatorSubscription(SUBSCRIPTION_NAME, ctx.operatorNamespace)
Copy link
Contributor

@AndrienkoAleksandr AndrienkoAleksandr Aug 2, 2021

Choose a reason for hiding this comment

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

Sorry, but you completely removed case with delete operator subscription for one specific namespace. And the same for Delete(OLM) Eclipse Che cluster service versions

}
task.title = `${task.title}...OK`
},
},
Expand All @@ -334,22 +353,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