"os"
"os/exec"
"os/signal"
+ "os/user"
"path/filepath"
"strings"
"sync"
return 2
}
- boot.Start(ctx, loader)
+ loader.SkipAPICalls = true
+ cfg, err := loader.Load()
+ if err != nil {
+ return 1
+ }
+
+ boot.Start(ctx, cfg)
defer boot.Stop()
- if boot.WaitReady() {
- fmt.Fprintln(stdout, boot.cluster.Services.Controller.ExternalURL)
+ if url, ok := boot.WaitReady(); ok {
+ fmt.Fprintln(stdout, url)
<-ctx.Done() // wait for signal
return 0
} else {
goMutex sync.Mutex
}
-func (boot *Booter) Start(ctx context.Context, loader *config.Loader) {
+func (boot *Booter) Start(ctx context.Context, cfg *arvados.Config) {
boot.ctx, boot.cancel = context.WithCancel(ctx)
boot.done = make(chan struct{})
go func() {
- err := boot.run(loader)
+ err := boot.run(cfg)
if err != nil {
fmt.Fprintln(boot.Stderr, err)
}
}()
}
-func (boot *Booter) run(loader *config.Loader) error {
+func (boot *Booter) run(cfg *arvados.Config) error {
cwd, err := os.Getwd()
if err != nil {
return err
}
defer os.RemoveAll(boot.tempdir)
- loader.SkipAPICalls = true
- cfg, err := loader.Load()
- if err != nil {
- return err
- }
-
// Fill in any missing config keys, and write the resulting
// config in the temp dir for child services to use.
err = boot.autofillConfig(cfg, boot.logger)
boot.configfile = conffile.Name()
boot.environ = os.Environ()
+ boot.cleanEnv()
boot.setEnv("ARVADOS_CONFIG", boot.configfile)
boot.setEnv("RAILS_ENV", boot.ClusterType)
+ boot.setEnv("TMPDIR", boot.tempdir)
boot.prependEnv("PATH", filepath.Join(boot.LibPath, "bin")+":")
boot.cluster, err = cfg.GetCluster("")
<-boot.done
}
-func (boot *Booter) WaitReady() bool {
+func (boot *Booter) WaitReady() (*arvados.URL, bool) {
for waiting := true; waiting; {
time.Sleep(time.Second)
if boot.ctx.Err() != nil {
- return false
+ return nil, false
}
if boot.healthChecker == nil {
// not set up yet
}
}
}
- return true
+ u := boot.cluster.Services.Controller.ExternalURL
+ return &u, true
}
func (boot *Booter) prependEnv(key, prepend string) {
boot.environ = append(boot.environ, key+"="+prepend)
}
+var cleanEnvPrefixes = []string{
+ "GEM_HOME=",
+ "GEM_PATH=",
+ "ARVADOS_",
+}
+
+func (boot *Booter) cleanEnv() {
+ var cleaned []string
+ for _, s := range boot.environ {
+ drop := false
+ for _, p := range cleanEnvPrefixes {
+ if strings.HasPrefix(s, p) {
+ drop = true
+ break
+ }
+ }
+ if !drop {
+ cleaned = append(cleaned, s)
+ }
+ }
+ boot.environ = cleaned
+}
+
func (boot *Booter) setEnv(key, val string) {
for i, s := range boot.environ {
if strings.HasPrefix(s, key+"=") {
}
func (boot *Booter) setupRubyEnv() error {
- buf, err := exec.Command("gem", "env", "gempath").Output() // /var/lib/arvados/.gem/ruby/2.5.0/bin:...
+ cmd := exec.Command("gem", "env", "gempath")
+ cmd.Env = boot.environ
+ buf, err := cmd.Output() // /var/lib/arvados/.gem/ruby/2.5.0/bin:...
if err != nil || len(buf) == 0 {
return fmt.Errorf("gem env gempath: %v", err)
}
boot.prependEnv("PATH", gempath+"/bin:")
boot.setEnv("GEM_HOME", gempath)
boot.setEnv("GEM_PATH", gempath)
+ // Passenger install doesn't work unless $HOME is ~user
+ u, err := user.Current()
+ if err != nil {
+ return err
+ }
+ boot.setEnv("HOME", u.HomeDir)
return nil
}