@@ -49,6 +49,28 @@ const (
4949 defaultRegistryName = "cloudrunci"
5050)
5151
52+ // HTTPGetProbe describes a probe definition using HTTP Get.
53+ type HTTPGetProbe struct {
54+ Path string
55+ Port int
56+ }
57+
58+ // GRPCProbe describes a probe definition using gRPC.
59+ type GRPCProbe struct {
60+ Port int
61+ Service string
62+ }
63+
64+ // ReadinessProbe describes the readiness probe for a Cloud Run service.
65+ type ReadinessProbe struct {
66+ TimeoutSeconds int
67+ PeriodSeconds int
68+ SuccessThreshold int
69+ FailureThreshold int
70+ HttpGet * HTTPGetProbe
71+ GRPC * GRPCProbe
72+ }
73+
5274// Service describes a Cloud Run service
5375type Service struct {
5476 // Name is an ID, used for logging and to generate a unique version to this run.
@@ -85,6 +107,9 @@ type Service struct {
85107
86108 // Location to deploy the Service, and related artifacts
87109 Location string
110+
111+ // ReadinessProbe description
112+ Readiness * ReadinessProbe
88113}
89114
90115// runID is an identifier that changes between runs.
@@ -272,7 +297,7 @@ func (s *Service) validate() error {
272297
273298// revision returns the revision that the service will be deployed to.
274299// NOTE: Until traffic splitting is available, this will be used as the service name.
275- func (s * Service ) version () string {
300+ func (s * Service ) Version () string {
276301 return s .Name + "-" + runID
277302}
278303
@@ -293,7 +318,7 @@ func (s *Service) Deploy() error {
293318 }
294319
295320 if _ , err := gcloud (s .operationLabel (labelOperationDeploy ), s .deployCmd ()); err != nil {
296- return fmt .Errorf ("gcloud: %s: %q" , s .version (), err )
321+ return fmt .Errorf ("gcloud: %s: %q" , s .Version (), err )
297322 }
298323
299324 s .deployed = true
@@ -339,15 +364,15 @@ func (s *Service) Clean() error {
339364 }
340365
341366 if _ , err := gcloud (s .operationLabel (labelOperationDeleteService ), s .deleteServiceCmd ()); err != nil {
342- return fmt .Errorf ("gcloud: %v: %q" , s .version (), err )
367+ return fmt .Errorf ("gcloud: %v: %q" , s .Version (), err )
343368 }
344369 s .deployed = false
345370
346371 // If s.built is false no image was created or is not managed by cloudrun-ci.
347372 if s .built {
348373 _ , err := gcloud (s .operationLabel ("delete container image" ), s .deleteImageCmd ())
349374 if err != nil {
350- return fmt .Errorf ("gcloud: %v: %q" , s .version (), err )
375+ return fmt .Errorf ("gcloud: %v: %q" , s .Version (), err )
351376 }
352377 s .built = false
353378 }
@@ -365,7 +390,7 @@ func (s *Service) deployCmd() *exec.Cmd {
365390 "alpha" , // TODO until --use-http2 goes GA
366391 "run" ,
367392 "deploy" ,
368- s .version (),
393+ s .Version (),
369394 "--project" ,
370395 s .ProjectID ,
371396 "--image" ,
@@ -384,6 +409,40 @@ func (s *Service) deployCmd() *exec.Cmd {
384409 args = append (args , "--use-http2" )
385410 }
386411
412+ if s .Readiness != nil {
413+ var readinessProbeParts []string
414+ if s .Readiness .TimeoutSeconds > 0 {
415+ readinessProbeParts = append (readinessProbeParts , fmt .Sprintf ("timeoutSeconds=%d" , s .Readiness .TimeoutSeconds ))
416+ }
417+ if s .Readiness .PeriodSeconds > 0 {
418+ readinessProbeParts = append (readinessProbeParts , fmt .Sprintf ("periodSeconds=%d" , s .Readiness .PeriodSeconds ))
419+ }
420+ if s .Readiness .SuccessThreshold > 0 {
421+ readinessProbeParts = append (readinessProbeParts , fmt .Sprintf ("successThreshold=%d" , s .Readiness .SuccessThreshold ))
422+ }
423+ if s .Readiness .FailureThreshold > 0 {
424+ readinessProbeParts = append (readinessProbeParts , fmt .Sprintf ("failureThreshold=%d" , s .Readiness .FailureThreshold ))
425+ }
426+ if s .Readiness .HttpGet != nil {
427+ if s .Readiness .HttpGet .Path != "" {
428+ readinessProbeParts = append (readinessProbeParts , fmt .Sprintf ("httpGet.path=%s" , s .Readiness .HttpGet .Path ))
429+ }
430+ if s .Readiness .HttpGet .Port > 0 {
431+ readinessProbeParts = append (readinessProbeParts , fmt .Sprintf ("httpGet.port=%d" , s .Readiness .HttpGet .Port ))
432+ }
433+ } else if s .Readiness .GRPC != nil {
434+ if s .Readiness .GRPC .Service != "" {
435+ readinessProbeParts = append (readinessProbeParts , fmt .Sprintf ("grpc.service=%s" , s .Readiness .GRPC .Service ))
436+ }
437+ if s .Readiness .GRPC .Port > 0 {
438+ readinessProbeParts = append (readinessProbeParts , fmt .Sprintf ("grpc.port=%d" , s .Readiness .GRPC .Port ))
439+ }
440+ }
441+ if len (readinessProbeParts ) > 0 {
442+ args = append (args , "--readiness-probe=" + strings .Join (readinessProbeParts , "," ))
443+ }
444+ }
445+
387446 // NOTE: if the "beta" component is not available, and this is run in parallel,
388447 // gcloud will attempt to install those components multiple
389448 // times and will eventually fail on IO.
@@ -439,7 +498,7 @@ func (s *Service) deleteServiceCmd() *exec.Cmd {
439498 "run" ,
440499 "services" ,
441500 "delete" ,
442- s .version (),
501+ s .Version (),
443502 "--project" ,
444503 s .ProjectID ,
445504 }, s .Platform .CommandFlags ()... )
@@ -458,7 +517,7 @@ func (s *Service) urlCmd() *exec.Cmd {
458517 "run" ,
459518 "services" ,
460519 "describe" ,
461- s .version (),
520+ s .Version (),
462521 "--project" ,
463522 s .ProjectID ,
464523 "--format" ,
@@ -481,7 +540,7 @@ func (s *Service) LogEntries(filter string, find string, maxAttempts int) (bool,
481540 }
482541 defer client .Close ()
483542
484- preparedFilter := fmt .Sprintf (`resource.type="cloud_run_revision" resource.labels.service_name="%s" %s` , s .version (), filter )
543+ preparedFilter := fmt .Sprintf (`resource.type="cloud_run_revision" resource.labels.service_name="%s" %s` , s .Version (), filter )
485544 log .Printf ("Using log filter: %s\n " , preparedFilter )
486545
487546 log .Println ("Waiting for logs..." )
0 commit comments