@@ -12,29 +12,36 @@ use stackable_operator::k8s_openapi::api::core::v1::{
1212 ConfigMap , EnvFromSource , EnvVar , PodSpec , Secret , Volume ,
1313} ;
1414use stackable_operator:: kube;
15- use stackable_operator:: kube:: api:: { Patch , PatchParams } ;
16- use stackable_operator:: kube:: core:: DynamicObject ;
15+ use stackable_operator:: kube:: api:: { PartialObjectMeta , Patch , PatchParams } ;
16+ use stackable_operator:: kube:: core:: { error_boundary , DeserializeGuard , DynamicObject } ;
1717use stackable_operator:: kube:: runtime:: controller:: {
1818 trigger_self, trigger_with, Action , ReconcileRequest ,
1919} ;
2020use stackable_operator:: kube:: runtime:: reflector:: { ObjectRef , Store } ;
21- use stackable_operator:: kube:: runtime:: { applier, reflector, watcher, Config , WatchStreamExt } ;
21+ use stackable_operator:: kube:: runtime:: {
22+ applier, metadata_watcher, reflector, watcher, Config , WatchStreamExt ,
23+ } ;
2224use stackable_operator:: kube:: { Resource , ResourceExt } ;
2325use stackable_operator:: logging:: controller:: { report_controller_reconciled, ReconcilerError } ;
2426use stackable_operator:: namespace:: WatchNamespace ;
2527use strum:: { EnumDiscriminants , IntoStaticStr } ;
2628
2729struct Ctx {
2830 kube : kube:: Client ,
29- cms : Store < ConfigMap > ,
31+ cms : Store < PartialObjectMeta < ConfigMap > > ,
3032 cms_inited : Arc < AtomicBool > ,
31- secrets : Store < Secret > ,
33+ secrets : Store < PartialObjectMeta < Secret > > ,
3234 secrets_inited : Arc < AtomicBool > ,
3335}
3436
3537#[ derive( Snafu , Debug , EnumDiscriminants ) ]
3638#[ strum_discriminants( derive( IntoStaticStr ) ) ]
3739enum Error {
40+ #[ snafu( display( "StatefulSet object is invalid" ) ) ]
41+ InvalidStatefulSet {
42+ source : error_boundary:: InvalidObject ,
43+ } ,
44+
3845 #[ snafu( display( "failed to patch object {obj_ref}" ) ) ]
3946 PatchFailed {
4047 source : kube:: Error ,
@@ -55,6 +62,7 @@ impl ReconcilerError for Error {
5562
5663 fn secondary_object ( & self ) -> Option < ObjectRef < DynamicObject > > {
5764 match self {
65+ Error :: InvalidStatefulSet { source : _ } => None ,
5866 Error :: PatchFailed { obj_ref, .. } => Some ( * obj_ref. clone ( ) ) ,
5967 Error :: ConfigMapsUninitialized => None ,
6068 Error :: SecretsUninitialized => None ,
@@ -63,12 +71,12 @@ impl ReconcilerError for Error {
6371}
6472
6573pub async fn start ( client : & Client , watch_namespace : & WatchNamespace ) {
66- let stses = watch_namespace. get_api :: < StatefulSet > ( client) ;
74+ let stses = watch_namespace. get_api :: < DeserializeGuard < StatefulSet > > ( client) ;
6775 let cms = watch_namespace. get_api :: < ConfigMap > ( client) ;
6876 let secrets = watch_namespace. get_api :: < Secret > ( client) ;
69- let sts_store = reflector:: store:: Writer :: new ( ( ) ) ;
70- let cm_store = reflector:: store:: Writer :: new ( ( ) ) ;
71- let secret_store = reflector:: store:: Writer :: new ( ( ) ) ;
77+ let sts_store = reflector:: store:: Writer :: < DeserializeGuard < StatefulSet > > :: new ( ( ) ) ;
78+ let cm_store = reflector:: store:: Writer :: < PartialObjectMeta < ConfigMap > > :: new ( ( ) ) ;
79+ let secret_store = reflector:: store:: Writer :: < PartialObjectMeta < Secret > > :: new ( ( ) ) ;
7280 let cms_inited = Arc :: new ( AtomicBool :: from ( false ) ) ;
7381 let secrets_inited = Arc :: new ( AtomicBool :: from ( false ) ) ;
7482
@@ -86,17 +94,18 @@ pub async fn start(client: &Client, watch_namespace: &WatchNamespace) {
8694 stream:: select (
8795 stream:: select (
8896 trigger_all (
89- reflector ( cm_store, watcher ( cms, watcher:: Config :: default ( ) ) )
97+ reflector ( cm_store, metadata_watcher ( cms, watcher:: Config :: default ( ) ) )
9098 . inspect ( |_| cms_inited. store ( true , std:: sync:: atomic:: Ordering :: SeqCst ) )
9199 . touched_objects ( ) ,
92100 sts_store. as_reader ( ) ,
93101 ) ,
94102 trigger_all (
95- reflector ( secret_store, watcher ( secrets, watcher:: Config :: default ( ) ) )
96- . inspect ( |_| {
97- secrets_inited. store ( true , std:: sync:: atomic:: Ordering :: SeqCst )
98- } )
99- . touched_objects ( ) ,
103+ reflector (
104+ secret_store,
105+ metadata_watcher ( secrets, watcher:: Config :: default ( ) ) ,
106+ )
107+ . inspect ( |_| secrets_inited. store ( true , std:: sync:: atomic:: Ordering :: SeqCst ) )
108+ . touched_objects ( ) ,
100109 sts_store. as_reader ( ) ,
101110 ) ,
102111 ) ,
@@ -161,7 +170,17 @@ fn find_pod_refs<'a, K: Resource + 'a>(
161170 . chain ( container_env_from_refs)
162171}
163172
164- async fn reconcile ( sts : Arc < StatefulSet > , ctx : Arc < Ctx > ) -> Result < Action , Error > {
173+ async fn reconcile (
174+ sts : Arc < DeserializeGuard < StatefulSet > > ,
175+ ctx : Arc < Ctx > ,
176+ ) -> Result < Action , Error > {
177+ tracing:: info!( "Starting reconcile" ) ;
178+ let sts = sts
179+ . 0
180+ . as_ref ( )
181+ . map_err ( error_boundary:: InvalidObject :: clone)
182+ . context ( InvalidStatefulSetSnafu ) ?;
183+
165184 if !ctx. cms_inited . load ( std:: sync:: atomic:: Ordering :: SeqCst ) {
166185 return ConfigMapsUninitializedSnafu . fail ( ) ;
167186 }
@@ -181,12 +200,12 @@ async fn reconcile(sts: Arc<StatefulSet>, ctx: Arc<Ctx>) -> Result<Action, Error
181200 find_pod_refs (
182201 pod_spec,
183202 |volume| {
184- Some ( ObjectRef :: < ConfigMap > :: new (
203+ Some ( ObjectRef :: < PartialObjectMeta < ConfigMap > > :: new (
185204 & volume. config_map . as_ref ( ) ?. name ,
186205 ) )
187206 } ,
188207 |env_var| {
189- Some ( ObjectRef :: < ConfigMap > :: new (
208+ Some ( ObjectRef :: < PartialObjectMeta < ConfigMap > > :: new (
190209 & env_var
191210 . value_from
192211 . as_ref ( ) ?
@@ -196,7 +215,7 @@ async fn reconcile(sts: Arc<StatefulSet>, ctx: Arc<Ctx>) -> Result<Action, Error
196215 ) )
197216 } ,
198217 |env_from| {
199- Some ( ObjectRef :: < ConfigMap > :: new (
218+ Some ( ObjectRef :: < PartialObjectMeta < ConfigMap > > :: new (
200219 & env_from. config_map_ref . as_ref ( ) ?. name ,
201220 ) )
202221 } ,
@@ -225,17 +244,17 @@ async fn reconcile(sts: Arc<StatefulSet>, ctx: Arc<Ctx>) -> Result<Action, Error
225244 find_pod_refs (
226245 pod_spec,
227246 |volume| {
228- Some ( ObjectRef :: < Secret > :: new (
247+ Some ( ObjectRef :: < PartialObjectMeta < Secret > > :: new (
229248 volume. secret . as_ref ( ) ?. secret_name . as_deref ( ) ?,
230249 ) )
231250 } ,
232251 |env_var| {
233- Some ( ObjectRef :: < Secret > :: new (
252+ Some ( ObjectRef :: < PartialObjectMeta < Secret > > :: new (
234253 & env_var. value_from . as_ref ( ) ?. secret_key_ref . as_ref ( ) ?. name ,
235254 ) )
236255 } ,
237256 |env_from| {
238- Some ( ObjectRef :: < Secret > :: new (
257+ Some ( ObjectRef :: < PartialObjectMeta < Secret > > :: new (
239258 & env_from. secret_ref . as_ref ( ) ?. name ,
240259 ) )
241260 } ,
@@ -290,11 +309,16 @@ async fn reconcile(sts: Arc<StatefulSet>, ctx: Arc<Ctx>) -> Result<Action, Error
290309 )
291310 . await
292311 . context ( PatchFailedSnafu {
293- obj_ref : ObjectRef :: from_obj ( sts. as_ref ( ) ) . erase ( ) ,
312+ obj_ref : ObjectRef :: from_obj ( sts) . erase ( ) ,
294313 } ) ?;
295314 Ok ( Action :: await_change ( ) )
296315}
297316
298- fn error_policy ( _obj : Arc < StatefulSet > , _error : & Error , _ctx : Arc < Ctx > ) -> Action {
299- Action :: requeue ( Duration :: from_secs ( 5 ) )
317+ fn error_policy ( _obj : Arc < DeserializeGuard < StatefulSet > > , error : & Error , _ctx : Arc < Ctx > ) -> Action {
318+ match error {
319+ // root object is invalid, will be requeued when modified anyway
320+ Error :: InvalidStatefulSet { .. } => Action :: await_change ( ) ,
321+
322+ _ => Action :: requeue ( Duration :: from_secs ( 5 ) ) ,
323+ }
300324}
0 commit comments