15954: Add comments.
[arvados.git] / lib / boot / cmd.go
index e0e357e1ed1e9ed05dd1e0b1e1ba63916be23156..992c7c6e510f669fc5d884c6fd3a1af962dae9a8 100644 (file)
@@ -221,6 +221,14 @@ func (boot *bootCommand) setupRubyEnv() error {
        return boot.setupRubyErr
 }
 
+// Run prog with args, using dir as working directory. If ctx is
+// cancelled while the child is running, RunProgram terminates the
+// child, waits for it to exit, then returns.
+//
+// Child's environment will have our env vars, plus any given in env.
+//
+// Child's stdout will be written to output if non-nil, otherwise the
+// boot command's stderr.
 func (boot *bootCommand) RunProgram(ctx context.Context, dir string, output io.Writer, env []string, prog string, args ...string) error {
        cmdline := fmt.Sprintf("%s", append([]string{prog}, args...))
        fmt.Fprintf(boot.stderr, "%s executing in %s\n", cmdline, dir)
@@ -243,12 +251,14 @@ func (boot *bootCommand) RunProgram(ctx context.Context, dir string, output io.W
                <-ctx.Done()
                log := ctxlog.FromContext(ctx).WithFields(logrus.Fields{"dir": dir, "cmdline": cmdline})
                for cmd.ProcessState == nil {
+                       // Child hasn't exited yet
                        if cmd.Process == nil {
                                log.Infof("waiting for child process to start")
                                time.Sleep(time.Second)
                        } else {
+                               log.WithField("PID", cmd.Process.Pid).Info("sending SIGTERM")
                                cmd.Process.Signal(syscall.SIGTERM)
-                               log.WithField("PID", cmd.Process.Pid).Infof("waiting for child process to exit after SIGTERM")
+                               log.WithField("PID", cmd.Process.Pid).Info("waiting for child process to exit after SIGTERM")
                                time.Sleep(5 * time.Second)
                        }
                }
@@ -297,6 +307,11 @@ func (cmpt *component) Run(ctx context.Context, boot *bootCommand, stdout, stder
                }
        }
        if cmpt.goProg != "" {
+               boot.RunProgram(ctx, cmpt.goProg, nil, nil, "go", "install")
+               if ctx.Err() != nil {
+                       return nil
+               }
+               _, basename := filepath.Split(cmpt.goProg)
                if len(cmpt.svc.InternalURLs) > 0 {
                        // Run one for each URL
                        var wg sync.WaitGroup
@@ -305,14 +320,14 @@ func (cmpt *component) Run(ctx context.Context, boot *bootCommand, stdout, stder
                                wg.Add(1)
                                go func() {
                                        defer wg.Done()
-                                       boot.RunProgram(ctx, cmpt.goProg, nil, []string{"ARVADOS_SERVICE_INTERNAL_URL=" + u.String()}, "go", "run", ".")
+                                       boot.RunProgram(ctx, boot.tempdir, nil, []string{"ARVADOS_SERVICE_INTERNAL_URL=" + u.String()}, basename)
                                }()
                        }
                        wg.Wait()
                        return nil
                } else {
                        // Just run one
-                       return boot.RunProgram(ctx, cmpt.goProg, nil, nil, "go", "run", ".")
+                       boot.RunProgram(ctx, boot.tempdir, nil, nil, basename)
                }
        }
        if cmpt.runFunc != nil {
@@ -425,26 +440,27 @@ func (boot *bootCommand) autofillConfig(cfg *arvados.Config, log logrus.FieldLog
                cluster.TLS.Insecure = true
        }
        if boot.clusterType == "test" {
+               // Add a second keepstore process.
                port++
                cluster.Services.Keepstore.InternalURLs[arvados.URL{Scheme: "http", Host: fmt.Sprintf("localhost:%d", port)}] = arvados.ServiceInstance{}
 
-               n := -1
+               // Create a directory-backed volume for each keepstore
+               // process.
+               cluster.Volumes = map[string]arvados.Volume{}
                for url := range cluster.Services.Keepstore.InternalURLs {
-                       n++
-                       datadir := fmt.Sprintf("%s/keep%d.data", boot.tempdir, n)
+                       volnum := len(cluster.Volumes)
+                       datadir := fmt.Sprintf("%s/keep%d.data", boot.tempdir, volnum)
                        if _, err = os.Stat(datadir + "/."); err == nil {
                        } else if !os.IsNotExist(err) {
                                return err
                        } else if err = os.Mkdir(datadir, 0777); err != nil {
                                return err
                        }
-                       cluster.Volumes = map[string]arvados.Volume{
-                               fmt.Sprintf("zzzzz-nyw5e-%015d", n): arvados.Volume{
-                                       Driver:           "Directory",
-                                       DriverParameters: json.RawMessage(fmt.Sprintf(`{"Root":%q}`, datadir)),
-                                       AccessViaHosts: map[arvados.URL]arvados.VolumeAccess{
-                                               url: {},
-                                       },
+                       cluster.Volumes[fmt.Sprintf("zzzzz-nyw5e-%015d", volnum)] = arvados.Volume{
+                               Driver:           "Directory",
+                               DriverParameters: json.RawMessage(fmt.Sprintf(`{"Root":%q}`, datadir)),
+                               AccessViaHosts: map[arvados.URL]arvados.VolumeAccess{
+                                       url: {},
                                },
                        }
                }