aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRodolfo Alonso Hernandez <rodolfo.alonso.hernandez@intel.com>2018-05-05 11:13:28 +0100
committerRodolfo Alonso Hernandez <rodolfo.alonso.hernandez@intel.com>2018-06-14 07:15:23 +0000
commit34292694f596561de9c78f0feb663ffa5de0dc2d (patch)
tree2460af044a7f541cc7e103ee542f59379a2d6c25
parent01edaefa20775921200a6a1b17fbfd67f7aca77e (diff)
Define several containers per pod in a replication controller
Add the ability to define not only one but many containers per pod in a replication controller descriptor. This feature must be backwards compatible; all current test cases using the "single container" server definition must be accepted. Example of single container pod definition: context: type: Kubernetes servers: host: image: ... commands: ... volumes: - name: volume1 # mandatory <volume type definition> # mandatory Example of several container pod definition: context: type: Kubernetes servers: host: containers: # if this key is present, all container specific parameters (image, commands, args, volumeMounts, etc.) must be defined per container - image: ... commands: ... - image: ... commands: ... volumes: - name: volume1 # mandatory <volume type definition> # mandatory NOTE: other parameters, like "volumes" or "nodeSelector", are common to all containers in the pod. JIRA: YARDSTICK-1155 Change-Id: Ib95668c68e9c09e6de3f1aa41c903cc52e6809ad Signed-off-by: Rodolfo Alonso Hernandez <rodolfo.alonso.hernandez@intel.com>
-rw-r--r--yardstick/orchestrator/kubernetes.py87
-rw-r--r--yardstick/tests/unit/orchestrator/test_kubernetes.py65
2 files changed, 102 insertions, 50 deletions
diff --git a/yardstick/orchestrator/kubernetes.py b/yardstick/orchestrator/kubernetes.py
index e05c971ac..8ccb98853 100644
--- a/yardstick/orchestrator/kubernetes.py
+++ b/yardstick/orchestrator/kubernetes.py
@@ -14,23 +14,66 @@ from yardstick.common import utils
from yardstick.common import kubernetes_utils as k8s_utils
-class KubernetesObject(object):
+class ContainerObject(object):
SSH_MOUNT_PATH = '/tmp/.ssh/'
IMAGE_DEFAULT = 'openretriever/yardstick'
COMMAND_DEFAULT = '/bin/bash'
+
+ def __init__(self, name, ssh_key, **kwargs):
+ self._name = name
+ self._ssh_key = ssh_key
+ self._image = kwargs.get('image', self.IMAGE_DEFAULT)
+ self._command = [kwargs.get('command', self.COMMAND_DEFAULT)]
+ self._args = kwargs.get('args', [])
+ self._volume_mounts = kwargs.get('volumeMounts', [])
+
+ def _create_volume_mounts(self):
+ """Return all "volumeMounts" items per container"""
+ volume_mounts_items = [self._create_volume_mounts_item(vol)
+ for vol in self._volume_mounts]
+ ssh_vol = {'name': self._ssh_key,
+ 'mountPath': self.SSH_MOUNT_PATH}
+ volume_mounts_items.append(self._create_volume_mounts_item(ssh_vol))
+ return volume_mounts_items
+
+ @staticmethod
+ def _create_volume_mounts_item(volume_mount):
+ """Create a "volumeMounts" item"""
+ return {'name': volume_mount['name'],
+ 'mountPath': volume_mount['mountPath'],
+ 'readOnly': volume_mount.get('readOnly', False)}
+
+ def get_container_item(self):
+ """Create a "container" item"""
+ container_name = '{}-container'.format(self._name)
+ return {'args': self._args,
+ 'command': self._command,
+ 'image': self._image,
+ 'name': container_name,
+ 'volumeMounts': self._create_volume_mounts()}
+
+
+class KubernetesObject(object):
+
SSHKEY_DEFAULT = 'yardstick_key'
def __init__(self, name, **kwargs):
super(KubernetesObject, self).__init__()
+ parameters = copy.deepcopy(kwargs)
self.name = name
- self.image = kwargs.get('image', self.IMAGE_DEFAULT)
- self.command = [kwargs.get('command', self.COMMAND_DEFAULT)]
- self.args = kwargs.get('args', [])
- self.ssh_key = kwargs.get('ssh_key', self.SSHKEY_DEFAULT)
- self.node_selector = kwargs.get('nodeSelector', {})
- self._volumes = kwargs.get('volumes', [])
- self._volume_mounts = kwargs.get('volumeMounts', [])
+ self.node_selector = parameters.pop('nodeSelector', {})
+ self.ssh_key = parameters.pop('ssh_key', self.SSHKEY_DEFAULT)
+ self._volumes = parameters.pop('volumes', [])
+
+ containers = parameters.pop('containers', None)
+ if containers:
+ self._containers = [
+ ContainerObject(self.name, self.ssh_key, **container)
+ for container in containers]
+ else:
+ self._containers = [
+ ContainerObject(self.name, self.ssh_key, **parameters)]
self.template = {
"apiVersion": "v1",
@@ -71,20 +114,12 @@ class KubernetesObject(object):
name)
def _add_containers(self):
- containers = [self._create_container_item()]
+ containers = [container.get_container_item()
+ for container in self._containers]
utils.set_dict_value(self.template,
'spec.template.spec.containers',
containers)
- def _create_container_item(self):
- """Create a "container" item"""
- container_name = '{}-container'.format(self.name)
- return {'args': self.args,
- 'command': self.command,
- 'image': self.image,
- 'name': container_name,
- 'volumeMounts': self._create_volume_mounts()}
-
def _add_node_selector(self):
utils.set_dict_value(self.template,
'spec.template.spec.nodeSelector',
@@ -118,22 +153,6 @@ class KubernetesObject(object):
return {'name': name,
type_name: type_data}
- def _create_volume_mounts(self):
- """Return all "volumeMounts" items per container"""
- volume_mounts_items = [self._create_volume_mounts_item(vol)
- for vol in self._volume_mounts]
- ssh_vol = {'name': self.ssh_key,
- 'mountPath': self.SSH_MOUNT_PATH}
- volume_mounts_items.append(self._create_volume_mounts_item(ssh_vol))
- return volume_mounts_items
-
- @staticmethod
- def _create_volume_mounts_item(volume_mount):
- """Create a "volumeMounts" item"""
- return {'name': volume_mount['name'],
- 'mountPath': volume_mount['mountPath'],
- 'readOnly': volume_mount.get('readOnly', False)}
-
class ServiceObject(object):
diff --git a/yardstick/tests/unit/orchestrator/test_kubernetes.py b/yardstick/tests/unit/orchestrator/test_kubernetes.py
index 21a12a0d3..4323c026a 100644
--- a/yardstick/tests/unit/orchestrator/test_kubernetes.py
+++ b/yardstick/tests/unit/orchestrator/test_kubernetes.py
@@ -110,6 +110,36 @@ service ssh restart;while true ; do sleep 10000; done']
class KubernetesObjectTestCase(base.BaseUnitTestCase):
+ def test__init_one_container(self):
+ pod_name = 'pod_name'
+ _kwargs = {'args': ['arg1', 'arg2'],
+ 'image': 'fake_image',
+ 'command': 'fake_command'}
+ k8s_obj = kubernetes.KubernetesObject(pod_name, **_kwargs)
+ self.assertEqual(1, len(k8s_obj._containers))
+ container = k8s_obj._containers[0]
+ self.assertEqual(['arg1', 'arg2'], container._args)
+ self.assertEqual('fake_image', container._image)
+ self.assertEqual(['fake_command'], container._command)
+ self.assertEqual([], container._volume_mounts)
+
+ def test__init_multipe_containers(self):
+ pod_name = 'pod_name'
+ containers = []
+ for i in range(5):
+ containers.append({'args': ['arg1', 'arg2'],
+ 'image': 'fake_image_%s' % i,
+ 'command': 'fake_command_%s' % i})
+ _kwargs = {'containers': containers}
+ k8s_obj = kubernetes.KubernetesObject(pod_name, **_kwargs)
+ self.assertEqual(5, len(k8s_obj._containers))
+ for i in range(5):
+ container = k8s_obj._containers[i]
+ self.assertEqual(['arg1', 'arg2'], container._args)
+ self.assertEqual('fake_image_%s' % i, container._image)
+ self.assertEqual(['fake_command_%s' % i], container._command)
+ self.assertEqual([], container._volume_mounts)
+
def test__add_volumes(self):
volume1 = {'name': 'fake_sshkey',
'configMap': {'name': 'fake_sshkey'}}
@@ -150,26 +180,29 @@ class KubernetesObjectTestCase(base.BaseUnitTestCase):
with self.assertRaises(exceptions.KubernetesTemplateInvalidVolumeType):
kubernetes.KubernetesObject._create_volume_item(volume)
+
+class ContainerObjectTestCase(base.BaseUnitTestCase):
+
def test__create_volume_mounts(self):
volume_mount = {'name': 'fake_name',
'mountPath': 'fake_path'}
- ssh_vol = {'name': kubernetes.KubernetesObject.SSHKEY_DEFAULT,
- 'mountPath': kubernetes.KubernetesObject.SSH_MOUNT_PATH,
+ ssh_vol = {'name': 'fake_ssh_key',
+ 'mountPath': kubernetes.ContainerObject.SSH_MOUNT_PATH,
'readOnly': False}
expected = copy.deepcopy(volume_mount)
expected['readOnly'] = False
expected = [expected, ssh_vol]
- k8s_obj = kubernetes.KubernetesObject('name',
- volumeMounts=[volume_mount])
- output = k8s_obj._create_volume_mounts()
+ container_obj = kubernetes.ContainerObject(
+ 'cname', 'fake_ssh_key', volumeMounts=[volume_mount])
+ output = container_obj._create_volume_mounts()
self.assertEqual(expected, output)
def test__create_volume_mounts_no_volume_mounts(self):
- ssh_vol = {'name': kubernetes.KubernetesObject.SSHKEY_DEFAULT,
- 'mountPath': kubernetes.KubernetesObject.SSH_MOUNT_PATH,
+ ssh_vol = {'name': 'fake_ssh_key2',
+ 'mountPath': kubernetes.ContainerObject.SSH_MOUNT_PATH,
'readOnly': False}
- k8s_obj = kubernetes.KubernetesObject('name')
- output = k8s_obj._create_volume_mounts()
+ container_obj = kubernetes.ContainerObject('name', 'fake_ssh_key2')
+ output = container_obj._create_volume_mounts()
self.assertEqual([ssh_vol], output)
def test__create_volume_mounts_item(self):
@@ -177,20 +210,20 @@ class KubernetesObjectTestCase(base.BaseUnitTestCase):
'mountPath': 'fake_path'}
expected = copy.deepcopy(volume_mount)
expected['readOnly'] = False
- output = kubernetes.KubernetesObject._create_volume_mounts_item(
+ output = kubernetes.ContainerObject._create_volume_mounts_item(
volume_mount)
self.assertEqual(expected, output)
- def test__create_container_item(self):
+ def test_get_container_item(self):
volume_mount = {'name': 'fake_name',
'mountPath': 'fake_path'}
args = ['arg1', 'arg2']
- k8s_obj = kubernetes.KubernetesObject(
+ container_obj = kubernetes.ContainerObject(
'cname', ssh_key='fake_sshkey', volumeMount=[volume_mount],
args=args)
expected = {'args': args,
- 'command': [kubernetes.KubernetesObject.COMMAND_DEFAULT],
- 'image': kubernetes.KubernetesObject.IMAGE_DEFAULT,
+ 'command': [kubernetes.ContainerObject.COMMAND_DEFAULT],
+ 'image': kubernetes.ContainerObject.IMAGE_DEFAULT,
'name': 'cname-container',
- 'volumeMounts': k8s_obj._create_volume_mounts()}
- self.assertEqual(expected, k8s_obj._create_container_item())
+ 'volumeMounts': container_obj._create_volume_mounts()}
+ self.assertEqual(expected, container_obj.get_container_item())