From f3863736a8ae48bcc4fe6e2ebc8862d6f9d66458 Mon Sep 17 00:00:00 2001 From: Retros <371373446@qq.com> Date: Sat, 25 Feb 2023 12:10:19 +0800 Subject: [PATCH] add network in use check to `compose down` Signed-off-by: Yuruosheng <371373446@qq.com> --- cmd/nerdctl/compose_down_linux_test.go | 41 +++++++++++++++++++++++++- pkg/cmd/compose/compose.go | 14 +++++++++ pkg/composer/composer.go | 1 + pkg/composer/down.go | 8 +++++ 4 files changed, 63 insertions(+), 1 deletion(-) diff --git a/cmd/nerdctl/compose_down_linux_test.go b/cmd/nerdctl/compose_down_linux_test.go index e1798acb6fd..17143a1b806 100644 --- a/cmd/nerdctl/compose_down_linux_test.go +++ b/cmd/nerdctl/compose_down_linux_test.go @@ -24,9 +24,12 @@ import ( "github.com/containerd/nerdctl/pkg/testutil" ) -func TestComposeDownRemoveOrphans(t *testing.T) { +func TestComposeDownRemoveUsedNetwork(t *testing.T) { base := testutil.NewBase(t) + // The error output is different with docker + testutil.DockerIncompatible(t) + var ( dockerComposeYAMLOrphan = fmt.Sprintf(` version: '3.1' @@ -53,6 +56,42 @@ services: projectName := fmt.Sprintf("nerdctl-compose-test-%d", time.Now().Unix()) t.Logf("projectName=%q", projectName) + base.ComposeCmd("-p", projectName, "-f", compFull.YAMLFullPath(), "up", "-d").AssertOK() + defer base.ComposeCmd("-p", projectName, "-f", compFull.YAMLFullPath(), "down", "--remove-orphans").AssertOK() + + base.ComposeCmd("-p", projectName, "-f", compOrphan.YAMLFullPath(), "down", "-v").AssertCombinedOutContains("is in use") + +} + +func TestComposeDownRemoveOrphans(t *testing.T) { + base := testutil.NewBase(t) + + var ( + dockerComposeYAMLOrphan = fmt.Sprintf(` +version: '3.1' + +services: + test: + image: %s + command: "sleep infinity" +`, testutil.AlpineImage) + + dockerComposeYAMLFull = fmt.Sprintf(` +%s + orphan: + image: %s + command: "sleep infinity" +`, dockerComposeYAMLOrphan, testutil.AlpineImage) + ) + + compOrphan := testutil.NewComposeDir(t, dockerComposeYAMLOrphan) + defer compOrphan.CleanUp() + compFull := testutil.NewComposeDir(t, dockerComposeYAMLFull) + defer compFull.CleanUp() + + projectName := compFull.ProjectName() + t.Logf("projectName=%q", projectName) + orphanContainer := fmt.Sprintf("%s_orphan_1", projectName) base.ComposeCmd("-p", projectName, "-f", compFull.YAMLFullPath(), "up", "-d").AssertOK() diff --git a/pkg/cmd/compose/compose.go b/pkg/cmd/compose/compose.go index bc302be8d73..6697b4acc45 100644 --- a/pkg/cmd/compose/compose.go +++ b/pkg/cmd/compose/compose.go @@ -36,6 +36,7 @@ import ( "github.com/containerd/nerdctl/pkg/ipfs" "github.com/containerd/nerdctl/pkg/netutil" "github.com/containerd/nerdctl/pkg/referenceutil" + "github.com/containerd/nerdctl/pkg/strutil" ocispec "github.com/opencontainers/image-spec/specs-go/v1" "github.com/sirupsen/logrus" ) @@ -58,6 +59,19 @@ func New(client *containerd.Client, globalOptions types.GlobalCommandOptions, op return false, nil } + options.NetworkInUse = func(ctx context.Context, netName string) (bool, error) { + networkUsedByNsMap, err := netutil.UsedNetworks(ctx, client) + if err != nil { + return false, err + } + for _, v := range networkUsedByNsMap { + if strutil.InStringSlice(v, netName) { + return true, nil + } + } + return false, nil + } + volStore, err := volume.Store(globalOptions.Namespace, globalOptions.DataRoot, globalOptions.Address) if err != nil { return nil, err diff --git a/pkg/composer/composer.go b/pkg/composer/composer.go index 4b3e4a72529..d806191f25d 100644 --- a/pkg/composer/composer.go +++ b/pkg/composer/composer.go @@ -40,6 +40,7 @@ type Options struct { EnvFile string NerdctlCmd string NerdctlArgs []string + NetworkInUse func(ctx context.Context, netName string) (bool, error) NetworkExists func(string) (bool, error) VolumeExists func(string) (bool, error) ImageExists func(ctx context.Context, imageName string) (bool, error) diff --git a/pkg/composer/down.go b/pkg/composer/down.go index b4cac156249..9a7a7cc33b7 100644 --- a/pkg/composer/down.go +++ b/pkg/composer/down.go @@ -97,6 +97,14 @@ func (c *Composer) downNetwork(ctx context.Context, shortName string) error { if err != nil { return err } else if netExists { + netUsed, err := c.NetworkInUse(ctx, fullName) + if err != nil { + return err + } + if netUsed { + return fmt.Errorf("network %s is in use", fullName) + } + logrus.Infof("Removing network %s", fullName) if err := c.runNerdctlCmd(ctx, "network", "rm", fullName); err != nil { logrus.Warn(err)