@@ -2,6 +2,8 @@ package main
22
33import (
44 "context"
5+ "flag"
6+ "io"
57 "log"
68 "net/http"
79 "net/http/httputil"
@@ -56,16 +58,18 @@ import (
5658const (
5759 readHeaderTimeout = 3 * time .Second
5860 folderPermission = 0o750
61+ cleanupWorkerFlag = "cleanup-worker-only"
5962)
6063
6164func main () {
6265 program .RunMain (func (ctx context.Context , siblingsGroup , dependenciesGroup program.Group ) error {
63- if len (os .Args ) != 2 {
64- return status .Error (codes .InvalidArgument , "Usage: bb_portal bb_portal.jsonnet" )
66+ configurationPath , runCleanupWorkerOnly , err := parseArguments (os .Args )
67+ if err != nil {
68+ return err
6569 }
6670 var configuration bb_portal.ApplicationConfiguration
67- if err := util .UnmarshalConfigurationFromFile (os . Args [ 1 ] , & configuration ); err != nil {
68- return util .StatusWrapf (err , "Failed to read configuration from %s" , os . Args [ 1 ] )
71+ if err := util .UnmarshalConfigurationFromFile (configurationPath , & configuration ); err != nil {
72+ return util .StatusWrapf (err , "Failed to read configuration from %s" , configurationPath )
6973 }
7074
7175 prometheusmetrics .RegisterMetrics ()
@@ -79,6 +83,16 @@ func main() {
7983 if tracerProvider == nil || reflect .ValueOf (tracerProvider ).IsNil () {
8084 return status .Error (codes .Internal , "Otel tracer provider is nil" )
8185 }
86+
87+ if runCleanupWorkerOnly {
88+ log .Println ("Starting in cleanup worker only mode" )
89+ if err := startBuildEventStreamCleanupWorker (ctx , & configuration , dependenciesGroup , tracerProvider ); err != nil {
90+ return util .StatusWrap (err , "Failed to start BES cleanup worker" )
91+ }
92+ lifecycleState .MarkReadyAndWait (siblingsGroup )
93+ return nil
94+ }
95+
8296 router := mux .NewRouter ()
8397 router .Use (otelmux .Middleware ("bb-portal-http" , otelmux .WithTracerProvider (tracerProvider )))
8498
@@ -113,36 +127,56 @@ func main() {
113127 })
114128}
115129
116- func newBuildEventStreamService (
117- configuration * bb_portal.ApplicationConfiguration ,
118- siblingsGroup program.Group ,
119- dependenciesGroup program.Group ,
120- grpcClientFactory bb_grpc.ClientFactory ,
121- router * mux.Router ,
122- tracerProvider trace.TracerProvider ,
123- ) error {
124- besConfiguration := configuration .BesServiceConfiguration
125- if besConfiguration == nil {
126- log .Printf ("Did not start BuildEventStream service because buildEventStreamConfiguration is not configured" )
127- return nil
130+ func parseArguments (args []string ) (string , bool , error ) {
131+ flagSet := flag .NewFlagSet (args [0 ], flag .ContinueOnError )
132+ flagSet .SetOutput (io .Discard )
133+ runCleanupWorkerOnly := flagSet .Bool (cleanupWorkerFlag , false , "Run only the BES cleanup worker" )
134+ if err := flagSet .Parse (args [1 :]); err != nil {
135+ return "" , false , status .Errorf (codes .InvalidArgument , "Failed to parse flags: %v" , err )
136+ }
137+ if flagSet .NArg () != 1 {
138+ return "" , false , status .Error (codes .InvalidArgument , "Usage: bb_portal [--cleanup-worker-only] bb_portal.jsonnet" )
128139 }
140+ return flagSet .Arg (0 ), * runCleanupWorkerOnly , nil
141+ }
129142
143+ func newBuildEventStreamDatabaseClient (
144+ besConfiguration * bb_portal.BuildEventStreamService ,
145+ tracerProvider trace.TracerProvider ,
146+ ) (database.Client , error ) {
130147 dialect , connection , err := common .NewSQLConnectionFromConfiguration (besConfiguration .Database , tracerProvider )
131148 if err != nil {
132- return util .StatusWrap (err , "Failed to connect to database for BuildEventStreamService" )
149+ return nil , util .StatusWrap (err , "Failed to connect to database for BuildEventStreamService" )
133150 }
134151
135152 dbClient , err := database .New (dialect , connection )
136153 if err != nil {
137- return util .StatusWrap (err , "Failed to create database client from connection" )
154+ return nil , util .StatusWrap (err , "Failed to create database client from connection" )
138155 }
139156
140157 // Attempt to migrate towards ents model.
141158 if err = dbClient .Ent ().Schema .Create (context .Background (), migrate .WithDropIndex (true )); err != nil {
142- return util .StatusWrap (err , "Could not automatically migrate to desired schema" )
159+ return nil , util .StatusWrap (err , "Could not automatically migrate to desired schema" )
160+ }
161+ return dbClient , nil
162+ }
163+
164+ func startBuildEventStreamCleanupWorker (
165+ ctx context.Context ,
166+ configuration * bb_portal.ApplicationConfiguration ,
167+ dependenciesGroup program.Group ,
168+ tracerProvider trace.TracerProvider ,
169+ ) error {
170+ besConfiguration := configuration .BesServiceConfiguration
171+ if besConfiguration == nil {
172+ return status .Error (codes .InvalidArgument , "BuildEventStreamService must be configured when running cleanup worker" )
173+ }
174+
175+ dbClient , err := newBuildEventStreamDatabaseClient (besConfiguration , tracerProvider )
176+ if err != nil {
177+ return err
143178 }
144179
145- // Configure the database cleanup service.
146180 cleanupConfiguration := besConfiguration .DatabaseCleanupConfiguration
147181 if cleanupConfiguration == nil {
148182 return status .Error (codes .InvalidArgument , "No databaseCleanupConfiguration configured for BuildEventStreamService" )
@@ -158,7 +192,34 @@ func newBuildEventStreamService(
158192 return util .StatusWrap (err , "Failed to create DatabaseCleanupService" )
159193 }
160194
161- databaseCleanerService .StartDbCleanupService (context .Background (), dependenciesGroup )
195+ databaseCleanerService .StartDbCleanupService (ctx , dependenciesGroup )
196+ return nil
197+ }
198+
199+ func newBuildEventStreamService (
200+ configuration * bb_portal.ApplicationConfiguration ,
201+ siblingsGroup program.Group ,
202+ dependenciesGroup program.Group ,
203+ grpcClientFactory bb_grpc.ClientFactory ,
204+ router * mux.Router ,
205+ tracerProvider trace.TracerProvider ,
206+ ) error {
207+ besConfiguration := configuration .BesServiceConfiguration
208+ if besConfiguration == nil {
209+ log .Printf ("Did not start BuildEventStream service because buildEventStreamConfiguration is not configured" )
210+ return nil
211+ }
212+
213+ dbClient , err := newBuildEventStreamDatabaseClient (besConfiguration , tracerProvider )
214+ if err != nil {
215+ return err
216+ }
217+
218+ // Configure the database cleanup service.
219+ cleanupConfiguration := besConfiguration .DatabaseCleanupConfiguration
220+ if cleanupConfiguration == nil {
221+ return status .Error (codes .InvalidArgument , "No databaseCleanupConfiguration configured for BuildEventStreamService" )
222+ }
162223
163224 instanceNameAuthorizer , err := auth_configuration .DefaultAuthorizerFactory .NewAuthorizerFromConfiguration (configuration .InstanceNameAuthorizer , dependenciesGroup , grpcClientFactory )
164225 if err != nil {
0 commit comments