Skip to content

Commit

Permalink
Merge pull request #1608 from weaveworks/1600-start-networkmode
Browse files Browse the repository at this point in the history
LGTM.  Fixes #1600
  • Loading branch information
bboreham committed Nov 3, 2015
2 parents 77c7963 + ec5a1a3 commit 54ba100
Show file tree
Hide file tree
Showing 12 changed files with 106 additions and 42 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Expand Up @@ -39,6 +39,7 @@ prog/weavehosts/weavehosts
prog/weaveproxy/weaveproxy
prog/sigproxy/sigproxy
prog/weavewait/weavewait
prog/weavewait/weavewait_noop
prog/netcheck/netcheck
prog/docker_tls_args/docker_tls_args
testing/cover/cover
Expand All @@ -52,6 +53,7 @@ prog/weaveexec/weave
prog/weaveexec/weavehosts
prog/weaveexec/weaveproxy
prog/weaveexec/weavewait
prog/weaveexec/weavewait_noop
prog/weaveexec/sigproxy
prog/weaveexec/netcheck
prog/weaveexec/docker_tls_args
Expand Down
12 changes: 9 additions & 3 deletions Makefile
Expand Up @@ -13,11 +13,12 @@ WEAVER_EXE=prog/weaver/weaver
WEAVEPROXY_EXE=prog/weaveproxy/weaveproxy
SIGPROXY_EXE=prog/sigproxy/sigproxy
WEAVEWAIT_EXE=prog/weavewait/weavewait
WEAVEWAIT_NOOP_EXE=prog/weavewait/weavewait_noop
NETCHECK_EXE=prog/netcheck/netcheck
DOCKERTLSARGS_EXE=prog/docker_tls_args/docker_tls_args
RUNNER_EXE=testing/runner/runner

EXES=$(WEAVER_EXE) $(SIGPROXY_EXE) $(WEAVEPROXY_EXE) $(WEAVEWAIT_EXE) $(NETCHECK_EXE) $(DOCKERTLSARGS_EXE) $(RUNNER_EXE)
EXES=$(WEAVER_EXE) $(SIGPROXY_EXE) $(WEAVEPROXY_EXE) $(WEAVEWAIT_EXE) $(WEAVEWAIT_NOOP_EXE) $(NETCHECK_EXE) $(DOCKERTLSARGS_EXE) $(RUNNER_EXE)

WEAVER_UPTODATE=.weaver.uptodate
WEAVEEXEC_UPTODATE=.weaveexec.uptodate
Expand Down Expand Up @@ -76,23 +77,28 @@ $(NETCHECK_EXE): prog/netcheck/netcheck.go
# Sigproxy and weavewait need separate rules as they fail the netgo check in
# the main build stanza due to not importing net package
$(SIGPROXY_EXE): prog/sigproxy/main.go
$(WEAVEWAIT_EXE): prog/weavewait/main.go net/*.go
$(WEAVEWAIT_EXE): prog/weavewait/*.go net/*.go
$(RUNNER_EXE): testing/runner/runner.go
$(DOCKERTLSARGS_EXE): prog/docker_tls_args/*.go

$(WEAVEWAIT_EXE) $(SIGPROXY_EXE) $(RUNNER_EXE) $(DOCKERTLSARGS_EXE):
go get -tags netgo ./$(@D)
go build $(BUILD_FLAGS) -o $@ ./$(@D)

$(WEAVEWAIT_NOOP_EXE): prog/weavewait/*.go
go get -tags netgo ./$(@D)
go build $(BUILD_FLAGS) -tags noop -o $@ ./$(@D)

$(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) $(NETCHECK_EXE) $(DOCKERTLSARGS_EXE)
$(WEAVEEXEC_UPTODATE): prog/weaveexec/Dockerfile $(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
cp $(WEAVEWAIT_EXE) prog/weaveexec/weavewait
cp $(WEAVEWAIT_NOOP_EXE) prog/weaveexec/weavewait_noop
cp $(NETCHECK_EXE) prog/weaveexec/netcheck
cp $(DOCKERTLSARGS_EXE) prog/weaveexec/docker_tls_args
cp $(DOCKER_DISTRIB) prog/weaveexec/docker.tgz
Expand Down
2 changes: 2 additions & 0 deletions prog/weaveexec/Dockerfile
Expand Up @@ -5,6 +5,7 @@ LABEL works.weave.role=system

WORKDIR /home/weave
VOLUME /w
VOLUME /w-noop
ENTRYPOINT ["/home/weave/sigproxy", "/home/weave/weave"]

RUN apk add --update \
Expand All @@ -20,4 +21,5 @@ RUN apk add --update \
ADD ./weave ./sigproxy ./weaveproxy /home/weave/
ADD ./netcheck ./docker_tls_args /usr/bin/
ADD ./weavewait /w/w
ADD ./weavewait_noop /w-noop/w
ADD ./docker.tgz /
12 changes: 12 additions & 0 deletions prog/weavewait/check_network.go
@@ -0,0 +1,12 @@
// +build !noop

package main

import (
weavenet "github.com/weaveworks/weave/net"
)

func checkNetwork() error {
_, err := weavenet.EnsureInterfaceAndMcastRoute("ethwe")
return err
}
5 changes: 1 addition & 4 deletions prog/weavewait/main.go
Expand Up @@ -6,8 +6,6 @@ import (
"os"
"os/exec"
"syscall"

weavenet "github.com/weaveworks/weave/net"
)

var (
Expand All @@ -19,8 +17,7 @@ func main() {
args = os.Args[1:]
)

_, err := weavenet.EnsureInterfaceAndMcastRoute("ethwe")
checkErr(err)
checkErr(checkNetwork())

if len(args) == 0 {
checkErr(ErrNoCommandSpecified)
Expand Down
7 changes: 7 additions & 0 deletions prog/weavewait/noop.go
@@ -0,0 +1,7 @@
// +build noop

package main

func checkNetwork() error {
return nil
}
22 changes: 22 additions & 0 deletions proxy/common.go
Expand Up @@ -155,3 +155,25 @@ func weaveContainerIPs(containerID string) (mac string, ips []net.IP, nets []*ne
}
return
}

func addVolume(hostConfig jsonObject, source, target, mode string) error {
configBinds, err := hostConfig.StringArray("Binds")
if err != nil {
return err
}

var binds []string
for _, bind := range configBinds {
s := strings.Split(bind, ":")
if len(s) >= 2 && s[1] == target {
continue
}
binds = append(binds, bind)
}
bind := source + ":" + target
if mode != "" {
bind += ":" + mode
}
hostConfig["Binds"] = append(binds, bind)
return nil
}
2 changes: 1 addition & 1 deletion proxy/create_container_interceptor.go
Expand Up @@ -53,7 +53,7 @@ func (i *createContainerInterceptor) InterceptRequest(r *http.Request) error {
Log.Infof("Leaving container alone because %s", err)
} else {
Log.Infof("Creating container with WEAVE_CIDR \"%s\"", strings.Join(cidrs, " "))
if err := i.proxy.addWeaveWaitVolume(hostConfig); err != nil {
if err := addVolume(hostConfig, i.proxy.weaveWaitVolume, "/w", "ro"); err != nil {
return err
}
if err := i.setWeaveWaitEntrypoint(container); err != nil {
Expand Down
45 changes: 18 additions & 27 deletions proxy/proxy.go
Expand Up @@ -70,6 +70,7 @@ type Proxy struct {
dockerBridgeIP string
hostnameMatchRegexp *regexp.Regexp
weaveWaitVolume string
weaveWaitNoopVolume string
normalisedAddrs []string
waiters map[*http.Request]*wait
}
Expand Down Expand Up @@ -106,7 +107,7 @@ func NewProxy(c Config) (*Proxy, error) {
return nil, err
}

if err = p.findWeaveWaitVolume(); err != nil {
if err = p.findWeaveWaitVolumes(); err != nil {
return nil, err
}

Expand Down Expand Up @@ -135,23 +136,31 @@ func (proxy *Proxy) Dial() (net.Conn, error) {
return net.Dial("unix", dockerSock)
}

func (proxy *Proxy) findWeaveWaitVolume() error {
func (proxy *Proxy) findWeaveWaitVolumes() error {
var err error
if proxy.weaveWaitVolume, err = proxy.findVolume("/w"); err != nil {
return err
}
proxy.weaveWaitNoopVolume, err = proxy.findVolume("/w-noop")
return err
}

func (proxy *Proxy) findVolume(v string) (string, error) {
container, err := proxy.client.InspectContainer("weaveproxy")
if err != nil {
return fmt.Errorf("Could not find the weavewait volume: %s", err)
return "", fmt.Errorf("Could not find the weavewait volume: %s", err)
}

if container.Volumes == nil {
return fmt.Errorf("Could not find the weavewait volume")
return "", fmt.Errorf("Could not find the weavewait volume")
}

volume, ok := container.Volumes["/w"]
volume, ok := container.Volumes[v]
if !ok {
return fmt.Errorf("Could not find the weavewait volume")
return "", fmt.Errorf("Could not find the weavewait volume")
}

proxy.weaveWaitVolume = volume
return nil
return volume, nil
}

func (proxy *Proxy) ServeHTTP(w http.ResponseWriter, r *http.Request) {
Expand Down Expand Up @@ -425,7 +434,7 @@ func (proxy *Proxy) attachRouter(container *docker.Container) error {

func (proxy *Proxy) weaveCIDRs(networkMode string, env []string) ([]string, error) {
if networkMode == "host" || strings.HasPrefix(networkMode, "container:") {
return nil, fmt.Errorf("the container was created with the '--net=%s'", networkMode)
return nil, fmt.Errorf("the container has '--net=%s'", networkMode)
}
for _, e := range env {
if strings.HasPrefix(e, "WEAVE_CIDR=") {
Expand All @@ -441,24 +450,6 @@ func (proxy *Proxy) weaveCIDRs(networkMode string, env []string) ([]string, erro
return nil, nil
}

func (proxy *Proxy) addWeaveWaitVolume(hostConfig jsonObject) error {
configBinds, err := hostConfig.StringArray("Binds")
if err != nil {
return err
}

var binds []string
for _, bind := range configBinds {
s := strings.Split(bind, ":")
if len(s) >= 2 && s[1] == "/w" {
continue
}
binds = append(binds, bind)
}
hostConfig["Binds"] = append(binds, fmt.Sprintf("%s:/w:ro", proxy.weaveWaitVolume))
return nil
}

func (proxy *Proxy) setWeaveDNS(hostConfig jsonObject, hostname, dnsDomain string) error {
dns, err := hostConfig.StringArray("Dns")
if err != nil {
Expand Down
19 changes: 16 additions & 3 deletions proxy/start_container_interceptor.go
Expand Up @@ -2,6 +2,7 @@ package proxy

import (
"net/http"
"strings"
)

type startContainerInterceptor struct{ proxy *Proxy }
Expand Down Expand Up @@ -31,11 +32,23 @@ func (i *startContainerInterceptor) InterceptRequest(r *http.Request) error {
hostConfig = params
}
if hostConfig != nil {
i.proxy.addWeaveWaitVolume(hostConfig)
if dnsDomain := i.proxy.getDNSDomain(); dnsDomain != "" {
if err := i.proxy.setWeaveDNS(hostConfig, container.Config.Hostname, dnsDomain); err != nil {
networkMode, err := jsonObject(hostConfig).String("NetworkMode")
if err != nil {
return err
}
if strings.HasPrefix(networkMode, "container:") || networkMode == "host" {
if err := addVolume(hostConfig, i.proxy.weaveWaitNoopVolume, "/w", "ro"); err != nil {
return err
}
} else {
if err := addVolume(hostConfig, i.proxy.weaveWaitVolume, "/w", "ro"); err != nil {
return err
}
if dnsDomain := i.proxy.getDNSDomain(); dnsDomain != "" {
if err := i.proxy.setWeaveDNS(hostConfig, container.Config.Hostname, dnsDomain); err != nil {
return err
}
}
}

// Note we marshal the original top-level dictionary to avoid disturbing anything else
Expand Down
19 changes: 15 additions & 4 deletions test/666_abuse_of_start_test.sh
Expand Up @@ -9,8 +9,8 @@ docker_bridge_ip=$(weave_on $HOST1 docker-bridge-ip)
proxy_start_container $HOST1 --name=c1

check_hostconfig() {
docker_on $HOST1 attach c2 >/dev/null 2>&1 || true # Wait for container to exit
assert "docker_on $HOST1 inspect -f '{{.HostConfig.Dns}} {{.HostConfig.NetworkMode}} {{.State.Running}} {{.State.ExitCode}}' $1" "[$docker_bridge_ip] $2 false 0"
docker_on $HOST1 attach $1 >/dev/null 2>&1 || true # Wait for container to exit
assert "docker_on $HOST1 inspect -f '{{.HostConfig.Dns}} {{.HostConfig.NetworkMode}} {{.State.Running}} {{.State.ExitCode}}' $1" "[$3] $2 false 0"
}

# Start c2 with a sneaky HostConfig
Expand All @@ -26,7 +26,7 @@ check_hostconfig c5 container:c1
# Start c3 with HostConfig having empty binds and null dns/networking settings
proxy docker_on $HOST1 create --name=c3 -v /tmp:/hosttmp $SMALL_IMAGE $CHECK_ETHWE_UP
proxy docker_api_on $HOST1 POST /containers/c3/start '{"Binds":[],"Dns":null,"DnsSearch":null,"ExtraHosts":null,"VolumesFrom":null,"Devices":null,"NetworkMode":""}'
check_hostconfig c3 default
check_hostconfig c3 default $docker_bridge_ip

# Start c4 with an 'null' HostConfig and check this doesn't remove previous parameters
proxy docker_on $HOST1 create --name=c4 --memory-swap -1 $SMALL_IMAGE echo foo
Expand All @@ -42,6 +42,17 @@ check_hostconfig c6 container:c1
proxy docker_on $HOST1 create --name=c7 --memory-swap -1 $SMALL_IMAGE $CHECK_ETHWE_UP
proxy docker_api_on $HOST1 POST /containers/c7/start '{"HostConfig":{}}'
assert "docker_on $HOST1 inspect -f '{{.HostConfig.MemorySwap}}' c7" "0"
check_hostconfig c7 default
check_hostconfig c7 default $docker_bridge_ip

# Start c8 in host network mode
proxy docker_on $HOST1 create --name=c8 $SMALL_IMAGE $CHECK_ETHWE_MISSING
proxy docker_api_on $HOST1 POST /containers/c8/start '{"HostConfig": {"NetworkMode": "host"}}'
check_hostconfig c8 host

# Start c10 in network of host container
proxy_start_container $HOST1 --name=c9 --net=host
proxy docker_on $HOST1 create --name=c10 $SMALL_IMAGE $CHECK_ETHWE_MISSING
proxy docker_api_on $HOST1 POST /containers/c10/start '{"HostConfig": {"NetworkMode": "container:c9"}}'
check_hostconfig c10 container:c9

end_suite
1 change: 1 addition & 0 deletions test/config.sh
Expand Up @@ -40,6 +40,7 @@ TEST_IMAGES="$SMALL_IMAGE $DNS_IMAGE"

PING="ping -nq -W 1 -c 1"
CHECK_ETHWE_UP="grep ^1$ /sys/class/net/ethwe/carrier"
CHECK_ETHWE_MISSING="test ! -d /sys/class/net/ethwe"

DOCKER_PORT=2375

Expand Down

0 comments on commit 54ba100

Please sign in to comment.