diff --git a/.gitignore b/.gitignore index 4d5f7002..9a5aa837 100644 --- a/.gitignore +++ b/.gitignore @@ -41,8 +41,7 @@ prog/sigproxy/sigproxy prog/weavewait/weavewait prog/weavewait/weavewait_noop prog/weavewait/weavewait_nomcast -prog/netcheck/netcheck -prog/docker_tls_args/docker_tls_args +prog/weaveutil/weaveutil prog/plugin/plugin testing/cover/cover testing/runner/runner @@ -59,8 +58,7 @@ prog/weaveexec/weavewait prog/weaveexec/weavewait_noop prog/weaveexec/weavewait_nomcast prog/weaveexec/sigproxy -prog/weaveexec/netcheck -prog/weaveexec/docker_tls_args +prog/weaveexec/weaveutil prog/weaveexec/docker*.tgz Vagrantfile.local test/tls/tls diff --git a/Makefile b/Makefile index 29190932..57e1fffb 100644 --- a/Makefile +++ b/Makefile @@ -15,13 +15,12 @@ SIGPROXY_EXE=prog/sigproxy/sigproxy WEAVEWAIT_EXE=prog/weavewait/weavewait WEAVEWAIT_NOOP_EXE=prog/weavewait/weavewait_noop WEAVEWAIT_NOMCAST_EXE=prog/weavewait/weavewait_nomcast -NETCHECK_EXE=prog/netcheck/netcheck -DOCKERTLSARGS_EXE=prog/docker_tls_args/docker_tls_args +WEAVEUTIL_EXE=prog/weaveutil/weaveutil DOCKERPLUGIN_EXE=prog/plugin/plugin RUNNER_EXE=tools/runner/runner TEST_TLS_EXE=test/tls/tls -EXES=$(WEAVER_EXE) $(SIGPROXY_EXE) $(WEAVEPROXY_EXE) $(WEAVEWAIT_EXE) $(WEAVEWAIT_NOOP_EXE) $(WEAVEWAIT_NOMCAST_EXE) $(NETCHECK_EXE) $(DOCKERTLSARGS_EXE) $(DOCKERPLUGIN_EXE) $(TEST_TLS_EXE) +EXES=$(WEAVER_EXE) $(SIGPROXY_EXE) $(WEAVEPROXY_EXE) $(WEAVEWAIT_EXE) $(WEAVEWAIT_NOOP_EXE) $(WEAVEWAIT_NOMCAST_EXE) $(WEAVEUTIL_EXE) $(DOCKERPLUGIN_EXE) $(TEST_TLS_EXE) WEAVER_UPTODATE=.weaver.uptodate WEAVEEXEC_UPTODATE=.weaveexec.uptodate @@ -70,23 +69,22 @@ else endif $(NETGO_CHECK) -$(NETCHECK_EXE): common/*.go common/*/*.go net/*.go +$(WEAVEUTIL_EXE): common/*.go common/*/*.go net/*.go go get -tags netgo ./$(@D) go build $(BUILD_FLAGS) -o $@ ./$(@D) $(NETGO_CHECK) $(WEAVER_EXE): router/*.go mesh/*.go ipam/*.go ipam/*/*.go nameserver/*.go prog/weaver/*.go $(WEAVEPROXY_EXE): proxy/*.go prog/weaveproxy/*.go -$(NETCHECK_EXE): prog/netcheck/*.go +$(WEAVEUTIL_EXE): prog/weaveutil/*.go # These next programs need separate rules as they fail the netgo check in # the main build stanza due to not importing net package $(SIGPROXY_EXE): prog/sigproxy/*.go -$(DOCKERTLSARGS_EXE): prog/docker_tls_args/*.go $(DOCKERPLUGIN_EXE): prog/plugin/*.go plugin/net/*.go plugin/ipam/*.go plugin/skel/*.go api/*.go common/docker/*.go $(TEST_TLS_EXE): test/tls/*.go -$(SIGPROXY_EXE) $(DOCKERTLSARGS_EXE) $(DOCKERPLUGIN_EXE) $(TEST_TLS_EXE): +$(SIGPROXY_EXE) $(DOCKERPLUGIN_EXE) $(TEST_TLS_EXE): go get -tags netgo ./$(@D) go build $(BUILD_FLAGS) -o $@ ./$(@D) @@ -106,15 +104,14 @@ $(WEAVER_UPTODATE): prog/weaver/Dockerfile $(WEAVER_EXE) $(SUDO) DOCKER_HOST=$(DOCKER_HOST) docker build -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) $(NETCHECK_EXE) $(DOCKERTLSARGS_EXE) +$(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) cp weave prog/weaveexec/weave cp $(SIGPROXY_EXE) prog/weaveexec/sigproxy cp $(WEAVEPROXY_EXE) prog/weaveexec/weaveproxy cp $(WEAVEWAIT_EXE) prog/weaveexec/weavewait cp $(WEAVEWAIT_NOOP_EXE) prog/weaveexec/weavewait_noop cp $(WEAVEWAIT_NOMCAST_EXE) prog/weaveexec/weavewait_nomcast - cp $(NETCHECK_EXE) prog/weaveexec/netcheck - cp $(DOCKERTLSARGS_EXE) prog/weaveexec/docker_tls_args + 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 touch $@ diff --git a/prog/netcheck/main.go b/prog/netcheck/main.go deleted file mode 100644 index fe822f2e..00000000 --- a/prog/netcheck/main.go +++ /dev/null @@ -1,54 +0,0 @@ -/* netcheck: check whether a given network or address overlaps with any existing routes */ -package main - -import ( - "fmt" - "net" - "os" - - "github.com/docker/docker/pkg/mflag" - weavenet "github.com/weaveworks/weave/net" -) - -func fatal(err error) { - fmt.Fprintln(os.Stderr, err) - os.Exit(1) -} - -type stringList map[string]struct{} - -func (ss *stringList) Set(value string) error { - (*ss)[value] = struct{}{} - return nil -} - -func (ss *stringList) String() string { - return fmt.Sprintf("%v", *ss) -} - -func main() { - ignoreIfaceNames := make(stringList) - - mflag.Var(&ignoreIfaceNames, []string{"-ignore-iface"}, "name of interface to ignore)") - mflag.Parse() - - if len(mflag.Args()) < 1 { - fmt.Fprintln(os.Stderr, "usage: netcheck [--ignore-iface ] network-cidr") - os.Exit(1) - } - - cidrStr := mflag.Args()[0] - addr, ipnet, err := net.ParseCIDR(cidrStr) - if err != nil { - fatal(err) - } - if ipnet.IP.Equal(addr) { - err = weavenet.CheckNetworkFree(ipnet, ignoreIfaceNames) - } else { - err = weavenet.CheckAddressOverlap(addr, ignoreIfaceNames) - } - if err != nil { - fatal(err) - } - os.Exit(0) -} diff --git a/prog/weaveexec/Dockerfile b/prog/weaveexec/Dockerfile index f700f20a..1e916e4c 100644 --- a/prog/weaveexec/Dockerfile +++ b/prog/weaveexec/Dockerfile @@ -20,7 +20,7 @@ RUN apk add --update \ && rm -rf /var/cache/apk/* ADD ./weave ./sigproxy ./weaveproxy ./symlink /home/weave/ -ADD ./netcheck ./docker_tls_args /usr/bin/ +ADD ./weaveutil /usr/bin/ ADD ./weavewait /w/w ADD ./weavewait_noop /w-noop/w ADD ./weavewait_nomcast /w-nomcast/w diff --git a/prog/weaver/main.go b/prog/weaver/main.go index a1a81a8c..a50eda64 100644 --- a/prog/weaver/main.go +++ b/prog/weaver/main.go @@ -16,7 +16,6 @@ import ( . "github.com/weaveworks/weave/common" "github.com/weaveworks/weave/common/docker" - "github.com/weaveworks/weave/common/odp" "github.com/weaveworks/weave/ipam" "github.com/weaveworks/weave/mesh" "github.com/weaveworks/weave/nameserver" @@ -37,12 +36,7 @@ func main() { runtime.GOMAXPROCS(procs) var ( - // flags that cause immediate exit - justVersion bool - createDatapath bool - deleteDatapath bool - addDatapathInterface string - + justVersion bool config mesh.Config networkConfig weave.NetworkConfig protocolMinVersion int @@ -79,10 +73,6 @@ func main() { } mflag.BoolVar(&justVersion, []string{"#version", "-version"}, false, "print version and exit") - mflag.BoolVar(&createDatapath, []string{"-create-datapath"}, false, "create ODP datapath and exit") - mflag.BoolVar(&deleteDatapath, []string{"-delete-datapath"}, false, "delete ODP datapath and exit") - mflag.StringVar(&addDatapathInterface, []string{"-add-datapath-iface"}, "", "add a network interface to the ODP datapath and exit") - mflag.IntVar(&config.Port, []string{"#port", "-port"}, mesh.Port, "router port") mflag.IntVar(&protocolMinVersion, []string{"-min-protocol-version"}, mesh.ProtocolMinVersion, "minimum weave protocol version") mflag.StringVar(&ifaceName, []string{"#iface", "-iface"}, "", "name of interface to capture/inject from (disabled if blank)") @@ -124,34 +114,9 @@ func main() { SetLogLevel(logLevel) - switch { - case justVersion: + if justVersion { fmt.Printf("weave router %s\n", version) os.Exit(0) - - case createDatapath: - odpSupported, err := odp.CreateDatapath(datapathName) - if !odpSupported { - if err != nil { - Log.Error(err) - } - - // When the kernel lacks ODP support, exit - // with a special status to distinguish it for - // the weave script. - os.Exit(17) - } - - checkFatal(err) - os.Exit(0) - - case deleteDatapath: - checkFatal(odp.DeleteDatapath(datapathName)) - os.Exit(0) - - case addDatapathInterface != "": - checkFatal(odp.AddDatapathInterface(datapathName, addDatapathInterface)) - os.Exit(0) } Log.Println("Command line options:", options()) diff --git a/prog/weaveutil/datapath.go b/prog/weaveutil/datapath.go new file mode 100644 index 00000000..f4494967 --- /dev/null +++ b/prog/weaveutil/datapath.go @@ -0,0 +1,39 @@ +// various fastdp operations +package main + +import ( + "fmt" + "os" + + "github.com/weaveworks/weave/common/odp" +) + +func createDatapath(args []string) error { + if len(args) != 1 { + cmdUsage("create-datapath", "") + } + odpSupported, err := odp.CreateDatapath(args[0]) + if !odpSupported { + if err != nil { + fmt.Fprintln(os.Stderr, err) + } + // When the kernel lacks ODP support, exit with a special + // status to distinguish it for the weave script. + os.Exit(17) + } + return err +} + +func deleteDatapath(args []string) error { + if len(args) != 1 { + cmdUsage("delete-datapath", "") + } + return odp.DeleteDatapath(args[0]) +} + +func addDatapathInterface(args []string) error { + if len(args) != 2 { + cmdUsage("add-datapath-interface", " ") + } + return odp.AddDatapathInterface(args[0], args[1]) +} diff --git a/prog/docker_tls_args/main.go b/prog/weaveutil/docker_tls_args.go similarity index 88% rename from prog/docker_tls_args/main.go rename to prog/weaveutil/docker_tls_args.go index 37c747a5..a61ab8ce 100644 --- a/prog/docker_tls_args/main.go +++ b/prog/weaveutil/docker_tls_args.go @@ -13,14 +13,18 @@ import ( "strings" ) -func main() { +func dockerTLSArgs(args []string) error { + if len(args) > 0 { + cmdUsage("docker-tls-args", "") + } procRoot := os.Getenv("PROCFS") if procRoot == "" { procRoot = "/proc" } - dirEntries, err := ioutil.ReadDir(procRoot) - checkErr(err) + if err != nil { + return err + } for _, dirEntry := range dirEntries { dirName := dirEntry.Name() @@ -63,15 +67,8 @@ func main() { } fmt.Println(strings.Join(tlsArgs, " ")) - os.Exit(0) + return nil } - os.Exit(1) -} - -func checkErr(err error) { - if err != nil { - fmt.Fprintln(os.Stderr, err) - os.Exit(1) - } + return fmt.Errorf("cannot locate running docker daemon") } diff --git a/prog/weaveutil/main.go b/prog/weaveutil/main.go new file mode 100644 index 00000000..539e5c89 --- /dev/null +++ b/prog/weaveutil/main.go @@ -0,0 +1,59 @@ +/* weaveutil: collection of operations required by weave script */ +package main + +import ( + "fmt" + "os" +) + +var commands map[string]func([]string) error + +func init() { + commands = map[string]func([]string) error{ + "help": help, + "netcheck": netcheck, + "docker-tls-args": dockerTLSArgs, + "create-datapath": createDatapath, + "delete-datapath": deleteDatapath, + "add-datapath-interface": addDatapathInterface, + } +} + +func main() { + if len(os.Args) < 2 { + usage() + os.Exit(1) + } + cmd, found := commands[os.Args[1]] + if !found { + usage() + os.Exit(1) + } + if err := cmd(os.Args[2:]); err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } +} + +func help(args []string) error { + if len(args) > 0 { + cmdUsage("help", "") + } + usage() + return nil +} + +func usage() { + fmt.Fprintln(os.Stderr, "usage: weaveutil ...") + fmt.Fprintln(os.Stderr) + fmt.Fprintln(os.Stderr, "where is one of:") + fmt.Fprintln(os.Stderr) + for cmd := range commands { + fmt.Fprintln(os.Stderr, cmd) + } +} + +func cmdUsage(cmd string, usage string) { + fmt.Fprintf(os.Stderr, "usage: weaveutil %s %s\n", cmd, usage) + os.Exit(1) +} diff --git a/prog/weaveutil/netcheck.go b/prog/weaveutil/netcheck.go new file mode 100644 index 00000000..843fab22 --- /dev/null +++ b/prog/weaveutil/netcheck.go @@ -0,0 +1,28 @@ +/* netcheck: check whether a given network or address overlaps with any existing routes */ +package main + +import ( + "net" + + weavenet "github.com/weaveworks/weave/net" +) + +func netcheck(args []string) error { + if len(args) < 1 { + cmdUsage("netcheck", " [ ...]") + } + addr, ipnet, err := net.ParseCIDR(args[0]) + if err != nil { + return err + } + ignoreIfaceNames := make(map[string]struct{}) + for _, ifName := range args[1:] { + ignoreIfaceNames[ifName] = struct{}{} + } + if ipnet.IP.Equal(addr) { + err = weavenet.CheckNetworkFree(ipnet, ignoreIfaceNames) + } else { + err = weavenet.CheckAddressOverlap(addr, ignoreIfaceNames) + } + return err +} diff --git a/weave b/weave index d35b8626..3f5f3d87 100755 --- a/weave +++ b/weave @@ -443,8 +443,13 @@ random_mac() { # weave and docker specific helpers ###################################################################### -fastdp_op() { - docker run --rm --privileged --net=host $IMAGE $COVERAGE_ARGS --$1 --datapath=$2 +util_op() { + if command_exists weaveutil ; then + weaveutil "$@" + else + docker run --rm --privileged --net=host -v /proc:/hostproc -e PROCFS=/hostproc \ + --entrypoint=/usr/bin/weaveutil $EXEC_IMAGE "$@" + fi } # Detect the current bridge/datapath state. When invoked, the values of @@ -488,7 +493,7 @@ create_bridge() { # The datapath is the bridge when there is no intermediary DATAPATH="$BRIDGE" fi - if fastdp_op create-datapath $DATAPATH ; then + if util_op create-datapath $DATAPATH ; then : # ODP datapath created successfully elif [ $? = 17 ] ; then # Exit status of 17 means the kernel doesn't have ODP @@ -614,7 +619,7 @@ init_bridged_fastdp() { ip link del $BRIDGE >/dev/null 2>&1 || true ip link del $DATAPATH_IFNAME >/dev/null 2>&1 || true ip link del $BRIDGE_IFNAME >/dev/null 2>&1 || true - fastdp_op delete-datapath $DATAPATH >/dev/null 2>&1 || true + util_op delete-datapath $DATAPATH >/dev/null 2>&1 || true return 1 fi @@ -644,7 +649,7 @@ destroy_bridge() { if [ -d /sys/class/net/$NETDEV/bridge ] ; then ip link del $NETDEV else - fastdp_op delete-datapath $NETDEV + util_op delete-datapath $NETDEV fi fi done @@ -763,7 +768,7 @@ connect_container_to_bridge() { } add_iface_fastdp() { - fastdp_op add-datapath-iface=$1 $DATAPATH + util_op add-datapath-interface $DATAPATH $1 } add_iface_bridge() { @@ -1250,7 +1255,7 @@ collect_dns_add_remove_args() { ###################################################################### check_overlap() { - ! command_exists netcheck || netcheck --ignore-iface=$BRIDGE $1 + util_op netcheck $1 $BRIDGE } # Claim addresses for a container in IPAM. Expects to be called from @@ -1433,8 +1438,8 @@ proxy_args() { PROXY_HOST="" proxy_parse_args "$@" - if [ -z "$PROXY_TLS_ENABLED" -a -z "$PROXY_TLS_DETECTION_DISABLED" ] && command_exists docker_tls_args ; then - if ! DOCKER_TLS_ARGS=$(docker_tls_args) ; then + if [ -z "$PROXY_TLS_ENABLED" -a -z "$PROXY_TLS_DETECTION_DISABLED" ] ; then + if ! DOCKER_TLS_ARGS=$(util_op docker-tls-args) ; then echo "Unable to auto-detect proxy TLS configuration; you must launch the proxy with" >&2 echo "'weave launch-proxy' and supply '--no-detect-tls' or TLS options." >&2 exit 1