]> git.apps.os.sepia.ceph.com Git - ceph-ansible.git/commitdiff
ceph_key: rework container support
authorSébastien Han <seb@redhat.com>
Fri, 16 Nov 2018 09:46:10 +0000 (10:46 +0100)
committermergify[bot] <mergify[bot]@users.noreply.github.com>
Tue, 27 Nov 2018 16:47:40 +0000 (16:47 +0000)
Previously, we were doing a 'docker exec' inside a mon container, this
worked but this wasn't ideal since it required a mon to be up to
generate keys. We must be able to generate a key without a running mon,
e.g, when we create the initial key or simply when you want to generate
a key from any node that is not a mon.
Now, just like the ceph_volume module we use a 'docker run' command with
the right binary as an entrypoint to perform the choosen action, this is
more elegant and also only requires an env variable to be set in the
playbook: CEPH_CONTAINER_IMAGE.

Signed-off-by: Sébastien Han <seb@redhat.com>
library/ceph_key.py
library/test_ceph_key.py

index 60df45edd6e6fcf99d4b0aef4b4d2895ea43d6ce..3c92419affbbecd4baf40d806feb2e216bc9f3e7 100644 (file)
@@ -74,12 +74,6 @@ options:
             - keyring's secret value
         required: false
         default: None
-    containerized:
-        description:
-            - Wether or not this is a containerized cluster. The value is
-            assigned or not depending on how the playbook runs.
-        required: false
-        default: None
     import_key:
         description:
             - Wether or not to import the created keyring into Ceph.
@@ -208,6 +202,36 @@ def fatal(message, module):
         raise(Exception(message))
 
 
+def container_exec(binary, container_image):
+    '''
+    Build the docker CLI to run a command inside a container
+    '''
+
+    command_exec = ['docker',
+                    'run',
+                    '--rm',
+                    '--net=host',
+                    '-v', '/etc/ceph:/etc/ceph:z',
+                    '-v', '/var/lib/ceph/:/var/lib/ceph/:z',
+                    '-v', '/var/log/ceph/:/var/log/ceph/:z',
+                    os.path.join('--entrypoint=' + binary),
+                    container_image]
+    return command_exec
+
+
+def is_containerized():
+    '''
+    Check if we are running on a containerized cluster
+    '''
+
+    if 'CEPH_CONTAINER_IMAGE' in os.environ:
+        container_image = os.getenv('CEPH_CONTAINER_IMAGE')
+    else:
+        container_image = None
+
+    return container_image
+
+
 def generate_secret():
     '''
     Generate a CephX secret
@@ -237,15 +261,20 @@ def generate_caps(cmd, _type, caps):
     return cmd
 
 
-def generate_ceph_cmd(cluster, args, user, user_key, containerized=None):
+def generate_ceph_cmd(cluster, args, user, user_key, container_image=None):
     '''
     Generate 'ceph' command line to execute
     '''
 
-    cmd = []
+    if container_image:
+        binary = 'ceph'
+        cmd = container_exec(
+            binary, container_image)
+    else:
+        binary = ['ceph']
+        cmd = binary
 
     base_cmd = [
-        'ceph',
         '-n',
         user,
         '-k',
@@ -257,19 +286,23 @@ def generate_ceph_cmd(cluster, args, user, user_key, containerized=None):
 
     cmd.extend(base_cmd + args)
 
-    if containerized:
-        cmd = containerized.split() + cmd
-
     return cmd
 
 
-def generate_ceph_authtool_cmd(cluster, name, secret, caps, auid, dest, containerized=None):  # noqa E501
+def generate_ceph_authtool_cmd(cluster, name, secret, caps, dest, container_image=None):  # noqa E501
     '''
     Generate 'ceph-authtool' command line to execute
     '''
 
-    cmd = [
-        'ceph-authtool',
+    if container_image:
+        binary = 'ceph-authtool'
+        cmd = container_exec(
+            binary, container_image)
+    else:
+        binary = ['ceph-authtool']
+        cmd = binary
+
+    base_cmd = [
         '--create-keyring',
         dest,
         '--name',
@@ -278,18 +311,17 @@ def generate_ceph_authtool_cmd(cluster, name, secret, caps, auid, dest, containe
         secret,
     ]
 
+    cmd.extend(base_cmd)
+
     if auid:
         cmd.extend(['--set-uid', auid])
 
     cmd = generate_caps(cmd, "ceph-authtool", caps)
 
-    if containerized:
-        cmd = containerized.split() + cmd
-
     return cmd
 
 
-def create_key(module, result, cluster, name, secret, caps, import_key, auid, dest, containerized=None):  # noqa E501
+def create_key(module, result, cluster, name, secret, caps, import_key, dest, container_image=None):  # noqa E501
     '''
     Create a CephX key
     '''
@@ -305,7 +337,7 @@ def create_key(module, result, cluster, name, secret, caps, import_key, auid, de
         secret = generate_secret()
 
     cmd_list.append(generate_ceph_authtool_cmd(
-        cluster, name, secret, caps, auid, dest, containerized))
+        cluster, name, secret, caps, auid, dest, container_image))
 
     if import_key:
         user = "client.admin"
@@ -313,12 +345,12 @@ def create_key(module, result, cluster, name, secret, caps, import_key, auid, de
         user_key = os.path.join(
             "/etc/ceph/" + cluster + ".client.admin.keyring")
         cmd_list.append(generate_ceph_cmd(
-            cluster, args, user, user_key, containerized))
+            cluster, args, user, user_key, container_image))
 
     return cmd_list
 
 
-def update_key(cluster, name, caps, containerized=None):
+def update_key(cluster, name, caps, container_image=None):
     '''
     Update a CephX key's capabilities
     '''
@@ -335,12 +367,12 @@ def update_key(cluster, name, caps, containerized=None):
     user_key = os.path.join(
         "/etc/ceph/" + cluster + ".client.admin.keyring")
     cmd_list.append(generate_ceph_cmd(
-        cluster, args, user, user_key, containerized))
+        cluster, args, user, user_key, container_image))
 
     return cmd_list
 
 
-def delete_key(cluster, name, containerized=None):
+def delete_key(cluster, name, container_image=None):
     '''
     Delete a CephX key
     '''
@@ -356,12 +388,12 @@ def delete_key(cluster, name, containerized=None):
     user_key = os.path.join(
         "/etc/ceph/" + cluster + ".client.admin.keyring")
     cmd_list.append(generate_ceph_cmd(
-        cluster, args, user, user_key, containerized))
+        cluster, args, user, user_key, container_image))
 
     return cmd_list
 
 
-def get_key(cluster, name, dest, containerized=None):
+def get_key(cluster, name, dest, container_image=None):
     '''
     Get a CephX key (write on the filesystem)
     '''
@@ -379,12 +411,12 @@ def get_key(cluster, name, dest, containerized=None):
     user_key = os.path.join(
         "/etc/ceph/" + cluster + ".client.admin.keyring")
     cmd_list.append(generate_ceph_cmd(
-        cluster, args, user, user_key, containerized))
+        cluster, args, user, user_key, container_image))
 
     return cmd_list
 
 
-def info_key(cluster, name, user, user_key, output_format, containerized=None):
+def info_key(cluster, name, user, user_key, output_format, container_image=None):  # noqa E501
     '''
     Get information about a CephX key
     '''
@@ -399,12 +431,12 @@ def info_key(cluster, name, user, user_key, output_format, containerized=None):
     ]
 
     cmd_list.append(generate_ceph_cmd(
-        cluster, args, user, user_key, containerized))
+        cluster, args, user, user_key, container_image))
 
     return cmd_list
 
 
-def list_keys(cluster, user, user_key, containerized=None):
+def list_keys(cluster, user, user_key, container_image=None):
     '''
     List all CephX keys
     '''
@@ -418,7 +450,7 @@ def list_keys(cluster, user, user_key, containerized=None):
     ]
 
     cmd_list.append(generate_ceph_cmd(
-        cluster, args, user, user_key, containerized))
+        cluster, args, user, user_key, container_image))
 
     return cmd_list
 
@@ -491,7 +523,6 @@ def run_module():
         cluster=dict(type='str', required=False, default='ceph'),
         name=dict(type='str', required=False),
         state=dict(type='str', required=True),
-        containerized=dict(type='str', required=False, default=None),
         caps=dict(type='dict', required=False, default=None),
         secret=dict(type='str', required=False, default=None),
         import_key=dict(type='bool', required=False, default=True),
@@ -509,7 +540,6 @@ def run_module():
     state = module.params['state']
     name = module.params.get('name')
     cluster = module.params.get('cluster')
-    containerized = module.params.get('containerized')
     caps = module.params.get('caps')
     secret = module.params.get('secret')
     import_key = module.params.get('import_key')
@@ -531,6 +561,9 @@ def run_module():
 
     startd = datetime.datetime.now()
 
+    # will return either the image name or None
+    container_image = is_containerized()
+
     # Test if the key exists, if it does we skip its creation
     # We only want to run this check when a key needs to be added
     # There is no guarantee that any cluster is running and we don't need one
@@ -540,7 +573,7 @@ def run_module():
             "/etc/ceph/" + cluster + ".client.admin.keyring")
         output_format = "json"
         rc, cmd, out, err = exec_commands(
-            module, info_key(cluster, name, user, user_key, output_format, containerized))  # noqa E501
+            module, info_key(cluster, name, user, user_key, output_format, container_image))  # noqa E501
 
     if state == "present":
         if not caps:
@@ -561,14 +594,14 @@ def run_module():
             if rc == 0 and not secret:
                 # If the key exists in Ceph we must fetch it on the system
                 # because nothing tells us it exists on the fs or not
-                rc, cmd, out, err = exec_commands(module, get_key(cluster, name, file_path, containerized))  # noqa E501
+                rc, cmd, out, err = exec_commands(module, get_key(cluster, name, file_path, container_image))  # noqa E501
                 result["stdout"] = "skipped, since {0} already exists, we only fetched the key at {1}. If you want to update a key use 'state: update'".format(  # noqa E501
                     name, file_path)
                 result['rc'] = rc
                 module.exit_json(**result)
 
         rc, cmd, out, err = exec_commands(module, create_key(
-            module, result, cluster, name, secret, caps, import_key, auid, file_path, containerized))  # noqa E501
+            module, result, cluster, name, secret, caps, import_key, auid, file_path, container_image))  # noqa E501
 
         file_args = module.load_file_common_arguments(module.params)
         file_args['path'] = file_path
@@ -583,13 +616,13 @@ def run_module():
             module.exit_json(**result)
 
         rc, cmd, out, err = exec_commands(
-            module, update_key(cluster, name, caps, containerized))
+            module, update_key(cluster, name, caps, container_image))
         # After the update we don't need to overwrite the key on the filesystem
         # since the secret has not changed
 
     elif state == "absent":
         rc, cmd, out, err = exec_commands(
-            module, delete_key(cluster, name, containerized))
+            module, delete_key(cluster, name, container_image))
 
     elif state == "info":
         if rc != 0:
@@ -602,14 +635,14 @@ def run_module():
             "/etc/ceph/" + cluster + ".client.admin.keyring")
         output_format = "json"
         rc, cmd, out, err = exec_commands(
-            module, info_key(cluster, name, user, user_key, output_format, containerized))  # noqa E501
+            module, info_key(cluster, name, user, user_key, output_format, container_image))  # noqa E501
 
     elif state == "list":
         user = "client.admin"
         user_key = os.path.join(
             "/etc/ceph/" + cluster + ".client.admin.keyring")
         rc, cmd, out, err = exec_commands(
-            module, list_keys(cluster, user, user_key, containerized))
+            module, list_keys(cluster, user, user_key, container_image))
 
     elif state == "fetch_initial_keys":
         hostname = socket.gethostname()
@@ -617,7 +650,7 @@ def run_module():
         user_key = os.path.join(
             "/var/lib/ceph/mon/" + cluster + "-" + hostname + "/keyring")
         rc, cmd, out, err = exec_commands(
-            module, list_keys(cluster, user, user_key, containerized))
+            module, list_keys(cluster, user, user_key, container_image))
         if rc != 0:
             result["stdout"] = "failed to retrieve ceph keys".format(name)
             result['rc'] = 0
@@ -628,8 +661,12 @@ def run_module():
             fatal("Failed to find some of the initial entities", module)
 
         # get ceph's group and user id
-        ceph_uid = pwd.getpwnam('ceph').pw_uid
-        ceph_grp = grp.getgrnam('ceph').gr_gid
+        if container_image:
+            ceph_uid = os.getenv('CEPH_UID')
+            ceph_grp = os.getenv('CEPH_UID')
+        else:
+            ceph_uid = pwd.getpwnam('ceph').pw_uid
+            ceph_grp = grp.getgrnam('ceph').gr_gid
 
         output_format = "plain"
         for entity in entities:
@@ -647,7 +684,7 @@ def run_module():
             ]
 
             info_cmd = info_key(cluster, entity, user,
-                                user_key, output_format, containerized)
+                                user_key, output_format, container_image)
             # we use info_cmd[0] because info_cmd is an array made of an array
             info_cmd[0].extend(extra_args)
             rc, cmd, out, err = exec_commands(
index b8761fac3b3df5a394cf718d44a29e17e21af2ee..d9e217ccdfc0686cd187e51288dd3ca69f429cde 100644 (file)
@@ -1,7 +1,6 @@
 import json
 import os
 from . import ceph_key
-from ansible.compat.tests.mock import MagicMock
 
 
 class TestCephKeyModule(object):
@@ -72,13 +71,16 @@ class TestCephKeyModule(object):
         fake_args = ['arg']
         fake_user = "fake-user"
         fake_key = "/tmp/my-key"
-        fake_containerized = "docker exec -ti ceph-mon"
-        expected_command_list = [
-            'docker',
-            'exec',
-            '-ti',
-            'ceph-mon',
-            'ceph',
+        fake_container_image = "docker.io/ceph/daemon:latest-luminous"
+        expected_command_list = ['docker',
+            'run',
+            '--rm',
+            '--net=host',  # noqa E501
+            '-v', '/etc/ceph:/etc/ceph:z',
+            '-v', '/var/lib/ceph/:/var/lib/ceph/:z',
+            '-v', '/var/log/ceph/:/var/log/ceph/:z',
+            '--entrypoint=ceph',
+            'docker.io/ceph/daemon:latest-luminous',
             '-n',
             "fake-user",
             '-k',
@@ -86,10 +88,9 @@ class TestCephKeyModule(object):
             '--cluster',
             fake_cluster,
             'auth',
-            'arg'
-        ]
+            'arg']
         result = ceph_key.generate_ceph_cmd(
-            fake_cluster, fake_args, fake_user, fake_key, fake_containerized)
+            fake_cluster, fake_args, fake_user, fake_key, fake_container_image)
         assert result == expected_command_list
 
     def test_generate_ceph_authtool_cmd_non_container_no_auid(self):
@@ -160,7 +161,6 @@ class TestCephKeyModule(object):
         fake_cluster = "fake"
         fake_name = "client.fake"
         fake_secret = "super-secret"
-        fake_containerized = "docker exec -ti ceph-mon"
         fake_caps = {
             'mon': 'allow *',
             'osd': 'allow rwx',
@@ -169,32 +169,35 @@ class TestCephKeyModule(object):
         fake_auid = None
         fake_file_destination = os.path.join(
             fake_dest + "/" + fake_cluster + "." + fake_name + ".keyring")
-        expected_command_list = [
-            'docker',
-            'exec',
-            '-ti',
-            'ceph-mon',
-            'ceph-authtool',
-            '--create-keyring',
-            fake_file_destination,
-            '--name',
-            fake_name,
-            '--add-key',
-            fake_secret,
-            '--cap',
-            'mon',
-            'allow *',
-            '--cap',
-            'osd',
-            'allow rwx'
-        ]
+        fake_container_image = "docker.io/ceph/daemon:latest-luminous"
+        expected_command_list = ['docker',
+                                 'run',
+                                 '--rm',
+                                 '--net=host',
+                                 '-v', '/etc/ceph:/etc/ceph:z',
+                                 '-v', '/var/lib/ceph/:/var/lib/ceph/:z',
+                                 '-v', '/var/log/ceph/:/var/log/ceph/:z',
+                                 '--entrypoint=ceph-authtool',
+                                 'docker.io/ceph/daemon:latest-luminous',
+                                 '--create-keyring',
+                                 fake_file_destination,
+                                 '--name',
+                                 fake_name,
+                                 '--add-key',
+                                 fake_secret,
+                                 '--cap',
+                                 'mon',
+                                 'allow *',
+                                 '--cap',
+                                 'osd',
+                                 'allow rwx']
         result = ceph_key.generate_ceph_authtool_cmd(
             fake_cluster, fake_name, fake_secret, fake_caps, fake_auid, fake_file_destination, fake_containerized)  # noqa E501
         assert result == expected_command_list
 
     def test_create_key_non_container(self):
         fake_module = "fake"
-        fake_result = "fake"
+        fake_result = " fake"
         fake_cluster = "fake"
         fake_name = "client.fake"
         fake_secret = "super-secret"
@@ -223,7 +226,6 @@ class TestCephKeyModule(object):
         fake_cluster = "fake"
         fake_name = "client.fake"
         fake_secret = "super-secret"
-        fake_containerized = "docker exec -ti ceph-mon"
         fake_caps = {
             'mon': 'allow *',
             'osd': 'allow rwx',
@@ -233,11 +235,36 @@ class TestCephKeyModule(object):
         fake_auid = None
         fake_file_destination = os.path.join(
             fake_dest + "/" + fake_cluster + "." + fake_name + ".keyring")
+        fake_container_image = "docker.io/ceph/daemon:latest-luminous"
         expected_command_list = [
-            ['docker', 'exec', '-ti', 'ceph-mon', 'ceph-authtool', '--create-keyring', fake_file_destination,  # noqa E501
-                '--name', fake_name, '--add-key', fake_secret, '--cap', 'mon', 'allow *', '--cap', 'osd', 'allow rwx'],  # noqa E501
-            ['docker', 'exec', '-ti', 'ceph-mon', 'ceph', '-n', 'client.admin', '-k', '/etc/ceph/fake.client.admin.keyring', '--cluster',  # noqa E501
-                fake_cluster, 'auth', 'import', '-i', fake_file_destination],
+            ['docker',   # noqa E128
+            'run',
+            '--rm',
+            '--net=host',
+            '-v', '/etc/ceph:/etc/ceph:z',
+            '-v', '/var/lib/ceph/:/var/lib/ceph/:z',
+            '-v', '/var/log/ceph/:/var/log/ceph/:z',
+            '--entrypoint=ceph-authtool',
+            'docker.io/ceph/daemon:latest-luminous',
+            '--create-keyring', fake_file_destination,
+            '--name', fake_name,
+            '--add-key', fake_secret,
+            '--cap', 'mon', 'allow *',
+            '--cap', 'osd', 'allow rwx'],
+            ['docker',
+            'run',
+            '--rm',
+            '--net=host',
+            '-v', '/etc/ceph:/etc/ceph:z',
+            '-v', '/var/lib/ceph/:/var/lib/ceph/:z',
+            '-v', '/var/log/ceph/:/var/log/ceph/:z',
+            '--entrypoint=ceph',
+            'docker.io/ceph/daemon:latest-luminous',
+            '-n', 'client.admin',
+            '-k', '/etc/ceph/fake.client.admin.keyring',
+            '--cluster', fake_cluster,
+            'auth', 'import',
+            '-i', fake_file_destination]
         ]
         result = ceph_key.create_key(fake_module, fake_result, fake_cluster, fake_name,  # noqa E501
                                      fake_secret, fake_caps, fake_import_key, fake_auid, fake_file_destination, fake_containerized)  # noqa E501
@@ -284,7 +311,6 @@ class TestCephKeyModule(object):
         fake_cluster = "fake"
         fake_name = "client.fake"
         fake_secret = "super-secret"
-        fake_containerized = "docker exec -ti ceph-mon"
         fake_caps = {
             'mon': 'allow *',
             'osd': 'allow rwx',
@@ -295,25 +321,28 @@ class TestCephKeyModule(object):
             fake_dest + "/" + fake_cluster + "." + fake_name + ".keyring")
         fake_auid = None
         # create_key passes (one for ceph-authtool and one for itself) itw own array so the expected result is an array within an array # noqa E501
-        expected_command_list = [[
-            'docker',
-            'exec',
-            '-ti',
-            'ceph-mon',
-            'ceph-authtool',
-            '--create-keyring',
-            fake_file_destination,
-            '--name',
-            fake_name,
-            '--add-key',
-            fake_secret,
-            '--cap',
-            'mon',
-            'allow *',
-            '--cap',
-            'osd',
-            'allow rwx', ]
-        ]
+        fake_container_image = "docker.io/ceph/daemon:latest-luminous"
+        expected_command_list = [['docker',   # noqa E128
+                                 'run',
+                                 '--rm',
+                                 '--net=host',
+                                 '-v', '/etc/ceph:/etc/ceph:z',
+                                 '-v', '/var/lib/ceph/:/var/lib/ceph/:z',
+                                 '-v', '/var/log/ceph/:/var/log/ceph/:z',
+                                 '--entrypoint=ceph-authtool',
+                                 'docker.io/ceph/daemon:latest-luminous',
+                                 '--create-keyring',
+                                 fake_file_destination,
+                                 '--name',
+                                 fake_name,
+                                 '--add-key',
+                                 fake_secret,
+                                 '--cap',
+                                 'mon',
+                                 'allow *',
+                                 '--cap',
+                                 'osd',
+                                 'allow rwx']]
         result = ceph_key.create_key(fake_module, fake_result, fake_cluster, fake_name,  # noqa E501
                                      fake_secret, fake_caps, fake_import_key, fake_auid, fake_file_destination, fake_containerized)  # noqa E501
         assert result == expected_command_list
@@ -335,17 +364,29 @@ class TestCephKeyModule(object):
     def test_update_key_container(self):
         fake_cluster = "fake"
         fake_name = "client.fake"
-        fake_containerized = "docker exec -ti ceph-mon"
         fake_caps = {
             'mon': 'allow *',
             'osd': 'allow rwx',
         }
-        expected_command_list = [
-            ['docker', 'exec', '-ti', 'ceph-mon', 'ceph', '-n', 'client.admin', '-k', '/etc/ceph/fake.client.admin.keyring',  '--cluster', fake_cluster,  # noqa E501
-                'auth', 'caps', fake_name, 'mon', 'allow *', 'osd', 'allow rwx'],  # noqa E501
+        fake_container_image = "docker.io/ceph/daemon:latest-luminous"
+        expected_command_list = [['docker',   # noqa E128
+                                 'run',
+                                 '--rm',
+                                 '--net=host',
+                                 '-v', '/etc/ceph:/etc/ceph:z',
+                                 '-v', '/var/lib/ceph/:/var/lib/ceph/:z',
+                                 '-v', '/var/log/ceph/:/var/log/ceph/:z',
+                                 '--entrypoint=ceph',
+                                 'docker.io/ceph/daemon:latest-luminous',
+                                 '-n', 'client.admin',
+                                 '-k', '/etc/ceph/fake.client.admin.keyring',
+                                 '--cluster', fake_cluster,
+                                 'auth',
+                                 'caps', fake_name,
+                                 'mon', 'allow *', 'osd', 'allow rwx']
         ]
         result = ceph_key.update_key(
-            fake_cluster, fake_name, fake_caps, fake_containerized)
+            fake_cluster, fake_name, fake_caps, fake_container_image)
         assert result == expected_command_list
 
     def test_delete_key_non_container(self):
@@ -361,13 +402,23 @@ class TestCephKeyModule(object):
     def test_delete_key_container(self):
         fake_cluster = "fake"
         fake_name = "client.fake"
-        fake_containerized = "docker exec -ti ceph-mon"
-        expected_command_list = [
-            ['docker', 'exec', '-ti', 'ceph-mon', 'ceph', '-n', 'client.admin', '-k', '/etc/ceph/fake.client.admin.keyring',  # noqa E501
-                '--cluster', fake_cluster, 'auth', 'del', fake_name],
+        fake_container_image = "docker.io/ceph/daemon:latest-luminous"
+        expected_command_list = [['docker',   # noqa E128
+                                 'run',
+                                 '--rm',
+                                 '--net=host',
+                                 '-v', '/etc/ceph:/etc/ceph:z',
+                                 '-v', '/var/lib/ceph/:/var/lib/ceph/:z',
+                                 '-v', '/var/log/ceph/:/var/log/ceph/:z',
+                                 '--entrypoint=ceph',
+                                 'docker.io/ceph/daemon:latest-luminous',
+                                 '-n', 'client.admin',
+                                 '-k', '/etc/ceph/fake.client.admin.keyring',
+                                 '--cluster', fake_cluster,
+                                 'auth', 'del', fake_name]
         ]
         result = ceph_key.delete_key(
-            fake_cluster, fake_name, fake_containerized)
+            fake_cluster, fake_name, fake_container_image)
         assert result == expected_command_list
 
     def test_info_key_non_container(self):
@@ -389,14 +440,25 @@ class TestCephKeyModule(object):
         fake_name = "client.fake"
         fake_user = "fake-user"
         fake_key = "/tmp/my-key"
-        fake_containerized = "docker exec -ti ceph-mon"
         fake_output_format = "json"
-        expected_command_list = [
-            ['docker', 'exec', '-ti', 'ceph-mon', 'ceph', '-n', "fake-user", '-k', "/tmp/my-key", '--cluster',  # noqa E501
-                fake_cluster, 'auth', 'get', fake_name, '-f', 'json'],
+        fake_container_image = "docker.io/ceph/daemon:latest-luminous"
+        expected_command_list = [['docker',   # noqa E128
+                                 'run',
+                                 '--rm',
+                                 '--net=host',
+                                 '-v', '/etc/ceph:/etc/ceph:z',
+                                 '-v', '/var/lib/ceph/:/var/lib/ceph/:z',
+                                 '-v', '/var/log/ceph/:/var/log/ceph/:z',
+                                 '--entrypoint=ceph',
+                                 'docker.io/ceph/daemon:latest-luminous',
+                                 '-n', "fake-user",
+                                 '-k', "/tmp/my-key",
+                                 '--cluster', fake_cluster,
+                                 'auth', 'get', fake_name,
+                                 '-f', 'json']
         ]
         result = ceph_key.info_key(
-            fake_cluster, fake_name, fake_user, fake_key, fake_output_format, fake_containerized)  # noqa E501
+            fake_cluster, fake_name, fake_user, fake_key, fake_output_format, fake_container_image)  # noqa E501
         assert result == expected_command_list
 
     def test_list_key_non_container(self):
@@ -454,27 +516,49 @@ class TestCephKeyModule(object):
     def test_list_key_container_with_mon_key(self):
         fake_hostname = "mon01"
         fake_cluster = "fake"
-        fake_containerized = "docker exec -ti ceph-mon"
         fake_user = "mon."
         fake_key = os.path.join("/var/lib/ceph/mon/" + fake_cluster + "-" + fake_hostname + "/keyring") # noqa E501
-        expected_command_list = [
-            ['docker', 'exec', '-ti', 'ceph-mon','ceph', '-n', "mon.", '-k', "/var/lib/ceph/mon/fake-mon01/keyring",  # noqa E501
-                '--cluster', fake_cluster, 'auth', 'ls', '-f', 'json'],
+        fake_container_image = "docker.io/ceph/daemon:latest-luminous"
+        expected_command_list = [['docker',   # noqa E128
+                                 'run',
+                                 '--rm',
+                                 '--net=host',
+                                 '-v', '/etc/ceph:/etc/ceph:z',
+                                 '-v', '/var/lib/ceph/:/var/lib/ceph/:z',
+                                 '-v', '/var/log/ceph/:/var/log/ceph/:z',
+                                 '--entrypoint=ceph',
+                                 'docker.io/ceph/daemon:latest-luminous',
+                                 '-n', "mon.",
+                                 '-k', "/var/lib/ceph/mon/fake-mon01/keyring",  # noqa E501
+                                 '--cluster', fake_cluster,
+                                 'auth', 'ls',
+                                 '-f', 'json'],
         ]
-        result = ceph_key.list_keys(fake_cluster, fake_user, fake_key, fake_containerized)  # noqa E501
+        result = ceph_key.list_keys(fake_cluster, fake_user, fake_key, fake_container_image)  # noqa E501
         assert result == expected_command_list
 
     def test_list_key_container(self):
         fake_cluster = "fake"
-        fake_containerized = "docker exec -ti ceph-mon"
         fake_user = "fake-user"
         fake_key = "/tmp/my-key"
-        expected_command_list = [
-            ['docker', 'exec', '-ti', 'ceph-mon', 'ceph', '-n', "fake-user", '-k', "/tmp/my-key", '--cluster',  # noqa E501
-                fake_cluster, 'auth', 'ls', '-f', 'json'],
+        fake_container_image = "docker.io/ceph/daemon:latest-luminous"
+        expected_command_list = [['docker',   # noqa E128
+                                 'run',
+                                 '--rm',
+                                 '--net=host',
+                                 '-v', '/etc/ceph:/etc/ceph:z',
+                                 '-v', '/var/lib/ceph/:/var/lib/ceph/:z',
+                                 '-v', '/var/log/ceph/:/var/log/ceph/:z',
+                                 '--entrypoint=ceph',
+                                 'docker.io/ceph/daemon:latest-luminous',
+                                 '-n', "fake-user",
+                                 '-k', "/tmp/my-key",
+                                 '--cluster', fake_cluster,
+                                 'auth', 'ls',
+                                 '-f', 'json'],
         ]
         result = ceph_key.list_keys(
-            fake_cluster, fake_user, fake_key, fake_containerized)
+            fake_cluster, fake_user, fake_key, fake_container_image)
         assert result == expected_command_list
 
     def test_lookup_ceph_initial_entities(self):