github.com/adityamillind98/moby@v23.0.0-rc.4+incompatible/integration-cli/docker_cli_prune_unix_test.go (about)

     1  //go:build !windows
     2  // +build !windows
     3  
     4  package main
     5  
     6  import (
     7  	"os"
     8  	"path/filepath"
     9  	"strconv"
    10  	"strings"
    11  	"testing"
    12  	"time"
    13  
    14  	"github.com/docker/docker/integration-cli/checker"
    15  	"github.com/docker/docker/integration-cli/cli"
    16  	"github.com/docker/docker/integration-cli/cli/build"
    17  	"github.com/docker/docker/integration-cli/daemon"
    18  	"gotest.tools/v3/assert"
    19  	"gotest.tools/v3/icmd"
    20  	"gotest.tools/v3/poll"
    21  )
    22  
    23  func (s *DockerCLIPruneSuite) TearDownTest(c *testing.T) {
    24  	s.ds.TearDownTest(c)
    25  }
    26  
    27  func (s *DockerCLIPruneSuite) OnTimeout(c *testing.T) {
    28  	s.ds.OnTimeout(c)
    29  }
    30  
    31  func pruneNetworkAndVerify(c *testing.T, d *daemon.Daemon, kept, pruned []string) {
    32  	_, err := d.Cmd("network", "prune", "--force")
    33  	assert.NilError(c, err)
    34  
    35  	for _, s := range kept {
    36  		poll.WaitOn(c, pollCheck(c, func(*testing.T) (interface{}, string) {
    37  			out, err := d.Cmd("network", "ls", "--format", "{{.Name}}")
    38  			assert.NilError(c, err)
    39  			return out, ""
    40  		}, checker.Contains(s)), poll.WithTimeout(defaultReconciliationTimeout))
    41  	}
    42  
    43  	for _, s := range pruned {
    44  		poll.WaitOn(c, pollCheck(c, func(*testing.T) (interface{}, string) {
    45  			out, err := d.Cmd("network", "ls", "--format", "{{.Name}}")
    46  			assert.NilError(c, err)
    47  			return out, ""
    48  		}, checker.Not(checker.Contains(s))), poll.WithTimeout(defaultReconciliationTimeout))
    49  	}
    50  }
    51  
    52  func (s *DockerSwarmSuite) TestPruneNetwork(c *testing.T) {
    53  	d := s.AddDaemon(c, true, true)
    54  	_, err := d.Cmd("network", "create", "n1") // used by container (testprune)
    55  	assert.NilError(c, err)
    56  	_, err = d.Cmd("network", "create", "n2")
    57  	assert.NilError(c, err)
    58  	_, err = d.Cmd("network", "create", "n3", "--driver", "overlay") // used by service (testprunesvc)
    59  	assert.NilError(c, err)
    60  	_, err = d.Cmd("network", "create", "n4", "--driver", "overlay")
    61  	assert.NilError(c, err)
    62  
    63  	cName := "testprune"
    64  	_, err = d.Cmd("run", "-d", "--name", cName, "--net", "n1", "busybox", "top")
    65  	assert.NilError(c, err)
    66  
    67  	serviceName := "testprunesvc"
    68  	replicas := 1
    69  	out, err := d.Cmd("service", "create", "--detach", "--no-resolve-image",
    70  		"--name", serviceName,
    71  		"--replicas", strconv.Itoa(replicas),
    72  		"--network", "n3",
    73  		"busybox", "top")
    74  	assert.NilError(c, err)
    75  	assert.Assert(c, strings.TrimSpace(out) != "")
    76  	poll.WaitOn(c, pollCheck(c, d.CheckActiveContainerCount, checker.Equals(replicas+1)), poll.WithTimeout(defaultReconciliationTimeout))
    77  
    78  	// prune and verify
    79  	pruneNetworkAndVerify(c, d, []string{"n1", "n3"}, []string{"n2", "n4"})
    80  
    81  	// remove containers, then prune and verify again
    82  	_, err = d.Cmd("rm", "-f", cName)
    83  	assert.NilError(c, err)
    84  	_, err = d.Cmd("service", "rm", serviceName)
    85  	assert.NilError(c, err)
    86  	poll.WaitOn(c, pollCheck(c, d.CheckActiveContainerCount, checker.Equals(0)), poll.WithTimeout(defaultReconciliationTimeout))
    87  
    88  	pruneNetworkAndVerify(c, d, []string{}, []string{"n1", "n3"})
    89  }
    90  
    91  func (s *DockerDaemonSuite) TestPruneImageDangling(c *testing.T) {
    92  	s.d.StartWithBusybox(c)
    93  
    94  	result := cli.BuildCmd(c, "test", cli.Daemon(s.d),
    95  		build.WithDockerfile(`FROM busybox
    96                   LABEL foo=bar`),
    97  		cli.WithFlags("-q"),
    98  	)
    99  	result.Assert(c, icmd.Success)
   100  	id := strings.TrimSpace(result.Combined())
   101  
   102  	out, err := s.d.Cmd("images", "-q", "--no-trunc")
   103  	assert.NilError(c, err)
   104  	assert.Assert(c, strings.Contains(strings.TrimSpace(out), id))
   105  	out, err = s.d.Cmd("image", "prune", "--force")
   106  	assert.NilError(c, err)
   107  	assert.Assert(c, !strings.Contains(strings.TrimSpace(out), id))
   108  	out, err = s.d.Cmd("images", "-q", "--no-trunc")
   109  	assert.NilError(c, err)
   110  	assert.Assert(c, strings.Contains(strings.TrimSpace(out), id))
   111  	out, err = s.d.Cmd("image", "prune", "--force", "--all")
   112  	assert.NilError(c, err)
   113  	assert.Assert(c, strings.Contains(strings.TrimSpace(out), id))
   114  	out, err = s.d.Cmd("images", "-q", "--no-trunc")
   115  	assert.NilError(c, err)
   116  	assert.Assert(c, !strings.Contains(strings.TrimSpace(out), id))
   117  }
   118  
   119  func (s *DockerCLIPruneSuite) TestPruneContainerUntil(c *testing.T) {
   120  	out := cli.DockerCmd(c, "run", "-d", "busybox").Combined()
   121  	id1 := strings.TrimSpace(out)
   122  	cli.WaitExited(c, id1, 5*time.Second)
   123  
   124  	until := daemonUnixTime(c)
   125  
   126  	out = cli.DockerCmd(c, "run", "-d", "busybox").Combined()
   127  	id2 := strings.TrimSpace(out)
   128  	cli.WaitExited(c, id2, 5*time.Second)
   129  
   130  	out = cli.DockerCmd(c, "container", "prune", "--force", "--filter", "until="+until).Combined()
   131  	assert.Assert(c, strings.Contains(strings.TrimSpace(out), id1))
   132  	assert.Assert(c, !strings.Contains(strings.TrimSpace(out), id2))
   133  	out = cli.DockerCmd(c, "ps", "-a", "-q", "--no-trunc").Combined()
   134  	assert.Assert(c, !strings.Contains(strings.TrimSpace(out), id1))
   135  	assert.Assert(c, strings.Contains(strings.TrimSpace(out), id2))
   136  }
   137  
   138  func (s *DockerCLIPruneSuite) TestPruneContainerLabel(c *testing.T) {
   139  	out := cli.DockerCmd(c, "run", "-d", "--label", "foo", "busybox").Combined()
   140  	id1 := strings.TrimSpace(out)
   141  	cli.WaitExited(c, id1, 5*time.Second)
   142  
   143  	out = cli.DockerCmd(c, "run", "-d", "--label", "bar", "busybox").Combined()
   144  	id2 := strings.TrimSpace(out)
   145  	cli.WaitExited(c, id2, 5*time.Second)
   146  
   147  	out = cli.DockerCmd(c, "run", "-d", "busybox").Combined()
   148  	id3 := strings.TrimSpace(out)
   149  	cli.WaitExited(c, id3, 5*time.Second)
   150  
   151  	out = cli.DockerCmd(c, "run", "-d", "--label", "foobar", "busybox").Combined()
   152  	id4 := strings.TrimSpace(out)
   153  	cli.WaitExited(c, id4, 5*time.Second)
   154  
   155  	// Add a config file of label=foobar, that will have no impact if cli is label!=foobar
   156  	config := `{"pruneFilters": ["label=foobar"]}`
   157  	d, err := os.MkdirTemp("", "integration-cli-")
   158  	assert.NilError(c, err)
   159  	defer os.RemoveAll(d)
   160  	err = os.WriteFile(filepath.Join(d, "config.json"), []byte(config), 0644)
   161  	assert.NilError(c, err)
   162  
   163  	// With config.json only, prune based on label=foobar
   164  	out = cli.DockerCmd(c, "--config", d, "container", "prune", "--force").Combined()
   165  	assert.Assert(c, !strings.Contains(strings.TrimSpace(out), id1))
   166  	assert.Assert(c, !strings.Contains(strings.TrimSpace(out), id2))
   167  	assert.Assert(c, !strings.Contains(strings.TrimSpace(out), id3))
   168  	assert.Assert(c, strings.Contains(strings.TrimSpace(out), id4))
   169  	out = cli.DockerCmd(c, "container", "prune", "--force", "--filter", "label=foo").Combined()
   170  	assert.Assert(c, strings.Contains(strings.TrimSpace(out), id1))
   171  	assert.Assert(c, !strings.Contains(strings.TrimSpace(out), id2))
   172  	assert.Assert(c, !strings.Contains(strings.TrimSpace(out), id3))
   173  	out = cli.DockerCmd(c, "ps", "-a", "-q", "--no-trunc").Combined()
   174  	assert.Assert(c, !strings.Contains(strings.TrimSpace(out), id1))
   175  	assert.Assert(c, strings.Contains(strings.TrimSpace(out), id2))
   176  	assert.Assert(c, strings.Contains(strings.TrimSpace(out), id3))
   177  	out = cli.DockerCmd(c, "container", "prune", "--force", "--filter", "label!=bar").Combined()
   178  	assert.Assert(c, !strings.Contains(strings.TrimSpace(out), id2))
   179  	assert.Assert(c, strings.Contains(strings.TrimSpace(out), id3))
   180  	out = cli.DockerCmd(c, "ps", "-a", "-q", "--no-trunc").Combined()
   181  	assert.Assert(c, strings.Contains(strings.TrimSpace(out), id2))
   182  	assert.Assert(c, !strings.Contains(strings.TrimSpace(out), id3))
   183  	// With config.json label=foobar and CLI label!=foobar, CLI label!=foobar supersede
   184  	out = cli.DockerCmd(c, "--config", d, "container", "prune", "--force", "--filter", "label!=foobar").Combined()
   185  	assert.Assert(c, strings.Contains(strings.TrimSpace(out), id2))
   186  	out = cli.DockerCmd(c, "ps", "-a", "-q", "--no-trunc").Combined()
   187  	assert.Assert(c, !strings.Contains(strings.TrimSpace(out), id2))
   188  }
   189  
   190  func (s *DockerCLIPruneSuite) TestPruneVolumeLabel(c *testing.T) {
   191  	out, _ := dockerCmd(c, "volume", "create", "--label", "foo")
   192  	id1 := strings.TrimSpace(out)
   193  	assert.Assert(c, id1 != "")
   194  
   195  	out, _ = dockerCmd(c, "volume", "create", "--label", "bar")
   196  	id2 := strings.TrimSpace(out)
   197  	assert.Assert(c, id2 != "")
   198  
   199  	out, _ = dockerCmd(c, "volume", "create")
   200  	id3 := strings.TrimSpace(out)
   201  	assert.Assert(c, id3 != "")
   202  
   203  	out, _ = dockerCmd(c, "volume", "create", "--label", "foobar")
   204  	id4 := strings.TrimSpace(out)
   205  	assert.Assert(c, id4 != "")
   206  
   207  	// Add a config file of label=foobar, that will have no impact if cli is label!=foobar
   208  	config := `{"pruneFilters": ["label=foobar"]}`
   209  	d, err := os.MkdirTemp("", "integration-cli-")
   210  	assert.NilError(c, err)
   211  	defer os.RemoveAll(d)
   212  	err = os.WriteFile(filepath.Join(d, "config.json"), []byte(config), 0644)
   213  	assert.NilError(c, err)
   214  
   215  	// With config.json only, prune based on label=foobar
   216  	out, _ = dockerCmd(c, "--config", d, "volume", "prune", "--force")
   217  	assert.Assert(c, !strings.Contains(strings.TrimSpace(out), id1))
   218  	assert.Assert(c, !strings.Contains(strings.TrimSpace(out), id2))
   219  	assert.Assert(c, !strings.Contains(strings.TrimSpace(out), id3))
   220  	assert.Assert(c, strings.Contains(strings.TrimSpace(out), id4))
   221  	out, _ = dockerCmd(c, "volume", "prune", "--force", "--filter", "label=foo")
   222  	assert.Assert(c, strings.Contains(strings.TrimSpace(out), id1))
   223  	assert.Assert(c, !strings.Contains(strings.TrimSpace(out), id2))
   224  	assert.Assert(c, !strings.Contains(strings.TrimSpace(out), id3))
   225  	out, _ = dockerCmd(c, "volume", "ls", "--format", "{{.Name}}")
   226  	assert.Assert(c, !strings.Contains(strings.TrimSpace(out), id1))
   227  	assert.Assert(c, strings.Contains(strings.TrimSpace(out), id2))
   228  	assert.Assert(c, strings.Contains(strings.TrimSpace(out), id3))
   229  	out, _ = dockerCmd(c, "volume", "prune", "--force", "--filter", "label!=bar")
   230  	assert.Assert(c, !strings.Contains(strings.TrimSpace(out), id2))
   231  	assert.Assert(c, strings.Contains(strings.TrimSpace(out), id3))
   232  	out, _ = dockerCmd(c, "volume", "ls", "--format", "{{.Name}}")
   233  	assert.Assert(c, strings.Contains(strings.TrimSpace(out), id2))
   234  	assert.Assert(c, !strings.Contains(strings.TrimSpace(out), id3))
   235  	// With config.json label=foobar and CLI label!=foobar, CLI label!=foobar supersede
   236  	out, _ = dockerCmd(c, "--config", d, "volume", "prune", "--force", "--filter", "label!=foobar")
   237  	assert.Assert(c, strings.Contains(strings.TrimSpace(out), id2))
   238  	out, _ = dockerCmd(c, "volume", "ls", "--format", "{{.Name}}")
   239  	assert.Assert(c, !strings.Contains(strings.TrimSpace(out), id2))
   240  }
   241  
   242  func (s *DockerCLIPruneSuite) TestPruneNetworkLabel(c *testing.T) {
   243  	dockerCmd(c, "network", "create", "--label", "foo", "n1")
   244  	dockerCmd(c, "network", "create", "--label", "bar", "n2")
   245  	dockerCmd(c, "network", "create", "n3")
   246  
   247  	out, _ := dockerCmd(c, "network", "prune", "--force", "--filter", "label=foo")
   248  	assert.Assert(c, strings.Contains(strings.TrimSpace(out), "n1"))
   249  	assert.Assert(c, !strings.Contains(strings.TrimSpace(out), "n2"))
   250  	assert.Assert(c, !strings.Contains(strings.TrimSpace(out), "n3"))
   251  	out, _ = dockerCmd(c, "network", "prune", "--force", "--filter", "label!=bar")
   252  	assert.Assert(c, !strings.Contains(strings.TrimSpace(out), "n1"))
   253  	assert.Assert(c, !strings.Contains(strings.TrimSpace(out), "n2"))
   254  	assert.Assert(c, strings.Contains(strings.TrimSpace(out), "n3"))
   255  	out, _ = dockerCmd(c, "network", "prune", "--force")
   256  	assert.Assert(c, !strings.Contains(strings.TrimSpace(out), "n1"))
   257  	assert.Assert(c, strings.Contains(strings.TrimSpace(out), "n2"))
   258  	assert.Assert(c, !strings.Contains(strings.TrimSpace(out), "n3"))
   259  }
   260  
   261  func (s *DockerDaemonSuite) TestPruneImageLabel(c *testing.T) {
   262  	s.d.StartWithBusybox(c)
   263  
   264  	result := cli.BuildCmd(c, "test1", cli.Daemon(s.d),
   265  		build.WithDockerfile(`FROM busybox
   266                   LABEL foo=bar`),
   267  		cli.WithFlags("-q"),
   268  	)
   269  	result.Assert(c, icmd.Success)
   270  	id1 := strings.TrimSpace(result.Combined())
   271  	out, err := s.d.Cmd("images", "-q", "--no-trunc")
   272  	assert.NilError(c, err)
   273  	assert.Assert(c, strings.Contains(strings.TrimSpace(out), id1))
   274  	result = cli.BuildCmd(c, "test2", cli.Daemon(s.d),
   275  		build.WithDockerfile(`FROM busybox
   276                   LABEL bar=foo`),
   277  		cli.WithFlags("-q"),
   278  	)
   279  	result.Assert(c, icmd.Success)
   280  	id2 := strings.TrimSpace(result.Combined())
   281  	out, err = s.d.Cmd("images", "-q", "--no-trunc")
   282  	assert.NilError(c, err)
   283  	assert.Assert(c, strings.Contains(strings.TrimSpace(out), id2))
   284  	out, err = s.d.Cmd("image", "prune", "--force", "--all", "--filter", "label=foo=bar")
   285  	assert.NilError(c, err)
   286  	assert.Assert(c, strings.Contains(strings.TrimSpace(out), id1))
   287  	assert.Assert(c, !strings.Contains(strings.TrimSpace(out), id2))
   288  	out, err = s.d.Cmd("image", "prune", "--force", "--all", "--filter", "label!=bar=foo")
   289  	assert.NilError(c, err)
   290  	assert.Assert(c, !strings.Contains(strings.TrimSpace(out), id1))
   291  	assert.Assert(c, !strings.Contains(strings.TrimSpace(out), id2))
   292  	out, err = s.d.Cmd("image", "prune", "--force", "--all", "--filter", "label=bar=foo")
   293  	assert.NilError(c, err)
   294  	assert.Assert(c, !strings.Contains(strings.TrimSpace(out), id1))
   295  	assert.Assert(c, strings.Contains(strings.TrimSpace(out), id2))
   296  }