diff --git a/install/installer/pkg/config/loader.go b/install/installer/pkg/config/loader.go index e15f931fbdaf17..976b44bfdfa1c6 100644 --- a/install/installer/pkg/config/loader.go +++ b/install/installer/pkg/config/loader.go @@ -6,9 +6,9 @@ package config import ( "fmt" - "regexp" "github.com/gitpod-io/gitpod/installer/pkg/cluster" + "github.com/gitpod-io/gitpod/installer/pkg/yq" "github.com/go-playground/validator/v10" "sigs.k8s.io/yaml" @@ -107,17 +107,18 @@ func Load(overrideConfig string, strict bool) (cfg interface{}, version string, return } - // `apiVersion: vx` line is removed from config since the version dependant - // Config structure doesn't have that field - // The line-ending is either comma (minified YAML) or newline (unminified) - apiVersionRegexp := regexp.MustCompile(`apiVersion: ` + apiVersion + `(,)?`) - overrideConfig = apiVersionRegexp.ReplaceAllString(overrideConfig, "") + // Remove the apiVersion from the config as this has already been parsed + // Use yq to make processing reliable + output, err := yq.Process(overrideConfig, "del(.apiVersion)") + if err != nil { + return + } // Override passed configuration onto the default if strict { - err = yaml.UnmarshalStrict([]byte(overrideConfig), cfg) + err = yaml.UnmarshalStrict([]byte(*output), cfg) } else { - err = yaml.Unmarshal([]byte(overrideConfig), cfg) + err = yaml.Unmarshal([]byte(*output), cfg) } if err != nil { return diff --git a/install/installer/pkg/postprocess/postprocess.go b/install/installer/pkg/postprocess/postprocess.go index c6f3d89caa45c8..c6b82ad8483359 100644 --- a/install/installer/pkg/postprocess/postprocess.go +++ b/install/installer/pkg/postprocess/postprocess.go @@ -4,15 +4,9 @@ package postprocess import ( - "bytes" - "fmt" - "os" - "strings" - "github.com/gitpod-io/gitpod/installer/pkg/common" openvsxproxy "github.com/gitpod-io/gitpod/installer/pkg/components/openvsx-proxy" - "github.com/mikefarah/yq/v4/pkg/yqlib" - logging "gopkg.in/op/go-logging.v1" + "github.com/gitpod-io/gitpod/installer/pkg/yq" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/utils/pointer" ) @@ -38,52 +32,6 @@ type Processor struct { Name *string // Optional } -// process emulates how YQ parsers the file -func process(expression string, obj *common.RuntimeObject) error { - // Stop the logging to Stderr - var format = logging.MustStringFormatter( - `%{color}%{time:15:04:05} %{shortfunc} [%{level:.4s}]%{color:reset} %{message}`, - ) - var backend = logging.AddModuleLevel( - logging.NewBackendFormatter(logging.NewLogBackend(os.Stderr, "", 0), format)) - - backend.SetLevel(logging.ERROR, "") - logging.SetBackend(backend) - // End of logger config - - yqlib.InitExpressionParser() - - var writer bytes.Buffer - printerWriter := yqlib.NewSinglePrinterWriter(&writer) - encoder := yqlib.NewYamlEncoder(2, false, false, true) - - printer := yqlib.NewPrinter(encoder, printerWriter) - - decoder := yqlib.NewYamlDecoder() - - streamEvaluator := yqlib.NewStreamEvaluator() - - reader := strings.NewReader(obj.Content) - - node, err := yqlib.ExpressionParser.ParseExpression(expression) - if err != nil { - return err - } - - // This is used for debugging - filename := fmt.Sprintf("%s %s %s", obj.APIVersion, obj.Kind, obj.Metadata.Name) - - _, err = streamEvaluator.Evaluate(filename, reader, node, printer, "", decoder) - if err != nil { - return err - } - - // Overwrite the content with the parsed data - obj.Content = writer.String() - - return nil -} - func useProcessor(object common.RuntimeObject, processor Processor) bool { if object.APIVersion == processor.Type.APIVersion && object.Kind == processor.Type.Kind { // Name is optional @@ -105,10 +53,11 @@ func Run(objects []common.RuntimeObject) ([]common.RuntimeObject, error) { for _, o := range objects { for _, p := range Processors { if useProcessor(o, p) { - err := process(p.Expression, &o) + output, err := yq.Process(o.Content, p.Expression) if err != nil { return nil, err } + o.Content = *output } } diff --git a/install/installer/pkg/yq/yq.go b/install/installer/pkg/yq/yq.go new file mode 100644 index 00000000000000..42ade014b36266 --- /dev/null +++ b/install/installer/pkg/yq/yq.go @@ -0,0 +1,53 @@ +// Copyright (c) 2022 Gitpod GmbH. All rights reserved. +// Licensed under the MIT License. See License-MIT.txt in the project root for license information. + +package yq + +import ( + "bytes" + "os" + "strings" + + "github.com/mikefarah/yq/v4/pkg/yqlib" + logging "gopkg.in/op/go-logging.v1" + "k8s.io/utils/pointer" +) + +func Process(input string, expression string) (*string, error) { + // Stop the logging to Stderr + var format = logging.MustStringFormatter( + `%{color}%{time:15:04:05} %{shortfunc} [%{level:.4s}]%{color:reset} %{message}`, + ) + var backend = logging.AddModuleLevel( + logging.NewBackendFormatter(logging.NewLogBackend(os.Stderr, "", 0), format)) + + backend.SetLevel(logging.ERROR, "") + logging.SetBackend(backend) + // End of logger config + + yqlib.InitExpressionParser() + + var writer bytes.Buffer + printerWriter := yqlib.NewSinglePrinterWriter(&writer) + encoder := yqlib.NewYamlEncoder(2, false, false, true) + + printer := yqlib.NewPrinter(encoder, printerWriter) + + decoder := yqlib.NewYamlDecoder() + + streamEvaluator := yqlib.NewStreamEvaluator() + + reader := strings.NewReader(input) + + node, err := yqlib.ExpressionParser.ParseExpression(expression) + if err != nil { + return nil, err + } + + _, err = streamEvaluator.Evaluate("gitpod-installer.tmp.yaml", reader, node, printer, "", decoder) + if err != nil { + return nil, err + } + + return pointer.String(writer.String()), nil +}