From 202b3e25b242e3ffa00f1294c0c895dd3a4d0036 Mon Sep 17 00:00:00 2001 From: Tom George Date: Fri, 11 Oct 2019 11:19:38 -0500 Subject: [PATCH] Add airgap mode (#91) * Determine if we are in airgap mode and patch the images appropriately * Do the rest of the images in the che deployment * Add map of extra images for airgap * Add a script to generate extra_images.go, only add the extra images data to che configmap if we are in airgap mode * Download the release version of che.properties * Remove unnecessary properties * Remove airGapMode boolean, make it so that setting either the airGapHostname/Organization will start the deployment in airgap mode Signed-off-by: Tom George --- pkg/apis/org/v1/che_types.go | 9 +++ pkg/controller/che/che_controller.go | 11 +-- pkg/deploy/che_configmap.go | 15 ++++ pkg/deploy/defaults.go | 110 +++++++++++++++++++++------ pkg/deploy/defaults_test.go | 108 ++++++++++++++++++++++++++ pkg/deploy/deployment_keycloak.go | 8 +- pkg/deploy/deployment_postgres.go | 8 +- pkg/deploy/extra_images.go | 8 ++ release-operator-code.sh | 19 +++++ 9 files changed, 260 insertions(+), 36 deletions(-) create mode 100644 pkg/deploy/defaults_test.go create mode 100644 pkg/deploy/extra_images.go diff --git a/pkg/apis/org/v1/che_types.go b/pkg/apis/org/v1/che_types.go index cc7b8cd6a..21aebda21 100644 --- a/pkg/apis/org/v1/che_types.go +++ b/pkg/apis/org/v1/che_types.go @@ -31,6 +31,10 @@ type CheClusterSpec struct { } type CheClusterSpecServer struct { + // AirGapContainerRegistryHostname is the hostname to the internal registry to pull images from in the air-gapped environment + AirGapContainerRegistryHostname string `json:"airGapContainerRegistryHostname"` + // AirGapContainerRegistryOrganization is the repository name in the registry to pull images from in the air-gapped environment + AirGapContainerRegistryOrganization string `json:"airGapContainerRegistryOrganization"` // CheImage is a server image used in Che deployment CheImage string `json:"cheImage"` // CheImageTag is a tag of an image used in Che deployment @@ -246,3 +250,8 @@ type CheClusterList struct { func init() { SchemeBuilder.Register(&CheCluster{}, &CheClusterList{}) } + +func (c *CheCluster) IsAirGapMode() bool { + return c.Spec.Server.AirGapContainerRegistryHostname != "" || + c.Spec.Server.AirGapContainerRegistryOrganization != "" +} diff --git a/pkg/controller/che/che_controller.go b/pkg/controller/che/che_controller.go index fb389dedc..fcc93094e 100644 --- a/pkg/controller/che/che_controller.go +++ b/pkg/controller/che/che_controller.go @@ -419,6 +419,7 @@ func (r *ReconcileChe) Reconcile(request reconcile.Request) (reconcile.Result, e } // Create a new Postgres deployment postgresDeployment := deploy.NewPostgresDeployment(instance, chePostgresPassword, isOpenShift, cheFlavor) + if err := r.CreateNewDeployment(instance, postgresDeployment); err != nil { return reconcile.Result{}, err } @@ -436,7 +437,7 @@ func (r *ReconcileChe) Reconcile(request reconcile.Request) (reconcile.Result, e } } - desiredImage := util.GetValue(instance.Spec.Database.PostgresImage, deploy.DefaultPostgresImage(cheFlavor)) + desiredImage := util.GetValue(instance.Spec.Database.PostgresImage, deploy.DefaultPostgresImage(instance, cheFlavor)) effectiveImage := pgDeployment.Spec.Template.Spec.Containers[0].Image desiredImagePullPolicy := util.GetValue(string(instance.Spec.Database.PostgresImagePullPolicy), deploy.DefaultPullPolicyFromDockerImage(desiredImage)) effectiveImagePullPolicy := string(pgDeployment.Spec.Template.Spec.Containers[0].ImagePullPolicy) @@ -613,7 +614,7 @@ func (r *ReconcileChe) Reconcile(request reconcile.Request) (reconcile.Result, e k8sclient.GetDeploymentRollingUpdateStatus("keycloak", instance.Namespace) } - desiredImage := util.GetValue(instance.Spec.Auth.KeycloakImage, deploy.DefaultKeycloakImage(cheFlavor)) + desiredImage := util.GetValue(instance.Spec.Auth.KeycloakImage, deploy.DefaultKeycloakImage(instance, cheFlavor)) effectiveImage := effectiveKeycloakDeployment.Spec.Template.Spec.Containers[0].Image desiredImagePullPolicy := util.GetValue(string(instance.Spec.Auth.KeycloakImagePullPolicy), deploy.DefaultPullPolicyFromDockerImage(desiredImage)) effectiveImagePullPolicy := string(effectiveKeycloakDeployment.Spec.Template.Spec.Containers[0].ImagePullPolicy) @@ -803,7 +804,7 @@ func (r *ReconcileChe) Reconcile(request reconcile.Request) (reconcile.Result, e devfileRegistryURL = guessedDevfileRegistryURL } - devfileRegistryImage := util.GetValue(instance.Spec.Server.DevfileRegistryImage, deploy.DefaultDevfileRegistryImage(cheFlavor)) + devfileRegistryImage := util.GetValue(instance.Spec.Server.DevfileRegistryImage, deploy.DefaultDevfileRegistryImage(instance, cheFlavor)) result, err := addRegistryDeployment( "devfile", devfileRegistryImage, @@ -839,7 +840,7 @@ func (r *ReconcileChe) Reconcile(request reconcile.Request) (reconcile.Result, e pluginRegistryURL = guessedPluginRegistryURL } - pluginRegistryImage := util.GetValue(instance.Spec.Server.PluginRegistryImage, deploy.DefaultPluginRegistryImage(cheFlavor)) + pluginRegistryImage := util.GetValue(instance.Spec.Server.PluginRegistryImage, deploy.DefaultPluginRegistryImage(instance, cheFlavor)) result, err := addRegistryDeployment( "plugin", pluginRegistryImage, @@ -873,7 +874,7 @@ func (r *ReconcileChe) Reconcile(request reconcile.Request) (reconcile.Result, e // which will automatically trigger Che rolling update cmResourceVersion := cheConfigMap.ResourceVersion // create Che deployment - cheImageRepo := util.GetValue(instance.Spec.Server.CheImage, deploy.DefaultCheServerImageRepo(cheFlavor)) + cheImageRepo := util.GetValue(instance.Spec.Server.CheImage, deploy.DefaultCheServerImageRepo(instance, cheFlavor)) cheImageTag := util.GetValue(instance.Spec.Server.CheImageTag, deploy.DefaultCheServerImageTag(cheFlavor)) cheDeploymentToCreate, err := deploy.NewCheDeployment(instance, cheImageRepo, cheImageTag, cmResourceVersion, isOpenShift) if err != nil { diff --git a/pkg/deploy/che_configmap.go b/pkg/deploy/che_configmap.go index 93948ccee..9e23f4d29 100644 --- a/pkg/deploy/che_configmap.go +++ b/pkg/deploy/che_configmap.go @@ -65,6 +65,9 @@ type CheConfigMap struct { PluginRegistryUrl string `json:"CHE_WORKSPACE_PLUGIN__REGISTRY__URL,omitempty"` DevfileRegistryUrl string `json:"CHE_WORKSPACE_DEVFILE__REGISTRY__URL,omitempty"` WebSocketEndpointMinor string `json:"CHE_WEBSOCKET_ENDPOINT__MINOR"` + CheWorkspacePluginBrokerInitImage string `json:"CHE_WORKSPACE_PLUGIN__BROKER_INIT_IMAGE,omitempty"` + CheWorkspacePluginBrokerUnifiedImage string `json:"CHE_WORKSPACE_PLUGIN__BROKER_UNIFIED_IMAGE,omitempty"` + CheServerSecureExposerJwtProxyImage string `json:"CHE_SERVER_SECURE__EXPOSER_JWTPROXY_IMAGE,omitempty"` } // GetConfigMapData gets env values from CR spec and returns a map with key:value @@ -207,6 +210,9 @@ func GetConfigMapData(cr *orgv1.CheCluster) (cheEnv map[string]string) { } addMap(cheEnv, cr.Spec.Server.CustomCheProperties) + if cr.IsAirGapMode() { + addMap(cheEnv, extraImagesConfig(cr)) + } return cheEnv } @@ -225,3 +231,12 @@ func NewCheConfigMap(cr *orgv1.CheCluster, cheEnv map[string]string) *corev1.Con Data: cheEnv, } } + +func extraImagesConfig(cr *orgv1.CheCluster) map[string]string { + extraImages := map[string]string{ + "CHE_WORKSPACE_PLUGIN__BROKER_INIT_IMAGE": patchDefaultImageName(cr, cheWorkspacePluginBrokerInitImage), + "CHE_WORKSPACE_PLUGIN__BROKER_UNIFIED_IMAGE": patchDefaultImageName(cr, cheWorkspacePluginBrokerUnifiedImage), + "CHE_SERVER_SECURE__EXPOSER_JWTPROXY_IMAGE": patchDefaultImageName(cr, cheServerSecureExposerJwtProxyImage), + } + return extraImages +} diff --git a/pkg/deploy/defaults.go b/pkg/deploy/defaults.go index 8120e36ae..2592e9ece 100644 --- a/pkg/deploy/defaults.go +++ b/pkg/deploy/defaults.go @@ -13,7 +13,10 @@ package deploy import ( + "fmt" "strings" + + orgv1 "github.com/eclipse/che-operator/pkg/apis/org/v1" ) const ( @@ -55,17 +58,17 @@ const ( "-XX:MinHeapFreeRatio=10 -XX:MaxHeapFreeRatio=20 -XX:GCTimeRatio=4 -XX:AdaptiveSizePolicyWeight=90 " + "-Dsun.zip.disableMemoryMapping=true " + "-Xms20m -Djava.security.egd=file:/dev/./urandom" - DefaultServerMemoryRequest = "512Mi" - DefaultServerMemoryLimit = "1Gi" - DefaultSecurityContextFsGroup = "1724" - DefaultSecurityContextRunAsUser = "1724" + DefaultServerMemoryRequest = "512Mi" + DefaultServerMemoryLimit = "1Gi" + DefaultSecurityContextFsGroup = "1724" + DefaultSecurityContextRunAsUser = "1724" // This is only to correctly manage defaults during the transition // from Upstream 7.0.0 GA to the next version // That fixed bug https://github.com/eclipse/che/issues/13714 - OldDefaultKeycloakUpstreamImageToDetect = "eclipse/che-keycloak:7.0.0" - OldDefaultPvcJobsUpstreamImageToDetect = "registry.access.redhat.com/ubi8-minimal:8.0-127" - OldDefaultPostgresUpstreamImageToDetect = "centos/postgresql-96-centos7:9.6" + OldDefaultKeycloakUpstreamImageToDetect = "eclipse/che-keycloak:7.0.0" + OldDefaultPvcJobsUpstreamImageToDetect = "registry.access.redhat.com/ubi8-minimal:8.0-127" + OldDefaultPostgresUpstreamImageToDetect = "centos/postgresql-96-centos7:9.6" // ConsoleLink default DefaultConsoleLinkName = "che" @@ -81,11 +84,12 @@ func DefaultCheServerImageTag(cheFlavor string) string { return defaultCheServerImageTag } -func DefaultCheServerImageRepo(cheFlavor string) string { +func DefaultCheServerImageRepo(cr *orgv1.CheCluster, cheFlavor string) string { if cheFlavor == "codeready" { - return defaultCodeReadyServerImageRepo + return patchDefaultImageName(cr, defaultCodeReadyServerImageRepo) + } else { + return patchDefaultImageName(cr, defaultCheServerImageRepo) } - return defaultCheServerImageRepo } func DefaultPvcJobsImage(cheFlavor string) string { @@ -95,33 +99,36 @@ func DefaultPvcJobsImage(cheFlavor string) string { return defaultPvcJobsUpstreamImage } -func DefaultPostgresImage(cheFlavor string) string { +func DefaultPostgresImage(cr *orgv1.CheCluster, cheFlavor string) string { if cheFlavor == "codeready" { - return defaultPostgresImage + return patchDefaultImageName(cr, defaultPostgresImage) + } else { + return patchDefaultImageName(cr, defaultPostgresUpstreamImage) } - return defaultPostgresUpstreamImage } - -func DefaultKeycloakImage(cheFlavor string) string { +func DefaultKeycloakImage(cr *orgv1.CheCluster, cheFlavor string) string { if cheFlavor == "codeready" { - return defaultKeycloakImage + return patchDefaultImageName(cr, defaultKeycloakImage) + } else { + return patchDefaultImageName(cr, defaultKeycloakUpstreamImage) } - return defaultKeycloakUpstreamImage } -func DefaultPluginRegistryImage(cheFlavor string) string { +func DefaultPluginRegistryImage(cr *orgv1.CheCluster, cheFlavor string) string { if cheFlavor == "codeready" { - return defaultPluginRegistryImage + return patchDefaultImageName(cr, defaultPluginRegistryImage) + } else { + return patchDefaultImageName(cr, defaultPluginRegistryUpstreamImage) } - return defaultPluginRegistryUpstreamImage } -func DefaultDevfileRegistryImage(cheFlavor string) string { +func DefaultDevfileRegistryImage(cr *orgv1.CheCluster, cheFlavor string) string { if cheFlavor == "codeready" { - return defaultDevfileRegistryImage + return patchDefaultImageName(cr, defaultDevfileRegistryImage) + } else { + return patchDefaultImageName(cr, defaultDevfileRegistryUpstreamImage) } - return defaultDevfileRegistryUpstreamImage } func DefaultPullPolicyFromDockerImage(dockerImage string) string { @@ -135,3 +142,60 @@ func DefaultPullPolicyFromDockerImage(dockerImage string) string { } return "IfNotPresent" } + +func patchDefaultImageName(cr *orgv1.CheCluster, imageName string) string { + if !cr.IsAirGapMode() { + return imageName + } + var hostname, organization string + if cr.Spec.Server.AirGapContainerRegistryHostname != "" { + hostname = cr.Spec.Server.AirGapContainerRegistryHostname + } else { + hostname = getHostnameFromImage(imageName) + } + if cr.Spec.Server.AirGapContainerRegistryOrganization != "" { + organization = cr.Spec.Server.AirGapContainerRegistryOrganization + } else { + organization = getOrganizationFromImage(imageName) + } + image := getImageNameFromFullImage(imageName) + return fmt.Sprintf("%s/%s/%s", hostname, organization, image) +} + +func getImageNameFromFullImage(image string) string { + imageParts := strings.Split(image, "/") + nameAndTag := "" + switch len(imageParts) { + case 1: + nameAndTag = imageParts[0] + case 2: + nameAndTag = imageParts[1] + case 3: + nameAndTag = imageParts[2] + } + return nameAndTag +} + +func getHostnameFromImage(image string) string { + imageParts := strings.Split(image, "/") + hostname := "" + switch len(imageParts) { + case 3: + hostname = imageParts[0] + default: + hostname = "docker.io" + } + return hostname +} + +func getOrganizationFromImage(image string) string { + imageParts := strings.Split(image, "/") + organization := "" + switch len(imageParts) { + case 2: + organization = imageParts[0] + case 3: + organization = imageParts[1] + } + return organization +} diff --git a/pkg/deploy/defaults_test.go b/pkg/deploy/defaults_test.go new file mode 100644 index 000000000..4d767f372 --- /dev/null +++ b/pkg/deploy/defaults_test.go @@ -0,0 +1,108 @@ +package deploy + +import ( + orgv1 "github.com/eclipse/che-operator/pkg/apis/org/v1" + "testing" +) + +func TestCorrectImageName(t *testing.T) { + testCases := map[string]string{ + "docker.io/eclipse/che-operator:latest": "che-operator:latest", + "eclipse/che-operator:7.1.0": "che-operator:7.1.0", + "che-operator:7.2.0": "che-operator:7.2.0", + } + for k, v := range testCases { + t.Run(k, func(*testing.T) { + actual := getImageNameFromFullImage(k) + if actual != v { + t.Errorf("Expected %s but was %s", v, actual) + } + }) + } +} + +func TestCorrectAirGapPatchedImage(t *testing.T) { + type testcase struct { + image string + expected string + cr *orgv1.CheCluster + } + upstream := &orgv1.CheCluster{ + Spec: orgv1.CheClusterSpec{ + Server: orgv1.CheClusterSpecServer{}, + }, + } + crw := &orgv1.CheCluster{ + Spec: orgv1.CheClusterSpec{ + Server: orgv1.CheClusterSpecServer{ + CheFlavor: "codeready", + }, + }, + } + airGapUpstream := &orgv1.CheCluster{ + Spec: orgv1.CheClusterSpec{ + Server: orgv1.CheClusterSpecServer{ + AirGapContainerRegistryHostname: "bigcorp.net", + AirGapContainerRegistryOrganization: "che-images", + }, + }, + } + airGapCRW := &orgv1.CheCluster{ + Spec: orgv1.CheClusterSpec{ + Server: orgv1.CheClusterSpecServer{ + AirGapContainerRegistryHostname: "bigcorp.net", + AirGapContainerRegistryOrganization: "che-images", + CheFlavor: "codeready", + }, + }, + } + upstreamOnlyOrg := &orgv1.CheCluster{ + Spec: orgv1.CheClusterSpec{ + Server: orgv1.CheClusterSpecServer{ + AirGapContainerRegistryOrganization: "che-images", + }, + }, + } + upstreamOnlyHostname := &orgv1.CheCluster{ + Spec: orgv1.CheClusterSpec{ + Server: orgv1.CheClusterSpecServer{ + AirGapContainerRegistryHostname: "bigcorp.net", + }, + }, + } + crwOnlyOrg := &orgv1.CheCluster{ + Spec: orgv1.CheClusterSpec{ + Server: orgv1.CheClusterSpecServer{ + AirGapContainerRegistryOrganization: "che-images", + CheFlavor: "codeready", + }, + }, + } + crwOnlyHostname := &orgv1.CheCluster{ + Spec: orgv1.CheClusterSpec{ + Server: orgv1.CheClusterSpecServer{ + AirGapContainerRegistryHostname: "bigcorp.net", + CheFlavor: "codeready", + }, + }, + } + + testCases := map[string]testcase{ + "upstream default postgres": {image: defaultPostgresUpstreamImage, expected: defaultPostgresUpstreamImage, cr: upstream}, + "airgap upstream postgres": {image: defaultPostgresUpstreamImage, expected: "bigcorp.net/che-images/postgresql-96-centos7:9.6", cr: airGapUpstream}, + "upstream with only the org changed": {image: defaultPostgresUpstreamImage, expected: "docker.io/che-images/postgresql-96-centos7:9.6", cr: upstreamOnlyOrg}, + "codeready plugin registry with only the org changed": {image: defaultPluginRegistryImage, expected: "registry.redhat.io/che-images/pluginregistry-rhel8:2.0", cr: crwOnlyOrg}, + "CRW postgres": {image: defaultPostgresImage, expected: defaultPostgresImage, cr: crw}, + "CRW airgap postgres": {image: defaultPostgresImage, expected: "bigcorp.net/che-images/postgresql-96-rhel7:1-47", cr: airGapCRW}, + "upstream airgap with only hostname defined": {image: defaultKeycloakUpstreamImage, expected: "bigcorp.net/eclipse/che-keycloak:7.2.0", cr: upstreamOnlyHostname}, + "crw airgap with only hostname defined": {image: defaultDevfileRegistryImage, expected: "bigcorp.net/codeready-workspaces/devfileregistry-rhel8:2.0", cr: crwOnlyHostname}, + } + for name, tc := range testCases { + t.Run(name, func(*testing.T) { + actual := patchDefaultImageName(tc.cr, tc.image) + if actual != tc.expected { + t.Errorf("Expected %s but was %s", tc.expected, actual) + } + }) + } +} diff --git a/pkg/deploy/deployment_keycloak.go b/pkg/deploy/deployment_keycloak.go index cc9cc05bd..94871a6cc 100644 --- a/pkg/deploy/deployment_keycloak.go +++ b/pkg/deploy/deployment_keycloak.go @@ -25,7 +25,7 @@ func NewKeycloakDeployment(cr *orgv1.CheCluster, keycloakPostgresPassword string optionalEnv := true keycloakName := "keycloak" labels := GetLabels(cr, keycloakName) - keycloakImage := util.GetValue(cr.Spec.Auth.KeycloakImage, DefaultKeycloakImage(cheFlavor)) + keycloakImage := util.GetValue(cr.Spec.Auth.KeycloakImage, DefaultKeycloakImage(cr, cheFlavor)) pullPolicy := corev1.PullPolicy(util.GetValue(string(cr.Spec.Auth.KeycloakImagePullPolicy), DefaultPullPolicyFromDockerImage(keycloakImage))) trustpass := util.GeneratePasswd(12) jbossDir := "/opt/eap" @@ -62,7 +62,7 @@ func NewKeycloakDeployment(cr *orgv1.CheCluster, keycloakPostgresPassword string startCommand := "sed -i 's/WILDCARD/ANY/g' /opt/eap/bin/launch/keycloak-spi.sh && /opt/eap/bin/openshift-launch.sh -b 0.0.0.0" // upstream Keycloak has a bit different mechanism of adding jks changeConfigCommand := "echo Installing certificates into Keycloak && " + - "echo -e \"embed-server --server-config=standalone.xml --std-out=echo \n" + + "echo -e \"embed-server --server-config=standalone.xml --std-out=echo \n" + "/subsystem=keycloak-server/spi=truststore/:add \n" + "/subsystem=keycloak-server/spi=truststore/provider=file/:add(properties={file => " + "\"" + jbossDir + "/openshift.jks\", password => \"" + trustpass + "\", disabled => \"false\" },enabled=true) \n" + @@ -230,9 +230,9 @@ func NewKeycloakDeployment(cr *orgv1.CheCluster, keycloakPostgresPassword string Name: keycloakName, Namespace: cr.Namespace, Labels: labels, - Annotations: map[string]string { + Annotations: map[string]string{ "che.self-signed-certificate.version": cheCertSecretVersion, - "che.openshift-api-crt.version": openshiftCertSecretVersion, + "che.openshift-api-crt.version": openshiftCertSecretVersion, }, }, Spec: appsv1.DeploymentSpec{ diff --git a/pkg/deploy/deployment_postgres.go b/pkg/deploy/deployment_postgres.go index 632b72964..e02477d76 100644 --- a/pkg/deploy/deployment_postgres.go +++ b/pkg/deploy/deployment_postgres.go @@ -24,7 +24,7 @@ func NewPostgresDeployment(cr *orgv1.CheCluster, chePostgresPassword string, isO chePostgresUser := util.GetValue(cr.Spec.Database.ChePostgresUser, "pgche") chePostgresDb := util.GetValue(cr.Spec.Database.ChePostgresDb, "dbche") postgresAdminPassword := util.GeneratePasswd(12) - postgresImage := util.GetValue(cr.Spec.Database.PostgresImage, DefaultPostgresImage(cheFlavor)) + postgresImage := util.GetValue(cr.Spec.Database.PostgresImage, DefaultPostgresImage(cr, cheFlavor)) pullPolicy := corev1.PullPolicy(util.GetValue(string(cr.Spec.Database.PostgresImagePullPolicy), DefaultPullPolicyFromDockerImage(postgresImage))) name := "postgres" @@ -124,11 +124,11 @@ func NewPostgresDeployment(cr *orgv1.CheCluster, chePostgresPassword string, isO }, }, } - if ! isOpenshift { + if !isOpenshift { var runAsUser int64 = 26 - deployment.Spec.Template.Spec.SecurityContext = &corev1.PodSecurityContext { + deployment.Spec.Template.Spec.SecurityContext = &corev1.PodSecurityContext{ RunAsUser: &runAsUser, - FSGroup: &runAsUser, + FSGroup: &runAsUser, } } return &deployment diff --git a/pkg/deploy/extra_images.go b/pkg/deploy/extra_images.go new file mode 100644 index 000000000..333381142 --- /dev/null +++ b/pkg/deploy/extra_images.go @@ -0,0 +1,8 @@ +// This file is generated, and contains the latest versions of certain properties from che.properties +package deploy + +const ( + cheWorkspacePluginBrokerInitImage = "eclipse/che-init-plugin-broker:v0.21" + cheWorkspacePluginBrokerUnifiedImage = "eclipse/che-unified-plugin-broker:v0.21" + cheServerSecureExposerJwtProxyImage = "quay.io/eclipse/che-jwtproxy:dbd0578" +) diff --git a/release-operator-code.sh b/release-operator-code.sh index 20b6c6253..21942e9de 100755 --- a/release-operator-code.sh +++ b/release-operator-code.sh @@ -66,6 +66,25 @@ pkg/deploy/defaults.go \ > pkg/deploy/defaults.go.new mv pkg/deploy/defaults.go.new pkg/deploy/defaults.go +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 +latestCheWorkspacePluginBrokerInitImage=$(cat /tmp/che.properties| grep "che.workspace.plugin_broker.init.image" | cut -d = -f2) +latestCheWorkspacePluginBrokerUnifiedImage=$(cat /tmp/che.properties | grep "che.workspace.plugin_broker.unified.image" | cut -d = -f2) +latestCheServerSecureExposerJwtProxyImage=$(cat /tmp/che.properties | grep "che.server.secure_exposer.jwtproxy.image" | cut -d = -f2) + +cat << EOF > pkg/deploy/extra_images.go +// This file is generated, and contains the latest versions of certain properties from che.properties +package deploy + +const ( + cheWorkspacePluginBrokerInitImage = "${latestCheWorkspacePluginBrokerInitImage}" + cheWorkspacePluginBrokerUnifiedImage = "${latestCheWorkspacePluginBrokerUnifiedImage}" + cheServerSecureExposerJwtProxyImage = "${latestCheServerSecureExposerJwtProxyImage}" +) +EOF + +gofmt -w pkg/deploy/extra_images.go +rm /tmp/che.properties + dockerImage="quay.io/eclipse/che-operator:${RELEASE}" echo " - Building Che Operator docker image for new release ${RELEASE}" docker build -t "quay.io/eclipse/che-operator:${RELEASE}" .