浏览代码

Network UX and integration tests

* Exiting experimental network UX
* removed experimental service UX
* integrated with the new network remote API

Signed-off-by: Madhu Venugopal <madhu@docker.com>
Madhu Venugopal 9 年之前
父节点
当前提交
22a9ba090e

+ 200 - 7
api/client/network.go

@@ -1,14 +1,207 @@
-// +build experimental
-
 package client
 package client
 
 
 import (
 import (
-	nwclient "github.com/docker/libnetwork/client"
+	"bytes"
+	"encoding/json"
+	"fmt"
+	"io"
+	"text/tabwriter"
+
+	"github.com/docker/docker/api/types"
+	Cli "github.com/docker/docker/cli"
+	flag "github.com/docker/docker/pkg/mflag"
+	"github.com/docker/docker/pkg/stringid"
 )
 )
 
 
-// CmdNetwork is used to create, display and configure network endpoints.
+// CmdNetwork is the parent subcommand for all network commands
+//
+// Usage: docker network <COMMAND> [OPTIONS]
 func (cli *DockerCli) CmdNetwork(args ...string) error {
 func (cli *DockerCli) CmdNetwork(args ...string) error {
-	nCli := nwclient.NewNetworkCli(cli.out, cli.err, nwclient.CallFunc(cli.callWrapper))
-	args = append([]string{"network"}, args...)
-	return nCli.Cmd("docker", args...)
+	cmd := Cli.Subcmd("network", []string{"COMMAND [OPTIONS]"}, networkUsage(), false)
+	cmd.Require(flag.Min, 1)
+	err := cmd.ParseFlags(args, true)
+	cmd.Usage()
+	return err
+}
+
+// CmdNetworkCreate creates a new network with a given name
+//
+// Usage: docker network create [OPTIONS] <NETWORK-NAME>
+func (cli *DockerCli) CmdNetworkCreate(args ...string) error {
+	cmd := Cli.Subcmd("network create", []string{"NETWORK-NAME"}, "Creates a new network with a name specified by the user", false)
+	flDriver := cmd.String([]string{"d", "-driver"}, "", "Driver to manage the Network")
+	cmd.Require(flag.Exact, 1)
+	err := cmd.ParseFlags(args, true)
+	if err != nil {
+		return err
+	}
+
+	// Construct network create request body
+	nc := types.NetworkCreate{Name: cmd.Arg(0), Driver: *flDriver, CheckDuplicate: true}
+	obj, _, err := readBody(cli.call("POST", "/networks/create", nc, nil))
+	if err != nil {
+		return err
+	}
+	var resp types.NetworkCreateResponse
+	err = json.Unmarshal(obj, &resp)
+	if err != nil {
+		return err
+	}
+	fmt.Fprintf(cli.out, "%s\n", resp.ID)
+	return nil
+}
+
+// CmdNetworkRm deletes a network
+//
+// Usage: docker network rm <NETWORK-NAME | NETWORK-ID>
+func (cli *DockerCli) CmdNetworkRm(args ...string) error {
+	cmd := Cli.Subcmd("network rm", []string{"NETWORK"}, "Deletes a network", false)
+	cmd.Require(flag.Exact, 1)
+	err := cmd.ParseFlags(args, true)
+	if err != nil {
+		return err
+	}
+	_, _, err = readBody(cli.call("DELETE", "/networks/"+cmd.Arg(0), nil, nil))
+	if err != nil {
+		return err
+	}
+	return nil
+}
+
+// CmdNetworkConnect connects a container to a network
+//
+// Usage: docker network connect <NETWORK> <CONTAINER>
+func (cli *DockerCli) CmdNetworkConnect(args ...string) error {
+	cmd := Cli.Subcmd("network connect", []string{"NETWORK CONTAINER"}, "Connects a container to a network", false)
+	cmd.Require(flag.Exact, 2)
+	err := cmd.ParseFlags(args, true)
+	if err != nil {
+		return err
+	}
+
+	nc := types.NetworkConnect{Container: cmd.Arg(1)}
+	_, _, err = readBody(cli.call("POST", "/networks/"+cmd.Arg(0)+"/connect", nc, nil))
+	return err
+}
+
+// CmdNetworkDisconnect disconnects a container from a network
+//
+// Usage: docker network disconnect <NETWORK> <CONTAINER>
+func (cli *DockerCli) CmdNetworkDisconnect(args ...string) error {
+	cmd := Cli.Subcmd("network disconnect", []string{"NETWORK CONTAINER"}, "Disconnects container from a network", false)
+	cmd.Require(flag.Exact, 2)
+	err := cmd.ParseFlags(args, true)
+	if err != nil {
+		return err
+	}
+
+	nc := types.NetworkConnect{Container: cmd.Arg(1)}
+	_, _, err = readBody(cli.call("POST", "/networks/"+cmd.Arg(0)+"/disconnect", nc, nil))
+	return err
+}
+
+// CmdNetworkLs lists all the netorks managed by docker daemon
+//
+// Usage: docker network ls [OPTIONS]
+func (cli *DockerCli) CmdNetworkLs(args ...string) error {
+	cmd := Cli.Subcmd("network ls", []string{""}, "Lists all the networks created by the user", false)
+	quiet := cmd.Bool([]string{"q", "-quiet"}, false, "Only display numeric IDs")
+	noTrunc := cmd.Bool([]string{"", "-no-trunc"}, false, "Do not truncate the output")
+	nLatest := cmd.Bool([]string{"l", "-latest"}, false, "Show the latest network created")
+	last := cmd.Int([]string{"n"}, -1, "Show n last created networks")
+	err := cmd.ParseFlags(args, true)
+	if err != nil {
+		return err
+	}
+	obj, _, err := readBody(cli.call("GET", "/networks", nil, nil))
+	if err != nil {
+		return err
+	}
+	if *last == -1 && *nLatest {
+		*last = 1
+	}
+
+	var networkResources []types.NetworkResource
+	err = json.Unmarshal(obj, &networkResources)
+	if err != nil {
+		return err
+	}
+
+	wr := tabwriter.NewWriter(cli.out, 20, 1, 3, ' ', 0)
+
+	// unless quiet (-q) is specified, print field titles
+	if !*quiet {
+		fmt.Fprintln(wr, "NETWORK ID\tNAME\tDRIVER")
+	}
+
+	for _, networkResource := range networkResources {
+		ID := networkResource.ID
+		netName := networkResource.Name
+		if !*noTrunc {
+			ID = stringid.TruncateID(ID)
+		}
+		if *quiet {
+			fmt.Fprintln(wr, ID)
+			continue
+		}
+		driver := networkResource.Driver
+		fmt.Fprintf(wr, "%s\t%s\t%s\t",
+			ID,
+			netName,
+			driver)
+		fmt.Fprint(wr, "\n")
+	}
+	wr.Flush()
+	return nil
+}
+
+// CmdNetworkInspect inspects the network object for more details
+//
+// Usage: docker network inspect <NETWORK>
+// CmdNetworkInspect handles Network inspect UI
+func (cli *DockerCli) CmdNetworkInspect(args ...string) error {
+	cmd := Cli.Subcmd("network inspect", []string{"NETWORK"}, "Displays detailed information on a network", false)
+	cmd.Require(flag.Exact, 1)
+	err := cmd.ParseFlags(args, true)
+	if err != nil {
+		return err
+	}
+
+	obj, _, err := readBody(cli.call("GET", "/networks/"+cmd.Arg(0), nil, nil))
+	if err != nil {
+		return err
+	}
+	networkResource := &types.NetworkResource{}
+	if err := json.NewDecoder(bytes.NewReader(obj)).Decode(networkResource); err != nil {
+		return err
+	}
+
+	indented := new(bytes.Buffer)
+	if err := json.Indent(indented, obj, "", "    "); err != nil {
+		return err
+	}
+	if _, err := io.Copy(cli.out, indented); err != nil {
+		return err
+	}
+	return nil
+}
+
+func networkUsage() string {
+	networkCommands := map[string]string{
+		"create":     "Create a network",
+		"connect":    "Connect container to a network",
+		"disconnect": "Disconnect container from a network",
+		"inspect":    "Display detailed network information",
+		"ls":         "List all networks",
+		"rm":         "Remove a network",
+	}
+
+	help := "Commands:\n"
+
+	for cmd, description := range networkCommands {
+		help += fmt.Sprintf("  %-25.25s%s\n", cmd, description)
+	}
+
+	help += fmt.Sprintf("\nRun 'docker network COMMAND --help' for more information on a command.")
+	return help
 }
 }

+ 0 - 17
api/client/service.go

@@ -1,17 +0,0 @@
-// +build experimental
-
-package client
-
-import (
-	"os"
-
-	nwclient "github.com/docker/libnetwork/client"
-)
-
-// CmdService is used to manage network services.
-// service command is user to publish, attach and list a service from a container.
-func (cli *DockerCli) CmdService(args ...string) error {
-	nCli := nwclient.NewNetworkCli(cli.out, cli.err, nwclient.CallFunc(cli.callWrapper))
-	args = append([]string{"service"}, args...)
-	return nCli.Cmd(os.Args[0], args...)
-}

+ 0 - 113
integration-cli/docker_api_service_test.go

@@ -1,113 +0,0 @@
-// +build experimental
-
-package main
-
-import (
-	"encoding/json"
-	"fmt"
-	"net/http"
-
-	"github.com/go-check/check"
-)
-
-func isServiceAvailable(c *check.C, name string, network string) bool {
-	status, body, err := sockRequest("GET", "/services", nil)
-	c.Assert(status, check.Equals, http.StatusOK)
-	c.Assert(err, check.IsNil)
-
-	var inspectJSON []struct {
-		Name    string
-		ID      string
-		Network string
-	}
-	if err = json.Unmarshal(body, &inspectJSON); err != nil {
-		c.Fatalf("unable to unmarshal response body: %v", err)
-	}
-	for _, s := range inspectJSON {
-		if s.Name == name && s.Network == network {
-			return true
-		}
-	}
-	return false
-
-}
-
-func isServiceNetworkAvailable(c *check.C, name string) bool {
-	status, body, err := sockRequest("GET", "/networks", nil)
-	c.Assert(status, check.Equals, http.StatusOK)
-	c.Assert(err, check.IsNil)
-
-	var inspectJSON []struct {
-		Name string
-		ID   string
-		Type string
-	}
-	if err = json.Unmarshal(body, &inspectJSON); err != nil {
-		c.Fatalf("unable to unmarshal response body: %v", err)
-	}
-	for _, n := range inspectJSON {
-		if n.Name == name {
-			return true
-		}
-	}
-	return false
-
-}
-
-func (s *DockerSuite) TestServiceApiCreateDelete(c *check.C) {
-	name := "testnetwork"
-	config := map[string]interface{}{
-		"name":         name,
-		"network_type": "bridge",
-	}
-
-	status, resp, err := sockRequest("POST", "/networks", config)
-	c.Assert(status, check.Equals, http.StatusCreated)
-	c.Assert(err, check.IsNil)
-
-	if !isServiceNetworkAvailable(c, name) {
-		c.Fatalf("Network %s not found", name)
-	}
-
-	var nid string
-	err = json.Unmarshal(resp, &nid)
-	if err != nil {
-		c.Fatal(err)
-	}
-
-	sname := "service1"
-	sconfig := map[string]interface{}{
-		"name":         sname,
-		"network_name": name,
-	}
-
-	status, resp, err = sockRequest("POST", "/services", sconfig)
-	c.Assert(status, check.Equals, http.StatusCreated)
-	c.Assert(err, check.IsNil)
-
-	if !isServiceAvailable(c, sname, name) {
-		c.Fatalf("Service %s.%s not found", sname, name)
-	}
-
-	var id string
-	err = json.Unmarshal(resp, &id)
-	if err != nil {
-		c.Fatal(err)
-	}
-
-	status, _, err = sockRequest("DELETE", fmt.Sprintf("/services/%s", id), nil)
-	c.Assert(status, check.Equals, http.StatusOK)
-	c.Assert(err, check.IsNil)
-
-	if isServiceAvailable(c, sname, name) {
-		c.Fatalf("Service %s.%s not deleted", sname, name)
-	}
-
-	status, _, err = sockRequest("DELETE", fmt.Sprintf("/networks/%s", nid), nil)
-	c.Assert(status, check.Equals, http.StatusOK)
-	c.Assert(err, check.IsNil)
-
-	if isNetworkAvailable(c, name) {
-		c.Fatalf("Network %s not deleted", name)
-	}
-}

+ 53 - 2
integration-cli/docker_cli_network_test.go

@@ -1,10 +1,11 @@
-// +build experimental
-
 package main
 package main
 
 
 import (
 import (
+	"encoding/json"
+	"net"
 	"strings"
 	"strings"
 
 
+	"github.com/docker/docker/api/types"
 	"github.com/go-check/check"
 	"github.com/go-check/check"
 )
 )
 
 
@@ -31,6 +32,14 @@ func isNwPresent(c *check.C, name string) bool {
 	return false
 	return false
 }
 }
 
 
+func getNwResource(c *check.C, name string) *types.NetworkResource {
+	out, _ := dockerCmd(c, "network", "inspect", name)
+	nr := types.NetworkResource{}
+	err := json.Unmarshal([]byte(out), &nr)
+	c.Assert(err, check.IsNil)
+	return &nr
+}
+
 func (s *DockerSuite) TestDockerNetworkLsDefault(c *check.C) {
 func (s *DockerSuite) TestDockerNetworkLsDefault(c *check.C) {
 	defaults := []string{"bridge", "host", "none"}
 	defaults := []string{"bridge", "host", "none"}
 	for _, nn := range defaults {
 	for _, nn := range defaults {
@@ -45,3 +54,45 @@ func (s *DockerSuite) TestDockerNetworkCreateDelete(c *check.C) {
 	dockerCmd(c, "network", "rm", "test")
 	dockerCmd(c, "network", "rm", "test")
 	assertNwNotAvailable(c, "test")
 	assertNwNotAvailable(c, "test")
 }
 }
+
+func (s *DockerSuite) TestDockerNetworkConnectDisconnect(c *check.C) {
+	dockerCmd(c, "network", "create", "test")
+	assertNwIsAvailable(c, "test")
+	nr := getNwResource(c, "test")
+
+	c.Assert(nr.Name, check.Equals, "test")
+	c.Assert(len(nr.Containers), check.Equals, 0)
+
+	// run a container
+	out, _ := dockerCmd(c, "run", "-d", "--name", "test", "busybox", "top")
+	c.Assert(waitRun("test"), check.IsNil)
+	containerID := strings.TrimSpace(out)
+
+	// connect the container to the test network
+	dockerCmd(c, "network", "connect", "test", containerID)
+
+	// inspect the network to make sure container is connected
+	nr = getNetworkResource(c, nr.ID)
+	c.Assert(len(nr.Containers), check.Equals, 1)
+	c.Assert(nr.Containers[containerID], check.NotNil)
+
+	// check if container IP matches network inspect
+	ip, _, err := net.ParseCIDR(nr.Containers[containerID].IPv4Address)
+	c.Assert(err, check.IsNil)
+	containerIP := findContainerIP(c, "test")
+	c.Assert(ip.String(), check.Equals, containerIP)
+
+	// disconnect container from the network
+	dockerCmd(c, "network", "disconnect", "test", containerID)
+	nr = getNwResource(c, "test")
+	c.Assert(nr.Name, check.Equals, "test")
+	c.Assert(len(nr.Containers), check.Equals, 0)
+
+	// check if network connect fails for inactive containers
+	dockerCmd(c, "stop", containerID)
+	_, _, err = dockerCmdWithError("network", "connect", "test", containerID)
+	c.Assert(err, check.NotNil)
+
+	dockerCmd(c, "network", "rm", "test")
+	assertNwNotAvailable(c, "test")
+}

+ 43 - 2
integration-cli/docker_cli_run_test.go

@@ -18,7 +18,9 @@ import (
 	"sync"
 	"sync"
 	"time"
 	"time"
 
 
+	"github.com/docker/docker/pkg/integration/checker"
 	"github.com/docker/docker/pkg/nat"
 	"github.com/docker/docker/pkg/nat"
+	"github.com/docker/docker/runconfig"
 	"github.com/docker/libnetwork/resolvconf"
 	"github.com/docker/libnetwork/resolvconf"
 	"github.com/go-check/check"
 	"github.com/go-check/check"
 )
 )
@@ -3408,6 +3410,7 @@ func (s *DockerSuite) TestContainersInUserDefinedNetwork(c *check.C) {
 	testRequires(c, DaemonIsLinux)
 	testRequires(c, DaemonIsLinux)
 	dockerCmd(c, "network", "create", "-d", "bridge", "testnetwork")
 	dockerCmd(c, "network", "create", "-d", "bridge", "testnetwork")
 	dockerCmd(c, "run", "-d", "--net=testnetwork", "--name=first", "busybox", "top")
 	dockerCmd(c, "run", "-d", "--net=testnetwork", "--name=first", "busybox", "top")
+	c.Assert(waitRun("first"), check.IsNil)
 	dockerCmd(c, "run", "-t", "--net=testnetwork", "--name=second", "busybox", "ping", "-c", "1", "first")
 	dockerCmd(c, "run", "-t", "--net=testnetwork", "--name=second", "busybox", "ping", "-c", "1", "first")
 	dockerCmd(c, "stop", "first")
 	dockerCmd(c, "stop", "first")
 	dockerCmd(c, "stop", "second")
 	dockerCmd(c, "stop", "second")
@@ -3421,7 +3424,9 @@ func (s *DockerSuite) TestContainersInMultipleNetworks(c *check.C) {
 	dockerCmd(c, "network", "create", "-d", "bridge", "testnetwork2")
 	dockerCmd(c, "network", "create", "-d", "bridge", "testnetwork2")
 	// Run and connect containers to testnetwork1
 	// Run and connect containers to testnetwork1
 	dockerCmd(c, "run", "-d", "--net=testnetwork1", "--name=first", "busybox", "top")
 	dockerCmd(c, "run", "-d", "--net=testnetwork1", "--name=first", "busybox", "top")
+	c.Assert(waitRun("first"), check.IsNil)
 	dockerCmd(c, "run", "-d", "--net=testnetwork1", "--name=second", "busybox", "top")
 	dockerCmd(c, "run", "-d", "--net=testnetwork1", "--name=second", "busybox", "top")
+	c.Assert(waitRun("second"), check.IsNil)
 	// Check connectivity between containers in testnetwork2
 	// Check connectivity between containers in testnetwork2
 	dockerCmd(c, "exec", "first", "ping", "-c", "1", "second.testnetwork1")
 	dockerCmd(c, "exec", "first", "ping", "-c", "1", "second.testnetwork1")
 	// Connect containers to testnetwork2
 	// Connect containers to testnetwork2
@@ -3440,9 +3445,11 @@ func (s *DockerSuite) TestContainersNetworkIsolation(c *check.C) {
 	// Create 2 networks using bridge driver
 	// Create 2 networks using bridge driver
 	dockerCmd(c, "network", "create", "-d", "bridge", "testnetwork1")
 	dockerCmd(c, "network", "create", "-d", "bridge", "testnetwork1")
 	dockerCmd(c, "network", "create", "-d", "bridge", "testnetwork2")
 	dockerCmd(c, "network", "create", "-d", "bridge", "testnetwork2")
-	// Run 1 containers in testnetwork1 and another in testnetwork2
+	// Run 1 container in testnetwork1 and another in testnetwork2
 	dockerCmd(c, "run", "-d", "--net=testnetwork1", "--name=first", "busybox", "top")
 	dockerCmd(c, "run", "-d", "--net=testnetwork1", "--name=first", "busybox", "top")
+	c.Assert(waitRun("first"), check.IsNil)
 	dockerCmd(c, "run", "-d", "--net=testnetwork2", "--name=second", "busybox", "top")
 	dockerCmd(c, "run", "-d", "--net=testnetwork2", "--name=second", "busybox", "top")
+	c.Assert(waitRun("second"), check.IsNil)
 
 
 	// Check Isolation between containers : ping must fail
 	// Check Isolation between containers : ping must fail
 	_, _, err := dockerCmdWithError("exec", "first", "ping", "-c", "1", "second")
 	_, _, err := dockerCmdWithError("exec", "first", "ping", "-c", "1", "second")
@@ -3471,7 +3478,9 @@ func (s *DockerSuite) TestNetworkRmWithActiveContainers(c *check.C) {
 	dockerCmd(c, "network", "create", "-d", "bridge", "testnetwork1")
 	dockerCmd(c, "network", "create", "-d", "bridge", "testnetwork1")
 	// Run and connect containers to testnetwork1
 	// Run and connect containers to testnetwork1
 	dockerCmd(c, "run", "-d", "--net=testnetwork1", "--name=first", "busybox", "top")
 	dockerCmd(c, "run", "-d", "--net=testnetwork1", "--name=first", "busybox", "top")
+	c.Assert(waitRun("first"), check.IsNil)
 	dockerCmd(c, "run", "-d", "--net=testnetwork1", "--name=second", "busybox", "top")
 	dockerCmd(c, "run", "-d", "--net=testnetwork1", "--name=second", "busybox", "top")
+	c.Assert(waitRun("second"), check.IsNil)
 	// Network delete with active containers must fail
 	// Network delete with active containers must fail
 	_, _, err := dockerCmdWithError("network", "rm", "testnetwork1")
 	_, _, err := dockerCmdWithError("network", "rm", "testnetwork1")
 	c.Assert(err, check.NotNil)
 	c.Assert(err, check.NotNil)
@@ -3492,7 +3501,9 @@ func (s *DockerSuite) TestContainerRestartInMultipleNetworks(c *check.C) {
 	dockerCmd(c, "network", "create", "-d", "bridge", "testnetwork2")
 	dockerCmd(c, "network", "create", "-d", "bridge", "testnetwork2")
 	// Run and connect containers to testnetwork1
 	// Run and connect containers to testnetwork1
 	dockerCmd(c, "run", "-d", "--net=testnetwork1", "--name=first", "busybox", "top")
 	dockerCmd(c, "run", "-d", "--net=testnetwork1", "--name=first", "busybox", "top")
+	c.Assert(waitRun("first"), check.IsNil)
 	dockerCmd(c, "run", "-d", "--net=testnetwork1", "--name=second", "busybox", "top")
 	dockerCmd(c, "run", "-d", "--net=testnetwork1", "--name=second", "busybox", "top")
+	c.Assert(waitRun("second"), check.IsNil)
 	// Check connectivity between containers in testnetwork2
 	// Check connectivity between containers in testnetwork2
 	dockerCmd(c, "exec", "first", "ping", "-c", "1", "second.testnetwork1")
 	dockerCmd(c, "exec", "first", "ping", "-c", "1", "second.testnetwork1")
 	// Connect containers to testnetwork2
 	// Connect containers to testnetwork2
@@ -3523,6 +3534,7 @@ func (s *DockerSuite) TestContainerWithConflictingHostNetworks(c *check.C) {
 	testRequires(c, DaemonIsLinux)
 	testRequires(c, DaemonIsLinux)
 	// Run a container with --net=host
 	// Run a container with --net=host
 	dockerCmd(c, "run", "-d", "--net=host", "--name=first", "busybox", "top")
 	dockerCmd(c, "run", "-d", "--net=host", "--name=first", "busybox", "top")
+	c.Assert(waitRun("first"), check.IsNil)
 
 
 	// Create a network using bridge driver
 	// Create a network using bridge driver
 	dockerCmd(c, "network", "create", "-d", "bridge", "testnetwork1")
 	dockerCmd(c, "network", "create", "-d", "bridge", "testnetwork1")
@@ -3537,14 +3549,43 @@ func (s *DockerSuite) TestContainerWithConflictingHostNetworks(c *check.C) {
 func (s *DockerSuite) TestContainerWithConflictingSharedNetwork(c *check.C) {
 func (s *DockerSuite) TestContainerWithConflictingSharedNetwork(c *check.C) {
 	testRequires(c, DaemonIsLinux)
 	testRequires(c, DaemonIsLinux)
 	dockerCmd(c, "run", "-d", "--name=first", "busybox", "top")
 	dockerCmd(c, "run", "-d", "--name=first", "busybox", "top")
+	c.Assert(waitRun("first"), check.IsNil)
 	// Run second container in first container's network namespace
 	// Run second container in first container's network namespace
 	dockerCmd(c, "run", "-d", "--net=container:first", "--name=second", "busybox", "top")
 	dockerCmd(c, "run", "-d", "--net=container:first", "--name=second", "busybox", "top")
+	c.Assert(waitRun("second"), check.IsNil)
 
 
 	// Create a network using bridge driver
 	// Create a network using bridge driver
 	dockerCmd(c, "network", "create", "-d", "bridge", "testnetwork1")
 	dockerCmd(c, "network", "create", "-d", "bridge", "testnetwork1")
 
 
 	// Connecting to the user defined network must fail
 	// Connecting to the user defined network must fail
-	_, _, err := dockerCmdWithError("network", "connect", "testnetwork1", "second")
+	out, _, err := dockerCmdWithError("network", "connect", "testnetwork1", "second")
+	c.Assert(err, check.NotNil)
+	c.Assert(out, checker.Contains, runconfig.ErrConflictSharedNetwork.Error())
+
+	dockerCmd(c, "stop", "first")
+	dockerCmd(c, "stop", "second")
+	dockerCmd(c, "network", "rm", "testnetwork1")
+}
+
+func (s *DockerSuite) TestContainerWithConflictingNoneNetwork(c *check.C) {
+	testRequires(c, DaemonIsLinux)
+	dockerCmd(c, "run", "-d", "--net=none", "--name=first", "busybox", "top")
+	c.Assert(waitRun("first"), check.IsNil)
+
+	// Create a network using bridge driver
+	dockerCmd(c, "network", "create", "-d", "bridge", "testnetwork1")
+
+	// Connecting to the user defined network must fail
+	out, _, err := dockerCmdWithError("network", "connect", "testnetwork1", "first")
+	c.Assert(err, check.NotNil)
+	c.Assert(out, checker.Contains, runconfig.ErrConflictNoNetwork.Error())
+
+	// create a container connected to testnetwork1
+	dockerCmd(c, "run", "-d", "--net=testnetwork1", "--name=second", "busybox", "top")
+	c.Assert(waitRun("second"), check.IsNil)
+
+	// Connect second container to none network. it must fail as well
+	_, _, err = dockerCmdWithError("network", "connect", "none", "second")
 	c.Assert(err, check.NotNil)
 	c.Assert(err, check.NotNil)
 
 
 	dockerCmd(c, "stop", "first")
 	dockerCmd(c, "stop", "first")

+ 0 - 69
integration-cli/docker_cli_service_test.go

@@ -1,69 +0,0 @@
-// +build experimental
-
-package main
-
-import (
-	"fmt"
-	"strings"
-
-	"github.com/go-check/check"
-)
-
-func assertSrvIsAvailable(c *check.C, sname, name string) {
-	if !isSrvPresent(c, sname, name) {
-		c.Fatalf("Service %s on network %s not found in service ls o/p", sname, name)
-	}
-}
-
-func assertSrvNotAvailable(c *check.C, sname, name string) {
-	if isSrvPresent(c, sname, name) {
-		c.Fatalf("Found service %s on network %s in service ls o/p", sname, name)
-	}
-}
-
-func isSrvPresent(c *check.C, sname, name string) bool {
-	out, _, _ := dockerCmdWithStdoutStderr(c, "service", "ls")
-	lines := strings.Split(out, "\n")
-	for i := 1; i < len(lines)-1; i++ {
-		if strings.Contains(lines[i], sname) && strings.Contains(lines[i], name) {
-			return true
-		}
-	}
-	return false
-}
-
-func isCntPresent(c *check.C, cname, sname, name string) bool {
-	out, _, _ := dockerCmdWithStdoutStderr(c, "service", "ls", "--no-trunc")
-	lines := strings.Split(out, "\n")
-	for i := 1; i < len(lines)-1; i++ {
-		fmt.Println(lines)
-		if strings.Contains(lines[i], name) && strings.Contains(lines[i], sname) && strings.Contains(lines[i], cname) {
-			return true
-		}
-	}
-	return false
-}
-
-func (s *DockerSuite) TestDockerServiceCreateDelete(c *check.C) {
-	dockerCmdWithStdoutStderr(c, "network", "create", "test")
-	assertNwIsAvailable(c, "test")
-
-	dockerCmdWithStdoutStderr(c, "service", "publish", "s1.test")
-	assertSrvIsAvailable(c, "s1", "test")
-
-	dockerCmdWithStdoutStderr(c, "service", "unpublish", "s1.test")
-	assertSrvNotAvailable(c, "s1", "test")
-
-	dockerCmdWithStdoutStderr(c, "network", "rm", "test")
-	assertNwNotAvailable(c, "test")
-}
-
-func (s *DockerSuite) TestDockerPublishServiceFlag(c *check.C) {
-	// Run saying the container is the backend for the specified service on the specified network
-	out, _ := dockerCmd(c, "run", "-d", "--expose=23", "--publish-service", "telnet.production", "busybox", "top")
-	cid := strings.TrimSpace(out)
-
-	// Verify container is attached in service ps o/p
-	assertSrvIsAvailable(c, "telnet", "production")
-	dockerCmd(c, "rm", "-f", cid)
-}

+ 0 - 115
vendor/src/github.com/docker/libnetwork/client/client.go

@@ -1,115 +0,0 @@
-package client
-
-import (
-	"fmt"
-	"io"
-	"io/ioutil"
-	"net/http"
-	"reflect"
-	"strings"
-
-	flag "github.com/docker/docker/pkg/mflag"
-)
-
-// CallFunc provides environment specific call utility to invoke backend functions from UI
-type CallFunc func(string, string, interface{}, map[string][]string) (io.ReadCloser, http.Header, int, error)
-
-// NetworkCli is the UI object for network subcmds
-type NetworkCli struct {
-	out  io.Writer
-	err  io.Writer
-	call CallFunc
-}
-
-// NewNetworkCli is a convenient function to create a NetworkCli object
-func NewNetworkCli(out, err io.Writer, call CallFunc) *NetworkCli {
-	return &NetworkCli{
-		out:  out,
-		err:  err,
-		call: call,
-	}
-}
-
-// getMethod is Borrowed from Docker UI which uses reflection to identify the UI Handler
-func (cli *NetworkCli) getMethod(args ...string) (func(string, ...string) error, bool) {
-	camelArgs := make([]string, len(args))
-	for i, s := range args {
-		if len(s) == 0 {
-			return nil, false
-		}
-		camelArgs[i] = strings.ToUpper(s[:1]) + strings.ToLower(s[1:])
-	}
-	methodName := "Cmd" + strings.Join(camelArgs, "")
-	method := reflect.ValueOf(cli).MethodByName(methodName)
-	if !method.IsValid() {
-		return nil, false
-	}
-	return method.Interface().(func(string, ...string) error), true
-}
-
-// Cmd is borrowed from Docker UI and acts as the entry point for network UI commands.
-// network UI commands are designed to be invoked from multiple parent chains
-func (cli *NetworkCli) Cmd(chain string, args ...string) error {
-	if len(args) > 2 {
-		method, exists := cli.getMethod(args[:3]...)
-		if exists {
-			return method(chain+" "+args[0]+" "+args[1], args[3:]...)
-		}
-	}
-	if len(args) > 1 {
-		method, exists := cli.getMethod(args[:2]...)
-		if exists {
-			return method(chain+" "+args[0], args[2:]...)
-		}
-	}
-	if len(args) > 0 {
-		method, exists := cli.getMethod(args[0])
-		if !exists {
-			return fmt.Errorf("%s: '%s' is not a %s command. See '%s --help'.\n", chain, args[0], chain, chain)
-		}
-		return method(chain, args[1:]...)
-	}
-	flag.Usage()
-	return nil
-}
-
-// Subcmd is borrowed from Docker UI and performs the same function of configuring the subCmds
-func (cli *NetworkCli) Subcmd(chain, name, signature, description string, exitOnError bool) *flag.FlagSet {
-	var errorHandling flag.ErrorHandling
-	if exitOnError {
-		errorHandling = flag.ExitOnError
-	} else {
-		errorHandling = flag.ContinueOnError
-	}
-	flags := flag.NewFlagSet(name, errorHandling)
-	flags.Usage = func() {
-		flags.ShortUsage()
-		flags.PrintDefaults()
-	}
-	flags.ShortUsage = func() {
-		options := ""
-		if signature != "" {
-			signature = " " + signature
-		}
-		if flags.FlagCountUndeprecated() > 0 {
-			options = " [OPTIONS]"
-		}
-		fmt.Fprintf(cli.out, "\nUsage: %s %s%s%s\n\n%s\n\n", chain, name, options, signature, description)
-		flags.SetOutput(cli.out)
-	}
-	return flags
-}
-
-func readBody(stream io.ReadCloser, hdr http.Header, statusCode int, err error) ([]byte, int, error) {
-	if stream != nil {
-		defer stream.Close()
-	}
-	if err != nil {
-		return nil, statusCode, err
-	}
-	body, err := ioutil.ReadAll(stream)
-	if err != nil {
-		return nil, -1, err
-	}
-	return body, statusCode, nil
-}

+ 0 - 231
vendor/src/github.com/docker/libnetwork/client/network.go

@@ -1,231 +0,0 @@
-package client
-
-import (
-	"bytes"
-	"encoding/json"
-	"fmt"
-	"net/http"
-	"text/tabwriter"
-
-	flag "github.com/docker/docker/pkg/mflag"
-	"github.com/docker/docker/pkg/stringid"
-)
-
-type command struct {
-	name        string
-	description string
-}
-
-var (
-	networkCommands = []command{
-		{"create", "Create a network"},
-		{"rm", "Remove a network"},
-		{"ls", "List all networks"},
-		{"info", "Display information of a network"},
-	}
-)
-
-// CmdNetwork handles the root Network UI
-func (cli *NetworkCli) CmdNetwork(chain string, args ...string) error {
-	cmd := cli.Subcmd(chain, "network", "COMMAND [OPTIONS] [arg...]", networkUsage(chain), false)
-	cmd.Require(flag.Min, 1)
-	err := cmd.ParseFlags(args, true)
-	if err == nil {
-		cmd.Usage()
-		return fmt.Errorf("invalid command : %v", args)
-	}
-	return err
-}
-
-// CmdNetworkCreate handles Network Create UI
-func (cli *NetworkCli) CmdNetworkCreate(chain string, args ...string) error {
-	cmd := cli.Subcmd(chain, "create", "NETWORK-NAME", "Creates a new network with a name specified by the user", false)
-	flDriver := cmd.String([]string{"d", "-driver"}, "", "Driver to manage the Network")
-	cmd.Require(flag.Exact, 1)
-	err := cmd.ParseFlags(args, true)
-	if err != nil {
-		return err
-	}
-
-	// Construct network create request body
-	ops := make(map[string]interface{})
-	nc := networkCreate{Name: cmd.Arg(0), NetworkType: *flDriver, Options: ops}
-	obj, _, err := readBody(cli.call("POST", "/networks", nc, nil))
-	if err != nil {
-		return err
-	}
-	var replyID string
-	err = json.Unmarshal(obj, &replyID)
-	if err != nil {
-		return err
-	}
-	fmt.Fprintf(cli.out, "%s\n", replyID)
-	return nil
-}
-
-// CmdNetworkRm handles Network Delete UI
-func (cli *NetworkCli) CmdNetworkRm(chain string, args ...string) error {
-	cmd := cli.Subcmd(chain, "rm", "NETWORK", "Deletes a network", false)
-	cmd.Require(flag.Exact, 1)
-	err := cmd.ParseFlags(args, true)
-	if err != nil {
-		return err
-	}
-	id, err := lookupNetworkID(cli, cmd.Arg(0))
-	if err != nil {
-		return err
-	}
-	_, _, err = readBody(cli.call("DELETE", "/networks/"+id, nil, nil))
-	if err != nil {
-		return err
-	}
-	return nil
-}
-
-// CmdNetworkLs handles Network List UI
-func (cli *NetworkCli) CmdNetworkLs(chain string, args ...string) error {
-	cmd := cli.Subcmd(chain, "ls", "", "Lists all the networks created by the user", false)
-	quiet := cmd.Bool([]string{"q", "-quiet"}, false, "Only display numeric IDs")
-	noTrunc := cmd.Bool([]string{"#notrunc", "-no-trunc"}, false, "Do not truncate the output")
-	nLatest := cmd.Bool([]string{"l", "-latest"}, false, "Show the latest network created")
-	last := cmd.Int([]string{"n"}, -1, "Show n last created networks")
-	err := cmd.ParseFlags(args, true)
-	if err != nil {
-		return err
-	}
-	obj, _, err := readBody(cli.call("GET", "/networks", nil, nil))
-	if err != nil {
-		return err
-	}
-	if *last == -1 && *nLatest {
-		*last = 1
-	}
-
-	var networkResources []networkResource
-	err = json.Unmarshal(obj, &networkResources)
-	if err != nil {
-		return err
-	}
-
-	wr := tabwriter.NewWriter(cli.out, 20, 1, 3, ' ', 0)
-
-	// unless quiet (-q) is specified, print field titles
-	if !*quiet {
-		fmt.Fprintln(wr, "NETWORK ID\tNAME\tTYPE")
-	}
-
-	for _, networkResource := range networkResources {
-		ID := networkResource.ID
-		netName := networkResource.Name
-		if !*noTrunc {
-			ID = stringid.TruncateID(ID)
-		}
-		if *quiet {
-			fmt.Fprintln(wr, ID)
-			continue
-		}
-		netType := networkResource.Type
-		fmt.Fprintf(wr, "%s\t%s\t%s\t",
-			ID,
-			netName,
-			netType)
-		fmt.Fprint(wr, "\n")
-	}
-	wr.Flush()
-	return nil
-}
-
-// CmdNetworkInfo handles Network Info UI
-func (cli *NetworkCli) CmdNetworkInfo(chain string, args ...string) error {
-	cmd := cli.Subcmd(chain, "info", "NETWORK", "Displays detailed information on a network", false)
-	cmd.Require(flag.Exact, 1)
-	err := cmd.ParseFlags(args, true)
-	if err != nil {
-		return err
-	}
-
-	id, err := lookupNetworkID(cli, cmd.Arg(0))
-	if err != nil {
-		return err
-	}
-
-	obj, _, err := readBody(cli.call("GET", "/networks/"+id, nil, nil))
-	if err != nil {
-		return err
-	}
-	networkResource := &networkResource{}
-	if err := json.NewDecoder(bytes.NewReader(obj)).Decode(networkResource); err != nil {
-		return err
-	}
-	fmt.Fprintf(cli.out, "Network Id: %s\n", networkResource.ID)
-	fmt.Fprintf(cli.out, "Name: %s\n", networkResource.Name)
-	fmt.Fprintf(cli.out, "Type: %s\n", networkResource.Type)
-	if networkResource.Services != nil {
-		for _, serviceResource := range networkResource.Services {
-			fmt.Fprintf(cli.out, "  Service Id: %s\n", serviceResource.ID)
-			fmt.Fprintf(cli.out, "\tName: %s\n", serviceResource.Name)
-		}
-	}
-
-	return nil
-}
-
-// Helper function to predict if a string is a name or id or partial-id
-// This provides a best-effort mechanism to identify a id with the help of GET Filter APIs
-// Being a UI, its most likely that name will be used by the user, which is used to lookup
-// the corresponding ID. If ID is not found, this function will assume that the passed string
-// is an ID by itself.
-
-func lookupNetworkID(cli *NetworkCli, nameID string) (string, error) {
-	obj, statusCode, err := readBody(cli.call("GET", "/networks?name="+nameID, nil, nil))
-	if err != nil {
-		return "", err
-	}
-
-	if statusCode != http.StatusOK {
-		return "", fmt.Errorf("name query failed for %s due to : statuscode(%d) %v", nameID, statusCode, string(obj))
-	}
-
-	var list []*networkResource
-	err = json.Unmarshal(obj, &list)
-	if err != nil {
-		return "", err
-	}
-	if len(list) > 0 {
-		// name query filter will always return a single-element collection
-		return list[0].ID, nil
-	}
-
-	// Check for Partial-id
-	obj, statusCode, err = readBody(cli.call("GET", "/networks?partial-id="+nameID, nil, nil))
-	if err != nil {
-		return "", err
-	}
-
-	if statusCode != http.StatusOK {
-		return "", fmt.Errorf("partial-id match query failed for %s due to : statuscode(%d) %v", nameID, statusCode, string(obj))
-	}
-
-	err = json.Unmarshal(obj, &list)
-	if err != nil {
-		return "", err
-	}
-	if len(list) == 0 {
-		return "", fmt.Errorf("resource not found %s", nameID)
-	}
-	if len(list) > 1 {
-		return "", fmt.Errorf("multiple Networks matching the partial identifier (%s). Please use full identifier", nameID)
-	}
-	return list[0].ID, nil
-}
-
-func networkUsage(chain string) string {
-	help := "Commands:\n"
-
-	for _, cmd := range networkCommands {
-		help += fmt.Sprintf("  %-25.25s%s\n", cmd.name, cmd.description)
-	}
-
-	help += fmt.Sprintf("\nRun '%s network COMMAND --help' for more information on a command.", chain)
-	return help
-}

+ 0 - 392
vendor/src/github.com/docker/libnetwork/client/service.go

@@ -1,392 +0,0 @@
-package client
-
-import (
-	"bytes"
-	"encoding/json"
-	"fmt"
-	"net/http"
-	"strings"
-	"text/tabwriter"
-
-	flag "github.com/docker/docker/pkg/mflag"
-	"github.com/docker/docker/pkg/stringid"
-)
-
-var (
-	serviceCommands = []command{
-		{"publish", "Publish a service"},
-		{"unpublish", "Remove a service"},
-		{"attach", "Attach a backend (container) to the service"},
-		{"detach", "Detach the backend from the service"},
-		{"ls", "Lists all services"},
-		{"info", "Display information about a service"},
-	}
-)
-
-func lookupServiceID(cli *NetworkCli, nwName, svNameID string) (string, error) {
-	// Sanity Check
-	obj, _, err := readBody(cli.call("GET", fmt.Sprintf("/networks?name=%s", nwName), nil, nil))
-	if err != nil {
-		return "", err
-	}
-	var nwList []networkResource
-	if err = json.Unmarshal(obj, &nwList); err != nil {
-		return "", err
-	}
-	if len(nwList) == 0 {
-		return "", fmt.Errorf("Network %s does not exist", nwName)
-	}
-
-	if nwName == "" {
-		obj, _, err := readBody(cli.call("GET", "/networks/"+nwList[0].ID, nil, nil))
-		if err != nil {
-			return "", err
-		}
-		networkResource := &networkResource{}
-		if err := json.NewDecoder(bytes.NewReader(obj)).Decode(networkResource); err != nil {
-			return "", err
-		}
-		nwName = networkResource.Name
-	}
-
-	// Query service by name
-	obj, statusCode, err := readBody(cli.call("GET", fmt.Sprintf("/services?name=%s", svNameID), nil, nil))
-	if err != nil {
-		return "", err
-	}
-
-	if statusCode != http.StatusOK {
-		return "", fmt.Errorf("name query failed for %s due to: (%d) %s", svNameID, statusCode, string(obj))
-	}
-
-	var list []*serviceResource
-	if err = json.Unmarshal(obj, &list); err != nil {
-		return "", err
-	}
-	for _, sr := range list {
-		if sr.Network == nwName {
-			return sr.ID, nil
-		}
-	}
-
-	// Query service by Partial-id (this covers full id as well)
-	obj, statusCode, err = readBody(cli.call("GET", fmt.Sprintf("/services?partial-id=%s", svNameID), nil, nil))
-	if err != nil {
-		return "", err
-	}
-
-	if statusCode != http.StatusOK {
-		return "", fmt.Errorf("partial-id match query failed for %s due to: (%d) %s", svNameID, statusCode, string(obj))
-	}
-
-	if err = json.Unmarshal(obj, &list); err != nil {
-		return "", err
-	}
-	for _, sr := range list {
-		if sr.Network == nwName {
-			return sr.ID, nil
-		}
-	}
-
-	return "", fmt.Errorf("Service %s not found on network %s", svNameID, nwName)
-}
-
-func lookupContainerID(cli *NetworkCli, cnNameID string) (string, error) {
-	// Container is a Docker resource, ask docker about it.
-	// In case of connecton error, we assume we are running in dnet and return whatever was passed to us
-	obj, _, err := readBody(cli.call("GET", fmt.Sprintf("/containers/%s/json", cnNameID), nil, nil))
-	if err != nil {
-		// We are probably running outside of docker
-		return cnNameID, nil
-	}
-
-	var x map[string]interface{}
-	err = json.Unmarshal(obj, &x)
-	if err != nil {
-		return "", err
-	}
-	if iid, ok := x["Id"]; ok {
-		if id, ok := iid.(string); ok {
-			return id, nil
-		}
-		return "", fmt.Errorf("Unexpected data type for container ID in json response")
-	}
-	return "", fmt.Errorf("Cannot find container ID in json response")
-}
-
-func lookupSandboxID(cli *NetworkCli, containerID string) (string, error) {
-	obj, _, err := readBody(cli.call("GET", fmt.Sprintf("/sandboxes?partial-container-id=%s", containerID), nil, nil))
-	if err != nil {
-		return "", err
-	}
-
-	var sandboxList []SandboxResource
-	err = json.Unmarshal(obj, &sandboxList)
-	if err != nil {
-		return "", err
-	}
-
-	if len(sandboxList) == 0 {
-		return "", fmt.Errorf("cannot find sandbox for container: %s", containerID)
-	}
-
-	return sandboxList[0].ID, nil
-}
-
-// CmdService handles the service UI
-func (cli *NetworkCli) CmdService(chain string, args ...string) error {
-	cmd := cli.Subcmd(chain, "service", "COMMAND [OPTIONS] [arg...]", serviceUsage(chain), false)
-	cmd.Require(flag.Min, 1)
-	err := cmd.ParseFlags(args, true)
-	if err == nil {
-		cmd.Usage()
-		return fmt.Errorf("Invalid command : %v", args)
-	}
-	return err
-}
-
-// Parse service name for "SERVICE[.NETWORK]" format
-func parseServiceName(name string) (string, string) {
-	s := strings.Split(name, ".")
-	var sName, nName string
-	if len(s) > 1 {
-		nName = s[len(s)-1]
-		sName = strings.Join(s[:len(s)-1], ".")
-	} else {
-		sName = s[0]
-	}
-	return sName, nName
-}
-
-// CmdServicePublish handles service create UI
-func (cli *NetworkCli) CmdServicePublish(chain string, args ...string) error {
-	cmd := cli.Subcmd(chain, "publish", "SERVICE[.NETWORK]", "Publish a new service on a network", false)
-	cmd.Require(flag.Exact, 1)
-	err := cmd.ParseFlags(args, true)
-	if err != nil {
-		return err
-	}
-
-	sn, nn := parseServiceName(cmd.Arg(0))
-	sc := serviceCreate{Name: sn, Network: nn}
-	obj, _, err := readBody(cli.call("POST", "/services", sc, nil))
-	if err != nil {
-		return err
-	}
-
-	var replyID string
-	err = json.Unmarshal(obj, &replyID)
-	if err != nil {
-		return err
-	}
-
-	fmt.Fprintf(cli.out, "%s\n", replyID)
-	return nil
-}
-
-// CmdServiceUnpublish handles service delete UI
-func (cli *NetworkCli) CmdServiceUnpublish(chain string, args ...string) error {
-	cmd := cli.Subcmd(chain, "unpublish", "SERVICE[.NETWORK]", "Removes a service", false)
-	cmd.Require(flag.Exact, 1)
-	err := cmd.ParseFlags(args, true)
-	if err != nil {
-		return err
-	}
-
-	sn, nn := parseServiceName(cmd.Arg(0))
-	serviceID, err := lookupServiceID(cli, nn, sn)
-	if err != nil {
-		return err
-	}
-
-	_, _, err = readBody(cli.call("DELETE", "/services/"+serviceID, nil, nil))
-
-	return err
-}
-
-// CmdServiceLs handles service list UI
-func (cli *NetworkCli) CmdServiceLs(chain string, args ...string) error {
-	cmd := cli.Subcmd(chain, "ls", "SERVICE", "Lists all the services on a network", false)
-	flNetwork := cmd.String([]string{"net", "-network"}, "", "Only show the services that are published on the specified network")
-	quiet := cmd.Bool([]string{"q", "-quiet"}, false, "Only display numeric IDs")
-	noTrunc := cmd.Bool([]string{"#notrunc", "-no-trunc"}, false, "Do not truncate the output")
-
-	err := cmd.ParseFlags(args, true)
-	if err != nil {
-		return err
-	}
-
-	var obj []byte
-	if *flNetwork == "" {
-		obj, _, err = readBody(cli.call("GET", "/services", nil, nil))
-	} else {
-		obj, _, err = readBody(cli.call("GET", "/services?network="+*flNetwork, nil, nil))
-	}
-	if err != nil {
-		return err
-	}
-
-	var serviceResources []serviceResource
-	err = json.Unmarshal(obj, &serviceResources)
-	if err != nil {
-		fmt.Println(err)
-		return err
-	}
-
-	wr := tabwriter.NewWriter(cli.out, 20, 1, 3, ' ', 0)
-	// unless quiet (-q) is specified, print field titles
-	if !*quiet {
-		fmt.Fprintln(wr, "SERVICE ID\tNAME\tNETWORK\tCONTAINER\tSANDBOX")
-	}
-
-	for _, sr := range serviceResources {
-		ID := sr.ID
-		bkID, sbID, err := getBackendID(cli, ID)
-		if err != nil {
-			return err
-		}
-		if !*noTrunc {
-			ID = stringid.TruncateID(ID)
-			bkID = stringid.TruncateID(bkID)
-			sbID = stringid.TruncateID(sbID)
-		}
-		if !*quiet {
-			fmt.Fprintf(wr, "%s\t%s\t%s\t%s\t%s\n", ID, sr.Name, sr.Network, bkID, sbID)
-		} else {
-			fmt.Fprintln(wr, ID)
-		}
-	}
-	wr.Flush()
-
-	return nil
-}
-
-func getBackendID(cli *NetworkCli, servID string) (string, string, error) {
-	var (
-		obj []byte
-		err error
-		bk  string
-		sb  string
-	)
-
-	if obj, _, err = readBody(cli.call("GET", "/services/"+servID+"/backend", nil, nil)); err == nil {
-		var sr SandboxResource
-		if err := json.NewDecoder(bytes.NewReader(obj)).Decode(&sr); err == nil {
-			bk = sr.ContainerID
-			sb = sr.ID
-		} else {
-			// Only print a message, don't make the caller cli fail for this
-			fmt.Fprintf(cli.out, "Failed to retrieve backend list for service %s (%v)\n", servID, err)
-		}
-	}
-
-	return bk, sb, err
-}
-
-// CmdServiceInfo handles service info UI
-func (cli *NetworkCli) CmdServiceInfo(chain string, args ...string) error {
-	cmd := cli.Subcmd(chain, "info", "SERVICE[.NETWORK]", "Displays detailed information about a service", false)
-	cmd.Require(flag.Min, 1)
-
-	err := cmd.ParseFlags(args, true)
-	if err != nil {
-		return err
-	}
-
-	sn, nn := parseServiceName(cmd.Arg(0))
-	serviceID, err := lookupServiceID(cli, nn, sn)
-	if err != nil {
-		return err
-	}
-
-	obj, _, err := readBody(cli.call("GET", "/services/"+serviceID, nil, nil))
-	if err != nil {
-		return err
-	}
-
-	sr := &serviceResource{}
-	if err := json.NewDecoder(bytes.NewReader(obj)).Decode(sr); err != nil {
-		return err
-	}
-
-	fmt.Fprintf(cli.out, "Service Id: %s\n", sr.ID)
-	fmt.Fprintf(cli.out, "\tName: %s\n", sr.Name)
-	fmt.Fprintf(cli.out, "\tNetwork: %s\n", sr.Network)
-
-	return nil
-}
-
-// CmdServiceAttach handles service attach UI
-func (cli *NetworkCli) CmdServiceAttach(chain string, args ...string) error {
-	cmd := cli.Subcmd(chain, "attach", "CONTAINER SERVICE[.NETWORK]", "Sets a container as a service backend", false)
-	cmd.Require(flag.Min, 2)
-	err := cmd.ParseFlags(args, true)
-	if err != nil {
-		return err
-	}
-
-	containerID, err := lookupContainerID(cli, cmd.Arg(0))
-	if err != nil {
-		return err
-	}
-
-	sandboxID, err := lookupSandboxID(cli, containerID)
-	if err != nil {
-		return err
-	}
-
-	sn, nn := parseServiceName(cmd.Arg(1))
-	serviceID, err := lookupServiceID(cli, nn, sn)
-	if err != nil {
-		return err
-	}
-
-	nc := serviceAttach{SandboxID: sandboxID}
-
-	_, _, err = readBody(cli.call("POST", "/services/"+serviceID+"/backend", nc, nil))
-
-	return err
-}
-
-// CmdServiceDetach handles service detach UI
-func (cli *NetworkCli) CmdServiceDetach(chain string, args ...string) error {
-	cmd := cli.Subcmd(chain, "detach", "CONTAINER SERVICE", "Removes a container from service backend", false)
-	cmd.Require(flag.Min, 2)
-	err := cmd.ParseFlags(args, true)
-	if err != nil {
-		return err
-	}
-
-	sn, nn := parseServiceName(cmd.Arg(1))
-	containerID, err := lookupContainerID(cli, cmd.Arg(0))
-	if err != nil {
-		return err
-	}
-
-	sandboxID, err := lookupSandboxID(cli, containerID)
-	if err != nil {
-		return err
-	}
-
-	serviceID, err := lookupServiceID(cli, nn, sn)
-	if err != nil {
-		return err
-	}
-
-	_, _, err = readBody(cli.call("DELETE", "/services/"+serviceID+"/backend/"+sandboxID, nil, nil))
-	if err != nil {
-		return err
-	}
-	return nil
-}
-
-func serviceUsage(chain string) string {
-	help := "Commands:\n"
-
-	for _, cmd := range serviceCommands {
-		help += fmt.Sprintf("    %-10.10s%s\n", cmd.name, cmd.description)
-	}
-
-	help += fmt.Sprintf("\nRun '%s service COMMAND --help' for more information on a command.", chain)
-	return help
-}

+ 0 - 79
vendor/src/github.com/docker/libnetwork/client/types.go

@@ -1,79 +0,0 @@
-package client
-
-import "github.com/docker/libnetwork/types"
-
-/***********
- Resources
-************/
-
-// networkResource is the body of the "get network" http response message
-type networkResource struct {
-	Name     string             `json:"name"`
-	ID       string             `json:"id"`
-	Type     string             `json:"type"`
-	Services []*serviceResource `json:"services"`
-}
-
-// serviceResource is the body of the "get service" http response message
-type serviceResource struct {
-	Name    string `json:"name"`
-	ID      string `json:"id"`
-	Network string `json:"network"`
-}
-
-// SandboxResource is the body of "get service backend" response message
-type SandboxResource struct {
-	ID          string `json:"id"`
-	Key         string `json:"key"`
-	ContainerID string `json:"container_id"`
-}
-
-/***********
-  Body types
-  ************/
-
-// networkCreate is the expected body of the "create network" http request message
-type networkCreate struct {
-	Name        string                 `json:"name"`
-	NetworkType string                 `json:"network_type"`
-	Options     map[string]interface{} `json:"options"`
-}
-
-// serviceCreate represents the body of the "publish service" http request message
-type serviceCreate struct {
-	Name         string                `json:"name"`
-	Network      string                `json:"network_name"`
-	ExposedPorts []types.TransportPort `json:"exposed_ports"`
-	PortMapping  []types.PortBinding   `json:"port_mapping"`
-}
-
-// serviceAttach represents the expected body of the "attach/detach sandbox to/from service" http request messages
-type serviceAttach struct {
-	SandboxID string `json:"sandbox_id"`
-}
-
-// SandboxCreate is the body of the "post /sandboxes" http request message
-type SandboxCreate struct {
-	ContainerID       string      `json:"container_id"`
-	HostName          string      `json:"host_name"`
-	DomainName        string      `json:"domain_name"`
-	HostsPath         string      `json:"hosts_path"`
-	ResolvConfPath    string      `json:"resolv_conf_path"`
-	DNS               []string    `json:"dns"`
-	ExtraHosts        []extraHost `json:"extra_hosts"`
-	UseDefaultSandbox bool        `json:"use_default_sandbox"`
-}
-
-// extraHost represents the extra host object
-type extraHost struct {
-	Name    string `json:"name"`
-	Address string `json:"address"`
-}
-
-// sandboxParentUpdate is the object carrying the information about the
-// sanbox parent that needs to be updated
-type sandboxParentUpdate struct {
-	ContainerID string `json:"container_id"`
-	Name        string `json:"name"`
-	Address     string `json:"address"`
-}