Move proxy attach from shell to Go

Note we don't need to propagate shell-script env vars now
This commit is contained in:
Bryan Boreham committed 2017-05-12 06:56:52 +00:00
1 parent edbf85655a
commit b1917d909a
4 files changed
+60 -74

No files matched your search

-38
View File
@@ -6,8 +6,6 @@ import (
"fmt"
"io/ioutil"
"net/http"
"os"
"os/exec"
"regexp"
"strings"
@@ -25,42 +23,6 @@ var (
Log = common.Log
)
func callWeave(args ...string) ([]byte, []byte, error) {
args = append([]string{"--local"}, args...)
cmd := exec.Command("./weave", args...)
cmd.Env = []string{
"PATH=/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
}
propagateEnv := func(key string) {
if val := os.Getenv(key); val != "" {
cmd.Env = append(cmd.Env, fmt.Sprintf("%s=%s", key, val))
}
}
propagateEnv("DOCKER_HOST")
// Propagate WEAVE_DEBUG, to make debugging easier.
propagateEnv("WEAVE_DEBUG")
// This prevents the code coverage contortions in our
// integration test suite breaking things.
propagateEnv("COVERAGE")
// In case the router control endpoint address is non-standard.
propagateEnv("WEAVE_HTTP_ADDR")
Log.Debug("Calling weave args: ", args, "env: ", cmd.Env)
var stdout, stderr bytes.Buffer
cmd.Stdout = &stdout
cmd.Stderr = &stderr
err := cmd.Run()
if err != nil {
Log.Debug("weave returned error: ", err)
}
return stdout.Bytes(), stderr.Bytes(), err
}
func unmarshalRequestBody(r *http.Request, target interface{}) error {
body, err := ioutil.ReadAll(r.Body)
if err != nil {
+59 -34
View File
@@ -3,7 +3,6 @@ package proxy
import (
"bytes"
"crypto/tls"
"errors"
"fmt"
"net"
"net/http"
@@ -16,10 +15,11 @@ import (
"time"
docker "github.com/fsouza/go-dockerclient"
"github.com/pkg/errors"
weaveapi "github.com/weaveworks/weave/api"
weavedocker "github.com/weaveworks/weave/common/docker"
weavenet "github.com/weaveworks/weave/net"
"github.com/weaveworks/weave/net/address"
)
const (
@@ -63,6 +63,7 @@ type Config struct {
Version string
WithoutDNS bool
NoMulticastRoute bool
KeepTXOn bool
DockerBridge string
DockerHost string
}
@@ -509,53 +510,77 @@ func (proxy *Proxy) attach(containerID string) error {
return nil
}
Log.Infof("Attaching container %s with WEAVE_CIDR \"%s\" to weave network", container.ID, strings.Join(cidrs, " "))
if err := validateCIDRs(cidrs); err != nil {
ips, err := proxy.allocateCIDRs(container.ID, cidrs)
if err != nil {
return err
}
args := []string{"attach"}
args = append(args, cidrs...)
fqdn := container.Config.Hostname + "." + container.Config.Domainname
if !proxy.NoRewriteHosts {
args = append(args, "--rewrite-hosts")
var extraHosts []string
if container.HostConfig != nil {
for _, eh := range container.HostConfig.ExtraHosts {
args = append(args, fmt.Sprintf("--add-host=%s", eh))
extraHosts = container.HostConfig.ExtraHosts
}
proxy.RewriteEtcHosts(container.HostsPath, fqdn, ips, extraHosts)
}
pid := container.State.Pid
// Passing 0 for mtu means it will be taken from the bridge
err = weavenet.AttachContainer(weavenet.NSPathByPid(pid), fmt.Sprint(pid), weavenet.VethName, weavenet.WeaveBridgeName, 0, !proxy.NoMulticastRoute, ips, proxy.KeepTXOn)
if err != nil {
return err
}
if !proxy.WithoutDNS {
for _, ip := range ips {
if err := proxy.weave.RegisterWithDNS(container.ID, fqdn, ip.IP.String()); err != nil {
return errors.Wrapf(err, "unable to register %s with weaveDNS: %s", container.ID, err)
}
}
}
if proxy.NoMulticastRoute {
args = append(args, "--no-multicast-route")
}
args = append(args, container.ID)
return callWeaveAttach(container, args)
return err
}
func callWeaveAttach(container *docker.Container, args []string) error {
if _, stderr, err := callWeave(args...); err != nil {
Log.Warningf("Attaching container %s to weave network failed: %s", container.ID, string(stderr))
return errors.New(string(stderr))
} else if len(stderr) > 0 {
Log.Warningf("Attaching container %s to weave network: %s", container.ID, string(stderr))
func (proxy *Proxy) allocateCIDRs(containerID string, cidrs []string) ([]*net.IPNet, error) {
if len(cidrs) == 0 {
cidrs = []string{"net:default"}
}
return nil
}
func validateCIDRs(cidrs []string) error {
var ipnet *net.IPNet
var err error
var ipnets []*net.IPNet
for _, cidr := range cidrs {
if cidr == "net:default" {
continue
}
for _, prefix := range []string{"ip:", "net:", ""} {
if strings.HasPrefix(cidr, prefix) {
if _, err := address.ParseCIDR(strings.TrimPrefix(cidr, prefix)); err == nil {
break
}
return fmt.Errorf("invalid WEAVE_CIDR: %s", cidr)
switch {
case cidr == "net:default":
ipnet, err = proxy.weave.AllocateIP(containerID)
case strings.HasPrefix(cidr, "net:"):
var subnet *net.IPNet
_, subnet, err = net.ParseCIDR(strings.TrimPrefix(cidr, "net:"))
if err != nil {
break
}
ipnet, err = proxy.weave.AllocateIPInSubnet(containerID, subnet)
case strings.HasPrefix(cidr, "ip:"):
ipnet, err = proxy.claimCIDR(containerID, strings.TrimPrefix(cidr, "ip:"))
default:
ipnet, err = proxy.claimCIDR(containerID, cidr)
}
if err != nil {
return nil, errors.Wrapf(err, "for %q", cidr)
}
ipnets = append(ipnets, ipnet)
}
return nil
return ipnets, nil
}
func (proxy *Proxy) claimCIDR(containerID, cidr string) (*net.IPNet, error) {
ip, ipnet, err := net.ParseCIDR(cidr)
if err != nil {
return nil, err
}
ipnet.IP = ip // we want the specific IP plus the mask
err = proxy.weave.ClaimIP(containerID, ipnet)
return ipnet, err
}
func (proxy *Proxy) weaveCIDRs(networkMode string, env []string) ([]string, error) {