Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

*: Port from Update to Release for ClusterVersion status #419

Merged
merged 2 commits into from Aug 1, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/user/status.md
Expand Up @@ -110,7 +110,7 @@ It could also be an overloaded or otherwise failing Cincinnati server.

### ResponseInvalid

The Cincinnati server returned a response that was not valid JSON.
The Cincinnati server returned a response that was not valid JSON or is otherwise corrupted.

This could be caused by a buggy Cincinnati server.
It could also be caused by response corruption, e.g. if the configured `upstream` was in the clear over HTTP or via a man-in-the-middle HTTPS proxy, and an intervening component altered the response in flight.
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Expand Up @@ -11,7 +11,7 @@ require (
github.com/google/uuid v1.1.1
github.com/hashicorp/golang-lru v0.5.3 // indirect
github.com/imdario/mergo v0.3.8 // indirect
github.com/openshift/api v0.0.0-20200723134351-89de68875e7c
github.com/openshift/api v0.0.0-20200724204552-3ae6754513d4
github.com/openshift/client-go v0.0.0-20200723130357-94e1065ab1f8
github.com/openshift/library-go v0.0.0-20200724192307-1ed21c4fa86c
github.com/pkg/errors v0.9.1
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Expand Up @@ -337,6 +337,8 @@ github.com/openshift/api v0.0.0-20200722170803-0ba2c3658da6/go.mod h1:IXsT3F4NjL
github.com/openshift/api v0.0.0-20200723113038-c1d9554393d6/go.mod h1:IXsT3F4NjLtRzfnQvwU+g/oPWpoNsVV5vd5aaOMO8eU=
github.com/openshift/api v0.0.0-20200723134351-89de68875e7c h1:qsj/GaQ1sdT584yIcGmqqRpR5xtX5jTw5Gis3/09YI4=
github.com/openshift/api v0.0.0-20200723134351-89de68875e7c/go.mod h1:IXsT3F4NjLtRzfnQvwU+g/oPWpoNsVV5vd5aaOMO8eU=
github.com/openshift/api v0.0.0-20200724204552-3ae6754513d4 h1:sUTyOVzcbILg4Gtk2j+DLaV4vVnMmt8SNz3efONPQ/s=
github.com/openshift/api v0.0.0-20200724204552-3ae6754513d4/go.mod h1:IXsT3F4NjLtRzfnQvwU+g/oPWpoNsVV5vd5aaOMO8eU=
github.com/openshift/build-machinery-go v0.0.0-20200713135615-1f43d26dccc7/go.mod h1:b1BuldmJlbA/xYtdZvKi+7j5YGB44qJUJDZ9zwiNCfE=
github.com/openshift/client-go v0.0.0-20200722173614-5a1b0aaeff15/go.mod h1:yd4Zpcdk+8JyMWi6v+h78jPqK0FvXbJY41Wq3SZxl+c=
github.com/openshift/client-go v0.0.0-20200723130357-94e1065ab1f8 h1:rCyKXyp937G/UAen+i+m2pUNE7W4ScHpbAes7uhbJfg=
Expand Down
9 changes: 6 additions & 3 deletions pkg/autoupdate/autoupdate.go
Expand Up @@ -175,7 +175,10 @@ func (ctrl *Controller) sync(ctx context.Context, key string) error {
return nil
}
up := nextUpdate(clusterversion.Status.AvailableUpdates)
clusterversion.Spec.DesiredUpdate = &up
clusterversion.Spec.DesiredUpdate = &v1.Update{
Version: up.Version,
Image: up.Image,
}
wking marked this conversation as resolved.
Show resolved Hide resolved

_, updated, err := resourceapply.ApplyClusterVersionFromCache(ctx, ctrl.cvLister, ctrl.client.ConfigV1(), clusterversion)
if updated {
Expand All @@ -184,11 +187,11 @@ func (ctrl *Controller) sync(ctx context.Context, key string) error {
return err
}

func updateAvail(ups []v1.Update) bool {
func updateAvail(ups []v1.Release) bool {
return len(ups) > 0
}

func nextUpdate(ups []v1.Update) v1.Update {
func nextUpdate(ups []v1.Release) v1.Release {
sorted := ups
sort.Slice(sorted, func(i, j int) bool {
vi := semver.MustParse(sorted[i].Version)
Expand Down
4 changes: 2 additions & 2 deletions pkg/autoupdate/autoupdate_test.go
Expand Up @@ -29,9 +29,9 @@ func TestNextUpdate(t *testing.T) {
}}
for idx, test := range tests {
t.Run(fmt.Sprintf("test: #%d", idx), func(t *testing.T) {
ups := []v1.Update{}
ups := []v1.Release{}
for _, v := range test.avail {
ups = append(ups, v1.Update{Version: v})
ups = append(ups, v1.Release{Version: v})
}

got := nextUpdate(ups)
Expand Down
25 changes: 14 additions & 11 deletions pkg/cincinnati/cincinnati.go
Expand Up @@ -56,14 +56,15 @@ func (err *Error) Error() string {
return fmt.Sprintf("%s: %s", err.Reason, err.Message)
}

// GetUpdates fetches the next-applicable update payloads from the specified
// GetUpdates fetches the current and next-applicable update payloads from the specified
// upstream Cincinnati stack given the current version and channel. The next-
// applicable updates are determined by downloading the update graph, finding
// the current version within that graph (typically the root node), and then
// finding all of the children. These children are the available updates for
// the current version and their payloads indicate from where the actual update
// image can be downloaded.
func (c Client) GetUpdates(ctx context.Context, uri *url.URL, arch string, channel string, version semver.Version) ([]Update, error) {
func (c Client) GetUpdates(ctx context.Context, uri *url.URL, arch string, channel string, version semver.Version) (Update, []Update, error) {
var current Update
transport := http.Transport{}
// Prepare parametrized cincinnati query.
queryParams := uri.Query()
Expand All @@ -76,7 +77,7 @@ func (c Client) GetUpdates(ctx context.Context, uri *url.URL, arch string, chann
// Download the update graph.
req, err := http.NewRequest("GET", uri.String(), nil)
if err != nil {
return nil, &Error{Reason: "InvalidRequest", Message: err.Error(), cause: err}
return current, nil, &Error{Reason: "InvalidRequest", Message: err.Error(), cause: err}
}
req.Header.Add("Accept", GraphMediaType)
if c.tlsConfig != nil {
Expand All @@ -92,23 +93,23 @@ func (c Client) GetUpdates(ctx context.Context, uri *url.URL, arch string, chann
defer cancel()
resp, err := client.Do(req.WithContext(timeoutCtx))
if err != nil {
return nil, &Error{Reason: "RemoteFailed", Message: err.Error(), cause: err}
return current, nil, &Error{Reason: "RemoteFailed", Message: err.Error(), cause: err}
}
defer resp.Body.Close()

if resp.StatusCode != http.StatusOK {
return nil, &Error{Reason: "ResponseFailed", Message: fmt.Sprintf("unexpected HTTP status: %s", resp.Status)}
return current, nil, &Error{Reason: "ResponseFailed", Message: fmt.Sprintf("unexpected HTTP status: %s", resp.Status)}
}

// Parse the graph.
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, &Error{Reason: "ResponseFailed", Message: err.Error(), cause: err}
return current, nil, &Error{Reason: "ResponseFailed", Message: err.Error(), cause: err}
}

var graph graph
if err = json.Unmarshal(body, &graph); err != nil {
return nil, &Error{Reason: "ResponseInvalid", Message: err.Error(), cause: err}
return current, nil, &Error{Reason: "ResponseInvalid", Message: err.Error(), cause: err}
}

// Find the current version within the graph.
Expand All @@ -117,12 +118,13 @@ func (c Client) GetUpdates(ctx context.Context, uri *url.URL, arch string, chann
for i, node := range graph.Nodes {
if version.EQ(node.Version) {
currentIdx = i
current = Update(graph.Nodes[i])
found = true
break
}
}
if !found {
return nil, &Error{
return current, nil, &Error{
Reason: "VersionNotFound",
Message: fmt.Sprintf("currently installed version %s not found in the %q channel", version, channel),
}
Expand All @@ -141,7 +143,7 @@ func (c Client) GetUpdates(ctx context.Context, uri *url.URL, arch string, chann
updates = append(updates, Update(graph.Nodes[i]))
}

return updates, nil
return current, updates, nil
}

type graph struct {
Expand All @@ -150,8 +152,9 @@ type graph struct {
}

type node struct {
Version semver.Version `json:"version"`
Image string `json:"payload"`
Version semver.Version `json:"version"`
Image string `json:"payload"`
Metadata map[string]string `json:"metadata,omitempty"`
}

type edge struct {
Expand Down
52 changes: 31 additions & 21 deletions pkg/cincinnati/cincinnati_test.go
Expand Up @@ -25,26 +25,30 @@ func TestGetUpdates(t *testing.T) {
version string

expectedQuery string
current Update
available []Update
err string
}{{
name: "one update available",
version: "4.0.0-4",
expectedQuery: "arch=test-arch&channel=test-channel&id=01234567-0123-0123-0123-0123456789ab&version=4.0.0-4",
current: Update{Version: semver.MustParse("4.0.0-4"), Image: "quay.io/openshift-release-dev/ocp-release:4.0.0-4"},
available: []Update{
{semver.MustParse("4.0.0-5"), "quay.io/openshift-release-dev/ocp-release:4.0.0-5"},
{Version: semver.MustParse("4.0.0-5"), Image: "quay.io/openshift-release-dev/ocp-release:4.0.0-5"},
},
}, {
name: "two updates available",
version: "4.0.0-5",
expectedQuery: "arch=test-arch&channel=test-channel&id=01234567-0123-0123-0123-0123456789ab&version=4.0.0-5",
current: Update{Version: semver.MustParse("4.0.0-5"), Image: "quay.io/openshift-release-dev/ocp-release:4.0.0-5"},
available: []Update{
{semver.MustParse("4.0.0-6"), "quay.io/openshift-release-dev/ocp-release:4.0.0-6"},
{semver.MustParse("4.0.0-6+2"), "quay.io/openshift-release-dev/ocp-release:4.0.0-6+2"},
{Version: semver.MustParse("4.0.0-6"), Image: "quay.io/openshift-release-dev/ocp-release:4.0.0-6"},
{Version: semver.MustParse("4.0.0-6+2"), Image: "quay.io/openshift-release-dev/ocp-release:4.0.0-6+2"},
},
}, {
name: "no updates available",
version: "4.0.0-0.okd-0",
current: Update{Version: semver.MustParse("4.0.0-0.okd-0"), Image: "quay.io/openshift-release-dev/ocp-release:4.0.0-0.okd-0"},
expectedQuery: "arch=test-arch&channel=test-channel&id=01234567-0123-0123-0123-0123456789ab&version=4.0.0-0.okd-0",
}, {
name: "unknown version",
Expand Down Expand Up @@ -79,38 +83,31 @@ func TestGetUpdates(t *testing.T) {
"nodes": [
{
"version": "4.0.0-4",
"payload": "quay.io/openshift-release-dev/ocp-release:4.0.0-4",
"metadata": {}
"payload": "quay.io/openshift-release-dev/ocp-release:4.0.0-4"
},
{
"version": "4.0.0-5",
"payload": "quay.io/openshift-release-dev/ocp-release:4.0.0-5",
"metadata": {}
"payload": "quay.io/openshift-release-dev/ocp-release:4.0.0-5"
},
{
"version": "4.0.0-6",
"payload": "quay.io/openshift-release-dev/ocp-release:4.0.0-6",
"metadata": {}
"payload": "quay.io/openshift-release-dev/ocp-release:4.0.0-6"
},
{
"version": "4.0.0-6+2",
"payload": "quay.io/openshift-release-dev/ocp-release:4.0.0-6+2",
"metadata": {}
"payload": "quay.io/openshift-release-dev/ocp-release:4.0.0-6+2"
},
{
"version": "4.0.0-0.okd-0",
"payload": "quay.io/openshift-release-dev/ocp-release:4.0.0-0.okd-0",
"metadata": {}
"payload": "quay.io/openshift-release-dev/ocp-release:4.0.0-0.okd-0"
},
{
"version": "4.0.0-0.2",
"payload": "quay.io/openshift-release-dev/ocp-release:4.0.0-0.2",
"metadata": {}
"payload": "quay.io/openshift-release-dev/ocp-release:4.0.0-0.2"
},
{
"version": "4.0.0-0.3",
"payload": "quay.io/openshift-release-dev/ocp-release:4.0.0-0.3",
"metadata": {}
"payload": "quay.io/openshift-release-dev/ocp-release:4.0.0-0.3"
}
],
"edges": [[0,1],[1,2],[1,3],[5,6]]
Expand All @@ -133,13 +130,16 @@ func TestGetUpdates(t *testing.T) {
t.Fatal(err)
}

updates, err := c.GetUpdates(context.Background(), uri, arch, channelName, semver.MustParse(test.version))
current, updates, err := c.GetUpdates(context.Background(), uri, arch, channelName, semver.MustParse(test.version))
if test.err == "" {
if err != nil {
t.Fatalf("expected nil error, got: %v", err)
}
if !reflect.DeepEqual(current, test.current) {
t.Fatalf("expected current %v, got: %v", test.current, current)
}
if !reflect.DeepEqual(updates, test.available) {
t.Fatalf("expected %v, got: %v", test.available, updates)
t.Fatalf("expected updates %v, got: %v", test.available, updates)
}
} else {
if err == nil || err.Error() != test.err {
Expand Down Expand Up @@ -181,7 +181,11 @@ func Test_nodeUnmarshalJSON(t *testing.T) {
"metadata": {}
}`),

exp: node{semver.MustParse("4.0.0-5"), "quay.io/openshift-release-dev/ocp-release:4.0.0-5"},
exp: node{
Version: semver.MustParse("4.0.0-5"),
Image: "quay.io/openshift-release-dev/ocp-release:4.0.0-5",
Metadata: map[string]string{},
},
}, {
raw: []byte(`{
"version": "4.0.0-0.1",
Expand All @@ -190,7 +194,13 @@ func Test_nodeUnmarshalJSON(t *testing.T) {
"description": "This is the beta1 image based on the 4.0.0-0.nightly-2019-01-15-010905 build"
}
}`),
exp: node{semver.MustParse("4.0.0-0.1"), "quay.io/openshift-release-dev/ocp-release:4.0.0-0.1"},
exp: node{
Version: semver.MustParse("4.0.0-0.1"),
Image: "quay.io/openshift-release-dev/ocp-release:4.0.0-0.1",
Metadata: map[string]string{
"description": "This is the beta1 image based on the 4.0.0-0.nightly-2019-01-15-010905 build",
},
},
}, {
raw: []byte(`{
"version": "v4.0.0-0.1",
Expand Down