che-operator/pkg/deploy/pluginregistry/pluginregistry_editors.go

130 lines
3.5 KiB
Go

//
// Copyright (c) 2019-2024 Red Hat, Inc.
// This program and the accompanying materials are made
// available under the terms of the Eclipse Public License 2.0
// which is available at https://www.eclipse.org/legal/epl-2.0/
//
// SPDX-License-Identifier: EPL-2.0
//
// Contributors:
// Red Hat, Inc. - initial API and implementation
//
package pluginregistry
import (
"fmt"
"os"
"path/filepath"
"regexp"
"github.com/eclipse-che/che-operator/pkg/common/chetypes"
"github.com/eclipse-che/che-operator/pkg/common/constants"
"github.com/eclipse-che/che-operator/pkg/common/utils"
"github.com/eclipse-che/che-operator/pkg/deploy"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"sigs.k8s.io/yaml"
)
var (
editorsDefinitionsDir = "/tmp/editors-definitions"
editorsDefinitionsConfigMapName = "editors-definitions"
)
func (p *PluginRegistryReconciler) syncEditors(ctx *chetypes.DeployContext) (bool, error) {
editorDefinitions, err := readEditorDefinitions()
if err != nil {
return false, err
}
done, err := syncEditorDefinitions(ctx, editorDefinitions)
if !done {
return false, err
}
return true, nil
}
func readEditorDefinitions() (map[string][]byte, error) {
editorDefinitions := make(map[string][]byte)
files, err := os.ReadDir(editorsDefinitionsDir)
if err != nil {
return editorDefinitions, err
}
for _, file := range files {
if !file.IsDir() {
fileName := file.Name()
editorContent, err := os.ReadFile(filepath.Join(editorsDefinitionsDir, fileName))
if err != nil {
return editorDefinitions, err
}
var devfile map[string]interface{}
err = yaml.Unmarshal(editorContent, &devfile)
if err != nil {
return editorDefinitions, err
}
updateEditorDefinitionImageFromEnv(devfile)
editorContent, err = yaml.Marshal(devfile)
if err != nil {
return editorDefinitions, err
}
editorDefinitions[fileName] = editorContent
}
}
return editorDefinitions, nil
}
func updateEditorDefinitionImageFromEnv(devfile map[string]interface{}) {
notAllowedCharsReg, _ := regexp.Compile("[^a-zA-Z0-9]+")
metadata := devfile["metadata"].(map[string]interface{})
devfileName := metadata["name"].(string)
attributes := metadata["attributes"].(map[string]interface{})
devfileVersion := attributes["version"].(string)
components := devfile["components"].([]interface{})
for _, component := range components {
componentName := component.(map[string]interface{})["name"].(string)
if container, ok := component.(map[string]interface{})["container"].(map[string]interface{}); ok {
imageEnvName := fmt.Sprintf("RELATED_IMAGE_%s_%s_%s", devfileName, devfileVersion, componentName)
imageEnvName = notAllowedCharsReg.ReplaceAllString(imageEnvName, "_")
imageEnvName = utils.GetArchitectureDependentEnvName(imageEnvName)
if imageEnvValue, ok := os.LookupEnv(imageEnvName); ok {
container["image"] = imageEnvValue
}
}
}
}
func syncEditorDefinitions(ctx *chetypes.DeployContext, editorDefinitions map[string][]byte) (bool, error) {
cm := &corev1.ConfigMap{
TypeMeta: metav1.TypeMeta{
Kind: "ConfigMap",
APIVersion: "v1",
},
ObjectMeta: metav1.ObjectMeta{
Name: editorsDefinitionsConfigMapName,
Namespace: ctx.CheCluster.Namespace,
Labels: deploy.GetLabels(constants.EditorDefinitionComponentName),
Annotations: map[string]string{},
},
Data: map[string]string{},
}
for fileName, content := range editorDefinitions {
cm.Data[fileName] = string(content)
}
return deploy.Sync(ctx, cm, deploy.ConfigMapDiffOpts)
}