Skip to content

Commit

Permalink
Use CR from CSV for olm installer.
Browse files Browse the repository at this point in the history
Signed-off-by: Oleksandr Andriienko <oandriie@redhat.com>
  • Loading branch information
AndrienkoAleksandr committed Oct 21, 2020
1 parent f448adc commit 2885d5f
Show file tree
Hide file tree
Showing 11 changed files with 189 additions and 112 deletions.
49 changes: 44 additions & 5 deletions .vscode/tasks.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
"version": "2.0.0",
"tasks": [
{
"label": "Custom che-operator Minikube",
"command": "./bin/run server:deploy -n che -m -p minikube --che-operator-image=${IMAGE_REGISTRY_HOST}/${IMAGE_REGISTRY_USER_NAME}/che-operator:nightly --cheimage=${IMAGE_REGISTRY_HOST}/${IMAGE_REGISTRY_USER_NAME}/che-server:nightly",
"label": "[Minikube] Install Che",
"command": "./bin/run server:deploy -n che -m -p minikube",
"type": "shell",
"args": [],
"problemMatcher": [
Expand All @@ -15,7 +15,20 @@
"group": "build"
},
{
"label": "Custom che-operator and che-server Minikube",
"label": "[Minikube] Install Che with custom che-operator image",
"command": "./bin/run server:deploy -n che -m -p minikube --che-operator-image=${IMAGE_REGISTRY_HOST}/${IMAGE_REGISTRY_USER_NAME}/che-operator:nightly",
"type": "shell",
"args": [],
"problemMatcher": [
"$tsc"
],
"presentation": {
"reveal": "always"
},
"group": "build"
},
{
"label": "[Minikube] Install Che with custom che-operator and che-server images",
"command": "./bin/run server:deploy -n che -m -p minikube --che-operator-image=${IMAGE_REGISTRY_HOST}/${IMAGE_REGISTRY_USER_NAME}/che-operator:nightly --cheimage=${IMAGE_REGISTRY_HOST}/${IMAGE_REGISTRY_USER_NAME}/che-server:nightly",
"type": "shell",
"args": [],
Expand All @@ -28,7 +41,20 @@
"group": "build"
},
{
"label": "Custom che-operator Openshift",
"label": "[Openshift] Install Che",
"command": "./bin/run server:deploy -n che -m -p openshift",
"type": "shell",
"args": [],
"problemMatcher": [
"$tsc"
],
"presentation": {
"reveal": "always"
},
"group": "build"
},
{
"label": "[Openshift] Install Che with custom che-operator image",
"command": "./bin/run server:deploy -n che -m -p openshift -a operator --che-operator-image=${IMAGE_REGISTRY_HOST}/${IMAGE_REGISTRY_USER_NAME}/che-operator:nightly",
"type": "shell",
"args": [],
Expand All @@ -41,7 +67,7 @@
"group": "build"
},
{
"label": "Custom che-operator and che-server Openshift",
"label": "[Openshift] Install Che with custom che-operator and che-server images",
"command": "./bin/run server:deploy -n che -m -p openshift -a operator --che-operator-image=${IMAGE_REGISTRY_HOST}/${IMAGE_REGISTRY_USER_NAME}/che-operator:nightly --cheimage=${IMAGE_REGISTRY_HOST}/${IMAGE_REGISTRY_USER_NAME}/che-server:nightly",
"type": "shell",
"args": [],
Expand Down Expand Up @@ -91,6 +117,19 @@
"reveal": "always"
},
"group": "build"
},
{
"label": "Fix tslint",
"command": "yarn run tslint-fix",
"type": "shell",
"args": [],
"problemMatcher": [
"$tsc"
],
"presentation": {
"reveal": "always"
},
"group": "build"
}
]
}
73 changes: 38 additions & 35 deletions src/api/kube.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import { CHE_CLUSTER_CRD, DEFAULT_CHE_IMAGE, OLM_STABLE_CHANNEL_NAME } from '../
import { getClusterClientCommand, isKubernetesPlatformFamily } from '../util'

import { V1alpha2Certificate } from './typings/cert-manager'
import { CatalogSource, ClusterServiceVersionList, InstallPlan, OperatorGroup, PackageManifest, Subscription } from './typings/olm'
import { CatalogSource, ClusterServiceVersion, ClusterServiceVersionList, InstallPlan, OperatorGroup, PackageManifest, Subscription } from './typings/olm'
import { IdentityProvider, OAuth } from './typings/openshift'

const AWAIT_TIMEOUT_S = 30
Expand Down Expand Up @@ -1261,9 +1261,7 @@ export class KubeHelper {
}
}

async createCheClusterFromFile(filePath: string, flags: any, ctx: any, useDefaultCR: boolean): Promise<any> {
let yamlCr = this.safeLoadFromYamlFile(filePath)

async createCheCluster(cheClusterCR: any, flags: any, ctx: any, useDefaultCR: boolean): Promise<any> {
const cheNamespace = flags.chenamespace
if (useDefaultCR) {
// If we don't use an explicitly provided CheCluster CR,
Expand All @@ -1272,70 +1270,70 @@ export class KubeHelper {
const cheImage = flags.cheimage
if (cheImage) {
const imageAndTag = cheImage.split(':', 2)
yamlCr.spec.server.cheImage = imageAndTag[0]
yamlCr.spec.server.cheImageTag = imageAndTag.length === 2 ? imageAndTag[1] : 'latest'
cheClusterCR.spec.server.cheImage = imageAndTag[0]
cheClusterCR.spec.server.cheImageTag = imageAndTag.length === 2 ? imageAndTag[1] : 'latest'
}

if ((flags.installer === 'olm' && !flags['catalog-source-yaml']) || (flags['catalog-source-yaml'] && flags['olm-channel'] === OLM_STABLE_CHANNEL_NAME)) {
// use default image tag for `olm` to install stable Che, because we don't have nightly channel for OLM catalog.
yamlCr.spec.server.cheImageTag = ''
cheClusterCR.spec.server.cheImageTag = ''
}
yamlCr.spec.server.cheDebug = flags.debug ? flags.debug.toString() : 'false'
cheClusterCR.spec.server.cheDebug = flags.debug ? flags.debug.toString() : 'false'

if (isKubernetesPlatformFamily(flags.platform) || !yamlCr.spec.auth.openShiftoAuth) {
yamlCr.spec.auth.updateAdminPassword = true
if (isKubernetesPlatformFamily(flags.platform) || !cheClusterCR.spec.auth.openShiftoAuth) {
cheClusterCR.spec.auth.updateAdminPassword = true
}

if (!yamlCr.spec.k8s) {
yamlCr.spec.k8s = {}
if (!cheClusterCR.spec.k8s) {
cheClusterCR.spec.k8s = {}
}
if (flags.tls) {
yamlCr.spec.server.tlsSupport = flags.tls
if (!yamlCr.spec.k8s.tlsSecretName) {
yamlCr.spec.k8s.tlsSecretName = 'che-tls'
cheClusterCR.spec.server.tlsSupport = flags.tls
if (!cheClusterCR.spec.k8s.tlsSecretName) {
cheClusterCR.spec.k8s.tlsSecretName = 'che-tls'
}
}
if (flags.domain) {
yamlCr.spec.k8s.ingressDomain = flags.domain
cheClusterCR.spec.k8s.ingressDomain = flags.domain
}
const pluginRegistryUrl = flags['plugin-registry-url']
if (pluginRegistryUrl) {
yamlCr.spec.server.pluginRegistryUrl = pluginRegistryUrl
yamlCr.spec.server.externalPluginRegistry = true
cheClusterCR.spec.server.pluginRegistryUrl = pluginRegistryUrl
cheClusterCR.spec.server.externalPluginRegistry = true
}
const devfileRegistryUrl = flags['devfile-registry-url']
if (devfileRegistryUrl) {
yamlCr.spec.server.devfileRegistryUrl = devfileRegistryUrl
yamlCr.spec.server.externalDevfileRegistry = true
cheClusterCR.spec.server.devfileRegistryUrl = devfileRegistryUrl
cheClusterCR.spec.server.externalDevfileRegistry = true
}

yamlCr.spec.storage.postgresPVCStorageClassName = flags['postgres-pvc-storage-class-name']
yamlCr.spec.storage.workspacePVCStorageClassName = flags['workspace-pvc-storage-class-name']
cheClusterCR.spec.storage.postgresPVCStorageClassName = flags['postgres-pvc-storage-class-name']
cheClusterCR.spec.storage.workspacePVCStorageClassName = flags['workspace-pvc-storage-class-name']

if (flags.cheimage === DEFAULT_CHE_IMAGE &&
yamlCr.spec.server.cheImageTag !== 'nightly' &&
yamlCr.spec.server.cheImageTag !== 'latest') {
cheClusterCR.spec.server.cheImageTag !== 'nightly' &&
cheClusterCR.spec.server.cheImageTag !== 'latest') {
// We obviously are using a release version of chectl with the default `cheimage`
// => We should use the operator defaults for docker images
yamlCr.spec.server.cheImage = ''
yamlCr.spec.server.cheImageTag = ''
yamlCr.spec.server.pluginRegistryImage = ''
yamlCr.spec.server.devfileRegistryImage = ''
yamlCr.spec.auth.identityProviderImage = ''
cheClusterCR.spec.server.cheImage = ''
cheClusterCR.spec.server.cheImageTag = ''
cheClusterCR.spec.server.pluginRegistryImage = ''
cheClusterCR.spec.server.devfileRegistryImage = ''
cheClusterCR.spec.auth.identityProviderImage = ''
}
}

// override default values
if (ctx.CRPatch) {
merge(yamlCr, ctx.CRPatch)
merge(cheClusterCR, ctx.CRPatch)
}

// Back off some configuration properties(chectl estimated them like not working or not desired)
merge(yamlCr, ctx.CROverrides)
merge(cheClusterCR, ctx.CROverrides)

const customObjectsApi = KubeHelper.KUBE_CONFIG.makeApiClient(CustomObjectsApi)
try {
const { body } = await customObjectsApi.createNamespacedCustomObject('org.eclipse.che', 'v1', cheNamespace, 'checlusters', yamlCr)
const { body } = await customObjectsApi.createNamespacedCustomObject('org.eclipse.che', 'v1', cheNamespace, 'checlusters', cheClusterCR)
return body
} catch (e) {
throw this.wrapK8sClientError(e)
Expand Down Expand Up @@ -1551,7 +1549,7 @@ export class KubeHelper {
async createCatalogSource(catalogSource: CatalogSource) {
const customObjectsApi = KubeHelper.KUBE_CONFIG.makeApiClient(CustomObjectsApi)
try {
const namespace = catalogSource.metadata.namespace
const namespace = catalogSource.metadata.namespace!
const { body } = await customObjectsApi.createNamespacedCustomObject('operators.coreos.com', 'v1alpha1', namespace, 'catalogsources', catalogSource)
return body
} catch (e) {
Expand Down Expand Up @@ -1633,7 +1631,7 @@ export class KubeHelper {
async createOperatorSubscription(subscription: Subscription) {
const customObjectsApi = KubeHelper.KUBE_CONFIG.makeApiClient(CustomObjectsApi)
try {
const { body } = await customObjectsApi.createNamespacedCustomObject('operators.coreos.com', 'v1alpha1', subscription.metadata.namespace, 'subscriptions', subscription)
const { body } = await customObjectsApi.createNamespacedCustomObject('operators.coreos.com', 'v1alpha1', subscription.metadata.namespace!, 'subscriptions', subscription)
return body
} catch (e) {
throw this.wrapK8sClientError(e)
Expand Down Expand Up @@ -1721,7 +1719,7 @@ export class KubeHelper {
if (installPlan.status && installPlan.status.conditions) {
for (const condition of installPlan.status.conditions) {
if (condition.type === 'Installed' && condition.status === 'True') {
resolve()
resolve(installPlan)
}
}
}
Expand All @@ -1739,6 +1737,11 @@ export class KubeHelper {
})
}

async getCSV(csvName: string, namespace: string): Promise<ClusterServiceVersion | undefined> {
const csvs = await this.getClusterServiceVersions(namespace)
return csvs.items.find(item => item.metadata.name === csvName)
}

async getClusterServiceVersions(namespace: string): Promise<ClusterServiceVersionList> {
const customObjectsApi = KubeHelper.KUBE_CONFIG.makeApiClient(CustomObjectsApi)
try {
Expand Down
5 changes: 4 additions & 1 deletion src/api/typings/olm.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
* SPDX-License-Identifier: EPL-2.0
**********************************************************************/

import { V1ObjectMeta } from '@kubernetes/client-node';

export interface OperatorGroup {
apiVersion: string;
kind: string;
Expand Down Expand Up @@ -41,6 +43,7 @@ export interface SubscriptionSpec {
export interface SubscriptionStatus {
conditions: SubscriptionStatusCondition[]
currentCSV: string
installedCSV?: string
installplan: InstallPlan
state: string
}
Expand Down Expand Up @@ -98,7 +101,7 @@ export interface CatalogSourceSpec {
mediatype?: string
sourceType: string
image: string
updateStrategy: CatalogSourceUpdateStrategy
updateStrategy?: CatalogSourceUpdateStrategy
}

export interface CatalogSourceUpdateStrategy {
Expand Down
34 changes: 13 additions & 21 deletions src/commands/server/deploy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,13 @@ import { Command, flags } from '@oclif/command'
import { boolean, string } from '@oclif/parser/lib/flags'
import { cli } from 'cli-ux'
import * as fs from 'fs-extra'
import * as yaml from 'js-yaml'
import * as Listr from 'listr'
import * as notifier from 'node-notifier'
import * as os from 'os'
import * as path from 'path'

import { KubeHelper } from '../../api/kube'
import { cheDeployment, cheNamespace, cheOperatorCRPatchYaml, CHE_OPERATOR_CR_PATCH_YAML_KEY, devWorkspaceControllerNamespace, listrRenderer, skipKubeHealthzCheck as skipK8sHealthCheck } from '../../common-flags'
import { cheDeployment, cheNamespace, cheOperatorCRPatchYaml, cheOperatorCRYaml, CHE_OPERATOR_CR_PATCH_YAML_KEY, CHE_OPERATOR_CR_YAML_KEY, devWorkspaceControllerNamespace, listrRenderer, skipKubeHealthzCheck as skipK8sHealthCheck } from '../../common-flags'
import { DEFAULT_CHE_OPERATOR_IMAGE, DEFAULT_DEV_WORKSPACE_CONTROLLER_IMAGE, DOCS_LINK_INSTALL_RUNNING_CHE_LOCALLY } from '../../constants'
import { CheTasks } from '../../tasks/che'
import { DevWorkspaceTasks } from '../../tasks/component-installers/devfile-workspace-operator-installer'
Expand All @@ -28,7 +27,7 @@ import { InstallerTasks } from '../../tasks/installers/installer'
import { ApiTasks } from '../../tasks/platforms/api'
import { CommonPlatformTasks } from '../../tasks/platforms/common-platform-tasks'
import { PlatformTasks } from '../../tasks/platforms/platform'
import { getCommandSuccessMessage, initializeContext, isOpenshiftPlatformFamily, readCRPatchFile } from '../../util'
import { getCommandSuccessMessage, initializeContext, isOpenshiftPlatformFamily, readCRFile } from '../../util'

export default class Deploy extends Command {
static description = 'start Eclipse Che server'
Expand Down Expand Up @@ -118,10 +117,7 @@ export default class Deploy extends Command {
description: 'Container image of the operator. This parameter is used only when the installer is the operator',
default: DEFAULT_CHE_OPERATOR_IMAGE
}),
'che-operator-cr-yaml': string({
description: 'Path to a yaml file that defines a CheCluster used by the operator. This parameter is used only when the installer is the \'operator\' or the \'olm\'.',
default: ''
}),
[CHE_OPERATOR_CR_YAML_KEY]: cheOperatorCRYaml,
[CHE_OPERATOR_CR_PATCH_YAML_KEY]: cheOperatorCRPatchYaml,
directory: string({
char: 'd',
Expand Down Expand Up @@ -200,7 +196,7 @@ export default class Deploy extends Command {
}

async setPlaformDefaults(flags: any, ctx: any): Promise<void> {
flags.tls = await this.checkTlsMode(flags, ctx)
flags.tls = await this.checkTlsMode(ctx)

if (!flags.installer) {
await this.setDefaultInstaller(flags)
Expand Down Expand Up @@ -243,27 +239,22 @@ export default class Deploy extends Command {
* Checks if TLS is disabled via operator custom resource.
* Returns true if TLS is enabled (or omitted) and false if it is explicitly disabled.
*/
async checkTlsMode(flags: any, ctx: any): Promise<boolean> {
async checkTlsMode(ctx: any): Promise<boolean> {
const crPatch = ctx.CRPatch
if (crPatch && crPatch.spec && crPatch.spec.server && crPatch.spec.server.tlsSupport === false) {
return false
}

if (flags['che-operator-cr-yaml']) {
const cheOperatorCrYamlPath = flags['che-operator-cr-yaml']
if (fs.existsSync(cheOperatorCrYamlPath)) {
const cr: any = yaml.safeLoad(fs.readFileSync(cheOperatorCrYamlPath).toString())
if (cr && cr.spec && cr.spec.server && cr.spec.server.tlsSupport === false) {
return false
}
}
const customCR = ctx.CustomCR
if (customCR && customCR.spec && customCR.spec.server && customCR.spec.server.tlsSupport === false) {
return false
}

return true
}

checkPlatformCompatibility(flags: any) {
if (flags.installer === 'operator' && flags['che-operator-cr-yaml']) {
if (flags.installer === 'operator' && flags[CHE_OPERATOR_CR_YAML_KEY]) {
const ignoredFlags = []
flags['plugin-registry-url'] && ignoredFlags.push('--plugin-registry-url')
flags['devfile-registry-url'] && ignoredFlags.push('--devfile-registry-url')
Expand All @@ -276,11 +267,11 @@ export default class Deploy extends Command {
flags.multiuser && ignoredFlags.push('--multiuser')

if (ignoredFlags.length) {
this.warn(`--che-operator-cr-yaml is used. The following flag(s) will be ignored: ${ignoredFlags.join('\t')}`)
this.warn(`--${CHE_OPERATOR_CR_YAML_KEY} is used. The following flag(s) will be ignored: ${ignoredFlags.join('\t')}`)
}
}

if (flags.domain && !flags['che-operator-cr-yaml'] && isOpenshiftPlatformFamily(flags.platform)) {
if (flags.domain && !flags[CHE_OPERATOR_CR_YAML_KEY] && isOpenshiftPlatformFamily(flags.platform)) {
this.warn('"--domain" flag is ignored for Openshift family infrastructures. It should be done on the cluster level.')
}

Expand Down Expand Up @@ -343,7 +334,8 @@ export default class Deploy extends Command {
ctx.directory = path.resolve(flags.directory ? flags.directory : path.resolve(os.tmpdir(), 'chectl-logs', Date.now().toString()))
const listrOptions: Listr.ListrOptions = { renderer: (flags['listr-renderer'] as any), collapse: false, showSubtasks: true } as Listr.ListrOptions
ctx.listrOptions = listrOptions
ctx.CRPatch = readCRPatchFile(flags, this)
ctx.CustomCR = readCRFile(flags, CHE_OPERATOR_CR_YAML_KEY , this)
ctx.CRPatch = readCRFile(flags, CHE_OPERATOR_CR_PATCH_YAML_KEY, this)

if (flags['self-signed-cert']) {
this.warn('"self-signed-cert" flag is deprecated and has no effect. Autodetection is used instead.')
Expand Down
4 changes: 2 additions & 2 deletions src/commands/server/update.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import { InstallerTasks } from '../../tasks/installers/installer'
import { ApiTasks } from '../../tasks/platforms/api'
import { CommonPlatformTasks } from '../../tasks/platforms/common-platform-tasks'
import { PlatformTasks } from '../../tasks/platforms/platform'
import { getCommandSuccessMessage, getImageTag, initializeContext, isKubernetesPlatformFamily, readCRPatchFile } from '../../util'
import { getCommandSuccessMessage, getImageTag, initializeContext, isKubernetesPlatformFamily, readCRFile } from '../../util'

export default class Update extends Command {
static description = 'Update Eclipse Che server.'
Expand Down Expand Up @@ -96,7 +96,7 @@ export default class Update extends Command {
const ctx = initializeContext()
const listrOptions: Listr.ListrOptions = { renderer: (flags['listr-renderer'] as any), collapse: false } as Listr.ListrOptions
ctx.listrOptions = listrOptions
ctx.CRPatch = readCRPatchFile(flags, this)
ctx.CRPatch = readCRFile(flags, CHE_OPERATOR_CR_PATCH_YAML_KEY, this)

const cheTasks = new CheTasks(flags)
const kubeHelper = new KubeHelper(flags)
Expand Down
Loading

0 comments on commit 2885d5f

Please sign in to comment.