Add libgbm1 testing dependency.
[arvados.git] / lib / boot / nginx.go
index f212254d23c48724e9e86dffe3d2171ab8b88994..b391c4dc8c93f61f50d221bb116cf71da3c10960 100644 (file)
@@ -12,9 +12,9 @@ import (
        "net/url"
        "os"
        "os/exec"
-       "os/user"
        "path/filepath"
        "regexp"
+       "strings"
 
        "git.arvados.org/arvados.git/sdk/go/arvados"
 )
@@ -32,8 +32,20 @@ func (runNginx) Run(ctx context.Context, fail func(error), super *Supervisor) er
        if err != nil {
                return err
        }
+       extListenHost := "0.0.0.0"
+       if super.ClusterType == "test" {
+               // Our dynamic port number assignment strategy (choose
+               // an available port, write it in a config file, and
+               // have another process/goroutine bind to it) is prone
+               // to races when used by concurrent supervisors. In
+               // test mode we don't accept remote connections, so we
+               // can avoid collisions by using the per-cluster
+               // loopback address instead of 0.0.0.0.
+               extListenHost = super.ListenHost
+       }
        vars := map[string]string{
-               "LISTENHOST":       super.ListenHost,
+               "LISTENHOST":       extListenHost,
+               "UPSTREAMHOST":     super.ListenHost,
                "SSLCERT":          filepath.Join(super.tempdir, "server.crt"),
                "SSLKEY":           filepath.Join(super.tempdir, "server.key"),
                "ACCESSLOG":        filepath.Join(super.tempdir, "nginx_access.log"),
@@ -43,7 +55,10 @@ func (runNginx) Run(ctx context.Context, fail func(error), super *Supervisor) er
        }
        u := url.URL(super.cluster.Services.Controller.ExternalURL)
        ctrlHost := u.Hostname()
-       if f, err := os.Open("/var/lib/acme/live/" + ctrlHost + "/privkey"); err == nil {
+       if strings.HasPrefix(super.cluster.TLS.Certificate, "file:/") && strings.HasPrefix(super.cluster.TLS.Key, "file:/") {
+               vars["SSLCERT"] = filepath.Clean(super.cluster.TLS.Certificate[5:])
+               vars["SSLKEY"] = filepath.Clean(super.cluster.TLS.Key[5:])
+       } else if f, err := os.Open("/var/lib/acme/live/" + ctrlHost + "/privkey"); err == nil {
                f.Close()
                vars["SSLCERT"] = "/var/lib/acme/live/" + ctrlHost + "/cert"
                vars["SSLKEY"] = "/var/lib/acme/live/" + ctrlHost + "/privkey"
@@ -117,28 +132,18 @@ func (runNginx) Run(ctx context.Context, fail func(error), super *Supervisor) er
                }
        }
 
-       args := []string{
-               "-g", "error_log stderr info;",
-               "-g", "pid " + filepath.Join(super.wwwtempdir, "nginx.pid") + ";",
-               "-c", conffile,
-       }
-       // Nginx ignores "user www-data;" when running as a non-root
-       // user... except that it causes it to ignore our other -g
-       // options. So we still have to decide for ourselves whether
-       // it's needed.
-       if u, err := user.Current(); err != nil {
-               return fmt.Errorf("user.Current(): %w", err)
-       } else if u.Uid == "0" {
-               args = append([]string{"-g", "user www-data;"}, args...)
-       }
+       configs := "error_log stderr info; "
+       configs += "pid " + filepath.Join(super.wwwtempdir, "nginx.pid") + "; "
+       configs += "user www-data; "
 
        super.waitShutdown.Add(1)
        go func() {
                defer super.waitShutdown.Done()
-               fail(super.RunProgram(ctx, ".", runOptions{}, nginx, args...))
+               fail(super.RunProgram(ctx, ".", runOptions{}, nginx, "-g", configs, "-c", conffile))
        }()
        // Choose one of the ports where Nginx should listen, and wait
-       // here until we can connect. If ExternalURL is https://foo (with no port) then we connect to "foo:https"
+       // here until we can connect. If ExternalURL is https://foo
+       // (with no port) then we connect to "foo:https"
        testurl := url.URL(super.cluster.Services.Controller.ExternalURL)
        if testurl.Port() == "" {
                testurl.Host = net.JoinHostPort(testurl.Host, testurl.Scheme)