mirror of https://github.com/docker/docs.git
add 'docker network ls' support
add 'docker network inspect' suport Signed-off-by: Victor Vieux <vieux@docker.com>
This commit is contained in:
parent
267d7e6701
commit
e634df03a7
|
|
@ -114,7 +114,7 @@
|
|||
},
|
||||
{
|
||||
"ImportPath": "github.com/samalba/dockerclient",
|
||||
"Rev": "73edd1c3a9d280bcec6a22a12fc90c1a46558b4e"
|
||||
"Rev": "32a9231a6d93f563010c5ffc2f6fb223b347b6b1"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/samuel/go-zookeeper/zk",
|
||||
|
|
|
|||
|
|
@ -778,3 +778,79 @@ func (client *DockerClient) CreateVolume(request *VolumeCreateRequest) (*Volume,
|
|||
err = json.Unmarshal(data, volume)
|
||||
return volume, err
|
||||
}
|
||||
|
||||
func (client *DockerClient) ListNetworks(filters string) ([]*NetworkResource, error) {
|
||||
uri := fmt.Sprintf("/%s/networks", APIVersion)
|
||||
|
||||
if filters != "" {
|
||||
uri += "&filters=" + filters
|
||||
}
|
||||
|
||||
data, err := client.doRequest("GET", uri, nil, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ret := []*NetworkResource{}
|
||||
err = json.Unmarshal(data, &ret)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (client *DockerClient) InspectNetwork(id string) (*NetworkResource, error) {
|
||||
uri := fmt.Sprintf("/%s/networks/%s", APIVersion, id)
|
||||
|
||||
data, err := client.doRequest("GET", uri, nil, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ret := &NetworkResource{}
|
||||
err = json.Unmarshal(data, ret)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (client *DockerClient) CreateNetwork(config *NetworkCreate) (*NetworkCreateResponse, error) {
|
||||
data, err := json.Marshal(config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
uri := fmt.Sprintf("/%s/networks/create", APIVersion)
|
||||
data, err = client.doRequest("POST", uri, data, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ret := &NetworkCreateResponse{}
|
||||
err = json.Unmarshal(data, ret)
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (client *DockerClient) ConnectNetwork(id, container string) error {
|
||||
data, err := json.Marshal(NetworkConnect{Container: container})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
uri := fmt.Sprintf("/%s/networks/%s/connect", APIVersion, id)
|
||||
_, err = client.doRequest("POST", uri, data, nil)
|
||||
return err
|
||||
}
|
||||
|
||||
func (client *DockerClient) DisconnectNetwork(id, container string) error {
|
||||
data, err := json.Marshal(NetworkDisconnect{Container: container})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
uri := fmt.Sprintf("/%s/networks/%s/disconnect", APIVersion, id)
|
||||
_, err = client.doRequest("POST", uri, data, nil)
|
||||
return err
|
||||
}
|
||||
|
||||
func (client *DockerClient) RemoveNetwork(id string) error {
|
||||
uri := fmt.Sprintf("/%s/networks/%s", APIVersion, id)
|
||||
_, err := client.doRequest("DELETE", uri, nil, nil)
|
||||
return err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -119,6 +119,7 @@ func TestListContainersWithSize(t *testing.T) {
|
|||
cnt := containers[0]
|
||||
assertEqual(t, cnt.SizeRw, int64(123), "")
|
||||
}
|
||||
|
||||
func TestListContainersWithFilters(t *testing.T) {
|
||||
client := testDockerClient(t)
|
||||
containers, err := client.ListContainers(true, true, "{'id':['332375cfbc23edb921a21026314c3497674ba8bdcb2c85e0e65ebf2017f688ce']}")
|
||||
|
|
|
|||
|
|
@ -48,4 +48,10 @@ type Client interface {
|
|||
ListVolumes() ([]*Volume, error)
|
||||
RemoveVolume(name string) error
|
||||
CreateVolume(request *VolumeCreateRequest) (*Volume, error)
|
||||
ListNetworks(filters string) ([]*NetworkResource, error)
|
||||
InspectNetwork(id string) (*NetworkResource, error)
|
||||
CreateNetwork(config *NetworkCreate) (*NetworkCreateResponse, error)
|
||||
ConnectNetwork(id, container string) error
|
||||
DisconnectNetwork(id, container string) error
|
||||
RemoveNetwork(id string) error
|
||||
}
|
||||
|
|
|
|||
|
|
@ -185,3 +185,33 @@ func (client *MockClient) CreateVolume(request *dockerclient.VolumeCreateRequest
|
|||
args := client.Mock.Called(request)
|
||||
return args.Get(0).(*dockerclient.Volume), args.Error(1)
|
||||
}
|
||||
|
||||
func (client *MockClient) ListNetworks(filters string) ([]*dockerclient.NetworkResource, error) {
|
||||
args := client.Mock.Called(filters)
|
||||
return args.Get(0).([]*dockerclient.NetworkResource), args.Error(1)
|
||||
}
|
||||
|
||||
func (client *MockClient) InspectNetwork(id string) (*dockerclient.NetworkResource, error) {
|
||||
args := client.Mock.Called(id)
|
||||
return args.Get(0).(*dockerclient.NetworkResource), args.Error(1)
|
||||
}
|
||||
|
||||
func (client *MockClient) CreateNetwork(config *dockerclient.NetworkCreate) (*dockerclient.NetworkCreateResponse, error) {
|
||||
args := client.Mock.Called(config)
|
||||
return args.Get(0).(*dockerclient.NetworkCreateResponse), args.Error(1)
|
||||
}
|
||||
|
||||
func (client *MockClient) ConnectNetwork(id, container string) error {
|
||||
args := client.Mock.Called(id, container)
|
||||
return args.Error(0)
|
||||
}
|
||||
|
||||
func (client *MockClient) DisconnectNetwork(id, container string) error {
|
||||
args := client.Mock.Called(id, container)
|
||||
return args.Error(0)
|
||||
}
|
||||
|
||||
func (client *MockClient) RemoveNetwork(id string) error {
|
||||
args := client.Mock.Called(id)
|
||||
return args.Error(0)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -153,6 +153,31 @@ func (client *NopClient) ListVolumes() ([]*dockerclient.Volume, error) {
|
|||
func (client *NopClient) RemoveVolume(name string) error {
|
||||
return ErrNoEngine
|
||||
}
|
||||
|
||||
func (client *NopClient) CreateVolume(request *dockerclient.VolumeCreateRequest) (*dockerclient.Volume, error) {
|
||||
return nil, ErrNoEngine
|
||||
}
|
||||
|
||||
func (client *NopClient) ListNetworks(filters string) ([]*dockerclient.NetworkResource, error) {
|
||||
return nil, ErrNoEngine
|
||||
}
|
||||
|
||||
func (client *NopClient) InspectNetwork(id string) (*dockerclient.NetworkResource, error) {
|
||||
return nil, ErrNoEngine
|
||||
}
|
||||
|
||||
func (client *NopClient) CreateNetwork(config *dockerclient.NetworkCreate) (*dockerclient.NetworkCreateResponse, error) {
|
||||
return nil, ErrNoEngine
|
||||
}
|
||||
|
||||
func (client *NopClient) ConnectNetwork(id, container string) error {
|
||||
return ErrNoEngine
|
||||
}
|
||||
|
||||
func (client *NopClient) DisconnectNetwork(id, container string) error {
|
||||
return ErrNoEngine
|
||||
}
|
||||
|
||||
func (client *NopClient) RemoveNetwork(id string) error {
|
||||
return ErrNoEngine
|
||||
}
|
||||
|
|
|
|||
|
|
@ -460,3 +460,44 @@ type VolumeCreateRequest struct {
|
|||
Driver string // Driver is the name of the driver that should be used to create the volume
|
||||
DriverOpts map[string]string // DriverOpts holds the driver specific options to use for when creating the volume.
|
||||
}
|
||||
|
||||
// NetworkResource is the body of the "get network" http response message
|
||||
type NetworkResource struct {
|
||||
Name string `json:"name"`
|
||||
ID string `json:"id"`
|
||||
Driver string `json:"driver"`
|
||||
Containers map[string]EndpointResource `json:"containers"`
|
||||
Options map[string]interface{} `json:"options,omitempty"`
|
||||
}
|
||||
|
||||
//EndpointResource contains network resources allocated and usd for a container in a network
|
||||
type EndpointResource struct {
|
||||
EndpointID string `json:"endpoint"`
|
||||
MacAddress string `json:"mac_address"`
|
||||
IPv4Address string `json:"ipv4_address"`
|
||||
IPv6Address string `json:"ipv6_address"`
|
||||
}
|
||||
|
||||
// NetworkCreate is the expected body of the "create network" http request message
|
||||
type NetworkCreate struct {
|
||||
Name string `json:"name"`
|
||||
CheckDuplicate bool `json:"check_duplicate"`
|
||||
Driver string `json:"driver"`
|
||||
Options map[string]interface{} `json:"options"`
|
||||
}
|
||||
|
||||
// NetworkCreateResponse is the response message sent by the server for network create call
|
||||
type NetworkCreateResponse struct {
|
||||
ID string `json:"id"`
|
||||
Warning string `json:"warning"`
|
||||
}
|
||||
|
||||
// NetworkConnect represents the data to be used to connect a container to the network
|
||||
type NetworkConnect struct {
|
||||
Container string `json:"container"`
|
||||
}
|
||||
|
||||
// NetworkDisconnect represents the data to be used to disconnect a container from the network
|
||||
type NetworkDisconnect struct {
|
||||
Container string `json:"container"`
|
||||
}
|
||||
|
|
|
|||
|
|
@ -169,6 +169,13 @@ func getImagesJSON(c *context, w http.ResponseWriter, r *http.Request) {
|
|||
json.NewEncoder(w).Encode(images)
|
||||
}
|
||||
|
||||
// GET /networks
|
||||
func getNetworks(c *context, w http.ResponseWriter, r *http.Request) {
|
||||
networks := c.cluster.Networks()
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
json.NewEncoder(w).Encode(networks)
|
||||
}
|
||||
|
||||
// GET /volumes
|
||||
func getVolumes(c *context, w http.ResponseWriter, r *http.Request) {
|
||||
volumes := struct {
|
||||
|
|
@ -663,6 +670,16 @@ func ping(c *context, w http.ResponseWriter, r *http.Request) {
|
|||
w.Write([]byte{'O', 'K'})
|
||||
}
|
||||
|
||||
// Proxy a request to the right node
|
||||
func proxyNetwork(c *context, w http.ResponseWriter, r *http.Request) {
|
||||
var id = mux.Vars(r)["networkid"]
|
||||
if network := c.cluster.Network(id); network != nil {
|
||||
proxy(c.tlsConfig, network.Engine.Addr, w, r)
|
||||
return
|
||||
}
|
||||
httpError(w, fmt.Sprintf("No such network: %s", id), http.StatusNotFound)
|
||||
}
|
||||
|
||||
// Proxy a request to the right node
|
||||
func proxyVolume(c *context, w http.ResponseWriter, r *http.Request) {
|
||||
var name = mux.Vars(r)["volumename"]
|
||||
|
|
|
|||
|
|
@ -47,6 +47,8 @@ var routes = map[string]map[string]handler{
|
|||
"/containers/{name:.*}/stats": proxyContainer,
|
||||
"/containers/{name:.*}/attach/ws": proxyHijack,
|
||||
"/exec/{execid:.*}/json": proxyContainer,
|
||||
"/networks": getNetworks,
|
||||
"/networks/{networkid:.*}": proxyNetwork,
|
||||
"/volumes": getVolumes,
|
||||
"/volumes/{volumename:.*}": proxyVolume,
|
||||
},
|
||||
|
|
|
|||
|
|
@ -32,6 +32,12 @@ type Cluster interface {
|
|||
// cluster.Containers().Get(IDOrName)
|
||||
Container(IDOrName string) *Container
|
||||
|
||||
// Return all networks
|
||||
Networks() Networks
|
||||
|
||||
// Return network the matching `IDOrName`
|
||||
Network(IDOrName string) *Network
|
||||
|
||||
// Create a volume
|
||||
CreateVolume(request *dockerclient.VolumeCreateRequest) (*Volume, error)
|
||||
|
||||
|
|
|
|||
|
|
@ -73,6 +73,7 @@ type Engine struct {
|
|||
refreshDelayer *delayer
|
||||
containers map[string]*Container
|
||||
images []*Image
|
||||
networks map[string]*Network
|
||||
volumes map[string]*Volume
|
||||
client dockerclient.Client
|
||||
eventHandler EventHandler
|
||||
|
|
@ -89,6 +90,7 @@ func NewEngine(addr string, overcommitRatio float64) *Engine {
|
|||
Labels: make(map[string]string),
|
||||
stopCh: make(chan struct{}),
|
||||
containers: make(map[string]*Container),
|
||||
networks: make(map[string]*Network),
|
||||
volumes: make(map[string]*Volume),
|
||||
healthy: true,
|
||||
overcommitRatio: int64(overcommitRatio * 100),
|
||||
|
|
@ -138,6 +140,7 @@ func (e *Engine) ConnectWithClient(client dockerclient.Client) error {
|
|||
|
||||
// Do not check error as older daemon don't support this call
|
||||
e.RefreshVolumes()
|
||||
e.RefreshNetworks()
|
||||
|
||||
// Start the update loop.
|
||||
go e.refreshLoop()
|
||||
|
|
@ -249,6 +252,21 @@ func (e *Engine) RefreshImages() error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// RefreshNetworks refreshes the list of networks on the engine.
|
||||
func (e *Engine) RefreshNetworks() error {
|
||||
networks, err := e.client.ListNetworks("")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
e.Lock()
|
||||
e.networks = make(map[string]*Network)
|
||||
for _, network := range networks {
|
||||
e.networks[network.ID] = &Network{NetworkResource: *network, Engine: e}
|
||||
}
|
||||
e.Unlock()
|
||||
return nil
|
||||
}
|
||||
|
||||
// RefreshVolumes refreshes the list of volumes on the engine.
|
||||
func (e *Engine) RefreshVolumes() error {
|
||||
volumes, err := e.client.ListVolumes()
|
||||
|
|
@ -382,6 +400,7 @@ func (e *Engine) refreshLoop() {
|
|||
if err == nil {
|
||||
// Do not check error as older daemon don't support this call
|
||||
e.RefreshVolumes()
|
||||
e.RefreshNetworks()
|
||||
err = e.RefreshImages()
|
||||
}
|
||||
|
||||
|
|
@ -496,6 +515,7 @@ func (e *Engine) Create(config *ContainerConfig, name string, pullImage bool) (*
|
|||
// Register the container immediately while waiting for a state refresh.
|
||||
// Force a state refresh to pick up the newly created container.
|
||||
e.refreshContainer(id, true)
|
||||
e.RefreshNetworks()
|
||||
|
||||
e.RLock()
|
||||
defer e.RUnlock()
|
||||
|
|
@ -621,6 +641,18 @@ func (e *Engine) Images(all bool, filters dockerfilters.Args) []*Image {
|
|||
return images
|
||||
}
|
||||
|
||||
// Networks returns all the networks in the engine
|
||||
func (e *Engine) Networks() Networks {
|
||||
e.RLock()
|
||||
|
||||
networks := Networks{}
|
||||
for _, network := range e.networks {
|
||||
networks = append(networks, network)
|
||||
}
|
||||
e.RUnlock()
|
||||
return networks
|
||||
}
|
||||
|
||||
// Volumes returns all the volumes in the engine
|
||||
func (e *Engine) Volumes() []*Volume {
|
||||
e.RLock()
|
||||
|
|
@ -662,10 +694,12 @@ func (e *Engine) handler(ev *dockerclient.Event, _ chan error, args ...interface
|
|||
// order to update container.Info and get the new NetworkSettings.
|
||||
e.refreshContainer(ev.Id, true)
|
||||
e.RefreshVolumes()
|
||||
e.RefreshNetworks()
|
||||
default:
|
||||
// Otherwise, do a "soft" refresh of the container.
|
||||
e.refreshContainer(ev.Id, false)
|
||||
e.RefreshVolumes()
|
||||
e.RefreshNetworks()
|
||||
}
|
||||
|
||||
// If there is no event handler registered, abort right now.
|
||||
|
|
|
|||
|
|
@ -75,6 +75,7 @@ func TestEngineCpusMemory(t *testing.T) {
|
|||
client.On("ListContainers", true, false, "").Return([]dockerclient.Container{}, nil)
|
||||
client.On("ListImages", mock.Anything).Return([]*dockerclient.Image{}, nil)
|
||||
client.On("ListVolumes", mock.Anything).Return([]*dockerclient.Volume{}, nil)
|
||||
client.On("ListNetworks", mock.Anything).Return([]*dockerclient.NetworkResource{}, nil)
|
||||
client.On("StartMonitorEvents", mock.Anything, mock.Anything, mock.Anything).Return()
|
||||
|
||||
assert.NoError(t, engine.ConnectWithClient(client))
|
||||
|
|
@ -97,6 +98,7 @@ func TestEngineSpecs(t *testing.T) {
|
|||
client.On("ListContainers", true, false, "").Return([]dockerclient.Container{}, nil)
|
||||
client.On("ListImages", mock.Anything).Return([]*dockerclient.Image{}, nil)
|
||||
client.On("ListVolumes", mock.Anything).Return([]*dockerclient.Volume{}, nil)
|
||||
client.On("ListNetworks", mock.Anything).Return([]*dockerclient.NetworkResource{}, nil)
|
||||
client.On("StartMonitorEvents", mock.Anything, mock.Anything, mock.Anything).Return()
|
||||
|
||||
assert.NoError(t, engine.ConnectWithClient(client))
|
||||
|
|
@ -127,6 +129,7 @@ func TestEngineState(t *testing.T) {
|
|||
client.On("ListContainers", true, false, "").Return([]dockerclient.Container{{Id: "one"}}, nil).Once()
|
||||
client.On("ListImages", mock.Anything).Return([]*dockerclient.Image{}, nil).Once()
|
||||
client.On("ListVolumes", mock.Anything).Return([]*dockerclient.Volume{}, nil)
|
||||
client.On("ListNetworks", mock.Anything).Return([]*dockerclient.NetworkResource{}, nil)
|
||||
client.On("InspectContainer", "one").Return(&dockerclient.ContainerInfo{Config: &dockerclient.ContainerConfig{CpuShares: 100}}, nil).Once()
|
||||
client.On("ListContainers", true, false, fmt.Sprintf("{%q:[%q]}", "id", "two")).Return([]dockerclient.Container{{Id: "two"}}, nil).Once()
|
||||
client.On("InspectContainer", "two").Return(&dockerclient.ContainerInfo{Config: &dockerclient.ContainerConfig{CpuShares: 100}}, nil).Once()
|
||||
|
|
@ -173,6 +176,7 @@ func TestCreateContainer(t *testing.T) {
|
|||
client.On("ListContainers", true, false, "").Return([]dockerclient.Container{}, nil).Once()
|
||||
client.On("ListImages", mock.Anything).Return([]*dockerclient.Image{}, nil).Once()
|
||||
client.On("ListVolumes", mock.Anything).Return([]*dockerclient.Volume{}, nil)
|
||||
client.On("ListNetworks", mock.Anything).Return([]*dockerclient.NetworkResource{}, nil)
|
||||
assert.NoError(t, engine.ConnectWithClient(client))
|
||||
assert.True(t, engine.isConnected())
|
||||
|
||||
|
|
@ -187,6 +191,7 @@ func TestCreateContainer(t *testing.T) {
|
|||
client.On("ListContainers", true, false, fmt.Sprintf(`{"id":[%q]}`, id)).Return([]dockerclient.Container{{Id: id}}, nil).Once()
|
||||
client.On("ListImages", mock.Anything).Return([]*dockerclient.Image{}, nil).Once()
|
||||
client.On("ListVolumes", mock.Anything).Return([]*dockerclient.Volume{}, nil)
|
||||
client.On("ListNetworks", mock.Anything).Return([]*dockerclient.NetworkResource{}, nil)
|
||||
client.On("InspectContainer", id).Return(&dockerclient.ContainerInfo{Config: &config.ContainerConfig}, nil).Once()
|
||||
container, err := engine.Create(config, name, false)
|
||||
assert.Nil(t, err)
|
||||
|
|
@ -211,6 +216,7 @@ func TestCreateContainer(t *testing.T) {
|
|||
client.On("ListContainers", true, false, fmt.Sprintf(`{"id":[%q]}`, id)).Return([]dockerclient.Container{{Id: id}}, nil).Once()
|
||||
client.On("ListImages", mock.Anything).Return([]*dockerclient.Image{}, nil).Once()
|
||||
client.On("ListVolumes", mock.Anything).Return([]*dockerclient.Volume{}, nil)
|
||||
client.On("ListNetworks", mock.Anything).Return([]*dockerclient.NetworkResource{}, nil)
|
||||
client.On("InspectContainer", id).Return(&dockerclient.ContainerInfo{Config: &config.ContainerConfig}, nil).Once()
|
||||
container, err = engine.Create(config, name, true)
|
||||
assert.Nil(t, err)
|
||||
|
|
@ -288,6 +294,7 @@ func TestUsedCpus(t *testing.T) {
|
|||
client.On("ListImages", mock.Anything).Return([]*dockerclient.Image{}, nil).Once()
|
||||
client.On("ListContainers", true, false, "").Return([]dockerclient.Container{{Id: "test"}}, nil).Once()
|
||||
client.On("ListVolumes", mock.Anything).Return([]*dockerclient.Volume{}, nil)
|
||||
client.On("ListNetworks", mock.Anything).Return([]*dockerclient.NetworkResource{}, nil)
|
||||
client.On("InspectContainer", "test").Return(&dockerclient.ContainerInfo{Config: &dockerclient.ContainerConfig{CpuShares: cpuShares}}, nil).Once()
|
||||
engine.ConnectWithClient(client)
|
||||
|
||||
|
|
@ -317,6 +324,7 @@ func TestContainerRemovedDuringRefresh(t *testing.T) {
|
|||
client.On("StartMonitorEvents", mock.Anything, mock.Anything, mock.Anything).Return()
|
||||
client.On("ListContainers", true, false, "").Return([]dockerclient.Container{container1, container2}, nil)
|
||||
client.On("ListVolumes", mock.Anything).Return([]*dockerclient.Volume{}, nil)
|
||||
client.On("ListNetworks", mock.Anything).Return([]*dockerclient.NetworkResource{}, nil)
|
||||
client.On("InspectContainer", "c1").Return(info1, errors.New("Not found"))
|
||||
client.On("InspectContainer", "c2").Return(info2, nil)
|
||||
|
||||
|
|
|
|||
|
|
@ -306,6 +306,16 @@ func (c *Cluster) RenameContainer(container *cluster.Container, newName string)
|
|||
return nil
|
||||
}
|
||||
|
||||
// Networks returns all the networks in the cluster.
|
||||
func (c *Cluster) Networks() cluster.Networks {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Network returns the network name in the cluster
|
||||
func (c *Cluster) Network(name string) *cluster.Network {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Volumes returns all the volumes in the cluster.
|
||||
func (c *Cluster) Volumes() []*cluster.Volume {
|
||||
return nil
|
||||
|
|
|
|||
|
|
@ -0,0 +1,62 @@
|
|||
package cluster
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/docker/docker/pkg/stringid"
|
||||
"github.com/samalba/dockerclient"
|
||||
)
|
||||
|
||||
// Network is exported
|
||||
type Network struct {
|
||||
dockerclient.NetworkResource
|
||||
|
||||
Engine *Engine
|
||||
}
|
||||
|
||||
// Networks represents a map of networks
|
||||
type Networks []*Network
|
||||
|
||||
// Get returns a network using it's ID or Name
|
||||
func (networks Networks) Get(IDOrName string) *Network {
|
||||
// Abort immediately if the name is empty.
|
||||
if len(IDOrName) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Match exact or short Network ID.
|
||||
for _, network := range networks {
|
||||
if network.ID == IDOrName || stringid.TruncateID(network.ID) == IDOrName {
|
||||
return network
|
||||
}
|
||||
}
|
||||
|
||||
candidates := []*Network{}
|
||||
|
||||
// Match name, /name or engine/name.
|
||||
for _, network := range networks {
|
||||
if network.Name == IDOrName || network.Name == "/"+IDOrName || network.Engine.ID+network.Name == IDOrName || network.Engine.Name+network.Name == IDOrName {
|
||||
return network
|
||||
}
|
||||
}
|
||||
|
||||
if size := len(candidates); size == 1 {
|
||||
return candidates[0]
|
||||
} else if size > 1 {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Match Network ID prefix.
|
||||
for _, network := range networks {
|
||||
if strings.HasPrefix(network.ID, IDOrName) {
|
||||
candidates = append(candidates, network)
|
||||
}
|
||||
}
|
||||
|
||||
if len(candidates) == 1 {
|
||||
return candidates[0]
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
}
|
||||
|
|
@ -569,7 +569,33 @@ func (c *Cluster) Container(IDOrName string) *cluster.Container {
|
|||
c.RLock()
|
||||
defer c.RUnlock()
|
||||
|
||||
return cluster.Containers(c.Containers()).Get(IDOrName)
|
||||
return c.Containers().Get(IDOrName)
|
||||
}
|
||||
|
||||
// Networks returns all the networks in the cluster.
|
||||
func (c *Cluster) Networks() cluster.Networks {
|
||||
c.RLock()
|
||||
defer c.RUnlock()
|
||||
|
||||
out := cluster.Networks{}
|
||||
for _, e := range c.engines {
|
||||
out = append(out, e.Networks()...)
|
||||
}
|
||||
|
||||
return out
|
||||
}
|
||||
|
||||
// Network returns the network `IDOrName` in the cluster
|
||||
func (c *Cluster) Network(IDOrName string) *cluster.Network {
|
||||
// Abort immediately if the name is empty.
|
||||
if len(IDOrName) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
c.RLock()
|
||||
defer c.RUnlock()
|
||||
|
||||
return c.Networks().Get(IDOrName)
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -131,6 +131,7 @@ func TestImportImage(t *testing.T) {
|
|||
client.On("ListContainers", true, false, "").Return([]dockerclient.Container{}, nil).Once()
|
||||
client.On("ListImages", mock.Anything).Return([]*dockerclient.Image{}, nil)
|
||||
client.On("ListVolumes", mock.Anything).Return([]*dockerclient.Volume{}, nil)
|
||||
client.On("ListNetworks", mock.Anything).Return([]*dockerclient.NetworkResource{}, nil)
|
||||
|
||||
// connect client
|
||||
engine.ConnectWithClient(client)
|
||||
|
|
@ -180,6 +181,7 @@ func TestLoadImage(t *testing.T) {
|
|||
client.On("ListContainers", true, false, "").Return([]dockerclient.Container{}, nil).Once()
|
||||
client.On("ListImages", mock.Anything).Return([]*dockerclient.Image{}, nil)
|
||||
client.On("ListVolumes", mock.Anything).Return([]*dockerclient.Volume{}, nil)
|
||||
client.On("ListNetworks", mock.Anything).Return([]*dockerclient.NetworkResource{}, nil)
|
||||
|
||||
// connect client
|
||||
engine.ConnectWithClient(client)
|
||||
|
|
@ -232,6 +234,7 @@ func TestTagImage(t *testing.T) {
|
|||
client.On("ListContainers", true, false, "").Return([]dockerclient.Container{}, nil).Once()
|
||||
client.On("ListImages", mock.Anything).Return(images, nil)
|
||||
client.On("ListVolumes", mock.Anything).Return([]*dockerclient.Volume{}, nil)
|
||||
client.On("ListNetworks", mock.Anything).Return([]*dockerclient.NetworkResource{}, nil)
|
||||
|
||||
// connect client
|
||||
engine.ConnectWithClient(client)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,72 @@
|
|||
#!/usr/bin/env bats
|
||||
|
||||
load ../helpers
|
||||
|
||||
function teardown() {
|
||||
swarm_manage_cleanup
|
||||
stop_docker
|
||||
}
|
||||
|
||||
@test "docker network ls" {
|
||||
start_docker 2
|
||||
swarm_manage
|
||||
|
||||
run docker_swarm network ls
|
||||
[ "${#lines[@]}" -eq 7 ]
|
||||
}
|
||||
|
||||
@test "docker network inspect" {
|
||||
start_docker_with_busybox 2
|
||||
swarm_manage
|
||||
|
||||
# run
|
||||
docker_swarm run -d busybox sleep 100
|
||||
|
||||
run docker_swarm network inspect bridge
|
||||
[ "${#lines[@]}" -eq 13 ]
|
||||
}
|
||||
|
||||
@test "docker volume create" {
|
||||
skip
|
||||
start_docker 2
|
||||
swarm_manage
|
||||
|
||||
run docker_swarm volume ls
|
||||
[ "${#lines[@]}" -eq 1 ]
|
||||
|
||||
docker_swarm volume create --name=test_volume
|
||||
run docker_swarm volume
|
||||
[ "${#lines[@]}" -eq 3 ]
|
||||
|
||||
docker_swarm run -d -v=/tmp busybox true
|
||||
run docker_swarm volume
|
||||
[ "${#lines[@]}" -eq 4 ]
|
||||
}
|
||||
|
||||
@test "docker volume rm" {
|
||||
skip
|
||||
start_docker_with_busybox 2
|
||||
swarm_manage
|
||||
|
||||
run docker_swarm volume rm test_volume
|
||||
[ "$status" -ne 0 ]
|
||||
|
||||
docker_swarm run -d --name=test_container -v=/tmp busybox true
|
||||
|
||||
run docker_swarm volume ls -q
|
||||
volume=${output}
|
||||
[ "${#lines[@]}" -eq 1 ]
|
||||
|
||||
run docker_swarm volume rm $volume
|
||||
[ "$status" -ne 0 ]
|
||||
|
||||
docker_swarm rm test_container
|
||||
|
||||
run docker_swarm volume rm $volume
|
||||
[ "$status" -eq 0 ]
|
||||
[ "${#lines[@]}" -eq 1 ]
|
||||
|
||||
run docker_swarm volume
|
||||
echo $output
|
||||
[ "${#lines[@]}" -eq 1 ]
|
||||
}
|
||||
Loading…
Reference in New Issue