Skip to content

Commit

Permalink
Perform AWSVPC checks for attach in script rather than in weaveutil
Browse files Browse the repository at this point in the history
  • Loading branch information
bboreham committed Jun 7, 2016
1 parent c774df6 commit d29afb5
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 55 deletions.
8 changes: 0 additions & 8 deletions api/ipam.go
Expand Up @@ -53,14 +53,6 @@ func (client *Client) DefaultSubnet() (*net.IPNet, error) {
return ipnet, err
}

func (client *Client) LocalRangeTracker() (string, error) {
t, err := client.httpVerb("GET", fmt.Sprintf("/ipinfo/tracker"), nil)
if err != nil {
return "", err
}
return t, nil
}

func parseIP(body string) (*net.IPNet, error) {
ip, ipnet, err := net.ParseCIDR(string(body))
if err != nil {
Expand Down
55 changes: 10 additions & 45 deletions prog/weaveutil/attach.go
Expand Up @@ -3,42 +3,31 @@ package main
import (
"fmt"
"net"
"os"
"strconv"
"syscall"

docker "github.com/fsouza/go-dockerclient"
"github.com/vishvananda/netns"

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

func attach(args []string) error {
if len(args) < 4 {
cmdUsage("attach-container", "[--no-multicast-route] <container-id> <bridge-name> <mtu> <cidr>...")
cmdUsage("attach-container", "[--no-multicast-route] [--keep-tx-on] <container-id> <bridge-name> <mtu> <cidr>...")
}

client := api.NewClient(os.Getenv("WEAVE_HTTP_ADDR"), common.Log)
keepTXOn := false
isAWSVPC := false
// In a case of an error, we skip applying necessary steps for AWSVPC, because
// "attach" should work without the weave router running.
if t, err := client.LocalRangeTracker(); err != nil {
fmt.Fprintf(os.Stderr, "unable to determine tracker: %s; skipping AWSVPC initialization\n", err)
} else if t == "awsvpc" {
isAWSVPC = true
keepTXOn = true
}

withMulticastRoute := true
if args[0] == "--no-multicast-route" {
withMulticastRoute = false
args = args[1:]
}
if isAWSVPC {
withMulticastRoute = false
for i := 0; i < len(args); i++ {
switch args[i] {
case "--no-multicast-route":
withMulticastRoute = false
args = append(args[:i], args[i+1:]...)
case "--keep-tx-on":
keepTXOn = true
args = append(args[:i], args[i+1:]...)
}
}

pid, nsContainer, err := containerPidAndNs(args[0])
Expand All @@ -59,20 +48,6 @@ func attach(args []string) error {
return err
}

if isAWSVPC {
// Currently, we allow only IP addresses from the default subnet
if defaultSubnet, err := client.DefaultSubnet(); err != nil {
fmt.Fprintf(os.Stderr, "unable to retrieve default subnet: %s; skipping AWSVPC checks\n", err)
} else {
for _, cidr := range cidrs {
if !sameSubnet(cidr, defaultSubnet) {
format := "AWSVPC constraints violation: %s does not belong to the default subnet %s"
return fmt.Errorf(format, cidr, defaultSubnet)
}
}
}
}

err = weavenet.AttachContainer(nsContainer, fmt.Sprint(pid), weavenet.VethName, args[1], mtu, withMulticastRoute, cidrs, keepTXOn)
// If we detected an error but the container has died, tell the user that instead.
if err != nil && !processExists(pid) {
Expand All @@ -81,16 +56,6 @@ func attach(args []string) error {
return err
}

// sameSubnet checks whether ip belongs to network's subnet
func sameSubnet(ip *net.IPNet, network *net.IPNet) bool {
if network.Contains(ip.IP) {
i1, i2 := ip.Mask.Size()
n1, n2 := network.Mask.Size()
return i1 == n1 && i2 == n2
}
return false
}

func containerPidAndNs(containerID string) (int, netns.NsHandle, error) {
c, err := docker.NewVersionedClientFromEnv("1.18")
if err != nil {
Expand Down
17 changes: 15 additions & 2 deletions weave
Expand Up @@ -533,10 +533,9 @@ random_mac() {

util_op() {
if command_exists weaveutil ; then
WEAVE_HTTP_ADDR=$WEAVE_HTTP_ADDR weaveutil "$@"
weaveutil "$@"
else
docker run --rm --privileged --net=host --pid=host $(docker_sock_options) \
-e WEAVE_HTTP_ADDR \
--entrypoint=/usr/bin/weaveutil $EXEC_IMAGE "$@"
fi
}
Expand Down Expand Up @@ -894,6 +893,8 @@ container_in_host_ns() {
attach() {
ATTACH_ARGS=""
[ -n "$NO_MULTICAST_ROUTE" ] && ATTACH_ARGS="--no-multicast-route"
# Relying on AWSVPC being set in 'ipam_cidrs allocate', except for 'weave restart'
[ -n "$AWSVPC" ] && ATTACH_ARGS="--no-multicast-route --keep-tx-on"
util_op attach-container $ATTACH_ARGS $CONTAINER $BRIDGE $MTU "$@"
}

Expand Down Expand Up @@ -1269,6 +1270,12 @@ ipam_reclaim_no_check_alive() {
done
}

detect_awsvpc() {
# Ignoring errors here: if we cannot detect AWSVPC we will skip the relevant
# steps, because "attach" should work without the weave router running.
[ "$(call_weave GET /ipinfo/tracker)" != "awsvpc" ] || AWSVPC=1
}

# Call IPAM as necessary to lookup or allocate addresses
#
# $1 is one of 'lookup', 'allocate' or 'allocate_no_check_alive', $2
Expand All @@ -1285,6 +1292,11 @@ ipam_cidrs() {
allocate)
METHOD=POST
CHECK_ALIVE="?check-alive=true"
detect_awsvpc
if [ -n "$AWSVPC" -a $# -gt 0 ] ; then
echo "Error: no IP addresses or subnets may be specified in AWSVPC mode" >&2
return 1
fi
;;
allocate_no_check_alive)
METHOD=POST
Expand Down Expand Up @@ -2098,6 +2110,7 @@ EOF
for CIDR in $ALL_CIDRS ; do
call_weave PUT /ip/$CONTAINER/$CIDR?check-alive=true
done
detect_awsvpc
do_or_die $CONTAINER attach $ALL_CIDRS
when_weave_running with_container_fqdn $CONTAINER put_dns_fqdn $ALL_CIDRS
echo $RES
Expand Down

0 comments on commit d29afb5

Please sign in to comment.