X-Git-Url: https://git.arvados.org/arvados.git/blobdiff_plain/8b1b770d208c2886c7b46a502f0d67d8fdcc919a..ff2844616f4da0055039d39c88486e0e042c1f3e:/lib/boot/cmd.go diff --git a/lib/boot/cmd.go b/lib/boot/cmd.go index 60955dfa0f..5147e3ac33 100644 --- a/lib/boot/cmd.go +++ b/lib/boot/cmd.go @@ -6,9 +6,11 @@ package boot import ( "context" + "errors" "flag" "fmt" "io" + "time" "git.arvados.org/arvados.git/lib/cmd" "git.arvados.org/arvados.git/lib/config" @@ -22,7 +24,7 @@ type supervisedTask interface { // done enough to satisfy a dependency relationship (e.g., the // service is running and ready). If the task starts a // goroutine that fails after Run returns (e.g., the service - // shuts down), it should call cancel. + // shuts down), it should call fail(). Run(ctx context.Context, fail func(error), super *Supervisor) error String() string } @@ -56,6 +58,8 @@ func (bootCommand) RunCommand(prog string, args []string, stdin io.Reader, stdou flags.StringVar(&super.ListenHost, "listen-host", "localhost", "host name or interface address for service listeners") flags.StringVar(&super.ControllerAddr, "controller-address", ":0", "desired controller address, `host:port` or `:port`") flags.BoolVar(&super.OwnTemporaryDatabase, "own-temporary-database", false, "bring up a postgres server and create a temporary database") + timeout := flags.Duration("timeout", 0, "maximum time to wait for cluster to be ready") + shutdown := flags.Bool("shutdown", false, "shut down when the cluster becomes ready") err = flags.Parse(args) if err == flag.ErrHelp { err = nil @@ -77,12 +81,28 @@ func (bootCommand) RunCommand(prog string, args []string, stdin io.Reader, stdou super.Start(ctx, cfg) defer super.Stop() - if url, ok := super.WaitReady(); ok { - fmt.Fprintln(stdout, url) - // Wait for signal/crash + orderly shutdown - <-super.done - return 0 - } else { + + var timer *time.Timer + if *timeout > 0 { + timer = time.AfterFunc(*timeout, super.Stop) + } + + url, ok := super.WaitReady() + if timer != nil && !timer.Stop() { + err = errors.New("boot timed out") + return 1 + } else if !ok { + err = errors.New("boot failed") return 1 } + // Write controller URL to stdout. Nothing else goes to + // stdout, so this provides an easy way for a calling script + // to discover the controller URL when everything is ready. + fmt.Fprintln(stdout, url) + if *shutdown { + super.Stop() + } + // Wait for signal/crash + orderly shutdown + <-super.done + return 0 }