Compare commits

...
677 Commits
Author SHA1 Message Date
Bryan Boreham a7ebe53cfa Add release v1.9.8 2017-06-15 17:05:11 +00:00
Marc Carré b655a3aede Merge pull request #3014 from weaveworks/issues/3011-allow-non-pod-source
Allow any non-local traffic onto the weave bridge
2017-06-14 14:52:11 +01:00
Bryan Boreham 819b395ae4 Temporarily raise the test timeout
Docker 1.11 seems much slower at the pull tests than Docker 1.13
while we investigate that, raise the timeout to allow tests to pass
2017-06-14 13:14:06 +00:00
Bryan Boreham 2584335b11 Allow any non-local traffic onto the weave bridge
If it's destined for a pod on another node it will be checked again
when it reaches that other node.  The previous version was rejecting
traffic coming in from outside the cluster.
2017-06-12 17:00:57 +00:00
Bryan Boreham 21d4fff450 Update broken link to Docker docs 2017-06-12 09:42:22 +01:00
Marc Carré a5d7fb66f0 Merge pull request #3010 from weaveworks/issues/3003-anonymous-claim
Fix use of '_' as container ID in claim outside range
2017-06-09 08:30:13 +01:00
Bryan Boreham b01a204c1f Check who previously owned an address claimed outside the range 2017-06-08 16:25:09 +00:00
Bryan Boreham e9310eba98 Don't use '_' as container ID in claim outside range
And added unit test for various claim-without-ID situations
2017-06-07 16:38:19 +00:00
Bryan Boreham 69285270e5 Bump Ruby version
2.3.4 is pre-installed by CircleCI, whereas 2.3.0 isn't
2017-06-07 13:01:15 +00:00
Bryan Boreham 6bd11a426e typo 2017-06-01 14:28:10 +00:00
Bryan Boreham 1abdc3afcf Add release v1.9.7 2017-06-01 13:51:06 +00:00
Bryan Boreham b8f98a5387 Merge pull request #2996 from Bregor/issues/2995-npc-and-hostname_override
Weave-NPC should get hostname from K8s Downward API.
2017-06-01 14:33:22 +01:00
Maxim Filatov cb3b858df6 Weave-NPC should get hostname from K8s Downward API.
It is necessary in case when kubelet's args includes `--hostname_override=`.
Without this change, pods on hostname overriding kubelets will never be local,
and all pod's traffic will be blocked.
2017-05-31 18:06:17 +03:00
Bryan Boreham afb0d5bd3d Add release v1.9.6 2017-05-30 16:28:11 +00:00
Bryan Boreham 2d3e070288 Let through connections from local pods to non-local pods
This means we only filter connections at the destination end,
which is a better match for the ingress-only rules.
2017-05-30 14:11:35 +00:00
Bryan Boreham 138141ac9b Ignore updates for pods on other nodes 2017-05-30 14:11:34 +00:00
Bryan Boreham fa56ad8bc3 Refactor: move logging of ipset entries down to ipset package 2017-05-30 14:11:33 +00:00
Bryan Boreham 9d29da8d27 Refactor creation of base iptables rules 2017-05-30 14:11:31 +00:00
Bryan Boreham 68f2cb9caa Merge pull request #2993 from weaveworks/hairpin-option-1.9
Turn on hairpin mode on veth bridge ports
2017-05-30 14:50:37 +01:00
Avi Deitcher d13c7ea7ee Make hairpin mode default true in CNI 2017-05-30 10:30:54 +00:00
Avi Deitcher 4c7c702b6d Test of hairpin mode in CNI 2017-05-30 10:30:54 +00:00
Avi Deitcher c05955d598 First cut of adding hairpin functionality to weave 2017-05-30 10:30:49 +00:00
Bryan Boreham ca64ab54e7 Remove trailing space 2017-05-30 10:30:02 +00:00
Àbéjídé Àyodélé e64442f6de Highlight the forward rules 2017-05-25 13:43:51 +00:00
Bryan Boreham 987a1618e9 Merge pull request #2985 from weaveworks/fix-broken-url-to-ecs-guide
Fix broken link to ECS guide
2017-05-23 17:59:49 +01:00
Marc CARRE 0ab95cdd27 Fix broken URL to ECS guide. 2017-05-23 16:58:36 +00:00
Marc Carré b0d0c3d731 Merge pull request #2986 from weaveworks/remove-wordepress
Stop doing Wordpress previews on Pantheon
2017-05-23 12:01:05 +01:00
Bryan Boreham 534dd8e16a Stop doing Wordpress previews on Pantheon
Now we are using Netlify instead
2017-05-23 11:33:57 +01:00
Marc Carré 79e703c8ac Merge pull request #2987 from weaveworks/use-fixed-version-of-shfmt
Use shfmt v1.3.0 instead of latest from master
2017-05-23 11:31:03 +01:00
Marc CARRE d4a98a58f4 Use shfmt v1.3.0 instead of latest from master.
Before this change, `go get`-ting` would pick the latest version of `shfmt` which keeps changing, hence frequently breaking our builds.

After this change, we download the `shfmt` binary from its GitHub releases page which is fast and locks the version we use. Note that `RUN` does not like herestrings, hence `echo "..." | sha256sum -c` for checksum.

Alternatives considered:
- `go get gopkg.in/mvdan/sh.v1/cmd/shfmt` -- but `gopkg.in` currently doesn't behave well for this tool
- `go build` from a `git` tag -- but this is much more involved.
2017-05-23 10:59:11 +01:00
Bryan Boreham 72532324ed Give up on versioned copy of shfmt; it doesn't build 2017-05-18 10:18:11 +00:00
Marc Carré 68106d804e Merge pull request #2959 from ocadotechnology/wip-2958
fix(npc): create ipsets with only valid xml characters
2017-05-15 13:30:10 +01:00
Bryan Boreham efff6d6e63 Merge pull request #2962 from weaveworks/fix-shfmt-lint-error
Fix shfmt lint error by escaping $ in sed expression
2017-05-15 13:21:12 +01:00
Marc CARRE 6bbd8d7a4c Escape $ in sed expression.
This fixes new error raised by latest version of shfmt, leading to build failures.
2017-05-15 12:36:55 +01:00
stuart.warren 9cbf0289d8 fix(npc): create ipsets with only valid xml characters
Why:
* xml output of ipset is invalid because ipset itself doesn't appear to
 escape invalid chars

* fixes #2958
2017-05-15 11:20:04 +01:00
Bryan Boreham 255d087416 Merge pull request #2949 from ocadotechnology/wip-2915
Flush weave ipsets before destroying
2017-05-12 13:15:09 +01:00
Mike Bryant 8668f6bb1e Flush weave ipsets before destroying
ipsets can't be destroyed when there are references to them.
This takes the easy way out and flushes all weave ipsets first.

Fixes #2915
2017-05-12 09:44:26 +01:00
Mike Bryant 95ee99d652 style: singular vs plural 2017-05-12 09:44:18 +01:00
Bryan Boreham 30583ec8f2 Merge pull request #2930 from weaveworks/fix-broken-links
Fix some broken links in documentation
2017-05-11 16:24:00 +01:00
Bryan Boreham e370ef7007 Fix 'How Weave Finds Containers' link 2017-05-11 15:06:29 +00:00
Ilya Dmitrichenko 42953faf70 Fix some broken links in documentation 2017-05-11 15:06:20 +00:00
Bryan Boreham 6c29a1f648 Merge pull request #2940 from weaveworks/fix_libssl_mismatch
Fix build libssl issue: Use cross-compilers from debian rather than ubuntu
2017-05-09 13:37:10 +01:00
Marcus Cobden fa29b18be7 Use cross-compilers from debian rather than ubuntu 2017-05-09 09:32:54 +00:00
Bryan Boreham 40db885b3a Merge pull request #2935 from ocadotechnology/wip-2934
Clean up xt_set_exists components in advance
2017-05-09 10:04:56 +01:00
Bryan Boreham ae0c16f375 Merge pull request #2884 from weaveworks/issues/2794-kube-evict-docs
Add pod resources and eviction to weave-kube doc
2017-05-09 10:02:54 +01:00
Bryan Boreham 909b751d6d Explain how to see Evicted pods 2017-05-08 13:14:59 +00:00
Mike Bryant 9419ad16bf Clean up xt_set_exists components in advance
If this function dies in the middle, the leftover weave-kube-test set
causes this function and weave-npc to break. In particular
this means we can never restart weave with the launch script.

Here we clean up in advance, in case there's leftovers from a previous run

Fixes #2934
2017-05-08 12:15:23 +01:00
Bryan Boreham 2c12c4f67e Merge pull request #2928 from weaveworks/issues/2921-ignore-enoent-on-iface-del
Ignore errors on network interface delete during CNI Delete
2017-05-05 20:45:38 +01:00
Marc CARRE be11db45d8 Ignore error when deleting a container's interface.
Fixes #2921, as all errors are now ignored, including `ENOENT`.
This command typically attempts to delete the network interface `eth0` of a container being destroyed by Kubernetes.
If this interface has already been destroyed or is missing for whatever reason, we still want to remove this container's entry from IPAM in order to free associated resources.
2017-05-05 17:24:08 +00:00
Marc CARRE 30213bd71e Comply to CNI 0.5 spec by always returning nil on DEL.
See also:
  "Plugins should generally complete a DEL action without error even if some resources are missing."
in:
  https://github.com/containernetworking/cni/blob/v0.5.0/SPEC.md
2017-05-05 17:24:08 +00:00
Bryan Boreham b14501f358 Merge pull request #2931 from weaveworks/patch-wordepress
Use a version of wordepress that handles 'search-type' attribute
2017-05-05 18:21:42 +01:00
Bryan Boreham e93a145bab Build a version of wordepress that handles 'search-type' attribute 2017-05-05 16:58:33 +00:00
Ilya Dmitrichenko 8b245a442c Add website preview 2017-05-05 15:23:08 +01:00
Bryan Boreham 041b6fe251 Add release v1.9.5 2017-05-04 08:49:15 +00:00
Marc Carré d128488339 Merge pull request #2926 from weaveworks/issues/2808-improve-hairpin-messages
Fixes #2808. Improve hairpin log messages.
2017-05-03 20:21:20 +01:00
Marc Carré c8c61adca4 Merge pull request #2907 from weaveworks/issues/2771-checkpoint-net-modes
Add checkpoint flag per connection type
2017-05-03 18:20:30 +01:00
Bryan Boreham 7c8f33f525 Add checkpoint flag per connection type 2017-05-03 16:56:49 +00:00
Bryan Boreham 15bf6eab1e Merge pull request #2925 from weaveworks/doc-search-tag
added search tag type
2017-05-03 17:35:00 +01:00
abuehrle 10333b0f3e added search tag type 2017-05-03 16:33:40 +00:00
Ilya Dmitrichenko 52a5ca8f88 Fix broken link in docs 2017-05-03 16:43:57 +01:00
Bryan Boreham b19f2df6f8 Improve hairpin log messages 2017-05-03 14:35:20 +00:00
Bryan Boreham b3ac56e3d2 Update mesh library and check for errors newly returned 2017-05-03 11:08:28 +00:00
Marc Carré cc77ad2c65 Merge pull request #2912 from weaveworks/issues/2904-filter-ipv6-kube-peers
Filter out IPv6 addresses from kube-peers
2017-05-02 11:45:31 +01:00
Bryan Boreham 24c2743a58 Check addresses are IPv4 in kube-peers 2017-04-28 11:05:38 +00:00
Bryan Boreham b49f5bdb99 Merge pull request #2916 from ocadotechnology/allow-for-externalip
fix(kube-peers): Add support for ExternalIP addresses
2017-04-27 15:29:02 +01:00
Marc CARRE 28a1578d20 Please ./tools/lint -nocomment -notestpackage.
Fixes:
- `test/run-integration-tests.sh:160:75: arithmetic expressions must consist of names and numbers`
- `test/run-integration-tests.sh:265:56: arithmetic expressions must consist of names and numbers`
- `test/run-integration-tests.sh:295:61: arithmetic expressions must consist of names and numbers`
- `test/run-integration-tests.sh:309:49: arithmetic expressions must consist of names and numbers`
- `test/run-integration-tests.sh:316:41: arithmetic expressions must consist of names and numbers`
- `test/run-integration-tests.sh: run shfmt -i 4 -w test/run-integration-tests.sh`

See also: https://circleci.com/gh/weaveworks/weave/8685
2017-04-27 14:06:42 +00:00
Mike Bryant e78be1fc35 fix(kube-peers): Add support for ExternalIP addresses
Why:
* In some environments Nodes have an ExternalIP but no InternalIP

This change addresses the need by:
* Falling back to ExternalIP addresses if there isn't an InternalIP for a node
2017-04-27 13:56:23 +01:00
Bryan Boreham 109e249aa6 Review feedback 2017-04-25 14:08:25 +00:00
Marc Carré 402fe094f4 Merge pull request #2893 from weaveworks/ipam-ops-reentrant. Fixes #2892.
IPAM: Make sure we have a ring before calling tryOps()
2017-04-12 13:25:32 +01:00
Bryan Boreham 1c1b3248c0 Make sure we have a ring before calling tryOps()
because otherwise the pending ops can be modified from inside Try()
2017-04-11 15:36:53 +00:00
Bryan Boreham 60c5e11871 Add pod resources and eviction to weave-kube doc 2017-04-11 12:29:27 +00:00
Ilya Dmitrichenko 5cae747b36 Consisten spacing in Markdown headings
Jekyll doesn't tolerate this, and it's generally cosidered a cleaner
style, we've had a bit of mixed style and this makes it consistent.
2017-04-10 12:44:38 +00:00
Bryan Boreham ef0dae4ed3 Simple example is only on two hosts 2017-04-10 11:37:06 +00:00
Bryan Boreham 2686be1b93 Update mention of Docker 1.6 to 1.10 2017-04-10 10:45:42 +00:00
Marc Carré b845360091 Merge pull request #2887 from weaveworks/issues/add-gcloud-to-circle-path
Fix gcloud dependency for CI builds
2017-04-07 15:01:20 +01:00
Martynas Pumputis 953d451105 Check for gcloud in verify_dependencies
In CI builds, we rely on gcloud installed by Circle CI. Any change to
Circle $PATH or the installation might break CI builds in non-obvious
way.
2017-04-07 14:44:31 +01:00
Martynas Pumputis 75d80c4828 Add /opt/google-cloud-sk/bin to PATH of circle.yml
Otherwise, "gcloud" cannot be found.
2017-04-07 14:43:35 +01:00
Bryan Boreham 877658d22e Merge pull request #2886 from weaveworks/lock-kubeadm-version
Lock kubeadm's Kubernetes version
2017-04-06 14:37:58 +01:00
Marc CARRE 1c797ca901 Upgrade to latest version of build-tools.
This brings a fix to the Ansible playbook which enables locking of `kubeadm`'s Kubernetes version.
2017-04-06 13:49:51 +01:00
Marc CARRE 520a72c8e6 Lock kubeadm's Kubernetes version.
Without this commit, `kubeadm` typically upgrades whichever version of Kubernetes is installed, sometimes leading to conflicts in between components' version.

This fixes the issue behind #2876 and should avoid build failures like [weave/8373](https://circleci.com/gh/weaveworks/weave/8373).
2017-04-06 13:49:48 +01:00
Marc CARRE 98fec7e5aa Revert "Disable temporary 840 smoke tests"
This reverts commit b687484dda.
2017-04-06 10:43:56 +01:00
Bryan Boreham 038aac41fd Fix weave-kube doc table of contents 2017-04-05 13:56:17 +00:00
Martynas Pumputis c54fe016b1 Merge pull request #2880 from weaveworks/upgrade-build-tools
Upgrade to latest build-tools.
2017-04-04 15:44:05 +01:00
Marc CARRE 9c9b46479d Upgrade to latest build-tools.
Adds better support for CentOS, for Kubernetes 1.6 (default: 1.6.1), and makes Docker installation role configurable, among others.
2017-04-04 15:13:41 +01:00
Bryan Boreham 28c290074b Merge pull request #2876 from weaveworks/issues/disable-840
Disable temporary the 840 weave kube smoke test
2017-03-31 18:55:59 +02:00
Martynas Pumputis b687484dda Disable temporary 840 smoke tests
To trigger doc publishing
2017-03-30 17:45:20 +01:00
Bryan Boreham fd731beb87 Merge pull request #2871 from weaveworks/weave-kube-formatting
Fix formatting of code snippets in site/kube-addon.md.
2017-03-29 11:53:07 +01:00
Marc CARRE 35cc653737 Add links to URLs and relevant resources. 2017-03-29 11:28:49 +01:00
Marc CARRE 1254d680ed Fix formatting of env. vars. in site/kube-addon.md. 2017-03-29 11:28:42 +01:00
Marc CARRE 23c0b6a04b Fix formatting of kubectl apply snippets in site/kube-addon.md. 2017-03-29 11:28:36 +01:00
Martynas Pumputis ede1ec970c Merge pull request #2861 from weaveworks/weave-kube-1.6-docs
Update weave-kube docs for k8s  1.6
2017-03-29 10:36:49 +01:00
Bryan Boreham fbab5a7280 Review feedback 2017-03-29 08:37:28 +00:00
Bryan Boreham a92cfc1ffe Added instructions for Kubernetes 1.6 changes 2017-03-21 15:28:41 +00:00
Bryan Boreham 178cf85183 Add release v1.9.4 2017-03-21 14:30:35 +00:00
Bryan Boreham 272161b00b Add k8s-1.6 daemonset to release script 2017-03-21 14:23:13 +00:00
Bryan Boreham 56155d0819 Extra checks on return value from IPAM plugin 2017-03-21 11:39:36 +00:00
Bryan Boreham c711826996 Blank out container ID when exec-ing a CNI ipam plugin to get bridge address 2017-03-21 11:39:36 +00:00
Bryan Boreham eef6965590 Clean out weave CNI plugin before tests 2017-03-21 11:39:36 +00:00
Bryan Boreham 4926cb6f9a Add test to check that bridge IP is not the same as container IP 2017-03-21 11:39:36 +00:00
Bryan Boreham d9ca54e777 Don't use Printf without a format 2017-03-21 11:38:35 +00:00
Bryan Boreham 1f6a6349a9 Remove useless 'break' 2017-03-21 11:38:35 +00:00
Bryan Boreham 8f27f8f442 Clean up some tests that were not checking results 2017-03-21 11:38:35 +00:00
Bryan Boreham 681109ba71 use net.IP.Equal to compare, not bytes.Equal 2017-03-21 11:38:35 +00:00
Bryan Boreham 99c691745a Check error return on udp dial() 2017-03-21 11:38:35 +00:00
Bryan Boreham 1af5699948 cancelOp was cancelling the first op in the queue 2017-03-21 11:38:35 +00:00
Bryan Boreham ef7571f1ef Can't catch SIGKILL 2017-03-21 11:38:35 +00:00
Bryan Boreham c0726923f5 Merge pull request #2851 from weaveworks/k8s-1.6-beta
Upgrade to latest build-tools to be able to test against 1.6+ and/or "unstable" versions of K8S
2017-03-20 12:07:38 +00:00
Marc CARRE 4d9eadde5b Upgrade to latest version of build-tools.
Integrate latest changes required for testing against Kubernetes 1.6.0-beta.*.
See also: github.com/weaveworks/build-tools/pull/81
2017-03-17 12:05:27 +00:00
Bryan Boreham 9da5cee8d9 Rename Kubernetes daemonset to "1.6"
To emphasise this is the version that adopters of Kubernetes 1.6 need
to use.
2017-03-17 11:45:06 +00:00
Bryan Boreham ca22ecdf09 Merge branch 'luxaslabs-add_head_manifest' into 1.9 2017-03-17 11:44:16 +00:00
Lucas Käldström 2e58e92d48 Add a weave-kube manifest that works for kubeadm v1.6 2017-03-17 11:43:48 +00:00
Bryan Boreham fd0c53b424 Merge pull request #2852 from weaveworks/assert-no-defunct
Assert no defunct process is generated as a postcondition of all tests.
2017-03-17 11:40:32 +00:00
Marc CARRE 7b1e8ac1cf Assert no defunct process is generated as a postcondition of all tests. 2017-03-17 10:36:16 +00:00
Bryan Boreham 31b7e063e7 Use version 3 in the test
CNI_VERSION env var was never used, so removed from the test script.
The second test is crashing on v1, so bumped to v3.
2017-03-16 18:23:20 +00:00
Bryan Boreham b5172f46c1 Honour the input version number 2017-03-16 18:23:20 +00:00
Bryan Boreham 5a6cb8e708 Allow CNI netns to be blank on DEL
Also don't error on DEL with no namespace and no addresses
2017-03-16 18:23:20 +00:00
Bryan Boreham c3c28ea27e Update CNI library to version 0.5.0 2017-03-16 18:23:20 +00:00
Bryan Boreham 623abeef4c gofmt 2017-03-14 17:56:59 +00:00
Bryan Boreham 5f30846092 Unwind changes to doExec and handle List() error differently
exec.Output() already wraps the stderr output, so we don't need to do that.
2017-03-14 17:56:59 +00:00
Bryan Boreham 6ddbc5cb57 Simplify List() 2017-03-14 17:56:59 +00:00
Bryan Boreham f9f3b18ce4 Test whether non-weave ipsets get blown away 2017-03-14 17:56:59 +00:00
Stephan Austermühle dc2925263c Destroy ipsets prefixed weave- only (issue #2751) 2017-03-14 17:56:59 +00:00
Bryan Boreham 56fd45f7ea Merge pull request #2845 from weaveworks/issues/2836-defunct-launch.sh-no-exec
Remove exec from weaver command; Fixes #2836.
2017-03-14 16:52:17 +00:00
Marc CARRE 21a0fc30e8 Run weaver without exec.
This:

1. prevents from generating defunct (a.k.a. zombie) processes, and therefore fixes #2836; but also
2. reintroduces #2684/#2688 as shells do not forward signals and we are still running more than one process.

A proper fix would leverage something like tini.
See also:

- github.com/krallin/tini
- github.com/krallin/tini/issues/8
- github.com/docker-library/official-images#init

Sample output:

- during initialisation:

```
$ ps auxf
[...]
root      1380  0.4  1.9 879660 74660 ?        Ssl  Mar13   6:02 /usr/bin/docker daemon -H fd:// -H unix:///
root      1664  0.0  0.4 502116 18528 ?        Ssl  Mar13   0:06  \_ docker-containerd -l /var/run/docker/li
root     15482  0.0  0.0 200496  3364 ?        Sl   15:04   0:00      \_ docker-containerd-shim 3d1f5eb6e090
root     15496  0.0  0.0   1524   996 ?        Ss   15:04   0:00      |   \_ /bin/sh /home/weave/launch.sh
root     15780  0.0  0.0   1524    64 ?        S    15:04   0:00      |       \_ /bin/sh /home/weave/launch.
root     15872  0.0  0.0   1772  1272 ?        S    15:04   0:00      |       |   \_ /bin/sh /home/weave/wea
root     15897  0.0  0.0   1772   324 ?        S    15:04   0:00      |       |       \_ /bin/sh /home/weave
root     15898  0.0  0.0  14656  2948 ?        S    15:04   0:00      |       |           \_ curl -o /tmp/we
root     15781 10.0  1.5 484556 60296 ?        Sl   15:04   0:00      |       \_ /home/weave/weaver --port=6
[...]
```

- after initialisation:

```
$ ps auxf
[...]
root      1380  0.4  1.9 879660 74660 ?        Ssl  Mar13   6:02 /usr/bin/docker daemon -H fd:// -H unix:///
root      1664  0.0  0.4 502116 18592 ?        Ssl  Mar13   0:06  \_ docker-containerd -l /var/run/docker/li
root     15482  0.0  0.0 200496  3364 ?        Sl   15:04   0:00      \_ docker-containerd-shim 3d1f5eb6e090
root     15496  0.0  0.0   1524   996 ?        Ss   15:04   0:00      |   \_ /bin/sh /home/weave/launch.sh
root     15781  2.3  1.6 503064 64320 ?        Sl   15:04   0:00      |       \_ /home/weave/weaver --port=6[...]
```
2017-03-14 15:34:47 +00:00
Marc CARRE 673d0af97d Add failing test catching defunct launch.sh processses.
Reproduces issue #2836, i.e.:

- during initialisation:

```
$ ps auxf
[...]
root      1380  0.4  1.6 879660 60732 ?        Ssl  Mar13   5:54 /usr/bin/docker daemon -H fd:// -H unix:///
root      1664  0.0  0.4 502116 18540 ?        Ssl  Mar13   0:06  \_ docker-containerd -l /var/run/docker/li
root     12615  0.0  0.1 200496  5424 ?        Sl   14:38   0:00      \_ docker-containerd-shim c5637e5bbdcb
root     12629  6.2  1.6 296400 62312 ?        Ssl  14:38   0:00      |   \_ /home/weave/weaver --port=6783
root     12910  0.0  0.0   1524    68 ?        S    14:38   0:00      |       \_ /bin/sh /home/weave/launch.
root     13002  0.0  0.0   1772  1232 ?        S    14:38   0:00      |           \_ /bin/sh /home/weave/wea
root     13027  0.0  0.0   1772   320 ?        S    14:38   0:00      |               \_ /bin/sh /home/weave
root     13028  0.0  0.0  14656  2708 ?        S    14:38   0:00      |                   \_ curl -o /tmp/we
[...]
```

- after initialisation:

```
$ ps auxf
[...]
root      1380  0.4  1.6 879660 60732 ?        Ssl  Mar13   5:54 /usr/bin/docker daemon -H fd:// -H unix:///
root      1664  0.0  0.4 502116 18540 ?        Ssl  Mar13   0:06  \_ docker-containerd -l /var/run/docker/li
root     12615  0.0  0.1 200496  5424 ?        Sl   14:38   0:00      \_ docker-containerd-shim c5637e5bbdcb
root     12629  3.5  1.6 297460 63340 ?        Ssl  14:38   0:00      |   \_ /home/weave/weaver --port=6783
root     12910  0.0  0.0      0     0 ?        Z    14:38   0:00      |       \_ [launch.sh] <defunct>
[...]
```

Sample output:

```
test #5 "run_on mct-0.us-central1-a.weave-net ps aux | grep -c '[d]efunct'" failed:
	expected "0"
	got "1"
test #6 "run_on mct-1.us-central1-a.weave-net ps aux | grep -c '[d]efunct'" failed:
	expected "0"
	got "1"
test #7 "run_on mct-2.us-central1-a.weave-net ps aux | grep -c '[d]efunct'" failed:
	expected "0"
	got "1"
3 of 8 tests failed in 62.012s.
```
2017-03-14 14:39:34 +00:00
Bryan Boreham 402400d4cb Merge pull request #2831 from weaveworks/issues/2830-fix-fastdp-crypto-docs
doc: Remove invalid statement about missing encryption in fastdp; Fixes #2830
2017-03-09 16:00:54 +00:00
Martynas Pumputis b1a66012bd doc: Remove invalid statement about missing encryption in fastdp 2017-03-09 15:38:13 +00:00
Marc CARRE 85fa976a25 Add release v1.9.3 2017-03-07 14:38:42 +00:00
Bryan Boreham 640b487914 Merge pull request #2825 from weaveworks/issues/2824-fastdp-timer-race
Do not reset fastdp heartbeat timer for non-confirmed connections.  Fixes #2824
2017-03-06 10:45:45 +00:00
Martynas Pumputis 7c84e24f48 fastdp: Do not reset heartbeat timer for non-confirmed connections
It is possible to receive FastDatapathCryptoInitSARemote control plane
message before Confirm'ing a connection. In such case, resetting
heartbeatTimer leads to null pointer dereference, as the timer is
initialized during Confirm'ation.

In this situation, skipping the reset is non-harmful, because
Confirm'ing will reset it.

NB: the reset to 0 should only happen after establishing the connection
on both ends.
2017-03-02 16:59:48 +00:00
Martynas Pumputis 125f3cf6f6 Add release v1.9.2 2017-03-01 14:11:20 +00:00
Bryan Boreham b2ffe77029 Merge pull request #2821 from weaveworks/issues/2820-busybox-modprobe
Ignore modprobe errors in weave-kube/launch.sh
2017-03-01 11:32:52 +00:00
Martynas Pumputis 3607cf2d7a Add check for xt_set module
The check is based on actually trying to install an iptables rule
which uses the module.
2017-03-01 10:37:43 +00:00
Martynas Pumputis a57cf4bc83 Ignore modprobe errors in weave-kube/launch.sh
weave-kube is run by alpine image which uses busybox. modprobe of
busybox will return the "module not found" error [1], if a module is
built-in, which is an opposite behavior to modprobe distributed in
mainstream distros (e.g. ubuntu).

[1]: https://bugs.busybox.net/show_bug.cgi?id=5270
2017-02-28 11:26:40 +00:00
Bryan Boreham 6036037817 Added kops update to the release instructions 2017-02-27 18:10:13 +00:00
Bryan Boreham 242b8907bf Add release v1.9.1 2017-02-27 16:20:02 +00:00
Bryan Boreham 9db22c3cd6 Merge pull request #2818 from 'tobowers-fix-reverse-dns'
Lowercase the request before comparing it

Fix #2817
2017-02-27 16:15:18 +00:00
Bryan Boreham e57d79bd70 Test reverse DNS using dig
so that we can check it works with upper and lower case IN-ADDR.ARPA
2017-02-27 14:56:25 +00:00
Martynas Pumputis 589ab4f01d Merge pull request #2819 from weaveworks/issues/2726-modprobe
Ensure we have the right modules loaded for weave-npc

Fix #2726
2017-02-27 14:23:12 +00:00
Bryan Boreham 01fe09065c Add weave-npc required kernel modules to docs 2017-02-27 14:25:43 +00:00
Topper Bowers 83958561f7 some DNS clients send reverse lookups with uppercase suffixes. This lowercases the request before trimming the lowercase suffix. Problem discovered and discussed here: https://github.com/weaveworks/weave/issues/2817 2017-02-27 14:19:31 +01:00
Bryan Boreham cb73cf3f51 Ensure we have the kernel modules loaded for weave-npc 2017-02-27 12:32:57 +00:00
Martynas Pumputis 7a3e8e64b7 Merge pull request #2810 from ocadotechnology/add-pending-metrics
Add prometheus metrics for pending Allocates and Claims
2017-02-24 15:55:39 +00:00
Bryan Boreham f7ce16cba8 Move detailed warning about rmpeer from FAQ to docs 2017-02-23 13:22:28 +00:00
Bryan Boreham 6ac1fef01d Fix broken link 2017-02-23 13:22:16 +00:00
Bryan Boreham 5c19efae48 Merge pull request #2811 from weaveworks/issues/2223-faq-anchors
Add anchors to faq questions
2017-02-23 13:19:39 +00:00
Bryan Boreham f7c0da3ae1 Merge pull request #2781 from keontang/luanch-update
Add CONN_LIMIT environment var for running container
2017-02-23 12:40:01 +00:00
Bryan Boreham fe0c833cdf Move FAQ to the bottom of the menu 2017-02-23 12:28:51 +00:00
Bryan Boreham 58342f7509 add anchors to faq questions 2017-02-23 12:26:03 +00:00
Mike Bryant fad537cad7 Add prometheus metrics for pending Allocates and Claims 2017-02-23 11:41:07 +00:00
Bryan Boreham 6d5c2ad0fa Merge pull request #2793 from weaveworks/improve-fastdp-crypto-tests
Improve encryption tests
2017-02-22 14:56:14 +00:00
Martynas Pumputis b585e1f4cb Merge pull request #2795 from weaveworks/issues/2792-refcount-ipset
Reference-count ipset entries

Fix #2792
2017-02-22 14:01:26 +00:00
Bryan Boreham 7102bf6d9d Merge pull request #2803 from weaveworks/update-readme
update slack community and weave user group details
2017-02-21 15:38:34 +00:00
Bryan Boreham 77988012ed Merge pull request #2765 from weaveworks/issues/1644-fastdp-crypto-docs
Add fastdp-crypto docs
2017-02-20 17:56:32 +00:00
Bryan Boreham 2989e3cccd Merge pull request #2790 from weaveworks/update-netlink-dep
Update vishvananda/netlink
2017-02-20 17:51:37 +00:00
Bryan Boreham 5a47d1d13f Merge pull request #2796 from weaveworks/versions-manifest
Add versions manifest file for dependencies.
2017-02-20 11:42:30 +00:00
Martynas Pumputis d3795d4e74 Merge pull request #2774 from weaveworks/update-ipam-doc
Update IPAM documentation.
2017-02-16 12:09:08 +00:00
Marc CARRE bc97daf5c0 Update IPAM documentation. 2017-02-15 16:25:12 +00:00
abuehrle 08e4c98172 open new window punctuation 2017-02-14 14:41:25 -06:00
abuehrle ca254e066a changed to pro link for WUOG 2017-02-14 14:28:22 -06:00
abuehrle aea92a3563 update slack community and wuog 2017-02-14 14:16:37 -06:00
Bryan Boreham e9fa655e0e Merge pull request #2802 from weaveworks/issues/2761-build-chown
Make /usr/local/go writable to anyone
2017-02-14 16:55:37 +00:00
Martynas Pumputis 7d178ecee9 Make /usr/local/go writable to anyone
Previous attempt to chown the dir inside build.sh resulted in
a significant increase in a build time, and build.sh is exec'd
once per each build.
2017-02-14 15:45:25 +00:00
Bryan Boreham 201321f390 Remove refcounts on destroy and flush 2017-02-14 10:50:22 +00:00
Bryan Boreham 3afc528c88 Reference-count ipset entries 2017-02-14 10:26:59 +00:00
Marc CARRE 62c9522bf6 Fix bug in get_go_version_from_build_dockerfile.
Previously, the first line of the Dockerfile would have been selected, regardless of its value.
What we want is to actually select the first line matching the regex, and then extract the group corresponding to the Go version out of it.
2017-02-13 19:54:38 +00:00
Marc CARRE 1b45e8662e Add DEPENDENCIES file and source Vagrant and tests versions from it.
- One unique file to list all dependencies and dependencies' versions (except Go, currently defined in `build/Dockerfile`).
- Custom versions can now be injected into Vagrant VMs.
- Vagrant dev VMs, Vagrant test VMs, and `run-integration-tests.sh` all source from `DEPENDENCIES`, to keep things 'DRY'.
- Vagrant versions can be overriden using environment variables, like it was possible in `run-integration-tests.sh`.
2017-02-13 19:54:38 +00:00
Marc CARRE 3ce8aec039 Removed unecessary trailing whitespaces.
Noise on git diff if/when text editors remove them automatically, so might as well proactively remove them.
2017-02-13 19:54:38 +00:00
Martynas Pumputis 32d44e09a1 Merge pull request #2787 from weaveworks/issues/2784-preclaim-addresses
Claim existing IP addresses at startup with no race condition

Fixes #2784
2017-02-13 17:51:38 +00:00
Bryan Boreham 4e37f5ec42 Add explanations of various claim and allocation fields 2017-02-13 17:31:02 +00:00
Bryan Boreham 39f471e9d3 Merge pull request #2773 from weaveworks/issues/2772-check-type-on-delete
Handle cache.DeleteFinalStateUnknown
2017-02-13 15:49:24 +00:00
Bryan Boreham 293abd953e Fix flaky test 320
The intention, per the comments, is that host1 should claim from host2.
But host2 and host3 can carve up the space either way round.  If host1
claims from host3 then there is a race whether anyone finds out about
it.
Adding a 'prime' on host2 ensures the space is all owned by host2 at that point.
2017-02-13 11:30:34 +00:00
Bryan Boreham fde7dcdde9 Stop collecting addresses in weave script now we do it in Go 2017-02-13 11:30:34 +00:00
Bryan Boreham 7075b5d9fd Extend pre-existing address reclaim to docker containers 2017-02-13 11:30:34 +00:00
Bryan Boreham 50b1aa0c74 Merge pull request #2785 from weaveworks/typo-app-isolation-doc
Fix typo in CIDR.
2017-02-13 11:15:17 +00:00
Martynas Pumputis 7f48cc9239 Replace 110_encryption_2_test.sh by 110_sleeve_encryption_2_test.sh 2017-02-10 17:30:30 +00:00
Martynas Pumputis 8211afe5d5 Improve 111_fastdp_encryption_2_test.sh 2017-02-10 17:20:24 +00:00
Bryan Boreham e26dbf11e9 Stop collecting addresses in launch script now we do it in Go 2017-02-10 15:11:14 +00:00
Bryan Boreham 39ac1a0037 Collect existing weave addresses at start-up, to avoid a race when
doing it from the script

Note we need to run weaver in the host pid namespace, so it can search
for existing container IPs. Also now we are firing off sub-processes
it's better to not be PID 1 so Linux doesn't expect us to reap zombies.
2017-02-10 15:10:02 +00:00
Martynas Pumputis 86f716c38c Add fastdp-crypto docs 2017-02-10 14:49:47 +00:00
Marc CARRE d5c7c4476b Fix typo in CIDR. 2017-02-09 20:58:06 +00:00
Martynas Pumputis 2a02883f07 Update vishvananda/netlink 2017-02-09 15:56:02 +00:00
Martynas Pumputis f592e4b70a Merge pull request #2780 from weaveworks/tf-ansi-macos
Upgrade to latest build-tools.
2017-02-09 14:58:43 +00:00
Marc CARRE 968855e0a4 Upgrade to latest build-tools.
Make tools/provisioning/setup.sh behave consistently regardless of whether under Linux or macOS, and whether sourced or executed.
2017-02-09 14:35:54 +00:00
Jiyuan Tang bee031ad70 Add CONN_LIMIT environment for running container 2017-02-09 19:34:16 +08:00
Martynas Pumputis 3378e09b6a Merge pull request #2775 from weaveworks/num-hosts-via-env-var
Remove hard-coded NUM_HOSTS env. var.
2017-02-08 18:17:35 +00:00
Marc CARRE ab37b4a6c4 Remove hard-coded NUM_HOSTS env. var.
Instead of hardcoding this in the code, this should be passed by CircleCI from Settings > weaveworks > weave > Environment Variables.
2017-02-08 17:56:48 +00:00
Martynas Pumputis dff5b6d3f1 Merge pull request #2694 from weaveworks/2647-testing-mvp
Testing MVP

Fixes #2647
2017-02-08 16:25:56 +00:00
Marc CARRE c026579cec Update make lint to cope with latest changes made in build-tools. 2017-02-08 14:15:59 +00:00
Marc CARRE ef8b576742 Default behaviour now is to create a GCP image if missing.
We previously had 'use image' as a default, but not 'create image', which is inconsistent and leads to unexpected failures.
2017-02-08 14:15:59 +00:00
Marc CARRE 69398a9d7e Source config.sh using relative path to the script, regardless of current directory.
Sourcing failed when running make integration-tests.
2017-02-08 14:15:59 +00:00
Marc CARRE 0a2beedad3 Add flag to skip destruction of test VMS.
This should be useful when we just want to type one make integration-tests / ./run-integration-tests command to make/start VMs/configure them/test, but also investigate potential failures afterwards.
2017-02-08 14:15:59 +00:00
Marc CARRE 29d50bbf09 Globally redirect stdout to stderr, except when echo'ing "export HOSTS=...".
This should make development easier by allowing developers to set HOSTS in their calling shell, and re-use the value for this env. var. when calling individual test scripts, e.g.:
```
cd test
eval $(./run-integration-tests.sh setup)
./200_dns_test.sh
```
2017-02-08 14:15:59 +00:00
Marc CARRE 673fc73cd5 Increase number of test machines for CircleCI to 16.
This should speed the build up, and provide faster feedback to developers.
2017-02-08 14:15:59 +00:00
Marc CARRE 1185bed370 Changed default number of test machines to 3.
CircleCI keeps 10 nodes in order to speed up the build, but the default is 3, as this is the minimum required to run any test. This should make more sense as a default for a developer to quickly start an environment and iterate.
2017-02-08 14:15:59 +00:00
Marc CARRE 1176d44044 Run git submodule update --init as the very first step in CircleCI.
Doing so in circle-dependencies-post arrives too late for background provisioning.
2017-02-08 14:15:59 +00:00
Marc CARRE 77649ab81b Relax .lintignore in order for lint to cover newly added scripts. 2017-02-08 14:15:59 +00:00
Marc CARRE a51bc6164c Signal provisioning failures to fail the build fast.
There may be situations when Terraform/Ansible/etc. fail to provision test machines.
In these cases, we want to fail fast instead of waiting until we time out in circle-test-pre and circle-test-smoke.
2017-02-08 14:15:59 +00:00
Marc CARRE dd935b7e9e Provision and destroy test VMs in the background.
This should help speed-up the build by provisioning test VMs while we run unit tests, and destroying them while we generate coverage reports.
2017-02-08 14:15:59 +00:00
Marc CARRE 67dbdd377c Configure Vagrant VMs using Ansible.
This way, Vagrant VMs and cloud-provided VMs are configured in the exact same way, hence avoiding configuration drift and subtle bugs associated to different versions of software.
2017-02-08 14:15:59 +00:00
Marc CARRE e5185e73ce Refactor Vagrant configuration. 2017-02-08 14:15:59 +00:00
Marc CARRE 17ada094f8 Updated and improved testing documentation. 2017-02-08 14:15:59 +00:00
Marc CARRE 3e5593dc4f Add GCP image creation and usage.
Provisioning and configuration being expensive time-wise, we create Google Cloud Platform images for each Docker/Kubernetes/Kubernetes CNI versions triple, and configure these once (instead of for each build), and then re-use these in subsequent builds, effectively implementing a 'cache' of images.
2017-02-08 14:15:59 +00:00
Marc CARRE e647fe6331 Highlight setup and sanity checks in CircleCI's logs. 2017-02-08 14:15:59 +00:00
Marc CARRE a2679794b3 Install Terraform and Ansible in CircleCI's containers.
Terraform and Ansible are now required to run the smoke tests.
2017-02-08 14:15:59 +00:00
Marc CARRE 30f59953d2 Smoke tests are now run using Terraform, Ansible and run-integration-tests.sh. 2017-02-08 14:15:59 +00:00
Marc CARRE acd16881d9 Add make integration-tests based on Terraform/Ansible. 2017-02-08 14:15:59 +00:00
Marc CARRE 2aaa400d62 Add Terraform and Ansible scripts as part of tools submodule. 2017-02-08 14:15:55 +00:00
Marc CARRE 487ebfb514 Increased timeout for test #840.
Reason: test is periodically failing because of the timeout being too aggressive, especially when using Google Cloud Platform together with Terraform and Ansible.
2017-02-08 14:15:02 +00:00
Marc CARRE fde7e88e66 Allow RUNNER_ARGS to be passed by calling script.
This is required in order to be able to dependency-inject values from layers higher up, e.g.: RUNNER_ARGS="-parallel" from the Makefile.
2017-02-08 14:15:02 +00:00
Marc CARRE 9e4ce8c052 Git-ignore Terraform state files. 2017-02-08 14:15:02 +00:00
Adam Harrison defa5cc3d3 Handle cache.DeleteFinalStateUnknown 2017-02-08 12:48:32 +00:00
Martynas Pumputis dea2755161 Merge pull request #2764 from weaveworks/ports-faq
Expand FAQ info about port usage
2017-02-07 14:23:15 +00:00
Bryan Boreham cc8785fdcf Expand info about port usage 2017-02-07 14:06:24 +00:00
Bryan Boreham 7265c6ea03 Move sed of daemonset up next to weave script
For consistency, also for easier unpicking if the 'draft' stage fails
2017-02-03 12:18:48 +00:00
Bryan Boreham 0792f0717d Revert "Temporarily release weave-daemonset.yaml to weave-kube repo"
This reverts commit 23056cbb45.
Explanation: weave-kube has been moved into the weave repo
2017-02-02 11:56:54 +00:00
Bryan Boreham 851b58cca8 Add release v1.9.0 2017-02-02 11:01:34 +00:00
Bryan Boreham cb48ebc399 Bump alpine version to 3.5 for arm64
Since 3.4 doesn't exist, and the package repo seems ok for ulogd now
2017-02-02 10:43:29 +00:00
Martynas Pumputis 5278eb7ebc Merge pull request #2747 from weaveworks/issues/2689-npc-mcast-simple
Add rule to allow multicast at top level
2017-02-01 18:20:38 +00:00
Bryan Boreham 418c256689 Allow traffic to forward off the weave bridge 2017-02-01 15:01:18 +00:00
Bryan Boreham 4eeb846507 Add tests for connectivity to the world 2017-02-01 15:01:18 +00:00
Bryan Boreham 7529f5f9af Raise ping timeout to reduce false negatives 2017-02-01 15:01:18 +00:00
Michal Rostecki 8506e57482 Pin alpine container version
Alpine 3.5 doesn't provide PCAP plugin with ulogd, so until
we investigate the problem upstream, we need to pin to 3.4
version.

Fixes #2732
2017-02-01 12:05:31 +00:00
Adam Harrison b1d09305e4 Merge pull request #2687 from weaveworks/issues/1644-fastdp-crypto
Fastdp crypto
2017-02-01 10:28:24 +00:00
Martynas Pumputis 07892bff7d Reduce the default MTU 2017-01-31 17:21:01 +00:00
Martynas Pumputis 50985dee90 Enable ESN in fastdp-crypto 2017-01-31 17:21:01 +00:00
Martynas Pumputis 60323d0960 Add fastdp crypto 2017-01-31 17:21:01 +00:00
Bryan Boreham a9cef6327f Update information about Weaveworks products 2017-01-31 12:43:53 +00:00
Bryan Boreham fdeb9010ba Merge pull request #2757 from weaveworks/upgrade-build-tools
Upgrade to latest 'common' and 'build-tools'.
2017-01-31 12:17:31 +00:00
Marc CARRE ee659d4033 Replace weave/common/mflagext with common/mflagext.
Removes duplication between weave and common and reduces the amount of sources to compile.
2017-01-31 10:49:29 +00:00
Marc CARRE 8f9b2a36c0 Remove dep. on docker and use mflag from common.
This reduces the number of dependencies, and avoids having docker as a vendored dependency, which should speed the build up.
2017-01-31 10:30:12 +00:00
Bryan Boreham 6a83130685 Document multicast behaviour of weave-npc 2017-01-30 18:14:57 +00:00
Marc CARRE 77e6c6f886 Upgrade to latest 'common' and 'build-tools'.
If building against the latest 'build-tools', you would typically get:
tools/runner/runner.go:18:2: cannot find package github.com/weaveworks/common/mflag
This change fixes the issue by upgrading both dependencies.
2017-01-30 18:05:58 +00:00
Adam Harrison 8a5a15d5e9 Merge pull request #2753 from weaveworks/mv-signal-to-common
Move signal handling loop to common.
2017-01-30 12:38:23 +00:00
Bryan Boreham bcc8c73f59 Fix build of manifest_tool in 'make publish' 2017-01-30 11:02:11 +00:00
Bryan Boreham e22c6375c9 Fix build of manifest_tool 2017-01-27 18:09:22 +00:00
Marc Carré 22ae0d200c Merge pull request #2752 from weaveworks/makefile-cleanup
Makefile cleanup after multiarch merge
2017-01-27 16:51:44 +00:00
Bryan Boreham 7231bd00f8 Remove .weavedb.uptodate file when we remove the weavedb image in 'make clean-bin' 2017-01-27 16:26:05 +00:00
Tom Wilkie 590a151bde Move signal handling loop to common. 2017-01-26 17:55:19 +00:00
Martynas Pumputis f5dfefef75 Merge pull request #2749 from weaveworks/shfmt-ignore
Upgrade Weave Net to latest version of build-tools, skipping bash scripts when lint-ing.
2017-01-26 10:55:36 +00:00
Marc CARRE 8e6cb5e24d Print files we currently do not lint.
Makes what the build does explicitly and helps for potential debugging.
Also reminds us that we are skipping these files, so that we ultimately shfmt them and stop lint-ignoring them.
2017-01-25 17:14:48 +00:00
Marc CARRE ed629d420d Pass additional options to ./tools/test to revert to previous behaviour.
Previous commit upgrades Weave Net to the latest version of `build-tools`.
However, `./tools/test`'s default behaviour has changed, so we need to explicitly pass new options/arguments, in order to keep it behaving like before fd568682c3.
2017-01-25 17:14:05 +00:00
Marc CARRE fd568682c3 Upgrade Weave Net to latest version of build-tools, skipping bash scripts when lint-ing.
Lint-ing all of Weave Net is currently not desirable because:

* it would create conflicts on many branches,
* it would pollute the git history,
* etc.

and because `lint` currently lints all files except `./vendor`, this breaks Weave Net's build.
As a result, Weave Net is not using the latest commit in `build-tools`'s `master` branch, which is also source of problems:

* it limits standardisation of projects across Weaveworks,
* it limits the ability to use the latest features of `build-tools`,
* it complexifies merging changes in `build-tools` (e.g. #53 and weaveworks/weave#2694 for weaveworks/weave#2647),
* etc.

This change:

* brings Weave Net to the latest version of `build-tools` (which now supports `.lintignore` files),
* adds such a `.lintignore` file to skip all bash scripts (in order to avoid breaking the build).

`GLOB`s in `.lintignore` can then, over time and as scripts are `shfmt`-ed, be relaxed and maybe even removed.
2017-01-25 16:50:32 +00:00
Bryan Boreham dbb9849b8c Remove whitespace from blank lines and comment lines
Principally because emacs complains about it, but also to remove the
overhead of firing up a shell process to ignore a comment in a recipe
2017-01-25 14:20:54 +00:00
Bryan Boreham 776af44782 Make manifest-tool using weave build container 2017-01-25 14:18:55 +00:00
Bryan Boreham 69dacd0594 Restrict CircleCI publishing to AMD64 2017-01-25 10:52:53 +00:00
Bryan Boreham f17a2a00b1 Merge pull request #2713 from luxaslabs/multiarch
Make Weave Net multi-architecture
2017-01-24 18:07:32 +00:00
Lucas Käldström 1a64420e01 Fix duplicate publish target 2017-01-24 17:38:44 +02:00
Bryan Boreham 49b9a2c8df Bump Docker to 1.10 2017-01-24 17:28:08 +02:00
Bryan Boreham 6c251417d5 Update 'docker inspect weavedb' format for Docker 1.10 2017-01-24 17:27:53 +02:00
Lucas Käldström 8c0c38c8b3 Add manifest-tool as a submodule 2017-01-24 17:27:30 +02:00
Lucas Käldström 29eee4e858 Fixing review feedback, adding checksums, etc 2017-01-24 17:24:04 +02:00
Lucas Käldström 454c6f713d Make Weave Net multi-architecture and add support for ARM and ARM 64-bit 2017-01-24 17:23:00 +02:00
Marc Carré dd715e18ec Merge pull request #2743 from weaveworks/fix-uuid
Don't fail if only half the system IDs are blank
2017-01-23 15:00:06 +00:00
Bryan Boreham f067c7d44e Add rule to allow multicast at top level 2017-01-23 12:11:44 +00:00
Bryan Boreham c1023eaf18 Hard-code repository name for weavebuild container
so we don't create a new one when testing publish to different DOCKERHUB_USER
2017-01-20 14:55:10 +00:00
Bryan Boreham b091f59311 Merge pull request #2734 from Compositional/master
Add partial support for non-FHS host systems
2017-01-20 14:45:33 +00:00
Marc Carré f98ad822e3 Merge pull request #2740 from weaveworks/issues/2738-dedupe-surrogate
Update mesh lib to break cycle of old gossip
2017-01-20 12:36:08 +00:00
Bryan Boreham 917c1ddbad Update mesh lib to break cycle of old gossip 2017-01-20 12:05:55 +00:00
Marc Carré d81d2f691d Merge pull request #2742 from weaveworks/build-improvements
Build improvements
2017-01-20 11:26:18 +00:00
Bryan Boreham 1ad118a38f Merge branch '1.8' 2017-01-20 09:45:13 +00:00
Bryan Boreham 9d1648cee7 Merge pull request #2741 from weaveworks/document-mtu-with-weave-kube
Document WEAVE_MTU in weave-kube config options
2017-01-20 09:40:57 +00:00
Bryan Boreham 929167366a Don't fail if only half the system IDs are blank 2017-01-19 15:57:21 +00:00
Bryan Boreham 353ccf5e6c Move build to 'dependencies' section
This means we don't spend time trying to run other tests if the build failed.
2017-01-19 10:59:16 +00:00
Bryan Boreham cfc1fa4fae Build test runner inside build container for consistency 2017-01-19 10:59:04 +00:00
Robert Hensing d881f47088 Add partial support for non-FHS host systems
Fixes weaveworks/weave#2733 partially, where <host>/etc/resolv.conf is not a
symlink
2017-01-18 23:28:49 +01:00
Bryan Boreham 84013c4452 Merge pull request #2735 from weaveworks/issues/2732-pin-alpine-version
Pin alpine container version
2017-01-18 16:49:04 +00:00
Adam Harrison d9dc1a988c Document WEAVE_MTU in weave-kube config options 2017-01-18 15:11:41 +00:00
Marc CARRE 5fd14348aa Fix broken link to 'Building Weave Net' documentation. 2017-01-17 17:49:17 +00:00
Adam Harrison 57a250a20b Pin alpine container version 2017-01-16 12:27:53 +00:00
Adam Harrison 81add75258 Merge pull request #2711 from weaveworks/issues/2427-unique-ids
Better machine unique IDs
2017-01-13 09:40:18 +00:00
Bryan Boreham 0145282a10 Merge pull request #2728 from weaveworks/issues/2653-ulogd-pdeathsig
SIGKILL ulogd on weave-npc exit
2017-01-11 17:31:18 +00:00
Adam Harrison ae0cb5d483 SIGKILL ulogd on weave-npc exit 2017-01-11 14:12:01 +00:00
Bryan Boreham e7eeecd762 Smoke test for peer names 2017-01-11 13:14:35 +00:00
Bryan Boreham 7d308a4ac5 Wire weaveutil unique-id into weave script
Also ensure the right host directories are mounted when create-bridge
is called from either the weave script or weave-kube.
2017-01-11 13:14:35 +00:00
Bryan Boreham ebcb7f6108 Use persisted peer name if it matches old-style ID 2017-01-11 13:14:35 +00:00
Bryan Boreham e03c7b1b7c Allow opening persistence file read-only 2017-01-11 13:13:19 +00:00
Bryan Boreham 70a20b4d26 Generate peer name / mac address in Go 2017-01-11 13:12:30 +00:00
Bryan Boreham d143470d77 Refactor: extract db filename to a constant 2017-01-11 13:05:25 +00:00
Bryan Boreham 30d6639a98 Refactor: move peer name identifier to DB package 2017-01-11 13:05:25 +00:00
Adam Harrison 92cfd3b4f9 Merge pull request #2725 from weaveworks/update-tools
Update tools submodule to avoid breaking on missing Docker mflag
2017-01-09 17:09:53 +00:00
Adam Harrison 7659ea21c7 Merge branch '1.8'
Fixes #2693.
2017-01-09 16:24:08 +00:00
Adam Harrison 4e740736e7 Merge pull request #2697 from weaveworks/issues/2693-npc-log-instructions
Fix instructions to view npc logs when >1 pod exists
2017-01-09 16:23:42 +00:00
Adam Harrison 4f44d9e25a Merge branch '1.8'
Fixes #2719.
2017-01-09 15:49:29 +00:00
Adam Harrison 2ae2d52289 Merge pull request #2722 from weaveworks/issues/2719-delete-pods
Warn not to delete all Weave Net pods
2017-01-09 15:48:48 +00:00
Adam Harrison 635191970f Merge pull request #2688 from weaveworks/issues/2684-exec-weaver
Exec weaver from weave-kube launch rather than running in background
2017-01-09 15:24:19 +00:00
Bryan Boreham e370443a3f Merge pull request #2699 from weaveworks/2647-parallelise-sanity-checks
Parallelise sanity checks in order to speed them up.
2017-01-09 12:57:44 +00:00
Bryan Boreham 738ff2b65f Update tools submodule to avoid breaking on missing Docker mflag 2017-01-09 12:50:18 +00:00
Bryan Boreham cef8c908d0 Merge pull request #2704 from weaveworks/2647-parallelise-setup
Parallelise setup.sh's individual tasks.
2017-01-09 12:30:53 +00:00
Marc CARRE edc0cdbc10 Sanity checks' output is now redirected to $CIRCLE_ARTIFACTS directly when running smoke tests in CircleCI.
Previously sanity checks' output was redirected to /tmp and then copied to $CIRCLE_ARTIFACTS, which is more "moving pieces".
2017-01-09 12:25:29 +00:00
Marc CARRE 89e116961c Now measure time spent in setup. 2017-01-09 12:03:13 +00:00
Marc CARRE 71180f97e7 Parallelise setup.sh. 2017-01-09 12:03:09 +00:00
Adam Harrison be8d9d88d8 Merge pull request #2724 from weaveworks/2647-remove-dependency-on-jq
Removed dependency on jq in test #175.
2017-01-09 10:59:52 +00:00
Bryan Boreham 35de3720e9 Merge pull request #2698 from weaveworks/2647-find-relative-dir
Finding and running tests no longer depends on current directory.
2017-01-09 10:34:07 +00:00
Marc CARRE 4a7e2054db Removed dependency on jq in test #175.
If the machine coordinating the test runs does not have jq, then test #175 fails with:
> test #1 "weave_on test-0.lon1.weave-net report | jq -r '.Router.Targets[] | tostring' | sort" failed:
>     expected "test-1.lon1.weave-net
> test-2.lon1.weave-net"
>     got nothing
This change completely removes the dependency on jq to make the test more robust and avoid potential confusion.
2017-01-09 10:16:05 +00:00
Marc CARRE fe75047988 weave-daemonset.yaml is now referred to using relative paths. 2017-01-09 10:08:38 +00:00
Marc CARRE f73fb5307f Redirect sanity checks' output to temporary files (and archive them as artifact files under CircleCLI).
This should make it easier to find and access relevant debugging information without polluting STDOUT and without any risk of log interleaving. See also:
- https://weaveworks.slack.com/archives/net/p1482154505001192
- https://weaveworks.slack.com/archives/net/p1482254780001493
2017-01-09 09:17:45 +00:00
Marc CARRE 172597a68d Now measure time spent in sanity checks. 2017-01-09 09:17:45 +00:00
Marc CARRE f05169e457 Initialise pids before using it, to avoid potential issues with previously set values. 2017-01-09 09:17:45 +00:00
Marc CARRE b171497466 Ensure sanity checks exit early in case of a ping failure. 2017-01-09 09:17:45 +00:00
Marc CARRE 61375fb785 Format ping output as one line. 2017-01-09 09:17:45 +00:00
Marc CARRE 04cc4edf26 Parallelise sanity checks in order to speed them up. 2017-01-09 09:17:45 +00:00
Marc CARRE 0101a12fba Undo 0dff07dc8b since current directory is already changed on previous line. 2017-01-09 09:16:53 +00:00
Marc CARRE e094fb1547 DOCKER_CERT_PATH is now set using a relative path. 2017-01-09 09:16:53 +00:00
Marc CARRE e0a44a901a Tests now source dependencies using relative paths (previously breaking make depending on current directory). 2017-01-09 09:16:53 +00:00
Marc CARRE d4f9abeefd Finding tests no longer depends on current directory. 2017-01-09 09:16:53 +00:00
Bryan Boreham 0338d4595b Fix instructions to view npc logs when >1 pod exists 2017-01-06 11:24:20 +00:00
Bryan Boreham 7328c3fe86 Comment about full build on first push 2017-01-06 10:54:13 +00:00
Bryan Boreham bf288ff6f5 Warn not to delete all Weave Net pods 2017-01-06 10:30:46 +00:00
Marc Carré ef4c4024bc Merge pull request #2720 from weaveworks/2647-fix-test-150
Fix ordering bug in test #150.
2017-01-05 15:29:58 +00:00
Marc CARRE 6f24cca4b1 Fix ordering bug in test #150.
Test hard-codes a string containing '\n' and then expects echo
to interpret it as a newline, which it does not without the -e option.

This fixes flaky test runs like the below:
>>> Running /root/src/github.com/weaveworks/weave/test/150_connect_forget_2_test.sh on [138.68.153.213 138.68.149.186]
>>> Test /root/src/github.com/weaveworks/weave/test/150_connect_forget_2_test.sh finished after 12.4 secs with error: exit status 1
test #5 "direct_peers 138.68.149.186 | sort" failed:
  expected "138.68.153.213\n138.68.149.186"
  got "138.68.149.186\n138.68.153.213"
2017-01-05 15:02:16 +00:00
Bryan Boreham bf59a003bb Exec weaver from weave-kube launch rather than running in background
So we only have one process running inside the container after all
set-up is finished
2017-01-04 15:00:52 +00:00
Bryan Boreham 2298a40327 Fix bug which was killing all smoke-tests
- only fail if there is no secret password
2017-01-04 14:53:43 +00:00
Adam Harrison 61d22bb8b4 Merge pull request #2686 from weaveworks/issues/2580-allow-ips
Allow docker bridge to have more than one IP address
2017-01-04 14:35:48 +00:00
Adam Harrison eb3bbff883 Merge pull request #2708 from weaveworks/weave-kube-mounts
Mount /etc under a different path for weave-kube
2017-01-04 10:15:54 +00:00
Adam Harrison 03c1379d1b Merge pull request #2716 from liubog2008/fix
fix a bug of updating network policy
2017-01-03 17:44:58 +00:00
liubog2008 1635093341 fix a bug of updating network policy 2016-12-28 14:12:06 +08:00
Bryan Boreham 93dcc4550a Merge pull request #2712 from luxaslabs/deprecate_maintainer_dockerfile
Remove the deprecated MAINTAINER field in Dockerfiles and change to "LABEL maintainer" instead
2016-12-23 16:06:41 +00:00
Bryan Boreham ab55da47b6 Check if we have secrets before decrypting or running smoke tests
And enable running CircleCI on forked pull requests
2016-12-23 16:06:20 +00:00
Lucas Käldström 17971a5a3a Remove the deprecated MAINTAINER field in Dockerfiles for LABEL maintainer instead
Also add https://microbadger.com/labels labels and remove LABEL fields where they already are inherited
2016-12-23 14:57:02 +02:00
Bryan Boreham e0b90e8f02 Inline single-line function docker_bridge_ip 2016-12-23 12:15:04 +00:00
Bryan Boreham ea014d1362 Reimplement docker_bridge_ip shell pipeline in Go 2016-12-23 12:10:26 +00:00
Bryan Boreham 6ef302b8a1 Extract FindBridgeIP to net package 2016-12-23 11:57:04 +00:00
Bryan Boreham 1e7afe3bec Merge branch '1.8' 2016-12-23 11:35:53 +00:00
Bryan Boreham 48508044d6 Merge pull request #2703 from weaveworks/issues/2700-ip-link
Docs: improve IP route links
2016-12-23 11:26:52 +00:00
Bryan Boreham a4ad66f1c8 Mount /etc under a different path for weave-kube
So we don't accidentally read or write the hosts's /etc.
Also move the other volumes under /host to be more consistent with
what the weave script expects.
2016-12-22 10:35:47 +00:00
Bryan Boreham 0f85a959bb Merge branch '1.8' 2016-12-21 11:15:04 +00:00
Bryan Boreham d9a8adda1d Merge pull request #2706 from weaveworks/issues/2638-segfault-dp
Do not segfault if the datapath exists
2016-12-21 11:12:19 +00:00
Marc Carré ef4a8648a9 Merge pull request #2707 from weaveworks/2647-fix-typo-in-sanity-checks
Fixed typo in sanity check of weave's version
2016-12-21 10:28:09 +00:00
Marc CARRE 8bb72aa175 Fixed typo in sanity check of weave's version (previously checking locally, now checking test host). 2016-12-21 10:03:05 +00:00
Martynas Pumputis fa05dcf6ee Do not segfault if the datapath exists
If the datapath exists when creating it, dpif.CreateDatapath
will return an empty handle which access will cause the segfault.
2016-12-20 18:16:16 +02:00
Martynas Pumputis 8affa26858 Merge pull request #2695 from weaveworks/issues/2692-consistent-npc-log
Change rest of npc to weave common logging

Fixes #2692
2016-12-19 16:41:27 +02:00
Martynas Pumputis 856cb48170 Merge pull request #2685 from weaveworks/issues/2480-correct-mac
Take peerName from weave bridge if not specified

Fixes #2480
2016-12-19 16:35:15 +02:00
Bryan Boreham 1239fca567 Docs: improve IP route links 2016-12-19 12:34:05 +00:00
Bryan Boreham 6592a9afc7 Merge branch '1.8' 2016-12-14 11:57:11 +00:00
Mathias Methner 7ffd96f425 Document how to publish prometheus metric endpoint on all interfaces
This is a combination of 4 commits.
 The first commit's message is:
2677 docu, how to publish prometheus metric endpoint on all interfaces

 This is the 2nd commit message:
2677 change docu on how to publish metrics, be more careful with publishing on all interfaces

 This is the 3rd commit message:
2677 fix spelling

 This is the 4th commit message:
2677 fix wrong port title and grammar
2016-12-14 11:54:56 +00:00
Bryan Boreham 906d9a47b1 Merge pull request #2696 from weaveworks/2647-import-using-absolute-paths
Scripts now source dependencies using relative paths
2016-12-13 17:00:58 +00:00
Marc CARRE 0dff07dc8b Scripts now source dependencies using relative paths (previously breaking make depending on current directory). 2016-12-13 16:00:37 +00:00
Bryan Boreham 9261d17dbe Fix option name 2016-12-13 14:59:45 +00:00
Bryan Boreham 7d8a18bd20 Change rest of npc to weave common logging 2016-12-13 13:52:48 +00:00
Bryan Boreham 29cb13cba6 Merge branch '1.8' 2016-12-13 13:34:03 +00:00
Martynas Pumputis 52f375ac1e Merge pull request #2663 from weaveworks/issues/2389-report-mtu
Add MTU to connection status

Fixes #2389
2016-12-13 11:53:39 +00:00
Bryan Boreham 73f184df7e Fix quotes in anchors 2016-12-13 11:42:20 +00:00
Bryan Boreham bbd631f08f weave-kube no longer needs to supply the peer address 2016-12-09 15:34:31 +00:00
Bryan Boreham cf315fb6ba Take peerName from weave bridge if not specified 2016-12-09 15:34:31 +00:00
Bryan Boreham c03a2caac2 Allow docker0 to have >1 IP address
and log the one we end up using
2016-12-09 15:22:49 +00:00
Bryan Boreham 9c2bc0b825 Add MTU to connection status 2016-12-09 13:59:49 +00:00
Martynas Pumputis fcda8985fb Remove bin/setup-ci-secrets
It was used by Travis CI which we do not use anymore.
2016-12-08 16:22:12 +00:00
Martynas Pumputis 14082f9332 Merge branch '1.8' 2016-12-08 15:44:40 +00:00
Martynas Pumputis 83401eb245 Update release-process.md
git.io/weave-kube does not point to the weave-kube repo anymore.
2016-12-08 15:35:54 +00:00
Martynas Pumputis 022a98d4a4 Add release v1.8.2 2016-12-08 15:11:21 +00:00
Bryan Boreham bb1cca713d Merge branch '1.8' 2016-12-08 12:27:40 +00:00
Bryan Boreham 1d80a8d676 Merge pull request #2674 from weaveworks/issues/2650-fix-looping-flows
Detect looping flows
2016-12-08 12:27:15 +00:00
Martynas Pumputis aa9c032176 Add sanity check to detect when receiving own packets 2016-12-08 11:38:37 +00:00
Martynas Pumputis baa8f229f7 Detect enabling of hairpin mode on vethwe-bridge
Enabled hairpin mode on vethwe-bridge was one of the root causes
for installing looping flows in the fastdp mode.

Also, it confused the weave custom L2 bridge, as the bridge treats
a bounced back packet, e.g. ARP brodcast request, as a local one
(the case for "Captured a packet associated with remote host").
2016-12-08 11:37:52 +00:00
Martynas Pumputis ab1b99a4d9 Update vishvananda/netlink vendored dependency
The updated version includes parsing of IFLA_PROTINFO
which is needed to get info about hairpin mode when
subscribing to link updates.
2016-12-08 10:33:22 +00:00
Adam Harrison 11ff1880e5 Merge pull request #2666 from weaveworks/issues/2633-json-events
Log objects via JSON for better debugging
2016-12-07 17:25:55 +00:00
Bryan Boreham 71bf040715 Add --log-level option, default to debug 2016-12-07 11:53:40 +00:00
Bryan Boreham 6a04c6c7bd Change to weave common logging 2016-12-07 11:53:31 +00:00
Bryan Boreham 8530528dd5 Drop pod log messages to Debug level 2016-12-07 11:51:53 +00:00
Adam Harrison e1d8992ec5 Merge branch '1.8'
Fixes #2673.
2016-12-07 11:24:13 +00:00
Adam Harrison b03311e99d Merge pull request #2683 from weaveworks/issues/2673-expose-again
Re-add expose to ensure it gets run on all nodes
2016-12-07 11:23:52 +00:00
Adam Harrison 0c1138ee60 Merge pull request #2662 from weaveworks/issues/2594-setup-cni
Unify weave and launch.sh CNI setup
2016-12-07 11:21:25 +00:00
Bryan Boreham 8a45292e24 Log objects via JSON for better debugging 2016-12-06 17:40:17 +00:00
Bryan Boreham d1712e9589 Re-add expose to ensure it gets run on all nodes
Previous change in a07e3301b1 meant that if there are no pods on
this node then the 'expose' never gets run.
2016-12-06 14:58:31 +00:00
Bryan Boreham ec21afb426 Unify weave and launch.sh CNI setup
Test 830 has to run CNI plugin under sudo now
2016-12-06 11:52:09 +00:00
Bryan Boreham 882bff292e Fix test invocation of weave again
Previous fix in b4a43f1b85 did not work
when built with code coverage.

Running a test script with -v causes `weave_on` to output progress
messages, so we don't want to use those commands inside `$()`
2016-12-06 11:48:48 +00:00
Adam Harrison f3843a6b18 Merge branch '1.8' 2016-12-06 11:41:45 +00:00
Adam Harrison 597c6c111d Merge pull request #2657 from weaveworks/remove-bridge-on-error
Remove weave bridge if something goes wrong when creating it
2016-12-06 11:41:29 +00:00
Adam Harrison ac4957e15c Merge branch '1.8' 2016-12-06 11:30:32 +00:00
Adam Harrison f3915592b2 Merge pull request #2679 from weaveworks/expose-loop
Run iptables commands in a loop
2016-12-06 11:30:20 +00:00
Bryan Boreham 8a292fd9f3 Merge pull request #2678 from weaveworks/issues/2593-remove-cni-from-plugin
Remove CNI support from Docker plugin
2016-12-06 02:51:23 -08:00
Bryan Boreham f34936d9be Merge branch '1.8' 2016-12-06 10:39:50 +00:00
Bryan Boreham d4367457a9 Merge pull request #2671 from weaveworks/document-env-vars
Document env-var configuration for weave-kube
2016-12-06 02:39:20 -08:00
Bryan Boreham b4a43f1b85 Fix test running with -v flag
Running a test script with -v causes `weave_on` and `docker_on` to
output progress messages, so we don't want to use those commands
inside `$()`
2016-12-05 16:12:15 +00:00
Bryan Boreham 3674808244 Remove weave bridge and associated devices if something goes wrong when creating it
Otherwise it is left in a half-created state and the user has to run `weave reset` to continue.
2016-12-05 15:11:47 +00:00
Bryan Boreham 44cc978a94 Update CNI information 2016-12-05 14:29:07 +00:00
Bryan Boreham f441ec2644 Document env-var configuration for weave-kube
E.g. how to configure the IP allocation range
2016-12-05 13:55:33 +00:00
Martynas Pumputis 0ae13a2650 Detect hairpin flows
The introduced "isHairpinFlow" detects whether a flow has been
created due to enabled hairpin mode.
2016-12-05 12:42:24 +00:00
Bryan Boreham ee6596e21c Run iptables commands in a loop
in case they get  "temporarily unavailable" exit
2016-12-05 11:11:20 +00:00
Anita Buehrle a63147beda Improve wording of kube-addon page 2016-11-30 16:15:30 +00:00
Adam Harrison cdcf5808db Remove CNI support from Docker plugin 2016-11-30 10:43:50 +00:00
Bryan Boreham d501c78795 Merge pull request #2659 from weaveworks/issues/2581-optional-bridge-nf
Optional bridge-nf detection
2016-11-28 18:09:40 -08:00
Adam Harrison e61ddc59c4 Merge branch '1.8'
Fixes #2669.
2016-11-28 11:54:03 +00:00
Adam Harrison 46e4f047de Merge pull request #2672 from weaveworks/issues/2669-iprange-clash
Check whether Weave's IP range overlaps something on the host already
2016-11-28 11:53:50 +00:00
Adam Harrison 9cff5f2c5e Merge branch '1.8' 2016-11-25 17:23:39 +00:00
Adam Harrison 5f031453d3 Remove backticks which are tripping up the markdown renderer 2016-11-25 16:55:22 +00:00
Marc CARRE 028216021f Fixed formatting of documentation about logging of connection blocked by Weave NPC. 2016-11-25 16:00:05 +00:00
Bryan Boreham d6544302d3 Check whether Weave's IP range overlaps something on the host already 2016-11-25 14:43:23 +00:00
Adam Harrison bc529c5d09 Merge branch '1.8'
Fixes #2667.
2016-11-25 13:10:29 +00:00
Adam Harrison 354d1ddd5c Merge pull request #2670 from weaveworks/issues/2667-firewall-rules
Run GCE test VMs on a locked-down network
2016-11-25 13:09:54 +00:00
Adam Harrison 28bf4e6e95 Optional bridge-nf detection 2016-11-25 12:40:20 +00:00
Marc Carré 33b7faa17d Merge pull request #2668 from weaveworks/fix-doc-formatting
Fix documentation's formatting.
2016-11-25 12:28:26 +00:00
Marc CARRE ac731c0ff7 Fixed formatting of documentation about logging of connection blocked by Weave NPC. 2016-11-25 12:19:53 +00:00
Bryan Boreham fd34dda6c1 Run test instances on a locked-down network
and open up a rule from the specific IP running the tests
2016-11-24 17:17:12 +00:00
Bryan Boreham 16fca913de Merge branch '1.8' 2016-11-24 15:27:36 +00:00
Bryan Boreham f989a82eb0 Merge pull request #2573 from weaveworks/2546-clarify-npc-packet-drop-no-link
Clarified and documented Weave NPC packet drops (w/o short URL).
2016-11-24 15:26:49 +00:00
Marc CARRE d410ecd34c Document logging of connection blocked by Weave NPC. 2016-11-24 14:04:43 +00:00
Marc CARRE 48569265e2 Add logging of connection blocked by Weave NPC. 2016-11-24 14:02:22 +00:00
Bryan Boreham ad43acf843 Merge branch '1.8' 2016-11-24 10:53:59 +00:00
Bryan Boreham 71782a6aa5 Merge pull request #2661 from weaveworks/fix-700-again
Wait up to 30s for version check error in logs
2016-11-24 10:52:47 +00:00
Adam Harrison 6df24d1a40 Merge branch '1.8' 2016-11-23 12:37:14 +00:00
Adam Harrison e283b0a1ce Add release v1.8.1 2016-11-23 12:25:07 +00:00
Adam Harrison fa15193011 Wait up to 30s for version check error in logs 2016-11-23 10:53:42 +00:00
Bryan Boreham dff14c19f8 Don't remove base CNI plugins in test 2016-11-23 10:38:23 +00:00
Adam Harrison 6103595b9c Merge branch '1.8' 2016-11-23 10:36:53 +00:00
Adam Harrison 01c436ae15 Merge pull request #2642 from weaveworks/fix-launch-version
Fix weave-kube launch.sh version usage
2016-11-23 10:36:16 +00:00
Adam Harrison c3a2539445 Merge branch '1.8' 2016-11-22 16:17:30 +00:00
Adam Harrison 664ba8735f Merge pull request #2643 from weaveworks/issues/2632-cni-no-check-alive
Don't release CNI-allocated IP address when container dies
2016-11-22 16:17:11 +00:00
Bryan Boreham 937036aa64 Simplify default version string 2016-11-22 15:43:17 +00:00
Bryan Boreham 47cdf2b755 Simplify version sed 2016-11-22 15:42:53 +00:00
Adam Harrison ef270764f3 Merge branch '1.8'
Fixes #2632.
2016-11-22 15:28:03 +00:00
Adam Harrison a6edd40de3 Merge pull request #2658 from weaveworks/issues/2632-use-pod-status
Make NPC only look at IP addresses on running pods
2016-11-22 15:27:48 +00:00
Bryan Boreham 4219c2c2ab Only look at IP addresses on pods that haven't finished 2016-11-22 13:49:28 +00:00
Bryan Boreham 4785de1a34 Merge branch '1.8' 2016-11-22 09:59:27 +00:00
Bryan Boreham cbec624cd8 Remove CNI files when tearing down Kubernetes 2016-11-21 16:08:50 +00:00
Bryan Boreham e7bde18f71 Merge pull request #2656 from weaveworks/add-jq-to-vagrantfile
Include jq in the build VM
2016-11-21 11:53:03 +00:00
Bryan Boreham e9eeaee520 Warn user on unknown gce util command 2016-11-21 09:49:41 +00:00
Bryan Boreham d5ec9fb38d Fix test 700 to use resolver override
instead of /etc/hosts override that didn't work in netgo mode
2016-11-18 20:42:15 +00:00
Adam Harrison 233a776c41 Include jq in the build VM
Required to run the tests.
2016-11-18 17:59:13 +00:00
Bryan Boreham d5f1c233bf Remove punctuation from the end of error messages
to placate the linter
2016-11-18 10:40:41 +00:00
Bryan Boreham af732d0495 Merge pull request #2529 from weaveworks/use-golang-171
Build container FROM golang:1.7.3
2016-11-17 15:04:12 +00:00
Marc Carré 04a87f951b Merge pull request #2644 from weaveworks/issues/2567-tighter-iprange
Better value for --ipalloc-range in attach-router
2016-11-17 11:38:12 +00:00
Bryan Boreham 9cc98919fa Adjust CNI smoke-test to cope with new plugin behaviour 2016-11-14 19:53:54 +00:00
Bryan Boreham e42600632f Don't release dead container's IP addresses if not asked to check it is alive. 2016-11-14 19:53:54 +00:00
Bryan Boreham 93aa3fed16 Merge branch '1.8' 2016-11-14 19:47:05 +00:00
Bryan Boreham 49e76d1486 Merge pull request #2645 from weaveworks/fix-test-700
Replace iptables block with resolver override
2016-11-14 19:44:26 +00:00
Adam Harrison 965bed7c4f Replace iptables block with resolver override 2016-11-14 17:11:17 +00:00
Bryan Boreham 317c6ba04c Better value for --ipalloc-range in attach-router
The previous regex matched a blank --ipalloc-range and the following
parameter, which defeated the whole point of the check.
2016-11-14 16:11:42 +00:00
Adam Harrison 41d127934b Remove redundant GO15VENDOREXPERIMENT setting 2016-11-14 15:13:19 +00:00
Adam Harrison 915638d17a Address linter failures 2016-11-14 15:13:19 +00:00
Adam Harrison f73355abcc Incorporate Docker's malformed host fix 2016-11-14 15:13:19 +00:00
Adam Harrison 8f9da95e5e Restore golint 2016-11-14 15:13:19 +00:00
Adam Harrison 0935aa9221 Build container FROM golang:1.7.3 2016-11-14 15:13:19 +00:00
Adam Harrison aaa073afed Merge branch '1.8'
Fixes #2617 and fixes #2570.
2016-11-14 15:11:57 +00:00
Adam Harrison 9b606fb823 Merge pull request #2637 from weaveworks/issues/2617-cni-expose
Remove 'weave expose' race in CNI plugin
2016-11-14 15:11:38 +00:00
Bryan Boreham 15d91c558b Quote version string which may contain spaces, etc 2016-11-14 12:49:00 +00:00
Bryan Boreham ffc5a78139 Add code-coverage options to weaver version call 2016-11-14 12:42:17 +00:00
Bryan Boreham f8693074a3 Move CNI config file to the end of launch script
So something waiting for the config (e.g. Kubernetes) doesn't try to
talk to Weave before then (this only helps on first install, but that
tends to be when things are busiest).
2016-11-14 12:37:42 +00:00
Bryan Boreham 1629f4f3f0 Loop round iptables commands on EAGAIN 2016-11-14 12:37:42 +00:00
Bryan Boreham 10baab38d3 Extend smoke-test to include pinging 2016-11-14 12:37:42 +00:00
Bryan Boreham e458c11e66 Weave script calls Go implementation of expose_nat 2016-11-14 12:37:42 +00:00
Bryan Boreham a07e3301b1 Add 'weave expose' NAT iptables rules inside CNI plugin
This avoids a race between the plugin and the script
2016-11-14 12:37:42 +00:00
Bryan Boreham 2b4d13c5b1 Don't error on bridge address already there 2016-11-14 12:37:42 +00:00
Bryan Boreham 755e42836c Merge branch '1.8' 2016-11-14 11:29:34 +00:00
Bryan Boreham ad743b0e96 Merge pull request #2577 from weaveworks/2548-fix-reclaim-after-using-cni
Fix reclaim after using CNI; Fixes #2548.
2016-11-14 11:28:42 +00:00
Marc CARRE 0544901357 Factorise "_" duplicates as a constant. 2016-11-11 17:00:26 +00:00
Marc CARRE bc94633180 Re-claim IP on start-up when an existing ID has been found.
- Rewrote conditions to keep c.ident immutable and hopefully makes
things clearer.
- Added a case to tolerate reclaim after we have used CNI (passed CID
is “_” and existing CID is a real container ID).
2016-11-11 17:00:26 +00:00
Marc CARRE 16415404c7 Added automated test reproducing the issue.
test #4 "[
3e52b548e6df304c61ea5bee0af4b3515e025e7e25152c65ecae3d03c71cf52d ==
Unable to claim: address 10.32.0.3/12 is already owned by
fbe411facc8b657c5850591ab56fc40fb56160d43db0d7363a29ba3edad61134
Unable to claim: address 10.32.0.1/12 is already owned by
cf16a2bcdee8dd1ef7e5f0a611127611e67ea734f45d7526678fc3b1fc0c6f5d
3e52b548e6df304c61ea5bee0af4b3515e025e7e25152c65ecae3d03c71cf52d ]"
failed:
	program terminated with code 2 instead of 0
1 of 6 tests failed in 6.499s.
2016-11-11 17:00:26 +00:00
Adam Harrison 702d12d801 Merge branch '1.8'
Fixes #2537.
2016-11-11 16:14:52 +00:00
Adam Harrison 46eb01604c Merge pull request #2565 from weaveworks/2537-fix-status-on-version-check-failures
Improve 'status' to handle cases when the checkpoint API is not available
2016-11-11 16:14:24 +00:00
Adam Harrison af36682a7e Merge branch '1.8' 2016-11-11 11:27:25 +00:00
Bryan Boreham 03d9e3db69 weaveutil now depends on plugin code 2016-11-10 17:04:10 +00:00
Marc CARRE b03b3fccc7 Fixes 2537: status now prints 'failed to check latest version' when the checkpoint API is not available (+test). 2016-11-09 17:46:52 +00:00
Marc Carré 9414e2979d Merge pull request #2599 from weaveworks/replace-kubectl-create-with-apply
Updated doc: replaced kubectl create with kubectl apply.
2016-11-07 16:31:31 +00:00
Marc CARRE 865664425b Updated doc: replaced kubectl create with kubectl apply. 2016-11-07 16:18:40 +00:00
Adam Harrison b060cf30f4 Add release v1.8.0 2016-11-04 15:49:36 +00:00
Marc Carré 5352ed837a Merge pull request #2598 from weaveworks/cni-setup-remove-symlink
Clean up CNI symlinks from weave-kube
2016-11-04 15:28:44 +00:00
Adam Harrison d4d54a1ff5 Clean up CNI symlinks from weave-kube 2016-11-04 14:41:34 +00:00
Adam Harrison ea82a6715f Merge pull request #2569 from weaveworks/weave-kube-smoke-test
weave-kube smoke test
2016-11-04 12:58:20 +00:00
Martynas Pumputis d356e32bdf Merge pull request #2588 from weaveworks/kube-npc-docs
Document k8s addon & prometheus metrics
2016-11-04 12:50:41 +00:00
Martynas Pumputis 6193d22d2e Merge pull request #2595 from weaveworks/change-npc-metrics-port
Change default NPC metrics port
2016-11-04 12:41:25 +00:00
Adam Harrison 50c9568073 Document Prometheus metrics endpoints 2016-11-04 12:33:06 +00:00
Adam Harrison 9d05ed41b2 Change default NPC metrics port 2016-11-04 12:31:01 +00:00
Adam Harrison e3f7e0a23a Merge pull request #2590 from weaveworks/issues/2586-/opt/cni/bin-never-upgraded
Add support for atomic and versioned upgrades of CNI plugin.
2016-11-04 12:27:48 +00:00
Marc CARRE da2f0803ce Add support for atomic and versioned upgrades of CNI plugin. 2016-11-04 11:54:22 +00:00
Bryan Boreham 6dde5e5ee9 Add code-coverage options to weaver start 2016-11-04 10:52:36 +00:00
Bryan Boreham 494df21bdf Disable imagePullPolicy so we test the image we just built 2016-11-04 10:52:36 +00:00
Bryan Boreham e44bbbec63 Add smoke-test for weave-kube 2016-11-04 10:52:36 +00:00
Bryan Boreham c19f49a284 Install Kubernetes packages and pre-pull images
Bump template version too
Note that we disable kubelet in the image, so you have to start it if
you want to use it.
2016-11-04 10:52:36 +00:00
Adam Harrison d3f2c110e4 Merge pull request #2589 from weaveworks/issues/2587-cni-weaveutil
Fix CNI plugin calling weaveutil
2016-11-04 10:47:38 +00:00
Bryan Boreham 09628178e4 Weave-kube doesn't need to depend on plugin repo any more 2016-11-03 17:42:39 +00:00
Bryan Boreham 5630a01a8c Implement CNI plugin via weaveutil 2016-11-03 17:42:39 +00:00
Adam Harrison 40b3a49c90 Merge pull request #2563 from weaveworks/update-test-template
Update CI VMs to Ubuntu 16.04 and Docker 1.11
2016-11-03 17:35:21 +00:00
Adam Harrison 431b87b94a Merge pull request #2591 from weaveworks/reset-npc
Have 'weave reset' remove NPC rules
2016-11-03 15:22:46 +00:00
Adam Harrison 828c3d21d2 Recommend using the k8s addon from the CNI docs 2016-11-03 15:13:50 +00:00
Adam Harrison f0e75481d5 Add network policy to features 2016-11-03 15:13:50 +00:00
Adam Harrison 8bb7e1cf24 Document Kubernetes Addon 2016-11-03 15:13:50 +00:00
Bryan Boreham e117a6bd04 Have 'weave reset' remove NPC rules 2016-11-03 14:24:26 +00:00
Adam Harrison ac44fa63c8 Fix breakage caused by #2574 2016-11-03 11:52:58 +00:00
Martynas Pumputis bb639dbf32 Merge pull request #2585 from weaveworks/merge-weave-npc
Merge weave npc
2016-11-02 11:58:43 +00:00
Bryan Boreham 64c890005a Merge pull request #2583 from damoon/fixup-74b477ac82e1ae267cf8501519f52e1f71a782dc
weaveworks/weave-kube:latest broken - fixup! allow to not run NPC: do not create iptables rules for NPC
2016-11-02 11:58:02 +00:00
Adam Harrison 19088ba8bc Import from weave-npc repo 2016-11-02 11:28:59 +00:00
Martynas Pumputis ec5f7033a4 Merge pull request #2579 from weaveworks/issues/2557-improve-metric-naming
Improve metric naming
2016-11-02 11:02:23 +00:00
Bryan Boreham eb60f68df2 Report metrics on all connection states 2016-11-02 09:51:13 +00:00
David Sauer d72e671d8b fixup! allow to not run NPC: do not create iptables rules for NPC 2016-11-02 10:10:33 +01:00
Martynas Pumputis 3462357481 Merge pull request #2578 from weaveworks/issues/2576-metrics-on
Serve metrics by default, on port 6782
2016-11-02 09:08:13 +00:00
Bryan Boreham 2b4da35b1c Remove 'total' DNS entries; let the caller add them up 2016-11-01 18:03:35 +00:00
Bryan Boreham 86d68c9875 Move total IPs in range from a state to a separate metric 2016-11-01 18:03:35 +00:00
Bryan Boreham cfff8ee8be Merge pull request #2568 from weaveworks/rename-conn-term-prom-metric
Rename weave_connection_termination_count metric
2016-11-01 18:02:55 +00:00
Bryan Boreham af10cef5f0 Set --status-addr for metrics by default 2016-11-01 17:04:04 +00:00
Bryan Boreham a1a42736ed Fix hard-coded http address 2016-11-01 16:53:37 +00:00
Adam Harrison b533a11bee Update client-go
weave-npc needs some fixes from client-go master (specifically the
unversioned.LabelSelector change)
2016-11-01 16:19:43 +00:00
Bryan Boreham afed9e9646 Merge pull request #2574 from pondohva/fix_weave_static_pod
allow to not run NPC: do not create iptables rules for NPC
2016-11-01 15:35:49 +00:00
Artur Gadelshin 74b477ac82 allow to not run NPC: do not create iptables rules for NPC 2016-11-01 17:32:41 +03:00
Bryan Boreham bf74c8f108 Add dependency of weave-kube on launch.sh 2016-11-01 10:46:25 +00:00
Bryan Boreham 04c7f5283e Reconfigure and restart docker for systemctl 2016-10-31 17:33:33 +00:00
Bryan Boreham d1d53ba45c Pre-install more stuff in the image.
Install bc and jq in the image rather than on every build.
Also pre-pull some Docker images
2016-10-31 17:33:33 +00:00
Bryan Boreham dfadb8f189 Upgrade to Ubuntu 16.04 and Docker 1.11
Using Docker 1.11 since there isn't a Docker-supplied package for 1.10 on Xenial
2016-10-31 17:33:33 +00:00
Bryan Boreham 5335c133a3 Update deprecated gcloud syntax 2016-10-31 17:33:33 +00:00
Adam Harrison 8fcb5daedf Merge pull request #2551 from weaveworks/weave-kube
Merge weave-kube into the Weave Net repo
2016-10-31 17:12:03 +00:00
Martynas Pumputis ede70a78d6 Rename weave_connection_termination_count metric
To make it follow the Prometheus naming conventions:
https://prometheus.io/docs/practices/naming/
2016-10-31 13:23:12 +00:00
Bryan Boreham 23056cbb45 Temporarily release weave-daemonset.yaml to weave-kube repo 2016-10-31 10:59:15 +00:00
Bryan Boreham 29e9e70ac9 Add weave-kube to release script 2016-10-31 10:59:15 +00:00
Bryan Boreham d0b711513e Add weave-daemonset.yaml 2016-10-31 10:59:15 +00:00
Bryan Boreham 7dbee74e85 Add weave-kube image 2016-10-31 10:59:15 +00:00
Bryan Boreham 4e7a3b1805 Add kube-peers program 2016-10-31 10:59:15 +00:00
Bryan Boreham 3c7b244f18 Change image layering - plugin builds on weaver & weaver builds on weaveexec 2016-10-31 10:59:13 +00:00
Bryan Boreham e50f5c52c5 Make templating of Dockerfiles more generic 2016-10-31 10:56:18 +00:00
Bryan Boreham baf91658d6 Fix static linking flags 2016-10-28 14:51:26 +01:00
Adam Harrison fda035d8d6 Merge branch '1.7' 2016-10-28 14:29:26 +01:00
Adam Harrison a4a53e1a11 Fix broken link 2016-10-28 14:08:54 +01:00
Martynas Pumputis aad3e52d72 Merge pull request #2564 from weaveworks/improved-dh-org-override-fix
Improve Dockerfile template substitution
2016-10-28 10:24:28 +01:00
Adam Harrison cb778a9af5 Improve Dockerfile template substitution 2016-10-27 11:43:41 +01:00
Marc CARRE 3af9732c84 Merge branch '1.7' 2016-10-26 16:49:58 +01:00
Marc Carré 00e754ed9f Merge pull request #2562 from weaveworks/build-test-runner-with-vendoring
Use vendoring when building test runner & Vagrantfile improvements
2016-10-26 16:44:15 +01:00
Marc CARRE d893f44833 Vagrantfile now copies SSH key required to run smoke tests from host to guest. 2016-10-26 16:09:09 +01:00
Marc CARRE 4839f41809 Improve resolution of Dockerfile since used in both Vagrantfile and test/Vagrantfile. 2016-10-26 16:09:09 +01:00
Marc CARRE c801409c94 Set VM's memory to 2048 MB by default. 2016-10-26 16:09:09 +01:00
Marc CARRE 1c4a01d52c Read Go version from Dockerfile in order to keep things 'DRY'. 2016-10-26 16:09:09 +01:00
Adam Harrison 880b0a883a Use vendoring when building test runner 2016-10-26 16:09:09 +01:00
Adam Harrison 4b77662e3b Merge pull request #2561 from weaveworks/issues/2560-fix-dns-ipam-metrics
Do not expose IPAM or DNS metrics if weave does not run IPAM or DNS
2016-10-26 14:24:43 +01:00
Adam Harrison a5ff7ab8df Merge pull request #2475 from weaveworks/issues/2419-withnetns
Add a safer version of WithNetNS*
2016-10-26 13:50:34 +01:00
Adam Harrison 04a6e6d13b Merge branch '1.7' 2016-10-26 13:47:05 +01:00
Martynas Pumputis 5c2e878c64 Do not expose IPAM or DNS metrics when weave does not run IPAM or DNS
Otherwise, GET /metrics will crash weaver.
2016-10-25 16:54:35 +01:00
Adam Harrison f9bada5af8 Merge pull request #2558 from weaveworks/fix-broken-url-in-doc
Fixed broken link to plugin.md to weave-docker-api.md.
2016-10-24 16:57:07 +01:00
Marc CARRE 80d66f8f68 Fixed broken link to plugin.md to weave-docker-api.md. 2016-10-24 16:37:55 +01:00
Martynas Pumputis 98b35b87a9 Fix weave_connection_termination_count
Do not count terminations caused by connect-to-ourselves.
2016-10-24 11:37:15 +01:00
Martynas Pumputis b1d6605e8f Remove inaccurate Prometheus metrics
The metrics include:
- weave_packets_total
- weave_bytes_total

The problem with those metrics is that fastdp periodically flushes
flows including their stats thus makes the current implementation
of the metrics unreliable.
2016-10-24 11:23:10 +01:00
Martynas Pumputis 2cd3bde348 Merge pull request #2555 from weaveworks/forget-immediately
Recompute targets immediately after 'weave forget'
2016-10-24 10:52:14 +01:00
Bryan Boreham f2454775b9 Merge pull request #2552 from weaveworks/issues/2550-fix-make-dockerhub-user
Ensure Dockerfiles obey DOCKERHUB_USER
2016-10-24 09:59:38 +01:00
Bryan Boreham a53d1e00ee Recompute targets immediately after 'weave forget' 2016-10-21 18:02:25 +01:00
Martynas Pumputis 523a964ac8 Merge pull request #2547 from weaveworks/prometheus-metrics
Prometheus metrics
2016-10-21 14:57:42 +01:00
Adam Harrison f8cf7a1054 Ensure Dockerfiles obey DOCKERHUB_USER 2016-10-21 14:45:10 +01:00
Bryan Boreham 4d8a40c0b5 Reduce metrics mechanism to just support fastdp 2016-10-21 14:44:12 +01:00
Martynas Pumputis 9754da15d6 Encode "list-netdevs" output in JSON 2016-10-20 18:18:57 +01:00
Bryan Boreham 0458d32089 Serve metrics on a different socket to the main API
Serve metrics+status on status socket and api+status+metrics on api
socket; the reasoning is that metrics or status are read-only hence
may be scraped from an off-machine connection, while we don't want to
open the control port up unprotected.
2016-10-20 16:25:16 +01:00
Bryan Boreham ee4e8eb994 Pull in updated mesh lib 2016-10-20 16:25:16 +01:00
Bryan Boreham b8d619dde7 Add Prometheus http handler for metrics
Metrics are: connection counts, active IP addresses, DNS addresses,
FastDP flow metrics, connection termination count
2016-10-20 16:25:16 +01:00
Bryan Boreham 00c86fed42 Expose overlay metrics from fastdp
and allow them to pass through OverlaySwitch
2016-10-20 16:25:16 +01:00
Bryan Boreham 6d5af85eee Report count of active IP addresses in status 2016-10-20 14:04:41 +01:00
Bryan Boreham 1ae2d33714 Remove old-style 'expvar' metrics 2016-10-20 13:54:42 +01:00
Bryan Boreham 71d550260f Extract countDNSEntries function 2016-10-20 13:54:42 +01:00
Bryan Boreham 1092bae05c Refactor: move 'unreachable' logic out of printing function 2016-10-20 13:54:42 +01:00
Martynas Pumputis e611f04f41 Move NetDev utils from common/ to net/ 2016-10-19 17:03:30 +01:00
Martynas Pumputis 3492cd93d0 Use safe version of WithNetNS 2016-10-19 16:15:59 +01:00
Martynas Pumputis 947ae11fee Refactor NetDev utilities
- Make them safe by using the safe version of WithNetNS.
- Improve naming.
2016-10-19 16:07:53 +01:00
Martynas Pumputis cdd6ed548c Add netdev subcommands to weaveutil
The subcommands are going to be used with WithNetNS wrapper.
2016-10-19 16:07:53 +01:00
Martynas Pumputis fc940d0017 Merge pull request #2549 from weaveworks/log-drops-via-nflog
Log dropped policy controller traffic via NFLOG
2016-10-19 11:02:28 +01:00
Bryan Boreham b38a55ca7c Include more context in error messages from CNI operations 2016-10-18 17:45:09 +01:00
Adam Harrison 8e739d5240 Log dropped policy controller traffic via NFLOG
Send blocked NEW connection attempts to NFLOG group 86 for accounting by
the weave-npc process.
2016-10-14 15:59:15 +01:00
Adam Harrison 71f8bb7e9a Merge branch '1.7' 2016-10-11 17:02:00 +01:00
Adam Harrison ebfaf11f4a Add release v1.7.2 2016-10-11 11:07:18 +01:00
Matthias Radestock 4a6cec3ecc Merge branch '1.7' 2016-10-07 12:47:04 +01:00
Matthias Radestock 1abce148a3 Merge pull request #2543 from weaveworks/issues/2527-remote-addr
Update Weave Mesh to bring in two fixes

Fixes #2481 via weaveworks/mesh#57
Fixes #2527 via weaveworks/mesh#60
2016-10-07 12:45:51 +01:00
Adam Harrison e0cc7f17b2 Merge branch '1.7'
Fixes #2540
2016-10-07 12:24:11 +01:00
Adam Harrison 264e5c9979 Merge pull request #2541 from weaveworks/issues/2540-withnetns
Change namespace via nsenter, for plugin arp-config step
2016-10-07 12:20:47 +01:00
Bryan Boreham a6a1ce5c9e Update Weave Mesh to bring in fix of panic 2016-10-07 12:13:49 +01:00
Bryan Boreham 6ac7ab162f Merge branch '1.7' 2016-10-06 16:42:07 +01:00
Bryan Boreham 5e660311d2 Merge pull request #2538 from weaveworks/2506-uts-release-bytes
inline (u)int8 array to string conversion
2016-10-06 16:41:26 +01:00
Martynas Pumputis 4a49ff3083 Replace usage of WithNetNSUnsafe in plugin/net/watcher.go with safer version
Unsafe version was in ConfigureARPforVeths; replacement is via `weaveutil configure-arp`
2016-10-06 15:25:05 +01:00
Martynas Pumputis 7f92c8c4c6 Add a safer version of WithNetNS*
The introduced functions are executing the work function via
a process which executes "nsenter --net=path weaveutil ...".
2016-10-06 15:25:05 +01:00
Matthias Radestock 85ac8177ad inline (u)int8 array to string conversion
so that the code compiles regardless of the uts.Release array type,
which varies across platforms.

Fixes #2506
2016-10-06 08:57:12 +01:00
Adam Harrison 03bd1fb91d Merge branch '1.7' 2016-10-05 16:49:33 +01:00
Adam Harrison eb5b16614c Add release v1.7.1 2016-10-05 15:23:25 +01:00
Adam Harrison a5873a3970 Merge branch '1.7' 2016-10-05 15:18:26 +01:00
Adam Harrison e48ca80dee Disable golint as it no longer builds with 1.5.x 2016-10-05 15:16:23 +01:00
Bryan Boreham e7c9e22350 Merge pull request #2274 from weaveworks/issues/2273-improve-doc-ci
Improve doc CI
2016-10-03 15:34:39 +01:00
Adam Harrison b8e7d83f19 Rename SKIP_TESTS 2016-10-03 14:07:57 +01:00
Adam Harrison 4c304c0013 Extract install-wordepress 2016-10-03 14:01:15 +01:00
Adam Harrison 7249350757 Merge pull request #2531 from weaveworks/process-addrs
Add weaveutil process-addrs
2016-09-30 10:28:59 +01:00
Bryan Boreham 50a8dc1383 Add weaveutil process-addrs
Fetches addresses for every veth that is in a network namespace and
attached to the specified bridge.  Works by iterating over every process.
2016-09-29 14:16:05 +01:00
Bryan Boreham 71491138aa Extract function to return all current process ids
This implementation should be more efficient because it only uses the
names under /proc, whereas the previous implementation fetched the
full directory entry for each one, and sorted them too.
2016-09-29 14:12:02 +01:00
Bryan Boreham ca87f8ada3 Improve comments 2016-09-29 14:06:43 +01:00
Adam Harrison 835b3f3d67 Improve script names 2016-09-29 13:01:18 +01:00
Adam Harrison 263dffeedc Extract shared function 2016-09-29 11:45:28 +01:00
Adam Harrison e1063944f6 Comment on GitHub PR with site changes 2016-09-29 11:45:28 +01:00
Adam Harrison 2380018457 Skip tests if PR contains only site changes 2016-09-29 11:45:28 +01:00
Adam Harrison a9db631836 Add toggle for skipping tests 2016-09-29 11:35:01 +01:00
Adam Harrison b45f138ff1 Propagate state between scripts 2016-09-29 11:25:34 +01:00
Adam Harrison b239694d34 Move circle commands into shell scripts 2016-09-29 11:25:34 +01:00
Adam Harrison 0c2774f367 Add release v1.7.0 2016-09-27 14:46:35 +01:00
Bryan Boreham ea4647bc74 Merge pull request #2524 from weaveworks/expect-npc
Implement `--expect-npc` flag to `create-bridge`
2016-09-27 13:41:22 +01:00
Adam Harrison 6ec21d3a58 Implement --expect-npc flag to create-bridge
Add a private flag for weave-kube to steer overlay traffic via the
network policy engine chain.
2016-09-27 09:23:19 +01:00
Adam Harrison 44a4a56024 Merge branch '1.6' 2016-09-21 17:14:07 +01:00
Adam Harrison 0aac614c08 Add release v1.6.2 2016-09-21 16:18:03 +01:00
Adam Harrison 2ea027d3a8 Merge branch '1.6' 2016-09-21 11:15:49 +01:00
Adam Harrison cd4cbed5a0 Merge pull request #2501 from weaveworks/issues/2495-filter-empty-peers
Reject empty peers
2016-09-21 11:12:10 +01:00
Adam Harrison 69b688b357 Merge pull request #2509 from weaveworks/issues/2503-persist-peers-fix
Create restart.sentinel after storing the peer list
2016-09-21 10:09:05 +01:00
Adam Harrison 7a81bc2ddc Merge pull request #2510 from weaveworks/issues/2329-fix-830-flakiness
Enable unsolicited ARPs in 830 test suite
2016-09-20 17:17:19 +01:00
Martynas Pumputis cdeae04238 Create restart.sentinel after storing peer list
Otherwise, we risk to lose peer list when any failure happens after
the creation but before storing the list and as a consequence,
the weave container gets restarted.
2016-09-20 17:07:48 +01:00
Martynas Pumputis 6df2782d73 Update weaveworks/mesh submodule 2016-09-20 17:03:38 +01:00
Adam Harrison 3fc7efa536 Merge pull request #2498 from weaveworks/broken-link
fixed broken link to command line args
2016-09-20 16:40:06 +01:00
Adam Harrison a556deec78 Merge branch '1.6' 2016-09-20 16:26:48 +01:00
Adam Harrison 71e43c2023 Merge pull request #2511 from weaveworks/issues/2340-make-640-less-flaky
Filter out netns of non-existing containers
2016-09-20 15:52:54 +01:00
Bryan Boreham 370f258c3a Fix outdated option ipam-seed 2016-09-16 15:53:43 -07:00
Martynas Pumputis 9b32bc2ab3 Close opened netns 2016-09-14 16:47:40 +01:00
Martynas Pumputis fd5e1970e1 Return nil netdev if netns of container cannot be found
The change applies to GetNetDevsWithPredicate. The function calls
FindNetDevs which already does the same filtering.

The change prevents from "container-addrs" (weaveutil) returning
"unable to open X process namespace" error which happens when
a container dies while the cmd is being executed.
2016-09-14 16:47:16 +01:00
Martynas Pumputis a1de7f3eef Enable unsolicited ARPs in 830 test case
Otherwise, ping (c1->c3) after the address reuse might time out.
2016-09-14 11:05:00 +01:00
Matthias Radestock 06a63db4cf Merge branch '1.6' 2016-09-08 12:55:05 +01:00
Matthias Radestock c720ebec02 Merge pull request #2502 from weaveworks/issues/2469-supply-subnet
Pass in default subnet when creating 'weave' plugin network.

Fixes #2469.
2016-09-08 12:49:01 +01:00
Matthias Radestock 6a528409ab Merge pull request #2504 from weaveworks/check-tx-off
Check current tx value before trying to set it
2016-09-08 12:32:15 +01:00
Bryan Boreham c69e140e9e Check current tx value before trying to set it 2016-09-08 10:20:35 +01:00
Anita Buehrle 8ed0c13645 removed broken link 2016-09-06 14:36:25 +01:00
Anita Buehrle b635f9a994 fixed broken link to command line args 2016-09-06 14:36:25 +01:00
Bryan Boreham ac4246e1f5 Pass in default subnet when creating 'weave' plugin network.
New behaviour in Docker 1.12 means it disregards a plugin-supplied
address pool that overlaps an existing route, which causes a hang as
noted in #2469. When we pass in the subnet, Docker believes we really
do want that address range and avoids the hang.
2016-09-06 12:05:51 +01:00
Martynas Pumputis 06a325a05f Use weaveworks/docker/pkg/mflag everywhere 2016-09-05 17:22:28 +03:00
Martynas Pumputis 68e9bbe350 Add github.com/weaveworks/docker submodule 2016-09-05 16:16:06 +03:00
Matthias Radestock 3bd9e369cd Merge branch '1.6' 2016-09-05 12:51:30 +01:00
Matthias Radestock 3d12e8088e Merge pull request #2491 from weaveworks/switch-ci-14.04
Switch CircleCI build VM to 14.04
2016-09-05 12:49:25 +01:00
Martynas Pumputis aee35b34fe Pin joffrey/docker-py image to 1.8.1 vsn
The latest image requires 1.12.x dockerd.
2016-09-05 14:30:49 +03:00
Martynas Pumputis c06ccb3b0d Change owner of /usr/local/go on build VM
Otherwise "go get -tags netgo" fails with the permission denied error.
2016-09-05 14:30:49 +03:00
Martynas Pumputis 268bb656fc Do not fetch Google Cloud SDK
As it is already installed on CircleCI 14.04 build VMs
2016-09-05 14:30:49 +03:00
Martynas Pumputis 57357a728c Merge branch '1.6' 2016-09-05 13:48:30 +03:00
Martynas Pumputis a335c419ec Fix typo 2016-09-05 13:27:49 +03:00
Martynas Pumputis e263295720 Revert "Do not fetch Google Cloud SDK"
This reverts commit f557835ad0.
2016-08-26 14:42:50 +01:00
Martynas Pumputis 0c854f2144 Merge pull request #2489 from weaveworks/fix-mflag-missing
Use mflag package from weaveworks fork until we find a better solution
2016-08-26 12:19:59 +01:00
Alfonso Acosta bdf4debdfd Use mflag package from weaveworks fork until we find a better solution 2016-08-26 11:07:21 +00:00
Martynas Pumputis f557835ad0 Do not fetch Google Cloud SDK
As it is already installed on CircleCI 14.04 build VMs
2016-08-26 11:38:37 +01:00
Martynas Pumputis 17a7391086 Remove unused functions 2016-08-26 10:15:27 +01:00
Martynas Pumputis e65293eb50 Merge branch '1.6' 2016-08-19 14:12:26 +01:00
Martynas Pumputis 48c9547943 Update CHANGELOG.md 2016-08-19 14:11:57 +01:00
Martynas Pumputis caa6c6c931 Merge branch '1.6' 2016-08-19 11:22:07 +01:00
Adam Harrison 2e825242cd Merge branch '1.6' 2016-08-18 11:32:43 +01:00
Adam Harrison 027064cbdb Merge branch '1.6' 2016-08-18 10:56:03 +01:00
Martynas Pumputis 060f6392c7 Merge branch '1.6' 2016-08-16 18:03:00 +01:00
Bryan Boreham a466f55d59 Merge pull request #2462 from weaveworks/note-proxy-file
added note about net flag
2016-08-12 16:55:57 +01:00
Adam Harrison f686408808 Merge branch '1.6' 2016-08-10 14:44:25 +01:00
Adam Harrison b8c57ef10f Merge branch '1.6' 2016-08-10 13:58:53 +01:00
Adam Harrison 5cc0826ca0 Merge branch '1.6' 2016-08-10 13:16:24 +01:00
Adam Harrison e703f2f3f2 Merge branch '1.6' 2016-08-10 11:48:31 +01:00
Adam Harrison f544da9e19 Merge branch '1.6' 2016-08-10 10:18:01 +01:00
Adam Harrison 472eab2acd Merge pull request #2466 from weaveworks/issues/2464-enable-create-bridge
Re-enable 'weave create-bridge' in fastdp mode.
2016-08-10 09:57:40 +01:00
Bryan Boreham 7a5d7fca6c Allow 'weave create-bridge', if the user insists.
For example this is used when setting up CNI for Kubernetes, in
an environment where we know none of the bad consequences apply.
2016-08-08 17:20:25 +01:00
Bryan Boreham 589b45dace Merge branch '1.6' 2016-08-03 14:34:49 +01:00
Anita Buehrle 3273d13666 gave points numbers for clarity 2016-08-02 16:40:16 -05:00
abuehrle 5fdbbf3722 wording formatting 2016-08-02 16:38:41 -05:00
abuehrle 14350ff463 added anchor to attaching containers 2016-08-02 16:35:52 -05:00
abuehrle 0b49c961a7 reconfigured note to include additional method 2016-08-02 16:30:32 -05:00
abuehrle 39b80f26ed made terminology consistent 2016-08-02 13:15:17 -05:00
abuehrle 74b20265e4 fixed links and some titles 2016-08-02 12:59:27 -05:00
abuehrle 358fddb958 fixed broken link and title 2016-08-02 12:52:36 -05:00
abuehrle 5c8f6175b5 added note about net flag 2016-08-02 12:34:52 -05:00
Adam Harrison 83ce5875ee Merge branch '1.6' 2016-07-28 12:52:53 +01:00
Adam Harrison f5a30c790e Merge branch '1.6' 2016-07-28 11:30:47 +01:00
Martynas Pumputis 34415c3c17 Merge pull request #2422 from weaveworks/log-resolvconf-errors
Log errors arising from reading resolv.conf
2016-07-26 18:01:33 +01:00
Matthias Radestock 6387fa8bc9 Merge branch '1.6' 2016-07-20 07:30:56 +01:00
Adam Harrison 8ec6b699b1 Merge branch '1.6' 2016-07-18 11:48:08 +01:00
Matthias Radestock 551f164ec3 Merge branch '1.6' 2016-07-12 20:47:23 +01:00
Bryan Boreham 88bf64722f Merge branch '1.6' 2016-07-12 10:33:38 +00:00
Matthias Radestock d9c998b5c4 Merge pull request #2386 from weaveworks/issues/354-multicast-isolation
Provide multicast isolation with in-container-netns iptables rules

Fixes #354.
2016-07-12 09:46:14 +01:00
Adam Harrison 170e19c283 Merge branch '1.6' 2016-07-12 09:39:45 +01:00
Bryan Boreham 7c47a8ffb7 Log errors arising from reading resolv.conf 2016-07-11 12:08:04 +01:00
Matthias Radestock 791ab55875 Merge branch '1.6' 2016-07-09 05:42:02 +01:00
Bryan Boreham bd1a9d020c Merge branch '1.6' 2016-07-07 11:20:50 +00:00
Martynas Pumputis 71fd3b6b2b Merge remote-tracking branch 'origin/1.6' 2016-07-05 17:37:50 +01:00
Bryan Boreham f8ac27a6cc Merge branch '1.6' 2016-07-05 13:22:25 +01:00
Matthias Radestock 954cd0b86a Merge branch '1.6' 2016-07-04 16:27:59 +01:00
Matthias Radestock 9dedeadf15 Merge branch '1.6' 2016-07-04 16:22:42 +01:00
Matthias Radestock 6561272f8d Merge branch '1.6' 2016-07-04 16:20:37 +01:00
Matthias Radestock 881e795db5 correct RFC3484 address selection caveat (#2407)
and move it to a more prominent location

Fixes #1710
2016-07-04 16:19:20 +01:00
Matthias Radestock 4216231ec7 Merge branch '1.6' 2016-07-04 14:30:03 +01:00
Matthias Radestock 333d5f7511 Merge pull request #2412 from weaveworks/1803-plugin-create
Refactor plugin to create veths in CreateEndpoint



Fixes #1803.
2016-07-04 12:19:01 +01:00
Matthias Radestock 7be7945b29 Merge branch '1.6' 2016-07-04 10:08:43 +01:00
Bryan Boreham afe882cd94 Use more chars from endpointID to reduce clashes in veth names
Import library to get max name length IFNAMSIZ
2016-07-01 16:05:02 +01:00
Matthias Radestock 5b8a359475 Merge branch '1.6' 2016-07-01 10:31:39 +01:00
Matthias Radestock df0af203f8 Merge pull request #2416 from weaveworks/issues/2293-warn-router-down
Check that weave router is running before launching plugin

Fixes #2293.
2016-07-01 10:24:15 +01:00
Matthias Radestock 5b2a4ff614 Merge branch '1.6' 2016-06-29 20:12:58 +01:00
Bryan Boreham ceb5f8c714 Move endpoint creation into CreateEndpoint so we can return the MAC address 2016-06-29 17:38:07 +01:00
Bryan Boreham cc3359dfe5 Merge branch '1.6' 2016-06-29 14:42:17 +01:00
Matthias Radestock cda6785f1d Merge remote-tracking branch 'upstream/master' 2016-06-29 05:58:29 +01:00
Matthias Radestock cb030be4ad Merge branch '1.6' 2016-06-29 05:57:01 +01:00
Bryan Boreham b464ce86f7 Merge branch '1.6' 2016-06-28 13:36:10 +00:00
Adam Harrison 80b3514e24 Merge branch '1.6' 2016-06-20 16:29:29 +01:00
Adam Harrison e33f56f9b0 Merge branch '1.6' 2016-06-20 14:53:03 +01:00
Adam Harrison f386548890 Maintain per-subnet ACCEPT rule for multicast ingress 2016-06-17 17:19:52 +01:00
Adam Harrison c80d87554a Maintain per-interface DROP rule for multicast ingress 2016-06-17 16:10:13 +01:00
280 changed files with 7669 additions and 1732 deletions

No files matched your search

+12 -2
View File
@@ -43,12 +43,16 @@ prog/weavewait/weavewait
prog/weavewait/weavewait_noop
prog/weavewait/weavewait_nomcast
prog/weaveutil/weaveutil
prog/*/Dockerfile.weaveworks
prog/kube-peers/kube-peers
prog/weave-kube/kube-peers
prog/weave-npc/weave-npc
prog/plugin/plugin
testing/cover/cover
testing/runner/runner
releases
.*.uptodate
weave.tar.gz
weave*.tar.gz
prog/weaveexec/weave
prog/weaveexec/weavehosts
prog/weaveexec/weaveproxy
@@ -57,9 +61,15 @@ prog/weaveexec/weavewait_noop
prog/weaveexec/weavewait_nomcast
prog/weaveexec/sigproxy
prog/weaveexec/weaveutil
prog/weaveexec/docker*.tgz
prog/weaveexec/docker*
Vagrantfile.local
test/tls/tls
test/tls/*.pem
test/coverage
test/coverage.*
*qemu-*-static
terraform.tfstate
terraform.tfstate.backup
# Website
site-build
+51 -3
View File
@@ -61,9 +61,6 @@
[submodule "vendor/github.com/hashicorp/go-cleanhttp"]
path = vendor/github.com/hashicorp/go-cleanhttp
url = http://github.com/hashicorp/go-cleanhttp
[submodule "vendor/github.com/appc/cni"]
path = vendor/github.com/appc/cni
url = https://github.com/appc/cni
[submodule "vendor/github.com/coreos/go-iptables"]
path = vendor/github.com/coreos/go-iptables
url = https://github.com/coreos/go-iptables
@@ -76,3 +73,54 @@
[submodule "vendor/github.com/aws/aws-sdk-go"]
path = vendor/github.com/aws/aws-sdk-go
url = https://github.com/aws/aws-sdk-go
[submodule "vendor/golang.org/x/sys"]
path = vendor/golang.org/x/sys
url = https://go.googlesource.com/sys
[submodule "vendor/github.com/beorn7/perks"]
path = vendor/github.com/beorn7/perks
url = https://github.com/beorn7/perks
[submodule "vendor/github.com/prometheus/procfs"]
path = vendor/github.com/prometheus/procfs
url = https://github.com/prometheus/procfs
[submodule "vendor/github.com/prometheus/client_golang"]
path = vendor/github.com/prometheus/client_golang
url = https://github.com/prometheus/client_golang
[submodule "vendor/github.com/prometheus/client_model"]
path = vendor/github.com/prometheus/client_model
url = https://github.com/prometheus/client_model
[submodule "vendor/github.com/prometheus/common"]
path = vendor/github.com/prometheus/common
url = https://github.com/prometheus/common
[submodule "vendor/github.com/golang/protobuf"]
path = vendor/github.com/golang/protobuf
url = https://github.com/golang/protobuf
[submodule "vendor/github.com/matttproud/golang_protobuf_extensions"]
path = vendor/github.com/matttproud/golang_protobuf_extensions
url = https://github.com/matttproud/golang_protobuf_extensions
[submodule "vendor/k8s.io/client-go"]
path = vendor/k8s.io/client-go
url = https://github.com/kubernetes/client-go
[submodule "vendor/github.com/pkg/errors"]
path = vendor/github.com/pkg/errors
url = https://github.com/pkg/errors
[submodule "vendor/github.com/spf13/cobra"]
path = vendor/github.com/spf13/cobra
url = https://github.com/spf13/cobra
[submodule "vendor/github.com/spf13/plag"]
path = vendor/github.com/spf13/plag
url = https://github.com/spf13/pflag
[submodule "vendor/github.com/spf13/pflag"]
path = vendor/github.com/spf13/pflag
url = https://github.com/spf13/pflag
[submodule "vendor/github.com/mgutz/ansi"]
path = vendor/github.com/mgutz/ansi
url = https://github.com/mgutz/ansi
[submodule "vendor/github.com/estesp/manifest-tool"]
path = vendor/github.com/estesp/manifest-tool
url = https://github.com/estesp/manifest-tool
[submodule "vendor/github.com/weaveworks/common"]
path = vendor/github.com/weaveworks/common
url = https://github.com/weaveworks/common
[submodule "vendor/github.com/containernetworking/cni"]
path = vendor/github.com/containernetworking/cni
url = https://github.com/containernetworking/cni
+27
View File
@@ -0,0 +1,27 @@
# IMPORTANT: Please only use GLOBs to ignore files and directories.
# Do not lint the below bash scripts in Weave Net, in order to
# avoid breaking the build on make lint:
bin/circle-deploy-issues
bin/circle-deploy-master
bin/circle-teardown-pre
bin/circle-test-teardown
bin/circle-test-unit
bin/install-wordepress
bin/multiweave
bin/publish-site
bin/release
build/build.sh
prog/weave-kube/launch.sh
prog/weaveexec/symlink
test/*_test.sh
test/600_proxy_docker_py.sh
test/assert.sh
test/config.sh
test/gce.sh
test/gen_coverage_reports.sh
test/run_all.sh
test/sanity_check.sh
test/setup.sh
vendor/*.sh
weave
+1
View File
@@ -0,0 +1 @@
2.3.4
+239 -2
View File
@@ -1,14 +1,251 @@
## Release 1.9.8
Bug fixes and minor improvements
* Fix weave-npc blocking NodePort and any other non-local access #3011,#3014
* Fix bug where IPAM would duplicate a fixed IP address assigned via Docker plugin #3003,#3010
[Full list of changes](https://github.com/weaveworks/weave/milestone/56?closed=1).
## Release 1.9.7
This is identical to 1.9.6 with one additional bug-fix:
* weave-npc would block everything if `kubelet --hostname-override` was used #2995,#2996
## Release 1.9.6
Bug fixes and minor improvements
* Ensure that Kubernetes pods can contact a service implemented within
the same pod, by turning on "hairpin mode". This is required because
of a quiet change between Kubernetes 1.5 and 1.6. #2993
* Network Policy Controller (`weave-npc`) now checks local addresses
only, so it doesn't interfere with cross-cluster traffic. It should
be more efficient too #2622,#2973,#2979
* Stop reporting back to Kubernetes any issues encountered when
deleting a pod's network interface. This is required because
of a quiet change between Kubernetes 1.5 and 1.6. #2921,#2928
* Fixed an issue whereby `weave-npc` couldn't start because one
`ipset` was referring to another one and could not be destroyed #2915,#2949
* Improved the code which checks whether the kernel supports `ipset` #2934,#2935
* `weave-npc` now creates ipsets with only valid xml characters in the
name #2958,#2959
Build and Testing
* In build container use cross-compilers from debian package
repository, so they match other components #2940
* Pin the version of the linting tool `shfmt` so the set of things it
checks is stable #2987
* Fix lint error in script that runs smoke-tests #2962
* Moved website publishing from Wordpress to Netlify #2986
[Full list of changes](https://github.com/weaveworks/weave/milestone/55?closed=1).
## Release 1.9.5
Bug fixes and minor improvements
* Improve log messages generated if "hairpin" conditions are detected,
to make clear which kind is likely to cause problems #2808/#2926
* Filter out IPv6 peer addresses from Kubernetes; Weave Net currently
only supports IPv4 #2904/#2912
* Fix rare crash during initialization of weave-kube #2893/#2892
* Include overlay and encryption modes in checkpoint reports, in case
this is relevant to a version upgrade #2771/#2907
Build and Testing
* Ensure CI build can run gcloud tools #2887
* Prevent kubeadm from upgrading Kubernetes if we are trying to test an older version #2886
* Upgrade build scripts to support Kubernetes 1.6 #2880
[Full list of changes](https://github.com/weaveworks/weave/milestone/54?closed=1).
## Release 1.9.4
Bug fixes and minor improvements
* Support Kubernetes 1.6 by creating a new DaemonSet #2777,#2801
* Support Kubernetes 1.6 by allowing CNI callers to send a
network-delete request for a container that is not running or has
never been attached to the network #2850
* Leave non-weave ipsets alone in Network Policy Controller (e.g. when
running Weave Net alonside keepalived-vip) #2751,#2846
* Fix various small issues revealed by 'staticcheck' tool #2843,#2857
* Avoid leaving 'defunct' processes when weave-kube container restarts #2836,#2845
* When using the CNI plugin with a non-standard network configuration
file, the weave bridge could get the same IP as a container, if
'weave expose' hadn't run at that point #2839,#2856
Build and Testing
* Check that no defunct processes remain after each test #2852
* Update build and test scripts to work with Kubernetes 1.6 beta #2851
[Full list of changes](https://github.com/weaveworks/weave/milestone/53?closed=1).
## Release 1.9.3
Bug fixes and minor improvements
* Fixed a race condition in Fast Datapath encrypted connections which could lead Weave Net to crash: #2824, #2825.
## Release 1.9.2
Bug fixes and minor improvements
* Fix a weave-kube bug when `br_netfilter` or `xt_set` module is compiled into
kernel #2820/#2821
* Detect the absence of the required `xt_set` kernel module #2821
## Release 1.9.1
Bug fixes and minor improvements
* Fix a race condition when the Weave Net container is restarted
which could allow a new container to be allocated the same IP
address as an existing one #2784,#2787
* Handle the message type received when a pod has been deleted during
Kubernetes api-server fail-over #2772,#2773
* Make weave-kube work with `dockerd --iptables=false` #2726
* Ensure we have the right kernel modules loaded for Network Policy in weave-kube #2819
* Reference-count addresses in Network Policy Controller, to avoid
errors when updates come in an unexpected order #2792,#2795
* Allow the soft connection limit to be raised in weave-kube, so
larger clusters can be created #2781
* WeaveDNS was incorrectly case-sensitive for reverse DNS lookups #2817,#2818
Build and Testing
* Scripts to create VMs to run automated tests were rewritten to use
Terraform and Ansible, to make it much easier to test with different
versions of components such as Docker and Kubernetes #2647,#2694,#2775,#2796
* Upgrade to latest Weaveworks common build-tools #2780
* Improve encryption tests #2793
* Update vishvananda/netlink library to bring in changes we had previously forked #2790
* Slight change to the build container to avoid permission errors and slow builds #2761,#2802
## Release 1.9.0
Highlights:
* Encryption is now available for Fast Datapath connections, which
greatly improves the performance. #1644,#2687
* We now build images for Intel/AMD 64-bit, ARM and ARM 64-bit. #2713
* Weave Net Docker images are now labelled with description, vendor, etc. #2712
* `weave status connections` now shows the MTU #2389,#2663
* CNI plugin is now a stand-alone binary that does not depend on Docker #2594,#2662
* Embedded docker client updated to version 1.10.3 #2395
**NOTE:** The move to multi-architecture required that we update the
embedded Docker client, and this has the effect that this release of
Weave Net will not work with Docker installations older than
1.10.
[Full list of changes](https://github.com/weaveworks/weave/issues?q=milestone%3A1.9.0).
## Release 1.8.2
Bug fixes and minor improvements
* Fixed a bug where looping flows were installed which caused high CPU
usage #2650, #2674
* Fixed a bug where Kubernetes master could not contact pods #2673, #2683
* Fixed a bug where weave-kube was crashing in a loop due to invalid
Weave bridge state #2657
* Fixed a bug where iptables NAT rules were not appended due to
"temporary unavailable" iptables error #2679
* Added a detection of enabling the hairpin mode on the Weave bridge port
which caused installation of looping flows #2674
* Added a detection of overlaps between Weave and the host IP address
ranges when launching weave-kube #2669, #2672
* Added logging of connections blocked by weave-npc #2546, #2573
More details in the [change log](https://github.com/weaveworks/weave/issues?q=milestone%3A1.8.2).
## Release 1.8.1
Bug fixes and minor improvements
* Fixed weave-npc crash from Succeeded/Failed pods #2632,#2658
* Fixed occasional failure to create Weave bridge on node reboot
#2617,#2637
* Fixed a bug where weave-kube would fail to install when run with
unrelease snapshot builds #2642
* Improved conformance to CNI spec by not releasing IP addresses when
a container dies #2643
* Improved troubleshooting of install failure by creating CNI config
after Weave Net is up #2570
* "up to date" shown even when the version check was blocked by
firewall #2537,#2565,#2645
* "Unable to claim" message on re-launching Weave after using CNI
#2548,#2577
* Eliminated spurious IP reclaim operations when IPAM was disabled
#2567,#2644
* Include `jq` tool in our build VM configuration #2656
## Release 1.8.0
Highlights:
* Exposed network policy controller Prometheus metrics
weaveworks/weave-npc#23, #2595, #2549
* Exposed router Prometheus metrics #2535, #2547, #2523, #2579, #2578,
#2568, #2560, #2561
More details in the [change log](https://github.com/weaveworks/weave/issues?q=milestone%3A1.8.0).
## Release 1.7.2
Bug fixes and minor improvements
* Fixed an error where the Docker plugin could fail to attach a
container with a `bridge "weave" not present` error #2540/#2541
* Fixed `cannot connect to itself` panic on weave launch #2527/#2543
* Fixed inferred initial peer count when target peers includes self
#2481/#2543
* Fixed compilation on Raspberry Pi #2506/#2538
## Release 1.7.1
Bug fixes and minor improvements
* Added utility to recover container addresses without asking Docker #2531
* Improved CI #2274
## Release 1.7.0
Highlights:
* weave-kube - Deploy Weave Net to Kubernetes with a single command
* weave-npc - Kubernetes network policy controller implementation
More details in the [change log](https://github.com/weaveworks/weave/issues?q=milestone%3A1.7.0).
## Release 1.6.2
Bug fixes and minor improvements
* Fixed hang after stopping and restarting on Docker 1.12 #2469/#2502
* Avoid an error on Google container images by checking for tx offload support #2504
* Fixed an issue where the supplied peer list could be ignored when restarting after failure #2503/#2509
* Check for empty peer name on launch #2495/#2501
More details in the [change log](https://github.com/weaveworks/weave/issues?q=milestone%3A1.6.2).
## Release 1.6.1
Bug fixes and minor improvements
* `weave ps` was occasionally failing to list allocated addresses of containers #2388/#2418
* `weave ps` was occasionally failing to list allocated addresses of containers #2388/#2418/#2445
* `weave launch[-router]` on 4.2 kernel would appear to succeed even if the fast datapath VXLAN UDP port was in use by a different process #2375/#2474
* Launching the proxy would fail when the Docker daemon could not be detected #2457/#2424
* The CNI plugin did not work with Apache Mesos #2394/#2442
* Router stopped working after a restart in the AWSVPC mode #2381/#2409
* Router crashed when the Docker API endpoint parameter was explicitly set to empty #2421/#2467
* `weave ps` returned no error when the router was down #2445
* The CNI plugin did not work on recent versions of Docker for Mac #2434/#2442
* The CNI plugin assigns an IP to the bridge if necessary, which avoids failures if `weave expose` has not run yet #2471
* Distinguish peer name collisions from attempts to connect to self in logs #2460
+3
View File
@@ -0,0 +1,3 @@
DOCKER_VERSION=1.11.2
KUBERNETES_VERSION=1.5.2
KUBERNETES_CNI_VERSION=0.3.0.1
+242 -44
View File
@@ -1,7 +1,5 @@
PUBLISH=publish_weave publish_weaveexec publish_plugin
.DEFAULT: all
.PHONY: all exes testrunner update tests lint publish $(PUBLISH) clean clean-bin prerequisites build run-smoketests
.PHONY: all exes testrunner update tests lint publish-one-arch $(PUBLISH) clean clean-bin prerequisites build run-smoketests
# If you can use docker without being root, you can do "make SUDO="
SUDO=$(shell docker info >/dev/null 2>&1 || echo "sudo -E")
@@ -10,43 +8,130 @@ RM=--rm
RUN_FLAGS=-ti
COVERAGE=
DOCKERHUB_USER=weaveworks
WEAVE_VERSION=git-$(shell git rev-parse --short=12 HEAD)
# This specifies the architecture we're building for
ARCH?=amd64
# We're using QEMU to be able to build Docker images for other architectures
# from amd64 machines.
QEMU_VERSION=v2.7.0
# A list of all supported architectures here. Should be named as Go is naming platforms
# All supported architectures must have an "ifeq" block below that customizes the parameters
ALL_ARCHITECTURES=amd64 arm arm64
ML_PLATFORMS=linux/amd64,linux/arm,linux/arm64
ifeq ($(ARCH),amd64)
# The architecture to use when downloading the docker binary
WEAVEEXEC_DOCKER_ARCH?=x86_64
# The name of the alpine baseimage to use as the base for weave images
ALPINE_BASEIMAGE?=alpine:3.4
# The extension for the made images
# Specifying none means for example weaveworks/weave:latest
ARCH_EXT?=
# The name of the gcc we're using for compiling C code
CC=gcc
# Optional parameters that can be passed when linking C code into the Go binary
CGO_LDFLAGS=
endif
ifeq ($(ARCH),arm)
# The architecture to use when downloading the docker binary
WEAVEEXEC_DOCKER_ARCH?=armel
# Using the (semi-)official alpine image
ALPINE_BASEIMAGE?=armhf/alpine:3.4
# arm images have the -arm suffix, for instance weaveworks/weave-arm:latest
ARCH_EXT?=-arm
# The name of the gcc binary
CC=arm-linux-gnueabihf-gcc
# The architecture name to use when downloading a prebuilt QEMU binary
QEMUARCH=arm
# In the weaveworks/build image; libpcap libraries for arm are placed here
# Tell the gcc linker to search for libpcap here
CGO_LDFLAGS="-L/usr/local/lib/$(CC)"
endif
ifeq ($(ARCH),arm64)
# Use the arm 32-bit docker client variant
WEAVEEXEC_DOCKER_ARCH?=armel
# Using the (semi-)official alpine image
ALPINE_BASEIMAGE?=aarch64/alpine:3.5
# arm64 images have the -arm64 suffix, for instance weaveworks/weave-arm64:latest
ARCH_EXT?=-arm64
# The name of the gcc binary
CC=aarch64-linux-gnu-gcc
# The architecture name to use when downloading a prebuilt QEMU binary
QEMUARCH=aarch64
# In the weaveworks/build image; libpcap libraries for arm64 are placed here
# Tell the gcc linker to search for libpcap here
CGO_LDFLAGS="-L/usr/local/lib/$(CC)"
endif
# The name of the user that this Makefile should produce image artifacts for. Can/should be overridden
DOCKERHUB_USER?=weaveworks
# The default version that's chosen when pushing the images. Can/should be overridden
WEAVE_VERSION?=git-$(shell git rev-parse --short=12 HEAD)
# Paths to all relevant binaries that should be compiled
WEAVER_EXE=prog/weaver/weaver
WEAVEPROXY_EXE=prog/weaveproxy/weaveproxy
SIGPROXY_EXE=prog/sigproxy/sigproxy
KUBEPEERS_EXE=prog/kube-peers/kube-peers
WEAVENPC_EXE=prog/weave-npc/weave-npc
WEAVEWAIT_EXE=prog/weavewait/weavewait
WEAVEWAIT_NOOP_EXE=prog/weavewait/weavewait_noop
WEAVEWAIT_NOMCAST_EXE=prog/weavewait/weavewait_nomcast
WEAVEUTIL_EXE=prog/weaveutil/weaveutil
PLUGIN_EXE=prog/plugin/plugin
RUNNER_EXE=tools/runner/runner
MANIFEST_TOOL_DIR=vendor/github.com/estesp/manifest-tool
MANIFEST_TOOL_EXE=$(MANIFEST_TOOL_DIR)/manifest-tool
TEST_TLS_EXE=test/tls/tls
EXES=$(WEAVER_EXE) $(SIGPROXY_EXE) $(WEAVEPROXY_EXE) $(WEAVEWAIT_EXE) $(WEAVEWAIT_NOOP_EXE) $(WEAVEWAIT_NOMCAST_EXE) $(WEAVEUTIL_EXE) $(PLUGIN_EXE) $(TEST_TLS_EXE)
# All binaries together in a list
EXES=$(WEAVER_EXE) $(SIGPROXY_EXE) $(KUBEPEERS_EXE) $(WEAVENPC_EXE) $(WEAVEPROXY_EXE) $(WEAVEWAIT_EXE) $(WEAVEWAIT_NOOP_EXE) $(WEAVEWAIT_NOMCAST_EXE) $(WEAVEUTIL_EXE) $(PLUGIN_EXE) $(RUNNER_EXE) $(TEST_TLS_EXE) $(MANIFEST_TOOL_EXE)
# These stamp files are used to mark the current state of the build; whether an image has been built or not
BUILD_UPTODATE=.build.uptodate
WEAVER_UPTODATE=.weaver.uptodate
WEAVEEXEC_UPTODATE=.weaveexec.uptodate
PLUGIN_UPTODATE=.plugin.uptodate
WEAVER_UPTODATE=.weaver$(ARCH_EXT).uptodate
WEAVEEXEC_UPTODATE=.weaveexec$(ARCH_EXT).uptodate
PLUGIN_UPTODATE=.plugin$(ARCH_EXT).uptodate
WEAVEKUBE_UPTODATE=.weavekube$(ARCH_EXT).uptodate
WEAVENPC_UPTODATE=.weavenpc$(ARCH_EXT).uptodate
WEAVEDB_UPTODATE=.weavedb.uptodate
IMAGES_UPTODATE=$(WEAVER_UPTODATE) $(WEAVEEXEC_UPTODATE) $(PLUGIN_UPTODATE) $(WEAVEDB_UPTODATE)
IMAGES_UPTODATE=$(WEAVER_UPTODATE) $(WEAVEEXEC_UPTODATE) $(PLUGIN_UPTODATE) $(WEAVEKUBE_UPTODATE) $(WEAVENPC_UPTODATE)
WEAVER_IMAGE=$(DOCKERHUB_USER)/weave
WEAVEEXEC_IMAGE=$(DOCKERHUB_USER)/weaveexec
PLUGIN_IMAGE=$(DOCKERHUB_USER)/plugin
BUILD_IMAGE=$(DOCKERHUB_USER)/weavebuild
# The names of the images. Note that the images for other architectures than amd64 have a suffix in the image name.
WEAVER_IMAGE=$(DOCKERHUB_USER)/weave$(ARCH_EXT)
WEAVEEXEC_IMAGE=$(DOCKERHUB_USER)/weaveexec$(ARCH_EXT)
PLUGIN_IMAGE=$(DOCKERHUB_USER)/plugin$(ARCH_EXT)
WEAVEKUBE_IMAGE=$(DOCKERHUB_USER)/weave-kube$(ARCH_EXT)
WEAVENPC_IMAGE=$(DOCKERHUB_USER)/weave-npc$(ARCH_EXT)
BUILD_IMAGE=weaveworks/weavebuild
WEAVEDB_IMAGE=$(DOCKERHUB_USER)/weavedb
IMAGES=$(WEAVER_IMAGE) $(WEAVEEXEC_IMAGE) $(PLUGIN_IMAGE) $(WEAVEDB_IMAGE)
IMAGES=$(WEAVER_IMAGE) $(WEAVEEXEC_IMAGE) $(PLUGIN_IMAGE) $(WEAVEKUBE_IMAGE) $(WEAVENPC_IMAGE) $(WEAVEDB_IMAGE)
WEAVE_EXPORT=weave.tar.gz
PUBLISH=publish_weave publish_weaveexec publish_plugin publish_weave-kube publish_weave-npc
PUSH_ML=push_ml_weave push_ml_weaveexec push_ml_plugin push_ml_weave-kube push_ml_weave-npc
WEAVEEXEC_DOCKER_VERSION=1.6.2
DOCKER_DISTRIB=prog/weaveexec/docker-$(WEAVEEXEC_DOCKER_VERSION).tgz
DOCKER_DISTRIB_URL=https://get.docker.com/builds/Linux/x86_64/docker-$(WEAVEEXEC_DOCKER_VERSION).tgz
WEAVE_EXPORT=weave$(ARCH_EXT).tar.gz
DOCKER_VERSION=1.10.3
DOCKER_DISTRIB=prog/weaveexec/docker-$(DOCKER_VERSION).tgz
DOCKER_DISTRIB_URL=https://get.docker.com/builds/Linux/$(WEAVEEXEC_DOCKER_ARCH)/docker-$(DOCKER_VERSION).tgz
NETGO_CHECK=@strings $@ | grep cgo_stub\\\.go >/dev/null || { \
rm $@; \
echo "\nYour go standard library was built without the 'netgo' build tag."; \
@@ -55,7 +140,10 @@ NETGO_CHECK=@strings $@ | grep cgo_stub\\\.go >/dev/null || { \
echo " sudo go install -tags netgo std"; \
false; \
}
BUILD_FLAGS=-i -ldflags "-extldflags \"-static\" -X main.version=$(WEAVE_VERSION)" -tags netgo
# The flags we are passing to go build. -extldflags -static for making a static binary,
# -linkmode external for linking external C libraries into the binary, -X main.version for telling the
# Go binary which version it is, -tags netgo for enforcing the native Go DNS resolver
BUILD_FLAGS=-i -ldflags "-linkmode external -extldflags -static -X main.version=$(WEAVE_VERSION)" -tags netgo
PACKAGE_BASE=$(shell go list -e ./)
@@ -65,10 +153,14 @@ testrunner: $(RUNNER_EXE) $(TEST_TLS_EXE)
$(WEAVER_EXE) $(WEAVEPROXY_EXE) $(WEAVEUTIL_EXE): common/*.go common/*/*.go net/*.go net/*/*.go
$(WEAVER_EXE): router/*.go ipam/*.go ipam/*/*.go db/*.go nameserver/*.go prog/weaver/*.go
$(WEAVEPROXY_EXE): proxy/*.go prog/weaveproxy/*.go
$(WEAVEUTIL_EXE): prog/weaveutil/*.go net/*.go
$(WEAVEUTIL_EXE): prog/weaveutil/*.go net/*.go plugin/net/*.go plugin/ipam/*.go db/*.go
$(SIGPROXY_EXE): prog/sigproxy/*.go
$(KUBEPEERS_EXE): prog/kube-peers/*.go
$(WEAVENPC_EXE): prog/weave-npc/*.go npc/*.go npc/*/*.go
$(PLUGIN_EXE): prog/plugin/*.go plugin/*/*.go api/*.go common/*.go common/docker/*.go net/*.go
$(TEST_TLS_EXE): test/tls/*.go
$(RUNNER_EXE): tools/runner/*.go
$(MANIFEST_TOOL_EXE): $(MANIFEST_TOOL_DIR)/*.go
$(WEAVEWAIT_NOOP_EXE): prog/weavewait/*.go
$(WEAVEWAIT_EXE): prog/weavewait/*.go net/*.go
$(WEAVEWAIT_NOMCAST_EXE): prog/weavewait/*.go net/*.go
@@ -77,14 +169,18 @@ lint: tools/.git
ifeq ($(BUILD_IN_CONTAINER),true)
# This make target compiles all binaries inside of the weaveworks/build container
# It bind-mounts the source into the container and passes all important variables
exes $(EXES) tests lint: $(BUILD_UPTODATE)
git submodule update --init
# Containernetworking has another copy of vishvananda/netlink which leads to duplicate definitions
-@rm -r vendor/github.com/containernetworking/cni/vendor
@mkdir -p $(shell pwd)/.pkg
$(SUDO) docker run $(RM) $(RUN_FLAGS) \
-v $(shell pwd):/go/src/github.com/weaveworks/weave \
-v $(shell pwd)/.pkg:/go/pkg \
-e GOARCH -e GOOS -e CIRCLECI -e CIRCLE_BUILD_NUM -e CIRCLE_NODE_TOTAL -e CIRCLE_NODE_INDEX -e COVERDIR -e SLOW \
$(BUILD_IMAGE) COVERAGE=$(COVERAGE) WEAVE_VERSION=$(WEAVE_VERSION) $@
-e GOARCH=$(ARCH) -e CGO_ENABLED=1 -e GOOS=linux -e CIRCLECI -e CIRCLE_BUILD_NUM -e CIRCLE_NODE_TOTAL -e CIRCLE_NODE_INDEX -e COVERDIR -e SLOW -e DEBUG \
$(BUILD_IMAGE) COVERAGE=$(COVERAGE) WEAVE_VERSION=$(WEAVE_VERSION) CC=$(CC) QEMUARCH=$(QEMUARCH) CGO_LDFLAGS=$(CGO_LDFLAGS) $@
else
@@ -99,7 +195,7 @@ else
endif
$(NETGO_CHECK)
$(WEAVEUTIL_EXE):
$(WEAVEUTIL_EXE) $(KUBEPEERS_EXE) $(WEAVENPC_EXE):
go build $(BUILD_FLAGS) -o $@ ./$(@D)
$(NETGO_CHECK)
@@ -113,26 +209,48 @@ $(WEAVEWAIT_NOMCAST_EXE):
# These programs need a separate rule as they fail the netgo check in
# the main build stanza due to not importing net package
$(SIGPROXY_EXE) $(TEST_TLS_EXE) $(WEAVEWAIT_NOOP_EXE):
$(SIGPROXY_EXE) $(TEST_TLS_EXE) $(WEAVEWAIT_NOOP_EXE) $(RUNNER_EXE) $(MANIFEST_TOOL_EXE):
go build $(BUILD_FLAGS) -o $@ ./$(@D)
tests:
./tools/test -no-go-get
./tools/test -no-go-get -netgo -timeout 8m
lint:
./tools/lint -nocomment -notestpackage .
./tools/lint -nocomment -notestpackage
endif
# This rule makes sure the build image is up-to-date.
# It also makes sure the multiarch hooks are reqistered in the kernel so the QEMU emulation works
$(BUILD_UPTODATE): build/*
$(SUDO) docker build -t $(BUILD_IMAGE) build/
$(SUDO) docker run --rm --privileged multiarch/qemu-user-static:register --reset
touch $@
$(WEAVER_UPTODATE): prog/weaver/Dockerfile $(WEAVER_EXE)
$(SUDO) DOCKER_HOST=$(DOCKER_HOST) docker build -t $(WEAVER_IMAGE) prog/weaver
# Creates the Dockerfile.your-user-here file from the template
# Also replaces all placeholders with real values
# If the architecture is amd64, it deletes all CROSS_BUILD lines
# but otherwise, it only removes the "CROSS_BUILD_" placeholder and downloads QEMU
%/Dockerfile.$(DOCKERHUB_USER): %/Dockerfile.template
echo "DOCKERHUB_USER|$(DOCKERHUB_USER)|g;s|ARCH_EXT|$(ARCH_EXT)|g;s|ALPINE_BASEIMAGE|$(ALPINE_BASEIMAGE)|g;s|QEMUARCH|$(QEMUARCH)"
sed -e "s|DOCKERHUB_USER|$(DOCKERHUB_USER)|g;s|ARCH_EXT|$(ARCH_EXT)|g;s|ALPINE_BASEIMAGE|$(ALPINE_BASEIMAGE)|g;s|QEMUARCH|$(QEMUARCH)|g" $^ > $@
ifeq ($(ARCH),amd64)
# When building "normally" for amd64, remove the whole line, it has no part in the amd64 image
sed -i "/CROSS_BUILD_/d" $@
else
# When cross-building, only the placeholder "CROSS_BUILD_" should be removed
# Register /usr/bin/qemu-ARCH-static as the handler for ARM binaries in the kernel
curl -sSL https://github.com/multiarch/qemu-user-static/releases/download/$(QEMU_VERSION)/x86_64_qemu-$(QEMUARCH)-static.tar.gz | tar -xz -C $(shell dirname $@)
cd $(shell dirname $@) && sha256sum -c $(shell pwd)/build/shasums/qemu-$(QEMUARCH)-static.sha256sum
sed -i "s/CROSS_BUILD_//g" $@
endif
# The targets below builds the weave images
$(WEAVER_UPTODATE): prog/weaver/Dockerfile.$(DOCKERHUB_USER) $(WEAVER_EXE) $(WEAVEEXEC_UPTODATE)
$(SUDO) DOCKER_HOST=$(DOCKER_HOST) docker build -f prog/weaver/Dockerfile.$(DOCKERHUB_USER) -t $(WEAVER_IMAGE) prog/weaver
touch $@
$(WEAVEEXEC_UPTODATE): prog/weaveexec/Dockerfile prog/weaveexec/symlink $(DOCKER_DISTRIB) weave $(SIGPROXY_EXE) $(WEAVEPROXY_EXE) $(WEAVEWAIT_EXE) $(WEAVEWAIT_NOOP_EXE) $(WEAVEWAIT_NOMCAST_EXE) $(WEAVEUTIL_EXE)
$(WEAVEEXEC_UPTODATE): prog/weaveexec/Dockerfile.$(DOCKERHUB_USER) prog/weaveexec/symlink $(DOCKER_DISTRIB) weave $(SIGPROXY_EXE) $(WEAVEPROXY_EXE) $(WEAVEWAIT_EXE) $(WEAVEWAIT_NOOP_EXE) $(WEAVEWAIT_NOMCAST_EXE) $(WEAVEUTIL_EXE)
cp weave prog/weaveexec/weave
cp $(SIGPROXY_EXE) prog/weaveexec/sigproxy
cp $(WEAVEPROXY_EXE) prog/weaveexec/weaveproxy
@@ -140,49 +258,101 @@ $(WEAVEEXEC_UPTODATE): prog/weaveexec/Dockerfile prog/weaveexec/symlink $(DOCKER
cp $(WEAVEWAIT_NOOP_EXE) prog/weaveexec/weavewait_noop
cp $(WEAVEWAIT_NOMCAST_EXE) prog/weaveexec/weavewait_nomcast
cp $(WEAVEUTIL_EXE) prog/weaveexec/weaveutil
cp $(DOCKER_DISTRIB) prog/weaveexec/docker.tgz
$(SUDO) DOCKER_HOST=$(DOCKER_HOST) docker build -t $(WEAVEEXEC_IMAGE) prog/weaveexec
tar -xf $(DOCKER_DISTRIB) usr/local/bin/docker -O > prog/weaveexec/docker
chmod +x prog/weaveexec/docker
$(SUDO) DOCKER_HOST=$(DOCKER_HOST) docker build -f prog/weaveexec/Dockerfile.$(DOCKERHUB_USER) -t $(WEAVEEXEC_IMAGE) prog/weaveexec
touch $@
$(PLUGIN_UPTODATE): prog/plugin/Dockerfile $(PLUGIN_EXE) $(WEAVEEXEC_UPTODATE)
$(SUDO) docker build -t $(PLUGIN_IMAGE) prog/plugin
$(PLUGIN_UPTODATE): prog/plugin/Dockerfile.$(DOCKERHUB_USER) $(PLUGIN_EXE) $(WEAVER_UPTODATE)
$(SUDO) docker build -f prog/plugin/Dockerfile.$(DOCKERHUB_USER) -t $(PLUGIN_IMAGE) prog/plugin
touch $@
$(WEAVEKUBE_UPTODATE): prog/weave-kube/Dockerfile.$(DOCKERHUB_USER) prog/weave-kube/launch.sh $(KUBEPEERS_EXE) $(WEAVER_UPTODATE)
cp $(KUBEPEERS_EXE) prog/weave-kube/
$(SUDO) docker build -f prog/weave-kube/Dockerfile.$(DOCKERHUB_USER) -t $(WEAVEKUBE_IMAGE) prog/weave-kube
touch $@
$(WEAVENPC_UPTODATE): prog/weave-npc/Dockerfile.$(DOCKERHUB_USER) $(WEAVENPC_EXE) prog/weave-npc/ulogd.conf
$(SUDO) docker build -f prog/weave-npc/Dockerfile.$(DOCKERHUB_USER) -t $(WEAVENPC_IMAGE) prog/weave-npc
touch $@
$(WEAVEDB_UPTODATE): prog/weavedb/Dockerfile
$(SUDO) docker build -t $(WEAVEDB_IMAGE) prog/weavedb
touch $@
$(WEAVE_EXPORT): $(IMAGES_UPTODATE)
$(WEAVE_EXPORT): $(IMAGES_UPTODATE) $(WEAVEDB_UPTODATE)
$(SUDO) DOCKER_HOST=$(DOCKER_HOST) docker save $(addsuffix :latest,$(IMAGES)) | gzip > $@
$(DOCKER_DISTRIB):
curl -o $(DOCKER_DISTRIB) $(DOCKER_DISTRIB_URL)
cd $(shell dirname $@) && sha256sum -c $(shell pwd)/build/shasums/docker-tgz-$(WEAVEEXEC_DOCKER_ARCH).sha256sum
tools/.git:
tools/.git $(MANIFEST_TOOL_DIR)/.git:
git submodule update --init
$(RUNNER_EXE): tools/.git
make -C tools/runner
# CODE FOR PUBLISHING THE IMAGES
# This target first runs "make publish" for each architecture
# Then it pushes the manifest lists
publish: $(addprefix sub-publish-,$(ALL_ARCHITECTURES)) $(WEAVEDB_UPTODATE)
$(MAKE) DOCKER_HOST=$(DOCKER_HOST) DOCKERHUB_USER=$(DOCKERHUB_USER) WEAVE_VERSION=$(WEAVE_VERSION) UPDATE_LATEST=$(UPDATE_LATEST) $(PUSH_ML)
ifeq ($(PUBLISH_WEAVEDB),true)
$(SUDO) DOCKER_HOST=$(DOCKER_HOST) docker push $(DOCKERHUB_USER)/weavedb:latest
endif
sub-publish-%:
$(MAKE) ARCH=$* DOCKER_HOST=$(DOCKER_HOST) clean-bin
$(MAKE) ARCH=$* DOCKER_HOST=$(DOCKER_HOST) DOCKERHUB_USER=$(DOCKERHUB_USER) WEAVE_VERSION=$(WEAVE_VERSION) UPDATE_LATEST=$(UPDATE_LATEST) $(IMAGES_UPTODATE)
$(MAKE) ARCH=$* DOCKER_HOST=$(DOCKER_HOST) DOCKERHUB_USER=$(DOCKERHUB_USER) WEAVE_VERSION=$(WEAVE_VERSION) UPDATE_LATEST=$(UPDATE_LATEST) publish-one-arch
publish-one-arch: $(PUBLISH)
# This rule handles the pushing of the built images
$(PUBLISH): publish_%: $(IMAGES_UPTODATE)
$(SUDO) DOCKER_HOST=$(DOCKER_HOST) docker tag $(DOCKERHUB_USER)/$* $(DOCKERHUB_USER)/$*:$(WEAVE_VERSION)
# Tag :latest with the real version
$(SUDO) DOCKER_HOST=$(DOCKER_HOST) docker tag $(DOCKERHUB_USER)/$*$(ARCH_EXT) $(DOCKERHUB_USER)/$*$(ARCH_EXT):$(WEAVE_VERSION)
# Push the image with the arch suffix for arm and arm64, and without suffix for amd64
$(MAKE) DOCKER_HOST=$(DOCKER_HOST) DOCKERHUB_USER=$(DOCKERHUB_USER) WEAVE_VERSION=$(WEAVE_VERSION) UPDATE_LATEST=$(UPDATE_LATEST) push_$*$(ARCH_EXT)
ifeq ($(ARCH),amd64)
# If the architecture is amd64, add the -amd64 suffix.
$(SUDO) DOCKER_HOST=$(DOCKER_HOST) docker tag $(DOCKERHUB_USER)/$*:$(WEAVE_VERSION) $(DOCKERHUB_USER)/$*-amd64:$(WEAVE_VERSION)
# If the version is latest, tag the -amd64 with latest as well
ifneq ($(UPDATE_LATEST),false)
$(SUDO) DOCKER_HOST=$(DOCKER_HOST) docker tag $(DOCKERHUB_USER)/$*-amd64:$(WEAVE_VERSION) $(DOCKERHUB_USER)/$*-amd64:latest
endif
# Push the image with the -amd64-suffix so BINARY-ARCH-named images exist for all arches, so manifest lists may be made and ARCH is replaceable in scripts
$(MAKE) DOCKER_HOST=$(DOCKER_HOST) DOCKERHUB_USER=$(DOCKERHUB_USER) WEAVE_VERSION=$(WEAVE_VERSION) UPDATE_LATEST=$(UPDATE_LATEST) push_$*-amd64
endif
# This target pushes an image, and if UPDATE_LATEST is anything but false, also updates the latest tag
# It takes one parameter, the image name
push_%:
$(SUDO) DOCKER_HOST=$(DOCKER_HOST) docker push $(DOCKERHUB_USER)/$*:$(WEAVE_VERSION)
ifneq ($(UPDATE_LATEST),false)
$(SUDO) DOCKER_HOST=$(DOCKER_HOST) docker push $(DOCKERHUB_USER)/$*:latest
endif
publish: $(PUBLISH)
ifeq ($(PUBLISH_WEAVEDB),true)
$(SUDO) DOCKER_HOST=$(DOCKER_HOST) docker push $(DOCKERHUB_USER)/weavedb:latest
# This target pushes a manifest list; it takes one parameter, the image name.
# The variable UPDATE_LATEST controls whether it updates the versioned tag and/or the latest tag
$(PUSH_ML): push_ml_%: $(MANIFEST_TOOL_EXE)
ifneq ($(UPDATE_LATEST),latest-only)
$(MANIFEST_TOOL_EXE) push from-args --platforms $(ML_PLATFORMS) --template $(DOCKERHUB_USER)/$*-ARCH:$(WEAVE_VERSION) --target $(DOCKERHUB_USER)/$*:$(WEAVE_VERSION)
endif
ifneq ($(UPDATE_LATEST),false)
# Push the manifest list to :latest as well
$(MANIFEST_TOOL_EXE) push from-args --platforms $(ML_PLATFORMS) --template $(DOCKERHUB_USER)/$*-ARCH:latest --target $(DOCKERHUB_USER)/$*:latest
endif
clean-bin:
-$(SUDO) DOCKER_HOST=$(DOCKER_HOST) docker rmi $(IMAGES)
rm -rf $(EXES) $(IMAGES_UPTODATE) $(WEAVE_EXPORT) .pkg
find prog -type f -name "Dockerfile.*" -not -name "Dockerfile.template" -print | xargs rm -f
find prog -type f -name "*qemu-*" -print | xargs rm -f
rm -rf $(EXES) $(IMAGES_UPTODATE) $(WEAVEDB_UPTODATE) weave*.tar.gz $(DOCKER_DISTRIB) prog/weaveexec/docker .pkg
clean: clean-bin
-$(SUDO) DOCKER_HOST=$(DOCKER_HOST) docker rmi $(BUILD_IMAGE)
rm -rf test/tls/*.pem test/coverage.* test/coverage $(BUILD_UPTODATE)
rm -rf test/tls/*.pem test/coverage.* test/coverage $(BUILD_UPTODATE) $(MANIFEST_TOOL_EXE)
build:
$(SUDO) go clean -i net
@@ -191,3 +361,31 @@ build:
run-smoketests: all testrunner
cd test && ./setup.sh && ./run_all.sh
integration-tests: all testrunner
# Usage:
# $ make \
# NAME="<prefix used to name VMs and other resources>" \
# PROVIDER="<provider among {vagrant|gcp|aws|do}>" \
# NUM_HOSTS="<# test machines>" \
# PLAYBOOK="<filename>" \
# RUNNER_ARGS="<...>" \
# TESTS="<...>" \ # Can be set to only run one or a few tests instead of the full test suite.
# DOCKER_VERSION=<...> \
# KUBERNETES_VERSION=<...> \
# KUBERNETES_CNI_VERSION=<...> \
# <...> # See also run-integration-test.sh for all variables and individual functions.
# integration-tests
#
RUNNER_ARGS="-parallel" ./test/run-integration-tests.sh
# This target is only intended for use in Netlify CI environment for generating preview pages on feature branches and pull requests.
# We need to obtain website repository (checked out under `site-build`) and place `site` directory into the context (`site-build/_weave_net_docs`).
# We then run make in `site-build` and Netlify will publish the output (`site-build/_site`).
netlify-site-preview:
@mkdir -p site-build
@curl --user $(WEBSITE_GITHUB_USER) --silent 'https://codeload.github.com/weaveworks/website-next/tar.gz/$(WEBSITE_BRANCH)' \
| tar --extract --gunzip --directory site-build --strip 1
@cp -r site site-build/_weave_net_docs
@$(MAKE) -C site-build netlify_ensure_install
@$(MAKE) -C site-build BUILD_ENV=netlify
+21 -4
View File
@@ -11,9 +11,11 @@
[Weaveworks](https://www.weave.works) is the company that delivers the most productive way for developers to connect, observe and control
Docker containers.
This repository contains [Weave Net](https://www.weave.works/products/weave-net/), the first product developed by Weaveworks, and with nearly 5 million downloads to date, it enables you to get started with Docker clusters and portable apps in a fraction of the time compared with other solutions.
This repository contains [Weave Net](https://www.weave.works/products/weave-net/), the first product developed by Weaveworks, and with over 8 million downloads to date, it enables you to get started with Docker clusters and portable apps in a fraction of the time compared with other solutions.
Other products from Weaveworks include [Weave Scope](https://www.weave.works/products/weave-scope/), a powerful container monitoring tool that automatically maps Docker containers and their interactions, and [Weave Flux](https://www.weave.works/products/weave-flux/), a microservice router that automates the access of containers as services.
Weaveworks' product [Weave Cloud](https://www.weave.works/solution/cloud/) takes the heavy lifting out of building, integrating and operating open source components, so you don’t have to manage databases, storage and availability.
Weave Cloud is built using these Open Source projects: [Weave Scope](https://www.weave.works/products/weave-scope/), a powerful container monitoring tool that automatically maps Docker containers and their interactions, [Weave Cortex](https://github.com/weaveworks/cortex), a horizontally-scalable version of Prometheus, and [Weave Flux](https://www.weave.works/products/weave-flux/), a continuous deployment tool that works with Kubernetes.
# Weave Net
@@ -21,5 +23,20 @@ Weave Net creates a virtual network that connects Docker containers across multi
Services provided by application containers on the Weave network can be exposed to the outside world, regardless of where they are running. Similarly, existing internal systems can be opened to accept connections from application containers irrespective of their location.
* [Install Weave Net](https://www.weave.works/docs/net/latest/installing-weave/)
* [Find out more about Weave Net](https://www.weave.works/products/weave-net/)
## <a name="help"></a>Getting help
If you have any questions about, feedback for or a problem with Weave Net:
- Read [the Weave Net docs](https://www.weave.works/docs/net/latest/introducing-weave/).
- Invite yourself to the <a href="https://weaveworks.github.io/community-slack/" target="_blank"> #weave-community </a> slack channel.
- Ask a question on the <a href="https://weave-community.slack.com/messages/general/"> #weave-community</a> slack channel.
- Join the <a href="https://www.meetup.com/pro/Weave/"> Weave User Group </a> and get invited to online talks, hands-on training and meetups in your area.
- Send an email to <a href="mailto:weave-users@weave.works">weave-users@weave.works</a>
- <a href="https://github.com/weaveworks/weave/issues/new">File an issue.</a>
Your feedback is always welcome!
##Further Information
* [Installing Weave Net](https://www.weave.works/docs/net/latest/installing-weave/)
* [Weave Net Product Overview](https://www.weave.works/products/weave-net/)
Vendored
+18 -22
View File
@@ -1,40 +1,36 @@
VAGRANTFILE_API_VERSION = "2"
require './vagrant-common.rb'
require File.expand_path(File.join(File.dirname(__FILE__), 'vagrant-common.rb'))
vm_ip = "172.16.0.3" # arbitrary private IP
pkgs = %w(
docker-engine=1.10.2-0~wily
aufs-tools
build-essential
ethtool
iputils-arping
libpcap-dev
git
mercurial
bc
)
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
config.vm.box = "ubuntu/wily64"
config.vm.box = VAGRANT_IMAGE
config.vm.network "private_network", ip: vm_ip
config.vm.provider :virtualbox do |vb|
vb.customize ["modifyvm", :id, "--natdnshostresolver1", "off"]
vb.customize ["modifyvm", :id, "--natdnsproxy1", "off"]
vb.memory = 2048
configure_nat_dns(vb)
end
# Disable default Vagrant shared folder, which we don't need:
config.vm.synced_folder ".", "/vagrant", disabled: true
# Keep Weave Net sources' in sync:
config.vm.synced_folder ".", "/home/vagrant/src/github.com/weaveworks/weave"
# Create a convenience symlink to $HOME/src/github.com/weaveworks/weave
config.vm.provision :shell, :inline => 'ln -sf ~vagrant/src/github.com/weaveworks/weave ~vagrant/'
install_build_deps config.vm, pkgs
install_go_toochain config.vm
tweak_user_env config.vm
tweak_docker_daemon config.vm
# Set SSH keys up to be able to run smoke tests straightaway:
config.vm.provision "file", source: "~/.vagrant.d/insecure_private_key", destination: "/home/vagrant/src/github.com/weaveworks/weave/test/insecure_private_key"
# Grant permissions on sources:
config.vm.provision :shell, :inline => 'sudo chown -R vagrant:vagrant ~vagrant/src', :privileged => false
cleanup config.vm
config.vm.provision 'ansible' do |ansible|
ansible.playbook = 'tools/config_management/setup_weave-net_dev.yml'
ansible.extra_vars = {
go_version: GO_VERSION
}.merge(ansibleize(get_dependencies_version_from_file_and_env()))
end
end
begin
+9
View File
@@ -5,6 +5,15 @@ import (
"net"
)
// Special token used in place of a container identifier when:
// - the caller does not know the container ID, or
// - the caller is unsure whether IPAM was previously told the container ID.
//
// While addresses are typically stored under their container IDs, when this
// token is used, the address will be stored under its own string, something
// which should be kept in mind if the entry needs to be removed at any point.
const NoContainerID string = "_"
func (client *Client) ipamOp(ID string, op string) (*net.IPNet, error) {
ip, err := client.httpVerb(op, fmt.Sprintf("/ip/%s", ID), nil)
if err != nil {
+17
View File
@@ -0,0 +1,17 @@
#!/bin/bash
set -e
source "$STATE"
if [ -n "$TEST_AND_PUBLISH" ]; then
cd "$SRCDIR"
git submodule update --init
cd "$SRCDIR/build"
../tools/rebuild-image weaveworks/weavebuild . Dockerfile build.sh
touch "$SRCDIR/.build.uptodate"
sudo chown -R ubuntu /usr/local/go
cd "$SRCDIR"
make testrunner
make COVERAGE=true RM= exes all
fi
+36
View File
@@ -0,0 +1,36 @@
#!/bin/bash
set -e
echo "TEST_AND_PUBLISH=1" >"$STATE"
# Avoid doing a full build if we can. Note if the PR doesn't exist
# when the build is kicked off, we can't run this check so we do a
# full build. Subsequent pushes to the same branch will have the desired behaviour
if [ -n "$CI_PULL_REQUEST" -a "$CI_PULL_REQUEST" = "$CI_PULL_REQUESTS" ]; then
if PR=$(echo "$CI_PULL_REQUEST" | grep -oP '(?<=^https://github.com/weaveworks/weave/pull/)[0-9]+$'); then
echo "GH_PR=$PR" >>"$STATE"
if FILES=$(curl -s "https://api.github.com/repos/weaveworks/weave/pulls/$PR/files" | jq -r '.[]|.filename'); then
echo "PR touches [$FILES]"
if ! echo "$FILES" | grep -v ^site/; then
echo "PR contains site changes only - skipping tests"
echo "TEST_AND_PUBLISH=" >>"$STATE"
else
echo "PR contains non-site changes - running tests"
fi
else
echo "Unable to get files for PR $PR" >&2
fi
else
echo "Unable to extract PR number from $CI_PULL_REQUEST" >&2
fi
fi
source "$STATE"
mkdir -p "$(dirname "$SRCDIR")" && cp -r "$(pwd)/" "$SRCDIR"
if [ -n "$TEST_AND_PUBLISH" ]; then
cd "$SRCDIR"
git submodule update --init
fi
+13
View File
@@ -0,0 +1,13 @@
#!/bin/bash
set -e
source "$STATE"
if [ -n "$TEST_AND_PUBLISH" ] ; then
docker login -e $DOCKER_EMAIL -u $DOCKER_USER -p $DOCKER_PASS
cd $SRCDIR
make clean-bin
# CircleCI doesn't let us install the qemu module to do ARM docker builds
make publish ALL_ARCHITECTURES=amd64 UPDATE_LATEST=latest-only
fi
+13
View File
@@ -0,0 +1,13 @@
#!/bin/bash
set -e
source "$STATE"
if [ -n "$TEST_AND_PUBLISH" ] ; then
if [ "$CIRCLE_NODE_INDEX" = "0" ] ; then
go get github.com/mattn/goveralls
goveralls -repotoken $COVERALLS_REPO_TOKEN -coverprofile=$SRCDIR/test/profile.cov -service=circleci
cd $SRCDIR/test; cp coverage.* $CIRCLE_ARTIFACTS
fi
fi
+30
View File
@@ -0,0 +1,30 @@
#!/bin/bash
set -e
# Signal failures in lock file, in order to fail fast:
function signal_failure() {
echo "KO" >"$TEST_VMS_READY_LOCK_FILE"
exit 1
}
trap signal_failure ERR
source "$STATE"
source "$(dirname "$0")/wait_for.sh"
if [ -n "$TEST_AND_PUBLISH" ]; then
[ -n "$SECRET_KEY" ] || {
echo "Cannot run smoke tests: no secret key"
exit 1
}
# Provisioning from image typically take 90 seconds,
# but if we are creating a GCP image, it can take more than 10 minutes:
wait_for 900 "$TEST_VMS_PROV_AND_CONF_LOCK_FILE"
# Upload built binaries to testing VMs:
cd "$SRCDIR/test" # Ensures we generate Terraform state files in the right folder, for later use by integration tests.
./run-integration-tests.sh setup >>"$TEST_VMS_SETUP_OUTPUT_FILE" 2>&1
echo "OK" >"$TEST_VMS_READY_LOCK_FILE"
echo "Test VMs now ready. $(date)." >>"$TEST_VMS_SETUP_OUTPUT_FILE"
fi
+23
View File
@@ -0,0 +1,23 @@
#!/bin/bash
set -e
source "$STATE"
source "$(dirname "$0")/wait_for.sh"
if [ -n "$TEST_AND_PUBLISH" ]; then
[ -n "$SECRET_KEY" ] || {
echo "Cannot run smoke tests: no secret key"
exit 1
}
# Provisioning from image typically take 90 seconds,
# but if we are creating a GCP image, it can take more than 10 minutes:
wait_for 900 "$TEST_VMS_READY_LOCK_FILE"
# Run integration tests:
export COVERAGE=true
export WEAVE_NET_SANITY_CHECKS_FILES="$CIRCLE_ARTIFACTS/weave_net_sanity_check_*.log"
cd "$SRCDIR/test" # Ensures we generate code coverage files in the right folder, and use the Terraform state of previously provisionned VMs.
./run-integration-tests.sh test
fi
+10
View File
@@ -0,0 +1,10 @@
#!/bin/bash
set -e
source "$STATE"
if [ -n "$TEST_AND_PUBLISH" ] ; then
cd $SRCDIR/test
test "$CIRCLE_NODE_INDEX" != "0" || (cd $SRCDIR/test; ./gen_coverage_reports.sh)
fi
+11
View File
@@ -0,0 +1,11 @@
#!/bin/bash
set -e
source "$STATE"
if [ -n "$TEST_AND_PUBLISH" ] ; then
cd $SRCDIR
make DEBUG=1 lint
COVERDIR=test/coverage make RM= tests
fi
+41
View File
@@ -0,0 +1,41 @@
#!/bin/bash
set -e
# Signal failures in lock file, in order to fail fast:
function signal_failure() {
echo "KO" >"$TEST_VMS_PROV_AND_CONF_LOCK_FILE"
exit 1
}
trap signal_failure ERR
source "$STATE"
function install_terraform() {
curl -fsS https://releases.hashicorp.com/terraform/0.8.5/terraform_0.8.5_linux_amd64.zip | gunzip >terraform && chmod +x terraform && sudo mv terraform /usr/bin
}
function install_ansible() {
sudo apt-get update || true
sudo apt-get install -qq -y python-pip python-dev libffi-dev libssl-dev && pip install --user -U cffi && pip install --user ansible
export PATH="$PATH:$HOME/.local/bin"
}
if [ -n "$TEST_AND_PUBLISH" ]; then
[ -n "$SECRET_KEY" ] || {
echo "Cannot run smoke tests: no secret key"
exit 1
}
install_terraform >>"$TEST_VMS_SETUP_OUTPUT_FILE" 2>&1
install_ansible >>"$TEST_VMS_SETUP_OUTPUT_FILE" 2>&1
# Only attempt to create GCP image in first container, wait for it to be created otherwise:
[ "$CIRCLE_NODE_INDEX" != "0" ] && export CREATE_IMAGE=0
# Provision and configure testing VMs:
cd "$SRCDIR/test" # Ensures we generate Terraform state files in the right folder, for later use by integration tests.
./run-integration-tests.sh configure >>"$TEST_VMS_SETUP_OUTPUT_FILE" 2>&1
echo "OK" >"$TEST_VMS_PROV_AND_CONF_LOCK_FILE"
echo "Test VMs now provisioned and configured. $(date)." >>"$TEST_VMS_SETUP_OUTPUT_FILE"
fi
-46
View File
@@ -1,46 +0,0 @@
#!/bin/bash
set -e
set -o pipefail
PRODUCT=net
fatal() {
echo "$@" >&2
exit 1
}
if [ ! -d .git ] ; then
fatal "Current directory is not a git clone"
fi
if ! BRANCH=$(git symbolic-ref --short HEAD) || [ -z "$BRANCH" ] ; then
fatal "Could not determine branch"
fi
case "$BRANCH" in
issues/*)
VERSION="${BRANCH#issues/}"
TAGS="$VERSION"
;;
*)
if echo "$BRANCH" | grep -qE '^[0-9]+\.[0-9]+' ; then
DESCRIBE=$(git describe --match 'v*')
if ! VERSION=$(echo "$DESCRIBE" | grep -oP '(?<=^v)[0-9]+\.[0-9]+\.[0-9]+') ; then
fatal "Could not infer latest $BRANCH version from $DESCRIBE"
fi
TAGS="latest"
else
VERSION="$BRANCH"
TAGS="$VERSION"
fi
;;
esac
for TAG in $TAGS ; do
echo ">>> Publishing $PRODUCT $VERSION to $1/docs/$PRODUCT/$TAG"
wordepress \
--url "$1" --user "$2" --password "$3" \
--product "$PRODUCT" --version "$VERSION" --tag "$TAG" \
publish site
done
+30
View File
@@ -89,6 +89,8 @@ build() {
## Inject the version numbers and build the distributables
## (library versions?)
sed -i "/SCRIPT_VERSION=/ c\SCRIPT_VERSION=\"$VERSION\"" ./weave
sed -i -e "s/:latest/:$VERSION/" -e "/imagePullPolicy: Always/d" ./prog/weave-kube/weave-daemonset.yaml
sed -i -e "s/:latest/:$VERSION/" -e "/imagePullPolicy: Always/d" ./prog/weave-kube/weave-daemonset-k8s-1.6.yaml
make SUDO=$SUDO WEAVE_VERSION=$VERSION DOCKERHUB_USER=$DOCKERHUB_USER
if make tests; then
@@ -157,6 +159,20 @@ draft() {
--name "weave" \
--file "./weave"
github-release upload \
--user $GITHUB_USER \
--repo weave \
--tag $LATEST_TAG \
--name "weave-daemonset.yaml" \
--file "./prog/weave-kube/weave-daemonset.yaml"
github-release upload \
--user $GITHUB_USER \
--repo weave \
--tag $LATEST_TAG \
--name "weave-daemonset-k8s-1.6.yaml" \
--file "./prog/weave-kube/weave-daemonset-k8s-1.6.yaml"
echo "** Draft $TYPE $RELEASE_NAME $VERSION created at"
echo -e "\thttps://github.com/$GITHUB_USER/weave/releases/$LATEST_TAG"
}
@@ -236,6 +252,20 @@ publish() {
--name "weave" \
--file "./weave"
github-release upload \
--user $GITHUB_USER \
--repo weave \
--tag latest_release \
--name "weave-daemonset.yaml" \
--file "./prog/weave-kube/weave-daemonset.yaml"
github-release upload \
--user $GITHUB_USER \
--repo weave \
--tag latest_release \
--name "weave-daemonset-k8s-1.6.yaml" \
--file "./prog/weave-kube/weave-daemonset-k8s-1.6.yaml"
echo "** Release $RELEASE_NAME $VERSION published at"
echo -e "\thttps://github.com/$GITHUB_USER/weave/releases/$LATEST_TAG"
echo -e "\thttps://github.com/$GITHUB_USER/weave/releases/latest_release"
-57
View File
@@ -1,57 +0,0 @@
#!/bin/sh
## This is the shape of unencrypted `do-setup-ci-secrets`
##
## cat > /tmp/boto_gsutil_cert.pem << EOF
## -----BEGIN PRIVATE KEY-----
## <...>
## -----END PRIVATE KEY-----
## EOF
##
## cat > ~/.boto << EOF
## [Credentials]
## gs_service_client_id = <...>
## gs_service_key_file = /tmp/boto_gsutil_cert.pem
##
## [Boto]
## https_validate_certificates = True
##
## [GSUtil]
## content_language = en
## default_api_version = 2
## default_project_id = <...>
## EOF
openssl base64 -d << EOF \
| openssl aes-256-cbc -d -K $1 -iv $2 \
-out bin/do-setup-ci-secrets
mOYNzNsAdwva0LbB2YFMY9VgL0SITFu1bPrbOujyLtOrBNjmOYbzR5d/sG+ARMFr
7NZ5OKcvMbItllz0n7TtNkzkCOMztMC870Wcx3nGJzbBephdcYwos4tBlp5bihTU
AXgxLUiDT1broYAFKnbE1aZC/XyNxuLTN+nXJWIWeijaXTgvhkEEm3tab+z7ioCb
tlg71W1BrUuocctAJAuVwH/uTZAaXaJGJj1s2S7F2DrFnG6sFlrp8rnCucPLWKnC
4IwJFC5saR5gxK6wECffwmwbpeXVOoQ58OgzxoZTEyAr9nhVbaBt5UZz3tfHlx8W
Rn5jHehACw5kg5eMtGPqMEksJ63LX4h3mfSTLJXJHEmOrzCRpFrigVrsbA408U2u
8jJTHJmKrGfwBh5ZFzBg6NuV4VplOp+ZquJLgegv2WH/iu/ciopXqB2YDCdx5ZBi
nHV2Puth7kjS4EMCKUGfeqpesjL9Djb8cygzv/J3ZBmLjNH9dqlSXWy2DcFZA1Iy
pFTTHkVU3w5sNz3nYOuT2UPQvULBW0FUndDKX6olyVa0mlxPwGBP9N3yGg918/rw
7rNV/r54lA334F5QMhDrVxar6sl9wfLA+Z+8qemBbNFlLog1uQGhuwWK2nFu1tRM
9uyvQIq0oq5NHKpogWc7NEuk7CPe1JyfRIcbMVj8+ilmKjUPB2HPC43IDmKt9/56
rY3IXAcxZ/ClGfGpeNHXqop9T/WhfaowponOZFcdGSUddG0OswqkTE4KIv71mgTF
jXooMkTQBOG+gBnCe+8bCRdRCG3anxHX74za4dGD58cOJtl6DYWnjWuR91NWnxdT
1Zr3iUe41txg9hCNY9LHo2QHGLPxe6pmNnSClQ1mcFhuY6NF8RmCX3HAGKJQkxJb
vpLGbXTXjAIFgIYgLNgKP2RLvCif/LmSWgkvE3ZU9GXtCUbm6xgJodwOqXiI9uuO
4H4+/vpGHnSFENiclkgMFrLG4yiMu8ArgmnCBzg9E2AoOX5zCrh/2ZRTU8Dk4mt7
jUd5SKQLsjB9QtB+y3tRO7zY9RDvR6iBOPRsjx6t8EJMCfPb06KchfMJw+VGxvMM
48jtmepREFnhd/8XDRGnw5bznjRuwohGik8BToltjIviMkkpifKWaLwlaOiDXaHh
VBFNXnUKvOBwRMU+PZqv4+DP2qff1gSXnGKqA5GIURYrK9P7TqHHNTnmjBdfJLzc
0x+W1DTiYhLT2vrLrkEpZ99o6qrg+lwvjat6IsJF8xoQEo4pLD/ZRPJ0WzoDyctT
oWZ5rMsN1TzTvJrBrTAWIJyhIzZcuNwChMrU6qogMr0fd6TSxWhWn0sOJ5y8AaTR
ej4JHx0qroS/9JPmgFYU61pX3c0ypdef/sSHWG23mcFzLTgwe2d4ty9VakypZy3T
sXCl6EHVVXlUFWhY4zQCjdZpYJv/rtoKL1BL4fPE2NV5WTjCL2GNvaO5SfHR7pA0
yQJR/iU+cS2n8UXsWNjyV+/qEn6+QXuyVHGLbxyH8EeqlliAbyHsc2rzVI8Xctzo
W5DuIqxwHAkNNurhmx27ktIIQ6HhaCp028SWwvLttkbBBgF4v1mmd4u/2bKbKjUd
dOaetaIUx1hU9OAeaePvVkeTDcc3mlFtPARCS9Fqj16hgJQ43onZyC0H1K2WAxmU
GsmzjCHlTNquzFTuuQihYGZKfsWIh9z6HEOkvNJ3VEQ=
EOF
exec sh bin/do-setup-ci-secrets
-115
View File
@@ -1,115 +0,0 @@
#!/bin/bash
set -eu
# openssl enc -in do-setup-circleci-secrets.orig -out setup-circleci-secrets.orig -e -aes256 -pass stdin
# openssl base64 < setup-circleci-secrets.orig
openssl base64 -d << EOF \
| openssl enc \
-out bin/do-setup-circleci-secrets \
-d -aes256 -pass pass:$1
U2FsdGVkX1/3QHnDgpZn0srp+GiEQBTlag0CBdsw6Bp6iaIKy6Jy8gFshrsmvl3+
c+7hn1nqsBVpzVH0S5QA3Ex5nx9rl7/dcGoogsySFcwMmBFcauT0UTMK1bvX0Hqx
QrshYSndUkww72KA7EsSnjR1BBJWm3AhCDOTIcnO6nQhig1Fc+SBEj5FGS5xTQ5Z
/8hDsKf54Ms49vOO6QeE5w5ndZ+k7IvVJfq9Evhb7htD20RntDhR86foAwMnLV7R
Wh9qAqI3gnRq0GmbeRKaHmB7pcLq9f0OdScqM/Tn1D+q0556fqJjBziXpZiGbxVs
DxEp8zDJ8yNDAi0Wb2NXjoA79SXJ8Q7iTieaST4y2OmXQpY+Vw8RVDXxi6ERyVnH
41OeMzyLm0qvCoMl32pe1sSG5DRCUiAm7wOtDTVvNDRqmGJYUgwwexyayecJI1wQ
LlhYLJavUvw3UGDZOld8BaMQhfOKBVCdFrjmA4HuVxmOf3029qkgzOCSZiQVNqs+
fvM6J05zBuk+GPy8YInvRkzfxum/x00vmUyGjMs/lHDFfrmYDFK3ux41EoVqvWLG
S5uYxdZJFdR3Xsrs+sMr51XNBQGMmz6KoEEzFYyHs5fZgtdpRdPAuQS1m6FqgZyi
wSz6+EKsALtmGorEp+CF8JN5YzKJCrKzNkg0fILBqsqmJZGP64lmX69950lRLNGM
/l3KVR2zH31b4AnnzTcvldVSCKDXjaMw3JA2Ce/MK6XhOWOcpEv4oDt/62lbhUKP
QUQTPbfpQRvVfBcoIrfAm3ghi/CZc2TDVEuD7DhasLTZD3r7LoK261BWC9O5Wubi
vlXuFIF+uyrpTDf6EJKE/+XywtArppffMP6RkHu1Iqnd8JtsqPaIZsmMmZbjgb6j
BX4ZLb5U9R7jYoSgIke4+u6geFcrMQ+Lny4r7MxXaS0Y1UJ6Jo1bwpYw1TBIobZc
eQ30+xhbSeRC9vEw1NXI6qM2Ai2gIHtAZvEiBkBBXTG5Ld7N/mBAmDIJEzVRxh6F
jRkB3dzESF6eeTBm61OQepwV3aW6lslMaf26drPGv2W2q+K/WOpQOejfggtHUgVs
9SWqtn7hHYSpIASe1Ihi14HAWv3kPhQien0zY1DLKJWf4ilbRaICn1QSJjNuKwtl
A2ZwEw7FFddFcsF4okHPkxEoCre3shq0DEw9UA1gnwEaEF1Q+i9cvLtQg56zK3+R
MfTzFUv2K1z3j1s5tC6Z6LzL8j682EFOll7MkihqiIWh+po1zcNs6Ln0SkjB3v9T
OFRYVJis9GqXYO9PUW1mI69udR4nXbKlBl5tWNyAxn9hufJHLSAmbGMwActKLRM5
kROapKrN1Ra/sHUmhoSSDUK9AXeYKkqPXVMbhly9xC1Kya4hFaFokjRQIMLPmXdQ
lP46RL3HOq0v1BkXg05poSwDm+BtitZkcIhOzcmeucUqn1whsz39y3VoOhJqQu2j
0dUcj19Fue1CDZfwzACb9mLZr643h0yCIHQaVT7is/yiN2vEt0S0zynvOA1D+Xgy
4bFdjqed9DgBShLwF/lh4/hur5iZPpVr9A8rt3Vq0k5A1tdjsZpXP3qv5jLc7lJv
cAQxdVLEuv8WPwwTV/EQsoH7lpoEdjktw/gu0v5PkUgR/WBxEqJq4liTekViQ+8X
BAmdm/FGWeIxSSEm0a8I+muiBpIuKjuQoJit1f0k+lLUohoVDqpDDfeYHh1TxXHE
xSKAKNmFSc2XOr5Zg2mOInxeH7WoxH6iylXKADBgEgAQ4C55DoAPRjFNtGGz2iJl
WkzhQOfgsDss1VxpPZ4SWDQO+xxuuEnYcCYdJ6Tyi5hAwZ0+RZmXx0g9BCK+5qzc
Ffei066kCItBcayekwCs0i86r8JvDtsMUUkzEKDQTSWHpP8ypIZoz3P+Skdqcs6p
IcZHy2fODIsClctRAsHOjZ9BnWSY2rqf1lysqvRfOkNTViTOUVx2hf+LuL+8rT6g
K4GvS39Q+c9FYSMjCNxv1m37NfHJv2W7AlqVV95gMBEFB97M3388T7PfvmSLsyPv
qAKDE7genTOycQvEX9oeEACxPo08ai2Mgs/YXCig0g0btZoScoKPelQKtD0HLpZ+
j7ruaKFy4/vySDMostB3AKSkCE/SkGu/W9oI37n1guSYC/9yJjtTcwZULXAClfwt
LyHvLAw4+7BdGJqDe9Tf8z4zqVLax+BcBHkW7pbP+pvxC6fhIA4PO8k5HwwAVlRw
68lG6e3z9+Vst4zrFLewHJvkDRSOTSecs9h9SPOjReTK0ovlDzMHVakfUvqpk9mv
nCj8SWaMPF70z138AuRuKN7X4exNXPBFnOcseKp/NpT1DyvgoHm/oIO65mq9vvo+
42uSbyyegYiTdVK4SaXBc2hixkhaTteqdEy6GxfWqKCvHtYuRD2LyUSjZn/0Y6CG
3wZapylKL1sxfH+b1gogv2wAA8KtZAfiTlMISuymwQr5RbOFma7UVMVecCa7XrNG
fZwO8R+6++ru0efDzeC/gtLOItjn+yVfsbk2gfu0FikHIV1sogOjnsv3dl6IpH/s
w6WbuK/yZhyrrmhIIueHF30ES512Peogf/Gxp8U/ZAmqBa7p4qsv93XWDR52IPYz
yU1MtboLD02J39daBNrYZuO4Yfo/xAvU7Ijg2KIR9HS0bSWNuSFAZaZXlJ2bSag3
8l0dZMx2fZa0FALxWvY2+nd1tWcH+Wo99RSxX+4TH3guCpe1x/58yKOKL4d1xRpu
02nGaqerV9bHU6WjCUYTrrZurTp6yqivpSFCALDMhAU5Ihd/Qjz69zg4uZ7iqbNd
WqIYJ3SAOei2tSfoOJbdh8mohotnMFFbupck3Fv+lXAXYDp0V/sSuK32MSeJxan1
q3t0eenAh6zoBP0Tj53N8B9YmrgZ1i1AljQqYsAdb8N5Z3vecuzQa946U8H4axEc
BL5fgmqSfsbj1EjJVUrw3cE9hgqeqAYBBvZsyW5zSAsLq/RJKYtBxDGADqr0TOOu
TjVqfPObb1u9EAQj15ALBhhPORa2gBAK5gnhJWW5deNgA0UOYoWARFYfATuQvr1T
9xTVbqzZ0VJR4n7X5JyxJo2tZ44QYVzA0fqX0lt+uRkarrkbZMgplKp4MJTFCp2N
tLciWS0YSHPbKTm7svw5mROazUvEoj1N3SYrJT+Ai9UgSL1cA4FmQ5Jsi+GOeQbH
7E4pzjeST4b1aATY9ZZSy4TzK+UNYBcCVqY1dN5Xnk0e5yPMnrkkcYI41s/6oOaW
lQkp/yrHkvpzQWZa7vF2yWg54j3eX8YWx/TsLvmuJmSQqiIHfu9TXcAIPDispCpF
gp4ZbYPZ8RDQLw3ROc+bZ9E0J8e+FHwgXEELsMLW9n4d3PTj9pLFej1vmBKa03o3
g+JViNxb1gUPNmC6ADk4o7TQzBrjV2pmmuCza16kOmq6oAbJPOeCLtVWA5HJTX8d
AuOzBLO37tWP457dNqoNDaCMik3LCy8cslZjAz02D6VG/QGOAXP9x8bJ3zg9N7vW
EOn1BMtIeMI4yIxpC6HgotNWDNbUBWremAFWYQRgYQqo9L1SdW4hz6X8FqdlBFvK
ml7sdUwjEy2tNW+aiZI4cgAlI/VvMWYr5kPfhvaUu1wGYeS1TD1B+DPcjcXpOGWo
vB1f/uvGc61zZWD0ph9f3S9OnvEko5qV3VhxOnxYUZTrqlM7LVgy/sHrSaPdR7Eo
nb4QGdi5wEGMxVgQlDGwOmEmS5nCaA0RcfHbkQV4SebRleocLB9qcSwj5JzPICAB
sn1qeSv45LnGdTzUnCQErw1EzgrK1FXOknujjZ3GX5dM7a6Gag0E6cAxoQeC8Mh0
aUWolyBo9aSXltn7Vnywoe4X3v96eVH6tUQtN3wt51LBlfSDTWOQDeXLFyW57oYL
/ErbmJLaSHpANBcC9InI+rxNYePTTba7K8rdPDppmMEmdOXjaL+5aPay2Bay9K8T
FUyZdoyrbzxFZYT9/YyVJV/ukVcT9ru3HpzLTg9Vgc/CyRfIvCZY/Gzh+pPUbRsR
pHYDT09BFS+mjszTkcdbceweYXJvknXpajMiISrPUUkb9rwCTmLS4QR4y7I9zAgJ
9U72mCZB9yhhzS17kyKAANihXvOFrMXCO7QTWZbtSkobMBS2SybDxYP3rM5b6824
HQaY4MZW5qCndydfz4fa908XbPTDka9Nu3CZfI3fhGiiGDFWViotGEYE4i9BuGZJ
vmtzII7zeIoHwM4t5fb5mYDd9H+Rkct1yATGEIFEx7cu1fj4Ht2177EzhdkF3Q6I
Fccn43yGDW06nFvEjnjb+Lz4EvtGp6dDefUhNBohdzd4Rm2o+etKobm0lZ1xOX74
2gOGBLfXS6PF+msNkWP76mqKE6hG0+R1iPrN06Arti+ZRBhNGJDp1pnOERl7IyB0
hiLUqae7xVSMVRDeq4O04EUpMXh5ixs3RJXjthYILt7vX+6qskJC3rMuyThrsvMi
Kk0wErDpzR5U7KFnM2fk4jY5by/0b/jHZ/PWFGnaFrXNOiwK/mV1RIJtg5FCrvMv
xJN5Qo7o2ZYzUL+IBf5mP5O49FCnz3e++9r4ySY/K57ybhQft1l+cQPWS7xuvVAg
wZGM9DPl9AhBus0I3V3XzfkcWWHkMynMRcfTnkBHrmKjMopIOggsq05JPalM9b0V
NfwZngVvTFbQejbGjgQQQ+G7spav/icCIA8Iu8JPHaKZt2IX77L1xMcQOouqMrx8
JCXnJ7zsuU+8W3GQGm70H2kcen4bf4beA8TSkFmbVsaqDNtGaG+ZopWO8ctZX3CP
jFgIYgEGi137IWvs1KD5QNFHZI6l0JMzglmvcfnViRPDHLi+EQXAoL/98j/YzA9t
a9L4xMO0oucovKkqYOS2cdFaQKVIUM9L5ibcbW7Tol4ugMo5ibIsTgjZoyFohG6t
acg+h2wTTyxtrIapvOOBeAo9V/iQowTAPQf38LKQZ5tApksiCG1qvJerKALTMp1J
yUHjTCPCPsaiXVVO0mfa9OPtzVvi/icLmlz7umk82mew13djedgMS3/ghq5aEHbg
e7rtI5snFlm/GQnV6IaCDytb+jYxqQ0DZ9Mb0CHcMpnLyiBO6nzHfadpZYlrxrpx
dPx9MVqfLavj1UVjKuVj4Mgec9J38IBBRGMJZ4MGhde2hrw/s2jVzG1BzaIzcvFa
bWiJOkKKRC4BY9DBDYfae5c/obwzkxLmvkbWAVzoFXc+46K1IK6bbC2a4EerOAxc
C7B3X8BucD8OtiPORwXgjctd9AJ7cXq0EEVGoZZ8jkILnklsK6RXsxrT4gSOGFpx
cBU7TF4kHpH+o4KGQmjlFA2VYP1tXirjEep57LOHfL+zy+HiSXdsbexf6odkqLYA
1RR0TzSkmqJYvP0GfHPMvp2xredx1kP934fhTIUcWvErrG3NPd/Dod4BzQye1nNK
8Y8aFYF6fACcD4SFZ11ecK9DJmB+WXGlsxtO3w1LeEysny2lVkkH6HuMRIzPyXAM
/sEpwh3hwPJosAh6vGM6JxuL7CXP8hC1oUvK91VR0hxeDcO/LgdcHtDnlNMqt1wC
jvYt9Hg+3aY5GehBnQPRppnIMaGhiBrRC6HjBg8Umt6UTUr5PXNY2aia5wRcx4M6
Tj0O0dAt8WWZ9ySgzOoq4SRoaAp6m4E7CpRNMgXH031OWEeHqtt8rsYqAcvcQLuW
vIwts5hiXZOfgXyR6SBY3ANE1SjDY46na2G4oiG8FI7eAqYgehjHrXqCnGrzjefE
V1eVcIr7DBYuM8wq7C9x+qdMir6RNV4MrVD+7rO/drivnd3MaqDHlG0LfMZo6GIK
QZGIy0z1W5lOXm9x3RAz7/Ea11ynkZyPDDxBE5NRcV6JfukdjDrvsaQA/Qk2Wo7h
PdUZjv17H4syMdap6tUDTc8Cohut6n1UxnDnhaAYEDGR3TgPqI5vEaJ+yoaM9itv
b2I/K+0uK6GfWwca7PeTtYn92/5etO4czG99xEBFzw7tiEmBTA8KfseZIUe/i3fr
9LO+rKEGalFB4mVTYyCKPYYx4hOIvjdCox/jEBTFyYUEhgGnZvArgw9XabvII7eM
c1FmwnN2CM/MHUzM0Kw7cS/oaoRFcG/PqioO/krL2Bd+xThwSH4Zn+Y1UVO7aXNy
90MOehHSc2nhN984Y2re3ffVsjPhC3KdWxr8jbho/Az65rUkYg64roiO2ZqdqRvf
aYtX9fCe8N8SzgLTlWZt+l8sjY8HP2k9NoajphV1nG4iC/pX0ZJiVQ+VBRNaGhSl
6IhM9gM1ZsI86cULJpOTAhNu1fZBv+Mq8IXYD8SqlNVwVtjvshtlzBN4InSGEKiO
HM7coo7aDuu+Go5AEiIVMbR09jAa0VINsCVScfSbTFhlGRTrZr2DSO/s8WxbV+Mb
EQAfZmyrLF71Z3MfIukg+ps5iuqFhZ+gJSXXSFwumpg=
EOF
exec sh bin/do-setup-circleci-secrets
+21
View File
@@ -0,0 +1,21 @@
#!/bin/bash
# shellcheck disable=SC2155
wait_for() {
local timeout=$1
local lock_file=$2
for i in $(seq 1 "$timeout"); do
if [ -f "$lock_file" ]; then
local status="$(cat "$lock_file")"
if [ "$status" == "OK" ]; then
echo "[$i seconds]: $lock_file found and status: $status." && return
else
echo "[$i seconds]: $lock_file found and status: $status." && return 1
fi
fi
if ! ((i % 10)); then echo "[$i seconds]: Waiting for $lock_file to be created..."; fi
sleep 1
done
echo "Timed out waiting for test VMs to be ready. See details in: $TEST_VMS_SETUP_OUTPUT_FILE" >&2
return 1
}
+85 -6
View File
@@ -1,8 +1,87 @@
FROM golang:1.5.2
ENV GO15VENDOREXPERIMENT 1
RUN apt-get update && apt-get install -y libpcap-dev python-requests time file
RUN go get github.com/golang/lint/golint github.com/fzipp/gocyclo github.com/client9/misspell/cmd/misspell
RUN go clean -i net && go install -tags netgo std
RUN go install -race -tags netgo std
FROM golang:1.7.4
# Support Raspberry Pi 2 and newer
ENV GOARM 7
# The names of the architectures that we're fetching cross-compilers for from the Ubuntu packages
ENV DEB_CROSSPLATFORMS \
armhf \
arm64
# The go platforms we are supporting to cross-compile
ENV GO_CROSSPLATFORMS \
linux/arm \
linux/arm64
# The names of the gcc cross-compilers we have installed
ENV GCC_CROSSCOMPILERS \
arm-linux-gnueabihf \
aarch64-linux-gnu
# Temporarily add the Ubuntu repositories, because we're going to install gcc cross-compilers from there
# Install the build-essential and crossbuild-essential-ARCH packages
RUN echo "deb http://emdebian.org/tools/debian/ jessie main" > /etc/apt/sources.list.d/cgocrosscompiling.list \
&& curl http://emdebian.org/tools/debian/emdebian-toolchain-archive.key | apt-key add - \
&& for platform in ${DEB_CROSSPLATFORMS}; do dpkg --add-architecture $platform; done \
&& apt-get update \
&& apt-get install -y build-essential \
&& for platform in ${DEB_CROSSPLATFORMS}; do apt-get install -y crossbuild-essential-${platform}; done \
&& apt-get clean && rm -rf /var/lib/apt/lists/*
# Install some required packages
# libpcap is required because we're linking against its C libraries from the prog/weaver binary
# flex and bison are required packages for compiling libpcap manually later
RUN apt-get update \
&& apt-get install -y \
libpcap-dev \
python-requests \
time \
file \
flex \
bison
RUN curl -fsSLo shfmt https://github.com/mvdan/sh/releases/download/v1.3.0/shfmt_v1.3.0_linux_amd64 && \
echo "b1925c2c405458811f0c227266402cf1868b4de529f114722c2e3a5af4ac7bb2 shfmt" | sha256sum -c && \
chmod +x shfmt && \
mv shfmt /usr/bin
# Install common Go tools
RUN go get \
github.com/golang/lint/golint \
github.com/fzipp/gocyclo \
github.com/fatih/hclfmt \
github.com/client9/misspell/cmd/misspell
# First clean, because we're gonna rebuild the std both with -race enabled and disabled
# Running go install std twice is intentional and required, as content is written in two different directories
# (/usr/local/go/pkg/linux_amd64 vs /usr/local/go/pkg/linux_amd64_race)
# The other architectures do not have support for -race
RUN go clean -i net \
&& go install -tags netgo std \
&& go install -race -tags netgo std
# Prebuild std for the other architectures
RUN for platform in ${GO_CROSSPLATFORMS}; do \
GOOS=${platform%/*} GOARCH=${platform##*/} \
go install -tags netgo std; done
# Allow full write access to the Go folders for anyone
RUN chmod -R a+w /usr/local/go
# The libpcap version from Debian packages is 1.6.2, matching that version here although newer versions of libpcap have been released
# We have to cross-compile the libpcap library for the new architectures, that's what we're doing here
ENV LIBPCAP_CROSS_VERSION=1.6.2
RUN curl -sSL http://www.tcpdump.org/release/libpcap-${LIBPCAP_CROSS_VERSION}.tar.gz | tar -xz \
&& cd libpcap-${LIBPCAP_CROSS_VERSION} \
&& for crosscompiler in ${GCC_CROSSCOMPILERS}; do \
CC=${crosscompiler}-gcc ac_cv_linux_vers=2 ./configure --host=${crosscompiler} --with-pcap=linux \
&& make \
&& export LIB_DIR="/usr/local/lib/${crosscompiler}-gcc" VER="$(cat ./VERSION)" MAJOR_VER="$(sed 's/\([0-9][0-9]*\)\..*/\1/' ./VERSION)" \
&& mkdir -p ${LIB_DIR} \
&& cp -f libpcap.a libpcap.so.${VER} ${LIB_DIR} \
&& ln -sf libpcap.so.${VER} /usr/local/lib/libpcap.so.${MAJOR_VER} \
&& ln -sf libpcap.so.${MAJOR_VER} /usr/local/lib/libpcap.so \
&& make clean; done
COPY build.sh /
ENTRYPOINT ["sh", "/build.sh"]
+1
View File
@@ -0,0 +1 @@
8f313a9df867c207ae9ceac6e0935d1d2a0360aafce780dd5d1e0687ee98e0c3 docker-1.10.3.tgz
@@ -0,0 +1 @@
7541b5490cee1183d911f909c0e91d3d9d57b2b775e40f14a1a7a6de216ca4a8 docker-1.10.3.tgz
@@ -0,0 +1 @@
c02d861383d035ba020b361ef93bf14beb3964a42a6ae645b505b6148493e7ec qemu-aarch64-static
+1
View File
@@ -0,0 +1 @@
0ff63682b8868620d771aa812d3053dc3c579dc8633ce62d3d7ae7eee83beb06 qemu-arm-static
+31 -43
View File
@@ -2,77 +2,65 @@ general:
branches:
ignore:
- gh\-pages
- /pull\/.*/
machine:
pre:
- curl -sSL https://s3.amazonaws.com/circle-downloads/install-circleci-docker.sh | bash -s -- 1.10.0
services:
- docker
environment:
GOPATH: /home/ubuntu:$GOPATH
SRCDIR: /home/ubuntu/src/github.com/weaveworks/weave
PATH: $PATH:$HOME/.local/bin:$HOME/google-cloud-sdk/bin/
PATH: $PATH:$HOME/.local/bin:/opt/google-cloud-sdk/bin
CLOUDSDK_CORE_DISABLE_PROMPTS: 1
STATE: /home/ubuntu/state.env
# Base name of VMs for integration tests:
NAME: test-$CIRCLE_BUILD_NUM-$CIRCLE_NODE_INDEX
TEST_VMS_SETUP_OUTPUT_FILE: $CIRCLE_ARTIFACTS/test_vms_setup_output.txt
TEST_VMS_PROV_AND_CONF_LOCK_FILE: $CIRCLE_ARTIFACTS/test_vms_provisioned_and_configured.txt
TEST_VMS_READY_LOCK_FILE: $CIRCLE_ARTIFACTS/test_vms_ready.txt
# Google Cloud Platorm images for integration tests:
USE_IMAGE: 1
DISK_NAME_PREFIX: test-$CIRCLE_BUILD_NUM-0
dependencies:
cache_directories:
- "~/docker"
post:
- "sudo apt-get update && sudo apt-get install bc jq"
- curl https://sdk.cloud.google.com | bash
- bin/setup-circleci-secrets "$SECRET_PASSWORD"
- "mkdir -p $(dirname $SRCDIR) && cp -r $(pwd)/ $SRCDIR"
- "cd $SRCDIR; git submodule update --init"
- cd $SRCDIR/test; ./gce.sh make_template:
parallel: false
- "cd $SRCDIR/build; ../tools/rebuild-image weaveworks/weavebuild . Dockerfile build.sh && touch $SRCDIR/.build.uptodate"
- bin/circle-dependencies-post-sources
# Provision & configure testing VMs:
- "while [ ! -d $SRCDIR ]; do sleep 1; done; $SRCDIR/bin/provision_test_vms.sh":
parallel: true
background: true
- bin/circle-dependencies-post
test:
pre:
- "$SRCDIR/bin/circle-test-pre":
parallel: true
background: true
override:
- cd $SRCDIR; make lint:
- "$SRCDIR/bin/circle-test-unit":
parallel: true
- cd $SRCDIR; COVERDIR=test/coverage make RM= tests:
parallel: true
- cd $SRCDIR; make COVERAGE=true RM= exes all:
parallel: true
- cd $SRCDIR; make testrunner:
parallel: true
- cd $SRCDIR/test; ./gce.sh setup && eval $(./gce.sh hosts) && ./setup.sh:
parallel: true
- cd $SRCDIR/test; eval $(./gce.sh hosts); export COVERAGE=true; ./run_all.sh:
- "$SRCDIR/bin/circle-test-smoke":
parallel: true
timeout: 300
post:
- cd $SRCDIR/test; ./gce.sh destroy:
parallel: true
- test "$CIRCLE_NODE_INDEX" != "0" || (cd $SRCDIR/test; ./gen_coverage_reports.sh):
- "$SRCDIR/bin/circle-test-teardown":
parallel: true
teardown:
pre:
- test "$CIRCLE_NODE_INDEX" != "0" || (go get github.com/mattn/goveralls && goveralls -repotoken $COVERALLS_REPO_TOKEN -coverprofile=$SRCDIR/test/profile.cov -service=circleci || true):
# Destroy testing VMs:
- "cd $SRCDIR/test && ./run-integration-tests.sh destroy":
parallel: true
- test "$CIRCLE_NODE_INDEX" != "0" || (cd $SRCDIR/test; cp coverage.* $CIRCLE_ARTIFACTS):
background: true
- "$SRCDIR/bin/circle-teardown-pre":
parallel: true
deployment:
release:
branch: /[0-9]+\.[0-9]+/
owner: weaveworks
commands:
- go get github.com/weaveworks/wordepress && cd /home/ubuntu/src/github.com/weaveworks/wordepress && git checkout v1.0.0 && cd cmd/wordepress && go get
- cd $SRCDIR; bin/publish-site "$WP_LIVE_URL" "$WP_LIVE_USER" "$WP_LIVE_PASSWORD"
hub:
master:
branch: master
owner: weaveworks
commands:
- docker login -e $DOCKER_EMAIL -u $DOCKER_USER -p $DOCKER_PASS
- cd $SRCDIR; make clean-bin
- cd $SRCDIR; make exes publish
# - go get github.com/weaveworks/wordepress && cd /home/ubuntu/src/github.com/weaveworks/wordepress && git checkout v1.0.0 && cd cmd/wordepress && go get
# - cd $SRCDIR; bin/publish-site "$WP_DEV_URL" "$WP_DEV_USER" "$WP_DEV_PASSWORD"
# issues:
# branch: /.*/
# owner: weaveworks
# commands:
# - go get github.com/weaveworks/wordepress && cd /home/ubuntu/src/github.com/weaveworks/wordepress && git checkout v1.0.0 && cd cmd/wordepress && go get
# - cd $SRCDIR; bin/publish-site "$WP_DEV_URL" "$WP_DEV_USER" "$WP_DEV_PASSWORD"
- "$SRCDIR/bin/circle-deploy-master"
-31
View File
@@ -1,31 +0,0 @@
package mflagext
import (
"fmt"
"github.com/docker/docker/pkg/mflag"
)
type listOpts struct {
value *[]string
hasBeenSet bool
}
func ListVar(p *[]string, names []string, value []string, usage string) {
*p = value
mflag.Var(&listOpts{p, false}, names, usage)
}
func (opts *listOpts) Set(value string) error {
if opts.hasBeenSet {
(*opts.value) = append((*opts.value), value)
} else {
(*opts.value) = []string{value}
opts.hasBeenSet = true
}
return nil
}
func (opts *listOpts) String() string {
return fmt.Sprintf("%v", []string(*opts.value))
}
+7 -2
View File
@@ -21,8 +21,13 @@ func CreateDatapath(dpname string) (supported bool, err error) {
defer dpif.Close()
dp, err := dpif.CreateDatapath(dpname)
if err != nil && !odp.IsDatapathNameAlreadyExistsError(err) {
return true, err
if err != nil {
if !odp.IsDatapathNameAlreadyExistsError(err) {
return true, err
}
if dp, err = dpif.LookupDatapath(dpname); err != nil {
return true, err
}
}
// Pick an ephemeral port number to use in probing for vxlan
+27
View File
@@ -0,0 +1,27 @@
package common
import (
"os"
"strconv"
)
func AllPids(procRoot string) ([]int, error) {
fh, err := os.Open(procRoot)
if err != nil {
return nil, err
}
defer fh.Close()
dirNames, err := fh.Readdirnames(-1)
if err != nil {
return nil, err
}
pids := make([]int, len(dirNames))
for _, dirName := range dirNames {
pid, err := strconv.Atoi(dirName)
if err != nil { // Only interested in numeric entries - skip /proc/stat, etc.
continue
}
pids = append(pids, pid)
}
return pids, err
}
-32
View File
@@ -1,32 +0,0 @@
package common
import (
"os"
"os/signal"
"runtime"
"syscall"
)
// A subsystem/server/... that can be stopped or queried about the status with a signal
type SignalReceiver interface {
Stop() error
}
func SignalHandlerLoop(ss ...SignalReceiver) {
sigs := make(chan os.Signal, 1)
signal.Notify(sigs, syscall.SIGINT, syscall.SIGQUIT, syscall.SIGTERM)
buf := make([]byte, 1<<20)
for {
switch <-sigs {
case syscall.SIGINT, syscall.SIGTERM:
Log.Infof("=== received SIGINT/SIGTERM ===\n*** exiting")
for _, subsystem := range ss {
subsystem.Stop()
}
return
case syscall.SIGQUIT:
stacklen := runtime.Stack(buf, true)
Log.Infof("=== received SIGQUIT ===\n*** goroutine dump...\n%s\n*** end", buf[:stacklen])
}
}
}
+1 -163
View File
@@ -1,17 +1,6 @@
package common
import (
"fmt"
"net"
"os"
"strings"
"github.com/j-keck/arping"
"github.com/vishvananda/netlink"
"github.com/vishvananda/netns"
weavenet "github.com/weaveworks/weave/net"
)
import "strings"
// Assert test is true, panic otherwise
func Assert(test bool) {
@@ -27,154 +16,3 @@ func ErrorMessages(errors []error) string {
}
return strings.Join(result, "\n")
}
type NetDev struct {
Name string
MAC net.HardwareAddr
CIDRs []*net.IPNet
}
// Search the network namespace of a process for interfaces matching a predicate
// Note that the predicate is called while the goroutine is inside the process' netns
func FindNetDevs(processID int, match func(link netlink.Link) bool) ([]NetDev, error) {
var netDevs []NetDev
ns, err := netns.GetFromPid(processID)
if err != nil {
if os.IsNotExist(err) {
return nil, nil
}
return nil, err
}
defer ns.Close()
err = weavenet.WithNetNSUnsafe(ns, func() error {
return forEachLink(func(link netlink.Link) error {
if match(link) {
netDev, err := linkToNetDev(link)
if err != nil {
return err
}
netDevs = append(netDevs, netDev)
}
return nil
})
})
return netDevs, err
}
func forEachLink(f func(netlink.Link) error) error {
links, err := netlink.LinkList()
if err != nil {
return err
}
for _, link := range links {
if err := f(link); err != nil {
return err
}
}
return nil
}
func linkToNetDev(link netlink.Link) (NetDev, error) {
addrs, err := netlink.AddrList(link, netlink.FAMILY_V4)
if err != nil {
return NetDev{}, err
}
netDev := NetDev{Name: link.Attrs().Name, MAC: link.Attrs().HardwareAddr}
for _, addr := range addrs {
netDev.CIDRs = append(netDev.CIDRs, addr.IPNet)
}
return netDev, nil
}
// ConnectedToBridgePredicate returns a function which is used to query whether
// a given link is a veth interface which one end is connected to a bridge.
// The returned function should be called from a container network namespace which
// the bridge does NOT belong to.
func ConnectedToBridgePredicate(bridgeName string) (func(link netlink.Link) bool, error) {
indexes := make(map[int]struct{})
// Scan devices in root namespace to find those attached to weave bridge
err := weavenet.WithNetNSLinkByPidUnsafe(1, bridgeName,
func(br netlink.Link) error {
return forEachLink(func(link netlink.Link) error {
if link.Attrs().MasterIndex == br.Attrs().Index {
peerIndex := link.Attrs().ParentIndex
if peerIndex == 0 {
// perhaps running on an older kernel where ParentIndex doesn't work.
// as fall-back, assume the indexes are consecutive
peerIndex = link.Attrs().Index - 1
}
indexes[peerIndex] = struct{}{}
}
return nil
})
})
if err != nil {
return nil, err
}
return func(link netlink.Link) bool {
_, isveth := link.(*netlink.Veth)
_, found := indexes[link.Attrs().Index]
return isveth && found
}, nil
}
func GetNetDevsWithPredicate(processID int, predicate func(link netlink.Link) bool) ([]NetDev, error) {
// Bail out if this container is running in the root namespace
nsToplevel, err := netns.GetFromPid(1)
if err != nil {
return nil, fmt.Errorf("unable to open root namespace: %s", err)
}
nsContainr, err := netns.GetFromPid(processID)
if err != nil {
return nil, fmt.Errorf("unable to open process %d namespace: %s", processID, err)
}
if nsToplevel.Equal(nsContainr) {
return nil, nil
}
return FindNetDevs(processID, predicate)
}
// Lookup the weave interface of a container
func GetWeaveNetDevs(processID int) ([]NetDev, error) {
p, err := ConnectedToBridgePredicate("weave")
if err != nil {
return nil, err
}
return GetNetDevsWithPredicate(processID, p)
}
// Get the weave bridge interface.
// NB: Should be called from the root network namespace.
func GetBridgeNetDev(bridgeName string) (NetDev, error) {
link, err := netlink.LinkByName(bridgeName)
if err != nil {
return NetDev{}, err
}
return linkToNetDev(link)
}
// Do post-attach configuration of all veths we have created
func ConfigureARPforVeths(processID int, prefix string) error {
_, err := FindNetDevs(processID, func(link netlink.Link) bool {
ifName := link.Attrs().Name
if strings.HasPrefix(ifName, prefix) {
weavenet.ConfigureARPCache(ifName)
if addrs, err := netlink.AddrList(link, netlink.FAMILY_V4); err == nil {
for _, addr := range addrs {
arping.GratuitousArpOverIfaceByName(addr.IPNet.IP, ifName)
}
}
}
return false
})
return err
}
+30 -5
View File
@@ -4,6 +4,7 @@ import (
"bytes"
"encoding/gob"
"fmt"
"time"
"github.com/boltdb/bolt"
)
@@ -23,14 +24,39 @@ var (
topBucket = []byte("top")
)
const (
NameIdent = "peername"
FileName = "data.db"
)
func NewBoltDB(dbPathname string) (*BoltDB, error) {
db, err := bolt.Open(dbPathname, 0660, nil)
if err != nil {
return nil, fmt.Errorf("[boltDB] Unable to open %s: %s", dbPathname, err)
}
// check the persistence version
err = db.Update(func(tx *bolt.Tx) error {
err = db.Update(checkVersion(false))
return &BoltDB{db: db}, err
}
func NewBoltDBReadOnly(dbPathname string) (*BoltDB, error) {
options := bolt.Options{Timeout: time.Millisecond * 50, ReadOnly: true}
db, err := bolt.Open(dbPathname, 0660, &options)
if err != nil {
return nil, fmt.Errorf("[boltDB] Unable to open %s: %s", dbPathname, err)
}
err = db.View(checkVersion(true))
if err != nil {
return nil, fmt.Errorf("[boltDB] Cannot use persistence file %s: %s", dbPathname, err)
}
return &BoltDB{db: db}, nil
}
func checkVersion(readOnly bool) func(tx *bolt.Tx) error {
return func(tx *bolt.Tx) error {
if top := tx.Bucket(topBucket); top == nil {
if readOnly {
return fmt.Errorf("no top bucket")
}
top, err := tx.CreateBucket(topBucket)
if err != nil {
return err
@@ -41,13 +67,12 @@ func NewBoltDB(dbPathname string) (*BoltDB, error) {
} else {
if checkVersion := top.Get(versionIdent); checkVersion != nil {
if checkVersion[0] != persistenceVersion[0] {
return fmt.Errorf("[boltDB] Cannot use persistence file %s - version %x", dbPathname, checkVersion)
return fmt.Errorf("mismatched version %x", checkVersion)
}
}
}
return nil
})
return &BoltDB{db: db}, err
}
}
func (d *BoltDB) Load(ident string, data interface{}) (bool, error) {
+155
View File
@@ -0,0 +1,155 @@
This document describes implementation details of the fast datapath encryption.
# Overview
At the high level, we use the ESP protocol ([RFC 2406][esp]) in the Transport
mode. Each packet is encrypted with AES in GCM mode ([RFC 4106][aesgcm]), with
32 byte key and 4 byte salt. This combo provides the following security
properties:
* Data confidentiality.
* Data origin authentication.
* Integrity.
* Anti-replay.
* Limited traffic flow confidentiality as fast datapath VXLAN packets are fully
encrypted.
## Notation
* `SAin`: IPsec security association for inbound connections.
* `SAout`: IPsec security association for outbound connections.
* `SPout`: IPsec security policy for outbound connections. Used to match
outbound flows to SAout.
## SA Key Derivation
For each connection direction, a different AES-GCM key and salt is used.
The pairs are derived with HKDF ([RFC 5869][hkdf]):
```
SAin[KeyAndSalt] = HKDF(sha256, ikm=sessionKey, salt=nonceIn, info=localPeerName)
SAout[KeyAndSalt] = HKDF(sha256, ikm=sessionKey, salt=nonceOut, info=remotePeerName)
```
Where:
* the mutual `sessionKey` is derived by the [Mesh][mesh] library during
the control plane connection establishment between the local peer and
the remote peer.
* `nonceIn` and `nonceOut` are randomly generated 32byte nonces which
are exchanged over the encrypted control plane channel.
## SPI
A directional secure connection between two peers is identified with SPI.
The kernel requires the pair of SPI and dst IP to be unique among security
associations. Thus, to avoid collisions, we generate outbound SPI on a remote
peer.
## Connection Establishment
```
Peer A Peer B
-----------------------------------------------------------------------------------------------------------------
fastdp.fwd.Confirm():
install iptables blocking rules, fastdp.fwd.Confirm():
nonce_BA = rand(), install iptables blocking rules,
{key,salt}_BA = hkdf(sessionKey, nonce_BA, A), nonce_AB = rand(),
spi_BA = allocspi(), {key,salt}_AB = hkdf(sessionKey, nonce_AB, B),
create SA_BA(B<-A, spi_BA, key_BA, salt_BA), spi_AB = allocspi(),
send InitSARemote(spi_BA, nonce_BA). --> create SA_AB(A<-B, spi_AB, key_AB, salt_AB),
<-- send InitSARemote(spi_AB, nonce_AB).
--> recv InitSARemote(spi_BA, nonce_BA):
recv InitSARemote(spi_AB, nonce_AB): <-- {key,salt}_BA = hkdf(sessionKey, nonce_BA, A),
{key,salt}_AB = hkdf(sessionKey, nonce_AB, B), create SA_BA(B<-A, spi_BA, key_BA, salt_BA),
create SA_AB(A<-B, spi_AB, key_AB, salt_AB), create SP_BA(B<-A, spi_BA),
create SP_AB(A<-B, spi_AB), install marking rule.
install marking rule.
```
# Implementation Details
## XFRM
The implementation is based on the kernel IP packet transformation framework
called XFRM. Unfortunately, docs are barely existing and the complexity of
the framework is high. The best resource I found is Chapter 10 in
"Linux Kernel Networking: Implementation and Theory" by Rami Rosen.
## iptables Rules
The kernel VXLAN driver does not set a dst port of a tunnel in the ip flow
descriptor, thus XFRM policy lookup cannot match a policy (SPout) which includes
the port. This makes impossible to encrypt only tunneled traffic between
peers. To work around, we mark such outgoing packets with iptables and set
the same mark in the policy selector (funnily enough, `iptables_mangle` module
eventually sets the missing dst port in the flow descriptor). The challenge
here is to pick a mark that it would not interfere with other networking
applications before OUTPUT'ing a packet. For example, Kubernetes by default
uses 1<<14 and 1<<15 marks and we choose 1<<17 (0x20000). Additionally,
such workaround brings the requirement for at least the 4.2 kernel.
The marking rules are the following:
```
iptables -t mangle -A OUTPUT -j WEAVE-IPSEC-OUT
iptables -t mangle -A WEAVE-IPSEC-OUT -s ${LOCAL_PEER_IP} -d ${REMOTE_PEER_IP} \
-p udp --dport ${TUNNEL_PORT} -j WEAVE-IPSEC-OUT-MARK
iptables -t mangle -A WEAVE-IPSEC-OUT-MARK --set-xmark ${MARK} -j MARK
```
As Linux does not implement [IP Security Levels][ipseclevel], we install
additional iptables rules to prevent from accidentally sending unencrypted
traffic between peers which have previously established the secure connection.
For inbound traffic, we mark each ESP packet with the mark and drop non-marked
tunnel traffic:
```
iptables -t mangle -A INPUT -j WEAVE-IPSEC-IN
iptables -t mangle -A WEAVE-IPSEC-IN -s ${REMOTE_PEER_IP} -d ${LOCAL_PEER_IP} \
-m esp --espspi ${SPIin} -j WEAVE-IPSEC-IN-MARK
iptables -t mangle -A WEAVE-IPSEC-IN-MARK --set-xmark ${MARK} -j MARK
iptables -t filter -A INPUT -j WEAVE-IPSEC-IN
iptables -t filter -A WEAVE-IPSEC-IN -s ${REMOTE_PEER_IP} -d ${LOCAL_PEER_IP} \
-p udp --dport ${TUNNEL_PORT} -m mark ! --mark ${MARK} -j DROP
```
For outbound traffic, we drop marked traffic which does not match any SPout:
```
iptables -t filter -A OUTPUT ! -p esp -m policy --dir out --pol none \
-m mark --mark ${MARK} -j DROP
```
## ESN
To prevent from cycling SeqNo which makes replay attacks possible, we use
64-bit extended sequence numbers known as [ESN](esn).
## MTU
In addition to the VXLAN overhead, the MTU calculation should take into account
the ESP overhead which is 34-37 bytes (encrypted Payload is 4 bytes aligned) and
consists of:
* 4 bytes (SPI).
* 4 bytes (Sequence Number).
* 8 bytes (ESP IV).
* 1 byte (Pad Length).
* 1 byte (NextHeader).
* 16 bytes (ICV).
* 0-3 bytes (Padding).
[esp]: https://tools.ietf.org/html/rfc2406
[aesgcm]: https://tools.ietf.org/html/rfc4106
[hkdf]: https://tools.ietf.org/html/rfc5869
[esn]: https://tools.ietf.org/html/rfc4304
[ipseclevel]: https://tools.ietf.org/html/draft-mcdonald-simple-ipsec-api-01)
[mesh]: https://github.com/weaveworks/mesh
+2 -2
View File
@@ -52,9 +52,9 @@ overlay, which has a more sophisticated dynamic mechanism for coping
with low path MTUs.
To avoid triggering this fallback in typical deployments, the datapath
interface is statically configured with an MTU of 1410 bytes allowing
interface is statically configured with an MTU of 1376 bytes allowing
it to work with most underlay network provider MTUs, including GCE at
1460 bytes (the fifty byte difference accommodates the vxlan overhead).
1460 bytes (the eighty four byte difference accommodates the encrypted vxlan overhead).
This value can be overridden by setting `WEAVE_MTU` at launch if
necessary.
+22 -6
View File
@@ -65,14 +65,30 @@ peer for space:
- it will continue to ask for space until it receives some, or its
copy of the ring tells it all peers are full in that subnet.
### Data persistence
Key IPAM data is saved to disk, in a [BoltDB](https://github.com/boltdb/bolt)
file, stored within a [data volume container](https://docs.docker.com/engine/userguide/containers/dockervolumes/#creating-and-mounting-a-data-volume-container)
named `weavedb`.
This file is used to persist data for various Weave Net components; for IPAM it contains:
* the division of the IP allocation range amongst peers, and
* allocation of addresses to containers on the local peer,
so that it is immediately available when the peer restarts.
### Claiming an address
If a Weave process is restarted, in most cases it will hear from
another peer which ranges it used to own, but it needs to know which
individual IP addresses are assigned to containers in order to avoid
giving the same address out in subsequent allocation requests. The
weave script invokes the `claim` command in `populate_ipam` to do
this.
If a Weave process is restarted,
- if `weavedb` is present, then it loads persisted IPAM data from there, as
described, in the previous section;
- else, it learns from other peers which ranges it used to own.
Weave Net then consults the allocator to know which individual IP addresses
are assigned to containers, and therefore avoid giving the same address out in
subsequent allocation requests.
When the Allocator is told to claim an address, there are four
possibilities:
+2
View File
@@ -138,6 +138,8 @@ Finally, for **Mainline** releases only:
published to https://www.weave.works
* Add the new version of `weave-net` to the checkpoint system at
https://checkpoint-api.weave.works/admin
* File a PR to update the version of the daemonset at
https://github.com/kubernetes/kops/tree/master/upup/models/cloudup/resources/addons/networking.weave
## Troubleshooting
+108
View File
@@ -0,0 +1,108 @@
# Overview
# ipsets
The policy controller maintains a number of ipsets which are
subsequently referred to by the iptables rules used to effect network
policy specifications. These ipsets are created, modified and
destroyed automatically in response to Pod, Namespace and
NetworkPolicy object updates from the k8s API server:
* A `hash:ip` set per namespace, containing the IP addresses of all
pods in that namespace
* A `list:set` per distinct (across all network policies in all
namespaces) namespace selector mentioned in a network policy,
containing the names of any of the above hash:ip sets whose
corresponding namespace labels match the selector
* A `hash:ip` set for each distinct (within the scope of the
containing network policy's namespace) pod selector mentioned in a
network policy, containing the IP addresses of all pods in the
namespace whose labels match that selector
IPsets are implemented by the kernel module `xt_set`, without which
weave-npc will not work.
ipset names are generated deterministically from a string
representation of the corresponding label selector. Because ipset
names are limited to 31 characters in length, this is done by taking a
SHA hash of the selector string and then printing that out as a base
85 string with a "weave-" prefix e.g.:
weave-k?Z;25^M}|1s7P3|H9i;*;MhG
Because pod selectors are scoped to a namespace, we need to make sure
that if the same selector definition is used in different namespaces
that we maintain distinct ipsets. Consequently, for such selectors the
namespace name is prepended to the label selector string before
hashing to avoid clashes.
# iptables chains
The policy controller maintains two iptables chains in response to
changes to pods, namespaces and network policies. One chain contains
the ingress rules that implement the network policy specifications,
and the other is used to bypass the ingress rules for namespaces which
have an ingress isolation policy of `DefaultAllow`.
## Dynamically maintained `WEAVE-NPC-DEFAULT` chain
The policy controller maintains a rule in this chain for every
namespace whose ingress isolation policy is `DefaultAllow`. The
purpose of this rule is simply to ACCEPT any traffic destined for such
namespaces before it reaches the ingress chain.
```
iptables -A WEAVE-NPC-DEFAULT -m set --match-set $NSIPSET dst -j ACCEPT
```
## Dynamically maintained `WEAVE-NPC-INGRESS` chain
For each namespace network policy ingress rule peer/port combination:
```
iptables -A WEAVE-NPC-INGRESS -p $PROTO [-m set --match-set $SRCSET] -m set --match-set $DSTSET --dport $DPORT -j ACCEPT
```
## Static `WEAVE-NPC` chain
Static configuration:
```
iptables -A WEAVE-NPC -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A WEAVE-NPC -m state --state NEW -j WEAVE-NPC-DEFAULT
iptables -A WEAVE-NPC -m state --state NEW -j WEAVE-NPC-INGRESS
```
# Steering traffic into the policy engine
To direct traffic into the policy engine:
```
iptables -A FORWARD -o weave -m physdev ! --physdev-out vethwe-bridge -j WEAVE-NPC
iptables -A FORWARD -o weave -m physdev ! --physdev-out vethwe-bridge -j DROP
```
Note this only affects traffic which egresses the bridge on a physical
port which is not the Weave Net router - in other words, it is
destined for an application container veth. The following traffic is
affected:
* Traffic bridged between local application containers
* Traffic bridged from the router to a local application container
* Traffic originating from the internet destined for nodeports - this
is routed via the FORWARD chain to a container pod IP after DNAT
The following traffic is NOT affected:
* Traffic bridged from a local application container to the router
* Traffic originating from processes in the host network namespace
(e.g. kubelet health checks)
* Traffic routed from an application container to the internet
The above mechanism relies on the kernel module `br_netfilter` being
loaded and enabled via `/proc/sys/net/bridge/bridge-nf-call-iptables`.
See these resources for helpful context:
* http://ebtables.netfilter.org/br_fw_ia/br_fw_ia.html
* https://commons.wikimedia.org/wiki/File:Netfilter-packet-flow.svg
+4 -3
View File
@@ -3,6 +3,7 @@ package ipam
import (
"fmt"
"github.com/weaveworks/weave/api"
"github.com/weaveworks/weave/net/address"
)
@@ -13,9 +14,9 @@ type allocateResult struct {
type allocate struct {
resultChan chan<- allocateResult
ident string
ident string // a container ID, something like "weave:expose", or api.NoContainerID
r address.CIDR // Subnet we are trying to allocate within
isContainer bool
isContainer bool // true if ident is a container ID
hasBeenCancelled func() bool
}
@@ -43,7 +44,7 @@ func (g *allocate) Try(alloc *Allocator) bool {
if ok, addr := alloc.space.Allocate(g.r.HostRange()); ok {
// If caller hasn't supplied a unique ID, file it under the IP address
// which lets the caller then release the address using DELETE /ip/address
if g.ident == "_" {
if g.ident == api.NoContainerID {
g.ident = addr.String()
}
alloc.debugln("Allocated", addr, "for", g.ident, "in", g.r)
+36 -12
View File
@@ -76,6 +76,13 @@ type Allocator struct {
now func() time.Time
}
// PreClaims are IP addresses discovered before we could initialize IPAM
type PreClaim struct {
Ident string // a container ID, something like "weave:expose", or api.NoContainerID
IsContainer bool // true if Ident is a container ID
Cidr address.CIDR
}
type Config struct {
OurName mesh.PeerName
OurUID mesh.PeerUID
@@ -83,6 +90,7 @@ type Config struct {
Seed []mesh.PeerName
Universe address.CIDR
IsObserver bool
PreClaims []PreClaim
Quorum func() uint
Db db.DB
IsKnownPeer func(name mesh.PeerName) bool
@@ -123,6 +131,12 @@ func NewAllocator(config Config) *Allocator {
dead: make(map[string]time.Time),
now: time.Now,
}
alloc.pendingClaims = make([]operation, len(config.PreClaims))
for i, c := range config.PreClaims {
alloc.pendingClaims[i] = &claim{ident: c.Ident, cidr: c.Cidr}
}
return alloc
}
@@ -156,6 +170,9 @@ func (alloc *Allocator) Start() {
default:
alloc.infof("Initialising as observer - awaiting IPAM data from another peer")
}
if loadedPersistedData { // do any pre-claims right away
alloc.tryOps(&alloc.pendingClaims)
}
actionChan := make(chan func(), mesh.ChannelSize)
stopChan := make(chan struct{})
alloc.actionChan = actionChan
@@ -193,9 +210,9 @@ func (alloc *Allocator) doOperation(op operation, ops *[]operation) {
// already succeeded. If it is on the queue, we call
// cancel on it, allowing callers waiting for the resultChans
// to unblock.
func (alloc *Allocator) cancelOp(op operation, ops *[]operation) {
func (alloc *Allocator) cancelOp(opToCancel operation, ops *[]operation) {
for i, op := range *ops {
if op == op {
if op == opToCancel {
*ops = append((*ops)[:i], (*ops)[i+1:]...)
op.Cancel()
break
@@ -248,6 +265,10 @@ func (alloc *Allocator) tryPendingOps() {
alloc.tryOps(&alloc.pendingAllocates)
}
func (alloc *Allocator) havePendingOps() bool {
return len(alloc.pendingPrimes)+len(alloc.pendingClaims)+len(alloc.pendingAllocates) > 0
}
func (alloc *Allocator) spaceRequestDenied(sender mesh.PeerName, r address.Range) {
for i := 0; i < len(alloc.pendingClaims); {
claim := alloc.pendingClaims[i].(*claim)
@@ -322,7 +343,7 @@ func (alloc *Allocator) Claim(ident string, cidr address.CIDR, isContainer, noEr
// ContainerDied called from the updater interface. Async.
func (alloc *Allocator) ContainerDied(ident string) {
alloc.actionChan <- func() {
if alloc.hasOwned(ident) {
if alloc.hasOwnedByContainer(ident) {
alloc.debugln("Container", ident, "died; noting to remove later")
alloc.dead[ident] = alloc.now()
}
@@ -335,7 +356,7 @@ func (alloc *Allocator) ContainerDied(ident string) {
// ContainerDestroyed called from the updater interface. Async.
func (alloc *Allocator) ContainerDestroyed(ident string) {
alloc.actionChan <- func() {
if alloc.hasOwned(ident) {
if alloc.hasOwnedByContainer(ident) {
alloc.debugln("Container", ident, "destroyed; removing addresses")
alloc.delete(ident)
delete(alloc.dead, ident)
@@ -679,8 +700,12 @@ func (alloc *Allocator) actorLoop(actionChan <-chan func(), stopChan <-chan stru
// Retry things in case messages got lost between here and recipients
if alloc.awaitingConsensus {
alloc.propose()
} else {
alloc.tryPendingOps()
} else if alloc.havePendingOps() {
if alloc.ring.Empty() {
alloc.establishRing()
} else {
alloc.tryPendingOps()
}
}
alloc.removeDeadContainers()
}
@@ -920,13 +945,12 @@ func (alloc *Allocator) reportFreeSpace() {
// Persistent data
const (
ringIdent = "ring"
nameIdent = "peername"
ownedIdent = "ownedAddresses"
)
func (alloc *Allocator) persistRing() {
// It would be better if these two Save operations happened in the same transaction
if err := alloc.db.Save(nameIdent, alloc.ourName); err != nil {
if err := alloc.db.Save(db.NameIdent, alloc.ourName); err != nil {
alloc.fatalf("Error persisting ring data: %s", err)
return
}
@@ -938,7 +962,7 @@ func (alloc *Allocator) persistRing() {
// Returns true if persisted data is to be used, otherwise false
func (alloc *Allocator) loadPersistedData() bool {
var checkPeerName mesh.PeerName
nameFound, err := alloc.db.Load(nameIdent, &checkPeerName)
nameFound, err := alloc.db.Load(db.NameIdent, &checkPeerName)
if err != nil {
alloc.fatalf("Error loading persisted peer name: %s", err)
}
@@ -996,9 +1020,9 @@ func (alloc *Allocator) persistOwned() {
// Owned addresses
func (alloc *Allocator) hasOwned(ident string) bool {
_, b := alloc.owned[ident]
return b
func (alloc *Allocator) hasOwnedByContainer(ident string) bool {
d, b := alloc.owned[ident]
return b && d.IsContainer
}
// NB: addr must not be owned by ident already
+31 -2
View File
@@ -9,6 +9,7 @@ import (
"github.com/stretchr/testify/require"
"github.com/weaveworks/weave/api"
"github.com/weaveworks/weave/common"
"github.com/weaveworks/weave/net/address"
"github.com/weaveworks/weave/testing/gossip"
@@ -30,6 +31,10 @@ func (alloc *Allocator) SimplyClaim(ident string, cidr address.CIDR) error {
return alloc.Claim(ident, cidr, true, true, returnFalse)
}
func (alloc *Allocator) AnonymousClaim(cidr address.CIDR) error {
return alloc.Claim(api.NoContainerID, cidr, false, true, returnFalse)
}
func TestAllocFree(t *testing.T) {
const (
container1 = "abcdef"
@@ -168,11 +173,15 @@ func TestAllocatorClaim(t *testing.T) {
container1 = "abcdef"
container3 = "b01df00d"
universe = "10.0.3.0/24"
testAddr1 = "10.0.3.2/24"
testAddr1 = "10.0.3.5/24"
testAddr2 = "10.0.4.2/24"
testAddr4 = "10.0.2.3/23"
subnet4 = "10.0.2.0/23"
testPre = "10.0.3.1/24"
)
allocs, router, subnet := makeNetworkOfAllocators(2, universe)
preAddr, _ := address.ParseCIDR(testPre)
allocs, router, subnet := makeNetworkOfAllocators(2, universe, []PreClaim{{container1, true, preAddr}})
defer stopNetworkOfAllocators(allocs, router)
alloc := allocs[1]
addr1, _ := address.ParseCIDR(testAddr1)
@@ -184,6 +193,9 @@ func TestAllocatorClaim(t *testing.T) {
alloc.Prime()
// Do an allocate on the other peer, which we will try to claim later
addrx, err := allocs[0].Allocate(container1, subnet, true, returnFalse)
require.NoError(t, err)
// Should not get the address we pre-claimed
require.NotEqual(t, addrx, preAddr)
router.Flush()
// Now try the claim again
@@ -198,13 +210,30 @@ func TestAllocatorClaim(t *testing.T) {
// claim for a different container should fail
err = alloc.SimplyClaim(container1, addr1)
require.Error(t, err)
// claim for an anonymous container, will assume it's the same one
err = alloc.AnonymousClaim(addr1)
require.NoError(t, err)
// claiming the address allocated on the other peer should fail
err = alloc.SimplyClaim(container1, address.MakeCIDR(subnet, addrx))
require.Error(t, err, "claiming address allocated on other peer should fail")
// claiming the pre-claimed address should fail on both peers
err = alloc.SimplyClaim(container3, preAddr)
require.Error(t, err, "claiming address allocated on other peer should fail")
err = allocs[0].SimplyClaim(container3, preAddr)
require.Error(t, err, "claiming address allocated on other peer should fail")
// Check an address outside of our universe
addr2, _ := address.ParseCIDR(testAddr2)
err = alloc.SimplyClaim(container1, addr2)
require.NoError(t, err)
err = alloc.SimplyClaim(container3, addr2)
require.Error(t, err)
// Anonymous claim outside of our universe
addr4, _ := address.ParseCIDR(testAddr4)
subnet4cidr, _ := address.ParseCIDR(subnet4)
require.NoError(t, alloc.AnonymousClaim(addr4))
addr5, err := alloc.Allocate(api.NoContainerID, subnet4cidr, false, returnFalse)
require.NoError(t, err)
require.NotEqual(t, addr4.Start(), addr5)
}
func (alloc *Allocator) pause() func() {
+40 -16
View File
@@ -5,16 +5,17 @@ import (
"github.com/weaveworks/mesh"
"github.com/weaveworks/weave/api"
"github.com/weaveworks/weave/common"
"github.com/weaveworks/weave/net/address"
)
type claim struct {
resultChan chan<- error
ident string
cidr address.CIDR
isContainer bool
noErrorOnUnknown bool
ident string // a container ID, something like "weave:expose", or api.NoContainerID
cidr address.CIDR // single address being claimed
isContainer bool // true if ident is a container ID
noErrorOnUnknown bool // if false, error or block if we don't know; if true return ok but keep trying
hasBeenCancelled func() bool
}
@@ -34,15 +35,34 @@ func (c *claim) sendResult(result error) {
// Try returns true for success (or failure), false if we need to try again later
func (c *claim) Try(alloc *Allocator) bool {
if c.hasBeenCancelled() {
if c.hasBeenCancelled != nil && c.hasBeenCancelled() {
c.Cancel()
return true
}
addOwned := func() {
if c.ident == api.NoContainerID {
alloc.addOwned(c.cidr.Addr.String(), c.cidr, c.isContainer)
} else {
alloc.addOwned(c.ident, c.cidr, c.isContainer)
}
}
if !alloc.ring.Contains(c.cidr.Addr) {
// Address not within our universe; assume user knows what they are doing
alloc.infof("Address %s claimed by %s - not in our range", c.cidr, c.ident)
alloc.addOwned(c.ident, c.cidr, c.isContainer)
previousOwner := alloc.findOwner(c.cidr.Addr)
switch {
case previousOwner == "":
addOwned()
case previousOwner == c.ident: // already owned by this ID
case c.ident == api.NoContainerID: // already owned by anonymous container
// do nothing (no automatic fall-through in Go)
case !alloc.dead[previousOwner].IsZero(): // already owned by dead container
alloc.removeOwned(previousOwner, c.cidr.Addr)
addOwned()
default:
c.sendResult(fmt.Errorf("address %s already in use by %s", c.cidr, previousOwner))
}
c.sendResult(nil)
return true
}
@@ -77,26 +97,30 @@ func (c *claim) Try(alloc *Allocator) bool {
return false
}
if c.ident == "_" { // Special "I don't have a unique ID" identifier
c.ident = c.cidr.Addr.String()
}
// We are the owner, check we haven't given it to another container
switch existingIdent := alloc.findOwner(c.cidr.Addr); existingIdent {
case "":
existingIdent := alloc.findOwner(c.cidr.Addr)
switch {
case existingIdent == "":
// Unused address, we try to claim it:
if err := alloc.space.Claim(c.cidr.Addr); err == nil {
alloc.debugln("Claimed", c.cidr, "for", c.ident)
alloc.addOwned(c.ident, c.cidr, c.isContainer)
addOwned()
c.sendResult(nil)
} else {
c.sendResult(err)
}
case c.ident:
case (existingIdent == c.ident) || (c.ident == api.NoContainerID && existingIdent == c.cidr.Addr.String()):
// same identifier is claiming same address; that's OK
alloc.debugln("Re-Claimed", c.cidr, "for", c.ident)
c.sendResult(nil)
case c.cidr.Addr.String():
// Address already allocated via "_" name
case existingIdent == c.cidr.Addr.String():
// Address already allocated via api.NoContainerID name and current ID is a real container ID:
c.sendResult(fmt.Errorf("address %s already in use", c.cidr))
case c.ident == api.NoContainerID:
// We do not know whether this is the same container or another one,
// but we also cannot prove otherwise, so we let it reclaim the address:
alloc.debugln("Re-Claimed", c.cidr, "for ID", c.ident, "having existing ID as", existingIdent)
c.sendResult(nil)
default:
// Addr already owned by container on this machine
c.sendResult(fmt.Errorf("address %s is already owned by %s", c.cidr.String(), existingIdent))
-31
View File
@@ -1,31 +0,0 @@
package ring
/* Exported variables for monitoring and management */
import (
"expvar"
"strconv"
)
var (
expRingSize = expvar.NewMap("ipam.ringSize")
expRingEntries = expvar.NewMap("ipam.ringEntries")
)
type _int int
func (i _int) String() string {
return strconv.Itoa(int(i))
}
type _uint32 uint32
func (i _uint32) String() string {
return strconv.FormatUint(uint64(i), 10)
}
func (r *Ring) updateExportedVariables() {
ringName := r.Start.String()
expRingSize.Set(ringName, _uint32(r.End-r.Start))
expRingEntries.Set(ringName, _int(len(r.Entries)))
}
+2 -8
View File
@@ -41,8 +41,8 @@ var (
ErrNotSorted = errors.New("Ring not sorted")
ErrTokenRepeated = errors.New("Token appears twice in ring")
ErrTokenOutOfRange = errors.New("Token is out of range")
ErrDifferentSeeds = errors.New("Received ring was seeded differently from ours!")
ErrDifferentRange = errors.New("Received range differs from ours!")
ErrDifferentSeeds = errors.New("Received ring was seeded differently from ours")
ErrDifferentRange = errors.New("Received range differs from ours")
)
func errInconsistentEntry(mine, theirs *entry) error {
@@ -114,7 +114,6 @@ func New(start, end address.Address, peer mesh.PeerName, f OnUpdate) *Ring {
common.Assert(start < end)
ring := &Ring{Start: start, End: end, Peer: peer, Entries: make([]*entry, 0), onUpdate: f}
ring.updateExportedVariables()
return ring
}
@@ -151,7 +150,6 @@ func (r *Ring) GrantRangeToHost(start, end address.Address, peer mesh.PeerName)
r.assertInvariants()
defer r.trackUpdates()()
defer r.assertInvariants()
defer r.updateExportedVariables()
// ----------------- Start of Checks -----------------
@@ -218,7 +216,6 @@ func (r *Ring) GrantRangeToHost(start, end address.Address, peer mesh.PeerName)
func (r *Ring) Merge(gossip Ring) (bool, error) {
r.assertInvariants()
defer r.trackUpdates()()
defer r.updateExportedVariables()
// Don't panic when checking the gossiped in ring.
// In this case just return any error found.
@@ -404,7 +401,6 @@ func (r *Ring) ClaimForPeers(peers []mesh.PeerName) {
defer r.trackUpdates()()
defer r.assertInvariants()
defer r.updateExportedVariables()
defer func() {
e := r.Entries[len(r.Entries)-1]
common.Assert(address.Add(e.Token, address.Offset(e.Free)) == r.End)
@@ -455,7 +451,6 @@ func (r *Ring) String() string {
func (r *Ring) ReportFree(freespace map[address.Address]address.Count) (updated bool) {
r.assertInvariants()
defer r.assertInvariants()
defer r.updateExportedVariables()
common.Assert(!r.Empty())
entries := r.Entries
@@ -564,7 +559,6 @@ func (r *Ring) Transfer(from, to mesh.PeerName) []address.Range {
defer r.trackUpdates()()
defer r.trackUpdatesOfPeer(from)()
defer r.assertInvariants()
defer r.updateExportedVariables()
var newRanges []address.Range
+2 -2
View File
@@ -494,7 +494,7 @@ func TestTransfer(t *testing.T) {
ring1.ClaimItAll()
ring1.GrantRangeToHost(middle, end, peer2name)
ring1.Transfer(peer2name, peer1name)
require.Equal(t, []address.Range{{start, middle}, {middle, end}}, ring1.OwnedRanges())
require.Equal(t, []address.Range{{Start: start, End: middle}, {Start: middle, End: end}}, ring1.OwnedRanges())
// Second test is what happens when a token exists at the end of a range but is transferred
// - does it get resurrected correctly?
@@ -503,7 +503,7 @@ func TestTransfer(t *testing.T) {
ring1.GrantRangeToHost(middle, end, peer2name)
ring1.Transfer(peer2name, peer1name)
ring1.GrantRangeToHost(dot10, middle, peer2name)
require.Equal(t, []address.Range{{start, dot10}, {middle, end}}, ring1.OwnedRanges())
require.Equal(t, []address.Range{{Start: start, End: dot10}, {Start: middle, End: end}}, ring1.OwnedRanges())
}
func TestOwner(t *testing.T) {
+8
View File
@@ -88,6 +88,14 @@ func (s *Space) Claim(addr address.Address) error {
return nil
}
func (s *Space) NumOwnedAddresses() address.Count {
res := address.Count(0)
for i := 0; i < len(s.ours); i += 2 {
res += address.Length(s.ours[i+1], s.ours[i])
}
return res
}
func (s *Space) NumFreeAddresses() address.Count {
res := address.Count(0)
for i := 0; i < len(s.free); i += 2 {
+7 -2
View File
@@ -52,12 +52,12 @@ func TestLowlevel(t *testing.T) {
s := New()
require.Equal(t, address.Count(0), s.NumFreeAddresses())
ok, got := s.Allocate(address.NewRange(0, 1000))
ok, _ := s.Allocate(address.NewRange(0, 1000))
require.False(t, ok, "allocate in empty space should fail")
s.Add(100, 100)
require.Equal(t, address.Count(100), s.NumFreeAddresses())
ok, got = s.Allocate(address.NewRange(0, 1000))
ok, got := s.Allocate(address.NewRange(0, 1000))
require.True(t, ok && got == 100, "allocate")
require.Equal(t, address.Count(99), s.NumFreeAddresses())
require.NoError(t, s.Claim(150))
@@ -68,6 +68,7 @@ func TestLowlevel(t *testing.T) {
wt.AssertErrorInterface(t, (*error)(nil), s.Free(100), "double free")
r, ok := s.Donate(address.NewRange(0, 1000))
require.True(t, ok, "donate")
require.Equal(t, address.NewRange(0xa0, 0x20), r, "donate")
// test Donate when addresses are scarce
@@ -78,6 +79,7 @@ func TestLowlevel(t *testing.T) {
require.NoError(t, s.Claim(0))
require.NoError(t, s.Claim(2))
r, ok = s.Donate(address.NewRange(0, 1000))
require.True(t, ok, "donate")
require.Equal(t, address.NewRange(1, 1), r, "donate")
r, ok = s.Donate(address.NewRange(0, 1000))
require.True(t, !ok, "donate should fail")
@@ -98,16 +100,19 @@ func TestSpaceAllocate(t *testing.T) {
space1 := makeSpace(start, size)
require.Equal(t, address.Count(20), space1.NumFreeAddresses())
require.Equal(t, address.Count(0), space1.NumOwnedAddresses())
space1.assertInvariants()
_, addr1 := space1.Allocate(address.NewRange(start, size))
require.Equal(t, testAddr1, addr1.String(), "address")
require.Equal(t, address.Count(19), space1.NumFreeAddresses())
require.Equal(t, address.Count(1), space1.NumOwnedAddresses())
space1.assertInvariants()
_, addr2 := space1.Allocate(address.NewRange(start, size))
require.False(t, addr2.String() == testAddr1, "address")
require.Equal(t, address.Count(18), space1.NumFreeAddresses())
require.Equal(t, address.Count(2), space1.NumOwnedAddresses())
require.Equal(t, address.Count(13), space1.NumFreeAddressesInRange(address.Range{Start: ip(testAddr1), End: ip(testAddrx)}))
require.Equal(t, address.Count(18), space1.NumFreeAddressesInRange(address.Range{Start: ip(testAddr1), End: ip(testAddry)}))
space1.assertInvariants()
+2
View File
@@ -10,6 +10,7 @@ type Status struct {
Paxos *paxos.Status
Range string
RangeNumIPs int
ActiveIPs int
DefaultSubnet string
Entries []EntryStatus
PendingClaims []ClaimStatus
@@ -52,6 +53,7 @@ func NewStatus(allocator *Allocator, defaultSubnet address.CIDR) *Status {
paxosStatus,
allocator.universe.String(),
int(allocator.universe.Size()),
int(allocator.space.NumOwnedAddresses()),
defaultSubnet.String(),
newEntryStatusSlice(allocator),
newClaimStatusSlice(allocator),
+8 -3
View File
@@ -128,7 +128,7 @@ type mockDB struct{}
func (d *mockDB) Load(_ string, _ interface{}) (bool, error) { return false, nil }
func (d *mockDB) Save(_ string, _ interface{}) error { return nil }
func makeAllocator(name string, cidrStr string, quorum uint) (*Allocator, address.CIDR) {
func makeAllocator(name string, cidrStr string, quorum uint, preClaims ...PreClaim) (*Allocator, address.CIDR) {
peername, err := mesh.PeerNameFromString(name)
if err != nil {
panic(err)
@@ -145,6 +145,7 @@ func makeAllocator(name string, cidrStr string, quorum uint) (*Allocator, addres
OurNickname: "nick-" + name,
Universe: cidr,
IsObserver: quorum == 0,
PreClaims: preClaims,
Quorum: func() uint { return quorum },
Db: new(mockDB),
IsKnownPeer: func(mesh.PeerName) bool { return true },
@@ -213,15 +214,19 @@ func AssertNothingSentErr(t *testing.T, ch <-chan error) {
}
}
func makeNetworkOfAllocators(size int, cidr string) ([]*Allocator, *gossip.TestRouter, address.CIDR) {
func makeNetworkOfAllocators(size int, cidr string, preClaims ...[]PreClaim) ([]*Allocator, *gossip.TestRouter, address.CIDR) {
gossipRouter := gossip.NewTestRouter(0.0)
allocs := make([]*Allocator, size)
var subnet address.CIDR
for i := 0; i < size; i++ {
var alloc *Allocator
preClaim := []PreClaim{}
if i < len(preClaims) {
preClaim = preClaims[i]
}
alloc, subnet = makeAllocator(fmt.Sprintf("%02d:00:00:02:00:00", i),
cidr, uint(size/2+1))
cidr, uint(size/2+1), preClaim...)
alloc.SetInterfaces(gossipRouter.Connect(alloc.ourName, alloc))
alloc.Start()
allocs[i] = alloc
+14 -7
View File
@@ -28,7 +28,7 @@ const (
)
type Upstream interface {
Config() *dns.ClientConfig
Config() (*dns.ClientConfig, error)
}
func NewUpstream(resolvConf, filterAddress string) Upstream {
@@ -48,27 +48,31 @@ type upstream struct {
lastModified time.Time
}
func (u *upstream) Config() *dns.ClientConfig {
func (u *upstream) Config() (*dns.ClientConfig, error) {
u.Lock()
defer u.Unlock()
// If we checked less than five seconds ago return what we already have
now := time.Now()
if now.Sub(u.lastStat) < 5*time.Second {
return u.cachedConfig
return u.cachedConfig, nil
}
u.lastStat = now
// Reread file if it has changed
if fi, err := os.Stat(u.resolvConf); err == nil && fi.ModTime() != u.lastModified {
if fi, err := os.Stat(u.resolvConf); err != nil {
return u.cachedConfig, err
} else if fi.ModTime() != u.lastModified {
if config, err := dns.ClientConfigFromFile(u.resolvConf); err == nil {
config.Servers = filter(config.Servers, u.filterAddress)
u.lastModified = fi.ModTime()
u.cachedConfig = config
} else {
return u.cachedConfig, err
}
}
return u.cachedConfig
return u.cachedConfig, nil
}
func filter(ss []string, s string) []string {
@@ -218,7 +222,7 @@ func (h *handler) handleReverse(w dns.ResponseWriter, req *dns.Msg) {
return
}
ipStr := strings.TrimSuffix(req.Question[0].Name, "."+reverseDNSdomain)
ipStr := strings.TrimSuffix(strings.ToLower(req.Question[0].Name), "."+reverseDNSdomain)
ip, err := address.ParseIP(ipStr)
if err != nil {
h.nameError(w, req)
@@ -257,7 +261,10 @@ func (h *handler) handleRecursive(w dns.ResponseWriter, req *dns.Msg) {
}
}
upstreamConfig := h.upstream.Config()
upstreamConfig, err := h.upstream.Config()
if err != nil {
h.ns.errorf("unable to read upstream config: %s", err)
}
for _, server := range upstreamConfig.Servers {
reqCopy := req.Copy()
reqCopy.Id = dns.Id()
+2 -2
View File
@@ -19,8 +19,8 @@ type mockUpstream struct {
config *dns.ClientConfig
}
func (mu *mockUpstream) Config() *dns.ClientConfig {
return mu.config
func (mu *mockUpstream) Config() (*dns.ClientConfig, error) {
return mu.config, nil
}
func startServer(t *testing.T, upstream *dns.ClientConfig) (*DNSServer, *Nameserver, int, int) {
+1 -1
View File
@@ -120,7 +120,7 @@ func (e1 *Entry) tombstone() bool {
func check(es SortableEntries) error {
if !sort.IsSorted(es) {
return fmt.Errorf("Not sorted!")
return fmt.Errorf("Not sorted")
}
for i := 1; i < es.Len(); i++ {
if es.Get(i).equal(es.Get(i - 1)) {
+2 -1
View File
@@ -36,9 +36,10 @@ func NewStatus(ns *Nameserver, dnsServer *DNSServer) *Status {
entry.Tombstone})
}
upstreamConfig, _ := dnsServer.upstream.Config()
return &Status{
dnsServer.domain,
dnsServer.upstream.Config().Servers,
upstreamConfig.Servers,
dnsServer.address,
dnsServer.ttl,
entryStatusSlice}
+57
View File
@@ -1,6 +1,10 @@
package net
import (
"fmt"
"net"
"github.com/Sirupsen/logrus"
"github.com/vishvananda/netlink"
)
@@ -51,3 +55,56 @@ func isDatapath(link netlink.Link) bool {
return false
}
}
func DetectHairpin(portIfName string, log *logrus.Logger) error {
link, err := netlink.LinkByName(portIfName)
if err != nil {
return fmt.Errorf("Unable to find link %q: %s", portIfName, err)
}
ch := make(chan netlink.LinkUpdate)
// See EnsureInterface for why done channel is not passed
if err := netlink.LinkSubscribe(ch, nil); err != nil {
return fmt.Errorf("Unable to subscribe to netlink updates: %s", err)
}
pi, err := netlink.LinkGetProtinfo(link)
if err != nil {
return fmt.Errorf("Unable to get link protinfo %q: %s", portIfName, err)
}
if pi.Hairpin {
return fmt.Errorf("Hairpin mode enabled on %q", portIfName)
}
go func() {
for up := range ch {
if up.Attrs().Name == portIfName && up.Attrs().Protinfo != nil &&
up.Attrs().Protinfo.Hairpin {
log.Errorf("Hairpin mode enabled on %q", portIfName)
}
}
}()
return nil
}
var ErrBridgeNoIP = fmt.Errorf("Bridge has no IP address")
func FindBridgeIP(bridgeName string, subnet *net.IPNet) (net.IP, error) {
netdev, err := GetBridgeNetDev(bridgeName)
if err != nil {
return nil, fmt.Errorf("Failed to get netdev for %q bridge: %s", bridgeName, err)
}
if len(netdev.CIDRs) == 0 {
return nil, ErrBridgeNoIP
}
if subnet != nil {
for _, cidr := range netdev.CIDRs {
if subnet.Contains(cidr.IP) {
return cidr.IP, nil
}
}
}
// No subnet, or none in the required subnet; just return the first one
return netdev.CIDRs[0].IP, nil
}
+20 -12
View File
@@ -6,6 +6,7 @@ import "unsafe"
const (
SIOCETHTOOL = 0x8946 // linux/sockios.h
ETHTOOL_GTXCSUM = 0x00000016 // linux/ethtool.h
ETHTOOL_STXCSUM = 0x00000017 // linux/ethtool.h
IFNAMSIZ = 16 // linux/if.h
)
@@ -22,31 +23,38 @@ type EthtoolValue struct {
Data uint32
}
func ioctlEthtool(fd int, argp uintptr) error {
_, _, errno := syscall.RawSyscall(syscall.SYS_IOCTL, uintptr(fd), uintptr(SIOCETHTOOL), argp)
if errno != 0 {
return errno
}
return nil
}
// Disable TX checksum offload on specified interface
func EthtoolTXOff(name string) error {
if len(name)+1 > IFNAMSIZ {
return fmt.Errorf("name too long")
}
value := EthtoolValue{ETHTOOL_STXCSUM, 0}
request := IFReqData{Data: uintptr(unsafe.Pointer(&value))}
copy(request.Name[:], name)
socket, err := syscall.Socket(syscall.AF_INET, syscall.SOCK_DGRAM, 0)
if err != nil {
return err
}
defer syscall.Close(socket)
_, _, errno := syscall.RawSyscall(syscall.SYS_IOCTL,
uintptr(socket),
uintptr(SIOCETHTOOL),
uintptr(unsafe.Pointer(&request)))
// Request current value
value := EthtoolValue{Cmd: ETHTOOL_GTXCSUM}
request := IFReqData{Data: uintptr(unsafe.Pointer(&value))}
copy(request.Name[:], name)
if errno != 0 {
return errno
if err := ioctlEthtool(socket, uintptr(unsafe.Pointer(&request))); err != nil {
return err
}
if value.Data == 0 { // if already off, don't try to change
return nil
}
return nil
value = EthtoolValue{ETHTOOL_STXCSUM, 0}
return ioctlEthtool(socket, uintptr(unsafe.Pointer(&request)))
}
+562
View File
@@ -0,0 +1,562 @@
// package IPsec provides primitives for establishing IPsec in the fastdp mode.
package ipsec
import (
"crypto/rand"
"crypto/sha256"
"encoding/binary"
"fmt"
"io"
"net"
"strconv"
"sync"
"syscall"
"github.com/Sirupsen/logrus"
"github.com/coreos/go-iptables/iptables"
"github.com/pkg/errors"
"github.com/vishvananda/netlink"
"golang.org/x/crypto/hkdf"
"github.com/weaveworks/mesh"
)
const (
keySize = 36 // AES-GCM key 32 bytes + 4 bytes salt
nonceSize = 32 // HKDF nonce size
mark = uint32(0x1) << 17 // iptables marks
markStr = "0x20000/0x20000" // update if the above mark changes
tableMangle = "mangle"
tableFilter = "filter"
chainIn = "WEAVE-IPSEC-IN"
chainInMark = "WEAVE-IPSEC-IN-MARK"
chainOut = "WEAVE-IPSEC-OUT"
chainOutMark = "WEAVE-IPSEC-OUT-MARK"
)
type SPI uint32
// Used to identify:
// - directional SPIs,
// - ipsec establishments.
type spiID [24]byte
func getSPIId(srcPeer, dstPeer mesh.PeerName, connUID uint64) (id spiID) {
binary.BigEndian.PutUint64(id[:], uint64(srcPeer))
binary.BigEndian.PutUint64(id[8:], uint64(dstPeer))
binary.BigEndian.PutUint64(id[16:], connUID)
return
}
type spiInfo struct {
spi SPI
isDirOut bool
}
// IPSec
type IPSec struct {
sync.RWMutex
ipt *iptables.IPTables
log *logrus.Logger
spiInfo map[spiID]spiInfo
// A reference to spiInfo; spiInfo might be of an expired SPI.
spis map[SPI]*spiInfo
}
func New(log *logrus.Logger) (*IPSec, error) {
ipt, err := iptables.New()
if err != nil {
return nil, errors.Wrap(err, "iptables new")
}
ipsec := &IPSec{
ipt: ipt,
log: log,
spiInfo: make(map[spiID]spiInfo),
spis: make(map[SPI]*spiInfo),
}
return ipsec, nil
}
// InitSALocal initializes inbound ipsec from remotePeer and triggers
// the initialization on remotePeer.
func (ipsec *IPSec) InitSALocal(localPeer, remotePeer mesh.PeerName, connUID uint64, localIP, remoteIP net.IP, udpPort int, sessionKey *[32]byte, initRemote func([]byte) error) error {
// ID of inbound SPI
spiID := getSPIId(remotePeer, localPeer, connUID)
ipsec.Lock()
defer ipsec.Unlock()
// Derive SA key
nonce, err := genNonce()
if err != nil {
return errors.Wrap(err, "generate nonce")
}
key, err := deriveKey(sessionKey[:], nonce, localPeer)
if err != nil {
return errors.Wrap(err, "derive key")
}
// Allocate SA
sa, err := netlink.XfrmStateAllocSpi(xfrmAllocSpiState(remoteIP, localIP))
if err != nil {
return errors.Wrap(err, fmt.Sprintf("ip xfrm state allocspi (in, %s, %s)", remoteIP, localIP))
}
// Use SPI generated by the kernel. The kernel ensures {dstIP, spi} to
// be unique.
spi := SPI(sa.Spi)
ipsec.log.Infof("ipsec: InitSALocal: %s -> %s :%d 0x%x", remoteIP, localIP, udpPort, spi)
// Create SA
if sa, err := xfrmState(remoteIP, localIP, spi, false, key); err == nil {
if err := netlink.XfrmStateUpdate(sa); err != nil {
return errors.Wrap(err, fmt.Sprintf("xfrm state update (in, %s, %s, 0x%x)", sa.Src, sa.Dst, sa.Spi))
}
} else {
return errors.Wrap(err, "new xfrm state (in)")
}
// Install iptables rules
if err := ipsec.installDropNonEncrypted(localIP, remoteIP, udpPort, spi); err != nil {
return errors.Wrap(err, fmt.Sprintf("install protecting rules (%s, %s, %d, 0x%x)", localIP, remoteIP, udpPort, spi))
}
si := spiInfo{spi: spi, isDirOut: false}
ipsec.spiInfo[spiID] = si
ipsec.spis[spi] = &si
// Trigger the initialization on the remote peer
msg := &msgInitSARemote{nonce, spi}
if err := initRemote(msg.serialize()); err != nil {
return errors.Wrap(err, "send InitSARemote")
}
return nil
}
// InitSARemote initializes outbound ipsec to remotePeer.
// Triggered by remotePeer.
func (ipsec *IPSec) InitSARemote(msgInitSARemote []byte, localPeer, remotePeer mesh.PeerName, connUID uint64, localIP, remoteIP net.IP, udpPort int, sessionKey *[32]byte) error {
// ID of outbound SPI
spiID := getSPIId(localPeer, remotePeer, connUID)
msg, err := deserializeMsgInitSARemote(msgInitSARemote)
if err != nil {
return errors.Wrap(err, "deserialize InitSARemote")
}
spi := msg.spi
ipsec.Lock()
defer ipsec.Unlock()
ipsec.log.Infof("ipsec: InitSARemote: %s -> %s :%d 0x%x", localIP, remoteIP, udpPort, spi)
// Derive SA key by using the received nonce
key, err := deriveKey(sessionKey[:], msg.nonce, remotePeer)
if err != nil {
return errors.Wrap(err, "derive key")
}
// Create SA
if sa, err := xfrmState(localIP, remoteIP, spi, true, key); err == nil {
if err := netlink.XfrmStateAdd(sa); err != nil {
return errors.Wrap(err, fmt.Sprintf("xfrm state update (out, %s, %s, 0x%x)", sa.Src, sa.Dst, sa.Spi))
}
} else {
return errors.Wrap(err, "new xfrm state (out)")
}
// Create or update SP
sp := xfrmPolicy(localIP, remoteIP, spi)
if err := netlink.XfrmPolicyUpdate(sp); err != nil {
return errors.Wrap(err, fmt.Sprintf("xfrm policy update (%s, %s, 0x%x)", localIP, remoteIP, spi))
}
si := spiInfo{spi: spi, isDirOut: true}
ipsec.spiInfo[spiID] = si
ipsec.spis[spi] = &si
return nil
}
// Destroy destroys any (inbound / outbound) ipsec establishment between the peers.
func (ipsec *IPSec) Destroy(localPeer, remotePeer mesh.PeerName, connUID uint64, localIP, remoteIP net.IP, udpPort int) error {
outSPIID := getSPIId(localPeer, remotePeer, connUID)
inSPIID := getSPIId(remotePeer, localPeer, connUID)
ipsec.Lock()
defer ipsec.Unlock()
// Destroy inbound
if inSPIInfo, ok := ipsec.spiInfo[inSPIID]; ok {
ipsec.log.Infof("ipsec: destroy: in %s -> %s 0x%x", remoteIP, localIP, inSPIInfo.spi)
inSPI := inSPIInfo.spi
inSA := &netlink.XfrmState{
Src: remoteIP,
Dst: localIP,
Proto: netlink.XFRM_PROTO_ESP,
Spi: int(inSPI),
}
if err := netlink.XfrmStateDel(inSA); err != nil {
ipsec.log.Warnf("ipsec: xfrm state del (in, %s, %s, 0x%x) failed: %s", inSA.Src, inSA.Dst, inSA.Spi, err)
}
if err := ipsec.removeDropNonEncrypted(localIP, remoteIP, udpPort, inSPI); err != nil {
ipsec.log.Warnf("ipsec: remove protecting rules (%s, %s, %d, 0x%x) failed: %s", localIP, remoteIP, udpPort, inSPI, err)
}
delete(ipsec.spiInfo, inSPIID)
delete(ipsec.spis, inSPI)
}
// Destroy outbound
if outSPIInfo, ok := ipsec.spiInfo[outSPIID]; ok {
ipsec.log.Infof("ipsec: destroy: out %s -> %s 0x%x", localIP, remoteIP, outSPIInfo.spi)
if err := netlink.XfrmPolicyDel(xfrmPolicy(localIP, remoteIP, outSPIInfo.spi)); err != nil {
ipsec.log.Warnf("ipsec: xfrm policy del (%s, %s, 0x%x) failed: %s", localIP, remoteIP, outSPIInfo.spi, err)
}
outSA := &netlink.XfrmState{
Src: localIP,
Dst: remoteIP,
Proto: netlink.XFRM_PROTO_ESP,
Spi: int(outSPIInfo.spi),
}
if err := netlink.XfrmStateDel(outSA); err != nil {
ipsec.log.Warnf("ipsec: xfrm state del (out, %s, %s, 0x%x) failed: %s", outSA.Src, outSA.Dst, outSA.Spi, err)
}
delete(ipsec.spiInfo, outSPIID)
delete(ipsec.spis, outSPIInfo.spi)
}
return nil
}
// Flush removes all policies/SAs established by us. Also, it removes chains and
// rules of iptables.
//
// If destroy is true, the chains and the rules won't be re-created.
func (ipsec *IPSec) Flush(destroy bool) error {
ipsec.Lock()
defer ipsec.Unlock()
policies, err := netlink.XfrmPolicyList(syscall.AF_INET)
if err != nil {
return errors.Wrap(err, "xfrm policy list")
}
for _, p := range policies {
if p.Mark != nil && p.Mark.Value == mark && len(p.Tmpls) != 0 {
spi := SPI(p.Tmpls[0].Spi)
if err := netlink.XfrmPolicyDel(&p); err != nil {
return errors.Wrap(err, fmt.Sprintf("xfrm policy del (%s, %s, 0x%x)", p.Src, p.Dst, spi))
}
}
}
states, err := netlink.XfrmStateList(syscall.AF_INET)
if err != nil {
return errors.Wrap(err, "xfrm state list")
}
for _, s := range states {
if _, ok := ipsec.spis[SPI(s.Spi)]; ok {
if err := netlink.XfrmStateDel(&s); err != nil {
return errors.Wrap(err, fmt.Sprintf("xfrm state list (%s, %s, 0x%x)", s.Src, s.Dst, s.Spi))
}
}
}
if err := ipsec.resetIPTables(destroy); err != nil {
return errors.Wrap(err, "reset ip tables")
}
return nil
}
// iptables
type chain struct {
table string
chain string
}
type rule struct {
table string
chain string
rulespec []string
unique bool
}
func (ipsec *IPSec) clearChains(chains []chain) error {
for _, c := range chains {
if err := ipsec.ipt.ClearChain(c.table, c.chain); err != nil {
return errors.Wrap(err, fmt.Sprintf("iptables clear chain (%s, %s)", c.table, c.chain))
}
}
return nil
}
func (ipsec *IPSec) deleteChains(chains []chain) error {
for _, c := range chains {
if err := ipsec.ipt.DeleteChain(c.table, c.chain); err != nil {
return errors.Wrap(err, fmt.Sprintf("iptables delete chain (%s, %s)", c.table, c.chain))
}
}
return nil
}
func (ipsec *IPSec) resetRules(rules []rule, destroy bool) error {
for _, r := range rules {
ok, err := ipsec.ipt.Exists(r.table, r.chain, r.rulespec...)
if err != nil {
return errors.Wrap(err, fmt.Sprintf("iptables exists rule (%s, %s, %s)", r.table, r.chain, r.rulespec))
}
switch {
case !destroy && !ok:
if err := ipsec.ipt.Append(r.table, r.chain, r.rulespec...); err != nil {
return errors.Wrap(err, fmt.Sprintf("iptables append rule (%s, %s, %s)", r.table, r.chain, r.rulespec))
}
case destroy && ok:
if err := ipsec.ipt.Delete(r.table, r.chain, r.rulespec...); err != nil {
return errors.Wrap(err, fmt.Sprintf("iptables delete rule (%s, %s, %s)", r.table, r.chain, r.rulespec))
}
}
}
return nil
}
func (ipsec *IPSec) resetIPTables(destroy bool) error {
chains := []chain{
{tableMangle, chainIn},
{tableMangle, chainInMark},
{tableFilter, chainIn},
{tableMangle, chainOut},
{tableMangle, chainOutMark},
}
rules := []rule{
{tableMangle, "INPUT", []string{"-j", chainIn}, true},
{tableMangle, chainInMark, []string{"-j", "MARK", "--set-xmark", markStr}, true},
{tableFilter, "INPUT", []string{"-j", chainIn}, true},
{tableMangle, "OUTPUT", []string{"-j", chainOut}, true},
{tableMangle, chainOutMark, []string{"-j", "MARK", "--set-xmark", markStr}, true},
{tableFilter, "OUTPUT",
[]string{
"!", "-p", "esp",
"-m", "policy", "--dir", "out", "--pol", "none",
"-m", "mark", "--mark", markStr,
"-j", "DROP"}, true},
}
if err := ipsec.clearChains(chains); err != nil {
return err
}
if err := ipsec.resetRules(rules, destroy); err != nil {
return err
}
if destroy {
if err := ipsec.deleteChains(chains); err != nil {
return err
}
}
return nil
}
func ruleMarkInboundESP(srcIP, dstIP net.IP, inSPI SPI) rule {
return rule{tableMangle, chainIn,
[]string{
"-s", dstIP.String(), "-d", srcIP.String(),
"-p", "esp",
"-m", "esp", "--espspi", "0x" + strconv.FormatUint(uint64(inSPI), 16),
"-j", chainInMark,
}, true}
}
func rulesDropNonEncrypted(srcIP, dstIP net.IP, udpPort int, inSPI SPI) []rule {
udpPortStr := strconv.FormatUint(uint64(udpPort), 10)
return []rule{
ruleMarkInboundESP(srcIP, dstIP, inSPI),
{tableFilter, chainIn,
[]string{
"-s", dstIP.String(), "-d", srcIP.String(),
"-p", "udp", "--dport", udpPortStr,
"-m", "mark", "!", "--mark", markStr,
"-j", "DROP",
}, false},
{tableMangle, chainOut,
[]string{
"-s", srcIP.String(), "-d", dstIP.String(),
"-p", "udp", "--dport", udpPortStr,
"-j", chainOutMark,
}, false},
}
}
func (ipsec *IPSec) installDropNonEncrypted(srcIP, dstIP net.IP, udpPort int, inSPI SPI) error {
rules := rulesDropNonEncrypted(srcIP, dstIP, udpPort, inSPI)
for _, r := range rules {
appendFunc := ipsec.ipt.Append
if r.unique {
appendFunc = ipsec.ipt.AppendUnique
}
if err := appendFunc(r.table, r.chain, r.rulespec...); err != nil {
return errors.Wrap(err, fmt.Sprintf("iptables append (%s, %s, %s)", r.table, r.chain, r.rulespec))
}
}
return nil
}
func (ipsec *IPSec) removeDropNonEncrypted(srcIP, dstIP net.IP, udpPort int, inSPI SPI) error {
rules := rulesDropNonEncrypted(srcIP, dstIP, udpPort, inSPI)
if err := ipsec.resetRules(rules, true); err != nil {
return err
}
return nil
}
func (ipsec *IPSec) removeDropNonEncryptedInbound(srcIP, dstIP net.IP, inSPI SPI) error {
r := ruleMarkInboundESP(srcIP, dstIP, inSPI)
if err := ipsec.ipt.Delete(r.table, r.chain, r.rulespec...); err != nil {
return errors.Wrap(err, fmt.Sprintf("iptables delete unique (%s, %s, %s)", r.table, r.chain, r.rulespec))
}
return nil
}
// xfrm
func xfrmAllocSpiState(srcIP, dstIP net.IP) *netlink.XfrmState {
return &netlink.XfrmState{
Src: srcIP,
Dst: dstIP,
Proto: netlink.XFRM_PROTO_ESP,
Mode: netlink.XFRM_MODE_TRANSPORT,
ReplayWindow: 256,
ESN: true,
}
}
func xfrmState(srcIP, dstIP net.IP, spi SPI, isDirOut bool, key []byte) (*netlink.XfrmState, error) {
if len(key) != keySize {
return nil, fmt.Errorf("key should be %d bytes long", keySize)
}
state := xfrmAllocSpiState(srcIP, dstIP)
state.Spi = int(spi)
state.Aead = &netlink.XfrmStateAlgo{
Name: "rfc4106(gcm(aes))",
Key: key,
ICVLen: 128,
}
return state, nil
}
func xfrmPolicy(srcIP, dstIP net.IP, spi SPI) *netlink.XfrmPolicy {
ipMask := []byte{0xff, 0xff, 0xff, 0xff} // /32
return &netlink.XfrmPolicy{
Src: &net.IPNet{IP: srcIP, Mask: ipMask},
Dst: &net.IPNet{IP: dstIP, Mask: ipMask},
Proto: syscall.IPPROTO_UDP,
Dir: netlink.XFRM_DIR_OUT,
Mark: &netlink.XfrmMark{
Value: mark,
Mask: mark,
},
Tmpls: []netlink.XfrmPolicyTmpl{
{
Src: srcIP,
Dst: dstIP,
Proto: netlink.XFRM_PROTO_ESP,
Mode: netlink.XFRM_MODE_TRANSPORT,
Spi: int(spi),
},
},
}
}
// Key derivation
func genNonce() ([]byte, error) {
buf := make([]byte, nonceSize)
n, err := rand.Read(buf)
if err != nil {
return nil, fmt.Errorf("crypto rand failed: %s", err)
}
if n != nonceSize {
return nil, fmt.Errorf("not enough of random data: %d", n)
}
return buf, nil
}
func deriveKey(sessionKey []byte, nonce []byte, peerName mesh.PeerName) ([]byte, error) {
key := make([]byte, keySize)
info := make([]byte, 8)
binary.BigEndian.PutUint64(info, uint64(peerName))
hkdf := hkdf.New(sha256.New, sessionKey, nonce, info)
n, err := io.ReadFull(hkdf, key)
if err != nil {
return nil, err
}
if n != keySize {
return nil, fmt.Errorf("derived too short key: %d", n)
}
return key, nil
}
// Protocol Messages
type msgInitSARemote struct {
nonce []byte
spi SPI
}
func deserializeMsgInitSARemote(b []byte) (*msgInitSARemote, error) {
if len(b) == 0 {
return nil, fmt.Errorf("empty msg")
}
msg := &msgInitSARemote{}
if len(b) != msg.size() {
return nil, fmt.Errorf("invalid payload size: %d", len(b))
}
msg.nonce = make([]byte, nonceSize)
copy(msg.nonce, b[:nonceSize])
b = b[nonceSize:]
msg.spi = SPI(binary.BigEndian.Uint32(b))
return msg, nil
}
func (msg *msgInitSARemote) size() int {
return nonceSize + 32 // SPI
}
func (msg *msgInitSARemote) serialize() []byte {
b := make([]byte, msg.size())
copy(b[:nonceSize], msg.nonce)
binary.BigEndian.PutUint32(b[nonceSize:], uint32(msg.spi))
return b
}
+38
View File
@@ -0,0 +1,38 @@
package net
import (
"crypto/rand"
"crypto/sha256"
"net"
)
func RandomMAC() (net.HardwareAddr, error) {
mac := make([]byte, 6)
if _, err := rand.Read(mac); err != nil {
return nil, err
}
setUnicastAndLocal(mac)
return net.HardwareAddr(mac), nil
}
func MACfromUUID(uuid []byte) net.HardwareAddr {
hash := sha256.New()
// We salt the input just as a precaution to avoid clashes with
// other applications who might have had the bright idea of
// generating MACs in the same way.
hash.Write([]byte("9oBJ0Jmip-"))
hash.Write(uuid)
sum := hash.Sum(nil)
setUnicastAndLocal(sum)
return net.HardwareAddr(sum[:6])
}
// In the first byte of the MAC, the 'multicast' bit should be
// clear and 'locally administered' bit should be set.
func setUnicastAndLocal(mac []byte) {
mac[0] = (mac[0] & 0xFE) | 0x02
}
+116
View File
@@ -0,0 +1,116 @@
package net
import (
"encoding/json"
"fmt"
"net"
"os"
"strconv"
"github.com/vishvananda/netlink"
"github.com/vishvananda/netns"
)
type Dev struct {
Name string `json:"Name,omitempty"`
MAC net.HardwareAddr `json:"MAC,omitempty"`
CIDRs []*net.IPNet `json:"CIDRs,omitempty"`
}
func LinkToNetDev(link netlink.Link) (Dev, error) {
addrs, err := netlink.AddrList(link, netlink.FAMILY_V4)
if err != nil {
return Dev{}, err
}
netDev := Dev{Name: link.Attrs().Name, MAC: link.Attrs().HardwareAddr}
for _, addr := range addrs {
netDev.CIDRs = append(netDev.CIDRs, addr.IPNet)
}
return netDev, nil
}
// ConnectedToBridgeVethPeerIds returns peer indexes of veth links connected to
// the given bridge. The peer index is used to query from a container netns
// whether the container is connected to the bridge.
func ConnectedToBridgeVethPeerIds(bridgeName string) ([]int, error) {
var ids []int
br, err := netlink.LinkByName(bridgeName)
if err != nil {
return nil, err
}
links, err := netlink.LinkList()
if err != nil {
return nil, err
}
for _, link := range links {
if _, isveth := link.(*netlink.Veth); isveth && link.Attrs().MasterIndex == br.Attrs().Index {
peerID := link.Attrs().ParentIndex
if peerID == 0 {
// perhaps running on an older kernel where ParentIndex doesn't work.
// as fall-back, assume the peers are consecutive
peerID = link.Attrs().Index - 1
}
ids = append(ids, peerID)
}
}
return ids, nil
}
// Lookup the weave interface of a container
func GetWeaveNetDevs(processID int) ([]Dev, error) {
peerIDs, err := ConnectedToBridgeVethPeerIds("weave")
if err != nil {
return nil, err
}
return GetNetDevsByVethPeerIds(processID, peerIDs)
}
func GetNetDevsByVethPeerIds(processID int, peerIDs []int) ([]Dev, error) {
// Bail out if this container is running in the root namespace
netnsRoot, err := netns.GetFromPid(1)
if err != nil {
return nil, fmt.Errorf("unable to open root namespace: %s", err)
}
defer netnsRoot.Close()
netnsContainer, err := netns.GetFromPid(processID)
if err != nil {
// Unable to find a namespace for this process - just return nothing
if os.IsNotExist(err) {
return nil, nil
}
return nil, fmt.Errorf("unable to open process %d namespace: %s", processID, err)
}
defer netnsContainer.Close()
if netnsRoot.Equal(netnsContainer) {
return nil, nil
}
var netdevs []Dev
peersStr := make([]string, len(peerIDs))
for i, id := range peerIDs {
peersStr[i] = strconv.Itoa(id)
}
nds, err := WithNetNSByPid(processID, "list-netdevs", peersStr...)
if err != nil {
return nil, fmt.Errorf("list-netdevs failed: %s", err)
}
err = json.Unmarshal(nds, &netdevs)
return netdevs, err
}
// Get the weave bridge interface.
// NB: Should be called from the root network namespace.
func GetBridgeNetDev(bridgeName string) (Dev, error) {
link, err := netlink.LinkByName(bridgeName)
if err != nil {
return Dev{}, err
}
return LinkToNetDev(link)
}
+26 -7
View File
@@ -1,7 +1,10 @@
package net
import (
"bytes"
"errors"
"fmt"
"os/exec"
"runtime"
"github.com/vishvananda/netlink"
@@ -54,12 +57,28 @@ func WithNetNSLinkUnsafe(ns netns.NsHandle, ifName string, work func(link netlin
})
}
func WithNetNSLinkByPidUnsafe(pid int, ifName string, work func(link netlink.Link) error) error {
ns, err := netns.GetFromPid(pid)
if err != nil {
return err
}
defer ns.Close()
var WeaveUtilCmd = "weaveutil"
return WithNetNSLinkUnsafe(ns, ifName, work)
// A safe version of WithNetNS* which creates a process executing
// "nsenter --net=<ns-path> weaveutil <cmd> [args]".
func WithNetNS(nsPath string, cmd string, args ...string) ([]byte, error) {
var stdout, stderr bytes.Buffer
args = append([]string{"--net=" + nsPath, WeaveUtilCmd, cmd}, args...)
c := exec.Command("nsenter", args...)
c.Stdout = &stdout
c.Stderr = &stderr
if err := c.Run(); err != nil {
return nil, fmt.Errorf("%s: %s", string(stderr.Bytes()), err)
}
return stdout.Bytes(), nil
}
func WithNetNSByPid(pid int, cmd string, args ...string) ([]byte, error) {
return WithNetNS(NSPathByPid(pid), cmd, args...)
}
func NSPathByPid(pid int) string {
return fmt.Sprintf("/proc/%d/ns/net", pid)
}
+2 -2
View File
@@ -13,7 +13,7 @@ import (
func CheckNetworkFree(subnet *net.IPNet, ignoreIfaceNames map[string]struct{}) error {
return forEachRoute(ignoreIfaceNames, func(route netlink.Route) error {
if route.Dst != nil && overlaps(route.Dst, subnet) {
return fmt.Errorf("Network %s overlaps with existing route %s on host.", subnet, route.Dst)
return fmt.Errorf("Network %s overlaps with existing route %s on host", subnet, route.Dst)
}
return nil
})
@@ -29,7 +29,7 @@ func overlaps(n1, n2 *net.IPNet) bool {
func CheckAddressOverlap(addr net.IP, ignoreIfaceNames map[string]struct{}) error {
return forEachRoute(ignoreIfaceNames, func(route netlink.Route) error {
if route.Dst != nil && route.Dst.Contains(addr) {
return fmt.Errorf("Address %s overlaps with existing route %s on host.", addr, route.Dst)
return fmt.Errorf("Address %s overlaps with existing route %s on host", addr, route.Dst)
}
return nil
})
+84
View File
@@ -0,0 +1,84 @@
package net
import (
"errors"
"io/ioutil"
"net"
"os"
"github.com/weaveworks/mesh"
"github.com/weaveworks/weave/db"
)
func getOldStyleSystemUUID() ([]byte, error) {
uuid, err := ioutil.ReadFile("/sys/class/dmi/id/product_uuid")
if os.IsNotExist(err) {
uuid, err = ioutil.ReadFile("/sys/hypervisor/uuid")
}
return uuid, err
}
func getSystemUUID(hostRoot string) ([]byte, error) {
uuid, err := getOldStyleSystemUUID()
if err != nil && !os.IsNotExist(err) {
return nil, err
}
machineid, err := ioutil.ReadFile(hostRoot + "/etc/machine-id")
if os.IsNotExist(err) {
machineid, err = ioutil.ReadFile(hostRoot + "/var/lib/dbus/machine-id")
}
if err != nil && !os.IsNotExist(err) {
return nil, err
}
if len(uuid) == 0 && len(machineid) == 0 {
return nil, errors.New("All system IDs are blank")
}
return append(machineid, uuid...), nil
}
func getPersistedPeerName(pathName string) (mesh.PeerName, error) {
d, err := db.NewBoltDBReadOnly(pathName)
if err != nil {
return mesh.UnknownPeerName, err
}
defer d.Close()
var peerName mesh.PeerName
nameFound, err := d.Load(db.NameIdent, &peerName)
if err != nil || !nameFound {
return mesh.UnknownPeerName, err
}
return peerName, nil
}
// GetSystemPeerName returns an ID derived from concatenated machine-id
// (either systemd or dbus), the system (aka bios) UUID and the
// hypervisor UUID. It is tweaked and formatted to be usable as a mac address
func GetSystemPeerName(dbPrefix, hostRoot string) (string, error) {
// Check if we have a persisted name that matches the old-style ID for this host
if oldUUID, err := getOldStyleSystemUUID(); err == nil {
pathName := dbPrefix + db.FileName
if _, err := os.Stat(pathName); err == nil {
persistedPeerName, err := getPersistedPeerName(pathName)
if err != nil && !os.IsNotExist(err) {
return "", err
}
if persistedPeerName == mesh.PeerNameFromBin(MACfromUUID(oldUUID)) {
return persistedPeerName.String(), nil
}
}
} else if !os.IsNotExist(err) {
return "", err
}
var mac net.HardwareAddr
if uuid, err := getSystemUUID(hostRoot); err == nil {
mac = MACfromUUID(uuid)
} else if !os.IsNotExist(err) {
return "", err
} else {
mac, err = RandomMAC()
if err != nil {
return "", err
}
}
return mac.String(), nil
}
+128 -18
View File
@@ -3,8 +3,11 @@ package net
import (
"fmt"
"net"
"strings"
"syscall"
"time"
"github.com/coreos/go-iptables/iptables"
"github.com/j-keck/arping"
"github.com/vishvananda/netlink"
"github.com/vishvananda/netns"
@@ -103,34 +106,36 @@ const (
vethPrefix = "v" + VethName // starts with "veth" to suppress UI notifications
)
func interfaceExistsInNamespace(ns netns.NsHandle, ifName string) bool {
err := WithNetNSUnsafe(ns, func() error {
_, err := netlink.LinkByName(ifName)
return err
})
func interfaceExistsInNamespace(netNSPath string, ifName string) bool {
_, err := WithNetNS(netNSPath, "check-iface", ifName)
return err == nil
}
func AttachContainer(ns netns.NsHandle, id, ifName, bridgeName string, mtu int, withMulticastRoute bool, cidrs []*net.IPNet, keepTXOn bool) error {
if !interfaceExistsInNamespace(ns, ifName) {
// NB: This function can be used only by a process that terminates immediately
// after calling the function as it changes netns via WithNetNSLinkUnsafe.
func AttachContainer(netNSPath, id, ifName, bridgeName string, mtu int, withMulticastRoute bool, cidrs []*net.IPNet, keepTXOn bool, hairpinMode bool) error {
ns, err := netns.GetFromPath(netNSPath)
if err != nil {
return err
}
defer ns.Close()
ipt, err := iptables.New()
if err != nil {
return err
}
if !interfaceExistsInNamespace(netNSPath, ifName) {
maxIDLen := IFNAMSIZ - 1 - len(vethPrefix+"pl")
if len(id) > maxIDLen {
id = id[:maxIDLen] // trim passed ID if too long
}
name, peerName := vethPrefix+"pl"+id, vethPrefix+"pg"+id
_, err := CreateAndAttachVeth(name, peerName, bridgeName, mtu, keepTXOn, func(veth netlink.Link) error {
veth, err := CreateAndAttachVeth(name, peerName, bridgeName, mtu, keepTXOn, func(veth netlink.Link) error {
if err := netlink.LinkSetNsFd(veth, int(ns)); err != nil {
return fmt.Errorf("failed to move veth to container netns: %s", err)
}
if err := WithNetNSUnsafe(ns, func() error {
if err := netlink.LinkSetName(veth, ifName); err != nil {
return err
}
if err := ConfigureARPCache(ifName); err != nil {
return err
}
return nil
}); err != nil {
if _, err := WithNetNS(netNSPath, "setup-iface", peerName, ifName); err != nil {
return fmt.Errorf("error setting up interface: %s", err)
}
return nil
@@ -138,6 +143,10 @@ func AttachContainer(ns netns.NsHandle, id, ifName, bridgeName string, mtu int,
if err != nil {
return err
}
if err = netlink.LinkSetHairpin(veth, hairpinMode); err != nil {
return fmt.Errorf("unable to set hairpin mode to %t for bridge side of veth %s: %s", hairpinMode, name, err)
}
}
if err := WithNetNSLinkUnsafe(ns, ifName, func(veth netlink.Link) error {
@@ -145,6 +154,21 @@ func AttachContainer(ns netns.NsHandle, id, ifName, bridgeName string, mtu int,
if err != nil {
return err
}
// Add multicast ACCEPT rules for new subnets
for _, ipnet := range newAddresses {
acceptRule := []string{"-i", ifName, "-s", subnet(ipnet), "-d", "224.0.0.0/4", "-j", "ACCEPT"}
exists, err := ipt.Exists("filter", "INPUT", acceptRule...)
if err != nil {
return err
}
if !exists {
if err := ipt.Insert("filter", "INPUT", 1, acceptRule...); err != nil {
return err
}
}
}
if err := netlink.LinkSetUp(veth); err != nil {
return err
}
@@ -176,7 +200,20 @@ func AttachContainer(ns netns.NsHandle, id, ifName, bridgeName string, mtu int,
return nil
}
func DetachContainer(ns netns.NsHandle, id, ifName string, cidrs []*net.IPNet) error {
// NB: This function can be used only by a process that terminates immediately
// after calling the function as it changes netns via WithNetNSLinkUnsafe.
func DetachContainer(netNSPath, id, ifName string, cidrs []*net.IPNet) error {
ns, err := netns.GetFromPath(netNSPath)
if err != nil {
return err
}
defer ns.Close()
ipt, err := iptables.New()
if err != nil {
return err
}
return WithNetNSLinkUnsafe(ns, ifName, func(veth netlink.Link) error {
existingAddrs, err := netlink.AddrList(veth, netlink.FAMILY_V4)
if err != nil {
@@ -194,7 +231,31 @@ func DetachContainer(ns netns.NsHandle, id, ifName string, cidrs []*net.IPNet) e
if err != nil {
return fmt.Errorf("failed to get IP address for %q: %v", veth.Attrs().Name, err)
}
// Remove multicast ACCEPT rules for subnets we no longer have addresses in
subnets := subnets(addrs)
rules, err := ipt.List("filter", "INPUT")
if err != nil {
return err
}
for _, rule := range rules {
ps := strings.Split(rule, " ")
if len(ps) == 10 &&
ps[0] == "-A" && ps[2] == "-s" && ps[4] == "-d" && ps[5] == "224.0.0.0/4" &&
ps[6] == "-i" && ps[7] == ifName && ps[8] == "-j" && ps[9] == "ACCEPT" {
if _, found := subnets[ps[3]]; !found {
if err := ipt.Delete("filter", "INPUT", ps[2:]...); err != nil {
return err
}
}
}
}
if len(addrs) == 0 { // all addresses gone: remove the interface
if err := ipt.Delete("filter", "INPUT", "-i", ifName, "-d", "224.0.0.0/4", "-j", "DROP"); err != nil {
return err
}
if err := netlink.LinkDel(veth); err != nil {
return err
}
@@ -202,3 +263,52 @@ func DetachContainer(ns netns.NsHandle, id, ifName string, cidrs []*net.IPNet) e
return nil
})
}
func subnet(ipn *net.IPNet) string {
ones, _ := ipn.Mask.Size()
return fmt.Sprintf("%s/%d", ipn.IP.Mask(ipn.Mask).String(), ones)
}
func subnets(addrs []netlink.Addr) map[string]struct{} {
subnets := make(map[string]struct{})
for _, addr := range addrs {
subnets[subnet(addr.IPNet)] = struct{}{}
}
return subnets
}
func addNatRule(ipt *iptables.IPTables, rulespec ...string) error {
// Loop until we get an exit code other than "temporarily unavailable"
for {
if err := ipt.AppendUnique("nat", "WEAVE", rulespec...); err != nil {
if ierr, ok := err.(*iptables.Error); ok {
if status, ok := ierr.ExitError.Sys().(syscall.WaitStatus); ok {
// (magic exit code 4 found in iptables source code; undocumented)
if status.ExitStatus() == 4 {
continue
}
}
}
return err
}
return nil
}
}
func ExposeNAT(ipnet net.IPNet) error {
ipt, err := iptables.New()
if err != nil {
return err
}
cidr := ipnet.String()
if err := addNatRule(ipt, "-s", cidr, "-d", "224.0.0.0/4", "-j", "RETURN"); err != nil {
return err
}
if err := addNatRule(ipt, "-d", cidr, "!", "-s", cidr, "-j", "MASQUERADE"); err != nil {
return err
}
if err := addNatRule(ipt, "-s", cidr, "!", "-d", cidr, "-j", "MASQUERADE"); err != nil {
return err
}
return nil
}
+114
View File
@@ -0,0 +1,114 @@
package npc
import (
"fmt"
"k8s.io/client-go/pkg/api"
extnapi "k8s.io/client-go/pkg/apis/extensions/v1beta1"
"k8s.io/client-go/pkg/util/intstr"
"github.com/weaveworks/weave/npc/ipset"
)
func (ns *ns) analysePolicy(policy *extnapi.NetworkPolicy) (
rules map[string]*ruleSpec,
nsSelectors, podSelectors map[string]*selectorSpec,
err error) {
nsSelectors = make(map[string]*selectorSpec)
podSelectors = make(map[string]*selectorSpec)
rules = make(map[string]*ruleSpec)
dstSelector, err := newSelectorSpec(&policy.Spec.PodSelector, ns.name, ipset.HashIP)
if err != nil {
return nil, nil, nil, err
}
podSelectors[dstSelector.key] = dstSelector
for _, ingressRule := range policy.Spec.Ingress {
if ingressRule.Ports != nil && len(ingressRule.Ports) == 0 {
// Ports is empty, this rule matches no ports (no traffic matches).
continue
}
if ingressRule.From != nil && len(ingressRule.From) == 0 {
// From is empty, this rule matches no sources (no traffic matches).
continue
}
if ingressRule.From == nil {
// From is not provided, this rule matches all sources (traffic not restricted by source).
if ingressRule.Ports == nil {
// Ports is not provided, this rule matches all ports (traffic not restricted by port).
rule := newRuleSpec(nil, nil, dstSelector, nil)
rules[rule.key] = rule
} else {
// Ports is present and contains at least one item, then this rule allows traffic
// only if the traffic matches at least one port in the ports list.
withNormalisedProtoAndPort(ingressRule.Ports, func(proto, port string) {
rule := newRuleSpec(&proto, nil, dstSelector, &port)
rules[rule.key] = rule
})
}
} else {
// From is present and contains at least on item, this rule allows traffic only if the
// traffic matches at least one item in the from list.
for _, peer := range ingressRule.From {
var srcSelector *selectorSpec
if peer.PodSelector != nil {
srcSelector, err = newSelectorSpec(peer.PodSelector, ns.name, ipset.HashIP)
if err != nil {
return nil, nil, nil, err
}
podSelectors[srcSelector.key] = srcSelector
}
if peer.NamespaceSelector != nil {
srcSelector, err = newSelectorSpec(peer.NamespaceSelector, "", ipset.ListSet)
if err != nil {
return nil, nil, nil, err
}
nsSelectors[srcSelector.key] = srcSelector
}
if ingressRule.Ports == nil {
// Ports is not provided, this rule matches all ports (traffic not restricted by port).
rule := newRuleSpec(nil, srcSelector, dstSelector, nil)
rules[rule.key] = rule
} else {
// Ports is present and contains at least one item, then this rule allows traffic
// only if the traffic matches at least one port in the ports list.
withNormalisedProtoAndPort(ingressRule.Ports, func(proto, port string) {
rule := newRuleSpec(&proto, srcSelector, dstSelector, &port)
rules[rule.key] = rule
})
}
}
}
}
return rules, nsSelectors, podSelectors, nil
}
func withNormalisedProtoAndPort(npps []extnapi.NetworkPolicyPort, f func(proto, port string)) {
for _, npp := range npps {
// If no proto is specified, default to TCP
proto := string(api.ProtocolTCP)
if npp.Protocol != nil {
proto = string(*npp.Protocol)
}
// If no port is specified, match any port. Let iptables executable handle
// service name resolution
port := "0:65535"
if npp.Port != nil {
switch npp.Port.Type {
case intstr.Int:
port = fmt.Sprintf("%d", npp.Port.IntVal)
case intstr.String:
port = npp.Port.StrVal
}
}
f(proto, port)
}
}
+40
View File
@@ -0,0 +1,40 @@
package npc
// These types are defined in https://github.com/kubernetes/kubernetes/blob/master/docs/proposals/network-policy.md
// but not in the k8s API yet. Copies are included here for decoding the `net.beta.kubernetes.io/network-policy`
// annotation specified in the above document.
type IngressIsolationPolicy string
const (
// Deny all ingress traffic to pods in this namespace. Ingress means
// any incoming traffic to pods, whether that be from other pods within this namespace
// or any source outside of this namespace.
DefaultDeny IngressIsolationPolicy = "DefaultDeny"
)
// Standard NamespaceSpec object, modified to include a new
// NamespaceNetworkPolicy field.
type NamespaceSpec struct {
// This is a pointer so that it can be left undefined.
NetworkPolicy *NamespaceNetworkPolicy `json:"networkPolicy,omitempty"`
}
type NamespaceNetworkPolicy struct {
// Ingress configuration for this namespace. This config is
// applied to all pods within this namespace. For now, only
// ingress is supported. This field is optional - if not
// defined, then the cluster default for ingress is applied.
Ingress *NamespaceIngressPolicy `json:"ingress,omitempty"`
}
// Configuration for ingress to pods within this namespace.
// For now, this only supports specifying an isolation policy.
type NamespaceIngressPolicy struct {
// The isolation policy to apply to pods in this namespace.
// Currently this field only supports "DefaultDeny", but could
// be extended to support other policies in the future. When set to DefaultDeny,
// pods in this namespace are denied ingress traffic by default. When not defined,
// the cluster default ingress isolation policy is applied (currently allow all).
Isolation *IngressIsolationPolicy `json:"isolation,omitempty"`
}
+13
View File
@@ -0,0 +1,13 @@
package npc
const (
TableFilter = "filter"
MainChain = "WEAVE-NPC"
DefaultChain = "WEAVE-NPC-DEFAULT"
IngressChain = "WEAVE-NPC-INGRESS"
IpsetNamePrefix = "weave-"
LocalIpset = IpsetNamePrefix + "local-pods"
)
+194
View File
@@ -0,0 +1,194 @@
package npc
import (
"sync"
"github.com/coreos/go-iptables/iptables"
"github.com/pkg/errors"
coreapi "k8s.io/client-go/pkg/api/v1"
extnapi "k8s.io/client-go/pkg/apis/extensions/v1beta1"
"github.com/weaveworks/weave/common"
"github.com/weaveworks/weave/npc/ipset"
)
type NetworkPolicyController interface {
AddNamespace(ns *coreapi.Namespace) error
UpdateNamespace(oldObj, newObj *coreapi.Namespace) error
DeleteNamespace(ns *coreapi.Namespace) error
AddPod(obj *coreapi.Pod) error
UpdatePod(oldObj, newObj *coreapi.Pod) error
DeletePod(obj *coreapi.Pod) error
AddNetworkPolicy(obj *extnapi.NetworkPolicy) error
UpdateNetworkPolicy(oldObj, newObj *extnapi.NetworkPolicy) error
DeleteNetworkPolicy(obj *extnapi.NetworkPolicy) error
}
type controller struct {
sync.Mutex
nodeName string // my node name
ipt *iptables.IPTables
ips ipset.Interface
nss map[string]*ns // ns name -> ns struct
nsSelectors *selectorSet // selector string -> nsSelector
}
func New(nodeName string, ipt *iptables.IPTables, ips ipset.Interface) NetworkPolicyController {
c := &controller{
nodeName: nodeName,
ipt: ipt,
ips: ips,
nss: make(map[string]*ns)}
c.nsSelectors = newSelectorSet(ips, c.onNewNsSelector)
return c
}
func (npc *controller) onNewNsSelector(selector *selector) error {
for _, ns := range npc.nss {
if ns.namespace != nil {
if selector.matches(ns.namespace.ObjectMeta.Labels) {
if err := ns.ips.AddEntry(selector.spec.ipsetName, string(ns.allPods.ipsetName)); err != nil {
return err
}
}
}
}
return nil
}
func (npc *controller) withNS(name string, f func(ns *ns) error) error {
ns, found := npc.nss[name]
if !found {
newNs, err := newNS(name, npc.ipt, npc.ips, npc.nsSelectors)
if err != nil {
return err
}
npc.nss[name] = newNs
ns = newNs
}
if err := f(ns); err != nil {
return err
}
if ns.empty() {
if err := ns.destroy(); err != nil {
return err
}
delete(npc.nss, name)
}
return nil
}
func (npc *controller) checkLocalPod(obj *coreapi.Pod, event string) bool {
if obj.Spec.NodeName != npc.nodeName {
common.Log.Debugf("%s ignored for pod %s/%s on node %s", event, obj.ObjectMeta.Namespace, obj.ObjectMeta.Name, obj.Spec.NodeName)
return false
}
return true
}
func (npc *controller) AddPod(obj *coreapi.Pod) error {
npc.Lock()
defer npc.Unlock()
if !npc.checkLocalPod(obj, "AddPod") {
return nil
}
common.Log.Debugf("EVENT AddPod %s", js(obj))
return npc.withNS(obj.ObjectMeta.Namespace, func(ns *ns) error {
return errors.Wrap(ns.addPod(obj), "add pod")
})
}
func (npc *controller) UpdatePod(oldObj, newObj *coreapi.Pod) error {
npc.Lock()
defer npc.Unlock()
// Pods don't move across nodes so we only check the new version
if !npc.checkLocalPod(newObj, "UpdatePod") {
return nil
}
common.Log.Debugf("EVENT UpdatePod %s %s", js(oldObj), js(newObj))
return npc.withNS(oldObj.ObjectMeta.Namespace, func(ns *ns) error {
return errors.Wrap(ns.updatePod(oldObj, newObj), "update pod")
})
}
func (npc *controller) DeletePod(obj *coreapi.Pod) error {
npc.Lock()
defer npc.Unlock()
if !npc.checkLocalPod(obj, "DeletePod") {
return nil
}
common.Log.Debugf("EVENT DeletePod %s", js(obj))
return npc.withNS(obj.ObjectMeta.Namespace, func(ns *ns) error {
return errors.Wrap(ns.deletePod(obj), "delete pod")
})
}
func (npc *controller) AddNetworkPolicy(obj *extnapi.NetworkPolicy) error {
npc.Lock()
defer npc.Unlock()
common.Log.Infof("EVENT AddNetworkPolicy %s", js(obj))
return npc.withNS(obj.ObjectMeta.Namespace, func(ns *ns) error {
return errors.Wrap(ns.addNetworkPolicy(obj), "add network policy")
})
}
func (npc *controller) UpdateNetworkPolicy(oldObj, newObj *extnapi.NetworkPolicy) error {
npc.Lock()
defer npc.Unlock()
common.Log.Infof("EVENT UpdateNetworkPolicy %s %s", js(oldObj), js(newObj))
return npc.withNS(oldObj.ObjectMeta.Namespace, func(ns *ns) error {
return errors.Wrap(ns.updateNetworkPolicy(oldObj, newObj), "update network policy")
})
}
func (npc *controller) DeleteNetworkPolicy(obj *extnapi.NetworkPolicy) error {
npc.Lock()
defer npc.Unlock()
common.Log.Infof("EVENT DeleteNetworkPolicy %s", js(obj))
return npc.withNS(obj.ObjectMeta.Namespace, func(ns *ns) error {
return errors.Wrap(ns.deleteNetworkPolicy(obj), "delete network policy")
})
}
func (npc *controller) AddNamespace(obj *coreapi.Namespace) error {
npc.Lock()
defer npc.Unlock()
common.Log.Infof("EVENT AddNamespace %s", js(obj))
return npc.withNS(obj.ObjectMeta.Name, func(ns *ns) error {
return errors.Wrap(ns.addNamespace(obj), "add namespace")
})
}
func (npc *controller) UpdateNamespace(oldObj, newObj *coreapi.Namespace) error {
npc.Lock()
defer npc.Unlock()
common.Log.Infof("EVENT UpdateNamespace %s %s", js(oldObj), js(newObj))
return npc.withNS(oldObj.ObjectMeta.Name, func(ns *ns) error {
return errors.Wrap(ns.updateNamespace(oldObj, newObj), "update namespace")
})
}
func (npc *controller) DeleteNamespace(obj *coreapi.Namespace) error {
npc.Lock()
defer npc.Unlock()
common.Log.Infof("EVENT DeleteNamespace %s", js(obj))
return npc.withNS(obj.ObjectMeta.Name, func(ns *ns) error {
return errors.Wrap(ns.deleteNamespace(obj), "delete namespace")
})
}
+140
View File
@@ -0,0 +1,140 @@
package ipset
import (
"log"
"os/exec"
"strings"
"github.com/pkg/errors"
)
type Name string
type Type string
const (
ListSet = Type("list:set")
HashIP = Type("hash:ip")
)
type Interface interface {
Create(ipsetName Name, ipsetType Type) error
AddEntry(ipsetName Name, entry string) error
DelEntry(ipsetName Name, entry string) error
Flush(ipsetName Name) error
Destroy(ipsetName Name) error
List(prefix string) ([]Name, error)
FlushAll() error
DestroyAll() error
}
type ipset struct {
refCount
*log.Logger
}
func New(logger *log.Logger) Interface {
return &ipset{refCount: newRefCount(), Logger: logger}
}
func (i *ipset) Create(ipsetName Name, ipsetType Type) error {
return doExec("create", string(ipsetName), string(ipsetType))
}
func (i *ipset) AddEntry(ipsetName Name, entry string) error {
i.Logger.Printf("adding entry %s to %s", entry, ipsetName)
if i.inc(ipsetName, entry) > 1 { // already in the set
return nil
}
return doExec("add", string(ipsetName), entry)
}
func (i *ipset) DelEntry(ipsetName Name, entry string) error {
i.Logger.Printf("deleting entry %s from %s", entry, ipsetName)
if i.dec(ipsetName, entry) > 0 { // still needed
return nil
}
return doExec("del", string(ipsetName), entry)
}
func (i *ipset) Flush(ipsetName Name) error {
i.removeSet(ipsetName)
return doExec("flush", string(ipsetName))
}
func (i *ipset) FlushAll() error {
i.refCount = newRefCount()
return doExec("flush")
}
func (i *ipset) Destroy(ipsetName Name) error {
i.removeSet(ipsetName)
return doExec("destroy", string(ipsetName))
}
func (i *ipset) DestroyAll() error {
i.refCount = newRefCount()
return doExec("destroy")
}
// Fetch a list of all existing sets with a given prefix
func (i *ipset) List(prefix string) ([]Name, error) {
output, err := exec.Command("ipset", "list", "-name", "-output", "plain").Output()
if err != nil {
return nil, err
}
var selected []Name
sets := strings.Split(string(output), "\n")
for _, v := range sets {
if strings.HasPrefix(v, prefix) {
selected = append(selected, Name(v))
}
}
return selected, err
}
func doExec(args ...string) error {
if output, err := exec.Command("ipset", args...).CombinedOutput(); err != nil {
return errors.Wrapf(err, "ipset %v failed: %s", args, output)
}
return nil
}
// Reference-counting
type key struct {
ipsetName Name
entry string
}
// note no locking is required as all operations are serialised in the controller
type refCount struct {
ref map[key]int
}
func newRefCount() refCount {
return refCount{ref: make(map[key]int)}
}
func (rc *refCount) inc(ipsetName Name, entry string) int {
k := key{ipsetName, entry}
rc.ref[k]++
return rc.ref[k]
}
func (rc *refCount) dec(ipsetName Name, entry string) int {
k := key{ipsetName, entry}
rc.ref[k]--
return rc.ref[k]
}
func (rc *refCount) removeSet(ipsetName Name) {
for k := range rc.ref {
if k.ipsetName == ipsetName {
delete(rc.ref, k)
}
}
}
+10
View File
@@ -0,0 +1,10 @@
package npc
import (
"encoding/json"
)
func js(v interface{}) string {
a, _ := json.Marshal(v)
return string(a)
}
+111
View File
@@ -0,0 +1,111 @@
package metrics
import (
"net/http"
"os"
"strconv"
"github.com/google/gopacket"
"github.com/google/gopacket/layers"
"github.com/google/gopacket/pcapgo"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"
"github.com/weaveworks/weave/common"
)
var (
blockedConnections = prometheus.NewCounterVec(
prometheus.CounterOpts{
Name: "weavenpc_blocked_connections_total",
Help: "Connection attempts blocked by policy controller.",
},
[]string{"protocol", "dport"},
)
)
func gatherMetrics() {
pipe, err := os.Open("/var/log/ulogd.pcap")
if err != nil {
common.Log.Fatalf("Failed to open pcap: %v", err)
}
reader, err := pcapgo.NewReader(pipe)
if err != nil {
common.Log.Fatalf("Failed to read pcap header: %v", err)
}
for {
data, _, err := reader.ReadPacketData()
if err != nil {
common.Log.Fatalf("Failed to read pcap packet: %v", err)
}
packet := gopacket.NewPacket(data, layers.LayerTypeIPv4, gopacket.Default)
if tcpLayer := packet.Layer(layers.LayerTypeTCP); tcpLayer != nil {
tcp, _ := tcpLayer.(*layers.TCP)
if tcp.SYN && !tcp.ACK { // Only plain SYN constitutes a NEW TCP connection
blockedConnections.With(prometheus.Labels{"protocol": "tcp", "dport": strconv.Itoa(int(tcp.DstPort))}).Inc()
common.Log.Warnf("TCP connection from %v:%d to %v:%d blocked by Weave NPC.", srcIP(packet), tcp.SrcPort, dstIP(packet), tcp.DstPort)
continue
}
}
if udpLayer := packet.Layer(layers.LayerTypeUDP); udpLayer != nil {
udp, _ := udpLayer.(*layers.UDP)
blockedConnections.With(prometheus.Labels{"protocol": "udp", "dport": strconv.Itoa(int(udp.DstPort))}).Inc()
common.Log.Warnf("UDP connection from %v:%d to %v:%d blocked by Weave NPC.", srcIP(packet), udp.SrcPort, dstIP(packet), udp.DstPort)
continue
}
}
}
const unknownIP string = "<unknown IP>"
func srcIP(packet gopacket.Packet) string {
if layer := packet.Layer(layers.LayerTypeIPv4); layer != nil {
if ip, ok := layer.(*layers.IPv4); ok {
return ip.SrcIP.String()
}
}
if layer := packet.Layer(layers.LayerTypeIPv6); layer != nil {
if ip, ok := layer.(*layers.IPv6); ok {
return ip.SrcIP.String()
}
}
return unknownIP
}
func dstIP(packet gopacket.Packet) string {
if layer := packet.Layer(layers.LayerTypeIPv4); layer != nil {
if ip, ok := layer.(*layers.IPv4); ok {
return ip.DstIP.String()
}
}
if layer := packet.Layer(layers.LayerTypeIPv6); layer != nil {
if ip, ok := layer.(*layers.IPv6); ok {
return ip.DstIP.String()
}
}
return unknownIP
}
func Start(addr string) error {
if err := prometheus.Register(blockedConnections); err != nil {
return err
}
http.Handle("/metrics", promhttp.Handler())
go func() {
common.Log.Infof("Serving /metrics on %s", addr)
if err := http.ListenAndServe(addr, nil); err != nil {
common.Log.Fatalf("Failed to bind metrics server: %v", err)
}
}()
go gatherMetrics()
return nil
}
+342
View File
@@ -0,0 +1,342 @@
package npc
import (
"encoding/json"
"github.com/coreos/go-iptables/iptables"
"k8s.io/client-go/pkg/api/unversioned"
coreapi "k8s.io/client-go/pkg/api/v1"
extnapi "k8s.io/client-go/pkg/apis/extensions/v1beta1"
"k8s.io/client-go/pkg/types"
"k8s.io/client-go/pkg/util/uuid"
"github.com/weaveworks/weave/common"
"github.com/weaveworks/weave/npc/ipset"
)
type ns struct {
ipt *iptables.IPTables // interface to iptables
ips ipset.Interface // interface to ipset
name string // k8s Namespace name
namespace *coreapi.Namespace // k8s Namespace object
pods map[types.UID]*coreapi.Pod // k8s Pod objects by UID
policies map[types.UID]*extnapi.NetworkPolicy // k8s NetworkPolicy objects by UID
uid types.UID // surrogate UID to own allPods selector
allPods *selectorSpec // hash:ip ipset of all pod IPs in this namespace
nsSelectors *selectorSet
podSelectors *selectorSet
rules *ruleSet
}
func newNS(name string, ipt *iptables.IPTables, ips ipset.Interface, nsSelectors *selectorSet) (*ns, error) {
allPods, err := newSelectorSpec(&unversioned.LabelSelector{}, name, ipset.HashIP)
if err != nil {
return nil, err
}
ns := &ns{
ipt: ipt,
ips: ips,
name: name,
pods: make(map[types.UID]*coreapi.Pod),
policies: make(map[types.UID]*extnapi.NetworkPolicy),
uid: uuid.NewUUID(),
allPods: allPods,
nsSelectors: nsSelectors,
rules: newRuleSet(ipt)}
ns.podSelectors = newSelectorSet(ips, ns.onNewPodSelector)
if err := ns.podSelectors.provision(ns.uid, nil, map[string]*selectorSpec{ns.allPods.key: ns.allPods}); err != nil {
return nil, err
}
return ns, nil
}
func (ns *ns) empty() bool {
return len(ns.pods) == 0 && len(ns.policies) == 0 && ns.namespace == nil
}
func (ns *ns) destroy() error {
if err := ns.podSelectors.deprovision(ns.uid, map[string]*selectorSpec{ns.allPods.key: ns.allPods}, nil); err != nil {
return err
}
return nil
}
func (ns *ns) onNewPodSelector(selector *selector) error {
for _, pod := range ns.pods {
if hasIP(pod) {
if selector.matches(pod.ObjectMeta.Labels) {
if err := selector.addEntry(pod.Status.PodIP); err != nil {
return err
}
}
}
}
return nil
}
func (ns *ns) addPod(obj *coreapi.Pod) error {
ns.pods[obj.ObjectMeta.UID] = obj
if !hasIP(obj) {
return nil
}
ns.ips.AddEntry(LocalIpset, obj.Status.PodIP)
return ns.podSelectors.addToMatching(obj.ObjectMeta.Labels, obj.Status.PodIP)
}
func (ns *ns) updatePod(oldObj, newObj *coreapi.Pod) error {
delete(ns.pods, oldObj.ObjectMeta.UID)
ns.pods[newObj.ObjectMeta.UID] = newObj
if !hasIP(oldObj) && !hasIP(newObj) {
return nil
}
if hasIP(oldObj) && !hasIP(newObj) {
ns.ips.DelEntry(LocalIpset, oldObj.Status.PodIP)
return ns.podSelectors.delFromMatching(oldObj.ObjectMeta.Labels, oldObj.Status.PodIP)
}
if !hasIP(oldObj) && hasIP(newObj) {
ns.ips.AddEntry(LocalIpset, newObj.Status.PodIP)
return ns.podSelectors.addToMatching(newObj.ObjectMeta.Labels, newObj.Status.PodIP)
}
if !equals(oldObj.ObjectMeta.Labels, newObj.ObjectMeta.Labels) ||
oldObj.Status.PodIP != newObj.Status.PodIP {
for _, ps := range ns.podSelectors.entries {
oldMatch := ps.matches(oldObj.ObjectMeta.Labels)
newMatch := ps.matches(newObj.ObjectMeta.Labels)
if oldMatch == newMatch && oldObj.Status.PodIP == newObj.Status.PodIP {
continue
}
if oldMatch {
if err := ps.delEntry(oldObj.Status.PodIP); err != nil {
return err
}
}
if newMatch {
if err := ps.addEntry(newObj.Status.PodIP); err != nil {
return err
}
}
}
}
return nil
}
func (ns *ns) deletePod(obj *coreapi.Pod) error {
delete(ns.pods, obj.ObjectMeta.UID)
if !hasIP(obj) {
return nil
}
ns.ips.DelEntry(LocalIpset, obj.Status.PodIP)
return ns.podSelectors.delFromMatching(obj.ObjectMeta.Labels, obj.Status.PodIP)
}
func (ns *ns) addNetworkPolicy(obj *extnapi.NetworkPolicy) error {
ns.policies[obj.ObjectMeta.UID] = obj
// Analyse policy, determine which rules and ipsets are required
rules, nsSelectors, podSelectors, err := ns.analysePolicy(obj)
if err != nil {
return err
}
// Provision required resources in dependency order
if err := ns.nsSelectors.provision(obj.ObjectMeta.UID, nil, nsSelectors); err != nil {
return err
}
if err := ns.podSelectors.provision(obj.ObjectMeta.UID, nil, podSelectors); err != nil {
return err
}
if err := ns.rules.provision(obj.ObjectMeta.UID, nil, rules); err != nil {
return err
}
return nil
}
func (ns *ns) updateNetworkPolicy(oldObj, newObj *extnapi.NetworkPolicy) error {
delete(ns.policies, oldObj.ObjectMeta.UID)
ns.policies[newObj.ObjectMeta.UID] = newObj
// Analyse the old and the new policy so we can determine differences
oldRules, oldNsSelectors, oldPodSelectors, err := ns.analysePolicy(oldObj)
if err != nil {
return err
}
newRules, newNsSelectors, newPodSelectors, err := ns.analysePolicy(newObj)
if err != nil {
return err
}
// Deprovision unused and provision newly required resources in dependency order
if err := ns.rules.deprovision(oldObj.ObjectMeta.UID, oldRules, newRules); err != nil {
return err
}
if err := ns.nsSelectors.deprovision(oldObj.ObjectMeta.UID, oldNsSelectors, newNsSelectors); err != nil {
return err
}
if err := ns.podSelectors.deprovision(oldObj.ObjectMeta.UID, oldPodSelectors, newPodSelectors); err != nil {
return err
}
if err := ns.nsSelectors.provision(oldObj.ObjectMeta.UID, oldNsSelectors, newNsSelectors); err != nil {
return err
}
if err := ns.podSelectors.provision(oldObj.ObjectMeta.UID, oldPodSelectors, newPodSelectors); err != nil {
return err
}
if err := ns.rules.provision(oldObj.ObjectMeta.UID, oldRules, newRules); err != nil {
return err
}
return nil
}
func (ns *ns) deleteNetworkPolicy(obj *extnapi.NetworkPolicy) error {
delete(ns.policies, obj.ObjectMeta.UID)
// Analyse network policy to free resources
rules, nsSelectors, podSelectors, err := ns.analysePolicy(obj)
if err != nil {
return err
}
// Deprovision unused resources in dependency order
if err := ns.rules.deprovision(obj.ObjectMeta.UID, rules, nil); err != nil {
return err
}
if err := ns.nsSelectors.deprovision(obj.ObjectMeta.UID, nsSelectors, nil); err != nil {
return err
}
if err := ns.podSelectors.deprovision(obj.ObjectMeta.UID, podSelectors, nil); err != nil {
return err
}
return nil
}
func bypassRule(nsIpsetName ipset.Name) []string {
return []string{"-m", "set", "--match-set", string(nsIpsetName), "dst", "-j", "ACCEPT"}
}
func (ns *ns) ensureBypassRule(nsIpsetName ipset.Name) error {
return ns.ipt.Append(TableFilter, DefaultChain, bypassRule(ns.allPods.ipsetName)...)
}
func (ns *ns) deleteBypassRule(nsIpsetName ipset.Name) error {
return ns.ipt.Delete(TableFilter, DefaultChain, bypassRule(ns.allPods.ipsetName)...)
}
func (ns *ns) addNamespace(obj *coreapi.Namespace) error {
ns.namespace = obj
// Insert a rule to bypass policies if namespace is DefaultAllow
if !isDefaultDeny(obj) {
return ns.ensureBypassRule(ns.allPods.ipsetName)
}
// Add namespace ipset to matching namespace selectors
return ns.nsSelectors.addToMatching(obj.ObjectMeta.Labels, string(ns.allPods.ipsetName))
}
func (ns *ns) updateNamespace(oldObj, newObj *coreapi.Namespace) error {
ns.namespace = newObj
// Update bypass rule if ingress default has changed
oldDefaultDeny := isDefaultDeny(oldObj)
newDefaultDeny := isDefaultDeny(newObj)
if oldDefaultDeny != newDefaultDeny {
if oldDefaultDeny {
return ns.ensureBypassRule(ns.allPods.ipsetName)
}
if newDefaultDeny {
return ns.deleteBypassRule(ns.allPods.ipsetName)
}
}
// Re-evaluate namespace selector membership if labels have changed
if !equals(oldObj.ObjectMeta.Labels, newObj.ObjectMeta.Labels) {
for _, selector := range ns.nsSelectors.entries {
oldMatch := selector.matches(oldObj.ObjectMeta.Labels)
newMatch := selector.matches(newObj.ObjectMeta.Labels)
if oldMatch == newMatch {
continue
}
if oldMatch {
if err := selector.delEntry(string(ns.allPods.ipsetName)); err != nil {
return err
}
}
if newMatch {
if err := selector.addEntry(string(ns.allPods.ipsetName)); err != nil {
return err
}
}
}
}
return nil
}
func (ns *ns) deleteNamespace(obj *coreapi.Namespace) error {
ns.namespace = nil
// Remove bypass rule
if !isDefaultDeny(obj) {
return ns.deleteBypassRule(ns.allPods.ipsetName)
}
// Remove namespace ipset from any matching namespace selectors
return ns.nsSelectors.delFromMatching(obj.ObjectMeta.Labels, string(ns.allPods.ipsetName))
}
func hasIP(pod *coreapi.Pod) bool {
// Ensure pod isn't dead, has an IP address and isn't sharing the host network namespace
return pod.Status.Phase != "Succeeded" && pod.Status.Phase != "Failed" &&
len(pod.Status.PodIP) > 0 && !pod.Spec.HostNetwork
}
func equals(a, b map[string]string) bool {
if len(a) != len(b) {
return false
}
for ak, av := range a {
if b[ak] != av {
return false
}
}
return true
}
func isDefaultDeny(namespace *coreapi.Namespace) bool {
nnpJSON, found := namespace.ObjectMeta.Annotations["net.beta.kubernetes.io/network-policy"]
if !found {
return false
}
var nnp NamespaceNetworkPolicy
if err := json.Unmarshal([]byte(nnpJSON), &nnp); err != nil {
common.Log.Warn("Ignoring network policy annotation: unmarshal failed:", err)
// If we can't understand the annotation, behave as if it isn't present
return false
}
return nnp.Ingress != nil &&
nnp.Ingress.Isolation != nil &&
*(nnp.Ingress.Isolation) == DefaultDeny
}
+78
View File
@@ -0,0 +1,78 @@
package npc
import (
"strings"
"github.com/coreos/go-iptables/iptables"
"k8s.io/client-go/pkg/types"
"github.com/weaveworks/weave/common"
)
type ruleSpec struct {
key string
args []string
}
func newRuleSpec(proto *string, srcHost *selectorSpec, dstHost *selectorSpec, dstPort *string) *ruleSpec {
args := []string{}
if proto != nil {
args = append(args, "-p", *proto)
}
if srcHost != nil {
args = append(args, "-m", "set", "--match-set", string(srcHost.ipsetName), "src")
}
if dstHost != nil {
args = append(args, "-m", "set", "--match-set", string(dstHost.ipsetName), "dst")
}
if dstPort != nil {
args = append(args, "--dport", *dstPort)
}
args = append(args, "-j", "ACCEPT")
key := strings.Join(args, " ")
return &ruleSpec{key, args}
}
type ruleSet struct {
ipt *iptables.IPTables
users map[string]map[types.UID]struct{}
}
func newRuleSet(ipt *iptables.IPTables) *ruleSet {
return &ruleSet{ipt, make(map[string]map[types.UID]struct{})}
}
func (rs *ruleSet) deprovision(user types.UID, current, desired map[string]*ruleSpec) error {
for key, spec := range current {
if _, found := desired[key]; !found {
delete(rs.users[key], user)
if len(rs.users[key]) == 0 {
common.Log.Infof("deleting rule: %v", spec.args)
if err := rs.ipt.Delete(TableFilter, IngressChain, spec.args...); err != nil {
return err
}
delete(rs.users, key)
}
}
}
return nil
}
func (rs *ruleSet) provision(user types.UID, current, desired map[string]*ruleSpec) error {
for key, spec := range desired {
if _, found := current[key]; !found {
if _, found := rs.users[key]; !found {
common.Log.Infof("adding rule: %v", spec.args)
if err := rs.ipt.Append(TableFilter, IngressChain, spec.args...); err != nil {
return err
}
rs.users[key] = make(map[types.UID]struct{})
}
rs.users[key][user] = struct{}{}
}
}
return nil
}
+128
View File
@@ -0,0 +1,128 @@
package npc
import (
"k8s.io/client-go/pkg/api/unversioned"
"k8s.io/client-go/pkg/labels"
"k8s.io/client-go/pkg/types"
"github.com/weaveworks/weave/common"
"github.com/weaveworks/weave/npc/ipset"
)
type selectorSpec struct {
key string // string representation (for hash keying/equality comparison)
selector labels.Selector // k8s Selector object (for matching)
ipsetType ipset.Type // type of ipset to provision
ipsetName ipset.Name // generated ipset name
}
func newSelectorSpec(json *unversioned.LabelSelector, nsName string, ipsetType ipset.Type) (*selectorSpec, error) {
selector, err := unversioned.LabelSelectorAsSelector(json)
if err != nil {
return nil, err
}
key := selector.String()
return &selectorSpec{
key: key,
selector: selector,
// We prefix the selector string with the namespace name when generating
// the shortname because you can specify the same selector in multiple
// namespaces - we need those to map to distinct ipsets
ipsetName: ipset.Name(IpsetNamePrefix + shortName(nsName+":"+key)),
ipsetType: ipsetType}, nil
}
type selector struct {
ips ipset.Interface
spec *selectorSpec
}
func (s *selector) matches(labelMap map[string]string) bool {
return s.spec.selector.Matches(labels.Set(labelMap))
}
func (s *selector) addEntry(entry string) error {
return s.ips.AddEntry(s.spec.ipsetName, entry)
}
func (s *selector) delEntry(entry string) error {
return s.ips.DelEntry(s.spec.ipsetName, entry)
}
type selectorFn func(selector *selector) error
type selectorSet struct {
ips ipset.Interface
onNewSelector selectorFn
users map[string]map[types.UID]struct{} // list of users per selector
entries map[string]*selector
}
func newSelectorSet(ips ipset.Interface, onNewSelector selectorFn) *selectorSet {
return &selectorSet{
ips: ips,
onNewSelector: onNewSelector,
users: make(map[string]map[types.UID]struct{}),
entries: make(map[string]*selector)}
}
func (ss *selectorSet) addToMatching(labelMap map[string]string, entry string) error {
for _, s := range ss.entries {
if s.matches(labelMap) {
if err := s.addEntry(entry); err != nil {
return err
}
}
}
return nil
}
func (ss *selectorSet) delFromMatching(labelMap map[string]string, entry string) error {
for _, s := range ss.entries {
if s.matches(labelMap) {
if err := s.delEntry(entry); err != nil {
return err
}
}
}
return nil
}
func (ss *selectorSet) deprovision(user types.UID, current, desired map[string]*selectorSpec) error {
for key, spec := range current {
if _, found := desired[key]; !found {
delete(ss.users[key], user)
if len(ss.users[key]) == 0 {
common.Log.Infof("destroying ipset: %#v", spec)
if err := ss.ips.Destroy(spec.ipsetName); err != nil {
return err
}
delete(ss.entries, key)
delete(ss.users, key)
}
}
}
return nil
}
func (ss *selectorSet) provision(user types.UID, current, desired map[string]*selectorSpec) error {
for key, spec := range desired {
if _, found := current[key]; !found {
if _, found := ss.users[key]; !found {
common.Log.Infof("creating ipset: %#v", spec)
if err := ss.ips.Create(spec.ipsetName, spec.ipsetType); err != nil {
return err
}
selector := &selector{ss.ips, spec}
if err := ss.onNewSelector(selector); err != nil {
return err
}
ss.users[key] = make(map[types.UID]struct{})
ss.entries[key] = selector
}
ss.users[key][user] = struct{}{}
}
}
return nil
}
+37
View File
@@ -0,0 +1,37 @@
package npc
import (
"crypto/sha1"
"math/big"
)
const (
// This array:
// * Must include only printable UTF8 characters that are represented with a single byte (http://www.utf8-chartable.de/)
// * Must be at least of length 85 (`len("weave-") + l(2^160)/l(85)` equals 31, the maximum ipset name length)
// * Must not include commas as those are treated specially by `ipset add` when adding a named set to a list:set
// * Should not include space for readability
// * Should not include invalid chars for XML `<>&"'`
// * Should not include single quote or backslash to be nice to shell users
ShortNameSymbols = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789(){}[]+=_$%^!*|/?.;:@#~"
)
// sha1 hash an arbitrary string and represent it using the full range of
// printable ascii characters
func shortName(arbitrary string) string {
symbols := []byte(ShortNameSymbols)
sum := sha1.Sum([]byte(arbitrary))
i := big.NewInt(0).SetBytes(sum[:])
base := big.NewInt(int64(len(symbols)))
zero := big.NewInt(0)
result := make([]byte, 0)
for i.Cmp(zero) > 0 {
remainder := new(big.Int).Mod(i, base)
i.Sub(i, remainder)
i.Div(i, base)
result = append(result, symbols[remainder.Int64()])
}
return string(result)
}
+34
View File
@@ -0,0 +1,34 @@
package ulogd
import (
"io"
"os"
"os/exec"
"syscall"
"github.com/weaveworks/weave/common"
)
func waitForExit(cmd *exec.Cmd) {
if err := cmd.Wait(); err != nil {
common.Log.Fatalf("ulogd terminated: %v", err)
}
common.Log.Fatal("ulogd terminated normally")
}
func Start() error {
cmd := exec.Command("/usr/sbin/ulogd", "-v")
cmd.SysProcAttr = &syscall.SysProcAttr{
Pdeathsig: syscall.SIGKILL,
}
stdout, err := cmd.StderrPipe()
if err != nil {
return err
}
if err := cmd.Start(); err != nil {
return err
}
go io.Copy(os.Stdout, stdout)
go waitForExit(cmd)
return nil
}
+18 -12
View File
@@ -5,19 +5,24 @@ import (
"fmt"
"net"
"github.com/appc/cni/pkg/skel"
"github.com/appc/cni/pkg/types"
"github.com/containernetworking/cni/pkg/skel"
"github.com/containernetworking/cni/pkg/types"
"github.com/containernetworking/cni/pkg/types/current"
)
func (i *Ipam) CmdAdd(args *skel.CmdArgs) error {
var conf types.NetConf
if err := json.Unmarshal(args.StdinData, &conf); err != nil {
return fmt.Errorf("failed to load netconf: %v", err)
}
result, err := i.Allocate(args)
if err != nil {
return err
}
return result.Print()
return types.PrintResult(result, conf.CNIVersion)
}
func (i *Ipam) Allocate(args *skel.CmdArgs) (*types.Result, error) {
func (i *Ipam) Allocate(args *skel.CmdArgs) (types.Result, error) {
// extract the things we care about
conf, err := loadIPAMConf(args.StdinData)
if err != nil {
@@ -46,12 +51,13 @@ func (i *Ipam) Allocate(args *skel.CmdArgs) (*types.Result, error) {
if err != nil {
return nil, err
}
result := &types.Result{
IP4: &types.IPConfig{
IP: *ipnet,
result := &current.Result{
IPs: []*current.IPConfig{{
Version: "4",
Address: *ipnet,
Gateway: conf.Gateway,
Routes: conf.Routes,
},
}},
Routes: conf.Routes,
}
return result, nil
}
@@ -65,9 +71,9 @@ func (i *Ipam) Release(args *skel.CmdArgs) error {
}
type ipamConf struct {
Subnet string `json:"subnet,omitempty"`
Gateway net.IP `json:"gateway,omitempty"`
Routes []types.Route `json:"routes"`
Subnet string `json:"subnet,omitempty"`
Gateway net.IP `json:"gateway,omitempty"`
Routes []*types.Route `json:"routes"`
}
type netConf struct {
+3 -4
View File
@@ -72,9 +72,8 @@ func splitPoolID(poolID string) (subnet, iprange *net.IPNet, err error) {
func (i *Ipam) RequestAddress(poolID string, address net.IP, options map[string]string) (ip *net.IPNet, _ map[string]string, err error) {
i.logReq("RequestAddress", poolID, address, options)
defer func() { i.logRes("RequestAddress", err, ip) }()
// If we pass magic string "_" to weave IPAM it stores the address under its own string
if poolID == "weavepool" { // old-style
ip, err = i.weave.AllocateIP("_")
ip, err = i.weave.AllocateIP(api.NoContainerID)
return
}
subnet, iprange, err := splitPoolID(poolID)
@@ -83,12 +82,12 @@ func (i *Ipam) RequestAddress(poolID string, address net.IP, options map[string]
}
if address != nil { // try to claim specific address requested
ip = &net.IPNet{IP: address, Mask: subnet.Mask}
if err = i.weave.ClaimIP("_", ip); err != nil {
if err = i.weave.ClaimIP(api.NoContainerID, ip); err != nil {
return
}
} else {
// We are lying slightly to IPAM here: the range is not a subnet
if ip, err = i.weave.AllocateIPInSubnet("_", iprange); err != nil {
if ip, err = i.weave.AllocateIPInSubnet(api.NoContainerID, iprange); err != nil {
return
}
ip.Mask = subnet.Mask // fix up the subnet we lied about
+69 -60
View File
@@ -5,14 +5,16 @@ import (
"encoding/json"
"fmt"
"net"
"os"
"syscall"
"github.com/appc/cni/pkg/ipam"
"github.com/appc/cni/pkg/skel"
"github.com/appc/cni/pkg/types"
"github.com/containernetworking/cni/pkg/ipam"
"github.com/containernetworking/cni/pkg/skel"
"github.com/containernetworking/cni/pkg/types"
"github.com/containernetworking/cni/pkg/types/current"
"github.com/vishvananda/netlink"
"github.com/vishvananda/netns"
weaveapi "github.com/weaveworks/weave/api"
"github.com/weaveworks/weave/common"
weavenet "github.com/weaveworks/weave/net"
ipamplugin "github.com/weaveworks/weave/plugin/ipam"
)
@@ -32,7 +34,8 @@ func NewCNIPlugin(weave *weaveapi.Client) *CNIPlugin {
func loadNetConf(bytes []byte) (*NetConf, error) {
n := &NetConf{
BrName: weavenet.WeaveBridgeName,
BrName: weavenet.WeaveBridgeName,
HairpinMode: true,
}
if err := json.Unmarshal(bytes, n); err != nil {
return nil, fmt.Errorf("failed to load netconf: %v", err)
@@ -40,17 +43,26 @@ func loadNetConf(bytes []byte) (*NetConf, error) {
return n, nil
}
func (c *CNIPlugin) getIP(ipamType string, args *skel.CmdArgs) (result *types.Result, err error) {
func (c *CNIPlugin) getIP(ipamType string, args *skel.CmdArgs) (newResult *current.Result, err error) {
var result types.Result
// Default IPAM is Weave's own
if ipamType == "" {
result, err = ipamplugin.NewIpam(c.weave).Allocate(args)
} else {
result, err = ipam.ExecAdd(ipamType, args.StdinData)
}
if err == nil && result.IP4 == nil {
if err != nil {
return nil, err
}
if result == nil {
return nil, fmt.Errorf("Received no usable result from IPAM plugin")
}
newResult, err = current.NewResultFromResult(result)
// Check if ipam returned no results without error
if err == nil && len(newResult.IPs) == 0 {
return nil, fmt.Errorf("IPAM plugin failed to allocate IP address")
}
return result, err
return newResult, err
}
func (c *CNIPlugin) CmdAdd(args *skel.CmdArgs) error {
@@ -70,30 +82,40 @@ func (c *CNIPlugin) CmdAdd(args *skel.CmdArgs) error {
if err != nil {
return fmt.Errorf("unable to allocate IP address: %s", err)
}
// Only expecting one address
ip := result.IPs[0]
// If config says nothing about routes or gateway, default one will be via the bridge
if result.IP4.Routes == nil && result.IP4.Gateway == nil {
bridgeIP, err := findBridgeIP(conf.BrName, result.IP4.IP)
if err == errBridgeNoIP {
if len(result.Routes) == 0 && ip.Gateway == nil {
bridgeIP, err := weavenet.FindBridgeIP(conf.BrName, &ip.Address)
if err == weavenet.ErrBridgeNoIP {
bridgeArgs := *args
bridgeArgs.ContainerID = "weave:expose"
// It would be better if libcni let us send just the desired parameters,
// but there is a bug: https://github.com/containernetworking/cni/issues/410
// so just blank out the one we want to change
os.Setenv("CNI_CONTAINERID", bridgeArgs.ContainerID)
bridgeIPResult, err := c.getIP(conf.IPAM.Type, &bridgeArgs)
if err != nil {
return fmt.Errorf("unable to allocate IP address for bridge: %s", err)
}
if err := assignBridgeIP(conf.BrName, bridgeIPResult.IP4.IP); err != nil {
bridgeCIDR := bridgeIPResult.IPs[0].Address
if err := assignBridgeIP(conf.BrName, bridgeCIDR); err != nil {
return fmt.Errorf("unable to assign IP address to bridge: %s", err)
}
bridgeIP = bridgeIPResult.IP4.IP.IP
if err := weavenet.ExposeNAT(bridgeCIDR); err != nil {
return fmt.Errorf("unable to create NAT rules: %s", err)
}
bridgeIP = bridgeCIDR.IP
} else if err != nil {
return err
}
result.IP4.Gateway = bridgeIP
result.IPs[0].Gateway = bridgeIP
}
ns, err := netns.GetFromPath(args.Netns)
if err != nil {
return err
return fmt.Errorf("error accessing namespace %q: %s", args.Netns, err)
}
defer ns.Close()
@@ -107,20 +129,20 @@ func (c *CNIPlugin) CmdAdd(args *skel.CmdArgs) error {
id = fmt.Sprintf("%x", data)
}
if err := weavenet.AttachContainer(ns, id, args.IfName, conf.BrName, conf.MTU, false, []*net.IPNet{&result.IP4.IP}, false); err != nil {
if err := weavenet.AttachContainer(args.Netns, id, args.IfName, conf.BrName, conf.MTU, false, []*net.IPNet{&ip.Address}, false, conf.HairpinMode); err != nil {
return err
}
if err := weavenet.WithNetNSLinkUnsafe(ns, args.IfName, func(link netlink.Link) error {
return setupRoutes(link, args.IfName, result.IP4.IP, result.IP4.Gateway, result.IP4.Routes)
return setupRoutes(link, args.IfName, ip.Address, ip.Gateway, result.Routes)
}); err != nil {
return fmt.Errorf("error setting up routes: %s", err)
}
result.DNS = conf.DNS
return result.Print()
return types.PrintResult(result, conf.CNIVersion)
}
func setupRoutes(link netlink.Link, name string, ipnet net.IPNet, gw net.IP, routes []types.Route) error {
func setupRoutes(link netlink.Link, name string, ipnet net.IPNet, gw net.IP, routes []*types.Route) error {
var err error
if routes == nil { // If config says nothing about routes, add a default one
if !ipnet.Contains(gw) {
@@ -130,7 +152,7 @@ func setupRoutes(link netlink.Link, name string, ipnet net.IPNet, gw net.IP, rou
return err
}
}
routes = []types.Route{{Dst: zeroNetwork}}
routes = []*types.Route{{Dst: zeroNetwork}}
}
for _, r := range routes {
if r.GW != nil {
@@ -151,50 +173,32 @@ func assignBridgeIP(bridgeName string, ipnet net.IPNet) error {
return err
}
if err := netlink.AddrAdd(link, &netlink.Addr{IPNet: &ipnet}); err != nil {
// Treat as non-error if this address is already there
// - maybe another copy of this program just added it
if err == syscall.Errno(syscall.EEXIST) {
return nil
}
return fmt.Errorf("failed to add IP address to %q: %v", bridgeName, err)
}
return nil
}
var errBridgeNoIP = fmt.Errorf("Bridge has no IP address")
func findBridgeIP(bridgeName string, subnet net.IPNet) (net.IP, error) {
netdev, err := common.GetBridgeNetDev(bridgeName)
if err != nil {
return nil, fmt.Errorf("Failed to get netdev for %q bridge: %s", bridgeName, err)
}
if len(netdev.CIDRs) == 0 {
return nil, errBridgeNoIP
}
for _, cidr := range netdev.CIDRs {
if subnet.Contains(cidr.IP) {
return cidr.IP, nil
}
}
// None in the required subnet; just return the first one
return netdev.CIDRs[0].IP, nil
}
// As of CNI 0.5 spec:
// "Plugins should generally complete a DEL action without error even if some resources are missing"
// this method should therefore return nil in most, if not all, cases.
func (c *CNIPlugin) CmdDel(args *skel.CmdArgs) error {
conf, err := loadNetConf(args.StdinData)
if err != nil {
return err
logOnStderr(err)
return nil
}
ns, err := netns.GetFromPath(args.Netns)
if err != nil {
return err
}
defer ns.Close()
err = weavenet.WithNetNSUnsafe(ns, func() error {
link, err := netlink.LinkByName(args.IfName)
if err != nil {
return err
// As of CNI 0.3 spec, runtimes can send blank if they just want the address deallocated
if args.Netns != "" {
if _, err = weavenet.WithNetNS(args.Netns, "del-iface", args.IfName); err != nil {
// We log the error and carry on instead of returning nil, as there may still be resources to free in IPAM.
logOnStderr(fmt.Errorf("error removing interface %q: %s", args.IfName, err))
}
return netlink.LinkDel(link)
})
if err != nil {
return fmt.Errorf("error removing interface: %s", err)
}
// Default IPAM is Weave's own
@@ -203,16 +207,21 @@ func (c *CNIPlugin) CmdDel(args *skel.CmdArgs) error {
} else {
err = ipam.ExecDel(conf.IPAM.Type, args.StdinData)
}
if err != nil {
return fmt.Errorf("unable to release IP address: %s", err)
}
logOnStderr(fmt.Errorf("unable to release IP address: %s", err))
return nil
}
// Standard error is inherited from the caller (e.g. Kubelet, when running Weave Net's CNI plugin
// under Kubernetes) hence provided errors should eventually appear in the caller's log files.
func logOnStderr(err error) {
fmt.Fprintln(os.Stderr, "weave-cni:", err)
}
type NetConf struct {
types.NetConf
BrName string `json:"bridge"`
IsGW bool `json:"isGateway"`
IPMasq bool `json:"ipMasq"`
MTU int `json:"mtu"`
BrName string `json:"bridge"`
IsGW bool `json:"isGateway"`
IPMasq bool `json:"ipMasq"`
MTU int `json:"mtu"`
HairpinMode bool `json:"hairpinMode"`
}
+26 -13
View File
@@ -8,6 +8,7 @@ import (
"github.com/docker/libnetwork/drivers/remote/api"
"github.com/docker/libnetwork/netlabel"
"github.com/docker/libnetwork/types"
"golang.org/x/sys/unix"
"github.com/vishvananda/netlink"
weaveapi "github.com/weaveworks/weave/api"
@@ -94,11 +95,21 @@ func (driver *driver) DeleteNetwork(delreq *api.DeleteNetworkRequest) error {
func (driver *driver) CreateEndpoint(create *api.CreateEndpointRequest) (*api.CreateEndpointResponse, error) {
driver.logReq("CreateEndpoint", create, create.EndpointID)
common.Log.Debugf("interface %+v", create.Interface)
if create.Interface == nil {
return nil, driver.error("CreateEndpoint", "Not supported: creating an interface from within CreateEndpoint")
}
resp := &api.CreateEndpointResponse{}
// create veths. note we assume endpoint IDs are unique in the first 9 chars
name, peerName := vethPair(create.EndpointID)
if _, err := weavenet.CreateAndAttachVeth(name, peerName, weavenet.WeaveBridgeName, 0, false, nil); err != nil {
return nil, driver.error("JoinEndpoint", "%s", err)
}
// Send back the MAC address
link, _ := netlink.LinkByName(peerName)
resp := &api.CreateEndpointResponse{Interface: &api.EndpointInterface{MacAddress: link.Attrs().HardwareAddr.String()}}
driver.logRes("CreateEndpoint", resp)
return resp, nil
@@ -106,6 +117,17 @@ func (driver *driver) CreateEndpoint(create *api.CreateEndpointRequest) (*api.Cr
func (driver *driver) DeleteEndpoint(deleteReq *api.DeleteEndpointRequest) error {
driver.logReq("DeleteEndpoint", deleteReq, deleteReq.EndpointID)
name, _ := vethPair(deleteReq.EndpointID)
veth := &netlink.Veth{LinkAttrs: netlink.LinkAttrs{Name: name}}
if err := netlink.LinkDel(veth); err != nil {
// Try again using the name construction from earlier plugin version,
// in case user has upgraded with endpoints still extant
veth.Name = "vethwl" + deleteReq.EndpointID[:5]
if err2 := netlink.LinkDel(veth); err2 != nil {
// Note we report the first error
driver.warn("LeaveEndpoint", "unable to delete veth %q: %s", name, err)
}
}
return nil
}
@@ -122,11 +144,7 @@ func (driver *driver) JoinEndpoint(j *api.JoinRequest) (*api.JoinResponse, error
return nil, driver.error("JoinEndpoint", "unable to find network info: %s", err)
}
name, peerName := vethPair(j.EndpointID)
if _, err := weavenet.CreateAndAttachVeth(name, peerName, weavenet.WeaveBridgeName, 0, false, nil); err != nil {
return nil, driver.error("JoinEndpoint", "%s", err)
}
_, peerName := vethPair(j.EndpointID)
response := &api.JoinResponse{
InterfaceName: &api.InterfaceName{
SrcName: peerName,
@@ -186,12 +204,6 @@ func (driver *driver) setupNetworkInfo(id string, isOurs bool, options map[strin
func (driver *driver) LeaveEndpoint(leave *api.LeaveRequest) error {
driver.logReq("LeaveEndpoint", leave, fmt.Sprintf("%s:%s", leave.NetworkID, leave.EndpointID))
name, _ := vethPair(leave.EndpointID)
veth := &netlink.Veth{LinkAttrs: netlink.LinkAttrs{Name: name}}
if err := netlink.LinkDel(veth); err != nil {
driver.warn("LeaveEndpoint", "unable to delete veth: %s", err)
}
return nil
}
@@ -206,7 +218,8 @@ func (driver *driver) DiscoverDelete(disco *api.DiscoveryNotification) error {
}
func vethPair(id string) (string, string) {
return "vethwl" + id[:5], "vethwg" + id[:5]
// IFNAMSIZ is buffer length; subtract 6 for "vethwl" and 1 for terminating nul
return "vethwl" + id[:unix.IFNAMSIZ-7], "vethwg" + id[:unix.IFNAMSIZ-7]
}
// logging
+1 -2
View File
@@ -4,7 +4,6 @@ import (
"fmt"
weaveapi "github.com/weaveworks/weave/api"
"github.com/weaveworks/weave/common"
"github.com/weaveworks/weave/common/docker"
weavenet "github.com/weaveworks/weave/net"
)
@@ -46,7 +45,7 @@ func (w *watcher) ContainerStarted(id string) {
if err := w.weave.RegisterWithDNS(id, fqdn, net.IPAddress); err != nil {
w.driver.warn("ContainerStarted", "unable to register %s with weaveDNS: %s", id, err)
}
if err := common.ConfigureARPforVeths(info.State.Pid, weavenet.VethName); err != nil {
if _, err := weavenet.WithNetNSByPid(info.State.Pid, "configure-arp", weavenet.VethName); err != nil {
w.driver.warn("ContainerStarted", "unable to configure interfaces: %s", err)
}
}
+71
View File
@@ -0,0 +1,71 @@
package main
import (
"fmt"
"log"
"net"
"k8s.io/client-go/kubernetes"
api "k8s.io/client-go/pkg/api/v1"
"k8s.io/client-go/rest"
)
func getKubePeers() ([]string, error) {
config, err := rest.InClusterConfig()
if err != nil {
return nil, err
}
c, err := kubernetes.NewForConfig(config)
if err != nil {
return nil, err
}
nodeList, err := c.Nodes().List(api.ListOptions{})
if err != nil {
// Fallback for cases (e.g. from kube-up.sh) where kube-proxy is not running on master
config.Host = "http://localhost:8080"
log.Print("error contacting APIServer: ", err, "; trying with fallback: ", config.Host)
c, err = kubernetes.NewForConfig(config)
if err != nil {
return nil, err
}
nodeList, err = c.Nodes().List(api.ListOptions{})
}
if err != nil {
return nil, err
}
addresses := make([]string, 0, len(nodeList.Items))
for _, peer := range nodeList.Items {
var internalIP, externalIP string
for _, addr := range peer.Status.Addresses {
// Check it's a valid ipv4 address
ip := net.ParseIP(addr.Address)
if ip == nil || ip.To4() == nil {
continue
}
if addr.Type == "InternalIP" {
internalIP = ip.To4().String()
} else if addr.Type == "ExternalIP" {
externalIP = ip.To4().String()
}
}
// Fallback for cases where a Node has an ExternalIP but no InternalIP
if internalIP != "" {
addresses = append(addresses, internalIP)
} else if externalIP != "" {
addresses = append(addresses, externalIP)
}
}
return addresses, nil
}
func main() {
peers, err := getKubePeers()
if err != nil {
log.Fatalf("Could not get peers: %v", err)
}
for _, addr := range peers {
fmt.Println(addr)
}
}
@@ -1,3 +1,3 @@
FROM weaveworks/weaveexec
FROM DOCKERHUB_USER/weaveARCH_EXT
ADD ./plugin /home/weave/
ENTRYPOINT ["/home/weave/plugin"]
+2 -18
View File
@@ -11,7 +11,6 @@ import (
"strings"
"syscall"
cni "github.com/appc/cni/pkg/skel"
"github.com/docker/libnetwork/ipamapi"
weaveapi "github.com/weaveworks/weave/api"
"github.com/weaveworks/weave/common"
@@ -22,15 +21,13 @@ import (
"github.com/weaveworks/weave/plugin/skel"
)
var version = "(unreleased version)"
var version = "unreleased"
var Log = common.Log
func main() {
var (
justVersion bool
cniNet bool
cniIpam bool
address string
meshAddress string
logLevel string
@@ -38,8 +35,6 @@ func main() {
)
flag.BoolVar(&justVersion, "version", false, "print version and exit")
flag.BoolVar(&cniNet, "cni-net", false, "act as a CNI network plugin")
flag.BoolVar(&cniIpam, "cni-ipam", false, "act as a CNI IPAM plugin")
flag.StringVar(&logLevel, "log-level", "info", "logging level (debug, info, warning, error)")
flag.StringVar(&address, "socket", "/run/docker/plugins/weave.sock", "socket on which to listen")
flag.StringVar(&meshAddress, "meshsocket", "/run/docker/plugins/weavemesh.sock", "socket on which to listen in mesh mode")
@@ -56,17 +51,6 @@ func main() {
weave := weaveapi.NewClient(os.Getenv("WEAVE_HTTP_ADDR"), Log)
switch {
case cniIpam || strings.HasSuffix(os.Args[0], "weave-ipam"):
i := ipamplugin.NewIpam(weave)
cni.PluginMain(i.CmdAdd, i.CmdDel)
os.Exit(0)
case cniNet || strings.HasSuffix(os.Args[0], "weave-net"):
n := netplugin.NewCNIPlugin(weave)
cni.PluginMain(n.CmdAdd, n.CmdDel)
os.Exit(0)
}
// API 1.21 is the first version that supports docker network commands
dockerClient, err := docker.NewVersionedClientFromEnv("1.21")
if err != nil {
@@ -110,7 +94,7 @@ func run(dockerClient *docker.Client, weave *weaveapi.Client, address, meshAddre
}
go serveStatus(statusListener)
sigChan := make(chan os.Signal, 1)
signal.Notify(sigChan, os.Interrupt, os.Kill, syscall.SIGTERM)
signal.Notify(sigChan, os.Interrupt, syscall.SIGTERM)
select {
case sig := <-sigChan:
+3
View File
@@ -0,0 +1,3 @@
FROM DOCKERHUB_USER/weaveARCH_EXT
ADD ./launch.sh ./kube-peers /home/weave/
ENTRYPOINT ["/home/weave/launch.sh"]
+131
View File
@@ -0,0 +1,131 @@
#!/bin/sh
set -e
modprobe_safe() {
modprobe $1 || echo "Ignore the error if \"$1\" is built-in in the kernel" >&2
}
# Check whether xt_set actually exists
xt_set_exists() {
# Clean everything up in advance, in case there's leftovers
iptables -F WEAVE-KUBE-TEST 2>/dev/null || true
iptables -X WEAVE-KUBE-TEST 2>/dev/null || true
ipset destroy weave-kube-test 2>/dev/null || true
ipset create weave-kube-test hash:ip
iptables -t filter -N WEAVE-KUBE-TEST
if ! iptables -A WEAVE-KUBE-TEST -m set --match-set weave-kube-test src -j DROP; then
NOT_EXIST=1
fi
iptables -F WEAVE-KUBE-TEST
iptables -X WEAVE-KUBE-TEST
ipset destroy weave-kube-test
[ -z "$NOT_EXIST" ] || (echo "\"xt_set\" does not exist" >&2 && return 1)
}
# Default if not supplied - same as weave net default
IPALLOC_RANGE=${IPALLOC_RANGE:-10.32.0.0/12}
HTTP_ADDR=${WEAVE_HTTP_ADDR:-127.0.0.1:6784}
STATUS_ADDR=${WEAVE_STATUS_ADDR:-0.0.0.0:6782}
HOST_ROOT=${HOST_ROOT:-/host}
CONN_LIMIT=${CONN_LIMIT:-30}
# Check if the IP range overlaps anything existing on the host
/usr/bin/weaveutil netcheck $IPALLOC_RANGE weave
# Default for network policy
EXPECT_NPC=${EXPECT_NPC:-1}
# Ensure we have the required modules for NPC
if [ "${EXPECT_NPC}" != "0" ]; then
modprobe_safe br_netfilter
modprobe_safe xt_set
xt_set_exists
fi
# kube-proxy requires that bridged traffic passes through netfilter
if ! BRIDGE_NF_ENABLED=$(cat /proc/sys/net/bridge/bridge-nf-call-iptables); then
echo "Cannot detect bridge-nf support - network policy and iptables mode kubeproxy may not work reliably" >&2
else
if [ "$BRIDGE_NF_ENABLED" != "1" ]; then
echo 1 > /proc/sys/net/bridge/bridge-nf-call-iptables
fi
fi
# Explicitly create the bridge so we can pass --expect-npc
WEAVE_NPC_OPTS="--expect-npc"
if [ "${EXPECT_NPC}" = "0" ]; then
WEAVE_NPC_OPTS=""
fi
export HOST_ROOT=/host
/home/weave/weave --local create-bridge --force $WEAVE_NPC_OPTS
# Kubernetes sets HOSTNAME to the host's hostname
# when running a pod in host namespace.
NICKNAME_ARG=""
if [ -n "$HOSTNAME" ] ; then
NICKNAME_ARG="--nickname=$HOSTNAME"
fi
BRIDGE_OPTIONS="--datapath=datapath"
if [ "$(/home/weave/weave --local bridge-type)" = "bridge" ] ; then
# TODO: Call into weave script to do this
if ! ip link show vethwe-pcap >/dev/null 2>&1 ; then
ip link add name vethwe-bridge type veth peer name vethwe-pcap
ip link set vethwe-bridge up
ip link set vethwe-pcap up
ip link set vethwe-bridge master weave
fi
BRIDGE_OPTIONS="--iface=vethwe-pcap"
fi
if [ -z "$KUBE_PEERS" ]; then
if ! KUBE_PEERS=$(/home/weave/kube-peers) || [ -z "$KUBE_PEERS" ]; then
echo Failed to get peers >&2
exit 1
fi
fi
peer_count() {
echo $#
}
if [ -z "$IPALLOC_INIT" ]; then
IPALLOC_INIT="consensus=$(peer_count $KUBE_PEERS)"
fi
post_start_actions() {
# Wait for weave process to become responsive
while true ; do
curl $HTTP_ADDR/status >/dev/null 2>&1 && break
sleep 1
done
# Install CNI plugin binary to typical CNI bin location
# with fall-back to CNI directory used by kube-up on GCI OS
if ! mkdir -p $HOST_ROOT/opt/cni/bin ; then
if mkdir -p $HOST_ROOT/home/kubernetes/bin ; then
export WEAVE_CNI_PLUGIN_DIR=$HOST_ROOT/home/kubernetes/bin
else
echo "Failed to install the Weave CNI plugin" >&2
exit 1
fi
fi
mkdir -p $HOST_ROOT/etc/cni/net.d
/home/weave/weave --local setup-cni
# Expose the weave network so host processes can communicate with pods
/home/weave/weave --local expose $WEAVE_EXPOSE_IP
}
post_start_actions &
/home/weave/weaver $EXTRA_ARGS --port=6783 $BRIDGE_OPTIONS \
--http-addr=$HTTP_ADDR --status-addr=$STATUS_ADDR --docker-api='' --no-dns \
--ipalloc-range=$IPALLOC_RANGE $NICKNAME_ARG \
--ipalloc-init $IPALLOC_INIT \
--conn-limit=$CONN_LIMIT \
"$@" \
$KUBE_PEERS
@@ -0,0 +1,126 @@
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: weave-net
rules:
- apiGroups:
- ""
resources:
- pods
- namespaces
- nodes
verbs:
- get
- list
- watch
- apiGroups:
- extensions
resources:
- networkpolicies
verbs:
- get
- list
- watch
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: weave-net
namespace: kube-system
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: weave-net
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: weave-net
subjects:
- kind: ServiceAccount
name: weave-net
namespace: kube-system
---
apiVersion: extensions/v1beta1
kind: DaemonSet
metadata:
name: weave-net
namespace: kube-system
spec:
template:
metadata:
labels:
name: weave-net
spec:
hostNetwork: true
hostPID: true
containers:
- name: weave
image: weaveworks/weave-kube:latest
imagePullPolicy: Always
command:
- /home/weave/launch.sh
livenessProbe:
initialDelaySeconds: 30
httpGet:
host: 127.0.0.1
path: /status
port: 6784
securityContext:
privileged: true
volumeMounts:
- name: weavedb
mountPath: /weavedb
- name: cni-bin
mountPath: /host/opt
- name: cni-bin2
mountPath: /host/home
- name: cni-conf
mountPath: /host/etc
- name: dbus
mountPath: /host/var/lib/dbus
- name: lib-modules
mountPath: /lib/modules
resources:
requests:
cpu: 10m
- name: weave-npc
image: weaveworks/weave-npc:latest
imagePullPolicy: Always
resources:
requests:
cpu: 10m
securityContext:
privileged: true
env:
- name: HOSTNAME
valueFrom:
fieldRef:
apiVersion: v1
fieldPath: spec.nodeName
restartPolicy: Always
tolerations:
- key: node-role.kubernetes.io/master
effect: NoSchedule
serviceAccountName: weave-net
securityContext:
seLinuxOptions:
type: spc_t
volumes:
- name: weavedb
emptyDir: {}
- name: cni-bin
hostPath:
path: /opt
- name: cni-bin2
hostPath:
path: /home
- name: cni-conf
hostPath:
path: /etc
- name: dbus
hostPath:
path: /var/lib/dbus
- name: lib-modules
hostPath:
path: /lib/modules
+86
View File
@@ -0,0 +1,86 @@
apiVersion: extensions/v1beta1
kind: DaemonSet
metadata:
name: weave-net
namespace: kube-system
spec:
template:
metadata:
labels:
name: weave-net
annotations:
scheduler.alpha.kubernetes.io/tolerations: |
[
{
"key": "dedicated",
"operator": "Equal",
"value": "master",
"effect": "NoSchedule"
}
]
spec:
hostNetwork: true
hostPID: true
containers:
- name: weave
image: weaveworks/weave-kube:latest
imagePullPolicy: Always
command:
- /home/weave/launch.sh
livenessProbe:
initialDelaySeconds: 30
httpGet:
host: 127.0.0.1
path: /status
port: 6784
securityContext:
privileged: true
volumeMounts:
- name: weavedb
mountPath: /weavedb
- name: cni-bin
mountPath: /host/opt
- name: cni-bin2
mountPath: /host/home
- name: cni-conf
mountPath: /host/etc
- name: dbus
mountPath: /host/var/lib/dbus
- name: lib-modules
mountPath: /lib/modules
resources:
requests:
cpu: 10m
- name: weave-npc
image: weaveworks/weave-npc:latest
imagePullPolicy: Always
resources:
requests:
cpu: 10m
securityContext:
privileged: true
env:
- name: HOSTNAME
valueFrom:
fieldRef:
apiVersion: v1
fieldPath: spec.nodeName
restartPolicy: Always
volumes:
- name: weavedb
emptyDir: {}
- name: cni-bin
hostPath:
path: /opt
- name: cni-bin2
hostPath:
path: /home
- name: cni-conf
hostPath:
path: /etc
- name: dbus
hostPath:
path: /var/lib/dbus
- name: lib-modules
hostPath:
path: /lib/modules
+23
View File
@@ -0,0 +1,23 @@
FROM ALPINE_BASEIMAGE
# If we're building for another architecture than amd64, the CROSS_BUILD_ placeholder is removed so e.g. CROSS_BUILD_COPY turns into COPY
# If we're building normally, for amd64, CROSS_BUILD lines are removed
CROSS_BUILD_COPY qemu-QEMUARCH-static /usr/bin/
LABEL maintainer "Weaveworks Inc <help@weave.works>"
LABEL works.weave.role=system \
org.label-schema.name="Weave Net" \
org.label-schema.description="Weave Net creates a virtual network that connects Docker containers across multiple hosts and enables their automatic discovery" \
org.label-schema.url="https://weave.works" \
org.label-schema.vcs-url="https://github.com/weaveworks/weave" \
org.label-schema.vendor="Weaveworks"
RUN apk add --update \
iptables \
ipset \
ulogd \
&& rm -rf /var/cache/apk/* \
&& mknod /var/log/ulogd.pcap p
COPY ./weave-npc /usr/bin/weave-npc
COPY ./ulogd.conf /etc/ulogd.conf
ENTRYPOINT ["/usr/bin/weave-npc"]
+244
View File
@@ -0,0 +1,244 @@
package main
import (
"os"
"os/signal"
"syscall"
"github.com/coreos/go-iptables/iptables"
"github.com/spf13/cobra"
"k8s.io/client-go/kubernetes"
coreapi "k8s.io/client-go/pkg/api/v1"
extnapi "k8s.io/client-go/pkg/apis/extensions/v1beta1"
"k8s.io/client-go/pkg/fields"
"k8s.io/client-go/pkg/runtime"
"k8s.io/client-go/pkg/util/wait"
"k8s.io/client-go/rest"
"k8s.io/client-go/tools/cache"
"github.com/weaveworks/weave/common"
"github.com/weaveworks/weave/npc"
"github.com/weaveworks/weave/npc/ipset"
"github.com/weaveworks/weave/npc/metrics"
"github.com/weaveworks/weave/npc/ulogd"
)
var (
version = "unreleased"
metricsAddr string
logLevel string
allowMcast bool
nodeName string
)
func handleError(err error) { common.CheckFatal(err) }
func makeController(getter cache.Getter, resource string,
objType runtime.Object, handlers cache.ResourceEventHandlerFuncs) *cache.Controller {
listWatch := cache.NewListWatchFromClient(getter, resource, "", fields.Everything())
_, controller := cache.NewInformer(listWatch, objType, 0, handlers)
return controller
}
func resetIPTables(ipt *iptables.IPTables) error {
// Flush chains first so there are no refs to extant ipsets
if err := ipt.ClearChain(npc.TableFilter, npc.IngressChain); err != nil {
return err
}
if err := ipt.ClearChain(npc.TableFilter, npc.DefaultChain); err != nil {
return err
}
if err := ipt.ClearChain(npc.TableFilter, npc.MainChain); err != nil {
return err
}
return nil
}
func resetIPSets(ips ipset.Interface) error {
// Remove ipsets prefixed `weave-` only
sets, err := ips.List(npc.IpsetNamePrefix)
if err != nil {
common.Log.Errorf("Failed to retrieve list of ipsets")
return err
}
common.Log.Debugf("Got list of ipsets: %v", sets)
// Must remove references to ipsets by other ipsets before they're destroyed
for _, s := range sets {
common.Log.Debugf("Flushing ipset '%s'", string(s))
if err := ips.Flush(s); err != nil {
common.Log.Errorf("Failed to flush ipset '%s'", string(s))
return err
}
}
for _, s := range sets {
common.Log.Debugf("Destroying ipset '%s'", string(s))
if err := ips.Destroy(s); err != nil {
common.Log.Errorf("Failed to destroy ipset '%s'", string(s))
return err
}
}
return nil
}
func createBaseRules(ipt *iptables.IPTables, ips ipset.Interface) error {
// Configure main chain static rules
if err := ipt.Append(npc.TableFilter, npc.MainChain,
"-m", "state", "--state", "RELATED,ESTABLISHED", "-j", "ACCEPT"); err != nil {
return err
}
if allowMcast {
if err := ipt.Append(npc.TableFilter, npc.MainChain,
"-d", "224.0.0.0/4", "-j", "ACCEPT"); err != nil {
return err
}
}
if err := ipt.Append(npc.TableFilter, npc.MainChain,
"-m", "state", "--state", "NEW", "-j", string(npc.DefaultChain)); err != nil {
return err
}
if err := ipt.Append(npc.TableFilter, npc.MainChain,
"-m", "state", "--state", "NEW", "-j", string(npc.IngressChain)); err != nil {
return err
}
// If the destination address is not any of the local pods, let it through
if err := ips.Create(npc.LocalIpset, ipset.HashIP); err != nil {
return err
}
if err := ipt.Append(npc.TableFilter, npc.MainChain,
"-m", "set", "!", "--match-set", npc.LocalIpset, "dst", "-j", "ACCEPT"); err != nil {
return err
}
return nil
}
func root(cmd *cobra.Command, args []string) {
common.SetLogLevel(logLevel)
if nodeName == "" {
// HOSTNAME is set by Kubernetes for pods in the host network namespace
nodeName = os.Getenv("HOSTNAME")
}
if nodeName == "" {
common.Log.Fatalf("Must set node name via --node-name or $HOSTNAME")
}
common.Log.Infof("Starting Weaveworks NPC %s; node name %q", version, nodeName)
if err := metrics.Start(metricsAddr); err != nil {
common.Log.Fatalf("Failed to start metrics: %v", err)
}
if err := ulogd.Start(); err != nil {
common.Log.Fatalf("Failed to start ulogd: %v", err)
}
config, err := rest.InClusterConfig()
handleError(err)
client, err := kubernetes.NewForConfig(config)
handleError(err)
ipt, err := iptables.New()
handleError(err)
ips := ipset.New(common.LogLogger())
handleError(resetIPTables(ipt))
handleError(resetIPSets(ips))
handleError(createBaseRules(ipt, ips))
npc := npc.New(nodeName, ipt, ips)
nsController := makeController(client.Core().RESTClient(), "namespaces", &coreapi.Namespace{},
cache.ResourceEventHandlerFuncs{
AddFunc: func(obj interface{}) {
handleError(npc.AddNamespace(obj.(*coreapi.Namespace)))
},
DeleteFunc: func(obj interface{}) {
switch obj := obj.(type) {
case *coreapi.Namespace:
handleError(npc.DeleteNamespace(obj))
case cache.DeletedFinalStateUnknown:
// We know this object has gone away, but its final state is no longer
// available from the API server. Instead we use the last copy of it
// that we have, which is good enough for our cleanup.
handleError(npc.DeleteNamespace(obj.Obj.(*coreapi.Namespace)))
}
},
UpdateFunc: func(old, new interface{}) {
handleError(npc.UpdateNamespace(old.(*coreapi.Namespace), new.(*coreapi.Namespace)))
}})
podController := makeController(client.Core().RESTClient(), "pods", &coreapi.Pod{},
cache.ResourceEventHandlerFuncs{
AddFunc: func(obj interface{}) {
handleError(npc.AddPod(obj.(*coreapi.Pod)))
},
DeleteFunc: func(obj interface{}) {
switch obj := obj.(type) {
case *coreapi.Pod:
handleError(npc.DeletePod(obj))
case cache.DeletedFinalStateUnknown:
// We know this object has gone away, but its final state is no longer
// available from the API server. Instead we use the last copy of it
// that we have, which is good enough for our cleanup.
handleError(npc.DeletePod(obj.Obj.(*coreapi.Pod)))
}
},
UpdateFunc: func(old, new interface{}) {
handleError(npc.UpdatePod(old.(*coreapi.Pod), new.(*coreapi.Pod)))
}})
npController := makeController(client.Extensions().RESTClient(), "networkpolicies", &extnapi.NetworkPolicy{},
cache.ResourceEventHandlerFuncs{
AddFunc: func(obj interface{}) {
handleError(npc.AddNetworkPolicy(obj.(*extnapi.NetworkPolicy)))
},
DeleteFunc: func(obj interface{}) {
switch obj := obj.(type) {
case *extnapi.NetworkPolicy:
handleError(npc.DeleteNetworkPolicy(obj))
case cache.DeletedFinalStateUnknown:
// We know this object has gone away, but its final state is no longer
// available from the API server. Instead we use the last copy of it
// that we have, which is good enough for our cleanup.
handleError(npc.DeleteNetworkPolicy(obj.Obj.(*extnapi.NetworkPolicy)))
}
},
UpdateFunc: func(old, new interface{}) {
handleError(npc.UpdateNetworkPolicy(old.(*extnapi.NetworkPolicy), new.(*extnapi.NetworkPolicy)))
}})
go nsController.Run(wait.NeverStop)
go podController.Run(wait.NeverStop)
go npController.Run(wait.NeverStop)
signals := make(chan os.Signal, 1)
signal.Notify(signals, syscall.SIGINT, syscall.SIGTERM)
common.Log.Fatalf("Exiting: %v", <-signals)
}
func main() {
rootCmd := &cobra.Command{
Use: "weave-npc",
Short: "Weaveworks Kubernetes Network Policy Controller",
Run: root}
rootCmd.PersistentFlags().StringVar(&metricsAddr, "metrics-addr", ":6781", "metrics server bind address")
rootCmd.PersistentFlags().StringVar(&logLevel, "log-level", "debug", "logging level (debug, info, warning, error)")
rootCmd.PersistentFlags().BoolVar(&allowMcast, "allow-mcast", true, "allow all multicast traffic")
rootCmd.PersistentFlags().StringVar(&nodeName, "node-name", "", "only generate rules that apply to this node")
handleError(rootCmd.Execute())
}
+13
View File
@@ -0,0 +1,13 @@
[global]
logfile="/dev/null"
plugin="/usr/lib/ulogd/ulogd_inppkt_NFLOG.so"
plugin="/usr/lib/ulogd/ulogd_raw2packet_BASE.so"
plugin="/usr/lib/ulogd/ulogd_output_PCAP.so"
stack=log1:NFLOG,base1:BASE,pcap1:PCAP
[log1]
group=86
[pcap1]
file="/var/log/ulogd.pcap"
sync=1
+1 -1
View File
@@ -1,6 +1,6 @@
# This is a nearly-empty image that we use to create a data-only container for persistence
FROM scratch
MAINTAINER Weaveworks Inc <help@weave.works>
LABEL maintainer "Weaveworks Inc <help@weave.works>"
ENTRYPOINT ["data-only"]
# Work round Docker refusing to save an empty image
COPY Dockerfile /
-24
View File
@@ -1,24 +0,0 @@
FROM alpine
MAINTAINER Weaveworks Inc <help@weave.works>
LABEL works.weave.role=system
WORKDIR /home/weave
ENTRYPOINT ["/home/weave/sigproxy", "/home/weave/weave"]
RUN apk add --update \
curl \
ethtool \
iptables \
iproute2 \
util-linux \
conntrack-tools \
bind-tools \
&& rm -rf /var/cache/apk/*
ADD ./weave ./sigproxy ./weaveproxy ./symlink /home/weave/
ADD ./weaveutil /usr/bin/
ADD ./weavewait /w/w
ADD ./weavewait_noop /w-noop/w
ADD ./weavewait_nomcast /w-nomcast/w
ADD ./docker.tgz /
+34
View File
@@ -0,0 +1,34 @@
FROM ALPINE_BASEIMAGE
# If we're building for another architecture than amd64, the CROSS_BUILD_ placeholder is removed so e.g. CROSS_BUILD_COPY turns into COPY
# If we're building normally, for amd64, CROSS_BUILD lines are removed
CROSS_BUILD_COPY qemu-QEMUARCH-static /usr/bin/
LABEL maintainer "Weaveworks Inc <help@weave.works>"
LABEL works.weave.role=system \
org.label-schema.name="Weave Net" \
org.label-schema.description="Weave Net creates a virtual network that connects Docker containers across multiple hosts and enables their automatic discovery" \
org.label-schema.url="https://weave.works" \
org.label-schema.vcs-url="https://github.com/weaveworks/weave" \
org.label-schema.vendor="Weaveworks"
WORKDIR /home/weave
ENTRYPOINT ["/home/weave/sigproxy", "/home/weave/weave"]
RUN apk add --update \
curl \
ethtool \
iptables \
ipset \
iproute2 \
util-linux \
conntrack-tools \
bind-tools \
&& rm -rf /var/cache/apk/*
ADD ./weave ./sigproxy ./weaveproxy ./symlink /home/weave/
ADD ./weaveutil /usr/bin/
ADD ./weavewait /w/w
ADD ./weavewait_noop /w-noop/w
ADD ./weavewait_nomcast /w-nomcast/w
ADD ./docker /usr/bin/
+5 -4
View File
@@ -5,13 +5,14 @@ import (
"os"
"strings"
"github.com/docker/docker/pkg/mflag"
"github.com/weaveworks/common/mflag"
"github.com/weaveworks/common/mflagext"
"github.com/weaveworks/common/signals"
"github.com/weaveworks/weave/common"
"github.com/weaveworks/weave/common/mflagext"
"github.com/weaveworks/weave/proxy"
)
var version = "(unreleased version)"
var version = "unreleased"
var Log = common.Log
@@ -79,5 +80,5 @@ func main() {
p.AttachExistingContainers()
go p.Serve(listeners)
go p.ListenAndServeStatus("/home/weave/status.sock")
common.SignalHandlerLoop()
signals.SignalHandlerLoop(common.Log)
}
@@ -1,6 +1,4 @@
FROM scratch
MAINTAINER Weaveworks Inc <help@weave.works>
LABEL works.weave.role=system
FROM DOCKERHUB_USER/weaveexecARCH_EXT
WORKDIR /home/weave
ADD ./weaver /home/weave/
ADD weavedata.db /weavedb/
+29 -13
View File
@@ -6,20 +6,24 @@ import (
"time"
"github.com/weaveworks/go-checkpoint"
weave "github.com/weaveworks/weave/router"
)
var checker *checkpoint.Checker
var newVersion atomic.Value
var success atomic.Value
const (
updateCheckPeriod = 6 * time.Hour
)
func checkForUpdates(dockerVersion string, network string) {
func checkForUpdates(dockerVersion string, router *weave.NetworkRouter) {
newVersion.Store("")
success.Store(true)
handleResponse := func(r *checkpoint.CheckResponse, err error) {
if err != nil {
success.Store(false)
Log.Printf("Error checking version: %v", err)
return
}
@@ -32,12 +36,21 @@ func checkForUpdates(dockerVersion string, network string) {
var uts syscall.Utsname
syscall.Uname(&uts)
release := uts.Release[:]
releaseBytes := make([]byte, len(release))
i := 0
for ; i < len(release); i++ {
if release[i] == 0 {
break
}
releaseBytes[i] = uint8(release[i])
}
kernelVersion := string(releaseBytes[:i])
flags := map[string]string{
"docker-version": dockerVersion,
"kernel-version": charsToString(uts.Release[:]),
}
if network != "" {
flags["network"] = network
"kernel-version": kernelVersion,
}
// Start background version checking
@@ -46,18 +59,21 @@ func checkForUpdates(dockerVersion string, network string) {
Version: version,
SignatureFile: "",
Flags: flags,
ExtraFlags: func() []checkpoint.Flag { return checkpointFlags(router) },
}
checker = checkpoint.CheckInterval(&params, updateCheckPeriod, handleResponse)
}
func charsToString(ca []int8) string {
s := make([]byte, len(ca))
i := 0
for ; i < len(ca); i++ {
if ca[i] == 0 {
break
func checkpointFlags(router *weave.NetworkRouter) []checkpoint.Flag {
flags := []checkpoint.Flag{}
status := weave.NewNetworkRouterStatus(router)
for _, conn := range status.Connections {
if connectionName, ok := conn.Attrs["name"].(string); ok {
if _, encrypted := conn.Attrs["encrypted"]; encrypted {
connectionName = connectionName + " encrypted"
}
flags = append(flags, checkpoint.Flag{Key: "network", Value: connectionName})
}
s[i] = uint8(ca[i])
}
return string(s[:i])
return flags
}
+41 -23
View File
@@ -19,16 +19,10 @@ import (
weave "github.com/weaveworks/weave/router"
)
var allConnectionStates = []string{"established", "pending", "retrying", "failed", "connecting"}
var rootTemplate = template.New("root").Funcs(map[string]interface{}{
"countDNSEntries": func(entries []nameserver.EntryStatus) int {
count := 0
for _, entry := range entries {
if entry.Tombstone == 0 {
count++
}
}
return count
},
"countDNSEntries": countDNSEntries,
"printList": func(list []string) string {
if len(list) == 0 {
return "none"
@@ -55,27 +49,28 @@ var rootTemplate = template.New("root").Funcs(map[string]interface{}{
s.ips += entry.Size
}
printOwned := func(name string, nickName string, reachable bool, ips uint32) {
reachableStr := ""
if !reachable {
reachableStr = "- unreachable!"
}
printOwned := func(name string, nickName string, info string, ips uint32) {
percentageRanges := float32(ips) * 100.0 / float32(status.RangeNumIPs)
displayName := name + "(" + nickName + ")"
fmt.Fprintf(&buffer, "%-37v %8d IPs (%04.1f%% of total) %s\n",
displayName, ips, percentageRanges, reachableStr)
displayName, ips, percentageRanges, info)
}
// print the local info first
if ourStats := peerStats[router.Name]; ourStats != nil {
printOwned(router.Name, ourStats.nickname, true, ourStats.ips)
activeStr := fmt.Sprintf("(%d active)", status.ActiveIPs)
printOwned(router.Name, ourStats.nickname, activeStr, ourStats.ips)
}
// and then the rest
for peer, stats := range peerStats {
if peer != router.Name {
printOwned(peer, stats.nickname, stats.reachable, stats.ips)
reachableStr := ""
if !stats.reachable {
reachableStr = "- unreachable!"
}
printOwned(peer, stats.nickname, reachableStr, stats.ips)
}
}
@@ -94,7 +89,7 @@ var rootTemplate = template.New("root").Funcs(map[string]interface{}{
for _, conn := range conns {
counts[conn.State]++
}
return printCounts(counts, []string{"established", "pending", "retrying", "failed", "connecting"})
return printCounts(counts, allConnectionStates)
},
"printPeerConnectionCounts": func(peers []mesh.PeerStatus) string {
counts := make(map[string]int)
@@ -118,6 +113,26 @@ var rootTemplate = template.New("root").Funcs(map[string]interface{}{
"trimSuffix": strings.TrimSuffix,
})
func countDNSEntries(entries []nameserver.EntryStatus) int {
count := 0
for _, entry := range entries {
if entry.Tombstone == 0 {
count++
}
}
return count
}
func countDNSEntriesForPeer(peername string, entries []nameserver.EntryStatus) int {
count := 0
for _, entry := range entries {
if entry.Tombstone == 0 && entry.Origin == peername {
count++
}
}
return count
}
// Print counts in a specified order
func printCounts(counts map[string]int, keys []string) string {
var stringCounts []string
@@ -196,7 +211,7 @@ var targetsTemplate = defTemplate("targetsTemplate", `\
var connectionsTemplate = defTemplate("connectionsTemplate", `\
{{range .Router.Connections}}\
{{if .Outbound}}->{{else}}<-{{end}} {{printf "%-21v" .Address}} {{printf "%-11v" .State}} {{.Info}}
{{if .Outbound}}->{{else}}<-{{end}} {{printf "%-21v" .Address}} {{printf "%-11v" .State}} {{.Info}} {{range $key,$element := .Attrs}}{{if ne $key "name"}}{{$key}}={{$element}}{{end}}{{end}}
{{end}}\
`)
@@ -225,6 +240,7 @@ var ipamTemplate = defTemplate("ipamTemplate", `{{printIPAMRanges .Router .IPAM}
type VersionCheck struct {
Enabled bool
Success bool
NewVersion string
NextCheckAt time.Time
}
@@ -236,6 +252,7 @@ func versionCheck() *VersionCheck {
}
v.Enabled = true
v.Success = success.Load().(bool)
v.NewVersion = newVersion.Load().(string)
v.NextCheckAt = checker.NextCheckAt()
@@ -246,12 +263,12 @@ func (v *VersionCheck) String() string {
switch {
case !v.Enabled:
return "version check update disabled"
case !v.Success:
return fmt.Sprintf("failed to check latest version - see logs; next check at %s", v.NextCheckAt.Format("2006/01/02 15:04:05"))
case v.NewVersion != "":
return fmt.Sprintf("version %s available - please upgrade!",
v.NewVersion)
return fmt.Sprintf("version %s available - please upgrade!", v.NewVersion)
default:
return fmt.Sprintf("up to date; next check at %s",
v.NextCheckAt.Format("2006/01/02 15:04:05"))
return fmt.Sprintf("up to date; next check at %s", v.NextCheckAt.Format("2006/01/02 15:04:05"))
}
}
@@ -263,6 +280,7 @@ type WeaveStatus struct {
DNS *nameserver.Status `json:"DNS,omitempty"`
}
// Read-only functions, suitable for exposing on an unprotected socket
func HandleHTTP(muxRouter *mux.Router, version string, router *weave.NetworkRouter, allocator *ipam.Allocator, defaultSubnet address.CIDR, ns *nameserver.Nameserver, dnsserver *nameserver.DNSServer) {
status := func() WeaveStatus {
return WeaveStatus{
+57 -28
View File
@@ -11,9 +11,10 @@ import (
"strings"
"time"
"github.com/docker/docker/pkg/mflag"
"github.com/gorilla/mux"
"github.com/pkg/profile"
"github.com/weaveworks/common/mflag"
"github.com/weaveworks/common/signals"
"github.com/weaveworks/mesh"
"github.com/weaveworks/weave/common"
@@ -27,7 +28,7 @@ import (
weave "github.com/weaveworks/weave/router"
)
var version = "(unreleased version)"
var version = "unreleased"
var Log = common.Log
@@ -132,6 +133,7 @@ func main() {
bufSzMB int
noDiscovery bool
httpAddr string
statusAddr string
ipamConfig ipamConfig
dockerAPI string
peers []string
@@ -165,6 +167,7 @@ func main() {
mflag.BoolVar(&noDiscovery, []string{"#nodiscovery", "#-nodiscovery", "-no-discovery"}, false, "disable peer discovery")
mflag.IntVar(&bufSzMB, []string{"#bufsz", "-bufsz"}, 8, "capture buffer size in MB")
mflag.StringVar(&httpAddr, []string{"#httpaddr", "#-httpaddr", "-http-addr"}, "", "address to bind HTTP interface to (disabled if blank, absolute path indicates unix domain socket)")
mflag.StringVar(&statusAddr, []string{"-status-addr"}, "", "address to bind status+metrics interface to (disabled if blank, absolute path indicates unix domain socket)")
mflag.StringVar(&ipamConfig.Mode, []string{"-ipalloc-init"}, "", "allocator initialisation strategy (consensus, seed or observer)")
mflag.StringVar(&ipamConfig.IPRangeCIDR, []string{"#iprange", "#-iprange", "-ipalloc-range"}, "", "IP address range reserved for automatic allocation, in CIDR notation")
mflag.StringVar(&ipamConfig.IPSubnetCIDR, []string{"#ipsubnet", "#-ipsubnet", "-ipalloc-default-subnet"}, "", "subnet to allocate within by default, in CIDR notation")
@@ -221,10 +224,19 @@ func main() {
networkConfig.PacketLogging = nopPacketLogging{}
}
overlay, bridge := createOverlay(datapathName, ifaceName, isAWSVPC, config.Host, config.Port, bufSzMB)
config.Password = determinePassword(password)
overlay, bridge := createOverlay(datapathName, ifaceName, isAWSVPC, config.Host, config.Port, bufSzMB, config.Password != nil)
networkConfig.Bridge = bridge
name := peerName(routerName, bridge.Interface())
if bridge != nil {
if err := weavenet.DetectHairpin("vethwe-bridge", Log); err != nil {
Log.Errorf("Setting may cause connectivity issues : %s", err)
Log.Infof("Hairpin mode may have been enabled by other software on this machine")
}
}
name := peerName(routerName)
if nickName == "" {
var err error
@@ -232,7 +244,6 @@ func main() {
checkFatal(err)
}
config.Password = determinePassword(password)
config.TrustedSubnets = parseTrustedSubnets(trustedSubnetStr)
config.PeerDiscovery = !noDiscovery
@@ -240,11 +251,12 @@ func main() {
Log.Fatalf("--awsvpc mode is not compatible with the --password option")
}
db, err := db.NewBoltDB(dbPrefix + "data.db")
db, err := db.NewBoltDB(dbPrefix + db.FileName)
checkFatal(err)
defer db.Close()
router := weave.NewNetworkRouter(config, networkConfig, name, nickName, overlay, db)
router, err := weave.NewNetworkRouter(config, networkConfig, name, nickName, overlay, db)
checkFatal(err)
Log.Println("Our name is", router.Ourself)
if peers, err = router.InitialPeers(resume, peers); err != nil {
@@ -264,11 +276,7 @@ func main() {
dockerVersion = dockerCli.DockerVersion()
}
network := ""
if isAWSVPC {
network = "awsvpc"
}
checkForUpdates(dockerVersion, network)
checkForUpdates(dockerVersion, router)
observeContainers := func(o docker.ContainerObserver) {
if dockerCli != nil {
@@ -296,13 +304,16 @@ func main() {
}
trackerName = "awsvpc"
}
allocator, defaultSubnet = createAllocator(router, ipamConfig, db, t, isKnownPeer)
observeContainers(allocator)
var allContainerIDs []string
if dockerCli != nil {
ids, err := dockerCli.AllContainerIDs()
allContainerIDs, err = dockerCli.AllContainerIDs()
checkFatal(err)
allocator.PruneOwned(ids)
}
preClaims, err := findExistingAddresses(dockerCli, allContainerIDs, weavenet.WeaveBridgeName)
checkFatal(err)
allocator, defaultSubnet = createAllocator(router, ipamConfig, preClaims, db, t, isKnownPeer)
observeContainers(allocator)
allocator.PruneOwned(allContainerIDs)
}
var (
@@ -322,6 +333,7 @@ func main() {
if errors := router.InitiateConnections(peers, false); len(errors) > 0 {
Log.Fatal(common.ErrorMessages(errors))
}
checkFatal(router.CreateRestartSentinel())
// The weave script always waits for a status call to succeed,
// so there is no point in doing "weave launch --http-addr ''".
@@ -336,12 +348,23 @@ func main() {
}
router.HandleHTTP(muxRouter)
HandleHTTP(muxRouter, version, router, allocator, defaultSubnet, ns, dnsserver)
muxRouter.Methods("GET").Path("/metrics").Handler(metricsHandler(router, allocator, ns, dnsserver))
http.Handle("/", common.LoggingHTTPHandler(muxRouter))
Log.Println("Listening for HTTP control messages on", httpAddr)
go listenAndServeHTTP(httpAddr)
go listenAndServeHTTP(httpAddr, nil)
}
common.SignalHandlerLoop(router)
if statusAddr != "" {
muxRouter := mux.NewRouter()
HandleHTTP(muxRouter, version, router, allocator, defaultSubnet, ns, dnsserver)
muxRouter.Methods("GET").Path("/metrics").Handler(metricsHandler(router, allocator, ns, dnsserver))
statusMux := http.NewServeMux()
statusMux.Handle("/", muxRouter)
Log.Println("Listening for metrics requests on", statusAddr)
go listenAndServeHTTP(statusAddr, statusMux)
}
signals.SignalHandlerLoop(common.Log, router)
}
func options() map[string]string {
@@ -384,7 +407,7 @@ func (nopPacketLogging) LogPacket(string, weave.PacketKey) {
func (nopPacketLogging) LogForwardPacket(string, weave.ForwardPacketKey) {
}
func createOverlay(datapathName string, ifaceName string, isAWSVPC bool, host string, port int, bufSzMB int) (weave.NetworkOverlay, weave.Bridge) {
func createOverlay(datapathName string, ifaceName string, isAWSVPC bool, host string, port int, bufSzMB int, enableEncryption bool) (weave.NetworkOverlay, weave.Bridge) {
overlay := weave.NewOverlaySwitch()
var bridge weave.Bridge
var ignoreSleeve bool
@@ -401,7 +424,7 @@ func createOverlay(datapathName string, ifaceName string, isAWSVPC bool, host st
case datapathName != "":
iface, err := weavenet.EnsureInterface(datapathName)
checkFatal(err)
fastdp, err := weave.NewFastDatapath(iface, port)
fastdp, err := weave.NewFastDatapath(iface, port, enableEncryption)
checkFatal(err)
bridge = fastdp.Bridge()
overlay.Add("fastdp", fastdp.Overlay())
@@ -423,7 +446,7 @@ func createOverlay(datapathName string, ifaceName string, isAWSVPC bool, host st
return overlay, bridge
}
func createAllocator(router *weave.NetworkRouter, config ipamConfig, db db.DB, track tracker.LocalRangeTracker, isKnownPeer func(mesh.PeerName) bool) (*ipam.Allocator, address.CIDR) {
func createAllocator(router *weave.NetworkRouter, config ipamConfig, preClaims []ipam.PreClaim, db db.DB, track tracker.LocalRangeTracker, isKnownPeer func(mesh.PeerName) bool) (*ipam.Allocator, address.CIDR) {
ipRange, err := ipam.ParseCIDRSubnet(config.IPRangeCIDR)
checkFatal(err)
defaultSubnet := ipRange
@@ -442,6 +465,7 @@ func createAllocator(router *weave.NetworkRouter, config ipamConfig, db db.DB, t
Seed: config.SeedPeerNames,
Universe: ipRange,
IsObserver: config.Observer,
PreClaims: preClaims,
Quorum: func() uint { return determineQuorum(config.PeerCount, router) },
Db: db,
IsKnownPeer: isKnownPeer,
@@ -450,7 +474,9 @@ func createAllocator(router *weave.NetworkRouter, config ipamConfig, db db.DB, t
allocator := ipam.NewAllocator(c)
allocator.SetInterfaces(router.NewGossip("IPallocation", allocator))
gossip, err := router.NewGossip("IPallocation", allocator)
checkFatal(err)
allocator.SetInterfaces(gossip)
allocator.Start()
router.Peers.OnGC(func(peer *mesh.Peer) { allocator.PeerGone(peer.Name) })
@@ -460,7 +486,9 @@ func createAllocator(router *weave.NetworkRouter, config ipamConfig, db db.DB, t
func createDNSServer(config dnsConfig, router *mesh.Router, isKnownPeer func(mesh.PeerName) bool) (*nameserver.Nameserver, *nameserver.DNSServer) {
ns := nameserver.New(router.Ourself.Peer.Name, config.Domain, isKnownPeer)
router.Peers.OnGC(func(peer *mesh.Peer) { ns.PeerGone(peer.Name) })
ns.SetGossip(router.NewGossip("nameserver", ns))
gossip, err := router.NewGossip("nameserver", ns)
checkFatal(err)
ns.SetGossip(gossip)
upstream := nameserver.NewUpstream(config.ResolvConf, config.EffectiveListenAddress)
dnsserver, err := nameserver.NewDNSServer(ns, config.Domain, config.ListenAddress,
upstream, uint32(config.TTL), config.ClientTimeout)
@@ -508,10 +536,11 @@ func determinePassword(password string) []byte {
return []byte(password)
}
func peerName(routerName string, iface *net.Interface) mesh.PeerName {
func peerName(routerName string) mesh.PeerName {
if routerName == "" {
if iface == nil {
Log.Fatal("Either an interface must be specified with --datapath or --iface, or a name with --name")
iface, err := net.InterfaceByName(weavenet.WeaveBridgeName)
if err != nil {
Log.Fatalf("Unable to find bridge %q", weavenet.WeaveBridgeName)
}
routerName = iface.HardwareAddr.String()
}
@@ -554,7 +583,7 @@ func parsePeerNames(s string) ([]mesh.PeerName, error) {
return peerNames, nil
}
func listenAndServeHTTP(httpAddr string) {
func listenAndServeHTTP(httpAddr string, handler http.Handler) {
protocol := "tcp"
if strings.HasPrefix(httpAddr, "/") {
os.Remove(httpAddr) // in case it's there from last time
@@ -564,7 +593,7 @@ func listenAndServeHTTP(httpAddr string) {
if err != nil {
Log.Fatal("Unable to create http listener socket: ", err)
}
err = http.Serve(l, nil)
err = http.Serve(l, handler)
if err != nil {
Log.Fatal("Unable to create http server", err)
}
Loaded 100 of 280 files, more files were not shown because too many files have changed in this diff. Show more