From b0f15904f4b2d5968723055e0b7719548c0efaab Mon Sep 17 00:00:00 2001 From: Li Zhang Date: Thu, 23 Jul 2026 13:53:49 +0800 Subject: [PATCH] Fix HPA status for unmanaged components --- pkg/cmpstatus/evaluator_test.go | 2 +- pkg/cmpstatus/hpa.go | 12 ++- pkg/cmpstatus/hpa_test.go | 157 +++++++++++++++++++++++++------- 3 files changed, 137 insertions(+), 34 deletions(-) diff --git a/pkg/cmpstatus/evaluator_test.go b/pkg/cmpstatus/evaluator_test.go index 9762256e6..acbdcf8ab 100644 --- a/pkg/cmpstatus/evaluator_test.go +++ b/pkg/cmpstatus/evaluator_test.go @@ -83,7 +83,7 @@ func TestEvaluate(t *testing.T) { Type: qv1.ComponentHPAReady, Status: metav1.ConditionFalse, Reason: qv1.ConditionReasonComponentNotReady, - Message: "Horizontal pod autoscaler not found", + Message: "Horizontal pod autoscaler registry-quay-app not found", }, { Type: qv1.ComponentRouteReady, diff --git a/pkg/cmpstatus/hpa.go b/pkg/cmpstatus/hpa.go index 5ddc9374d..1fb556e78 100644 --- a/pkg/cmpstatus/hpa.go +++ b/pkg/cmpstatus/hpa.go @@ -39,7 +39,15 @@ func (h *HPA) Check(ctx context.Context, reg qv1.QuayRegistry) (qv1.Condition, e }, nil } - for _, hpasuffix := range []string{"quay-app", "clair-app", "quay-mirror"} { + hpaSuffixes := []string{"quay-app"} + if qv1.ComponentIsManaged(reg.Spec.Components, qv1.ComponentClair) { + hpaSuffixes = append(hpaSuffixes, "clair-app") + } + if qv1.ComponentIsManaged(reg.Spec.Components, qv1.ComponentMirror) { + hpaSuffixes = append(hpaSuffixes, "quay-mirror") + } + + for _, hpasuffix := range hpaSuffixes { nsn := types.NamespacedName{ Namespace: reg.Namespace, Name: fmt.Sprintf("%s-%s", reg.Name, hpasuffix), @@ -52,7 +60,7 @@ func (h *HPA) Check(ctx context.Context, reg qv1.QuayRegistry) (qv1.Condition, e Type: qv1.ComponentHPAReady, Status: metav1.ConditionFalse, Reason: qv1.ConditionReasonComponentNotReady, - Message: "Horizontal pod autoscaler not found", + Message: fmt.Sprintf("Horizontal pod autoscaler %s not found", nsn.Name), LastUpdateTime: metav1.NewTime(time.Now()), }, nil } diff --git a/pkg/cmpstatus/hpa_test.go b/pkg/cmpstatus/hpa_test.go index 787a0cacb..4f9b697fc 100644 --- a/pkg/cmpstatus/hpa_test.go +++ b/pkg/cmpstatus/hpa_test.go @@ -14,6 +14,22 @@ import ( qv1 "github.com/quay/quay-operator/apis/quay/v1" ) +func ownedHPA(name string) *asv2.HorizontalPodAutoscaler { + return &asv2.HorizontalPodAutoscaler{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + OwnerReferences: []metav1.OwnerReference{ + { + Kind: "QuayRegistry", + Name: "registry", + APIVersion: "quay.redhat.com/v1", + UID: "uid", + }, + }, + }, + } +} + func TestHPACheck(t *testing.T) { for _, tt := range []struct { name string @@ -66,7 +82,7 @@ func TestHPACheck(t *testing.T) { Type: qv1.ComponentHPAReady, Status: metav1.ConditionFalse, Reason: qv1.ConditionReasonComponentNotReady, - Message: "Horizontal pod autoscaler not found", + Message: "Horizontal pod autoscaler registry-quay-app not found", }, }, { @@ -114,50 +130,129 @@ func TestHPACheck(t *testing.T) { Kind: qv1.ComponentHPA, Managed: true, }, + { + Kind: qv1.ComponentClair, + Managed: true, + }, + { + Kind: qv1.ComponentMirror, + Managed: true, + }, }, }, }, objs: []client.Object{ - &asv2.HorizontalPodAutoscaler{ - ObjectMeta: metav1.ObjectMeta{ - Name: "registry-quay-app", - OwnerReferences: []metav1.OwnerReference{ - { - Kind: "QuayRegistry", - Name: "registry", - APIVersion: "quay.redhat.com/v1", - UID: "uid", - }, + ownedHPA("registry-quay-app"), + ownedHPA("registry-quay-mirror"), + ownedHPA("registry-clair-app"), + }, + cond: qv1.Condition{ + Type: qv1.ComponentHPAReady, + Status: metav1.ConditionTrue, + Reason: qv1.ConditionReasonComponentReady, + Message: "Horizontal pod autoscaler found", + }, + }, + { + name: "hpa found with clair unmanaged", + quay: qv1.QuayRegistry{ + ObjectMeta: metav1.ObjectMeta{ + Name: "registry", + UID: "uid", + }, + Spec: qv1.QuayRegistrySpec{ + ConfigBundleSecret: "config-bundle", + Components: []qv1.Component{ + { + Kind: qv1.ComponentHPA, + Managed: true, + }, + { + Kind: qv1.ComponentClair, + Managed: false, + }, + { + Kind: qv1.ComponentMirror, + Managed: true, }, }, }, - &asv2.HorizontalPodAutoscaler{ - ObjectMeta: metav1.ObjectMeta{ - Name: "registry-quay-mirror", - OwnerReferences: []metav1.OwnerReference{ - { - Kind: "QuayRegistry", - Name: "registry", - APIVersion: "quay.redhat.com/v1", - UID: "uid", - }, + }, + objs: []client.Object{ + ownedHPA("registry-quay-app"), + ownedHPA("registry-quay-mirror"), + }, + cond: qv1.Condition{ + Type: qv1.ComponentHPAReady, + Status: metav1.ConditionTrue, + Reason: qv1.ConditionReasonComponentReady, + Message: "Horizontal pod autoscaler found", + }, + }, + { + name: "hpa found with mirror unmanaged", + quay: qv1.QuayRegistry{ + ObjectMeta: metav1.ObjectMeta{ + Name: "registry", + UID: "uid", + }, + Spec: qv1.QuayRegistrySpec{ + ConfigBundleSecret: "config-bundle", + Components: []qv1.Component{ + { + Kind: qv1.ComponentHPA, + Managed: true, + }, + { + Kind: qv1.ComponentClair, + Managed: true, + }, + { + Kind: qv1.ComponentMirror, + Managed: false, }, }, }, - &asv2.HorizontalPodAutoscaler{ - ObjectMeta: metav1.ObjectMeta{ - Name: "registry-clair-app", - OwnerReferences: []metav1.OwnerReference{ - { - Kind: "QuayRegistry", - Name: "registry", - APIVersion: "quay.redhat.com/v1", - UID: "uid", - }, + }, + objs: []client.Object{ + ownedHPA("registry-quay-app"), + ownedHPA("registry-clair-app"), + }, + cond: qv1.Condition{ + Type: qv1.ComponentHPAReady, + Status: metav1.ConditionTrue, + Reason: qv1.ConditionReasonComponentReady, + Message: "Horizontal pod autoscaler found", + }, + }, + { + name: "hpa found with clair and mirror unmanaged", + quay: qv1.QuayRegistry{ + ObjectMeta: metav1.ObjectMeta{ + Name: "registry", + UID: "uid", + }, + Spec: qv1.QuayRegistrySpec{ + ConfigBundleSecret: "config-bundle", + Components: []qv1.Component{ + { + Kind: qv1.ComponentHPA, + Managed: true, + }, + { + Kind: qv1.ComponentClair, + Managed: false, + }, + { + Kind: qv1.ComponentMirror, + Managed: false, }, }, }, }, + objs: []client.Object{ + ownedHPA("registry-quay-app"), + }, cond: qv1.Condition{ Type: qv1.ComponentHPAReady, Status: metav1.ConditionTrue,