-
Notifications
You must be signed in to change notification settings - Fork 4.7k
/
Copy pathclusterversion.go
115 lines (108 loc) · 3.67 KB
/
clusterversion.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
package util
import (
"context"
"encoding/json"
"fmt"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
restclient "k8s.io/client-go/rest"
"k8s.io/kubernetes/test/e2e/framework"
e2epod "k8s.io/kubernetes/test/e2e/framework/pod"
configv1 "github.com/openshift/api/config/v1"
configv1client "github.com/openshift/client-go/config/clientset/versioned"
)
// GetClusterVersion returns the ClusterVersion object.
func GetClusterVersion(ctx context.Context, config *restclient.Config) (*configv1.ClusterVersion, error) {
c, err := configv1client.NewForConfig(config)
if err != nil {
return nil, err
}
cv, err := c.ConfigV1().ClusterVersions().Get(ctx, "version", metav1.GetOptions{})
if err != nil {
return nil, err
}
return cv, nil
}
// GetCurrentVersion determines and returns the cluster's current version by iterating through the
// provided update history until it finds the first version with update State of Completed. If a
// Completed version is not found the version of the oldest history entry, which is the originally
// installed version, is returned. If history is empty the empty string is returned.
func GetCurrentVersion(ctx context.Context, config *restclient.Config) (string, error) {
cv, err := GetClusterVersion(ctx, config)
if err != nil {
return "", err
}
for _, h := range cv.Status.History {
if h.State == configv1.CompletedUpdate {
return h.Version, nil
}
}
// Empty history should only occur if method is called early in startup before history is populated.
if len(cv.Status.History) != 0 {
return cv.Status.History[len(cv.Status.History)-1].Version, nil
}
return "", nil
}
// GetReleaseImage returns ReleaseImage.
func GetReleaseImage(ctx context.Context, config *restclient.Config) (string, error) {
cv, err := GetClusterVersion(ctx, config)
if err != nil {
return "", err
}
return cv.Status.Desired.Image, nil
}
// DetermineImageFromRelease will get the image and tag for imageTagName from the release image.
// For example, you can specify oauth-server for the oauth-server image or network-tools to get the image
// and tag for that image.
func DetermineImageFromRelease(ctx context.Context, oc *CLI, imageTagName string) (string, error) {
releaseImage, err := GetReleaseImage(ctx, oc.AdminConfig())
if err != nil {
return "", err
}
if len(releaseImage) == 0 {
return "", fmt.Errorf("cannot determine release image from ClusterVersion resource")
}
podName := "extract-release-imagerefs"
podClient := e2epod.PodClientNS(oc.KubeFramework(), oc.Namespace())
podClient.CreateSync(ctx, &corev1.Pod{
ObjectMeta: metav1.ObjectMeta{Name: podName},
Spec: corev1.PodSpec{
Containers: []corev1.Container{
{
Name: "imagerefs",
Image: releaseImage,
Command: []string{"/bin/sleep", "10000"},
},
},
},
})
defer func() {
podClient.Delete(ctx, podName, metav1.DeleteOptions{})
err = e2epod.WaitForPodNotFoundInNamespace(ctx, oc.kubeFramework.ClientSet,
podName, oc.Namespace(), e2epod.PodDeleteTimeout)
if err != nil {
framework.Logf("pod %q is still found in namespace %q", podName, oc.Namespace())
}
}()
imageRefsString := e2epod.ExecShellInContainer(oc.KubeFramework(), podName, "imagerefs", "cat /release-manifests/image-references")
imageRefs := struct {
Spec struct {
Tags []struct {
Name string `json:"name"`
From struct {
Name string `json:"name"`
} `json:"from"`
} `json:"tags"`
} `json:"spec"`
}{}
err = json.Unmarshal([]byte(imageRefsString), &imageRefs)
if err != nil {
return "", err
}
for _, t := range imageRefs.Spec.Tags {
if t.Name == imageTagName {
return t.From.Name, nil
}
}
return "", fmt.Errorf("Could not find image: %s", imageTagName)
}