]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
qa: test mgr live configuration updates
authorJohn Spray <john.spray@redhat.com>
Tue, 10 Apr 2018 13:28:36 +0000 (09:28 -0400)
committerJohn Spray <john.spray@redhat.com>
Mon, 23 Apr 2018 11:29:47 +0000 (07:29 -0400)
Signed-off-by: John Spray <john.spray@redhat.com>
qa/tasks/mgr/mgr_test_case.py
qa/tasks/mgr/test_module_selftest.py
src/pybind/mgr/selftest/module.py

index ea9d6a3b15d43c8b58da87cbae4cca9aa998a6e6..b73a6a296e126a343ae19e2da4dbebee2d1f445d 100644 (file)
@@ -48,13 +48,13 @@ class MgrCluster(CephCluster):
         return [s['name'] for s in self.get_mgr_map()["standbys"]]
 
     def set_module_conf(self, module, key, val):
-        self.mon_manager.raw_cluster_cmd("config-key", "set",
+        self.mon_manager.raw_cluster_cmd("config", "set", "mgr",
                                          "mgr/{0}/{1}".format(
                                              module, key
                                          ), val)
 
     def set_module_localized_conf(self, module, mgr_id, key, val):
-        self.mon_manager.raw_cluster_cmd("config-key", "set",
+        self.mon_manager.raw_cluster_cmd("config", "set", "mgr",
                                          "mgr/{0}/{1}/{2}".format(
                                              module, mgr_id, key
                                          ), val)
index c984b99589bac6779cc1a7ded8f0c2d366a0e523..63531fd5effa3eea9c67a588ccbb69376f52a132 100644 (file)
@@ -2,10 +2,13 @@
 import time
 import requests
 import errno
+import logging
 from teuthology.exceptions import CommandFailedError
 
 from tasks.mgr.mgr_test_case import MgrTestCase
 
+log = logging.getLogger(__name__)
+
 
 class TestModuleSelftest(MgrTestCase):
     """
@@ -49,6 +52,111 @@ class TestModuleSelftest(MgrTestCase):
         self._load_module("selftest")
         self.mgr_cluster.mon_manager.raw_cluster_cmd("mgr", "self-test", "run")
 
+    def test_selftest_config_update(self):
+        """
+        That configuration updates are seen by running mgr modules
+        """
+        self._load_module("selftest")
+
+        def get_value():
+            return self.mgr_cluster.mon_manager.raw_cluster_cmd(
+                    "mgr", "self-test", "config", "get", "testkey").strip()
+
+        self.assertEqual(get_value(), "None")
+
+        self.mgr_cluster.mon_manager.raw_cluster_cmd("config", "set",
+                "mgr", "mgr/selftest/testkey", "testvalue")
+
+        self.wait_until_equal(get_value, "testvalue",timeout=10)
+
+        active_id = self.mgr_cluster.get_active_id()
+
+        def get_localized_value():
+            return self.mgr_cluster.mon_manager.raw_cluster_cmd(
+                    "mgr", "self-test", "config", "get_localized", "testlkey").strip()
+
+        self.mgr_cluster.mon_manager.raw_cluster_cmd("config", "set",
+                "mgr", "mgr/selftest/{0}/testlkey".format(active_id),
+                "test localized value")
+
+        self.wait_until_equal(get_localized_value, "test localized value",
+                              timeout=10)
+
+    def test_selftest_config_upgrade(self):
+        """
+        That pre-mimic config-key config settings are migrated into
+        mimic-style config settings and visible from mgr modules.
+        """
+        self._load_module("selftest")
+
+        def get_value():
+            return self.mgr_cluster.mon_manager.raw_cluster_cmd(
+                    "mgr", "self-test", "config", "get", "testkey").strip()
+
+        def get_config():
+            lines = self.mgr_cluster.mon_manager.raw_cluster_cmd(
+                    "config", "dump")\
+                            .strip().split("\n")
+            result = []
+            for line in lines[1:]:
+                tokens = line.strip().split()
+                log.info("tokens: {0}".format(tokens))
+                subsys, key, value = tokens[0], tokens[2], tokens[3]
+                result.append((subsys, key, value))
+
+            return result
+
+        # Stop ceph-mgr while we synthetically create a pre-mimic
+        # configuration scenario
+        for mgr_id in self.mgr_cluster.mgr_daemons.keys():
+            self.mgr_cluster.mgr_stop(mgr_id)
+            self.mgr_cluster.mgr_fail(mgr_id)
+
+        # Blow away any modern-style mgr module config options
+        # (the ceph-mgr implementation may only do the upgrade if
+        #  it doesn't see new style options)
+        stash = []
+        for subsys, key, value in get_config():
+            if subsys == "mgr" and key.startswith("mgr/"):
+                log.info("Removing config key {0} ahead of upgrade".format(
+                    key))
+                self.mgr_cluster.mon_manager.raw_cluster_cmd(
+                        "config", "rm", subsys, key)
+                stash.append((subsys, key, value))
+
+        # Inject an old-style configuration setting in config-key
+        self.mgr_cluster.mon_manager.raw_cluster_cmd(
+                "config-key", "set", "mgr/selftest/testkey", "testvalue")
+
+        # Inject configuration settings that looks data-ish and should
+        # not be migrated to a config key
+        self.mgr_cluster.mon_manager.raw_cluster_cmd(
+                "config-key", "set", "mgr/selftest/testnewline", "foo\nbar")
+
+        # Bring mgr daemons back online, the one that goes active
+        # should be doing the upgrade.
+        for mgr_id in self.mgr_cluster.mgr_daemons.keys():
+            self.mgr_cluster.mgr_restart(mgr_id)
+
+        # Wait for a new active 
+        self.wait_until_true(
+                lambda: self.mgr_cluster.get_active_id() != "", timeout=30)
+
+        # Check that the selftest module sees the upgraded value
+        self.assertEqual(get_value(), "testvalue")
+
+        # Check that the upgraded value is visible in the configuration
+        seen_keys = [k for s,k,v in get_config()]
+        self.assertIn("mgr/selftest/testkey", seen_keys)
+
+        # And that the non-config-looking one isn't
+        self.assertNotIn("mgr/selftest/testnewline", seen_keys)
+
+        # Restore previous configuration
+        for subsys, key, value in stash:
+            self.mgr_cluster.mon_manager.raw_cluster_cmd(
+                    "config", "set", subsys, key, value)
+
     def test_selftest_command_spam(self):
         # Use the selftest module to stress the mgr daemon
         self._load_module("selftest")
index b9530c43b146c3cf10a6a0b4603fc5892be9e32d..ae8f50c47d5c7c261e46a21fd034b1cab646e38a 100644 (file)
@@ -29,23 +29,31 @@ class Module(MgrModule):
             {
                 "cmd": "mgr self-test run",
                 "desc": "Run mgr python interface tests",
-                "perm": "r"
+                "perm": "rw"
             },
             {
                 "cmd": "mgr self-test background start name=workload,type=CephString",
                 "desc": "Activate a background workload (one of {0})".format(
                     ", ".join(WORKLOADS)),
-                "perm": "r"
+                "perm": "rw"
             },
             {
                 "cmd": "mgr self-test background stop",
                 "desc": "Stop background workload if any is running",
-                "perm": "r"
+                "perm": "rw"
+            },
+            {
+                "cmd": "mgr self-test config get name=key,type=CephString",
+                "desc": "Peek at a configuration value",
+                "perm": "rw"
+            },
+            {
+                "cmd": "mgr self-test config get_localized name=key,type=CephString",
+                "desc": "Peek at a configuration value (localized variant)",
+                "perm": "rw"
             },
             ]
 
-
-
     def __init__(self, *args, **kwargs):
         super(Module, self).__init__(*args, **kwargs)
         self._event = threading.Event()
@@ -73,7 +81,10 @@ class Module(MgrModule):
                         was_running)
             else:
                 return 0, '', 'No background workload was running'
-
+        elif command['prefix'] == 'mgr self-test config get':
+            return 0, str(self.get_config(command['key'])), ''
+        elif command['prefix'] == 'mgr self-test config get_localized':
+            return 0, str(self.get_localized_config(command['key'])), ''
         else:
             return (-errno.EINVAL, '',
                     "Command not found '{0}'".format(command['prefix']))
@@ -139,16 +150,18 @@ class Module(MgrModule):
         self.set_localized_config("testkey", "testvalue")
         assert self.get_localized_config("testkey") == "testvalue"
 
-        assert sorted(self.get_config_prefix("test").keys()) == sorted(
-                ["testkey"])
-
     def _self_test_store(self):
+        existing_keys = set(self.get_store_prefix("test").keys())
         self.set_store("testkey", "testvalue")
         assert self.get_store("testkey") == "testvalue"
 
         self.set_store_json("testjsonkey", {"testblob": 2})
         assert self.get_store_json("testjsonkey") == {"testblob": 2}
 
+        assert sorted(self.get_store_prefix("test").keys()) == sorted(
+                list({"testkey", "testjsonkey"} | existing_keys))
+
+
     def _self_test_perf_counters(self):
         self.get_perf_schema("osd", "0")
         self.get_counter("osd", "0", "osd.op")