Skip to content

Commit e12d50c

Browse files
committed
Fix panic in finalizer handler
1 parent 37a7cc1 commit e12d50c

File tree

8 files changed

+116
-26
lines changed

8 files changed

+116
-26
lines changed

.gitignore

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
tmp/_output
55
tmp/_test
66
deploy/test
7-
cluster-image-registry-operator
87

98
#idea dev tools
109
.idea/

pkg/operator/finalizer.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ func (c *Controller) finalizeResources(o *imageregistryv1.Config) error {
5757
if cr == nil {
5858
// Skip using the cache here so we don't have as many
5959
// retries due to slow cache updates
60-
cr, err := client.Configs().Get(
60+
cr, err = client.Configs().Get(
6161
context.TODO(), o.Name, metav1.GetOptions{},
6262
)
6363
if err != nil {

test/framework/clusteroperators.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ func AreClusterOperatorsHealthy(cos []configv1.ClusterOperator) error {
3434
return utilerrors.NewAggregate(errs)
3535
}
3636

37-
func EnsureClusterOperatorsAreHealthy(te TestEnv, interval, timeout time.Duration) {
37+
func WaitUntilClusterOperatorsAreHealthy(te TestEnv, interval, timeout time.Duration) {
3838
ctx := context.Background()
3939
start := time.Now()
4040
var lastErr error

test/framework/imageregistry.go

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
appsv1 "k8s.io/api/apps/v1"
1111
"k8s.io/apimachinery/pkg/api/errors"
1212
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
13+
"k8s.io/apimachinery/pkg/labels"
1314
"k8s.io/apimachinery/pkg/types"
1415
"k8s.io/apimachinery/pkg/util/wait"
1516
"k8s.io/client-go/util/retry"
@@ -88,7 +89,8 @@ func (c ImageRegistryConditions) String() string {
8889
)
8990
}
9091

91-
func ensureImageRegistryToBeRemoved(te TestEnv) {
92+
func removeImageRegistry(te TestEnv) {
93+
te.Logf("uninstalling the image registry...")
9294
if _, err := te.Client().Configs().Patch(
9395
context.Background(),
9496
defaults.ImageRegistryResourceName,
@@ -130,6 +132,7 @@ func ensureImageRegistryToBeRemoved(te TestEnv) {
130132
}
131133

132134
func deleteImageRegistryConfig(te TestEnv) {
135+
te.Logf("deleting the image registry config...")
133136
// TODO(dmage): the finalizer should be removed by the operator
134137
if err := retry.RetryOnConflict(retry.DefaultBackoff, func() error {
135138
cr, err := te.Client().Configs().Get(
@@ -165,6 +168,19 @@ func deleteImageRegistryConfig(te TestEnv) {
165168
}
166169
}
167170

171+
func deleteLeaderElectionConfigMap(te TestEnv, name string) {
172+
err := te.Client().ConfigMaps(OperatorDeploymentNamespace).Delete(
173+
context.Background(),
174+
name,
175+
metav1.DeleteOptions{},
176+
)
177+
if err == nil {
178+
te.Logf("leader election configmap %s deleted", name)
179+
} else if !errors.IsNotFound(err) {
180+
te.Errorf("unable to delete leader election configmap %s: %s", name, err)
181+
}
182+
}
183+
168184
func deleteNodeCADaemonSet(te TestEnv) {
169185
ds, err := te.Client().DaemonSets(defaults.ImageRegistryOperatorNamespace).Get(
170186
context.Background(),
@@ -224,18 +240,16 @@ func deleteImageRegistryCertificates(te TestEnv) {
224240
}
225241

226242
func deleteImageRegistryAlwaysPresentResources(te TestEnv) {
243+
te.Logf("deleting always-present resources...")
227244
defer deleteImageRegistryCertificates(te)
228245
defer deleteNodeCADaemonSet(te)
246+
defer deleteLeaderElectionConfigMap(te, "openshift-master-controllers")
229247
}
230248

231249
func RemoveImageRegistry(te TestEnv) {
232-
te.Logf("uninstalling the image registry...")
233-
ensureImageRegistryToBeRemoved(te)
234-
te.Logf("stopping the operator...")
250+
removeImageRegistry(te)
235251
StopDeployment(te, OperatorDeploymentNamespace, OperatorDeploymentName)
236-
te.Logf("deleting the image registry config...")
237252
deleteImageRegistryConfig(te)
238-
te.Logf("deleting always-present resources...")
239253
deleteImageRegistryAlwaysPresentResources(te)
240254
}
241255

@@ -255,7 +269,6 @@ func DeployImageRegistry(te TestEnv, spec *imageregistryapiv1.ImageRegistrySpec)
255269
}
256270
}
257271

258-
te.Logf("starting the operator...")
259272
startOperator(te)
260273
}
261274

@@ -505,10 +518,10 @@ func SetupAvailableImageRegistry(t *testing.T, spec *imageregistryapiv1.ImageReg
505518
}
506519

507520
func TeardownImageRegistry(te TestEnv) {
508-
defer func() {
509-
RemoveImageRegistry(te)
510-
EnsureClusterOperatorsAreHealthy(te, 10*time.Second, AsyncOperationTimeout)
511-
}()
521+
defer WaitUntilClusterOperatorsAreHealthy(te, 10*time.Second, AsyncOperationTimeout)
522+
defer CheckAbsenceOfOperatorPods(te)
523+
defer RemoveImageRegistry(te)
524+
defer CheckPodsAreNotRestarted(te, labels.Everything())
512525
if te.Failed() {
513526
DumpImageRegistryResource(te)
514527
DumpOperatorDeployment(te)

test/framework/logs.go

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"fmt"
77
"io"
88
"regexp"
9+
"strings"
910

1011
corev1 "k8s.io/api/core/v1"
1112
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -44,7 +45,7 @@ func (psl PodSetLogs) Contains(re *regexp.Regexp) bool {
4445
return false
4546
}
4647

47-
func GetLogsByLabelSelector(client *Clientset, namespace string, labelSelector *metav1.LabelSelector) (PodSetLogs, error) {
48+
func GetLogsByLabelSelector(client *Clientset, namespace string, labelSelector *metav1.LabelSelector, previous bool) (PodSetLogs, error) {
4849
selector, err := metav1.LabelSelectorAsSelector(labelSelector)
4950
if err != nil {
5051
return nil, err
@@ -61,7 +62,7 @@ func GetLogsByLabelSelector(client *Clientset, namespace string, labelSelector *
6162

6263
podLogs := make(PodSetLogs)
6364
for _, pod := range podList.Items {
64-
podLog, err := readPodLogs(client, &pod)
65+
podLog, err := readPodLogs(client, &pod, previous)
6566
if err != nil {
6667
return nil, err
6768
}
@@ -76,7 +77,7 @@ func GetLogsForPod(client *Clientset, namespace string, podName string) (PodSetL
7677
if err != nil {
7778
return nil, err
7879
}
79-
podLogs, err := readPodLogs(client, pod)
80+
podLogs, err := readPodLogs(client, pod, false)
8081
if err != nil {
8182
return nil, err
8283
}
@@ -85,12 +86,13 @@ func GetLogsForPod(client *Clientset, namespace string, podName string) (PodSetL
8586
return podSetLogs, nil
8687
}
8788

88-
func readPodLogs(client *Clientset, pod *corev1.Pod) (PodLog, error) {
89+
func readPodLogs(client *Clientset, pod *corev1.Pod, previous bool) (PodLog, error) {
8990
podLog := make(PodLog)
9091
for _, container := range pod.Spec.Containers {
9192
var containerLog ContainerLog
9293
log, err := client.Pods(pod.Namespace).GetLogs(pod.Name, &corev1.PodLogOptions{
9394
Container: container.Name,
95+
Previous: previous,
9496
}).Stream(context.Background())
9597
if err != nil {
9698
return nil, fmt.Errorf("failed to get logs for pod %s: %s", pod.Name, err)
@@ -114,13 +116,16 @@ func readPodLogs(client *Clientset, pod *corev1.Pod) (PodLog, error) {
114116

115117
func DumpPodLogs(logger Logger, podLogs PodSetLogs) {
116118
if len(podLogs) > 0 {
117-
for pod, logs := range podLogs {
118-
logger.Logf("=== logs for pod/%s", pod)
119-
for _, line := range logs {
120-
logger.Logf("%s", line)
119+
for pod, containers := range podLogs {
120+
for container, logs := range containers {
121+
var buf strings.Builder
122+
fmt.Fprintf(&buf, "logs for pod/%s (container %s)\n", pod, container)
123+
for _, line := range logs {
124+
fmt.Fprintf(&buf, "%s", line)
125+
}
126+
logger.Logf("%s", buf.String())
121127
}
122128
}
123-
logger.Logf("=== end of logs")
124129
}
125130
}
126131

test/framework/operator.go

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package framework
22

33
import (
44
"context"
5+
"strings"
56
"time"
67

78
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -10,6 +11,7 @@ import (
1011
)
1112

1213
func startOperator(te TestEnv) {
14+
te.Logf("starting the operator...")
1315
if _, err := te.Client().Deployments(OperatorDeploymentNamespace).Patch(
1416
context.Background(),
1517
OperatorDeploymentName,
@@ -32,7 +34,25 @@ func DumpOperatorDeployment(te TestEnv) {
3234
DumpYAML(te, "the operator deployment", deployment)
3335
}
3436

37+
func CheckAbsenceOfOperatorPods(te TestEnv) {
38+
pods, err := te.Client().Pods(OperatorDeploymentNamespace).List(context.Background(), metav1.ListOptions{})
39+
if err != nil {
40+
te.Fatalf("failed to list the pods: %s", err)
41+
}
42+
i := 0
43+
for _, pod := range pods.Items {
44+
if strings.HasPrefix(pod.Name, OperatorDeploymentName+"-") {
45+
te.Errorf("unexpected operator pod %s (%s old)", pod.Name, time.Since(pod.CreationTimestamp.Time))
46+
i++
47+
}
48+
}
49+
if i > 0 {
50+
te.Fatalf("found %d unexpected operator pod(s)", i)
51+
}
52+
}
53+
3554
func StopDeployment(te TestEnv, namespace, name string) {
55+
te.Logf("scaling down the deployment %s/%s...", namespace, name)
3656
var realErr error
3757
err := wait.Poll(1*time.Second, 30*time.Second, func() (bool, error) {
3858
if _, realErr = te.Client().Deployments(namespace).Patch(
@@ -59,7 +79,7 @@ func GetOperatorLogs(client *Clientset) (PodSetLogs, error) {
5979
MatchLabels: map[string]string{
6080
"name": "cluster-image-registry-operator",
6181
},
62-
})
82+
}, false)
6383
}
6484

6585
func DumpOperatorLogs(te TestEnv) {

test/framework/pods.go

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package framework
2+
3+
import (
4+
"context"
5+
6+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
7+
"k8s.io/apimachinery/pkg/labels"
8+
)
9+
10+
func CheckPodsAreNotRestarted(te TestEnv, labels labels.Selector) {
11+
pods, err := te.Client().Pods(OperatorDeploymentNamespace).List(
12+
context.Background(),
13+
metav1.ListOptions{
14+
LabelSelector: labels.String(),
15+
},
16+
)
17+
if err != nil {
18+
te.Fatalf("failed to list pods: %s", err)
19+
}
20+
for _, pod := range pods.Items {
21+
for _, container := range pod.Status.InitContainerStatuses {
22+
if container.RestartCount > 0 {
23+
te.Errorf("pod %s/%s: init container %s: restarted %d time(s)", pod.Namespace, pod.Name, container.Name, container.RestartCount)
24+
}
25+
}
26+
for _, container := range pod.Status.ContainerStatuses {
27+
if container.RestartCount > 0 {
28+
te.Errorf("pod %s/%s: container %s: restarted %d time(s)", pod.Namespace, pod.Name, container.Name, container.RestartCount)
29+
}
30+
}
31+
}
32+
}

test/framework/testenv.go

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
package framework
22

3-
import "testing"
3+
import (
4+
"testing"
5+
"time"
6+
)
47

58
type TestEnv interface {
69
Client() *Clientset
@@ -24,12 +27,30 @@ func Setup(t *testing.T) TestEnv {
2427
t.Fatal(err)
2528
}
2629

27-
return &testEnv{
30+
te := &testEnv{
2831
T: t,
2932
client: client,
3033
}
34+
CheckAbsenceOfOperatorPods(te)
35+
return te
36+
}
37+
38+
func (te *testEnv) timestamp() string {
39+
return time.Now().UTC().Format("15:04:05.000")
3140
}
3241

3342
func (te *testEnv) Client() *Clientset {
3443
return te.client
3544
}
45+
46+
func (te *testEnv) Log(a ...interface{}) {
47+
te.T.Helper()
48+
args := append([]interface{}{te.timestamp()}, a...)
49+
te.T.Log(args...)
50+
}
51+
52+
func (te *testEnv) Logf(format string, a ...interface{}) {
53+
te.T.Helper()
54+
args := append([]interface{}{te.timestamp()}, a...)
55+
te.T.Logf("%s "+format, args...)
56+
}

0 commit comments

Comments
 (0)