18700: Merge branch 'main'
[arvados.git] / lib / boot / workbench2.go
1 // Copyright (C) The Arvados Authors. All rights reserved.
2 //
3 // SPDX-License-Identifier: AGPL-3.0
4
5 package boot
6
7 import (
8         "context"
9         "errors"
10         "fmt"
11         "io"
12         "io/fs"
13         "io/ioutil"
14         "net"
15         "os"
16
17         "git.arvados.org/arvados.git/sdk/go/arvados"
18 )
19
20 type runWorkbench2 struct {
21         svc arvados.Service
22 }
23
24 func (runner runWorkbench2) String() string {
25         return "runWorkbench2"
26 }
27
28 func (runner runWorkbench2) Run(ctx context.Context, fail func(error), super *Supervisor) error {
29         host, port, err := internalPort(runner.svc)
30         if err != nil {
31                 return fmt.Errorf("bug: no internalPort for %q: %v (%#v)", runner, err, runner.svc)
32         }
33         super.waitShutdown.Add(1)
34         go func() {
35                 defer super.waitShutdown.Done()
36                 if super.ClusterType == "production" {
37                         err = super.RunProgram(ctx, "/var/lib/arvados/workbench2", runOptions{
38                                 user: "www-data",
39                         }, "arvados-server", "workbench2", super.cluster.Services.Controller.ExternalURL.Host, net.JoinHostPort(host, port), ".")
40                 } else if super.Workbench2Source == "" {
41                         super.logger.Info("skipping Workbench2: Workbench2Source==\"\" and not in production mode")
42                         return
43                 } else {
44                         stdinr, stdinw := io.Pipe()
45                         defer stdinw.Close()
46                         go func() {
47                                 <-ctx.Done()
48                                 stdinw.Close()
49                         }()
50                         if err = os.Mkdir(super.Workbench2Source+"/public/_health", 0777); err != nil && !errors.Is(err, fs.ErrExist) {
51                                 fail(err)
52                                 return
53                         }
54                         if err = ioutil.WriteFile(super.Workbench2Source+"/public/_health/ping", []byte(`{"health":"OK"}`), 0666); err != nil {
55                                 fail(err)
56                                 return
57                         }
58                         err = super.RunProgram(ctx, super.Workbench2Source, runOptions{
59                                 env: []string{
60                                         "CI=true",
61                                         "HTTPS=false",
62                                         "PORT=" + port,
63                                         "REACT_APP_ARVADOS_API_HOST=" + super.cluster.Services.Controller.ExternalURL.Host,
64                                 },
65                                 // If we don't connect stdin, "yarn start" just exits.
66                                 stdin: stdinr,
67                         }, "yarn", "start")
68                         fail(errors.New("`yarn start` exited"))
69                 }
70                 fail(err)
71         }()
72         return nil
73 }