From 575f8d2f0d1f01ec9f096bacc13c98d1a7082300 Mon Sep 17 00:00:00 2001 From: "W. Trevor King" Date: Tue, 19 Nov 2019 10:20:25 -0800 Subject: [PATCH] config/v1: New Release type for ClusterVersionStatus This commit adds the ability to store release metadata, implementing openshift/enhancements@2eb16cf80d (enhancements/update/available-update-metadata: Propose a new enhancement, 2020-07-20, openshift/enhancements#123) as adjusted by openshift/enhancements@12eff48079 (enhancements/update/available-update-metadata: 'url' docstring context, 2020-07-21, openshift/enhancements#408). For example the list of channels that a release is in: $ curl -sH 'Accept:application/json' 'https://api.openshift.com/api/upgrades_info/v1/graph?channel=stable-4.2' | jq -r '.nodes[] | select(.version == "4.2.4").metadata["io.openshift.upgrades.graph.release.channels"] | split(",")[]' candidate-4.2 fast-4.2 stable-4.2 That will allow the console and other downstream tooling to expose a list of channels available to a given cluster right now, instead of hard-coding an expected list [1]. This will account for things like phased releases, where we may not recommend an upgrade for your particular stable-4.2 cluster even though we are recommending the upgrade for other stable-4.2 clusters. Pivoting around this retyping in Go will require consumer bumps, but I don't think it's a breaking change because the only YAML removal is 'force', which is meaningless in AvailableUpdates. So I don't think this needs to count as a backwards-compat-breaking schema bump. Autogenerated bumps via: $ unset GOBIN # vendor/k8s.io/code-generator/generate-groups.sh and such require "${GOPATH}/bin/deepcopy-gen" $ go get k8s.io/gengo/examples/deepcopy-gen $ hack/update-deepcopy.sh $ hack/update-swagger-docs.sh $ make update-codegen-crds [1]: https://github.com/openshift/console/pull/2935 --- ...ersion-operator_01_clusterversion.crd.yaml | 54 ++++++++++--------- config/v1/types_cluster_version.go | 35 ++++++++++-- config/v1/zz_generated.deepcopy.go | 29 ++++++++-- .../v1/zz_generated.swagger_doc_generated.go | 14 ++++- 4 files changed, 98 insertions(+), 34 deletions(-) diff --git a/config/v1/0000_00_cluster-version-operator_01_clusterversion.crd.yaml b/config/v1/0000_00_cluster-version-operator_01_clusterversion.crd.yaml index ccde0db23bb..cb26372e00a 100644 --- a/config/v1/0000_00_cluster-version-operator_01_clusterversion.crd.yaml +++ b/config/v1/0000_00_cluster-version-operator_01_clusterversion.crd.yaml @@ -162,28 +162,29 @@ spec: channel has been specified. type: array items: - description: Update represents a release of the ClusterVersionOperator, - referenced by the Image member. + description: Release represents an OpenShift release image and associated + metadata. type: object properties: - force: - description: "force allows an administrator to update to an image - that has failed verification, does not appear in the availableUpdates - list, or otherwise would be blocked by normal protections on - update. This option should only be used when the authenticity - of the provided image has been verified out of band because - the provided image will run with full administrative access - to the cluster. Do not use this flag with images that comes - from unknown or potentially malicious sources. \n This flag - does not override other forms of consistency checking that are - required before a new update is deployed." - type: boolean + channels: + description: channels is the set of Cincinnati channels to which + the release currently belongs. + type: array + items: + type: string image: description: image is a container image location that contains the update. When this field is part of spec, image is optional if version is specified and the availableUpdates field contains a matching version. type: string + url: + description: url contains information about this release. This + URL is set by the 'url' metadata property on a release or the + metadata returned by the update API and should be displayed + as a link in user interfaces. The URL field may not be set for + test or nightly releases. + type: string version: description: version is a semantic versioning identifying the update version. When this field is part of spec, version is @@ -234,24 +235,25 @@ spec: tag. type: object properties: - force: - description: "force allows an administrator to update to an image - that has failed verification, does not appear in the availableUpdates - list, or otherwise would be blocked by normal protections on update. - This option should only be used when the authenticity of the provided - image has been verified out of band because the provided image - will run with full administrative access to the cluster. Do not - use this flag with images that comes from unknown or potentially - malicious sources. \n This flag does not override other forms - of consistency checking that are required before a new update - is deployed." - type: boolean + channels: + description: channels is the set of Cincinnati channels to which + the release currently belongs. + type: array + items: + type: string image: description: image is a container image location that contains the update. When this field is part of spec, image is optional if version is specified and the availableUpdates field contains a matching version. type: string + url: + description: url contains information about this release. This URL + is set by the 'url' metadata property on a release or the metadata + returned by the update API and should be displayed as a link in + user interfaces. The URL field may not be set for test or nightly + releases. + type: string version: description: version is a semantic versioning identifying the update version. When this field is part of spec, version is optional diff --git a/config/v1/types_cluster_version.go b/config/v1/types_cluster_version.go index 771e962add0..58a65228da4 100644 --- a/config/v1/types_cluster_version.go +++ b/config/v1/types_cluster_version.go @@ -84,7 +84,7 @@ type ClusterVersionStatus struct { // with the information available, which may be an image or a tag. // +kubebuilder:validation:Required // +required - Desired Update `json:"desired"` + Desired Release `json:"desired"` // history contains a list of the most recent versions applied to the cluster. // This value may be empty during cluster startup, and then will be updated @@ -127,7 +127,7 @@ type ClusterVersionStatus struct { // +nullable // +kubebuilder:validation:Required // +required - AvailableUpdates []Update `json:"availableUpdates"` + AvailableUpdates []Release `json:"availableUpdates"` } // UpdateState is a constant representing whether an update was successfully @@ -221,8 +221,7 @@ type ComponentOverride struct { // URL is a thin wrapper around string that ensures the string is a valid URL. type URL string -// Update represents a release of the ClusterVersionOperator, referenced by the -// Image member. +// Update represents an administrator update request. // +k8s:deepcopy-gen=true type Update struct { // version is a semantic versioning identifying the update version. When this @@ -251,6 +250,34 @@ type Update struct { Force bool `json:"force"` } +// Release represents an OpenShift release image and associated metadata. +// +k8s:deepcopy-gen=true +type Release struct { + // version is a semantic versioning identifying the update version. When this + // field is part of spec, version is optional if image is specified. + // +required + Version string `json:"version"` + + // image is a container image location that contains the update. When this + // field is part of spec, image is optional if version is specified and the + // availableUpdates field contains a matching version. + // +required + Image string `json:"image"` + + // url contains information about this release. This URL is set by + // the 'url' metadata property on a release or the metadata returned by + // the update API and should be displayed as a link in user + // interfaces. The URL field may not be set for test or nightly + // releases. + // +optional + URL URL `json:"url,omitempty"` + + // channels is the set of Cincinnati channels to which the release + // currently belongs. + // +optional + Channels []string `json:"channels,omitempty"` +} + // RetrievedUpdates reports whether available updates have been retrieved from // the upstream update server. The condition is Unknown before retrieval, False // if the updates could not be retrieved or recently failed, or True if the diff --git a/config/v1/zz_generated.deepcopy.go b/config/v1/zz_generated.deepcopy.go index b81e4cc1fd8..7542490ef97 100644 --- a/config/v1/zz_generated.deepcopy.go +++ b/config/v1/zz_generated.deepcopy.go @@ -929,7 +929,7 @@ func (in *ClusterVersionSpec) DeepCopy() *ClusterVersionSpec { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ClusterVersionStatus) DeepCopyInto(out *ClusterVersionStatus) { *out = *in - out.Desired = in.Desired + in.Desired.DeepCopyInto(&out.Desired) if in.History != nil { in, out := &in.History, &out.History *out = make([]UpdateHistory, len(*in)) @@ -946,8 +946,10 @@ func (in *ClusterVersionStatus) DeepCopyInto(out *ClusterVersionStatus) { } if in.AvailableUpdates != nil { in, out := &in.AvailableUpdates, &out.AvailableUpdates - *out = make([]Update, len(*in)) - copy(*out, *in) + *out = make([]Release, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } } return } @@ -3256,6 +3258,27 @@ func (in *RegistrySources) DeepCopy() *RegistrySources { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Release) DeepCopyInto(out *Release) { + *out = *in + if in.Channels != nil { + in, out := &in.Channels, &out.Channels + *out = make([]string, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Release. +func (in *Release) DeepCopy() *Release { + if in == nil { + return nil + } + out := new(Release) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *RemoteConnectionInfo) DeepCopyInto(out *RemoteConnectionInfo) { *out = *in diff --git a/config/v1/zz_generated.swagger_doc_generated.go b/config/v1/zz_generated.swagger_doc_generated.go index e1a47303a4a..9c4e90014c1 100644 --- a/config/v1/zz_generated.swagger_doc_generated.go +++ b/config/v1/zz_generated.swagger_doc_generated.go @@ -529,8 +529,20 @@ func (ComponentOverride) SwaggerDoc() map[string]string { return map_ComponentOverride } +var map_Release = map[string]string{ + "": "Release represents an OpenShift release image and associated metadata.", + "version": "version is a semantic versioning identifying the update version. When this field is part of spec, version is optional if image is specified.", + "image": "image is a container image location that contains the update. When this field is part of spec, image is optional if version is specified and the availableUpdates field contains a matching version.", + "url": "url contains information about this release. This URL is set by the 'url' metadata property on a release or the metadata returned by the update API and should be displayed as a link in user interfaces. The URL field may not be set for test or nightly releases.", + "channels": "channels is the set of Cincinnati channels to which the release currently belongs.", +} + +func (Release) SwaggerDoc() map[string]string { + return map_Release +} + var map_Update = map[string]string{ - "": "Update represents a release of the ClusterVersionOperator, referenced by the Image member.", + "": "Update represents an administrator update request.", "version": "version is a semantic versioning identifying the update version. When this field is part of spec, version is optional if image is specified.", "image": "image is a container image location that contains the update. When this field is part of spec, image is optional if version is specified and the availableUpdates field contains a matching version.", "force": "force allows an administrator to update to an image that has failed verification, does not appear in the availableUpdates list, or otherwise would be blocked by normal protections on update. This option should only be used when the authenticity of the provided image has been verified out of band because the provided image will run with full administrative access to the cluster. Do not use this flag with images that comes from unknown or potentially malicious sources.\n\nThis flag does not override other forms of consistency checking that are required before a new update is deployed.",