You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by jl...@apache.org on 2016/04/12 19:19:31 UTC
[2/2] ambari git commit: AMBARI-15662: Ambari server upgrade should
reapply installed mpacks (jluniya)
AMBARI-15662: Ambari server upgrade should reapply installed mpacks (jluniya)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/5dddc529
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/5dddc529
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/5dddc529
Branch: refs/heads/trunk
Commit: 5dddc529f359d8557535efa4bf9eb33add9cda60
Parents: e371ac5
Author: Jayush Luniya <jl...@hortonworks.com>
Authored: Tue Apr 12 10:19:24 2016 -0700
Committer: Jayush Luniya <jl...@hortonworks.com>
Committed: Tue Apr 12 10:19:24 2016 -0700
----------------------------------------------------------------------
ambari-server/pom.xml | 1 +
.../python/ambari_server/serverConfiguration.py | 6 +-
.../main/python/ambari_server/serverUpgrade.py | 2 +
.../main/python/ambari_server/setupMpacks.py | 127 +++++-
.../src/test/python/TestAmbariServer.py | 4 +-
ambari-server/src/test/python/TestMpacks.py | 448 +++++++++++++++++++
.../MYSERVICE/1.0.0/metainfo.xml | 18 +
.../MYSERVICE/1.0.0/metainfo.xml | 18 +
.../MYSERVICE/2.0.0/metainfo.xml | 18 +
.../myservice-ambari-mpack-1.0.0.0/mpack.json | 50 +++
.../common-services/SERVICEA/1.0/metainfo.xml | 18 +
.../common-services/SERVICEA/2.0/metainfo.xml | 18 +
.../common-services/SERVICEB/1.0.0/metainfo.xml | 18 +
.../common-services/SERVICEB/2.0.0/metainfo.xml | 18 +
.../mystack-ambari-mpack-1.0.0.0/mpack.json | 21 +
.../stacks/MYSTACK/1.0/metainfo.xml | 18 +
.../MYSTACK/1.0/services/SERVICEA/metainfo.xml | 18 +
.../stacks/MYSTACK/1.1/metainfo.xml | 18 +
.../MYSTACK/1.1/services/SERVICEA/metainfo.xml | 18 +
.../stacks/MYSTACK/2.0/metainfo.xml | 18 +
.../MYSTACK/2.0/services/SERVICEA/metainfo.xml | 18 +
.../MYSTACK/2.0/services/SERVICEB/metainfo.xml | 18 +
.../common-services/SERVICEA/1.0/metainfo.xml | 18 +
.../common-services/SERVICEA/2.0/metainfo.xml | 18 +
.../common-services/SERVICEB/1.0.0/metainfo.xml | 18 +
.../common-services/SERVICEB/2.0.0/metainfo.xml | 18 +
.../common-services/SERVICEC/1.0.0/metainfo.xml | 18 +
.../common-services/SERVICEC/2.0.0/metainfo.xml | 18 +
.../mystack-ambari-mpack-1.0.0.1/mpack.json | 21 +
.../stacks/MYSTACK/1.0/metainfo.xml | 18 +
.../MYSTACK/1.0/services/SERVICEA/metainfo.xml | 18 +
.../stacks/MYSTACK/1.1/metainfo.xml | 18 +
.../MYSTACK/1.1/services/SERVICEA/metainfo.xml | 18 +
.../stacks/MYSTACK/2.0/metainfo.xml | 18 +
.../MYSTACK/2.0/services/SERVICEA/metainfo.xml | 18 +
.../MYSTACK/2.0/services/SERVICEB/metainfo.xml | 18 +
.../stacks/MYSTACK/3.0/metainfo.xml | 18 +
.../MYSTACK/3.0/services/SERVICEA/metainfo.xml | 18 +
.../MYSTACK/3.0/services/SERVICEB/metainfo.xml | 18 +
.../MYSTACK/3.0/services/SERVICEC/metainfo.xml | 18 +
.../src/test/resources/mpacks_replay.log | 2 +
41 files changed, 1215 insertions(+), 25 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/5dddc529/ambari-server/pom.xml
----------------------------------------------------------------------
diff --git a/ambari-server/pom.xml b/ambari-server/pom.xml
index b36c4e1..0240733 100644
--- a/ambari-server/pom.xml
+++ b/ambari-server/pom.xml
@@ -254,6 +254,7 @@
<exclude>src/test/resources/gsInstaller-hosts.txt</exclude>
<exclude>src/test/resources/temporal_ganglia_data.txt</exclude>
<exclude>src/test/resources/users.ldif</exclude>
+ <exclude>src/test/resources/mpacks_replay.log</exclude>
<exclude>src/main/resources/hive-schema-0.10.0.oracle.sql</exclude>
<exclude>src/main/resources/hive-schema-0.12.0.oracle.sql</exclude>
<exclude>src/main/resources/db/serial</exclude>
http://git-wip-us.apache.org/repos/asf/ambari/blob/5dddc529/ambari-server/src/main/python/ambari_server/serverConfiguration.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/python/ambari_server/serverConfiguration.py b/ambari-server/src/main/python/ambari_server/serverConfiguration.py
index 446b083..d5a388f 100644
--- a/ambari-server/src/main/python/ambari_server/serverConfiguration.py
+++ b/ambari-server/src/main/python/ambari_server/serverConfiguration.py
@@ -1354,7 +1354,7 @@ def get_resources_location(properties):
#
def get_stack_location(properties):
stack_location = properties[STACK_LOCATION_KEY]
- if stack_location is None:
+ if not stack_location:
stack_location = configDefaults.STACK_LOCATION_DEFAULT
return stack_location
@@ -1363,7 +1363,7 @@ def get_stack_location(properties):
#
def get_common_services_location(properties):
common_services_location = properties[COMMON_SERVICES_PATH_PROPERTY]
- if common_services_location is None:
+ if not common_services_location:
common_services_location = configDefaults.COMMON_SERVICES_LOCATION_DEFAULT
return common_services_location
@@ -1372,7 +1372,7 @@ def get_common_services_location(properties):
#
def get_mpacks_staging_location(properties):
mpacks_staging_location = properties[MPACKS_STAGING_PATH_PROPERTY]
- if mpacks_staging_location is None:
+ if not mpacks_staging_location:
mpacks_staging_location = configDefaults.MPACKS_STAGING_LOCATION_DEFAULT
return mpacks_staging_location
http://git-wip-us.apache.org/repos/asf/ambari/blob/5dddc529/ambari-server/src/main/python/ambari_server/serverUpgrade.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/python/ambari_server/serverUpgrade.py b/ambari-server/src/main/python/ambari_server/serverUpgrade.py
index 9521d61..72c4185 100644
--- a/ambari-server/src/main/python/ambari_server/serverUpgrade.py
+++ b/ambari-server/src/main/python/ambari_server/serverUpgrade.py
@@ -47,6 +47,7 @@ from ambari_server.utils import compare_versions
from ambari_server.serverUtils import is_server_runing, get_ambari_server_api_base
from ambari_server.userInput import get_validated_string_input, get_prompt_default, read_password, get_YN_input
from ambari_server.serverClassPath import ServerClassPath
+from ambari_server.setupMpacks import replay_mpack_logs
# constants
STACK_NAME_VER_SEP = "-"
@@ -336,6 +337,7 @@ def upgrade(args):
raise FatalException(retcode, err)
restore_custom_services()
+ replay_mpack_logs()
try:
update_database_name_property(upgrade=True)
except FatalException:
http://git-wip-us.apache.org/repos/asf/ambari/blob/5dddc529/ambari-server/src/main/python/ambari_server/setupMpacks.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/python/ambari_server/setupMpacks.py b/ambari-server/src/main/python/ambari_server/setupMpacks.py
index 45bb675..3aa071f 100644
--- a/ambari-server/src/main/python/ambari_server/setupMpacks.py
+++ b/ambari-server/src/main/python/ambari_server/setupMpacks.py
@@ -22,6 +22,7 @@ import os
import shutil
import tempfile
import json
+import ast
from ambari_commons.exceptions import FatalException
from ambari_commons.inet_utils import download_file
@@ -33,6 +34,10 @@ from ambari_server.serverConfiguration import get_ambari_properties, get_ambari_
from resource_management.core import sudo
from resource_management.libraries.functions.tar_archive import extract_archive, get_archive_root_dir
from resource_management.libraries.functions.version import compare_versions
+from ambari_server.setupActions import INSTALL_MPACK_ACTION, UPGRADE_MPACK_ACTION
+
+MPACKS_REPLAY_LOG_FILENAME = "mpacks_replay.log"
+MPACKS_CACHE_DIRNAME = "cache"
class _named_dict(dict):
"""
@@ -175,9 +180,10 @@ def remove_symlinks(stack_location, service_definitions_location, staged_mpack_d
print_info_msg("Removing symlink {0}".format(dir))
sudo.unlink(dir)
-def purge_stacks_and_mpacks():
+def purge_stacks_and_mpacks(replay_mode=False):
"""
Purge all stacks and management packs
+ :param replay_mode: Flag to indicate if purging in replay mode
"""
# Get ambari mpacks config properties
stack_location, service_definitions_location, mpacks_staging_location = get_mpack_properties()
@@ -192,7 +198,8 @@ def purge_stacks_and_mpacks():
print_info_msg("Purging service definitions location: " + service_definitions_location)
sudo.rmtree(service_definitions_location)
- if os.path.exists(mpacks_staging_location):
+ # Don't purge mpacks staging directory in replay mode
+ if os.path.exists(mpacks_staging_location) and not replay_mode:
print_info_msg("Purging mpacks staging location: " + mpacks_staging_location)
sudo.rmtree(mpacks_staging_location)
sudo.makedir(mpacks_staging_location, 0755)
@@ -206,7 +213,7 @@ def process_stack_definitions_artifact(artifact, artifact_source_dir, options):
"""
# Get ambari mpack properties
stack_location, service_definitions_location, mpacks_staging_location = get_mpack_properties()
- for file in os.listdir(artifact_source_dir):
+ for file in sorted(os.listdir(artifact_source_dir)):
if os.path.isfile(os.path.join(artifact_source_dir, file)):
# Example: /var/lib/ambari-server/resources/stacks/stack_advisor.py
create_symlink(artifact_source_dir, stack_location, file, options.force)
@@ -215,7 +222,7 @@ def process_stack_definitions_artifact(artifact, artifact_source_dir, options):
dest_stack_dir = os.path.join(stack_location, file)
if not os.path.exists(dest_stack_dir):
sudo.makedir(dest_stack_dir, 0755)
- for file in os.listdir(src_stack_dir):
+ for file in sorted(os.listdir(src_stack_dir)):
if os.path.isfile(os.path.join(src_stack_dir, file)):
create_symlink(src_stack_dir, dest_stack_dir, file, options.force)
else:
@@ -223,13 +230,13 @@ def process_stack_definitions_artifact(artifact, artifact_source_dir, options):
dest_stack_version_dir = os.path.join(dest_stack_dir, file)
if not os.path.exists(dest_stack_version_dir):
sudo.makedir(dest_stack_version_dir, 0755)
- for file in os.listdir(src_stack_version_dir):
+ for file in sorted(os.listdir(src_stack_version_dir)):
if file == "services":
src_stack_services_dir = os.path.join(src_stack_version_dir, file)
dest_stack_services_dir = os.path.join(dest_stack_version_dir, file)
if not os.path.exists(dest_stack_services_dir):
sudo.makedir(dest_stack_services_dir, 0755)
- for file in os.listdir(src_stack_services_dir):
+ for file in sorted(os.listdir(src_stack_services_dir)):
create_symlink(src_stack_services_dir, dest_stack_services_dir, file, options.force)
else:
create_symlink(src_stack_version_dir, dest_stack_version_dir, file, options.force)
@@ -269,12 +276,12 @@ def process_service_definitions_artifact(artifact, artifact_source_dir, options)
"""
# Get ambari mpack properties
stack_location, service_definitions_location, mpacks_staging_location = get_mpack_properties()
- for file in os.listdir(artifact_source_dir):
+ for file in sorted(os.listdir(artifact_source_dir)):
src_service_definitions_dir = os.path.join(artifact_source_dir, file)
dest_service_definitions_dir = os.path.join(service_definitions_location, file)
if not os.path.exists(dest_service_definitions_dir):
sudo.makedir(dest_service_definitions_dir, 0755)
- for file in os.listdir(src_service_definitions_dir):
+ for file in sorted(os.listdir(src_service_definitions_dir)):
create_symlink(src_service_definitions_dir, dest_service_definitions_dir, file, options.force)
def process_service_definition_artifact(artifact, artifact_source_dir, options):
@@ -321,9 +328,9 @@ def process_stack_extension_definitions_artifact(artifact, artifact_source_dir,
if not service_versions_map:
print_error_msg("Must provide service versions map for stack-extension-definitions artifact!")
raise FatalException(-1, 'Must provide service versions map for stack-extension-definition artifact!')
- for service_name in os.listdir(artifact_source_dir):
+ for service_name in sorted(os.listdir(artifact_source_dir)):
source_service_path = os.path.join(artifact_source_dir, service_name)
- for service_version in os.listdir(source_service_path):
+ for service_version in sorted(os.listdir(source_service_path)):
source_service_version_path = os.path.join(source_service_path, service_version)
for service_version_entry in service_versions_map:
if service_name == service_version_entry.service_name and service_version == service_version_entry.service_version:
@@ -389,14 +396,15 @@ def search_mpacks(mpack_name, max_mpack_version=None):
stack_location, service_definitions_location, mpacks_staging_location = get_mpack_properties()
results = []
if os.path.exists(mpacks_staging_location) and os.path.isdir(mpacks_staging_location):
- staged_mpack_dirs = os.listdir(mpacks_staging_location)
+ staged_mpack_dirs = sorted(os.listdir(mpacks_staging_location))
for dir in staged_mpack_dirs:
+ if dir == MPACKS_CACHE_DIRNAME:
+ continue
staged_mpack_dir = os.path.join(mpacks_staging_location, dir)
if os.path.isdir(staged_mpack_dir):
staged_mpack_metadata = read_mpack_metadata(staged_mpack_dir)
if not staged_mpack_metadata:
- print_error_msg("Skipping malformed management pack {0}-{1}. Metadata file missing!".format(
- staged_mpack_name, staged_mpack_version))
+ print_error_msg("Skipping malformed management pack in directory {0}.".format(staged_mpack_dir))
continue
staged_mpack_name = staged_mpack_metadata.name
staged_mpack_version = staged_mpack_metadata.version
@@ -427,8 +435,10 @@ def uninstall_mpack(mpack_name, mpack_version):
stack_location, service_definitions_location, mpacks_staging_location = get_mpack_properties()
found = False
if os.path.exists(mpacks_staging_location) and os.path.isdir(mpacks_staging_location):
- staged_mpack_dirs = os.listdir(mpacks_staging_location)
+ staged_mpack_dirs = sorted(os.listdir(mpacks_staging_location))
for dir in staged_mpack_dirs:
+ if dir == MPACKS_CACHE_DIRNAME:
+ continue
staged_mpack_dir = os.path.join(mpacks_staging_location, dir)
if os.path.isdir(staged_mpack_dir):
staged_mpack_metadata = read_mpack_metadata(staged_mpack_dir)
@@ -493,10 +503,11 @@ def validate_mpack_prerequisites(mpack_metadata):
raise FatalException(-1, "Prerequisites for management pack {0}-{1} failed!".format(
mpack_metadata.name, mpack_metadata.version))
-def install_mpack(options):
+def _install_mpack(options, replay_mode=False):
"""
Install management pack
:param options: Command line options
+ :param replay_mode: Flag to indicate if executing command in replay mode
"""
mpack_path = options.mpack_path
@@ -508,6 +519,9 @@ def install_mpack(options):
# Download management pack to a temp location
tmp_archive_path = download_mpack(mpack_path)
+ if not (tmp_archive_path and os.path.exists(tmp_archive_path)):
+ print_error_msg("Management pack could not be downloaded!")
+ raise FatalException(-1, 'Management pack could not be downloaded!')
# Expand management pack in temp directory
tmp_root_dir = expand_mpack(tmp_archive_path)
@@ -518,14 +532,17 @@ def install_mpack(options):
raise FatalException(-1, 'Malformed management pack {0}. Metadata file missing!'.format(mpack_path))
# Validate management pack prerequisites
- validate_mpack_prerequisites(mpack_metadata)
+ # Skip validation in replay mode
+ if not replay_mode:
+ validate_mpack_prerequisites(mpack_metadata)
# Purge previously installed stacks and management packs
if options.purge:
- purge_stacks_and_mpacks()
+ purge_stacks_and_mpacks(replay_mode)
# Get ambari mpack properties
stack_location, service_definitions_location, mpacks_staging_location = get_mpack_properties()
+ mpacks_cache_location = os.path.join(mpacks_staging_location, MPACKS_CACHE_DIRNAME)
# Create directories
if not os.path.exists(stack_location):
sudo.makedir(stack_location, 0755)
@@ -533,12 +550,15 @@ def install_mpack(options):
sudo.makedir(service_definitions_location, 0755)
if not os.path.exists(mpacks_staging_location):
sudo.makedir(mpacks_staging_location, 0755)
+ if not os.path.exists(mpacks_cache_location):
+ sudo.makedir(mpacks_cache_location, 0755)
# Stage management pack (Stage at /var/lib/ambari-server/resources/mpacks/mpack_name-mpack_version)
mpack_name = mpack_metadata.name
mpack_version = mpack_metadata.version
mpack_dirname = mpack_name + "-" + mpack_version
mpack_staging_dir = os.path.join(mpacks_staging_location, mpack_dirname)
+ mpack_archive_path = os.path.join(mpacks_cache_location, os.path.basename(tmp_archive_path))
print_info_msg("Stage management pack {0}-{1} to staging location {2}".format(
mpack_name, mpack_version, mpack_staging_dir))
@@ -551,6 +571,7 @@ def install_mpack(options):
print_error_msg(error_msg)
raise FatalException(-1, error_msg)
shutil.move(tmp_root_dir, mpack_staging_dir)
+ shutil.move(tmp_archive_path, mpack_archive_path)
# Process setup steps for all artifacts (stack-definitions, service-definitions, stack-extension-definitions)
# in the management pack
@@ -580,12 +601,49 @@ def install_mpack(options):
print_info_msg("Unknown artifact {0} of type {1}".format(artifact_name, artifact_type))
print_info_msg("Management pack {0}-{1} successfully installed!".format(mpack_name, mpack_version))
- return mpack_name, mpack_version, mpack_staging_dir
+ return mpack_name, mpack_version, mpack_staging_dir, mpack_archive_path
+
+def get_replay_log_file():
+ """
+ Helper function to get mpack replay log file path
+ :return: mpack replay log file path
+ """
+ stack_location, service_definitions_location, mpacks_staging_location = get_mpack_properties()
+ replay_log_file = os.path.join(mpacks_staging_location, MPACKS_REPLAY_LOG_FILENAME)
+ return replay_log_file
+
+def add_replay_log(mpack_command, mpack_archive_path, purge, force, verbose):
+ """
+ Helper function to add mpack replay log entry
+ :param mpack_command: mpack command
+ :param mpack_archive_path: mpack archive path (/var/lib/ambari-server/resources/mpacks/mpack.tar.gz)
+ :param purge: purge command line option
+ :param force: force command line option
+ :param verbose: verbose command line option
+ """
+ replay_log_file = get_replay_log_file()
+ log = { 'mpack_command' : mpack_command, 'mpack_path' : mpack_archive_path, 'purge' : purge, 'force' : force, 'verbose' : verbose }
+ with open(replay_log_file, "a") as replay_log:
+ replay_log.write("{0}\n".format(log))
-def upgrade_mpack(options):
+def install_mpack(options, replay_mode=False):
+ """
+ Install management pack
+ :param options: Command line options
+ :param replay_mode: Flag to indicate if executing command in replay mode
+ """
+ # Force install when replaying logs
+ if replay_mode:
+ options.force = True
+ (mpack_name, mpack_version, mpack_staging_dir, mpack_archive_path) = _install_mpack(options, replay_mode)
+ if not replay_mode:
+ add_replay_log(INSTALL_MPACK_ACTION, mpack_archive_path, options.purge, options.force, options.verbose)
+
+def upgrade_mpack(options, replay_mode=False):
"""
Upgrade management pack
:param options: command line options
+ :param replay_mode: Flag to indicate if executing command in replay mode
"""
mpack_path = options.mpack_path
if options.purge:
@@ -600,12 +658,39 @@ def upgrade_mpack(options):
# Force install new management pack version
options.force = True
- (mpack_name, mpack_version, mpack_staging_dir) = install_mpack(options)
+ (mpack_name, mpack_version, mpack_staging_dir, mpack_archive_path) = _install_mpack(options, replay_mode)
# Uninstall old management packs
uninstall_mpacks(mpack_name, mpack_version)
-
+ print_info_msg("Management pack {0}-{1} successfully upgraded!".format(mpack_name, mpack_version))
+ if not replay_mode:
+ add_replay_log(UPGRADE_MPACK_ACTION, mpack_archive_path, options.purge, options.force, options.verbose)
+
+def replay_mpack_logs():
+ """
+ Replay mpack logs during ambari-server upgrade
+ """
+ replay_log_file = get_replay_log_file()
+ if os.path.exists(replay_log_file):
+ with open(replay_log_file, "r") as f:
+ for replay_log in f:
+ replay_log = replay_log.strip()
+ print_info_msg("===========================================================================================")
+ print_info_msg("Executing Mpack Replay Log :")
+ print_info_msg(replay_log)
+ print_info_msg("===========================================================================================")
+ replay_options = _named_dict(ast.literal_eval(replay_log))
+ if replay_options.mpack_command == INSTALL_MPACK_ACTION:
+ install_mpack(replay_options, replay_mode=True)
+ elif replay_options.mpack_command == UPGRADE_MPACK_ACTION:
+ upgrade_mpack(replay_options, replay_mode=True)
+ else:
+ error_msg = "Invalid mpack command {0} in mpack replay log {1}!".format(replay_options.mpack_command, replay_log_file)
+ print_error_msg(error_msg)
+ raise FatalException(-1, error_msg)
+ else:
+ print_info_msg("No mpack replay logs found. Skipping replaying mpack commands")
http://git-wip-us.apache.org/repos/asf/ambari/blob/5dddc529/ambari-server/src/test/python/TestAmbariServer.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/python/TestAmbariServer.py b/ambari-server/src/test/python/TestAmbariServer.py
index 390e0fe..e96a7bd 100644
--- a/ambari-server/src/test/python/TestAmbariServer.py
+++ b/ambari-server/src/test/python/TestAmbariServer.py
@@ -5151,7 +5151,8 @@ class TestAmbariServer(TestCase):
@patch("ambari_server.serverUpgrade.move_user_custom_actions")
@patch("ambari_server.serverUpgrade.update_krb_jaas_login_properties")
@patch("ambari_server.serverUpgrade.update_ambari_env")
- def test_upgrade_from_161(self, update_ambari_env_mock, update_krb_jaas_login_properties_mock, move_user_custom_actions_mock, upgrade_local_repo_mock, get_ambari_properties_mock,
+ @patch("ambari_server.setupMpacks.get_replay_log_file")
+ def test_upgrade_from_161(self, get_replay_log_file_mock, update_ambari_env_mock, update_krb_jaas_login_properties_mock, move_user_custom_actions_mock, upgrade_local_repo_mock, get_ambari_properties_mock,
get_ambari_properties_2_mock, get_ambari_properties_3_mock, get_ambari_version_mock, write_property_mock,
is_root_mock, update_ambari_properties_mock, find_properties_file_mock, run_os_command_mock,
run_schema_upgrade_mock, read_ambari_user_mock, print_warning_msg_mock,
@@ -5215,6 +5216,7 @@ class TestAmbariServer(TestCase):
properties2.process_pair(JDBC_DATABASE_NAME_PROPERTY, "ambari")
properties2.process_pair(JDBC_DATABASE_PROPERTY, "postgres")
get_ambari_properties_3_mock.side_effect = get_ambari_properties_2_mock.side_effect = [properties, properties2, properties2]
+ get_replay_log_file_mock.return_value = "/invalid_path/mpacks_replay.log"
run_schema_upgrade_mock.return_value = 0
read_ambari_user_mock.return_value = "custom_user"
http://git-wip-us.apache.org/repos/asf/ambari/blob/5dddc529/ambari-server/src/test/python/TestMpacks.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/python/TestMpacks.py b/ambari-server/src/test/python/TestMpacks.py
new file mode 100644
index 0000000..68e00ee
--- /dev/null
+++ b/ambari-server/src/test/python/TestMpacks.py
@@ -0,0 +1,448 @@
+'''
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+'''
+import os
+from mock.mock import patch, MagicMock, call
+from ambari_commons.exceptions import FatalException
+from ambari_server.setupMpacks import install_mpack, upgrade_mpack, replay_mpack_logs
+from unittest import TestCase
+from ambari_server.serverConfiguration import STACK_LOCATION_KEY, COMMON_SERVICES_PATH_PROPERTY, MPACKS_STAGING_PATH_PROPERTY
+
+with patch.object(os, "geteuid", new=MagicMock(return_value=0)):
+ from resource_management.core import sudo
+ reload(sudo)
+
+def get_configs():
+ test_directory = os.path.dirname(os.path.abspath(__file__))
+ mpacks_directory = os.path.join(test_directory, "mpacks")
+ configs = {
+ STACK_LOCATION_KEY : "/var/lib/ambari-server/resources/stacks",
+ COMMON_SERVICES_PATH_PROPERTY : "/var/lib/ambari-server/resources/common-services",
+ MPACKS_STAGING_PATH_PROPERTY : mpacks_directory
+ }
+ return configs
+
+configs = get_configs()
+
+class TestMpacks(TestCase):
+
+ def test_install_mpack_with_no_mpack_path(self):
+ options = self._create_empty_options_mock()
+ fail = False
+ try:
+ install_mpack(options)
+ except FatalException as e:
+ self.assertEquals("Management pack not specified!", e.reason)
+ fail = True
+ self.assertTrue(fail)
+
+ @patch("ambari_server.setupMpacks.download_mpack")
+ def test_install_mpack_with_invalid_mpack_path(self, download_mpack_mock):
+ options = self._create_empty_options_mock()
+ options.mpack_path = "/invalid_path/mpack.tar.gz"
+ download_mpack_mock.return_value = None
+
+ fail = False
+ try:
+ install_mpack(options)
+ except FatalException as e:
+ self.assertEquals("Management pack could not be downloaded!", e.reason)
+ fail = True
+ self.assertTrue(fail)
+
+ @patch("os.path.exists")
+ @patch("ambari_server.setupMpacks.extract_archive")
+ @patch("ambari_server.setupMpacks.get_archive_root_dir")
+ @patch("ambari_server.setupMpacks.download_mpack")
+ def test_install_mpack_with_malformed_mpack(self, download_mpack_mock, get_archive_root_dir_mock, extract_archive_mock, os_path_exists_mock):
+ options = self._create_empty_options_mock()
+ options.mpack_path = "/path/to/mpack.tar.gz"
+ download_mpack_mock.return_value = "/tmp/mpack.tar.gz"
+ os_path_exists_mock.return_value = True
+ get_archive_root_dir_mock.return_value = None
+
+ fail = False
+ try:
+ install_mpack(options)
+ except FatalException as e:
+ self.assertEquals("Malformed management pack. Root directory missing!", e.reason)
+ fail = True
+ self.assertTrue(fail)
+
+ get_archive_root_dir_mock.return_value = "mpack"
+ os_path_exists_mock.side_effect = [True, False, False]
+ extract_archive_mock.return_value = None
+ fail = False
+ try:
+ install_mpack(options)
+ except FatalException as e:
+ self.assertEquals("Malformed management pack. Failed to expand management pack!", e.reason)
+ fail = True
+ self.assertTrue(fail)
+
+ get_archive_root_dir_mock.return_value = "mpack"
+ os_path_exists_mock.side_effect = [True, False, True, False]
+ extract_archive_mock.return_value = None
+ fail = False
+ try:
+ install_mpack(options)
+ except FatalException as e:
+ self.assertEquals("Malformed management pack {0}. Metadata file missing!".format(options.mpack_path), e.reason)
+ fail = True
+ self.assertTrue(fail)
+
+ @patch("os.path.exists")
+ @patch("shutil.move")
+ @patch("os.mkdir")
+ @patch("ambari_server.setupMpacks.create_symlink")
+ @patch("ambari_server.setupMpacks.get_ambari_version")
+ @patch("ambari_server.setupMpacks.get_ambari_properties")
+ @patch("ambari_server.setupMpacks.add_replay_log")
+ @patch("ambari_server.setupMpacks.purge_stacks_and_mpacks")
+ @patch("ambari_server.setupMpacks.expand_mpack")
+ @patch("ambari_server.setupMpacks.download_mpack")
+ def test_install_stack_mpack(self, download_mpack_mock, expand_mpack_mock, purge_stacks_and_mpacks_mock,
+ add_replay_log_mock, get_ambari_properties_mock, get_ambari_version_mock,
+ create_symlink_mock, os_mkdir_mock, shutil_move_mock, os_path_exists_mock):
+ options = self._create_empty_options_mock()
+ options.mpack_path = "/path/to/mystack.tar.gz"
+ options.purge = True
+ download_mpack_mock.return_value = "/tmp/mystack.tar.gz"
+ expand_mpack_mock.return_value = "mpacks/mystack-ambari-mpack-1.0.0.0"
+ get_ambari_version_mock.return_value = "2.4.0.0"
+ """
+ os_path_exists_calls = [call('/tmp/mystack.tar.gz'),
+ call('mpacks/mystack-ambari-mpack-1.0.0.0/mpack.json'),
+ call('/var/lib/ambari-server/resources/stacks'),
+ call('/var/lib/ambari-server/resources/common-services'),
+ call(mpacks_directory),
+ call(mpacks_directory + '/cache'),
+ call(mpacks_directory + '/mystack-ambari-mpack-1.0.0.0'),
+ call('/var/lib/ambari-server/resources/common-services/SERVICEA'),
+ call('/var/lib/ambari-server/resources/common-services/SERVICEB'),
+ call('/var/lib/ambari-server/resources/stacks/MYSTACK'),
+ call('/var/lib/ambari-server/resources/stacks/MYSTACK/1.0'),
+ call('/var/lib/ambari-server/resources/stacks/MYSTACK/1.0/services'),
+ call('/var/lib/ambari-server/resources/stacks/MYSTACK/1.1'),
+ call('/var/lib/ambari-server/resources/stacks/MYSTACK/1.1/services'),
+ call('/var/lib/ambari-server/resources/stacks/MYSTACK/2.0'),
+ call('/var/lib/ambari-server/resources/stacks/MYSTACK/2.0/services')]
+ """
+ os_path_exists_mock.side_effect = [True, True, False, False, False, False,
+ False, False, False, False, False, False,
+ False, False, False, False]
+ get_ambari_properties_mock.return_value = configs
+ shutil_move_mock.return_value = True
+
+ install_mpack(options)
+
+ stacks_directory = configs[STACK_LOCATION_KEY]
+ common_services_directory = configs[COMMON_SERVICES_PATH_PROPERTY]
+ mpacks_directory = configs[MPACKS_STAGING_PATH_PROPERTY]
+ mpacks_staging_directory = os.path.join(mpacks_directory, "mystack-ambari-mpack-1.0.0.0")
+
+ os_mkdir_calls = [
+ call(stacks_directory),
+ call(common_services_directory),
+ call(mpacks_directory),
+ call(mpacks_directory + '/cache'),
+ call(os.path.join(common_services_directory, "SERVICEA")),
+ call(os.path.join(common_services_directory, "SERVICEB")),
+ call(os.path.join(stacks_directory, "MYSTACK")),
+ call(os.path.join(stacks_directory, "MYSTACK/1.0")),
+ call(os.path.join(stacks_directory, "MYSTACK/1.0/services")),
+ call(os.path.join(stacks_directory, "MYSTACK/1.1")),
+ call(os.path.join(stacks_directory, "MYSTACK/1.1/services")),
+ call(os.path.join(stacks_directory, "MYSTACK/2.0")),
+ call(os.path.join(stacks_directory, "MYSTACK/2.0/services"))
+ ]
+ create_symlink_calls = [
+ call(os.path.join(mpacks_staging_directory, "common-services/SERVICEA"),
+ os.path.join(common_services_directory, "SERVICEA"),
+ "1.0", None),
+ call(os.path.join(mpacks_staging_directory, "common-services/SERVICEA"),
+ os.path.join(common_services_directory, "SERVICEA"),
+ "2.0", None),
+ call(os.path.join(mpacks_staging_directory, "common-services/SERVICEB"),
+ os.path.join(common_services_directory, "SERVICEB"),
+ "1.0.0", None),
+ call(os.path.join(mpacks_staging_directory, "common-services/SERVICEB"),
+ os.path.join(common_services_directory, "SERVICEB"),
+ "2.0.0", None),
+ call(os.path.join(mpacks_staging_directory, "stacks/MYSTACK/1.0"),
+ os.path.join(stacks_directory, "MYSTACK/1.0"),
+ "metainfo.xml", None),
+ call(os.path.join(mpacks_staging_directory, "stacks/MYSTACK/1.0/services"),
+ os.path.join(stacks_directory, "MYSTACK/1.0/services"),
+ "SERVICEA", None),
+ call(os.path.join(mpacks_staging_directory, "stacks/MYSTACK/1.1"),
+ os.path.join(stacks_directory, "MYSTACK/1.1"),
+ "metainfo.xml", None),
+ call(os.path.join(mpacks_staging_directory, "stacks/MYSTACK/1.1/services"),
+ os.path.join(stacks_directory, "MYSTACK/1.1/services"),
+ "SERVICEA", None),
+ call(os.path.join(mpacks_staging_directory, "stacks/MYSTACK/2.0"),
+ os.path.join(stacks_directory, "MYSTACK/2.0"),
+ "metainfo.xml", None),
+ call(os.path.join(mpacks_staging_directory, "stacks/MYSTACK/2.0/services"),
+ os.path.join(stacks_directory, "MYSTACK/2.0/services"),
+ "SERVICEA", None),
+ call(os.path.join(mpacks_staging_directory, "stacks/MYSTACK/2.0/services"),
+ os.path.join(stacks_directory, "MYSTACK/2.0/services"),
+ "SERVICEB", None)
+ ]
+
+ self.assertTrue(purge_stacks_and_mpacks_mock.called)
+ os_mkdir_mock.assert_has_calls(os_mkdir_calls)
+ create_symlink_mock.assert_has_calls(create_symlink_calls)
+ self.assertTrue(add_replay_log_mock.called)
+
+ @patch("os.path.exists")
+ @patch("os.path.isdir")
+ @patch("os.symlink")
+ @patch("shutil.move")
+ @patch("os.mkdir")
+ @patch("ambari_server.setupMpacks.create_symlink")
+ @patch("ambari_server.setupMpacks.get_ambari_version")
+ @patch("ambari_server.setupMpacks.get_ambari_properties")
+ @patch("ambari_server.setupMpacks.add_replay_log")
+ @patch("ambari_server.setupMpacks.purge_stacks_and_mpacks")
+ @patch("ambari_server.setupMpacks.expand_mpack")
+ @patch("ambari_server.setupMpacks.download_mpack")
+ def test_install_addon_service_mpack(self, download_mpack_mock, expand_mpack_mock, purge_stacks_and_mpacks_mock,
+ add_replay_log_mock, get_ambari_properties_mock, get_ambari_version_mock,
+ create_symlink_mock, os_mkdir_mock, shutil_move_mock,os_symlink_mock,
+ os_path_isdir_mock, os_path_exists_mock):
+ options = self._create_empty_options_mock()
+ options.mpack_path = "/path/to/myservice.tar.gz"
+ options.purge = False
+ download_mpack_mock.return_value = "/tmp/myservice.tar.gz"
+ expand_mpack_mock.return_value = "mpacks/myservice-ambari-mpack-1.0.0.0"
+ get_ambari_version_mock.return_value = "2.4.0.0"
+ """
+ os_path_exists_calls = [call('/tmp/myservice.tar.gz'),
+ call('mpacks/myservice-ambari-mpack-1.0.0.0/mpack.json'),
+ call('/var/lib/ambari-server/resources/stacks/MYSTACK/1.0'),
+ call('/var/lib/ambari-server/resources/stacks'),
+ call('/var/lib/ambari-server/resources/common-services'),
+ call(mpacks_directory),
+ call(mpacks_directory + '/cache'),
+ call(mpacks_directory + '/myservice-ambari-mpack-1.0.0.0'),
+ call('/var/lib/ambari-server/resources/common-services/MYSERVICE'),
+ call('/var/lib/ambari-server/resources/stacks/MYSTACK'),
+ call('/var/lib/ambari-server/resources/stacks/MYSTACK/1.0'),
+ call('/var/lib/ambari-server/resources/stacks/MYSTACK/1.0/services'),
+ call('/var/lib/ambari-server/resources/stacks/MYSTACK'),
+ call('/var/lib/ambari-server/resources/stacks/MYSTACK/2.0'),
+ call('/var/lib/ambari-server/resources/stacks/MYSTACK/2.0/services')]
+ """
+ os_path_exists_mock.side_effect = [True, True, True, True, True,
+ True, True, False, False, True,
+ True, True, True, True, True]
+
+ get_ambari_properties_mock.return_value = configs
+ shutil_move_mock.return_value = True
+ os_path_isdir_mock.return_value = True
+
+ install_mpack(options)
+
+ stacks_directory = configs[STACK_LOCATION_KEY]
+ common_services_directory = configs[COMMON_SERVICES_PATH_PROPERTY]
+ mpacks_directory = configs[MPACKS_STAGING_PATH_PROPERTY]
+ mpacks_staging_directory = os.path.join(mpacks_directory, "myservice-ambari-mpack-1.0.0.0")
+
+ os_mkdir_calls = [
+ call(os.path.join(common_services_directory, "MYSERVICE"))
+ ]
+ os_symlink_calls = [
+ call(os.path.join(mpacks_staging_directory, "common-services/MYSERVICE/1.0.0"),
+ os.path.join(common_services_directory, "MYSERVICE/1.0.0")),
+ call(os.path.join(mpacks_staging_directory, "custom-services/MYSERVICE/1.0.0"),
+ os.path.join(stacks_directory, "MYSTACK/1.0/services/MYSERVICE")),
+ call(os.path.join(mpacks_staging_directory, "custom-services/MYSERVICE/2.0.0"),
+ os.path.join(stacks_directory, "MYSTACK/2.0/services/MYSERVICE"))
+ ]
+
+ self.assertFalse(purge_stacks_and_mpacks_mock.called)
+ os_mkdir_mock.assert_has_calls(os_mkdir_calls)
+ os_symlink_mock.assert_has_calls(os_symlink_calls)
+ self.assertTrue(add_replay_log_mock.called)
+
+ @patch("os.path.exists")
+ @patch("shutil.move")
+ @patch("os.mkdir")
+ @patch("ambari_server.setupMpacks.create_symlink")
+ @patch("ambari_server.setupMpacks.get_ambari_version")
+ @patch("ambari_server.setupMpacks.get_ambari_properties")
+ @patch("ambari_server.setupMpacks.add_replay_log")
+ @patch("ambari_server.setupMpacks.uninstall_mpack")
+ @patch("ambari_server.setupMpacks.purge_stacks_and_mpacks")
+ @patch("ambari_server.setupMpacks.expand_mpack")
+ @patch("ambari_server.setupMpacks.download_mpack")
+ def test_upgrade_stack_mpack(self, download_mpack_mock, expand_mpack_mock, purge_stacks_and_mpacks_mock,
+ uninstall_mpack_mock, add_replay_log_mock, get_ambari_properties_mock,
+ get_ambari_version_mock, create_symlink_mock, os_mkdir_mock, shutil_move_mock,
+ os_path_exists_mock):
+ options = self._create_empty_options_mock()
+ options.mpack_path = "/path/to/mystack-1.0.0.1.tar.gz"
+ download_mpack_mock.return_value = "/tmp/mystack-1.0.0.1.tar.gz"
+ expand_mpack_mock.return_value = "mpacks/mystack-ambari-mpack-1.0.0.1"
+ get_ambari_version_mock.return_value = "2.4.0.0"
+ """
+ os_path_exists_calls = [call('/tmp/mystack-1.0.0.1.tar.gz'),
+ call('mpacks/mystack-ambari-mpack-1.0.0.1/mpack.json'),
+ call('/var/lib/ambari-server/resources/stacks'),
+ call('/var/lib/ambari-server/resources/common-services'),
+ call(mpacks_directory),
+ call(mpacks_directory + '/cache'),
+ call(mpacks_directory + '/mystack-ambari-mpack-1.0.0.1'),
+ call('/var/lib/ambari-server/resources/common-services/SERVICEA'),
+ call('/var/lib/ambari-server/resources/common-services/SERVICEB'),
+ call('/var/lib/ambari-server/resources/common-services/SERVICEC'),
+ call('/var/lib/ambari-server/resources/stacks/MYSTACK'),
+ call('/var/lib/ambari-server/resources/stacks/MYSTACK/1.0'),
+ call('/var/lib/ambari-server/resources/stacks/MYSTACK/1.0/services'),
+ call('/var/lib/ambari-server/resources/stacks/MYSTACK/1.1'),
+ call('/var/lib/ambari-server/resources/stacks/MYSTACK/1.1/services'),
+ call('/var/lib/ambari-server/resources/stacks/MYSTACK/2.0'),
+ call('/var/lib/ambari-server/resources/stacks/MYSTACK/2.0/services')]
+ call('/var/lib/ambari-server/resources/stacks/MYSTACK/3.0'),
+ call('/var/lib/ambari-server/resources/stacks/MYSTACK/3.0/services'),
+ call(mpacks_directory),
+ call(mpacks_directory + '/myservice-ambari-mpack-1.0.0.0/mpack.json'),
+ call(mpacks_directory + '/mystack-ambari-mpack-1.0.0.0/mpack.json'),
+ call(mpacks_directory + '/mystack-ambari-mpack-1.0.0.1/mpack.json')]
+ """
+ os_path_exists_mock.side_effect = [True, True, True, True, True, True,
+ False, True, True, False, True, True, True,
+ True, True, True, True, False, False,
+ True, True, True, True]
+ get_ambari_properties_mock.return_value = configs
+ shutil_move_mock.return_value = True
+
+ upgrade_mpack(options)
+
+ stacks_directory = configs[STACK_LOCATION_KEY]
+ common_services_directory = configs[COMMON_SERVICES_PATH_PROPERTY]
+ mpacks_directory = configs[MPACKS_STAGING_PATH_PROPERTY]
+ mpacks_staging_directory = os.path.join(mpacks_directory, "mystack-ambari-mpack-1.0.0.1")
+
+
+ os_mkdir_calls = [
+ call(os.path.join(common_services_directory, "SERVICEC")),
+ call(os.path.join(stacks_directory, "MYSTACK/3.0")),
+ call(os.path.join(stacks_directory, "MYSTACK/3.0/services"))
+ ]
+ create_symlink_calls = [
+ call(os.path.join(mpacks_staging_directory, "common-services/SERVICEA"),
+ os.path.join(common_services_directory, "SERVICEA"),
+ "1.0", True),
+ call(os.path.join(mpacks_staging_directory, "common-services/SERVICEA"),
+ os.path.join(common_services_directory, "SERVICEA"),
+ "2.0", True),
+ call(os.path.join(mpacks_staging_directory, "common-services/SERVICEB"),
+ os.path.join(common_services_directory, "SERVICEB"),
+ "1.0.0", True),
+ call(os.path.join(mpacks_staging_directory, "common-services/SERVICEB"),
+ os.path.join(common_services_directory, "SERVICEB"),
+ "2.0.0", True),
+ call(os.path.join(mpacks_staging_directory, "common-services/SERVICEC"),
+ os.path.join(common_services_directory, "SERVICEC"),
+ "1.0.0", True),
+ call(os.path.join(mpacks_staging_directory, "common-services/SERVICEC"),
+ os.path.join(common_services_directory, "SERVICEC"),
+ "2.0.0", True),
+ call(os.path.join(mpacks_staging_directory, "stacks/MYSTACK/1.0"),
+ os.path.join(stacks_directory, "MYSTACK/1.0"),
+ "metainfo.xml", True),
+ call(os.path.join(mpacks_staging_directory, "stacks/MYSTACK/1.0/services"),
+ os.path.join(stacks_directory, "MYSTACK/1.0/services"),
+ "SERVICEA", True),
+ call(os.path.join(mpacks_staging_directory, "stacks/MYSTACK/1.1"),
+ os.path.join(stacks_directory, "MYSTACK/1.1"),
+ "metainfo.xml", True),
+ call(os.path.join(mpacks_staging_directory, "stacks/MYSTACK/1.1/services"),
+ os.path.join(stacks_directory, "MYSTACK/1.1/services"),
+ "SERVICEA", True),
+ call(os.path.join(mpacks_staging_directory, "stacks/MYSTACK/2.0"),
+ os.path.join(stacks_directory, "MYSTACK/2.0"),
+ "metainfo.xml", True),
+ call(os.path.join(mpacks_staging_directory, "stacks/MYSTACK/2.0/services"),
+ os.path.join(stacks_directory, "MYSTACK/2.0/services"),
+ "SERVICEA", True),
+ call(os.path.join(mpacks_staging_directory, "stacks/MYSTACK/2.0/services"),
+ os.path.join(stacks_directory, "MYSTACK/2.0/services"),
+ "SERVICEB", True),
+ call(os.path.join(mpacks_staging_directory, "stacks/MYSTACK/3.0"),
+ os.path.join(stacks_directory, "MYSTACK/3.0"),
+ "metainfo.xml", True),
+ call(os.path.join(mpacks_staging_directory, "stacks/MYSTACK/3.0/services"),
+ os.path.join(stacks_directory, "MYSTACK/3.0/services"),
+ "SERVICEA", True),
+ call(os.path.join(mpacks_staging_directory, "stacks/MYSTACK/3.0/services"),
+ os.path.join(stacks_directory, "MYSTACK/3.0/services"),
+ "SERVICEB", True),
+ call(os.path.join(mpacks_staging_directory, "stacks/MYSTACK/3.0/services"),
+ os.path.join(stacks_directory, "MYSTACK/3.0/services"),
+ "SERVICEC", True)
+ ]
+
+ self.assertFalse(purge_stacks_and_mpacks_mock.called)
+ os_mkdir_mock.assert_has_calls(os_mkdir_calls)
+ create_symlink_mock.assert_has_calls(create_symlink_calls)
+ uninstall_mpack_mock.assert_has_calls([call("mystack-ambari-mpack", "1.0.0.0")])
+ self.assertTrue(add_replay_log_mock.called)
+
+
+ @patch("os.path.exists")
+ @patch("ambari_server.setupMpacks.get_replay_log_file")
+ @patch("ambari_server.setupMpacks.upgrade_mpack")
+ @patch("ambari_server.setupMpacks.install_mpack")
+ def test_replay_mpack_logs(self, install_mpack_mock, upgrade_mpack_mock, get_replay_log_file_mock, os_path_exists_mock):
+ test_directory = os.path.dirname(os.path.abspath(__file__))
+ resources_directory = os.path.join(test_directory, os.pardir, "resources")
+ get_replay_log_file_mock.return_value = os.path.join(resources_directory, "mpacks_replay.log")
+ os_path_exists_mock.return_value = True
+
+ replay_mpack_logs()
+
+ install_replay_options = {
+ 'purge' : True,
+ 'mpack_command' : 'install-mpack',
+ 'mpack_path': '/var/lib/ambari-server/resources/mpacks/cache/hdp-1.0.0.0.tar.gz',
+ 'force': False,
+ 'verbose': True
+ }
+
+ upgrade_replay_options = {
+ 'purge' : False,
+ 'mpack_command' : 'upgrade-mpack',
+ 'mpack_path': '/var/lib/ambari-server/resources/mpacks/cache/hdp-1.0.0.1.tar.gz',
+ 'force': True,
+ 'verbose': True
+ }
+
+ install_mpack_mock.assert_has_calls([call(install_replay_options, replay_mode=True)])
+ upgrade_mpack_mock.assert_has_calls([call(upgrade_replay_options, replay_mode=True)])
+
+ def _create_empty_options_mock(self):
+ options = MagicMock()
+ options.mpack_path = None
+ options.purge = None
+ options.force = None
+ options.verbose = None
+ return options
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/5dddc529/ambari-server/src/test/python/mpacks/myservice-ambari-mpack-1.0.0.0/common-services/MYSERVICE/1.0.0/metainfo.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/python/mpacks/myservice-ambari-mpack-1.0.0.0/common-services/MYSERVICE/1.0.0/metainfo.xml b/ambari-server/src/test/python/mpacks/myservice-ambari-mpack-1.0.0.0/common-services/MYSERVICE/1.0.0/metainfo.xml
new file mode 100644
index 0000000..7c20d4a
--- /dev/null
+++ b/ambari-server/src/test/python/mpacks/myservice-ambari-mpack-1.0.0.0/common-services/MYSERVICE/1.0.0/metainfo.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<metainfo></metainfo>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/5dddc529/ambari-server/src/test/python/mpacks/myservice-ambari-mpack-1.0.0.0/custom-services/MYSERVICE/1.0.0/metainfo.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/python/mpacks/myservice-ambari-mpack-1.0.0.0/custom-services/MYSERVICE/1.0.0/metainfo.xml b/ambari-server/src/test/python/mpacks/myservice-ambari-mpack-1.0.0.0/custom-services/MYSERVICE/1.0.0/metainfo.xml
new file mode 100644
index 0000000..7c20d4a
--- /dev/null
+++ b/ambari-server/src/test/python/mpacks/myservice-ambari-mpack-1.0.0.0/custom-services/MYSERVICE/1.0.0/metainfo.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<metainfo></metainfo>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/5dddc529/ambari-server/src/test/python/mpacks/myservice-ambari-mpack-1.0.0.0/custom-services/MYSERVICE/2.0.0/metainfo.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/python/mpacks/myservice-ambari-mpack-1.0.0.0/custom-services/MYSERVICE/2.0.0/metainfo.xml b/ambari-server/src/test/python/mpacks/myservice-ambari-mpack-1.0.0.0/custom-services/MYSERVICE/2.0.0/metainfo.xml
new file mode 100644
index 0000000..7c20d4a
--- /dev/null
+++ b/ambari-server/src/test/python/mpacks/myservice-ambari-mpack-1.0.0.0/custom-services/MYSERVICE/2.0.0/metainfo.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<metainfo></metainfo>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/5dddc529/ambari-server/src/test/python/mpacks/myservice-ambari-mpack-1.0.0.0/mpack.json
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/python/mpacks/myservice-ambari-mpack-1.0.0.0/mpack.json b/ambari-server/src/test/python/mpacks/myservice-ambari-mpack-1.0.0.0/mpack.json
new file mode 100644
index 0000000..faade4a
--- /dev/null
+++ b/ambari-server/src/test/python/mpacks/myservice-ambari-mpack-1.0.0.0/mpack.json
@@ -0,0 +1,50 @@
+{
+ "type" : "full-release",
+ "name" : "myservice-ambari-mpack",
+ "version": "1.0.0.0",
+ "description" : "MyService Management Pack",
+ "prerequisites": {
+ "min_ambari_version" : "2.4.0.0",
+ "min_stack_versions" : [
+ {
+ "stack_name" : "MYSTACK",
+ "stack_version" : "1.0"
+ }
+ ]
+ },
+ "artifacts": [
+ {
+ "name" : "MYSERVICE-service-definition",
+ "type" : "service-definition",
+ "source_dir" : "common-services/MYSERVICE/1.0.0",
+ "service_name" : "MYSERVICE",
+ "service_version" : "1.0.0"
+ },
+ {
+ "name" : "MYSERVICE-1.0.0",
+ "type" : "stack-extension-definition",
+ "source_dir": "custom-services/MYSERVICE/1.0.0",
+ "service_name" : "MYSERVICE",
+ "service_version" : "1.0.0",
+ "applicable_stacks" : [
+ {
+ "stack_name" : "MYSTACK",
+ "stack_version" : "1.0"
+ }
+ ]
+ },
+ {
+ "name" : "MYSERVICE-2.0.0",
+ "type" : "stack-extension-definition",
+ "source_dir": "custom-services/MYSERVICE/2.0.0",
+ "service_name" : "MYSERVICE",
+ "service_version" : "2.0.0",
+ "applicable_stacks" : [
+ {
+ "stack_name" : "MYSTACK",
+ "stack_version" : "2.0"
+ }
+ ]
+ }
+ ]
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/5dddc529/ambari-server/src/test/python/mpacks/mystack-ambari-mpack-1.0.0.0/common-services/SERVICEA/1.0/metainfo.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/python/mpacks/mystack-ambari-mpack-1.0.0.0/common-services/SERVICEA/1.0/metainfo.xml b/ambari-server/src/test/python/mpacks/mystack-ambari-mpack-1.0.0.0/common-services/SERVICEA/1.0/metainfo.xml
new file mode 100644
index 0000000..7c20d4a
--- /dev/null
+++ b/ambari-server/src/test/python/mpacks/mystack-ambari-mpack-1.0.0.0/common-services/SERVICEA/1.0/metainfo.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<metainfo></metainfo>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/5dddc529/ambari-server/src/test/python/mpacks/mystack-ambari-mpack-1.0.0.0/common-services/SERVICEA/2.0/metainfo.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/python/mpacks/mystack-ambari-mpack-1.0.0.0/common-services/SERVICEA/2.0/metainfo.xml b/ambari-server/src/test/python/mpacks/mystack-ambari-mpack-1.0.0.0/common-services/SERVICEA/2.0/metainfo.xml
new file mode 100644
index 0000000..7c20d4a
--- /dev/null
+++ b/ambari-server/src/test/python/mpacks/mystack-ambari-mpack-1.0.0.0/common-services/SERVICEA/2.0/metainfo.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<metainfo></metainfo>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/5dddc529/ambari-server/src/test/python/mpacks/mystack-ambari-mpack-1.0.0.0/common-services/SERVICEB/1.0.0/metainfo.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/python/mpacks/mystack-ambari-mpack-1.0.0.0/common-services/SERVICEB/1.0.0/metainfo.xml b/ambari-server/src/test/python/mpacks/mystack-ambari-mpack-1.0.0.0/common-services/SERVICEB/1.0.0/metainfo.xml
new file mode 100644
index 0000000..7c20d4a
--- /dev/null
+++ b/ambari-server/src/test/python/mpacks/mystack-ambari-mpack-1.0.0.0/common-services/SERVICEB/1.0.0/metainfo.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<metainfo></metainfo>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/5dddc529/ambari-server/src/test/python/mpacks/mystack-ambari-mpack-1.0.0.0/common-services/SERVICEB/2.0.0/metainfo.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/python/mpacks/mystack-ambari-mpack-1.0.0.0/common-services/SERVICEB/2.0.0/metainfo.xml b/ambari-server/src/test/python/mpacks/mystack-ambari-mpack-1.0.0.0/common-services/SERVICEB/2.0.0/metainfo.xml
new file mode 100644
index 0000000..7c20d4a
--- /dev/null
+++ b/ambari-server/src/test/python/mpacks/mystack-ambari-mpack-1.0.0.0/common-services/SERVICEB/2.0.0/metainfo.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<metainfo></metainfo>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/5dddc529/ambari-server/src/test/python/mpacks/mystack-ambari-mpack-1.0.0.0/mpack.json
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/python/mpacks/mystack-ambari-mpack-1.0.0.0/mpack.json b/ambari-server/src/test/python/mpacks/mystack-ambari-mpack-1.0.0.0/mpack.json
new file mode 100644
index 0000000..d987142
--- /dev/null
+++ b/ambari-server/src/test/python/mpacks/mystack-ambari-mpack-1.0.0.0/mpack.json
@@ -0,0 +1,21 @@
+{
+ "type" : "full-release",
+ "name" : "mystack-ambari-mpack",
+ "version": "1.0.0.0",
+ "description" : "HDP Management Pack",
+ "prerequisites": {
+ "min_ambari_version" : "2.4.0.0"
+ },
+ "artifacts": [
+ {
+ "name" : "mystack-service-definitions",
+ "type" : "service-definitions",
+ "source_dir": "common-services"
+ },
+ {
+ "name" : "mystack-stack-definitions",
+ "type" : "stack-definitions",
+ "source_dir": "stacks"
+ }
+ ]
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/5dddc529/ambari-server/src/test/python/mpacks/mystack-ambari-mpack-1.0.0.0/stacks/MYSTACK/1.0/metainfo.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/python/mpacks/mystack-ambari-mpack-1.0.0.0/stacks/MYSTACK/1.0/metainfo.xml b/ambari-server/src/test/python/mpacks/mystack-ambari-mpack-1.0.0.0/stacks/MYSTACK/1.0/metainfo.xml
new file mode 100644
index 0000000..7c20d4a
--- /dev/null
+++ b/ambari-server/src/test/python/mpacks/mystack-ambari-mpack-1.0.0.0/stacks/MYSTACK/1.0/metainfo.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<metainfo></metainfo>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/5dddc529/ambari-server/src/test/python/mpacks/mystack-ambari-mpack-1.0.0.0/stacks/MYSTACK/1.0/services/SERVICEA/metainfo.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/python/mpacks/mystack-ambari-mpack-1.0.0.0/stacks/MYSTACK/1.0/services/SERVICEA/metainfo.xml b/ambari-server/src/test/python/mpacks/mystack-ambari-mpack-1.0.0.0/stacks/MYSTACK/1.0/services/SERVICEA/metainfo.xml
new file mode 100644
index 0000000..7c20d4a
--- /dev/null
+++ b/ambari-server/src/test/python/mpacks/mystack-ambari-mpack-1.0.0.0/stacks/MYSTACK/1.0/services/SERVICEA/metainfo.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<metainfo></metainfo>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/5dddc529/ambari-server/src/test/python/mpacks/mystack-ambari-mpack-1.0.0.0/stacks/MYSTACK/1.1/metainfo.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/python/mpacks/mystack-ambari-mpack-1.0.0.0/stacks/MYSTACK/1.1/metainfo.xml b/ambari-server/src/test/python/mpacks/mystack-ambari-mpack-1.0.0.0/stacks/MYSTACK/1.1/metainfo.xml
new file mode 100644
index 0000000..7c20d4a
--- /dev/null
+++ b/ambari-server/src/test/python/mpacks/mystack-ambari-mpack-1.0.0.0/stacks/MYSTACK/1.1/metainfo.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<metainfo></metainfo>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/5dddc529/ambari-server/src/test/python/mpacks/mystack-ambari-mpack-1.0.0.0/stacks/MYSTACK/1.1/services/SERVICEA/metainfo.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/python/mpacks/mystack-ambari-mpack-1.0.0.0/stacks/MYSTACK/1.1/services/SERVICEA/metainfo.xml b/ambari-server/src/test/python/mpacks/mystack-ambari-mpack-1.0.0.0/stacks/MYSTACK/1.1/services/SERVICEA/metainfo.xml
new file mode 100644
index 0000000..7c20d4a
--- /dev/null
+++ b/ambari-server/src/test/python/mpacks/mystack-ambari-mpack-1.0.0.0/stacks/MYSTACK/1.1/services/SERVICEA/metainfo.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<metainfo></metainfo>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/5dddc529/ambari-server/src/test/python/mpacks/mystack-ambari-mpack-1.0.0.0/stacks/MYSTACK/2.0/metainfo.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/python/mpacks/mystack-ambari-mpack-1.0.0.0/stacks/MYSTACK/2.0/metainfo.xml b/ambari-server/src/test/python/mpacks/mystack-ambari-mpack-1.0.0.0/stacks/MYSTACK/2.0/metainfo.xml
new file mode 100644
index 0000000..7c20d4a
--- /dev/null
+++ b/ambari-server/src/test/python/mpacks/mystack-ambari-mpack-1.0.0.0/stacks/MYSTACK/2.0/metainfo.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<metainfo></metainfo>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/5dddc529/ambari-server/src/test/python/mpacks/mystack-ambari-mpack-1.0.0.0/stacks/MYSTACK/2.0/services/SERVICEA/metainfo.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/python/mpacks/mystack-ambari-mpack-1.0.0.0/stacks/MYSTACK/2.0/services/SERVICEA/metainfo.xml b/ambari-server/src/test/python/mpacks/mystack-ambari-mpack-1.0.0.0/stacks/MYSTACK/2.0/services/SERVICEA/metainfo.xml
new file mode 100644
index 0000000..7c20d4a
--- /dev/null
+++ b/ambari-server/src/test/python/mpacks/mystack-ambari-mpack-1.0.0.0/stacks/MYSTACK/2.0/services/SERVICEA/metainfo.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<metainfo></metainfo>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/5dddc529/ambari-server/src/test/python/mpacks/mystack-ambari-mpack-1.0.0.0/stacks/MYSTACK/2.0/services/SERVICEB/metainfo.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/python/mpacks/mystack-ambari-mpack-1.0.0.0/stacks/MYSTACK/2.0/services/SERVICEB/metainfo.xml b/ambari-server/src/test/python/mpacks/mystack-ambari-mpack-1.0.0.0/stacks/MYSTACK/2.0/services/SERVICEB/metainfo.xml
new file mode 100644
index 0000000..7c20d4a
--- /dev/null
+++ b/ambari-server/src/test/python/mpacks/mystack-ambari-mpack-1.0.0.0/stacks/MYSTACK/2.0/services/SERVICEB/metainfo.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<metainfo></metainfo>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/5dddc529/ambari-server/src/test/python/mpacks/mystack-ambari-mpack-1.0.0.1/common-services/SERVICEA/1.0/metainfo.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/python/mpacks/mystack-ambari-mpack-1.0.0.1/common-services/SERVICEA/1.0/metainfo.xml b/ambari-server/src/test/python/mpacks/mystack-ambari-mpack-1.0.0.1/common-services/SERVICEA/1.0/metainfo.xml
new file mode 100644
index 0000000..7c20d4a
--- /dev/null
+++ b/ambari-server/src/test/python/mpacks/mystack-ambari-mpack-1.0.0.1/common-services/SERVICEA/1.0/metainfo.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<metainfo></metainfo>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/5dddc529/ambari-server/src/test/python/mpacks/mystack-ambari-mpack-1.0.0.1/common-services/SERVICEA/2.0/metainfo.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/python/mpacks/mystack-ambari-mpack-1.0.0.1/common-services/SERVICEA/2.0/metainfo.xml b/ambari-server/src/test/python/mpacks/mystack-ambari-mpack-1.0.0.1/common-services/SERVICEA/2.0/metainfo.xml
new file mode 100644
index 0000000..7c20d4a
--- /dev/null
+++ b/ambari-server/src/test/python/mpacks/mystack-ambari-mpack-1.0.0.1/common-services/SERVICEA/2.0/metainfo.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<metainfo></metainfo>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/5dddc529/ambari-server/src/test/python/mpacks/mystack-ambari-mpack-1.0.0.1/common-services/SERVICEB/1.0.0/metainfo.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/python/mpacks/mystack-ambari-mpack-1.0.0.1/common-services/SERVICEB/1.0.0/metainfo.xml b/ambari-server/src/test/python/mpacks/mystack-ambari-mpack-1.0.0.1/common-services/SERVICEB/1.0.0/metainfo.xml
new file mode 100644
index 0000000..7c20d4a
--- /dev/null
+++ b/ambari-server/src/test/python/mpacks/mystack-ambari-mpack-1.0.0.1/common-services/SERVICEB/1.0.0/metainfo.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<metainfo></metainfo>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/5dddc529/ambari-server/src/test/python/mpacks/mystack-ambari-mpack-1.0.0.1/common-services/SERVICEB/2.0.0/metainfo.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/python/mpacks/mystack-ambari-mpack-1.0.0.1/common-services/SERVICEB/2.0.0/metainfo.xml b/ambari-server/src/test/python/mpacks/mystack-ambari-mpack-1.0.0.1/common-services/SERVICEB/2.0.0/metainfo.xml
new file mode 100644
index 0000000..7c20d4a
--- /dev/null
+++ b/ambari-server/src/test/python/mpacks/mystack-ambari-mpack-1.0.0.1/common-services/SERVICEB/2.0.0/metainfo.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<metainfo></metainfo>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/5dddc529/ambari-server/src/test/python/mpacks/mystack-ambari-mpack-1.0.0.1/common-services/SERVICEC/1.0.0/metainfo.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/python/mpacks/mystack-ambari-mpack-1.0.0.1/common-services/SERVICEC/1.0.0/metainfo.xml b/ambari-server/src/test/python/mpacks/mystack-ambari-mpack-1.0.0.1/common-services/SERVICEC/1.0.0/metainfo.xml
new file mode 100644
index 0000000..7c20d4a
--- /dev/null
+++ b/ambari-server/src/test/python/mpacks/mystack-ambari-mpack-1.0.0.1/common-services/SERVICEC/1.0.0/metainfo.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<metainfo></metainfo>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/5dddc529/ambari-server/src/test/python/mpacks/mystack-ambari-mpack-1.0.0.1/common-services/SERVICEC/2.0.0/metainfo.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/python/mpacks/mystack-ambari-mpack-1.0.0.1/common-services/SERVICEC/2.0.0/metainfo.xml b/ambari-server/src/test/python/mpacks/mystack-ambari-mpack-1.0.0.1/common-services/SERVICEC/2.0.0/metainfo.xml
new file mode 100644
index 0000000..7c20d4a
--- /dev/null
+++ b/ambari-server/src/test/python/mpacks/mystack-ambari-mpack-1.0.0.1/common-services/SERVICEC/2.0.0/metainfo.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<metainfo></metainfo>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/5dddc529/ambari-server/src/test/python/mpacks/mystack-ambari-mpack-1.0.0.1/mpack.json
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/python/mpacks/mystack-ambari-mpack-1.0.0.1/mpack.json b/ambari-server/src/test/python/mpacks/mystack-ambari-mpack-1.0.0.1/mpack.json
new file mode 100644
index 0000000..e06efb8
--- /dev/null
+++ b/ambari-server/src/test/python/mpacks/mystack-ambari-mpack-1.0.0.1/mpack.json
@@ -0,0 +1,21 @@
+{
+ "type" : "full-release",
+ "name" : "mystack-ambari-mpack",
+ "version": "1.0.0.1",
+ "description" : "HDP Management Pack",
+ "prerequisites": {
+ "min_ambari_version" : "2.4.0.0"
+ },
+ "artifacts": [
+ {
+ "name" : "mystack-service-definitions",
+ "type" : "service-definitions",
+ "source_dir": "common-services"
+ },
+ {
+ "name" : "mystack-stack-definitions",
+ "type" : "stack-definitions",
+ "source_dir": "stacks"
+ }
+ ]
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/5dddc529/ambari-server/src/test/python/mpacks/mystack-ambari-mpack-1.0.0.1/stacks/MYSTACK/1.0/metainfo.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/python/mpacks/mystack-ambari-mpack-1.0.0.1/stacks/MYSTACK/1.0/metainfo.xml b/ambari-server/src/test/python/mpacks/mystack-ambari-mpack-1.0.0.1/stacks/MYSTACK/1.0/metainfo.xml
new file mode 100644
index 0000000..7c20d4a
--- /dev/null
+++ b/ambari-server/src/test/python/mpacks/mystack-ambari-mpack-1.0.0.1/stacks/MYSTACK/1.0/metainfo.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<metainfo></metainfo>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/5dddc529/ambari-server/src/test/python/mpacks/mystack-ambari-mpack-1.0.0.1/stacks/MYSTACK/1.0/services/SERVICEA/metainfo.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/python/mpacks/mystack-ambari-mpack-1.0.0.1/stacks/MYSTACK/1.0/services/SERVICEA/metainfo.xml b/ambari-server/src/test/python/mpacks/mystack-ambari-mpack-1.0.0.1/stacks/MYSTACK/1.0/services/SERVICEA/metainfo.xml
new file mode 100644
index 0000000..7c20d4a
--- /dev/null
+++ b/ambari-server/src/test/python/mpacks/mystack-ambari-mpack-1.0.0.1/stacks/MYSTACK/1.0/services/SERVICEA/metainfo.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<metainfo></metainfo>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/5dddc529/ambari-server/src/test/python/mpacks/mystack-ambari-mpack-1.0.0.1/stacks/MYSTACK/1.1/metainfo.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/python/mpacks/mystack-ambari-mpack-1.0.0.1/stacks/MYSTACK/1.1/metainfo.xml b/ambari-server/src/test/python/mpacks/mystack-ambari-mpack-1.0.0.1/stacks/MYSTACK/1.1/metainfo.xml
new file mode 100644
index 0000000..7c20d4a
--- /dev/null
+++ b/ambari-server/src/test/python/mpacks/mystack-ambari-mpack-1.0.0.1/stacks/MYSTACK/1.1/metainfo.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<metainfo></metainfo>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/5dddc529/ambari-server/src/test/python/mpacks/mystack-ambari-mpack-1.0.0.1/stacks/MYSTACK/1.1/services/SERVICEA/metainfo.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/python/mpacks/mystack-ambari-mpack-1.0.0.1/stacks/MYSTACK/1.1/services/SERVICEA/metainfo.xml b/ambari-server/src/test/python/mpacks/mystack-ambari-mpack-1.0.0.1/stacks/MYSTACK/1.1/services/SERVICEA/metainfo.xml
new file mode 100644
index 0000000..7c20d4a
--- /dev/null
+++ b/ambari-server/src/test/python/mpacks/mystack-ambari-mpack-1.0.0.1/stacks/MYSTACK/1.1/services/SERVICEA/metainfo.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<metainfo></metainfo>
\ No newline at end of file