You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by jo...@apache.org on 2018/08/02 22:22:00 UTC

[ambari] branch branch-feature-AMBARI-14714 updated: [AMBARI-24364] - Mpack Instance Manager Not Listing Versions Correctly (#1922)

This is an automated email from the ASF dual-hosted git repository.

jonathanhurley pushed a commit to branch branch-feature-AMBARI-14714
in repository https://gitbox.apache.org/repos/asf/ambari.git


The following commit(s) were added to refs/heads/branch-feature-AMBARI-14714 by this push:
     new c439764  [AMBARI-24364] - Mpack Instance Manager Not Listing Versions Correctly (#1922)
c439764 is described below

commit c4397643d842fc745ee2e99c9df8f6a6e880cc77
Author: sduan <sd...@hortonworks.com>
AuthorDate: Thu Aug 2 15:21:58 2018 -0700

    [AMBARI-24364] - Mpack Instance Manager Not Listing Versions Correctly (#1922)
---
 .../execution_command/execution_command.py         |  13 ++-
 .../functions/get_not_managed_resources.py         |   4 +-
 .../libraries/functions/mpack_manager_helper.py    |  51 +++++------
 .../libraries/functions/stack_features.py          |   3 +-
 .../resource_management/libraries/script/script.py |   3 +-
 .../python/instance_manager/instance_manager.py    | 101 +++++++++++++++++++--
 .../instance_manager/test_instance_manager.py      |  95 +++++++++++++------
 7 files changed, 201 insertions(+), 69 deletions(-)

diff --git a/ambari-common/src/main/python/resource_management/libraries/execution_command/execution_command.py b/ambari-common/src/main/python/resource_management/libraries/execution_command/execution_command.py
index c147615..17e2f77 100644
--- a/ambari-common/src/main/python/resource_management/libraries/execution_command/execution_command.py
+++ b/ambari-common/src/main/python/resource_management/libraries/execution_command/execution_command.py
@@ -96,7 +96,8 @@ class ExecutionCommand(object):
     Retrieve service name from command.json, eg. 'zk1'
     :return: service name
     """
-    if '_CLIENTS' in self.get_module_name(): # FIXME temporary hack
+    module_name = self.get_module_name()
+    if module_name and '_CLIENTS' in module_name: # FIXME temporary hack
       return 'default'
     return self.__get_value("serviceName") # multi-service, but not multi-component per service
 
@@ -279,14 +280,20 @@ class ExecutionCommand(object):
     Retrieve a list of user groups from command.json, i.e "group_list": "[\"hadoop\"]"
     :return: a list of groups
     """
-    return self.__get_value("stackSettings/group_list")
+    group_list = self.__get_value("stackSettings/group_list")
+    if not group_list:
+      group_list = "[]"
+    return group_list
 
   def get_user_list(self):
     """
     Retrieve a list of users from command.json, i.e "user_list": "[\"zookeeper\",\"ambari-qa\"]"
     :return: a list of users
     """
-    return self.__get_value("stackSettings/user_list")
+    user_list = self.__get_value("stackSettings/user_list")
+    if not user_list:
+      user_list = "[]"
+    return user_list
 
   """
   Agent related variable section
diff --git a/ambari-common/src/main/python/resource_management/libraries/functions/get_not_managed_resources.py b/ambari-common/src/main/python/resource_management/libraries/functions/get_not_managed_resources.py
index 611e1d2..c5557c5 100644
--- a/ambari-common/src/main/python/resource_management/libraries/functions/get_not_managed_resources.py
+++ b/ambari-common/src/main/python/resource_management/libraries/functions/get_not_managed_resources.py
@@ -34,7 +34,9 @@ def get_not_managed_resources():
   except config values from cluster-env/managed_hdfs_resource_property_names
   """
   config = Script.get_config()
-  not_managed_hdfs_path_list = json.loads(config['stackSettings']['not_managed_hdfs_path_list'])[:]
+  not_managed_hdfs_path_list = []
+  if 'not_managed_hdfs_path_list' in config['stackSettings']:
+    not_managed_hdfs_path_list = json.loads(config['stackSettings']['not_managed_hdfs_path_list'])[:]
   if get_cluster_setting_value('managed_hdfs_resource_property_names') is not None:
     managed_hdfs_resource_property_names = get_cluster_setting_value('managed_hdfs_resource_property_names')
     managed_hdfs_resource_property_list = filter(None, [property.strip() for property in managed_hdfs_resource_property_names.split(',')])
diff --git a/ambari-common/src/main/python/resource_management/libraries/functions/mpack_manager_helper.py b/ambari-common/src/main/python/resource_management/libraries/functions/mpack_manager_helper.py
index dcce601..a27d62b 100644
--- a/ambari-common/src/main/python/resource_management/libraries/functions/mpack_manager_helper.py
+++ b/ambari-common/src/main/python/resource_management/libraries/functions/mpack_manager_helper.py
@@ -20,7 +20,7 @@ Ambari Agent
 """
 
 import os
-from instance_manager import create_mpack, set_mpack_instance, get_conf_dir, get_log_dir, get_run_dir, list_instances
+from instance_manager import create_mpack, set_mpack_instance, get_conf_dir, get_log_dir, get_run_dir, list_instances, walk_mpack_dict
 
 CONFIG_DIR_KEY_NAME = 'config_dir'
 LOG_DIR_KEY_NAME = 'log_dir'
@@ -31,75 +31,72 @@ COMPONENT_INSTANCES_PLURAL_KEY_NAME = 'component-instances'
 MPACK_VERSION_KEY_NAME = 'mpack_version'
 MODULE_VERSION_KEY_NAME = 'module_version'
 
-
 def get_component_conf_path(mpack_name, instance_name, module_name, components_instance_type,
                             subgroup_name='default', component_instance_name='default'):
   """
-  :returns the single string that contains the path to the configuration folder of given component instance
+  :returns a list contains the path to the configuration folder of given component instance,
+           this may include multiple mpack instances cases
   :raises ValueError if the parameters doesn't match the mpack or instances structure
   """
 
-  conf_json = get_conf_dir(mpack_name, instance_name, subgroup_name, module_name,
+  return get_conf_dir(mpack_name, instance_name, subgroup_name, module_name,
                            {components_instance_type: [component_instance_name]})
 
-  return conf_json[COMPONENTS_PLURAL_KEY_NAME][components_instance_type.lower()][COMPONENT_INSTANCES_PLURAL_KEY_NAME][
-    component_instance_name][CONFIG_DIR_KEY_NAME]
 
 def get_component_log_path(mpack_name, instance_name, module_name, components_instance_type,
                             subgroup_name='default', component_instance_name='default'):
   """
-  :returns the single string that contains the path to the log folder of given component instance
+  :returns a list contains the path to the log folder of given component instance,
+           this may include multiple mpack instances cases
   :raises ValueError if the parameters doesn't match the mpack or instances structure
   """
 
-  log_json = get_log_dir(mpack_name, instance_name, subgroup_name, module_name,
+  return get_log_dir(mpack_name, instance_name, subgroup_name, module_name,
                            {components_instance_type: [component_instance_name]})
 
-  return log_json[COMPONENTS_PLURAL_KEY_NAME][components_instance_type.lower()][COMPONENT_INSTANCES_PLURAL_KEY_NAME][
-    component_instance_name][LOG_DIR_KEY_NAME]
 
 def get_component_rundir_path(mpack_name, instance_name, module_name, components_instance_type,
                             subgroup_name='default', component_instance_name='default'):
   """
-  :returns the single string that contains the path to the rundir folder of given component instance
+  :returns a list contains the paths to the rundir folder of given component instance,
+           this may include multiple mpack instances cases
   :raises ValueError if the parameters doesn't match the mpack or instances structure
   """
 
-  run_json = get_run_dir(mpack_name, instance_name, subgroup_name, module_name,
+  return get_run_dir(mpack_name, instance_name, subgroup_name, module_name,
                            {components_instance_type: [component_instance_name]})
 
-  return run_json[COMPONENTS_PLURAL_KEY_NAME][components_instance_type.lower()][COMPONENT_INSTANCES_PLURAL_KEY_NAME][
-    component_instance_name][RUN_DIR_KEY_NAME]
 
 def get_component_target_path(mpack_name, instance_name, module_name, components_instance_type,
                               subgroup_name='default', component_instance_name='default'):
   """
-  :returns the single string that contains the path to the mpack component folder of given component instance
+  :returns a list contains the paths to the mpack component folder of given component instance,
+           this may include multiple mpack instances cases
   :raises ValueError if the parameters doesn't match the mpack or instances structure
   """
-
+  dirs = set()
   instances_json = list_instances(mpack_name, instance_name, subgroup_name, module_name,
                                   {components_instance_type: [component_instance_name]})
-
-  return instances_json[COMPONENTS_PLURAL_KEY_NAME][components_instance_type.lower()][
-    COMPONENT_INSTANCES_PLURAL_KEY_NAME][component_instance_name][PATH_KEY_NAME]
-
+  walk_mpack_dict(instances_json, PATH_KEY_NAME, dirs)
+  target_path_list =  [dir for dir in dirs if
+          (mpack_name == None or mpack_name.lower() in dir) and (instance_name == None or instance_name.lower() in dir)]
+  return "" if len(target_path_list) == 0 else target_path_list[0]
 
 def get_versions(mpack_name, instance_name, module_name, components_instance_type,
                               subgroup_name='default', component_instance_name='default'):
   """
-  :returns a tuple representing the mpack version and the module version
+  :returns a tuple representing the mpack version and the module version, module_name should not be None
   :raises ValueError if the parameters doesn't match the mpack or instances structure
   """
 
   instances_json = list_instances(mpack_name, instance_name, subgroup_name, module_name,
                                   {components_instance_type: [component_instance_name]})
-
-  mpack_version = instances_json[COMPONENTS_PLURAL_KEY_NAME][components_instance_type.lower()][
-    COMPONENT_INSTANCES_PLURAL_KEY_NAME][component_instance_name][MPACK_VERSION_KEY_NAME]
-
-  module_version = instances_json[COMPONENTS_PLURAL_KEY_NAME][components_instance_type.lower()][
-    COMPONENT_INSTANCES_PLURAL_KEY_NAME][component_instance_name][MODULE_VERSION_KEY_NAME]
+  dirs = set()
+  walk_mpack_dict(instances_json, MPACK_VERSION_KEY_NAME, dirs)
+  mpack_version = next(iter(dirs))
+  dirs.clear()
+  walk_mpack_dict(instances_json, MODULE_VERSION_KEY_NAME, dirs)
+  module_version = next(iter(dirs))
 
   return mpack_version, module_version
 
diff --git a/ambari-common/src/main/python/resource_management/libraries/functions/stack_features.py b/ambari-common/src/main/python/resource_management/libraries/functions/stack_features.py
index fe93ff3..d754cd9 100644
--- a/ambari-common/src/main/python/resource_management/libraries/functions/stack_features.py
+++ b/ambari-common/src/main/python/resource_management/libraries/functions/stack_features.py
@@ -108,7 +108,8 @@ def get_stack_feature_version(config):
     raise Fail("Unable to determine the correct version since stackSettings and commandParams were not present in the configuration dictionary")
 
   # should always be there
-  stack_version = config['stackSettings']['stack_version']
+  # Actually not always, i.e if we restart zookeeper service and no stack_version is included in command.json
+  stack_version = default("/stackSettings/stack_version", None)
 
   # something like 2.4.0.0-1234; represents the version for the command
   # (or None if this is a cluster install and it hasn't been calculated yet)
diff --git a/ambari-common/src/main/python/resource_management/libraries/script/script.py b/ambari-common/src/main/python/resource_management/libraries/script/script.py
index d1d249c..2211baf 100644
--- a/ambari-common/src/main/python/resource_management/libraries/script/script.py
+++ b/ambari-common/src/main/python/resource_management/libraries/script/script.py
@@ -216,10 +216,11 @@ class Script(object):
     mpack_instance_name = execution_command.get_servicegroup_name()
     module_name = execution_command.get_module_name()
     component_type = execution_command.get_component_type()
+    component_name = execution_command.get_component_instance_name()
 
     try:
       mpack_version, component_version = mpack_manager_helper.get_versions(mpack_name,
-        mpack_instance_name, module_name, component_type )
+        mpack_instance_name, module_name, component_type, "default", component_name )
 
       mpack_version_dictionary = {
         "mpackVersion": mpack_version,
diff --git a/mpack-instance-manager/src/main/python/instance_manager/instance_manager.py b/mpack-instance-manager/src/main/python/instance_manager/instance_manager.py
index 5d6ca16..9aed9c8 100644
--- a/mpack-instance-manager/src/main/python/instance_manager/instance_manager.py
+++ b/mpack-instance-manager/src/main/python/instance_manager/instance_manager.py
@@ -17,7 +17,7 @@ limitations under the License.
 
 """
 
-__all__ = ["create_mpack", "set_mpack_instance", "get_conf_dir", "get_log_dir", "get_run_dir", "list_instances"]
+__all__ = ["create_mpack", "set_mpack_instance", "get_conf_dir", "get_log_dir", "get_run_dir", "list_instances", "walk_mpack_dict"]
 
 import sys
 import os
@@ -97,7 +97,8 @@ def get_conf_dir(mpack=None, mpack_instance=None, subgroup_name=DEFAULT_SUBGROUP
   """
   Use case: retrieve conf directory paths for a given component instances based on the granularity specified
             ranging from: mpack, mpack-instance, subgroup-name, module-name and map of component instance
-            AND with a filtering on each level
+            AND with a filtering on each level. The return value is a list of conf_dir since we support
+            multiple mpacks and multiple mpack instances now.
 
   Granularity works only while names for all consecutive levels are specified.
   Note that subgroup has default value of 'default'
@@ -108,9 +109,21 @@ def get_conf_dir(mpack=None, mpack_instance=None, subgroup_name=DEFAULT_SUBGROUP
 
   Components are provided as map with key as 'component type' and value as 'list of individual component instances
   names' OR empty map for all component instances present
+
+  Note also that client component has different layout from server component, i.e:
+  zookeeper_client: /usr/hwx/instances/hdpcore/default/default/zookeeper_client/conf/
+  zookeeper_server: /usr/hwx/instances/hdpcore/default/default/zookeeper/zookeeper_server/ZOOKEEPER/conf/
   """
-  return build_granular_json_with_filtering(mpack, mpack_instance, subgroup_name, module_name, components_map,
-                                            output_conf_dir=True)
+  dirs, is_client = get_conf_log_run_dir_helper(mpack, mpack_instance, subgroup_name, module_name, components_map, output_conf_dir = True, output_log_dir = False, output_run_dir = False)
+  path = ""
+  if not is_client:
+    pathlist =  [dir for dir in dirs if
+            (mpack == None or mpack in dir) and (mpack_instance == None or mpack_instance in dir) and (
+            module_name == None or module_name in dir)]
+  else:
+    pathlist = [dir for dir in dirs if
+            (mpack == None or mpack in dir) and (mpack_instance == None or mpack_instance in dir)]
+  return path if len(pathlist) == 0 else pathlist[0]
 
 def get_log_dir(mpack=None, mpack_instance=None, subgroup_name=DEFAULT_SUBGROUP_NAME, module_name=None,
                  components_map=None):
@@ -129,8 +142,17 @@ def get_log_dir(mpack=None, mpack_instance=None, subgroup_name=DEFAULT_SUBGROUP_
   Components are provided as map with key as 'component type' and value as 'list of individual component instances
   names' OR empty map for all component instances present
   """
-  return build_granular_json_with_filtering(mpack, mpack_instance, subgroup_name, module_name, components_map,
-                                            output_log_dir=True)
+  dirs, is_client = get_conf_log_run_dir_helper(mpack, mpack_instance, subgroup_name, module_name, components_map, output_conf_dir = False, output_log_dir = True, output_run_dir = False)
+  path = ""
+  if not is_client:
+    pathlist = [dir for dir in dirs if
+            (mpack == None or mpack in dir) and (mpack_instance == None or mpack_instance in dir) and (
+            module_name == None or module_name in dir)]
+  else:
+    pathlist = [dir for dir in dirs if
+            (mpack == None or mpack in dir) and (mpack_instance == None or mpack_instance in dir)]
+  return path if len(pathlist) == 0 else pathlist[0]
+
 
 def get_run_dir(mpack=None, mpack_instance=None, subgroup_name=DEFAULT_SUBGROUP_NAME, module_name=None,
                  components_map=None):
@@ -149,12 +171,73 @@ def get_run_dir(mpack=None, mpack_instance=None, subgroup_name=DEFAULT_SUBGROUP_
   Components are provided as map with key as 'component type' and value as 'list of individual component instances
   names' OR empty map for all component instances present
   """
-  return build_granular_json_with_filtering(mpack, mpack_instance, subgroup_name, module_name, components_map,
-                                            output_run_dir=True)
+  dirs, is_client = get_conf_log_run_dir_helper(mpack, mpack_instance, subgroup_name, module_name, components_map, output_conf_dir = False, output_log_dir = False, output_run_dir = True)
+  path = ""
+  if not is_client:
+    pathlist = [dir for dir in dirs if
+            (mpack == None or mpack in dir) and (mpack_instance == None or mpack_instance in dir) and (
+            module_name == None or module_name in dir)]
+  else:
+    pathlist = [dir for dir in dirs if
+            (mpack == None or mpack in dir) and (mpack_instance == None or mpack_instance in dir)]
+  return path if len(pathlist) == 0 else pathlist[0]
+
+
+def walk_mpack_dict(mpack_dict, filter, dirs):
+  """
+  A utility funtion to traverse the nested dict to get a list of config/log/run dirs
+  :param mpack_dict: mpack json dict
+  :param dirs: Set to hold dir strings
+  :return: None
+  """
+  for key in mpack_dict:
+    if key == filter:
+      dirs.add(mpack_dict[key])
+    elif type(mpack_dict[key]) != dict:
+      pass
+    else:
+      walk_mpack_dict(mpack_dict[key], filter, dirs)
+
+def get_conf_log_run_dir_helper(mpack=None, mpack_instance=None, subgroup_name=DEFAULT_SUBGROUP_NAME, module_name=None,
+                 components_map=None, output_conf_dir=False, output_log_dir=False, output_run_dir=False):
+  """
+  A helper function to get dictionary to hold the path from mpack to config/log/run dirs
+  :param mpack: mpack name, can be None
+  :param mpack_instance: mpack_instance name, can be None
+  :param subgroup_name: subgroups name, default is "default"
+  :param module_name: module name, can be None
+  :param components_map: can be None
+  :param output_conf_dir: default is None
+  :param output_log_dir: default is None
+  :param output_run_dir: default is None
+  :return: list of dirs, can be empty if output_conf_dir/output_log_dir/output_run_dir are all False
+  """
+  dirs = set()
+  rst_json = {}
+  filter = ""
+  if output_conf_dir:
+    rst_json = build_granular_json_with_filtering(mpack, mpack_instance, subgroup_name, module_name, components_map,
+                                                  output_conf_dir=True)
+    filter = "config_dir"
+  elif output_log_dir:
+    rst_json = build_granular_json_with_filtering(mpack, mpack_instance, subgroup_name, module_name, components_map,
+                                                  output_log_dir=True)
+    filter = "log_dir"
+  elif output_run_dir:
+    rst_json = build_granular_json_with_filtering(mpack, mpack_instance, subgroup_name, module_name, components_map,
+                                                  output_run_dir=True)
+    filter = "run_dir"
+  walk_mpack_dict(rst_json, filter, dirs)
+  categories = set()
+  walk_mpack_dict(rst_json, "category", categories)
+  is_client = False
+  if categories and CLIENT_CATEGORY in categories:
+    is_client = True
+  return list(dirs), is_client
 
 
 def list_instances(mpack=None, mpack_instance=None, subgroup_name=DEFAULT_SUBGROUP_NAME, module_name=None,
-                   components_map=None):
+                   components_map=None, output_conf_dir=False, output_log_dir=False, output_run_dir=False):
   """
   Use case: figure out the versions a given component instances based on the granularity specified
             ranging from: mpack, mpack-instance, subgroup-name, module-name and map of component instance
diff --git a/mpack-instance-manager/src/test/python/instance_manager/test_instance_manager.py b/mpack-instance-manager/src/test/python/instance_manager/test_instance_manager.py
index 1eaed9e..d9bbe3e 100644
--- a/mpack-instance-manager/src/test/python/instance_manager/test_instance_manager.py
+++ b/mpack-instance-manager/src/test/python/instance_manager/test_instance_manager.py
@@ -164,8 +164,10 @@ class TestInstanceManager(TestCase):
     create_mpack_with_defaults(module_name=SERVER_MODULE_NAME.upper(), components=None,
                                components_map={SERVER_COMPONENT_NAME.upper(): ['server1']})
 
-    conf_dir_json = instance_manager.get_conf_dir()
-
+    conf_server_dir = instance_manager.get_conf_dir(components_map={"hdfs_server": ["server1"]}, module_name="hdfs")
+    conf_client_dir = instance_manager.get_conf_dir(components_map={"hdfs_client": [""]}, module_name="hdfs-clients")
+    """
+    This is the conf_dir_json
     expected_json = {
       "mpacks": {
         "hdpcore": {
@@ -211,15 +213,20 @@ class TestInstanceManager(TestCase):
         }
       }
     }
-    self.assertEqual(conf_dir_json, expected_json)
+    """
+    expected_conf_server_dir = "/tmp/instance_manager_test/instances/hdpcore/Production/default/hdfs/hdfs_server/server1/conf"
+    expected_conf_client_dir = "/tmp/instance_manager_test/instances/hdpcore/Production/default/hdfs_client/conf"
+    self.assertEqual(conf_server_dir, expected_conf_server_dir)
+    self.assertEqual(conf_client_dir, expected_conf_client_dir)
 
   def test_get_log_dir_all(self):
     create_mpack_with_defaults(module_name=CLIENT_MODULE_NAME.upper())
     create_mpack_with_defaults(module_name=SERVER_MODULE_NAME.upper(), components=None,
                                components_map={SERVER_COMPONENT_NAME.upper(): ['server1']})
 
-    log_dir_json = instance_manager.get_log_dir()
-
+    log_server_dir = instance_manager.get_log_dir(components_map={"hdfs_server": ["server1"]}, module_name="hdfs")
+    log_client_dir = instance_manager.get_log_dir(components_map={"hdfs_client": [""]}, module_name="hdfs-clients")
+    """
     expected_json = {
       "mpacks": {
         "hdpcore": {
@@ -265,15 +272,21 @@ class TestInstanceManager(TestCase):
         }
       }
     }
-    self.assertEqual(log_dir_json, expected_json)
+    """
+    expected_log_server_dir = "/tmp/instance_manager_test/instances/hdpcore/Production/default/hdfs/hdfs_server/server1/log"
+    expected_log_client_dir = "/tmp/instance_manager_test/instances/hdpcore/Production/default/hdfs_client/log"
+    self.assertEqual(log_server_dir, expected_log_server_dir)
+    self.assertEqual(log_client_dir, expected_log_client_dir)
+
 
   def test_get_run_dir_all(self):
     create_mpack_with_defaults(module_name=CLIENT_MODULE_NAME.upper())
     create_mpack_with_defaults(module_name=SERVER_MODULE_NAME.upper(), components=None,
                                components_map={SERVER_COMPONENT_NAME.upper(): ['server1']})
 
-    run_dir_json = instance_manager.get_run_dir()
-
+    run_server_dir = instance_manager.get_run_dir(components_map={"hdfs_server": ["server1"]}, module_name="hdfs")
+    run_client_dir = instance_manager.get_run_dir(components_map={"hdfs_client": [""]}, module_name="hdfs-clients")
+    """
     expected_json = {
       "mpacks": {
         "hdpcore": {
@@ -319,14 +332,41 @@ class TestInstanceManager(TestCase):
         }
       }
     }
-    self.assertEqual(run_dir_json, expected_json)
+    """
+    expected_run_server_dir = "/tmp/instance_manager_test/instances/hdpcore/Production/default/hdfs/hdfs_server/server1/run"
+    expected_run_client_dir = "/tmp/instance_manager_test/instances/hdpcore/Production/default/hdfs_client/run"
+    self.assertEqual(run_server_dir, expected_run_server_dir)
+    self.assertEqual(run_client_dir, expected_run_client_dir)
+
+  def test_get_mpack_module_versions(self):
+    MPACK_VERSION_KEY_NAME = 'mpack_version'
+    MODULE_VERSION_KEY_NAME = 'module_version'
+
+    create_mpack_with_defaults(module_name=CLIENT_MODULE_NAME.upper())
+    create_mpack_with_defaults(module_name=SERVER_MODULE_NAME.upper(), components=None,
+                               components_map={SERVER_COMPONENT_NAME.upper(): ['server1']})
+
+    instances_json = instance_manager.list_instances(module_name=CLIENT_MODULE_NAME)
+    dirs = set()
+    instance_manager.walk_mpack_dict(instances_json, MPACK_VERSION_KEY_NAME, dirs)
+    self.assertEqual(next(iter(dirs)), "1.0.0-b1")
+    dirs.clear()
+    instance_manager.walk_mpack_dict(instances_json, MODULE_VERSION_KEY_NAME, dirs)
+    self.assertEqual(next(iter(dirs)), "3.1.0.0-b1")
+    instances_json = instance_manager.list_instances(module_name=SERVER_MODULE_NAME)
+    dirs.clear()
+    instance_manager.walk_mpack_dict(instances_json, MPACK_VERSION_KEY_NAME, dirs)
+    self.assertEqual(next(iter(dirs)), "1.0.0-b1")
+    dirs.clear()
+    instance_manager.walk_mpack_dict(instances_json, MODULE_VERSION_KEY_NAME, dirs)
+    self.assertEqual(next(iter(dirs)), "3.1.0.0-b1")
 
   def test_list_instances_all(self):
     create_mpack_with_defaults(module_name=CLIENT_MODULE_NAME.upper())
     create_mpack_with_defaults(module_name=SERVER_MODULE_NAME.upper(), components=None,
                                components_map={SERVER_COMPONENT_NAME.upper(): ['server1']})
 
-    conf_dir_json = instance_manager.list_instances()
+    instance_json = instance_manager.list_instances()
 
     expected_json = {
       "mpacks": {
@@ -387,43 +427,44 @@ class TestInstanceManager(TestCase):
         }
       }
     }
-    self.assertDictEqual(conf_dir_json, expected_json)
+
+    self.assertDictEqual(instance_json, expected_json)
 
   def test_granularity(self):
     create_mpack_with_defaults()
     create_mpack_with_defaults(module_name=CLIENT_MODULE_NAME)
 
-    full_conf_dir_json = instance_manager.get_conf_dir()
-    self.assertTrue('mpacks' in full_conf_dir_json)
+    conf_dir = instance_manager.get_conf_dir()
+    self.assertTrue('/hdfs_server/default/conf' in conf_dir)
 
-    mpack_conf_dir_json = instance_manager.get_conf_dir(mpack=MPACK_NAME)
-    self.assertTrue('mpack-instances' in mpack_conf_dir_json)
+    conf_dir = instance_manager.get_conf_dir(mpack=MPACK_NAME, module_name=SERVER_MODULE_NAME)
+    self.assertTrue('/hdfs_server/default/conf' in conf_dir)
 
-    instance_conf_dir_json = instance_manager.get_conf_dir(mpack=MPACK_NAME, mpack_instance=INSTANCE_NAME_1,
+    instance_conf_dir = instance_manager.get_conf_dir(mpack=MPACK_NAME, mpack_instance=INSTANCE_NAME_1,
                                                            subgroup_name=None)
-    self.assertTrue('subgroups' in instance_conf_dir_json)
+    self.assertTrue('/hdfs_server/default/conf' in instance_conf_dir)
 
-    subgroup_conf_dir_json = instance_manager.get_conf_dir(mpack=MPACK_NAME, mpack_instance=INSTANCE_NAME_1,
+    subgroup_conf_dir = instance_manager.get_conf_dir(mpack=MPACK_NAME, mpack_instance=INSTANCE_NAME_1,
                                                            subgroup_name=SUBGROUP_NAME)
-    self.assertTrue('modules' in subgroup_conf_dir_json)
+    self.assertTrue('/hdfs_server/default/conf' in subgroup_conf_dir)
 
-    module_conf_dir_json = instance_manager.get_conf_dir(mpack=MPACK_NAME, mpack_instance=INSTANCE_NAME_1,
+    module_conf_dir = instance_manager.get_conf_dir(mpack=MPACK_NAME, mpack_instance=INSTANCE_NAME_1,
                                                          subgroup_name=SUBGROUP_NAME, module_name=SERVER_MODULE_NAME)
-    self.assertTrue('components' in module_conf_dir_json)
+    self.assertTrue('/hdfs_server/default/conf' in module_conf_dir)
 
-    module_conf_dir_json = instance_manager.get_conf_dir(mpack=MPACK_NAME, mpack_instance=INSTANCE_NAME_1,
+    module_conf_dir = instance_manager.get_conf_dir(mpack=MPACK_NAME, mpack_instance=INSTANCE_NAME_1,
                                                          subgroup_name=SUBGROUP_NAME, module_name=CLIENT_MODULE_NAME)
-    self.assertTrue('components' in module_conf_dir_json)
+    self.assertTrue('/hdfs_client/conf' in module_conf_dir)
 
     # The mpack level filter not specified
-    full_conf_dir_json = instance_manager.get_conf_dir(mpack_instance=INSTANCE_NAME_1, subgroup_name=SUBGROUP_NAME,
+    module_conf_dir = instance_manager.get_conf_dir(mpack_instance=INSTANCE_NAME_1, subgroup_name=SUBGROUP_NAME,
                                                        module_name=SERVER_MODULE_NAME)
-    self.assertTrue('mpacks' in full_conf_dir_json)
+    self.assertTrue('/hdfs_server/default/conf' in module_conf_dir)
 
     # The instance level filter not specified
-    mpack_conf_dir_json = instance_manager.get_conf_dir(mpack=MPACK_NAME, subgroup_name=SUBGROUP_NAME,
+    module_conf_dir = instance_manager.get_conf_dir(mpack=MPACK_NAME, subgroup_name=SUBGROUP_NAME,
                                                         module_name=SERVER_MODULE_NAME)
-    self.assertTrue('mpack-instances' in mpack_conf_dir_json)
+    self.assertTrue('/hdfs_server/default/conf' in module_conf_dir)
 
   def test_filtering(self):
     create_mpack_with_defaults(module_name=CLIENT_MODULE_NAME)