// Copyright (C) The Arvados Authors. All rights reserved. // // SPDX-License-Identifier: AGPL-3.0 package boot import ( "context" "errors" "fmt" "io" "io/fs" "io/ioutil" "net" "os" "git.arvados.org/arvados.git/sdk/go/arvados" ) type runWorkbench2 struct { svc arvados.Service } func (runner runWorkbench2) String() string { return "runWorkbench2" } func (runner runWorkbench2) Run(ctx context.Context, fail func(error), super *Supervisor) error { host, port, err := internalPort(runner.svc) if err != nil { return fmt.Errorf("bug: no internalPort for %q: %v (%#v)", runner, err, runner.svc) } super.waitShutdown.Add(1) go func() { defer super.waitShutdown.Done() if super.ClusterType == "production" { err = super.RunProgram(ctx, "/var/lib/arvados/workbench2", runOptions{ user: "www-data", }, "arvados-server", "workbench2", super.cluster.Services.Controller.ExternalURL.Host, net.JoinHostPort(host, port), ".") } else if super.Workbench2Source == "" { super.logger.Info("skipping Workbench2: Workbench2Source==\"\" and not in production mode") return } else { stdinr, stdinw := io.Pipe() defer stdinw.Close() go func() { <-ctx.Done() stdinw.Close() }() if err = os.Mkdir(super.Workbench2Source+"/public/_health", 0777); err != nil && !errors.Is(err, fs.ErrExist) { fail(err) return } if err = ioutil.WriteFile(super.Workbench2Source+"/public/_health/ping", []byte(`{"health":"OK"}`), 0666); err != nil { fail(err) return } err = super.RunProgram(ctx, super.Workbench2Source, runOptions{ env: []string{ "CI=true", "HTTPS=false", "PORT=" + port, "REACT_APP_ARVADOS_API_HOST=" + super.cluster.Services.Controller.ExternalURL.Host, }, // If we don't connect stdin, "yarn start" just exits. stdin: stdinr, }, "yarn", "start") fail(errors.New("`yarn start` exited")) } fail(err) }() return nil }