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/10/20 16:37:20 UTC

ambari git commit: AMBARI-22272: HDP + HDF installation fails in Ambari 2.6 (jluniya)

Repository: ambari
Updated Branches:
  refs/heads/branch-2.6 0fc8e9036 -> 6e80904b6


AMBARI-22272: HDP + HDF installation fails in Ambari 2.6 (jluniya)


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

Branch: refs/heads/branch-2.6
Commit: 6e80904b63d63d242924e6de69a9c07972fa4ed7
Parents: 0fc8e90
Author: Jayush Luniya <jl...@hortonworks.com>
Authored: Fri Oct 20 09:37:18 2017 -0700
Committer: Jayush Luniya <jl...@hortonworks.com>
Committed: Fri Oct 20 09:37:18 2017 -0700

----------------------------------------------------------------------
 .../libraries/functions/repository_util.py      |  1 +
 .../libraries/script/script.py                  | 12 ++++-
 .../ambari/annotations/ExperimentalFeature.java |  7 ++-
 .../ambari/server/agent/CommandRepository.java  | 21 +++++++-
 .../AmbariCustomCommandExecutionHelper.java     | 57 +++++++++++++-------
 .../AmbariManagementControllerImpl.java         | 12 +++--
 .../server/controller/RepositoryResponse.java   | 30 ++++++++---
 .../internal/RepositoryResourceProvider.java    |  7 +++
 .../VersionDefinitionResourceProvider.java      | 16 ++++++
 .../server/orm/entities/RepositoryEntity.java   | 55 +++++++++++++------
 .../apache/ambari/server/stack/RepoUtil.java    | 11 +++-
 .../apache/ambari/server/stack/StackModule.java | 25 ++++++---
 .../server/stack/StackServiceDirectory.java     |  8 +++
 .../stack/UpdateActiveRepoVersionOnStartup.java |  4 ++
 .../ambari/server/state/RepositoryInfo.java     | 25 ++++++++-
 .../stack/upgrade/RepositoryVersionHelper.java  | 44 ++++++++++++++-
 .../RepositoryResourceProviderTest.java         |  4 +-
 .../upgrade/RepositoryVersionHelperTest.java    |  2 +-
 18 files changed, 278 insertions(+), 63 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/6e80904b/ambari-common/src/main/python/resource_management/libraries/functions/repository_util.py
----------------------------------------------------------------------
diff --git a/ambari-common/src/main/python/resource_management/libraries/functions/repository_util.py b/ambari-common/src/main/python/resource_management/libraries/functions/repository_util.py
index 9ca1fe7..f1c8ef1 100644
--- a/ambari-common/src/main/python/resource_management/libraries/functions/repository_util.py
+++ b/ambari-common/src/main/python/resource_management/libraries/functions/repository_util.py
@@ -150,3 +150,4 @@ class CommandRepositoryItem(object):
 
     self.ubuntu_components = [self.distribution if self.distribution else self.repo_name] + \
                              [self.components.replace(",", " ") if self.components else UBUNTU_REPO_COMPONENTS_POSTFIX]
+    self.applicable_services = _find_value(json_dict, 'applicableServices')

http://git-wip-us.apache.org/repos/asf/ambari/blob/6e80904b/ambari-common/src/main/python/resource_management/libraries/script/script.py
----------------------------------------------------------------------
diff --git a/ambari-common/src/main/python/resource_management/libraries/script/script.py b/ambari-common/src/main/python/resource_management/libraries/script/script.py
index b106ae9..ccb8a54 100644
--- a/ambari-common/src/main/python/resource_management/libraries/script/script.py
+++ b/ambari-common/src/main/python/resource_management/libraries/script/script.py
@@ -756,9 +756,19 @@ class Script(object):
     if self.available_packages_in_repos:
       return self.available_packages_in_repos
 
+    config = self.get_config()
+
+    service_name = config['serviceName'] if 'serviceName' in config else None
+    repos = CommandRepository(config['repositoryFile'])
+    repo_ids = [repo.repo_id for repo in repos.items]
+    Logger.info("Command repositories: {0}".format(", ".join(repo_ids)))
+    repos.items = [x for x in repos.items if (not x.applicable_services or service_name in x.applicable_services) ]
+    applicable_repo_ids = [repo.repo_id for repo in repos.items]
+    Logger.info("Applicable repositories: {0}".format(", ".join(applicable_repo_ids)))
+
     pkg_provider = get_provider("Package")
     try:
-      self.available_packages_in_repos = pkg_provider.get_available_packages_in_repos(CommandRepository(self.get_config()['repositoryFile']))
+      self.available_packages_in_repos = pkg_provider.get_available_packages_in_repos(repos)
     except Exception as err:
       Logger.exception("Unable to load available packages")
       self.available_packages_in_repos = []

http://git-wip-us.apache.org/repos/asf/ambari/blob/6e80904b/ambari-server/src/main/java/org/apache/ambari/annotations/ExperimentalFeature.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/annotations/ExperimentalFeature.java b/ambari-server/src/main/java/org/apache/ambari/annotations/ExperimentalFeature.java
index 2bd1252..93dd9b7 100644
--- a/ambari-server/src/main/java/org/apache/ambari/annotations/ExperimentalFeature.java
+++ b/ambari-server/src/main/java/org/apache/ambari/annotations/ExperimentalFeature.java
@@ -45,5 +45,10 @@ public enum ExperimentalFeature {
   /**
    * Upgrades from one stack vendor (FOO-1.0) to another (BAR-5.5.0).
    */
-  STACK_UPGRADES_BETWEEN_VENDORS
+  STACK_UPGRADES_BETWEEN_VENDORS,
+
+  /**
+   * Support for service-specific repos for custom services
+   */
+  CUSTOM_SERVICE_REPOS
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/6e80904b/ambari-server/src/main/java/org/apache/ambari/server/agent/CommandRepository.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/agent/CommandRepository.java b/ambari-server/src/main/java/org/apache/ambari/server/agent/CommandRepository.java
index a70326e..b0e6d6f 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/agent/CommandRepository.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/agent/CommandRepository.java
@@ -255,6 +255,11 @@ public class CommandRepository {
     @SerializedName("mirrorsList")
     private String m_mirrorsList;
 
+    @SerializedName("applicableServices")
+    @Experimental(feature = ExperimentalFeature.CUSTOM_SERVICE_REPOS,
+      comment = "Remove logic for handling custom service repos after enabling multi-mpack cluster deployment")
+    private List<String> m_applicableServices;
+
     private transient String m_osType;
 
     private Repository(RepositoryInfo info) {
@@ -265,6 +270,7 @@ public class CommandRepository {
       m_distribution = info.getDistribution();
       m_components = info.getComponents();
       m_mirrorsList = info.getMirrorsList();
+      m_applicableServices = info.getApplicableServices();
     }
 
     private Repository(String osType, RepositoryEntity entity) {
@@ -275,6 +281,7 @@ public class CommandRepository {
       m_components = entity.getComponents();
       m_mirrorsList = entity.getMirrorsList();
       m_osType = osType;
+      m_applicableServices = entity.getApplicableServices();
     }
 
     public void setRepoId(String repoId){
@@ -313,6 +320,18 @@ public class CommandRepository {
       return m_ambariManaged;
     }
 
+    @Experimental(feature = ExperimentalFeature.CUSTOM_SERVICE_REPOS,
+      comment = "Remove logic for handling custom service repos after enabling multi-mpack cluster deployment")
+    public void setApplicableServices(List<String> applicableServices) {
+      m_applicableServices = applicableServices;
+    }
+
+    @Experimental(feature = ExperimentalFeature.CUSTOM_SERVICE_REPOS,
+      comment = "Remove logic for handling custom service repos after enabling multi-mpack cluster deployment")
+    public List<String> getApplicableServices() {
+      return m_applicableServices;
+    }
+
     /**
      * {@inheritDoc}
      */
@@ -325,8 +344,8 @@ public class CommandRepository {
           .append("components", m_components)
           .append("id", m_repoId)
           .append("baseUrl", m_baseUrl)
+          .append("applicableServices", (m_applicableServices != null? String.join(",", m_applicableServices) : ""))
           .toString();
     }
-
   }
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/6e80904b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariCustomCommandExecutionHelper.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariCustomCommandExecutionHelper.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariCustomCommandExecutionHelper.java
index 5924ab7..d8712f2 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariCustomCommandExecutionHelper.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariCustomCommandExecutionHelper.java
@@ -110,6 +110,7 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import com.google.common.base.Function;
+import com.google.common.collect.ListMultimap;
 import com.google.gson.Gson;
 import com.google.gson.JsonArray;
 import com.google.gson.JsonElement;
@@ -1274,39 +1275,57 @@ public class AmbariCustomCommandExecutionHelper {
   @Experimental(feature=ExperimentalFeature.PATCH_UPGRADES)
   public CommandRepository getCommandRepository(final Cluster cluster, ServiceComponent component, final Host host) throws AmbariException {
 
-    final CommandRepository command = new CommandRepository();
+    final CommandRepository commandRepo = new CommandRepository();
     boolean sysPreppedHost = configs.areHostsSysPrepped().equalsIgnoreCase("true");
     StackId stackId = component.getDesiredStackId();
-    command.setRepositories(Collections.<RepositoryInfo>emptyList());
-    command.setStackName(stackId.getStackName());
-    command.getFeature().setPreInstalled(configs.areHostsSysPrepped());
-    command.getFeature().setIsScoped(!sysPreppedHost);
-
+    commandRepo.setRepositories(Collections.<RepositoryInfo>emptyList());
+    commandRepo.setStackName(stackId.getStackName());
+    commandRepo.getFeature().setPreInstalled(configs.areHostsSysPrepped());
+    commandRepo.getFeature().setIsScoped(!sysPreppedHost);
+    final ListMultimap<String, RepositoryInfo> stackReposByOs =
+      ambariMetaInfo.getStack(stackId.getStackName(), stackId.getStackVersion()).getRepositoriesByOs();
+
+    @Experimental(feature = ExperimentalFeature.CUSTOM_SERVICE_REPOS,
+      comment = "Remove logic for handling custom service repos after enabling multi-mpack cluster deployment")
     final BaseUrlUpdater<Void> updater = new BaseUrlUpdater<Void>(null) {
       @Override
       public Void apply(RepositoryVersionEntity rve) {
-        command.setRepositoryVersionId(rve.getId());
-        command.setRepositoryVersion(rve.getVersion());
-        command.setResolved(rve.isResolved());
-        command.setStackName(rve.getStackName());
+        commandRepo.setRepositoryVersionId(rve.getId());
+        commandRepo.setRepositoryVersion(rve.getVersion());
+        commandRepo.setResolved(rve.isResolved());
+        commandRepo.setStackName(rve.getStackName());
 
         // !!! a repository version entity has all the repos worked out.  We shouldn't use
         // the stack at all.
+        // NOTE: The only exception here is we will add applicableServices from the stack model
+        // if the repository version entity doesn't include it.
         for (OperatingSystemEntity osEntity : rve.getOperatingSystems()) {
           String osEntityFamily = os_family.find(osEntity.getOsType());
           if (osEntityFamily.equals(host.getOsFamily())) {
-            command.setRepositories(osEntity.getOsType(), osEntity.getRepositories());
+
+            commandRepo.setRepositories(osEntity.getOsType(), osEntity.getRepositories());
+            for(CommandRepository.Repository repo : commandRepo.getRepositories()) {
+              List<String> applicableServices = repo.getApplicableServices();
+              if(applicableServices == null || applicableServices.isEmpty()) {
+                List<RepositoryInfo> stackRepos = stackReposByOs.get(osEntity.getOsType());
+                for(RepositoryInfo stackRepo : stackRepos) {
+                  if(stackRepo.getRepoName().equals(repo.getRepoName()) && stackRepo.getRepoId().equals(repo.getRepoId())) {
+                    repo.setApplicableServices(stackRepo.getApplicableServices());
+                  }
+                }
+              }
+            }
 
             if (!osEntity.isAmbariManagedRepos()) {
-              command.setNonManaged();
+              commandRepo.setNonManaged();
             } else {
               if (rve.isLegacy()){
-                command.setLegacyRepoId(rve.getVersion());
-                command.setLegacyRepoFileName(rve.getStackName(), rve.getVersion());
-                command.getFeature().setIsScoped(false);
+                commandRepo.setLegacyRepoId(rve.getVersion());
+                commandRepo.setLegacyRepoFileName(rve.getStackName(), rve.getVersion());
+                commandRepo.getFeature().setIsScoped(false);
               } else {
-                command.setRepoFileName(rve.getStackName(), rve.getId());
-                command.setUniqueSuffix(String.format("-repo-%s", rve.getId()));
+                commandRepo.setRepoFileName(rve.getStackName(), rve.getId());
+                commandRepo.setUniqueSuffix(String.format("-repo-%s", rve.getId()));
               }
             }
           }
@@ -1320,10 +1339,10 @@ public class AmbariCustomCommandExecutionHelper {
 
     if (configs.arePackagesLegacyOverridden()) {
       LOG.warn("Legacy override option is turned on, disabling CommandRepositoryFeature.scoped feature");
-      command.getFeature().setIsScoped(false);
+      commandRepo.getFeature().setIsScoped(false);
     }
 
-    return command;
+    return commandRepo;
   }
 
   /**

http://git-wip-us.apache.org/repos/asf/ambari/blob/6e80904b/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 83521c6..2150f7e 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
@@ -67,6 +67,8 @@ import java.util.concurrent.TimeUnit;
 
 import javax.persistence.RollbackException;
 
+import org.apache.ambari.annotations.Experimental;
+import org.apache.ambari.annotations.ExperimentalFeature;
 import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.ClusterNotFoundException;
 import org.apache.ambari.server.DuplicateResourceException;
@@ -4467,6 +4469,8 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle
     return response;
   }
 
+  @Experimental(feature = ExperimentalFeature.CUSTOM_SERVICE_REPOS,
+    comment = "Remove logic for handling custom service repos after enabling multi-mpack cluster deployment")
   private Set<RepositoryResponse> getRepositories(RepositoryRequest request) throws AmbariException {
 
     String stackName = request.getStackName();
@@ -4493,8 +4497,10 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle
         for (OperatingSystemEntity operatingSystem: repositoryVersion.getOperatingSystems()) {
           if (operatingSystem.getOsType().equals(osType)) {
             for (RepositoryEntity repository: operatingSystem.getRepositories()) {
-              final RepositoryResponse response = new RepositoryResponse(repository.getBaseUrl(), osType, repository.getRepositoryId(),
-                      repository.getName(), repository.getDistribution(), repository.getComponents(), "", "", "");
+              final RepositoryResponse response = new RepositoryResponse(repository.getBaseUrl(), osType,
+                repository.getRepositoryId(),
+                repository.getName(), repository.getDistribution(), repository.getComponents(), "", "", "",
+                repository.getApplicableServices());
               if (null != versionDefinitionId) {
                 response.setVersionDefinitionId(versionDefinitionId);
               } else {
@@ -4523,7 +4529,7 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle
         for (RepositoryXml.Repo repo : os.getRepos()) {
           RepositoryResponse resp = new RepositoryResponse(repo.getBaseUrl(), os.getFamily(),
               repo.getRepoId(), repo.getRepoName(), repo.getDistribution(), repo.getComponents(), repo.getMirrorsList(),
-              repo.getBaseUrl(), repo.getLatestUri());
+              repo.getBaseUrl(), repo.getLatestUri(), Collections.EMPTY_LIST);
 
           resp.setVersionDefinitionId(versionDefinitionId);
           resp.setStackName(stackId.getStackName());

http://git-wip-us.apache.org/repos/asf/ambari/blob/6e80904b/ambari-server/src/main/java/org/apache/ambari/server/controller/RepositoryResponse.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/RepositoryResponse.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/RepositoryResponse.java
index c50414b..5ec46f0 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/RepositoryResponse.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/RepositoryResponse.java
@@ -18,6 +18,11 @@
 
 package org.apache.ambari.server.controller;
 
+import java.util.List;
+
+import org.apache.ambari.annotations.Experimental;
+import org.apache.ambari.annotations.ExperimentalFeature;
+
 public class RepositoryResponse {
 
   private String stackName;
@@ -36,9 +41,13 @@ public class RepositoryResponse {
   private Long clusterVersionId;
   private boolean unique;
 
+  @Experimental(feature = ExperimentalFeature.CUSTOM_SERVICE_REPOS,
+    comment = "Remove logic for handling custom service repos after enabling multi-mpack cluster deployment")
+  private List<String> applicableServices;
+
   public RepositoryResponse(String baseUrl, String osType, String repoId,
       String repoName, String distribution, String components,
-      String mirrorsList, String defaultBaseUrl, String latestBaseUrl) {
+      String mirrorsList, String defaultBaseUrl, String latestBaseUrl, List<String> applicableServices) {
     setBaseUrl(baseUrl);
     setOsType(osType);
     setRepoId(repoId);
@@ -48,6 +57,7 @@ public class RepositoryResponse {
     setMirrorsList(mirrorsList);
     setDefaultBaseUrl(defaultBaseUrl);
     setLatestBaseUrl(latestBaseUrl);
+    setApplicableServices(applicableServices);
   }
 
   public String getStackName() {
@@ -70,32 +80,26 @@ public class RepositoryResponse {
     return baseUrl;
   }
 
-
   public void setBaseUrl(String baseUrl) {
     this.baseUrl = baseUrl;
   }
 
-
   public String getOsType() {
     return osType;
   }
 
-
   public void setOsType(String osType) {
     this.osType = osType;
   }
 
-
   public String getRepoId() {
     return repoId;
   }
 
-
   public void setRepoId(String repoId) {
     this.repoId = repoId;
   }
 
-
   public String getRepoName() {
     return repoName;
   }
@@ -187,4 +191,16 @@ public class RepositoryResponse {
   public void setUnique(boolean unique) {
     this.unique = unique;
   }
+
+  @Experimental(feature = ExperimentalFeature.CUSTOM_SERVICE_REPOS,
+    comment = "Remove logic for handling custom service repos after enabling multi-mpack cluster deployment")
+  public List<String> getApplicableServices() {
+    return applicableServices;
+  }
+
+  @Experimental(feature = ExperimentalFeature.CUSTOM_SERVICE_REPOS,
+    comment = "Remove logic for handling custom service repos after enabling multi-mpack cluster deployment")
+  public void setApplicableServices(List<String> applicableServices) {
+    this.applicableServices = applicableServices;
+  }
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/6e80904b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/RepositoryResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/RepositoryResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/RepositoryResourceProvider.java
index 1686f4c..3c10e43 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/RepositoryResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/RepositoryResourceProvider.java
@@ -26,6 +26,8 @@ import java.util.Iterator;
 import java.util.Map;
 import java.util.Set;
 
+import org.apache.ambari.annotations.Experimental;
+import org.apache.ambari.annotations.ExperimentalFeature;
 import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.api.resources.RepositoryResourceDefinition;
 import org.apache.ambari.server.controller.AmbariManagementController;
@@ -62,6 +64,9 @@ public class RepositoryResourceProvider extends AbstractControllerResourceProvid
   public static final String REPOSITORY_REPOSITORY_VERSION_ID_PROPERTY_ID = PropertyHelper.getPropertyId("Repositories", "repository_version_id");
   public static final String REPOSITORY_VERSION_DEFINITION_ID_PROPERTY_ID = PropertyHelper.getPropertyId("Repositories", "version_definition_id");
   public static final String REPOSITORY_UNIQUE_PROPERTY_ID                = PropertyHelper.getPropertyId("Repositories", "unique");
+  @Experimental(feature = ExperimentalFeature.CUSTOM_SERVICE_REPOS,
+    comment = "Remove logic for handling custom service repos after enabling multi-mpack cluster deployment")
+  public static final String REPOSITORY_APPLICABLE_SERVICES_PROPERTY_ID   = PropertyHelper.getPropertyId("Repositories", "applicable_services");
 
   @SuppressWarnings("serial")
   private static Set<String> pkPropertyIds = new HashSet<String>() {
@@ -92,6 +97,7 @@ public class RepositoryResourceProvider extends AbstractControllerResourceProvid
       add(REPOSITORY_VERSION_DEFINITION_ID_PROPERTY_ID);
       add(REPOSITORY_CLUSTER_STACK_VERSION_PROPERTY_ID);
       add(REPOSITORY_UNIQUE_PROPERTY_ID);
+      add(REPOSITORY_APPLICABLE_SERVICES_PROPERTY_ID);
     }
   };
 
@@ -177,6 +183,7 @@ public class RepositoryResourceProvider extends AbstractControllerResourceProvid
         setResourceProperty(resource, REPOSITORY_DEFAULT_BASE_URL_PROPERTY_ID, response.getDefaultBaseUrl(), requestedIds);
         setResourceProperty(resource, REPOSITORY_LATEST_BASE_URL_PROPERTY_ID, response.getLatestBaseUrl(), requestedIds);
         setResourceProperty(resource, REPOSITORY_UNIQUE_PROPERTY_ID, response.isUnique(), requestedIds);
+        setResourceProperty(resource, REPOSITORY_APPLICABLE_SERVICES_PROPERTY_ID, response.getApplicableServices(), requestedIds);
         if (null != response.getClusterVersionId()) {
           setResourceProperty(resource, REPOSITORY_CLUSTER_STACK_VERSION_PROPERTY_ID, response.getClusterVersionId(), requestedIds);
         }

http://git-wip-us.apache.org/repos/asf/ambari/blob/6e80904b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/VersionDefinitionResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/VersionDefinitionResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/VersionDefinitionResourceProvider.java
index a377350..3ca81d7 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/VersionDefinitionResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/VersionDefinitionResourceProvider.java
@@ -30,6 +30,8 @@ import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Set;
 
+import org.apache.ambari.annotations.Experimental;
+import org.apache.ambari.annotations.ExperimentalFeature;
 import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.StaticallyInject;
 import org.apache.ambari.server.api.resources.OperatingSystemResourceDefinition;
@@ -588,6 +590,8 @@ public class VersionDefinitionResourceProvider extends AbstractAuthorizedResourc
    *
    * @throws AmbariException if some properties are missing or json has incorrect structure
    */
+  @Experimental(feature = ExperimentalFeature.CUSTOM_SERVICE_REPOS,
+    comment = "Remove logic for handling custom service repos after enabling multi-mpack cluster deployment")
   protected void toRepositoryVersionEntity(XmlHolder holder) throws AmbariException {
 
     // !!! TODO validate parsed object graph
@@ -775,6 +779,18 @@ public class VersionDefinitionResourceProvider extends AbstractAuthorizedResourc
             entity.getStackName());
         repoElement.put(PropertyHelper.getPropertyName(RepositoryResourceProvider.REPOSITORY_STACK_VERSION_PROPERTY_ID),
             entity.getStackVersion());
+
+        @Experimental(feature = ExperimentalFeature.CUSTOM_SERVICE_REPOS,
+          comment = "Remove logic for handling custom service repos after enabling multi-mpack cluster deployment")
+        ArrayNode applicableServicesNode = factory.arrayNode();
+        if(repo.getApplicableServices() != null) {
+          for (String applicableService : repo.getApplicableServices()) {
+            applicableServicesNode.add(applicableService);
+          }
+        }
+        repoElement.put(PropertyHelper.getPropertyName(
+          RepositoryResourceProvider.REPOSITORY_APPLICABLE_SERVICES_PROPERTY_ID), applicableServicesNode);
+
         repoBase.put(PropertyHelper.getPropertyCategory(RepositoryResourceProvider.REPOSITORY_BASE_URL_PROPERTY_ID),
             repoElement);
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/6e80904b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/RepositoryEntity.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/RepositoryEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/RepositoryEntity.java
index 6d7498b..034f3bc 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/RepositoryEntity.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/RepositoryEntity.java
@@ -17,6 +17,11 @@
  */
 package org.apache.ambari.server.orm.entities;
 
+import java.util.List;
+
+import org.apache.ambari.annotations.Experimental;
+import org.apache.ambari.annotations.ExperimentalFeature;
+
 /**
  * Emulates entity to provide a quick way to change it to real entity in future.
  */
@@ -29,6 +34,9 @@ public class RepositoryEntity {
   private String repositoryId;
   private String mirrorsList;
   private boolean unique;
+  @Experimental(feature = ExperimentalFeature.CUSTOM_SERVICE_REPOS,
+    comment = "Remove logic for handling custom service repos after enabling multi-mpack cluster deployment")
+  private List<String> applicableServices;
 
   public String getName() {
     return name;
@@ -70,6 +78,34 @@ public class RepositoryEntity {
     this.repositoryId = repositoryId;
   }
 
+  public String getMirrorsList() {
+    return mirrorsList;
+  }
+
+  public void setMirrorsList(String mirrorsList) {
+    this.mirrorsList = mirrorsList;
+  }
+
+  public boolean isUnique() {
+    return unique;
+  }
+
+  public void setUnique(boolean unique) {
+    this.unique = unique;
+  }
+
+  @Experimental(feature = ExperimentalFeature.CUSTOM_SERVICE_REPOS,
+    comment = "Remove logic for handling custom service repos after enabling multi-mpack cluster deployment")
+  public List<String> getApplicableServices() {
+    return applicableServices;
+  }
+
+  @Experimental(feature = ExperimentalFeature.CUSTOM_SERVICE_REPOS,
+    comment = "Remove logic for handling custom service repos after enabling multi-mpack cluster deployment")
+  public void setApplicableServices(List<String> applicableServices) {
+    this.applicableServices = applicableServices;
+  }
+
   @Override
   public boolean equals(Object o) {
     if (this == o) return true;
@@ -82,7 +118,7 @@ public class RepositoryEntity {
     if (components != null ? !components.equals(that.components) : that.components != null) return false;
     if (baseUrl != null ? !baseUrl.equals(that.baseUrl) : that.baseUrl != null) return false;
     if (repositoryId != null ? !repositoryId.equals(that.repositoryId) : that.repositoryId != null) return false;
-
+    if (applicableServices != null? !applicableServices.equals(that.applicableServices) : that.applicableServices != null) return false;
     return true;
   }
 
@@ -93,22 +129,7 @@ public class RepositoryEntity {
     result = 31 * result + (components != null ? components.hashCode() : 0);
     result = 31 * result + (baseUrl != null ? baseUrl.hashCode() : 0);
     result = 31 * result + (repositoryId != null ? repositoryId.hashCode() : 0);
+    result = 31 * result + (applicableServices != null ? applicableServices.hashCode() : 0);
     return result;
   }
-
-  public String getMirrorsList() {
-    return mirrorsList;
-  }
-
-  public void setMirrorsList(String mirrorsList) {
-    this.mirrorsList = mirrorsList;
-  }
-
-  public boolean isUnique() {
-    return unique;
-  }
-
-  public void setUnique(boolean unique) {
-    this.unique = unique;
-  }
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/6e80904b/ambari-server/src/main/java/org/apache/ambari/server/stack/RepoUtil.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/stack/RepoUtil.java b/ambari-server/src/main/java/org/apache/ambari/server/stack/RepoUtil.java
index 073fd82..81b4da9 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/stack/RepoUtil.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/stack/RepoUtil.java
@@ -26,6 +26,8 @@ import java.util.Set;
 
 import javax.annotation.Nullable;
 
+import org.apache.ambari.annotations.Experimental;
+import org.apache.ambari.annotations.ExperimentalFeature;
 import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.controller.RepositoryResponse;
 import org.apache.ambari.server.orm.entities.OperatingSystemEntity;
@@ -46,7 +48,7 @@ import com.google.common.collect.Multimaps;
 import com.google.common.collect.Sets;
 
 /**
- * Utility functions for repository replated tasks.
+ * Utility functions for repository related tasks.
  */
 public class RepoUtil {
 
@@ -117,6 +119,8 @@ public class RepoUtil {
    * @param stackReposByOs - Stack repositories loaded from the disk (including service repositories), grouped by os.
    * @return {@code true} if there were added repositories
    */
+  @Experimental(feature = ExperimentalFeature.CUSTOM_SERVICE_REPOS,
+    comment = "Remove logic for handling custom service repos after enabling multi-mpack cluster deployment")
   public static boolean addServiceReposToOperatingSystemEntities(List<OperatingSystemEntity> operatingSystems,
       ListMultimap<String, RepositoryInfo> stackReposByOs) {
     Set<String> addedRepos = new HashSet<>();
@@ -142,6 +146,8 @@ public class RepoUtil {
    * @param stackReposByOs the repositories in the stack model (loaded from disks)
    * @return A list of service repositories
    */
+  @Experimental(feature = ExperimentalFeature.CUSTOM_SERVICE_REPOS,
+    comment = "Remove logic for handling custom service repos after enabling multi-mpack cluster deployment")
   public static List<RepositoryInfo> getServiceRepos(List<RepositoryInfo> vdfRepos,
                                                    ListMultimap<String, RepositoryInfo> stackReposByOs) {
     Set<String> serviceRepoIds = new HashSet<>();
@@ -184,6 +190,8 @@ public class RepoUtil {
     return responses;
   }
 
+  @Experimental(feature = ExperimentalFeature.CUSTOM_SERVICE_REPOS,
+    comment = "Remove logic for handling custom service repos after enabling multi-mpack cluster deployment")
   private static RepositoryEntity toRepositoryEntity(RepositoryInfo repoInfo) {
     RepositoryEntity re = new RepositoryEntity();
     re.setBaseUrl(repoInfo.getBaseUrl());
@@ -191,6 +199,7 @@ public class RepoUtil {
     re.setRepositoryId(repoInfo.getRepoId());
     re.setDistribution(repoInfo.getDistribution());
     re.setComponents(repoInfo.getComponents());
+    re.setApplicableServices(repoInfo.getApplicableServices());
     return re;
   }
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/6e80904b/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 4f498d4..d770ac9 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
@@ -31,6 +31,8 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
+import org.apache.ambari.annotations.Experimental;
+import org.apache.ambari.annotations.ExperimentalFeature;
 import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.state.ConfigHelper;
 import org.apache.ambari.server.state.ExtensionInfo;
@@ -1138,7 +1140,7 @@ public class StackModule extends BaseModule<StackModule, StackInfo> implements V
     }
 
     LOG.debug("Process service custom repositories");
-    Set<RepositoryInfo> serviceRepos = getUniqueServiceRepos(stackRepos);
+    Collection<RepositoryInfo> serviceRepos = getUniqueServiceRepos(stackRepos);
     stackInfo.getRepositories().addAll(serviceRepos);
 
     if (null != rxml && null != rxml.getLatestURI() && stackRepos.size() > 0) {
@@ -1200,12 +1202,14 @@ public class StackModule extends BaseModule<StackModule, StackInfo> implements V
    * @param stackRepos the list of stack repositories
    * @return the service repos with duplicates filtered out.
    */
-  private Set<RepositoryInfo> getUniqueServiceRepos(List<RepositoryInfo> stackRepos) {
+  @Experimental(feature = ExperimentalFeature.CUSTOM_SERVICE_REPOS,
+    comment = "Remove logic for handling custom service repos after enabling multi-mpack cluster deployment")
+  private Collection<RepositoryInfo> getUniqueServiceRepos(List<RepositoryInfo> stackRepos) {
     List<RepositoryInfo> serviceRepos = getAllServiceRepos();
     ImmutableListMultimap<String, RepositoryInfo> serviceReposByOsType = Multimaps.index(serviceRepos, RepositoryInfo.GET_OSTYPE_FUNCTION);
     ImmutableListMultimap<String, RepositoryInfo> stackReposByOsType = Multimaps.index(stackRepos, RepositoryInfo.GET_OSTYPE_FUNCTION);
 
-    Set<RepositoryInfo> uniqueServiceRepos = new HashSet<>();
+    Map<String, RepositoryInfo> uniqueServiceRepos = new HashMap<>();
 
     // Uniqueness is checked for each os type
     for (String osType: serviceReposByOsType.keySet()) {
@@ -1232,11 +1236,16 @@ public class StackModule extends BaseModule<StackModule, StackInfo> implements V
           LOG.warn("Discarding service repository with duplicate name and different content: {}", repo);
         }
         else {
-          uniqueServiceRepos.add(repo);
+          String key = String.join("-", repo.getOsType(), repo.getRepoName(), repo.getRepoId());
+          if(uniqueServiceRepos.containsKey(key)) {
+            uniqueServiceRepos.get(key).getApplicableServices().addAll(repo.getApplicableServices());
+          } else {
+            uniqueServiceRepos.put(key, repo);
+          }
         }
       }
     }
-    return uniqueServiceRepos;
+    return uniqueServiceRepos.values();
   }
 
   /**
@@ -1273,7 +1282,11 @@ public class StackModule extends BaseModule<StackModule, StackInfo> implements V
         StackServiceDirectory ssd = (StackServiceDirectory) sd;
         RepositoryXml serviceRepoXml = ssd.getRepoFile();
         if (null != serviceRepoXml) {
-          repos.addAll(serviceRepoXml.getRepositories());
+          List<RepositoryInfo> serviceRepos = serviceRepoXml.getRepositories();
+          for(RepositoryInfo serviceRepo : serviceRepos) {
+            serviceRepo.getApplicableServices().add(sm.getId());
+          }
+          repos.addAll(serviceRepos);
           if (null != serviceRepoXml.getLatestURI()) {
             registerRepoUpdateTask(serviceRepoXml);
           }

http://git-wip-us.apache.org/repos/asf/ambari/blob/6e80904b/ambari-server/src/main/java/org/apache/ambari/server/stack/StackServiceDirectory.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/stack/StackServiceDirectory.java b/ambari-server/src/main/java/org/apache/ambari/server/stack/StackServiceDirectory.java
index ff35ec2..2a80d58 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/stack/StackServiceDirectory.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/stack/StackServiceDirectory.java
@@ -23,6 +23,8 @@ import java.util.Arrays;
 import java.util.Collection;
 import javax.annotation.Nullable;
 
+import org.apache.ambari.annotations.Experimental;
+import org.apache.ambari.annotations.ExperimentalFeature;
 import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.state.stack.RepositoryXml;
 
@@ -51,6 +53,8 @@ public class StackServiceDirectory extends ServiceDirectory {
    * repository directory
    */
   @Nullable
+  @Experimental(feature = ExperimentalFeature.CUSTOM_SERVICE_REPOS,
+    comment = "Remove logic for handling custom service repos after enabling multi-mpack cluster deployment")
   private String repoDir;
 
   /**
@@ -69,6 +73,8 @@ public class StackServiceDirectory extends ServiceDirectory {
    * @return the repository xml file if exists or null
    */
   @Nullable
+  @Experimental(feature = ExperimentalFeature.CUSTOM_SERVICE_REPOS,
+    comment = "Remove logic for handling custom service repos after enabling multi-mpack cluster deployment")
   public RepositoryXml getRepoFile() {
     return repoFile;
   }
@@ -79,6 +85,8 @@ public class StackServiceDirectory extends ServiceDirectory {
    * @return the repository directory if exists or null
    */
   @Nullable
+  @Experimental(feature = ExperimentalFeature.CUSTOM_SERVICE_REPOS,
+    comment = "Remove logic for handling custom service repos after enabling multi-mpack cluster deployment")
   public String getRepoDir() {
     return repoDir;
   }

http://git-wip-us.apache.org/repos/asf/ambari/blob/6e80904b/ambari-server/src/main/java/org/apache/ambari/server/stack/UpdateActiveRepoVersionOnStartup.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/stack/UpdateActiveRepoVersionOnStartup.java b/ambari-server/src/main/java/org/apache/ambari/server/stack/UpdateActiveRepoVersionOnStartup.java
index b7064df..f7e1c2b 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/stack/UpdateActiveRepoVersionOnStartup.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/stack/UpdateActiveRepoVersionOnStartup.java
@@ -20,6 +20,8 @@ package org.apache.ambari.server.stack;
 
 import java.util.List;
 
+import org.apache.ambari.annotations.Experimental;
+import org.apache.ambari.annotations.ExperimentalFeature;
 import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.api.services.AmbariMetaInfo;
 import org.apache.ambari.server.orm.dao.ClusterDAO;
@@ -47,6 +49,8 @@ import com.google.inject.persist.Transactional;
  * cluster, the cluster's repository version entity must be updated with the custom repos provided by the
  * management pack. The class takes care of this.
  */
+@Experimental(feature = ExperimentalFeature.CUSTOM_SERVICE_REPOS,
+  comment = "Remove logic for handling custom service repos after enabling multi-mpack cluster deployment")
 public class UpdateActiveRepoVersionOnStartup {
 
   private static final Logger LOG = LoggerFactory.getLogger(UpdateActiveRepoVersionOnStartup.class);

http://git-wip-us.apache.org/repos/asf/ambari/blob/6e80904b/ambari-server/src/main/java/org/apache/ambari/server/state/RepositoryInfo.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/RepositoryInfo.java b/ambari-server/src/main/java/org/apache/ambari/server/state/RepositoryInfo.java
index ca96538..602d63b 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/RepositoryInfo.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/RepositoryInfo.java
@@ -18,7 +18,12 @@
 
 package org.apache.ambari.server.state;
 
+import java.util.LinkedList;
+import java.util.List;
 import com.google.common.base.Objects;
+
+import org.apache.ambari.annotations.Experimental;
+import org.apache.ambari.annotations.ExperimentalFeature;
 import org.apache.ambari.server.controller.RepositoryResponse;
 
 import com.google.common.base.Function;
@@ -37,6 +42,9 @@ public class RepositoryInfo {
   private boolean baseSaved = false;
   private boolean unique = false;
   private boolean ambariManagedRepositories = true;
+  @Experimental(feature = ExperimentalFeature.CUSTOM_SERVICE_REPOS,
+    comment = "Remove logic for handling custom service repos after enabling multi-mpack cluster deployment")
+  private List<String> applicableServices = new LinkedList<>();
 
   /**
    * @return the baseUrl
@@ -166,6 +174,18 @@ public class RepositoryInfo {
     baseSaved = saved;
   }
 
+  @Experimental(feature = ExperimentalFeature.CUSTOM_SERVICE_REPOS,
+    comment = "Remove logic for handling custom service repos after enabling multi-mpack cluster deployment")
+  public List<String> getApplicableServices() {
+    return applicableServices;
+  }
+
+  @Experimental(feature = ExperimentalFeature.CUSTOM_SERVICE_REPOS,
+    comment = "Remove logic for handling custom service repos after enabling multi-mpack cluster deployment")
+  public void setApplicableServices(List<String> applicableServices) {
+    this.applicableServices = applicableServices;
+  }
+
   @Override
   public String toString() {
     return "[ repoInfo: "
@@ -178,6 +198,7 @@ public class RepositoryInfo {
         + ", mirrorsList=" + mirrorsList
         + ", unique=" + unique
         + ", ambariManagedRepositories=" + ambariManagedRepositories
+        + ", applicableServices=" +  String.join(",", applicableServices)
         + " ]";
   }
 
@@ -206,8 +227,8 @@ public class RepositoryInfo {
 
   public RepositoryResponse convertToResponse()
   {
-    return new RepositoryResponse(getBaseUrl(), getOsType(), getRepoId(),
-        getRepoName(), getDistribution(), getComponents(), getMirrorsList(), getDefaultBaseUrl(), getLatestBaseUrl());
+    return new RepositoryResponse(getBaseUrl(), getOsType(), getRepoId(), getRepoName(), getDistribution(),
+      getComponents(), getMirrorsList(), getDefaultBaseUrl(), getLatestBaseUrl(), getApplicableServices());
   }
 
   /**

http://git-wip-us.apache.org/repos/asf/ambari/blob/6e80904b/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/RepositoryVersionHelper.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/RepositoryVersionHelper.java b/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/RepositoryVersionHelper.java
index 7454adf..1901950 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/RepositoryVersionHelper.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/RepositoryVersionHelper.java
@@ -20,11 +20,14 @@ package org.apache.ambari.server.state.stack.upgrade;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashMap;
+import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Set;
 
+import org.apache.ambari.annotations.Experimental;
+import org.apache.ambari.annotations.ExperimentalFeature;
 import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.agent.CommandRepository;
 import org.apache.ambari.server.agent.ExecutionCommand;
@@ -51,8 +54,10 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import com.google.common.collect.ArrayListMultimap;
+import com.google.common.collect.ListMultimap;
 import com.google.common.collect.Multimap;
 import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
 import com.google.gson.JsonArray;
 import com.google.gson.JsonElement;
 import com.google.gson.JsonObject;
@@ -136,6 +141,14 @@ public class RepositoryVersionHelper {
         if (repositoryJson.getAsJsonObject().get(RepositoryResourceProvider.REPOSITORY_UNIQUE_PROPERTY_ID) != null) {
           repositoryEntity.setUnique(repositoryJson.getAsJsonObject().get(RepositoryResourceProvider.REPOSITORY_UNIQUE_PROPERTY_ID).getAsBoolean());
         }
+        if (repositoryJson.get(RepositoryResourceProvider.REPOSITORY_APPLICABLE_SERVICES_PROPERTY_ID) != null) {
+          List<String> applicableServices = new LinkedList<>();
+          JsonArray jsonArray = repositoryJson.get(RepositoryResourceProvider.REPOSITORY_APPLICABLE_SERVICES_PROPERTY_ID).getAsJsonArray();
+          for(JsonElement je : jsonArray) {
+            applicableServices.add(je.getAsString());
+          }
+          repositoryEntity.setApplicableServices(applicableServices);
+        }
         operatingSystemEntity.getRepositories().add(repositoryEntity);
       }
       operatingSystems.add(operatingSystemEntity);
@@ -187,6 +200,12 @@ public class RepositoryVersionHelper {
         repositoryJson.addProperty(RepositoryResourceProvider.REPOSITORY_COMPONENTS_PROPERTY_ID, repository.getComponents());
         repositoryJson.addProperty(RepositoryResourceProvider.REPOSITORY_MIRRORS_LIST_PROPERTY_ID, repository.getMirrorsList());
         repositoryJson.addProperty(RepositoryResourceProvider.REPOSITORY_UNIQUE_PROPERTY_ID, repository.isUnique());
+
+        if(repository.getApplicableServices() != null) {
+          Gson gson = new GsonBuilder().create();
+          JsonArray applicableServicesJson = gson.toJsonTree(repository.getApplicableServices()).getAsJsonArray();
+          repositoryJson.add(RepositoryResourceProvider.REPOSITORY_APPLICABLE_SERVICES_PROPERTY_ID, applicableServicesJson);
+        }
         repositoriesJson.add(repositoryJson);
         operatingSystemJson.addProperty(OperatingSystemResourceProvider.OPERATING_SYSTEM_AMBARI_MANAGED_REPOS, repository.isAmbariManagedRepositories());
       }
@@ -312,13 +331,34 @@ public class RepositoryVersionHelper {
    * @param osEntity      the OS family
    * @param repoVersion   the repository version entity
    */
+  @Experimental(feature = ExperimentalFeature.CUSTOM_SERVICE_REPOS,
+    comment = "Remove logic for handling custom service repos in Ambari 3.0")
   public void addCommandRepository(ActionExecutionContext context,
-      RepositoryVersionEntity repoVersion, OperatingSystemEntity osEntity) {
+      RepositoryVersionEntity repoVersion, OperatingSystemEntity osEntity) throws SystemException {
 
     final CommandRepository commandRepo = new CommandRepository();
     boolean sysPreppedHost = configuration.get().areHostsSysPrepped().equalsIgnoreCase("true");
-
+    StackId stackId = repoVersion.getStackId();
+    ListMultimap<String, RepositoryInfo> stackReposByOs = null;
+    try {
+      stackReposByOs =
+        ami.get().getStack(stackId.getStackName(), stackId.getStackVersion()).getRepositoriesByOs();
+    } catch (AmbariException e) {
+      throw new SystemException(String.format("Cannot obtain stack information for %s-%s", stackId.getStackName(), stackId.getStackVersion()), e);
+    }
     commandRepo.setRepositories(osEntity.getOsType(), osEntity.getRepositories());
+    for(CommandRepository.Repository repo : commandRepo.getRepositories()) {
+      List<String> applicableServices = repo.getApplicableServices();
+      if(applicableServices == null || applicableServices.isEmpty() && stackReposByOs != null) {
+        List<RepositoryInfo> stackRepos = stackReposByOs.get(osEntity.getOsType());
+        for(RepositoryInfo stackRepo : stackRepos) {
+          if(stackRepo.getRepoName().equals(repo.getRepoName()) && stackRepo.getRepoId().equals(repo.getRepoId())) {
+            repo.setApplicableServices(stackRepo.getApplicableServices());
+          }
+        }
+      }
+    }
+
     commandRepo.setRepositoryVersion(repoVersion.getVersion());
     commandRepo.setRepositoryVersionId(repoVersion.getId());
     commandRepo.setResolved(repoVersion.isResolved());

http://git-wip-us.apache.org/repos/asf/ambari/blob/6e80904b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/RepositoryResourceProviderTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/RepositoryResourceProviderTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/RepositoryResourceProviderTest.java
index 0788838..c46cce7 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/RepositoryResourceProviderTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/RepositoryResourceProviderTest.java
@@ -57,7 +57,7 @@ public class RepositoryResourceProviderTest {
     AmbariManagementController managementController = EasyMock.createMock(AmbariManagementController.class);
 
     RepositoryResponse rr = new RepositoryResponse(VAL_BASE_URL, VAL_OS,
-        VAL_REPO_ID, VAL_REPO_NAME, VAL_DISTRIBUTION, VAL_COMPONENT_NAME, null, null, null);
+        VAL_REPO_ID, VAL_REPO_NAME, VAL_DISTRIBUTION, VAL_COMPONENT_NAME, null, null, null, null);
     rr.setStackName(VAL_STACK_NAME);
     rr.setStackVersion(VAL_STACK_VERSION);
     Set<RepositoryResponse> allResponse = new HashSet<RepositoryResponse>();
@@ -169,7 +169,7 @@ public class RepositoryResourceProviderTest {
     AmbariManagementController managementController = EasyMock.createMock(AmbariManagementController.class);
 
     RepositoryResponse rr = new RepositoryResponse(VAL_BASE_URL, VAL_OS,
-        VAL_REPO_ID, VAL_REPO_NAME, null, null, null, null ,null);
+        VAL_REPO_ID, VAL_REPO_NAME, null, null, null, null ,null, null);
     Set<RepositoryResponse> allResponse = new HashSet<RepositoryResponse>();
     allResponse.add(rr);
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/6e80904b/ambari-server/src/test/java/org/apache/ambari/server/state/stack/upgrade/RepositoryVersionHelperTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/state/stack/upgrade/RepositoryVersionHelperTest.java b/ambari-server/src/test/java/org/apache/ambari/server/state/stack/upgrade/RepositoryVersionHelperTest.java
index 422c0ec..70ff801 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/state/stack/upgrade/RepositoryVersionHelperTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/state/stack/upgrade/RepositoryVersionHelperTest.java
@@ -53,6 +53,6 @@ public class RepositoryVersionHelperTest {
     repositories.add(repository);
 
     final String serialized = helper.serializeOperatingSystems(repositories);
-    Assert.assertEquals("[{\"OperatingSystems/ambari_managed_repositories\":true,\"repositories\":[{\"Repositories/base_url\":\"baseurl\",\"Repositories/repo_id\":\"repoId\",\"Repositories/unique\":true}],\"OperatingSystems/os_type\":\"os\"}]", serialized);
+    Assert.assertEquals("[{\"OperatingSystems/ambari_managed_repositories\":true,\"repositories\":[{\"Repositories/base_url\":\"baseurl\",\"Repositories/repo_id\":\"repoId\",\"Repositories/unique\":true,\"Repositories/applicable_services\":[]}],\"OperatingSystems/os_type\":\"os\"}]", serialized);
   }
 }