diff --git a/pkg/reconciler/common/releases.go b/pkg/reconciler/common/releases.go index cca19a6a50..58b1a5d3c6 100644 --- a/pkg/reconciler/common/releases.go +++ b/pkg/reconciler/common/releases.go @@ -38,6 +38,8 @@ const ( VersionVariable = "${VERSION}" // COMMA is the character comma COMMA = "," + // LATEST_VERSION is the special version Knative Operator support, besides all semantic versions of Knative. + LATEST_VERSION = "latest" ) var cache = map[string]mf.Manifest{} @@ -81,7 +83,11 @@ func InstalledManifest(instance v1alpha1.KComponent) (mf.Manifest, error) { // manifest is able to upgrade or downgrade to the target manifest. func IsVersionValidMigrationEligible(instance v1alpha1.KComponent) error { var err error - target := sanitizeSemver(TargetVersion(instance)) + targetVersion := TargetVersion(instance) + if targetVersion == LATEST_VERSION { + return nil + } + target := sanitizeSemver(targetVersion) if !semver.IsValid(target) { return fmt.Errorf("target version %v is not in a valid semantic versioning format.", target) } @@ -92,7 +98,8 @@ func IsVersionValidMigrationEligible(instance v1alpha1.KComponent) error { current := instance.GetStatus().GetVersion() // If there is no manifest installed, return nil, because the target manifest is able to install. - if current == "" { + // If the installed manifest is versioned with latest, we allow any version to upgrade to or from it. + if current == "" || current == LATEST_VERSION { return nil } @@ -154,8 +161,9 @@ func getManifestWithVersionValidation(version string, instance v1alpha1.KCompone return manifests, fmt.Errorf("There is no resource available in the target manifests %s.", manifestsPath) } - if version == "" { - // If target version is empty, there is no need to check whether the versions match. + if version == "" || version == LATEST_VERSION { + // If target version is empty or equal to the special latest version, there is no need to check whether + // the versions match. return manifests, nil } diff --git a/pkg/reconciler/common/releases_test.go b/pkg/reconciler/common/releases_test.go index b4ab88c483..c6be327407 100644 --- a/pkg/reconciler/common/releases_test.go +++ b/pkg/reconciler/common/releases_test.go @@ -206,6 +206,16 @@ func TestTargetVersion(t *testing.T) { }, }, expected: "0.12", + }, { + name: "serving CR with the version latest", + component: &v1alpha1.KnativeServing{ + Spec: v1alpha1.KnativeServingSpec{ + CommonSpec: v1alpha1.CommonSpec{ + Version: "latest", + }, + }, + }, + expected: "latest", }, { name: "eventing CR with major.minor version not available", component: &v1alpha1.KnativeEventing{ @@ -236,6 +246,16 @@ func TestTargetVersion(t *testing.T) { }, }, expected: "0.12.1", + }, { + name: "eventing CR with the version latest", + component: &v1alpha1.KnativeEventing{ + Spec: v1alpha1.KnativeEventingSpec{ + CommonSpec: v1alpha1.CommonSpec{ + Version: "latest", + }, + }, + }, + expected: "latest", }} os.Setenv(KoEnvKey, koPath) @@ -364,11 +384,11 @@ func TestListReleases(t *testing.T) { }{{ name: "knative-serving", component: &v1alpha1.KnativeServing{}, - expected: []string{"0.16.1", "0.16.0", "0.15.0", "0.14.0"}, + expected: []string{"0.16.1", "0.16.0", "0.15.0", "0.14.0", "latest"}, }, { name: "knative-eventing", component: &v1alpha1.KnativeEventing{}, - expected: []string{"0.16.0", "0.15.0", "0.14.2"}, + expected: []string{"0.16.0", "0.15.0", "0.14.2", "latest"}, }} os.Setenv(KoEnvKey, koPath) @@ -424,6 +444,42 @@ func TestIsVersionValidMigrationEligible(t *testing.T) { }, }, expected: false, + }, { + name: "knative-serving with the version latest upgrading to", + component: &v1alpha1.KnativeServing{ + Spec: v1alpha1.KnativeServingSpec{ + CommonSpec: v1alpha1.CommonSpec{ + Version: "latest", + }, + }, + Status: v1alpha1.KnativeServingStatus{ + Version: "0.13.0", + }, + }, + expected: true, + }, { + name: "knative-serving with the version latest upgrading from", + component: &v1alpha1.KnativeServing{ + Spec: v1alpha1.KnativeServingSpec{ + CommonSpec: v1alpha1.CommonSpec{ + Version: "0.14.0", + }, + }, + Status: v1alpha1.KnativeServingStatus{ + Version: "latest", + }, + }, + expected: true, + }, { + name: "knative-serving with the version latest", + component: &v1alpha1.KnativeServing{ + Spec: v1alpha1.KnativeServingSpec{ + CommonSpec: v1alpha1.CommonSpec{ + Version: "latest", + }, + }, + }, + expected: true, }, { name: "knative-serving upgrading to the latest version across multiple minor versions", component: &v1alpha1.KnativeServing{ @@ -666,6 +722,17 @@ func TestTargetManifest(t *testing.T) { expectedNumResources: 0, expectedError: fmt.Errorf("The manifests of the target version %v are not available to this release.", "0.12.1"), + }, { + name: "knative-serving with the latest version available", + component: &v1alpha1.KnativeServing{ + Spec: v1alpha1.KnativeServingSpec{ + CommonSpec: v1alpha1.CommonSpec{ + Version: "latest", + }, + }, + }, + expectedNumResources: 2, + expectedError: nil, }, { name: "knative-eventing with major.minor spec.version not available", component: &v1alpha1.KnativeEventing{ @@ -690,6 +757,17 @@ func TestTargetManifest(t *testing.T) { expectedNumResources: 0, expectedError: fmt.Errorf("The manifests of the target version %v are not available to this release.", "0.12.1"), + }, { + name: "knative-eventing with the latest available", + component: &v1alpha1.KnativeEventing{ + Spec: v1alpha1.KnativeEventingSpec{ + CommonSpec: v1alpha1.CommonSpec{ + Version: "latest", + }, + }, + }, + expectedNumResources: 2, + expectedError: nil, }} koPath := "testdata/kodata" diff --git a/pkg/reconciler/common/testdata/kodata/knative-eventing/latest/eventing-core.yaml b/pkg/reconciler/common/testdata/kodata/knative-eventing/latest/eventing-core.yaml new file mode 100644 index 0000000000..05c264336c --- /dev/null +++ b/pkg/reconciler/common/testdata/kodata/knative-eventing/latest/eventing-core.yaml @@ -0,0 +1,20 @@ +# Copyright 2020 The Knative 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. + +apiVersion: v1 +kind: Namespace +metadata: + name: knative-eventing + labels: + eventing.knative.dev/release: "something-else" diff --git a/pkg/reconciler/common/testdata/kodata/knative-eventing/latest/in-memory-channel.yaml b/pkg/reconciler/common/testdata/kodata/knative-eventing/latest/in-memory-channel.yaml new file mode 100644 index 0000000000..781704c9df --- /dev/null +++ b/pkg/reconciler/common/testdata/kodata/knative-eventing/latest/in-memory-channel.yaml @@ -0,0 +1,20 @@ +# Copyright 2020 The Knative 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. + +apiVersion: v1 +kind: Namespace +metadata: + name: knative-eventing + labels: + eventing.knative.dev/release: "somthing-else" diff --git a/pkg/reconciler/common/testdata/kodata/knative-serving/latest/serving-core.yaml b/pkg/reconciler/common/testdata/kodata/knative-serving/latest/serving-core.yaml new file mode 100644 index 0000000000..77327c36c7 --- /dev/null +++ b/pkg/reconciler/common/testdata/kodata/knative-serving/latest/serving-core.yaml @@ -0,0 +1,20 @@ +# Copyright 2020 The Knative 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 +# +# https://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. + +apiVersion: v1 +kind: Namespace +metadata: + name: knative-serving + labels: + serving.knative.dev/release: "v0.16.0" diff --git a/pkg/reconciler/common/testdata/kodata/knative-serving/latest/serving-hpa.yaml b/pkg/reconciler/common/testdata/kodata/knative-serving/latest/serving-hpa.yaml new file mode 100644 index 0000000000..834263ad05 --- /dev/null +++ b/pkg/reconciler/common/testdata/kodata/knative-serving/latest/serving-hpa.yaml @@ -0,0 +1,20 @@ +# Copyright 2020 The Knative 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 +# +# https://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. + +apiVersion: v1 +kind: Namespace +metadata: + name: knative-serving + labels: + serving.knative.dev/release: "something-else" diff --git a/test/resources/knativeresources.go b/test/resources/knativeresources.go index 3fe3de2ccb..50db082c2a 100644 --- a/test/resources/knativeresources.go +++ b/test/resources/knativeresources.go @@ -91,7 +91,7 @@ func IsKnativeDeploymentReady(dpList *v1.DeploymentList, expectedDeployments []s // Currently, the network ingress resource is still specified together with the knative serving. // It is possible that network ingress resource is not using the same version as knative serving. // This is the reason why we skip the version checking for network ingress resource. - if val == fmt.Sprintf("v%s", version) || key == "networking.knative.dev/ingress-provider" { + if val == fmt.Sprintf("v%s", version) || version == common.LATEST_VERSION || key == "networking.knative.dev/ingress-provider" { for _, c := range d.Status.Conditions { if c.Type == v1.DeploymentAvailable && c.Status == corev1.ConditionTrue { return true