From 5263dabd222def8b1527926e6a65df11dd7ab6f6 Mon Sep 17 00:00:00 2001 From: Hidde Beydals Date: Mon, 15 Feb 2021 20:50:31 +0100 Subject: [PATCH] Check if targeted version is supported by binary Signed-off-by: Hidde Beydals --- cmd/flux/bootstrap.go | 4 ++++ cmd/flux/install.go | 4 ++++ internal/utils/utils.go | 24 ++++++++++++++++++++- internal/utils/utils_test.go | 42 ++++++++++++++++++++++++++++++++++++ 4 files changed, 73 insertions(+), 1 deletion(-) create mode 100644 internal/utils/utils_test.go diff --git a/cmd/flux/bootstrap.go b/cmd/flux/bootstrap.go index c87ccf43..b90e7160 100644 --- a/cmd/flux/bootstrap.go +++ b/cmd/flux/bootstrap.go @@ -141,6 +141,10 @@ func generateInstallManifests(targetPath, namespace, tmpDir string, localManifes } } + if !utils.CompatibleVersion(VERSION, bootstrapArgs.version) { + return "", fmt.Errorf("targeted version '%s' is not compatible with your current version of flux (%s)", bootstrapArgs.version, VERSION) + } + opts := install.Options{ BaseURL: localManifests, Version: bootstrapArgs.version, diff --git a/cmd/flux/install.go b/cmd/flux/install.go index 7816023f..bac6d058 100644 --- a/cmd/flux/install.go +++ b/cmd/flux/install.go @@ -126,6 +126,10 @@ func installCmdRun(cmd *cobra.Command, args []string) error { } } + if !utils.CompatibleVersion(VERSION, installVersion) { + return fmt.Errorf("targeted version '%s' is not compatible with your current version of flux (%s)", installVersion, VERSION) + } + tmpDir, err := ioutil.TempDir("", rootArgs.namespace) if err != nil { return err diff --git a/internal/utils/utils.go b/internal/utils/utils.go index 5e8f20d5..358bdf0e 100644 --- a/internal/utils/utils.go +++ b/internal/utils/utils.go @@ -46,14 +46,16 @@ import ( kustypes "sigs.k8s.io/kustomize/api/types" "sigs.k8s.io/yaml" - "github.com/fluxcd/flux2/pkg/manifestgen/install" helmv2 "github.com/fluxcd/helm-controller/api/v2beta1" imageautov1 "github.com/fluxcd/image-automation-controller/api/v1alpha1" imagereflectv1 "github.com/fluxcd/image-reflector-controller/api/v1alpha1" kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1beta1" notificationv1 "github.com/fluxcd/notification-controller/api/v1beta1" "github.com/fluxcd/pkg/runtime/dependency" + "github.com/fluxcd/pkg/version" sourcev1 "github.com/fluxcd/source-controller/api/v1beta1" + + "github.com/fluxcd/flux2/pkg/manifestgen/install" ) type Utils struct { @@ -420,3 +422,23 @@ func MergeMaps(a, b map[string]interface{}) map[string]interface{} { } return out } + +// CompatibleVersion returns if the provided binary version is compatible +// with the given target version. At present, this is true if the target +// version is equal to the MINOR range of the binary, or if the binary +// version is a prerelease. +func CompatibleVersion(binary, target string) bool { + binSv, err := version.ParseVersion(binary) + if err != nil { + return false + } + // Assume prerelease builds are compatible. + if binSv.Prerelease() != "" { + return true + } + targetSv, err := version.ParseVersion(target) + if err != nil { + return false + } + return binSv.Major() == targetSv.Major() && binSv.Minor() == targetSv.Minor() +} diff --git a/internal/utils/utils_test.go b/internal/utils/utils_test.go new file mode 100644 index 00000000..b4ed6eb4 --- /dev/null +++ b/internal/utils/utils_test.go @@ -0,0 +1,42 @@ +/* +Copyright 2021 The Flux authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package utils + +import "testing" + +func TestCompatibleVersion(t *testing.T) { + tests := []struct { + name string + binary string + target string + want bool + }{ + {"different major version", "1.1.0", "0.1.0", false}, + {"different minor version", "0.1.0", "0.2.0", false}, + {"same version", "0.1.0", "0.1.0", true}, + {"binary patch version ahead", "0.1.1", "0.1.0", true}, + {"target patch version ahead", "0.1.1", "0.1.2", true}, + {"prerelease binary", "0.0.0-dev.0", "0.1.0", true}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := CompatibleVersion(tt.binary, tt.target); got != tt.want { + t.Errorf("CompatibleVersion() = %v, want %v", got, tt.want) + } + }) + } +}