From e577cfeabb7b913e7690f451e971d2257c74f89a Mon Sep 17 00:00:00 2001 From: Melvin Witte Date: Sat, 21 Apr 2018 09:16:51 +0200 Subject: [PATCH 1/5] Change 'command' from events to 'commands' and support multiline command line calls in it --- README.md | 27 ++++++++++++++++----------- eventWorker.py | 14 ++++++++------ 2 files changed, 24 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index 8d2bb5f..2cac72b 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ python main.py example.yaml ## YAML-File -The YAML-File needs two keys, `setup` and `events` on the base level. +The YAML-File needs two keys, `setup` and `events` on the base level. ```yaml setup: # docker-compose setup @@ -22,7 +22,7 @@ events: # processed by event engine ``` -The setup part will be piped directly to docker-compose. +The setup part will be piped directly to docker-compose. This means, the whole part of container setup is managed by docker-compose. You can use each version of the docker-compose-file and all supported features. @@ -44,14 +44,17 @@ Each event can be directly identified with the key and has the following structu event1: dependOn: seconds: - command: + commands: + - command1 + - command2 + - .... do: ``` -The first three keys describes when the `do`-block should be executed. +The first three keys describes when the `do`-block should be executed. The order of these conditions is as shown above. -This means for example that after the events this event1 dependsOn have returned, the program waited a few seconds and the command has succesfully been executed the do-part of this event will be executed. +This means for example that after the events this event1 dependsOn have returned, the program waited a few seconds and the commands have succesfully been executed the do-part of this event will be executed. #### dependOn `dependOn` takes a list of other events (identified with their keys). @@ -73,14 +76,16 @@ seconds: 5 ``` This means the execution waits 5 seconds. -#### command -It can execute any command and if this command returns `1`, the `do`-block will be executed. +#### commands +It can execute any list of commands and if this command returns `1`, the `do`-block will be executed. Example: ```yaml -command: "ping -c 1 192.168.1.2" +command: + - ping -c 1 192.168.1.2 + - ls ``` -This would test if the computer with the IP-address `192.168.1.2` is reachable and execute the `do`-block (if there is an connection) once the command returned `1`. +This would test if the computer with the IP-address `192.168.1.2` is reachable and execute the `do`-block (if there is an connection) once the command returned `1`. Afterwards it executes ls and executes the `do`-block if ls fails. #### do The `do`-block will be executed when all conditions (see above) were processed. @@ -139,7 +144,7 @@ The value `container` are the identifiers of the containers, specified in the se The action will create a new network and add these containers to the network. The sorted list of the containers is the key of the network (not the name). -The value of `internal` can be `True` or `False`. +The value of `internal` can be `True` or `False`. It maps to the [internal flag](https://docs.docker.com/engine/reference/commandline/network_create/#network-internal-mode) of docker. The `mode` can be any of `row`, `ring` or `cluster`. @@ -195,7 +200,7 @@ restartContainer: ["Node3"] This example starts `Node1`, stops `Node2` and restarts `Node3`. #### delay, duplicate, corrupt and loss -These actions use the linux network emulator `netem`. +These actions use the linux network emulator `netem`. Make sure that your container support this network emulator when using this command. Have a look at the [documentation](http://man7.org/linux/man-pages/man8/tc-netem.8.html) for details. diff --git a/eventWorker.py b/eventWorker.py index c71cc4e..63567a1 100644 --- a/eventWorker.py +++ b/eventWorker.py @@ -24,12 +24,14 @@ def run(self): print "sleep for " + str(self.eventObject["seconds"]) + " seconds" time.sleep(int(self.eventObject["seconds"])) - if "command" in self.eventObject: - print "execute command: " + self.eventObject["command"] - exitCode = call(self.eventObject["command"], shell=True) - if exitCode != 0: - print "commend exited with exit code " + str(exitCode) + ". Abort." - return exitCode + if "commands" in self.eventObject: + print "execute commands: " + str(self.eventObject["commands"]) + for command in self.eventObject["commands"]: + print "execute command: " + command + exitCode = call(command, shell=True) + if exitCode != 0: + print "command exited with exit code " + str(exitCode) + ". Abort." + return exitCode if "do" in self.eventObject: doObject = self.eventObject["do"] From 2f4cc52af26c70128a668829729a41cd1ca329ab Mon Sep 17 00:00:00 2001 From: Melvin Witte Date: Fri, 27 Apr 2018 10:12:34 +0200 Subject: [PATCH 2/5] Add command for backwards compatibility --- eventWorker.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/eventWorker.py b/eventWorker.py index 63567a1..9498f18 100644 --- a/eventWorker.py +++ b/eventWorker.py @@ -24,8 +24,14 @@ def run(self): print "sleep for " + str(self.eventObject["seconds"]) + " seconds" time.sleep(int(self.eventObject["seconds"])) + if "command" in self.eventObject: + print "execute command: " + self.eventObject["command"] + exitCode = call(self.eventObject["command"], shell=True) + if exitCode != 0: + print "command exited with exit code " + str(exitCode) + ". Abort." + return exitCode + if "commands" in self.eventObject: - print "execute commands: " + str(self.eventObject["commands"]) for command in self.eventObject["commands"]: print "execute command: " + command exitCode = call(command, shell=True) From e51d52ad7a46e855d261b6ba27369a4cdd56f742 Mon Sep 17 00:00:00 2001 From: Melvin Witte Date: Fri, 27 Apr 2018 10:18:34 +0200 Subject: [PATCH 3/5] Update README.md to include backwards compatibility of 'command', include new example path, fixed mistake in commands description --- README.md | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 2cac72b..28aff9c 100644 --- a/README.md +++ b/README.md @@ -4,12 +4,12 @@ * Python 2.7 installed * PyYaml installed (see: [documentation](http://pyyaml.org/wiki/PyYAML)) -* Docker with Docker-composed installed +* Docker with Docker-compose installed ## Example-Run: ``` -python main.py example.yaml +python main.py examples/example-containers.yaml ``` ## YAML-File @@ -81,12 +81,22 @@ It can execute any list of commands and if this command returns `1`, the `do`-bl Example: ```yaml -command: +commands: - ping -c 1 192.168.1.2 - ls ``` -This would test if the computer with the IP-address `192.168.1.2` is reachable and execute the `do`-block (if there is an connection) once the command returned `1`. Afterwards it executes ls and executes the `do`-block if ls fails. +This would test if the computer with the IP-address `192.168.1.2` is reachable and execute the `do`-block (if there is a connection) once the command returned `1`. Afterwards it executes ls and executes the `do`-block if ls succeeds. +#### command (outdated) + +It can execute any command and if this command returns `1`, the `do`-block will be executed. + +Example: +```yaml +command: ping -c 1 192.168.1.2 +``` + +This would test if the computer with the IP-adress `192.168.1.2` is reachable and execute the `do`-block (if there is a connection) once the command returned `1`. #### do The `do`-block will be executed when all conditions (see above) were processed. Its a map from the key of an action to the values of these actions. From 89aef4d66088ee6257cea7a4cad8fb7116de2156 Mon Sep 17 00:00:00 2001 From: Melvin Witte Date: Wed, 2 May 2018 21:07:01 +0200 Subject: [PATCH 4/5] Update eventWorker.py to support docker exec calls for docker containers --- README.md | 17 +++++++++++++++++ eventWorker.py | 12 ++++++++++++ 2 files changed, 29 insertions(+) diff --git a/README.md b/README.md index 28aff9c..0066067 100644 --- a/README.md +++ b/README.md @@ -48,6 +48,9 @@ event1: - command1 - command2 - .... + docker_exec: + container: + commands: do: ``` @@ -97,6 +100,20 @@ command: ping -c 1 192.168.1.2 ``` This would test if the computer with the IP-adress `192.168.1.2` is reachable and execute the `do`-block (if there is a connection) once the command returned `1`. + +#### docker_exec +`docker_exec` takes the node name specified in the setup part and executes the `command`-collection with `docker exec` + +Example: +```yaml +docker_exec: + container: node1 + commands: + - ping -c 1 192.168.1.2 + - ls +``` + + #### do The `do`-block will be executed when all conditions (see above) were processed. Its a map from the key of an action to the values of these actions. diff --git a/eventWorker.py b/eventWorker.py index 9498f18..fd82963 100644 --- a/eventWorker.py +++ b/eventWorker.py @@ -39,6 +39,18 @@ def run(self): print "command exited with exit code " + str(exitCode) + ". Abort." return exitCode + # TODO support docker exec OPTIONS, see https://docs.docker.com/engine/reference/commandline/exec/ + if "docker_exec" in self.eventObject: + docker_exec = self.eventObject["docker_exec"] + container_id = check_output("docker ps -aqf name=" + docker_exec["container"], shell=True).strip() + for command in docker_exec["commands"]: + full_command = "docker exec " + container_id + command + print "run: docker exec " + container_id + command + exitCode = call("docker exec " + container_id + command, shell=True) + if exitCode != 0: + print "command exited with exit code " + str(exitCode) + ". Abort." + return exitCode + if "do" in self.eventObject: doObject = self.eventObject["do"] for action in doObject: From facee57afdc73d8a30143d0dd00b6dab1eaae92e Mon Sep 17 00:00:00 2001 From: Melvin Witte Date: Thu, 3 May 2018 00:21:44 +0200 Subject: [PATCH 5/5] Fix mising import --- eventWorker.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/eventWorker.py b/eventWorker.py index fd82963..f2f6610 100644 --- a/eventWorker.py +++ b/eventWorker.py @@ -1,6 +1,6 @@ import threading import time -from subprocess import call +from subprocess import call, check_output from executeAction import executeAction class eventWorker (threading.Thread): @@ -44,9 +44,9 @@ def run(self): docker_exec = self.eventObject["docker_exec"] container_id = check_output("docker ps -aqf name=" + docker_exec["container"], shell=True).strip() for command in docker_exec["commands"]: - full_command = "docker exec " + container_id + command - print "run: docker exec " + container_id + command - exitCode = call("docker exec " + container_id + command, shell=True) + full_command = "docker exec " + container_id + " " + command + print "run: "+ full_command + exitCode = call(full_command, shell=True) if exitCode != 0: print "command exited with exit code " + str(exitCode) + ". Abort." return exitCode