Skip to content

Commit

Permalink
Deploy private docker registry and copy required images
Browse files Browse the repository at this point in the history
Signed-off-by: Anatoliy Bazko <[email protected]>
  • Loading branch information
tolusha committed Apr 15, 2020
1 parent fec449a commit 9797597
Show file tree
Hide file tree
Showing 10 changed files with 363 additions and 54 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ bin/chectl-*
tsconfig.tsbuildinfo
# k8s templates are added at post-install step
templates/kubernetes
templates/docker-registry
templates/che-operator
templates/minishift-addon
templates/cert-manager
16 changes: 14 additions & 2 deletions make-release.sh
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,20 @@ release() {
echo "$RELEASE" > VERSION

# replace nightly versions by release version
apply_sed "s#quay.io/eclipse/che-server:nightly#quay.io/eclipse/che-server:${RELEASE}#g" src/constants.ts
apply_sed "s#quay.io/eclipse/che-operator:nightly#quay.io/eclipse/che-operator:${RELEASE}#g" src/constants.ts
wget https://raw.githubusercontent.com/eclipse/che/${RELEASE}/assembly/assembly-wsmaster-war/src/main/webapp/WEB-INF/classes/che/che.properties -q -O /tmp/che.properties
PLUGIN_BROKER_METADATA_IMAGE_RELEASE=$(cat /tmp/che.properties| grep "che.workspace.plugin_broker.metadata.image" | cut -d = -f2)
PLUGIN_BROKER_ARTIFACTS_IMAGE_RELEASE=$(cat /tmp/che.properties | grep "che.workspace.plugin_broker.artifacts.image" | cut -d = -f2)
JWT_PROXY_IMAGE_RELEASE=$(cat /tmp/che.properties | grep "che.server.secure_exposer.jwtproxy.image" | cut -d = -f2)
rm /tmp/che.properties

apply_sed "s#quay.io/eclipse/che-server:.*#quay.io/eclipse/che-server:${RELEASE}#g" src/constants.ts
apply_sed "s#quay.io/eclipse/che-operator:.*#quay.io/eclipse/che-operator:${RELEASE}#g" src/constants.ts
apply_sed "s#quay.io/eclipse/che-keycloak:.*#quay.io/eclipse/che-keycloak:${RELEASE}#g" src/constants.ts
apply_sed "s#quay.io/eclipse/che-devfile-registry:.*#quay.io/eclipse/che-devfile-registry:${RELEASE}#g" src/constants.ts
apply_sed "s#quay.io/eclipse/che-plugin-registry:.*#quay.io/eclipse/che-plugin-registry:${RELEASE}#g" src/constants.ts
apply_sed "s#quay.io/eclipse/che-jwtproxy:.*#${JWT_PROXY_IMAGE_RELEASE}#g" src/constants.ts
apply_sed "s#quay.io/eclipse/che-plugin-metadata-broker:.*#${PLUGIN_BROKER_METADATA_IMAGE_RELEASE}#g" src/constants.ts
apply_sed "s#quay.io/eclipse/che-plugin-artifacts-broker:.*#${PLUGIN_BROKER_ARTIFACTS_IMAGE_RELEASE}#g" src/constants.ts

# now replace package.json dependencies
apply_sed "s;github.com/eclipse/che#\(.*\)\",;github.com/eclipse/che#${RELEASE}\",;g" package.json
Expand Down
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
"cli-ux": "^5.4.5",
"command-exists": "^1.2.8",
"debug": "^4.1.1",
"eclipse-che": "git://github.com/eclipse/che#master",
"eclipse-che": "git://github.com/eclipse/che#ab/offline",
"eclipse-che-minishift": "git://github.com/minishift/minishift#master",
"eclipse-che-operator": "git://github.com/eclipse/che-operator#master",
"esprima": "^4.0.1",
Expand Down Expand Up @@ -115,9 +115,10 @@
},
"repository": "che-incubator/chectl",
"scripts": {
"postinstall": "npm run -s postinstall-repositories && npm run -s postinstall-helm && npm run -s postinstall-cert-manager && npm run -s postinstall-operator && npm run -s postinstall-minishift-addon && npm run -s postinstall-cleanup",
"postinstall": "npm run -s postinstall-repositories && npm run -s postinstall-helm && npm run -s postinstall-cert-manager && npm run -s postinstall-docker-registry && npm run -s postinstall-operator && npm run -s postinstall-minishift-addon && npm run -s postinstall-cleanup",
"postinstall-helm": "rimraf templates/kubernetes && cpx 'node_modules/eclipse-che/deploy/kubernetes/**' 'templates/kubernetes'",
"postinstall-cert-manager": "rimraf templates/cert-manager && cpx 'node_modules/eclipse-che/deploy/cert-manager/**' 'templates/cert-manager'",
"postinstall-docker-registry": "rimraf templates/docker-registry && cpx 'node_modules/eclipse-che/deploy/docker-registry/**' 'templates/docker-registry'",
"postinstall-minishift-addon": "rimraf templates/minishift-addon && cpx 'node_modules/eclipse-che-minishift/addons/che/**' 'templates/minishift-addon/che'",
"postinstall-operator": "rimraf templates/che-operator && cpx 'node_modules/eclipse-che-operator/deploy/**' 'templates/che-operator'",
"postinstall-repositories": "yarn upgrade eclipse-che eclipse-che-operator eclipse-che-minishift",
Expand Down
104 changes: 63 additions & 41 deletions src/api/kube.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
* SPDX-License-Identifier: EPL-2.0
**********************************************************************/

import { ApiextensionsV1beta1Api, ApisApi, AppsV1Api, BatchV1Api, CoreV1Api, CustomObjectsApi, ExtensionsV1beta1Api, KubeConfig, Log, PortForward, RbacAuthorizationV1Api, V1beta1CustomResourceDefinition, V1beta1IngressList, V1ClusterRole, V1ClusterRoleBinding, V1ConfigMap, V1ConfigMapEnvSource, V1Container, V1DeleteOptions, V1Deployment, V1DeploymentList, V1DeploymentSpec, V1EnvFromSource, V1Job, V1JobSpec, V1LabelSelector, V1NamespaceList, V1ObjectMeta, V1PersistentVolumeClaimList, V1Pod, V1PodList, V1PodSpec, V1PodTemplateSpec, V1Role, V1RoleBinding, V1RoleRef, V1Secret, V1ServiceAccount, V1ServiceList, V1Subject, Watch } from '@kubernetes/client-node'
import { ApiextensionsV1beta1Api, ApisApi, AppsV1Api, BatchV1Api, CoreV1Api, CustomObjectsApi, ExtensionsV1beta1Api, KubeConfig, Log, PortForward, RbacAuthorizationV1Api, V1beta1CustomResourceDefinition, V1beta1IngressList, V1ClusterRole, V1ClusterRoleBinding, V1ConfigMap, V1ConfigMapEnvSource, V1Container, V1DeleteOptions, V1Deployment, V1DeploymentList, V1DeploymentSpec, V1EnvFromSource, V1Job, V1JobSpec, V1LabelSelector, V1NamespaceList, V1ObjectMeta, V1PersistentVolumeClaimList, V1Pod, V1PodList, V1PodSpec, V1PodTemplateSpec, V1Role, V1RoleBinding, V1RoleRef, V1Secret, V1ServiceAccount, V1ServiceList, V1Subject, Watch, V1Service, V1beta1Ingress } from '@kubernetes/client-node'
import { Cluster, Context } from '@kubernetes/client-node/dist/config_types'
import axios, { AxiosRequestConfig } from 'axios'
import { cli } from 'cli-ux'
Expand Down Expand Up @@ -69,11 +69,21 @@ export class KubeHelper {
}
}

async applyResource(yamlPath: string, opts = ''): Promise<void> {
const command = `kubectl apply -f ${yamlPath} ${opts}`
async applyResource(yamlPath: string, opts = '', namespace?: string): Promise<void> {
const command = `kubectl apply -f ${yamlPath} ${opts} ${namespace ? ' -n ' + namespace : ''}`
await execa(command, { timeout: 30000, shell: true })
}

async createService(namespace: string, service: any): Promise<V1Service> {
const k8sCoreApi = this.kc.makeApiClient(CoreV1Api)
try {
const { body } = await k8sCoreApi.createNamespacedService(namespace, service)
return body
} catch (e) {
throw this.wrapK8sClientError(e)
}
}

async getServicesBySelector(labelSelector = '', namespace = ''): Promise<V1ServiceList> {
const k8sCoreApi = this.kc.makeApiClient(CoreV1Api)
try {
Expand Down Expand Up @@ -457,17 +467,17 @@ export class KubeHelper {
}
}

async createConfigMapFromFile(filePath: string, namespace = '') {
const yamlConfigMap = this.safeLoadFromYamlFile(filePath) as V1ConfigMap
async createConfigMap(namespace: string, confiMap: any): Promise<V1ConfigMap> {
const k8sCoreApi = this.kc.makeApiClient(CoreV1Api)
try {
return await k8sCoreApi.createNamespacedConfigMap(namespace, yamlConfigMap)
const { body } = await k8sCoreApi.createNamespacedConfigMap(namespace, confiMap)
return body
} catch (e) {
throw this.wrapK8sClientError(e)
}
}

async patchConfigMap(name: string, patch: any, namespace = '') {
async patchConfigMap(namespace: string, name: string, patch: any) {
const k8sCoreApi = this.kc.makeApiClient(PatchedK8sApi)
try {
return await k8sCoreApi.patchNamespacedConfigMap(name, namespace, patch)
Expand Down Expand Up @@ -554,7 +564,7 @@ export class KubeHelper {
return res.body.items[0].status.phase
}

async getPodReadyConditionStatus(selector: string, namespace = ''): Promise<string> {
async getPodReadyConditionStatus(selector: string, namespace = ''): Promise<string | undefined> {
const k8sCoreApi = this.kc.makeApiClient(CoreV1Api)
let res
try {
Expand All @@ -577,11 +587,11 @@ export class KubeHelper {
}

if (!res.body.items[0].status) {
throw new Error(`Get pods by selector "${selector}" returned a pod with an invalid state`)
return
}

if (!res.body.items[0].status.conditions || !(res.body.items[0].status.conditions.length > 0)) {
throw new Error(`Get pods by selector "${selector}" returned a pod with an invalid status.conditions`)
return
}

const conditions = res.body.items[0].status.conditions
Expand All @@ -590,8 +600,6 @@ export class KubeHelper {
return condition.status
}
}

throw new Error(`Get pods by selector "${selector}" returned a pod without a status.condition of type "Ready"`)
}

async waitForPodPhase(selector: string, targetPhase: string, namespace = '', intervalMs = 500, timeoutMs = this.podWaitTimeout) {
Expand Down Expand Up @@ -632,9 +640,6 @@ export class KubeHelper {
if (readyStatus === 'True') {
return
}
if (readyStatus !== 'False') {
throw new Error(`ERR_BAD_READY_STATUS: ${readyStatus} (True or False expected) `)
}
await cli.wait(intervalMs)
}
throw new Error(`ERR_TIMEOUT: Timeout set to pod ready timeout ${this.podReadyTimeout}`)
Expand All @@ -647,9 +652,6 @@ export class KubeHelper {
if (readyStatus === 'False') {
return
}
if (readyStatus !== 'True') {
throw new Error(`ERR_BAD_READY_STATUS: ${readyStatus} (True or False expected) `)
}
await cli.wait(intervalMs)
}
throw new Error(`ERR_TIMEOUT: Timeout set to pod ready timeout ${this.podReadyTimeout}`)
Expand Down Expand Up @@ -786,11 +788,11 @@ export class KubeHelper {
}

async createDeployment(name: string,
image: string,
serviceAccount: string,
pullPolicy: string,
configMapEnvSource: string,
namespace: string) {
image: string,
serviceAccount: string,
pullPolicy: string,
configMapEnvSource: string,
namespace: string) {
const k8sAppsApi = this.kc.makeApiClient(AppsV1Api)
let deployment = new V1Deployment()
deployment.metadata = new V1ObjectMeta()
Expand Down Expand Up @@ -877,6 +879,15 @@ export class KubeHelper {
}
}

async deleteAllJobs(namespace: string) {
const k8sBatchApi = this.kc.makeApiClient(BatchV1Api)
try {
await k8sBatchApi.deleteCollectionNamespacedJob(namespace)
} catch (e) {
throw this.wrapK8sClientError(e)
}
}

async getDeploymentsBySelector(labelSelector = '', namespace = ''): Promise<V1DeploymentList> {
const k8sAppsApi = this.kc.makeApiClient(AppsV1Api)
try {
Expand Down Expand Up @@ -906,13 +917,7 @@ export class KubeHelper {
throw new Error('ERR_GET_DEPLOYMENT')
}

async createPod(name: string,
image: string,
serviceAccount: string,
restartPolicy: string,
pullPolicy: string,
configMapEnvSource: string,
namespace: string) {
async createPod(name: string, image: string, serviceAccount: string, restartPolicy: string, pullPolicy: string, configMapEnvSource: string, namespace: string) {
const k8sCoreApi = this.kc.makeApiClient(CoreV1Api)
let pod = new V1Pod()
pod.metadata = new V1ObjectMeta()
Expand All @@ -939,19 +944,11 @@ export class KubeHelper {
}
}

async createJob(name: string,
image: string,
serviceAccount: string,
namespace: string,
backoffLimit = 0,
restartPolicy = 'Never') {
const k8sBatchApi = this.kc.makeApiClient(BatchV1Api)

createJobSpec(name: string, image: string, serviceAccount: string, backoffLimit = 0, restartPolicy = 'Never'): any {
const job = new V1Job()
job.metadata = new V1ObjectMeta()
job.metadata.name = name
job.metadata.labels = { app: name }
job.metadata.namespace = namespace
job.spec = new V1JobSpec()
job.spec.ttlSecondsAfterFinished = 10
job.spec.backoffLimit = backoffLimit
Expand All @@ -963,9 +960,14 @@ export class KubeHelper {
jobContainer.image = image
job.spec.template.spec.restartPolicy = restartPolicy
job.spec.template.spec.containers = [jobContainer]
return job
}

async createJob(namespace: string, job: any): Promise<V1Job> {
const k8sBatchApi = this.kc.makeApiClient(BatchV1Api)
try {
return await k8sBatchApi.createNamespacedJob(namespace, job)
const { body } = await k8sBatchApi.createNamespacedJob(namespace, job)
return body
} catch (e) {
throw this.wrapK8sClientError(e)
}
Expand Down Expand Up @@ -1015,7 +1017,7 @@ export class KubeHelper {
// Automatically stop watching after timeout
const timeoutHandler = setTimeout(() => {
request.abort()
reject(`Timeout reached while waiting for "${jobName}" job.`)
reject(new Error(`Timeout reached while waiting for "${jobName}" job.`))
}, timeout * 1000)

// Request job, for case if it is already ready
Expand Down Expand Up @@ -1060,6 +1062,16 @@ export class KubeHelper {
}
}

async createIngress(namespace: string, ingress: any): Promise<V1beta1Ingress> {
const k8sExtensionsApi = this.kc.makeApiClient(ExtensionsV1beta1Api)
try {
const { body } = await k8sExtensionsApi.createNamespacedIngress(namespace, ingress)
return body
} catch (e) {
throw this.wrapK8sClientError(e)
}
}

async deleteAllIngresses(namespace = '') {
const k8sExtensionsApi = this.kc.makeApiClient(ExtensionsV1beta1Api)
try {
Expand Down Expand Up @@ -1528,6 +1540,16 @@ export class KubeHelper {
}
}

async createPersistentVolumeClaim(namespace: string, pvc: any) {
const k8sCoreApi = this.kc.makeApiClient(CoreV1Api)
try {
const { body } = await k8sCoreApi.createNamespacedPersistentVolumeClaim(namespace, pvc)
return body
} catch (e) {
throw this.wrapK8sClientError(e)
}
}

async deletePersistentVolumeClaim(name = '', namespace = '') {
const k8sCoreApi = this.kc.makeApiClient(CoreV1Api)
try {
Expand Down
29 changes: 26 additions & 3 deletions src/commands/server/start.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import * as path from 'path'
import { cheDeployment, cheNamespace, listrRenderer } from '../../common-flags'
import { DEFAULT_CHE_IMAGE, DEFAULT_CHE_OPERATOR_IMAGE } from '../../constants'
import { CheTasks } from '../../tasks/che'
import { DockerRegistryTasks } from '../../tasks/component-installers/docker-registry'
import { InstallerTasks } from '../../tasks/installers/installer'
import { ApiTasks } from '../../tasks/platforms/api'
import { PlatformTasks } from '../../tasks/platforms/platform'
Expand Down Expand Up @@ -149,7 +150,13 @@ export default class Start extends Command {
}),
'skip-cluster-availability-check': flags.boolean({
description: 'Skip cluster availability check. The check is a simple request to ensure the cluster is reachable.',
}),
offline: flags.boolean({
description: 'Deploy Eclipse Che and configure it to work offline',
default: false
}),
'offline-stacks': flags.string({
description: 'Comma separated stacks names to work in offline mode.',
})
}

Expand Down Expand Up @@ -214,7 +221,9 @@ export default class Start extends Command {
flags['self-signed-cert'] && ignoredFlags.push('--self-signed-cert')
flags['os-oauth'] && ignoredFlags.push('--os-oauth')
flags.tls && ignoredFlags.push('--tls')
flags.cheimage && ignoredFlags.push('--cheimage')

// don't print warning if default value is used
flags.cheimage && flags.cheimage !== DEFAULT_CHE_IMAGE && ignoredFlags.push('--cheimage')
flags.debug && ignoredFlags.push('--debug')
flags.domain && ignoredFlags.push('--domain')
flags.multiuser && ignoredFlags.push('--multiuser')
Expand Down Expand Up @@ -247,6 +256,15 @@ export default class Start extends Command {
}
}
}

if (flags.offline) {
if (flags.installer !== 'operator') {
this.error('--offline flag can be used only if installer is operator.')
}
if (!flags['offline-stacks']) {
this.error('--offline-stacks flag is required.\nSee more help with --help.')
}
}
}

async run() {
Expand Down Expand Up @@ -275,7 +293,7 @@ export default class Start extends Command {
})

this.setPlaformDefaults(flags)
let installTasks = new Listr(installerTasks.installTasks(flags, this), listrOptions)
// let installTasks = new Listr(installerTasks.installTasks(flags, this), listrOptions)

const startDeployedCheTasks = new Listr([{
title: '👀 Starting already deployed Eclipse Che',
Expand Down Expand Up @@ -323,6 +341,11 @@ export default class Start extends Command {
this.log(`Eclipse Che logs will be available in '${ctx.directory}'`)
await logsTasks.run(ctx)
await eventTasks.run(ctx)

// should be initialized after platform tasks
const dockerRegistryTasks = new DockerRegistryTasks(flags)
let installTasks = new Listr(dockerRegistryTasks.getStartTasks(), listrOptions)

await installTasks.run(ctx)
} else if (!ctx.isCheReady
|| (ctx.isPostgresDeployed && !ctx.isPostgresReady)
Expand All @@ -336,7 +359,7 @@ export default class Start extends Command {
await startDeployedCheTasks.run(ctx)
}

await postInstallTasks.run(ctx)
// await postInstallTasks.run(ctx)
this.log('Command server:start has completed successfully.')
} catch (err) {
this.error(`${err}\nInstallation failed, check logs in '${ctx.directory}'`)
Expand Down
7 changes: 7 additions & 0 deletions src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,13 @@

export const DEFAULT_CHE_IMAGE = 'quay.io/eclipse/che-server:nightly'
export const DEFAULT_CHE_OPERATOR_IMAGE = 'quay.io/eclipse/che-operator:nightly'
export const DEFAULT_CHE_DEVFILE_REGISTRY_IMAGE = 'quay.io/eclipse/che-devfile-registry:nightly'
export const DEFAULT_CHE_PLUGIN_REGISTRY_IMAGE = 'quay.io/eclipse/che-plugin-registry:nightly'
export const DEFAULT_CHE_KEYCLOAK_IMAGE = 'quay.io/eclipse/che-keycloak:nightly'
export const DEFAULT_CHE_POSTGRES_IMAGE = 'centos/postgresql-96-centos7:9.6'
export const DEFAULT_CHE_JWTPROXY_IMAGE = 'quay.io/eclipse/che-jwtproxy:fd94e60'
export const DEFAULT_CHE_PLUGIN_METADATA_BROKER_IMAGE = 'quay.io/eclipse/che-plugin-metadata-broker:v3.1.2'
export const DEFAULT_CHE_PLUGIN_ARTIFACTS_BROKER_IMAGE = 'quay.io/eclipse/che-plugin-artifacts-broker:v3.1.2'

// This image should be updated manually when needed.
// Repository location: https://github.com/che-dockerfiles/che-cert-manager-ca-cert-generator-image
Expand Down
Loading

0 comments on commit 9797597

Please sign in to comment.