Repository: containrrr/watchtower
Pull request #594 (2020-07-06 11:37:12)

Warning if `WATCHTOWER_NO_PULL` and` WATCHTOWER_MONITOR_ONLY` are used simultaneously.
A warning was added if `WATCHTOWER_NO_PULL` and` WATCHTOWER_MONITOR_ONLY` are used simultaneously. #570 


Patch:
diff --git a/.all-contributorsrc b/.all-contributorsrc
index d96ff8c..cfeb640 100644
--- a/.all-contributorsrc
+++ b/.all-contributorsrc
@@ -620,6 +620,24 @@
       "contributions": [
         "code"
       ]
+    },
+    {
+      "login": "bugficks",
+      "name": "bugficks",
+      "avatar_url": "https://avatars1.githubusercontent.com/u/2992895?v=4",
+      "profile": "https://github.com/bugficks",
+      "contributions": [
+        "doc"
+      ]
+    },
+    {
+      "login": "MichaelSp",
+      "name": "Michael",
+      "avatar_url": "https://avatars0.githubusercontent.com/u/448282?v=4",
+      "profile": "https://github.com/MichaelSp",
+      "contributions": [
+        "code"
+      ]
     }
   ],
   "contributorsPerLine": 7,
diff --git a/README.md b/README.md
index 9826a5d..1a905bc 100644
--- a/README.md
+++ b/README.md
@@ -155,6 +155,8 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
     <td align="center"><a href="https://github.com/pgrimaud"><img src="https://avatars1.githubusercontent.com/u/1866496?v=4" width="100px;" alt=""/><br /><sub><b>Pierre Grimaud</b></sub></a><br /><a href="https://github.com/containrrr/watchtower/commits?author=pgrimaud" title="Documentation">📖</a></td>
     <td align="center"><a href="https://github.com/mattdoran"><img src="https://avatars0.githubusercontent.com/u/577779?v=4" width="100px;" alt=""/><br /><sub><b>Matt Doran</b></sub></a><br /><a href="https://github.com/containrrr/watchtower/commits?author=mattdoran" title="Documentation">📖</a></td>
     <td align="center"><a href="https://github.com/MihailITPlace"><img src="https://avatars2.githubusercontent.com/u/28401551?v=4" width="100px;" alt=""/><br /><sub><b>MihailITPlace</b></sub></a><br /><a href="https://github.com/containrrr/watchtower/commits?author=MihailITPlace" title="Code">💻</a></td>
+    <td align="center"><a href="https://github.com/bugficks"><img src="https://avatars1.githubusercontent.com/u/2992895?v=4" width="100px;" alt=""/><br /><sub><b>bugficks</b></sub></a><br /><a href="https://github.com/containrrr/watchtower/commits?author=bugficks" title="Documentation">📖</a></td>
+    <td align="center"><a href="https://github.com/MichaelSp"><img src="https://avatars0.githubusercontent.com/u/448282?v=4" width="100px;" alt=""/><br /><sub><b>Michael</b></sub></a><br /><a href="https://github.com/containrrr/watchtower/commits?author=MichaelSp" title="Code">💻</a></td>
   </tr>
 </table>
 
diff --git a/cmd/root.go b/cmd/root.go
index bef694c..d4839e6 100644
--- a/cmd/root.go
+++ b/cmd/root.go
@@ -102,6 +102,10 @@ func PreRun(cmd *cobra.Command, args []string) {
 	reviveStopped, _ := f.GetBool("revive-stopped")
 	removeVolumes, _ := f.GetBool("remove-volumes")
 
+	if monitorOnly && noPull {
+		log.Warn("Using `WATCHTOWER_NO_PULL` and `WATCHTOWER_MONITOR_ONLY` simultaneously might lead to no action being taken at all. If this is intentional, you may safely ignore this message.")
+	}
+
 	client = container.NewClient(
 		!noPull,
 		includeStopped,
diff --git a/docs/container-selection.md b/docs/container-selection.md
index 7283ce9..eea0c03 100644
--- a/docs/container-selection.md
+++ b/docs/container-selection.md
@@ -12,7 +12,7 @@ Or, it can be specified as part of the `docker run` command line:
 docker run -d --label=com.centurylinklabs.watchtower.enable=false someimage
 ```
 
-If you need to [include only containers with the enable label](https://containrrr.github.io/watchtower/arguments/#filter_by_enable_label), pass the `--label-enable` flag or the  `WATCTOWER_LABEL_ENABLE` environment variable on startup and set the _com.centurylinklabs.watchtower.enable_ label with a value of `true` for the containers you want to watch.
+If you need to [include only containers with the enable label](https://containrrr.github.io/watchtower/arguments/#filter_by_enable_label), pass the `--label-enable` flag or the `WATCHTOWER_LABEL_ENABLE` environment variable on startup and set the _com.centurylinklabs.watchtower.enable_ label with a value of `true` for the containers you want to watch.
 
 ```docker
 LABEL com.centurylinklabs.watchtower.enable="true"
diff --git a/docs/private-registries.md b/docs/private-registries.md
index dab0c46..147e307 100644
--- a/docs/private-registries.md
+++ b/docs/private-registries.md
@@ -32,9 +32,11 @@ echo -n 'username:password' | base64
 
 > ### ℹ️ Username and Password for GCloud
 >
-> For gcloud, we'll use `__json_key` as our username and the content
+> For gcloud, we'll use `_json_key` as our username and the content
 > of `gcloudauth.json` as the password.
-
+>```bash
+> echo -n "_json_key:$(cat gcloudauth.json)" | base64 -w0
+>```
 When the watchtower Docker container is started, the created configuration file
 (`<PATH>/config.json` in this example) needs to be passed to the container:
 
@@ -67,6 +69,21 @@ watchtower:
 [...]
 ```
 
+#### Docker Config path
+By default, watchtower will look for the `config.json` file in `/`, but this can be changed by setting the `DOCKER_CONFIG` environment variable to the directory path where your config is located. This is useful for setups where the config.json file is changed while the watchtower instance is running, as the changes will not be picked up for a mounted file if the inode changes.
+Example usage:
+
+```yaml
+watchtower:
+  image: containrrr/watchtower
+  environment:
+      DOCKER_CONFIG: /config
+    volumes:
+      - /etc/watchtower/config/:/config/
+      - /var/run/docker.sock:/var/run/docker.sock
+```
+
+
 ## Credential helpers
 Some private Docker registries (the most prominent probably being AWS ECR) use non-standard ways of authentication.
 To be able to use this together with watchtower, we need to use a credential helper.
diff --git a/pkg/lifecycle/lifecycle.go b/pkg/lifecycle/lifecycle.go
index 2d2d50c..df639d7 100644
--- a/pkg/lifecycle/lifecycle.go
+++ b/pkg/lifecycle/lifecycle.go
@@ -36,7 +36,7 @@ func ExecutePreCheckCommand(client container.Client, container container.Contain
 		return
 	}
 
-	log.Info("Executing pre-check command.")
+	log.Debug("Executing pre-check command.")
 	if err := client.ExecuteCommand(container.ID(), command, 1); err != nil {
 		log.Error(err)
 	}
@@ -50,7 +50,7 @@ func ExecutePostCheckCommand(client container.Client, container container.Contai
 		return
 	}
 
-	log.Info("Executing post-check command.")
+	log.Debug("Executing post-check command.")
 	if err := client.ExecuteCommand(container.ID(), command, 1); err != nil {
 		log.Error(err)
 	}
@@ -65,7 +65,7 @@ func ExecutePreUpdateCommand(client container.Client, container container.Contai
 		return nil
 	}
 
-	log.Info("Executing pre-update command.")
+	log.Debug("Executing pre-update command.")
 	return client.ExecuteCommand(container.ID(), command, timeout)
 }
 
@@ -83,7 +83,7 @@ func ExecutePostUpdateCommand(client container.Client, newContainerID string) {
 		return
 	}
 
-	log.Info("Executing post-update command.")
+	log.Debug("Executing post-update command.")
 	if err := client.ExecuteCommand(newContainerID, command, 1); err != nil {
 		log.Error(err)
 	}
diff --git a/pkg/notifications/shoutrrr.go b/pkg/notifications/shoutrrr.go
index 8cf3d7c..9a7cd62 100644
--- a/pkg/notifications/shoutrrr.go
+++ b/pkg/notifications/shoutrrr.go
@@ -4,6 +4,7 @@ import (
 	"bytes"
 	"fmt"
 	"text/template"
+    "strings"
 
 	"github.com/containrrr/shoutrrr"
 	"github.com/containrrr/shoutrrr/pkg/router"
@@ -109,10 +110,16 @@ func getShoutrrrTemplate(c *cobra.Command) *template.Template {
 
 	tplString, err := flags.GetString("notification-template")
 
+	funcs := template.FuncMap{
+		"ToUpper": strings.ToUpper,
+		"ToLower": strings.ToLower,
+		"Title": strings.Title,
+	}
+
 	// If we succeed in getting a non-empty template configuration
 	// try to parse the template string.
 	if tplString != "" && err == nil {
-		tpl, err = template.New("").Parse(tplString)
+		tpl, err = template.New("").Funcs(funcs).Parse(tplString)
 	}
 
 	// In case of errors (either from parsing the template string
@@ -128,7 +135,7 @@ func getShoutrrrTemplate(c *cobra.Command) *template.Template {
 	// template wasn't configured (the empty template string)
 	// fallback to using the default template.
 	if err != nil || tplString == "" {
-		tpl = template.Must(template.New("").Parse(shoutrrrDefaultTemplate))
+		tpl = template.Must(template.New("").Funcs(funcs).Parse(shoutrrrDefaultTemplate))
 	}
 
 	return tpl


Test patch:
diff --git a/pkg/notifications/shoutrrr_test.go b/pkg/notifications/shoutrrr_test.go
index 9795c2a..5db7473 100644
--- a/pkg/notifications/shoutrrr_test.go
+++ b/pkg/notifications/shoutrrr_test.go
@@ -51,6 +51,30 @@ func TestShoutrrrTemplate(t *testing.T) {
 	require.Equal(t, "info: foo bar\n", s)
 }
 
+func TestShoutrrrStringFunctions(t *testing.T) {
+	cmd := new(cobra.Command)
+	flags.RegisterNotificationFlags(cmd)
+	err := cmd.ParseFlags([]string{"--notification-template={{range .}}{{.Level | printf \"%v\" | ToUpper }}: {{.Message | ToLower }} {{.Message | Title }}{{println}}{{end}}"})
+
+	require.NoError(t, err)
+
+	shoutrrr := &shoutrrrTypeNotifier{
+		template: getShoutrrrTemplate(cmd),
+	}
+
+	entries := []*log.Entry{
+		{
+			Level:   log.InfoLevel,
+			Message: "foo Bar",
+		},
+	}
+
+	s := shoutrrr.buildMessage(entries)
+
+	require.Equal(t, "INFO: foo bar Foo Bar\n", s)
+}
+
+
 func TestShoutrrrInvalidTemplateUsesTemplate(t *testing.T) {
 	cmd := new(cobra.Command)