Skip to content
This repository has been archived by the owner on Oct 13, 2023. It is now read-only.

Commit

Permalink
Merge pull request #16 from mavenugo/cli-1706-stack
Browse files Browse the repository at this point in the history
Host and Bridge network support in docker stack deploy
  • Loading branch information
andrewhsu committed Jun 6, 2017
2 parents d236b52 + 91d25d6 commit 40d9516
Show file tree
Hide file tree
Showing 5 changed files with 136 additions and 21 deletions.
30 changes: 13 additions & 17 deletions components/cli/cli/command/stack/deploy_composefile.go
Expand Up @@ -13,6 +13,7 @@ import (
"github.com/docker/cli/cli/compose/loader"
composetypes "github.com/docker/cli/cli/compose/types"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/swarm"
apiclient "github.com/docker/docker/client"
dockerclient "github.com/docker/docker/client"
Expand Down Expand Up @@ -64,7 +65,7 @@ func deployCompose(ctx context.Context, dockerCli command.Cli, opts deployOption

serviceNetworks := getServicesDeclaredNetworks(config.Services)
networks, externalNetworks := convert.Networks(namespace, config.Networks, serviceNetworks)
if err := validateExternalNetworks(ctx, dockerCli, externalNetworks); err != nil {
if err := validateExternalNetworks(ctx, dockerCli.Client(), externalNetworks); err != nil {
return err
}
if err := createNetworks(ctx, dockerCli, namespace, networks); err != nil {
Expand All @@ -75,15 +76,15 @@ func deployCompose(ctx context.Context, dockerCli command.Cli, opts deployOption
if err != nil {
return err
}
if err := createSecrets(ctx, dockerCli, namespace, secrets); err != nil {
if err := createSecrets(ctx, dockerCli, secrets); err != nil {
return err
}

configs, err := convert.Configs(namespace, config.Configs)
if err != nil {
return err
}
if err := createConfigs(ctx, dockerCli, namespace, configs); err != nil {
if err := createConfigs(ctx, dockerCli, configs); err != nil {
return err
}

Expand Down Expand Up @@ -169,30 +170,26 @@ func getConfigFile(filename string) (*composetypes.ConfigFile, error) {

func validateExternalNetworks(
ctx context.Context,
dockerCli command.Cli,
externalNetworks []string) error {
client := dockerCli.Client()

client dockerclient.NetworkAPIClient,
externalNetworks []string,
) error {
for _, networkName := range externalNetworks {
network, err := client.NetworkInspect(ctx, networkName, false)
if err != nil {
if dockerclient.IsErrNetworkNotFound(err) {
return errors.Errorf("network %q is declared as external, but could not be found. You need to create the network before the stack is deployed (with overlay driver)", networkName)
}
switch {
case dockerclient.IsErrNotFound(err):
return errors.Errorf("network %q is declared as external, but could not be found. You need to create a swarm-scoped network before the stack is deployed", networkName)
case err != nil:
return err
}
if network.Scope != "swarm" {
return errors.Errorf("network %q is declared as external, but it is not in the right scope: %q instead of %q", networkName, network.Scope, "swarm")
case container.NetworkMode(networkName).IsUserDefined() && network.Scope != "swarm":
return errors.Errorf("network %q is declared as external, but it is not in the right scope: %q instead of \"swarm\"", networkName, network.Scope)
}
}

return nil
}

func createSecrets(
ctx context.Context,
dockerCli command.Cli,
namespace convert.Namespace,
secrets []swarm.SecretSpec,
) error {
client := dockerCli.Client()
Expand All @@ -219,7 +216,6 @@ func createSecrets(
func createConfigs(
ctx context.Context,
dockerCli command.Cli,
namespace convert.Namespace,
configs []swarm.ConfigSpec,
) error {
client := dockerCli.Client()
Expand Down
57 changes: 57 additions & 0 deletions components/cli/cli/command/stack/deploy_composefile_test.go
Expand Up @@ -5,9 +5,14 @@ import (
"path/filepath"
"testing"

"github.com/docker/cli/cli/internal/test/network"
"github.com/docker/docker/api/types"
"github.com/docker/docker/pkg/testutil"
"github.com/docker/docker/pkg/testutil/tempfile"
"github.com/pkg/errors"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"golang.org/x/net/context"
)

func TestGetConfigDetails(t *testing.T) {
Expand All @@ -26,3 +31,55 @@ services:
assert.Len(t, details.ConfigFiles, 1)
assert.Len(t, details.Environment, len(os.Environ()))
}

type notFound struct {
error
}

func (n notFound) NotFound() bool {
return true
}

func TestValidateExternalNetworks(t *testing.T) {
var testcases = []struct {
inspectResponse types.NetworkResource
inspectError error
expectedMsg string
network string
}{
{
inspectError: notFound{},
expectedMsg: "could not be found. You need to create a swarm-scoped network",
},
{
inspectError: errors.New("Unexpected"),
expectedMsg: "Unexpected",
},
{
network: "host",
},
{
network: "user",
expectedMsg: "is not in the right scope",
},
{
network: "user",
inspectResponse: types.NetworkResource{Scope: "swarm"},
},
}

for _, testcase := range testcases {
fakeClient := &network.FakeClient{
NetworkInspectFunc: func(_ context.Context, _ string, _ bool) (types.NetworkResource, error) {
return testcase.inspectResponse, testcase.inspectError
},
}
networks := []string{testcase.network}
err := validateExternalNetworks(context.Background(), fakeClient, networks)
if testcase.expectedMsg == "" {
assert.NoError(t, err)
} else {
testutil.ErrorContains(t, err, testcase.expectedMsg)
}
}
}
12 changes: 9 additions & 3 deletions components/cli/cli/compose/convert/service.go
Expand Up @@ -223,10 +223,16 @@ func convertServiceNetworks(
if networkConfig.External.External {
target = networkConfig.External.Name
}
nets = append(nets, swarm.NetworkAttachmentConfig{
netAttachConfig := swarm.NetworkAttachmentConfig{
Target: target,
Aliases: append(aliases, name),
})
Aliases: aliases,
}
// Only add default aliases to user defined networks. Other networks do
// not support aliases.
if container.NetworkMode(target).IsUserDefined() {
netAttachConfig.Aliases = append(netAttachConfig.Aliases, name)
}
nets = append(nets, netAttachConfig)
}

sort.Sort(byNetworkTarget(nets))
Expand Down
56 changes: 56 additions & 0 deletions components/cli/cli/internal/test/network/client.go
@@ -0,0 +1,56 @@
package network

import (
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/filters"
"github.com/docker/docker/api/types/network"
"golang.org/x/net/context"
)

// FakeClient is a fake NetworkAPIClient
type FakeClient struct {
NetworkInspectFunc func(ctx context.Context, networkID string, verbose bool) (types.NetworkResource, error)
}

// NetworkConnect fakes connecting to a network
func (c *FakeClient) NetworkConnect(ctx context.Context, networkID, container string, config *network.EndpointSettings) error {
return nil
}

// NetworkCreate fakes creating a network
func (c *FakeClient) NetworkCreate(ctx context.Context, name string, options types.NetworkCreate) (types.NetworkCreateResponse, error) {
return types.NetworkCreateResponse{}, nil
}

// NetworkDisconnect fakes disconencting from a network
func (c *FakeClient) NetworkDisconnect(ctx context.Context, networkID, container string, force bool) error {
return nil
}

// NetworkInspect fakes inspecting a network
func (c *FakeClient) NetworkInspect(ctx context.Context, networkID string, verbose bool) (types.NetworkResource, error) {
if c.NetworkInspectFunc != nil {
return c.NetworkInspectFunc(ctx, networkID, verbose)
}
return types.NetworkResource{}, nil
}

// NetworkInspectWithRaw fakes inspecting a network with a raw response
func (c *FakeClient) NetworkInspectWithRaw(ctx context.Context, networkID string, verbose bool) (types.NetworkResource, []byte, error) {
return types.NetworkResource{}, nil, nil
}

// NetworkList fakes listing networks
func (c *FakeClient) NetworkList(ctx context.Context, options types.NetworkListOptions) ([]types.NetworkResource, error) {
return nil, nil
}

// NetworkRemove fakes removing networks
func (c *FakeClient) NetworkRemove(ctx context.Context, networkID string) error {
return nil
}

// NetworksPrune fakes pruning networks
func (c *FakeClient) NetworksPrune(ctx context.Context, pruneFilter filters.Args) (types.NetworksPruneReport, error) {
return types.NetworksPruneReport{}, nil
}
2 changes: 1 addition & 1 deletion components/cli/scripts/test/watch
Expand Up @@ -3,7 +3,7 @@
set -e

filewatcher \
-L 5 \
-L 6 \
-x '**/*.swp' \
-x .git \
-x build \
Expand Down

0 comments on commit 40d9516

Please sign in to comment.