diff --git a/README.md b/README.md
index b423c67..dce9a20 100644
--- a/README.md
+++ b/README.md
@@ -236,6 +236,7 @@ Shell tasks support an extended syntax as well, which provides more fine-grained
| Option | Values | Default Value | Required | Description |
| --- | --- | --- | --- | --- |
+| `host` | `string` | - | No | The hostname of the machine this script should be executed on. Not supplying a host will result in the shell command executing on every host.
The hostname '-' can be specified as a default target that will match all hosts. |
| `command` | `string` | - | Yes | The command to be run. |
| `description` | `string` | - | No | A human-readable description. |
| `stdin` | `true`, `false` | `false` | No | Specifies if the standard input stream is enabled. |
diff --git a/snowsaw/plugins/shell.py b/snowsaw/plugins/shell.py
index 091c5ee..89d0913 100644
--- a/snowsaw/plugins/shell.py
+++ b/snowsaw/plugins/shell.py
@@ -3,6 +3,8 @@
import os
import subprocess
import snowsaw
+from socket import gethostname
+
class Shell(snowsaw.Plugin):
@@ -40,22 +42,33 @@ def _process_commands(self, data):
stdout = None
if item.get("stderr", defaults.get("stderr", False)) is True:
stderr = None
+ host = item.get("host", None)
elif isinstance(item, list):
cmd = item[0]
msg = item[1] if len(item) > 1 else None
else:
cmd = item
msg = None
- if msg is None:
- self._log.lowinfo(cmd)
- else:
- self._log.lowinfo('{} [{}]'.format(msg, cmd))
executable = os.environ.get("SHELL")
- ret = subprocess.call(cmd, shell=True, stdin=stdin, stdout=stdout, stderr=stderr, cwd=self._context.snowblock_dir(),
+ shouldExecute = False
+ if host is None:
+ shouldExecute = True
+ elif host == gethostname():
+ shouldExecute = True
+ elif host == "-":
+ shouldExecute = True
+ if shouldExecute:
+ if msg is None:
+ self._log.lowinfo(cmd)
+ else:
+ self._log.lowinfo('{} [{}]'.format(msg, cmd))
+ ret = subprocess.call(cmd, shell=True, stdin=stdin, stdout=stdout, stderr=stderr, cwd=self._context.snowblock_dir(),
executable=executable)
- if ret != 0:
- success = False
- self._log.warning("Command [{}] failed".format(cmd))
+ if ret != 0:
+ success = False
+ self._log.warning("Command [{}] failed".format(cmd))
+ else:
+ self._log.lowinfo("Skipping command [{}]".format(cmd))
if success:
self._log.info("=> All commands have been executed")
else: