summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStamatis Katsaounis <mokats@intracom-telecom.com>2019-03-04 16:12:10 +0200
committerDan Xu <xudan16@huawei.com>2019-03-18 02:29:02 +0000
commitef2d5282306a277e591aa3c355277c6f158d8e76 (patch)
tree9f2bdf2bf77e1cfd08a058eaa696b0ed673b67fe
parent1540d41ec9291d61c1cd5b5d2f347d1d8f9c3dbe (diff)
Replace subprocess commands with Docker SDK
JIRA: DOVETAIL-752 This patch replaces all python subprocess commands with the Docker SDK relevant commands. Change-Id: Iac7caffd80a863a8a022247d735b2a7f2792e49d Signed-off-by: Stamatis Katsaounis <mokats@intracom-telecom.com>
-rw-r--r--dovetail/container.py142
-rw-r--r--dovetail/tests/unit/test_container.py175
-rw-r--r--dovetail/tests/unit/utils/test_dovetail_utils.py75
-rw-r--r--dovetail/utils/dovetail_utils.py26
-rw-r--r--etc/conf/bottlenecks_config.yml26
-rw-r--r--etc/conf/functest-k8s_config.yml20
-rw-r--r--etc/conf/functest_config.yml32
-rw-r--r--etc/conf/onap-vtp_config.yml14
-rw-r--r--etc/conf/onap-vvp_config.yml9
-rw-r--r--etc/conf/yardstick_config.yml24
-rw-r--r--requirements.txt1
11 files changed, 282 insertions, 262 deletions
diff --git a/dovetail/container.py b/dovetail/container.py
index 57145034..250bb54a 100644
--- a/dovetail/container.py
+++ b/dovetail/container.py
@@ -9,6 +9,9 @@
# http://www.apache.org/licenses/LICENSE-2.0
#
+import docker
+import sys
+
import utils.dovetail_logger as dt_logger
import utils.dovetail_utils as dt_utils
from utils.dovetail_config import DovetailConfig as dt_cfg
@@ -19,9 +22,10 @@ class Container(object):
logger = None
def __init__(self, testcase):
- self.container_id = None
+ self.container = None
self.testcase = testcase
self.valid_type = self.testcase.validate_type()
+ self.client = docker.from_env(timeout=None)
def __str__(self):
pass
@@ -45,70 +49,69 @@ class Container(object):
name = self._get_config('image_name', project_cfg, testcase_cfg)
tag = self._get_config('docker_tag', project_cfg, testcase_cfg)
- return "{}:{}".format(name, tag) if name and tag else None
+ return '{}:{}'.format(name, tag) if name and tag else None
def create(self, docker_image):
dovetail_config = dt_cfg.dovetail_config
project_cfg = dovetail_config[self.valid_type]
- opts = dt_utils.get_value_from_dict('opts', project_cfg)
+ kwargs = dt_utils.get_value_from_dict('opts', project_cfg)
shell = dt_utils.get_value_from_dict('shell', project_cfg)
if not shell:
return None
- envs = dt_utils.get_value_from_dict('envs', project_cfg)
- volumes_list = dt_utils.get_value_from_dict('volumes', project_cfg)
- opts = ' ' if not opts else opts
- envs = ' ' if not envs else envs
- volumes = ' '.join(volume for volume in volumes_list if volume) \
- if volumes_list else ' '
-
- hosts_config = dt_utils.get_hosts_info(self.logger)
-
- cmd = 'sudo docker run {opts} {envs} {volumes} ' \
- '{hosts_config} {docker_image} {shell}'.format(**locals())
- ret, container_id = dt_utils.exec_cmd(cmd, self.logger)
- if ret != 0:
+ env_list = dt_utils.get_value_from_dict('envs', project_cfg)
+ kwargs['environment'] = [env for env in env_list if env is not None]
+ volume_list = dt_utils.get_value_from_dict('volumes', project_cfg)
+ kwargs['volumes'] = [vol for vol in volume_list if vol is not None]
+ kwargs['extra_hosts'] = dt_utils.get_hosts_info(self.logger)
+
+ try:
+ self.container = self.client.containers.run(
+ docker_image, shell, **kwargs)
+ except (docker.errors.ContainerError, docker.errors.ImageNotFound,
+ docker.errors.APIError):
return None
- self.container_id = container_id
- return container_id
+ return self.container.id
def get_image_id(self, image_name):
- cmd = 'sudo docker images -q %s' % (image_name)
- ret, image_id = dt_utils.exec_cmd(cmd, self.logger)
- if ret == 0:
- return image_id
- else:
- return None
+ try:
+ image_id = self.client.images.get(image_name).id
+ except (docker.errors.ImageNotFound, docker.errors.APIError):
+ image_id = None
+ return image_id
# remove the image according to the image_id
# if there exists containers using this image, then skip
def remove_image(self, image_id):
- cmd = "sudo docker ps -aq -f 'ancestor=%s'" % (image_id)
- ret, msg = dt_utils.exec_cmd(cmd, self.logger)
- if msg and ret == 0:
+ try:
+ containers = self.client.containers.list(
+ filters={'ancestor': image_id})
+ except docker.errors.APIError:
+ containers = []
+ if containers:
self.logger.debug('Image {} has containers, skip.'
.format(image_id))
return True
- cmd = 'sudo docker rmi %s' % (image_id)
self.logger.debug('Remove image {}.'.format(image_id))
- ret, msg = dt_utils.exec_cmd(cmd, self.logger)
- if ret == 0:
+ try:
+ self.client.images.remove(image_id)
self.logger.debug('Remove image {} successfully.'.format(image_id))
return True
- self.logger.error('Failed to remove image {}.'.format(image_id))
- return False
+ except (docker.errors.ImageNotFound, docker.errors.APIError):
+ self.logger.error('Failed to remove image {}.'.format(image_id))
+ return False
def pull_image_only(self, image_name):
- cmd = 'sudo docker pull %s' % (image_name)
- ret, _ = dt_utils.exec_cmd(cmd, self.logger)
- if ret != 0:
+ try:
+ self.client.images.pull(image_name)
+ self.logger.debug(
+ 'Success to pull docker image {}!'.format(image_name))
+ return True
+ except docker.errors.APIError:
self.logger.error(
'Failed to pull docker image {}!'.format(image_name))
return False
- self.logger.debug('Success to pull docker image {}!'
- .format(image_name))
- return True
def pull_image(self, docker_image):
if not docker_image:
@@ -119,7 +122,7 @@ class Container(object):
new_image_id = self.get_image_id(docker_image)
if not new_image_id:
self.logger.error(
- "Failed to get the id of image {}.".format(docker_image))
+ 'Failed to get the id of image {}.'.format(docker_image))
return None
if not old_image_id:
return docker_image
@@ -130,35 +133,50 @@ class Container(object):
self.remove_image(old_image_id)
return docker_image
- def check_container_exist(self, container_name):
- cmd = ('sudo docker ps -aq -f name={}'.format(container_name))
- ret, msg = dt_utils.exec_cmd(cmd, self.logger)
- if ret == 0 and msg:
- return True
- return False
+ def get_container(self, container_name):
+ try:
+ container = self.client.containers.get(container_name)
+ except (docker.errors.NotFound, docker.errors.APIError):
+ container = None
+ return container
def clean(self):
- cmd = ('sudo docker rm -f {}'.format(self.container_id))
- dt_utils.exec_cmd(cmd, self.logger)
+ try:
+ self.container.remove(force=True)
+ self.logger.debug(
+ 'container: {} was removed'.format(self.container.name))
+ except docker.errors.APIError as e:
+ self.logger.error(e)
extra_containers = dt_utils.get_value_from_dict(
'extra_container', dt_cfg.dovetail_config[self.valid_type])
if extra_containers:
- for container in extra_containers:
- if self.check_container_exist(container):
- cmd = ('sudo docker rm -f {}'.format(container))
- dt_utils.exec_cmd(cmd, self.logger)
+ for container_name in extra_containers:
+ container = self.get_container(container_name)
+ if container:
+ try:
+ container.remove(force=True)
+ self.logger.debug(
+ 'container: {} was removed'.format(container_name))
+ except docker.errors.APIError as e:
+ self.logger.error(e)
def exec_cmd(self, sub_cmd, exit_on_error=False):
- if sub_cmd == "":
+ if not sub_cmd:
return (1, 'sub_cmd is empty')
- dovetail_config = dt_cfg.dovetail_config
- project_cfg = dovetail_config[self.valid_type]
- shell = dt_utils.get_value_from_dict('shell', project_cfg)
+ shell = dt_utils.get_value_from_dict(
+ 'shell', dt_cfg.dovetail_config[self.valid_type])
if not shell:
return (1, 'shell is empty')
- cmd = 'sudo docker exec {} {} -c "{}"'.format(self.container_id, shell,
- sub_cmd)
- return dt_utils.exec_cmd(cmd, self.logger, exit_on_error)
+ cmd = '{} -c "{}"'.format(shell, sub_cmd)
+ try:
+ result = self.container.exec_run(cmd)
+ except docker.errors.APIError as e:
+ result = (e.response.status_code, str(e))
+ self.logger.error(e)
+ if exit_on_error:
+ sys.exit(1)
+
+ return result
def copy_file(self, src_path, dest_path, exit_on_error=False):
if not src_path or not dest_path:
@@ -166,14 +184,6 @@ class Container(object):
cmd = 'cp %s %s' % (src_path, dest_path)
return self.exec_cmd(cmd, exit_on_error)
- def docker_copy(self, src_path, dest_path):
- if not src_path or not dest_path:
- return (1, 'src_path or dest_path is empty')
- cmd = 'docker cp {} {}:{}'.format(src_path,
- self.container_id,
- dest_path)
- return dt_utils.exec_cmd(cmd, self.logger)
-
def copy_files_in_container(self):
project_config = dt_cfg.dovetail_config[self.valid_type]
if 'copy_file_in_container' not in project_config.keys():
diff --git a/dovetail/tests/unit/test_container.py b/dovetail/tests/unit/test_container.py
index 6a8b99fc..7c758a7c 100644
--- a/dovetail/tests/unit/test_container.py
+++ b/dovetail/tests/unit/test_container.py
@@ -10,6 +10,7 @@
import unittest
from mock import patch, call, Mock
+import docker
from dovetail.container import Container
@@ -19,6 +20,7 @@ __author__ = 'Stamatis Katsaounis <mokats@intracom-telecom.com>'
class ContainerTesting(unittest.TestCase):
def setUp(self):
+ self.patcher1 = patch.object(docker, 'from_env')
testcase = patch.object(Container, 'testcase')
testcase.testcase = {'validate': {
'type': 'bottlenecks'}}
@@ -28,12 +30,13 @@ class ContainerTesting(unittest.TestCase):
val_type_obj = Mock()
val_type_obj.return_value = 'bottlenecks'
testcase.validate_type = val_type_obj
+ self.client = self.patcher1.start().return_value
self.container = Container(testcase)
self.logger = Mock()
self.container.logger = self.logger
def tearDown(self):
- pass
+ self.patcher1.stop()
@patch('dovetail.container.dt_cfg')
@patch.object(Container, 'copy_file')
@@ -72,22 +75,6 @@ class ContainerTesting(unittest.TestCase):
mock_copy.assert_not_called()
- def test_docker_copy_error(self):
- expected = (1, 'src_path or dest_path is empty')
- result = self.container.docker_copy(None, None)
-
- self.assertEqual(expected, result)
-
- @patch('dovetail.container.dt_utils')
- def test_docker_copy(self, mock_utils):
- expected = (0, 'success')
- mock_utils.exec_cmd.return_value = expected
- result = self.container.docker_copy('source', 'dest')
-
- mock_utils.exec_cmd.assert_called_once_with(
- 'docker cp source None:dest', self.logger)
- self.assertEqual(expected, result)
-
def test_copy_file_error(self):
expected = (1, 'src_path or dest_path is empty')
result = self.container.copy_file(None, None)
@@ -114,17 +101,37 @@ class ContainerTesting(unittest.TestCase):
@patch('dovetail.container.dt_utils')
def test_exec_cmd(self, mock_utils, mock_config):
expected = (0, 'success')
- mock_utils.exec_cmd.return_value = expected
mock_utils.get_value_from_dict.return_value = 'shell'
mock_config.dovetail_config = {'bottlenecks': 'value'}
+ container_obj = Mock()
+ container_obj.exec_run.return_value = expected
+ self.container.container = container_obj
+
result = self.container.exec_cmd('command')
- mock_utils.exec_cmd.assert_called_once_with(
- 'sudo docker exec None shell -c "command"', self.logger, False)
self.assertEqual(expected, result)
@patch('dovetail.container.dt_cfg')
@patch('dovetail.container.dt_utils')
+ @patch('sys.exit')
+ def test_exec_cmd_exception(self, mock_exit, mock_utils, mock_config):
+ mock_utils.get_value_from_dict.return_value = 'shell'
+ mock_config.dovetail_config = {'bottlenecks': 'value'}
+ container_obj = Mock()
+ response_obj = Mock()
+ response_obj.status_code = 1
+ container_obj.exec_run.side_effect = \
+ docker.errors.APIError('error', response=response_obj)
+ self.container.container = container_obj
+
+ expected = (1, 'error')
+ result = self.container.exec_cmd('command', exit_on_error=True)
+
+ self.assertEqual(expected, result)
+ mock_exit.assert_called_once_with(1)
+
+ @patch('dovetail.container.dt_cfg')
+ @patch('dovetail.container.dt_utils')
def test_exec_cmd_no_shell(self, mock_utils, mock_config):
expected = (1, 'shell is empty')
mock_utils.exec_cmd.return_value = expected
@@ -136,50 +143,65 @@ class ContainerTesting(unittest.TestCase):
@patch('dovetail.container.dt_cfg')
@patch('dovetail.container.dt_utils')
- @patch.object(Container, 'check_container_exist')
+ @patch.object(Container, 'get_container')
def test_clean(self, mock_check, mock_utils, mock_config):
container_name = 'container'
mock_config.dovetail_config = {'bottlenecks': 'value'}
mock_utils.get_value_from_dict.return_value = [container_name]
- mock_check.return_value = True
+ self.container.container = Mock()
+ mock_check.return_value = Mock()
+
+ self.container.clean()
+
+ mock_utils.get_value_from_dict.assert_called_once_with(
+ 'extra_container', 'value')
+ mock_check.assert_called_once_with(container_name)
+
+ @patch('dovetail.container.dt_cfg')
+ @patch('dovetail.container.dt_utils')
+ @patch.object(Container, 'get_container')
+ def test_clean_extra_error(self, mock_check, mock_utils, mock_config):
+ container_name = 'container'
+ mock_config.dovetail_config = {'bottlenecks': 'value'}
+ mock_utils.get_value_from_dict.return_value = [container_name]
+ container_obj = Mock()
+ container_obj.remove.side_effect = docker.errors.APIError('error')
+ self.container.container = Mock()
+ mock_check.return_value = container_obj
self.container.clean()
mock_utils.get_value_from_dict.assert_called_once_with(
'extra_container', 'value')
mock_check.assert_called_once_with(container_name)
- mock_utils.exec_cmd.assert_has_calls([
- call('sudo docker rm -f None', self.logger),
- call('sudo docker rm -f container', self.logger)])
@patch('dovetail.container.dt_cfg')
@patch('dovetail.container.dt_utils')
def test_clean_no_extra_container(self, mock_utils, mock_config):
mock_utils.get_value_from_dict.return_value = None
+ container_obj = Mock()
+ container_obj.remove.side_effect = docker.errors.APIError('error')
+ self.container.container = container_obj
self.container.clean()
mock_utils.get_value_from_dict.assert_called_once()
- @patch('dovetail.container.dt_utils')
- def test_check_container_exist_true(self, mock_utils):
+ def test_get_container_exist_true(self):
container_name = 'container'
- cmd = ('sudo docker ps -aq -f name={}'.format(container_name))
- mock_utils.exec_cmd.return_value = (0, 'msg')
+ expected = Mock()
+ self.client.containers.get.return_value = expected
- result = self.container.check_container_exist(container_name)
+ result = self.container.get_container(container_name)
- mock_utils.exec_cmd.assert_called_once_with(cmd, self.logger)
- self.assertEquals(True, result)
+ self.assertEquals(expected, result)
- @patch('dovetail.container.dt_utils')
- def test_check_container_exist_false(self, mock_utils):
+ def test_get_container_none(self):
container_name = 'container'
- cmd = ('sudo docker ps -aq -f name={}'.format(container_name))
- mock_utils.exec_cmd.return_value = (1, 'msg')
+ self.client.containers.get.side_effect = \
+ docker.errors.APIError('error')
- result = self.container.check_container_exist(container_name)
+ result = self.container.get_container(container_name)
- mock_utils.exec_cmd.assert_called_once_with(cmd, self.logger)
- self.assertEquals(False, result)
+ self.assertEquals(None, result)
def test_pull_image_none(self):
result = self.container.pull_image(None)
@@ -260,98 +282,78 @@ class ContainerTesting(unittest.TestCase):
mock_remove.assert_called_once_with(old_obj)
self.assertEquals(docker_image, result)
- @patch('dovetail.container.dt_utils')
- def test_pull_image_only(self, mock_utils):
+ def test_pull_image_only(self):
docker_image = 'image'
- mock_utils.exec_cmd.return_value = (0, 'msg')
result = self.container.pull_image_only(docker_image)
- cmd = 'sudo docker pull %s' % (docker_image)
- mock_utils.exec_cmd.assert_called_once_with(cmd, self.logger)
self.logger.debug.assert_called_once_with(
'Success to pull docker image {}!'.format(docker_image))
self.assertEquals(True, result)
- @patch('dovetail.container.dt_utils')
- def test_pull_image_only_error(self, mock_utils):
+ def test_pull_image_only_error(self):
docker_image = 'image'
- mock_utils.exec_cmd.return_value = (1, 'error')
+ self.client.images.pull.side_effect = docker.errors.APIError('error')
result = self.container.pull_image_only(docker_image)
- cmd = 'sudo docker pull %s' % (docker_image)
- mock_utils.exec_cmd.assert_called_once_with(cmd, self.logger)
self.logger.error.assert_called_once_with(
'Failed to pull docker image {}!'.format(docker_image))
self.assertEquals(False, result)
- @patch('dovetail.container.dt_utils')
- def test_remove_image(self, mock_utils):
+ def test_remove_image(self):
image_id = 'image_id'
- mock_utils.exec_cmd.side_effect = [(1, 'error'), (0, 'msg')]
+ self.client.containers.list.side_effect = \
+ docker.errors.APIError('error')
result = self.container.remove_image(image_id)
- mock_utils.exec_cmd.assert_has_calls([
- call("sudo docker ps -aq -f 'ancestor=%s'" % (image_id),
- self.logger),
- call('sudo docker rmi %s' % (image_id), self.logger)])
self.logger.debug.assert_has_calls([
call('Remove image {}.'.format(image_id)),
call('Remove image {} successfully.'.format(image_id))])
self.assertEquals(True, result)
- @patch('dovetail.container.dt_utils')
- def test_remove_image_ancestors(self, mock_utils):
+ def test_remove_image_ancestors(self):
image_id = 'image_id'
- mock_utils.exec_cmd.return_value = (0, 'msg')
+ self.client.containers.list.return_value = ['cont_a']
result = self.container.remove_image(image_id)
- cmd = "sudo docker ps -aq -f 'ancestor=%s'" % (image_id)
- mock_utils.exec_cmd.assert_called_once_with(cmd, self.logger)
self.logger.debug.assert_called_once_with(
'Image {} has containers, skip.'.format(image_id))
self.assertEquals(True, result)
- @patch('dovetail.container.dt_utils')
- def test_remove_image_error(self, mock_utils):
+ def test_remove_image_error(self):
image_id = 'image_id'
- mock_utils.exec_cmd.return_value = (1, 'error')
+ self.client.containers.list.return_value = []
+ self.client.images.remove.side_effect = \
+ docker.errors.ImageNotFound('error')
result = self.container.remove_image(image_id)
- mock_utils.exec_cmd.assert_has_calls([
- call("sudo docker ps -aq -f 'ancestor=%s'" % (image_id),
- self.logger),
- call('sudo docker rmi %s' % (image_id), self.logger)])
self.logger.debug.assert_called_once_with(
'Remove image {}.'.format(image_id))
self.logger.error.assert_called_once_with(
'Failed to remove image {}.'.format(image_id))
self.assertEquals(False, result)
- @patch('dovetail.container.dt_utils')
- def test_get_image_id(self, mock_utils):
+ def test_get_image_id(self):
image_name = 'image_id'
- mock_utils.exec_cmd.return_value = (0, image_name)
+ mock_img = Mock()
+ mock_img.id = image_name
+ self.client.images.get.return_value = mock_img
result = self.container.get_image_id(image_name)
- cmd = 'sudo docker images -q %s' % (image_name)
- mock_utils.exec_cmd.assert_called_once_with(cmd, self.logger)
self.assertEquals(image_name, result)
- @patch('dovetail.container.dt_utils')
- def test_get_image_id_error(self, mock_utils):
+ def test_get_image_id_error(self):
image_name = 'image_id'
- mock_utils.exec_cmd.return_value = (1, 'error')
+ self.client.images.get.side_effect = \
+ docker.errors.ImageNotFound('error')
result = self.container.get_image_id(image_name)
- cmd = 'sudo docker images -q %s' % (image_name)
- mock_utils.exec_cmd.assert_called_once_with(cmd, self.logger)
self.assertEquals(None, result)
@patch('dovetail.container.dt_utils')
@@ -406,9 +408,11 @@ class ContainerTesting(unittest.TestCase):
docker_image = 'docker_image'
container_id = 'container_id'
mock_utils.get_value_from_dict.side_effect = [
- 'opts', 'shell', 'envs', ['volume_one', 'volume_two']]
+ {'key': 'value'}, 'shell', 'envs', ['volume_one', 'volume_two']]
mock_utils.get_hosts_info.return_value = 'host_info'
- mock_utils.exec_cmd.return_value = (0, container_id)
+ container_obj = Mock()
+ container_obj.id = container_id
+ self.client.containers.run.return_value = container_obj
project_config = {}
mock_config.dovetail_config = {'bottlenecks': project_config}
@@ -421,9 +425,6 @@ class ContainerTesting(unittest.TestCase):
call('envs', project_config),
call('volumes', project_config)])
mock_utils.get_hosts_info.assert_called_once_with(self.logger)
- mock_utils.exec_cmd.assert_called_once_with(
- 'sudo docker run opts envs volume_one volume_two host_info '
- 'docker_image shell', self.logger)
self.assertEquals(expected, result)
@patch('dovetail.container.dt_utils')
@@ -446,10 +447,11 @@ class ContainerTesting(unittest.TestCase):
def test_create_error(self, mock_config, mock_utils):
docker_image = 'docker_image'
mock_utils.get_value_from_dict.side_effect = [
- 'opts', 'shell', 'envs', ['volume_one']]
+ {'key': 'value'}, 'shell', ['envs'], ['volume_one']]
mock_utils.get_hosts_info.return_value = 'host_info'
mock_utils.check_https_enabled.return_value = True
- mock_utils.exec_cmd.return_value = (1, 'error')
+ self.client.containers.run.side_effect = \
+ docker.errors.ImageNotFound('error')
project_config = {}
mock_config.dovetail_config = {'bottlenecks': project_config}
result = self.container.create(docker_image)
@@ -460,7 +462,4 @@ class ContainerTesting(unittest.TestCase):
call('envs', project_config),
call('volumes', project_config)])
mock_utils.get_hosts_info.assert_called_once_with(self.logger)
- mock_utils.exec_cmd.assert_called_once_with(
- 'sudo docker run opts envs volume_one host_info '
- 'docker_image shell', self.logger)
self.assertEquals(None, result)
diff --git a/dovetail/tests/unit/utils/test_dovetail_utils.py b/dovetail/tests/unit/utils/test_dovetail_utils.py
index 0f0e14f3..33fc1eae 100644
--- a/dovetail/tests/unit/utils/test_dovetail_utils.py
+++ b/dovetail/tests/unit/utils/test_dovetail_utils.py
@@ -227,7 +227,7 @@ class DovetailUtilsTesting(unittest.TestCase):
mock_path.isfile.return_value = False
logger = Mock()
- expected = ''
+ expected = {}
result = dovetail_utils.get_hosts_info(logger)
mock_path.join.assert_called_once_with(file_path, 'hosts.yaml')
@@ -248,7 +248,7 @@ class DovetailUtilsTesting(unittest.TestCase):
mock_load.return_value = None
logger = Mock()
- expected = ''
+ expected = {}
result = dovetail_utils.get_hosts_info(logger)
mock_path.join.assert_called_once_with(file_path, 'hosts.yaml')
@@ -274,7 +274,7 @@ class DovetailUtilsTesting(unittest.TestCase):
mock_load.return_value = {'a': 'b'}
logger = Mock()
- expected = ''
+ expected = {}
result = dovetail_utils.get_hosts_info(logger)
mock_path.join.assert_called_once_with(file_path, 'hosts.yaml')
@@ -299,7 +299,7 @@ class DovetailUtilsTesting(unittest.TestCase):
mock_open.return_value.__enter__.return_value = file_obj
mock_load.return_value = {'hosts_info': {'127.0.0.1': []}}
- expected = ''
+ expected = {}
result = dovetail_utils.get_hosts_info()
mock_path.join.assert_called_once_with(file_path, 'hosts.yaml')
@@ -324,7 +324,7 @@ class DovetailUtilsTesting(unittest.TestCase):
hosts_info = {'127.0.0.1': [None]}
mock_load.return_value = {'hosts_info': hosts_info}
- expected = ''
+ expected = {}
result = dovetail_utils.get_hosts_info()
mock_path.join.assert_called_once_with(file_path, 'hosts.yaml')
@@ -353,7 +353,7 @@ class DovetailUtilsTesting(unittest.TestCase):
logger = Mock()
names_str = ' '.join(hostnames)
- expected = ' --add-host=\'{}\':{} '.format(names_str, hosts_ip)
+ expected = {names_str: hosts_ip}
result = dovetail_utils.get_hosts_info(logger)
mock_path.join.assert_called_once_with(file_path, 'hosts.yaml')
@@ -547,66 +547,45 @@ class DovetailUtilsTesting(unittest.TestCase):
mock_open.assert_called_once_with(file_path, 'r')
mock_env.update.assert_called_once_with({env_name: env_value})
- @patch('dovetail.utils.dovetail_utils.exec_cmd')
- def test_check_docker_version(self, mock_exec):
- server_version = client_version = '1.12.3'
- server_ret = client_ret = 0
- mock_exec.side_effect = [(server_ret, server_version),
- (client_ret, client_version)]
+ @patch('dovetail.utils.dovetail_utils.docker')
+ def test_check_docker_version(self, mock_docker):
+ server_version = '1.12.3'
+ client_obj = Mock()
+ mock_docker.from_env.return_value = client_obj
+ client_obj.version.return_value = {'Version': server_version}
logger = Mock()
dovetail_utils.check_docker_version(logger)
- mock_exec.assert_has_calls(
- [call("sudo docker version -f'{{.Server.Version}}'",
- logger=logger),
- call("sudo docker version -f'{{.Client.Version}}'",
- logger=logger)])
logger.debug.assert_has_calls(
- [call('docker server version: {}'.format(server_version)),
- call('docker client version: {}'.format(client_version))])
+ [call('Docker server version: {}'.format(server_version))])
- @patch('dovetail.utils.dovetail_utils.exec_cmd')
- def test_check_docker_version_error(self, mock_exec):
- server_version = client_version = '1.12.3'
- server_ret = client_ret = 1
- mock_exec.side_effect = [(server_ret, server_version),
- (client_ret, client_version)]
+ @patch('dovetail.utils.dovetail_utils.docker')
+ def test_check_docker_version_error(self, mock_docker):
+ client_obj = Mock()
+ mock_docker.from_env.return_value = client_obj
+ client_obj.version.return_value = {}
logger = Mock()
dovetail_utils.check_docker_version(logger)
- mock_exec.assert_has_calls(
- [call("sudo docker version -f'{{.Server.Version}}'",
- logger=logger),
- call("sudo docker version -f'{{.Client.Version}}'",
- logger=logger)])
logger.error.assert_has_calls(
[call("Don't support this Docker server version. "
- "Docker server should be updated to at least 1.12.3."),
- call("Don't support this Docker client version. "
- "Docker client should be updated to at least 1.12.3.")])
-
- @patch('dovetail.utils.dovetail_utils.exec_cmd')
- def test_check_docker_version_less_than(self, mock_exec):
- server_version = client_version = '1.12.1'
- server_ret = client_ret = 0
- mock_exec.side_effect = [(server_ret, server_version),
- (client_ret, client_version)]
+ "Docker server should be updated to at least 1.12.3.")])
+
+ @patch('dovetail.utils.dovetail_utils.docker')
+ def test_check_docker_version_less_than(self, mock_docker):
+ server_version = '1.12.1'
+ client_obj = Mock()
+ mock_docker.from_env.return_value = client_obj
+ client_obj.version.return_value = {'Version': server_version}
logger = Mock()
dovetail_utils.check_docker_version(logger)
- mock_exec.assert_has_calls(
- [call("sudo docker version -f'{{.Server.Version}}'",
- logger=logger),
- call("sudo docker version -f'{{.Client.Version}}'",
- logger=logger)])
logger.error.assert_has_calls(
[call("Don't support this Docker server version. "
- "Docker server should be updated to at least 1.12.3."),
- call("Don't support this Docker client version. "
- "Docker client should be updated to at least 1.12.3.")])
+ "Docker server should be updated to at least 1.12.3.")])
@patch('__builtin__.open')
@patch('os.path')
diff --git a/dovetail/utils/dovetail_utils.py b/dovetail/utils/dovetail_utils.py
index 0f26eb26..a3d07824 100644
--- a/dovetail/utils/dovetail_utils.py
+++ b/dovetail/utils/dovetail_utils.py
@@ -19,6 +19,7 @@ from datetime import datetime
from distutils.version import LooseVersion
import yaml
import python_hosts
+import docker
from dovetail import constants
from dovetail_config import DovetailConfig as dt_cfg
@@ -157,20 +158,17 @@ def show_progress_bar(length):
def check_docker_version(logger=None):
- server_ret, server_ver = \
- exec_cmd("sudo docker version -f'{{.Server.Version}}'", logger=logger)
- client_ret, client_ver = \
- exec_cmd("sudo docker version -f'{{.Client.Version}}'", logger=logger)
- if server_ret == 0:
- logger.debug('docker server version: {}'.format(server_ver))
- if server_ret != 0 or (LooseVersion(server_ver) < LooseVersion('1.12.3')):
+ client = docker.from_env()
+ server_ver = None
+ try:
+ server_ver = client.version()['Version']
+ except Exception:
+ logger.error('Failed to get Docker server version')
+ if server_ver and (LooseVersion(server_ver) >= LooseVersion('1.12.3')):
+ logger.debug('Docker server version: {}'.format(server_ver))
+ else:
logger.error("Don't support this Docker server version. "
"Docker server should be updated to at least 1.12.3.")
- if client_ret == 0:
- logger.debug('docker client version: {}'.format(client_ver))
- if client_ret != 0 or (LooseVersion(client_ver) < LooseVersion('1.12.3')):
- logger.error("Don't support this Docker client version. "
- "Docker client should be updated to at least 1.12.3.")
def add_hosts_info(ip, hostnames):
@@ -316,7 +314,7 @@ def check_cacert_file(cacert, logger=None):
def get_hosts_info(logger=None):
- hosts_config = ''
+ hosts_config = {}
hosts_config_file = os.path.join(dt_cfg.dovetail_config['config_dir'],
'hosts.yaml')
if not os.path.isfile(hosts_config_file):
@@ -341,7 +339,7 @@ def get_hosts_info(logger=None):
if hostname)
if not names_str:
continue
- hosts_config += ' --add-host=\'{}\':{} '.format(names_str, ip)
+ hosts_config[names_str] = ip
logger.debug('Get hosts info {}:{}.'.format(ip, names_str))
return hosts_config
diff --git a/etc/conf/bottlenecks_config.yml b/etc/conf/bottlenecks_config.yml
index 8a0a39bc..eb067c4a 100644
--- a/etc/conf/bottlenecks_config.yml
+++ b/etc/conf/bottlenecks_config.yml
@@ -8,7 +8,7 @@
{% set build_tag = build_tag or '' %}
{% set cacert_volume = '' %}
{% if cacert %}
- {% set cacert_volume = ' -v ' + cacert + ':' + cacert %}
+ {% set cacert_volume = cacert + ':' + cacert %}
{% endif %}
{% set openrc_file = '/tmp/admin_rc.sh' %}
{% set result_dir = '/home/opnfv/bottlenecks/results' %}
@@ -19,18 +19,24 @@
bottlenecks:
image_name: opnfv/bottlenecks
docker_tag: latest
- opts: '-id --privileged=true'
+ opts:
+ detach: true
+ stdin_open: true
+ privileged: true
shell: '/bin/bash'
- envs: '-e DEPLOY_SCENARIO={{deploy_scenario}} -e Yardstick_TAG=stable
- -e OUTPUT_FILE={{testcase}}.out -e CI_DEBUG={{debug}}
- -e BUILD_TAG={{build_tag}}-{{testcase}}'
+ envs:
+ - 'DEPLOY_SCENARIO={{deploy_scenario}}'
+ - 'Yardstick_TAG=stable'
+ - 'OUTPUT_FILE={{testcase}}.out'
+ - 'CI_DEBUG={{debug}}'
+ - 'BUILD_TAG={{build_tag}}-{{testcase}}'
volumes:
- - '-v /var/run/docker.sock:/var/run/docker.sock'
- - '-v {{dovetail_home}}/results/bottlenecks:/tmp'
- - '-v {{dovetail_home}}/pre_config/env_config.sh:{{openrc_file}}'
+ - '/var/run/docker.sock:/var/run/docker.sock'
+ - '{{dovetail_home}}/results/bottlenecks:/tmp'
+ - '{{dovetail_home}}/pre_config/env_config.sh:{{openrc_file}}'
- {{cacert_volume}}
- - '-v {{dovetail_home}}/images:{{images_dir}}'
- - '-v {{dovetail_home}}/results:{{result_dir}}'
+ - '{{dovetail_home}}/images:{{images_dir}}'
+ - '{{dovetail_home}}/results:{{result_dir}}'
pre_condition:
- 'cp {{images_dir}}/ubuntu-16.04-server-cloudimg-amd64-disk1.img {{image_file}}'
cmds:
diff --git a/etc/conf/functest-k8s_config.yml b/etc/conf/functest-k8s_config.yml
index b5ad12b6..e4781715 100644
--- a/etc/conf/functest-k8s_config.yml
+++ b/etc/conf/functest-k8s_config.yml
@@ -12,15 +12,21 @@
functest-k8s:
image_name: opnfv/functest-kubernetes-healthcheck
docker_tag: gambia
- opts: '-id'
+ opts:
+ detach: true
+ stdin_open: true
shell: '/bin/bash'
- envs: '-e INSTALLER_TYPE=unknown -e DEPLOY_SCENARIO=k8-deploy -e NODE_NAME=unknown
- -e TEST_DB_URL=file:///home/opnfv/functest/results/functest_results.txt
- -e CI_DEBUG={{debug}} -e BUILD_TAG={{build_tag}}-{{testcase}}'
+ envs:
+ - 'INSTALLER_TYPE=unknown'
+ - 'DEPLOY_SCENARIO=k8-deploy'
+ - 'NODE_NAME=unknown'
+ - 'TEST_DB_URL=file:///home/opnfv/functest/results/functest_results.txt'
+ - 'CI_DEBUG={{debug}}'
+ - 'BUILD_TAG={{build_tag}}-{{testcase}}'
volumes:
- - '-v {{dovetail_home}}/pre_config/k8.creds:{{openrc_file}}'
- - '-v {{dovetail_home}}/pre_config/admin.conf:{{kube_file}}'
- - '-v {{dovetail_home}}/results/:{{result_dir}}'
+ - '{{dovetail_home}}/pre_config/k8.creds:{{openrc_file}}'
+ - '{{dovetail_home}}/pre_config/admin.conf:{{kube_file}}'
+ - '{{dovetail_home}}/results/:{{result_dir}}'
pre_condition:
- 'echo test for precondition in functest'
cmds:
diff --git a/etc/conf/functest_config.yml b/etc/conf/functest_config.yml
index bf637541..3bf90218 100644
--- a/etc/conf/functest_config.yml
+++ b/etc/conf/functest_config.yml
@@ -6,14 +6,14 @@
{% set os_insecure = os_insecure or 'False' %}
{% set os_verify = '' %}
{% if os_insecure == 'True' %}
- {% set os_verify = ' -e OS_VERIFY= ' %}
+ {% set os_verify = 'OS_VERIFY=' %}
{% endif %}
{% set dovetail_home = dovetail_home or '' %}
{% set debug = debug or 'false' %}
{% set build_tag = build_tag or '' %}
{% set cacert_volume = '' %}
{% if cacert %}
- {% set cacert_volume = ' -v ' + cacert + ':' + cacert %}
+ {% set cacert_volume = cacert + ':' + cacert %}
{% endif %}
{% set openrc_file = '/home/opnfv/functest/conf/env_file' %}
{% set result_dir = '/home/opnfv/functest/results' %}
@@ -24,19 +24,27 @@
functest:
image_name: opnfv/functest-smoke
docker_tag: gambia
- opts: '-id --privileged=true'
+ opts:
+ detach: true
+ stdin_open: true
+ privileged: true
shell: '/bin/bash'
- envs: '{{os_verify}} -e INSTALLER_TYPE=unknown -e DEPLOY_SCENARIO={{deploy_scenario}} -e NODE_NAME=unknown
- -e TEST_DB_URL=file://{{result_dir}}/functest_results.txt
- -e CI_DEBUG={{debug}} -e BUILD_TAG={{build_tag}}-{{testcase}}'
+ envs:
+ - {{os_verify}}
+ - 'INSTALLER_TYPE=unknown'
+ - 'DEPLOY_SCENARIO={{deploy_scenario}}'
+ - 'NODE_NAME=unknown'
+ - 'TEST_DB_URL=file://{{result_dir}}/functest_results.txt'
+ - 'CI_DEBUG={{debug}}'
+ - 'BUILD_TAG={{build_tag}}-{{testcase}}'
volumes:
- - '-v {{dovetail_home}}/pre_config/env_config.sh:{{openrc_file}}'
+ - '{{dovetail_home}}/pre_config/env_config.sh:{{openrc_file}}'
- {{cacert_volume}}
- - '-v {{dovetail_home}}/pre_config:/home/opnfv/pre_config'
- - '-v {{dovetail_home}}/userconfig:{{userconfig_dir}}'
- - '-v {{dovetail_home}}/patches:{{patches_dir}}'
- - '-v {{dovetail_home}}/results:{{result_dir}}'
- - '-v {{dovetail_home}}/images:{{images_dir}}'
+ - '{{dovetail_home}}/pre_config:/home/opnfv/pre_config'
+ - '{{dovetail_home}}/userconfig:{{userconfig_dir}}'
+ - '{{dovetail_home}}/patches:{{patches_dir}}'
+ - '{{dovetail_home}}/results:{{result_dir}}'
+ - '{{dovetail_home}}/images:{{images_dir}}'
patches_dir: {{patches_dir}}
pre_condition:
- 'echo test for precondition in functest'
diff --git a/etc/conf/onap-vtp_config.yml b/etc/conf/onap-vtp_config.yml
index 72ebeab2..eb9b024d 100644
--- a/etc/conf/onap-vtp_config.yml
+++ b/etc/conf/onap-vtp_config.yml
@@ -10,13 +10,17 @@
onap-vtp:
image_name: nexus3.onap.org:10001/onap/cli
docker_tag: 2.0.5
- opts: '-td '
+ opts:
+ detach: true
+ tty: true
shell: '/bin/bash'
- envs: '-e OPEN_CLI_MODE=daemon -e BUILD_TAG={{build_tag}}-{{testcase}}
- -e OPEN_CLI_PRODUCT_IN_USE=onap-vtp'
+ envs:
+ - 'OPEN_CLI_MODE=daemon'
+ - 'BUILD_TAG={{build_tag}}-{{testcase}}'
+ - 'OPEN_CLI_PRODUCT_IN_USE=onap-vtp'
volumes:
- - '-v {{dovetail_home}}/pre_config/{{csar_file}}:/{{csar_file}}'
- - '-v {{dovetail_home}}/results:{{result_dir}}'
+ - '{{dovetail_home}}/pre_config/{{csar_file}}:/{{csar_file}}'
+ - '{{dovetail_home}}/results:{{result_dir}}'
pre_condition:
- 'echo this is pre_condition'
cmds:
diff --git a/etc/conf/onap-vvp_config.yml b/etc/conf/onap-vvp_config.yml
index 67d21fae..d812e1f4 100644
--- a/etc/conf/onap-vvp_config.yml
+++ b/etc/conf/onap-vvp_config.yml
@@ -7,11 +7,14 @@
onap-vvp:
image_name: nexus3.onap.org:10001/onap/vvp/validation-scripts
docker_tag: latest
- opts: '-td --entrypoint=""'
+ opts:
+ detach: true
+ tty: true
+ entrypoint: ''
shell: '/bin/ash'
volumes:
- - '-v {{dovetail_home}}/pre_config/{{heat_templates_archive}}.tar.gz:/tmp/{{heat_templates_archive}}.tar.gz'
- - '-v {{dovetail_home}}/results:{{result_dir}}'
+ - '{{dovetail_home}}/pre_config/{{heat_templates_archive}}.tar.gz:/tmp/{{heat_templates_archive}}.tar.gz'
+ - '{{dovetail_home}}/results:{{result_dir}}'
pre_condition:
- 'tar xf /tmp/{{heat_templates_archive}}.tar.gz -C /vvp'
cmds:
diff --git a/etc/conf/yardstick_config.yml b/etc/conf/yardstick_config.yml
index e43989e2..610cbfd8 100644
--- a/etc/conf/yardstick_config.yml
+++ b/etc/conf/yardstick_config.yml
@@ -7,14 +7,14 @@
{% set os_insecure = os_insecure or 'False' %}
{% set os_verify = '' %}
{% if os_insecure == 'True' %}
- {% set os_verify = ' -e OS_VERIFY= ' %}
+ {% set os_verify = 'OS_VERIFY=' %}
{% endif %}
{% set dovetail_home = dovetail_home or '' %}
{% set debug = debug or 'false' %}
{% set build_tag = build_tag or '' %}
{% set cacert_volume = '' %}
{% if cacert %}
- {% set cacert_volume = ' -v ' + cacert + ':' + cacert %}
+ {% set cacert_volume = cacert + ':' + cacert %}
{% endif %}
{% set openrc_file = '/etc/yardstick/openstack.creds' %}
{% set pod_file = '/etc/yardstick/pod.yaml' %}
@@ -23,16 +23,22 @@
yardstick:
image_name: opnfv/yardstick
docker_tag: latest
- opts: '-id --privileged=true'
+ opts:
+ detach: true
+ stdin_open: true
+ privileged: true
shell: '/bin/bash'
- envs: "{{os_verify}} -e YARDSTICK_BRANCH=fraser -e CI_DEBUG={{debug}}
- -e BUILD_TAG={{build_tag}}-{{testcase}}"
+ envs:
+ - {{os_verify}}
+ - 'YARDSTICK_BRANCH=fraser'
+ - 'CI_DEBUG={{debug}}'
+ - 'BUILD_TAG={{build_tag}}-{{testcase}}"'
volumes:
- - '-v {{dovetail_home}}/pre_config/env_config.sh:{{openrc_file}}'
+ - '{{dovetail_home}}/pre_config/env_config.sh:{{openrc_file}}'
- {{cacert_volume}}
- - '-v {{dovetail_home}}/pre_config/pod.yaml:{{pod_file}}'
- - '-v {{dovetail_home}}/images:/home/opnfv/images'
- - '-v {{dovetail_home}}/results:{{result_dir}}'
+ - '{{dovetail_home}}/pre_config/pod.yaml:{{pod_file}}'
+ - '{{dovetail_home}}/images:/home/opnfv/images'
+ - '{{dovetail_home}}/results:{{result_dir}}'
pre_condition:
- 'echo this is pre_condition'
cmds:
diff --git a/requirements.txt b/requirements.txt
index b79c1b64..7f95c60e 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -6,3 +6,4 @@ pbr==3.1.1
python-hosts==0.4.1
PyYAML==3.12
shade==1.27.2
+docker==3.4.1