Merge pull request #1026 from weaveworks/1003-proxy-unix-socket

Make proxy listen on unix:///var/run/weave.sock

Closes #1003
This commit is contained in:
Matthias Radestock committed 2015-06-26 16:44:41 +01:00
commit 906ff210fe
4 files changed
+106 -38

No files matched your search

+5 -17
View File
@@ -11,21 +11,21 @@ import (
)
var (
version = "(unreleased version)"
defaultListenAddr = "tcp://0.0.0.0:12375"
version = "(unreleased version)"
defaultListenAddrs = []string{"tcp://0.0.0.0:12375", "unix:///var/run/weave.sock"}
)
func main() {
var (
debug bool
justVersion bool
c = proxy.Config{ListenAddr: defaultListenAddr}
c = proxy.Config{ListenAddrs: defaultListenAddrs}
)
c.Version = version
getopt.BoolVarLong(&debug, "debug", 'd', "log debugging information")
getopt.BoolVarLong(&justVersion, "version", 0, "print version and exit")
getopt.StringVar(&c.ListenAddr, 'H', fmt.Sprintf("address on which to listen (default %s)", defaultListenAddr))
getopt.ListVar(&c.ListenAddrs, 'H', fmt.Sprintf("address on which to listen (default %s)", defaultListenAddrs))
getopt.BoolVarLong(&c.NoDefaultIPAM, "no-default-ipam", 0, "do not automatically allocate addresses for containers without a WEAVE_CIDR")
getopt.StringVarLong(&c.TLSConfig.CACert, "tlscacert", 0, "Trust certs signed only by this CA")
getopt.StringVarLong(&c.TLSConfig.Cert, "tlscert", 0, "Path to TLS certificate file")
@@ -52,22 +52,10 @@ func main() {
Info.Println("weave proxy", version)
Info.Println("Command line arguments:", strings.Join(os.Args[1:], " "))
protoAddrParts := strings.SplitN(c.ListenAddr, "://", 2)
if len(protoAddrParts) == 2 {
if protoAddrParts[0] != "tcp" {
Error.Fatalf("Invalid protocol format: %q", protoAddrParts[0])
}
c.ListenAddr = protoAddrParts[1]
} else {
c.ListenAddr = protoAddrParts[0]
}
p, err := proxy.NewProxy(c)
if err != nil {
Error.Fatalf("Could not start proxy: %s", err)
}
if err := p.ListenAndServe(); err != nil {
Error.Fatalf("Could not listen on %s: %s", p.ListenAddr, err)
}
p.ListenAndServe()
}
+93 -10
View File
@@ -2,10 +2,13 @@ package proxy
import (
"crypto/tls"
"fmt"
"net"
"net/http"
"os"
"regexp"
"strings"
"syscall"
"github.com/fsouza/go-dockerclient"
. "github.com/weaveworks/weave/common"
@@ -15,6 +18,8 @@ const (
defaultCaFile = "ca.pem"
defaultKeyFile = "key.pem"
defaultCertFile = "cert.pem"
dockerSock = "/var/run/docker.sock"
dockerSockUnix = "unix://" + dockerSock
)
var (
@@ -24,7 +29,7 @@ var (
)
type Config struct {
ListenAddr string
ListenAddrs []string
NoDefaultIPAM bool
TLSConfig TLSConfig
Version string
@@ -45,7 +50,7 @@ func NewProxy(c Config) (*Proxy, error) {
Error.Fatalf("Could not configure tls for proxy: %s", err)
}
client, err := docker.NewClient("unix:///var/run/docker.sock")
client, err := docker.NewClient(dockerSockUnix)
if err != nil {
return nil, err
}
@@ -63,7 +68,7 @@ func NewProxy(c Config) (*Proxy, error) {
}
func (proxy *Proxy) Dial() (net.Conn, error) {
return net.Dial("unix", "/var/run/docker.sock")
return net.Dial("unix", dockerSock)
}
func (proxy *Proxy) ServeHTTP(w http.ResponseWriter, r *http.Request) {
@@ -83,19 +88,97 @@ func (proxy *Proxy) ServeHTTP(w http.ResponseWriter, r *http.Request) {
proxy.Intercept(i, w, r)
}
func (proxy *Proxy) ListenAndServe() error {
listener, err := net.Listen("tcp", proxy.ListenAddr)
func (proxy *Proxy) ListenAndServe() {
listeners := []net.Listener{}
addrs := []string{}
for _, addr := range proxy.ListenAddrs {
listener, normalisedAddr, err := proxy.listen(addr)
if err != nil {
Error.Fatalf("Cannot listen on %s: %s", addr, err)
}
listeners = append(listeners, listener)
addrs = append(addrs, normalisedAddr)
}
for _, addr := range addrs {
Info.Println("proxy listening on", addr)
}
errs := make(chan error)
for _, listener := range listeners {
go func(listener net.Listener) {
errs <- (&http.Server{Handler: proxy}).Serve(listener)
}(listener)
}
for range listeners {
err := <-errs
if err != nil {
Error.Fatalf("Serve failed: %s", err)
}
}
}
func copyOwnerAndPermissions(from, to string) error {
stat, err := os.Stat(from)
if err != nil {
return err
}
if proxy.TLSConfig.enabled() {
listener = tls.NewListener(listener, proxy.TLSConfig.Config)
if err = os.Chmod(to, stat.Mode()); err != nil {
return err
}
Info.Println("proxy listening on", proxy.ListenAddr)
moreStat, ok := stat.Sys().(*syscall.Stat_t)
if !ok {
return nil
}
return (&http.Server{Handler: proxy}).Serve(listener)
if err = os.Chown(to, int(moreStat.Uid), int(moreStat.Gid)); err != nil {
return err
}
return nil
}
func (proxy *Proxy) listen(protoAndAddr string) (net.Listener, string, error) {
var (
listener net.Listener
err error
proto, addr string
)
if protoAddrParts := strings.SplitN(protoAndAddr, "://", 2); len(protoAddrParts) == 2 {
proto, addr = protoAddrParts[0], protoAddrParts[1]
} else if strings.HasPrefix(protoAndAddr, "/") {
proto, addr = "unix", protoAndAddr
} else {
proto, addr = "tcp", protoAndAddr
}
switch proto {
case "tcp":
listener, err = net.Listen(proto, addr)
if err != nil {
return nil, "", err
}
if proxy.TLSConfig.enabled() {
listener = tls.NewListener(listener, proxy.TLSConfig.Config)
}
case "unix":
os.Remove(addr) // remove socket from last invocation
listener, err = net.Listen(proto, addr)
if err != nil {
return nil, "", err
}
if err = copyOwnerAndPermissions(dockerSock, addr); err != nil {
return nil, "", err
}
default:
Error.Fatalf("Invalid protocol format: %q", proto)
}
return listener, fmt.Sprintf("%s://%s", proto, addr), nil
}
func (proxy *Proxy) weaveCIDRsFromConfig(config *docker.Config) ([]string, bool) {
+5 -4
View File
@@ -36,13 +36,14 @@ The first form is more convenient, however you can only pass proxy
related configuration arguments to `launch-proxy` so if you need to
modify the default behaviour you will have to use the latter.
By default, the proxy listens on port 12375, on all network
interfaces. This can be adjusted with the `-H` argument, e.g.
By default, the proxy listens on /var/run/weave.sock and port 12375, on
all network interfaces. This can be adjusted with the `-H` argument, e.g.
host1$ weave launch-proxy -H tcp://127.0.0.1:9999
If you are working with a remote docker daemon, then any firewalls
inbetween need to be configured to permit access to the proxy port.
Multiple -H arguments can be specified. If you are working with a remote
docker daemon, then any firewalls inbetween need to be configured to permit
access to the proxy port.
All docker commands can be run via the proxy, so it is safe to adjust
your `DOCKER_HOST` to point at the proxy. Weave provides a convenient
+3 -7
View File
@@ -58,7 +58,7 @@ usage() {
echo "where <peer> = <ip_address_or_fqdn>[:<port>]"
echo " <cidr> = <ip_address>/<routing_prefix_length>"
echo " <addr> = [ip:]<cidr> | net:<cidr> | net:default"
echo " <endpoint> = [tcp://][<ip_address>]:<port>"
echo " <endpoint> = [tcp://][<ip_address>]:<port> | [unix://]/path/to/socket"
echo " <peer_id> = <nickname> or weave internal peer ID"
exit 1
}
@@ -925,11 +925,7 @@ proxy_args() {
proxy_addr() {
if addr=$(docker logs $PROXY_CONTAINER_NAME 2>/dev/null | head -n3 | grep -oE "proxy listening on .*"); then
addr=${addr##* }
host=${addr%:*}
[ "$host" = "0.0.0.0" ] && host=$PROXY_HOST
port=${addr#*:}
echo "${1}tcp://${host:-$PROXY_HOST}:${port:-$PROXY_PORT}"
echo "${1}${addr##* }" | sed "s/0.0.0.0/$PROXY_HOST/g"
return 0
fi
echo "$PROXY_CONTAINER_NAME container is not present. Have you launched it?" >&2
@@ -1035,7 +1031,7 @@ launch_proxy() {
proxy_args "$@"
PROXY_CONTAINER=$(docker run --privileged -d --name=$PROXY_CONTAINER_NAME --net=host \
$PROXY_VOLUMES \
-v /var/run/docker.sock:/var/run/docker.sock \
-v /var/run:/var/run \
-v /proc:/hostproc \
-e PROCFS=/hostproc \
-e WEAVE_CIDR=none \