Skip to content
Snippets Groups Projects
Commit fbcbce12 authored by Nick Thomas's avatar Nick Thomas
Browse files

Merge branch '4-fix-daemonizing' into 'master'

Resolve "Gitlab daemon crashing. Omnibus installation (Ubuntu 14.04)"

Closes #4

See merge request !20
parents 79738be5 a3c94ef6
No related branches found
No related tags found
1 merge request!20Resolve "Gitlab daemon crashing. Omnibus installation (Ubuntu 14.04)"
Pipeline #
Loading
Loading
@@ -12,14 +12,22 @@ test:1.5:
image: golang:1.5
script:
- make verify-lite
- make acceptance
 
test:1.6:
image: golang:1.6
script:
- make verify
- make acceptance
 
test:1.7:
image: golang:1.7
script:
- make verify
- make acceptance
test:1.8:
image: golang:1.8
script:
- make verify
- make acceptance
Loading
Loading
@@ -40,10 +40,11 @@ complexity:
 
test:
go get golang.org/x/tools/cmd/cover
go test ./... -cover
go test ./... -short -cover -v -timeout 1m
 
acceptance: gitlab-pages
go test ./... -run-acceptance-tests
go get golang.org/x/tools/cmd/cover
go test ./... -cover -v -timeout 1m
 
docker:
docker run --rm -it -v ${PWD}:/go/src/pages -w /go/src/pages golang:1.5 /bin/bash
Loading
Loading
@@ -39,15 +39,18 @@ If load balancer is run in SSL-offloading mode the custom TLS certificate will n
 
Example:
```
go build
CGO_ENABLED=0 GO15VENDOREXPERIMENT=1 go build
./gitlab-pages -listen-https "" -listen-http ":8090" -pages-root path/to/gitlab/shared/pages -pages-domain example.com
```
 
### Run daemon **in secure mode**
 
The daemon can be run in chroot with dropped privileges.
When compiled with `CGO_ENABLED=0` (which is the default), `gitlab-pages` is a
static binary and so can be run in chroot with dropped privileges.
 
Run daemon as root user and pass the `-daemon-uid` and `-daemon-gid`.
To enter this mode, run `gitlab-pages` as the root user and pass it the
`-daemon-uid` and `-daemon-gid` arguments to specify the user you want it to run
as.
 
The daemon start listening on ports as root, reads certificates as root and re-executes itself as specified user.
When re-executing it copies it's own binary to `pages-root` and changes root to that directory.
Loading
Loading
@@ -74,8 +77,8 @@ This is most useful in dual-stack environments (IPv4+IPv6) where both Gitlab Pag
 
### Enable Prometheus Metrics
 
For monitoring purposes, one could pass the `-metrics-address` flag when
starting. This will expose general metrics about the Go runtime and pages
For monitoring purposes, one could pass the `-metrics-address` flag when
starting. This will expose general metrics about the Go runtime and pages
application for [Prometheus](https://prometheus.io/) to scrape.
 
Example:
Loading
Loading
Loading
Loading
@@ -4,12 +4,12 @@ import (
"flag"
"io/ioutil"
"net/http"
"os"
"testing"
 
"github.com/stretchr/testify/assert"
)
 
var shouldRun = flag.Bool("run-acceptance-tests", false, "Run the acceptance tests?")
var pagesBinary = flag.String("gitlab-pages-binary", "./gitlab-pages", "Path to the gitlab-pages binary")
 
// TODO: Use TCP port 0 everywhere to avoid conflicts. The binary could output
Loading
Loading
@@ -25,12 +25,15 @@ var listeners = []ListenSpec{
}
 
func skipUnlessEnabled(t *testing.T) {
if *shouldRun {
return
if testing.Short() {
t.Log("Acceptance tests disabled")
t.SkipNow()
}
 
t.Log("Acceptance tests disabled")
t.SkipNow()
if _, err := os.Stat(*pagesBinary); os.IsNotExist(err) {
t.Errorf("Couldn't find gitlab-pages binary at %s", *pagesBinary)
t.FailNow()
}
}
 
func TestUnknownHostReturnsNotFound(t *testing.T) {
Loading
Loading
Loading
Loading
@@ -188,7 +188,7 @@ func daemonize(config appConfig, uid, gid uint) {
// Run daemon in chroot environment
temporaryExecutable, err := daemonChroot(cmd)
if err != nil {
println("Chroot failed", err)
log.Println("Chroot failed", err)
return
}
defer os.Remove(temporaryExecutable)
Loading
Loading
@@ -211,7 +211,7 @@ func daemonize(config appConfig, uid, gid uint) {
 
// Start the process
if err = cmd.Start(); err != nil {
println("Start failed", err)
log.Println("Start failed", err)
return
}
 
Loading
Loading
Loading
Loading
@@ -34,7 +34,7 @@ func (d *domain) serveFile(w http.ResponseWriter, r *http.Request, fullPath stri
return err
}
 
println("Serving", fullPath, "for", r.URL.Path)
fmt.Println("Serving", fullPath, "for", r.URL.Path)
http.ServeContent(w, r, filepath.Base(file.Name()), fi.ModTime(), file)
return nil
}
Loading
Loading
@@ -52,7 +52,7 @@ func (d *domain) serveCustomFile(w http.ResponseWriter, r *http.Request, code in
return err
}
 
println("Serving", fullPath, "for", r.URL.Path, "with", code)
fmt.Println("Serving", fullPath, "for", r.URL.Path, "with", code)
 
// Serve the file
_, haveType := w.Header()["Content-Type"]
Loading
Loading
package main
 
import (
"bytes"
"crypto/tls"
"fmt"
"io/ioutil"
Loading
Loading
@@ -15,6 +16,16 @@ import (
"github.com/stretchr/testify/assert"
)
 
type tWriter struct {
t *testing.T
}
func (t *tWriter) Write(b []byte) (int, error) {
t.t.Log(string(bytes.TrimRight(b, "\r\n")))
return len(b), nil
}
var chdirSet = false
 
func setUpTests() {
Loading
Loading
@@ -131,6 +142,8 @@ func RunPagesProcess(t *testing.T, pagesPath string, listeners []ListenSpec, pro
 
args, tempfiles := getPagesArgs(t, listeners, promPort)
cmd := exec.Command(pagesPath, args...)
cmd.Stdout = &tWriter{t}
cmd.Stderr = &tWriter{t}
cmd.Start()
t.Logf("Running %s %v", pagesPath, args)
 
Loading
Loading
@@ -144,10 +157,10 @@ func RunPagesProcess(t *testing.T, pagesPath string, listeners []ListenSpec, pro
for _, spec := range listeners {
spec.WaitUntilListening()
}
time.Sleep(50 * time.Millisecond)
time.Sleep(500 * time.Millisecond)
 
return func() {
cmd.Process.Kill()
cmd.Process.Signal(os.Interrupt)
cmd.Process.Wait()
for _, tempfile := range tempfiles {
os.Remove(tempfile)
Loading
Loading
@@ -176,9 +189,11 @@ func getPagesArgs(t *testing.T, listeners []ListenSpec, promPort string) (args,
args = append(args, "-metrics-address", promPort)
}
 
if os.Geteuid() == 0 && os.Getenv("SUDO_UID") != "" && os.Getenv("SUDO_GID") != "" {
t.Log("Pages process will drop privileges")
args = append(args, "-daemon-uid", os.Getenv("SUDO_UID"), "-daemon-gid", os.Getenv("SUDO_GID"))
// At least one of `-daemon-uid` and `-daemon-gid` must be non-zero
if os.Geteuid() == 0 {
t.Log("Running pages as a daemon")
args = append(args, "-daemon-uid", "0")
args = append(args, "-daemon-gid", "65534") // Root user can switch to "nobody"
}
 
return
Loading
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment