Repository: containrrr/watchtower
Pull request #674 (2020-11-08 16:41:18)

add http head based digest comparison to avoid dockerhub rate limits
We currently experience a pretty urgent issue where each check by watchtower counts towards the DockerHub rate limit. What we've managed to understand so far after discussions with the docker OSS team and others:

- DockerHub does not count HEAD requests towards the rate limit
- Docker Engine was thought to do HEAD requests where possible. This, however, turned out to not be the case for various reasons outlined in https://github.com/moby/moby/pull/41607.
- Getting this fix out to the community will take time. My best bet is that even if it's released in 20.xx, it will take years until it reaches a significant portion of our users.
- The docker registry specification is fairly detailed in how registries should behave in terms of authentication, tokens, challenges, and what request headers do what.
- GHCR and DockerHub behave almost the same, which is a relief as they, together with quay, likely make up a significant part of all registry checks done by Watchtower.
- Depending on `skopeo` or any other repo in the `containers` org. is currently not an option. It has the same issue with fetching manifest list digests as docker engine, which would lead to digest mismatches for all multi-arch tags. As a multi-arch tag leads to at least 2 GET requests toward the rate limit, this in itself makes it a deal-breaker for us.
- I've not yet been able to verify whether HEAD requests bump the pull count. Hopefully, they don't, solving some other long-lingering issues (see #429, #201).
- To make sure we don't break anything for users on older/incompatible registries, we'll make sure to fallback to GET requests if a registry doesn't behave as expected.
- The Docker OSS team has kindly offered to work with us to see if there is anything to be done, in any end, to make the user experience smoother and less resource-consuming going forward. 

I'm fairly certain I've missed something, so we'll have to go through this again before releasing, but at least we're getting somewhere. 😅 

dudipsh: UP
@dudipsh
simskij: > UP
> @dudipsh

?
dudipsh: > > UP
> > @dudipsh
> 
> ?

I just wanted to follow the solution :)

Patch:
diff --git a/.gitignore b/.gitignore
index fda8d42..50b5c2d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -5,3 +5,4 @@ dist
 .idea
 .DS_Store
 /site
+coverage.out
diff --git a/coverage.out b/coverage.out
new file mode 100644
index 0000000..40470d1
--- /dev/null
+++ b/coverage.out
@@ -0,0 +1,620 @@
+mode: set
+github.com/containrrr/watchtower/internal/util/rand_name.go:8.24,10.19 2 0
+github.com/containrrr/watchtower/internal/util/rand_name.go:14.2,14.18 1 0
+github.com/containrrr/watchtower/internal/util/rand_name.go:10.19,12.3 1 0
+github.com/containrrr/watchtower/internal/util/util.go:4.39,5.24 1 1
+github.com/containrrr/watchtower/internal/util/util.go:9.2,9.20 1 1
+github.com/containrrr/watchtower/internal/util/util.go:15.2,15.13 1 1
+github.com/containrrr/watchtower/internal/util/util.go:5.24,7.3 1 1
+github.com/containrrr/watchtower/internal/util/util.go:9.20,10.21 1 1
+github.com/containrrr/watchtower/internal/util/util.go:10.21,12.4 1 1
+github.com/containrrr/watchtower/internal/util/util.go:19.46,22.24 2 1
+github.com/containrrr/watchtower/internal/util/util.go:37.2,37.10 1 1
+github.com/containrrr/watchtower/internal/util/util.go:22.24,25.25 2 1
+github.com/containrrr/watchtower/internal/util/util.go:32.3,32.13 1 1
+github.com/containrrr/watchtower/internal/util/util.go:25.25,26.16 1 1
+github.com/containrrr/watchtower/internal/util/util.go:26.16,28.10 2 1
+github.com/containrrr/watchtower/internal/util/util.go:32.13,34.4 1 1
+github.com/containrrr/watchtower/internal/util/util.go:41.68,44.25 2 1
+github.com/containrrr/watchtower/internal/util/util.go:54.2,54.10 1 1
+github.com/containrrr/watchtower/internal/util/util.go:44.25,45.27 1 1
+github.com/containrrr/watchtower/internal/util/util.go:45.27,46.16 1 1
+github.com/containrrr/watchtower/internal/util/util.go:46.16,48.5 1 1
+github.com/containrrr/watchtower/internal/util/util.go:49.9,51.4 1 1
+github.com/containrrr/watchtower/internal/util/util.go:58.72,61.25 2 1
+github.com/containrrr/watchtower/internal/util/util.go:67.2,67.10 1 1
+github.com/containrrr/watchtower/internal/util/util.go:61.25,62.27 1 1
+github.com/containrrr/watchtower/internal/util/util.go:62.27,64.4 1 1
+github.com/containrrr/watchtower/pkg/filters/filters.go:6.63,6.90 1 1
+github.com/containrrr/watchtower/pkg/filters/filters.go:9.43,9.58 1 1
+github.com/containrrr/watchtower/pkg/filters/filters.go:12.66,13.21 1 1
+github.com/containrrr/watchtower/pkg/filters/filters.go:17.2,17.44 1 1
+github.com/containrrr/watchtower/pkg/filters/filters.go:13.21,15.3 1 1
+github.com/containrrr/watchtower/pkg/filters/filters.go:17.44,18.30 1 1
+github.com/containrrr/watchtower/pkg/filters/filters.go:23.3,23.15 1 1
+github.com/containrrr/watchtower/pkg/filters/filters.go:18.30,19.52 1 1
+github.com/containrrr/watchtower/pkg/filters/filters.go:19.52,21.5 1 1
+github.com/containrrr/watchtower/pkg/filters/filters.go:28.56,29.44 1 1
+github.com/containrrr/watchtower/pkg/filters/filters.go:29.44,33.10 2 1
+github.com/containrrr/watchtower/pkg/filters/filters.go:37.3,37.23 1 1
+github.com/containrrr/watchtower/pkg/filters/filters.go:33.10,35.4 1 1
+github.com/containrrr/watchtower/pkg/filters/filters.go:42.58,43.44 1 1
+github.com/containrrr/watchtower/pkg/filters/filters.go:43.44,45.26 2 1
+github.com/containrrr/watchtower/pkg/filters/filters.go:50.3,50.23 1 1
+github.com/containrrr/watchtower/pkg/filters/filters.go:45.26,48.4 1 1
+github.com/containrrr/watchtower/pkg/filters/filters.go:55.64,56.17 1 1
+github.com/containrrr/watchtower/pkg/filters/filters.go:60.2,60.44 1 1
+github.com/containrrr/watchtower/pkg/filters/filters.go:56.17,58.3 1 0
+github.com/containrrr/watchtower/pkg/filters/filters.go:60.44,62.36 2 1
+github.com/containrrr/watchtower/pkg/filters/filters.go:66.3,66.15 1 1
+github.com/containrrr/watchtower/pkg/filters/filters.go:62.36,64.4 1 1
+github.com/containrrr/watchtower/pkg/filters/filters.go:71.75,74.17 3 1
+github.com/containrrr/watchtower/pkg/filters/filters.go:79.2,79.17 1 1
+github.com/containrrr/watchtower/pkg/filters/filters.go:84.2,85.15 2 1
+github.com/containrrr/watchtower/pkg/filters/filters.go:74.17,78.3 1 1
+github.com/containrrr/watchtower/pkg/filters/filters.go:79.17,83.3 1 0
+github.com/containrrr/watchtower/internal/flags/flags.go:20.50,25.2 4 1
+github.com/containrrr/watchtower/internal/flags/flags.go:28.50,154.2 22 0
+github.com/containrrr/watchtower/internal/flags/flags.go:157.56,299.2 24 1
+github.com/containrrr/watchtower/internal/flags/flags.go:302.20,313.2 10 1
+github.com/containrrr/watchtower/internal/flags/flags.go:317.42,325.53 6 1
+github.com/containrrr/watchtower/internal/flags/flags.go:328.2,328.55 1 1
+github.com/containrrr/watchtower/internal/flags/flags.go:331.2,331.63 1 1
+github.com/containrrr/watchtower/internal/flags/flags.go:334.2,334.57 1 1
+github.com/containrrr/watchtower/internal/flags/flags.go:337.2,337.63 1 1
+github.com/containrrr/watchtower/internal/flags/flags.go:340.2,340.67 1 1
+github.com/containrrr/watchtower/internal/flags/flags.go:343.2,343.12 1 1
+github.com/containrrr/watchtower/internal/flags/flags.go:325.53,327.3 1 0
+github.com/containrrr/watchtower/internal/flags/flags.go:328.55,330.3 1 0
+github.com/containrrr/watchtower/internal/flags/flags.go:331.63,333.3 1 0
+github.com/containrrr/watchtower/internal/flags/flags.go:334.57,336.3 1 0
+github.com/containrrr/watchtower/internal/flags/flags.go:337.63,339.3 1 0
+github.com/containrrr/watchtower/internal/flags/flags.go:340.67,342.3 1 0
+github.com/containrrr/watchtower/internal/flags/flags.go:347.70,356.57 7 0
+github.com/containrrr/watchtower/internal/flags/flags.go:359.2,359.62 1 0
+github.com/containrrr/watchtower/internal/flags/flags.go:362.2,362.66 1 0
+github.com/containrrr/watchtower/internal/flags/flags.go:365.2,365.66 1 0
+github.com/containrrr/watchtower/internal/flags/flags.go:369.2,369.49 1 0
+github.com/containrrr/watchtower/internal/flags/flags.go:356.57,358.3 1 0
+github.com/containrrr/watchtower/internal/flags/flags.go:359.62,361.3 1 0
+github.com/containrrr/watchtower/internal/flags/flags.go:362.66,364.3 1 0
+github.com/containrrr/watchtower/internal/flags/flags.go:365.66,367.3 1 0
+github.com/containrrr/watchtower/internal/flags/flags.go:372.49,373.40 1 1
+github.com/containrrr/watchtower/internal/flags/flags.go:376.2,377.16 2 1
+github.com/containrrr/watchtower/internal/flags/flags.go:380.2,380.12 1 1
+github.com/containrrr/watchtower/internal/flags/flags.go:373.40,375.3 1 0
+github.com/containrrr/watchtower/internal/flags/flags.go:377.16,379.3 1 0
+github.com/containrrr/watchtower/internal/flags/flags.go:383.48,384.9 1 1
+github.com/containrrr/watchtower/internal/flags/flags.go:387.2,387.12 1 1
+github.com/containrrr/watchtower/internal/flags/flags.go:384.9,386.3 1 1
+github.com/containrrr/watchtower/internal/flags/flags.go:392.50,401.33 3 1
+github.com/containrrr/watchtower/internal/flags/flags.go:401.33,403.3 1 1
+github.com/containrrr/watchtower/internal/flags/flags.go:407.61,409.16 2 1
+github.com/containrrr/watchtower/internal/flags/flags.go:412.2,412.34 1 1
+github.com/containrrr/watchtower/internal/flags/flags.go:409.16,411.3 1 0
+github.com/containrrr/watchtower/internal/flags/flags.go:412.34,414.17 2 1
+github.com/containrrr/watchtower/internal/flags/flags.go:417.3,418.17 2 1
+github.com/containrrr/watchtower/internal/flags/flags.go:414.17,416.4 1 0
+github.com/containrrr/watchtower/internal/flags/flags.go:418.17,420.4 1 0
+github.com/containrrr/watchtower/internal/flags/flags.go:424.28,426.24 2 1
+github.com/containrrr/watchtower/internal/flags/flags.go:429.2,429.13 1 1
+github.com/containrrr/watchtower/internal/flags/flags.go:426.24,428.3 1 1
+github.com/containrrr/watchtower/pkg/registry/helpers/helpers.go:9.60,12.16 3 1
+github.com/containrrr/watchtower/pkg/registry/helpers/helpers.go:15.2,19.28 4 1
+github.com/containrrr/watchtower/pkg/registry/helpers/helpers.go:12.16,14.3 1 0
+github.com/containrrr/watchtower/pkg/registry/helpers/helpers.go:23.57,25.16 2 1
+github.com/containrrr/watchtower/pkg/registry/helpers/helpers.go:29.2,29.67 1 1
+github.com/containrrr/watchtower/pkg/registry/helpers/helpers.go:33.2,33.16 1 1
+github.com/containrrr/watchtower/pkg/registry/helpers/helpers.go:36.2,36.22 1 1
+github.com/containrrr/watchtower/pkg/registry/helpers/helpers.go:25.16,27.3 1 0
+github.com/containrrr/watchtower/pkg/registry/helpers/helpers.go:29.67,31.3 1 1
+github.com/containrrr/watchtower/pkg/registry/helpers/helpers.go:33.16,35.3 1 0
+github.com/containrrr/watchtower/pkg/notifications/notifier.go:16.46,23.16 5 0
+github.com/containrrr/watchtower/pkg/notifications/notifier.go:27.2,31.16 3 0
+github.com/containrrr/watchtower/pkg/notifications/notifier.go:34.2,34.26 1 0
+github.com/containrrr/watchtower/pkg/notifications/notifier.go:53.2,53.10 1 0
+github.com/containrrr/watchtower/pkg/notifications/notifier.go:23.16,25.3 1 0
+github.com/containrrr/watchtower/pkg/notifications/notifier.go:31.16,33.3 1 0
+github.com/containrrr/watchtower/pkg/notifications/notifier.go:34.26,36.12 2 0
+github.com/containrrr/watchtower/pkg/notifications/notifier.go:50.3,50.32 1 0
+github.com/containrrr/watchtower/pkg/notifications/notifier.go:37.18,38.47 1 0
+github.com/containrrr/watchtower/pkg/notifications/notifier.go:39.18,40.47 1 0
+github.com/containrrr/watchtower/pkg/notifications/notifier.go:41.20,42.49 1 0
+github.com/containrrr/watchtower/pkg/notifications/notifier.go:43.19,44.48 1 0
+github.com/containrrr/watchtower/pkg/notifications/notifier.go:45.21,46.50 1 0
+github.com/containrrr/watchtower/pkg/notifications/notifier.go:47.11,48.49 1 0
+github.com/containrrr/watchtower/pkg/notifications/notifier.go:57.40,58.28 1 0
+github.com/containrrr/watchtower/pkg/notifications/notifier.go:58.28,60.3 1 0
+github.com/containrrr/watchtower/pkg/notifications/notifier.go:64.39,65.28 1 0
+github.com/containrrr/watchtower/pkg/notifications/notifier.go:65.28,67.3 1 0
+github.com/containrrr/watchtower/pkg/notifications/notifier.go:71.28,72.28 1 0
+github.com/containrrr/watchtower/pkg/notifications/notifier.go:72.28,74.3 1 0
+github.com/containrrr/watchtower/pkg/notifications/shoutrrr.go:36.86,41.16 4 0
+github.com/containrrr/watchtower/pkg/notifications/shoutrrr.go:45.2,59.10 4 0
+github.com/containrrr/watchtower/pkg/notifications/shoutrrr.go:41.16,43.3 1 0
+github.com/containrrr/watchtower/pkg/notifications/shoutrrr.go:62.49,63.30 1 1
+github.com/containrrr/watchtower/pkg/notifications/shoutrrr.go:74.2,74.16 1 1
+github.com/containrrr/watchtower/pkg/notifications/shoutrrr.go:63.30,66.28 2 1
+github.com/containrrr/watchtower/pkg/notifications/shoutrrr.go:66.28,67.18 1 0
+github.com/containrrr/watchtower/pkg/notifications/shoutrrr.go:67.18,70.5 1 0
+github.com/containrrr/watchtower/pkg/notifications/shoutrrr.go:77.74,79.59 2 1
+github.com/containrrr/watchtower/pkg/notifications/shoutrrr.go:83.2,83.22 1 1
+github.com/containrrr/watchtower/pkg/notifications/shoutrrr.go:79.59,81.3 1 0
+github.com/containrrr/watchtower/pkg/notifications/shoutrrr.go:86.66,89.2 2 1
+github.com/containrrr/watchtower/pkg/notifications/shoutrrr.go:91.52,92.22 1 1
+github.com/containrrr/watchtower/pkg/notifications/shoutrrr.go:92.22,94.3 1 1
+github.com/containrrr/watchtower/pkg/notifications/shoutrrr.go:97.51,98.45 1 1
+github.com/containrrr/watchtower/pkg/notifications/shoutrrr.go:102.2,103.17 2 1
+github.com/containrrr/watchtower/pkg/notifications/shoutrrr.go:98.45,100.3 1 0
+github.com/containrrr/watchtower/pkg/notifications/shoutrrr.go:106.40,113.2 3 1
+github.com/containrrr/watchtower/pkg/notifications/shoutrrr.go:115.53,117.2 1 0
+github.com/containrrr/watchtower/pkg/notifications/shoutrrr.go:119.61,120.22 1 1
+github.com/containrrr/watchtower/pkg/notifications/shoutrrr.go:126.2,126.12 1 1
+github.com/containrrr/watchtower/pkg/notifications/shoutrrr.go:120.22,122.3 1 1
+github.com/containrrr/watchtower/pkg/notifications/shoutrrr.go:122.8,125.3 1 0
+github.com/containrrr/watchtower/pkg/notifications/shoutrrr.go:129.63,144.35 5 1
+github.com/containrrr/watchtower/pkg/notifications/shoutrrr.go:152.2,152.16 1 1
+github.com/containrrr/watchtower/pkg/notifications/shoutrrr.go:160.2,160.35 1 1
+github.com/containrrr/watchtower/pkg/notifications/shoutrrr.go:164.2,164.12 1 1
+github.com/containrrr/watchtower/pkg/notifications/shoutrrr.go:144.35,146.3 1 1
+github.com/containrrr/watchtower/pkg/notifications/shoutrrr.go:152.16,154.3 1 1
+github.com/containrrr/watchtower/pkg/notifications/shoutrrr.go:160.35,162.3 1 1
+github.com/containrrr/watchtower/pkg/notifications/slack.go:18.83,40.2 9 0
+github.com/containrrr/watchtower/pkg/notifications/slack.go:42.50,42.51 0 0
+github.com/containrrr/watchtower/pkg/notifications/slack.go:44.49,44.50 0 0
+github.com/containrrr/watchtower/pkg/notifications/slack.go:46.38,46.39 0 0
+github.com/containrrr/watchtower/pkg/notifications/smtp.go:33.110,35.16 2 0
+github.com/containrrr/watchtower/pkg/notifications/smtp.go:38.2,39.44 2 0
+github.com/containrrr/watchtower/pkg/notifications/smtp.go:42.2,42.42 1 0
+github.com/containrrr/watchtower/pkg/notifications/smtp.go:49.2,49.14 1 0
+github.com/containrrr/watchtower/pkg/notifications/smtp.go:56.2,56.36 1 0
+github.com/containrrr/watchtower/pkg/notifications/smtp.go:59.2,59.26 1 0
+github.com/containrrr/watchtower/pkg/notifications/smtp.go:64.2,65.16 2 0
+github.com/containrrr/watchtower/pkg/notifications/smtp.go:68.2,69.16 2 0
+github.com/containrrr/watchtower/pkg/notifications/smtp.go:72.2,73.16 2 0
+github.com/containrrr/watchtower/pkg/notifications/smtp.go:76.2,76.17 1 0
+github.com/containrrr/watchtower/pkg/notifications/smtp.go:35.16,37.3 1 0
+github.com/containrrr/watchtower/pkg/notifications/smtp.go:39.44,41.3 1 0
+github.com/containrrr/watchtower/pkg/notifications/smtp.go:42.42,45.43 3 0
+github.com/containrrr/watchtower/pkg/notifications/smtp.go:45.43,47.4 1 0
+github.com/containrrr/watchtower/pkg/notifications/smtp.go:49.14,50.39 1 0
+github.com/containrrr/watchtower/pkg/notifications/smtp.go:50.39,51.35 1 0
+github.com/containrrr/watchtower/pkg/notifications/smtp.go:51.35,53.5 1 0
+github.com/containrrr/watchtower/pkg/notifications/smtp.go:56.36,58.3 1 0
+github.com/containrrr/watchtower/pkg/notifications/smtp.go:59.26,60.37 1 0
+github.com/containrrr/watchtower/pkg/notifications/smtp.go:60.37,62.4 1 0
+github.com/containrrr/watchtower/pkg/notifications/smtp.go:65.16,67.3 1 0
+github.com/containrrr/watchtower/pkg/notifications/smtp.go:69.16,71.3 1 0
+github.com/containrrr/watchtower/pkg/notifications/smtp.go:73.16,75.3 1 0
+github.com/containrrr/watchtower/pkg/notifications/util.go:7.42,13.26 5 0
+github.com/containrrr/watchtower/pkg/notifications/util.go:23.2,23.13 1 0
+github.com/containrrr/watchtower/pkg/notifications/util.go:13.26,15.19 2 0
+github.com/containrrr/watchtower/pkg/notifications/util.go:15.19,18.4 2 0
+github.com/containrrr/watchtower/pkg/notifications/util.go:18.9,18.26 1 0
+github.com/containrrr/watchtower/pkg/notifications/util.go:18.26,20.4 1 0
+github.com/containrrr/watchtower/pkg/notifications/email.go:36.83,65.2 13 0
+github.com/containrrr/watchtower/pkg/notifications/email.go:67.71,70.24 2 0
+github.com/containrrr/watchtower/pkg/notifications/email.go:75.2,75.48 1 0
+github.com/containrrr/watchtower/pkg/notifications/email.go:78.2,79.32 2 0
+github.com/containrrr/watchtower/pkg/notifications/email.go:84.2,96.27 11 0
+github.com/containrrr/watchtower/pkg/notifications/email.go:100.2,102.50 2 0
+github.com/containrrr/watchtower/pkg/notifications/email.go:106.2,106.24 1 0
+github.com/containrrr/watchtower/pkg/notifications/email.go:70.24,72.3 1 0
+github.com/containrrr/watchtower/pkg/notifications/email.go:72.8,74.3 1 0
+github.com/containrrr/watchtower/pkg/notifications/email.go:75.48,77.3 1 0
+github.com/containrrr/watchtower/pkg/notifications/email.go:79.32,82.3 1 0
+github.com/containrrr/watchtower/pkg/notifications/email.go:96.27,98.3 1 0
+github.com/containrrr/watchtower/pkg/notifications/email.go:102.50,104.3 1 0
+github.com/containrrr/watchtower/pkg/notifications/email.go:109.63,112.12 2 0
+github.com/containrrr/watchtower/pkg/notifications/email.go:112.12,113.18 1 0
+github.com/containrrr/watchtower/pkg/notifications/email.go:117.3,118.19 2 0
+github.com/containrrr/watchtower/pkg/notifications/email.go:121.3,122.17 2 0
+github.com/containrrr/watchtower/pkg/notifications/email.go:113.18,115.4 1 0
+github.com/containrrr/watchtower/pkg/notifications/email.go:118.19,120.4 1 0
+github.com/containrrr/watchtower/pkg/notifications/email.go:122.17,125.4 1 0
+github.com/containrrr/watchtower/pkg/notifications/email.go:129.49,130.22 1 0
+github.com/containrrr/watchtower/pkg/notifications/email.go:130.22,132.3 1 0
+github.com/containrrr/watchtower/pkg/notifications/email.go:135.48,136.45 1 0
+github.com/containrrr/watchtower/pkg/notifications/email.go:140.2,141.17 2 0
+github.com/containrrr/watchtower/pkg/notifications/email.go:136.45,138.3 1 0
+github.com/containrrr/watchtower/pkg/notifications/email.go:144.50,146.2 1 0
+github.com/containrrr/watchtower/pkg/notifications/email.go:148.58,149.22 1 0
+github.com/containrrr/watchtower/pkg/notifications/email.go:154.2,154.12 1 0
+github.com/containrrr/watchtower/pkg/notifications/email.go:149.22,151.3 1 0
+github.com/containrrr/watchtower/pkg/notifications/email.go:151.8,153.3 1 0
+github.com/containrrr/watchtower/pkg/notifications/email.go:157.38,157.39 0 0
+github.com/containrrr/watchtower/pkg/notifications/gotify.go:27.84,31.24 3 0
+github.com/containrrr/watchtower/pkg/notifications/gotify.go:39.2,40.26 2 0
+github.com/containrrr/watchtower/pkg/notifications/gotify.go:44.2,55.10 4 0
+github.com/containrrr/watchtower/pkg/notifications/gotify.go:31.24,33.3 1 0
+github.com/containrrr/watchtower/pkg/notifications/gotify.go:33.8,33.99 1 0
+github.com/containrrr/watchtower/pkg/notifications/gotify.go:33.99,35.3 1 0
+github.com/containrrr/watchtower/pkg/notifications/gotify.go:35.8,35.52 1 0
+github.com/containrrr/watchtower/pkg/notifications/gotify.go:35.52,37.3 1 0
+github.com/containrrr/watchtower/pkg/notifications/gotify.go:40.26,42.3 1 0
+github.com/containrrr/watchtower/pkg/notifications/gotify.go:58.51,58.52 0 0
+github.com/containrrr/watchtower/pkg/notifications/gotify.go:60.50,60.51 0 0
+github.com/containrrr/watchtower/pkg/notifications/gotify.go:62.39,62.40 0 0
+github.com/containrrr/watchtower/pkg/notifications/gotify.go:64.51,66.2 1 0
+github.com/containrrr/watchtower/pkg/notifications/gotify.go:68.46,70.34 2 0
+github.com/containrrr/watchtower/pkg/notifications/gotify.go:73.2,73.50 1 0
+github.com/containrrr/watchtower/pkg/notifications/gotify.go:70.34,72.3 1 0
+github.com/containrrr/watchtower/pkg/notifications/gotify.go:76.59,78.12 1 0
+github.com/containrrr/watchtower/pkg/notifications/gotify.go:110.2,110.12 1 0
+github.com/containrrr/watchtower/pkg/notifications/gotify.go:78.12,84.17 2 0
+github.com/containrrr/watchtower/pkg/notifications/gotify.go:90.3,99.17 4 0
+github.com/containrrr/watchtower/pkg/notifications/gotify.go:103.3,105.54 2 0
+github.com/containrrr/watchtower/pkg/notifications/gotify.go:84.17,87.4 2 0
+github.com/containrrr/watchtower/pkg/notifications/gotify.go:99.17,102.4 2 0
+github.com/containrrr/watchtower/pkg/notifications/gotify.go:105.54,107.4 1 0
+github.com/containrrr/watchtower/pkg/notifications/msteams.go:25.87,30.26 3 0
+github.com/containrrr/watchtower/pkg/notifications/msteams.go:34.2,43.10 4 0
+github.com/containrrr/watchtower/pkg/notifications/msteams.go:30.26,32.3 1 0
+github.com/containrrr/watchtower/pkg/notifications/msteams.go:46.52,46.53 0 0
+github.com/containrrr/watchtower/pkg/notifications/msteams.go:48.51,48.52 0 0
+github.com/containrrr/watchtower/pkg/notifications/msteams.go:50.40,50.41 0 0
+github.com/containrrr/watchtower/pkg/notifications/msteams.go:52.52,54.2 1 0
+github.com/containrrr/watchtower/pkg/notifications/msteams.go:56.60,60.12 2 0
+github.com/containrrr/watchtower/pkg/notifications/msteams.go:111.2,111.12 1 0
+github.com/containrrr/watchtower/pkg/notifications/msteams.go:60.12,68.57 2 0
+github.com/containrrr/watchtower/pkg/notifications/msteams.go:86.3,87.17 2 0
+github.com/containrrr/watchtower/pkg/notifications/msteams.go:92.3,93.17 2 0
+github.com/containrrr/watchtower/pkg/notifications/msteams.go:97.3,99.53 2 0
+github.com/containrrr/watchtower/pkg/notifications/msteams.go:68.57,75.33 3 0
+github.com/containrrr/watchtower/pkg/notifications/msteams.go:83.4,83.56 1 0
+github.com/containrrr/watchtower/pkg/notifications/msteams.go:75.33,81.5 2 0
+github.com/containrrr/watchtower/pkg/notifications/msteams.go:87.17,90.4 2 0
+github.com/containrrr/watchtower/pkg/notifications/msteams.go:93.17,95.4 1 0
+github.com/containrrr/watchtower/pkg/notifications/msteams.go:99.53,101.24 2 0
+github.com/containrrr/watchtower/pkg/notifications/msteams.go:101.24,103.19 2 0
+github.com/containrrr/watchtower/pkg/notifications/msteams.go:103.19,106.6 2 0
+github.com/containrrr/watchtower/pkg/registry/registry.go:9.71,12.16 3 0
+github.com/containrrr/watchtower/pkg/registry/registry.go:16.2,16.16 1 0
+github.com/containrrr/watchtower/pkg/registry/registry.go:19.2,24.8 2 0
+github.com/containrrr/watchtower/pkg/registry/registry.go:12.16,14.3 1 0
+github.com/containrrr/watchtower/pkg/registry/registry.go:16.16,18.3 1 0
+github.com/containrrr/watchtower/pkg/registry/registry.go:30.43,33.2 2 0
+github.com/containrrr/watchtower/pkg/registry/trust.go:20.46,22.16 2 0
+github.com/containrrr/watchtower/pkg/registry/trust.go:25.2,25.18 1 0
+github.com/containrrr/watchtower/pkg/registry/trust.go:22.16,24.3 1 0
+github.com/containrrr/watchtower/pkg/registry/trust.go:31.49,34.38 3 1
+github.com/containrrr/watchtower/pkg/registry/trust.go:43.2,43.93 1 1
+github.com/containrrr/watchtower/pkg/registry/trust.go:34.38,42.3 4 1
+github.com/containrrr/watchtower/pkg/registry/trust.go:50.52,52.16 2 1
+github.com/containrrr/watchtower/pkg/registry/trust.go:56.2,57.21 2 0
+github.com/containrrr/watchtower/pkg/registry/trust.go:60.2,61.16 2 0
+github.com/containrrr/watchtower/pkg/registry/trust.go:65.2,68.34 3 0
+github.com/containrrr/watchtower/pkg/registry/trust.go:72.2,74.25 3 0
+github.com/containrrr/watchtower/pkg/registry/trust.go:52.16,55.3 2 1
+github.com/containrrr/watchtower/pkg/registry/trust.go:57.21,59.3 1 0
+github.com/containrrr/watchtower/pkg/registry/trust.go:61.16,64.3 2 0
+github.com/containrrr/watchtower/pkg/registry/trust.go:68.34,71.3 2 0
+github.com/containrrr/watchtower/pkg/registry/trust.go:78.53,81.16 2 1
+github.com/containrrr/watchtower/pkg/registry/trust.go:85.2,86.22 2 1
+github.com/containrrr/watchtower/pkg/registry/trust.go:81.16,83.3 1 1
+github.com/containrrr/watchtower/pkg/registry/trust.go:91.75,92.39 1 0
+github.com/containrrr/watchtower/pkg/registry/trust.go:95.2,95.46 1 0
+github.com/containrrr/watchtower/pkg/registry/trust.go:92.39,94.3 1 0
+github.com/containrrr/watchtower/pkg/registry/trust.go:99.56,101.2 1 1
+github.com/containrrr/watchtower/pkg/registry/manifest/manifest.go:13.68,17.16 3 1
+github.com/containrrr/watchtower/pkg/registry/manifest/manifest.go:21.2,22.16 2 1
+github.com/containrrr/watchtower/pkg/registry/manifest/manifest.go:25.2,31.26 3 1
+github.com/containrrr/watchtower/pkg/registry/manifest/manifest.go:17.16,19.3 1 0
+github.com/containrrr/watchtower/pkg/registry/manifest/manifest.go:22.16,24.3 1 0
+github.com/containrrr/watchtower/pkg/registry/manifest/manifest.go:34.71,37.46 3 1
+github.com/containrrr/watchtower/pkg/registry/manifest/manifest.go:45.2,45.17 1 1
+github.com/containrrr/watchtower/pkg/registry/manifest/manifest.go:37.46,41.3 3 1
+github.com/containrrr/watchtower/pkg/registry/manifest/manifest.go:41.8,44.3 2 1
+github.com/containrrr/watchtower/pkg/container/container.go:16.97,21.2 1 1
+github.com/containrrr/watchtower/pkg/container/container.go:33.57,35.2 1 0
+github.com/containrrr/watchtower/pkg/container/container.go:38.32,40.2 1 1
+github.com/containrrr/watchtower/pkg/container/container.go:45.37,47.2 1 0
+github.com/containrrr/watchtower/pkg/container/container.go:50.34,52.2 1 1
+github.com/containrrr/watchtower/pkg/container/container.go:56.37,58.2 1 0
+github.com/containrrr/watchtower/pkg/container/container.go:63.39,66.9 2 1
+github.com/containrrr/watchtower/pkg/container/container.go:70.2,70.39 1 1
+github.com/containrrr/watchtower/pkg/container/container.go:74.2,74.18 1 1
+github.com/containrrr/watchtower/pkg/container/container.go:66.9,68.3 1 1
+github.com/containrrr/watchtower/pkg/container/container.go:70.39,72.3 1 1
+github.com/containrrr/watchtower/pkg/container/container.go:79.43,81.9 2 1
+github.com/containrrr/watchtower/pkg/container/container.go:85.2,86.16 2 1
+github.com/containrrr/watchtower/pkg/container/container.go:90.2,90.25 1 1
+github.com/containrrr/watchtower/pkg/container/container.go:81.9,83.3 1 1
+github.com/containrrr/watchtower/pkg/container/container.go:86.16,88.3 1 1
+github.com/containrrr/watchtower/pkg/container/container.go:95.41,97.9 2 0
+github.com/containrrr/watchtower/pkg/container/container.go:101.2,102.16 2 0
+github.com/containrrr/watchtower/pkg/container/container.go:106.2,106.19 1 0
+github.com/containrrr/watchtower/pkg/container/container.go:97.9,99.3 1 0
+github.com/containrrr/watchtower/pkg/container/container.go:102.16,104.3 1 0
+github.com/containrrr/watchtower/pkg/container/container.go:111.43,113.9 2 0
+github.com/containrrr/watchtower/pkg/container/container.go:117.2,117.24 1 0
+github.com/containrrr/watchtower/pkg/container/container.go:113.9,115.3 1 0
+github.com/containrrr/watchtower/pkg/container/container.go:122.37,127.31 3 1
+github.com/containrrr/watchtower/pkg/container/container.go:132.2,132.69 1 1
+github.com/containrrr/watchtower/pkg/container/container.go:139.2,139.14 1 1
+github.com/containrrr/watchtower/pkg/container/container.go:127.31,130.3 2 1
+github.com/containrrr/watchtower/pkg/container/container.go:132.69,133.57 1 1
+github.com/containrrr/watchtower/pkg/container/container.go:133.57,136.4 2 1
+github.com/containrrr/watchtower/pkg/container/container.go:144.37,146.2 1 0
+github.com/containrrr/watchtower/pkg/container/container.go:152.40,154.2 1 1
+github.com/containrrr/watchtower/pkg/container/container.go:161.43,168.29 5 0
+github.com/containrrr/watchtower/pkg/container/container.go:172.2,172.16 1 0
+github.com/containrrr/watchtower/pkg/container/container.go:168.29,170.3 1 0
+github.com/containrrr/watchtower/pkg/container/container.go:178.40,180.2 1 1
+github.com/containrrr/watchtower/pkg/container/container.go:193.60,198.49 4 0
+github.com/containrrr/watchtower/pkg/container/container.go:202.2,202.37 1 0
+github.com/containrrr/watchtower/pkg/container/container.go:206.2,206.42 1 0
+github.com/containrrr/watchtower/pkg/container/container.go:210.2,210.64 1 0
+github.com/containrrr/watchtower/pkg/container/container.go:217.2,224.37 4 0
+github.com/containrrr/watchtower/pkg/container/container.go:229.2,229.57 1 0
+github.com/containrrr/watchtower/pkg/container/container.go:233.2,234.15 2 0
+github.com/containrrr/watchtower/pkg/container/container.go:198.49,200.3 1 0
+github.com/containrrr/watchtower/pkg/container/container.go:202.37,204.3 1 0
+github.com/containrrr/watchtower/pkg/container/container.go:206.42,208.3 1 0
+github.com/containrrr/watchtower/pkg/container/container.go:210.64,212.51 2 0
+github.com/containrrr/watchtower/pkg/container/container.go:212.51,214.4 1 0
+github.com/containrrr/watchtower/pkg/container/container.go:224.37,225.47 1 0
+github.com/containrrr/watchtower/pkg/container/container.go:225.47,227.4 1 0
+github.com/containrrr/watchtower/pkg/container/container.go:229.57,231.3 1 0
+github.com/containrrr/watchtower/pkg/container/container.go:239.61,242.40 2 0
+github.com/containrrr/watchtower/pkg/container/container.go:249.2,249.19 1 0
+github.com/containrrr/watchtower/pkg/container/container.go:242.40,247.3 3 0
+github.com/containrrr/watchtower/pkg/container/container.go:253.40,255.2 1 0
+github.com/containrrr/watchtower/pkg/container/container.go:257.52,259.2 1 0
+github.com/containrrr/watchtower/pkg/container/metadata.go:19.57,21.2 1 0
+github.com/containrrr/watchtower/pkg/container/metadata.go:24.58,26.2 1 0
+github.com/containrrr/watchtower/pkg/container/metadata.go:29.58,31.2 1 0
+github.com/containrrr/watchtower/pkg/container/metadata.go:34.59,36.2 1 0
+github.com/containrrr/watchtower/pkg/container/metadata.go:40.61,43.2 2 1
+github.com/containrrr/watchtower/pkg/container/metadata.go:45.62,46.57 1 1
+github.com/containrrr/watchtower/pkg/container/metadata.go:49.2,49.11 1 1
+github.com/containrrr/watchtower/pkg/container/metadata.go:46.57,48.3 1 1
+github.com/containrrr/watchtower/pkg/container/metadata.go:52.63,55.2 2 1
+github.com/containrrr/watchtower/pkg/container/client.go:43.101,46.16 2 0
+github.com/containrrr/watchtower/pkg/container/client.go:50.2,56.3 1 0
+github.com/containrrr/watchtower/pkg/container/client.go:46.16,48.3 1 0
+github.com/containrrr/watchtower/pkg/container/client.go:67.77,71.27 3 1
+github.com/containrrr/watchtower/pkg/container/client.go:77.2,84.16 3 1
+github.com/containrrr/watchtower/pkg/container/client.go:88.2,88.46 1 1
+github.com/containrrr/watchtower/pkg/container/client.go:100.2,100.16 1 1
+github.com/containrrr/watchtower/pkg/container/client.go:71.27,73.3 1 1
+github.com/containrrr/watchtower/pkg/container/client.go:73.8,75.3 1 1
+github.com/containrrr/watchtower/pkg/container/client.go:84.16,86.3 1 0
+github.com/containrrr/watchtower/pkg/container/client.go:88.46,91.17 2 1
+github.com/containrrr/watchtower/pkg/container/client.go:95.3,95.12 1 1
+github.com/containrrr/watchtower/pkg/container/client.go:91.17,93.4 1 0
+github.com/containrrr/watchtower/pkg/container/client.go:95.12,97.4 1 1
+github.com/containrrr/watchtower/pkg/container/client.go:103.60,107.27 3 1
+github.com/containrrr/watchtower/pkg/container/client.go:112.2,112.19 1 1
+github.com/containrrr/watchtower/pkg/container/client.go:107.27,110.3 2 1
+github.com/containrrr/watchtower/pkg/container/client.go:115.80,119.16 3 1
+github.com/containrrr/watchtower/pkg/container/client.go:123.2,124.16 2 1
+github.com/containrrr/watchtower/pkg/container/client.go:128.2,128.77 1 1
+github.com/containrrr/watchtower/pkg/container/client.go:119.16,121.3 1 0
+github.com/containrrr/watchtower/pkg/container/client.go:124.16,126.3 1 0
+github.com/containrrr/watchtower/pkg/container/client.go:131.84,134.18 3 0
+github.com/containrrr/watchtower/pkg/container/client.go:138.2,138.19 1 0
+github.com/containrrr/watchtower/pkg/container/client.go:146.2,148.43 2 0
+github.com/containrrr/watchtower/pkg/container/client.go:159.2,159.64 1 0
+github.com/containrrr/watchtower/pkg/container/client.go:163.2,163.12 1 0
+github.com/containrrr/watchtower/pkg/container/client.go:134.18,136.3 1 0
+github.com/containrrr/watchtower/pkg/container/client.go:138.19,140.70 2 0
+github.com/containrrr/watchtower/pkg/container/client.go:140.70,142.4 1 0
+github.com/containrrr/watchtower/pkg/container/client.go:148.43,150.3 1 0
+github.com/containrrr/watchtower/pkg/container/client.go:150.8,153.144 2 0
+github.com/containrrr/watchtower/pkg/container/client.go:153.144,155.4 1 0
+github.com/containrrr/watchtower/pkg/container/client.go:159.64,161.3 1 0
+github.com/containrrr/watchtower/pkg/container/client.go:166.72,173.58 5 0
+github.com/containrrr/watchtower/pkg/container/client.go:183.2,187.16 4 0
+github.com/containrrr/watchtower/pkg/container/client.go:191.2,191.40 1 0
+github.com/containrrr/watchtower/pkg/container/client.go:209.2,209.45 1 0
+github.com/containrrr/watchtower/pkg/container/client.go:213.2,213.78 1 0
+github.com/containrrr/watchtower/pkg/container/client.go:173.58,175.51 2 0
+github.com/containrrr/watchtower/pkg/container/client.go:180.3,180.65 1 0
+github.com/containrrr/watchtower/pkg/container/client.go:175.51,178.9 2 0
+github.com/containrrr/watchtower/pkg/container/client.go:187.16,189.3 1 0
+github.com/containrrr/watchtower/pkg/container/client.go:191.40,193.54 1 0
+github.com/containrrr/watchtower/pkg/container/client.go:200.3,200.51 1 0
+github.com/containrrr/watchtower/pkg/container/client.go:193.54,195.18 2 0
+github.com/containrrr/watchtower/pkg/container/client.go:195.18,197.5 1 0
+github.com/containrrr/watchtower/pkg/container/client.go:200.51,202.18 2 0
+github.com/containrrr/watchtower/pkg/container/client.go:202.18,204.5 1 0
+github.com/containrrr/watchtower/pkg/container/client.go:209.45,211.3 1 0
+github.com/containrrr/watchtower/pkg/container/client.go:217.131,222.16 4 0
+github.com/containrrr/watchtower/pkg/container/client.go:225.2,225.12 1 0
+github.com/containrrr/watchtower/pkg/container/client.go:222.16,224.3 1 0
+github.com/containrrr/watchtower/pkg/container/client.go:228.79,232.2 3 0
+github.com/containrrr/watchtower/pkg/container/client.go:234.80,237.24 2 0
+github.com/containrrr/watchtower/pkg/container/client.go:243.2,243.43 1 0
+github.com/containrrr/watchtower/pkg/container/client.go:237.24,239.3 1 0
+github.com/containrrr/watchtower/pkg/container/client.go:239.8,239.64 1 0
+github.com/containrrr/watchtower/pkg/container/client.go:239.64,241.3 1 0
+github.com/containrrr/watchtower/pkg/container/client.go:246.96,251.16 4 0
+github.com/containrrr/watchtower/pkg/container/client.go:255.2,255.35 1 0
+github.com/containrrr/watchtower/pkg/container/client.go:260.2,261.18 2 0
+github.com/containrrr/watchtower/pkg/container/client.go:251.16,253.3 1 0
+github.com/containrrr/watchtower/pkg/container/client.go:255.35,258.3 2 0
+github.com/containrrr/watchtower/pkg/container/client.go:264.86,275.16 6 0
+github.com/containrrr/watchtower/pkg/container/client.go:280.2,281.86 2 0
+github.com/containrrr/watchtower/pkg/container/client.go:288.2,291.16 3 0
+github.com/containrrr/watchtower/pkg/container/client.go:296.2,298.51 2 0
+github.com/containrrr/watchtower/pkg/container/client.go:302.2,302.12 1 0
+github.com/containrrr/watchtower/pkg/container/client.go:275.16,278.3 2 0
+github.com/containrrr/watchtower/pkg/container/client.go:281.86,283.3 1 0
+github.com/containrrr/watchtower/pkg/container/client.go:283.8,283.18 1 0
+github.com/containrrr/watchtower/pkg/container/client.go:283.18,286.3 2 0
+github.com/containrrr/watchtower/pkg/container/client.go:291.16,294.3 2 0
+github.com/containrrr/watchtower/pkg/container/client.go:298.51,301.3 2 0
+github.com/containrrr/watchtower/pkg/container/client.go:305.61,316.2 3 0
+github.com/containrrr/watchtower/pkg/container/client.go:318.98,329.16 4 0
+github.com/containrrr/watchtower/pkg/container/client.go:333.2,337.22 2 0
+github.com/containrrr/watchtower/pkg/container/client.go:342.2,344.16 3 0
+github.com/containrrr/watchtower/pkg/container/client.go:348.2,349.22 2 0
+github.com/containrrr/watchtower/pkg/container/client.go:362.2,363.16 2 0
+github.com/containrrr/watchtower/pkg/container/client.go:367.2,367.12 1 0
+github.com/containrrr/watchtower/pkg/container/client.go:329.16,331.3 1 0
+github.com/containrrr/watchtower/pkg/container/client.go:337.22,339.3 1 0
+github.com/containrrr/watchtower/pkg/container/client.go:344.16,346.3 1 0
+github.com/containrrr/watchtower/pkg/container/client.go:349.22,353.17 4 0
+github.com/containrrr/watchtower/pkg/container/client.go:353.17,355.4 1 0
+github.com/containrrr/watchtower/pkg/container/client.go:355.9,355.25 1 0
+github.com/containrrr/watchtower/pkg/container/client.go:355.25,357.4 1 0
+github.com/containrrr/watchtower/pkg/container/client.go:363.16,365.3 1 0
+github.com/containrrr/watchtower/pkg/container/client.go:370.118,374.17 3 0
+github.com/containrrr/watchtower/pkg/container/client.go:381.2,381.6 1 0
+github.com/containrrr/watchtower/pkg/container/client.go:406.2,406.12 1 0
+github.com/containrrr/watchtower/pkg/container/client.go:374.17,377.3 2 0
+github.com/containrrr/watchtower/pkg/container/client.go:377.8,379.3 1 0
+github.com/containrrr/watchtower/pkg/container/client.go:381.6,390.17 3 0
+github.com/containrrr/watchtower/pkg/container/client.go:393.3,393.34 1 0
+github.com/containrrr/watchtower/pkg/container/client.go:397.3,397.26 1 0
+github.com/containrrr/watchtower/pkg/container/client.go:400.3,400.31 1 0
+github.com/containrrr/watchtower/pkg/container/client.go:404.3,404.8 1 0
+github.com/containrrr/watchtower/pkg/container/client.go:390.17,392.4 1 0
+github.com/containrrr/watchtower/pkg/container/client.go:393.34,395.12 2 0
+github.com/containrrr/watchtower/pkg/container/client.go:397.26,399.4 1 0
+github.com/containrrr/watchtower/pkg/container/client.go:400.31,403.4 2 0
+github.com/containrrr/watchtower/pkg/container/client.go:409.92,413.6 3 0
+github.com/containrrr/watchtower/pkg/container/client.go:413.6,414.10 1 0
+github.com/containrrr/watchtower/pkg/container/client.go:424.3,424.30 1 0
+github.com/containrrr/watchtower/pkg/container/client.go:415.18,416.14 1 0
+github.com/containrrr/watchtower/pkg/container/client.go:417.11,418.70 1 0
+github.com/containrrr/watchtower/pkg/container/client.go:418.70,420.5 1 0
+github.com/containrrr/watchtower/pkg/container/client.go:420.10,420.32 1 0
+github.com/containrrr/watchtower/pkg/container/client.go:420.32,422.5 1 0
+github.com/containrrr/watchtower/pkg/registry/auth/auth.go:24.121,30.49 5 1
+github.com/containrrr/watchtower/pkg/registry/auth/auth.go:34.2,35.53 2 1
+github.com/containrrr/watchtower/pkg/registry/auth/auth.go:39.2,41.43 3 1
+github.com/containrrr/watchtower/pkg/registry/auth/auth.go:45.2,52.43 4 1
+github.com/containrrr/watchtower/pkg/registry/auth/auth.go:55.2,55.44 1 1
+github.com/containrrr/watchtower/pkg/registry/auth/auth.go:60.2,60.67 1 0
+github.com/containrrr/watchtower/pkg/registry/auth/auth.go:30.49,32.3 1 0
+github.com/containrrr/watchtower/pkg/registry/auth/auth.go:35.53,37.3 1 0
+github.com/containrrr/watchtower/pkg/registry/auth/auth.go:41.43,43.3 1 0
+github.com/containrrr/watchtower/pkg/registry/auth/auth.go:52.43,54.3 1 0
+github.com/containrrr/watchtower/pkg/registry/auth/auth.go:55.44,58.3 2 1
+github.com/containrrr/watchtower/pkg/registry/auth/auth.go:64.63,67.16 2 1
+github.com/containrrr/watchtower/pkg/registry/auth/auth.go:70.2,72.17 3 1
+github.com/containrrr/watchtower/pkg/registry/auth/auth.go:67.16,69.3 1 0
+github.com/containrrr/watchtower/pkg/registry/auth/auth.go:76.139,81.16 4 1
+github.com/containrrr/watchtower/pkg/registry/auth/auth.go:85.2,86.72 2 1
+github.com/containrrr/watchtower/pkg/registry/auth/auth.go:90.2,90.62 1 1
+github.com/containrrr/watchtower/pkg/registry/auth/auth.go:97.2,98.50 2 1
+github.com/containrrr/watchtower/pkg/registry/auth/auth.go:102.2,106.16 4 1
+github.com/containrrr/watchtower/pkg/registry/auth/auth.go:110.2,110.33 1 1
+github.com/containrrr/watchtower/pkg/registry/auth/auth.go:81.16,83.3 1 0
+github.com/containrrr/watchtower/pkg/registry/auth/auth.go:86.72,88.3 1 0
+github.com/containrrr/watchtower/pkg/registry/auth/auth.go:90.62,93.3 2 1
+github.com/containrrr/watchtower/pkg/registry/auth/auth.go:93.8,95.3 1 0
+github.com/containrrr/watchtower/pkg/registry/auth/auth.go:98.50,100.3 1 0
+github.com/containrrr/watchtower/pkg/registry/auth/auth.go:106.16,108.3 1 0
+github.com/containrrr/watchtower/pkg/registry/auth/auth.go:114.66,120.29 5 1
+github.com/containrrr/watchtower/pkg/registry/auth/auth.go:128.2,128.79 1 1
+github.com/containrrr/watchtower/pkg/registry/auth/auth.go:132.2,140.21 8 1
+github.com/containrrr/watchtower/pkg/registry/auth/auth.go:120.29,126.3 5 1
+github.com/containrrr/watchtower/pkg/registry/auth/auth.go:128.79,130.3 1 1
+github.com/containrrr/watchtower/pkg/registry/auth/auth.go:144.52,147.16 3 1
+github.com/containrrr/watchtower/pkg/registry/auth/auth.go:151.2,156.17 2 1
+github.com/containrrr/watchtower/pkg/registry/auth/auth.go:147.16,149.3 1 0
+github.com/containrrr/watchtower/pkg/registry/digest/digest.go:24.124,28.16 4 1
+github.com/containrrr/watchtower/pkg/registry/digest/digest.go:32.2,33.16 2 1
+github.com/containrrr/watchtower/pkg/registry/digest/digest.go:37.2,37.64 1 1
+github.com/containrrr/watchtower/pkg/registry/digest/digest.go:41.2,44.24 3 1
+github.com/containrrr/watchtower/pkg/registry/digest/digest.go:48.2,48.40 1 1
+github.com/containrrr/watchtower/pkg/registry/digest/digest.go:56.2,56.19 1 0
+github.com/containrrr/watchtower/pkg/registry/digest/digest.go:28.16,30.3 1 0
+github.com/containrrr/watchtower/pkg/registry/digest/digest.go:33.16,35.3 1 0
+github.com/containrrr/watchtower/pkg/registry/digest/digest.go:37.64,39.3 1 0
+github.com/containrrr/watchtower/pkg/registry/digest/digest.go:44.24,46.3 1 0
+github.com/containrrr/watchtower/pkg/registry/digest/digest.go:48.40,51.28 3 1
+github.com/containrrr/watchtower/pkg/registry/digest/digest.go:51.28,53.4 1 1
+github.com/containrrr/watchtower/pkg/registry/digest/digest.go:60.79,63.17 3 1
+github.com/containrrr/watchtower/pkg/registry/digest/digest.go:69.2,75.16 6 1
+github.com/containrrr/watchtower/pkg/registry/digest/digest.go:78.2,78.27 1 1
+github.com/containrrr/watchtower/pkg/registry/digest/digest.go:81.2,81.49 1 1
+github.com/containrrr/watchtower/pkg/registry/digest/digest.go:63.17,65.3 1 1
+github.com/containrrr/watchtower/pkg/registry/digest/digest.go:65.8,67.3 1 0
+github.com/containrrr/watchtower/pkg/registry/digest/digest.go:75.16,77.3 1 0
+github.com/containrrr/watchtower/pkg/registry/digest/digest.go:78.27,80.3 1 0
+github.com/containrrr/watchtower/internal/actions/check.go:24.101,28.16 3 1
+github.com/containrrr/watchtower/internal/actions/check.go:33.2,33.26 1 1
+github.com/containrrr/watchtower/internal/actions/check.go:38.2,39.62 2 1
+github.com/containrrr/watchtower/internal/actions/check.go:28.16,31.3 2 0
+github.com/containrrr/watchtower/internal/actions/check.go:33.26,36.3 2 1
+github.com/containrrr/watchtower/internal/actions/check.go:42.110,49.44 5 1
+github.com/containrrr/watchtower/internal/actions/check.go:66.2,66.64 1 1
+github.com/containrrr/watchtower/internal/actions/check.go:49.44,50.65 1 1
+github.com/containrrr/watchtower/internal/actions/check.go:57.3,57.14 1 1
+github.com/containrrr/watchtower/internal/actions/check.go:50.65,54.12 3 0
+github.com/containrrr/watchtower/internal/actions/check.go:57.14,58.62 1 1
+github.com/containrrr/watchtower/internal/actions/check.go:58.62,62.5 2 0
+github.com/containrrr/watchtower/internal/actions/check.go:69.55,70.22 1 1
+github.com/containrrr/watchtower/internal/actions/check.go:74.2,76.11 2 0
+github.com/containrrr/watchtower/internal/actions/check.go:79.2,79.11 1 0
+github.com/containrrr/watchtower/internal/actions/check.go:82.2,82.36 1 0
+github.com/containrrr/watchtower/internal/actions/check.go:70.22,72.3 1 1
+github.com/containrrr/watchtower/internal/actions/check.go:76.11,78.3 1 0
+github.com/containrrr/watchtower/internal/actions/check.go:79.11,81.3 1 0
+github.com/containrrr/watchtower/internal/actions/check.go:85.26,88.2 2 1
+github.com/containrrr/watchtower/internal/actions/update.go:17.71,20.27 2 1
+github.com/containrrr/watchtower/internal/actions/update.go:24.2,25.16 2 1
+github.com/containrrr/watchtower/internal/actions/update.go:29.2,29.45 1 1
+github.com/containrrr/watchtower/internal/actions/update.go:41.2,42.16 2 1
+github.com/containrrr/watchtower/internal/actions/update.go:46.2,49.25 3 1
+github.com/containrrr/watchtower/internal/actions/update.go:57.2,57.27 1 1
+github.com/containrrr/watchtower/internal/actions/update.go:63.2,63.27 1 1
+github.com/containrrr/watchtower/internal/actions/update.go:66.2,66.12 1 1
+github.com/containrrr/watchtower/internal/actions/update.go:20.27,22.3 1 0
+github.com/containrrr/watchtower/internal/actions/update.go:25.16,27.3 1 0
+github.com/containrrr/watchtower/internal/actions/update.go:29.45,31.127 2 1
+github.com/containrrr/watchtower/internal/actions/update.go:34.3,34.17 1 1
+github.com/containrrr/watchtower/internal/actions/update.go:38.3,38.30 1 1
+github.com/containrrr/watchtower/internal/actions/update.go:31.127,33.4 1 0
+github.com/containrrr/watchtower/internal/actions/update.go:34.17,37.4 2 0
+github.com/containrrr/watchtower/internal/actions/update.go:42.16,44.3 1 0
+github.com/containrrr/watchtower/internal/actions/update.go:49.25,50.45 1 1
+github.com/containrrr/watchtower/internal/actions/update.go:50.45,51.38 1 1
+github.com/containrrr/watchtower/internal/actions/update.go:51.38,53.5 1 1
+github.com/containrrr/watchtower/internal/actions/update.go:57.27,59.3 1 0
+github.com/containrrr/watchtower/internal/actions/update.go:59.8,62.3 2 1
+github.com/containrrr/watchtower/internal/actions/update.go:63.27,65.3 1 0
+github.com/containrrr/watchtower/internal/actions/update.go:69.114,72.44 2 0
+github.com/containrrr/watchtower/internal/actions/update.go:79.2,79.20 1 0
+github.com/containrrr/watchtower/internal/actions/update.go:72.44,73.26 1 0
+github.com/containrrr/watchtower/internal/actions/update.go:73.26,76.4 2 0
+github.com/containrrr/watchtower/internal/actions/update.go:79.20,81.3 1 0
+github.com/containrrr/watchtower/internal/actions/update.go:84.122,85.44 1 1
+github.com/containrrr/watchtower/internal/actions/update.go:85.44,87.3 1 1
+github.com/containrrr/watchtower/internal/actions/update.go:90.108,91.30 1 1
+github.com/containrrr/watchtower/internal/actions/update.go:96.2,96.22 1 1
+github.com/containrrr/watchtower/internal/actions/update.go:99.2,99.27 1 1
+github.com/containrrr/watchtower/internal/actions/update.go:107.2,107.72 1 1
+github.com/containrrr/watchtower/internal/actions/update.go:91.30,94.3 2 0
+github.com/containrrr/watchtower/internal/actions/update.go:96.22,98.3 1 0
+github.com/containrrr/watchtower/internal/actions/update.go:99.27,100.78 1 0
+github.com/containrrr/watchtower/internal/actions/update.go:100.78,104.4 3 0
+github.com/containrrr/watchtower/internal/actions/update.go:107.72,109.3 1 1
+github.com/containrrr/watchtower/internal/actions/update.go:112.123,115.44 2 1
+github.com/containrrr/watchtower/internal/actions/update.go:123.2,123.20 1 1
+github.com/containrrr/watchtower/internal/actions/update.go:115.44,116.28 1 1
+github.com/containrrr/watchtower/internal/actions/update.go:119.3,120.44 2 1
+github.com/containrrr/watchtower/internal/actions/update.go:116.28,117.12 1 0
+github.com/containrrr/watchtower/internal/actions/update.go:123.20,125.3 1 1
+github.com/containrrr/watchtower/internal/actions/update.go:128.71,129.32 1 1
+github.com/containrrr/watchtower/internal/actions/update.go:129.32,130.57 1 1
+github.com/containrrr/watchtower/internal/actions/update.go:130.57,132.4 1 0
+github.com/containrrr/watchtower/internal/actions/update.go:136.111,141.30 1 1
+github.com/containrrr/watchtower/internal/actions/update.go:148.2,148.23 1 1
+github.com/containrrr/watchtower/internal/actions/update.go:141.30,142.76 1 0
+github.com/containrrr/watchtower/internal/actions/update.go:142.76,145.4 2 0
+github.com/containrrr/watchtower/internal/actions/update.go:148.23,149.74 1 1
+github.com/containrrr/watchtower/internal/actions/update.go:149.74,151.4 1 0
+github.com/containrrr/watchtower/internal/actions/update.go:151.9,151.54 1 1
+github.com/containrrr/watchtower/internal/actions/update.go:151.54,153.4 1 0
+github.com/containrrr/watchtower/internal/actions/update.go:157.58,159.36 1 1
+github.com/containrrr/watchtower/internal/actions/update.go:159.36,160.25 1 1
+github.com/containrrr/watchtower/internal/actions/update.go:164.2,165.43 1 0
+github.com/containrrr/watchtower/internal/actions/update.go:160.25,161.12 1 1
+github.com/containrrr/watchtower/internal/actions/update.go:165.43,166.37 1 0
+github.com/containrrr/watchtower/internal/actions/update.go:166.37,167.54 1 0
+github.com/containrrr/watchtower/internal/actions/update.go:167.54,169.20 2 0
diff --git a/docs/arguments.md b/docs/arguments.md
index 64bbdfc..62e73ad 100644
--- a/docs/arguments.md
+++ b/docs/arguments.md
@@ -145,7 +145,7 @@ Poll interval (in seconds). This value controls how frequently watchtower will p
             Argument: --interval, -i
 Environment Variable: WATCHTOWER_POLL_INTERVAL
                 Type: Integer
-             Default: 300
+             Default: 86400 (24 hours)
 ```
 
 ## Filter by enable label
diff --git a/go.mod b/go.mod
index 300eb31..0e37602 100644
--- a/go.mod
+++ b/go.mod
@@ -26,6 +26,7 @@ require (
 	github.com/docker/go-units v0.3.3 // indirect
 	github.com/docker/libtrust v0.0.0-20160708172513-aabc10ec26b7 // indirect
 	github.com/gofrs/uuid v3.2.0+incompatible // indirect
+	github.com/golang/protobuf v1.4.2 // indirect
 	github.com/google/certificate-transparency-go v1.0.21 // indirect
 	github.com/gorilla/mux v1.7.0 // indirect
 	github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed // indirect
@@ -39,11 +40,11 @@ require (
 	github.com/lib/pq v1.2.0 // indirect
 	github.com/miekg/pkcs11 v0.0.0-20190401114359-553cfdd26aaa // indirect
 	github.com/morikuni/aec v0.0.0-20170113033406-39771216ff4c // indirect
-	github.com/onsi/ginkgo v1.8.0
-	github.com/onsi/gomega v1.5.0
+	github.com/onsi/ginkgo v1.11.0
+	github.com/onsi/gomega v1.10.0
 	github.com/opencontainers/go-digest v1.0.0-rc1 // indirect
 	github.com/opencontainers/image-spec v1.0.1 // indirect
-	github.com/opencontainers/runc v0.1.1
+	github.com/opencontainers/runc v0.1.1 // indirect
 	github.com/pkg/errors v0.8.1 // indirect
 	github.com/robfig/cron v0.0.0-20180505203441-b41be1df6967
 	github.com/sirupsen/logrus v1.4.1
@@ -53,9 +54,14 @@ require (
 	github.com/stretchr/testify v1.3.0
 	github.com/theupdateframework/notary v0.6.1 // indirect
 	github.com/zmap/zlint v1.0.2 // indirect
-	golang.org/x/net v0.0.0-20190522155817-f3200d17e092
+	golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 // indirect
+	golang.org/x/net v0.0.0-20191004110552-13f9640d40b9
+	golang.org/x/sys v0.0.0-20190830141801-acfa387b8d69 // indirect
+	golang.org/x/text v0.3.4 // indirect
+	golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
 	gopkg.in/dancannon/gorethink.v3 v3.0.5 // indirect
 	gopkg.in/fatih/pool.v2 v2.0.0 // indirect
 	gopkg.in/gorethink/gorethink.v3 v3.0.5 // indirect
+	gopkg.in/yaml.v2 v2.4.0 // indirect
 	gotest.tools v2.2.0+incompatible // indirect
 )
diff --git a/go.sum b/go.sum
index 7285415..d1d77ae 100644
--- a/go.sum
+++ b/go.sum
@@ -63,7 +63,6 @@ github.com/docker/distribution v2.7.1+incompatible h1:a5mlkVzth6W5A4fOsS3D2EO5BU
 github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
 github.com/docker/docker v0.0.0-20190404075923-dbe4a30928d4 h1:34LfsqlE2kEvmGP9qbRoPvOWkmluYGzmlvWVTzwvT0A=
 github.com/docker/docker v0.0.0-20190404075923-dbe4a30928d4/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
-github.com/docker/docker v1.13.1 h1:IkZjBSIc8hBjLpqeAbeE5mca5mNgeatLHBy3GO78BWo=
 github.com/docker/docker-credential-helpers v0.6.1 h1:Dq4iIfcM7cNtddhLVWe9h4QDjsi4OER3Z8voPu/I52g=
 github.com/docker/docker-credential-helpers v0.6.1/go.mod h1:WRaJzqw3CTB9bk10avuGsjVBZsD05qeibJ1/TYlvc0Y=
 github.com/docker/go v1.5.1-1 h1:hr4w35acWBPhGBXlzPoHpmZ/ygPjnmFVxGxxGnMyP7k=
@@ -106,6 +105,13 @@ github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfb
 github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
 github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg=
 github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
+github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
+github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
+github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
+github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
+github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
+github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0=
+github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
 github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
 github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
 github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
@@ -115,6 +121,9 @@ github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ=
 github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
 github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY=
 github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
+github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
+github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4=
+github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
 github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
 github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
 github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
@@ -191,9 +200,13 @@ github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+W
 github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
 github.com/onsi/ginkgo v1.8.0 h1:VkHVNpR4iVnU8XQR6DBm8BqYjN7CRzw+xKUbVVbbW9w=
 github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
+github.com/onsi/ginkgo v1.11.0 h1:JAKSXpt1YjtLA7YpPiqO9ss6sNXEsPfSGdwN0UHqzrw=
+github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
 github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
 github.com/onsi/gomega v1.5.0 h1:izbySO9zDPmjJ8rDjLvkA2zJHIo+HkYXHnf7eN7SSyo=
 github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
+github.com/onsi/gomega v1.10.0 h1:Gwkk+PTu/nfOwNMtUB/mRUv0X7ewW5dO4AERT1ThVKo=
+github.com/onsi/gomega v1.10.0/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA=
 github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk=
 github.com/opencontainers/go-digest v1.0.0-rc1 h1:WzifXhOVOEOuFYOJAW6aQqW0TooG2iki3E3Ii+WN7gQ=
 github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
@@ -280,6 +293,8 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk
 golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
 golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4 h1:HuIa8hRrWRSrqYzx1qI49NNxhdi2PrY7gxVSq1JjLDc=
 golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI=
+golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
 golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
 golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
 golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
@@ -297,7 +312,8 @@ golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn
 golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
 golang.org/x/net v0.0.0-20190522155817-f3200d17e092 h1:4QSRKanuywn15aTZvI/mIDEgPQpswuFndXpOj3rKEco=
 golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
-golang.org/x/net v0.0.0-20191116160921-f9c825593386 h1:ktbWvQrW08Txdxno1PiDpSxPXG6ndGsfnJjRRtkM0LQ=
+golang.org/x/net v0.0.0-20191004110552-13f9640d40b9 h1:rjwSpXsdiK0dV8/Naq3kAw9ymfAeJIyd0upUIElB+lI=
+golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
 golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
 golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -314,24 +330,31 @@ golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5h
 golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
-golang.org/x/sys v0.0.0-20190412213103-97732733099d h1:+R4KGOnez64A81RvjARKc4UT5/tI9ujCIVX+P5KiHuI=
 golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190830141801-acfa387b8d69 h1:Wdn4Yb8d5VrsO3jWgaeSZss09x1VLVBMePDh4VW/xSQ=
+golang.org/x/sys v0.0.0-20190830141801-acfa387b8d69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2 h1:z99zHgr7hKfrUcX/KsoJk5FJfjTceCKIp96+biqP4To=
 golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/text v0.3.4 h1:0YWbFKbhXG/wIiuHDSKpS0Iy7FSA+u45VtBMfQcFTTc=
+golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 h1:SvFZT6jyqRaOeXpc5h/JSfZenJ2O330aBsf7JfSUXmQ=
 golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
 golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
 golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
 golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
 golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
+golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk=
 google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
 google.golang.org/appengine v1.4.0 h1:/wp5JvzpHIxhs/dumFmF7BXTf3Z+dd4uXta4kVyO508=
@@ -344,6 +367,13 @@ google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3
 google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
 google.golang.org/grpc v1.21.0 h1:G+97AoqBnmZIT91cLG/EkCoK9NSelj64P8bOHHNmGn0=
 google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
+google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
+google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
+google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
+google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
+google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
+google.golang.org/protobuf v1.23.0 h1:4MY060fB1DLGMB/7MBTLnwQUY6+F09GEiz6SsrNqyzM=
+google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
 gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc=
 gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
@@ -364,6 +394,9 @@ gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bl
 gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
 gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
+gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
 gosrc.io/xmpp v0.1.1 h1:iMtE9W3fx254+4E6rI34AOPJDqWvpfQR6EYaVMzhJ4s=
 gosrc.io/xmpp v0.1.1/go.mod h1:4JgaXzw4MnEv2sGltONtK3GMhj+h9gpQ7cO8nwbFJLU=
 gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=
diff --git a/internal/actions/check.go b/internal/actions/check.go
index 56a9fc4..aeff0cd 100644
--- a/internal/actions/check.go
+++ b/internal/actions/check.go
@@ -10,7 +10,7 @@ import (
 	"github.com/containrrr/watchtower/pkg/filters"
 	"github.com/containrrr/watchtower/pkg/sorter"
 
-	"github.com/opencontainers/runc/Godeps/_workspace/src/github.com/Sirupsen/logrus"
+	"github.com/sirupsen/logrus"
 
 	log "github.com/sirupsen/logrus"
 
diff --git a/internal/actions/mocks/container.go b/internal/actions/mocks/container.go
index e92ee1c..1db8652 100644
--- a/internal/actions/mocks/container.go
+++ b/internal/actions/mocks/container.go
@@ -17,6 +17,7 @@ func CreateMockContainer(id string, name string, image string, created time.Time
 			Created: created.String(),
 		},
 		Config: &container2.Config{
+			Image:  image,
 			Labels: make(map[string]string),
 		},
 	}
@@ -24,10 +25,40 @@ func CreateMockContainer(id string, name string, image string, created time.Time
 		&content,
 		&types.ImageInspect{
 			ID: image,
+			RepoDigests: []string{
+				image,
+			},
 		},
 	)
 }
 
+// CreateMockContainerWithImageInfo should only be used for testing
+func CreateMockContainerWithImageInfo(id string, name string, image string, created time.Time, imageInfo types.ImageInspect) container.Container {
+	content := types.ContainerJSON{
+		ContainerJSONBase: &types.ContainerJSONBase{
+			ID:      id,
+			Image:   image,
+			Name:    name,
+			Created: created.String(),
+		},
+		Config: &container2.Config{
+			Image:  image,
+			Labels: make(map[string]string),
+		},
+	}
+	return *container.NewContainer(
+		&content,
+		&imageInfo,
+	)
+}
+
+// CreateMockContainerWithDigest should only be used for testing
+func CreateMockContainerWithDigest(id string, name string, image string, created time.Time, digest string) container.Container {
+	c := CreateMockContainer(id, name, image, created)
+	c.ImageInfo().RepoDigests = []string{digest}
+	return c
+}
+
 // CreateMockContainerWithConfig creates a container substitute valid for testing
 func CreateMockContainerWithConfig(id string, name string, image string, created time.Time, config *container2.Config) container.Container {
 	content := types.ContainerJSON{
diff --git a/internal/flags/flags.go b/internal/flags/flags.go
index c7c98b1..163eefc 100644
--- a/internal/flags/flags.go
+++ b/internal/flags/flags.go
@@ -300,10 +300,11 @@ Should only be used for testing.`)
 
 // SetDefaults provides default values for environment variables
 func SetDefaults() {
+	day := time.Hour * 24 / time.Second
 	viper.AutomaticEnv()
 	viper.SetDefault("DOCKER_HOST", "unix:///var/run/docker.sock")
 	viper.SetDefault("DOCKER_API_VERSION", DockerAPIMinVersion)
-	viper.SetDefault("WATCHTOWER_POLL_INTERVAL", 300)
+	viper.SetDefault("WATCHTOWER_POLL_INTERVAL", day)
 	viper.SetDefault("WATCHTOWER_TIMEOUT", time.Second*10)
 	viper.SetDefault("WATCHTOWER_NOTIFICATIONS", []string{})
 	viper.SetDefault("WATCHTOWER_NOTIFICATIONS_LEVEL", "info")
diff --git a/pkg/container/client.go b/pkg/container/client.go
index a333ea5..ce694d0 100644
--- a/pkg/container/client.go
+++ b/pkg/container/client.go
@@ -8,6 +8,7 @@ import (
 	"time"
 
 	"github.com/containrrr/watchtower/pkg/registry"
+	"github.com/containrrr/watchtower/pkg/registry/digest"
 
 	t "github.com/containrrr/watchtower/pkg/types"
 	"github.com/docker/docker/api/types"
@@ -275,14 +276,36 @@ func (client dockerClient) HasNewImage(ctx context.Context, container Container)
 func (client dockerClient) PullImage(ctx context.Context, container Container) error {
 	containerName := container.Name()
 	imageName := container.ImageName()
-	log.Debugf("Pulling %s for %s", imageName, containerName)
 
+	fields := log.Fields{
+		"image":     imageName,
+		"container": containerName,
+	}
+
+	log.WithFields(fields).Debugf("Trying to load authentication credentials.")
 	opts, err := registry.GetPullOptions(imageName)
+	if opts.RegistryAuth != "" {
+		log.Debug("Credentials loaded")
+	}
 	if err != nil {
 		log.Debugf("Error loading authentication credentials %s", err)
 		return err
 	}
 
+	log.WithFields(fields).Debugf("Checking if pull is needed")
+
+	if match, err := digest.CompareDigest(container, opts.RegistryAuth); err != nil {
+		log.Info("Could not do a head request, falling back to regulara pull.")
+		log.Debugf("Reason: %s", err.Error())
+	} else if match {
+		log.Debug("No pull needed. Skipping image.")
+		return nil
+	} else {
+		log.Debug("Digests did not match, doing a pull.")
+	}
+
+	log.WithFields(fields).Debugf("Pulling image")
+
 	response, err := client.api.ImagePull(ctx, imageName, opts)
 	if err != nil {
 		log.Debugf("Error pulling image %s, %s", imageName, err)
diff --git a/pkg/container/container.go b/pkg/container/container.go
index 9e339c3..8a9d39e 100644
--- a/pkg/container/container.go
+++ b/pkg/container/container.go
@@ -253,3 +253,8 @@ func (c Container) hostConfig() *dockercontainer.HostConfig {
 func (c Container) HasImageInfo() bool {
 	return c.imageInfo != nil
 }
+
+// ImageInfo fetches the ImageInspect data of the current container
+func (c Container) ImageInfo() *types.ImageInspect {
+	return c.imageInfo
+}
diff --git a/pkg/registry/auth/auth.go b/pkg/registry/auth/auth.go
new file mode 100644
index 0000000..56f64a2
--- /dev/null
+++ b/pkg/registry/auth/auth.go
@@ -0,0 +1,168 @@
+package auth
+
+import (
+	"encoding/json"
+	"errors"
+	"fmt"
+	"github.com/containrrr/watchtower/pkg/registry/helpers"
+	"github.com/containrrr/watchtower/pkg/types"
+	"github.com/docker/distribution/reference"
+	"github.com/sirupsen/logrus"
+	"io/ioutil"
+	"net/http"
+	"net/url"
+	"strings"
+)
+
+// ChallengeHeader is the HTTP Header containing challenge instructions
+const ChallengeHeader = "WWW-Authenticate"
+
+// GetToken fetches a token for the registry hosting the provided image
+func GetToken(container types.Container, registryAuth string) (string, error) {
+	var err error
+	var URL url.URL
+
+	if URL, err = GetChallengeURL(container.ImageName()); err != nil {
+		return "", err
+	}
+	logrus.WithField("URL", URL.String()).Debug("Building challenge URL")
+
+	var req *http.Request
+	if req, err = GetChallengeRequest(URL); err != nil {
+		return "", err
+	}
+
+	client := &http.Client{}
+	var res *http.Response
+	if res, err = client.Do(req); err != nil {
+		return "", err
+	}
+
+	v := res.Header.Get(ChallengeHeader)
+
+	logrus.WithFields(logrus.Fields{
+		"status": res.Status,
+		"header": v,
+	}).Debug("Got response to challenge request")
+
+	challenge := strings.ToLower(v)
+	if strings.HasPrefix(challenge, "basic") {
+		if registryAuth == "" {
+			return "", fmt.Errorf("no credentials available")
+		}
+
+		return fmt.Sprintf("Basic %s", registryAuth), nil
+	}
+	if strings.HasPrefix(challenge, "bearer") {
+		return GetBearerHeader(challenge, container.ImageName(), err, registryAuth)
+	}
+
+	return "", errors.New("unsupported challenge type from registry")
+}
+
+// GetChallengeRequest creates a request for getting challenge instructions
+func GetChallengeRequest(URL url.URL) (*http.Request, error) {
+	req, err := http.NewRequest("GET", URL.String(), nil)
+	if err != nil {
+		return nil, err
+	}
+	req.Header.Set("Accept", "*/*")
+	req.Header.Set("User-Agent", "Watchtower (Docker)")
+	return req, nil
+}
+
+// GetBearerHeader tries to fetch a bearer token from the registry based on the challenge instructions
+func GetBearerHeader(challenge string, img string, err error, registryAuth string) (string, error) {
+	client := http.Client{}
+	if strings.Contains(img, ":") {
+		img = strings.Split(img, ":")[0]
+	}
+	authURL, err := GetAuthURL(challenge, img)
+
+	if err != nil {
+		return "", err
+	}
+
+	var r *http.Request
+	if r, err = http.NewRequest("GET", authURL.String(), nil); err != nil {
+		return "", err
+	}
+
+	if registryAuth != "" {
+		logrus.WithField("credentials", registryAuth).Debug("Credentials found.")
+		r.Header.Add("Authorization", fmt.Sprintf("Basic %s", registryAuth))
+	} else {
+		logrus.Debug("No credentials found.")
+	}
+
+	var authResponse *http.Response
+	if authResponse, err = client.Do(r); err != nil {
+		return "", err
+	}
+
+	body, _ := ioutil.ReadAll(authResponse.Body)
+	tokenResponse := &types.TokenResponse{}
+
+	err = json.Unmarshal(body, tokenResponse)
+	if err != nil {
+		return "", err
+	}
+
+	return fmt.Sprintf("Bearer %s", tokenResponse.Token), nil
+}
+
+// GetAuthURL from the instructions in the challenge
+func GetAuthURL(challenge string, img string) (*url.URL, error) {
+	loweredChallenge := strings.ToLower(challenge)
+	raw := strings.TrimPrefix(loweredChallenge, "bearer")
+
+	pairs := strings.Split(raw, ",")
+	values := make(map[string]string, len(pairs))
+
+	for _, pair := range pairs {
+		trimmed := strings.Trim(pair, " ")
+		kv := strings.Split(trimmed, "=")
+		key := kv[0]
+		val := strings.Trim(kv[1], "\"")
+		values[key] = val
+	}
+	logrus.WithFields(logrus.Fields{
+		"realm":   values["realm"],
+		"service": values["service"],
+	}).Debug("Checking challenge header content")
+	if values["realm"] == "" || values["service"] == "" {
+
+		return nil, fmt.Errorf("challenge header did not include all values needed to construct an auth url")
+	}
+
+	authURL, _ := url.Parse(fmt.Sprintf("%s", values["realm"]))
+	q := authURL.Query()
+	q.Add("service", values["service"])
+	scopeImage := strings.TrimPrefix(img, values["service"])
+	if !strings.Contains(scopeImage, "/") {
+		scopeImage = "library/" + scopeImage
+	}
+	scope := fmt.Sprintf("repository:%s:pull", scopeImage)
+	logrus.WithFields(logrus.Fields{"scope": scope, "image": img}).Debug("Setting scope for auth token")
+	q.Add("scope", scope)
+
+	authURL.RawQuery = q.Encode()
+	return authURL, nil
+}
+
+// GetChallengeURL creates a URL object based on the image info
+func GetChallengeURL(img string) (url.URL, error) {
+
+	normalizedNamed, _ := reference.ParseNormalizedNamed(img)
+	host, err := helpers.NormalizeRegistry(normalizedNamed.String())
+	if err != nil {
+		return url.URL{}, err
+	}
+
+	URL := url.URL{
+		Scheme: "https",
+		Host:   host,
+		Path:   "/v2/",
+	}
+	return URL, nil
+}
diff --git a/pkg/registry/digest/digest.go b/pkg/registry/digest/digest.go
new file mode 100644
index 0000000..aae8dfb
--- /dev/null
+++ b/pkg/registry/digest/digest.go
@@ -0,0 +1,98 @@
+package digest
+
+import (
+	"crypto/tls"
+	"encoding/base64"
+	"encoding/json"
+	"errors"
+	"fmt"
+	"github.com/containrrr/watchtower/pkg/registry/auth"
+	"github.com/containrrr/watchtower/pkg/registry/manifest"
+	"github.com/containrrr/watchtower/pkg/types"
+	"github.com/sirupsen/logrus"
+	"net/http"
+	"strings"
+)
+
+// ContentDigestHeader is the key for the key-value pair containing the digest header
+const ContentDigestHeader = "Docker-Content-Digest"
+
+// CompareDigest ...
+func CompareDigest(container types.Container, registryAuth string) (bool, error) {
+	var digest string
+
+	registryAuth = TransformAuth(registryAuth)
+	token, err := auth.GetToken(container, registryAuth)
+	if err != nil {
+		return false, err
+	}
+
+	digestURL, err := manifest.BuildManifestURL(container)
+	if err != nil {
+		return false, err
+	}
+
+	if digest, err = GetDigest(digestURL, token); err != nil {
+		return false, err
+	}
+
+	logrus.WithField("remote", digest).Debug("Found a remote digest to compare with")
+
+	for _, dig := range container.ImageInfo().RepoDigests {
+		localDigest := strings.Split(dig, "@")[1]
+		fields := logrus.Fields{"local": localDigest, "remote": digest}
+		logrus.WithFields(fields).Debug("Comparing")
+
+		if localDigest == digest {
+			logrus.Debug("Found a match")
+			return true, nil
+		}
+	}
+
+	return false, nil
+}
+
+// TransformAuth from a base64 encoded json object to base64 encoded string
+func TransformAuth(registryAuth string) string {
+	b, _ := base64.StdEncoding.DecodeString(registryAuth)
+	credentials := &types.RegistryCredentials{}
+	_ = json.Unmarshal(b, credentials)
+
+	if credentials.Username != "" && credentials.Password != "" {
+		ba := []byte(fmt.Sprintf("%s:%s", credentials.Username, credentials.Password))
+		registryAuth = base64.StdEncoding.EncodeToString(ba)
+	}
+
+	return registryAuth
+}
+
+// GetDigest from registry using a HEAD request to prevent rate limiting
+func GetDigest(url string, token string) (string, error) {
+	tr := &http.Transport{
+		TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
+	}
+	client := &http.Client{Transport: tr}
+
+	if token != "" {
+		logrus.WithField("token", token).Trace("Setting request token")
+	} else {
+		return "", errors.New("could not fetch token")
+	}
+
+	req, _ := http.NewRequest("HEAD", url, nil)
+	req.Header.Add("Authorization", token)
+	req.Header.Add("Accept", "application/vnd.docker.distribution.manifest.v2+json")
+	req.Header.Add("Accept", "application/vnd.docker.distribution.manifest.list.v2+json")
+	req.Header.Add("Accept", "application/vnd.docker.distribution.manifest.v1+json")
+
+	logrus.WithField("url", url).Debug("Doing a HEAD request to fetch a digest")
+
+	res, err := client.Do(req)
+	if err != nil {
+		return "", err
+	}
+	if res.StatusCode != 200 {
+		return "", fmt.Errorf("registry responded to head request with %d", res.StatusCode)
+	}
+	return res.Header.Get(ContentDigestHeader), nil
+}
diff --git a/pkg/registry/helpers/helpers.go b/pkg/registry/helpers/helpers.go
new file mode 100644
index 0000000..1469331
--- /dev/null
+++ b/pkg/registry/helpers/helpers.go
@@ -0,0 +1,36 @@
+package helpers
+
+import (
+	"fmt"
+	url2 "net/url"
+)
+
+// ConvertToHostname strips a url from everything but the hostname part
+func ConvertToHostname(url string) (string, string, error) {
+	urlWithSchema := fmt.Sprintf("x://%s", url)
+	u, err := url2.Parse(urlWithSchema)
+	if err != nil {
+		return "", "", err
+	}
+	hostName := u.Hostname()
+	port := u.Port()
+
+	return hostName, port, err
+}
+
+// NormalizeRegistry makes sure variations of DockerHubs registry
+func NormalizeRegistry(registry string) (string, error) {
+	hostName, port, err := ConvertToHostname(registry)
+	if err != nil {
+		return "", err
+	}
+
+	if hostName == "registry-1.docker.io" || hostName == "docker.io" {
+		hostName = "index.docker.io"
+	}
+
+	if port != "" {
+		return fmt.Sprintf("%s:%s", hostName, port), nil
+	}
+	return hostName, nil
+}
diff --git a/pkg/registry/manifest/manifest.go b/pkg/registry/manifest/manifest.go
new file mode 100644
index 0000000..837bc3f
--- /dev/null
+++ b/pkg/registry/manifest/manifest.go
@@ -0,0 +1,64 @@
+package manifest
+
+import (
+	"fmt"
+	"github.com/containrrr/watchtower/pkg/registry/helpers"
+	"github.com/containrrr/watchtower/pkg/types"
+	ref "github.com/docker/distribution/reference"
+	"github.com/sirupsen/logrus"
+	url2 "net/url"
+	"strings"
+)
+
+// BuildManifestURL from raw image data
+func BuildManifestURL(container types.Container) (string, error) {
+
+	normalizedName, err := ref.ParseNormalizedNamed(container.ImageName())
+	if err != nil {
+		return "", err
+	}
+
+	host, err := helpers.NormalizeRegistry(normalizedName.String())
+	img, tag := extractImageAndTag(strings.TrimPrefix(container.ImageName(), host+"/"))
+
+	logrus.WithFields(logrus.Fields{
+		"image":      img,
+		"tag":        tag,
+		"normalized": normalizedName,
+		"host":       host,
+	}).Debug("Parsing image ref")
+
+	if err != nil {
+		return "", err
+	}
+	img = strings.TrimPrefix(img, fmt.Sprintf("%s/", host))
+	if !strings.Contains(img, "/") {
+		img = "library/" + img
+	}
+	url := url2.URL{
+		Scheme: "https",
+		Host:   host,
+		Path:   fmt.Sprintf("/v2/%s/manifests/%s", img, tag),
+	}
+	return url.String(), nil
+}
+
+func extractImageAndTag(imageName string) (string, string) {
+	var img string
+	var tag string
+
+	if strings.Contains(imageName, ":") {
+		parts := strings.Split(imageName, ":")
+		if len(parts) > 2 {
+			img = fmt.Sprintf("%s%s", parts[0], parts[1])
+			tag = parts[3]
+		} else {
+			img = parts[0]
+			tag = parts[1]
+		}
+	} else {
+		img = imageName
+		tag = "latest"
+	}
+	return img, tag
+}
diff --git a/pkg/registry/trust.go b/pkg/registry/trust.go
index 937d2c3..c2bf7da 100644
--- a/pkg/registry/trust.go
+++ b/pkg/registry/trust.go
@@ -66,7 +66,7 @@ func EncodedConfigAuth(ref string) (string, error) {
 	auth, _ := credStore.Get(server) // returns (types.AuthConfig{}) if server not in credStore
 
 	if auth == (types.AuthConfig{}) {
-		log.Debugf("No credentials for %s in %s", server, configFile.Filename)
+		log.WithField("config_file", configFile.Filename).Debugf("No credentials for %s found", server)
 		return "", nil
 	}
 	log.Debugf("Loaded auth credentials for user %s, on registry %s, from file %s", auth.Username, ref, configFile.Filename)
diff --git a/pkg/types/container.go b/pkg/types/container.go
new file mode 100644
index 0000000..50baac6
--- /dev/null
+++ b/pkg/types/container.go
@@ -0,0 +1,26 @@
+package types
+
+import "github.com/docker/docker/api/types"
+
+// Container is a docker container running an image
+type Container interface {
+	ContainerInfo() *types.ContainerJSON
+	ID() string
+	IsRunning() bool
+	Name() string
+	ImageID() string
+	ImageName() string
+	Enabled() (bool, bool)
+	IsMonitorOnly() bool
+	Scope() (string, bool)
+	Links() []string
+	ToRestart() bool
+	IsWatchtower() bool
+	StopSignal() string
+	HasImageInfo() bool
+	ImageInfo() *types.ImageInspect
+	GetLifecyclePreCheckCommand() string
+	GetLifecyclePostCheckCommand() string
+	GetLifecyclePreUpdateCommand() string
+	GetLifecyclePostUpdateCommand() string
+}
diff --git a/pkg/types/registry_credentials.go b/pkg/types/registry_credentials.go
new file mode 100644
index 0000000..607fa05
--- /dev/null
+++ b/pkg/types/registry_credentials.go
@@ -0,0 +1,7 @@
+package types
+
+// RegistryCredentials is a credential pair used for basic auth
+type RegistryCredentials struct {
+	Username string
+	Password string // usually a token rather than an actual password
+}
diff --git a/pkg/types/token_response.go b/pkg/types/token_response.go
new file mode 100644
index 0000000..722dde8
--- /dev/null
+++ b/pkg/types/token_response.go
@@ -0,0 +1,6 @@
+package types
+
+// TokenResponse is returned by the registry on successful authentication
+type TokenResponse struct {
+	Token string `json:"token"`
+}


Test patch:
diff --git a/pkg/registry/auth/auth_test.go b/pkg/registry/auth/auth_test.go
new file mode 100644
index 0000000..16a6478
--- /dev/null
+++ b/pkg/registry/auth/auth_test.go
@@ -0,0 +1,98 @@
+package auth_test
+
+import (
+	"fmt"
+	"github.com/containrrr/watchtower/internal/actions/mocks"
+	"github.com/containrrr/watchtower/pkg/registry/auth"
+	"net/url"
+	"os"
+	"testing"
+	"time"
+
+	wtTypes "github.com/containrrr/watchtower/pkg/types"
+	. "github.com/onsi/ginkgo"
+	. "github.com/onsi/gomega"
+)
+
+func TestAuth(t *testing.T) {
+	RegisterFailHandler(Fail)
+	RunSpecs(t, "Registry Auth Suite")
+}
+func SkipIfCredentialsEmpty(credentials *wtTypes.RegistryCredentials, fn func()) func() {
+	if credentials.Username == "" {
+		return func() {
+			Skip("Username missing. Skipping integration test")
+		}
+	} else if credentials.Password == "" {
+		return func() {
+			Skip("Password missing. Skipping integration test")
+		}
+	} else {
+		return fn
+	}
+}
+
+var GHCRCredentials = &wtTypes.RegistryCredentials{
+	Username: os.Getenv("CI_INTEGRATION_TEST_REGISTRY_GH_USERNAME"),
+	Password: os.Getenv("CI_INTEGRATION_TEST_REGISTRY_GH_PASSWORD"),
+}
+
+var _ = Describe("the auth module", func() {
+	mockId := "mock-id"
+	mockName := "mock-container"
+	mockImage := "ghcr.io/k6io/operator:latest"
+	mockCreated := time.Now()
+	mockDigest := "ghcr.io/k6io/operator@sha256:d68e1e532088964195ad3a0a71526bc2f11a78de0def85629beb75e2265f0547"
+
+	mockContainer := mocks.CreateMockContainerWithDigest(
+		mockId,
+		mockName,
+		mockImage,
+		mockCreated,
+		mockDigest)
+
+	When("getting an auth url", func() {
+		It("should parse the token from the response",
+			SkipIfCredentialsEmpty(GHCRCredentials, func() {
+				creds := fmt.Sprintf("%s:%s", GHCRCredentials.Username, GHCRCredentials.Password)
+				token, err := auth.GetToken(mockContainer, creds)
+				Expect(err).NotTo(HaveOccurred())
+				Expect(token).NotTo(Equal(""))
+			}),
+		)
+
+		It("should create a valid auth url object based on the challenge header supplied", func() {
+			input := `bearer realm="https://ghcr.io/token",service="ghcr.io",scope="repository:user/image:pull"`
+			expected := &url.URL{
+				Host:     "ghcr.io",
+				Scheme:   "https",
+				Path:     "/token",
+				RawQuery: "scope=repository%3Acontainrrr%2Fwatchtower%3Apull&service=ghcr.io",
+			}
+			res, err := auth.GetAuthURL(input, "containrrr/watchtower")
+			Expect(err).NotTo(HaveOccurred())
+			Expect(res).To(Equal(expected))
+		})
+		It("should create a valid auth url object based on the challenge header supplied", func() {
+			input := `bearer realm="https://ghcr.io/token"`
+			res, err := auth.GetAuthURL(input, "containrrr/watchtower")
+			Expect(err).To(HaveOccurred())
+			Expect(res).To(BeNil())
+		})
+	})
+	When("getting a challenge url", func() {
+		It("should create a valid challenge url object based on the image ref supplied", func() {
+			expected := url.URL{Host: "ghcr.io", Scheme: "https", Path: "/v2/"}
+			Expect(auth.GetChallengeURL("ghcr.io/containrrr/watchtower:latest")).To(Equal(expected))
+		})
+		It("should assume dockerhub if the image ref is not fully qualified", func() {
+			expected := url.URL{Host: "index.docker.io", Scheme: "https", Path: "/v2/"}
+			Expect(auth.GetChallengeURL("containrrr/watchtower:latest")).To(Equal(expected))
+		})
+		It("should convert legacy dockerhub hostnames to index.docker.io", func() {
+			expected := url.URL{Host: "index.docker.io", Scheme: "https", Path: "/v2/"}
+			Expect(auth.GetChallengeURL("docker.io/containrrr/watchtower:latest")).To(Equal(expected))
+			Expect(auth.GetChallengeURL("registry-1.docker.io/containrrr/watchtower:latest")).To(Equal(expected))
+		})
+	})
+})
diff --git a/pkg/registry/digest/digest_test.go b/pkg/registry/digest/digest_test.go
new file mode 100644
index 0000000..0de6025
--- /dev/null
+++ b/pkg/registry/digest/digest_test.go
@@ -0,0 +1,87 @@
+package digest_test
+
+import (
+	"fmt"
+	"github.com/containrrr/watchtower/internal/actions/mocks"
+	"github.com/containrrr/watchtower/pkg/registry/digest"
+	wtTypes "github.com/containrrr/watchtower/pkg/types"
+	. "github.com/onsi/ginkgo"
+	. "github.com/onsi/gomega"
+	"os"
+	"testing"
+	"time"
+)
+
+func TestDigest(t *testing.T) {
+
+	RegisterFailHandler(Fail)
+	RunSpecs(GinkgoT(), "Digest Suite")
+}
+
+var DockerHubCredentials = &wtTypes.RegistryCredentials{
+	Username: os.Getenv("CI_INTEGRATION_TEST_REGISTRY_DH_USERNAME"),
+	Password: os.Getenv("CI_INTEGRATION_TEST_REGISTRY_DH_PASSWORD"),
+}
+var GHCRCredentials = &wtTypes.RegistryCredentials{
+	Username: os.Getenv("CI_INTEGRATION_TEST_REGISTRY_GH_USERNAME"),
+	Password: os.Getenv("CI_INTEGRATION_TEST_REGISTRY_GH_PASSWORD"),
+}
+
+func SkipIfCredentialsEmpty(credentials *wtTypes.RegistryCredentials, fn func()) func() {
+	if credentials.Username == "" {
+		return func() {
+			Skip("Username missing. Skipping integration test")
+		}
+	} else if credentials.Password == "" {
+		return func() {
+			Skip("Password missing. Skipping integration test")
+		}
+	} else {
+		return fn
+	}
+}
+
+var _ = Describe("Digests", func() {
+	mockId := "mock-id"
+	mockName := "mock-container"
+	mockImage := "ghcr.io/k6io/operator:latest"
+	mockCreated := time.Now()
+	mockDigest := "ghcr.io/k6io/operator@sha256:d68e1e532088964195ad3a0a71526bc2f11a78de0def85629beb75e2265f0547"
+
+	mockContainer := mocks.CreateMockContainerWithDigest(
+		mockId,
+		mockName,
+		mockImage,
+		mockCreated,
+		mockDigest)
+
+	When("a digest comparison is done", func() {
+		It("should return true if digests match",
+			SkipIfCredentialsEmpty(GHCRCredentials, func() {
+				creds := fmt.Sprintf("%s:%s", GHCRCredentials.Username, GHCRCredentials.Password)
+				matches, err := digest.CompareDigest(mockContainer, creds)
+				Expect(err).NotTo(HaveOccurred())
+				Expect(matches).To(Equal(true))
+			}),
+		)
+
+		It("should return false if digests differ", func() {
+
+		})
+		It("should return an error if the registry isn't available", func() {
+
+		})
+	})
+	When("using different registries", func() {
+		It("should work with DockerHub",
+			SkipIfCredentialsEmpty(DockerHubCredentials, func() {
+				fmt.Println(DockerHubCredentials != nil) // to avoid crying linters
+			}),
+		)
+		It("should work with GitHub Container Registry",
+			SkipIfCredentialsEmpty(GHCRCredentials, func() {
+				fmt.Println(GHCRCredentials != nil) // to avoid crying linters
+			}),
+		)
+	})
+})
diff --git a/pkg/registry/helpers/helpers_test.go b/pkg/registry/helpers/helpers_test.go
new file mode 100644
index 0000000..92e9116
--- /dev/null
+++ b/pkg/registry/helpers/helpers_test.go
@@ -0,0 +1,31 @@
+package helpers
+
+import (
+	. "github.com/onsi/ginkgo"
+	. "github.com/onsi/gomega"
+	"testing"
+)
+
+func TestHelpers(t *testing.T) {
+	RegisterFailHandler(Fail)
+	RunSpecs(t, "Helper Suite")
+}
+
+var _ = Describe("the helpers", func() {
+
+	When("converting an url to a hostname", func() {
+		It("should return docker.io given docker.io/containrrr/watchtower:latest", func() {
+			host, port, err := ConvertToHostname("docker.io/containrrr/watchtower:latest")
+			Expect(err).NotTo(HaveOccurred())
+			Expect(host).To(Equal("docker.io"))
+			Expect(port).To(BeEmpty())
+		})
+	})
+	When("normalizing the registry information", func() {
+		It("should return index.docker.io given docker.io", func() {
+			out, err := NormalizeRegistry("docker.io/containrrr/watchtower:latest")
+			Expect(err).NotTo(HaveOccurred())
+			Expect(out).To(Equal("index.docker.io"))
+		})
+	})
+})
diff --git a/pkg/registry/manifest/manifest_test.go b/pkg/registry/manifest/manifest_test.go
new file mode 100644
index 0000000..3b86f90
--- /dev/null
+++ b/pkg/registry/manifest/manifest_test.go
@@ -0,0 +1,66 @@
+package manifest_test
+
+import (
+	"github.com/containrrr/watchtower/internal/actions/mocks"
+	"github.com/containrrr/watchtower/pkg/registry/manifest"
+	apiTypes "github.com/docker/docker/api/types"
+	. "github.com/onsi/ginkgo"
+	. "github.com/onsi/gomega"
+	"testing"
+	"time"
+)
+
+func TestManifest(t *testing.T) {
+	RegisterFailHandler(Fail)
+	RunSpecs(t, "Manifest Suite")
+}
+
+var _ = Describe("the manifest module", func() {
+	mockId := "mock-id"
+	mockName := "mock-container"
+	mockCreated := time.Now()
+
+	When("building a manifest url", func() {
+		It("should return a valid url given a fully qualified image", func() {
+			expected := "https://ghcr.io/v2/containrrr/watchtower/manifests/latest"
+			imageInfo := apiTypes.ImageInspect{
+				RepoTags: []string{
+					"ghcr.io/k6io/operator:latest",
+				},
+			}
+			mock := mocks.CreateMockContainerWithImageInfo(mockId, mockName, "ghcr.io/containrrr/watchtower:latest", mockCreated, imageInfo)
+			res, err := manifest.BuildManifestURL(mock)
+			Expect(err).NotTo(HaveOccurred())
+			Expect(res).To(Equal(expected))
+		})
+		It("should assume dockerhub for non-qualified images", func() {
+			expected := "https://index.docker.io/v2/containrrr/watchtower/manifests/latest"
+			imageInfo := apiTypes.ImageInspect{
+				RepoTags: []string{
+					"containrrr/watchtower:latest",
+				},
+			}
+
+			mock := mocks.CreateMockContainerWithImageInfo(mockId, mockName, "containrrr/watchtower:latest", mockCreated, imageInfo)
+			res, err := manifest.BuildManifestURL(mock)
+			Expect(err).NotTo(HaveOccurred())
+			Expect(res).To(Equal(expected))
+		})
+		It("should assume latest for images that lack an explicit tag", func() {
+			expected := "https://index.docker.io/v2/containrrr/watchtower/manifests/latest"
+			imageInfo := apiTypes.ImageInspect{
+
+				RepoTags: []string{
+					"containrrr/watchtower",
+				},
+			}
+
+			mock := mocks.CreateMockContainerWithImageInfo(mockId, mockName, "containrrr/watchtower", mockCreated, imageInfo)
+
+			res, err := manifest.BuildManifestURL(mock)
+			Expect(err).NotTo(HaveOccurred())
+			Expect(res).To(Equal(expected))
+		})
+	})
+
+})
diff --git a/pkg/registry/trust_test.go b/pkg/registry/trust_test.go
index 8ffe1b9..7d4d48d 100644
--- a/pkg/registry/trust_test.go
+++ b/pkg/registry/trust_test.go
@@ -1,59 +1,71 @@
 package registry
 
 import (
-	"github.com/stretchr/testify/assert"
+	. "github.com/onsi/ginkgo"
+	. "github.com/onsi/gomega"
 	"os"
 	"testing"
 )
 
-func TestEncodedEnvAuth_ShouldReturnAnErrorIfRepoEnvsAreUnset(t *testing.T) {
-	os.Unsetenv("REPO_USER")
-	os.Unsetenv("REPO_PASS")
-	_, err := EncodedEnvAuth("")
-	assert.Error(t, err)
+func TestTrust(t *testing.T) {
+	RegisterFailHandler(Fail)
+	RunSpecs(t, "Trust Suite")
 }
-func TestEncodedEnvAuth_ShouldReturnAuthHashIfRepoEnvsAreSet(t *testing.T) {
-	expectedHash := "eyJ1c2VybmFtZSI6ImNvbnRhaW5ycnItdXNlciIsInBhc3N3b3JkIjoiY29udGFpbnJyci1wYXNzIn0="
 
-	os.Setenv("REPO_USER", "containrrr-user")
-	os.Setenv("REPO_PASS", "containrrr-pass")
-	config, _ := EncodedEnvAuth("")
+var _ = Describe("Testing with Ginkgo", func() {
+	It("encoded env auth_ should return an error if repo envs are unset", func() {
+		_ = os.Unsetenv("REPO_USER")
+		_ = os.Unsetenv("REPO_PASS")
 
-	assert.Equal(t, config, expectedHash)
-}
+		_, err := EncodedEnvAuth("")
+		Expect(err).To(HaveOccurred())
+	})
+	It("encoded env auth_ should return auth hash if repo envs are set", func() {
+		var err error
+		expectedHash := "eyJ1c2VybmFtZSI6ImNvbnRhaW5ycnItdXNlciIsInBhc3N3b3JkIjoiY29udGFpbnJyci1wYXNzIn0="
 
-func TestEncodedConfigAuth_ShouldReturnAnErrorIfFileIsNotPresent(t *testing.T) {
-	os.Setenv("DOCKER_CONFIG", "/dev/null/should-fail")
-	_, err := EncodedConfigAuth("")
-	assert.Error(t, err)
-}
+		err = os.Setenv("REPO_USER", "containrrr-user")
+		Expect(err).NotTo(HaveOccurred())
 
-/*
- * TODO:
- * This part only confirms that it still works in the same way as it did
- * with the old version of the docker api client sdk. I'd say that
- * ParseServerAddress likely needs to be elaborated a bit to default to
- * dockerhub in case no server address was provided.
- *
- * ++ @simskij, 2019-04-04
- */
-
-func TestParseServerAddress_ShouldReturnErrorIfPassedEmptyString(t *testing.T) {
-	_, err := ParseServerAddress("")
-	assert.Error(t, err)
-}
+		err = os.Setenv("REPO_PASS", "containrrr-pass")
+		Expect(err).NotTo(HaveOccurred())
 
-func TestParseServerAddress_ShouldReturnTheRepoNameIfPassedAFullyQualifiedImageName(t *testing.T) {
-	val, _ := ParseServerAddress("github.com/containrrrr/config")
-	assert.Equal(t, val, "github.com")
-}
+		config, err := EncodedEnvAuth("")
+		Expect(config).To(Equal(expectedHash))
+		Expect(err).NotTo(HaveOccurred())
+	})
+	It("encoded config auth_ should return an error if file is not present", func() {
+		var err error
 
-func TestParseServerAddress_ShouldReturnTheOrganizationPartIfPassedAnImageNameMissingServerName(t *testing.T) {
-	val, _ := ParseServerAddress("containrrr/config")
-	assert.Equal(t, val, "containrrr")
-}
+		err = os.Setenv("DOCKER_CONFIG", "/dev/null/should-fail")
+		Expect(err).NotTo(HaveOccurred())
 
-func TestParseServerAddress_ShouldReturnTheServerNameIfPassedAFullyQualifiedImageName(t *testing.T) {
-	val, _ := ParseServerAddress("github.com/containrrrr/config")
-	assert.Equal(t, val, "github.com")
-}
+		_, err = EncodedConfigAuth("")
+		Expect(err).To(HaveOccurred())
+
+	})
+	/*
+	 * TODO:
+	 * This part only confirms that it still works in the same way as it did
+	 * with the old version of the docker api client sdk. I'd say that
+	 * ParseServerAddress likely needs to be elaborated a bit to default to
+	 * dockerhub in case no server address was provided.
+	 *
+	 * ++ @simskij, 2019-04-04
+	 */
+	It("parse server address_ should return error if passed empty string", func() {
+
+		_, err := ParseServerAddress("")
+		Expect(err).To(HaveOccurred())
+	})
+	It("parse server address_ should return the organization part if passed an image name missing server name", func() {
+
+		val, _ := ParseServerAddress("containrrr/config")
+		Expect(val).To(Equal("containrrr"))
+	})
+	It("parse server address_ should return the server name if passed a fully qualified image name", func() {
+
+		val, _ := ParseServerAddress("github.com/containrrrr/config")
+		Expect(val).To(Equal("github.com"))
+	})
+})