From f26a87acceafb205bac872cd502aa9dc633bdfe9 Mon Sep 17 00:00:00 2001 From: Lauris BH Date: Tue, 31 Jan 2023 22:33:40 +0200 Subject: [PATCH] Deduplicate step docker container volumes (#1571) Try to fix #1495 It's very hard to reproduce it and only way to fix when it gets in this state is woodpecker agent restart. This anyway fixes problem if step mounts and `WOODPECKER_BACKEND_DOCKER_VOLUMES` conflict --- pipeline/backend/docker/docker.go | 8 ++++---- shared/utils/strings.go | 24 ++++++++++++++---------- 2 files changed, 18 insertions(+), 14 deletions(-) diff --git a/pipeline/backend/docker/docker.go b/pipeline/backend/docker/docker.go index 4283d4bec..a671ad07d 100644 --- a/pipeline/backend/docker/docker.go +++ b/pipeline/backend/docker/docker.go @@ -31,6 +31,7 @@ import ( "github.com/rs/zerolog/log" backend "github.com/woodpecker-ci/woodpecker/pipeline/backend/types" + "github.com/woodpecker-ci/woodpecker/shared/utils" ) type docker struct { @@ -133,12 +134,11 @@ func (e *docker) Exec(ctx context.Context, step *backend.Step) error { if step.Pull { responseBody, perr := e.client.ImagePull(ctx, config.Image, pullopts) if perr == nil { - defer responseBody.Close() - fd, isTerminal := term.GetFdInfo(os.Stdout) if err := jsonmessage.DisplayJSONMessagesStream(responseBody, os.Stdout, fd, isTerminal, nil); err != nil { log.Error().Err(err).Msg("DisplayJSONMessagesStream") } + responseBody.Close() } // Fix "Show warning when fail to auth to docker registry" // (https://web.archive.org/web/20201023145804/https://github.com/drone/drone/issues/1917) @@ -148,7 +148,7 @@ func (e *docker) Exec(ctx context.Context, step *backend.Step) error { } // add default volumes to the host configuration - hostConfig.Binds = append(hostConfig.Binds, e.volumes...) + hostConfig.Binds = utils.DedupStrings(append(hostConfig.Binds, e.volumes...)) _, err := e.client.ContainerCreate(ctx, config, hostConfig, nil, nil, step.Name) if client.IsErrNotFound(err) { @@ -158,11 +158,11 @@ func (e *docker) Exec(ctx context.Context, step *backend.Step) error { if perr != nil { return perr } - defer responseBody.Close() fd, isTerminal := term.GetFdInfo(os.Stdout) if err := jsonmessage.DisplayJSONMessagesStream(responseBody, os.Stdout, fd, isTerminal, nil); err != nil { log.Error().Err(err).Msg("DisplayJSONMessagesStream") } + responseBody.Close() _, err = e.client.ContainerCreate(ctx, config, hostConfig, nil, nil, step.Name) } diff --git a/shared/utils/strings.go b/shared/utils/strings.go index f9ebe1f68..4534e6d60 100644 --- a/shared/utils/strings.go +++ b/shared/utils/strings.go @@ -15,20 +15,24 @@ package utils // DedupStrings deduplicate string list, empty items are dropped -func DedupStrings(list []string) []string { - m := make(map[string]struct{}, len(list)) +func DedupStrings(src []string) []string { + m := make(map[string]struct{}, len(src)) + dst := make([]string, 0, len(src)) - for i := range list { - if s := list[i]; len(s) > 0 { - m[list[i]] = struct{}{} + for _, v := range src { + // Skip empty items + if len(v) == 0 { + continue } + // Skip duplicates + if _, ok := m[v]; ok { + continue + } + m[v] = struct{}{} + dst = append(dst, v) } - newList := make([]string, 0, len(m)) - for k := range m { - newList = append(newList, k) - } - return newList + return dst } // EqualStringSlice compare two string slices if they have equal values independent of how they are sorted