Prechádzať zdrojové kódy

Fixed ctrl+c and SIGTERM handling (#3491)

Fixed ctrl+c and SIGTERM handling
Mike Smith 7 rokov pred
rodič
commit
84c8f30099

+ 30 - 10
README.md

@@ -25,25 +25,45 @@ required.
 
         $ git clone https://github.com/TechEmpower/FrameworkBenchmarks.git
 
-2. Move into the vagrant-development directory.
+2. Change directories
 
         $ cd FrameworkBenchmarks/deployment/vagrant
 
-3. Turn on the VM (takes at least 20 minutes).
+3. Create the TFB Docker virtual network
 
-        $ vagrant up
+        $ docker network create tfb
 
-4. Enter the VM.
+4. Run a test.
 
-        $ vagrant ssh
+        $ docker run -it --network=tfb -v /var/run/docker.sock:/var/run/docker.sock --mount type=bind,source=[ABS PATH TO THIS DIR],target=/FrameworkBenchmarks techempower/tfb --mode verify --test gemini
 
-5. Move into the FrameworkBenchmarks directory in the vm.
+### Explanation of the run script
 
-        vagrant@TFB-all:~$ cd ~/FrameworkBenchmarks
-        
-6. Run a test.
+That run script is pretty wordy, but each and every flag is required. Unfortunately, because of the way that Docker runs processes, you **cannot** put this inside of a shell script without breaking how `ctrl+c` and `SIGTERM` work (the shell script would receive the signal, do nothing with the underlying python suite running, and exit, orphaning the toolset to continue running).
 
-        vagrant@TFB-all:~/FrameworkBenchmarks$ tfb --mode verify --test beego
+- `-it` tells docker to run this in 'interactive' mode and simulate a TTY, so that `ctrl+c` is propagated.
+- `--network=tfb` tells the container to join the 'tfb' Docker virtual network
+- `-v` specifies which Docker socket path to mount as a volume in the running container. This allows docker commands run inside this container to use the host container's docker to create/run/stop/remove containers.
+- `--mount` mounts the FrameworkBenchmarks source directory as a volume to share with the container so that rebuilding the toolset image is unnecessary and any changes you make on the host system are available in the running toolset container.
+- `techempower/tfb` is the name of toolset container to run
+- `--mode verify --test gemini` are the command to pass to the toolset.
+
+#### A note on Linux:
+
+You may not want to call step 4 from above every time. You can add an `alias` to your `~/.bash_aliases` file to shorten it since it will not change once configured:
+
+`$ alias tfb="docker run -it --network=tfb -v /var/run/docker.sock:/var/run/docker.sock --mount type=bind,source=[ABS PATH TO THIS DIR],target=/FrameworkBenchmarks techempower/tfb"`
+
+`$ source ~/.bash_aliases`
+
+Now you can run the toolset via `tfb`:
+
+`$ tfb --mode verify --test gemini`
+
+#### A note on Windows:
+
+- Docker expects Linux-style paths. If you cloned on your `C:\` drive, then `[ABS PATH TO THIS DIR]` would be `/c/FrameworkBenchmarks`.
+- [Docker for Windows](https://www.docker.com/docker-windows) understands `/var/run/docker.sock` even though that is not a valid path on Windows. [Docker Toolbox](https://docs.docker.com/toolbox/toolbox_install_windows/) **may** not - use at your own risk.
 
 ## Add a New Test
 

+ 5 - 21
deployment/vagrant/bootstrap.sh

@@ -29,9 +29,6 @@ if [ ! -e "~/.firstboot" ]; then
   sudo cat <<EOF > motd
 Welcome to the FrameworkBenchmarks project!
 
-  To get started, perhaps try this:
-    $ cd FrameworkBenchmarks
-
   You can get lots of help:
     $ tfb --help
 
@@ -41,24 +38,11 @@ Welcome to the FrameworkBenchmarks project!
   This Vagrant environment is already setup and ready to go.
 EOF
 
-  sudo mv motd /etc/
-
-  sudo cat <<EOF > tfb
-#!/bin/bash
-
-# Defaults
-ds=/var/run/docker.sock
-sd=/home/vagrant/FrameworkBenchmarks
-
-# Build the tfb image
-docker pull techempower/tfb
-
-# Create the tfb network
-docker network create tfb > /dev/null 2>&1
-# Run the suite
-docker run --network=tfb -v \${DOCKER_SOCKET_PATH-\$ds}:/var/run/docker.sock --mount type=bind,source=\${TFB_SOURCE_DIR-\$sd},target=/FrameworkBenchmarks techempower/tfb "\$@"
+  cat <<EOF > /home/vagrant/.bash_aliases
+alias tfb="docker run -it --network=tfb -v /var/run/docker.sock:/var/run/docker.sock --mount type=bind,source=/home/vagrant/FrameworkBenchmarks,target=/FrameworkBenchmarks techempower/tfb"
 EOF
-  sudo mv tfb /usr/local/bin
-  sudo chmod a+x /usr/local/bin/tfb
+
+  sudo mv motd /etc/
   sudo chmod 777 /var/run/docker.sock
+  docker network create tfb
 fi

+ 0 - 13
tfb.sh

@@ -1,13 +0,0 @@
-#!/bin/bash
-
-# Defaults
-ds=/var/run/docker.sock
-sd=`pwd`
-
-# Build the tfb image
-docker pull techempower/tfb
-
-# Create the tfb network
-docker network create tfb > /dev/null 2>&1
-# Run the suite
-docker run --network=tfb -v ${DOCKER_SOCKET_PATH-$ds}:/var/run/docker.sock --mount type=bind,source=${TFB_SOURCE_DIR-$sd},target=/FrameworkBenchmarks techempower/tfb "$@"

+ 1 - 1
toolset/benchmark/framework_test.py

@@ -68,7 +68,7 @@ class FrameworkTest:
         result = docker_helper.build(self.benchmarker_config, [self.name],
                                      build_log_dir)
         if result != 0:
-            return result
+            return None
 
         return docker_helper.run(self.benchmarker_config, test_docker_files,
                                  run_log_dir)

+ 15 - 0
toolset/run-tests.py

@@ -1,6 +1,7 @@
 import argparse
 import socket
 import sys
+import signal
 from toolset.benchmark.benchmarker import Benchmarker
 from toolset.utils.scaffolding import Scaffolding
 from toolset.utils import cleaner
@@ -14,6 +15,9 @@ from toolset.utils.output_helper import log
 from colorama import init, Fore
 init()
 
+# Required to be globally known
+config = None
+
 
 class StoreSeqAction(argparse.Action):
     '''
@@ -42,6 +46,16 @@ class StoreSeqAction(argparse.Action):
         return [abs(int(item)) for item in result]
 
 
+def __stop(signal, frame):
+    log("Shutting down (may take a moment)")
+    docker_helper.stop(config)
+    sys.exit(0)
+
+
+signal.signal(signal.SIGTERM, __stop)
+signal.signal(signal.SIGINT, __stop)
+
+
 ###################################################################################################
 # Main
 ###################################################################################################
@@ -195,6 +209,7 @@ def main(argv=None):
 
     args = parser.parse_args()
 
+    global config
     config = BenchmarkConfig(args)
     results = Results(config)
 

+ 34 - 13
toolset/utils/docker_helper.py

@@ -267,25 +267,46 @@ def stop(benchmarker_config=None,
     '''
     client = docker.DockerClient(
         base_url=benchmarker_config.server_docker_host)
-    # Stop all our running containers
-    for container in containers:
-        container.stop()
-        # 'techempower/tfb.test.gemini:0.1' -> 'techempower/tfb.test.gemini'
-        client.images.remove(container.image.tags[0].split(':')[0], force=True)
+    if containers is None:
+        for container in client.containers.list():
+            if len(
+                    container.image.tags
+            ) > 0 and 'techempower' in container.image.tags[0] and 'tfb:latest' not in container.image.tags[0]:
+                container.stop()
+                # 'techempower/tfb.test.gemini:0.1' -> 'techempower/tfb.test.gemini'
+                client.images.remove(
+                    container.image.tags[0].split(':')[0], force=True)
+    else:
+        # Stop all our running containers
+        for container in containers:
+            container.stop()
+            # 'techempower/tfb.test.gemini:0.1' -> 'techempower/tfb.test.gemini'
+            client.images.remove(
+                container.image.tags[0].split(':')[0], force=True)
+
+    database_client = docker.DockerClient(
+        base_url=benchmarker_config.database_docker_host)
     # Stop the database container
-    if database_container is not None:
+    if database_container is None:
+        for container in database_client.containers.list():
+            if len(
+                    container.image.tags
+            ) > 0 and 'techempower' in container.image.tags[0] and 'tfb:latest' not in container.image.tags[0]:
+                container.stop()
+                # 'techempower/tfb.test.gemini:0.1' -> 'techempower/tfb.test.gemini'
+                client.images.remove(
+                    container.image.tags[0].split(':')[0], force=True)
+    else:
         database_container.stop()
+
     client.images.prune()
     client.containers.prune()
-    client.networks.prune()
     client.volumes.prune()
+
     if benchmarker_config.server_docker_host != benchmarker_config.database_docker_host:
-        db_client = docker.DockerClient(
-            base_url=benchmarker_config.database_docker_host)
-        db_client.images.prune()
-        db_client.containers.prune()
-        db_client.networks.prune()
-        db_client.volumes.prune()
+        database_client.images.prune()
+        database_client.containers.prune()
+        database_client.volumes.prune()
 
 
 def find(path, pattern):