DockerClient { public String writeCommandToTempFile(DockerCommand cmd, ContainerId containerId, Context nmContext) throws ContainerExecutionException { String filePrefix = containerId.toString(); ApplicationId appId = containerId.getApplicationAttemptId() .getApplicationId(); File dockerCommandFile; File cmdDir = null; if(nmContext == null || nmContext.getLocalDirsHandler() == null) { throw new ContainerExecutionException( "Unable to write temporary docker command"); } try { String cmdDirPath = nmContext.getLocalDirsHandler().getLocalPathForWrite( ResourceLocalizationService.NM_PRIVATE_DIR + Path.SEPARATOR + appId + Path.SEPARATOR + filePrefix + Path.SEPARATOR).toString(); cmdDir = new File(cmdDirPath); if (!cmdDir.mkdirs() && !cmdDir.exists()) { throw new IOException("Cannot create container private directory " + cmdDir); } dockerCommandFile = File.createTempFile(TMP_FILE_PREFIX + filePrefix, TMP_FILE_SUFFIX, cmdDir); try ( Writer writer = new OutputStreamWriter( new FileOutputStream(dockerCommandFile.toString()), "UTF-8"); PrintWriter printWriter = new PrintWriter(writer); ) { printWriter.println("[docker-command-execution]"); for (Map.Entry<String, List<String>> entry : cmd.getDockerCommandWithArguments().entrySet()) { if (entry.getKey().contains("=")) { throw new ContainerExecutionException( "'=' found in entry for docker command file, key = " + entry .getKey() + "; value = " + entry.getValue()); } String value = StringUtils.join(",", entry.getValue()); if (value.contains("\n")) { throw new ContainerExecutionException( "'\\n' found in entry for docker command file, key = " + entry .getKey() + "; value = " + value); } printWriter.println(" " + entry.getKey() + "=" + value); } if (cmd instanceof DockerRunCommand) { DockerRunCommand runCommand = (DockerRunCommand) cmd; if (runCommand.containsEnv()) { String path = writeEnvFile(runCommand, filePrefix, cmdDir); printWriter.println(" environ=" + path); } } return dockerCommandFile.toString(); } } catch (IOException e) { LOG.warn("Unable to write docker command to " + cmdDir); throw new ContainerExecutionException(e); } }  String writeCommandToTempFile(DockerCommand cmd,
      ContainerId containerId, Context nmContext);  }
@Test public void testWriteCommandToTempFile() throws Exception { String absRoot = TEST_ROOT_DIR.getAbsolutePath(); ApplicationId appId = ApplicationId.newInstance(1, 1); ApplicationAttemptId attemptId = ApplicationAttemptId.newInstance(appId, 1); ContainerId cid = ContainerId.newContainerId(attemptId, 1); DockerCommand dockerCmd = new DockerInspectCommand(cid.toString()); Configuration conf = new Configuration(); conf.set("hadoop.tmp.dir", absRoot); conf.set(YarnConfiguration.NM_LOCAL_DIRS, absRoot); conf.set(YarnConfiguration.NM_LOG_DIRS, absRoot); LocalDirsHandlerService dirsHandler = new LocalDirsHandlerService(); Context mockContext = mock(Context.class); doReturn(conf).when(mockContext).getConf(); doReturn(dirsHandler).when(mockContext).getLocalDirsHandler(); DockerClient dockerClient = new DockerClient(); dirsHandler.init(conf); dirsHandler.start(); String tmpPath = dockerClient.writeCommandToTempFile(dockerCmd, cid, mockContext); dirsHandler.stop(); File tmpFile = new File(tmpPath); assertTrue(tmpFile + " was not created", tmpFile.exists()); }
@Test public void testCommandValidation() throws Exception { String absRoot = TEST_ROOT_DIR.getAbsolutePath(); ApplicationId appId = ApplicationId.newInstance(1, 1); ApplicationAttemptId attemptId = ApplicationAttemptId.newInstance(appId, 1); ContainerId cid = ContainerId.newContainerId(attemptId, 1); Configuration conf = new Configuration(); conf.set("hadoop.tmp.dir", absRoot); conf.set(YarnConfiguration.NM_LOCAL_DIRS, absRoot); conf.set(YarnConfiguration.NM_LOG_DIRS, absRoot); LocalDirsHandlerService dirsHandler = new LocalDirsHandlerService(); Context mockContext = mock(Context.class); doReturn(conf).when(mockContext).getConf(); doReturn(dirsHandler).when(mockContext).getLocalDirsHandler(); DockerClient dockerClient = new DockerClient(); dirsHandler.init(conf); dirsHandler.start(); try { DockerRunCommand dockerCmd = new DockerRunCommand(cid.toString(), "user", "image"); dockerCmd.addCommandArguments("prop=bad", "val"); dockerClient.writeCommandToTempFile(dockerCmd, cid, mockContext); fail("Expected exception writing command file"); } catch (ContainerExecutionException e) { assertTrue("Expected key validation error", e.getMessage() .contains("'=' found in entry for docker command file")); } try { DockerRunCommand dockerCmd = new DockerRunCommand(cid.toString(), "user", "image"); dockerCmd.setOverrideCommandWithArgs(Arrays.asList("sleep", "1000\n")); dockerClient.writeCommandToTempFile(dockerCmd, cid, mockContext); fail("Expected exception writing command file"); } catch (ContainerExecutionException e) { assertTrue("Expected value validation error", e.getMessage() .contains("'\\n' found in entry for docker command file")); } dirsHandler.stop(); }