Merge tag 'v1.1.1' into latest_release_doc_updates

Release v1.1.1
This commit is contained in:
Matthias Radestock committed 2015-10-06 15:13:50 +01:00
commit 2f86326405
25 files changed
+238 -135

No files matched your search

+11
View File
@@ -1,3 +1,14 @@
## Release 1.1.1
This release contains a number of bug fixes and minor
enhancements. More details in the
[change log](https://github.com/weaveworks/weave/issues?q=milestone%3A1.1.1).
The release is fully compatible with 1.1.0 versions, so existing
clusters can be upgraded incrementally. When upgrading from 1.0.x,
note the compatibility information in the
[Installation & Upgrading instructions for Weave 1.1.0](https://github.com/weaveworks/weave/releases/tag/v1.1.0).
## Release v1.1.0
**Highlights**:
+1 -1
View File
@@ -50,7 +50,7 @@ all: $(WEAVE_EXPORT) $(COVER_EXE) $(RUNNER_EXE)
travis: $(EXES)
update:
go get -u -f -v -tags -netgo $(addprefix ./,$(dir $(EXES)))
go get -u -f -v -tags netgo $(addprefix ./,$(dir $(EXES)))
$(WEAVER_EXE) $(WEAVEPROXY_EXE): common/*.go common/*/*.go net/*.go
ifeq ($(COVERAGE),true)
Vendored
+1 -1
View File
@@ -5,7 +5,7 @@ require './vagrant-common.rb'
vm_ip = "172.16.0.3" # arbitrary private IP
pkgs = %w(
lxc-docker
docker-engine
aufs-tools
build-essential
ethtool
+8 -4
View File
@@ -52,7 +52,11 @@ setup() {
LATEST_TAG_COMMIT_SHA=$(git rev-list -1 $LATEST_TAG)
LATEST_RELEASE_SHA=$(git rev-parse latest_release)
LATEST_RELEASE_COMMIT_SHA=$(git rev-list -1 latest_release)
VERSION=${LATEST_TAG}
if [ "$RELEASE_TYPE" != 'PRERELEASE' ] ; then
VERSION=${LATEST_TAG#v}
else
VERSION=${LATEST_TAG}
fi
# NB does not check that this tag is on master
RELEASE_DIR=./releases/$LATEST_TAG
}
@@ -223,7 +227,7 @@ publish() {
--repo weave \
--tag latest_release \
--name "$RELEASE_NAME latest ($VERSION)" \
--description "$RELEASE_DESCRIPTION"
--description "[Release Notes](https://github.com/$GITHUB_USER/weave/releases/$LATEST_TAG)"
github-release upload \
--user $GITHUB_USER \
@@ -252,8 +256,8 @@ usage() {
# Ensure required tooling is installed
if ! which github-release >/dev/null; then
echo "Please install git-release:" >&2
echo -e "\tgo get github.com/aktau/github-release" >&2
echo "and create a git token per https://github.com/aktau/github-release" >&2
echo -e "\tgo get github.com/weaveworks/github-release" >&2
echo "and create a git token per https://github.com/weaveworks/github-release" >&2
exit 1
fi
+1 -1
View File
@@ -31,7 +31,7 @@ behaviours for that type of release will be obtained from the script.
* Choose a version tag (see above) henceforth referred to as `$TAG`.
* Add a changelog entry for the new tag at the top of `CHANGELOG.md`.
The first line must be a markdown header of the form `## Release
$TAG`
$TAG` for **Prerelease** builds, `## Release ${TAG#v}` otherwise.
Commit the changelog update:
+1 -1
View File
@@ -59,7 +59,7 @@ func (g *allocate) Try(alloc *Allocator) bool {
}
func (g *allocate) Cancel() {
g.resultChan <- allocateResult{0, fmt.Errorf("Allocate request for %s cancelled", g.ident)}
g.resultChan <- allocateResult{0, &errorCancelled{"Allocate", g.ident}}
}
func (g *allocate) ForContainer(ident string) bool {
+13 -2
View File
@@ -126,11 +126,13 @@ func (alloc *Allocator) cancelOps(ops *[]operation) {
// if we found any.
func (alloc *Allocator) cancelOpsFor(ops *[]operation, ident string) bool {
var found bool
for i, op := range *ops {
if op.ForContainer(ident) {
for i := 0; i < len(*ops); {
if op := (*ops)[i]; op.ForContainer(ident) {
found = true
op.Cancel()
*ops = append((*ops)[:i], (*ops)[i+1:]...)
} else {
i++
}
}
return found
@@ -184,6 +186,15 @@ func hasBeenCancelled(cancelChan <-chan bool) func() bool {
}
}
type errorCancelled struct {
kind string
ident string
}
func (e *errorCancelled) Error() string {
return fmt.Sprintf("%s request for %s cancelled", e.kind, e.ident)
}
// Actor client API
// Allocate (Sync) - get new IP address for container with given name in range
+33 -1
View File
@@ -229,7 +229,6 @@ func TestCancel(t *testing.T) {
doneChan <- ok == nil
}()
AssertNothingSent(t, doneChan)
time.Sleep(100 * time.Millisecond)
AssertNothingSent(t, doneChan)
@@ -240,6 +239,39 @@ func TestCancel(t *testing.T) {
}
}
func TestCancelOnDied(t *testing.T) {
const (
CIDR = "10.0.1.7/26"
container1 = "abcdef"
)
router := gossip.NewTestRouter(0.0)
alloc1, subnet := makeAllocator("01:00:00:02:00:00", CIDR, 2)
alloc1.SetInterfaces(router.Connect(alloc1.ourName, alloc1))
alloc1.Start()
doneChan := make(chan bool)
f := func() {
_, ok := alloc1.Allocate(container1, subnet, nil)
doneChan <- ok == nil
}
// Attempt two allocations in parallel, to check that this is handled correctly
go f()
go f()
// Nothing should happen, because we declared the quorum as 2
time.Sleep(100 * time.Millisecond)
AssertNothingSent(t, doneChan)
alloc1.ContainerDied(container1)
// Check that the two allocations both exit with an error
if <-doneChan || <-doneChan {
require.FailNow(t, "Error: got result from Allocate")
}
}
func TestGossipShutdown(t *testing.T) {
const (
container1 = "abcdef"
+1 -1
View File
@@ -95,7 +95,7 @@ func (c *claim) deniedBy(alloc *Allocator, owner router.PeerName) {
}
func (c *claim) Cancel() {
c.sendResult(fmt.Errorf("Operation cancelled."))
c.sendResult(&errorCancelled{"Claim", c.ident})
}
func (c *claim) ForContainer(ident string) bool {
+46 -48
View File
@@ -16,6 +16,41 @@ func badRequest(w http.ResponseWriter, err error) {
common.Log.Warningln("[allocator]:", err.Error())
}
func parseCIDR(w http.ResponseWriter, cidrStr string) (address.CIDR, bool) {
subnetAddr, cidr, err := address.ParseCIDR(cidrStr)
if err != nil {
badRequest(w, err)
return address.CIDR{}, false
}
if cidr.Start != subnetAddr {
badRequest(w, fmt.Errorf("Invalid subnet %s - bits after network prefix are not all zero", cidrStr))
return address.CIDR{}, false
}
return cidr, true
}
func (alloc *Allocator) handleHTTPAllocate(dockerCli *docker.Client, w http.ResponseWriter, ident string, checkAlive bool, subnet address.CIDR) {
closedChan := w.(http.CloseNotifier).CloseNotify()
addr, err := alloc.Allocate(ident, subnet.HostRange(), closedChan)
if err != nil {
if _, ok := err.(*errorCancelled); ok { // cancellation is not really an error
common.Log.Infoln("[allocator]:", err.Error())
fmt.Fprint(w, "cancelled")
return
}
badRequest(w, err)
return
}
if checkAlive && dockerCli != nil && dockerCli.IsContainerNotRunning(ident) {
common.Log.Infof("[allocator] '%s' is not running: freeing %s", ident, addr)
alloc.Free(ident, addr)
fmt.Fprint(w, "cancelled")
return
}
fmt.Fprintf(w, "%s/%d", addr, subnet.PrefixLen)
}
// HandleHTTP wires up ipams HTTP endpoints to the provided mux.
func (alloc *Allocator) HandleHTTP(router *mux.Router, defaultSubnet address.CIDR, dockerCli *docker.Client) {
router.Methods("PUT").Path("/ip/{id}/{ip}").HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
@@ -36,18 +71,14 @@ func (alloc *Allocator) HandleHTTP(router *mux.Router, defaultSubnet address.CID
router.Methods("GET").Path("/ip/{id}/{ip}/{prefixlen}").HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
cidr := vars["ip"] + "/" + vars["prefixlen"]
_, subnet, err := address.ParseCIDR(cidr)
if err != nil {
badRequest(w, err)
return
if subnet, ok := parseCIDR(w, vars["ip"]+"/"+vars["prefixlen"]); ok {
addr, err := alloc.Lookup(vars["id"], subnet.HostRange())
if err != nil {
http.NotFound(w, r)
return
}
fmt.Fprintf(w, "%s/%d", addr, subnet.PrefixLen)
}
addr, err := alloc.Lookup(vars["id"], subnet.HostRange())
if err != nil {
http.NotFound(w, r)
return
}
fmt.Fprintf(w, "%s/%d", addr, subnet.PrefixLen)
})
router.Methods("GET").Path("/ip/{id}").HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
@@ -60,48 +91,15 @@ func (alloc *Allocator) HandleHTTP(router *mux.Router, defaultSubnet address.CID
})
router.Methods("POST").Path("/ip/{id}/{ip}/{prefixlen}").HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
closedChan := w.(http.CloseNotifier).CloseNotify()
vars := mux.Vars(r)
ident := vars["id"]
cidrStr := vars["ip"] + "/" + vars["prefixlen"]
subnetAddr, cidr, err := address.ParseCIDR(cidrStr)
if err != nil {
badRequest(w, err)
return
if subnet, ok := parseCIDR(w, vars["ip"]+"/"+vars["prefixlen"]); ok {
alloc.handleHTTPAllocate(dockerCli, w, vars["id"], r.FormValue("check-alive") == "true", subnet)
}
if cidr.Start != subnetAddr {
badRequest(w, fmt.Errorf("Invalid subnet %s - bits after network prefix are not all zero", cidrStr))
return
}
addr, err := alloc.Allocate(ident, cidr.HostRange(), closedChan)
if err != nil {
badRequest(w, fmt.Errorf("Unable to allocate: %s", err))
return
}
if r.FormValue("check-alive") == "true" && dockerCli != nil && dockerCli.IsContainerNotRunning(ident) {
common.Log.Infof("[allocator] '%s' is not running: freeing %s", ident, addr)
alloc.Free(ident, addr)
return
}
fmt.Fprintf(w, "%s/%d", addr, cidr.PrefixLen)
})
router.Methods("POST").Path("/ip/{id}").HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
closedChan := w.(http.CloseNotifier).CloseNotify()
ident := mux.Vars(r)["id"]
newAddr, err := alloc.Allocate(ident, defaultSubnet.HostRange(), closedChan)
if err != nil {
badRequest(w, err)
return
}
if r.FormValue("check-alive") == "true" && dockerCli != nil && dockerCli.IsContainerNotRunning(ident) {
common.Log.Infof("[allocator] '%s' is not running: freeing %s", ident, newAddr)
alloc.Free(ident, newAddr)
return
}
fmt.Fprintf(w, "%s/%d", newAddr, defaultSubnet.PrefixLen)
vars := mux.Vars(r)
alloc.handleHTTPAllocate(dockerCli, w, vars["id"], r.FormValue("check-alive") == "true", defaultSubnet)
})
router.Methods("DELETE").Path("/ip/{id}/{ip}").HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+10 -8
View File
@@ -15,7 +15,7 @@ import (
"github.com/weaveworks/weave/router"
)
func startServer(t *testing.T) (*DNSServer, *Nameserver, int, int) {
func startServer(t *testing.T, upstream *dns.ClientConfig) (*DNSServer, *Nameserver, int, int) {
peername, err := router.PeerNameFromString("00:00:00:02:00:00")
require.Nil(t, err)
nameserver := New(peername, nil, nil, "")
@@ -23,13 +23,16 @@ func startServer(t *testing.T) (*DNSServer, *Nameserver, int, int) {
require.Nil(t, err)
udpPort := dnsserver.servers[0].PacketConn.LocalAddr().(*net.UDPAddr).Port
tcpPort := dnsserver.servers[1].Listener.Addr().(*net.TCPAddr).Port
if upstream != nil {
dnsserver.upstream = upstream
}
go dnsserver.ActivateAndServe()
return dnsserver, nameserver, udpPort, tcpPort
}
func TestTruncation(t *testing.T) {
//common.SetLogLevel("debug")
dnsserver, nameserver, udpPort, tcpPort := startServer(t)
dnsserver, nameserver, udpPort, tcpPort := startServer(t, nil)
defer dnsserver.Stop()
// Add 100 mappings to nameserver
@@ -122,9 +125,9 @@ func TestRecursiveCompress(t *testing.T) {
require.True(t, response.Len() <= maxSize)
// A dns server that returns the above response
var gotRequest = false
var gotRequest = make(chan struct{}, 1)
handleRecursive := func(w dns.ResponseWriter, req *dns.Msg) {
gotRequest = true
gotRequest <- struct{}{}
require.Equal(t, req.Question[0].Name, hostname)
response.SetReply(req)
err := w.WriteMsg(&response)
@@ -140,14 +143,13 @@ func TestRecursiveCompress(t *testing.T) {
defer udpServer.Shutdown()
// The weavedns server, pointed at the above server
dnsserver, _, udpPort, _ := startServer(t)
dnsserver.upstream = &dns.ClientConfig{
dnsserver, _, udpPort, _ := startServer(t, &dns.ClientConfig{
Servers: []string{"127.0.0.1"},
Port: strconv.Itoa(udpServerPort),
Ndots: 1,
Timeout: 5,
Attempts: 2,
}
})
defer dnsserver.Stop()
// Now do lookup, check its what we expected.
@@ -165,6 +167,6 @@ func TestRecursiveCompress(t *testing.T) {
c := new(dns.Client)
res, _, err := c.Exchange(req, fmt.Sprintf("127.0.0.1:%d", udpPort))
require.Nil(t, err)
require.True(t, gotRequest)
require.True(t, len(gotRequest) > 0)
require.True(t, res.Len() > maxSize)
}
+7
View File
@@ -148,11 +148,18 @@ func (c *GossipChannel) gcSenders(connections ConnectionSet) {
}
}
// We have seen a couple of failures which suggest a >128GB slice was encountered.
// 100MB should be enough for anyone.
const maxFeasibleMessageLen = 100 * 1024 * 1024
func (c *GossipChannel) sendDown(conn Connection, data GossipData) {
sender, found := c.senders[conn]
if !found {
sender = NewGossipSender(func(pending GossipData) {
for _, msg := range pending.Encode() {
if len(msg) > maxFeasibleMessageLen {
panic(fmt.Sprintf("Gossip message too large: len=%d bytes; on channel '%s' from %+v", len(msg), c.name, pending))
}
protocolMsg := ProtocolMsg{ProtocolGossip, GobEncode(c.name, c.ourself.Name, msg)}
conn.(ProtocolSender).SendProtocolMsg(protocolMsg)
}
File renamed without changes.
+31
View File
@@ -0,0 +1,31 @@
#! /bin/bash
. ./config.sh
C1=10.2.1.43
C2=10.2.1.44
C3=10.2.1.45
start_suite "re-using IP addresses (arp cache updating)"
weave_on $HOST1 launch
check() {
assert_raises "exec_on $HOST1 c1 $PING $C2"
}
start_container $HOST1 $C1/24 --name=c1
start_container $HOST1 $C2/24 --name=c2
check
docker_on $HOST1 stop c2
start_container $HOST1 $C2/24 --name=c3
check
docker_on $HOST1 stop c3
start_container $HOST1 $C3/24 --name=c4
weave_on $HOST1 attach $C2/24 c4
check
end_suite
-2
View File
@@ -15,6 +15,4 @@ start_container_with_dns $HOST1 $C1/24 --name=c1
assert_dns_record $HOST1 c1 $NAME $C2
assert_raises "exec_on $HOST1 c1 dig MX $NAME | grep -q 'status: NXDOMAIN'"
end_suite
+6 -2
View File
@@ -6,7 +6,11 @@ start_suite "Negative DNS queries"
weave_on $HOST1 launch
start_container_with_dns $HOST1 --name c1
assert_raises "exec_on $HOST1 c1 dig A foo.weave.local | grep 'status: NXDOMAIN'"
assert_raises "exec_on $HOST1 c1 dig A foo.invalid | grep 'status: NXDOMAIN'"
# unsupported query types, unknown names, and unknown domains should
# all trigger NXDOMAIN
assert_raises "exec_on $HOST1 c1 dig MX c1.weave.local | grep -q 'status: NXDOMAIN'"
assert_raises "exec_on $HOST1 c1 dig A xx.weave.local | grep -q 'status: NXDOMAIN'"
assert_raises "exec_on $HOST1 c1 dig A xx.invalid | grep -q 'status: NXDOMAIN'"
end_suite
-2
View File
@@ -14,12 +14,10 @@ start_container $HOST1 $C2/24 --name=c2 -h $NAME
start_container_with_dns $HOST1 $C1/24 --name=c1
assert_dns_record $HOST1 c1 $NAME $C2
assert_raises "exec_on $HOST1 c1 dig MX $NAME | grep -q 'status: NXDOMAIN'"
weave_on $HOST1 stop
weave_on $HOST1 launch
assert_dns_record $HOST1 c1 $NAME $C2
assert_raises "exec_on $HOST1 c1 dig MX $NAME | grep -q 'status: NXDOMAIN'"
end_suite
-2
View File
@@ -16,8 +16,6 @@ for i in $(seq $N); do
done
weave_on $HOST1 dns-add $IPS $CID -h $NAME
assert_raises "exec_on $HOST1 c0 dig MX $NAME | grep -q 'status: NXDOMAIN'"
check() {
assert "exec_on $HOST1 c0 dig +short $* $NAME A | grep -v ';;' | wc -l" $N
}
+2 -2
View File
@@ -28,8 +28,8 @@ assert_raises "DOCKER_CLIENT_ARGS='--tls' weave_on $HOST1 launch-proxy" 1
assert_raises "DOCKER_CERT_PATH='./tls' DOCKER_TLS_VERIFY=1 weave_on $HOST1 launch-proxy" 1
# Booting it with a specific -H overrides defaults
weave_on $HOST1 launch-proxy -H unix:///var/run/weave2.sock
assert_raises "run_on $HOST1 sudo docker -H unix:///var/run/weave2.sock ps"
weave_on $HOST1 launch-proxy -H tcp://0.0.0.0:12345
assert_raises "run_on $HOST1 sudo docker -H tcp://$HOST1:12345 ps"
assert_raises "proxy docker_on $HOST1 ps" 1
weave_on $HOST1 stop-proxy
+20
View File
@@ -57,3 +57,23 @@ DOCKER_OPTS="--host unix:///var/run/docker.sock --host tcp://0.0.0.0:2375"
```
to the file `/etc/default/docker`, then restart docker.
## Updating the GCE test image
When a new version of Docker is released, you'll need to update the GCE test image.
To do this, pick a fresh ```TEMPLATE_NAME``` and update any commands in
```function make_template``` in gce.sh, then run:
```
./gce.sh make_template
```
For this you'll need the GCE credentials, which can be found in ```bin/setup-circleci-secrets```,
which you'll need to decrypt and run (its echos the secrets into know locations):
```
./bin/setup-circleci-secrets "$SECRET_PASSWORD"
```
If you don't know the password, ask tom@weave.works.
+3 -3
View File
@@ -12,7 +12,7 @@ ip_suffix_base = 10
require '../vagrant-common.rb'
def configure_docker(host, hostname, ip)
pkgs = %w(lxc-docker ethtool)
pkgs = %w(docker-engine ethtool)
host.vm.box = "ubuntu/ubuntu-15.04-amd64"
host.vm.box_url = "https://cloud-images.ubuntu.com/vagrant/vivid/current/vivid-server-cloudimg-amd64-vagrant-disk1.box"
@@ -22,8 +22,8 @@ def configure_docker(host, hostname, ip)
host.vm.synced_folder ".", "/vagrant", disabled: true
host.vm.provision :shell, :inline => "sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 36A1D7869245C8950F966E92D8576A8BA88D21E9"
host.vm.provision :shell, :inline => "echo deb https://get.docker.io/ubuntu docker main > /etc/apt/sources.list.d/docker.list"
host.vm.provision :shell, :inline => "sudo apt-key adv --keyserver hkp://p80.pool.sks-keyservers.net:80 --recv-keys 58118E89F3A912897C070ADBF76221572C52609D"
host.vm.provision :shell, :inline => "echo deb https://apt.dockerproject.org/repo ubuntu-vivid main > /etc/apt/sources.list.d/docker.list"
install_packages host.vm, pkgs
tweak_docker_daemon host.vm
+4 -4
View File
@@ -11,7 +11,7 @@ set -e
: ${SSH_KEY_FILE:=$HOME/.ssh/gce_ssh_key}
: ${PROJECT:=positive-cocoa-90213}
: ${IMAGE:=ubuntu-14-04}
: ${TEMPLATE_NAME:=test-template-3}
: ${TEMPLATE_NAME:=test-template-4}
: ${ZONE:=us-central1-a}
: ${NUM_HOSTS:=5}
SUFFIX=""
@@ -68,10 +68,10 @@ function try_connect {
function install_docker_on {
name=$1
ssh -t $name sudo bash -x -s <<EOF
apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 36A1D7869245C8950F966E92D8576A8BA88D21E9;
echo deb https://get.docker.io/ubuntu docker main > /etc/apt/sources.list.d/docker.list;
curl -sSL https://get.docker.com/gpg | sudo apt-key add -
curl -sSL https://get.docker.com/ | sh
apt-get update -qq;
apt-get install -q -y --force-yes --no-install-recommends lxc-docker ethtool;
apt-get install -q -y --force-yes --no-install-recommends ethtool;
usermod -a -G docker vagrant;
echo 'DOCKER_OPTS="-H unix:///var/run/docker.sock -H tcp://0.0.0.0:2375"' >> /etc/default/docker;
service docker restart
+4 -4
View File
@@ -5,7 +5,7 @@ import (
"log"
"os"
"github.com/docker/machine/utils"
"github.com/docker/machine/libmachine/cert"
)
const (
@@ -28,7 +28,7 @@ func main() {
log.Fatalf("The CA key already exists. Please remove it or specify a different key/cert.")
}
if err := utils.GenerateCACertificate(caCertPath, caKeyPath, org, bits); err != nil {
if err := cert.GenerateCACertificate(caCertPath, caKeyPath, org, bits); err != nil {
log.Printf("Error generating CA certificate: %s", err)
}
}
@@ -41,7 +41,7 @@ func main() {
log.Fatalf("The client key already exists. Please remove it or specify a different key/cert.")
}
err = utils.GenerateCert(
err = cert.GenerateCert(
[]string{""},
clientCertPath,
clientKeyPath,
@@ -64,7 +64,7 @@ func main() {
if _, err := os.Stat(serverCertPath); os.IsNotExist(err) {
log.Printf("Creating server certificate: %s", serverCertPath)
err = utils.GenerateCert(
err = cert.GenerateCert(
[]string{ip},
serverCertPath,
serverKeyPath,
+3 -3
View File
@@ -13,9 +13,9 @@ def install_build_deps(vm, pkgs)
vm.provision :shell, :inline => <<SCRIPT
export DEBIAN_FRONTEND=noninteractive
apt-key adv \
--keyserver hkp://keyserver.ubuntu.com:80 \
--recv-keys 36A1D7869245C8950F966E92D8576A8BA88D21E9
echo 'deb https://get.docker.io/ubuntu docker main' \
--keyserver hkp://p80.pool.sks-keyservers.net:80 \
--recv-keys 58118E89F3A912897C070ADBF76221572C52609D
echo 'deb https://apt.dockerproject.org/repo ubuntu-vivid main' \
> /etc/apt/sources.list.d/docker.list
SCRIPT
install_packages(vm, pkgs)
+32 -43
View File
@@ -96,7 +96,7 @@ usage() {
exec_remote() {
docker $DOCKER_CLIENT_ARGS run --rm --privileged --net=host \
-v /var/run/docker.sock:/var/run/docker.sock \
-v /var/run:/var/run \
-v /proc:/hostproc \
-e PROCFS=/hostproc \
-e DOCKERHUB_USER="$DOCKERHUB_USER" \
@@ -332,8 +332,9 @@ configure_arp_cache() {
echo 1 >/proc/sys/net/ipv4/neigh/$1/ucast_solicit"
}
# Send out an unsolicated ARP response to update ARP cache entries
# across the weave network. We do this in addition to
# Send out an ARP announcement
# (https://tools.ietf.org/html/rfc5227#page-15) to update ARP cache
# entries across the weave network. We do this in addition to
# configure_arp_cache because a) with those ARP cache settings it
# still takes a few seconds to correct a stale ARP mapping, and b)
# there is a kernel bug that means that the base_reachable_time
@@ -520,29 +521,23 @@ launch() {
}
attach() {
if netnsenter ip link show $CONTAINER_IFNAME >/dev/null 2>&1 ; then
for ADDR in "$@" ; do
# container already has the expected network interface, so assume we set it up already;
# just add the IP address.
if netnsenter ip addr show dev $CONTAINER_IFNAME | grep -F $ADDR >/dev/null ; then
# address was there already
continue
fi
netnsenter ip addr add $ADDR dev $CONTAINER_IFNAME || return 1
done
return 0
if ! netnsenter ip link show $CONTAINER_IFNAME >/dev/null 2>&1 ; then
connect_container_to_bridge || return 1
fi
connect_container_to_bridge || return 1
NEW_ADDRS=
for ADDR in "$@" ; do
if netnsenter ip addr show dev $CONTAINER_IFNAME | grep -F $ADDR >/dev/null ; then
# address was there already
continue
fi
netnsenter ip addr add $ADDR dev $CONTAINER_IFNAME || return 1
NEW_ADDRS="$NEW_ADDRS $ADDR"
done
netnsenter ip link set $CONTAINER_IFNAME up || return 1
for ADDR in "$@" ; do
for ADDR in $NEW_ADDRS ; do
arp_update $CONTAINER_IFNAME $ADDR "netnsenter"
done
@@ -913,28 +908,20 @@ ipam_cidrs() {
shift 1
ALL_CIDRS=""
IPAM_CIDRs=""
if [ $# -eq 0 ] ; then
# If no addresses passed in, get one in the default subnet
IPAM_CIDRS=$(call_weave POST /ip/$CONTAINER_ID$CHECK_ALIVE) || return 1
if [ "$IPAM_CIDRS" = "404 page not found" ] ; then
echo "No IP address supplied (use the -iprange option on 'weave launch' to enable IP address allocation)" >&2
return 1
fi
ALL_CIDRS="$IPAM_CIDRS"
fi
while [ $# -gt 0 ] ; do
if [ "${1%:*}" = "net" ] ; then
if [ "$1" = "net:default" ] ; then
# If no addresses passed in, get one in the default subnet
[ $# -gt 0 ] || set -- net:default
for arg in "$@" ; do
if [ "${arg%:*}" = "net" ] ; then
if [ "$arg" = "net:default" ] ; then
IPAM_URL=/ip/$CONTAINER_ID
else
IPAM_URL=/ip/$CONTAINER_ID/"${1#net:}"
IPAM_URL=/ip/$CONTAINER_ID/"${arg#net:}"
fi
CIDR=$(call_weave POST $IPAM_URL$CHECK_ALIVE) || return 1
if [ "$CIDR" = "404 page not found" ] ; then
echo "IP address allocation must be enabled to use 'net:'" >&2
return 1
fi
if ! is_cidr "$CIDR" ; then
elif ! is_cidr "$CIDR" ; then
echo "$CIDR" >&2
return 1
fi
@@ -942,13 +929,12 @@ ipam_cidrs() {
ALL_CIDRS="$ALL_CIDRS $CIDR"
else
# This is a plain IP address; warn if it clashes but carry on
command_exists netcheck && netcheck --ignore-iface=$BRIDGE $1 || true
command_exists netcheck && netcheck --ignore-iface=$BRIDGE $arg || true
if container_ip $CONTAINER_NAME 2>/dev/null ; then
http_call_ip $CONTAINER_IP $HTTP_PORT PUT /ip/$CONTAINER_ID/${1%/*} >&2
http_call_ip $CONTAINER_IP $HTTP_PORT PUT /ip/$CONTAINER_ID/${arg%/*} >&2
fi
ALL_CIDRS="$ALL_CIDRS $1"
ALL_CIDRS="$ALL_CIDRS $arg"
fi
shift 1
done
}
@@ -1053,7 +1039,7 @@ proxy_args() {
if [ -z "$PROXY_HOST" ] ; then
case "$DOCKER_CLIENT_HOST" in
""|unix://*)
PROXY_HOST="unix:///var/run/weave.sock"
PROXY_HOST="unix:///var/run/weave/weave.sock"
;;
*)
PROXY_HOST="tcp://0.0.0.0:12375"
@@ -1074,7 +1060,7 @@ proxy_addr() {
warn_if_stopping_proxy_in_env() {
if PROXY_ADDR=$(proxy_addr 2>/dev/null) ; then
[ "$PROXY_ADDR" != "$DOCKER_CLIENT_HOST" ] || echo "WARNING: It appears that your environment is configured to use the Weave Docker API proxy. Stopping it will break this and subsequent docker invocations. To restore your environment, run '\$(eval weave env --restore)'."
[ "$PROXY_ADDR" != "$DOCKER_CLIENT_HOST" ] || echo "WARNING: It appears that your environment is configured to use the Weave Docker API proxy. Stopping it will break this and subsequent docker invocations. To restore your environment, run 'eval \$(weave env --restore)'."
fi
}
@@ -1215,7 +1201,8 @@ launch_proxy() {
PROXY_CONTAINER=$(docker run --privileged -d --name=$PROXY_CONTAINER_NAME --net=host \
$PROXY_VOLUMES \
-v "$CONTAINERS_PATH":"$CONTAINERS_PATH" \
-v /var/run:/var/run \
-v /var/run/docker.sock:/var/run/docker.sock \
-v /var/run/weave:/var/run/weave \
-v /proc:/hostproc \
-e PROCFS=/hostproc \
-e WEAVE_CIDR=none \
@@ -1223,6 +1210,8 @@ launch_proxy() {
--entrypoint=/home/weave/weaveproxy \
$WEAVEPROXY_DOCKER_ARGS $EXEC_IMAGE $COVERAGE_ARGS $PROXY_ARGS)
wait_for_log $PROXY_CONTAINER_NAME "proxy listening"
# backward compatibility
ln -sf -T /var/run/weave/weave.sock /var/run/weave.sock
}
##########################################################################################
@@ -1350,7 +1339,7 @@ case "$COMMAND" in
launch)
deprecation_warnings "$@"
check_not_running $CONTAINER_NAME $BASE_IMAGE
check_not_running $PROXY_CONTAINER_NAME $EXEC_IMAGE
check_not_running $PROXY_CONTAINER_NAME $BASE_EXEC_IMAGE
COMMON_ARGS=$(common_launch_args "$@")
launch_router "$@"
launch_proxy $COMMON_ARGS
@@ -1363,7 +1352,7 @@ case "$COMMAND" in
;;
launch-proxy)
deprecation_warnings "$@"
check_not_running $PROXY_CONTAINER_NAME $EXEC_IMAGE
check_not_running $PROXY_CONTAINER_NAME $BASE_EXEC_IMAGE
launch_proxy "$@"
echo $PROXY_CONTAINER
;;
@@ -1616,7 +1605,7 @@ case "$COMMAND" in
conntrack -D -p udp --dport $PORT >/dev/null 2>&1 || true
destroy_bridge
for LOCAL_IFNAME in $(ip link show | grep v${CONTAINER_IFNAME}pl | cut -d ' ' -f 2 | tr -d ':') ; do
ip link del $LOCAL_IFNAME >/dev/null 2>&1 || true
ip link del ${LOCAL_IFNAME%@*} >/dev/null 2>&1 || true
done
;;
rmpeer)