16306: Make sure that the non-passenger nginx process runs as the
[arvados.git] / lib / boot / nginx.go
index 0f105d6b6ca3ad8b835f90c626060edd454aa513..07ff1fc1d3e330d89c0f69649ed996f2ca5f7866 100644 (file)
@@ -9,6 +9,7 @@ import (
        "fmt"
        "io/ioutil"
        "net"
+       "net/url"
        "os"
        "os/exec"
        "path/filepath"
@@ -36,7 +37,7 @@ func (runNginx) Run(ctx context.Context, fail func(error), super *Supervisor) er
                "SSLKEY":     filepath.Join(super.tempdir, "server.key"),
                "ACCESSLOG":  filepath.Join(super.tempdir, "nginx_access.log"),
                "ERRORLOG":   filepath.Join(super.tempdir, "nginx_error.log"),
-               "TMPDIR":     super.tempdir,
+               "TMPDIR":     super.wwwtempdir,
        }
        for _, cmpt := range []struct {
                varname string
@@ -53,7 +54,7 @@ func (runNginx) Run(ctx context.Context, fail func(error), super *Supervisor) er
        } {
                port, err := internalPort(cmpt.svc)
                if err != nil {
-                       return fmt.Errorf("%s internal port: %s (%v)", cmpt.varname, err, cmpt.svc)
+                       return fmt.Errorf("%s internal port: %w (%v)", cmpt.varname, err, cmpt.svc)
                }
                if ok, err := addrIsLocal(net.JoinHostPort(super.ListenHost, port)); !ok || err != nil {
                        return fmt.Errorf("urlIsLocal() failed for host %q port %q: %v", super.ListenHost, port, err)
@@ -62,14 +63,20 @@ func (runNginx) Run(ctx context.Context, fail func(error), super *Supervisor) er
 
                port, err = externalPort(cmpt.svc)
                if err != nil {
-                       return fmt.Errorf("%s external port: %s (%v)", cmpt.varname, err, cmpt.svc)
+                       return fmt.Errorf("%s external port: %w (%v)", cmpt.varname, err, cmpt.svc)
                }
                if ok, err := addrIsLocal(net.JoinHostPort(super.ListenHost, port)); !ok || err != nil {
                        return fmt.Errorf("urlIsLocal() failed for host %q port %q: %v", super.ListenHost, port, err)
                }
                vars[cmpt.varname+"SSLPORT"] = port
        }
-       tmpl, err := ioutil.ReadFile(filepath.Join(super.SourcePath, "sdk", "python", "tests", "nginx.conf"))
+       var conftemplate string
+       if super.ClusterType == "production" {
+               conftemplate = "/var/lib/arvados/share/nginx.conf"
+       } else {
+               conftemplate = filepath.Join(super.SourcePath, "sdk", "python", "tests", "nginx.conf")
+       }
+       tmpl, err := ioutil.ReadFile(conftemplate)
        if err != nil {
                return err
        }
@@ -98,8 +105,14 @@ func (runNginx) Run(ctx context.Context, fail func(error), super *Supervisor) er
                defer super.waitShutdown.Done()
                fail(super.RunProgram(ctx, ".", nil, nil, nginx,
                        "-g", "error_log stderr info;",
-                       "-g", "pid "+filepath.Join(super.tempdir, "nginx.pid")+";",
+                       "-g", "user www-data; pid "+filepath.Join(super.wwwtempdir, "nginx.pid")+";",
                        "-c", conffile))
        }()
-       return waitForConnect(ctx, super.cluster.Services.Controller.ExternalURL.Host)
+       // 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"
+       testurl := url.URL(super.cluster.Services.Controller.ExternalURL)
+       if testurl.Port() == "" {
+               testurl.Host = net.JoinHostPort(testurl.Host, testurl.Scheme)
+       }
+       return waitForConnect(ctx, testurl.Host)
 }