diff --git a/cmd/backup/exec.go b/cmd/backup/exec.go index 00f1c05..9499396 100644 --- a/cmd/backup/exec.go +++ b/cmd/backup/exec.go @@ -13,12 +13,12 @@ import ( "io/ioutil" "os" "strings" - "sync" "github.com/cosiner/argv" "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/filters" "github.com/docker/docker/pkg/stdcopy" + "golang.org/x/sync/errgroup" ) func (s *script) exec(containerRef string, command string) ([]byte, []byte, error) { @@ -97,29 +97,27 @@ func (s *script) runLabeledCommands(label string) error { return nil } - wg := sync.WaitGroup{} - wg.Add(len(containersWithCommand)) + g := new(errgroup.Group) - var cmdErrors []error for _, container := range containersWithCommand { - go func(c types.Container) { + c := container + g.Go(func() error { cmd, _ := c.Labels[label] s.logger.Infof("Running %s command %s for container %s", label, cmd, strings.TrimPrefix(c.Names[0], "/")) stdout, stderr, err := s.exec(c.ID, cmd) - if err != nil { - cmdErrors = append(cmdErrors, err) - } if s.c.ExecForwardOutput { os.Stderr.Write(stderr) os.Stdout.Write(stdout) } - wg.Done() - }(container) + if err != nil { + return fmt.Errorf("runLabeledCommands: error executing command: %w", err) + } + return nil + }) } - wg.Wait() - if len(cmdErrors) != 0 { - return join(cmdErrors...) + if err := g.Wait(); err != nil { + return fmt.Errorf("runLabeledCommands: error from errgroup: %w", err) } return nil } diff --git a/go.mod b/go.mod index 99683b5..bcc4891 100644 --- a/go.mod +++ b/go.mod @@ -47,6 +47,7 @@ require ( github.com/pkg/errors v0.9.1 // indirect github.com/rs/xid v1.3.0 // indirect golang.org/x/net v0.0.0-20210226172049-e18ecbb05110 // indirect + golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1 // indirect golang.org/x/text v0.3.6 // indirect golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect diff --git a/go.sum b/go.sum index 1b7ec47..04d34ec 100644 --- a/go.sum +++ b/go.sum @@ -806,6 +806,8 @@ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=