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:
commit
906ff210fe
4 files changed
+106
-38
No files matched your search
+5
-17
@@ -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
@@ -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
@@ -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
|
||||
|
||||
@@ -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 \
|
||||
|
||||
Reference in new issue
Block a user