Skip to content

Commit

Permalink
enhancements/update/available-update-metadata: Propose a new enhancement
Browse files Browse the repository at this point in the history
  • Loading branch information
wking committed Nov 19, 2019
1 parent a16654e commit 594521f
Showing 1 changed file with 173 additions and 0 deletions.
173 changes: 173 additions & 0 deletions enhancements/update/available-update-metadata.md
@@ -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

0 comments on commit 594521f

Please sign in to comment.