2019-08-29 16:52:40 -04:00
|
|
|
package environment
|
2017-08-25 18:48:36 -04:00
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
2019-09-23 08:23:01 -04:00
|
|
|
"testing"
|
2017-08-25 18:48:36 -04:00
|
|
|
|
|
|
|
"github.com/docker/docker/api/types"
|
|
|
|
"github.com/docker/docker/api/types/filters"
|
2019-11-01 11:11:35 -04:00
|
|
|
"github.com/docker/docker/api/types/volume"
|
2022-07-08 18:54:36 -04:00
|
|
|
"github.com/docker/docker/errdefs"
|
2020-02-07 08:39:24 -05:00
|
|
|
"gotest.tools/v3/assert"
|
2017-08-25 18:48:36 -04:00
|
|
|
)
|
|
|
|
|
2021-08-19 17:40:38 -04:00
|
|
|
var frozenImages = []string{"busybox:latest", "busybox:glibc", "hello-world:frozen", "debian:bullseye-slim"}
|
2017-10-18 17:59:16 -04:00
|
|
|
|
2017-08-25 18:48:36 -04:00
|
|
|
type protectedElements struct {
|
2017-09-08 10:41:02 -04:00
|
|
|
containers map[string]struct{}
|
|
|
|
images map[string]struct{}
|
|
|
|
networks map[string]struct{}
|
|
|
|
plugins map[string]struct{}
|
|
|
|
volumes map[string]struct{}
|
|
|
|
}
|
|
|
|
|
|
|
|
func newProtectedElements() protectedElements {
|
|
|
|
return protectedElements{
|
|
|
|
containers: map[string]struct{}{},
|
|
|
|
images: map[string]struct{}{},
|
|
|
|
networks: map[string]struct{}{},
|
|
|
|
plugins: map[string]struct{}{},
|
|
|
|
volumes: map[string]struct{}{},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// ProtectAll protects the existing environment (containers, images, networks,
|
|
|
|
// volumes, and, on Linux, plugins) from being cleaned up at the end of test
|
|
|
|
// runs
|
2019-09-23 08:23:01 -04:00
|
|
|
func ProtectAll(t testing.TB, testEnv *Execution) {
|
|
|
|
t.Helper()
|
2017-09-08 10:41:02 -04:00
|
|
|
ProtectContainers(t, testEnv)
|
|
|
|
ProtectImages(t, testEnv)
|
|
|
|
ProtectNetworks(t, testEnv)
|
|
|
|
ProtectVolumes(t, testEnv)
|
2017-09-20 08:47:49 -04:00
|
|
|
if testEnv.OSType == "linux" {
|
2017-09-08 10:41:02 -04:00
|
|
|
ProtectPlugins(t, testEnv)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// ProtectContainer adds the specified container(s) to be protected in case of
|
|
|
|
// clean
|
2019-09-23 08:23:01 -04:00
|
|
|
func (e *Execution) ProtectContainer(t testing.TB, containers ...string) {
|
|
|
|
t.Helper()
|
2017-09-08 10:41:02 -04:00
|
|
|
for _, container := range containers {
|
|
|
|
e.protectedElements.containers[container] = struct{}{}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// ProtectContainers protects existing containers from being cleaned up at the
|
|
|
|
// end of test runs
|
2019-09-23 08:23:01 -04:00
|
|
|
func ProtectContainers(t testing.TB, testEnv *Execution) {
|
|
|
|
t.Helper()
|
2017-09-08 10:41:02 -04:00
|
|
|
containers := getExistingContainers(t, testEnv)
|
|
|
|
testEnv.ProtectContainer(t, containers...)
|
|
|
|
}
|
|
|
|
|
2019-09-23 08:23:01 -04:00
|
|
|
func getExistingContainers(t testing.TB, testEnv *Execution) []string {
|
|
|
|
t.Helper()
|
2017-09-08 10:41:02 -04:00
|
|
|
client := testEnv.APIClient()
|
|
|
|
containerList, err := client.ContainerList(context.Background(), types.ContainerListOptions{
|
|
|
|
All: true,
|
|
|
|
})
|
2018-03-13 15:28:34 -04:00
|
|
|
assert.NilError(t, err, "failed to list containers")
|
2017-09-08 10:41:02 -04:00
|
|
|
|
2018-05-19 07:38:54 -04:00
|
|
|
var containers []string
|
2017-09-08 10:41:02 -04:00
|
|
|
for _, container := range containerList {
|
|
|
|
containers = append(containers, container.ID)
|
|
|
|
}
|
|
|
|
return containers
|
2017-08-25 18:48:36 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
// ProtectImage adds the specified image(s) to be protected in case of clean
|
2019-09-23 08:23:01 -04:00
|
|
|
func (e *Execution) ProtectImage(t testing.TB, images ...string) {
|
|
|
|
t.Helper()
|
2017-08-25 18:48:36 -04:00
|
|
|
for _, image := range images {
|
|
|
|
e.protectedElements.images[image] = struct{}{}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// ProtectImages protects existing images and on linux frozen images from being
|
|
|
|
// cleaned up at the end of test runs
|
2019-09-23 08:23:01 -04:00
|
|
|
func ProtectImages(t testing.TB, testEnv *Execution) {
|
|
|
|
t.Helper()
|
2017-08-25 18:48:36 -04:00
|
|
|
images := getExistingImages(t, testEnv)
|
|
|
|
|
2017-09-20 08:47:49 -04:00
|
|
|
if testEnv.OSType == "linux" {
|
2017-10-18 17:59:16 -04:00
|
|
|
images = append(images, frozenImages...)
|
2017-08-25 18:48:36 -04:00
|
|
|
}
|
|
|
|
testEnv.ProtectImage(t, images...)
|
|
|
|
}
|
|
|
|
|
2019-09-23 08:23:01 -04:00
|
|
|
func getExistingImages(t testing.TB, testEnv *Execution) []string {
|
|
|
|
t.Helper()
|
2017-08-25 18:48:36 -04:00
|
|
|
client := testEnv.APIClient()
|
|
|
|
filter := filters.NewArgs()
|
|
|
|
filter.Add("dangling", "false")
|
|
|
|
imageList, err := client.ImageList(context.Background(), types.ImageListOptions{
|
2017-09-08 10:41:02 -04:00
|
|
|
All: true,
|
2017-08-25 18:48:36 -04:00
|
|
|
Filters: filter,
|
|
|
|
})
|
2018-03-13 15:28:34 -04:00
|
|
|
assert.NilError(t, err, "failed to list images")
|
2017-08-25 18:48:36 -04:00
|
|
|
|
2018-05-19 07:38:54 -04:00
|
|
|
var images []string
|
2017-08-25 18:48:36 -04:00
|
|
|
for _, image := range imageList {
|
|
|
|
images = append(images, tagsFromImageSummary(image)...)
|
|
|
|
}
|
|
|
|
return images
|
|
|
|
}
|
|
|
|
|
|
|
|
func tagsFromImageSummary(image types.ImageSummary) []string {
|
2018-05-19 07:38:54 -04:00
|
|
|
var result []string
|
2017-08-25 18:48:36 -04:00
|
|
|
for _, tag := range image.RepoTags {
|
|
|
|
if tag != "<none>:<none>" {
|
|
|
|
result = append(result, tag)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for _, digest := range image.RepoDigests {
|
|
|
|
if digest != "<none>@<none>" {
|
|
|
|
result = append(result, digest)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return result
|
|
|
|
}
|
|
|
|
|
2017-09-08 10:41:02 -04:00
|
|
|
// ProtectNetwork adds the specified network(s) to be protected in case of
|
|
|
|
// clean
|
2019-09-23 08:23:01 -04:00
|
|
|
func (e *Execution) ProtectNetwork(t testing.TB, networks ...string) {
|
|
|
|
t.Helper()
|
2017-09-08 10:41:02 -04:00
|
|
|
for _, network := range networks {
|
|
|
|
e.protectedElements.networks[network] = struct{}{}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// ProtectNetworks protects existing networks from being cleaned up at the end
|
|
|
|
// of test runs
|
2019-09-23 08:23:01 -04:00
|
|
|
func ProtectNetworks(t testing.TB, testEnv *Execution) {
|
|
|
|
t.Helper()
|
2017-09-08 10:41:02 -04:00
|
|
|
networks := getExistingNetworks(t, testEnv)
|
|
|
|
testEnv.ProtectNetwork(t, networks...)
|
|
|
|
}
|
|
|
|
|
2019-09-23 08:23:01 -04:00
|
|
|
func getExistingNetworks(t testing.TB, testEnv *Execution) []string {
|
|
|
|
t.Helper()
|
2017-09-08 10:41:02 -04:00
|
|
|
client := testEnv.APIClient()
|
|
|
|
networkList, err := client.NetworkList(context.Background(), types.NetworkListOptions{})
|
2018-03-13 15:28:34 -04:00
|
|
|
assert.NilError(t, err, "failed to list networks")
|
2017-09-08 10:41:02 -04:00
|
|
|
|
2018-05-19 07:38:54 -04:00
|
|
|
var networks []string
|
2017-09-08 10:41:02 -04:00
|
|
|
for _, network := range networkList {
|
|
|
|
networks = append(networks, network.ID)
|
|
|
|
}
|
|
|
|
return networks
|
|
|
|
}
|
|
|
|
|
|
|
|
// ProtectPlugin adds the specified plugin(s) to be protected in case of clean
|
2019-09-23 08:23:01 -04:00
|
|
|
func (e *Execution) ProtectPlugin(t testing.TB, plugins ...string) {
|
|
|
|
t.Helper()
|
2017-09-08 10:41:02 -04:00
|
|
|
for _, plugin := range plugins {
|
|
|
|
e.protectedElements.plugins[plugin] = struct{}{}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// ProtectPlugins protects existing plugins from being cleaned up at the end of
|
|
|
|
// test runs
|
2019-09-23 08:23:01 -04:00
|
|
|
func ProtectPlugins(t testing.TB, testEnv *Execution) {
|
|
|
|
t.Helper()
|
2017-09-08 10:41:02 -04:00
|
|
|
plugins := getExistingPlugins(t, testEnv)
|
|
|
|
testEnv.ProtectPlugin(t, plugins...)
|
|
|
|
}
|
|
|
|
|
2019-09-23 08:23:01 -04:00
|
|
|
func getExistingPlugins(t testing.TB, testEnv *Execution) []string {
|
|
|
|
t.Helper()
|
2017-09-08 10:41:02 -04:00
|
|
|
client := testEnv.APIClient()
|
|
|
|
pluginList, err := client.PluginList(context.Background(), filters.Args{})
|
2017-09-25 08:09:17 -04:00
|
|
|
// Docker EE does not allow cluster-wide plugin management.
|
2022-07-08 18:54:36 -04:00
|
|
|
if errdefs.IsNotImplemented(err) {
|
2017-09-25 08:09:17 -04:00
|
|
|
return []string{}
|
|
|
|
}
|
2018-03-13 15:28:34 -04:00
|
|
|
assert.NilError(t, err, "failed to list plugins")
|
2017-09-08 10:41:02 -04:00
|
|
|
|
2018-05-19 07:38:54 -04:00
|
|
|
var plugins []string
|
2017-09-08 10:41:02 -04:00
|
|
|
for _, plugin := range pluginList {
|
|
|
|
plugins = append(plugins, plugin.Name)
|
|
|
|
}
|
|
|
|
return plugins
|
|
|
|
}
|
|
|
|
|
|
|
|
// ProtectVolume adds the specified volume(s) to be protected in case of clean
|
2019-09-23 08:23:01 -04:00
|
|
|
func (e *Execution) ProtectVolume(t testing.TB, volumes ...string) {
|
|
|
|
t.Helper()
|
2019-11-01 11:11:35 -04:00
|
|
|
for _, vol := range volumes {
|
|
|
|
e.protectedElements.volumes[vol] = struct{}{}
|
2017-09-08 10:41:02 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// ProtectVolumes protects existing volumes from being cleaned up at the end of
|
|
|
|
// test runs
|
2019-09-23 08:23:01 -04:00
|
|
|
func ProtectVolumes(t testing.TB, testEnv *Execution) {
|
|
|
|
t.Helper()
|
2017-09-08 10:41:02 -04:00
|
|
|
volumes := getExistingVolumes(t, testEnv)
|
|
|
|
testEnv.ProtectVolume(t, volumes...)
|
|
|
|
}
|
|
|
|
|
2019-09-23 08:23:01 -04:00
|
|
|
func getExistingVolumes(t testing.TB, testEnv *Execution) []string {
|
|
|
|
t.Helper()
|
2017-09-08 10:41:02 -04:00
|
|
|
client := testEnv.APIClient()
|
2019-11-01 11:11:35 -04:00
|
|
|
volumeList, err := client.VolumeList(context.Background(), volume.ListOptions{})
|
2018-03-13 15:28:34 -04:00
|
|
|
assert.NilError(t, err, "failed to list volumes")
|
2017-09-08 10:41:02 -04:00
|
|
|
|
2018-05-19 07:38:54 -04:00
|
|
|
var volumes []string
|
2019-11-01 11:11:35 -04:00
|
|
|
for _, vol := range volumeList.Volumes {
|
|
|
|
volumes = append(volumes, vol.Name)
|
2017-09-08 10:41:02 -04:00
|
|
|
}
|
|
|
|
return volumes
|
|
|
|
}
|