Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
enhancements/update/available-update-metadata: Propose a new enhancement
- Loading branch information
Showing
1 changed file
with
173 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,173 @@ | ||
--- | ||
title: available-update-metadata | ||
authors: | ||
- "@wking" | ||
reviewers: | ||
- "@abhinavdahiya" | ||
- "@crawford" | ||
approvers: | ||
- TBD | ||
creation-date: 2019-11-19 | ||
last-updated: 2019-11-19 | ||
status: implementable | ||
--- | ||
|
||
# Available-update Metadata | ||
|
||
Expose Cincinnati release metadata in ClusterVersion's `status.desired` and `status.availableUpdates`. | ||
|
||
## Release Signoff Checklist | ||
|
||
- [x] Enhancement is `implementable` | ||
- [ ] Design details are appropriately documented from clear requirements | ||
- [ ] Test plan is defined | ||
- [ ] Graduation criteria for dev preview, tech preview, GA | ||
- [ ] User-facing documentation is created in [openshift-docs](https://github.com/openshift/openshift-docs/) | ||
|
||
## Summary | ||
|
||
Currently the ClusterVersion API has [a single `Update` type][api-update] used for both [the `desiredUpdate` input][api-desiredUpdate] and the [`desired`][api-desired] and [`availableUpdates`][api-availableUpdates] outputs. | ||
But update requests like `desiredUpdate` have different schema requirements than output like `desired` and `availableUpdates`. | ||
For example, [the `force` property][api-force] makes sense in the `desiredUpdate` context, but not in the `availableUpdates` contexts. | ||
And release metadata like landing page URIs and release metadata makes sense in the `desired` and `availableUpdates` contexts, but not in the `desiredUpdate` context. | ||
This enhancement adds a new `Release` type to be used in `status` properties so we can distinguish between input and output schema. | ||
|
||
## Motivation | ||
|
||
Cincinnati provides [metadata about releases][cincinnati-metadata], including (since [here][cincinnati-channel-metadata]). | ||
Exposing that information to ClusterVersion consumers allows them to use live metadata, instead of talking to Cincinnati directly or hard-coding expected values. | ||
For example, the console currently [hard-codes an expected set of available channels][console-channels] for a given release; with this enhancement they could look up available channels in `status.desired.metadata["io.openshift.upgrades.graph.release.channels"]`. | ||
|
||
### Goals | ||
|
||
* Exposing release metadata provided by upstream Cincinnati for the currently-desired and available-update releases. | ||
* Documenting some well-known metadata keys. | ||
|
||
### Non-Goals | ||
|
||
* Restricting metadata keys to those documented in this enhancement. | ||
Cincinnati may continue to add and remove keys as they see fit as long as they provide at least the keys required by this enhancement. | ||
* Teaching Cincinnati to support requests without `channel` query parameters. | ||
This might be useful for recovering from users specifying [`desiredUpdate`][api-desiredUpdate] that were not in their configured [`channel`][api-channel], but I am fine leaving recovery to the users. | ||
They should have received sufficient information to adjust their channel from wherever they received the target release they are supplying. | ||
|
||
## Proposal | ||
|
||
As proposed in [this API pull request][api-pull-request], to add a new type: | ||
|
||
|
||
```go | ||
// Release represents an OpenShift release in the release graph. | ||
// +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. | ||
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. | ||
Image string `json:"image"` | ||
|
||
// metadata is additional metadata associated with the release, such | ||
// as associated channels (under | ||
// io.openshift.upgrades.graph.release.channels) or a landing page | ||
// (under url). | ||
// | ||
// +optional | ||
Metadata map[string]string `json:"metadata,omitempty"` | ||
} | ||
``` | ||
|
||
And to use that type instead of the current `Update` for | ||
`ClusterVersionStatus` properties. | ||
|
||
Then, in the cluster-version operator, to port existing logic like | ||
[available-update | ||
translation][cluster-version-operator-update-translation] and | ||
[available-update lookup][cluster-version-operator-update-lookup] to | ||
preserve the Cincinnati metadata. In some cases (when an | ||
administrator requested an update that was not in the available update | ||
set), this would require an additional Cincinnati request to retrieve | ||
metadata about the requested release. | ||
|
||
### Metadata properties | ||
|
||
This enhancement declares the following to be well-known metadata properties: | ||
|
||
* `url` (optional), a landing page for the release. | ||
For releases created by Red Hat, this will usually be the Errata for the release. | ||
* `io.openshift.upgrades.graph.release.channels` (optional), the comma-delimited set of channels to which the release currently belongs. | ||
|
||
Cincinnati implementation may, at their discretion, define, add, and remove additional properties as they see fit. | ||
|
||
### User Stories | ||
|
||
#### Dynamic Channel Selection | ||
|
||
Alice's cluster is on release 4.1.23, and she wants to know if she can update to 4.2. | ||
With interfaces like the console and `oc adm upgrade ...` exposing: | ||
|
||
```console | ||
$ curl -sH 'Accept:application/json' 'https://api.stage.openshift.com/api/upgrades_info/v1/graph?channel=stable-4.1&version=4.1.23' | jq -r '.nodes[] | select(.version == "4.1.23").metadata["io.openshift.upgrades.graph.release.channels"] | split(",")[]' | ||
prerelease-4.1 | ||
stable-4.1 | ||
candidate-4.2 | ||
``` | ||
|
||
she could see that, while upgrading to 4.2 was possible, it was not yet considered stable. | ||
And running the query again later, she could see that it had been added to `stable-4.2`. | ||
|
||
### Risks and Mitigations | ||
|
||
There is no security risk, because this is only exposing through ClusterVersion information that is already public via direct Cincinnati requests. | ||
|
||
## Design Details | ||
|
||
### Test Plan | ||
|
||
There will be no testing outside of cluster-version operator unit tests, where a test harness already exists with [mock Cincinnati responses][cluster-version-operator-available-updates-handler]. | ||
|
||
### Graduation Criteria | ||
|
||
The ClusterVersion object is already GA, so there would be nothing to graduate or space to cool a preview implementation. | ||
|
||
##### Removing a deprecated feature | ||
|
||
This change would remove [the `force` property][api-force] from [`desired`][api-desired] and [`availableUpdates`][api-availableUpdates]. | ||
But that property was optional before and did not have clear semantics in either location, so the removal should break no consumers. | ||
|
||
### Upgrade / Downgrade Strategy | ||
|
||
The YAML rendering of the old and updated type are compatible, with the only difference being optional properties, so there is no need for upgrade/downgrade logic. | ||
|
||
### Version Skew Strategy | ||
|
||
The YAML rendering of the old and updated type are compatible, with the only difference being optional properties, so there is no need for upgrade/downgrade logic. | ||
|
||
## Implementation History | ||
|
||
* [API pull request][api-pull-request]. | ||
|
||
## Drawbacks | ||
|
||
A risk in exposing metadata is that users would rely on unstable metadata properties not defined in this enhancement, and then break when Cincinnati removed the property. | ||
The instability of those properties is clearly explained in this enhancement, but that doesn't mean that users will be happy if they decide to take a risk on an unstable metadata property that is subsequently removed. | ||
|
||
## Alternatives | ||
|
||
Components like the console could bypass ClusterVersion and talk to the upstream Cincinnati directly, but this would require significant code duplication. | ||
|
||
[api-availableUpdates]: https://github.com/openshift/api/blob/082f8e2a947ea8b4ed15c9c0f7b190d1fd35e6bc/config/v1/types_cluster_version.go#L123-L130 | ||
[api-channel]: https://github.com/openshift/api/blob/082f8e2a947ea8b4ed15c9c0f7b190d1fd35e6bc/config/v1/types_cluster_version.go#L61-L66 | ||
[api-desired]: https://github.com/openshift/api/blob/082f8e2a947ea8b4ed15c9c0f7b190d1fd35e6bc/config/v1/types_cluster_version.go#L82-L87 | ||
[api-desiredUpdate]: https://github.com/openshift/api/blob/082f8e2a947ea8b4ed15c9c0f7b190d1fd35e6bc/config/v1/types_cluster_version.go#L40-L54 | ||
[api-force]: https://github.com/openshift/api/blob/082f8e2a947ea8b4ed15c9c0f7b190d1fd35e6bc/config/v1/types_cluster_version.go#L239-L251 | ||
[api-pull-request]: https://github.com/openshift/api/pull/521#issuecomment-555649500 | ||
[api-update]: https://github.com/openshift/api/blob/082f8e2a947ea8b4ed15c9c0f7b190d1fd35e6bc/config/v1/types_cluster_version.go#L224-L252 | ||
[cincinnati-channel-metadata]: https://github.com/openshift/cincinnati/pull/167 | ||
[cincinnati-metadata]: https://github.com/openshift/cincinnati/blob/c59f45c7bc09740055c54a28f2b8cac250f8e356/docs/design/cincinnati.md#update-graph | ||
[cluster-version-operator-available-updates-handler]: https://github.com/openshift/cluster-version-operator/blob/751c6d0c872e05f218f01d2a9f20293b4dfcca88/pkg/cvo/cvo_test.go#L2284 | ||
[cluster-version-operator-update-lookup]: https://github.com/openshift/cluster-version-operator/blob/01adf75393b6e11d3d8c98ecfeeebd3feb998a6c/pkg/cvo/updatepayload.go#L297-L309 | ||
[cluster-version-operator-update-translation]: https://github.com/openshift/cluster-version-operator/blob/8240a9b3711fa6938129d06ee8c6957a8f3b6464/pkg/cvo/availableupdates.go#L192-L198 | ||
[console-channels]: https://github.com/openshift/console/pull/2935 |