Skip to content

Commit 755637f

Browse files
committed
HAWNG-1855: Implements the update poller and integrates it into hawtio controller
* hawtio_controller.go * Adds a watch on the update channel. If the channel signals there is new data then the reconcile loop will be executed. * Adds both the channel and the poller to the ReconcileHawtio object to make them available to the deployment reconciler. * lifecycle.go * Improves handleResultAndError to allow for a requeue of the reconciler if the reconcile functions require it - requires a RequeueError * reconcile_deployment.go * If the updatePoller has been initialized then fetch the digests * Should the digests not be returned yet, requeue and await the response * Should the poller have errored then ignore and continue with the original image urls * manager.go * Creates the update poller and channel for the background thread * poller.go * The poller that runs in the background thread and checks the image digests at the interval specified
1 parent 90c656b commit 755637f

12 files changed

Lines changed: 784 additions & 59 deletions

File tree

go.mod

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ require (
1616
github.com/go-logr/logr v1.4.3
1717
github.com/go-logr/zapr v1.3.0
1818
github.com/google/go-cmp v0.7.0
19+
github.com/google/go-containerregistry v0.21.5
1920
github.com/onsi/ginkgo/v2 v2.28.1
2021
github.com/onsi/gomega v1.39.1
2122
github.com/openshift/api v0.0.0-20251016080153-44baf885fd37
@@ -48,7 +49,6 @@ require (
4849
github.com/gogo/protobuf v1.3.2 // indirect
4950
github.com/google/btree v1.1.3 // indirect
5051
github.com/google/gnostic-models v0.7.0 // indirect
51-
github.com/google/go-containerregistry v0.21.5 // indirect
5252
github.com/google/pprof v0.0.0-20260115054156-294ebfa9ad83 // indirect
5353
github.com/google/uuid v1.6.0 // indirect
5454
github.com/josharian/intern v1.0.0 // indirect
@@ -87,6 +87,7 @@ require (
8787
gopkg.in/evanphx/json-patch.v4 v4.13.0 // indirect
8888
gopkg.in/inf.v0 v0.9.1 // indirect
8989
gopkg.in/yaml.v3 v3.0.1 // indirect
90+
gotest.tools/v3 v3.5.2 // indirect
9091
k8s.io/klog/v2 v2.130.1 // indirect
9192
k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912 // indirect
9293
sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect

go.sum

Lines changed: 2 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,6 @@ github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnr
7171
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
7272
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
7373
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
74-
github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo=
75-
github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ=
7674
github.com/klauspost/compress v1.18.5 h1:/h1gH5Ce+VWNLSWqPzOVn6XBO+vJbCNGvjoaGBFW2IE=
7775
github.com/klauspost/compress v1.18.5/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ=
7876
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
@@ -129,8 +127,6 @@ github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 h1:lZUw3E0/J3roVtGQ+SCrUrg3ON6Ng
129127
github.com/santhosh-tekuri/jsonschema/v5 v5.3.1/go.mod h1:uToXkOrWAZ6/Oc07xWQrPOhJotwFIyu2bBVN41fcDUY=
130128
github.com/sirupsen/logrus v1.9.4 h1:TsZE7l11zFCLZnZ+teH4Umoq5BhEIfIzfRDZ1Uzql2w=
131129
github.com/sirupsen/logrus v1.9.4/go.mod h1:ftWc9WdOfJ0a92nsE2jF5u5ZwH8Bv2zdeOC42RjbV2g=
132-
github.com/spf13/pflag v1.0.9 h1:9exaQaMOCwffKiiiYk6/BndUBv+iRViNW+4lEMi0PvY=
133-
github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
134130
github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk=
135131
github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
136132
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
@@ -168,44 +164,30 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U
168164
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
169165
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
170166
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
171-
golang.org/x/mod v0.32.0 h1:9F4d3PHLljb6x//jOyokMv3eX+YDeepZSEo3mFJy93c=
172-
golang.org/x/mod v0.32.0/go.mod h1:SgipZ/3h2Ci89DlEtEXWUk/HteuRin+HHhN+WbNhguU=
173167
golang.org/x/mod v0.35.0 h1:Ww1D637e6Pg+Zb2KrWfHQUnH2dQRLBQyAtpr/haaJeM=
174168
golang.org/x/mod v0.35.0/go.mod h1:+GwiRhIInF8wPm+4AoT6L0FA1QWAad3OMdTRx4tFYlU=
175169
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
176170
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
177171
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
178172
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
179-
golang.org/x/net v0.49.0 h1:eeHFmOGUTtaaPSGNmjBKpbng9MulQsJURQUAfUwY++o=
180-
golang.org/x/net v0.49.0/go.mod h1:/ysNB2EvaqvesRkuLAyjI1ycPZlQHM3q01F02UY/MV8=
181173
golang.org/x/net v0.53.0 h1:d+qAbo5L0orcWAr0a9JweQpjXF19LMXJE8Ey7hwOdUA=
182174
golang.org/x/net v0.53.0/go.mod h1:JvMuJH7rrdiCfbeHoo3fCQU24Lf5JJwT9W3sJFulfgs=
183-
golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI=
184-
golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU=
185175
golang.org/x/oauth2 v0.36.0 h1:peZ/1z27fi9hUOFCAZaHyrpWG5lwe0RJEEEeH0ThlIs=
186176
golang.org/x/oauth2 v0.36.0/go.mod h1:YDBUJMTkDnJS+A4BP4eZBjCqtokkg1hODuPjwiGPO7Q=
187177
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
188178
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
189179
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
190-
golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4=
191-
golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
192180
golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4=
193181
golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0=
194182
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
195183
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
196184
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
197-
golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ=
198-
golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
199185
golang.org/x/sys v0.43.0 h1:Rlag2XtaFTxp19wS8MXlJwTvoh8ArU6ezoyFsMyCTNI=
200186
golang.org/x/sys v0.43.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
201-
golang.org/x/term v0.39.0 h1:RclSuaJf32jOqZz74CkPA9qFuVTX7vhLlpfj/IGWlqY=
202-
golang.org/x/term v0.39.0/go.mod h1:yxzUCTP/U+FzoxfdKmLaA0RV1WgE0VY7hXBwKtY/4ww=
203187
golang.org/x/term v0.42.0 h1:UiKe+zDFmJobeJ5ggPwOshJIVt6/Ft0rcfrXZDLWAWY=
204188
golang.org/x/term v0.42.0/go.mod h1:Dq/D+snpsbazcBG5+F9Q1n2rXV8Ma+71xEjTRufARgY=
205189
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
206190
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
207-
golang.org/x/text v0.33.0 h1:B3njUFyqtHDUI5jMn1YIr5B0IE2U0qck04r6d4KPAxE=
208-
golang.org/x/text v0.33.0/go.mod h1:LuMebE6+rBincTi9+xWTY8TztLzKHc/9C1uBCG27+q8=
209191
golang.org/x/text v0.36.0 h1:JfKh3XmcRPqZPKevfXVpI1wXPTqbkE5f7JA92a55Yxg=
210192
golang.org/x/text v0.36.0/go.mod h1:NIdBknypM8iqVmPiuco0Dh6P5Jcdk8lJL0CUebqK164=
211193
golang.org/x/time v0.9.0 h1:EsRrnYcQiGH+5FfbgvV4AP7qEZstoyrHB0DzarOQ4ZY=
@@ -214,8 +196,6 @@ golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGm
214196
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
215197
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
216198
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
217-
golang.org/x/tools v0.41.0 h1:a9b8iMweWG+S0OBnlU36rzLp20z1Rp10w+IY2czHTQc=
218-
golang.org/x/tools v0.41.0/go.mod h1:XSY6eDqxVNiYgezAVqqCeihT4j1U2CCsqvH3WhQpnlg=
219199
golang.org/x/tools v0.44.0 h1:UP4ajHPIcuMjT1GqzDWRlalUEoY+uzoZKnhOjbIPD2c=
220200
golang.org/x/tools v0.44.0/go.mod h1:KA0AfVErSdxRZIsOVipbv3rQhVXTnlU6UhKxHd1seDI=
221201
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
@@ -235,6 +215,8 @@ gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
235215
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
236216
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
237217
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
218+
gotest.tools/v3 v3.5.2 h1:7koQfIKdy+I8UTetycgUqXWSDwpgv193Ka+qRsmBY8Q=
219+
gotest.tools/v3 v3.5.2/go.mod h1:LtdLGcnqToBH83WByAAi/wiwSFCArdFIUV/xxN4pcjA=
238220
k8s.io/api v0.35.3 h1:pA2fiBc6+N9PDf7SAiluKGEBuScsTzd2uYBkA5RzNWQ=
239221
k8s.io/api v0.35.3/go.mod h1:9Y9tkBcFwKNq2sxwZTQh1Njh9qHl81D0As56tu42GA4=
240222
k8s.io/apiextensions-apiserver v0.35.3 h1:2fQUhEO7P17sijylbdwt0nBdXP0TvHrHj0KeqHD8FiU=

pkg/controller/hawtio/hawtio_controller.go

Lines changed: 60 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ import (
4242
oresources "github.com/hawtio/hawtio-operator/pkg/resources/openshift"
4343
"github.com/hawtio/hawtio-operator/pkg/util"
4444
"github.com/hawtio/hawtio-operator/pkg/clients"
45+
"github.com/hawtio/hawtio-operator/pkg/updater"
4546
)
4647

4748
var hawtioLogger = logf.Log.WithName("controller_hawtio")
@@ -53,13 +54,32 @@ const (
5354

5455
var ErrLegacyResourceAdopted = errs.New("A legacy resource has been adopted, requeue required")
5556

57+
// ReconcileHawtio reconciles a Hawtio object
58+
type ReconcileHawtio struct {
59+
util.BuildVariables
60+
// This client, initialized using mgr.Client() above, is a split client
61+
// that reads objects from the cache and writes to the API server
62+
client client.Client
63+
scheme *runtime.Scheme
64+
apiReader client.Reader
65+
coreClient corev1client.CoreV1Interface
66+
oauthClient oauthclient.Interface
67+
configClient configclient.Interface
68+
apiClient kclient.Interface
69+
apiSpec *capabilities.ApiServerSpec
70+
logger logr.Logger
71+
operatorPod types.NamespacedName
72+
updatePoller *updater.RegistryPoller
73+
updateChannel <-chan event.GenericEvent // only receives events
74+
}
75+
5676
func enqueueRequestForOwner[T client.Object](mgr manager.Manager) handler.TypedEventHandler[T, reconcile.Request] {
5777
return handler.TypedEnqueueRequestForOwner[T](mgr.GetScheme(), mgr.GetRESTMapper(), hawtiov2.NewHawtio(), handler.OnlyControllerOwner())
5878
}
5979

6080
// Add creates a new Hawtio Controller and adds it to the Manager. The Manager will set fields on the Controller
6181
// and Start it when the Manager is Started.
62-
func Add(mgr manager.Manager, operatorPod types.NamespacedName, clientTools *clients.ClientTools, apiSpec *capabilities.ApiServerSpec, bv util.BuildVariables) error {
82+
func Add(mgr manager.Manager, operatorPod types.NamespacedName, clientTools *clients.ClientTools, apiSpec *capabilities.ApiServerSpec, bv util.BuildVariables, updatePoller *updater.RegistryPoller, updateChannel chan event.GenericEvent) error {
6383
r := &ReconcileHawtio{
6484
BuildVariables: bv,
6585
client: mgr.GetClient(),
@@ -71,6 +91,8 @@ func Add(mgr manager.Manager, operatorPod types.NamespacedName, clientTools *cli
7191
apiClient: clientTools.ApiClient,
7292
apiSpec: apiSpec,
7393
operatorPod: operatorPod,
94+
updatePoller: updatePoller,
95+
updateChannel: updateChannel,
7496
}
7597

7698
if r.apiSpec.IsOpenShift4 {
@@ -164,40 +186,47 @@ func Add(mgr manager.Manager, operatorPod types.NamespacedName, clientTools *cli
164186
return errs.Wrap(err, "Failed to create watch for Secret resource")
165187
}
166188

167-
return nil
168-
}
169-
170-
// handleResultAndError
171-
// If error is the Sentinel legacy adopted resource error
172-
// then signal for a requeue. Otherwise, just return the error
173-
func handleResultAndError(err error) (reconcile.Result, error) {
174-
if err == ErrLegacyResourceAdopted {
175-
// Adoption occurred so requeue
176-
return reconcile.Result{Requeue: true}, err
189+
//
190+
// Watch for changes to the update channel if it has been defined
191+
//
192+
if r.updateChannel != nil {
193+
err = c.Watch(
194+
source.Channel(
195+
r.updateChannel,
196+
handler.EnqueueRequestsFromMapFunc(func(ctx context.Context, obj client.Object) []reconcile.Request {
197+
// When the poller fires an event, list all Hawtio CRs
198+
// and queue a reconcile for every single one of them.
199+
hawtioList := &hawtiov2.HawtioList{}
200+
201+
listErr := r.client.List(ctx, hawtioList)
202+
if listErr != nil {
203+
hawtioLogger.Error(listErr, "CRITICAL: Failed to list Hawtio CRs during update event")
204+
return nil
205+
}
206+
207+
var requests []reconcile.Request
208+
for _, h := range hawtioList.Items {
209+
requests = append(requests, reconcile.Request{
210+
NamespacedName: types.NamespacedName{
211+
Name: h.Name,
212+
Namespace: h.Namespace,
213+
},
214+
})
215+
}
216+
return requests
217+
}),
218+
),
219+
)
220+
if err != nil {
221+
return errs.Wrap(err, "Failed to create watch for updater")
222+
}
177223
}
178224

179-
return reconcile.Result{}, err
225+
return nil
180226
}
181227

182228
var _ reconcile.Reconciler = &ReconcileHawtio{}
183229

184-
// ReconcileHawtio reconciles a Hawtio object
185-
type ReconcileHawtio struct {
186-
util.BuildVariables
187-
// This client, initialized using mgr.Client() above, is a split client
188-
// that reads objects from the cache and writes to the API server
189-
client client.Client
190-
scheme *runtime.Scheme
191-
apiReader client.Reader
192-
coreClient corev1client.CoreV1Interface
193-
oauthClient oauthclient.Interface
194-
configClient configclient.Interface
195-
apiClient kclient.Interface
196-
apiSpec *capabilities.ApiServerSpec
197-
logger logr.Logger
198-
operatorPod types.NamespacedName
199-
}
200-
201230
// DeploymentConfiguration acquires properties used in deployment
202231
type DeploymentConfiguration struct {
203232
openShiftConsoleURL string
@@ -469,7 +498,8 @@ func (r *ReconcileHawtio) Reconcile(ctx context.Context, request reconcile.Reque
469498
"Phase", newStatus.Phase,
470499
"URL", newStatus.URL,
471500
"Replicas", newStatus.Replicas,
472-
"Image", newStatus.Image)
501+
"Image", newStatus.Image,
502+
"Gateway Image", newStatus.GatewayImage)
473503
if err := r.client.Status().Update(ctx, hawtio); err != nil {
474504
r.logger.Error(err, "Failed to update Hawtio status")
475505
return reconcile.Result{}, err

pkg/controller/hawtio/lifecycle.go

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,25 +2,64 @@ package hawtio
22

33
import (
44
"context"
5+
"errors"
56
"fmt"
7+
"time"
68

79
kerrors "k8s.io/apimachinery/pkg/api/errors"
810
"k8s.io/apimachinery/pkg/types"
911

1012
consolev1 "github.com/openshift/api/console/v1"
13+
oauthv1 "github.com/openshift/api/oauth/v1"
1114
"k8s.io/apimachinery/pkg/api/meta"
1215
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
13-
oauthv1 "github.com/openshift/api/oauth/v1"
1416

1517
"sigs.k8s.io/controller-runtime/pkg/client"
1618
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
19+
"sigs.k8s.io/controller-runtime/pkg/reconcile"
1720

1821
hawtiov2 "github.com/hawtio/hawtio-operator/pkg/apis/hawtio/v2"
19-
2022
"github.com/hawtio/hawtio-operator/pkg/resources"
2123
"github.com/hawtio/hawtio-operator/pkg/util"
2224
)
2325

26+
// RequeueError is a custom error type used to signal that the controller
27+
// should gracefully requeue the reconciliation after a specific duration,
28+
// without treating it as a crash or failure.
29+
type RequeueError struct {
30+
Message string
31+
RequeueAfter time.Duration
32+
}
33+
34+
func (e *RequeueError) Error() string {
35+
return e.Message
36+
}
37+
38+
// handleResultAndError
39+
// If error is the Sentinel legacy adopted resource error
40+
// then signal for a requeue. Otherwise, just return the error
41+
func handleResultAndError(err error) (reconcile.Result, error) {
42+
if err == nil {
43+
return reconcile.Result{}, nil
44+
}
45+
46+
// Check for custom delayed requeue error
47+
var reqErr *RequeueError
48+
if errors.As(err, &reqErr) {
49+
// Return the delay, but return a NIL error so Kubernetes
50+
// respects the timer instead of triggering exponential backoff
51+
return reconcile.Result{RequeueAfter: reqErr.RequeueAfter}, nil
52+
}
53+
54+
// Check for your existing legacy adoption
55+
if err == ErrLegacyResourceAdopted {
56+
return reconcile.Result{Requeue: true}, nil
57+
}
58+
59+
// Fallback for actual system failures
60+
return reconcile.Result{}, err
61+
}
62+
2463
func (r *ReconcileHawtio) fetchHawtio(ctx context.Context, namespacedName client.ObjectKey) (*hawtiov2.Hawtio, error) {
2564
r.logger.V(util.DebugLogLevel).Info("Fetching the Hawtio custom resource")
2665

0 commit comments

Comments
 (0)