From 51dce409149f7137ba20113eaee732324c81dd17 Mon Sep 17 00:00:00 2001 From: Ivan Ilves Date: Sun, 29 Apr 2018 10:47:08 +0200 Subject: [PATCH] IMPROVE: Tolerate errors on `Pull` and `Push` actions As stated in https://github.com/ivanilves/lstags/issues/146 we need to try harder while pulling or pushing Docker images. --- api/v1/v1.go | 4 ++-- main.go | 6 +++++- util/wait/wait.go | 28 ++++++++++++++++++++++++++++ 3 files changed, 35 insertions(+), 3 deletions(-) diff --git a/api/v1/v1.go b/api/v1/v1.go index bb0408a..d399303 100644 --- a/api/v1/v1.go +++ b/api/v1/v1.go @@ -300,7 +300,7 @@ func (api *API) PullTags(cn *collection.Collection) error { }(repo, tags, done) } - return wait.Until(done) + return wait.WithTolerance(done) } // PushTags compares images from remote and "push" (usually local) registries, @@ -357,7 +357,7 @@ func (api *API) PushTags(cn *collection.Collection, push PushConfig) error { }(repo, tags, done) } - return wait.Until(done) + return wait.WithTolerance(done) } func logDebugData(data io.Reader) { diff --git a/main.go b/main.go index 78db5bf..8c0a0d5 100644 --- a/main.go +++ b/main.go @@ -36,6 +36,8 @@ type Options struct { } `positional-args:"yes" required:"yes"` } +var exitCode = 0 + var doNotFail = false func suicide(err error, critical bool) { @@ -44,6 +46,8 @@ func suicide(err error, critical bool) { if !doNotFail || critical { os.Exit(1) } + + exitCode = 254 // not typical error code, for "git grep" friendliness } func parseFlags() (*Options, error) { @@ -169,7 +173,7 @@ func main() { } if !o.DaemonMode { - os.Exit(0) + os.Exit(exitCode) } fmt.Printf("WAIT: %v\n-\n", o.PollingInterval) diff --git a/util/wait/wait.go b/util/wait/wait.go index 6366827..09889e7 100644 --- a/util/wait/wait.go +++ b/util/wait/wait.go @@ -1,5 +1,7 @@ package wait +import "fmt" + // Until iterates over buffered error channel and: // * upon receiving non-nil value from the channel, makes an early return with this value // * if no non-nil values were received from iteration over the channel, it just returns nil @@ -21,3 +23,29 @@ func Until(done chan error) error { return nil } + +// WithTolerance is the same as Until, but it does not return immediately on errors +// rather loops through all channel capacity returning "composite" error in the end. +func WithTolerance(done chan error) error { + var errMessage string + + i := 0 + + for err := range done { + if err != nil { + errMessage = errMessage + err.Error() + "\n" + } + + i++ + + if i >= cap(done) { + close(done) + } + } + + if len(errMessage) == 0 { + return nil + } + + return fmt.Errorf(errMessage) +}