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)
<-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)
}
}
}
}
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
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 {
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: {},
},
}
}