YARN-8448. AM HTTPS Support for AM communication with RMWeb proxy. (Contributed 
by Robert Kanter)


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

Branch: refs/heads/HDDS-4
Commit: c2288ac45b748b4119442c46147ccc324926c340
Parents: d59ca43
Author: Haibo Chen <haiboc...@apache.org>
Authored: Tue Oct 16 13:36:26 2018 -0700
Committer: Haibo Chen <haiboc...@apache.org>
Committed: Tue Oct 16 13:36:26 2018 -0700

----------------------------------------------------------------------
 .../org/apache/hadoop/security/Credentials.java |   1 +
 .../hadoop/security/ssl/KeyStoreTestUtil.java   |  21 +-
 .../hadoop/yarn/api/ApplicationConstants.java   |  22 +
 .../hadoop/yarn/conf/YarnConfiguration.java     |  20 +
 .../src/main/resources/yarn-default.xml         |  18 +
 .../yarn/server/security/AMSecretKeys.java      |  45 ++
 .../nodemanager/DefaultContainerExecutor.java   |  14 +
 .../nodemanager/LinuxContainerExecutor.java     |   4 +
 .../launcher/ContainerLaunch.java               |  50 ++
 .../launcher/ContainerRelaunch.java             |  23 +
 .../runtime/DefaultLinuxContainerRuntime.java   |  14 +-
 .../runtime/DockerLinuxContainerRuntime.java    |  36 +-
 .../runtime/LinuxContainerRuntimeConstants.java |   4 +
 .../executor/ContainerStartContext.java         |  24 +
 .../impl/container-executor.c                   | 121 ++++-
 .../impl/container-executor.h                   |  17 +-
 .../main/native/container-executor/impl/main.c  |  35 +-
 .../main/native/container-executor/impl/util.h  |   6 +-
 .../test/test-container-executor.c              | 228 +++++---
 .../TestDefaultContainerExecutor.java           | 157 ++++++
 .../TestLinuxContainerExecutorWithMocks.java    | 115 ++--
 .../launcher/TestContainerLaunch.java           | 149 ++++++
 .../launcher/TestContainerRelaunch.java         |  32 +-
 .../runtime/TestDockerContainerRuntime.java     | 225 ++++----
 .../resourcemanager/RMActiveServiceContext.java |  15 +
 .../yarn/server/resourcemanager/RMContext.java  |   5 +
 .../server/resourcemanager/RMContextImpl.java   |  11 +
 .../server/resourcemanager/ResourceManager.java |   9 +
 .../resourcemanager/amlauncher/AMLauncher.java  |  29 ++
 .../security/ProxyCAManager.java                |  68 +++
 .../TestApplicationMasterLauncher.java          |  86 ++-
 .../security/TestProxyCAManager.java            |  51 ++
 .../hadoop/yarn/server/webproxy/ProxyCA.java    | 408 +++++++++++++++
 .../yarn/server/webproxy/WebAppProxy.java       |   1 +
 .../server/webproxy/WebAppProxyServlet.java     |  89 +++-
 .../yarn/server/webproxy/TestProxyCA.java       | 518 +++++++++++++++++++
 .../server/webproxy/TestWebAppProxyServlet.java |  58 ++-
 37 files changed, 2406 insertions(+), 323 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/hadoop/blob/c2288ac4/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/Credentials.java
----------------------------------------------------------------------
diff --git 
a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/Credentials.java
 
b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/Credentials.java
index 6a9527a..4fafa4a 100644
--- 
a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/Credentials.java
+++ 
b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/Credentials.java
@@ -59,6 +59,7 @@ import org.slf4j.LoggerFactory;
 @InterfaceAudience.Public
 @InterfaceStability.Evolving
 public class Credentials implements Writable {
+
   public enum SerializedFormat {
     WRITABLE((byte) 0x00),
     PROTOBUF((byte) 0x01);

http://git-wip-us.apache.org/repos/asf/hadoop/blob/c2288ac4/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/security/ssl/KeyStoreTestUtil.java
----------------------------------------------------------------------
diff --git 
a/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/security/ssl/KeyStoreTestUtil.java
 
b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/security/ssl/KeyStoreTestUtil.java
index 898c94e..1870b22 100644
--- 
a/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/security/ssl/KeyStoreTestUtil.java
+++ 
b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/security/ssl/KeyStoreTestUtil.java
@@ -25,6 +25,7 @@ import 
org.apache.hadoop.security.alias.CredentialProviderFactory;
 import org.apache.hadoop.security.alias.JavaKeyStoreProvider;
 import org.apache.hadoop.test.GenericTestUtils;
 
+import java.io.ByteArrayInputStream;
 import java.io.File;
 import java.io.FileOutputStream;
 import java.io.FileWriter;
@@ -50,6 +51,7 @@ import java.security.NoSuchProviderException;
 import java.security.SignatureException;
 import java.security.cert.CertificateEncodingException;
 import javax.security.auth.x500.X500Principal;
+
 import org.bouncycastle.x509.X509V1CertificateGenerator;
 
 public class KeyStoreTestUtil {
@@ -127,9 +129,16 @@ public class KeyStoreTestUtil {
       String password, String alias,
       Key privateKey, Certificate cert)
       throws GeneralSecurityException, IOException {
-    KeyStore ks = createEmptyKeyStore();
-    ks.setKeyEntry(alias, privateKey, password.toCharArray(),
+    createKeyStore(filename, password, alias, privateKey,
         new Certificate[]{cert});
+  }
+
+  public static void createKeyStore(String filename,
+      String password, String alias,
+      Key privateKey, Certificate[] certs)
+      throws GeneralSecurityException, IOException {
+    KeyStore ks = createEmptyKeyStore();
+    ks.setKeyEntry(alias, privateKey, password.toCharArray(), certs);
     saveKeyStore(ks, filename, password);
   }
 
@@ -174,6 +183,14 @@ public class KeyStoreTestUtil {
     saveKeyStore(ks, filename, password);
   }
 
+  public static KeyStore bytesToKeyStore(byte[] bytes, String password)
+      throws GeneralSecurityException, IOException {
+    KeyStore keyStore = createEmptyKeyStore();
+    ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
+    keyStore.load(bais, password.toCharArray());
+    return keyStore;
+  }
+
   public static void cleanupSSLConfig(String keystoresDir, String sslConfDir)
       throws Exception {
     File f = new File(keystoresDir + "/clientKS.jks");

http://git-wip-us.apache.org/repos/asf/hadoop/blob/c2288ac4/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/api/ApplicationConstants.java
----------------------------------------------------------------------
diff --git 
a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/api/ApplicationConstants.java
 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/api/ApplicationConstants.java
index b63fe61..490e95e 100644
--- 
a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/api/ApplicationConstants.java
+++ 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/api/ApplicationConstants.java
@@ -48,6 +48,28 @@ public interface ApplicationConstants {
       UserGroupInformation.HADOOP_TOKEN_FILE_LOCATION;
 
   /**
+   * The file into which the keystore containing the AM's certificate is
+   * written.
+   */
+  String KEYSTORE_FILE_LOCATION_ENV_NAME = "KEYSTORE_FILE_LOCATION";
+
+  /**
+   * The password for the AM's keystore.
+   */
+  String KEYSTORE_PASSWORD_ENV_NAME = "KEYSTORE_PASSWORD";
+
+  /**
+   * The file into which the truststore containing the AM's certificate is
+   * written.
+   */
+  String TRUSTSTORE_FILE_LOCATION_ENV_NAME = "TRUSTSTORE_FILE_LOCATION";
+
+  /**
+   * The password for the AM's truststore.
+   */
+  String TRUSTSTORE_PASSWORD_ENV_NAME = "TRUSTSTORE_PASSWORD";
+
+  /**
    * The environmental variable for APPLICATION_WEB_PROXY_BASE. Set in
    * ApplicationMaster's environment only. This states that for all 
non-relative
    * web URLs in the app masters web UI what base should they have.

http://git-wip-us.apache.org/repos/asf/hadoop/blob/c2288ac4/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/conf/YarnConfiguration.java
----------------------------------------------------------------------
diff --git 
a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/conf/YarnConfiguration.java
 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/conf/YarnConfiguration.java
index 6488ebf..ce38d27 100644
--- 
a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/conf/YarnConfiguration.java
+++ 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/conf/YarnConfiguration.java
@@ -2132,6 +2132,26 @@ public class YarnConfiguration extends Configuration {
       3000;
 
   /**
+   * Specifies what the RM does regarding HTTPS enforcement for communication
+   * with AM Web Servers, as well as generating and providing certificates.
+   * Possible values are:
+   * <ul>
+   *   <li>NONE - the RM will do nothing special.</li>
+   *   <li>LENIENT - the RM will generate and provide a keystore and truststore
+   *   to the AM, which it is free to use for HTTPS in its tracking URL web
+   *   server.  The RM proxy will still allow HTTP connections to AMs that opt
+   *   not to use HTTPS.</li>
+   *   <li>STRICT - this is the same as LENIENT, except that the RM proxy will
+   *   only allow HTTPS connections to AMs; HTTP connections will be blocked
+   *   and result in a warning page to the user.</li>
+   * </ul>
+   */
+  public static final String RM_APPLICATION_HTTPS_POLICY =
+      RM_PREFIX + "application-https.policy";
+
+  public static final String DEFAULT_RM_APPLICATION_HTTPS_POLICY = "NONE";
+
+  /**
    * Interval of time the linux container executor should try cleaning up
    * cgroups entry when cleaning up a container. This is required due to what 
    * it seems a race condition because the SIGTERM/SIGKILL is asynch.

http://git-wip-us.apache.org/repos/asf/hadoop/blob/c2288ac4/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/resources/yarn-default.xml
----------------------------------------------------------------------
diff --git 
a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/resources/yarn-default.xml
 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/resources/yarn-default.xml
index 8e9f15b..2ea6bfc 100644
--- 
a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/resources/yarn-default.xml
+++ 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/resources/yarn-default.xml
@@ -3505,6 +3505,24 @@
 
   <property>
     <description>
+      Specifies what the RM does regarding HTTPS enforcement for communication
+      with AM Web Servers, as well as generating and providing certificates.
+      Possible values are:
+      - NONE - the RM will do nothing special.
+      - LENIENT - the RM will generate and provide a keystore and truststore
+      to the AM, which it is free to use for HTTPS in its tracking URL web
+      server.  The RM proxy will still allow HTTP connections to AMs that opt
+      not to use HTTPS.
+      - STRICT - this is the same as LENIENT, except that the RM proxy will
+      only allow HTTPS connections to AMs; HTTP connections will be blocked
+      and result in a warning page to the user.
+    </description>
+    <name>yarn.resourcemanager.application-https.policy</name>
+    <value>NONE</value>
+  </property>
+
+  <property>
+    <description>
       Defines the limit of the diagnostics message of an application
       attempt, in kilo characters (character count * 1024).
       When using ZooKeeper to store application state behavior, its

http://git-wip-us.apache.org/repos/asf/hadoop/blob/c2288ac4/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-common/src/main/java/org/apache/hadoop/yarn/server/security/AMSecretKeys.java
----------------------------------------------------------------------
diff --git 
a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-common/src/main/java/org/apache/hadoop/yarn/server/security/AMSecretKeys.java
 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-common/src/main/java/org/apache/hadoop/yarn/server/security/AMSecretKeys.java
new file mode 100644
index 0000000..e3f93d8
--- /dev/null
+++ 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-common/src/main/java/org/apache/hadoop/yarn/server/security/AMSecretKeys.java
@@ -0,0 +1,45 @@
+/**
+ * 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.hadoop.yarn.server.security;
+
+import org.apache.hadoop.classification.InterfaceAudience;
+import org.apache.hadoop.classification.InterfaceStability;
+import org.apache.hadoop.io.Text;
+
+/**
+ * Constants for AM Secret Keys.
+ */
+@InterfaceAudience.Private
+@InterfaceStability.Unstable
+public final class AMSecretKeys {
+
+  public final static Text YARN_APPLICATION_AM_KEYSTORE =
+      new Text("yarn.application.am.keystore");
+  public final static Text YARN_APPLICATION_AM_KEYSTORE_PASSWORD =
+      new Text("yarn.application.am.keystore.password");
+  public final static Text YARN_APPLICATION_AM_TRUSTSTORE =
+      new Text("yarn.application.am.truststore");
+  public final static Text YARN_APPLICATION_AM_TRUSTSTORE_PASSWORD =
+      new Text("yarn.application.am.truststore.password");
+
+  private AMSecretKeys() {
+    // not used
+  }
+}
+

http://git-wip-us.apache.org/repos/asf/hadoop/blob/c2288ac4/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/DefaultContainerExecutor.java
----------------------------------------------------------------------
diff --git 
a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/DefaultContainerExecutor.java
 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/DefaultContainerExecutor.java
index 4001333..b552c1f 100644
--- 
a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/DefaultContainerExecutor.java
+++ 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/DefaultContainerExecutor.java
@@ -218,6 +218,8 @@ public class DefaultContainerExecutor extends 
ContainerExecutor {
     Container container = ctx.getContainer();
     Path nmPrivateContainerScriptPath = ctx.getNmPrivateContainerScriptPath();
     Path nmPrivateTokensPath = ctx.getNmPrivateTokensPath();
+    Path nmPrivateKeystorePath = ctx.getNmPrivateKeystorePath();
+    Path nmPrivateTruststorePath = ctx.getNmPrivateTruststorePath();
     String user = ctx.getUser();
     Path containerWorkDir = ctx.getContainerWorkDir();
     List<String> localDirs = ctx.getLocalDirs();
@@ -253,6 +255,18 @@ public class DefaultContainerExecutor extends 
ContainerExecutor {
       new Path(containerWorkDir, ContainerLaunch.FINAL_CONTAINER_TOKENS_FILE);
     copyFile(nmPrivateTokensPath, tokenDst, user);
 
+    if (nmPrivateKeystorePath != null) {
+      Path keystoreDst =
+          new Path(containerWorkDir, ContainerLaunch.KEYSTORE_FILE);
+      copyFile(nmPrivateKeystorePath, keystoreDst, user);
+    }
+
+    if (nmPrivateTruststorePath != null) {
+      Path truststoreDst =
+          new Path(containerWorkDir, ContainerLaunch.TRUSTSTORE_FILE);
+      copyFile(nmPrivateTruststorePath, truststoreDst, user);
+    }
+
     // copy launch script to work dir
     Path launchDst =
         new Path(containerWorkDir, ContainerLaunch.CONTAINER_SCRIPT);

http://git-wip-us.apache.org/repos/asf/hadoop/blob/c2288ac4/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/LinuxContainerExecutor.java
----------------------------------------------------------------------
diff --git 
a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/LinuxContainerExecutor.java
 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/LinuxContainerExecutor.java
index 58d3068..3946eed 100644
--- 
a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/LinuxContainerExecutor.java
+++ 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/LinuxContainerExecutor.java
@@ -658,6 +658,10 @@ public class LinuxContainerExecutor extends 
ContainerExecutor {
         ctx.getNmPrivateContainerScriptPath())
       .setExecutionAttribute(NM_PRIVATE_TOKENS_PATH,
         ctx.getNmPrivateTokensPath())
+      .setExecutionAttribute(NM_PRIVATE_KEYSTORE_PATH,
+        ctx.getNmPrivateKeystorePath())
+      .setExecutionAttribute(NM_PRIVATE_TRUSTSTORE_PATH,
+        ctx.getNmPrivateTruststorePath())
       .setExecutionAttribute(PID_FILE_PATH, pidFilePath)
       .setExecutionAttribute(LOCAL_DIRS, ctx.getLocalDirs())
       .setExecutionAttribute(LOG_DIRS, ctx.getLogDirs())

http://git-wip-us.apache.org/repos/asf/hadoop/blob/c2288ac4/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/launcher/ContainerLaunch.java
----------------------------------------------------------------------
diff --git 
a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/launcher/ContainerLaunch.java
 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/launcher/ContainerLaunch.java
index f198e83..008c09b 100644
--- 
a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/launcher/ContainerLaunch.java
+++ 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/launcher/ContainerLaunch.java
@@ -91,6 +91,7 @@ import 
org.apache.hadoop.yarn.server.nodemanager.executor.ContainerReapContext;
 import 
org.apache.hadoop.yarn.server.nodemanager.executor.ContainerSignalContext;
 import 
org.apache.hadoop.yarn.server.nodemanager.executor.ContainerStartContext;
 import org.apache.hadoop.yarn.server.nodemanager.util.ProcessIdFileReader;
+import org.apache.hadoop.yarn.server.security.AMSecretKeys;
 import org.apache.hadoop.yarn.util.Apps;
 import org.apache.hadoop.yarn.util.AuxiliaryServiceHelper;
 
@@ -112,6 +113,9 @@ public class ContainerLaunch implements Callable<Integer> {
 
   public static final String FINAL_CONTAINER_TOKENS_FILE = "container_tokens";
 
+  public static final String KEYSTORE_FILE = "yarn_provided.keystore";
+  public static final String TRUSTSTORE_FILE = "yarn_provided.truststore";
+
   private static final String PID_FILE_NAME_FMT = "%s.pid";
   static final String EXIT_CODE_FILE_SUFFIX = ".exitcode";
 
@@ -232,6 +236,12 @@ public class ContainerLaunch implements Callable<Integer> {
           getContainerPrivateDir(appIdStr, containerIdStr) + Path.SEPARATOR
               + String.format(ContainerLocalizer.TOKEN_FILE_NAME_FMT,
               containerIdStr));
+      Path nmPrivateKeystorePath = dirsHandler.getLocalPathForWrite(
+          getContainerPrivateDir(appIdStr, containerIdStr) + Path.SEPARATOR
+              + KEYSTORE_FILE);
+      Path nmPrivateTruststorePath = dirsHandler.getLocalPathForWrite(
+          getContainerPrivateDir(appIdStr, containerIdStr) + Path.SEPARATOR
+              + TRUSTSTORE_FILE);
       Path nmPrivateClasspathJarDir = dirsHandler.getLocalPathForWrite(
           getContainerPrivateDir(appIdStr, containerIdStr));
 
@@ -267,6 +277,44 @@ public class ContainerLaunch implements Callable<Integer> {
         appDirs.add(new Path(appsdir, appIdStr));
       }
 
+      byte[] keystore = container.getCredentials().getSecretKey(
+          AMSecretKeys.YARN_APPLICATION_AM_KEYSTORE);
+      if (keystore != null) {
+        try (DataOutputStream keystoreOutStream =
+                 lfs.create(nmPrivateKeystorePath,
+                     EnumSet.of(CREATE, OVERWRITE))) {
+          keystoreOutStream.write(keystore);
+          environment.put(ApplicationConstants.KEYSTORE_FILE_LOCATION_ENV_NAME,
+              new Path(containerWorkDir,
+                  ContainerLaunch.KEYSTORE_FILE).toUri().getPath());
+          environment.put(ApplicationConstants.KEYSTORE_PASSWORD_ENV_NAME,
+              new String(container.getCredentials().getSecretKey(
+                  AMSecretKeys.YARN_APPLICATION_AM_KEYSTORE_PASSWORD),
+                  StandardCharsets.UTF_8));
+        }
+      } else {
+        nmPrivateKeystorePath = null;
+      }
+      byte[] truststore = container.getCredentials().getSecretKey(
+          AMSecretKeys.YARN_APPLICATION_AM_TRUSTSTORE);
+      if (truststore != null) {
+        try (DataOutputStream truststoreOutStream =
+                 lfs.create(nmPrivateTruststorePath,
+                     EnumSet.of(CREATE, OVERWRITE))) {
+          truststoreOutStream.write(truststore);
+          environment.put(
+              ApplicationConstants.TRUSTSTORE_FILE_LOCATION_ENV_NAME,
+              new Path(containerWorkDir,
+                  ContainerLaunch.TRUSTSTORE_FILE).toUri().getPath());
+          environment.put(ApplicationConstants.TRUSTSTORE_PASSWORD_ENV_NAME,
+              new String(container.getCredentials().getSecretKey(
+                  AMSecretKeys.YARN_APPLICATION_AM_TRUSTSTORE_PASSWORD),
+                  StandardCharsets.UTF_8));
+        }
+      } else {
+        nmPrivateTruststorePath = null;
+      }
+
       // Set the token location too.
       addToEnvMap(environment, nmEnvVars,
           ApplicationConstants.CONTAINER_TOKEN_FILE_ENV_NAME,
@@ -304,6 +352,8 @@ public class ContainerLaunch implements Callable<Integer> {
           .setLocalizedResources(localResources)
           .setNmPrivateContainerScriptPath(nmPrivateContainerScriptPath)
           .setNmPrivateTokensPath(nmPrivateTokensPath)
+          .setNmPrivateKeystorePath(nmPrivateKeystorePath)
+          .setNmPrivateTruststorePath(nmPrivateTruststorePath)
           .setUser(user)
           .setAppId(appIdStr)
           .setContainerWorkDir(containerWorkDir)

http://git-wip-us.apache.org/repos/asf/hadoop/blob/c2288ac4/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/launcher/ContainerRelaunch.java
----------------------------------------------------------------------
diff --git 
a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/launcher/ContainerRelaunch.java
 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/launcher/ContainerRelaunch.java
index a34ed62..307ded5 100644
--- 
a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/launcher/ContainerRelaunch.java
+++ 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/launcher/ContainerRelaunch.java
@@ -34,6 +34,7 @@ import 
org.apache.hadoop.yarn.server.nodemanager.containermanager.container.Cont
 import 
org.apache.hadoop.yarn.server.nodemanager.containermanager.container.ContainerExitEvent;
 import 
org.apache.hadoop.yarn.server.nodemanager.containermanager.localizer.ContainerLocalizer;
 import 
org.apache.hadoop.yarn.server.nodemanager.executor.ContainerStartContext;
+import org.apache.hadoop.yarn.server.security.AMSecretKeys;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -81,6 +82,12 @@ public class ContainerRelaunch extends ContainerLaunch {
           getNmPrivateContainerScriptPath(appIdStr, containerIdStr);
       Path nmPrivateTokensPath =
           getNmPrivateTokensPath(appIdStr, containerIdStr);
+      Path nmPrivateKeystorePath = (container.getCredentials().getSecretKey(
+          AMSecretKeys.YARN_APPLICATION_AM_KEYSTORE) == null) ? null :
+          getNmPrivateKeystorePath(appIdStr, containerIdStr);
+      Path nmPrivateTruststorePath = (container.getCredentials().getSecretKey(
+          AMSecretKeys.YARN_APPLICATION_AM_TRUSTSTORE) == null) ? null :
+          getNmPrivateTruststorePath(appIdStr, containerIdStr);
       pidFilePath = getPidFilePath(appIdStr, containerIdStr);
 
       LOG.info("Relaunch container with "
@@ -112,6 +119,8 @@ public class ContainerRelaunch extends ContainerLaunch {
           .setLocalizedResources(localResources)
           .setNmPrivateContainerScriptPath(nmPrivateContainerScriptPath)
           .setNmPrivateTokensPath(nmPrivateTokensPath)
+          .setNmPrivateKeystorePath(nmPrivateKeystorePath)
+          .setNmPrivateTruststorePath(nmPrivateTruststorePath)
           .setUser(container.getUser())
           .setAppId(appIdStr)
           .setContainerWorkDir(containerWorkDir)
@@ -173,6 +182,20 @@ public class ContainerRelaunch extends ContainerLaunch {
             containerIdStr));
   }
 
+  private Path getNmPrivateKeystorePath(String appIdStr,
+      String containerIdStr) throws IOException {
+    return dirsHandler.getLocalPathForRead(
+        getContainerPrivateDir(appIdStr, containerIdStr) + Path.SEPARATOR
+            + ContainerLaunch.KEYSTORE_FILE);
+  }
+
+  private Path getNmPrivateTruststorePath(String appIdStr,
+      String containerIdStr) throws IOException {
+    return dirsHandler.getLocalPathForRead(
+        getContainerPrivateDir(appIdStr, containerIdStr) + Path.SEPARATOR
+            + ContainerLaunch.TRUSTSTORE_FILE);
+  }
+
   private Path getPidFilePath(String appIdStr,
       String containerIdStr) throws IOException {
     return dirsHandler.getLocalPathForRead(

http://git-wip-us.apache.org/repos/asf/hadoop/blob/c2288ac4/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/linux/runtime/DefaultLinuxContainerRuntime.java
----------------------------------------------------------------------
diff --git 
a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/linux/runtime/DefaultLinuxContainerRuntime.java
 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/linux/runtime/DefaultLinuxContainerRuntime.java
index 82ca6d9..b4cead2 100644
--- 
a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/linux/runtime/DefaultLinuxContainerRuntime.java
+++ 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/linux/runtime/DefaultLinuxContainerRuntime.java
@@ -23,6 +23,7 @@ package 
org.apache.hadoop.yarn.server.nodemanager.containermanager.linux.runtime
 import org.apache.hadoop.classification.InterfaceAudience;
 import org.apache.hadoop.classification.InterfaceStability;
 import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.fs.Path;
 import org.apache.hadoop.util.StringUtils;
 import org.apache.hadoop.yarn.conf.YarnConfiguration;
 import org.apache.hadoop.yarn.server.nodemanager.ContainerExecutor;
@@ -106,8 +107,17 @@ public class DefaultLinuxContainerRuntime implements 
LinuxContainerRuntime {
         ctx.getExecutionAttribute(CONTAINER_WORK_DIR).toString(),
         ctx.getExecutionAttribute(NM_PRIVATE_CONTAINER_SCRIPT_PATH).toUri()
             .getPath(),
-        ctx.getExecutionAttribute(NM_PRIVATE_TOKENS_PATH).toUri().getPath(),
-        ctx.getExecutionAttribute(PID_FILE_PATH).toString(),
+        ctx.getExecutionAttribute(NM_PRIVATE_TOKENS_PATH).toUri().getPath());
+    Path keystorePath = ctx.getExecutionAttribute(NM_PRIVATE_KEYSTORE_PATH);
+    Path truststorePath = 
ctx.getExecutionAttribute(NM_PRIVATE_TRUSTSTORE_PATH);
+    if (keystorePath != null && truststorePath != null) {
+      launchOp.appendArgs("--https",
+          keystorePath.toUri().getPath(),
+          truststorePath.toUri().getPath());
+    } else {
+      launchOp.appendArgs("--http");
+    }
+    launchOp.appendArgs(ctx.getExecutionAttribute(PID_FILE_PATH).toString(),
         StringUtils.join(PrivilegedOperation.LINUX_FILE_PATH_SEPARATOR,
             ctx.getExecutionAttribute(LOCAL_DIRS)),
         StringUtils.join(PrivilegedOperation.LINUX_FILE_PATH_SEPARATOR,

http://git-wip-us.apache.org/repos/asf/hadoop/blob/c2288ac4/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/linux/runtime/DockerLinuxContainerRuntime.java
----------------------------------------------------------------------
diff --git 
a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/linux/runtime/DockerLinuxContainerRuntime.java
 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/linux/runtime/DockerLinuxContainerRuntime.java
index c86ed53..21660c1 100644
--- 
a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/linux/runtime/DockerLinuxContainerRuntime.java
+++ 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/linux/runtime/DockerLinuxContainerRuntime.java
@@ -1205,19 +1205,29 @@ public class DockerLinuxContainerRuntime implements 
LinuxContainerRuntime {
             PrivilegedOperation.OperationType.LAUNCH_DOCKER_CONTAINER);
 
     launchOp.appendArgs(runAsUser, ctx.getExecutionAttribute(USER),
-            Integer.toString(PrivilegedOperation
-                    .RunAsUserCommand.LAUNCH_DOCKER_CONTAINER.getValue()),
-            ctx.getExecutionAttribute(APPID),
-            containerIdStr,
-            containerWorkDir.toString(),
-            nmPrivateContainerScriptPath.toUri().getPath(),
-            
ctx.getExecutionAttribute(NM_PRIVATE_TOKENS_PATH).toUri().getPath(),
-            ctx.getExecutionAttribute(PID_FILE_PATH).toString(),
-            StringUtils.join(PrivilegedOperation.LINUX_FILE_PATH_SEPARATOR,
-                    localDirs),
-            StringUtils.join(PrivilegedOperation.LINUX_FILE_PATH_SEPARATOR,
-                    logDirs),
-            commandFile);
+        Integer.toString(PrivilegedOperation
+            .RunAsUserCommand.LAUNCH_DOCKER_CONTAINER.getValue()),
+        ctx.getExecutionAttribute(APPID),
+        containerIdStr,
+        containerWorkDir.toString(),
+        nmPrivateContainerScriptPath.toUri().getPath(),
+        ctx.getExecutionAttribute(NM_PRIVATE_TOKENS_PATH).toUri().getPath());
+    Path keystorePath = ctx.getExecutionAttribute(NM_PRIVATE_KEYSTORE_PATH);
+    Path truststorePath = 
ctx.getExecutionAttribute(NM_PRIVATE_TRUSTSTORE_PATH);
+    if (keystorePath != null && truststorePath != null) {
+      launchOp.appendArgs("--https",
+          keystorePath.toUri().getPath(),
+          truststorePath.toUri().getPath());
+    } else {
+      launchOp.appendArgs("--http");
+    }
+    launchOp.appendArgs(
+        ctx.getExecutionAttribute(PID_FILE_PATH).toString(),
+        StringUtils.join(PrivilegedOperation.LINUX_FILE_PATH_SEPARATOR,
+            localDirs),
+        StringUtils.join(PrivilegedOperation.LINUX_FILE_PATH_SEPARATOR,
+            logDirs),
+        commandFile);
 
     String tcCommandFile = ctx.getExecutionAttribute(TC_COMMAND_FILE);
 

http://git-wip-us.apache.org/repos/asf/hadoop/blob/c2288ac4/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/linux/runtime/LinuxContainerRuntimeConstants.java
----------------------------------------------------------------------
diff --git 
a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/linux/runtime/LinuxContainerRuntimeConstants.java
 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/linux/runtime/LinuxContainerRuntimeConstants.java
index 2f4aad4..fc86b17 100644
--- 
a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/linux/runtime/LinuxContainerRuntimeConstants.java
+++ 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/linux/runtime/LinuxContainerRuntimeConstants.java
@@ -58,6 +58,10 @@ public final class LinuxContainerRuntimeConstants {
       Attribute.attribute(Path.class, "nm_private_container_script_path");
   public static final Attribute<Path> NM_PRIVATE_TOKENS_PATH = Attribute
       .attribute(Path.class, "nm_private_tokens_path");
+  public static final Attribute<Path> NM_PRIVATE_KEYSTORE_PATH = Attribute
+      .attribute(Path.class, "nm_private_keystore_path");
+  public static final Attribute<Path> NM_PRIVATE_TRUSTSTORE_PATH = Attribute
+      .attribute(Path.class, "nm_private_truststore_path");
   public static final Attribute<Path> PID_FILE_PATH = Attribute.attribute(
       Path.class, "pid_file_path");
   public static final Attribute<List> LOCAL_DIRS = Attribute.attribute(

http://git-wip-us.apache.org/repos/asf/hadoop/blob/c2288ac4/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/executor/ContainerStartContext.java
----------------------------------------------------------------------
diff --git 
a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/executor/ContainerStartContext.java
 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/executor/ContainerStartContext.java
index ff41572..444a1e0 100644
--- 
a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/executor/ContainerStartContext.java
+++ 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/executor/ContainerStartContext.java
@@ -40,6 +40,8 @@ public final class ContainerStartContext {
   private final Map<Path, List<String>> localizedResources;
   private final Path nmPrivateContainerScriptPath;
   private final Path nmPrivateTokensPath;
+  private final Path nmPrivateKeystorePath;
+  private final Path nmPrivateTruststorePath;
   private final String user;
   private final String appId;
   private final Path containerWorkDir;
@@ -57,6 +59,8 @@ public final class ContainerStartContext {
     private Map<Path, List<String>> localizedResources;
     private Path nmPrivateContainerScriptPath;
     private Path nmPrivateTokensPath;
+    private Path nmPrivateKeystorePath;
+    private Path nmPrivateTruststorePath;
     private String user;
     private String appId;
     private Path containerWorkDir;
@@ -94,6 +98,16 @@ public final class ContainerStartContext {
       return this;
     }
 
+    public Builder setNmPrivateKeystorePath(Path nmPrivateKeystorePath) {
+      this.nmPrivateKeystorePath = nmPrivateKeystorePath;
+      return this;
+    }
+
+    public Builder setNmPrivateTruststorePath(Path nmPrivateTruststorePath) {
+      this.nmPrivateTruststorePath = nmPrivateTruststorePath;
+      return this;
+    }
+
     public Builder setUser(String user) {
       this.user = user;
       return this;
@@ -161,6 +175,8 @@ public final class ContainerStartContext {
     this.localizedResources = builder.localizedResources;
     this.nmPrivateContainerScriptPath = builder.nmPrivateContainerScriptPath;
     this.nmPrivateTokensPath = builder.nmPrivateTokensPath;
+    this.nmPrivateKeystorePath = builder.nmPrivateKeystorePath;
+    this.nmPrivateTruststorePath = builder.nmPrivateTruststorePath;
     this.user = builder.user;
     this.appId = builder.appId;
     this.containerWorkDir = builder.containerWorkDir;
@@ -194,6 +210,14 @@ public final class ContainerStartContext {
     return this.nmPrivateTokensPath;
   }
 
+  public Path getNmPrivateKeystorePath() {
+    return this.nmPrivateKeystorePath;
+  }
+
+  public Path getNmPrivateTruststorePath() {
+    return this.nmPrivateTruststorePath;
+  }
+
   public String getUser() {
     return this.user;
   }

http://git-wip-us.apache.org/repos/asf/hadoop/blob/c2288ac4/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/container-executor.c
----------------------------------------------------------------------
diff --git 
a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/container-executor.c
 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/container-executor.c
index 1f7ae3f..6704177 100644
--- 
a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/container-executor.c
+++ 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/container-executor.c
@@ -613,6 +613,16 @@ char *get_container_credentials_file(const char* work_dir) 
{
       CREDENTIALS_FILENAME);
 }
 
+char *get_container_keystore_file(const char* work_dir) {
+  return concatenate("%s/%s", "am container keystore", 2, work_dir,
+      KEYSTORE_FILENAME);
+}
+
+char *get_container_truststore_file(const char* work_dir) {
+  return concatenate("%s/%s", "am container truststore", 2, work_dir,
+      TRUSTSTORE_FILENAME);
+}
+
 /**
  * Get the app log directory under the given log_root
  */
@@ -1565,9 +1575,11 @@ int exec_docker_command(char *docker_command, char 
**argv, int argc) {
 }
 
 int create_script_paths(const char *work_dir,
-  const char *script_name, const char *cred_file,
-  char** script_file_dest, char** cred_file_dest,
-  int* container_file_source, int* cred_file_source ) {
+  const char *script_name, const char *cred_file, const int https,
+  const char *keystore_file, const char *truststore_file,
+  char** script_file_dest, char** cred_file_dest, char** keystore_file_dest,
+  char** truststore_file_dest, int* container_file_source,
+  int* cred_file_source, int* keystore_file_source, int* 
truststore_file_source) {
   int exit_code = -1;
 
   *script_file_dest = get_container_launcher_file(work_dir);
@@ -1585,6 +1597,24 @@ int create_script_paths(const char *work_dir,
     fflush(ERRORFILE);
     return exit_code;
   }
+
+  if (https == 1) {
+    *keystore_file_dest = get_container_keystore_file(work_dir);
+    if (NULL == keystore_file_dest) {
+      exit_code = OUT_OF_MEMORY;
+      fprintf(ERRORFILE, "Could not create keystore_file_dest");
+      fflush(ERRORFILE);
+      return exit_code;
+    }
+    *truststore_file_dest = get_container_truststore_file(work_dir);
+    if (NULL == truststore_file_dest) {
+      exit_code = OUT_OF_MEMORY;
+      fprintf(ERRORFILE, "Could not create truststore_file_dest");
+      fflush(ERRORFILE);
+      return exit_code;
+    }
+  }
+
   // open launch script
   *container_file_source = open_file_as_nm(script_name);
   if (*container_file_source == -1) {
@@ -1596,12 +1626,31 @@ int create_script_paths(const char *work_dir,
   // open credentials
   *cred_file_source = open_file_as_nm(cred_file);
   if (*cred_file_source == -1) {
-    exit_code = INVALID_ARGUMENT_NUMBER;
+    exit_code = INVALID_NM_ROOT_DIRS;
     fprintf(ERRORFILE, "Could not open cred file");
     fflush(ERRORFILE);
     return exit_code;
   }
 
+  if (https == 1) {
+    // open keystore
+    *keystore_file_source = open_file_as_nm(keystore_file);
+    if (*keystore_file_source == -1) {
+      exit_code = INVALID_NM_ROOT_DIRS;
+      fprintf(ERRORFILE, "Could not open keystore file");
+      fflush(ERRORFILE);
+      return exit_code;
+    }
+    // open truststore
+    *truststore_file_source = open_file_as_nm(truststore_file);
+    if (*truststore_file_source == -1) {
+      exit_code = INVALID_NM_ROOT_DIRS;
+      fprintf(ERRORFILE, "Could not open truststore file");
+      fflush(ERRORFILE);
+      return exit_code;
+    }
+  }
+
   exit_code = 0;
   return exit_code;
 }
@@ -1609,10 +1658,14 @@ int create_script_paths(const char *work_dir,
 int create_local_dirs(const char * user, const char *app_id,
                        const char *container_id, const char *work_dir,
                        const char *script_name, const char *cred_file,
+                       const int https,
+                       const char *keystore_file, const char *truststore_file,
                        char* const* local_dirs,
                        char* const* log_dirs, int effective_user,
                        char* script_file_dest, char* cred_file_dest,
-                       int container_file_source, int cred_file_source) {
+                       char* keystore_file_dest, char* truststore_file_dest,
+                       int container_file_source, int cred_file_source,
+                       int keystore_file_source, int truststore_file_source) {
   int exit_code = -1;
   // create the user directory on all disks
   int result = initialize_user(user, local_dirs);
@@ -1665,12 +1718,32 @@ int create_local_dirs(const char * user, const char 
*app_id,
   // Copy credential file to permissions 600
   if (copy_file(cred_file_source, cred_file, cred_file_dest,
         S_IRUSR | S_IWUSR) != 0) {
-    exit_code = COULD_NOT_CREATE_CREDENTIALS_FILE;
+    exit_code = COULD_NOT_CREATE_CREDENTIALS_COPY;
     fprintf(ERRORFILE, "Could not copy file");
     fflush(ERRORFILE);
     goto cleanup;
   }
 
+  if (https == 1) {
+    // Copy keystore file to permissions 600
+    if (copy_file(keystore_file_source, keystore_file, keystore_file_dest,
+          S_IRUSR | S_IWUSR) != 0) {
+      exit_code = COULD_NOT_CREATE_KEYSTORE_COPY;
+      fprintf(ERRORFILE, "Could not copy file");
+      fflush(ERRORFILE);
+      goto cleanup;
+    }
+
+    // Copy truststore file to permissions 600
+    if (copy_file(truststore_file_source, truststore_file, 
truststore_file_dest,
+          S_IRUSR | S_IWUSR) != 0) {
+      exit_code = COULD_NOT_CREATE_TRUSTSTORE_COPY;
+      fprintf(ERRORFILE, "Could not copy file");
+      fflush(ERRORFILE);
+      goto cleanup;
+    }
+  }
+
   if (chdir(work_dir) != 0) {
     fprintf(ERRORFILE, "Can't change directory to %s -%s\n", work_dir,
       strerror(errno));
@@ -1708,17 +1781,23 @@ int create_user_filecache_dirs(const char * user, char* 
const* local_dirs) {
 int launch_docker_container_as_user(const char * user, const char *app_id,
                               const char *container_id, const char *work_dir,
                               const char *script_name, const char *cred_file,
+                              const int https,
+                              const char *keystore_file, const char 
*truststore_file,
                               const char *pid_file, char* const* local_dirs,
                               char* const* log_dirs, const char *command_file) 
{
   int exit_code = -1;
   char *script_file_dest = NULL;
   char *cred_file_dest = NULL;
+  char *keystore_file_dest = NULL;
+  char *truststore_file_dest = NULL;
   char *exit_code_file = NULL;
   char *docker_command_with_binary = NULL;
   char *docker_inspect_command = NULL;
   char *docker_inspect_exitcode_command = NULL;
   int container_file_source =-1;
   int cred_file_source = -1;
+  int keystore_file_source = -1;
+  int truststore_file_source = -1;
   int use_entry_point = 0;
 
   gid_t user_gid = getegid();
@@ -1729,8 +1808,8 @@ int launch_docker_container_as_user(const char * user, 
const char *app_id,
 
   fprintf(LOGFILE, "Creating script paths...\n");
   exit_code = create_script_paths(
-    work_dir, script_name, cred_file, &script_file_dest, &cred_file_dest,
-    &container_file_source, &cred_file_source);
+    work_dir, script_name, cred_file, https, keystore_file, truststore_file, 
&script_file_dest, &cred_file_dest,
+    &keystore_file_dest, &truststore_file_dest, &container_file_source, 
&cred_file_source, &keystore_file_source, &truststore_file_source);
   if (exit_code != 0) {
     fprintf(ERRORFILE, "Could not create script path\n");
     fflush(ERRORFILE);
@@ -1739,9 +1818,9 @@ int launch_docker_container_as_user(const char * user, 
const char *app_id,
 
   fprintf(LOGFILE, "Creating local dirs...\n");
   exit_code = create_local_dirs(user, app_id, container_id,
-    work_dir, script_name, cred_file, local_dirs, log_dirs,
-    1, script_file_dest, cred_file_dest,
-    container_file_source, cred_file_source);
+    work_dir, script_name, cred_file, https, keystore_file, truststore_file, 
local_dirs, log_dirs,
+    1, script_file_dest, cred_file_dest, keystore_file_dest, 
truststore_file_dest,
+    container_file_source, cred_file_source, keystore_file_source, 
truststore_file_source);
   if (exit_code != 0) {
     fprintf(ERRORFILE, "Could not create local files and directories %d %d\n", 
container_file_source, cred_file_source);
     fflush(ERRORFILE);
@@ -1973,6 +2052,8 @@ cleanup:
   free(exit_code_file);
   free(script_file_dest);
   free(cred_file_dest);
+  free(keystore_file_dest);
+  free(truststore_file_dest);
   free(docker_command_with_binary);
   free(docker_inspect_command);
   free_values(docker_command);
@@ -1983,12 +2064,16 @@ cleanup:
 int launch_container_as_user(const char *user, const char *app_id,
                    const char *container_id, const char *work_dir,
                    const char *script_name, const char *cred_file,
+                   const int https,
+                   const char *keystore_file, const char *truststore_file,
                    const char* pid_file, char* const* local_dirs,
                    char* const* log_dirs, const char *resources_key,
                    char* const* resources_values) {
   int exit_code = -1;
   char *script_file_dest = NULL;
   char *cred_file_dest = NULL;
+  char *keystore_file_dest = NULL;
+  char *truststore_file_dest = NULL;
   char *exit_code_file = NULL;
 
   fprintf(LOGFILE, "Getting exit code file...\n");
@@ -2000,11 +2085,13 @@ int launch_container_as_user(const char *user, const 
char *app_id,
 
   int container_file_source =-1;
   int cred_file_source = -1;
+  int keystore_file_source = -1;
+  int truststore_file_source = -1;
 
   fprintf(LOGFILE, "Creating script paths...\n");
   exit_code = create_script_paths(
-    work_dir, script_name, cred_file, &script_file_dest, &cred_file_dest,
-    &container_file_source, &cred_file_source);
+    work_dir, script_name, cred_file, https, keystore_file, truststore_file, 
&script_file_dest, &cred_file_dest,
+    &keystore_file_dest, &truststore_file_dest, &container_file_source, 
&cred_file_source, &keystore_file_source, &truststore_file_source);
   if (exit_code != 0) {
     fprintf(ERRORFILE, "Could not create local files and directories");
     fflush(ERRORFILE);
@@ -2052,9 +2139,9 @@ int launch_container_as_user(const char *user, const char 
*app_id,
 
   fprintf(LOGFILE, "Creating local dirs...\n");
   exit_code = create_local_dirs(user, app_id, container_id,
-    work_dir, script_name, cred_file, local_dirs, log_dirs,
-    0, script_file_dest, cred_file_dest,
-    container_file_source, cred_file_source);
+    work_dir, script_name, cred_file, https, keystore_file, truststore_file, 
local_dirs, log_dirs,
+    0, script_file_dest, cred_file_dest, keystore_file_dest, 
truststore_file_dest,
+    container_file_source, cred_file_source, keystore_file_source, 
truststore_file_source);
   if (exit_code != 0) {
     fprintf(ERRORFILE, "Could not create local files and directories");
     fflush(ERRORFILE);
@@ -2087,6 +2174,8 @@ int launch_container_as_user(const char *user, const char 
*app_id,
     free(exit_code_file);
     free(script_file_dest);
     free(cred_file_dest);
+    free(keystore_file_dest);
+    free(truststore_file_dest);
     return exit_code;
 }
 

http://git-wip-us.apache.org/repos/asf/hadoop/blob/c2288ac4/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/container-executor.h
----------------------------------------------------------------------
diff --git 
a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/container-executor.h
 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/container-executor.h
index ce05c57..3eb931a 100644
--- 
a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/container-executor.h
+++ 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/container-executor.h
@@ -59,6 +59,8 @@ enum operations {
 #define CONTAINER_DIR_PATTERN NM_APP_DIR_PATTERN "/%s"
 #define CONTAINER_SCRIPT "launch_container.sh"
 #define CREDENTIALS_FILENAME "container_tokens"
+#define KEYSTORE_FILENAME "yarn_provided.keystore"
+#define TRUSTSTORE_FILENAME "yarn_provided.truststore"
 #define MIN_USERID_KEY "min.user.id"
 #define BANNED_USERS_KEY "banned.users"
 #define ALLOWED_SYSTEM_USERS_KEY "allowed.system.users"
@@ -102,6 +104,8 @@ int initialize_app(const char *user, const char *app_id,
 int launch_docker_container_as_user(const char * user, const char *app_id,
                               const char *container_id, const char *work_dir,
                               const char *script_name, const char *cred_file,
+                              const int https,
+                              const char *keystore_file, const char 
*truststore_file,
                               const char *pid_file, char* const* local_dirs,
                               char* const* log_dirs,
                               const char *command_file);
@@ -118,8 +122,13 @@ int launch_docker_container_as_user(const char * user, 
const char *app_id,
  * @param container_id the container id
  * @param work_dir the working directory for the container.
  * @param script_name the name of the script to be run to launch the container.
- * @param cred_file the credentials file that needs to be compied to the
+ * @param cred_file the credentials file that needs to be copied to the
  * working directory.
+ * @param https 1 if a keystore and truststore will be provided, 0 if not
+ * @param keystore_file the keystore file that needs to be copied to the
+ * working directory.
+ * @param truststore_file the truststore file that needs to be copied to the
+ * working directory
  * @param pid_file file where pid of process should be written to
  * @param local_dirs nodemanager-local-directories to be used
  * @param log_dirs nodemanager-log-directories to be used
@@ -130,6 +139,8 @@ int launch_docker_container_as_user(const char * user, 
const char *app_id,
 int launch_container_as_user(const char * user, const char *app_id,
                      const char *container_id, const char *work_dir,
                      const char *script_name, const char *cred_file,
+                     const int https,
+                     const char *keystore_file, const char *truststore_file,
                      const char *pid_file, char* const* local_dirs,
                      char* const* log_dirs, const char *resources_key,
                      char* const* resources_value);
@@ -194,6 +205,10 @@ char *get_container_launcher_file(const char* work_dir);
 
 char *get_container_credentials_file(const char* work_dir);
 
+char *get_container_keystore_file(const char* work_dir);
+
+char *get_container_truststore_file(const char* work_dir);
+
 /**
  * Get the app log directory under log_root
  */

http://git-wip-us.apache.org/repos/asf/hadoop/blob/c2288ac4/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/main.c
----------------------------------------------------------------------
diff --git 
a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/main.c
 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/main.c
index a3057e6..c269fa4 100644
--- 
a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/main.c
+++ 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/main.c
@@ -227,6 +227,9 @@ static struct {
   char **resources_values;
   const char *app_id;
   const char *container_id;
+  int https;
+  const char *keystore_file;
+  const char *truststore_file;
   const char *cred_file;
   const char *script_file;
   const char *current_dir;
@@ -432,8 +435,8 @@ static int validate_run_as_user_commands(int argc, char 
**argv, int *operation)
  case LAUNCH_DOCKER_CONTAINER:
    if(is_docker_support_enabled()) {
       //kill me now.
-      if (!(argc == 13 || argc == 14)) {
-        fprintf(ERRORFILE, "Wrong number of arguments (%d vs 13 or 14) for"
+      if (!(argc >= 14 && argc <= 17)) {
+        fprintf(ERRORFILE, "Wrong number of arguments (%d vs 14 - 17) for"
           " launch docker container\n", argc);
         fflush(ERRORFILE);
         return INVALID_ARGUMENT_NUMBER;
@@ -444,6 +447,13 @@ static int validate_run_as_user_commands(int argc, char 
**argv, int *operation)
       cmd_input.current_dir = argv[optind++];
       cmd_input.script_file = argv[optind++];
       cmd_input.cred_file = argv[optind++];
+      if (strcmp("--https", argv[optind++]) == 0) {
+        cmd_input.https = 1;
+        cmd_input.keystore_file = argv[optind++];
+        cmd_input.truststore_file = argv[optind++];
+      } else {
+        cmd_input.https = 0;
+      }
       cmd_input.pid_file = argv[optind++];
       // good local dirs as a comma separated list
       cmd_input.local_dirs = argv[optind++];
@@ -451,7 +461,7 @@ static int validate_run_as_user_commands(int argc, char 
**argv, int *operation)
       cmd_input.log_dirs = argv[optind++];
       cmd_input.docker_command_file = argv[optind++];
       //network isolation through tc
-      if (argc == 14) {
+      if ((argc == 15 && !cmd_input.https) || (argc == 17 && cmd_input.https)) 
{
         if(is_tc_support_enabled()) {
           cmd_input.traffic_control_command_file = argv[optind++];
         } else {
@@ -469,8 +479,8 @@ static int validate_run_as_user_commands(int argc, char 
**argv, int *operation)
 
   case LAUNCH_CONTAINER:
     //kill me now.
-    if (!(argc == 13 || argc == 14)) {
-      fprintf(ERRORFILE, "Wrong number of arguments (%d vs 13 or 14)"
+    if (!(argc >= 14 && argc <= 17)) {
+      fprintf(ERRORFILE, "Wrong number of arguments (%d vs 14 - 17)"
         " for launch container\n", argc);
       fflush(ERRORFILE);
       return INVALID_ARGUMENT_NUMBER;
@@ -481,6 +491,13 @@ static int validate_run_as_user_commands(int argc, char 
**argv, int *operation)
     cmd_input.current_dir = argv[optind++];
     cmd_input.script_file = argv[optind++];
     cmd_input.cred_file = argv[optind++];
+    if (strcmp("--https", argv[optind++]) == 0) {
+      cmd_input.https = 1;
+      cmd_input.keystore_file = argv[optind++];
+      cmd_input.truststore_file = argv[optind++];
+    } else {
+      cmd_input.https = 0;
+    }
     cmd_input.pid_file = argv[optind++];
     cmd_input.local_dirs = argv[optind++];// good local dirs as a comma 
separated list
     cmd_input.log_dirs = argv[optind++];// good log dirs as a comma separated 
list
@@ -499,7 +516,7 @@ static int validate_run_as_user_commands(int argc, char 
**argv, int *operation)
     }
 
     //network isolation through tc
-    if (argc == 14) {
+    if ((argc == 15 && !cmd_input.https) || (argc == 17 && cmd_input.https)) {
       if(is_tc_support_enabled()) {
         cmd_input.traffic_control_command_file = argv[optind++];
       } else {
@@ -636,6 +653,9 @@ int main(int argc, char **argv) {
                       cmd_input.current_dir,
                       cmd_input.script_file,
                       cmd_input.cred_file,
+                      cmd_input.https,
+                      cmd_input.keystore_file,
+                      cmd_input.truststore_file,
                       cmd_input.pid_file,
                       split(cmd_input.local_dirs),
                       split(cmd_input.log_dirs),
@@ -662,6 +682,9 @@ int main(int argc, char **argv) {
                     cmd_input.current_dir,
                     cmd_input.script_file,
                     cmd_input.cred_file,
+                    cmd_input.https,
+                    cmd_input.keystore_file,
+                    cmd_input.truststore_file,
                     cmd_input.pid_file,
                     split(cmd_input.local_dirs),
                     split(cmd_input.log_dirs),

http://git-wip-us.apache.org/repos/asf/hadoop/blob/c2288ac4/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/util.h
----------------------------------------------------------------------
diff --git 
a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/util.h
 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/util.h
index 372c17a..5702b0c 100644
--- 
a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/util.h
+++ 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/util.h
@@ -59,7 +59,7 @@ enum errorcodes {
   ERROR_READING_DOCKER_FILE = 31,
   FEATURE_DISABLED = 32,
   COULD_NOT_CREATE_SCRIPT_COPY = 33,
-  COULD_NOT_CREATE_CREDENTIALS_FILE = 34,
+  COULD_NOT_CREATE_CREDENTIALS_COPY = 34,
   COULD_NOT_CREATE_WORK_DIRECTORIES = 35,
   COULD_NOT_CREATE_APP_LOG_DIRECTORIES = 36,
   COULD_NOT_CREATE_TMP_DIRECTORIES = 37,
@@ -69,7 +69,9 @@ enum errorcodes {
   // DOCKER_CONTAINER_NAME_INVALID = 41, (NOT USED)
   ERROR_COMPILING_REGEX = 42,
   INVALID_CONTAINER_ID = 43,
-  DOCKER_EXEC_FAILED = 44
+  DOCKER_EXEC_FAILED = 44,
+  COULD_NOT_CREATE_KEYSTORE_COPY = 45,
+  COULD_NOT_CREATE_TRUSTSTORE_COPY = 46
 };
 
 /* Macros for min/max. */

http://git-wip-us.apache.org/repos/asf/hadoop/blob/c2288ac4/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/test/test-container-executor.c
----------------------------------------------------------------------
diff --git 
a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/test/test-container-executor.c
 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/test/test-container-executor.c
index f4f00c0..a4515ce 100644
--- 
a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/test/test-container-executor.c
+++ 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/test/test-container-executor.c
@@ -168,13 +168,13 @@ void test_get_user_directory() {
 void test_check_nm_local_dir() {
   // check filesystem is same as running user.
   int expected = 0;
-  char *local_path = TEST_ROOT "target";
+  char *local_path = TEST_ROOT "/target";
   char *root_path = "/";
   if (mkdirs(local_path, 0700) != 0) {
     printf("FAIL: unble to create node manager local directory: %s\n", 
local_path);
     exit(1);
   }
-  int actual = check_nm_local_dir(nm_uid, local_path);
+  int actual = check_nm_local_dir(user_detail->pw_uid, local_path);
   if (expected != actual) {
     printf("test_nm_local_dir expected %d got %d\n", expected, actual);
     exit(1);
@@ -199,31 +199,76 @@ void test_get_app_directory() {
   free(app_dir);
 }
 
-void test_get_container_directory() {
-  char *container_dir = get_container_work_directory(TEST_ROOT, "owen", 
"app_1",
+void test_get_container_work_directory() {
+  char *expected_file = TEST_ROOT "/usercache/user/appcache/app_1/container_1";
+  char *work_dir = get_container_work_directory(TEST_ROOT, "user", "app_1",
                                                 "container_1");
-  char *expected = TEST_ROOT "/usercache/owen/appcache/app_1/container_1";
-  if (strcmp(container_dir, expected) != 0) {
-    printf("Fail get_container_work_directory got %s expected %s\n",
-          container_dir, expected);
+  if (strcmp(work_dir, expected_file) != 0) {
+    printf("Fail get_container_work_directory expected %s got %s\n",
+         expected_file, work_dir);
     exit(1);
   }
-  free(container_dir);
+  free(work_dir);
 }
 
 void test_get_container_launcher_file() {
-  char *expected_file = (TEST_ROOT 
"/usercache/user/appcache/app_200906101234_0001"
-                        "/launch_container.sh");
-  char *app_dir = get_app_directory(TEST_ROOT, "user",
-                                    "app_200906101234_0001");
-  char *container_file =  get_container_launcher_file(app_dir);
-  if (strcmp(container_file, expected_file) != 0) {
-    printf("failure to match expected container file %s vs %s\n", 
container_file,
-           expected_file);
+  char *expected_file = (TEST_ROOT "/usercache/user/appcache/"
+            "app_200906101234_0001/container_1/launch_container.sh");
+  char *work_dir = get_container_work_directory(TEST_ROOT, "user",
+            "app_200906101234_0001", "container_1");
+  char *launcher_file =  get_container_launcher_file(work_dir);
+  if (strcmp(launcher_file, expected_file) != 0) {
+    printf("failure to match expected launcher file %s got %s\n",
+      expected_file, launcher_file);
+    exit(1);
+  }
+  free(work_dir);
+  free(launcher_file);
+}
+
+void test_get_container_credentials_file() {
+  char *expected_file = (TEST_ROOT "/usercache/user/appcache/"
+            "app_200906101234_0001/container_1/container_tokens");
+  char *work_dir = get_container_work_directory(TEST_ROOT, "user",
+            "app_200906101234_0001", "container_1");
+  char *credentials_file =  get_container_credentials_file(work_dir);
+  if (strcmp(credentials_file, expected_file) != 0) {
+    printf("failure to match expected credentials file %s got %s\n",
+      expected_file, credentials_file);
     exit(1);
   }
-  free(app_dir);
-  free(container_file);
+  free(work_dir);
+  free(credentials_file);
+}
+
+void test_get_container_keystore_file() {
+  char *expected_file = (TEST_ROOT "/usercache/user/appcache/"
+            "app_200906101234_0001/container_1/yarn_provided.keystore");
+  char *work_dir = get_container_work_directory(TEST_ROOT, "user",
+            "app_200906101234_0001", "container_1");
+  char *keystore_file =  get_container_keystore_file(work_dir);
+  if (strcmp(keystore_file, expected_file) != 0) {
+    printf("failure to match expected keystore file %s got %s\n",
+      expected_file, keystore_file);
+    exit(1);
+  }
+  free(work_dir);
+  free(keystore_file);
+}
+
+void test_get_container_truststore_file() {
+  char *expected_file = (TEST_ROOT "/usercache/user/appcache/"
+            "app_200906101234_0001/container_1/yarn_provided.truststore");
+  char *work_dir = get_container_work_directory(TEST_ROOT, "user",
+            "app_200906101234_0001", "container_1");
+  char *truststore_file =  get_container_truststore_file(work_dir);
+  if (strcmp(truststore_file, expected_file) != 0) {
+    printf("failure to match expected truststore file %s got %s\n",
+      expected_file, truststore_file);
+    exit(1);
+  }
+  free(work_dir);
+  free(truststore_file);
 }
 
 void test_get_app_log_dir() {
@@ -762,38 +807,31 @@ void test_signal_container_group() {
   }
 }
 
-void test_init_app() {
-  printf("\nTesting init app\n");
-  if (seteuid(0) != 0) {
-    printf("FAIL: seteuid to root failed - %s\n", strerror(errno));
-    exit(1);
-  }
-  FILE* creds = fopen(TEST_ROOT "/creds.txt", "w");
+void create_text_file(const char* filename, const char* contents) {
+  FILE* creds = fopen(filename, "w");
   if (creds == NULL) {
-    printf("FAIL: failed to create credentials file - %s\n", strerror(errno));
+    printf("FAIL: failed to create %s file - %s\n", filename, strerror(errno));
     exit(1);
   }
-  if (fprintf(creds, "secret key\n") < 0) {
-    printf("FAIL: fprintf failed - %s\n", strerror(errno));
+  if (fwrite(contents, sizeof(char), sizeof(contents), creds)
+        < sizeof(contents)) {
+    printf("FAIL: fwrite failed on file %s- %s\n", filename, strerror(errno));
     exit(1);
   }
   if (fclose(creds) != 0) {
-    printf("FAIL: fclose failed - %s\n", strerror(errno));
-    exit(1);
-  }
-  FILE* job_xml = fopen(TEST_ROOT "/job.xml", "w");
-  if (job_xml == NULL) {
-    printf("FAIL: failed to create job file - %s\n", strerror(errno));
-    exit(1);
-  }
-  if (fprintf(job_xml, "<jobconf/>\n") < 0) {
-    printf("FAIL: fprintf failed - %s\n", strerror(errno));
+    printf("FAIL: fclose failed on file %s - %s\n", filename, strerror(errno));
     exit(1);
   }
-  if (fclose(job_xml) != 0) {
-    printf("FAIL: fclose failed - %s\n", strerror(errno));
+}
+
+void test_init_app() {
+  printf("\nTesting init app\n");
+  if (seteuid(0) != 0) {
+    printf("FAIL: seteuid to root failed - %s\n", strerror(errno));
     exit(1);
   }
+  create_text_file(TEST_ROOT "/creds.txt", "secret key");
+  create_text_file(TEST_ROOT "/job.xml", "<jobconf/>\n");
   if (seteuid(user_detail->pw_uid) != 0) {
     printf("FAIL: failed to seteuid back to user - %s\n", strerror(errno));
     exit(1);
@@ -807,14 +845,9 @@ void test_init_app() {
     exit(1);
   } else if (child == 0) {
     char *final_pgm[] = {"touch", "my-touch-file", 0};
-    if (initialize_app(yarn_username, "app_4", "container_1",
+    exit(initialize_app(yarn_username, "app_4", "container_1",
                        TEST_ROOT "/creds.txt",
-                       local_dirs, log_dirs, final_pgm) != 0) {
-      printf("FAIL: failed in child\n");
-      exit(42);
-    }
-    // should never return
-    exit(1);
+                       local_dirs, log_dirs, final_pgm));
   }
   int status = 0;
   if (waitpid(child, &status, 0) <= 0) {
@@ -822,6 +855,11 @@ void test_init_app() {
           strerror(errno));
     exit(1);
   }
+  if (WEXITSTATUS(status) != 0) {
+    printf("FAIL: child %" PRId64 " exited with bad status %d\n",
+           (int64_t)child, WEXITSTATUS(status));
+    exit(1);
+  }
   if (access(TEST_ROOT "/logs/userlogs/app_4", R_OK) != 0) {
     printf("FAIL: failed to create app log directory\n");
     exit(1);
@@ -859,24 +897,24 @@ void test_init_app() {
   free(container_dir);
 }
 
-void test_run_container() {
-  printf("\nTesting run container\n");
+void test_launch_container(const char* app, int https) {
+  if (https == 1) {
+    printf("\nTesting launch container with HTTPS\n");
+  } else {
+    printf("\nTesting launch container without HTTPS\n");
+  }
   if (seteuid(0) != 0) {
     printf("FAIL: seteuid to root failed - %s\n", strerror(errno));
     exit(1);
   }
-  FILE* creds = fopen(TEST_ROOT "/creds.txt", "w");
-  if (creds == NULL) {
-    printf("FAIL: failed to create credentials file - %s\n", strerror(errno));
-    exit(1);
-  }
-  if (fprintf(creds, "secret key\n") < 0) {
-    printf("FAIL: fprintf failed - %s\n", strerror(errno));
-    exit(1);
-  }
-  if (fclose(creds) != 0) {
-    printf("FAIL: fclose failed - %s\n", strerror(errno));
-    exit(1);
+  create_text_file(TEST_ROOT "/creds.txt", "secret key");
+  char* keystore_file = NULL;
+  char* truststore_file = NULL;
+  if (https == 1) {
+    keystore_file = TEST_ROOT "/yarn_provided.keystore";
+    truststore_file = TEST_ROOT "/yarn_provided.truststore";
+    create_text_file(keystore_file, "keystore");
+    create_text_file(truststore_file, "truststore");
   }
 
   char * cgroups_pids[] = { TEST_ROOT "/cgroups-pid1.txt", TEST_ROOT 
"/cgroups-pid2.txt", 0 };
@@ -906,32 +944,36 @@ void test_run_container() {
   fflush(stdout);
   fflush(stderr);
   char* container_dir = get_container_work_directory(TEST_ROOT "/local-1",
-                                             yarn_username, "app_4", 
"container_1");
+         yarn_username, app, "container_1");
   const char * pid_file = TEST_ROOT "/pid.txt";
 
   pid_t child = fork();
   if (child == -1) {
     printf("FAIL: failed to fork process for init_app - %s\n",
-          strerror(errno));
+         strerror(errno));
     exit(1);
   } else if (child == 0) {
-    if (launch_container_as_user(yarn_username, "app_4", "container_1",
-          container_dir, script_name, TEST_ROOT "/creds.txt", pid_file,
-          local_dirs, log_dirs,
-          "cgroups", cgroups_pids) != 0) {
-      printf("FAIL: failed in child\n");
-      exit(42);
-    }
-    // should never return
-    exit(1);
+    exit(launch_container_as_user(yarn_username, app, "container_1",
+                        container_dir, script_name, TEST_ROOT "/creds.txt",
+                        https, keystore_file, truststore_file,
+                        pid_file, local_dirs, log_dirs,
+                        "cgroups", cgroups_pids));
   }
   int status = 0;
   if (waitpid(child, &status, 0) <= 0) {
     printf("FAIL: failed waiting for process %" PRId64 " - %s\n", 
(int64_t)child,
-          strerror(errno));
+         strerror(errno));
+    exit(1);
+  }
+  if (WEXITSTATUS(status) != 0) {
+    printf("FAIL: child %" PRId64 " exited with bad status %d\n",
+           (int64_t)child, WEXITSTATUS(status));
     exit(1);
   }
-  if (access(TEST_ROOT "/logs/userlogs/app_4/container_1", R_OK) != 0) {
+  char container_log_path[100000];
+  snprintf(container_log_path, sizeof container_log_path, "%s%s%s%s", 
TEST_ROOT,
+            "/logs/userlogs/", app, "/container_1");
+  if (access(container_log_path, R_OK) != 0) {
     printf("FAIL: failed to create container log directory\n");
     exit(1);
   }
@@ -939,14 +981,17 @@ void test_run_container() {
     printf("FAIL: failed to create container directory %s\n", container_dir);
     exit(1);
   }
-  char buffer[100000];
-  sprintf(buffer, "%s/foobar", container_dir);
-  if (access(buffer, R_OK) != 0) {
-    printf("FAIL: failed to create touch file %s\n", buffer);
+  char touchfile[100000];
+  sprintf(touchfile, "%s/foobar", container_dir);
+  if (access(touchfile, R_OK) != 0) {
+    printf("FAIL: failed to create touch file %s\n", touchfile);
     exit(1);
   }
   free(container_dir);
-  container_dir = get_app_log_directory(TEST_ROOT "/logs/userlogs", 
"app_4/container_1");
+  char app_log_path[100000];
+  snprintf(app_log_path, sizeof app_log_path, "%s%s%s", TEST_ROOT,
+            "/logs/userlogs/", app);
+  container_dir = get_app_log_directory(app_log_path, "container_1");
   if (access(container_dir, R_OK) != 0) {
     printf("FAIL: failed to create app log directory %s\n", container_dir);
     exit(1);
@@ -1395,6 +1440,13 @@ int main(int argc, char **argv) {
     exit(1);
   }
 
+  if (mkdirs(TEST_ROOT, 0777) != 0) {
+    exit(1);
+  }
+  if (chmod(TEST_ROOT, 0777) != 0) {    // in case of umask
+    exit(1);
+  }
+
   if (mkdirs(TEST_ROOT "/logs/userlogs", 0755) != 0) {
     exit(1);
   }
@@ -1448,12 +1500,21 @@ int main(int argc, char **argv) {
   printf("\nTesting get_app_directory()\n");
   test_get_app_directory();
 
-  printf("\nTesting get_container_directory()\n");
-  test_get_container_directory();
+  printf("\nTesting get_container_work_directory()\n");
+  test_get_container_work_directory();
 
   printf("\nTesting get_container_launcher_file()\n");
   test_get_container_launcher_file();
 
+  printf("\nTesting get_container_credentials_file()\n");
+  test_get_container_credentials_file();
+
+  printf("\nTesting get_container_keystore_file()\n");
+  test_get_container_keystore_file();
+
+  printf("\nTesting get_container_truststore_file()\n");
+  test_get_container_truststore_file();
+
   printf("\nTesting get_app_log_dir()\n");
   test_get_app_log_dir();
 
@@ -1510,7 +1571,8 @@ int main(int argc, char **argv) {
     // these tests do internal forks so that the change_owner and execs
     // don't mess up our process.
     test_init_app();
-    test_run_container();
+    test_launch_container("app_4", 0);
+    test_launch_container("app_5", 1);
   }
 
   /*

http://git-wip-us.apache.org/repos/asf/hadoop/blob/c2288ac4/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/TestDefaultContainerExecutor.java
----------------------------------------------------------------------
diff --git 
a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/TestDefaultContainerExecutor.java
 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/TestDefaultContainerExecutor.java
index 9b180c7..7ec3ae3 100644
--- 
a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/TestDefaultContainerExecutor.java
+++ 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/TestDefaultContainerExecutor.java
@@ -47,6 +47,7 @@ import java.util.Random;
 
 import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.fs.CommonConfigurationKeys;
+import org.apache.hadoop.fs.FSDataInputStream;
 import org.apache.hadoop.fs.FSDataOutputStream;
 import org.apache.hadoop.fs.FileContext;
 import org.apache.hadoop.fs.FileStatus;
@@ -69,6 +70,7 @@ import 
org.apache.hadoop.yarn.server.nodemanager.api.protocolrecords.LocalizerAc
 import 
org.apache.hadoop.yarn.server.nodemanager.api.protocolrecords.LocalizerStatus;
 import 
org.apache.hadoop.yarn.server.nodemanager.containermanager.container.Container;
 import 
org.apache.hadoop.yarn.server.nodemanager.containermanager.container.ContainerDiagnosticsUpdateEvent;
+import 
org.apache.hadoop.yarn.server.nodemanager.containermanager.launcher.ContainerLaunch;
 import 
org.apache.hadoop.yarn.server.nodemanager.containermanager.localizer.ContainerLocalizer;
 import 
org.apache.hadoop.yarn.server.nodemanager.containermanager.localizer.MockLocalizerHeartbeatResponse;
 import 
org.apache.hadoop.yarn.server.nodemanager.executor.ContainerStartContext;
@@ -225,6 +227,157 @@ public class TestDefaultContainerExecutor {
     }
   }
 
+  private void writeStringToRelativePath(FileContext fc, Path p, String str)
+      throws IOException {
+    p = p.makeQualified(fc.getDefaultFileSystem().getUri(),
+        new Path(new File(".").getAbsolutePath()));
+    try (FSDataOutputStream os = fc.create(p).build()) {
+      os.writeUTF(str);
+    }
+  }
+
+  private String readStringFromPath(FileContext fc, Path p) throws IOException 
{
+    try (FSDataInputStream is = fc.open(p)) {
+      return is.readUTF();
+    }
+  }
+
+  @Test
+  public void testLaunchContainerCopyFilesWithoutHTTPS() throws Exception {
+    testLaunchContainerCopyFiles(false);
+  }
+
+  @Test
+  public void testLaunchContainerCopyFilesWithHTTPS() throws Exception {
+    testLaunchContainerCopyFiles(true);
+  }
+
+  private void testLaunchContainerCopyFiles(boolean https) throws Exception {
+    if (Shell.WINDOWS) {
+      BASE_TMP_PATH =
+          new Path(new File("target").getAbsolutePath(),
+              TestDefaultContainerExecutor.class.getSimpleName());
+    }
+
+    Path localDir = new Path(BASE_TMP_PATH, "localDir");
+    List<String> localDirs = new ArrayList<String>();
+    localDirs.add(localDir.toString());
+    List<String> logDirs = new ArrayList<String>();
+    Path logDir = new Path(BASE_TMP_PATH, "logDir");
+    logDirs.add(logDir.toString());
+
+    Configuration conf = new Configuration();
+    conf.set(CommonConfigurationKeys.FS_PERMISSIONS_UMASK_KEY, "077");
+    conf.set(YarnConfiguration.NM_LOCAL_DIRS, localDir.toString());
+    conf.set(YarnConfiguration.NM_LOG_DIRS, logDir.toString());
+
+    FileContext lfs = FileContext.getLocalFSFileContext(conf);
+    deleteTmpFiles();
+    lfs.mkdir(BASE_TMP_PATH, FsPermission.getDefault(), true);
+    DefaultContainerExecutor dce = new DefaultContainerExecutor(lfs);
+    dce.setConf(conf);
+
+    Container container = mock(Container.class);
+    ContainerId cId = mock(ContainerId.class);
+    ContainerLaunchContext context = mock(ContainerLaunchContext.class);
+    HashMap<String, String> env = new HashMap<String, String>();
+    env.put("LANG", "C");
+
+    String appSubmitter = "nobody";
+    String appId = "APP_ID";
+    String containerId = "CONTAINER_ID";
+
+    when(container.getContainerId()).thenReturn(cId);
+    when(container.getLaunchContext()).thenReturn(context);
+    when(cId.toString()).thenReturn(containerId);
+    when(cId.getApplicationAttemptId()).thenReturn(
+        ApplicationAttemptId.newInstance(ApplicationId.newInstance(0, 1), 0));
+    when(context.getEnvironment()).thenReturn(env);
+
+    Path scriptPath = new Path(BASE_TMP_PATH, "script");
+    Path tokensPath = new Path(BASE_TMP_PATH, "tokens");
+    Path keystorePath = new Path(BASE_TMP_PATH, "keystore");
+    Path truststorePath = new Path(BASE_TMP_PATH, "truststore");
+    writeStringToRelativePath(lfs, scriptPath, "script");
+    writeStringToRelativePath(lfs, tokensPath, "tokens");
+    if (https) {
+      writeStringToRelativePath(lfs, keystorePath, "keystore");
+      writeStringToRelativePath(lfs, truststorePath, "truststore");
+    }
+
+    Path workDir = localDir;
+    Path pidFile = new Path(workDir, "pid.txt");
+
+    dce.init(null);
+    dce.activateContainer(cId, pidFile);
+    ContainerStartContext.Builder ctxBuilder =
+        new ContainerStartContext.Builder()
+            .setContainer(container)
+            .setNmPrivateContainerScriptPath(scriptPath)
+            .setNmPrivateTokensPath(tokensPath)
+            .setUser(appSubmitter)
+            .setAppId(appId)
+            .setContainerWorkDir(workDir)
+            .setLocalDirs(localDirs)
+            .setLogDirs(logDirs);
+    if (https) {
+      ctxBuilder.setNmPrivateTruststorePath(truststorePath)
+          .setNmPrivateKeystorePath(keystorePath);
+    }
+    ContainerStartContext ctx = ctxBuilder.build();
+
+    // #launchContainer will copy a number of files to this directory.
+    // Ensure that it doesn't exist first
+    lfs.delete(workDir, true);
+    try {
+      lfs.getFileStatus(workDir);
+      Assert.fail("Expected FileNotFoundException on " + workDir);
+    } catch (FileNotFoundException e) {
+      // expected
+    }
+
+    dce.launchContainer(ctx);
+
+    Path finalScriptPath = new Path(workDir,
+        ContainerLaunch.CONTAINER_SCRIPT);
+    Path finalTokensPath = new Path(workDir,
+        ContainerLaunch.FINAL_CONTAINER_TOKENS_FILE);
+    Path finalKeystorePath = new Path(workDir,
+        ContainerLaunch.KEYSTORE_FILE);
+    Path finalTrustorePath = new Path(workDir,
+        ContainerLaunch.TRUSTSTORE_FILE);
+
+    Assert.assertTrue(lfs.getFileStatus(workDir).isDirectory());
+    Assert.assertTrue(lfs.getFileStatus(finalScriptPath).isFile());
+    Assert.assertTrue(lfs.getFileStatus(finalTokensPath).isFile());
+    if (https) {
+      Assert.assertTrue(lfs.getFileStatus(finalKeystorePath).isFile());
+      Assert.assertTrue(lfs.getFileStatus(finalTrustorePath).isFile());
+    } else {
+      try {
+        lfs.getFileStatus(finalKeystorePath);
+        Assert.fail("Expected FileNotFoundException on " + finalKeystorePath);
+      } catch (FileNotFoundException e) {
+        // expected
+      }
+      try {
+        lfs.getFileStatus(finalTrustorePath);
+        Assert.fail("Expected FileNotFoundException on " + finalKeystorePath);
+      } catch (FileNotFoundException e) {
+        // expected
+      }
+    }
+
+    Assert.assertEquals("script", readStringFromPath(lfs, finalScriptPath));
+    Assert.assertEquals("tokens", readStringFromPath(lfs, finalTokensPath));
+    if (https) {
+      Assert.assertEquals("keystore", readStringFromPath(lfs,
+          finalKeystorePath));
+      Assert.assertEquals("truststore", readStringFromPath(lfs,
+          finalTrustorePath));
+    }
+  }
+
   @Test
   public void testContainerLaunchError()
       throws IOException, InterruptedException, ConfigurationException {
@@ -303,6 +456,8 @@ public class TestDefaultContainerExecutor {
 
       Path scriptPath = new Path("file:///bin/echo");
       Path tokensPath = new Path("file:///dev/null");
+      Path keystorePath = new Path("file:///dev/null");
+      Path truststorePath = new Path("file:///dev/null");
       if (Shell.WINDOWS) {
         File tmp = new File(BASE_TMP_PATH.toString(), "test_echo.cmd");
         BufferedWriter output = new BufferedWriter(new FileWriter(tmp));
@@ -323,6 +478,8 @@ public class TestDefaultContainerExecutor {
           .setContainer(container)
           .setNmPrivateContainerScriptPath(scriptPath)
           .setNmPrivateTokensPath(tokensPath)
+          .setNmPrivateKeystorePath(keystorePath)
+          .setNmPrivateTruststorePath(truststorePath)
           .setUser(appSubmitter)
           .setAppId(appId)
           .setContainerWorkDir(workDir)


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

Reply via email to