You are viewing a plain text version of this content. The canonical link for it is here.
Posted to common-commits@hadoop.apache.org by ji...@apache.org on 2016/12/07 21:11:03 UTC

[63/76] [abbrv] hadoop git commit: YARN-5505. Create an agent-less docker provider in the native-services framework. Contributed by Billie Rinaldi

http://git-wip-us.apache.org/repos/asf/hadoop/blob/cb61fe3f/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-slider/hadoop-yarn-slider-core/src/main/java/org/apache/slider/providers/docker/DockerProviderService.java
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-slider/hadoop-yarn-slider-core/src/main/java/org/apache/slider/providers/docker/DockerProviderService.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-slider/hadoop-yarn-slider-core/src/main/java/org/apache/slider/providers/docker/DockerProviderService.java
new file mode 100644
index 0000000..bebb5f0
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-slider/hadoop-yarn-slider-core/src/main/java/org/apache/slider/providers/docker/DockerProviderService.java
@@ -0,0 +1,355 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.slider.providers.docker;
+
+import org.apache.hadoop.fs.Path;
+import org.apache.hadoop.registry.client.types.ServiceRecord;
+import org.apache.hadoop.yarn.api.ApplicationConstants;
+import org.apache.hadoop.yarn.api.records.Container;
+import org.apache.hadoop.yarn.api.records.ContainerId;
+import org.apache.hadoop.yarn.api.records.ContainerStatus;
+import org.apache.hadoop.yarn.api.records.LocalResource;
+import org.apache.hadoop.yarn.api.records.LocalResourceType;
+import org.apache.slider.api.ClusterDescription;
+import org.apache.slider.api.ClusterNode;
+import org.apache.slider.api.OptionKeys;
+import org.apache.slider.common.SliderKeys;
+import org.apache.slider.common.tools.SliderFileSystem;
+import org.apache.slider.common.tools.SliderUtils;
+import org.apache.slider.core.conf.AggregateConf;
+import org.apache.slider.core.conf.ConfTreeOperations;
+import org.apache.slider.core.conf.MapOperations;
+import org.apache.slider.core.exceptions.SliderException;
+import org.apache.slider.core.launch.CommandLineBuilder;
+import org.apache.slider.core.launch.ContainerLauncher;
+import org.apache.slider.core.registry.docstore.ConfigFormat;
+import org.apache.slider.core.registry.docstore.ConfigUtils;
+import org.apache.slider.core.registry.docstore.ExportEntry;
+import org.apache.slider.providers.AbstractProviderService;
+import org.apache.slider.providers.ProviderCore;
+import org.apache.slider.providers.ProviderRole;
+import org.apache.slider.providers.ProviderUtils;
+import org.apache.slider.server.appmaster.state.RoleInstance;
+import org.apache.slider.server.appmaster.state.StateAccessForProviders;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Scanner;
+
+public class DockerProviderService extends AbstractProviderService implements
+    ProviderCore,
+    DockerKeys,
+    SliderKeys {
+
+  protected static final Logger log =
+      LoggerFactory.getLogger(DockerProviderService.class);
+  private static final ProviderUtils providerUtils = new ProviderUtils(log);
+  private static final String EXPORT_GROUP = "quicklinks";
+  private static final String APPLICATION_TAG = "application";
+
+  private String clusterName = null;
+  private SliderFileSystem fileSystem = null;
+
+  protected DockerProviderService() {
+    super("DockerProviderService");
+  }
+
+  @Override
+  public List<ProviderRole> getRoles() {
+    return Collections.emptyList();
+  }
+
+  @Override
+  public boolean isSupportedRole(String role) {
+    return true;
+  }
+
+  @Override
+  public void validateInstanceDefinition(AggregateConf instanceDefinition)
+      throws SliderException {
+  }
+
+  private String getClusterName() {
+    if (SliderUtils.isUnset(clusterName)) {
+      clusterName = getAmState().getInternalsSnapshot().get(OptionKeys.APPLICATION_NAME);
+    }
+    return clusterName;
+  }
+
+  @Override
+  public void buildContainerLaunchContext(ContainerLauncher launcher,
+      AggregateConf instanceDefinition, Container container,
+      ProviderRole providerRole, SliderFileSystem fileSystem,
+      Path generatedConfPath, MapOperations resourceComponent,
+      MapOperations appComponent, Path containerTmpDirPath)
+      throws IOException, SliderException {
+
+    String roleName = providerRole.name;
+    String roleGroup = providerRole.group;
+
+    initializeApplicationConfiguration(instanceDefinition, fileSystem,
+        roleGroup);
+
+    log.info("Build launch context for Docker");
+    log.debug(instanceDefinition.toString());
+
+    ConfTreeOperations appConf = instanceDefinition.getAppConfOperations();
+    launcher.setYarnDockerMode(true);
+    launcher.setDockerImage(appConf.getComponentOpt(roleGroup, DOCKER_IMAGE,
+        null));
+    launcher.setDockerNetwork(appConf.getComponentOpt(roleGroup, DOCKER_NETWORK,
+        DEFAULT_DOCKER_NETWORK));
+    launcher.setRunPrivilegedContainer(appConf.getComponentOptBool(roleGroup,
+        DOCKER_USE_PRIVILEGED, false));
+
+    // Set the environment
+    launcher.putEnv(SliderUtils.buildEnvMap(appComponent,
+        providerUtils.getStandardTokenMap(getAmState().getAppConfSnapshot(),
+            getAmState().getInternalsSnapshot(), roleName, roleGroup,
+            getClusterName())));
+
+    String workDir = ApplicationConstants.Environment.PWD.$();
+    launcher.setEnv("WORK_DIR", workDir);
+    log.info("WORK_DIR set to {}", workDir);
+    String logDir = ApplicationConstants.LOG_DIR_EXPANSION_VAR;
+    launcher.setEnv("LOG_DIR", logDir);
+    log.info("LOG_DIR set to {}", logDir);
+    if (System.getenv(HADOOP_USER_NAME) != null) {
+      launcher.setEnv(HADOOP_USER_NAME, System.getenv(HADOOP_USER_NAME));
+    }
+    //add english env
+    launcher.setEnv("LANG", "en_US.UTF-8");
+    launcher.setEnv("LC_ALL", "en_US.UTF-8");
+    launcher.setEnv("LANGUAGE", "en_US.UTF-8");
+
+    //local resources
+    providerUtils.localizePackages(launcher, fileSystem, appConf, roleGroup,
+        getClusterName());
+
+    if (SliderUtils.isHadoopClusterSecure(getConfig())) {
+      providerUtils.localizeServiceKeytabs(launcher, instanceDefinition,
+          fileSystem, getClusterName());
+    }
+
+    if (providerUtils.areStoresRequested(appComponent)) {
+      providerUtils.localizeContainerSecurityStores(launcher, container,
+          roleName, fileSystem, instanceDefinition, appComponent, getClusterName());
+    }
+
+    if (appComponent.getOptionBool(AM_CONFIG_GENERATION, false)) {
+      // build and localize configuration files
+      Map<String, Map<String, String>> configurations =
+          providerUtils.buildConfigurations(
+              instanceDefinition.getAppConfOperations(),
+              instanceDefinition.getInternalOperations(),
+              container.getId().toString(), roleName, roleGroup,
+              getAmState());
+      providerUtils.localizeConfigFiles(launcher, roleName, roleGroup,
+          appConf, configurations, launcher.getEnv(), fileSystem,
+          getClusterName());
+    }
+
+    //add the configuration resources
+    launcher.addLocalResources(fileSystem.submitDirectory(
+        generatedConfPath,
+        PROPAGATED_CONF_DIR_NAME));
+
+    CommandLineBuilder operation = new CommandLineBuilder();
+    operation.add(appConf.getComponentOpt(roleGroup, DOCKER_START_COMMAND,
+        "/bin/bash"));
+
+    operation.add("> " + ApplicationConstants.LOG_DIR_EXPANSION_VAR + "/"
+        + OUT_FILE + " 2>" + ERR_FILE);
+
+    launcher.addCommand(operation.build());
+
+    // Additional files to localize
+    String appResourcesString = instanceDefinition.getAppConfOperations()
+        .getGlobalOptions().getOption(APP_RESOURCES, null);
+    log.info("Configuration value for extra resources to localize: {}", appResourcesString);
+    if (null != appResourcesString) {
+      try (Scanner scanner = new Scanner(appResourcesString).useDelimiter(",")) {
+        while (scanner.hasNext()) {
+          String resource = scanner.next();
+          Path resourcePath = new Path(resource);
+          LocalResource extraResource = fileSystem.createAmResource(
+              fileSystem.getFileSystem().resolvePath(resourcePath),
+              LocalResourceType.FILE);
+          String destination = APP_RESOURCES_DIR + "/" + resourcePath.getName();
+          log.info("Localizing {} to {}", resourcePath, destination);
+          // TODO Can we try harder to avoid collisions?
+          launcher.addLocalResource(destination, extraResource);
+        }
+      }
+    }
+  }
+
+  @Override
+  public void initializeApplicationConfiguration(
+      AggregateConf instanceDefinition, SliderFileSystem fileSystem,
+      String roleGroup)
+      throws IOException, SliderException {
+        this.fileSystem = fileSystem;
+  }
+
+  @Override
+  public void applyInitialRegistryDefinitions(URL amWebURI,
+      ServiceRecord serviceRecord)
+      throws IOException {
+    super.applyInitialRegistryDefinitions(amWebURI, serviceRecord);
+
+    // identify client component
+    String clientName = null;
+    ConfTreeOperations appConf = getAmState().getAppConfSnapshot();
+    for (String component : appConf.getComponentNames()) {
+      if (COMPONENT_TYPE_CLIENT.equals(appConf.getComponentOpt(component,
+          COMPONENT_TYPE_KEY, null))) {
+        clientName = component;
+        break;
+      }
+    }
+    if (clientName == null) {
+      log.info("No client component specified, not publishing client configs");
+      return;
+    }
+
+    // register AM-generated client configs
+    // appConf should already be resolved!
+    MapOperations clientOperations = appConf.getComponent(clientName);
+    if (!clientOperations.getOptionBool(AM_CONFIG_GENERATION, false)) {
+      log.info("AM config generation is false, not publishing client configs");
+      return;
+    }
+
+    // build and localize configuration files
+    Map<String, Map<String, String>> configurations =
+        providerUtils.buildConfigurations(appConf, getAmState()
+            .getInternalsSnapshot(), null, clientName, clientName,
+            getAmState());
+
+    for (String configFileDN : configurations.keySet()) {
+      String configFileName = appConf.getComponentOpt(clientName,
+          OptionKeys.CONF_FILE_PREFIX + configFileDN + OptionKeys
+              .NAME_SUFFIX, null);
+      String configFileType = appConf.getComponentOpt(clientName,
+          OptionKeys.CONF_FILE_PREFIX + configFileDN + OptionKeys
+              .TYPE_SUFFIX, null);
+      if (configFileName == null && configFileType == null) {
+        continue;
+      }
+      ConfigFormat configFormat = ConfigFormat.resolve(configFileType);
+
+      Map<String, String> config = configurations.get(configFileDN);
+      ConfigUtils.prepConfigForTemplateOutputter(configFormat, config,
+          fileSystem, getClusterName(),
+          new File(configFileName).getName());
+      providerUtils.publishApplicationInstanceData(configFileDN, configFileDN,
+          config.entrySet(), getAmState());
+    }
+  }
+
+  @Override
+  public boolean processContainerStatus(ContainerId containerId,
+      ContainerStatus status) {
+    log.debug("Handling container status: {}", status);
+    if (SliderUtils.isEmpty(status.getIPs()) ||
+        SliderUtils.isUnset(status.getHost())) {
+      return true;
+    }
+    RoleInstance instance = getAmState().getOwnedContainer(containerId);
+    if (instance == null) {
+      // container is completed?
+      return false;
+    }
+
+    String roleName = instance.role;
+    String roleGroup = instance.group;
+    String containerIdStr = containerId.toString();
+
+    providerUtils.updateServiceRecord(getAmState(), yarnRegistry,
+        containerIdStr, roleName, status.getIPs(), status.getHost());
+
+    publishExportGroups(containerIdStr, roleName, roleGroup,
+        status.getHost());
+    return false;
+  }
+
+  /**
+   * This method looks for configuration properties of the form
+   * export.key,value and publishes the key,value pair. Standard tokens are
+   * substituted into the value, and COMPONENTNAME_HOST and THIS_HOST tokens
+   * are substituted with the actual hostnames of the containers.
+   */
+  protected void publishExportGroups(String containerId,
+      String roleName, String roleGroup, String thisHost) {
+    ConfTreeOperations appConf = getAmState().getAppConfSnapshot();
+    ConfTreeOperations internalsConf = getAmState().getInternalsSnapshot();
+
+    Map<String, String> exports = providerUtils.getExports(
+        getAmState().getAppConfSnapshot(), roleGroup);
+
+    String hostKeyFormat = "${%s_HOST}";
+
+    // publish export groups if any
+    Map<String, String> replaceTokens =
+        providerUtils.filterSiteOptions(
+            appConf.getComponent(roleGroup).options,
+            providerUtils.getStandardTokenMap(appConf, internalsConf, roleName,
+                roleGroup, containerId, getClusterName()));
+    for (Map.Entry<String, Map<String, ClusterNode>> entry :
+        getAmState().getRoleClusterNodeMapping().entrySet()) {
+      String hostName = providerUtils.getHostsList(
+          entry.getValue().values(), true).iterator().next();
+      replaceTokens.put(String.format(hostKeyFormat,
+          entry.getKey().toUpperCase(Locale.ENGLISH)), hostName);
+    }
+    replaceTokens.put("${THIS_HOST}", thisHost);
+
+    Map<String, List<ExportEntry>> entries = new HashMap<>();
+    for (Entry<String, String> export : exports.entrySet()) {
+      String value = export.getValue();
+      // replace host names and site properties
+      for (String token : replaceTokens.keySet()) {
+        if (value.contains(token)) {
+          value = value.replace(token, replaceTokens.get(token));
+        }
+      }
+      ExportEntry entry = new ExportEntry();
+      entry.setLevel(APPLICATION_TAG);
+      entry.setValue(value);
+      entry.setUpdatedTime(new Date().toString());
+      // over-write, app exports are singletons
+      entries.put(export.getKey(), new ArrayList(Arrays.asList(entry)));
+      log.info("Preparing to publish. Key {} and Value {}",
+          export.getKey(), value);
+    }
+    providerUtils.publishExportGroup(entries, getAmState(), EXPORT_GROUP);
+  }
+}

http://git-wip-us.apache.org/repos/asf/hadoop/blob/cb61fe3f/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-slider/hadoop-yarn-slider-core/src/main/java/org/apache/slider/providers/slideram/SliderAMProviderService.java
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-slider/hadoop-yarn-slider-core/src/main/java/org/apache/slider/providers/slideram/SliderAMProviderService.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-slider/hadoop-yarn-slider-core/src/main/java/org/apache/slider/providers/slideram/SliderAMProviderService.java
index 67d3647..c021b80 100644
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-slider/hadoop-yarn-slider-core/src/main/java/org/apache/slider/providers/slideram/SliderAMProviderService.java
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-slider/hadoop-yarn-slider-core/src/main/java/org/apache/slider/providers/slideram/SliderAMProviderService.java
@@ -103,13 +103,9 @@ public class SliderAMProviderService extends AbstractProviderService implements
 
   @Override
   public void applyInitialRegistryDefinitions(URL amWebURI,
-      URL agentOpsURI,
-      URL agentStatusURI,
       ServiceRecord serviceRecord)
       throws IOException {
     super.applyInitialRegistryDefinitions(amWebURI,
-        agentOpsURI,
-        agentStatusURI,
         serviceRecord);
     // now publish site.xml files
     YarnConfiguration defaultYarnConfig = new YarnConfiguration();

http://git-wip-us.apache.org/repos/asf/hadoop/blob/cb61fe3f/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-slider/hadoop-yarn-slider-core/src/main/java/org/apache/slider/server/appmaster/SliderAppMaster.java
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-slider/hadoop-yarn-slider-core/src/main/java/org/apache/slider/server/appmaster/SliderAppMaster.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-slider/hadoop-yarn-slider-core/src/main/java/org/apache/slider/server/appmaster/SliderAppMaster.java
index 983b5ba..57ec218 100644
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-slider/hadoop-yarn-slider-core/src/main/java/org/apache/slider/server/appmaster/SliderAppMaster.java
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-slider/hadoop-yarn-slider-core/src/main/java/org/apache/slider/server/appmaster/SliderAppMaster.java
@@ -784,8 +784,10 @@ public class SliderAppMaster extends AbstractSliderLaunchedService
               contentCache);
       initAMFilterOptions(serviceConf);
 
-      // start the agent web app
-      startAgentWebApp(appInformation, serviceConf, webAppApi);
+      if (providerService instanceof AgentProviderService) {
+        // start the agent web app
+        startAgentWebApp(appInformation, serviceConf, webAppApi);
+      }
       int webAppPort = deployWebApplication(webAppApi);
 
       String scheme = WebAppUtils.HTTP_PREFIX;
@@ -1296,8 +1298,6 @@ public class SliderAppMaster extends AbstractSliderLaunchedService
     
     // the registry is running, so register services
     URL amWebURI = new URL(appMasterProxiedUrl);
-    URL agentOpsURI = new URL(agentOpsUrl);
-    URL agentStatusURI = new URL(agentStatusUrl);
 
     //Give the provider restricted access to the state, registry
     setupInitialRegistryPaths();
@@ -1324,15 +1324,20 @@ public class SliderAppMaster extends AbstractSliderLaunchedService
             
     // internal services
     sliderAMProvider.applyInitialRegistryDefinitions(amWebURI,
-        agentOpsURI,
-        agentStatusURI,
         serviceRecord);
 
     // provider service dynamic definitions.
-    providerService.applyInitialRegistryDefinitions(amWebURI,
-        agentOpsURI,
-        agentStatusURI,
-        serviceRecord);
+    if (providerService instanceof AgentProviderService) {
+      URL agentOpsURI = new URL(agentOpsUrl);
+      URL agentStatusURI = new URL(agentStatusUrl);
+      ((AgentProviderService)providerService).applyInitialRegistryDefinitions(
+          amWebURI,
+          agentOpsURI,
+          agentStatusURI,
+          serviceRecord);
+    } else {
+      providerService.applyInitialRegistryDefinitions(amWebURI, serviceRecord);
+    }
 
     // set any provided attributes
     setProvidedServiceRecordAttributes(
@@ -2285,6 +2290,20 @@ public class SliderAppMaster extends AbstractSliderLaunchedService
       ContainerStatus containerStatus) {
     LOG_YARN.debug("Container Status: id={}, status={}", containerId,
         containerStatus);
+    if (providerService.processContainerStatus(containerId, containerStatus)) {
+      try {
+        Thread.sleep(1000);
+      } catch (InterruptedException e) {
+      }
+      RoleInstance cinfo = appState.getOwnedContainer(containerId);
+      if (cinfo != null) {
+        LOG_YARN.info("Re-requesting status for role {}, {}",
+            cinfo.role, containerId);
+        //trigger another async container status
+        nmClientAsync.getContainerStatusAsync(containerId,
+            cinfo.container.getNodeId());
+      }
+    }
   }
 
   @Override //  NMClientAsync.CallbackHandler 

http://git-wip-us.apache.org/repos/asf/hadoop/blob/cb61fe3f/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-slider/hadoop-yarn-slider-core/src/main/resources/org/apache/slider/slider.xml
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-slider/hadoop-yarn-slider-core/src/main/resources/org/apache/slider/slider.xml b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-slider/hadoop-yarn-slider-core/src/main/resources/org/apache/slider/slider.xml
index 37ac65c..a2517d5 100644
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-slider/hadoop-yarn-slider-core/src/main/resources/org/apache/slider/slider.xml
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-slider/hadoop-yarn-slider-core/src/main/resources/org/apache/slider/slider.xml
@@ -27,4 +27,8 @@
     <name>slider.provider.agent</name>
     <value>org.apache.slider.providers.agent.AgentProviderFactory</value>
   </property>
+  <property>
+    <name>slider.provider.docker</name>
+    <value>org.apache.slider.providers.docker.DockerProviderFactory</value>
+  </property>
 </configuration>

http://git-wip-us.apache.org/repos/asf/hadoop/blob/cb61fe3f/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-slider/hadoop-yarn-slider-core/src/test/resources/org/apache/slider/providers/docker/appConfig.json
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-slider/hadoop-yarn-slider-core/src/test/resources/org/apache/slider/providers/docker/appConfig.json b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-slider/hadoop-yarn-slider-core/src/test/resources/org/apache/slider/providers/docker/appConfig.json
new file mode 100644
index 0000000..c87f77c
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-slider/hadoop-yarn-slider-core/src/test/resources/org/apache/slider/providers/docker/appConfig.json
@@ -0,0 +1,42 @@
+{
+  "schema": "http://example.org/specification/v2.0.0",
+  "metadata": {},
+  "global": {
+    "am.config.generation": "true",
+    "component.unique.names": "true",
+
+    "export.app.monitor": "${COMPONENT1_HOST} : ${@//site/test-xml/xmlkey}",
+    "export.other.key": "exportvalue",
+
+    "docker.image": "docker.io/centos:centos6",
+    "docker.startCommand": "sleep 600",
+
+    "conf.test-json.type": "json",
+    "conf.test-json.name": "/tmp/test.json",
+    "conf.test-xml.type": "xml",
+    "conf.test-xml.name": "/tmp/test.xml",
+    "conf.test-properties.type": "properties",
+    "conf.test-properties.name": "/tmp/test.xml",
+    "conf.test-yaml.type": "yaml",
+    "conf.test-yaml.name": "/tmp/test.yaml",
+    "conf.test-env.type": "env",
+    "conf.test-env.name": "/tmp/testenv",
+    "conf.test-template.type": "template",
+    "conf.test-template.name": "/tmp/test.template",
+    "conf.test-hadoop-xml.type": "hadoop-xml",
+    "conf.test-hadoop-xml.name": "/tmp/test-hadoop.xml",
+
+    "site.test-json.jsonkey": "val1",
+    "site.test-xml.xmlkey": "val2",
+    "site.test-hadoop-xml.xmlkey": "val3",
+    "site.test-properties.propkey": "val4",
+    "site.test-yaml.yamlkey": "val5",
+    "site.test-env.content": "test ${envkey1} {{envkey2}} content",
+    "site.test-env.envkey1": "envval1",
+    "site.test-env.envkey2": "envval2",
+    "site.test-template.templatekey1": "templateval1",
+    "site.test-template.templatekey2": "templateval2"
+  },
+  "components": {
+  }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/hadoop/blob/cb61fe3f/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-slider/hadoop-yarn-slider-core/src/test/resources/org/apache/slider/providers/docker/resources.json
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-slider/hadoop-yarn-slider-core/src/test/resources/org/apache/slider/providers/docker/resources.json b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-slider/hadoop-yarn-slider-core/src/test/resources/org/apache/slider/providers/docker/resources.json
new file mode 100644
index 0000000..1b06224
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-slider/hadoop-yarn-slider-core/src/test/resources/org/apache/slider/providers/docker/resources.json
@@ -0,0 +1,16 @@
+{
+  "schema": "http://example.org/specification/v2.0.0",
+  "metadata": {},
+  "global": {},
+  "components": {
+    "slider-appmaster": {
+      "yarn.memory": "384"
+    },
+    "COMPONENT": {
+      "yarn.role.priority": "1",
+      "yarn.component.instances": 2,
+      "yarn.memory": "512",
+      "yarn.vcores": "2"
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/hadoop/blob/cb61fe3f/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-slider/hadoop-yarn-slider-core/src/test/resources/org/apache/slider/providers/docker/test.template
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-slider/hadoop-yarn-slider-core/src/test/resources/org/apache/slider/providers/docker/test.template b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-slider/hadoop-yarn-slider-core/src/test/resources/org/apache/slider/providers/docker/test.template
new file mode 100644
index 0000000..2922655
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-slider/hadoop-yarn-slider-core/src/test/resources/org/apache/slider/providers/docker/test.template
@@ -0,0 +1,16 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+test ${templatekey1} {{templatekey2}} content


---------------------------------------------------------------------
To unsubscribe, e-mail: common-commits-unsubscribe@hadoop.apache.org
For additional commands, e-mail: common-commits-help@hadoop.apache.org