aboutsummaryrefslogtreecommitdiffstats
path: root/yardstick/common/ansible_common.py
diff options
context:
space:
mode:
Diffstat (limited to 'yardstick/common/ansible_common.py')
-rw-r--r--yardstick/common/ansible_common.py88
1 files changed, 70 insertions, 18 deletions
diff --git a/yardstick/common/ansible_common.py b/yardstick/common/ansible_common.py
index 9a4426bf9..dee7044a5 100644
--- a/yardstick/common/ansible_common.py
+++ b/yardstick/common/ansible_common.py
@@ -12,8 +12,6 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-from __future__ import absolute_import
-
import cgitb
import collections
import contextlib as cl
@@ -23,17 +21,18 @@ import os
from collections import Mapping, MutableMapping, Iterable, Callable, deque
from functools import partial
from itertools import chain
-from subprocess import CalledProcessError, Popen, PIPE
-from tempfile import NamedTemporaryFile
+import subprocess
+import tempfile
import six
-import six.moves.configparser as ConfigParser
+from six.moves import configparser
import yaml
from six import StringIO
from chainmap import ChainMap
+from oslo_serialization import jsonutils
from yardstick.common.utils import Timer
-
+from yardstick.common import constants as consts
cgitb.enable(format="text")
@@ -133,10 +132,9 @@ class CustomTemporaryFile(object):
else:
self.data_types = self.DEFAULT_DATA_TYPES
# must open "w+" so unicode is encoded correctly
- self.creator = partial(NamedTemporaryFile, mode="w+", delete=False,
- dir=directory,
- prefix=prefix,
- suffix=self.suffix)
+ self.creator = partial(
+ tempfile.NamedTemporaryFile, mode="w+", delete=False,
+ dir=directory, prefix=prefix, suffix=self.suffix)
def make_context(self, data, write_func, descriptor='data'):
return TempfileContext(data, write_func, descriptor, self.data_types,
@@ -190,8 +188,8 @@ class FileNameGenerator(object):
if not prefix.endswith('_'):
prefix += '_'
- temp_file = NamedTemporaryFile(delete=False, dir=directory,
- prefix=prefix, suffix=suffix)
+ temp_file = tempfile.NamedTemporaryFile(delete=False, dir=directory,
+ prefix=prefix, suffix=suffix)
with cl.closing(temp_file):
return temp_file.name
@@ -435,6 +433,7 @@ class AnsibleCommon(object):
ansible_dict = dict(os.environ, **{
"ANSIBLE_LOG_PATH": os.path.join(directory, log_file),
"ANSIBLE_LOG_BASE": directory,
+ "ANSIBLE_ROLES_PATH": consts.ANSIBLE_ROLES_PATH,
# # required for SSH to work
# "ANSIBLE_SSH_ARGS": "-o UserKnownHostsFile=/dev/null "
# "-o GSSAPIAuthentication=no "
@@ -472,7 +471,7 @@ class AnsibleCommon(object):
prefix = '_'.join([self.prefix, prefix, 'inventory'])
ini_temp_file = IniMapTemporaryFile(directory=directory, prefix=prefix)
- inventory_config = ConfigParser.ConfigParser(allow_no_value=True)
+ inventory_config = configparser.ConfigParser(allow_no_value=True)
# disable default lowercasing
inventory_config.optionxform = str
return ini_temp_file.make_context(self.inventory_dict, write_func,
@@ -507,6 +506,58 @@ class AnsibleCommon(object):
timeout = 1200.0
return timeout
+ def _generate_ansible_cfg(self, directory):
+ parser = configparser.ConfigParser()
+ parser.add_section('defaults')
+ parser.set('defaults', 'host_key_checking', 'False')
+
+ cfg_path = os.path.join(directory, 'ansible.cfg')
+ with open(cfg_path, 'w') as f:
+ parser.write(f)
+
+ def get_sut_info(self, directory, sut_dir='sut'):
+ if not os.path.isdir(directory):
+ raise OSError('No such directory: %s' % directory)
+
+ self._generate_ansible_cfg(directory)
+
+ prefix = 'tmp'
+ self.gen_inventory_ini_dict()
+ ini_file = self._gen_ansible_inventory_file(directory, prefix=prefix)
+ with ini_file as f:
+ inventory_path = str(f)
+
+ self._exec_get_sut_info_cmd(directory, inventory_path, sut_dir)
+
+ sut_dir = os.path.join(directory, sut_dir)
+ sut_info = self._gen_sut_info_dict(sut_dir)
+
+ return sut_info
+
+ def _exec_get_sut_info_cmd(self, directory, inventory_path, sut_dir):
+ cmd = ['ansible', 'all', '-m', 'setup', '-i',
+ inventory_path, '--tree', sut_dir]
+
+ proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, cwd=directory)
+ output, _ = proc.communicate()
+ retcode = proc.wait()
+ LOG.debug("exit status = %s", retcode)
+ if retcode != 0:
+ raise subprocess.CalledProcessError(retcode, cmd, output)
+
+ def _gen_sut_info_dict(self, sut_dir):
+ sut_info = {}
+
+ if os.path.isdir(sut_dir):
+ root, _, files = next(os.walk(sut_dir))
+ for filename in files:
+ abs_path = os.path.join(root, filename)
+ with open(abs_path) as f:
+ data = jsonutils.load(f)
+ sut_info[filename] = data
+
+ return sut_info
+
def execute_ansible(self, playbooks, directory, timeout=None,
extra_vars=None, ansible_check=False, prefix='tmp',
verbose=False):
@@ -516,7 +567,7 @@ class AnsibleCommon(object):
# playbook dir: use include to point to files in consts.ANSIBLE_DIR
if not os.path.isdir(directory):
- raise OSError("Not a directory, %s", directory)
+ raise OSError("Not a directory, %s" % directory)
timeout = self.get_timeout(timeout, self.default_timeout)
self.counter += 1
@@ -563,12 +614,13 @@ class AnsibleCommon(object):
# 'timeout': timeout / 2,
})
with Timer() as timer:
- proc = Popen(cmd, stdout=PIPE, **exec_args)
+ proc = subprocess.Popen(cmd, stdout=subprocess.PIPE,
+ **exec_args)
output, _ = proc.communicate()
retcode = proc.wait()
LOG.debug("exit status = %s", retcode)
if retcode != 0:
- raise CalledProcessError(retcode, cmd, output)
+ raise subprocess.CalledProcessError(retcode, cmd, output)
timeout -= timer.total_seconds()
cmd.remove("--syntax-check")
@@ -578,10 +630,10 @@ class AnsibleCommon(object):
# TODO: add timeout support of use subprocess32 backport
# 'timeout': timeout,
})
- proc = Popen(cmd, stdout=PIPE, **exec_args)
+ proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, **exec_args)
output, _ = proc.communicate()
retcode = proc.wait()
LOG.debug("exit status = %s", retcode)
if retcode != 0:
- raise CalledProcessError(retcode, cmd, output)
+ raise subprocess.CalledProcessError(retcode, cmd, output)
return output