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 2017/09/11 15:29:02 UTC

ambari git commit: AMBARI-21918: Mpack Generator Tool to generate mpack from stack definition (jluniya)

Repository: ambari
Updated Branches:
  refs/heads/branch-feature-AMBARI-14714 baa12055b -> 6f8d546aa


AMBARI-21918: Mpack Generator Tool to generate mpack from stack definition (jluniya)


Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/6f8d546a
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/6f8d546a
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/6f8d546a

Branch: refs/heads/branch-feature-AMBARI-14714
Commit: 6f8d546aab3a723923501dafac634cf27ce5b7fd
Parents: baa1205
Author: Jayush Luniya <jl...@hortonworks.com>
Authored: Mon Sep 11 08:28:57 2017 -0700
Committer: Jayush Luniya <jl...@hortonworks.com>
Committed: Mon Sep 11 08:28:57 2017 -0700

----------------------------------------------------------------------
 .../server/api/services/AmbariMetaInfo.java     |   2 +-
 .../controller/AmbariManagementController.java  |   3 +-
 .../AmbariManagementControllerImpl.java         |   2 +-
 .../internal/MpackResourceProvider.java         |   5 +-
 .../ambari/server/mpack/MpackGenerator.java     | 560 +++++++++++++++++++
 .../ambari/server/mpack/MpackManager.java       |  12 +-
 .../server/stack/CommonServiceDirectory.java    |   3 +-
 .../ambari/server/stack/ServiceDirectory.java   |   2 +-
 .../ambari/server/stack/ServiceModule.java      |   2 +-
 .../ambari/server/stack/StackManager.java       |  29 +-
 .../apache/ambari/server/stack/StackModule.java |   4 +-
 .../ambari/server/state/AutoDeployInfo.java     |   4 +
 .../ambari/server/state/ComponentInfo.java      |   2 +
 .../ambari/server/state/DependencyInfo.java     |   7 +-
 .../org/apache/ambari/server/state/Mpack.java   |  41 +-
 .../apache/ambari/server/state/ServiceInfo.java |  37 +-
 .../state/repository/ManifestServiceInfo.java   |   8 +
 .../state/repository/VersionDefinitionXml.java  |  14 +
 .../server/state/stack/ConfigurationXml.java    |  11 +
 .../server/state/stack/StackMetainfoXml.java    |  22 +-
 .../AMBARI_INFRA/0.1.0/service_advisor.py       |   2 +-
 .../ATLAS/0.7.0.3.0/service_advisor.py          |   2 +-
 .../HAWQ/2.0.0/service_advisor.py               |   2 +-
 .../HBASE/2.0.0.3.0/service_advisor.py          |   2 +-
 .../HDFS/3.0.0.3.0/service_advisor.py           |   2 +-
 .../HIVE/2.1.0.3.0/service_advisor.py           |   2 +-
 .../KAFKA/0.10.0.3.0/service_advisor.py         |   2 +-
 .../KNOX/0.5.0.3.0/service_advisor.py           |   2 +-
 .../LOGSEARCH/0.5.0/service_advisor.py          |   2 +-
 .../OOZIE/4.2.0.3.0/service_advisor.py          |   2 +-
 .../PIG/0.16.1.3.0/service_advisor.py           |   2 +-
 .../PXF/3.0.0/service_advisor.py                |   2 +-
 .../RANGER/1.0.0.3.0/service_advisor.py         |   2 +-
 .../RANGER_KMS/1.0.0.3.0/service_advisor.py     |   2 +-
 .../SLIDER/0.91.0.3.0/service_advisor.py        |   2 +-
 .../SPARK/2.2.0/service_advisor.py              |   2 +-
 .../SQOOP/1.4.4.3.0/service_advisor.py          |   2 +-
 .../STORM/1.0.1.3.0/service_advisor.py          |   2 +-
 .../TEZ/0.9.0.3.0/service_advisor.py            |   2 +-
 .../YARN/3.0.0.3.0/service_advisor.py           |   2 +-
 .../ZEPPELIN/0.6.0.3.0/service_advisor.py       |   2 +-
 .../ZOOKEEPER/3.4.9/service_advisor.py          |   2 +-
 .../src/main/resources/scripts/stack_advisor.py |   6 +
 .../stacks/HDP/2.1/services/stack_advisor.py    |   6 +
 .../stacks/HDP/2.2/services/stack_advisor.py    |   6 +
 .../stacks/HDP/2.3/services/stack_advisor.py    |   6 +
 .../stacks/HDP/2.4/services/stack_advisor.py    |   5 +
 .../stacks/HDP/2.5/services/stack_advisor.py    |   5 +
 .../stacks/HDP/2.6/services/stack_advisor.py    |   5 +
 49 files changed, 791 insertions(+), 62 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/6f8d546a/ambari-server/src/main/java/org/apache/ambari/server/api/services/AmbariMetaInfo.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/AmbariMetaInfo.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/AmbariMetaInfo.java
index 895fc09..843b032 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/api/services/AmbariMetaInfo.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/services/AmbariMetaInfo.java
@@ -655,7 +655,7 @@ public class AmbariMetaInfo {
    * @param mpackId
    * @return List of Packlets.
    */
-  public ArrayList<Packlet> getPacklets(Long mpackId) {
+  public List<Packlet> getPacklets(Long mpackId) {
     return mpackManager.getPacklets(mpackId);
   }
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/6f8d546a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementController.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementController.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementController.java
index 9613280..f2c4c52 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementController.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementController.java
@@ -19,7 +19,6 @@
 package org.apache.ambari.server.controller;
 
 import java.io.IOException;
-import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
 import java.util.Map;
@@ -961,7 +960,7 @@ public interface AmbariManagementController {
    * @param mpackId
    * @return List of packlets
    */
-  ArrayList<Packlet> getPacklets(Long mpackId);
+  List<Packlet> getPacklets(Long mpackId);
 
   /**
    * Get the software registries identified by the given request objects.

http://git-wip-us.apache.org/repos/asf/ambari/blob/6f8d546a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java
index 68f9b04..96e86cc 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java
@@ -572,7 +572,7 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle
   }
 
   @Override
-  public ArrayList<Packlet> getPacklets(Long mpackId) {
+  public List<Packlet> getPacklets(Long mpackId) {
     return ambariMetaInfo.getPacklets(mpackId);
   }
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/6f8d546a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/MpackResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/MpackResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/MpackResourceProvider.java
index 68a8e24..94b5fdf 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/MpackResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/MpackResourceProvider.java
@@ -21,7 +21,6 @@ import java.io.IOException;
 import java.net.ConnectException;
 import java.net.URI;
 import java.net.URL;
-import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.HashMap;
@@ -293,8 +292,8 @@ public class MpackResourceProvider extends AbstractControllerResourceProvider {
           resource.setProperty(MPACK_URI, entity.getMpackUri());
           resource.setProperty(REGISTRY_ID, entity.getRegistryId());
 
-          ArrayList<Packlet> packletArrayList = getManagementController().getPacklets(entity.getMpackId());
-          resource.setProperty(PACKLETS, packletArrayList);
+          List<Packlet> packlets = getManagementController().getPacklets(entity.getMpackId());
+          resource.setProperty(PACKLETS, packlets);
           results.add(resource);
         }
       }

http://git-wip-us.apache.org/repos/asf/ambari/blob/6f8d546a/ambari-server/src/main/java/org/apache/ambari/server/mpack/MpackGenerator.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/mpack/MpackGenerator.java b/ambari-server/src/main/java/org/apache/ambari/server/mpack/MpackGenerator.java
new file mode 100644
index 0000000..f7654ca
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/mpack/MpackGenerator.java
@@ -0,0 +1,560 @@
+/**
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.
+ */
+package org.apache.ambari.server.mpack;
+
+import java.io.BufferedOutputStream;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.net.URL;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.StandardCopyOption;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.Marshaller;
+
+import org.apache.ambari.server.api.services.AmbariMetaInfo;
+import org.apache.ambari.server.stack.ServiceDirectory;
+import org.apache.ambari.server.stack.StackManager;
+import org.apache.ambari.server.state.Mpack;
+import org.apache.ambari.server.state.Packlet;
+import org.apache.ambari.server.state.PropertyInfo;
+import org.apache.ambari.server.state.QuickLinksConfigurationInfo;
+import org.apache.ambari.server.state.ServiceInfo;
+import org.apache.ambari.server.state.StackId;
+import org.apache.ambari.server.state.StackInfo;
+import org.apache.ambari.server.state.ThemeInfo;
+import org.apache.ambari.server.state.quicklinks.QuickLinks;
+import org.apache.ambari.server.state.repository.ManifestServiceInfo;
+import org.apache.ambari.server.state.repository.VersionDefinitionXml;
+import org.apache.ambari.server.state.stack.ConfigurationXml;
+import org.apache.ambari.server.state.stack.RepositoryXml;
+import org.apache.ambari.server.state.stack.ServiceMetainfoXml;
+import org.apache.ambari.server.state.stack.StackMetainfoXml;
+import org.apache.ambari.server.state.stack.StackRoleCommandOrder;
+import org.apache.ambari.server.state.theme.Theme;
+import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
+import org.apache.commons.compress.archivers.tar.TarArchiveOutputStream;
+import org.apache.commons.compress.compressors.gzip.GzipCompressorOutputStream;
+import org.apache.commons.compress.utils.IOUtils;
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.lang.StringUtils;
+import org.codehaus.jackson.map.ObjectMapper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+
+/**
+ * Generate management pack from stack definition
+ */
+public class MpackGenerator {
+  private static final Logger LOG = LoggerFactory.getLogger
+    (MpackGenerator.class);
+
+  private static final ObjectMapper mapper = new ObjectMapper();
+  private File commonServicesRoot;
+  private File stackRoot;
+  private File mpacksRoot;
+  private StackId srcStackId;
+  private StackId dstStackId;
+  private StackManager stackManager;
+  private VersionDefinitionXml vdf;
+  private Gson gson = new GsonBuilder().setPrettyPrinting().create();
+
+  /**
+   * {@link MpackGenerator} constructor
+   * @param stackRoot           Stack root directory
+   * @param commonServicesRoot  Common services root directory
+   * @param srcStackId          Source stack id
+   * @param vdfUrl              Version Definition File
+   * @param mpacksRoot          Management pack root directory
+   * @throws Exception
+   */
+  public MpackGenerator(File stackRoot, File commonServicesRoot, StackId srcStackId, URL vdfUrl, File mpacksRoot)
+    throws Exception {
+    this.commonServicesRoot = commonServicesRoot;
+    this.stackRoot = stackRoot;
+    this.mpacksRoot = mpacksRoot;
+    this.srcStackId = srcStackId;
+    this.stackManager = new StackManager(stackRoot, commonServicesRoot, false);
+    this.vdf = VersionDefinitionXml.load(vdfUrl);
+    this.dstStackId = new StackId(vdf.release.stackId);
+  }
+
+  /**
+   * Generate management pack
+   * @throws Exception
+   */
+  public void generateMpack() throws Exception {
+    String dstStackName = dstStackId.getStackName();
+    String version = vdf.release.version;
+    String build = vdf.release.build;
+
+    System.out.println("===========================================================");
+    System.out.println("Source Stack Id: " + srcStackId);
+    System.out.println("Destination Stack Id: " + dstStackId);
+    System.out.println("===========================================================");
+
+    String mpackName = dstStackName.toLowerCase() + "-ambari-mpack" + "-" + version + "-" + build;
+    File mpackRootDir = new File(mpacksRoot.getAbsolutePath() + File.separator + mpackName);
+    if (!mpacksRoot.exists()) {
+      mpacksRoot.mkdirs();
+    }
+    if (mpackRootDir.exists()) {
+      FileUtils.deleteDirectory(mpackRootDir);
+    }
+    mpackRootDir.mkdir();
+
+    File mpackPackletsDir = new File(mpackRootDir.getAbsolutePath() + File.separator + "packlets");
+    if (mpackPackletsDir.exists()) {
+      mpackPackletsDir.delete();
+    }
+    mpackPackletsDir.mkdir();
+
+    StackInfo srcStackInfo = stackManager.getStack(srcStackId.getStackName(), srcStackId.getStackVersion());
+    StackRoleCommandOrder stackRoleCommandOrder = srcStackInfo.getRoleCommandOrder();
+    FileWriter stackRCOFile = new FileWriter(
+      mpackRootDir.getAbsolutePath() + File.separator + AmbariMetaInfo.RCO_FILE_NAME);
+    mapper.writerWithDefaultPrettyPrinter().writeValue(stackRCOFile, stackRoleCommandOrder.getContent());
+
+    // Export stack configs
+    File stackConfigDir = new File(
+      mpackRootDir.getAbsolutePath() + File.separator + AmbariMetaInfo.SERVICE_CONFIG_FOLDER_NAME);
+    exportConfigs(srcStackInfo.getProperties(), stackConfigDir);
+
+    // Export widgets.json
+    exportFile(new File(srcStackInfo.getWidgetsDescriptorFileLocation()), mpackRootDir);
+
+    // Export kerberos.json
+    exportFile(new File(srcStackInfo.getKerberosDescriptorFileLocation()), mpackRootDir);
+
+    // Export repoinfo.xml
+    RepositoryXml repositoryXml =  srcStackInfo.getRepositoryXml();
+    JAXBContext ctx = JAXBContext.newInstance(RepositoryXml.class);
+    Marshaller marshaller = ctx.createMarshaller();
+    marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
+    File reposDir = new File(mpackRootDir.getAbsolutePath() + File.separator + "repos");
+    if (!reposDir.exists()) {
+      reposDir.mkdir();
+    }
+    FileOutputStream repoXmlFileStream = new FileOutputStream(
+      reposDir.getAbsolutePath() + File.separator + "repoinfo.xml");
+    marshaller.marshal(repositoryXml, repoXmlFileStream);
+    repoXmlFileStream.flush();
+    repoXmlFileStream.close();
+
+    // Copy JSON cluster property files (example: stacks/HDP/2.0.6/properties/stack_tools.json)
+    File destPropertiesDir = new File(mpackRootDir.getAbsoluteFile() + File.separator + "properties");
+    if(!destPropertiesDir.exists()) {
+      destPropertiesDir.mkdir();
+    }
+    String srcStackName = srcStackId.getStackName();
+    String currentStackVersion = srcStackId.getStackVersion();
+
+    while (!StringUtils.isEmpty(currentStackVersion)) {
+      StackInfo currentStackInfo = stackManager.getStack(srcStackName, currentStackVersion);
+      File srcPropertiesDir = new File(stackRoot.getAbsolutePath() + File.separator + srcStackName + File.separator + currentStackVersion + File.separator + "properties");
+      if (srcPropertiesDir.exists() && srcPropertiesDir.isDirectory()) {
+        for (File srcPropertiesFile : srcPropertiesDir.listFiles()) {
+          File destPropertiesFile = new File(destPropertiesDir.getAbsolutePath() + File.separator + srcPropertiesFile.getName());
+          if (!destPropertiesFile.exists()) {
+            FileUtils.copyFile(srcPropertiesFile, destPropertiesFile);
+          }
+        }
+      }
+      currentStackVersion = currentStackInfo.getParentStackVersion();
+    }
+
+    // Copy stack hooks folder
+    String srcStackHooksFolder = srcStackInfo.getStackHooksFolder();
+    srcStackHooksFolder = stackRoot.getAbsolutePath() + File.separator + srcStackHooksFolder;
+    File srcStackHooksFile = new File(srcStackHooksFolder);
+    if (srcStackHooksFile != null && srcStackHooksFile.exists()) {
+      File destStackHooksFile = new File(
+        mpackRootDir.getAbsolutePath() + File.separator
+          + srcStackHooksFile.getName());
+      FileUtils.copyDirectory(srcStackHooksFile, destStackHooksFile);
+    }
+
+    // Export stack metainfo.xml
+    String parentStackVersion = srcStackInfo.getParentStackVersion();
+    StackMetainfoXml stackMetainfoXml = new StackMetainfoXml();
+    stackMetainfoXml.setMinJdk(srcStackInfo.getMinJdk());
+    stackMetainfoXml.setMaxJdk(srcStackInfo.getMaxJdk());
+    StackMetainfoXml.Version ver = new StackMetainfoXml.Version();
+    ver.setActive(srcStackInfo.isActive());
+    stackMetainfoXml.setVersion(ver);
+    ctx = JAXBContext.newInstance(StackMetainfoXml.class);
+    marshaller = ctx.createMarshaller();
+    marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
+    FileOutputStream stackMetainfoFileStream = new FileOutputStream(
+      mpackRootDir.getAbsolutePath() + File.separator + "metainfo.xml");
+    marshaller.marshal(stackMetainfoXml, stackMetainfoFileStream);
+    stackMetainfoFileStream.flush();
+    stackMetainfoFileStream.close();
+
+    // Export stack advisors
+    File stackAdvisorsDir = new File(mpackRootDir.getAbsolutePath() + File.separator + "stack-advisor");
+    if(!stackAdvisorsDir.exists()) {
+      stackAdvisorsDir.mkdir();
+    }
+
+    currentStackVersion = srcStackId.getStackVersion();
+    String baseStackAdvisor = null;
+    String baseStackAdvisorModule = null;
+    while (!StringUtils.isEmpty(currentStackVersion)) {
+      // Copy all inherited stack advisors from source stack to "stack-advisor" folder
+      StackInfo currentStackInfo = stackManager.getStack(srcStackName, currentStackVersion);
+      File srcStackAdvisor = new File(stackRoot.getAbsolutePath() + File.separator + srcStackName + File.separator + currentStackVersion + File.separator + "services" + File.separator + "stack_advisor.py");
+      if(srcStackAdvisor.exists()) {
+        if(baseStackAdvisor == null) {
+          baseStackAdvisor = srcStackName.toUpperCase() + currentStackVersion.replace(".", "") + "StackAdvisor";
+          baseStackAdvisorModule = "stack_advisor_" + srcStackName.toLowerCase() + currentStackVersion.replace(".", "");
+        }
+        File dstStackAdvisor = new File(
+          stackAdvisorsDir.getAbsolutePath() + File.separator + "stack_advisor_" + srcStackName.toLowerCase()
+            + currentStackVersion.replace(".", "") + ".py");
+        FileUtils.copyFile(srcStackAdvisor, dstStackAdvisor);
+      }
+      currentStackVersion = currentStackInfo.getParentStackVersion();
+    }
+    if(baseStackAdvisor != null) {
+      File mpackServicesDir = new File(mpackRootDir.getAbsolutePath() + File.separator + "services");
+      if (!mpackServicesDir.exists()) {
+        mpackServicesDir.mkdir();
+      }
+      String mpackStackAdvisorName = dstStackId.getStackName().toUpperCase() + dstStackId.getStackVersion().replace(".", "") + "StackAdvisor";
+      if(baseStackAdvisor.equalsIgnoreCase(mpackStackAdvisorName)) {
+        // Use top level stack advisor from source stack as mpack stack advisor
+        String srcPath = stackAdvisorsDir.getAbsolutePath() + File.separator + baseStackAdvisorModule + ".py";
+        String dstPath = mpackServicesDir.getAbsolutePath() + File.separator + "stack_advisor.py";
+        Files.move(Paths.get(srcPath), Paths.get(dstPath));
+      } else {
+        // Create mpack stack advisor that inherits from top level stack advisor from source stack
+        FileWriter fileWriter = new FileWriter(
+          mpackServicesDir.getAbsolutePath() + File.separator + "stack_advisor.py");
+        BufferedWriter bw = new BufferedWriter(fileWriter);
+        bw.write("from " + baseStackAdvisorModule + " import *");
+        bw.newLine();
+        bw.write("class " + mpackStackAdvisorName + "(" + baseStackAdvisor + ")");
+        bw.newLine();
+        bw.write("  pass");
+        bw.newLine();
+        bw.flush();
+        fileWriter.flush();
+        bw.close();
+        fileWriter.close();
+      }
+    }
+
+    Mpack mpack = new Mpack();
+    mpack.setName(dstStackName);
+    mpack.setVersion(vdf.release.getFullVersion());
+    mpack.setStackId(dstStackId.getStackId());
+    mpack.setDescription(dstStackName + " Ambari Management Pack");
+    Map<String, String> prereqs = new HashMap<>();
+    prereqs.put("min-ambari-version", "3.0.0.0");
+    mpack.setPrerequisites(prereqs);
+    List<Packlet> packlets = new ArrayList<>();
+    mpack.setPacklets(packlets);
+
+    for (ManifestServiceInfo manifestServiceInfo : vdf.getStackServices(srcStackInfo, true /* skipMissingServices = true */)) {
+      ServiceInfo serviceInfo = srcStackInfo.getService(manifestServiceInfo.getName());
+      String serviceName = manifestServiceInfo.getName();
+      String serviceVersion = (String) manifestServiceInfo.getVersions().toArray()[0];
+      ServiceInfo clonedServiceInfo =  (ServiceInfo) serviceInfo.clone();
+      clonedServiceInfo.setVersion(serviceVersion);
+      clonedServiceInfo.setParent(null);
+      if (serviceInfo.getMetricsFile() != null) {
+        clonedServiceInfo.setMetricsFileName(serviceInfo.getMetricsFile().getName());
+      }
+      if( serviceInfo.getWidgetsDescriptorFile() != null) {
+        clonedServiceInfo.setWidgetsFileName(serviceInfo.getWidgetsDescriptorFile().getName());
+      }
+
+      System.out.println("Processing service=" + serviceInfo.getName() + ", version=" + serviceVersion);
+      System.out.println("Service Parent : " + serviceInfo.getParent());
+      String packletDirName = serviceName + "-packlet-" + serviceVersion;
+      String packletTarName = packletDirName + ".tar.gz";
+      File packletDir = new File(
+        mpackPackletsDir.getAbsolutePath() + File.separator + packletDirName);
+      if (!packletDir.exists()) {
+        packletDir.mkdir();
+      }
+      Packlet packlet = new Packlet();
+      packlet.setType(Packlet.PackletType.SERVICE_PACKLET);
+      packlet.setName(serviceName);
+      packlet.setVersion(serviceVersion);
+      packlet.setServiceId(serviceVersion);
+      packlet.setSourceLocation("packlets" + File.separator + packletTarName);
+      packlets.add(packlet);
+
+      // Export service metainfo.xml
+      ServiceMetainfoXml serviceMetainfoXml = new ServiceMetainfoXml();
+      serviceMetainfoXml.setSchemaVersion(clonedServiceInfo.getSchemaVersion());
+      List<ServiceInfo> serviceInfos = Collections.singletonList(clonedServiceInfo);
+      serviceMetainfoXml.setServices(serviceInfos);
+      ctx = JAXBContext.newInstance(ServiceMetainfoXml.class);
+      marshaller = ctx.createMarshaller();
+      marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
+      FileOutputStream serviceMetainfoFileStream = new FileOutputStream(
+        packletDir.getAbsolutePath() + File.separator + "metainfo.xml");
+      marshaller.marshal(serviceMetainfoXml, serviceMetainfoFileStream);
+      serviceMetainfoFileStream.flush();
+      serviceMetainfoFileStream.close();
+
+      // Export mertrics.json
+      File srcMetricsFile = serviceInfo.getMetricsFile();
+      exportFile(srcMetricsFile, packletDir);
+
+      // Export widgets.json
+      File srcWidgetsFile = serviceInfo.getWidgetsDescriptorFile();
+      exportFile(srcWidgetsFile, packletDir);
+
+      // Export alerts.json
+      File srcAlertsFile = serviceInfo.getAlertsFile();
+      exportFile(srcAlertsFile, packletDir);
+
+      // Export kerberos.json
+      File srcKerberosFile = serviceInfo.getKerberosDescriptorFile();
+      exportFile(srcKerberosFile, packletDir);
+
+      // Export quicklinks
+      for (Map.Entry<String, QuickLinksConfigurationInfo> entry : serviceInfo.getQuickLinksConfigurationsMap()
+        .entrySet()) {
+        QuickLinksConfigurationInfo quickLinksConfigurationInfo = entry.getValue();
+        String quickLinksFileName = quickLinksConfigurationInfo.getFileName();
+        for (Map.Entry<String, QuickLinks> quickLinksEntry : quickLinksConfigurationInfo
+          .getQuickLinksConfigurationMap().entrySet()) {
+          File quickLinksDir = new File(
+            packletDir.getAbsolutePath() + File.separator + serviceInfo
+              .getQuickLinksConfigurationsDir());
+          if (!quickLinksDir.exists()) {
+            quickLinksDir.mkdir();
+          }
+          FileWriter quickLinksFileWriter = new FileWriter(
+            quickLinksDir.getAbsolutePath() + File.separator + quickLinksFileName, true);
+          mapper.writerWithDefaultPrettyPrinter()
+            .writeValue(quickLinksFileWriter, quickLinksEntry.getValue());
+        }
+      }
+
+      // Export themes
+      for (Map.Entry<String, ThemeInfo> entry : serviceInfo.getThemesMap().entrySet()) {
+        ThemeInfo themeInfo = entry.getValue();
+        String themeFileName = themeInfo.getFileName();
+        for (Map.Entry<String, Theme> themeEntry : themeInfo.getThemeMap().entrySet()) {
+          File themesDir = new File(
+            packletDir.getAbsolutePath() + File.separator + serviceInfo.getThemesDir());
+          if (!themesDir.exists()) {
+            themesDir.mkdir();
+          }
+          FileWriter themesFileWriter = new FileWriter(
+            themesDir.getAbsolutePath() + File.separator + themeFileName, true);
+          mapper.writerWithDefaultPrettyPrinter().writeValue(themesFileWriter, themeEntry.getValue());
+        }
+      }
+
+      // Export package folder
+      String srcPackageFolder = serviceInfo.getServicePackageFolder();
+      if (srcPackageFolder.startsWith("common-services")) {
+        srcPackageFolder = srcPackageFolder
+          .replace("common-services", commonServicesRoot.getAbsolutePath());
+      } else {
+        srcPackageFolder = srcPackageFolder.replace("stacks", stackRoot.getAbsolutePath());
+      }
+      File srcPackageFile = new File(srcPackageFolder);
+      if (srcPackageFile != null && srcPackageFile.exists()) {
+        File destPackageFile = new File(
+          packletDir.getAbsolutePath() + File.separator
+            + ServiceDirectory.PACKAGE_FOLDER_NAME);
+        FileUtils.copyDirectory(srcPackageFile, destPackageFile);
+      }
+
+      // Export merged configs
+      File configDir = new File(
+        packletDir.getAbsolutePath() + File.separator + serviceInfo.getConfigDir());
+      exportConfigs(serviceInfo.getProperties(), configDir);
+
+      // Copy service advisor
+      File srcServiceAdvisor = serviceInfo.getAdvisorFile();
+      File destServiceAdvisor = new File(packletDir.getAbsolutePath() + File.separator + "service_advisor.py");
+      if(srcServiceAdvisor != null && srcServiceAdvisor.exists()) {
+        FileUtils.copyFile(srcServiceAdvisor, destServiceAdvisor);
+      }
+
+      // TODO: Export upgrade packs
+
+      // Create packlet tarball
+      createTarGzip(packletDir.getAbsolutePath());
+      if(packletDir.exists()) {
+        FileUtils.deleteDirectory(packletDir);
+      }
+    }
+
+    // Create mpack.json
+    String mpackFilePath = mpackRootDir.getAbsolutePath() + File.separator + "mpack.json";
+    FileWriter mpackFileWriter = new FileWriter(mpackFilePath);
+    gson.toJson(mpack, Mpack.class, mpackFileWriter);
+    mpackFileWriter.flush();
+    mpackFileWriter.close();
+
+    // Create mpack tarball
+    createTarGzip(mpackRootDir.getAbsolutePath());
+    if(mpackRootDir.exists()) {
+      FileUtils.deleteDirectory(mpackRootDir);
+    }
+  }
+
+  public static void exportFile(File srcFile, File destRootDir) throws Exception {
+    if (srcFile != null && srcFile.exists()) {
+      Path srcPath = Paths.get(srcFile.getAbsolutePath());
+      Path destPath = Paths.get(
+        destRootDir.getAbsolutePath() + File.separator + srcFile.getName());
+      Files.copy(srcPath, destPath, StandardCopyOption.COPY_ATTRIBUTES,
+        StandardCopyOption.REPLACE_EXISTING);
+    }
+  }
+
+  public void createTarGzip(String path) throws FileNotFoundException, IOException {
+    File file = new File(path);
+    if(!file.exists()) {
+      throw new FileNotFoundException(path + " does not exist");
+    }
+    String parentDirName = file.getParent();
+    String tarGzPath = parentDirName + File.separator + file.getName() + ".tar.gz";
+    // Delete existing tarball
+    File f = new File(tarGzPath);
+    if(f.exists()) {
+      f.delete();
+    }
+    FileOutputStream fOut = null;
+    BufferedOutputStream bOut = null;
+    GzipCompressorOutputStream gzOut = null;
+    TarArchiveOutputStream tOut = null;
+    try {
+      fOut = new FileOutputStream(new File(tarGzPath));
+      bOut = new BufferedOutputStream(fOut);
+      gzOut = new GzipCompressorOutputStream(bOut);
+      tOut = new TarArchiveOutputStream(gzOut);
+      addFileToTarGz(tOut, path, "");
+      System.out.println("Compressed " + path + " -> " + tarGzPath);
+    } finally {
+      if(tOut != null) {
+        tOut.finish();
+        tOut.close();
+      }
+      if(gzOut != null) {
+        gzOut.close();
+      }
+      if(bOut != null) {
+        bOut.close();
+      }
+      if(fOut != null) {
+        fOut.close();
+      }
+    }
+
+  }
+
+  private void addFileToTarGz(TarArchiveOutputStream tOut, String path, String base)
+    throws IOException
+  {
+    File f = new File(path);
+    String entryName = base + f.getName();
+    TarArchiveEntry tarEntry = new TarArchiveEntry(f, entryName);
+    tOut.putArchiveEntry(tarEntry);
+
+    if (f.isFile()) {
+      IOUtils.copy(new FileInputStream(f), tOut);
+      tOut.closeArchiveEntry();
+    } else {
+      tOut.closeArchiveEntry();
+      File[] children = f.listFiles();
+      if (children != null) {
+        for (File child : children) {
+          addFileToTarGz(tOut, child.getAbsolutePath(), entryName + "/");
+        }
+      }
+    }
+  }
+
+  public static void exportConfigs(List<PropertyInfo> properties, File configDir) throws Exception {
+    if (!configDir.exists()) {
+      configDir.mkdir();
+    }
+
+    Map<String, List<PropertyInfo>> configFilesMap = new HashMap<>();
+    for (PropertyInfo propertyInfo : properties) {
+      String fileName = propertyInfo.getFilename();
+      if (!configFilesMap.containsKey(fileName)) {
+        configFilesMap.put(fileName, new ArrayList<PropertyInfo>());
+      }
+      configFilesMap.get(fileName).add(propertyInfo);
+    }
+
+    for (Map.Entry<String, List<PropertyInfo>> entry : configFilesMap.entrySet()) {
+      String fileName = entry.getKey();
+      ConfigurationXml configXml = new ConfigurationXml();
+      configXml.setProperties(entry.getValue());
+      JAXBContext ctx = JAXBContext.newInstance(ConfigurationXml.class);
+      Marshaller marshaller = ctx.createMarshaller();
+      marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
+      FileOutputStream configFileStream = new FileOutputStream(
+        configDir.getAbsolutePath() + File.separator + fileName);
+      marshaller.marshal(configXml, configFileStream);
+      configFileStream.flush();
+      configFileStream.close();
+    }
+  }
+
+  /**
+   * Main method for generating mpack
+   * @param args
+   * @throws Exception
+   */
+  public static void main(String[] args) throws Exception {
+    System.out.println("Mpack Generator Started");
+    String stackDir = args[0];
+    String commonServicesDir = args[1];
+    String srcStack = args[2];
+    String vdfPath = args[3];
+    String mpacksDir = args[4];
+    MpackGenerator mpackGenerator = new MpackGenerator(
+      new File(stackDir),
+      new File(commonServicesDir),
+      new StackId(srcStack),
+      new URL(vdfPath),
+      new File(mpacksDir));
+    mpackGenerator.generateMpack();
+    System.out.println("Mpack Generator Finished");
+  }
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/6f8d546a/ambari-server/src/main/java/org/apache/ambari/server/mpack/MpackManager.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/mpack/MpackManager.java b/ambari-server/src/main/java/org/apache/ambari/server/mpack/MpackManager.java
index e475e96..80be404 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/mpack/MpackManager.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/mpack/MpackManager.java
@@ -28,7 +28,6 @@ import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.nio.file.StandardCopyOption;
-import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
@@ -243,9 +242,9 @@ public class MpackManager {
     if (!servicesDir.exists()) {
       servicesDir.mkdir();
     }
-    ArrayList<Packlet> packletArrayList = mpack.getPacklets();
+    List<Packlet> packlets = mpack.getPacklets();
 
-    for (Packlet packlet : packletArrayList) {
+    for (Packlet packlet : packlets) {
       if (packlet.getType() == Packlet.PackletType.SERVICE_PACKLET) {
         String packletSourceLocation = packlet.getSourceLocation();
         File serviceTargetDir = new File(servicesDir + File.separator + packlet.getName());
@@ -440,13 +439,14 @@ public class MpackManager {
    * Fetches the packlet info stored in the memory for mpacks/{mpack_id} call.
    *
    * @param mpackId
-   * @return ArrayList
+   * @return list of {@link Packlet}
    */
-  public ArrayList<Packlet> getPacklets(Long mpackId) {
+  public List<Packlet> getPacklets(Long mpackId) {
 
     Mpack mpack = mpackMap.get(mpackId);
-    if (mpack.getPacklets() != null)
+    if (mpack.getPacklets() != null) {
       return mpack.getPacklets();
+    }
     return null;
   }
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/6f8d546a/ambari-server/src/main/java/org/apache/ambari/server/stack/CommonServiceDirectory.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/stack/CommonServiceDirectory.java b/ambari-server/src/main/java/org/apache/ambari/server/stack/CommonServiceDirectory.java
index 80b0b7f..da06de3 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/stack/CommonServiceDirectory.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/stack/CommonServiceDirectory.java
@@ -44,8 +44,9 @@ public class CommonServiceDirectory extends ServiceDirectory {
    */
   @Override
   public String getAdvisorName(String serviceName) {
-    if (getAdvisorFile() == null || serviceName == null)
+    if (getAdvisorFile() == null || serviceName == null) {
       return null;
+    }
 
     File serviceVersionDir = new File(getAbsolutePath());
     String serviceVersion = serviceVersionDir.getName().replaceAll("\\.", "");

http://git-wip-us.apache.org/repos/asf/ambari/blob/6f8d546a/ambari-server/src/main/java/org/apache/ambari/server/stack/ServiceDirectory.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/stack/ServiceDirectory.java b/ambari-server/src/main/java/org/apache/ambari/server/stack/ServiceDirectory.java
index ae59b3f..1ad257e 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/stack/ServiceDirectory.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/stack/ServiceDirectory.java
@@ -104,7 +104,7 @@ public abstract class ServiceDirectory extends StackDefinitionDirectory {
   /**
    * package directory name
    */
-  protected static final String PACKAGE_FOLDER_NAME = "package";
+  public static final String PACKAGE_FOLDER_NAME = "package";
 
   /**
    * upgrades directory name

http://git-wip-us.apache.org/repos/asf/ambari/blob/6f8d546a/ambari-server/src/main/java/org/apache/ambari/server/stack/ServiceModule.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/stack/ServiceModule.java b/ambari-server/src/main/java/org/apache/ambari/server/stack/ServiceModule.java
index 3b3d52c..ec4382e 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/stack/ServiceModule.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/stack/ServiceModule.java
@@ -386,7 +386,7 @@ public class ServiceModule extends BaseModule<ServiceModule, ServiceInfo> implem
     finalizeChildModules(configurationModules.values());
     finalizeChildModules(componentModules.values());
     finalizeConfiguration();
-    if(serviceInfo.getCommandScript() != null && ! isDeleted()) {
+    if(serviceInfo.getCommandScript() != null && ! isDeleted() && stackContext != null) {
       stackContext.registerServiceCheck(getId());
     }
   }

http://git-wip-us.apache.org/repos/asf/ambari/blob/6f8d546a/ambari-server/src/main/java/org/apache/ambari/server/stack/StackManager.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/stack/StackManager.java b/ambari-server/src/main/java/org/apache/ambari/server/stack/StackManager.java
index a59249e..da23ebc 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/stack/StackManager.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/stack/StackManager.java
@@ -205,6 +205,28 @@ public class StackManager {
     populateDB(stackDao, extensionDao);
   }
 
+  /***
+   *  Constructor. Initialize StackManager for merging service definitions and creating management packs
+   * @param stackRoot
+   * @param commonServicesRoot
+   */
+  public StackManager(File stackRoot, File commonServicesRoot, boolean validate) throws AmbariException{
+    LOG.info("Initializing the stack manager...");
+
+    if (validate) {
+      validateStackDirectory(stackRoot);
+      validateCommonServicesDirectory(commonServicesRoot);
+    }
+
+    stackMap = new HashMap<>();
+
+    parseDirectories(stackRoot, commonServicesRoot, null);
+
+    fullyResolveCommonServices(stackModules, commonServiceModules, extensionModules);
+    fullyResolveExtensions(stackModules, commonServiceModules, extensionModules);
+    fullyResolveStacks(stackModules, commonServiceModules, extensionModules);
+  }
+
   protected void updateArchives(
     File resourcesRoot, File stackRoot, Map<String, StackModule> stackModules, Map<String, ServiceModule> commonServiceModules,
     Map<String, ExtensionModule> extensionModules ) throws AmbariException {
@@ -460,6 +482,9 @@ public class StackManager {
    * @return true if all of the repo update tasks have completed; false otherwise
    */
   public boolean haveAllRepoUrlsBeenResolved() {
+    if(stackContext == null) {
+      return true;
+    }
     return stackContext.haveAllRepoTasksCompleted();
   }
 
@@ -493,7 +518,9 @@ public class StackManager {
       stack.finalizeModule();
     }
     // Execute all of the repo tasks in a single thread executor
-    stackContext.executeRepoTasks();
+    if(stackContext != null) {
+      stackContext.executeRepoTasks();
+    }
   }
 
   /**

http://git-wip-us.apache.org/repos/asf/ambari/blob/6f8d546a/ambari-server/src/main/java/org/apache/ambari/server/stack/StackModule.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/stack/StackModule.java b/ambari-server/src/main/java/org/apache/ambari/server/stack/StackModule.java
index 84eb08c..15d0539 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/stack/StackModule.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/stack/StackModule.java
@@ -1144,7 +1144,7 @@ public class StackModule extends BaseModule<StackModule, StackInfo> implements V
     Set<RepositoryInfo> serviceRepos = getUniqueServiceRepos(stackRepos);
     stackInfo.getRepositories().addAll(serviceRepos);
 
-    if (null != rxml && null != rxml.getLatestURI() && stackRepos.size() > 0) {
+    if (null != rxml && null != rxml.getLatestURI() && stackRepos.size() > 0 && stackContext != null) {
       stackContext.registerRepoUpdateTask(rxml.getLatestURI(), this);
     }
   }
@@ -1234,7 +1234,7 @@ public class StackModule extends BaseModule<StackModule, StackInfo> implements V
         RepositoryXml serviceRepoXml = ssd.getRepoFile();
         if (null != serviceRepoXml) {
           repos.addAll(serviceRepoXml.getRepositories());
-          if (null != serviceRepoXml.getLatestURI()) {
+          if (null != serviceRepoXml.getLatestURI() && stackContext != null) {
             stackContext.registerRepoUpdateTask(serviceRepoXml.getLatestURI(), this);
           }
         }

http://git-wip-us.apache.org/repos/asf/ambari/blob/6f8d546a/ambari-server/src/main/java/org/apache/ambari/server/state/AutoDeployInfo.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/AutoDeployInfo.java b/ambari-server/src/main/java/org/apache/ambari/server/state/AutoDeployInfo.java
index c2d4d8b..4ebf6ba 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/AutoDeployInfo.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/AutoDeployInfo.java
@@ -18,16 +18,20 @@
 
 package org.apache.ambari.server.state;
 
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
 import javax.xml.bind.annotation.XmlElement;
 
 /**
  * Represents auto-deployment stack information.
  * This element may be a child of the component and dependency elements.
  */
+@XmlAccessorType(XmlAccessType.FIELD)
 public class AutoDeployInfo {
   /**
    * Whether auto-deploy is enabled
    */
+  @XmlElement(name="enabled")
   private boolean m_enabled = true;
 
   /**

http://git-wip-us.apache.org/repos/asf/ambari/blob/6f8d546a/ambari-server/src/main/java/org/apache/ambari/server/state/ComponentInfo.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/ComponentInfo.java b/ambari-server/src/main/java/org/apache/ambari/server/state/ComponentInfo.java
index d361a29..a3f7f89 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/ComponentInfo.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/ComponentInfo.java
@@ -26,6 +26,7 @@ import javax.xml.bind.annotation.XmlAccessorType;
 import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlElementWrapper;
 import javax.xml.bind.annotation.XmlElements;
+import javax.xml.bind.annotation.XmlTransient;
 
 import org.apache.commons.lang.builder.ToStringBuilder;
 import org.apache.commons.lang.builder.ToStringStyle;
@@ -53,6 +54,7 @@ public class ComponentInfo {
    * This is the translation of the xml element ["true", "false", null] (note that if a value is not specified,
    * it will inherit from the parent) into a boolean after actually resolving it.
    */
+  @XmlTransient
   private boolean versionAdvertisedInternal = false;
 
   /**

http://git-wip-us.apache.org/repos/asf/ambari/blob/6f8d546a/ambari-server/src/main/java/org/apache/ambari/server/state/DependencyInfo.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/DependencyInfo.java b/ambari-server/src/main/java/org/apache/ambari/server/state/DependencyInfo.java
index 2c4ddcc..a2690a5 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/DependencyInfo.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/DependencyInfo.java
@@ -22,6 +22,8 @@ package org.apache.ambari.server.state;
 import java.util.ArrayList;
 import java.util.List;
 
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
 import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlElementWrapper;
 import javax.xml.bind.annotation.XmlElements;
@@ -31,6 +33,7 @@ import org.apache.commons.collections.CollectionUtils;
 /**
  * Represents stack component dependency information.
  */
+@XmlAccessorType(XmlAccessType.FIELD)
 public class DependencyInfo {
   /**
    * The name of the component which is the dependency.
@@ -64,6 +67,8 @@ public class DependencyInfo {
   /**
    * Conditions for Component dependency to other components.
    */
+  @XmlElementWrapper(name="conditions")
+  @XmlElements(@XmlElement(name="condition"))
   private List<DependencyConditionInfo> dependencyConditions = new ArrayList<>();
   /**
    * Setter for name property.
@@ -150,8 +155,6 @@ public class DependencyInfo {
    *
    * @return dependencyConditions
    */
-  @XmlElementWrapper(name="conditions")
-  @XmlElements(@XmlElement(name="condition"))
   public List<DependencyConditionInfo> getDependencyConditions() {
     return dependencyConditions;
   }

http://git-wip-us.apache.org/repos/asf/ambari/blob/6f8d546a/ambari-server/src/main/java/org/apache/ambari/server/state/Mpack.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/Mpack.java b/ambari-server/src/main/java/org/apache/ambari/server/state/Mpack.java
index 9090f28..1eabd69 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/Mpack.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/Mpack.java
@@ -17,8 +17,8 @@
  */
 package org.apache.ambari.server.state;
 
-import java.util.ArrayList;
-import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
 
 import com.google.gson.annotations.SerializedName;
 
@@ -41,10 +41,10 @@ public class Mpack {
   private String description;
 
   @SerializedName("prerequisites")
-  private HashMap<String, String> prerequisites;
+  private Map<String, String> prerequisites;
 
   @SerializedName("packlets")
-  private ArrayList<Packlet> packlets;
+  private List<Packlet> packlets;
 
   @SerializedName("stack-id")
   private String stackId;
@@ -99,19 +99,19 @@ public class Mpack {
     this.description = description;
   }
 
-  public HashMap<String, String> getPrerequisites() {
+  public Map<String, String> getPrerequisites() {
     return prerequisites;
   }
 
-  public void setPrerequisites(HashMap<String, String> prerequisites) {
+  public void setPrerequisites(Map<String, String> prerequisites) {
     this.prerequisites = prerequisites;
   }
 
-  public ArrayList<Packlet> getPacklets() {
+  public List<Packlet> getPacklets() {
     return packlets;
   }
 
-  public void setPacklets(ArrayList<Packlet> packlets) {
+  public void setPacklets(List<Packlet> packlets) {
     this.packlets = packlets;
   }
 
@@ -250,22 +250,29 @@ public class Mpack {
   }
 
   public void copyFrom(Mpack mpack) {
-    if (this.name == null)
+    if (this.name == null) {
       this.name = mpack.getName();
-    if (this.mpackId == null)
+    }
+    if (this.mpackId == null) {
       this.mpackId = mpack.getMpackId();
-    if (this.version == null)
+    }
+    if (this.version == null) {
       this.version = mpack.getVersion();
-    if (this.stackId == null)
+    }
+    if (this.stackId == null) {
       this.stackId = mpack.getStackId();
-    if (this.registryId == null)
+    }
+    if (this.registryId == null) {
       this.registryId = mpack.getRegistryId();
-    if (this.description == null)
+    }
+    if (this.description == null) {
       this.description = mpack.getDescription();
-    if (this.prerequisites == null)
+    }
+    if (this.prerequisites == null) {
       this.prerequisites = mpack.getPrerequisites();
-    if (this.packlets == null)
+    }
+    if (this.packlets == null) {
       this.packlets = mpack.getPacklets();
-
+    }
   }
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/6f8d546a/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceInfo.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceInfo.java b/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceInfo.java
index ef18bd9..42d2c18 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceInfo.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceInfo.java
@@ -57,7 +57,7 @@ import com.google.common.collect.Multimaps;
 
 @XmlAccessorType(XmlAccessType.FIELD)
 @JsonFilter("propertiesfilter")
-public class ServiceInfo implements Validable{
+public class ServiceInfo implements Validable, Cloneable {
 
   public static final AbstractMap.SimpleEntry<String, String> DEFAULT_SERVICE_INSTALLABLE_PROPERTY = new AbstractMap.SimpleEntry<>("installable", "true");
   public static final AbstractMap.SimpleEntry<String, String> DEFAULT_SERVICE_MANAGED_PROPERTY = new AbstractMap.SimpleEntry<>("managed", "true");
@@ -177,6 +177,7 @@ public class ServiceInfo implements Validable{
   @XmlTransient
   private File widgetsDescriptorFile = null;
 
+  @XmlTransient
   private StackRoleCommandOrder roleCommandOrder;
 
   @XmlTransient
@@ -265,6 +266,7 @@ public class ServiceInfo implements Validable{
    * at getter.
    * Added at schema ver 2
    */
+  @XmlTransient
   private volatile Map<String, ServiceOsSpecific> serviceOsSpecificsMap;
 
   /**
@@ -441,6 +443,39 @@ public class ServiceInfo implements Validable{
     this.properties = properties;
   }
 
+  @Override
+  public Object clone() throws CloneNotSupportedException {
+    ServiceInfo clone = (ServiceInfo) super.clone();
+    clone.setSchemaVersion(schemaVersion);
+    clone.setName(name);
+    clone.setDisplayName(displayName);
+    clone.setVersion(version);
+    clone.setComment(comment);
+    clone.setServiceType(serviceType);
+    clone.setSelection(selection);
+    clone.components = components;
+    clone.setDeleted(isDeleted);
+    clone.setConfigDependencies(configDependencies);
+    clone.setExcludedConfigTypes(excludedConfigTypes);
+    clone.setMonitoringService(monitoringService);
+    clone.setRestartRequiredAfterChange(restartRequiredAfterChange);
+    clone.setRestartRequiredAfterRackChange(restartRequiredAfterRackChange);
+    clone.setParent(parent);
+    clone.setWidgetsFileName(widgetsFileName);
+    clone.setMetricsFileName(metricsFileName);
+    clone.setCredentialStoreInfo(credentialStoreInfo);
+    clone.setServicePropertyList(servicePropertyList);
+    clone.serviceOsSpecifics =  serviceOsSpecifics;
+    clone.configDir = configDir;
+    clone.themesDir = themesDir;
+    clone.setThemes(themes);
+    clone.setQuickLinksConfigurationsDir(quickLinksConfigurationsDir);
+    clone.setQuickLinksConfigurations(quickLinksConfigurations);
+    clone.setCommandScript(commandScript);
+    clone.setRequiredServices(requiredServices);
+    return clone;
+  }
+
   public List<ComponentInfo> getComponents() {
     if (components == null) components = new ArrayList<>();
     return components;

http://git-wip-us.apache.org/repos/asf/ambari/blob/6f8d546a/ambari-server/src/main/java/org/apache/ambari/server/state/repository/ManifestServiceInfo.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/repository/ManifestServiceInfo.java b/ambari-server/src/main/java/org/apache/ambari/server/state/repository/ManifestServiceInfo.java
index 8d88509..b9be079 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/repository/ManifestServiceInfo.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/repository/ManifestServiceInfo.java
@@ -38,6 +38,14 @@ public class ManifestServiceInfo {
   @JsonProperty("versions")
   Set<String> m_versions;
 
+  public String getName() {
+    return m_name;
+  }
+
+  public Set<String> getVersions() {
+    return m_versions;
+  }
+
   /**
    * @param name      the service name
    * @param display   the display name

http://git-wip-us.apache.org/repos/asf/ambari/blob/6f8d546a/ambari-server/src/main/java/org/apache/ambari/server/state/repository/VersionDefinitionXml.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/repository/VersionDefinitionXml.java b/ambari-server/src/main/java/org/apache/ambari/server/state/repository/VersionDefinitionXml.java
index c5b2d7c..ba035ab 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/repository/VersionDefinitionXml.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/repository/VersionDefinitionXml.java
@@ -189,7 +189,16 @@ public class VersionDefinitionXml {
    * @return the list of {@code ManifestServiceInfo} instances for each service in the stack
    */
   public synchronized List<ManifestServiceInfo> getStackServices(StackInfo stack) {
+    return getStackServices(stack, false);
+  }
 
+  /**
+   * Gets the list of stack services, applying information from the version definition.
+   * @param stack the stack for which to get the information
+   * @param skipMissingServices skip services missing in version definition
+   * @return the list of {@code ManifestServiceInfo} instances for each service in the stack
+   */
+  public synchronized List<ManifestServiceInfo> getStackServices(StackInfo stack, boolean skipMissingServices) {
     if (null != m_manifest) {
       return m_manifest;
     }
@@ -209,6 +218,9 @@ public class VersionDefinitionXml {
     m_manifest = new ArrayList<>();
 
     for (ServiceInfo si : stack.getServices()) {
+      if(skipMissingServices && !manifestVersions.containsKey(si.getName())) {
+        continue;
+      }
       Set<String> versions = manifestVersions.containsKey(si.getName()) ?
           manifestVersions.get(si.getName()) : Collections.singleton(
               null == si.getVersion() ? "" : si.getVersion());
@@ -220,6 +232,8 @@ public class VersionDefinitionXml {
     return m_manifest;
   }
 
+
+
   /**
    * Gets the package version for an OS family
    * @param osFamily  the os family

http://git-wip-us.apache.org/repos/asf/ambari/blob/6f8d546a/ambari-server/src/main/java/org/apache/ambari/server/state/stack/ConfigurationXml.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/stack/ConfigurationXml.java b/ambari-server/src/main/java/org/apache/ambari/server/state/stack/ConfigurationXml.java
index 0f471fe..8df3b46 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/stack/ConfigurationXml.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/stack/ConfigurationXml.java
@@ -25,6 +25,8 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
 import javax.xml.bind.annotation.XmlAnyAttribute;
 import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlRootElement;
@@ -38,6 +40,7 @@ import org.apache.ambari.server.state.PropertyInfo;
  * The elements within a service's configuration file.
  */
 @XmlRootElement(name="configuration")
+@XmlAccessorType(XmlAccessType.FIELD)
 public class ConfigurationXml implements Validable{
   
   @XmlAnyAttribute
@@ -92,6 +95,14 @@ public class ConfigurationXml implements Validable{
     return properties;
   }
 
+  /***
+   *
+   * @param listProperties
+   */
+  public void setProperties(List<PropertyInfo> listProperties) {
+    this.properties = listProperties;
+  }
+
   public Map<QName, String> getAttributes() {
     return attributes;
   }

http://git-wip-us.apache.org/repos/asf/ambari/blob/6f8d546a/ambari-server/src/main/java/org/apache/ambari/server/state/stack/StackMetainfoXml.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/stack/StackMetainfoXml.java b/ambari-server/src/main/java/org/apache/ambari/server/state/stack/StackMetainfoXml.java
index 753c2b8..82096eb 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/stack/StackMetainfoXml.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/stack/StackMetainfoXml.java
@@ -40,10 +40,18 @@ public class StackMetainfoXml implements Validable{
     return minJdk;
   }
 
+  public void setMinJdk(String minJdk) {
+    this.minJdk = minJdk;
+  }
+
   public String getMaxJdk() {
     return maxJdk;
   }
 
+  public void setMaxJdk(String maxJdk) {
+    this.maxJdk = maxJdk;
+  }
+
   @XmlElement(name="minJdk")
   private String minJdk = null;
 
@@ -52,6 +60,10 @@ public class StackMetainfoXml implements Validable{
 
   @XmlElement(name="extends")
   private String extendsVersion = null;
+
+  public void setExtendsVersion(String extendsVersion) {
+    this.extendsVersion = extendsVersion;
+  }
   
   @XmlElement(name="versions")
   private Version version = new Version();
@@ -108,10 +120,14 @@ public class StackMetainfoXml implements Validable{
   public Version getVersion() {
     return version;
   }
+
+  public void setVersion(Version version) {
+    this.version = version;
+  }
   
   @XmlAccessorType(XmlAccessType.FIELD)
   public static class Version {
-    private Version() {
+    public Version() {
     }
     private boolean active = false;
     private String upgrade = null;
@@ -122,6 +138,10 @@ public class StackMetainfoXml implements Validable{
     public boolean isActive() {
       return active;
     }
+
+    public void setActive(boolean active) {
+      this.active = active;
+    }
     
     /**
      * @return the upgrade version number, if set

http://git-wip-us.apache.org/repos/asf/ambari/blob/6f8d546a/ambari-server/src/main/resources/common-services/AMBARI_INFRA/0.1.0/service_advisor.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/AMBARI_INFRA/0.1.0/service_advisor.py b/ambari-server/src/main/resources/common-services/AMBARI_INFRA/0.1.0/service_advisor.py
index 9b6aace..2af7e0b 100644
--- a/ambari-server/src/main/resources/common-services/AMBARI_INFRA/0.1.0/service_advisor.py
+++ b/ambari-server/src/main/resources/common-services/AMBARI_INFRA/0.1.0/service_advisor.py
@@ -29,7 +29,7 @@ import fnmatch
 from resource_management.core.logger import Logger
 
 SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
-STACKS_DIR = os.path.join(SCRIPT_DIR, '../../../stacks/')
+STACKS_DIR = os.path.join(SCRIPT_DIR, '/var/lib/ambari-server/resources/stacks/')
 PARENT_FILE = os.path.join(STACKS_DIR, 'service_advisor.py')
 
 try:

http://git-wip-us.apache.org/repos/asf/ambari/blob/6f8d546a/ambari-server/src/main/resources/common-services/ATLAS/0.7.0.3.0/service_advisor.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/ATLAS/0.7.0.3.0/service_advisor.py b/ambari-server/src/main/resources/common-services/ATLAS/0.7.0.3.0/service_advisor.py
index a2e31cc..ee19bed 100644
--- a/ambari-server/src/main/resources/common-services/ATLAS/0.7.0.3.0/service_advisor.py
+++ b/ambari-server/src/main/resources/common-services/ATLAS/0.7.0.3.0/service_advisor.py
@@ -29,7 +29,7 @@ from ambari_commons.str_utils import string_set_equals
 from resource_management.core.logger import Logger
 
 SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
-STACKS_DIR = os.path.join(SCRIPT_DIR, '../../../stacks/')
+STACKS_DIR = os.path.join(SCRIPT_DIR, '/var/lib/ambari-server/resources/stacks/')
 PARENT_FILE = os.path.join(STACKS_DIR, 'service_advisor.py')
 
 try:

http://git-wip-us.apache.org/repos/asf/ambari/blob/6f8d546a/ambari-server/src/main/resources/common-services/HAWQ/2.0.0/service_advisor.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/HAWQ/2.0.0/service_advisor.py b/ambari-server/src/main/resources/common-services/HAWQ/2.0.0/service_advisor.py
index 434228d..6b78ea9 100644
--- a/ambari-server/src/main/resources/common-services/HAWQ/2.0.0/service_advisor.py
+++ b/ambari-server/src/main/resources/common-services/HAWQ/2.0.0/service_advisor.py
@@ -24,7 +24,7 @@ import socket
 import traceback
 
 SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
-STACKS_DIR = os.path.join(SCRIPT_DIR, '../../../stacks/')
+STACKS_DIR = os.path.join(SCRIPT_DIR, '/var/lib/ambari-server/resources/stacks/')
 PARENT_FILE = os.path.join(STACKS_DIR, 'service_advisor.py')
 
 try:

http://git-wip-us.apache.org/repos/asf/ambari/blob/6f8d546a/ambari-server/src/main/resources/common-services/HBASE/2.0.0.3.0/service_advisor.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/HBASE/2.0.0.3.0/service_advisor.py b/ambari-server/src/main/resources/common-services/HBASE/2.0.0.3.0/service_advisor.py
index f9d1a59..5c67a02 100644
--- a/ambari-server/src/main/resources/common-services/HBASE/2.0.0.3.0/service_advisor.py
+++ b/ambari-server/src/main/resources/common-services/HBASE/2.0.0.3.0/service_advisor.py
@@ -29,7 +29,7 @@ import fnmatch
 from resource_management.core.logger import Logger
 
 SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
-STACKS_DIR = os.path.join(SCRIPT_DIR, '../../../stacks/')
+STACKS_DIR = os.path.join(SCRIPT_DIR, '/var/lib/ambari-server/resources/stacks/')
 PARENT_FILE = os.path.join(STACKS_DIR, 'service_advisor.py')
 
 try:

http://git-wip-us.apache.org/repos/asf/ambari/blob/6f8d546a/ambari-server/src/main/resources/common-services/HDFS/3.0.0.3.0/service_advisor.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/HDFS/3.0.0.3.0/service_advisor.py b/ambari-server/src/main/resources/common-services/HDFS/3.0.0.3.0/service_advisor.py
index e135275..ded8778 100644
--- a/ambari-server/src/main/resources/common-services/HDFS/3.0.0.3.0/service_advisor.py
+++ b/ambari-server/src/main/resources/common-services/HDFS/3.0.0.3.0/service_advisor.py
@@ -28,7 +28,7 @@ from resource_management.libraries.functions.mounted_dirs_helper import get_moun
 
 
 SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
-STACKS_DIR = os.path.join(SCRIPT_DIR, '../../../stacks/')
+STACKS_DIR = os.path.join(SCRIPT_DIR, '/var/lib/ambari-server/resources/stacks/')
 PARENT_FILE = os.path.join(STACKS_DIR, 'service_advisor.py')
 
 try:

http://git-wip-us.apache.org/repos/asf/ambari/blob/6f8d546a/ambari-server/src/main/resources/common-services/HIVE/2.1.0.3.0/service_advisor.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/HIVE/2.1.0.3.0/service_advisor.py b/ambari-server/src/main/resources/common-services/HIVE/2.1.0.3.0/service_advisor.py
index 48058f7..9cc4657 100644
--- a/ambari-server/src/main/resources/common-services/HIVE/2.1.0.3.0/service_advisor.py
+++ b/ambari-server/src/main/resources/common-services/HIVE/2.1.0.3.0/service_advisor.py
@@ -28,7 +28,7 @@ import fnmatch
 
 
 SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
-STACKS_DIR = os.path.join(SCRIPT_DIR, '../../../stacks/')
+STACKS_DIR = os.path.join(SCRIPT_DIR, '/var/lib/ambari-server/resources/stacks/')
 PARENT_FILE = os.path.join(STACKS_DIR, 'service_advisor.py')
 
 try:

http://git-wip-us.apache.org/repos/asf/ambari/blob/6f8d546a/ambari-server/src/main/resources/common-services/KAFKA/0.10.0.3.0/service_advisor.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/KAFKA/0.10.0.3.0/service_advisor.py b/ambari-server/src/main/resources/common-services/KAFKA/0.10.0.3.0/service_advisor.py
index 27c7173..bf19fee 100644
--- a/ambari-server/src/main/resources/common-services/KAFKA/0.10.0.3.0/service_advisor.py
+++ b/ambari-server/src/main/resources/common-services/KAFKA/0.10.0.3.0/service_advisor.py
@@ -29,7 +29,7 @@ import fnmatch
 from resource_management.core.logger import Logger
 
 SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
-STACKS_DIR = os.path.join(SCRIPT_DIR, '../../../stacks/')
+STACKS_DIR = os.path.join(SCRIPT_DIR, '/var/lib/ambari-server/resources/stacks/')
 PARENT_FILE = os.path.join(STACKS_DIR, 'service_advisor.py')
 
 try:

http://git-wip-us.apache.org/repos/asf/ambari/blob/6f8d546a/ambari-server/src/main/resources/common-services/KNOX/0.5.0.3.0/service_advisor.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/KNOX/0.5.0.3.0/service_advisor.py b/ambari-server/src/main/resources/common-services/KNOX/0.5.0.3.0/service_advisor.py
index 575f910..3051d82 100644
--- a/ambari-server/src/main/resources/common-services/KNOX/0.5.0.3.0/service_advisor.py
+++ b/ambari-server/src/main/resources/common-services/KNOX/0.5.0.3.0/service_advisor.py
@@ -30,7 +30,7 @@ import xml.etree.ElementTree as ET
 from resource_management.core.logger import Logger
 
 SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
-STACKS_DIR = os.path.join(SCRIPT_DIR, '../../../stacks/')
+STACKS_DIR = os.path.join(SCRIPT_DIR, '/var/lib/ambari-server/resources/stacks/')
 PARENT_FILE = os.path.join(STACKS_DIR, 'service_advisor.py')
 
 try:

http://git-wip-us.apache.org/repos/asf/ambari/blob/6f8d546a/ambari-server/src/main/resources/common-services/LOGSEARCH/0.5.0/service_advisor.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/LOGSEARCH/0.5.0/service_advisor.py b/ambari-server/src/main/resources/common-services/LOGSEARCH/0.5.0/service_advisor.py
index 6b29dbc..bb1fb2a 100644
--- a/ambari-server/src/main/resources/common-services/LOGSEARCH/0.5.0/service_advisor.py
+++ b/ambari-server/src/main/resources/common-services/LOGSEARCH/0.5.0/service_advisor.py
@@ -30,7 +30,7 @@ import math
 from resource_management.core.logger import Logger
 
 SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
-STACKS_DIR = os.path.join(SCRIPT_DIR, '../../../stacks/')
+STACKS_DIR = os.path.join(SCRIPT_DIR, './var/lib/ambari-server/resources/stacks/')
 PARENT_FILE = os.path.join(STACKS_DIR, 'service_advisor.py')
 
 try:

http://git-wip-us.apache.org/repos/asf/ambari/blob/6f8d546a/ambari-server/src/main/resources/common-services/OOZIE/4.2.0.3.0/service_advisor.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/OOZIE/4.2.0.3.0/service_advisor.py b/ambari-server/src/main/resources/common-services/OOZIE/4.2.0.3.0/service_advisor.py
index d1e2b77..da565d6 100644
--- a/ambari-server/src/main/resources/common-services/OOZIE/4.2.0.3.0/service_advisor.py
+++ b/ambari-server/src/main/resources/common-services/OOZIE/4.2.0.3.0/service_advisor.py
@@ -29,7 +29,7 @@ import fnmatch
 from resource_management.core.logger import Logger
 
 SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
-STACKS_DIR = os.path.join(SCRIPT_DIR, '../../../stacks/')
+STACKS_DIR = os.path.join(SCRIPT_DIR, '/var/lib/ambari-server/resources/stacks/')
 PARENT_FILE = os.path.join(STACKS_DIR, 'service_advisor.py')
 
 try:

http://git-wip-us.apache.org/repos/asf/ambari/blob/6f8d546a/ambari-server/src/main/resources/common-services/PIG/0.16.1.3.0/service_advisor.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/PIG/0.16.1.3.0/service_advisor.py b/ambari-server/src/main/resources/common-services/PIG/0.16.1.3.0/service_advisor.py
index 8f89c5d..0bc6e4a 100644
--- a/ambari-server/src/main/resources/common-services/PIG/0.16.1.3.0/service_advisor.py
+++ b/ambari-server/src/main/resources/common-services/PIG/0.16.1.3.0/service_advisor.py
@@ -29,7 +29,7 @@ import fnmatch
 from resource_management.core.logger import Logger
 
 SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
-STACKS_DIR = os.path.join(SCRIPT_DIR, '../../../stacks/')
+STACKS_DIR = os.path.join(SCRIPT_DIR, '/var/lib/ambari-server/resources/stacks/')
 PARENT_FILE = os.path.join(STACKS_DIR, 'service_advisor.py')
 
 try:

http://git-wip-us.apache.org/repos/asf/ambari/blob/6f8d546a/ambari-server/src/main/resources/common-services/PXF/3.0.0/service_advisor.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/PXF/3.0.0/service_advisor.py b/ambari-server/src/main/resources/common-services/PXF/3.0.0/service_advisor.py
index d2a80a9..aa16b72 100644
--- a/ambari-server/src/main/resources/common-services/PXF/3.0.0/service_advisor.py
+++ b/ambari-server/src/main/resources/common-services/PXF/3.0.0/service_advisor.py
@@ -21,7 +21,7 @@ import imp
 import traceback
 
 SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
-STACKS_DIR = os.path.join(SCRIPT_DIR, '../../../stacks/')
+STACKS_DIR = os.path.join(SCRIPT_DIR, '/var/lib/ambari-server/resources/stacks/')
 PARENT_FILE = os.path.join(STACKS_DIR, 'service_advisor.py')
 
 try:

http://git-wip-us.apache.org/repos/asf/ambari/blob/6f8d546a/ambari-server/src/main/resources/common-services/RANGER/1.0.0.3.0/service_advisor.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/RANGER/1.0.0.3.0/service_advisor.py b/ambari-server/src/main/resources/common-services/RANGER/1.0.0.3.0/service_advisor.py
index f37261f..d472176 100644
--- a/ambari-server/src/main/resources/common-services/RANGER/1.0.0.3.0/service_advisor.py
+++ b/ambari-server/src/main/resources/common-services/RANGER/1.0.0.3.0/service_advisor.py
@@ -29,7 +29,7 @@ import fnmatch
 from resource_management.core.logger import Logger
 
 SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
-STACKS_DIR = os.path.join(SCRIPT_DIR, '../../../stacks/')
+STACKS_DIR = os.path.join(SCRIPT_DIR, '/var/lib/ambari-server/resources/stacks/')
 PARENT_FILE = os.path.join(STACKS_DIR, 'service_advisor.py')
 
 try:

http://git-wip-us.apache.org/repos/asf/ambari/blob/6f8d546a/ambari-server/src/main/resources/common-services/RANGER_KMS/1.0.0.3.0/service_advisor.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/RANGER_KMS/1.0.0.3.0/service_advisor.py b/ambari-server/src/main/resources/common-services/RANGER_KMS/1.0.0.3.0/service_advisor.py
index b81e05b..d7b7e34 100644
--- a/ambari-server/src/main/resources/common-services/RANGER_KMS/1.0.0.3.0/service_advisor.py
+++ b/ambari-server/src/main/resources/common-services/RANGER_KMS/1.0.0.3.0/service_advisor.py
@@ -29,7 +29,7 @@ import fnmatch
 from resource_management.core.logger import Logger
 
 SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
-STACKS_DIR = os.path.join(SCRIPT_DIR, '../../../stacks/')
+STACKS_DIR = os.path.join(SCRIPT_DIR, '/var/lib/ambari-server/resources/stacks/')
 PARENT_FILE = os.path.join(STACKS_DIR, 'service_advisor.py')
 
 try:

http://git-wip-us.apache.org/repos/asf/ambari/blob/6f8d546a/ambari-server/src/main/resources/common-services/SLIDER/0.91.0.3.0/service_advisor.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/SLIDER/0.91.0.3.0/service_advisor.py b/ambari-server/src/main/resources/common-services/SLIDER/0.91.0.3.0/service_advisor.py
index 5614868..a8081f1 100644
--- a/ambari-server/src/main/resources/common-services/SLIDER/0.91.0.3.0/service_advisor.py
+++ b/ambari-server/src/main/resources/common-services/SLIDER/0.91.0.3.0/service_advisor.py
@@ -25,7 +25,7 @@ import traceback
 
 
 SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
-STACKS_DIR = os.path.join(SCRIPT_DIR, '../../../stacks/')
+STACKS_DIR = os.path.join(SCRIPT_DIR, '/var/lib/ambari-server/resources/stacks/')
 PARENT_FILE = os.path.join(STACKS_DIR, 'service_advisor.py')
 
 try:

http://git-wip-us.apache.org/repos/asf/ambari/blob/6f8d546a/ambari-server/src/main/resources/common-services/SPARK/2.2.0/service_advisor.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/SPARK/2.2.0/service_advisor.py b/ambari-server/src/main/resources/common-services/SPARK/2.2.0/service_advisor.py
index 389dfae..5c62768 100644
--- a/ambari-server/src/main/resources/common-services/SPARK/2.2.0/service_advisor.py
+++ b/ambari-server/src/main/resources/common-services/SPARK/2.2.0/service_advisor.py
@@ -25,7 +25,7 @@ import traceback
 
 
 SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
-STACKS_DIR = os.path.join(SCRIPT_DIR, '../../../stacks/')
+STACKS_DIR = os.path.join(SCRIPT_DIR, '/var/lib/ambari-server/resources/stacks/')
 PARENT_FILE = os.path.join(STACKS_DIR, 'service_advisor.py')
 
 try:

http://git-wip-us.apache.org/repos/asf/ambari/blob/6f8d546a/ambari-server/src/main/resources/common-services/SQOOP/1.4.4.3.0/service_advisor.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/SQOOP/1.4.4.3.0/service_advisor.py b/ambari-server/src/main/resources/common-services/SQOOP/1.4.4.3.0/service_advisor.py
index 115ca06..109c20f 100644
--- a/ambari-server/src/main/resources/common-services/SQOOP/1.4.4.3.0/service_advisor.py
+++ b/ambari-server/src/main/resources/common-services/SQOOP/1.4.4.3.0/service_advisor.py
@@ -29,7 +29,7 @@ import fnmatch
 from resource_management.core.logger import Logger
 
 SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
-STACKS_DIR = os.path.join(SCRIPT_DIR, '../../../stacks/')
+STACKS_DIR = os.path.join(SCRIPT_DIR, '/var/lib/ambari-server/resources/stacks/')
 PARENT_FILE = os.path.join(STACKS_DIR, 'service_advisor.py')
 
 try:

http://git-wip-us.apache.org/repos/asf/ambari/blob/6f8d546a/ambari-server/src/main/resources/common-services/STORM/1.0.1.3.0/service_advisor.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/STORM/1.0.1.3.0/service_advisor.py b/ambari-server/src/main/resources/common-services/STORM/1.0.1.3.0/service_advisor.py
index 1d6bbe0..98627ed 100644
--- a/ambari-server/src/main/resources/common-services/STORM/1.0.1.3.0/service_advisor.py
+++ b/ambari-server/src/main/resources/common-services/STORM/1.0.1.3.0/service_advisor.py
@@ -30,7 +30,7 @@ from resource_management.core.logger import Logger
 from resource_management.libraries.functions.get_bare_principal import get_bare_principal
 
 SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
-STACKS_DIR = os.path.join(SCRIPT_DIR, '../../../stacks/')
+STACKS_DIR = os.path.join(SCRIPT_DIR, '/var/lib/ambari-server/resources/stacks/')
 PARENT_FILE = os.path.join(STACKS_DIR, 'service_advisor.py')
 
 try:

http://git-wip-us.apache.org/repos/asf/ambari/blob/6f8d546a/ambari-server/src/main/resources/common-services/TEZ/0.9.0.3.0/service_advisor.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/TEZ/0.9.0.3.0/service_advisor.py b/ambari-server/src/main/resources/common-services/TEZ/0.9.0.3.0/service_advisor.py
index d71983f..c7fe737 100644
--- a/ambari-server/src/main/resources/common-services/TEZ/0.9.0.3.0/service_advisor.py
+++ b/ambari-server/src/main/resources/common-services/TEZ/0.9.0.3.0/service_advisor.py
@@ -28,7 +28,7 @@ import fnmatch
 
 
 SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
-STACKS_DIR = os.path.join(SCRIPT_DIR, '../../../stacks/')
+STACKS_DIR = os.path.join(SCRIPT_DIR, '/var/lib/ambari-server/resources/stacks/')
 PARENT_FILE = os.path.join(STACKS_DIR, 'service_advisor.py')
 
 try:

http://git-wip-us.apache.org/repos/asf/ambari/blob/6f8d546a/ambari-server/src/main/resources/common-services/YARN/3.0.0.3.0/service_advisor.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/YARN/3.0.0.3.0/service_advisor.py b/ambari-server/src/main/resources/common-services/YARN/3.0.0.3.0/service_advisor.py
index ecf245d..0ba92dd 100644
--- a/ambari-server/src/main/resources/common-services/YARN/3.0.0.3.0/service_advisor.py
+++ b/ambari-server/src/main/resources/common-services/YARN/3.0.0.3.0/service_advisor.py
@@ -30,7 +30,7 @@ from math import floor, ceil
 
 
 SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
-STACKS_DIR = os.path.join(SCRIPT_DIR, '../../../stacks/')
+STACKS_DIR = os.path.join(SCRIPT_DIR, '/var/lib/ambari-server/resources/stacks/')
 PARENT_FILE = os.path.join(STACKS_DIR, 'service_advisor.py')
 
 try:

http://git-wip-us.apache.org/repos/asf/ambari/blob/6f8d546a/ambari-server/src/main/resources/common-services/ZEPPELIN/0.6.0.3.0/service_advisor.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/ZEPPELIN/0.6.0.3.0/service_advisor.py b/ambari-server/src/main/resources/common-services/ZEPPELIN/0.6.0.3.0/service_advisor.py
index 4548961..834b21e 100644
--- a/ambari-server/src/main/resources/common-services/ZEPPELIN/0.6.0.3.0/service_advisor.py
+++ b/ambari-server/src/main/resources/common-services/ZEPPELIN/0.6.0.3.0/service_advisor.py
@@ -29,7 +29,7 @@ import fnmatch
 from resource_management.core.logger import Logger
 
 SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
-STACKS_DIR = os.path.join(SCRIPT_DIR, '../../../stacks/')
+STACKS_DIR = os.path.join(SCRIPT_DIR, '/var/lib/ambari-server/resources/stacks/')
 PARENT_FILE = os.path.join(STACKS_DIR, 'service_advisor.py')
 
 try:

http://git-wip-us.apache.org/repos/asf/ambari/blob/6f8d546a/ambari-server/src/main/resources/common-services/ZOOKEEPER/3.4.9/service_advisor.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/ZOOKEEPER/3.4.9/service_advisor.py b/ambari-server/src/main/resources/common-services/ZOOKEEPER/3.4.9/service_advisor.py
index c86eb33..be86927 100644
--- a/ambari-server/src/main/resources/common-services/ZOOKEEPER/3.4.9/service_advisor.py
+++ b/ambari-server/src/main/resources/common-services/ZOOKEEPER/3.4.9/service_advisor.py
@@ -27,7 +27,7 @@ import inspect
 
 
 SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
-STACKS_DIR = os.path.join(SCRIPT_DIR, '../../../stacks/')
+STACKS_DIR = os.path.join(SCRIPT_DIR, '/var/lib/ambari-server/resources/stacks/')
 PARENT_FILE = os.path.join(STACKS_DIR, 'service_advisor.py')
 
 try:

http://git-wip-us.apache.org/repos/asf/ambari/blob/6f8d546a/ambari-server/src/main/resources/scripts/stack_advisor.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/scripts/stack_advisor.py b/ambari-server/src/main/resources/scripts/stack_advisor.py
index b728a8a..1c9215c7 100755
--- a/ambari-server/src/main/resources/scripts/stack_advisor.py
+++ b/ambari-server/src/main/resources/scripts/stack_advisor.py
@@ -42,6 +42,10 @@ STACK_ADVISOR_DEFAULT_IMPL_CLASS = 'DefaultStackAdvisor'
 STACK_ADVISOR_IMPL_PATH_TEMPLATE = os.path.join(SCRIPT_DIRECTORY, './../stacks/{0}/{1}/services/stack_advisor.py')
 STACK_ADVISOR_IMPL_CLASS_TEMPLATE = '{0}{1}StackAdvisor'
 
+# Stack advisor may have deeper inheritance than the stack,
+# The extra classes are defined in the following directory:
+STACK_ADVISOR_BASE_MODULES = os.path.join(SCRIPT_DIRECTORY, '../stacks/{0}/{1}/stack-advisor')
+
 ADVISOR_CONTEXT = "advisor_context"
 CALL_TYPE = "call_type"
 
@@ -139,6 +143,8 @@ def instantiateStackAdvisor(stackName, stackVersion, parentVersions):
   versions = [stackVersion]
   versions.extend(parentVersions)
 
+  sys.path.append(STACK_ADVISOR_BASE_MODULES.format(stackName, versions[-1]))
+
   for version in reversed(versions):
     try:
       path = STACK_ADVISOR_IMPL_PATH_TEMPLATE.format(stackName, version)

http://git-wip-us.apache.org/repos/asf/ambari/blob/6f8d546a/ambari-server/src/main/resources/stacks/HDP/2.1/services/stack_advisor.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.1/services/stack_advisor.py b/ambari-server/src/main/resources/stacks/HDP/2.1/services/stack_advisor.py
index ddd795f..d6d5027 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.1/services/stack_advisor.py
+++ b/ambari-server/src/main/resources/stacks/HDP/2.1/services/stack_advisor.py
@@ -20,6 +20,12 @@ limitations under the License.
 # Python imports
 import socket
 
+try:
+  from stack_advisor_hdp206 import *
+except ImportError:
+  #Ignore ImportError
+  print("stack_advisor_hd206 not found")
+
 # Local Imports
 
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/6f8d546a/ambari-server/src/main/resources/stacks/HDP/2.2/services/stack_advisor.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.2/services/stack_advisor.py b/ambari-server/src/main/resources/stacks/HDP/2.2/services/stack_advisor.py
index 2dc1738..bfdf457 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.2/services/stack_advisor.py
+++ b/ambari-server/src/main/resources/stacks/HDP/2.2/services/stack_advisor.py
@@ -27,6 +27,12 @@ import socket
 import re
 import xml.etree.ElementTree as ET
 
+try:
+  from stack_advisor_hdp21 import *
+except ImportError:
+  #Ignore ImportError
+  print("stack_advisor_hdp21 not found")
+
 # Local Imports
 
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/6f8d546a/ambari-server/src/main/resources/stacks/HDP/2.3/services/stack_advisor.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.3/services/stack_advisor.py b/ambari-server/src/main/resources/stacks/HDP/2.3/services/stack_advisor.py
index 201efff..95f9978 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.3/services/stack_advisor.py
+++ b/ambari-server/src/main/resources/stacks/HDP/2.3/services/stack_advisor.py
@@ -24,6 +24,12 @@ import fnmatch
 import math
 import socket
 
+try:
+  from stack_advisor_hdp22 import *
+except ImportError:
+  #Ignore ImportError
+  print("stack_advisor_hdp22 not found")
+
 # Local Imports
 
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/6f8d546a/ambari-server/src/main/resources/stacks/HDP/2.4/services/stack_advisor.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.4/services/stack_advisor.py b/ambari-server/src/main/resources/stacks/HDP/2.4/services/stack_advisor.py
index 985c101..bcfb908 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.4/services/stack_advisor.py
+++ b/ambari-server/src/main/resources/stacks/HDP/2.4/services/stack_advisor.py
@@ -17,6 +17,11 @@ See the License for the specific language governing permissions and
 limitations under the License.
 """
 
+try:
+ from stack_advisor_hdp23 import *
+except ImportError:
+ #Ignore ImportError
+ print("stack_advisor_hdp23 not found")
 
 class HDP24StackAdvisor(HDP23StackAdvisor):
  pass

http://git-wip-us.apache.org/repos/asf/ambari/blob/6f8d546a/ambari-server/src/main/resources/stacks/HDP/2.5/services/stack_advisor.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.5/services/stack_advisor.py b/ambari-server/src/main/resources/stacks/HDP/2.5/services/stack_advisor.py
index 2a5d76b..a8eba78 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.5/services/stack_advisor.py
+++ b/ambari-server/src/main/resources/stacks/HDP/2.5/services/stack_advisor.py
@@ -24,6 +24,11 @@ from ambari_commons.str_utils import string_set_equals
 from resource_management.core.exceptions import Fail
 from resource_management.libraries.functions.get_bare_principal import get_bare_principal
 
+try:
+  from stack_advisor_hdp24 import *
+except ImportError:
+  #Ignore ImportError
+  print("stack_advisor_hdp24 not found")
 
 class HDP25StackAdvisor(HDP24StackAdvisor):
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/6f8d546a/ambari-server/src/main/resources/stacks/HDP/2.6/services/stack_advisor.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.6/services/stack_advisor.py b/ambari-server/src/main/resources/stacks/HDP/2.6/services/stack_advisor.py
index 723ff4e..4daab86 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.6/services/stack_advisor.py
+++ b/ambari-server/src/main/resources/stacks/HDP/2.6/services/stack_advisor.py
@@ -22,6 +22,11 @@ import json
 import re
 from resource_management.libraries.functions import format
 
+try:
+    from stack_advisor_hdp25 import *
+except ImportError:
+    #Ignore ImportError
+    print("stack_advisor_hdp25 not found")
 
 class HDP26StackAdvisor(HDP25StackAdvisor):
   def __init__(self):