@@ -49,7 +49,7 @@ type Probe interface {
4949}
5050
5151type probeCheckBuilder struct {
52- liveness , readiness probeBuilder
52+ liveness , readiness , startup probeBuilder
5353}
5454
5555type probeBuilder func (spec api.DeploymentSpec , group api.ServerGroup , version driver.Version ) (Probe , error )
@@ -118,6 +118,36 @@ func (r *Resources) getLivenessProbe(spec api.DeploymentSpec, group api.ServerGr
118118 return config , nil
119119}
120120
121+ func (r * Resources ) getStartupProbe (spec api.DeploymentSpec , group api.ServerGroup , version driver.Version ) (Probe , error ) {
122+ if ! r .isStartupProbeEnabled (spec , group ) {
123+ return nil , nil
124+ }
125+
126+ builders := r .probeBuilders ()
127+
128+ builder , ok := builders [group ]
129+ if ! ok {
130+ return nil , nil
131+ }
132+
133+ config , err := builder .startup (spec , group , version )
134+ if err != nil {
135+ return nil , err
136+ }
137+
138+ groupSpec := spec .GetServerGroupSpec (group )
139+
140+ if ! groupSpec .HasProbesSpec () {
141+ return config , nil
142+ }
143+
144+ probeSpec := groupSpec .GetProbesSpec ()
145+
146+ config .SetSpec (probeSpec .StartupProbeSpec )
147+
148+ return config , nil
149+ }
150+
121151func (r * Resources ) isReadinessProbeEnabled (spec api.DeploymentSpec , group api.ServerGroup ) bool {
122152 probe := pod .ReadinessSpec (group )
123153
@@ -146,29 +176,49 @@ func (r *Resources) isLivenessProbeEnabled(spec api.DeploymentSpec, group api.Se
146176 return probe .CanBeEnabled && probe .EnabledByDefault
147177}
148178
179+ func (r * Resources ) isStartupProbeEnabled (spec api.DeploymentSpec , group api.ServerGroup ) bool {
180+ probe := pod .StartupSpec (group )
181+
182+ groupSpec := spec .GetServerGroupSpec (group )
183+
184+ if groupSpec .HasProbesSpec () {
185+ if p := groupSpec .GetProbesSpec ().StartupProbeDisabled ; p != nil {
186+ return ! * p && probe .CanBeEnabled
187+ }
188+ }
189+
190+ return probe .CanBeEnabled && probe .EnabledByDefault
191+ }
192+
149193func (r * Resources ) probeBuilders () map [api.ServerGroup ]probeCheckBuilder {
150194 return map [api.ServerGroup ]probeCheckBuilder {
151195 api .ServerGroupSingle : {
196+ startup : r .probeBuilderStartupCoreSelect (),
152197 liveness : r .probeBuilderLivenessCoreSelect (),
153198 readiness : r .probeBuilderReadinessCoreSelect (),
154199 },
155200 api .ServerGroupAgents : {
201+ startup : r .probeBuilderStartupCoreSelect (),
156202 liveness : r .probeBuilderLivenessCoreSelect (),
157203 readiness : r .probeBuilderReadinessSimpleCoreSelect (),
158204 },
159205 api .ServerGroupDBServers : {
206+ startup : r .probeBuilderStartupCoreSelect (),
160207 liveness : r .probeBuilderLivenessCoreSelect (),
161208 readiness : r .probeBuilderReadinessSimpleCoreSelect (),
162209 },
163210 api .ServerGroupCoordinators : {
211+ startup : r .probeBuilderStartupCoreSelect (),
164212 liveness : r .probeBuilderLivenessCoreSelect (),
165213 readiness : r .probeBuilderReadinessCoreSelect (),
166214 },
167215 api .ServerGroupSyncMasters : {
216+ startup : r .probeBuilderStartupSync ,
168217 liveness : r .probeBuilderLivenessSync ,
169218 readiness : nilProbeBuilder ,
170219 },
171220 api .ServerGroupSyncWorkers : {
221+ startup : r .probeBuilderStartupSync ,
172222 liveness : r .probeBuilderLivenessSync ,
173223 readiness : nilProbeBuilder ,
174224 },
@@ -207,6 +257,14 @@ func (r *Resources) probeBuilderLivenessCoreSelect() probeBuilder {
207257 return r .probeBuilderLivenessCore
208258}
209259
260+ func (r * Resources ) probeBuilderStartupCoreSelect () probeBuilder {
261+ if features .JWTRotation ().Enabled () {
262+ return r .probeBuilderStartupCoreOperator
263+ }
264+
265+ return r .probeBuilderStartupCore
266+ }
267+
210268func (r * Resources ) probeBuilderLivenessCoreOperator (spec api.DeploymentSpec , group api.ServerGroup , version driver.Version ) (Probe , error ) {
211269 args , err := r .probeCommand (spec , "/_api/version" )
212270 if err != nil {
@@ -218,6 +276,29 @@ func (r *Resources) probeBuilderLivenessCoreOperator(spec api.DeploymentSpec, gr
218276 }, nil
219277}
220278
279+ func (r * Resources ) probeBuilderStartupCoreOperator (spec api.DeploymentSpec , group api.ServerGroup , version driver.Version ) (Probe , error ) {
280+ args , err := r .probeCommand (spec , "/_api/version" )
281+ if err != nil {
282+ return nil , err
283+ }
284+
285+ var retries int32
286+
287+ switch group {
288+ case api .ServerGroupDBServers :
289+ retries = 6 * 60 * 60 / 5 // Wait 6 hours for wal replay
290+ default :
291+ retries = 60
292+ }
293+
294+ return & probes.CMDProbeConfig {
295+ Command : args ,
296+ FailureThreshold : retries ,
297+ PeriodSeconds : 5 ,
298+ InitialDelaySeconds : 1 ,
299+ }, nil
300+ }
301+
221302func (r * Resources ) probeBuilderLivenessCore (spec api.DeploymentSpec , group api.ServerGroup , version driver.Version ) (Probe , error ) {
222303 authorization := ""
223304 if spec .IsAuthenticated () {
@@ -237,6 +318,38 @@ func (r *Resources) probeBuilderLivenessCore(spec api.DeploymentSpec, group api.
237318 }, nil
238319}
239320
321+ func (r * Resources ) probeBuilderStartupCore (spec api.DeploymentSpec , group api.ServerGroup , version driver.Version ) (Probe , error ) {
322+
323+ var retries int32
324+
325+ switch group {
326+ case api .ServerGroupDBServers :
327+ retries = 6 * 60 * 60 / 5 // Wait 6 hours for wal replay
328+ default :
329+ retries = 60
330+ }
331+
332+ authorization := ""
333+ if spec .IsAuthenticated () {
334+ secretData , err := r .getJWTSecret (spec )
335+ if err != nil {
336+ return nil , errors .WithStack (err )
337+ }
338+ authorization , err = jwt .CreateArangodJwtAuthorizationHeaderAllowedPaths (secretData , "kube-arangodb" , []string {"/_api/version" })
339+ if err != nil {
340+ return nil , errors .WithStack (err )
341+ }
342+ }
343+ return & probes.HTTPProbeConfig {
344+ LocalPath : "/_api/version" ,
345+ Secure : spec .IsSecure (),
346+ Authorization : authorization ,
347+ FailureThreshold : retries ,
348+ PeriodSeconds : 5 ,
349+ InitialDelaySeconds : 1 ,
350+ }, nil
351+ }
352+
240353func (r * Resources ) probeBuilderReadinessSimpleCoreSelect () probeBuilder {
241354 if features .JWTRotation ().Enabled () {
242355 return r .probeBuilderReadinessSimpleCoreOperator
@@ -363,3 +476,38 @@ func (r *Resources) probeBuilderLivenessSync(spec api.DeploymentSpec, group api.
363476 Port : port ,
364477 }, nil
365478}
479+
480+ func (r * Resources ) probeBuilderStartupSync (spec api.DeploymentSpec , group api.ServerGroup , version driver.Version ) (Probe , error ) {
481+ authorization := ""
482+ port := k8sutil .ArangoSyncMasterPort
483+ if group == api .ServerGroupSyncWorkers {
484+ port = k8sutil .ArangoSyncWorkerPort
485+ }
486+ if spec .Sync .Monitoring .GetTokenSecretName () != "" {
487+ // Use monitoring token
488+ token , err := r .getSyncMonitoringToken (spec )
489+ if err != nil {
490+ return nil , errors .WithStack (err )
491+ }
492+ authorization = "bearer " + token
493+ } else if group == api .ServerGroupSyncMasters {
494+ // Fall back to JWT secret
495+ secretData , err := r .getSyncJWTSecret (spec )
496+ if err != nil {
497+ return nil , errors .WithStack (err )
498+ }
499+ authorization , err = jwt .CreateArangodJwtAuthorizationHeaderAllowedPaths (secretData , "kube-arangodb" , []string {"/_api/version" })
500+ if err != nil {
501+ return nil , errors .WithStack (err )
502+ }
503+ } else {
504+ // Don't have a probe
505+ return nil , nil
506+ }
507+ return & probes.HTTPProbeConfig {
508+ LocalPath : "/_api/version" ,
509+ Secure : spec .Sync .TLS .IsSecure (),
510+ Authorization : authorization ,
511+ Port : port ,
512+ }, nil
513+ }
0 commit comments