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 }