mirror of https://github.com/docker/docs.git
vendor: bump github.com/coreos/go-systemd/activation
tests now work in the Docker tree with `go test github.com/coreos/go-systemd/activation` Docker-DCO-1.1-Signed-off-by: Brandon Philips <brandon.philips@coreos.com> (github: philips)
This commit is contained in:
parent
1603039a71
commit
f82d1291cc
|
|
@ -13,7 +13,6 @@ const (
|
||||||
)
|
)
|
||||||
|
|
||||||
func Files(unsetEnv bool) []*os.File {
|
func Files(unsetEnv bool) []*os.File {
|
||||||
|
|
||||||
if unsetEnv {
|
if unsetEnv {
|
||||||
// there is no way to unset env in golang os package for now
|
// there is no way to unset env in golang os package for now
|
||||||
// https://code.google.com/p/go/issues/detail?id=6423
|
// https://code.google.com/p/go/issues/detail?id=6423
|
||||||
|
|
@ -25,14 +24,17 @@ func Files(unsetEnv bool) []*os.File {
|
||||||
if err != nil || pid != os.Getpid() {
|
if err != nil || pid != os.Getpid() {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
nfds, err := strconv.Atoi(os.Getenv("LISTEN_FDS"))
|
nfds, err := strconv.Atoi(os.Getenv("LISTEN_FDS"))
|
||||||
if err != nil || nfds == 0 {
|
if err != nil || nfds == 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var files []*os.File
|
var files []*os.File
|
||||||
for fd := listenFdsStart; fd < listenFdsStart+nfds; fd++ {
|
for fd := listenFdsStart; fd < listenFdsStart+nfds; fd++ {
|
||||||
syscall.CloseOnExec(fd)
|
syscall.CloseOnExec(fd)
|
||||||
files = append(files, os.NewFile(uintptr(fd), "LISTEN_FD_"+strconv.Itoa(fd)))
|
files = append(files, os.NewFile(uintptr(fd), "LISTEN_FD_"+strconv.Itoa(fd)))
|
||||||
}
|
}
|
||||||
|
|
||||||
return files
|
return files
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
package activation
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Listeners returns net.Listeners for all socket activated fds passed to this process.
|
||||||
|
func Listeners(unsetEnv bool) ([]net.Listener, error) {
|
||||||
|
files := Files(unsetEnv)
|
||||||
|
listeners := make([]net.Listener, len(files))
|
||||||
|
|
||||||
|
for i, f := range files {
|
||||||
|
var err error
|
||||||
|
listeners[i], err = net.FileListener(f)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("Error setting up FileListener for fd %d: %s", f.Fd(), err.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return listeners, nil
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,72 @@
|
||||||
|
package activation
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io"
|
||||||
|
"net"
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
// correctStringWritten fails the text if the correct string wasn't written
|
||||||
|
// to the other side of the pipe.
|
||||||
|
func correctStringWrittenNet(t *testing.T, r net.Conn, expected string) bool {
|
||||||
|
bytes := make([]byte, len(expected))
|
||||||
|
io.ReadAtLeast(r, bytes, len(expected))
|
||||||
|
|
||||||
|
if string(bytes) != expected {
|
||||||
|
t.Fatalf("Unexpected string %s", string(bytes))
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestActivation forks out a copy of activation.go example and reads back two
|
||||||
|
// strings from the pipes that are passed in.
|
||||||
|
func TestListeners(t *testing.T) {
|
||||||
|
cmd := exec.Command("go", "run", "../examples/activation/listen.go")
|
||||||
|
|
||||||
|
l1, err := net.Listen("tcp", ":9999")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf(err.Error())
|
||||||
|
}
|
||||||
|
l2, err := net.Listen("tcp", ":1234")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
t1 := l1.(*net.TCPListener)
|
||||||
|
t2 := l2.(*net.TCPListener)
|
||||||
|
|
||||||
|
f1, _ := t1.File()
|
||||||
|
f2, _ := t2.File()
|
||||||
|
|
||||||
|
cmd.ExtraFiles = []*os.File{
|
||||||
|
f1,
|
||||||
|
f2,
|
||||||
|
}
|
||||||
|
|
||||||
|
r1, err := net.Dial("tcp", "127.0.0.1:9999")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf(err.Error())
|
||||||
|
}
|
||||||
|
r1.Write([]byte("Hi"))
|
||||||
|
|
||||||
|
r2, err := net.Dial("tcp", "127.0.0.1:1234")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf(err.Error())
|
||||||
|
}
|
||||||
|
r2.Write([]byte("Hi"))
|
||||||
|
|
||||||
|
cmd.Env = os.Environ()
|
||||||
|
cmd.Env = append(cmd.Env, "LISTEN_FDS=2", "FIX_LISTEN_PID=1")
|
||||||
|
|
||||||
|
out, err := cmd.Output()
|
||||||
|
if err != nil {
|
||||||
|
println(string(out))
|
||||||
|
t.Fatalf(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
correctStringWrittenNet(t, r1, "Hello world")
|
||||||
|
correctStringWrittenNet(t, r2, "Goodbye world")
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,44 @@
|
||||||
|
// Activation example used by the activation unit tests.
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/coreos/go-systemd/activation"
|
||||||
|
)
|
||||||
|
|
||||||
|
func fixListenPid() {
|
||||||
|
if os.Getenv("FIX_LISTEN_PID") != "" {
|
||||||
|
// HACK: real systemd would set LISTEN_PID before exec'ing but
|
||||||
|
// this is too difficult in golang for the purpose of a test.
|
||||||
|
// Do not do this in real code.
|
||||||
|
os.Setenv("LISTEN_PID", fmt.Sprintf("%d", os.Getpid()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
fixListenPid()
|
||||||
|
|
||||||
|
files := activation.Files(false)
|
||||||
|
|
||||||
|
if len(files) == 0 {
|
||||||
|
panic("No files")
|
||||||
|
}
|
||||||
|
|
||||||
|
if os.Getenv("LISTEN_PID") == "" || os.Getenv("LISTEN_FDS") == "" {
|
||||||
|
panic("Should not unset envs")
|
||||||
|
}
|
||||||
|
|
||||||
|
files = activation.Files(true)
|
||||||
|
|
||||||
|
if os.Getenv("LISTEN_PID") != "" || os.Getenv("LISTEN_FDS") != "" {
|
||||||
|
panic("Can not unset envs")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write out the expected strings to the two pipes
|
||||||
|
files[0].Write([]byte("Hello world"))
|
||||||
|
files[1].Write([]byte("Goodbye world"))
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
1
vendor/src/github.com/coreos/go-systemd/examples/activation/httpserver/README.md
vendored
Normal file
1
vendor/src/github.com/coreos/go-systemd/examples/activation/httpserver/README.md
vendored
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
Example of using socket activation with systemd to serve a simple HTTP server on http://127.0.0.1:8076
|
||||||
11
vendor/src/github.com/coreos/go-systemd/examples/activation/httpserver/hello.service
vendored
Normal file
11
vendor/src/github.com/coreos/go-systemd/examples/activation/httpserver/hello.service
vendored
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
[Unit]
|
||||||
|
Description=Hello World HTTP
|
||||||
|
Requires=network.target
|
||||||
|
After=multi-user.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
ExecStart=/usr/local/bin/httpserver
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
5
vendor/src/github.com/coreos/go-systemd/examples/activation/httpserver/hello.socket
vendored
Normal file
5
vendor/src/github.com/coreos/go-systemd/examples/activation/httpserver/hello.socket
vendored
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
[Socket]
|
||||||
|
ListenStream=127.0.0.1:8076
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=sockets.target
|
||||||
29
vendor/src/github.com/coreos/go-systemd/examples/activation/httpserver/httpserver.go
vendored
Normal file
29
vendor/src/github.com/coreos/go-systemd/examples/activation/httpserver/httpserver.go
vendored
Normal file
|
|
@ -0,0 +1,29 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io"
|
||||||
|
"net"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/coreos/go-systemd/activation"
|
||||||
|
)
|
||||||
|
|
||||||
|
func HelloServer(w http.ResponseWriter, req *http.Request) {
|
||||||
|
io.WriteString(w, "hello socket activated world!\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
files := activation.Files(true)
|
||||||
|
|
||||||
|
if len(files) != 1 {
|
||||||
|
panic("Unexpected number of socket activation fds")
|
||||||
|
}
|
||||||
|
|
||||||
|
l, err := net.FileListener(files[0])
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
http.HandleFunc("/", HelloServer)
|
||||||
|
http.Serve(l, nil)
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,50 @@
|
||||||
|
// Activation example used by the activation unit tests.
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/coreos/go-systemd/activation"
|
||||||
|
)
|
||||||
|
|
||||||
|
func fixListenPid() {
|
||||||
|
if os.Getenv("FIX_LISTEN_PID") != "" {
|
||||||
|
// HACK: real systemd would set LISTEN_PID before exec'ing but
|
||||||
|
// this is too difficult in golang for the purpose of a test.
|
||||||
|
// Do not do this in real code.
|
||||||
|
os.Setenv("LISTEN_PID", fmt.Sprintf("%d", os.Getpid()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
fixListenPid()
|
||||||
|
|
||||||
|
listeners, _ := activation.Listeners(false)
|
||||||
|
|
||||||
|
if len(listeners) == 0 {
|
||||||
|
panic("No listeners")
|
||||||
|
}
|
||||||
|
|
||||||
|
if os.Getenv("LISTEN_PID") == "" || os.Getenv("LISTEN_FDS") == "" {
|
||||||
|
panic("Should not unset envs")
|
||||||
|
}
|
||||||
|
|
||||||
|
listeners, err := activation.Listeners(true)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if os.Getenv("LISTEN_PID") != "" || os.Getenv("LISTEN_FDS") != "" {
|
||||||
|
panic("Can not unset envs")
|
||||||
|
}
|
||||||
|
|
||||||
|
c0, _ := listeners[0].Accept()
|
||||||
|
c1, _ := listeners[1].Accept()
|
||||||
|
|
||||||
|
// Write out the expected strings to the two pipes
|
||||||
|
c0.Write([]byte("Hello world"))
|
||||||
|
c1.Write([]byte("Goodbye world"))
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue