From 8e1cb3ca09c1752863f867a9428d5441ed21f8a5 Mon Sep 17 00:00:00 2001 From: Merlin Mathesius Date: Aug 03 2017 16:42:16 +0000 Subject: Updates to address review feedback. --- diff --git a/scripts/README.md b/scripts/README.md index 8c61c34..bf5da45 100644 --- a/scripts/README.md +++ b/scripts/README.md @@ -2,9 +2,26 @@ ## `merge-standard-inventory` -`merge-standard-inventory` is a wrapper script that runs _all_ of the available Standard Testing Interface dynamic inventory scripts from `/usr/share/ansible/inventory` and merges their output. This allows an individual test to provide a single customized dynamic inventory script that sets up certain environment variables before running all the default standard-inventory scripts. To make use of it, simply have `ansible` use the custom inventory script (which makes use of the `merge-standard-inventory` wrapper) in place of the `/usr/share/ansible/inventory` directory. +`merge-standard-inventory` is a wrapper script that runs _all_ of the +available Standard Testing Interface dynamic inventory scripts from +`/usr/share/ansible/inventory` and merges their output. This allows +an individual test to provide a single customized dynamic inventory +script that sets up certain environment variables before running all +the default standard-inventory scripts. To make use of it, simply +have `ansible` use the custom inventory script (which makes use of +the `merge-standard-inventory` wrapper) in place of the +`/usr/share/ansible/inventory` directory. -The following short example custom inventory script sets the `TEST_DOCKER_EXTRA_ARGS` environment variable before running `merge-standard-inventory` with any command line arguments provided by ansible. By doing this, when `merge-standard-inventory` runs the `standard-inventory-docker` script it will launch the docker container with `CAP_SYS_ADMIN` capabilities (if the `TEST_SUBJECTS` environment variable triggers a container to be launched). Other `standard-inventory-*` scripts will simply ignore the `TEST_DOCKER_EXTRA_ARGS` environment variable--but may have their own environment variables set in the inventory script. +The following short example custom inventory script sets the +`TEST_DOCKER_EXTRA_ARGS` environment variable before running +`merge-standard-inventory` with any command line arguments provided +by ansible. By doing this, when `merge-standard-inventory` runs the +`standard-inventory-docker` script it will launch the docker +container with `CAP_SYS_ADMIN` capabilities (if the `TEST_SUBJECTS` +environment variable triggers a container to be launched). Other +`standard-inventory-*` scripts will simply ignore the +`TEST_DOCKER_EXTRA_ARGS` environment variable--but may have their own +environment variables set in the inventory script. ``` #!/bin/bash diff --git a/scripts/merge-standard-inventory b/scripts/merge-standard-inventory index faeec61..64fcdc1 100755 --- a/scripts/merge-standard-inventory +++ b/scripts/merge-standard-inventory @@ -1,6 +1,5 @@ #!/usr/bin/python2 -import argparse import json import os import sys @@ -12,12 +11,19 @@ def main(argv): """ Run all standard inventory scripts and return their merged output. - Note the standard inventory scripts clean up their spawned hosts when they detect their parent processes go away. To accomodate that behavior, this script forks a child process to run the inventory scripts, send back the merged inventory, and then wait for the parent of this script (ansible) to die before silently exiting. In the mean time, this script outputs the merged inventory gathered by the child and then exits. + Note the standard inventory scripts clean up their spawned hosts + when they detect their parent processes go away. To accomodate + that behavior, this script forks a child process to run the + inventory scripts, send back the merged inventory, and then wait + for the parent of this script (ansible) to die before silently + exiting. In the mean time, this script outputs the merged + inventory gathered by the child and then exits. """ # Keep track of our parent waitpid = os.getppid() + tty = err_to_tty() pipein, pipeout = os.pipe() childpid = os.fork() @@ -37,7 +43,7 @@ def main(argv): os.close(pipeout) # wait for the grandparent process to exit - linger(waitpid) + linger(waitpid, tty) # exit cleanly sys.exit(0) @@ -68,12 +74,15 @@ def merge_standard_inventories(args): merged = Inventory() for i in os.listdir(inventory_dir): + ipath = os.path.join(inventory_dir, i) if not i.startswith("standard-inventory-"): continue if i.endswith(inventory_ignore_extensions): continue + if not os.access(ipath, os.X_OK): + continue - cmd = [os.path.join(inventory_dir, i)] + args + cmd = [ipath] + args try: inv_out = subprocess.check_output(cmd, stdin=None, close_fds=True) @@ -85,16 +94,20 @@ def merge_standard_inventories(args): return merged.dumps() -def linger(waitpid): - # Go into daemon mode and watch the process - null = open(os.devnull, 'w') - +def err_to_tty(): try: tty = os.open("/dev/tty", os.O_WRONLY) os.dup2(tty, 2) except OSError: tty = None - pass + + return tty + + +def linger(waitpid, tty=None): + # Go into daemon mode and watch the process + + null = open(os.devnull, 'w') os.chdir("/") os.setsid() @@ -121,6 +134,14 @@ def linger(waitpid): class Inventory: + """ + Merge JSON data from standard test dynamic inventory scripts. + + Note: This class is very specific to the JSON data written by the + ansible dynamic inventory scripts that are provided by the + standard-test-roles package. In particular, it insists on finding + and generating "subjects" and "localhost" members. + """ def __init__(self): self.hosts = []