diff --git a/prog/weaveproxy/main.go b/prog/weaveproxy/main.go
index 4b8f039b..8f66e59f 100644
--- a/prog/weaveproxy/main.go
+++ b/prog/weaveproxy/main.go
@@ -36,7 +36,8 @@ func main() {
getopt.BoolVarLong(&c.TLSConfig.Enabled, "tls", 0, "Use TLS; implied by --tlsverify")
getopt.StringVarLong(&c.TLSConfig.Key, "tlskey", 0, "Path to TLS key file")
getopt.BoolVarLong(&c.TLSConfig.Verify, "tlsverify", 0, "Use TLS and verify the remote")
- getopt.BoolVarLong(&c.WithDNS, "with-dns", 'w', "instruct created containers to use weaveDNS as their nameserver")
+ getopt.BoolVarLong(&c.WithDNS, "with-dns", 'w', "instruct created containers to always use weaveDNS as their nameserver")
+ getopt.BoolVarLong(&c.WithoutDNS, "without-dns", 0, "instruct created containers to never use weaveDNS as their nameserver")
getopt.BoolVarLong(&c.WithIPAM, "with-ipam", 'i', "automatically allocate addresses for containers without a WEAVE_CIDR")
getopt.Parse()
@@ -45,6 +46,10 @@ func main() {
os.Exit(0)
}
+ if c.WithDNS && c.WithoutDNS {
+ Error.Fatalf("Cannot use both '--with-dns' and '--without-dns' flags")
+ }
+
if debug {
InitDefaultLogging(true)
}
diff --git a/proxy/create_container_interceptor.go b/proxy/create_container_interceptor.go
index 22d29214..dbb3c920 100644
--- a/proxy/create_container_interceptor.go
+++ b/proxy/create_container_interceptor.go
@@ -81,7 +81,12 @@ func (i *createContainerInterceptor) setWeaveWaitEntrypoint(container *docker.Co
}
func (i *createContainerInterceptor) setWeaveDNS(container *createContainerRequestBody, r *http.Request) error {
- if !i.proxy.WithDNS {
+ if i.proxy.WithoutDNS {
+ return nil
+ }
+
+ dnsDomain, dnsRunning := i.getDNSDomain()
+ if !(dnsRunning || i.proxy.WithDNS) {
return nil
}
@@ -95,13 +100,13 @@ func (i *createContainerInterceptor) setWeaveDNS(container *createContainerReque
if container.Hostname == "" && name != "" {
container.Hostname = name
// Strip trailing period because it's unusual to see it used on the end of a host name
- container.Domainname = strings.TrimSuffix(i.getDNSDomain(), ".")
+ container.Domainname = strings.TrimSuffix(dnsDomain, ".")
}
return nil
}
-func (i *createContainerInterceptor) getDNSDomain() (domain string) {
+func (i *createContainerInterceptor) getDNSDomain() (domain string, running bool) {
domain = nameserver.DefaultLocalDomain
dnsContainer, err := i.proxy.client.InspectContainer("weavedns")
if err != nil ||
@@ -122,7 +127,7 @@ func (i *createContainerInterceptor) getDNSDomain() (domain string) {
return
}
- return string(b)
+ return string(b), true
}
func (i *createContainerInterceptor) InterceptResponse(r *http.Response) error {
diff --git a/proxy/proxy.go b/proxy/proxy.go
index 1751b48c..1c44b679 100644
--- a/proxy/proxy.go
+++ b/proxy/proxy.go
@@ -37,6 +37,7 @@ type Config struct {
TLSConfig TLSConfig
Version string
WithDNS bool
+ WithoutDNS bool
WithIPAM bool
}
@@ -61,7 +62,7 @@ func NewProxy(c Config) (*Proxy, error) {
},
}
- if p.WithDNS {
+ if !p.WithoutDNS {
dockerBridgeIP, err := callWeave("docker-bridge-ip")
if err != nil {
return nil, err
diff --git a/site/proxy.md b/site/proxy.md
index 0c666afe..4b0a1e6e 100644
--- a/site/proxy.md
+++ b/site/proxy.md
@@ -119,17 +119,14 @@ Containers started via the proxy are automatically registered in
[weaveDNS](weavedns.html) if they have a hostname in the weaveDNS
domain (usually `.weave.local`). In order for containers to be able to
look up such names, their DNS resolver needs to be configured to point
-at weaveDNS. This can be done [manually](weavedns.html#without-run),
-or automatically by the proxy by launching it with the `--with-dns`
-option, i.e.
-
- host1$ weave launch-proxy --with-dns
-
-Now any containers started via the proxy, and with a `WEAVE_CIDR=...`
-environment variable (or even without it, if IPAM is
-[configured](#ipam)), will use weaveDNS for name resolution. If not
-provided, the hostname will default to the container name and will be
-registered in weaveDNS.
+at weaveDNS. This will be done automatically by the proxy while
+weaveDNS is running. To override this behaviour launch the proxy with
+either `--with-dns` or `--without-dns`, which will force the proxy to
+always/never set the resolver to weaveDNS. If there is no hostname
+provided, the container will be registered in weaveDNS using its
+container name. Otherwise, if there is no container name, and no
+hostname (or a hostname outside the weaveDNS domain), the container
+will not be registered in weaveDNS.
## Multi-host example
diff --git a/site/weavedns.md b/site/weavedns.md
index dbe2ab83..7eda546e 100644
--- a/site/weavedns.md
+++ b/site/weavedns.md
@@ -27,16 +27,27 @@ hosts.
WeaveDNS is deployed as a set of containers that communicate with each
other over the weave network. One such container needs to be started
on every weave host, by invoking the weave script command
-`launch-dns`. Application containers are then instructed to use
-weaveDNS as their nameserver by supplying the `--with-dns` option when
-starting them; containers so started also automatically register their
-container name in the weaveDNS domain. For example:
+`launch-dns`.
```bash
$ weave launch
$ weave launch-dns 10.2.254.1/24
-$ weave run --with-dns 10.2.1.25/24 -ti --name=pingme ubuntu
-$ shell1=$(weave run --with-dns 10.2.1.26/24 -ti --name=ubuntu ubuntu)
+```
+
+Containers started while weaveDNS is running are automatically
+registered in [weaveDNS](weavedns.html) if they have a hostname in the
+weaveDNS domain (usually `.weave.local`). In order for containers to
+be able to look up such names, their DNS resolver needs to be
+configured to point at weaveDNS. This will be done automatically while
+weaveDNS is running. If there is no hostname provided, the container
+will be registered in weaveDNS using its container name. Otherwise, if
+there is no container name, and no hostname (or a hostname outside the
+weaveDNS domain), the container will not be registered in weaveDNS.
+For example, to use the container name as the hostname:
+
+```bash
+$ weave run 10.2.1.25/24 -ti --name=pingme ubuntu
+$ shell1=$(weave run 10.2.1.26/24 -ti --name=ubuntu ubuntu)
$ docker attach $shell1
root@ubuntu:/# ping pingme
@@ -51,6 +62,11 @@ it in weaveDNS simply by giving the container a hostname in the
$ weave run 10.2.1.25/24 -ti -h pingme.weave.local ubuntu
```
+It is also possible to force or forbid an application container's use
+of weaveDNS with the `--with-dns` and `--without-dns` options to
+`weave run`; these override the runtime detection of the weaveDNS
+container.
+
Each weaveDNS container started with `launch-dns` needs to be given
its own, unique, IP address, in a subnet that is common to all
weaveDNS containers and not in use on any of the hosts.
@@ -62,7 +78,7 @@ use weaveDNS on a second host we would run:
```bash
host2$ weave launch $HOST1
host2$ weave launch-dns 10.2.254.2/24
-host2$ shell2=$(weave run --with-dns 10.2.1.36/24 -ti --name=ubuntu2 ubuntu)
+host2$ shell2=$(weave run 10.2.1.36/24 -ti --name=ubuntu2 ubuntu)
host2$ docker attach $shell2
root@ubuntu2:/# ping pingme
@@ -117,7 +133,7 @@ Returning to our earlier example, let us start an additional `pingme`
container, this time on the 2nd host, and then run some ping tests...
```bash
-host2$ weave run --with-dns 10.2.1.35/24 -ti --name=pingme ubuntu
+host2$ weave run 10.2.1.35/24 -ti --name=pingme ubuntu
host2$ docker attach $shell2
root@ubuntu2:/# ping -nq -c 1 pingme
diff --git a/test/240_dns_add_name_test.sh b/test/240_dns_add_name_test.sh
index 176354f6..1b0a4070 100755
--- a/test/240_dns_add_name_test.sh
+++ b/test/240_dns_add_name_test.sh
@@ -12,8 +12,8 @@ start_suite "Add and remove names on a single host"
weave_on $HOST1 launch-dns 10.2.254.1/24 $WEAVEDNS_ARGS
-start_container $HOST1 $C2/24 --name=c2
-start_container_with_dns $HOST1 $C1/24 --name=c1
+start_container $HOST1 --without-dns $C2/24 --name=c2
+start_container_with_dns $HOST1 $C1/24 --name=c1
weave_on $HOST1 dns-add $C2 c2 -h $NAME2
diff --git a/test/280_with_or_without_dns_test.sh b/test/280_with_or_without_dns_test.sh
new file mode 100755
index 00000000..f537b7dd
--- /dev/null
+++ b/test/280_with_or_without_dns_test.sh
@@ -0,0 +1,40 @@
+#! /bin/bash
+
+. ./config.sh
+
+IP=10.2.0.34
+TARGET=seetwo.weave.local
+TARGET_IP=10.2.0.78
+
+assert_no_resolution() {
+ container=$(weave_on $HOST1 run "$@" $IP/24 -t $DNS_IMAGE /bin/sh)
+ assert_no_dns_record $HOST1 $container $TARGET
+ rm_containers $HOST1 $container
+}
+
+assert_resolution() {
+ container=$(weave_on $HOST1 run "$@" $IP/24 -t $DNS_IMAGE /bin/sh)
+ assert_dns_record $HOST1 $container $TARGET $TARGET_IP
+ rm_containers $HOST1 $container
+}
+
+start_suite "With or without DNS test"
+
+weave_on $HOST1 launch
+
+DNS_IP=$(weave_on $HOST1 docker-bridge-ip)
+
+# Assert behaviour without weaveDNS running
+assert_no_resolution --without-dns
+assert_no_resolution
+assert_no_resolution --with-dns
+
+weave_on $HOST1 launch-dns 10.2.254.1/24 $WEAVEDNS_ARGS
+start_container $HOST1 $TARGET_IP/24 --name c2 -h $TARGET
+
+# Assert behaviour with weaveDNS running
+assert_no_resolution --without-dns
+assert_resolution
+assert_resolution --with-dns
+
+end_suite
diff --git a/test/630_proxy_dns_test.sh b/test/630_proxy_dns_test.sh
index e0284f60..f37e388b 100755
--- a/test/630_proxy_dns_test.sh
+++ b/test/630_proxy_dns_test.sh
@@ -7,14 +7,45 @@ C2=10.2.0.34
C1_NAME=c1.weave.local
C2_NAME=seetwo.weave.local
+boot_containers() {
+ proxy docker_on $HOST1 run -e WEAVE_CIDR=$C2/24 -dt --name=c2 -h $C2_NAME $DNS_IMAGE /bin/sh
+ proxy docker_on $HOST1 run -e WEAVE_CIDR=$C1/24 -dt --name=c1 $DNS_IMAGE /bin/sh
+}
+
+kill_containers() {
+ rm_containers $HOST1 c1 c2
+}
+
+assert_no_resolution() {
+ boot_containers
+ assert_no_dns_record $HOST1 c1 $C2_NAME $C2
+ assert_no_dns_record $HOST1 c2 $C1_NAME $C1
+ kill_containers
+}
+
start_suite "Proxy registers containers with dns"
-weave_on $HOST1 launch-dns 10.2.254.1/24 $WEAVEDNS_ARGS
-weave_on $HOST1 launch-proxy --with-dns
-proxy docker_on $HOST1 run -e WEAVE_CIDR=$C2/24 -dt --name=c2 -h $C2_NAME $DNS_IMAGE /bin/sh
-proxy docker_on $HOST1 run -e WEAVE_CIDR=$C1/24 -dt --name=c1 $DNS_IMAGE /bin/sh
+bridge_ip=$(weave_on $HOST1 docker-bridge-ip)
+# Assert behaviour without weaveDNS running, but dns forced
+weave_on $HOST1 launch-proxy --with-dns
+assert_no_resolution
+weave_on $HOST1 stop-proxy
+
+# Assert behaviour without weaveDNS
+weave_on $HOST1 launch-proxy
+assert_no_resolution
+
+# Assert behaviour with weaveDNS running
+weave_on $HOST1 launch-dns 10.2.254.1/24 $WEAVEDNS_ARGS
+boot_containers
assert_dns_record $HOST1 c1 $C2_NAME $C2
assert_dns_record $HOST1 c2 $C1_NAME $C1
+kill_containers
+weave_on $HOST1 stop-proxy
+
+# Assert behaviour with weaveDNS running, but dns forced off
+weave_on $HOST1 launch-proxy --without-dns
+assert_no_resolution
end_suite
diff --git a/weave b/weave
index 339a1c0e..c5e9eb3b 100755
--- a/weave
+++ b/weave
@@ -29,10 +29,11 @@ usage() {
echo "weave launch [-password ] [-nickname ] [-nodiscovery]"
echo " [-iprange [-ipsubnet ]] ..."
echo "weave launch-dns []"
- echo "weave launch-proxy [-D ] [-H ] [--with-dns] [--with-ipam]"
+ echo "weave launch-proxy [-D ] [-H ]"
+ echo " [--with-dns | --without-dns] [--with-ipam]"
echo "weave connect [--replace] [ ...]"
echo "weave forget ..."
- echo "weave run [--with-dns] [ ...] ..."
+ echo "weave run [--with-dns | --without-dns] [ ...] ..."
echo "weave start [ ...] "
echo "weave attach [ ...] "
echo "weave detach [ ...] "
@@ -119,6 +120,14 @@ collect_ip_args() {
done
}
+dns_arg_count() {
+ if [ "$1" = "--with-dns" -o "$1" = "--without-dns" ]; then
+ echo 1
+ else
+ echo 0
+ fi
+}
+
# "run" is a special case because we want to use docker directly,
# rather than the docker in $EXEC_IMAGE remotely. That's because we
# are passing arbitrary arguments on to docker run, and we can't rely
@@ -126,10 +135,10 @@ collect_ip_args() {
if [ "$1" = "run" ] ; then
shift 1
check_docker_version
- if [ "$1" = "--with-dns" ] ; then
- shift 1
- DNS_ARGS=$(exec_remote dns-args "$@")
+ if [ "$1" != "--without-dns" ] ; then
+ DNS_ARGS=$(exec_remote dns-args "$@" || true)
fi
+ shift $(dns_arg_count "$@")
collect_cidr_args "$@"
shift $CIDR_ARG_COUNT
CONTAINER=$(docker $DOCKER_CLIENT_ARGS run $DNS_ARGS -d "$@")
@@ -631,7 +640,7 @@ dns_args() {
# versions prior to 1.3.0 fail to include the domain when
# setting the hostname, so lookups for non-fully-qualified
# names fail.
- echo "ERROR: The '--with-dns' option requires Docker 1.3.0 or later; you are running $DOCKER_VERSION" >&2
+ echo "ERROR: Need Docker 1.3.0 or later to configure container DNS; you are running $DOCKER_VERSION" >&2
exit 1
fi
docker_bridge_ip
@@ -639,6 +648,8 @@ dns_args() {
DNS_SEARCH_ARG="--dns-search=."
NAME_ARG=""
HOSTNAME_SPECIFIED=
+ WITH_DNS=
+ WITHOUT_DNS=
while [ $# -gt 0 ] ; do
case "$1" in
--dns-search=*)
@@ -654,9 +665,19 @@ dns_args() {
-h|--hostname|--hostname=*)
HOSTNAME_SPECIFIED=1
;;
+ --with-dns)
+ WITH_DNS=1
+ ;;
+ --without-dns)
+ WITHOUT_DNS=1
+ ;;
esac
shift
done
+ [ -n "$WITHOUT_DNS" ] && return 0
+ if [ -z "$WITH_DNS" ] ; then
+ check_running $DNS_CONTAINER_NAME 2>/dev/null || return 0
+ fi
DNS_ARGS="$DNS_ARG $DNS_SEARCH_ARG"
if [ -n "$NAME_ARG" -a -z "$HOSTNAME_SPECIFIED" ] ; then
DOMAIN=$(call_dns GET /domain 2>/dev/null) || DOMAIN=weave.local.
@@ -1071,10 +1092,8 @@ case "$COMMAND" in
fi
;;
run)
- if [ "$1" = "--with-dns" ] ; then
- shift 1
- dns_args "$@"
- fi
+ dns_args "$@"
+ shift $(dns_arg_count "$@")
collect_cidr_args "$@"
shift $CIDR_ARG_COUNT
CONTAINER=$(docker run $DNS_ARGS -d "$@")