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