[proxy] Symlink sockets to /var/run/weave/weave.sock from inside the proxy

We copy docker.sock owner to symlinks. Permissions are not copied,
because the permissions will inherit from the target.

use versioned exec image to create symlinks
This commit is contained in:
Paul Bellamy committed 2015-11-30 15:45:30 +00:00
1 parent 1980ffea30
commit cd7c88e5a5
8 files changed
+152 -9

No files matched your search

+1 -1
View File
@@ -96,7 +96,7 @@ $(WEAVER_UPTODATE): prog/weaver/Dockerfile $(WEAVER_EXE)
$(SUDO) docker build -t $(WEAVER_IMAGE) prog/weaver
touch $@
$(WEAVEEXEC_UPTODATE): prog/weaveexec/Dockerfile $(DOCKER_DISTRIB) weave $(SIGPROXY_EXE) $(WEAVEPROXY_EXE) $(WEAVEWAIT_EXE) $(WEAVEWAIT_NOOP_EXE) $(NETCHECK_EXE) $(DOCKERTLSARGS_EXE)
$(WEAVEEXEC_UPTODATE): prog/weaveexec/Dockerfile prog/weaveexec/symlink $(DOCKER_DISTRIB) weave $(SIGPROXY_EXE) $(WEAVEPROXY_EXE) $(WEAVEWAIT_EXE) $(WEAVEWAIT_NOOP_EXE) $(NETCHECK_EXE) $(DOCKERTLSARGS_EXE)
cp weave prog/weaveexec/weave
cp $(SIGPROXY_EXE) prog/weaveexec/sigproxy
cp $(WEAVEPROXY_EXE) prog/weaveexec/weaveproxy
+1 -1
View File
@@ -18,7 +18,7 @@ RUN apk add --update \
bind-tools \
&& rm -rf /var/cache/apk/*
ADD ./weave ./sigproxy ./weaveproxy /home/weave/
ADD ./weave ./sigproxy ./weaveproxy ./symlink /home/weave/
ADD ./netcheck ./docker_tls_args /usr/bin/
ADD ./weavewait /w/w
ADD ./weavewait_noop /w-noop/w
+18
View File
@@ -0,0 +1,18 @@
#!/bin/sh
# This lets us force-symlink a bunch of stuff all at once, so we can minimize
# running containers.
set -e
[ -z "$DEBUG" ] || set -x
target="$1"
user="$(stat -c '%u:%g' "$target")"
mode="$(stat -c '%a' "$target")"
shift 1
for link in "$@" ; do
ln -sfT "$target" "$link"
done
chown -h "$user" "$@"
chmod "$mode" "$@"
+5 -1
View File
@@ -19,7 +19,7 @@ func main() {
var (
justVersion bool
logLevel = "info"
c = proxy.Config{ListenAddrs: []string{}}
c = proxy.Config{Image: "weaveworks/weaveexec"}
)
c.Version = version
@@ -53,6 +53,10 @@ func main() {
SetLogLevel(logLevel)
if image := os.Getenv("EXEC_IMAGE"); image != "" {
c.Image = image
}
Log.Infoln("weave proxy", version)
Log.Infoln("Command line arguments:", strings.Join(os.Args[1:], " "))
+96
View File
@@ -1,6 +1,7 @@
package proxy
import (
"bytes"
"crypto/tls"
"errors"
"fmt"
@@ -8,6 +9,7 @@ import (
"net"
"net/http"
"os"
"path/filepath"
"regexp"
"strings"
"sync"
@@ -25,6 +27,9 @@ const (
defaultCertFile = "cert.pem"
dockerSock = "/var/run/docker.sock"
dockerSockUnix = "unix://" + dockerSock
weaveSock = "/var/run/weave/weave.sock"
weaveSockUnix = "unix://" + weaveSock
)
var (
@@ -46,6 +51,7 @@ type Config struct {
HostnameFromLabel string
HostnameMatch string
HostnameReplacement string
Image string
ListenAddrs []string
RewriteInspect bool
NoDefaultIPAM bool
@@ -186,7 +192,12 @@ func (proxy *Proxy) ServeHTTP(w http.ResponseWriter, r *http.Request) {
func (proxy *Proxy) Listen() []net.Listener {
listeners := []net.Listener{}
proxy.normalisedAddrs = []string{}
unixAddrs := []string{}
for _, addr := range proxy.ListenAddrs {
if strings.HasPrefix(addr, "unix://") {
unixAddrs = append(unixAddrs, addr)
continue
}
listener, normalisedAddr, err := proxy.listen(addr)
if err != nil {
Log.Fatalf("Cannot listen on %s: %s", addr, err)
@@ -195,6 +206,20 @@ func (proxy *Proxy) Listen() []net.Listener {
proxy.normalisedAddrs = append(proxy.normalisedAddrs, normalisedAddr)
}
if len(unixAddrs) > 0 {
listener, _, err := proxy.listen(weaveSockUnix)
if err != nil {
Log.Fatalf("Cannot listen on %s: %s", weaveSockUnix, err)
}
listeners = append(listeners, listener)
if err := proxy.symlink(unixAddrs); err != nil {
Log.Fatalf("Cannot listen on unix sockets: %s", err)
}
proxy.normalisedAddrs = append(proxy.normalisedAddrs, weaveSockUnix)
}
for _, addr := range proxy.normalisedAddrs {
Log.Infoln("proxy listening on", addr)
}
@@ -527,3 +552,74 @@ func (proxy *Proxy) updateContainerNetworkSettings(container jsonObject) error {
networkSettings["IPPrefixLen"], _ = nets[0].Mask.Size()
return nil
}
func (proxy *Proxy) symlink(unixAddrs []string) (err error) {
var container *docker.Container
binds := []string{"/var/run/weave:/var/run/weave"}
froms := []string{}
for _, addr := range unixAddrs {
if addr == weaveSockUnix {
continue
}
from := strings.TrimPrefix(addr, "unix://")
dir := filepath.Dir(from)
binds = append(binds, dir+":"+filepath.Join("/host", dir))
froms = append(froms, filepath.Join("/host", from))
proxy.normalisedAddrs = append(proxy.normalisedAddrs, addr)
}
if len(froms) == 0 {
return nil
}
env := []string{
"PATH=/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
}
if val := os.Getenv("DEBUG"); val != "" {
env = append(env, fmt.Sprintf("%s=%s", "DEBUG", val))
}
container, err = proxy.client.CreateContainer(docker.CreateContainerOptions{
Config: &docker.Config{
Image: proxy.Image,
Entrypoint: []string{"/home/weave/symlink", weaveSock},
Cmd: froms,
Env: env,
},
HostConfig: &docker.HostConfig{Binds: binds},
})
if err != nil {
return err
}
defer func() {
err2 := proxy.client.RemoveContainer(docker.RemoveContainerOptions{ID: container.ID})
if err == nil {
err = err2
}
}()
if err := proxy.client.StartContainer(container.ID, nil); err != nil {
return err
}
var buf bytes.Buffer
err = proxy.client.AttachToContainer(docker.AttachToContainerOptions{
Container: container.ID,
ErrorStream: &buf,
Logs: true,
Stderr: true,
})
if err != nil {
return err
}
rc, err := proxy.client.WaitContainer(container.ID)
if err != nil {
return err
}
if rc != 0 {
return errors.New(buf.String())
}
return nil
}
+6
View File
@@ -28,4 +28,10 @@ weave_on $HOST1 stop
weave_on $HOST1 launch-proxy -H tcp://0.0.0.0:12375 -H unix:///var/run/weave/weave.sock
check
# Check we can use weave env/config with unix -Hs specified
weave_on $HOST1 stop
weave_on $HOST1 launch-proxy -H unix:///var/run/weave/weave.sock
assert_raises "run_on $HOST1 'eval \$(weave env) ; docker $CMD'"
assert_raises "run_on $HOST1 'docker \$(weave config) $CMD'"
end_suite
@@ -2,7 +2,7 @@
. ./config.sh
start_suite "Boot the proxy should only listen on client's interface"
start_suite "Various launch-proxy configurations"
# Booting it over unix socket listens on unix socket
run_on $HOST1 COVERAGE=$COVERAGE sudo -E weave launch-proxy
@@ -22,6 +22,11 @@ assert_raises "run_on $HOST1 sudo docker -H unix:///var/run/weave/weave.sock ps"
assert_raises "proxy docker_on $HOST1 ps"
weave_on $HOST1 stop-proxy
# Booting it with -H outside /var/run/weave, still works
socket="$(mktemp -d)/weave.sock"
weave_on $HOST1 launch-proxy -H unix://$socket
assert_raises "run_on $HOST1 sudo docker -H unix:///$socket ps" 0
weave_on $HOST1 stop-proxy
# Booting it over tls errors
assert_raises "DOCKER_CLIENT_ARGS='--tls' weave_on $HOST1 launch-proxy" 1
+19 -5
View File
@@ -1275,17 +1275,30 @@ tls_arg() {
PROXY_ARGS="$PROXY_ARGS $1 /home/weave/tls/$3.pem"
}
# TODO: Handle relative paths for args
# TODO: Handle args with spaces
host_arg() {
PROXY_HOST="$1"
if [ "$PROXY_HOST" != "${PROXY_HOST#unix://}" ]; then
host=$(dirname ${PROXY_HOST#unix://})
if [ "$host" = "${host#/}" ]; then
echo "When launching the proxy, unix sockets must be specified as an absolute path." >&2
exit 1
fi
PROXY_VOLUMES="$PROXY_VOLUMES -v /var/run/weave:/var/run/weave"
fi
PROXY_ARGS="$PROXY_ARGS -H $1"
}
proxy_parse_args() {
while [ $# -gt 0 ]; do
case "$1" in
-H)
PROXY_HOST="$2"
PROXY_ARGS="$PROXY_ARGS $1 $2"
host_arg "$2"
shift
;;
-H=*)
PROXY_HOST="${1#*=}"
PROXY_ARGS="$PROXY_ARGS $1"
host_arg "${1#*=}"
;;
-no-detect-tls|--no-detect-tls)
PROXY_TLS_DETECTION_DISABLED=1
@@ -1346,7 +1359,7 @@ proxy_args() {
PROXY_HOST="tcp://0.0.0.0:12375"
;;
esac
PROXY_ARGS="$PROXY_ARGS -H $PROXY_HOST"
host_arg "$PROXY_HOST"
fi
}
@@ -1559,6 +1572,7 @@ launch_proxy() {
-e DOCKER_BRIDGE \
-e WEAVE_DEBUG \
-e COVERAGE \
-e EXEC_IMAGE=$EXEC_IMAGE \
--entrypoint=/home/weave/weaveproxy \
$WEAVEPROXY_DOCKER_ARGS $EXEC_IMAGE $COVERAGE_ARGS $PROXY_ARGS)
wait_for_status $PROXY_CONTAINER_NAME http_call_unix $PROXY_CONTAINER_NAME status.sock