You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@dolphinscheduler.apache.org by GitBox <gi...@apache.org> on 2020/11/09 14:18:36 UTC

[GitHub] [incubator-dolphinscheduler] Eights-Li opened a new pull request #4042: [FIX-3900][server] kill multi yarn app in one job

Eights-Li opened a new pull request #4042:
URL: https://github.com/apache/incubator-dolphinscheduler/pull/4042


   ## What is the purpose of the pull request
   
   *fix #3900 kill multi yarn app in one job*
   
   ## Brief change log
   
     - *modify server/utils/ProcessUtils.java  **cancelApplication** method*
   
   ## Verify this pull request
   
     - *server/utils/ProcessUtilsTest to verify this pr*
   


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-dolphinscheduler] Eights-Li commented on a change in pull request #4042: [FIX-3900][server] kill multi yarn app in one job

Posted by GitBox <gi...@apache.org>.
Eights-Li commented on a change in pull request #4042:
URL: https://github.com/apache/incubator-dolphinscheduler/pull/4042#discussion_r527697138



##########
File path: dolphinscheduler-server/src/main/java/org/apache/dolphinscheduler/server/utils/ProcessUtils.java
##########
@@ -38,368 +41,408 @@
 import java.util.regex.Pattern;
 
 /**
- *  mainly used to get the start command line of a process.
+ * mainly used to get the start command line of a process.
  */
 public class ProcessUtils {
-  /**
-   * logger.
-   */
-  private static final Logger logger = LoggerFactory.getLogger(ProcessUtils.class);
-
-  /**
-   * Initialization regularization, solve the problem of pre-compilation performance,
-   * avoid the thread safety problem of multi-thread operation.
-   */
-  private static final Pattern MACPATTERN = Pattern.compile("-[+|-]-\\s(\\d+)");
-
-  private static final Pattern WINDOWSATTERN = Pattern.compile("(\\d+)");
-
-  /**
-   * build command line characters.
-   * @param commandList command list
-   * @return command
-   */
-  public static String buildCommandStr(List<String> commandList) {
-    String cmdstr;
-    String[] cmd = commandList.toArray(new String[commandList.size()]);
-    SecurityManager security = System.getSecurityManager();
-    boolean allowAmbiguousCommands = false;
-    if (security == null) {
-      allowAmbiguousCommands = true;
-      String value = System.getProperty("jdk.lang.Process.allowAmbiguousCommands");
-      if (value != null) {
-        allowAmbiguousCommands = !"false".equalsIgnoreCase(value);
-      }
+    /**
+     * logger.
+     */
+    private static final Logger logger = LoggerFactory.getLogger(ProcessUtils.class);
+
+    /**
+     * Initialization regularization, solve the problem of pre-compilation performance,
+     * avoid the thread safety problem of multi-thread operation.
+     */
+    private static final Pattern MACPATTERN = Pattern.compile("-[+|-]-\\s(\\d+)");
+
+    private static final Pattern WINDOWSATTERN = Pattern.compile("(\\d+)");
+
+    private static final String LOCAL_PROCESS_EXEC = "jdk.lang.Process.allowAmbiguousCommands";
+
+    /**
+     * build command line characters.
+     *
+     * @param commandList command list
+     * @return command
+     */
+    public static String buildCommandStr(List<String> commandList) {
+        String cmdstr;
+        String[] cmd = commandList.toArray(new String[0]);
+        SecurityManager security = System.getSecurityManager();
+        boolean allowAmbiguousCommands = isAllowAmbiguousCommands(security);
+        if (allowAmbiguousCommands) {
+
+            String executablePath = new File(cmd[0]).getPath();
+
+            if (needsEscaping(VERIFICATION_LEGACY, executablePath)) {
+                executablePath = quoteString(executablePath);
+            }
+
+            cmdstr = createCommandLine(
+                VERIFICATION_LEGACY, executablePath, cmd);
+        } else {
+            String executablePath;
+            try {
+                executablePath = getExecutablePath(cmd[0]);
+            } catch (IllegalArgumentException e) {
+
+                StringBuilder join = new StringBuilder();
+                for (String s : cmd) {
+                    join.append(s).append(' ');
+                }
+
+                cmd = getTokensFromCommand(join.toString());
+                executablePath = getExecutablePath(cmd[0]);
+
+                // Check new executable name once more
+                if (security != null) {
+                    security.checkExec(executablePath);
+                }
+            }
+
+            cmdstr = createCommandLine(
+
+                isShellFile(executablePath) ? VERIFICATION_CMD_BAT : VERIFICATION_WIN32, quoteString(executablePath), cmd);
+        }
+        return cmdstr;
     }
-    if (allowAmbiguousCommands) {
-
-      String executablePath = new File(cmd[0]).getPath();
-
-      if (needsEscaping(VERIFICATION_LEGACY, executablePath)) {
-        executablePath = quoteString(executablePath);
-      }
-
-      cmdstr = createCommandLine(
-              VERIFICATION_LEGACY, executablePath, cmd);
-    } else {
-      String executablePath;
-      try {
-        executablePath = getExecutablePath(cmd[0]);
-      } catch (IllegalArgumentException e) {
 
-        StringBuilder join = new StringBuilder();
-        for (String s : cmd) {
-          join.append(s).append(' ');
+    /**
+     * check is allow ambiguous commands
+     *
+     * @param security security manager
+     * @return allow ambiguous command flag
+     */
+    private static boolean isAllowAmbiguousCommands(SecurityManager security) {
+        boolean allowAmbiguousCommands = false;
+        if (security == null) {
+            allowAmbiguousCommands = true;
+            String value = System.getProperty(LOCAL_PROCESS_EXEC);
+            if (value != null) {
+                allowAmbiguousCommands = !Constants.STRING_FALSE.equalsIgnoreCase(value);
+            }
         }
+        return allowAmbiguousCommands;
+    }
 
-        cmd = getTokensFromCommand(join.toString());
-        executablePath = getExecutablePath(cmd[0]);
+    /**
+     * get executable path.
+     *
+     * @param path path
+     * @return executable path
+     */
+    private static String getExecutablePath(String path) {
+        boolean pathIsQuoted = isQuoted(true, path, "Executable name has embedded quote, split the arguments");
+
+        File fileToRun = new File(pathIsQuoted ? path.substring(1, path.length() - 1) : path);
+        return fileToRun.getPath();
+    }
 
-        // Check new executable name once more
-        if (security != null) {
-          security.checkExec(executablePath);
-        }
-      }
+    /**
+     * whether is shell file.
+     *
+     * @param executablePath executable path
+     * @return true if endsWith .CMD or .BAT
+     */
+    private static boolean isShellFile(String executablePath) {
+        String upPath = executablePath.toUpperCase();
+        return (upPath.endsWith(".CMD") || upPath.endsWith(".BAT"));
+    }
 
-      cmdstr = createCommandLine(
+    /**
+     * quote string.
+     *
+     * @param arg argument
+     * @return format arg
+     */
+    private static String quoteString(String arg) {
+        return '"' + arg + '"';
+    }
 
-              isShellFile(executablePath) ? VERIFICATION_CMD_BAT : VERIFICATION_WIN32, quoteString(executablePath), cmd);
+    /**
+     * get tokens from command.
+     *
+     * @param command command
+     * @return token string array
+     */
+    private static String[] getTokensFromCommand(String command) {
+        ArrayList<String> matchList = new ArrayList<>(8);
+        Matcher regexMatcher = LazyPattern.PATTERN.matcher(command);
+        while (regexMatcher.find()) {
+            matchList.add(regexMatcher.group());
+        }
+        return matchList.toArray(new String[0]);
     }
-    return cmdstr;
-  }
-
-  /**
-   * get executable path.
-   *
-   * @param path path
-   * @return executable path
-   */
-  private static String getExecutablePath(String path) {
-    boolean pathIsQuoted = isQuoted(true, path, "Executable name has embedded quote, split the arguments");
-
-    File fileToRun = new File(pathIsQuoted ? path.substring(1, path.length() - 1) : path);
-    return fileToRun.getPath();
-  }
-
-  /**
-   * whether is shell file.
-   *
-   * @param executablePath executable path
-   * @return true if endsWith .CMD or .BAT
-   */
-  private static boolean isShellFile(String executablePath) {
-    String upPath = executablePath.toUpperCase();
-    return (upPath.endsWith(".CMD") || upPath.endsWith(".BAT"));
-  }
-
-  /**
-   * quote string.
-   *
-   * @param arg argument
-   * @return format arg
-   */
-  private static String quoteString(String arg) {
-    StringBuilder argbuf = new StringBuilder(arg.length() + 2);
-    return argbuf.append('"').append(arg).append('"').toString();
-  }
-
-  /**
-   * get tokens from command.
-   *
-   * @param command command
-   * @return token string array
-   */
-  private static String[] getTokensFromCommand(String command) {
-    ArrayList<String> matchList = new ArrayList<>(8);
-    Matcher regexMatcher = LazyPattern.PATTERN.matcher(command);
-    while (regexMatcher.find()) {
-      matchList.add(regexMatcher.group());
+
+    /**
+     * Lazy Pattern.
+     */
+    private static class LazyPattern {
+        /**
+         * Escape-support version:
+         * "(\")((?:\\\\\\1|.)+?)\\1|([^\\s\"]+)";
+         */
+        private static final Pattern PATTERN = Pattern.compile("[^\\s\"]+|\"[^\"]*\"");
     }
-    return matchList.toArray(new String[matchList.size()]);
-  }
-
-  /**
-   * Lazy Pattern.
-   */
-  private static class LazyPattern {
-    // Escape-support version:
-    // "(\")((?:\\\\\\1|.)+?)\\1|([^\\s\"]+)";
-    private static final Pattern PATTERN = Pattern.compile("[^\\s\"]+|\"[^\"]*\"");
-  }
-
-  /**
-   * verification cmd bat.
-   */
-  private static final int VERIFICATION_CMD_BAT = 0;
-
-  /**
-   * verification win32.
-   */
-  private static final int VERIFICATION_WIN32 = 1;
-
-  /**
-   * verification legacy.
-   */
-  private static final int VERIFICATION_LEGACY = 2;
-
-  /**
-   * escape verification.
-   */
-  private static final char[][] ESCAPE_VERIFICATION = {{' ', '\t', '<', '>', '&', '|', '^'},
-
-    {' ', '\t', '<', '>'}, {' ', '\t'}};
-
-  /**
-   * create command line.
-   * @param verificationType  verification type
-   * @param executablePath    executable path
-   * @param cmd               cmd
-   * @return command line
-   */
-  private static String createCommandLine(int verificationType, final String executablePath, final String[] cmd) {
-    StringBuilder cmdbuf = new StringBuilder(80);
-
-    cmdbuf.append(executablePath);
-
-    for (int i = 1; i < cmd.length; ++i) {
-      cmdbuf.append(' ');
-      String s = cmd[i];
-      if (needsEscaping(verificationType, s)) {
-        cmdbuf.append('"').append(s);
-
-        if ((verificationType != VERIFICATION_CMD_BAT) && s.endsWith("\\")) {
-          cmdbuf.append('\\');
+
+    /**
+     * verification cmd bat.
+     */
+    private static final int VERIFICATION_CMD_BAT = 0;
+
+    /**
+     * verification win32.
+     */
+    private static final int VERIFICATION_WIN32 = 1;
+
+    /**
+     * verification legacy.
+     */
+    private static final int VERIFICATION_LEGACY = 2;
+
+    /**
+     * escape verification.
+     */
+    private static final char[][] ESCAPE_VERIFICATION = {{' ', '\t', '<', '>', '&', '|', '^'},
+
+        {' ', '\t', '<', '>'}, {' ', '\t'}};
+
+    /**
+     * create command line.
+     *
+     * @param verificationType verification type
+     * @param executablePath   executable path
+     * @param cmd              cmd
+     * @return command line
+     */
+    private static String createCommandLine(int verificationType, final String executablePath, final String[] cmd) {
+        StringBuilder cmdbuf = new StringBuilder(80);
+
+        cmdbuf.append(executablePath);
+
+        for (int i = 1; i < cmd.length; ++i) {
+            cmdbuf.append(' ');
+            String s = cmd[i];
+            if (needsEscaping(verificationType, s)) {
+                cmdbuf.append('"').append(s);
+
+                if ((verificationType != VERIFICATION_CMD_BAT) && s.endsWith("\\")) {
+                    cmdbuf.append('\\');
+                }
+                cmdbuf.append('"');
+            } else {
+                cmdbuf.append(s);
+            }
         }
-        cmdbuf.append('"');
-      } else {
-        cmdbuf.append(s);
-      }
+        return cmdbuf.toString();
     }
-    return cmdbuf.toString();
-  }
-
-  /**
-   * whether is quoted.
-   * @param noQuotesInside
-   * @param arg
-   * @param errorMessage
-   * @return boolean
-   */
-  private static boolean isQuoted(boolean noQuotesInside, String arg, String errorMessage) {
-    int lastPos = arg.length() - 1;
-    if (lastPos >= 1 && arg.charAt(0) == '"' && arg.charAt(lastPos) == '"') {
-      // The argument has already been quoted.
-      if (noQuotesInside) {
-        if (arg.indexOf('"', 1) != lastPos) {
-          // There is ["] inside.
-          throw new IllegalArgumentException(errorMessage);
+
+    /**
+     * whether is quoted.
+     *
+     * @param noQuotesInside no quotes inside
+     * @param arg            arg
+     * @param errorMessage   error message
+     * @return boolean
+     */
+    private static boolean isQuoted(boolean noQuotesInside, String arg, String errorMessage) {
+        int lastPos = arg.length() - 1;
+        if (lastPos >= 1 && arg.charAt(0) == '"' && arg.charAt(lastPos) == '"') {
+            // The argument has already been quoted.
+            if (noQuotesInside && arg.indexOf('"', 1) != lastPos) {
+                // There is ["] inside.
+                throw new IllegalArgumentException(errorMessage);
+            }
+            return true;
         }
-      }
-      return true;
-    }
-    if (noQuotesInside) {
-      if (arg.indexOf('"') >= 0) {
-        // There is ["] inside.
-        throw new IllegalArgumentException(errorMessage);
-      }
-    }
-    return false;
-  }
-
-  /**
-   * whether needs escaping.
-   *
-   * @param verificationType  verification type
-   * @param arg               arg
-   * @return boolean
-   */
-  private static boolean needsEscaping(int verificationType, String arg) {
-
-    boolean argIsQuoted = isQuoted((verificationType == VERIFICATION_CMD_BAT), arg, "Argument has embedded quote, use the explicit CMD.EXE call.");
-
-    if (!argIsQuoted) {
-      char[] testEscape = ESCAPE_VERIFICATION[verificationType];
-      for (int i = 0; i < testEscape.length; ++i) {
-        if (arg.indexOf(testEscape[i]) >= 0) {
-          return true;
+        if (noQuotesInside && arg.indexOf('"') >= 0) {
+            // There is ["] inside.
+            throw new IllegalArgumentException(errorMessage);
         }
-      }
+        return false;
     }
-    return false;
-  }
-
-  /**
-   * kill yarn application.
-   *
-   * @param appIds      app id list
-   * @param logger      logger
-   * @param tenantCode  tenant code
-   * @param executePath     execute path
-   */
-  public static void cancelApplication(List<String> appIds, Logger logger, String tenantCode, String executePath) {
-    if (appIds.size() > 0) {
-      String appid = appIds.get(appIds.size() - 1);
-      String commandFile = String
-              .format("%s/%s.kill", executePath, appid);
-      String cmd = "yarn application -kill " + appid;
-      try {
-        StringBuilder sb = new StringBuilder();
-        sb.append("#!/bin/sh\n");
-        sb.append("BASEDIR=$(cd `dirname $0`; pwd)\n");
-        sb.append("cd $BASEDIR\n");
-        if (CommonUtils.getSystemEnvPath() != null) {
-          sb.append("source " + CommonUtils.getSystemEnvPath() + "\n");
-        }
-        sb.append("\n\n");
-        sb.append(cmd);
-
-        File f = new File(commandFile);
 
-        if (!f.exists()) {
-          FileUtils.writeStringToFile(new File(commandFile), sb.toString(), StandardCharsets.UTF_8);
+    /**
+     * whether needs escaping.
+     *
+     * @param verificationType verification type
+     * @param arg              arg
+     * @return boolean
+     */
+    private static boolean needsEscaping(int verificationType, String arg) {
+
+        boolean argIsQuoted = isQuoted((verificationType == VERIFICATION_CMD_BAT), arg, "Argument has embedded quote, use the explicit CMD.EXE call.");
+
+        if (!argIsQuoted) {
+            char[] testEscape = ESCAPE_VERIFICATION[verificationType];
+            for (char c : testEscape) {
+                if (arg.indexOf(c) >= 0) {
+                    return true;
+                }
+            }
         }
+        return false;
+    }
 
-        String runCmd = "sh " + commandFile;
-        if (StringUtils.isNotEmpty(tenantCode)) {
-          runCmd = "sudo -u " + tenantCode + " " + runCmd;
+    /**
+     * kill yarn application.
+     *
+     * @param appIds      app id list
+     * @param logger      logger
+     * @param tenantCode  tenant code
+     * @param executePath execute path
+     */
+    public static void cancelApplication(List<String> appIds, Logger logger, String tenantCode, String executePath) {
+        if (CollectionUtils.isNotEmpty(appIds)) {
+
+            for (String appId : appIds) {
+                try {
+                    ExecutionStatus applicationStatus = HadoopUtils.getInstance().getApplicationStatus(appId);
+
+                    if (!applicationStatus.typeIsFinished()) {
+                        String commandFile = String
+                            .format("%s/%s.kill", executePath, appId);
+                        String cmd = "yarn application -kill " + appId;
+                        execYarnKillCommand(logger, tenantCode, appId, commandFile, cmd);
+                    }
+                } catch (Exception e) {
+                    logger.error(String.format("Get yarn application app id [%s] status failed: [%s]", appId, e.getMessage()));
+                }
+            }
         }
+    }
 
-        logger.info("kill cmd:{}", runCmd);
-
-        Runtime.getRuntime().exec(runCmd);
-      } catch (Exception e) {
-        logger.error("kill application error", e);
-      }
+    /**
+     * build kill command for yarn application
+     *
+     * @param logger      logger
+     * @param tenantCode  tenant code
+     * @param appId       app id
+     * @param commandFile command file
+     * @param cmd         cmd
+     */
+    private static void execYarnKillCommand(Logger logger, String tenantCode, String appId, String commandFile, String cmd) {
+        try {
+            StringBuilder sb = new StringBuilder();
+            sb.append("#!/bin/sh\n");
+            sb.append("BASEDIR=$(cd `dirname $0`; pwd)\n");
+            sb.append("cd $BASEDIR\n");
+            if (CommonUtils.getSystemEnvPath() != null) {
+                sb.append("source ").append(CommonUtils.getSystemEnvPath()).append("\n");
+            }
+            sb.append("\n\n");
+            sb.append(cmd);
+
+            File f = new File(commandFile);
+
+            if (!f.exists()) {
+                FileUtils.writeStringToFile(new File(commandFile), sb.toString(), StandardCharsets.UTF_8);
+            }
+
+            String runCmd = String.format("%s %s", Constants.SH, commandFile);
+            if (StringUtils.isNotEmpty(tenantCode)) {
+                runCmd = "sudo -u " + tenantCode + " " + runCmd;
+            }
+
+            logger.info("kill cmd:{}", runCmd);
+            Runtime.getRuntime().exec(runCmd);

Review comment:
       yes, fixed




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-dolphinscheduler] sonarcloud[bot] commented on pull request #4042: [FIX-3900][server] kill multi yarn app in one job

Posted by GitBox <gi...@apache.org>.
sonarcloud[bot] commented on pull request #4042:
URL: https://github.com/apache/incubator-dolphinscheduler/pull/4042#issuecomment-728970207


   Kudos, SonarCloud Quality Gate passed!
   
   [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/bug.png' alt='Bug' width='16' height='16' />](https://sonarcloud.io/project/issues?id=apache-dolphinscheduler&pullRequest=4042&resolved=false&types=BUG) [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A.png' alt='A' width='16' height='16' />](https://sonarcloud.io/project/issues?id=apache-dolphinscheduler&pullRequest=4042&resolved=false&types=BUG) [0 Bugs](https://sonarcloud.io/project/issues?id=apache-dolphinscheduler&pullRequest=4042&resolved=false&types=BUG)  
   [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/vulnerability.png' alt='Vulnerability' width='16' height='16' />](https://sonarcloud.io/project/issues?id=apache-dolphinscheduler&pullRequest=4042&resolved=false&types=VULNERABILITY) [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A.png' alt='A' width='16' height='16' />](https://sonarcloud.io/project/issues?id=apache-dolphinscheduler&pullRequest=4042&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonarcloud.io/project/issues?id=apache-dolphinscheduler&pullRequest=4042&resolved=false&types=VULNERABILITY) (and [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/security_hotspot.png' alt='Security Hotspot' width='16' height='16' />](https://sonarcloud.io/project/issues?id=apache-dolphinscheduler&pullRequest=4042&resolved=false&types=SECURITY_HOTSPOT) [0 Security Hotspots](https://sonarcloud.io/proje
 ct/issues?id=apache-dolphinscheduler&pullRequest=4042&resolved=false&types=SECURITY_HOTSPOT) to review)  
   [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/code_smell.png' alt='Code Smell' width='16' height='16' />](https://sonarcloud.io/project/issues?id=apache-dolphinscheduler&pullRequest=4042&resolved=false&types=CODE_SMELL) [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A.png' alt='A' width='16' height='16' />](https://sonarcloud.io/project/issues?id=apache-dolphinscheduler&pullRequest=4042&resolved=false&types=CODE_SMELL) [0 Code Smells](https://sonarcloud.io/project/issues?id=apache-dolphinscheduler&pullRequest=4042&resolved=false&types=CODE_SMELL)
   
   [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/CoverageChart/60.png' alt='63.6%' width='16' height='16' />](https://sonarcloud.io/component_measures?id=apache-dolphinscheduler&pullRequest=4042&metric=new_coverage&view=list) [63.6% Coverage](https://sonarcloud.io/component_measures?id=apache-dolphinscheduler&pullRequest=4042&metric=new_coverage&view=list)  
   [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/Duplications/3.png' alt='0.0%' width='16' height='16' />](https://sonarcloud.io/component_measures?id=apache-dolphinscheduler&pullRequest=4042&metric=new_duplicated_lines_density&view=list) [0.0% Duplication](https://sonarcloud.io/component_measures?id=apache-dolphinscheduler&pullRequest=4042&metric=new_duplicated_lines_density&view=list)
   
   


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-dolphinscheduler] lenboo commented on a change in pull request #4042: [FIX-3900][server] kill multi yarn app in one job

Posted by GitBox <gi...@apache.org>.
lenboo commented on a change in pull request #4042:
URL: https://github.com/apache/incubator-dolphinscheduler/pull/4042#discussion_r524946884



##########
File path: dolphinscheduler-server/src/main/java/org/apache/dolphinscheduler/server/utils/ProcessUtils.java
##########
@@ -38,368 +41,408 @@
 import java.util.regex.Pattern;
 
 /**
- *  mainly used to get the start command line of a process.
+ * mainly used to get the start command line of a process.
  */
 public class ProcessUtils {
-  /**
-   * logger.
-   */
-  private static final Logger logger = LoggerFactory.getLogger(ProcessUtils.class);
-
-  /**
-   * Initialization regularization, solve the problem of pre-compilation performance,
-   * avoid the thread safety problem of multi-thread operation.
-   */
-  private static final Pattern MACPATTERN = Pattern.compile("-[+|-]-\\s(\\d+)");
-
-  private static final Pattern WINDOWSATTERN = Pattern.compile("(\\d+)");
-
-  /**
-   * build command line characters.
-   * @param commandList command list
-   * @return command
-   */
-  public static String buildCommandStr(List<String> commandList) {
-    String cmdstr;
-    String[] cmd = commandList.toArray(new String[commandList.size()]);
-    SecurityManager security = System.getSecurityManager();
-    boolean allowAmbiguousCommands = false;
-    if (security == null) {
-      allowAmbiguousCommands = true;
-      String value = System.getProperty("jdk.lang.Process.allowAmbiguousCommands");
-      if (value != null) {
-        allowAmbiguousCommands = !"false".equalsIgnoreCase(value);
-      }
+    /**
+     * logger.
+     */
+    private static final Logger logger = LoggerFactory.getLogger(ProcessUtils.class);
+
+    /**
+     * Initialization regularization, solve the problem of pre-compilation performance,
+     * avoid the thread safety problem of multi-thread operation.
+     */
+    private static final Pattern MACPATTERN = Pattern.compile("-[+|-]-\\s(\\d+)");
+
+    private static final Pattern WINDOWSATTERN = Pattern.compile("(\\d+)");
+
+    private static final String LOCAL_PROCESS_EXEC = "jdk.lang.Process.allowAmbiguousCommands";
+
+    /**
+     * build command line characters.
+     *
+     * @param commandList command list
+     * @return command
+     */
+    public static String buildCommandStr(List<String> commandList) {
+        String cmdstr;
+        String[] cmd = commandList.toArray(new String[0]);
+        SecurityManager security = System.getSecurityManager();
+        boolean allowAmbiguousCommands = isAllowAmbiguousCommands(security);
+        if (allowAmbiguousCommands) {
+
+            String executablePath = new File(cmd[0]).getPath();
+
+            if (needsEscaping(VERIFICATION_LEGACY, executablePath)) {
+                executablePath = quoteString(executablePath);
+            }
+
+            cmdstr = createCommandLine(
+                VERIFICATION_LEGACY, executablePath, cmd);
+        } else {
+            String executablePath;
+            try {
+                executablePath = getExecutablePath(cmd[0]);
+            } catch (IllegalArgumentException e) {
+
+                StringBuilder join = new StringBuilder();
+                for (String s : cmd) {
+                    join.append(s).append(' ');
+                }
+
+                cmd = getTokensFromCommand(join.toString());
+                executablePath = getExecutablePath(cmd[0]);
+
+                // Check new executable name once more
+                if (security != null) {
+                    security.checkExec(executablePath);
+                }
+            }
+
+            cmdstr = createCommandLine(
+
+                isShellFile(executablePath) ? VERIFICATION_CMD_BAT : VERIFICATION_WIN32, quoteString(executablePath), cmd);
+        }
+        return cmdstr;
     }
-    if (allowAmbiguousCommands) {
-
-      String executablePath = new File(cmd[0]).getPath();
-
-      if (needsEscaping(VERIFICATION_LEGACY, executablePath)) {
-        executablePath = quoteString(executablePath);
-      }
-
-      cmdstr = createCommandLine(
-              VERIFICATION_LEGACY, executablePath, cmd);
-    } else {
-      String executablePath;
-      try {
-        executablePath = getExecutablePath(cmd[0]);
-      } catch (IllegalArgumentException e) {
 
-        StringBuilder join = new StringBuilder();
-        for (String s : cmd) {
-          join.append(s).append(' ');
+    /**
+     * check is allow ambiguous commands
+     *
+     * @param security security manager
+     * @return allow ambiguous command flag
+     */
+    private static boolean isAllowAmbiguousCommands(SecurityManager security) {
+        boolean allowAmbiguousCommands = false;
+        if (security == null) {
+            allowAmbiguousCommands = true;
+            String value = System.getProperty(LOCAL_PROCESS_EXEC);
+            if (value != null) {
+                allowAmbiguousCommands = !Constants.STRING_FALSE.equalsIgnoreCase(value);
+            }
         }
+        return allowAmbiguousCommands;
+    }
 
-        cmd = getTokensFromCommand(join.toString());
-        executablePath = getExecutablePath(cmd[0]);
+    /**
+     * get executable path.
+     *
+     * @param path path
+     * @return executable path
+     */
+    private static String getExecutablePath(String path) {
+        boolean pathIsQuoted = isQuoted(true, path, "Executable name has embedded quote, split the arguments");
+
+        File fileToRun = new File(pathIsQuoted ? path.substring(1, path.length() - 1) : path);
+        return fileToRun.getPath();
+    }
 
-        // Check new executable name once more
-        if (security != null) {
-          security.checkExec(executablePath);
-        }
-      }
+    /**
+     * whether is shell file.
+     *
+     * @param executablePath executable path
+     * @return true if endsWith .CMD or .BAT
+     */
+    private static boolean isShellFile(String executablePath) {
+        String upPath = executablePath.toUpperCase();
+        return (upPath.endsWith(".CMD") || upPath.endsWith(".BAT"));
+    }
 
-      cmdstr = createCommandLine(
+    /**
+     * quote string.
+     *
+     * @param arg argument
+     * @return format arg
+     */
+    private static String quoteString(String arg) {
+        return '"' + arg + '"';
+    }
 
-              isShellFile(executablePath) ? VERIFICATION_CMD_BAT : VERIFICATION_WIN32, quoteString(executablePath), cmd);
+    /**
+     * get tokens from command.
+     *
+     * @param command command
+     * @return token string array
+     */
+    private static String[] getTokensFromCommand(String command) {
+        ArrayList<String> matchList = new ArrayList<>(8);
+        Matcher regexMatcher = LazyPattern.PATTERN.matcher(command);
+        while (regexMatcher.find()) {
+            matchList.add(regexMatcher.group());
+        }
+        return matchList.toArray(new String[0]);
     }
-    return cmdstr;
-  }
-
-  /**
-   * get executable path.
-   *
-   * @param path path
-   * @return executable path
-   */
-  private static String getExecutablePath(String path) {
-    boolean pathIsQuoted = isQuoted(true, path, "Executable name has embedded quote, split the arguments");
-
-    File fileToRun = new File(pathIsQuoted ? path.substring(1, path.length() - 1) : path);
-    return fileToRun.getPath();
-  }
-
-  /**
-   * whether is shell file.
-   *
-   * @param executablePath executable path
-   * @return true if endsWith .CMD or .BAT
-   */
-  private static boolean isShellFile(String executablePath) {
-    String upPath = executablePath.toUpperCase();
-    return (upPath.endsWith(".CMD") || upPath.endsWith(".BAT"));
-  }
-
-  /**
-   * quote string.
-   *
-   * @param arg argument
-   * @return format arg
-   */
-  private static String quoteString(String arg) {
-    StringBuilder argbuf = new StringBuilder(arg.length() + 2);
-    return argbuf.append('"').append(arg).append('"').toString();
-  }
-
-  /**
-   * get tokens from command.
-   *
-   * @param command command
-   * @return token string array
-   */
-  private static String[] getTokensFromCommand(String command) {
-    ArrayList<String> matchList = new ArrayList<>(8);
-    Matcher regexMatcher = LazyPattern.PATTERN.matcher(command);
-    while (regexMatcher.find()) {
-      matchList.add(regexMatcher.group());
+
+    /**
+     * Lazy Pattern.
+     */
+    private static class LazyPattern {
+        /**
+         * Escape-support version:
+         * "(\")((?:\\\\\\1|.)+?)\\1|([^\\s\"]+)";
+         */
+        private static final Pattern PATTERN = Pattern.compile("[^\\s\"]+|\"[^\"]*\"");
     }
-    return matchList.toArray(new String[matchList.size()]);
-  }
-
-  /**
-   * Lazy Pattern.
-   */
-  private static class LazyPattern {
-    // Escape-support version:
-    // "(\")((?:\\\\\\1|.)+?)\\1|([^\\s\"]+)";
-    private static final Pattern PATTERN = Pattern.compile("[^\\s\"]+|\"[^\"]*\"");
-  }
-
-  /**
-   * verification cmd bat.
-   */
-  private static final int VERIFICATION_CMD_BAT = 0;
-
-  /**
-   * verification win32.
-   */
-  private static final int VERIFICATION_WIN32 = 1;
-
-  /**
-   * verification legacy.
-   */
-  private static final int VERIFICATION_LEGACY = 2;
-
-  /**
-   * escape verification.
-   */
-  private static final char[][] ESCAPE_VERIFICATION = {{' ', '\t', '<', '>', '&', '|', '^'},
-
-    {' ', '\t', '<', '>'}, {' ', '\t'}};
-
-  /**
-   * create command line.
-   * @param verificationType  verification type
-   * @param executablePath    executable path
-   * @param cmd               cmd
-   * @return command line
-   */
-  private static String createCommandLine(int verificationType, final String executablePath, final String[] cmd) {
-    StringBuilder cmdbuf = new StringBuilder(80);
-
-    cmdbuf.append(executablePath);
-
-    for (int i = 1; i < cmd.length; ++i) {
-      cmdbuf.append(' ');
-      String s = cmd[i];
-      if (needsEscaping(verificationType, s)) {
-        cmdbuf.append('"').append(s);
-
-        if ((verificationType != VERIFICATION_CMD_BAT) && s.endsWith("\\")) {
-          cmdbuf.append('\\');
+
+    /**
+     * verification cmd bat.
+     */
+    private static final int VERIFICATION_CMD_BAT = 0;
+
+    /**
+     * verification win32.
+     */
+    private static final int VERIFICATION_WIN32 = 1;
+
+    /**
+     * verification legacy.
+     */
+    private static final int VERIFICATION_LEGACY = 2;
+
+    /**
+     * escape verification.
+     */
+    private static final char[][] ESCAPE_VERIFICATION = {{' ', '\t', '<', '>', '&', '|', '^'},
+
+        {' ', '\t', '<', '>'}, {' ', '\t'}};
+
+    /**
+     * create command line.
+     *
+     * @param verificationType verification type
+     * @param executablePath   executable path
+     * @param cmd              cmd
+     * @return command line
+     */
+    private static String createCommandLine(int verificationType, final String executablePath, final String[] cmd) {
+        StringBuilder cmdbuf = new StringBuilder(80);
+
+        cmdbuf.append(executablePath);
+
+        for (int i = 1; i < cmd.length; ++i) {
+            cmdbuf.append(' ');
+            String s = cmd[i];
+            if (needsEscaping(verificationType, s)) {
+                cmdbuf.append('"').append(s);
+
+                if ((verificationType != VERIFICATION_CMD_BAT) && s.endsWith("\\")) {
+                    cmdbuf.append('\\');
+                }
+                cmdbuf.append('"');
+            } else {
+                cmdbuf.append(s);
+            }
         }
-        cmdbuf.append('"');
-      } else {
-        cmdbuf.append(s);
-      }
+        return cmdbuf.toString();
     }
-    return cmdbuf.toString();
-  }
-
-  /**
-   * whether is quoted.
-   * @param noQuotesInside
-   * @param arg
-   * @param errorMessage
-   * @return boolean
-   */
-  private static boolean isQuoted(boolean noQuotesInside, String arg, String errorMessage) {
-    int lastPos = arg.length() - 1;
-    if (lastPos >= 1 && arg.charAt(0) == '"' && arg.charAt(lastPos) == '"') {
-      // The argument has already been quoted.
-      if (noQuotesInside) {
-        if (arg.indexOf('"', 1) != lastPos) {
-          // There is ["] inside.
-          throw new IllegalArgumentException(errorMessage);
+
+    /**
+     * whether is quoted.
+     *
+     * @param noQuotesInside no quotes inside
+     * @param arg            arg
+     * @param errorMessage   error message
+     * @return boolean
+     */
+    private static boolean isQuoted(boolean noQuotesInside, String arg, String errorMessage) {
+        int lastPos = arg.length() - 1;
+        if (lastPos >= 1 && arg.charAt(0) == '"' && arg.charAt(lastPos) == '"') {
+            // The argument has already been quoted.
+            if (noQuotesInside && arg.indexOf('"', 1) != lastPos) {
+                // There is ["] inside.
+                throw new IllegalArgumentException(errorMessage);
+            }
+            return true;
         }
-      }
-      return true;
-    }
-    if (noQuotesInside) {
-      if (arg.indexOf('"') >= 0) {
-        // There is ["] inside.
-        throw new IllegalArgumentException(errorMessage);
-      }
-    }
-    return false;
-  }
-
-  /**
-   * whether needs escaping.
-   *
-   * @param verificationType  verification type
-   * @param arg               arg
-   * @return boolean
-   */
-  private static boolean needsEscaping(int verificationType, String arg) {
-
-    boolean argIsQuoted = isQuoted((verificationType == VERIFICATION_CMD_BAT), arg, "Argument has embedded quote, use the explicit CMD.EXE call.");
-
-    if (!argIsQuoted) {
-      char[] testEscape = ESCAPE_VERIFICATION[verificationType];
-      for (int i = 0; i < testEscape.length; ++i) {
-        if (arg.indexOf(testEscape[i]) >= 0) {
-          return true;
+        if (noQuotesInside && arg.indexOf('"') >= 0) {
+            // There is ["] inside.
+            throw new IllegalArgumentException(errorMessage);
         }
-      }
+        return false;
     }
-    return false;
-  }
-
-  /**
-   * kill yarn application.
-   *
-   * @param appIds      app id list
-   * @param logger      logger
-   * @param tenantCode  tenant code
-   * @param executePath     execute path
-   */
-  public static void cancelApplication(List<String> appIds, Logger logger, String tenantCode, String executePath) {
-    if (appIds.size() > 0) {
-      String appid = appIds.get(appIds.size() - 1);
-      String commandFile = String
-              .format("%s/%s.kill", executePath, appid);
-      String cmd = "yarn application -kill " + appid;
-      try {
-        StringBuilder sb = new StringBuilder();
-        sb.append("#!/bin/sh\n");
-        sb.append("BASEDIR=$(cd `dirname $0`; pwd)\n");
-        sb.append("cd $BASEDIR\n");
-        if (CommonUtils.getSystemEnvPath() != null) {
-          sb.append("source " + CommonUtils.getSystemEnvPath() + "\n");
-        }
-        sb.append("\n\n");
-        sb.append(cmd);
-
-        File f = new File(commandFile);
 
-        if (!f.exists()) {
-          FileUtils.writeStringToFile(new File(commandFile), sb.toString(), StandardCharsets.UTF_8);
+    /**
+     * whether needs escaping.
+     *
+     * @param verificationType verification type
+     * @param arg              arg
+     * @return boolean
+     */
+    private static boolean needsEscaping(int verificationType, String arg) {
+
+        boolean argIsQuoted = isQuoted((verificationType == VERIFICATION_CMD_BAT), arg, "Argument has embedded quote, use the explicit CMD.EXE call.");
+
+        if (!argIsQuoted) {
+            char[] testEscape = ESCAPE_VERIFICATION[verificationType];
+            for (char c : testEscape) {
+                if (arg.indexOf(c) >= 0) {
+                    return true;
+                }
+            }
         }
+        return false;
+    }
 
-        String runCmd = "sh " + commandFile;
-        if (StringUtils.isNotEmpty(tenantCode)) {
-          runCmd = "sudo -u " + tenantCode + " " + runCmd;
+    /**
+     * kill yarn application.
+     *
+     * @param appIds      app id list
+     * @param logger      logger
+     * @param tenantCode  tenant code
+     * @param executePath execute path
+     */
+    public static void cancelApplication(List<String> appIds, Logger logger, String tenantCode, String executePath) {
+        if (CollectionUtils.isNotEmpty(appIds)) {
+
+            for (String appId : appIds) {
+                try {
+                    ExecutionStatus applicationStatus = HadoopUtils.getInstance().getApplicationStatus(appId);
+
+                    if (!applicationStatus.typeIsFinished()) {
+                        String commandFile = String
+                            .format("%s/%s.kill", executePath, appId);
+                        String cmd = "yarn application -kill " + appId;
+                        execYarnKillCommand(logger, tenantCode, appId, commandFile, cmd);
+                    }
+                } catch (Exception e) {
+                    logger.error(String.format("Get yarn application app id [%s] status failed: [%s]", appId, e.getMessage()));
+                }
+            }
         }
+    }
 
-        logger.info("kill cmd:{}", runCmd);
-
-        Runtime.getRuntime().exec(runCmd);
-      } catch (Exception e) {
-        logger.error("kill application error", e);
-      }
+    /**
+     * build kill command for yarn application
+     *
+     * @param logger      logger
+     * @param tenantCode  tenant code
+     * @param appId       app id
+     * @param commandFile command file
+     * @param cmd         cmd
+     */
+    private static void execYarnKillCommand(Logger logger, String tenantCode, String appId, String commandFile, String cmd) {
+        try {
+            StringBuilder sb = new StringBuilder();
+            sb.append("#!/bin/sh\n");
+            sb.append("BASEDIR=$(cd `dirname $0`; pwd)\n");
+            sb.append("cd $BASEDIR\n");
+            if (CommonUtils.getSystemEnvPath() != null) {
+                sb.append("source ").append(CommonUtils.getSystemEnvPath()).append("\n");
+            }
+            sb.append("\n\n");
+            sb.append(cmd);
+
+            File f = new File(commandFile);
+
+            if (!f.exists()) {
+                FileUtils.writeStringToFile(new File(commandFile), sb.toString(), StandardCharsets.UTF_8);
+            }
+
+            String runCmd = "sh " + commandFile;

Review comment:
       is this "sh " can be instead?
   I can find it elsewhere.




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-dolphinscheduler] lenboo commented on a change in pull request #4042: [FIX-3900][server] kill multi yarn app in one job

Posted by GitBox <gi...@apache.org>.
lenboo commented on a change in pull request #4042:
URL: https://github.com/apache/incubator-dolphinscheduler/pull/4042#discussion_r524083485



##########
File path: dolphinscheduler-server/src/main/java/org/apache/dolphinscheduler/server/utils/ProcessUtils.java
##########
@@ -38,368 +41,406 @@
 import java.util.regex.Pattern;
 
 /**
- *  mainly used to get the start command line of a process.
+ * mainly used to get the start command line of a process.
  */
 public class ProcessUtils {
-  /**
-   * logger.
-   */
-  private static final Logger logger = LoggerFactory.getLogger(ProcessUtils.class);
-
-  /**
-   * Initialization regularization, solve the problem of pre-compilation performance,
-   * avoid the thread safety problem of multi-thread operation.
-   */
-  private static final Pattern MACPATTERN = Pattern.compile("-[+|-]-\\s(\\d+)");
-
-  private static final Pattern WINDOWSATTERN = Pattern.compile("(\\d+)");
-
-  /**
-   * build command line characters.
-   * @param commandList command list
-   * @return command
-   */
-  public static String buildCommandStr(List<String> commandList) {
-    String cmdstr;
-    String[] cmd = commandList.toArray(new String[commandList.size()]);
-    SecurityManager security = System.getSecurityManager();
-    boolean allowAmbiguousCommands = false;
-    if (security == null) {
-      allowAmbiguousCommands = true;
-      String value = System.getProperty("jdk.lang.Process.allowAmbiguousCommands");
-      if (value != null) {
-        allowAmbiguousCommands = !"false".equalsIgnoreCase(value);
-      }
+    /**
+     * logger.
+     */
+    private static final Logger logger = LoggerFactory.getLogger(ProcessUtils.class);
+
+    /**
+     * Initialization regularization, solve the problem of pre-compilation performance,
+     * avoid the thread safety problem of multi-thread operation.
+     */
+    private static final Pattern MACPATTERN = Pattern.compile("-[+|-]-\\s(\\d+)");
+
+    private static final Pattern WINDOWSATTERN = Pattern.compile("(\\d+)");
+
+    /**
+     * build command line characters.
+     *
+     * @param commandList command list
+     * @return command
+     */
+    public static String buildCommandStr(List<String> commandList) {
+        String cmdstr;
+        String[] cmd = commandList.toArray(new String[0]);
+        SecurityManager security = System.getSecurityManager();
+        boolean allowAmbiguousCommands = isAllowAmbiguousCommands(security);
+        if (allowAmbiguousCommands) {
+
+            String executablePath = new File(cmd[0]).getPath();
+
+            if (needsEscaping(VERIFICATION_LEGACY, executablePath)) {
+                executablePath = quoteString(executablePath);
+            }
+
+            cmdstr = createCommandLine(
+                VERIFICATION_LEGACY, executablePath, cmd);
+        } else {
+            String executablePath;
+            try {
+                executablePath = getExecutablePath(cmd[0]);
+            } catch (IllegalArgumentException e) {
+
+                StringBuilder join = new StringBuilder();
+                for (String s : cmd) {
+                    join.append(s).append(' ');
+                }
+
+                cmd = getTokensFromCommand(join.toString());
+                executablePath = getExecutablePath(cmd[0]);
+
+                // Check new executable name once more
+                if (security != null) {
+                    security.checkExec(executablePath);
+                }
+            }
+
+            cmdstr = createCommandLine(
+
+                isShellFile(executablePath) ? VERIFICATION_CMD_BAT : VERIFICATION_WIN32, quoteString(executablePath), cmd);
+        }
+        return cmdstr;
     }
-    if (allowAmbiguousCommands) {
-
-      String executablePath = new File(cmd[0]).getPath();
-
-      if (needsEscaping(VERIFICATION_LEGACY, executablePath)) {
-        executablePath = quoteString(executablePath);
-      }
-
-      cmdstr = createCommandLine(
-              VERIFICATION_LEGACY, executablePath, cmd);
-    } else {
-      String executablePath;
-      try {
-        executablePath = getExecutablePath(cmd[0]);
-      } catch (IllegalArgumentException e) {
 
-        StringBuilder join = new StringBuilder();
-        for (String s : cmd) {
-          join.append(s).append(' ');
+    /**
+     * check is allow ambiguous commands
+     *
+     * @param security security manager
+     * @return allow ambiguous command flag
+     */
+    private static boolean isAllowAmbiguousCommands(SecurityManager security) {
+        boolean allowAmbiguousCommands = false;
+        if (security == null) {
+            allowAmbiguousCommands = true;
+            String value = System.getProperty("jdk.lang.Process.allowAmbiguousCommands");

Review comment:
       magic number here




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-dolphinscheduler] sonarcloud[bot] commented on pull request #4042: [FIX-3900][server] kill multi yarn app in one job

Posted by GitBox <gi...@apache.org>.
sonarcloud[bot] commented on pull request #4042:
URL: https://github.com/apache/incubator-dolphinscheduler/pull/4042#issuecomment-726603497


   Kudos, SonarCloud Quality Gate passed!
   
   [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/bug.png' alt='Bug' width='16' height='16' />](https://sonarcloud.io/project/issues?id=apache-dolphinscheduler&pullRequest=4042&resolved=false&types=BUG) [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A.png' alt='A' width='16' height='16' />](https://sonarcloud.io/project/issues?id=apache-dolphinscheduler&pullRequest=4042&resolved=false&types=BUG) [0 Bugs](https://sonarcloud.io/project/issues?id=apache-dolphinscheduler&pullRequest=4042&resolved=false&types=BUG)  
   [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/vulnerability.png' alt='Vulnerability' width='16' height='16' />](https://sonarcloud.io/project/issues?id=apache-dolphinscheduler&pullRequest=4042&resolved=false&types=VULNERABILITY) [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A.png' alt='A' width='16' height='16' />](https://sonarcloud.io/project/issues?id=apache-dolphinscheduler&pullRequest=4042&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonarcloud.io/project/issues?id=apache-dolphinscheduler&pullRequest=4042&resolved=false&types=VULNERABILITY) (and [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/security_hotspot.png' alt='Security Hotspot' width='16' height='16' />](https://sonarcloud.io/project/issues?id=apache-dolphinscheduler&pullRequest=4042&resolved=false&types=SECURITY_HOTSPOT) [0 Security Hotspots](https://sonarcloud.io/proje
 ct/issues?id=apache-dolphinscheduler&pullRequest=4042&resolved=false&types=SECURITY_HOTSPOT) to review)  
   [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/code_smell.png' alt='Code Smell' width='16' height='16' />](https://sonarcloud.io/project/issues?id=apache-dolphinscheduler&pullRequest=4042&resolved=false&types=CODE_SMELL) [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A.png' alt='A' width='16' height='16' />](https://sonarcloud.io/project/issues?id=apache-dolphinscheduler&pullRequest=4042&resolved=false&types=CODE_SMELL) [0 Code Smells](https://sonarcloud.io/project/issues?id=apache-dolphinscheduler&pullRequest=4042&resolved=false&types=CODE_SMELL)
   
   [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/CoverageChart/60.png' alt='63.5%' width='16' height='16' />](https://sonarcloud.io/component_measures?id=apache-dolphinscheduler&pullRequest=4042&metric=new_coverage&view=list) [63.5% Coverage](https://sonarcloud.io/component_measures?id=apache-dolphinscheduler&pullRequest=4042&metric=new_coverage&view=list)  
   [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/Duplications/3.png' alt='0.0%' width='16' height='16' />](https://sonarcloud.io/component_measures?id=apache-dolphinscheduler&pullRequest=4042&metric=new_duplicated_lines_density&view=list) [0.0% Duplication](https://sonarcloud.io/component_measures?id=apache-dolphinscheduler&pullRequest=4042&metric=new_duplicated_lines_density&view=list)
   
   


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-dolphinscheduler] sonarcloud[bot] commented on pull request #4042: [FIX-3900][server] kill multi yarn app in one job

Posted by GitBox <gi...@apache.org>.
sonarcloud[bot] commented on pull request #4042:
URL: https://github.com/apache/incubator-dolphinscheduler/pull/4042#issuecomment-731184583


   Kudos, SonarCloud Quality Gate passed!
   
   [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/bug.png' alt='Bug' width='16' height='16' />](https://sonarcloud.io/project/issues?id=apache-dolphinscheduler&pullRequest=4042&resolved=false&types=BUG) [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A.png' alt='A' width='16' height='16' />](https://sonarcloud.io/project/issues?id=apache-dolphinscheduler&pullRequest=4042&resolved=false&types=BUG) [0 Bugs](https://sonarcloud.io/project/issues?id=apache-dolphinscheduler&pullRequest=4042&resolved=false&types=BUG)  
   [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/vulnerability.png' alt='Vulnerability' width='16' height='16' />](https://sonarcloud.io/project/issues?id=apache-dolphinscheduler&pullRequest=4042&resolved=false&types=VULNERABILITY) [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A.png' alt='A' width='16' height='16' />](https://sonarcloud.io/project/issues?id=apache-dolphinscheduler&pullRequest=4042&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonarcloud.io/project/issues?id=apache-dolphinscheduler&pullRequest=4042&resolved=false&types=VULNERABILITY) (and [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/security_hotspot.png' alt='Security Hotspot' width='16' height='16' />](https://sonarcloud.io/project/issues?id=apache-dolphinscheduler&pullRequest=4042&resolved=false&types=SECURITY_HOTSPOT) [0 Security Hotspots](https://sonarcloud.io/proje
 ct/issues?id=apache-dolphinscheduler&pullRequest=4042&resolved=false&types=SECURITY_HOTSPOT) to review)  
   [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/code_smell.png' alt='Code Smell' width='16' height='16' />](https://sonarcloud.io/project/issues?id=apache-dolphinscheduler&pullRequest=4042&resolved=false&types=CODE_SMELL) [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A.png' alt='A' width='16' height='16' />](https://sonarcloud.io/project/issues?id=apache-dolphinscheduler&pullRequest=4042&resolved=false&types=CODE_SMELL) [0 Code Smells](https://sonarcloud.io/project/issues?id=apache-dolphinscheduler&pullRequest=4042&resolved=false&types=CODE_SMELL)
   
   [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/CoverageChart/60.png' alt='62.7%' width='16' height='16' />](https://sonarcloud.io/component_measures?id=apache-dolphinscheduler&pullRequest=4042&metric=new_coverage&view=list) [62.7% Coverage](https://sonarcloud.io/component_measures?id=apache-dolphinscheduler&pullRequest=4042&metric=new_coverage&view=list)  
   [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/Duplications/3.png' alt='0.0%' width='16' height='16' />](https://sonarcloud.io/component_measures?id=apache-dolphinscheduler&pullRequest=4042&metric=new_duplicated_lines_density&view=list) [0.0% Duplication](https://sonarcloud.io/component_measures?id=apache-dolphinscheduler&pullRequest=4042&metric=new_duplicated_lines_density&view=list)
   
   


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-dolphinscheduler] Eights-Li commented on pull request #4042: [FIX-3900][server] kill multi yarn app in one job

Posted by GitBox <gi...@apache.org>.
Eights-Li commented on pull request #4042:
URL: https://github.com/apache/incubator-dolphinscheduler/pull/4042#issuecomment-731693996


   > don't use Runtime.getRuntime().exec directly, replace with OSUtils.exeCmd, thx
   please review this pr~ 
   


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-dolphinscheduler] sonarcloud[bot] commented on pull request #4042: [FIX-3900][server] kill multi yarn app in one job

Posted by GitBox <gi...@apache.org>.
sonarcloud[bot] commented on pull request #4042:
URL: https://github.com/apache/incubator-dolphinscheduler/pull/4042#issuecomment-727956170


   Kudos, SonarCloud Quality Gate passed!
   
   [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/bug.png' alt='Bug' width='16' height='16' />](https://sonarcloud.io/project/issues?id=apache-dolphinscheduler&pullRequest=4042&resolved=false&types=BUG) [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A.png' alt='A' width='16' height='16' />](https://sonarcloud.io/project/issues?id=apache-dolphinscheduler&pullRequest=4042&resolved=false&types=BUG) [0 Bugs](https://sonarcloud.io/project/issues?id=apache-dolphinscheduler&pullRequest=4042&resolved=false&types=BUG)  
   [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/vulnerability.png' alt='Vulnerability' width='16' height='16' />](https://sonarcloud.io/project/issues?id=apache-dolphinscheduler&pullRequest=4042&resolved=false&types=VULNERABILITY) [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A.png' alt='A' width='16' height='16' />](https://sonarcloud.io/project/issues?id=apache-dolphinscheduler&pullRequest=4042&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonarcloud.io/project/issues?id=apache-dolphinscheduler&pullRequest=4042&resolved=false&types=VULNERABILITY) (and [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/security_hotspot.png' alt='Security Hotspot' width='16' height='16' />](https://sonarcloud.io/project/issues?id=apache-dolphinscheduler&pullRequest=4042&resolved=false&types=SECURITY_HOTSPOT) [0 Security Hotspots](https://sonarcloud.io/proje
 ct/issues?id=apache-dolphinscheduler&pullRequest=4042&resolved=false&types=SECURITY_HOTSPOT) to review)  
   [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/code_smell.png' alt='Code Smell' width='16' height='16' />](https://sonarcloud.io/project/issues?id=apache-dolphinscheduler&pullRequest=4042&resolved=false&types=CODE_SMELL) [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A.png' alt='A' width='16' height='16' />](https://sonarcloud.io/project/issues?id=apache-dolphinscheduler&pullRequest=4042&resolved=false&types=CODE_SMELL) [0 Code Smells](https://sonarcloud.io/project/issues?id=apache-dolphinscheduler&pullRequest=4042&resolved=false&types=CODE_SMELL)
   
   [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/CoverageChart/60.png' alt='63.5%' width='16' height='16' />](https://sonarcloud.io/component_measures?id=apache-dolphinscheduler&pullRequest=4042&metric=new_coverage&view=list) [63.5% Coverage](https://sonarcloud.io/component_measures?id=apache-dolphinscheduler&pullRequest=4042&metric=new_coverage&view=list)  
   [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/Duplications/3.png' alt='0.0%' width='16' height='16' />](https://sonarcloud.io/component_measures?id=apache-dolphinscheduler&pullRequest=4042&metric=new_duplicated_lines_density&view=list) [0.0% Duplication](https://sonarcloud.io/component_measures?id=apache-dolphinscheduler&pullRequest=4042&metric=new_duplicated_lines_density&view=list)
   
   


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-dolphinscheduler] sonarcloud[bot] removed a comment on pull request #4042: [FIX-3900][server] kill multi yarn app in one job

Posted by GitBox <gi...@apache.org>.
sonarcloud[bot] removed a comment on pull request #4042:
URL: https://github.com/apache/incubator-dolphinscheduler/pull/4042#issuecomment-726603497


   Kudos, SonarCloud Quality Gate passed!
   
   [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/bug.png' alt='Bug' width='16' height='16' />](https://sonarcloud.io/project/issues?id=apache-dolphinscheduler&pullRequest=4042&resolved=false&types=BUG) [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A.png' alt='A' width='16' height='16' />](https://sonarcloud.io/project/issues?id=apache-dolphinscheduler&pullRequest=4042&resolved=false&types=BUG) [0 Bugs](https://sonarcloud.io/project/issues?id=apache-dolphinscheduler&pullRequest=4042&resolved=false&types=BUG)  
   [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/vulnerability.png' alt='Vulnerability' width='16' height='16' />](https://sonarcloud.io/project/issues?id=apache-dolphinscheduler&pullRequest=4042&resolved=false&types=VULNERABILITY) [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A.png' alt='A' width='16' height='16' />](https://sonarcloud.io/project/issues?id=apache-dolphinscheduler&pullRequest=4042&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonarcloud.io/project/issues?id=apache-dolphinscheduler&pullRequest=4042&resolved=false&types=VULNERABILITY) (and [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/security_hotspot.png' alt='Security Hotspot' width='16' height='16' />](https://sonarcloud.io/project/issues?id=apache-dolphinscheduler&pullRequest=4042&resolved=false&types=SECURITY_HOTSPOT) [0 Security Hotspots](https://sonarcloud.io/proje
 ct/issues?id=apache-dolphinscheduler&pullRequest=4042&resolved=false&types=SECURITY_HOTSPOT) to review)  
   [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/code_smell.png' alt='Code Smell' width='16' height='16' />](https://sonarcloud.io/project/issues?id=apache-dolphinscheduler&pullRequest=4042&resolved=false&types=CODE_SMELL) [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A.png' alt='A' width='16' height='16' />](https://sonarcloud.io/project/issues?id=apache-dolphinscheduler&pullRequest=4042&resolved=false&types=CODE_SMELL) [0 Code Smells](https://sonarcloud.io/project/issues?id=apache-dolphinscheduler&pullRequest=4042&resolved=false&types=CODE_SMELL)
   
   [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/CoverageChart/60.png' alt='63.5%' width='16' height='16' />](https://sonarcloud.io/component_measures?id=apache-dolphinscheduler&pullRequest=4042&metric=new_coverage&view=list) [63.5% Coverage](https://sonarcloud.io/component_measures?id=apache-dolphinscheduler&pullRequest=4042&metric=new_coverage&view=list)  
   [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/Duplications/3.png' alt='0.0%' width='16' height='16' />](https://sonarcloud.io/component_measures?id=apache-dolphinscheduler&pullRequest=4042&metric=new_duplicated_lines_density&view=list) [0.0% Duplication](https://sonarcloud.io/component_measures?id=apache-dolphinscheduler&pullRequest=4042&metric=new_duplicated_lines_density&view=list)
   
   


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-dolphinscheduler] sonarcloud[bot] removed a comment on pull request #4042: [FIX-3900][server] kill multi yarn app in one job

Posted by GitBox <gi...@apache.org>.
sonarcloud[bot] removed a comment on pull request #4042:
URL: https://github.com/apache/incubator-dolphinscheduler/pull/4042#issuecomment-727956170


   Kudos, SonarCloud Quality Gate passed!
   
   [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/bug.png' alt='Bug' width='16' height='16' />](https://sonarcloud.io/project/issues?id=apache-dolphinscheduler&pullRequest=4042&resolved=false&types=BUG) [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A.png' alt='A' width='16' height='16' />](https://sonarcloud.io/project/issues?id=apache-dolphinscheduler&pullRequest=4042&resolved=false&types=BUG) [0 Bugs](https://sonarcloud.io/project/issues?id=apache-dolphinscheduler&pullRequest=4042&resolved=false&types=BUG)  
   [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/vulnerability.png' alt='Vulnerability' width='16' height='16' />](https://sonarcloud.io/project/issues?id=apache-dolphinscheduler&pullRequest=4042&resolved=false&types=VULNERABILITY) [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A.png' alt='A' width='16' height='16' />](https://sonarcloud.io/project/issues?id=apache-dolphinscheduler&pullRequest=4042&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonarcloud.io/project/issues?id=apache-dolphinscheduler&pullRequest=4042&resolved=false&types=VULNERABILITY) (and [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/security_hotspot.png' alt='Security Hotspot' width='16' height='16' />](https://sonarcloud.io/project/issues?id=apache-dolphinscheduler&pullRequest=4042&resolved=false&types=SECURITY_HOTSPOT) [0 Security Hotspots](https://sonarcloud.io/proje
 ct/issues?id=apache-dolphinscheduler&pullRequest=4042&resolved=false&types=SECURITY_HOTSPOT) to review)  
   [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/code_smell.png' alt='Code Smell' width='16' height='16' />](https://sonarcloud.io/project/issues?id=apache-dolphinscheduler&pullRequest=4042&resolved=false&types=CODE_SMELL) [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A.png' alt='A' width='16' height='16' />](https://sonarcloud.io/project/issues?id=apache-dolphinscheduler&pullRequest=4042&resolved=false&types=CODE_SMELL) [0 Code Smells](https://sonarcloud.io/project/issues?id=apache-dolphinscheduler&pullRequest=4042&resolved=false&types=CODE_SMELL)
   
   [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/CoverageChart/60.png' alt='63.5%' width='16' height='16' />](https://sonarcloud.io/component_measures?id=apache-dolphinscheduler&pullRequest=4042&metric=new_coverage&view=list) [63.5% Coverage](https://sonarcloud.io/component_measures?id=apache-dolphinscheduler&pullRequest=4042&metric=new_coverage&view=list)  
   [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/Duplications/3.png' alt='0.0%' width='16' height='16' />](https://sonarcloud.io/component_measures?id=apache-dolphinscheduler&pullRequest=4042&metric=new_duplicated_lines_density&view=list) [0.0% Duplication](https://sonarcloud.io/component_measures?id=apache-dolphinscheduler&pullRequest=4042&metric=new_duplicated_lines_density&view=list)
   
   


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-dolphinscheduler] lenboo commented on a change in pull request #4042: [FIX-3900][server] kill multi yarn app in one job

Posted by GitBox <gi...@apache.org>.
lenboo commented on a change in pull request #4042:
URL: https://github.com/apache/incubator-dolphinscheduler/pull/4042#discussion_r524083485



##########
File path: dolphinscheduler-server/src/main/java/org/apache/dolphinscheduler/server/utils/ProcessUtils.java
##########
@@ -38,368 +41,406 @@
 import java.util.regex.Pattern;
 
 /**
- *  mainly used to get the start command line of a process.
+ * mainly used to get the start command line of a process.
  */
 public class ProcessUtils {
-  /**
-   * logger.
-   */
-  private static final Logger logger = LoggerFactory.getLogger(ProcessUtils.class);
-
-  /**
-   * Initialization regularization, solve the problem of pre-compilation performance,
-   * avoid the thread safety problem of multi-thread operation.
-   */
-  private static final Pattern MACPATTERN = Pattern.compile("-[+|-]-\\s(\\d+)");
-
-  private static final Pattern WINDOWSATTERN = Pattern.compile("(\\d+)");
-
-  /**
-   * build command line characters.
-   * @param commandList command list
-   * @return command
-   */
-  public static String buildCommandStr(List<String> commandList) {
-    String cmdstr;
-    String[] cmd = commandList.toArray(new String[commandList.size()]);
-    SecurityManager security = System.getSecurityManager();
-    boolean allowAmbiguousCommands = false;
-    if (security == null) {
-      allowAmbiguousCommands = true;
-      String value = System.getProperty("jdk.lang.Process.allowAmbiguousCommands");
-      if (value != null) {
-        allowAmbiguousCommands = !"false".equalsIgnoreCase(value);
-      }
+    /**
+     * logger.
+     */
+    private static final Logger logger = LoggerFactory.getLogger(ProcessUtils.class);
+
+    /**
+     * Initialization regularization, solve the problem of pre-compilation performance,
+     * avoid the thread safety problem of multi-thread operation.
+     */
+    private static final Pattern MACPATTERN = Pattern.compile("-[+|-]-\\s(\\d+)");
+
+    private static final Pattern WINDOWSATTERN = Pattern.compile("(\\d+)");
+
+    /**
+     * build command line characters.
+     *
+     * @param commandList command list
+     * @return command
+     */
+    public static String buildCommandStr(List<String> commandList) {
+        String cmdstr;
+        String[] cmd = commandList.toArray(new String[0]);
+        SecurityManager security = System.getSecurityManager();
+        boolean allowAmbiguousCommands = isAllowAmbiguousCommands(security);
+        if (allowAmbiguousCommands) {
+
+            String executablePath = new File(cmd[0]).getPath();
+
+            if (needsEscaping(VERIFICATION_LEGACY, executablePath)) {
+                executablePath = quoteString(executablePath);
+            }
+
+            cmdstr = createCommandLine(
+                VERIFICATION_LEGACY, executablePath, cmd);
+        } else {
+            String executablePath;
+            try {
+                executablePath = getExecutablePath(cmd[0]);
+            } catch (IllegalArgumentException e) {
+
+                StringBuilder join = new StringBuilder();
+                for (String s : cmd) {
+                    join.append(s).append(' ');
+                }
+
+                cmd = getTokensFromCommand(join.toString());
+                executablePath = getExecutablePath(cmd[0]);
+
+                // Check new executable name once more
+                if (security != null) {
+                    security.checkExec(executablePath);
+                }
+            }
+
+            cmdstr = createCommandLine(
+
+                isShellFile(executablePath) ? VERIFICATION_CMD_BAT : VERIFICATION_WIN32, quoteString(executablePath), cmd);
+        }
+        return cmdstr;
     }
-    if (allowAmbiguousCommands) {
-
-      String executablePath = new File(cmd[0]).getPath();
-
-      if (needsEscaping(VERIFICATION_LEGACY, executablePath)) {
-        executablePath = quoteString(executablePath);
-      }
-
-      cmdstr = createCommandLine(
-              VERIFICATION_LEGACY, executablePath, cmd);
-    } else {
-      String executablePath;
-      try {
-        executablePath = getExecutablePath(cmd[0]);
-      } catch (IllegalArgumentException e) {
 
-        StringBuilder join = new StringBuilder();
-        for (String s : cmd) {
-          join.append(s).append(' ');
+    /**
+     * check is allow ambiguous commands
+     *
+     * @param security security manager
+     * @return allow ambiguous command flag
+     */
+    private static boolean isAllowAmbiguousCommands(SecurityManager security) {
+        boolean allowAmbiguousCommands = false;
+        if (security == null) {
+            allowAmbiguousCommands = true;
+            String value = System.getProperty("jdk.lang.Process.allowAmbiguousCommands");

Review comment:
       magic number here?




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-dolphinscheduler] sonarcloud[bot] removed a comment on pull request #4042: [FIX-3900][server] kill multi yarn app in one job

Posted by GitBox <gi...@apache.org>.
sonarcloud[bot] removed a comment on pull request #4042:
URL: https://github.com/apache/incubator-dolphinscheduler/pull/4042#issuecomment-728970207


   Kudos, SonarCloud Quality Gate passed!
   
   [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/bug.png' alt='Bug' width='16' height='16' />](https://sonarcloud.io/project/issues?id=apache-dolphinscheduler&pullRequest=4042&resolved=false&types=BUG) [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A.png' alt='A' width='16' height='16' />](https://sonarcloud.io/project/issues?id=apache-dolphinscheduler&pullRequest=4042&resolved=false&types=BUG) [0 Bugs](https://sonarcloud.io/project/issues?id=apache-dolphinscheduler&pullRequest=4042&resolved=false&types=BUG)  
   [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/vulnerability.png' alt='Vulnerability' width='16' height='16' />](https://sonarcloud.io/project/issues?id=apache-dolphinscheduler&pullRequest=4042&resolved=false&types=VULNERABILITY) [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A.png' alt='A' width='16' height='16' />](https://sonarcloud.io/project/issues?id=apache-dolphinscheduler&pullRequest=4042&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonarcloud.io/project/issues?id=apache-dolphinscheduler&pullRequest=4042&resolved=false&types=VULNERABILITY) (and [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/security_hotspot.png' alt='Security Hotspot' width='16' height='16' />](https://sonarcloud.io/project/issues?id=apache-dolphinscheduler&pullRequest=4042&resolved=false&types=SECURITY_HOTSPOT) [0 Security Hotspots](https://sonarcloud.io/proje
 ct/issues?id=apache-dolphinscheduler&pullRequest=4042&resolved=false&types=SECURITY_HOTSPOT) to review)  
   [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/code_smell.png' alt='Code Smell' width='16' height='16' />](https://sonarcloud.io/project/issues?id=apache-dolphinscheduler&pullRequest=4042&resolved=false&types=CODE_SMELL) [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A.png' alt='A' width='16' height='16' />](https://sonarcloud.io/project/issues?id=apache-dolphinscheduler&pullRequest=4042&resolved=false&types=CODE_SMELL) [0 Code Smells](https://sonarcloud.io/project/issues?id=apache-dolphinscheduler&pullRequest=4042&resolved=false&types=CODE_SMELL)
   
   [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/CoverageChart/60.png' alt='63.6%' width='16' height='16' />](https://sonarcloud.io/component_measures?id=apache-dolphinscheduler&pullRequest=4042&metric=new_coverage&view=list) [63.6% Coverage](https://sonarcloud.io/component_measures?id=apache-dolphinscheduler&pullRequest=4042&metric=new_coverage&view=list)  
   [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/Duplications/3.png' alt='0.0%' width='16' height='16' />](https://sonarcloud.io/component_measures?id=apache-dolphinscheduler&pullRequest=4042&metric=new_duplicated_lines_density&view=list) [0.0% Duplication](https://sonarcloud.io/component_measures?id=apache-dolphinscheduler&pullRequest=4042&metric=new_duplicated_lines_density&view=list)
   
   


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-dolphinscheduler] lenboo commented on a change in pull request #4042: [FIX-3900][server] kill multi yarn app in one job

Posted by GitBox <gi...@apache.org>.
lenboo commented on a change in pull request #4042:
URL: https://github.com/apache/incubator-dolphinscheduler/pull/4042#discussion_r521867404



##########
File path: dolphinscheduler-server/src/main/java/org/apache/dolphinscheduler/server/utils/ProcessUtils.java
##########
@@ -38,368 +41,385 @@
 import java.util.regex.Pattern;
 
 /**
- *  mainly used to get the start command line of a process.
+ * mainly used to get the start command line of a process.
  */
 public class ProcessUtils {
-  /**
-   * logger.
-   */
-  private static final Logger logger = LoggerFactory.getLogger(ProcessUtils.class);
-
-  /**
-   * Initialization regularization, solve the problem of pre-compilation performance,
-   * avoid the thread safety problem of multi-thread operation.
-   */
-  private static final Pattern MACPATTERN = Pattern.compile("-[+|-]-\\s(\\d+)");
-
-  private static final Pattern WINDOWSATTERN = Pattern.compile("(\\d+)");
-
-  /**
-   * build command line characters.
-   * @param commandList command list
-   * @return command
-   */
-  public static String buildCommandStr(List<String> commandList) {
-    String cmdstr;
-    String[] cmd = commandList.toArray(new String[commandList.size()]);
-    SecurityManager security = System.getSecurityManager();
-    boolean allowAmbiguousCommands = false;
-    if (security == null) {
-      allowAmbiguousCommands = true;
-      String value = System.getProperty("jdk.lang.Process.allowAmbiguousCommands");
-      if (value != null) {
-        allowAmbiguousCommands = !"false".equalsIgnoreCase(value);
-      }
-    }
-    if (allowAmbiguousCommands) {
+    /**
+     * logger.
+     */
+    private static final Logger logger = LoggerFactory.getLogger(ProcessUtils.class);
+
+    /**
+     * Initialization regularization, solve the problem of pre-compilation performance,
+     * avoid the thread safety problem of multi-thread operation.
+     */
+    private static final Pattern MACPATTERN = Pattern.compile("-[+|-]-\\s(\\d+)");
+
+    private static final Pattern WINDOWSATTERN = Pattern.compile("(\\d+)");
+
+    /**
+     * build command line characters.
+     *
+     * @param commandList command list
+     * @return command
+     */
+    public static String buildCommandStr(List<String> commandList) {
+        String cmdstr;
+        String[] cmd = commandList.toArray(new String[0]);
+        SecurityManager security = System.getSecurityManager();
+        boolean allowAmbiguousCommands = false;
+        if (security == null) {
+            allowAmbiguousCommands = true;
+            String value = System.getProperty("jdk.lang.Process.allowAmbiguousCommands");
+            if (value != null) {
+                allowAmbiguousCommands = !"false".equalsIgnoreCase(value);
+            }
+        }
+        if (allowAmbiguousCommands) {
 
-      String executablePath = new File(cmd[0]).getPath();
+            String executablePath = new File(cmd[0]).getPath();
 
-      if (needsEscaping(VERIFICATION_LEGACY, executablePath)) {
-        executablePath = quoteString(executablePath);
-      }
+            if (needsEscaping(VERIFICATION_LEGACY, executablePath)) {
+                executablePath = quoteString(executablePath);
+            }
 
-      cmdstr = createCommandLine(
-              VERIFICATION_LEGACY, executablePath, cmd);
-    } else {
-      String executablePath;
-      try {
-        executablePath = getExecutablePath(cmd[0]);
-      } catch (IllegalArgumentException e) {
+            cmdstr = createCommandLine(
+                VERIFICATION_LEGACY, executablePath, cmd);
+        } else {
+            String executablePath;
+            try {
+                executablePath = getExecutablePath(cmd[0]);
+            } catch (IllegalArgumentException e) {
 
-        StringBuilder join = new StringBuilder();
-        for (String s : cmd) {
-          join.append(s).append(' ');
-        }
+                StringBuilder join = new StringBuilder();
+                for (String s : cmd) {
+                    join.append(s).append(' ');
+                }
 
-        cmd = getTokensFromCommand(join.toString());
-        executablePath = getExecutablePath(cmd[0]);
+                cmd = getTokensFromCommand(join.toString());
+                executablePath = getExecutablePath(cmd[0]);
 
-        // Check new executable name once more
-        if (security != null) {
-          security.checkExec(executablePath);
-        }
-      }
+                // Check new executable name once more
+                if (security != null) {
+                    security.checkExec(executablePath);
+                }
+            }
 
-      cmdstr = createCommandLine(
+            cmdstr = createCommandLine(
 
-              isShellFile(executablePath) ? VERIFICATION_CMD_BAT : VERIFICATION_WIN32, quoteString(executablePath), cmd);
-    }
-    return cmdstr;
-  }
-
-  /**
-   * get executable path.
-   *
-   * @param path path
-   * @return executable path
-   */
-  private static String getExecutablePath(String path) {
-    boolean pathIsQuoted = isQuoted(true, path, "Executable name has embedded quote, split the arguments");
-
-    File fileToRun = new File(pathIsQuoted ? path.substring(1, path.length() - 1) : path);
-    return fileToRun.getPath();
-  }
-
-  /**
-   * whether is shell file.
-   *
-   * @param executablePath executable path
-   * @return true if endsWith .CMD or .BAT
-   */
-  private static boolean isShellFile(String executablePath) {
-    String upPath = executablePath.toUpperCase();
-    return (upPath.endsWith(".CMD") || upPath.endsWith(".BAT"));
-  }
-
-  /**
-   * quote string.
-   *
-   * @param arg argument
-   * @return format arg
-   */
-  private static String quoteString(String arg) {
-    StringBuilder argbuf = new StringBuilder(arg.length() + 2);
-    return argbuf.append('"').append(arg).append('"').toString();
-  }
-
-  /**
-   * get tokens from command.
-   *
-   * @param command command
-   * @return token string array
-   */
-  private static String[] getTokensFromCommand(String command) {
-    ArrayList<String> matchList = new ArrayList<>(8);
-    Matcher regexMatcher = LazyPattern.PATTERN.matcher(command);
-    while (regexMatcher.find()) {
-      matchList.add(regexMatcher.group());
-    }
-    return matchList.toArray(new String[matchList.size()]);
-  }
-
-  /**
-   * Lazy Pattern.
-   */
-  private static class LazyPattern {
-    // Escape-support version:
-    // "(\")((?:\\\\\\1|.)+?)\\1|([^\\s\"]+)";
-    private static final Pattern PATTERN = Pattern.compile("[^\\s\"]+|\"[^\"]*\"");
-  }
-
-  /**
-   * verification cmd bat.
-   */
-  private static final int VERIFICATION_CMD_BAT = 0;
-
-  /**
-   * verification win32.
-   */
-  private static final int VERIFICATION_WIN32 = 1;
-
-  /**
-   * verification legacy.
-   */
-  private static final int VERIFICATION_LEGACY = 2;
-
-  /**
-   * escape verification.
-   */
-  private static final char[][] ESCAPE_VERIFICATION = {{' ', '\t', '<', '>', '&', '|', '^'},
-
-    {' ', '\t', '<', '>'}, {' ', '\t'}};
-
-  /**
-   * create command line.
-   * @param verificationType  verification type
-   * @param executablePath    executable path
-   * @param cmd               cmd
-   * @return command line
-   */
-  private static String createCommandLine(int verificationType, final String executablePath, final String[] cmd) {
-    StringBuilder cmdbuf = new StringBuilder(80);
-
-    cmdbuf.append(executablePath);
-
-    for (int i = 1; i < cmd.length; ++i) {
-      cmdbuf.append(' ');
-      String s = cmd[i];
-      if (needsEscaping(verificationType, s)) {
-        cmdbuf.append('"').append(s);
-
-        if ((verificationType != VERIFICATION_CMD_BAT) && s.endsWith("\\")) {
-          cmdbuf.append('\\');
+                isShellFile(executablePath) ? VERIFICATION_CMD_BAT : VERIFICATION_WIN32, quoteString(executablePath), cmd);
         }
-        cmdbuf.append('"');
-      } else {
-        cmdbuf.append(s);
-      }
+        return cmdstr;
     }
-    return cmdbuf.toString();
-  }
-
-  /**
-   * whether is quoted.
-   * @param noQuotesInside
-   * @param arg
-   * @param errorMessage
-   * @return boolean
-   */
-  private static boolean isQuoted(boolean noQuotesInside, String arg, String errorMessage) {
-    int lastPos = arg.length() - 1;
-    if (lastPos >= 1 && arg.charAt(0) == '"' && arg.charAt(lastPos) == '"') {
-      // The argument has already been quoted.
-      if (noQuotesInside) {
-        if (arg.indexOf('"', 1) != lastPos) {
-          // There is ["] inside.
-          throw new IllegalArgumentException(errorMessage);
-        }
-      }
-      return true;
+
+    /**
+     * get executable path.
+     *
+     * @param path path
+     * @return executable path
+     */
+    private static String getExecutablePath(String path) {
+        boolean pathIsQuoted = isQuoted(true, path, "Executable name has embedded quote, split the arguments");
+
+        File fileToRun = new File(pathIsQuoted ? path.substring(1, path.length() - 1) : path);
+        return fileToRun.getPath();
     }
-    if (noQuotesInside) {
-      if (arg.indexOf('"') >= 0) {
-        // There is ["] inside.
-        throw new IllegalArgumentException(errorMessage);
-      }
+
+    /**
+     * whether is shell file.
+     *
+     * @param executablePath executable path
+     * @return true if endsWith .CMD or .BAT
+     */
+    private static boolean isShellFile(String executablePath) {
+        String upPath = executablePath.toUpperCase();
+        return (upPath.endsWith(".CMD") || upPath.endsWith(".BAT"));
     }
-    return false;
-  }
-
-  /**
-   * whether needs escaping.
-   *
-   * @param verificationType  verification type
-   * @param arg               arg
-   * @return boolean
-   */
-  private static boolean needsEscaping(int verificationType, String arg) {
-
-    boolean argIsQuoted = isQuoted((verificationType == VERIFICATION_CMD_BAT), arg, "Argument has embedded quote, use the explicit CMD.EXE call.");
-
-    if (!argIsQuoted) {
-      char[] testEscape = ESCAPE_VERIFICATION[verificationType];
-      for (int i = 0; i < testEscape.length; ++i) {
-        if (arg.indexOf(testEscape[i]) >= 0) {
-          return true;
-        }
-      }
+
+    /**
+     * quote string.
+     *
+     * @param arg argument
+     * @return format arg
+     */
+    private static String quoteString(String arg) {
+        return '"' + arg + '"';
     }
-    return false;
-  }
-
-  /**
-   * kill yarn application.
-   *
-   * @param appIds      app id list
-   * @param logger      logger
-   * @param tenantCode  tenant code
-   * @param executePath     execute path
-   */
-  public static void cancelApplication(List<String> appIds, Logger logger, String tenantCode, String executePath) {
-    if (appIds.size() > 0) {
-      String appid = appIds.get(appIds.size() - 1);
-      String commandFile = String
-              .format("%s/%s.kill", executePath, appid);
-      String cmd = "yarn application -kill " + appid;
-      try {
-        StringBuilder sb = new StringBuilder();
-        sb.append("#!/bin/sh\n");
-        sb.append("BASEDIR=$(cd `dirname $0`; pwd)\n");
-        sb.append("cd $BASEDIR\n");
-        if (CommonUtils.getSystemEnvPath() != null) {
-          sb.append("source " + CommonUtils.getSystemEnvPath() + "\n");
+
+    /**
+     * get tokens from command.
+     *
+     * @param command command
+     * @return token string array
+     */
+    private static String[] getTokensFromCommand(String command) {
+        ArrayList<String> matchList = new ArrayList<>(8);
+        Matcher regexMatcher = LazyPattern.PATTERN.matcher(command);
+        while (regexMatcher.find()) {
+            matchList.add(regexMatcher.group());
         }
-        sb.append("\n\n");
-        sb.append(cmd);
+        return matchList.toArray(new String[0]);
+    }
 
-        File f = new File(commandFile);
+    /**
+     * Lazy Pattern.
+     */
+    private static class LazyPattern {
+        // Escape-support version:
+        // "(\")((?:\\\\\\1|.)+?)\\1|([^\\s\"]+)";
+        private static final Pattern PATTERN = Pattern.compile("[^\\s\"]+|\"[^\"]*\"");
+    }
 
-        if (!f.exists()) {
-          FileUtils.writeStringToFile(new File(commandFile), sb.toString(), StandardCharsets.UTF_8);
+    /**
+     * verification cmd bat.
+     */
+    private static final int VERIFICATION_CMD_BAT = 0;
+
+    /**
+     * verification win32.
+     */
+    private static final int VERIFICATION_WIN32 = 1;
+
+    /**
+     * verification legacy.
+     */
+    private static final int VERIFICATION_LEGACY = 2;
+
+    /**
+     * escape verification.
+     */
+    private static final char[][] ESCAPE_VERIFICATION = {{' ', '\t', '<', '>', '&', '|', '^'},
+
+        {' ', '\t', '<', '>'}, {' ', '\t'}};
+
+    /**
+     * create command line.
+     *
+     * @param verificationType verification type
+     * @param executablePath   executable path
+     * @param cmd              cmd
+     * @return command line
+     */
+    private static String createCommandLine(int verificationType, final String executablePath, final String[] cmd) {
+        StringBuilder cmdbuf = new StringBuilder(80);
+
+        cmdbuf.append(executablePath);
+
+        for (int i = 1; i < cmd.length; ++i) {
+            cmdbuf.append(' ');
+            String s = cmd[i];
+            if (needsEscaping(verificationType, s)) {
+                cmdbuf.append('"').append(s);
+
+                if ((verificationType != VERIFICATION_CMD_BAT) && s.endsWith("\\")) {
+                    cmdbuf.append('\\');
+                }
+                cmdbuf.append('"');
+            } else {
+                cmdbuf.append(s);
+            }
         }
+        return cmdbuf.toString();
+    }
 
-        String runCmd = "sh " + commandFile;
-        if (StringUtils.isNotEmpty(tenantCode)) {
-          runCmd = "sudo -u " + tenantCode + " " + runCmd;
+    /**
+     * whether is quoted.
+     *
+     * @param noQuotesInside no quotes inside
+     * @param arg            arg
+     * @param errorMessage   error message
+     * @return boolean
+     */
+    private static boolean isQuoted(boolean noQuotesInside, String arg, String errorMessage) {
+        int lastPos = arg.length() - 1;
+        if (lastPos >= 1 && arg.charAt(0) == '"' && arg.charAt(lastPos) == '"') {
+            // The argument has already been quoted.
+            if (noQuotesInside) {
+                if (arg.indexOf('"', 1) != lastPos) {
+                    // There is ["] inside.
+                    throw new IllegalArgumentException(errorMessage);
+                }
+            }
+            return true;
+        }
+        if (noQuotesInside) {
+            if (arg.indexOf('"') >= 0) {
+                // There is ["] inside.
+                throw new IllegalArgumentException(errorMessage);
+            }
         }
+        return false;
+    }
 
-        logger.info("kill cmd:{}", runCmd);
+    /**
+     * whether needs escaping.
+     *
+     * @param verificationType verification type
+     * @param arg              arg
+     * @return boolean
+     */
+    private static boolean needsEscaping(int verificationType, String arg) {
+
+        boolean argIsQuoted = isQuoted((verificationType == VERIFICATION_CMD_BAT), arg, "Argument has embedded quote, use the explicit CMD.EXE call.");
+
+        if (!argIsQuoted) {
+            char[] testEscape = ESCAPE_VERIFICATION[verificationType];
+            for (char c : testEscape) {
+                if (arg.indexOf(c) >= 0) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
 
-        Runtime.getRuntime().exec(runCmd);
-      } catch (Exception e) {
-        logger.error("kill application error", e);
-      }
+    /**
+     * kill yarn application.
+     *
+     * @param appIds      app id list
+     * @param logger      logger
+     * @param tenantCode  tenant code
+     * @param executePath execute path
+     */
+    public static void cancelApplication(List<String> appIds, Logger logger, String tenantCode, String executePath) {
+        if (CollectionUtils.isNotEmpty(appIds)) {
+

Review comment:
       i think we should reduce its cognitive complexity here.




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-dolphinscheduler] lenboo commented on a change in pull request #4042: [FIX-3900][server] kill multi yarn app in one job

Posted by GitBox <gi...@apache.org>.
lenboo commented on a change in pull request #4042:
URL: https://github.com/apache/incubator-dolphinscheduler/pull/4042#discussion_r524948727



##########
File path: dolphinscheduler-server/src/main/java/org/apache/dolphinscheduler/server/utils/ProcessUtils.java
##########
@@ -38,368 +41,408 @@
 import java.util.regex.Pattern;
 
 /**
- *  mainly used to get the start command line of a process.
+ * mainly used to get the start command line of a process.
  */
 public class ProcessUtils {
-  /**
-   * logger.
-   */
-  private static final Logger logger = LoggerFactory.getLogger(ProcessUtils.class);
-
-  /**
-   * Initialization regularization, solve the problem of pre-compilation performance,
-   * avoid the thread safety problem of multi-thread operation.
-   */
-  private static final Pattern MACPATTERN = Pattern.compile("-[+|-]-\\s(\\d+)");
-
-  private static final Pattern WINDOWSATTERN = Pattern.compile("(\\d+)");
-
-  /**
-   * build command line characters.
-   * @param commandList command list
-   * @return command
-   */
-  public static String buildCommandStr(List<String> commandList) {
-    String cmdstr;
-    String[] cmd = commandList.toArray(new String[commandList.size()]);
-    SecurityManager security = System.getSecurityManager();
-    boolean allowAmbiguousCommands = false;
-    if (security == null) {
-      allowAmbiguousCommands = true;
-      String value = System.getProperty("jdk.lang.Process.allowAmbiguousCommands");
-      if (value != null) {
-        allowAmbiguousCommands = !"false".equalsIgnoreCase(value);
-      }
+    /**
+     * logger.
+     */
+    private static final Logger logger = LoggerFactory.getLogger(ProcessUtils.class);
+
+    /**
+     * Initialization regularization, solve the problem of pre-compilation performance,
+     * avoid the thread safety problem of multi-thread operation.
+     */
+    private static final Pattern MACPATTERN = Pattern.compile("-[+|-]-\\s(\\d+)");
+
+    private static final Pattern WINDOWSATTERN = Pattern.compile("(\\d+)");
+
+    private static final String LOCAL_PROCESS_EXEC = "jdk.lang.Process.allowAmbiguousCommands";
+
+    /**
+     * build command line characters.
+     *
+     * @param commandList command list
+     * @return command
+     */
+    public static String buildCommandStr(List<String> commandList) {
+        String cmdstr;
+        String[] cmd = commandList.toArray(new String[0]);
+        SecurityManager security = System.getSecurityManager();
+        boolean allowAmbiguousCommands = isAllowAmbiguousCommands(security);
+        if (allowAmbiguousCommands) {
+
+            String executablePath = new File(cmd[0]).getPath();
+
+            if (needsEscaping(VERIFICATION_LEGACY, executablePath)) {
+                executablePath = quoteString(executablePath);
+            }
+
+            cmdstr = createCommandLine(
+                VERIFICATION_LEGACY, executablePath, cmd);
+        } else {
+            String executablePath;
+            try {
+                executablePath = getExecutablePath(cmd[0]);
+            } catch (IllegalArgumentException e) {
+
+                StringBuilder join = new StringBuilder();
+                for (String s : cmd) {
+                    join.append(s).append(' ');
+                }
+
+                cmd = getTokensFromCommand(join.toString());
+                executablePath = getExecutablePath(cmd[0]);
+
+                // Check new executable name once more
+                if (security != null) {
+                    security.checkExec(executablePath);
+                }
+            }
+
+            cmdstr = createCommandLine(
+
+                isShellFile(executablePath) ? VERIFICATION_CMD_BAT : VERIFICATION_WIN32, quoteString(executablePath), cmd);
+        }
+        return cmdstr;
     }
-    if (allowAmbiguousCommands) {
-
-      String executablePath = new File(cmd[0]).getPath();
-
-      if (needsEscaping(VERIFICATION_LEGACY, executablePath)) {
-        executablePath = quoteString(executablePath);
-      }
-
-      cmdstr = createCommandLine(
-              VERIFICATION_LEGACY, executablePath, cmd);
-    } else {
-      String executablePath;
-      try {
-        executablePath = getExecutablePath(cmd[0]);
-      } catch (IllegalArgumentException e) {
 
-        StringBuilder join = new StringBuilder();
-        for (String s : cmd) {
-          join.append(s).append(' ');
+    /**
+     * check is allow ambiguous commands
+     *
+     * @param security security manager
+     * @return allow ambiguous command flag
+     */
+    private static boolean isAllowAmbiguousCommands(SecurityManager security) {
+        boolean allowAmbiguousCommands = false;
+        if (security == null) {
+            allowAmbiguousCommands = true;
+            String value = System.getProperty(LOCAL_PROCESS_EXEC);
+            if (value != null) {
+                allowAmbiguousCommands = !Constants.STRING_FALSE.equalsIgnoreCase(value);
+            }
         }
+        return allowAmbiguousCommands;
+    }
 
-        cmd = getTokensFromCommand(join.toString());
-        executablePath = getExecutablePath(cmd[0]);
+    /**
+     * get executable path.
+     *
+     * @param path path
+     * @return executable path
+     */
+    private static String getExecutablePath(String path) {
+        boolean pathIsQuoted = isQuoted(true, path, "Executable name has embedded quote, split the arguments");
+
+        File fileToRun = new File(pathIsQuoted ? path.substring(1, path.length() - 1) : path);
+        return fileToRun.getPath();
+    }
 
-        // Check new executable name once more
-        if (security != null) {
-          security.checkExec(executablePath);
-        }
-      }
+    /**
+     * whether is shell file.
+     *
+     * @param executablePath executable path
+     * @return true if endsWith .CMD or .BAT
+     */
+    private static boolean isShellFile(String executablePath) {
+        String upPath = executablePath.toUpperCase();
+        return (upPath.endsWith(".CMD") || upPath.endsWith(".BAT"));
+    }
 
-      cmdstr = createCommandLine(
+    /**
+     * quote string.
+     *
+     * @param arg argument
+     * @return format arg
+     */
+    private static String quoteString(String arg) {
+        return '"' + arg + '"';
+    }
 
-              isShellFile(executablePath) ? VERIFICATION_CMD_BAT : VERIFICATION_WIN32, quoteString(executablePath), cmd);
+    /**
+     * get tokens from command.
+     *
+     * @param command command
+     * @return token string array
+     */
+    private static String[] getTokensFromCommand(String command) {
+        ArrayList<String> matchList = new ArrayList<>(8);
+        Matcher regexMatcher = LazyPattern.PATTERN.matcher(command);
+        while (regexMatcher.find()) {
+            matchList.add(regexMatcher.group());
+        }
+        return matchList.toArray(new String[0]);
     }
-    return cmdstr;
-  }
-
-  /**
-   * get executable path.
-   *
-   * @param path path
-   * @return executable path
-   */
-  private static String getExecutablePath(String path) {
-    boolean pathIsQuoted = isQuoted(true, path, "Executable name has embedded quote, split the arguments");
-
-    File fileToRun = new File(pathIsQuoted ? path.substring(1, path.length() - 1) : path);
-    return fileToRun.getPath();
-  }
-
-  /**
-   * whether is shell file.
-   *
-   * @param executablePath executable path
-   * @return true if endsWith .CMD or .BAT
-   */
-  private static boolean isShellFile(String executablePath) {
-    String upPath = executablePath.toUpperCase();
-    return (upPath.endsWith(".CMD") || upPath.endsWith(".BAT"));
-  }
-
-  /**
-   * quote string.
-   *
-   * @param arg argument
-   * @return format arg
-   */
-  private static String quoteString(String arg) {
-    StringBuilder argbuf = new StringBuilder(arg.length() + 2);
-    return argbuf.append('"').append(arg).append('"').toString();
-  }
-
-  /**
-   * get tokens from command.
-   *
-   * @param command command
-   * @return token string array
-   */
-  private static String[] getTokensFromCommand(String command) {
-    ArrayList<String> matchList = new ArrayList<>(8);
-    Matcher regexMatcher = LazyPattern.PATTERN.matcher(command);
-    while (regexMatcher.find()) {
-      matchList.add(regexMatcher.group());
+
+    /**
+     * Lazy Pattern.
+     */
+    private static class LazyPattern {
+        /**
+         * Escape-support version:
+         * "(\")((?:\\\\\\1|.)+?)\\1|([^\\s\"]+)";
+         */
+        private static final Pattern PATTERN = Pattern.compile("[^\\s\"]+|\"[^\"]*\"");
     }
-    return matchList.toArray(new String[matchList.size()]);
-  }
-
-  /**
-   * Lazy Pattern.
-   */
-  private static class LazyPattern {
-    // Escape-support version:
-    // "(\")((?:\\\\\\1|.)+?)\\1|([^\\s\"]+)";
-    private static final Pattern PATTERN = Pattern.compile("[^\\s\"]+|\"[^\"]*\"");
-  }
-
-  /**
-   * verification cmd bat.
-   */
-  private static final int VERIFICATION_CMD_BAT = 0;
-
-  /**
-   * verification win32.
-   */
-  private static final int VERIFICATION_WIN32 = 1;
-
-  /**
-   * verification legacy.
-   */
-  private static final int VERIFICATION_LEGACY = 2;
-
-  /**
-   * escape verification.
-   */
-  private static final char[][] ESCAPE_VERIFICATION = {{' ', '\t', '<', '>', '&', '|', '^'},
-
-    {' ', '\t', '<', '>'}, {' ', '\t'}};
-
-  /**
-   * create command line.
-   * @param verificationType  verification type
-   * @param executablePath    executable path
-   * @param cmd               cmd
-   * @return command line
-   */
-  private static String createCommandLine(int verificationType, final String executablePath, final String[] cmd) {
-    StringBuilder cmdbuf = new StringBuilder(80);
-
-    cmdbuf.append(executablePath);
-
-    for (int i = 1; i < cmd.length; ++i) {
-      cmdbuf.append(' ');
-      String s = cmd[i];
-      if (needsEscaping(verificationType, s)) {
-        cmdbuf.append('"').append(s);
-
-        if ((verificationType != VERIFICATION_CMD_BAT) && s.endsWith("\\")) {
-          cmdbuf.append('\\');
+
+    /**
+     * verification cmd bat.
+     */
+    private static final int VERIFICATION_CMD_BAT = 0;
+
+    /**
+     * verification win32.
+     */
+    private static final int VERIFICATION_WIN32 = 1;
+
+    /**
+     * verification legacy.
+     */
+    private static final int VERIFICATION_LEGACY = 2;
+
+    /**
+     * escape verification.
+     */
+    private static final char[][] ESCAPE_VERIFICATION = {{' ', '\t', '<', '>', '&', '|', '^'},
+
+        {' ', '\t', '<', '>'}, {' ', '\t'}};
+
+    /**
+     * create command line.
+     *
+     * @param verificationType verification type
+     * @param executablePath   executable path
+     * @param cmd              cmd
+     * @return command line
+     */
+    private static String createCommandLine(int verificationType, final String executablePath, final String[] cmd) {
+        StringBuilder cmdbuf = new StringBuilder(80);
+
+        cmdbuf.append(executablePath);
+
+        for (int i = 1; i < cmd.length; ++i) {
+            cmdbuf.append(' ');
+            String s = cmd[i];
+            if (needsEscaping(verificationType, s)) {
+                cmdbuf.append('"').append(s);
+
+                if ((verificationType != VERIFICATION_CMD_BAT) && s.endsWith("\\")) {
+                    cmdbuf.append('\\');
+                }
+                cmdbuf.append('"');
+            } else {
+                cmdbuf.append(s);
+            }
         }
-        cmdbuf.append('"');
-      } else {
-        cmdbuf.append(s);
-      }
+        return cmdbuf.toString();
     }
-    return cmdbuf.toString();
-  }
-
-  /**
-   * whether is quoted.
-   * @param noQuotesInside
-   * @param arg
-   * @param errorMessage
-   * @return boolean
-   */
-  private static boolean isQuoted(boolean noQuotesInside, String arg, String errorMessage) {
-    int lastPos = arg.length() - 1;
-    if (lastPos >= 1 && arg.charAt(0) == '"' && arg.charAt(lastPos) == '"') {
-      // The argument has already been quoted.
-      if (noQuotesInside) {
-        if (arg.indexOf('"', 1) != lastPos) {
-          // There is ["] inside.
-          throw new IllegalArgumentException(errorMessage);
+
+    /**
+     * whether is quoted.
+     *
+     * @param noQuotesInside no quotes inside
+     * @param arg            arg
+     * @param errorMessage   error message
+     * @return boolean
+     */
+    private static boolean isQuoted(boolean noQuotesInside, String arg, String errorMessage) {
+        int lastPos = arg.length() - 1;
+        if (lastPos >= 1 && arg.charAt(0) == '"' && arg.charAt(lastPos) == '"') {
+            // The argument has already been quoted.
+            if (noQuotesInside && arg.indexOf('"', 1) != lastPos) {
+                // There is ["] inside.
+                throw new IllegalArgumentException(errorMessage);
+            }
+            return true;
         }
-      }
-      return true;
-    }
-    if (noQuotesInside) {
-      if (arg.indexOf('"') >= 0) {
-        // There is ["] inside.
-        throw new IllegalArgumentException(errorMessage);
-      }
-    }
-    return false;
-  }
-
-  /**
-   * whether needs escaping.
-   *
-   * @param verificationType  verification type
-   * @param arg               arg
-   * @return boolean
-   */
-  private static boolean needsEscaping(int verificationType, String arg) {
-
-    boolean argIsQuoted = isQuoted((verificationType == VERIFICATION_CMD_BAT), arg, "Argument has embedded quote, use the explicit CMD.EXE call.");
-
-    if (!argIsQuoted) {
-      char[] testEscape = ESCAPE_VERIFICATION[verificationType];
-      for (int i = 0; i < testEscape.length; ++i) {
-        if (arg.indexOf(testEscape[i]) >= 0) {
-          return true;
+        if (noQuotesInside && arg.indexOf('"') >= 0) {
+            // There is ["] inside.
+            throw new IllegalArgumentException(errorMessage);
         }
-      }
+        return false;
     }
-    return false;
-  }
-
-  /**
-   * kill yarn application.
-   *
-   * @param appIds      app id list
-   * @param logger      logger
-   * @param tenantCode  tenant code
-   * @param executePath     execute path
-   */
-  public static void cancelApplication(List<String> appIds, Logger logger, String tenantCode, String executePath) {
-    if (appIds.size() > 0) {
-      String appid = appIds.get(appIds.size() - 1);
-      String commandFile = String
-              .format("%s/%s.kill", executePath, appid);
-      String cmd = "yarn application -kill " + appid;
-      try {
-        StringBuilder sb = new StringBuilder();
-        sb.append("#!/bin/sh\n");
-        sb.append("BASEDIR=$(cd `dirname $0`; pwd)\n");
-        sb.append("cd $BASEDIR\n");
-        if (CommonUtils.getSystemEnvPath() != null) {
-          sb.append("source " + CommonUtils.getSystemEnvPath() + "\n");
-        }
-        sb.append("\n\n");
-        sb.append(cmd);
-
-        File f = new File(commandFile);
 
-        if (!f.exists()) {
-          FileUtils.writeStringToFile(new File(commandFile), sb.toString(), StandardCharsets.UTF_8);
+    /**
+     * whether needs escaping.
+     *
+     * @param verificationType verification type
+     * @param arg              arg
+     * @return boolean
+     */
+    private static boolean needsEscaping(int verificationType, String arg) {
+
+        boolean argIsQuoted = isQuoted((verificationType == VERIFICATION_CMD_BAT), arg, "Argument has embedded quote, use the explicit CMD.EXE call.");
+
+        if (!argIsQuoted) {
+            char[] testEscape = ESCAPE_VERIFICATION[verificationType];
+            for (char c : testEscape) {
+                if (arg.indexOf(c) >= 0) {
+                    return true;
+                }
+            }
         }
+        return false;
+    }
 
-        String runCmd = "sh " + commandFile;
-        if (StringUtils.isNotEmpty(tenantCode)) {
-          runCmd = "sudo -u " + tenantCode + " " + runCmd;
+    /**
+     * kill yarn application.
+     *
+     * @param appIds      app id list
+     * @param logger      logger
+     * @param tenantCode  tenant code
+     * @param executePath execute path
+     */
+    public static void cancelApplication(List<String> appIds, Logger logger, String tenantCode, String executePath) {
+        if (CollectionUtils.isNotEmpty(appIds)) {
+
+            for (String appId : appIds) {
+                try {
+                    ExecutionStatus applicationStatus = HadoopUtils.getInstance().getApplicationStatus(appId);
+
+                    if (!applicationStatus.typeIsFinished()) {
+                        String commandFile = String
+                            .format("%s/%s.kill", executePath, appId);
+                        String cmd = "yarn application -kill " + appId;
+                        execYarnKillCommand(logger, tenantCode, appId, commandFile, cmd);
+                    }
+                } catch (Exception e) {
+                    logger.error(String.format("Get yarn application app id [%s] status failed: [%s]", appId, e.getMessage()));
+                }
+            }
         }
+    }
 
-        logger.info("kill cmd:{}", runCmd);
-
-        Runtime.getRuntime().exec(runCmd);
-      } catch (Exception e) {
-        logger.error("kill application error", e);
-      }
+    /**
+     * build kill command for yarn application
+     *
+     * @param logger      logger
+     * @param tenantCode  tenant code
+     * @param appId       app id
+     * @param commandFile command file
+     * @param cmd         cmd
+     */
+    private static void execYarnKillCommand(Logger logger, String tenantCode, String appId, String commandFile, String cmd) {
+        try {
+            StringBuilder sb = new StringBuilder();
+            sb.append("#!/bin/sh\n");
+            sb.append("BASEDIR=$(cd `dirname $0`; pwd)\n");
+            sb.append("cd $BASEDIR\n");
+            if (CommonUtils.getSystemEnvPath() != null) {
+                sb.append("source ").append(CommonUtils.getSystemEnvPath()).append("\n");
+            }
+            sb.append("\n\n");
+            sb.append(cmd);
+
+            File f = new File(commandFile);
+
+            if (!f.exists()) {
+                FileUtils.writeStringToFile(new File(commandFile), sb.toString(), StandardCharsets.UTF_8);
+            }
+
+            String runCmd = "sh " + commandFile;
+            if (StringUtils.isNotEmpty(tenantCode)) {
+                runCmd = "sudo -u " + tenantCode + " " + runCmd;
+            }
+
+            logger.info("kill cmd:{}", runCmd);
+            Runtime.getRuntime().exec(runCmd);
+        } catch (Exception e) {
+            logger.error(String.format("Kill yarn application app id [%s] failed: [%s]", appId, e.getMessage()));
+        }
     }
-  }
 
-  /**
-   * kill tasks according to different task types.
-   *
-   * @param taskExecutionContext  taskExecutionContext
-   */
-  public static void kill(TaskExecutionContext taskExecutionContext) {
-    try {
-      int processId = taskExecutionContext.getProcessId();
-      if (processId == 0) {
-        logger.error("process kill failed, process id :{}, task id:{}",
-                processId, taskExecutionContext.getTaskInstanceId());
-        return;
-      }
+    /**
+     * kill tasks according to different task types.
+     *
+     * @param taskExecutionContext taskExecutionContext
+     */
+    public static void kill(TaskExecutionContext taskExecutionContext) {
+        try {
+            int processId = taskExecutionContext.getProcessId();
+            if (processId == 0) {
+                logger.error("process kill failed, process id :{}, task id:{}",
+                    processId, taskExecutionContext.getTaskInstanceId());
+                return;
+            }
 
-      String cmd = String.format("sudo kill -9 %s", getPidsStr(processId));
+            String cmd = String.format("sudo kill -9 %s", getPidsStr(processId));
 
-      logger.info("process id:{}, cmd:{}", processId, cmd);
+            logger.info("process id:{}, cmd:{}", processId, cmd);
 
-      OSUtils.exeCmd(cmd);
+            OSUtils.exeCmd(cmd);
 
-      // find log and kill yarn job
-      killYarnJob(taskExecutionContext);
+            // find log and kill yarn job
+            killYarnJob(taskExecutionContext);
 
-    } catch (Exception e) {
-      logger.error("kill task failed", e);
-    }
-  }
-
-  /**
-   * get pids str.
-   *
-   * @param processId process id
-   * @return pids
-   * @throws Exception exception
-   */
-  public static String getPidsStr(int processId) throws Exception {
-    StringBuilder sb = new StringBuilder();
-    Matcher mat;
-    // pstree pid get sub pids
-    if (OSUtils.isMacOS()) {
-      String pids = OSUtils.exeCmd("pstree -sp " + processId);
-      mat = MACPATTERN.matcher(pids);
-    } else {
-      String pids = OSUtils.exeCmd("pstree -p " + processId);
-      mat = WINDOWSATTERN.matcher(pids);
+        } catch (Exception e) {
+            logger.error("kill task failed", e);
+        }
     }
 
-    while (mat.find()) {
-      sb.append(mat.group(1)).append(" ");
-    }
-    return sb.toString().trim();
-  }
-
-  /**
-   * find logs and kill yarn tasks.
-   *
-   * @param taskExecutionContext  taskExecutionContext
-   */
-  public static void killYarnJob(TaskExecutionContext taskExecutionContext) {
-    try {
-      Thread.sleep(Constants.SLEEP_TIME_MILLIS);
-      LogClientService logClient = null;
-      String log = null;
-      try {
-        logClient = new LogClientService();
-        log = logClient.viewLog(Host.of(taskExecutionContext.getHost()).getIp(),
-                Constants.RPC_PORT,
-                taskExecutionContext.getLogPath());
-      } finally {
-        if (logClient != null) {
-          logClient.close();
-        }
-      }
-      if (StringUtils.isNotEmpty(log)) {
-        List<String> appIds = LoggerUtils.getAppIds(log, logger);
-        String workerDir = taskExecutionContext.getExecutePath();
-        if (StringUtils.isEmpty(workerDir)) {
-          logger.error("task instance work dir is empty");
-          throw new RuntimeException("task instance work dir is empty");
+    /**
+     * get pids str.
+     *
+     * @param processId process id
+     * @return pids pid String
+     * @throws Exception exception
+     */
+    public static String getPidsStr(int processId) throws Exception {
+        StringBuilder sb = new StringBuilder();
+        Matcher mat = null;
+        // pstree pid get sub pids
+        if (OSUtils.isMacOS()) {
+            String pids = OSUtils.exeCmd("pstree -sp " + processId);
+            if (null != pids) {
+                mat = MACPATTERN.matcher(pids);
+            }
+        } else {
+            String pids = OSUtils.exeCmd("pstree -p " + processId);

Review comment:
       i think this "pstree " can be extracted to one variable,  then I can easily replace this variable.




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-dolphinscheduler] codecov-io commented on pull request #4042: [FIX-3900][server] kill multi yarn app in one job

Posted by GitBox <gi...@apache.org>.
codecov-io commented on pull request #4042:
URL: https://github.com/apache/incubator-dolphinscheduler/pull/4042#issuecomment-727954797


   # [Codecov](https://codecov.io/gh/apache/incubator-dolphinscheduler/pull/4042?src=pr&el=h1) Report
   > Merging [#4042](https://codecov.io/gh/apache/incubator-dolphinscheduler/pull/4042?src=pr&el=desc) (cb669b5) into [dev](https://codecov.io/gh/apache/incubator-dolphinscheduler/commit/1eecbb1ef7d35c7d1363b1bcafc3367bb25caa8a?el=desc) (1eecbb1) will **increase** coverage by `0.17%`.
   > The diff coverage is `48.29%`.
   
   [![Impacted file tree graph](https://codecov.io/gh/apache/incubator-dolphinscheduler/pull/4042/graphs/tree.svg?width=650&height=150&src=pr&token=bv9iXXRLi9)](https://codecov.io/gh/apache/incubator-dolphinscheduler/pull/4042?src=pr&el=tree)
   
   ```diff
   @@             Coverage Diff              @@
   ##                dev    #4042      +/-   ##
   ============================================
   + Coverage     39.24%   39.42%   +0.17%     
   - Complexity     2962     2980      +18     
   ============================================
     Files           467      467              
     Lines         22107    22116       +9     
     Branches       2713     2715       +2     
   ============================================
   + Hits           8676     8719      +43     
   + Misses        12629    12590      -39     
   - Partials        802      807       +5     
   ```
   
   
   | [Impacted Files](https://codecov.io/gh/apache/incubator-dolphinscheduler/pull/4042?src=pr&el=tree) | Coverage Δ | Complexity Δ | |
   |---|---|---|---|
   | [...he/dolphinscheduler/server/utils/ProcessUtils.java](https://codecov.io/gh/apache/incubator-dolphinscheduler/pull/4042/diff?src=pr&el=tree#diff-ZG9scGhpbnNjaGVkdWxlci1zZXJ2ZXIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2RvbHBoaW5zY2hlZHVsZXIvc2VydmVyL3V0aWxzL1Byb2Nlc3NVdGlscy5qYXZh) | `48.34% <48.29%> (+29.33%)` | `25.00 <25.00> (+17.00)` | |
   | [...er/master/processor/queue/TaskResponseService.java](https://codecov.io/gh/apache/incubator-dolphinscheduler/pull/4042/diff?src=pr&el=tree#diff-ZG9scGhpbnNjaGVkdWxlci1zZXJ2ZXIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2RvbHBoaW5zY2hlZHVsZXIvc2VydmVyL21hc3Rlci9wcm9jZXNzb3IvcXVldWUvVGFza1Jlc3BvbnNlU2VydmljZS5qYXZh) | `32.39% <0.00%> (-7.05%)` | `5.00% <0.00%> (ø%)` | |
   | [...er/master/dispatch/host/assign/RandomSelector.java](https://codecov.io/gh/apache/incubator-dolphinscheduler/pull/4042/diff?src=pr&el=tree#diff-ZG9scGhpbnNjaGVkdWxlci1zZXJ2ZXIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2RvbHBoaW5zY2hlZHVsZXIvc2VydmVyL21hc3Rlci9kaXNwYXRjaC9ob3N0L2Fzc2lnbi9SYW5kb21TZWxlY3Rvci5qYXZh) | `77.77% <0.00%> (-5.56%)` | `3.00% <0.00%> (-1.00%)` | |
   | [...eduler/server/worker/runner/TaskExecuteThread.java](https://codecov.io/gh/apache/incubator-dolphinscheduler/pull/4042/diff?src=pr&el=tree#diff-ZG9scGhpbnNjaGVkdWxlci1zZXJ2ZXIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2RvbHBoaW5zY2hlZHVsZXIvc2VydmVyL3dvcmtlci9ydW5uZXIvVGFza0V4ZWN1dGVUaHJlYWQuamF2YQ==) | `57.02% <0.00%> (+0.82%)` | `13.00% <0.00%> (+1.00%)` | |
   | [...inscheduler/service/zk/CuratorZookeeperClient.java](https://codecov.io/gh/apache/incubator-dolphinscheduler/pull/4042/diff?src=pr&el=tree#diff-ZG9scGhpbnNjaGVkdWxlci1zZXJ2aWNlL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9kb2xwaGluc2NoZWR1bGVyL3NlcnZpY2UvemsvQ3VyYXRvclpvb2tlZXBlckNsaWVudC5qYXZh) | `65.85% <0.00%> (+4.87%)` | `8.00% <0.00%> (+1.00%)` | |
   
   ------
   
   [Continue to review full report at Codecov](https://codecov.io/gh/apache/incubator-dolphinscheduler/pull/4042?src=pr&el=continue).
   > **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
   > `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
   > Powered by [Codecov](https://codecov.io/gh/apache/incubator-dolphinscheduler/pull/4042?src=pr&el=footer). Last update [1eecbb1...cb669b5](https://codecov.io/gh/apache/incubator-dolphinscheduler/pull/4042?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).
   


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-dolphinscheduler] Eights-Li commented on a change in pull request #4042: [FIX-3900][server] kill multi yarn app in one job

Posted by GitBox <gi...@apache.org>.
Eights-Li commented on a change in pull request #4042:
URL: https://github.com/apache/incubator-dolphinscheduler/pull/4042#discussion_r524230617



##########
File path: dolphinscheduler-server/src/main/java/org/apache/dolphinscheduler/server/utils/ProcessUtils.java
##########
@@ -38,368 +41,406 @@
 import java.util.regex.Pattern;
 
 /**
- *  mainly used to get the start command line of a process.
+ * mainly used to get the start command line of a process.
  */
 public class ProcessUtils {
-  /**
-   * logger.
-   */
-  private static final Logger logger = LoggerFactory.getLogger(ProcessUtils.class);
-
-  /**
-   * Initialization regularization, solve the problem of pre-compilation performance,
-   * avoid the thread safety problem of multi-thread operation.
-   */
-  private static final Pattern MACPATTERN = Pattern.compile("-[+|-]-\\s(\\d+)");
-
-  private static final Pattern WINDOWSATTERN = Pattern.compile("(\\d+)");
-
-  /**
-   * build command line characters.
-   * @param commandList command list
-   * @return command
-   */
-  public static String buildCommandStr(List<String> commandList) {
-    String cmdstr;
-    String[] cmd = commandList.toArray(new String[commandList.size()]);
-    SecurityManager security = System.getSecurityManager();
-    boolean allowAmbiguousCommands = false;
-    if (security == null) {
-      allowAmbiguousCommands = true;
-      String value = System.getProperty("jdk.lang.Process.allowAmbiguousCommands");
-      if (value != null) {
-        allowAmbiguousCommands = !"false".equalsIgnoreCase(value);
-      }
+    /**
+     * logger.
+     */
+    private static final Logger logger = LoggerFactory.getLogger(ProcessUtils.class);
+
+    /**
+     * Initialization regularization, solve the problem of pre-compilation performance,
+     * avoid the thread safety problem of multi-thread operation.
+     */
+    private static final Pattern MACPATTERN = Pattern.compile("-[+|-]-\\s(\\d+)");
+
+    private static final Pattern WINDOWSATTERN = Pattern.compile("(\\d+)");
+
+    /**
+     * build command line characters.
+     *
+     * @param commandList command list
+     * @return command
+     */
+    public static String buildCommandStr(List<String> commandList) {
+        String cmdstr;
+        String[] cmd = commandList.toArray(new String[0]);
+        SecurityManager security = System.getSecurityManager();
+        boolean allowAmbiguousCommands = isAllowAmbiguousCommands(security);
+        if (allowAmbiguousCommands) {
+
+            String executablePath = new File(cmd[0]).getPath();
+
+            if (needsEscaping(VERIFICATION_LEGACY, executablePath)) {
+                executablePath = quoteString(executablePath);
+            }
+
+            cmdstr = createCommandLine(
+                VERIFICATION_LEGACY, executablePath, cmd);
+        } else {
+            String executablePath;
+            try {
+                executablePath = getExecutablePath(cmd[0]);
+            } catch (IllegalArgumentException e) {
+
+                StringBuilder join = new StringBuilder();
+                for (String s : cmd) {
+                    join.append(s).append(' ');
+                }
+
+                cmd = getTokensFromCommand(join.toString());
+                executablePath = getExecutablePath(cmd[0]);
+
+                // Check new executable name once more
+                if (security != null) {
+                    security.checkExec(executablePath);
+                }
+            }
+
+            cmdstr = createCommandLine(
+
+                isShellFile(executablePath) ? VERIFICATION_CMD_BAT : VERIFICATION_WIN32, quoteString(executablePath), cmd);
+        }
+        return cmdstr;
     }
-    if (allowAmbiguousCommands) {
-
-      String executablePath = new File(cmd[0]).getPath();
-
-      if (needsEscaping(VERIFICATION_LEGACY, executablePath)) {
-        executablePath = quoteString(executablePath);
-      }
-
-      cmdstr = createCommandLine(
-              VERIFICATION_LEGACY, executablePath, cmd);
-    } else {
-      String executablePath;
-      try {
-        executablePath = getExecutablePath(cmd[0]);
-      } catch (IllegalArgumentException e) {
 
-        StringBuilder join = new StringBuilder();
-        for (String s : cmd) {
-          join.append(s).append(' ');
+    /**
+     * check is allow ambiguous commands
+     *
+     * @param security security manager
+     * @return allow ambiguous command flag
+     */
+    private static boolean isAllowAmbiguousCommands(SecurityManager security) {
+        boolean allowAmbiguousCommands = false;
+        if (security == null) {
+            allowAmbiguousCommands = true;
+            String value = System.getProperty("jdk.lang.Process.allowAmbiguousCommands");

Review comment:
       fixed

##########
File path: dolphinscheduler-server/src/main/java/org/apache/dolphinscheduler/server/utils/ProcessUtils.java
##########
@@ -38,368 +41,406 @@
 import java.util.regex.Pattern;
 
 /**
- *  mainly used to get the start command line of a process.
+ * mainly used to get the start command line of a process.
  */
 public class ProcessUtils {
-  /**
-   * logger.
-   */
-  private static final Logger logger = LoggerFactory.getLogger(ProcessUtils.class);
-
-  /**
-   * Initialization regularization, solve the problem of pre-compilation performance,
-   * avoid the thread safety problem of multi-thread operation.
-   */
-  private static final Pattern MACPATTERN = Pattern.compile("-[+|-]-\\s(\\d+)");
-
-  private static final Pattern WINDOWSATTERN = Pattern.compile("(\\d+)");
-
-  /**
-   * build command line characters.
-   * @param commandList command list
-   * @return command
-   */
-  public static String buildCommandStr(List<String> commandList) {
-    String cmdstr;
-    String[] cmd = commandList.toArray(new String[commandList.size()]);
-    SecurityManager security = System.getSecurityManager();
-    boolean allowAmbiguousCommands = false;
-    if (security == null) {
-      allowAmbiguousCommands = true;
-      String value = System.getProperty("jdk.lang.Process.allowAmbiguousCommands");
-      if (value != null) {
-        allowAmbiguousCommands = !"false".equalsIgnoreCase(value);
-      }
+    /**
+     * logger.
+     */
+    private static final Logger logger = LoggerFactory.getLogger(ProcessUtils.class);
+
+    /**
+     * Initialization regularization, solve the problem of pre-compilation performance,
+     * avoid the thread safety problem of multi-thread operation.
+     */
+    private static final Pattern MACPATTERN = Pattern.compile("-[+|-]-\\s(\\d+)");
+
+    private static final Pattern WINDOWSATTERN = Pattern.compile("(\\d+)");
+
+    /**
+     * build command line characters.
+     *
+     * @param commandList command list
+     * @return command
+     */
+    public static String buildCommandStr(List<String> commandList) {
+        String cmdstr;
+        String[] cmd = commandList.toArray(new String[0]);
+        SecurityManager security = System.getSecurityManager();
+        boolean allowAmbiguousCommands = isAllowAmbiguousCommands(security);
+        if (allowAmbiguousCommands) {
+
+            String executablePath = new File(cmd[0]).getPath();
+
+            if (needsEscaping(VERIFICATION_LEGACY, executablePath)) {
+                executablePath = quoteString(executablePath);
+            }
+
+            cmdstr = createCommandLine(
+                VERIFICATION_LEGACY, executablePath, cmd);
+        } else {
+            String executablePath;
+            try {
+                executablePath = getExecutablePath(cmd[0]);
+            } catch (IllegalArgumentException e) {
+
+                StringBuilder join = new StringBuilder();
+                for (String s : cmd) {
+                    join.append(s).append(' ');
+                }
+
+                cmd = getTokensFromCommand(join.toString());
+                executablePath = getExecutablePath(cmd[0]);
+
+                // Check new executable name once more
+                if (security != null) {
+                    security.checkExec(executablePath);
+                }
+            }
+
+            cmdstr = createCommandLine(
+
+                isShellFile(executablePath) ? VERIFICATION_CMD_BAT : VERIFICATION_WIN32, quoteString(executablePath), cmd);
+        }
+        return cmdstr;
     }
-    if (allowAmbiguousCommands) {
-
-      String executablePath = new File(cmd[0]).getPath();
-
-      if (needsEscaping(VERIFICATION_LEGACY, executablePath)) {
-        executablePath = quoteString(executablePath);
-      }
-
-      cmdstr = createCommandLine(
-              VERIFICATION_LEGACY, executablePath, cmd);
-    } else {
-      String executablePath;
-      try {
-        executablePath = getExecutablePath(cmd[0]);
-      } catch (IllegalArgumentException e) {
 
-        StringBuilder join = new StringBuilder();
-        for (String s : cmd) {
-          join.append(s).append(' ');
+    /**
+     * check is allow ambiguous commands
+     *
+     * @param security security manager
+     * @return allow ambiguous command flag
+     */
+    private static boolean isAllowAmbiguousCommands(SecurityManager security) {
+        boolean allowAmbiguousCommands = false;
+        if (security == null) {
+            allowAmbiguousCommands = true;
+            String value = System.getProperty("jdk.lang.Process.allowAmbiguousCommands");
+            if (value != null) {
+                allowAmbiguousCommands = !"false".equalsIgnoreCase(value);
+            }
         }
+        return allowAmbiguousCommands;
+    }
 
-        cmd = getTokensFromCommand(join.toString());
-        executablePath = getExecutablePath(cmd[0]);
+    /**
+     * get executable path.
+     *
+     * @param path path
+     * @return executable path
+     */
+    private static String getExecutablePath(String path) {
+        boolean pathIsQuoted = isQuoted(true, path, "Executable name has embedded quote, split the arguments");

Review comment:
       fixed




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-dolphinscheduler] dailidong merged pull request #4042: [FIX-3900][server] kill multi yarn app in one job

Posted by GitBox <gi...@apache.org>.
dailidong merged pull request #4042:
URL: https://github.com/apache/incubator-dolphinscheduler/pull/4042


   


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-dolphinscheduler] codecov-io edited a comment on pull request #4042: [FIX-3900][server] kill multi yarn app in one job

Posted by GitBox <gi...@apache.org>.
codecov-io edited a comment on pull request #4042:
URL: https://github.com/apache/incubator-dolphinscheduler/pull/4042#issuecomment-727954797


   # [Codecov](https://codecov.io/gh/apache/incubator-dolphinscheduler/pull/4042?src=pr&el=h1) Report
   > Merging [#4042](https://codecov.io/gh/apache/incubator-dolphinscheduler/pull/4042?src=pr&el=desc) (dedc539) into [dev](https://codecov.io/gh/apache/incubator-dolphinscheduler/commit/1c5be9acf18cd66e4424194e7f148eac68e8ac86?el=desc) (1c5be9a) will **increase** coverage by `0.19%`.
   > The diff coverage is `51.28%`.
   
   [![Impacted file tree graph](https://codecov.io/gh/apache/incubator-dolphinscheduler/pull/4042/graphs/tree.svg?width=650&height=150&src=pr&token=bv9iXXRLi9)](https://codecov.io/gh/apache/incubator-dolphinscheduler/pull/4042?src=pr&el=tree)
   
   ```diff
   @@             Coverage Diff              @@
   ##                dev    #4042      +/-   ##
   ============================================
   + Coverage     39.36%   39.55%   +0.19%     
   - Complexity     2966     2983      +17     
   ============================================
     Files           467      467              
     Lines         22107    22116       +9     
     Branches       2713     2715       +2     
   ============================================
   + Hits           8703     8749      +46     
   + Misses        12595    12553      -42     
   - Partials        809      814       +5     
   ```
   
   
   | [Impacted Files](https://codecov.io/gh/apache/incubator-dolphinscheduler/pull/4042?src=pr&el=tree) | Coverage Δ | Complexity Δ | |
   |---|---|---|---|
   | [...he/dolphinscheduler/server/utils/ProcessUtils.java](https://codecov.io/gh/apache/incubator-dolphinscheduler/pull/4042/diff?src=pr&el=tree#diff-ZG9scGhpbnNjaGVkdWxlci1zZXJ2ZXIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2RvbHBoaW5zY2hlZHVsZXIvc2VydmVyL3V0aWxzL1Byb2Nlc3NVdGlscy5qYXZh) | `48.34% <48.29%> (+29.33%)` | `25.00 <25.00> (+17.00)` | |
   | [.../org/apache/dolphinscheduler/common/Constants.java](https://codecov.io/gh/apache/incubator-dolphinscheduler/pull/4042/diff?src=pr&el=tree#diff-ZG9scGhpbnNjaGVkdWxlci1jb21tb24vc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2RvbHBoaW5zY2hlZHVsZXIvY29tbW9uL0NvbnN0YW50cy5qYXZh) | `85.00% <100.00%> (ø)` | `1.00 <0.00> (ø)` | |
   
   ------
   
   [Continue to review full report at Codecov](https://codecov.io/gh/apache/incubator-dolphinscheduler/pull/4042?src=pr&el=continue).
   > **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
   > `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
   > Powered by [Codecov](https://codecov.io/gh/apache/incubator-dolphinscheduler/pull/4042?src=pr&el=footer). Last update [1c5be9a...c24dbc4](https://codecov.io/gh/apache/incubator-dolphinscheduler/pull/4042?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).
   


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-dolphinscheduler] sonarcloud[bot] commented on pull request #4042: [FIX-3900][server] kill multi yarn app in one job

Posted by GitBox <gi...@apache.org>.
sonarcloud[bot] commented on pull request #4042:
URL: https://github.com/apache/incubator-dolphinscheduler/pull/4042#issuecomment-725829135


   Kudos, SonarCloud Quality Gate passed!
   
   [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/bug.png' alt='Bug' width='16' height='16' />](https://sonarcloud.io/project/issues?id=apache-dolphinscheduler&pullRequest=4042&resolved=false&types=BUG) [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A.png' alt='A' width='16' height='16' />](https://sonarcloud.io/project/issues?id=apache-dolphinscheduler&pullRequest=4042&resolved=false&types=BUG) [0 Bugs](https://sonarcloud.io/project/issues?id=apache-dolphinscheduler&pullRequest=4042&resolved=false&types=BUG)  
   [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/vulnerability.png' alt='Vulnerability' width='16' height='16' />](https://sonarcloud.io/project/issues?id=apache-dolphinscheduler&pullRequest=4042&resolved=false&types=VULNERABILITY) [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A.png' alt='A' width='16' height='16' />](https://sonarcloud.io/project/issues?id=apache-dolphinscheduler&pullRequest=4042&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonarcloud.io/project/issues?id=apache-dolphinscheduler&pullRequest=4042&resolved=false&types=VULNERABILITY) (and [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/security_hotspot.png' alt='Security Hotspot' width='16' height='16' />](https://sonarcloud.io/project/issues?id=apache-dolphinscheduler&pullRequest=4042&resolved=false&types=SECURITY_HOTSPOT) [0 Security Hotspots](https://sonarcloud.io/proje
 ct/issues?id=apache-dolphinscheduler&pullRequest=4042&resolved=false&types=SECURITY_HOTSPOT) to review)  
   [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/code_smell.png' alt='Code Smell' width='16' height='16' />](https://sonarcloud.io/project/issues?id=apache-dolphinscheduler&pullRequest=4042&resolved=false&types=CODE_SMELL) [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A.png' alt='A' width='16' height='16' />](https://sonarcloud.io/project/issues?id=apache-dolphinscheduler&pullRequest=4042&resolved=false&types=CODE_SMELL) [8 Code Smells](https://sonarcloud.io/project/issues?id=apache-dolphinscheduler&pullRequest=4042&resolved=false&types=CODE_SMELL)
   
   [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/CoverageChart/50.png' alt='58.8%' width='16' height='16' />](https://sonarcloud.io/component_measures?id=apache-dolphinscheduler&pullRequest=4042&metric=new_coverage&view=list) [58.8% Coverage](https://sonarcloud.io/component_measures?id=apache-dolphinscheduler&pullRequest=4042&metric=new_coverage&view=list)  
   [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/Duplications/3.png' alt='0.0%' width='16' height='16' />](https://sonarcloud.io/component_measures?id=apache-dolphinscheduler&pullRequest=4042&metric=new_duplicated_lines_density&view=list) [0.0% Duplication](https://sonarcloud.io/component_measures?id=apache-dolphinscheduler&pullRequest=4042&metric=new_duplicated_lines_density&view=list)
   
   


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-dolphinscheduler] Eights-Li commented on a change in pull request #4042: [FIX-3900][server] kill multi yarn app in one job

Posted by GitBox <gi...@apache.org>.
Eights-Li commented on a change in pull request #4042:
URL: https://github.com/apache/incubator-dolphinscheduler/pull/4042#discussion_r524224257



##########
File path: dolphinscheduler-server/src/main/java/org/apache/dolphinscheduler/server/utils/ProcessUtils.java
##########
@@ -38,368 +41,406 @@
 import java.util.regex.Pattern;
 
 /**
- *  mainly used to get the start command line of a process.
+ * mainly used to get the start command line of a process.
  */
 public class ProcessUtils {
-  /**
-   * logger.
-   */
-  private static final Logger logger = LoggerFactory.getLogger(ProcessUtils.class);
-
-  /**
-   * Initialization regularization, solve the problem of pre-compilation performance,
-   * avoid the thread safety problem of multi-thread operation.
-   */
-  private static final Pattern MACPATTERN = Pattern.compile("-[+|-]-\\s(\\d+)");
-
-  private static final Pattern WINDOWSATTERN = Pattern.compile("(\\d+)");
-
-  /**
-   * build command line characters.
-   * @param commandList command list
-   * @return command
-   */
-  public static String buildCommandStr(List<String> commandList) {
-    String cmdstr;
-    String[] cmd = commandList.toArray(new String[commandList.size()]);
-    SecurityManager security = System.getSecurityManager();
-    boolean allowAmbiguousCommands = false;
-    if (security == null) {
-      allowAmbiguousCommands = true;
-      String value = System.getProperty("jdk.lang.Process.allowAmbiguousCommands");
-      if (value != null) {
-        allowAmbiguousCommands = !"false".equalsIgnoreCase(value);
-      }
+    /**
+     * logger.
+     */
+    private static final Logger logger = LoggerFactory.getLogger(ProcessUtils.class);
+
+    /**
+     * Initialization regularization, solve the problem of pre-compilation performance,
+     * avoid the thread safety problem of multi-thread operation.
+     */
+    private static final Pattern MACPATTERN = Pattern.compile("-[+|-]-\\s(\\d+)");
+
+    private static final Pattern WINDOWSATTERN = Pattern.compile("(\\d+)");
+
+    /**
+     * build command line characters.
+     *
+     * @param commandList command list
+     * @return command
+     */
+    public static String buildCommandStr(List<String> commandList) {
+        String cmdstr;
+        String[] cmd = commandList.toArray(new String[0]);
+        SecurityManager security = System.getSecurityManager();
+        boolean allowAmbiguousCommands = isAllowAmbiguousCommands(security);
+        if (allowAmbiguousCommands) {
+
+            String executablePath = new File(cmd[0]).getPath();
+
+            if (needsEscaping(VERIFICATION_LEGACY, executablePath)) {
+                executablePath = quoteString(executablePath);
+            }
+
+            cmdstr = createCommandLine(
+                VERIFICATION_LEGACY, executablePath, cmd);
+        } else {
+            String executablePath;
+            try {
+                executablePath = getExecutablePath(cmd[0]);
+            } catch (IllegalArgumentException e) {
+
+                StringBuilder join = new StringBuilder();
+                for (String s : cmd) {
+                    join.append(s).append(' ');
+                }
+
+                cmd = getTokensFromCommand(join.toString());
+                executablePath = getExecutablePath(cmd[0]);
+
+                // Check new executable name once more
+                if (security != null) {
+                    security.checkExec(executablePath);
+                }
+            }
+
+            cmdstr = createCommandLine(
+
+                isShellFile(executablePath) ? VERIFICATION_CMD_BAT : VERIFICATION_WIN32, quoteString(executablePath), cmd);
+        }
+        return cmdstr;
     }
-    if (allowAmbiguousCommands) {
-
-      String executablePath = new File(cmd[0]).getPath();
-
-      if (needsEscaping(VERIFICATION_LEGACY, executablePath)) {
-        executablePath = quoteString(executablePath);
-      }
-
-      cmdstr = createCommandLine(
-              VERIFICATION_LEGACY, executablePath, cmd);
-    } else {
-      String executablePath;
-      try {
-        executablePath = getExecutablePath(cmd[0]);
-      } catch (IllegalArgumentException e) {
 
-        StringBuilder join = new StringBuilder();
-        for (String s : cmd) {
-          join.append(s).append(' ');
+    /**
+     * check is allow ambiguous commands
+     *
+     * @param security security manager
+     * @return allow ambiguous command flag
+     */
+    private static boolean isAllowAmbiguousCommands(SecurityManager security) {
+        boolean allowAmbiguousCommands = false;
+        if (security == null) {
+            allowAmbiguousCommands = true;
+            String value = System.getProperty("jdk.lang.Process.allowAmbiguousCommands");
+            if (value != null) {
+                allowAmbiguousCommands = !"false".equalsIgnoreCase(value);
+            }
         }
+        return allowAmbiguousCommands;
+    }
 
-        cmd = getTokensFromCommand(join.toString());
-        executablePath = getExecutablePath(cmd[0]);
+    /**
+     * get executable path.
+     *
+     * @param path path
+     * @return executable path
+     */
+    private static String getExecutablePath(String path) {
+        boolean pathIsQuoted = isQuoted(true, path, "Executable name has embedded quote, split the arguments");

Review comment:
       This string is error message




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-dolphinscheduler] codecov-io edited a comment on pull request #4042: [FIX-3900][server] kill multi yarn app in one job

Posted by GitBox <gi...@apache.org>.
codecov-io edited a comment on pull request #4042:
URL: https://github.com/apache/incubator-dolphinscheduler/pull/4042#issuecomment-727954797


   # [Codecov](https://codecov.io/gh/apache/incubator-dolphinscheduler/pull/4042?src=pr&el=h1) Report
   > Merging [#4042](https://codecov.io/gh/apache/incubator-dolphinscheduler/pull/4042?src=pr&el=desc) (802de19) into [dev](https://codecov.io/gh/apache/incubator-dolphinscheduler/commit/f152cae7f6beee585bc43a2b0bee2686c21d03c4?el=desc) (f152cae) will **increase** coverage by `0.10%`.
   > The diff coverage is `51.28%`.
   
   [![Impacted file tree graph](https://codecov.io/gh/apache/incubator-dolphinscheduler/pull/4042/graphs/tree.svg?width=650&height=150&src=pr&token=bv9iXXRLi9)](https://codecov.io/gh/apache/incubator-dolphinscheduler/pull/4042?src=pr&el=tree)
   
   ```diff
   @@             Coverage Diff              @@
   ##                dev    #4042      +/-   ##
   ============================================
   + Coverage     39.39%   39.49%   +0.10%     
   - Complexity     2968     2981      +13     
   ============================================
     Files           467      467              
     Lines         22104    22113       +9     
     Branches       2712     2714       +2     
   ============================================
   + Hits           8708     8734      +26     
   + Misses        12589    12570      -19     
   - Partials        807      809       +2     
   ```
   
   
   | [Impacted Files](https://codecov.io/gh/apache/incubator-dolphinscheduler/pull/4042?src=pr&el=tree) | Coverage Δ | Complexity Δ | |
   |---|---|---|---|
   | [...he/dolphinscheduler/server/utils/ProcessUtils.java](https://codecov.io/gh/apache/incubator-dolphinscheduler/pull/4042/diff?src=pr&el=tree#diff-ZG9scGhpbnNjaGVkdWxlci1zZXJ2ZXIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2RvbHBoaW5zY2hlZHVsZXIvc2VydmVyL3V0aWxzL1Byb2Nlc3NVdGlscy5qYXZh) | `48.34% <48.29%> (+29.33%)` | `25.00 <25.00> (+17.00)` | |
   | [.../org/apache/dolphinscheduler/common/Constants.java](https://codecov.io/gh/apache/incubator-dolphinscheduler/pull/4042/diff?src=pr&el=tree#diff-ZG9scGhpbnNjaGVkdWxlci1jb21tb24vc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2RvbHBoaW5zY2hlZHVsZXIvY29tbW9uL0NvbnN0YW50cy5qYXZh) | `85.00% <100.00%> (ø)` | `1.00 <0.00> (ø)` | |
   | [...che/dolphinscheduler/common/utils/LoggerUtils.java](https://codecov.io/gh/apache/incubator-dolphinscheduler/pull/4042/diff?src=pr&el=tree#diff-ZG9scGhpbnNjaGVkdWxlci1jb21tb24vc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2RvbHBoaW5zY2hlZHVsZXIvY29tbW9uL3V0aWxzL0xvZ2dlclV0aWxzLmphdmE=) | `62.50% <0.00%> (-8.34%)` | `5.00% <0.00%> (-1.00%)` | |
   | [...e/dolphinscheduler/common/shell/AbstractShell.java](https://codecov.io/gh/apache/incubator-dolphinscheduler/pull/4042/diff?src=pr&el=tree#diff-ZG9scGhpbnNjaGVkdWxlci1jb21tb24vc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2RvbHBoaW5zY2hlZHVsZXIvY29tbW9uL3NoZWxsL0Fic3RyYWN0U2hlbGwuamF2YQ==) | `44.53% <0.00%> (-5.89%)` | `5.00% <0.00%> (-1.00%)` | |
   | [...er/master/dispatch/host/assign/RandomSelector.java](https://codecov.io/gh/apache/incubator-dolphinscheduler/pull/4042/diff?src=pr&el=tree#diff-ZG9scGhpbnNjaGVkdWxlci1zZXJ2ZXIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2RvbHBoaW5zY2hlZHVsZXIvc2VydmVyL21hc3Rlci9kaXNwYXRjaC9ob3N0L2Fzc2lnbi9SYW5kb21TZWxlY3Rvci5qYXZh) | `77.77% <0.00%> (-5.56%)` | `3.00% <0.00%> (-1.00%)` | |
   | [...inscheduler/service/zk/CuratorZookeeperClient.java](https://codecov.io/gh/apache/incubator-dolphinscheduler/pull/4042/diff?src=pr&el=tree#diff-ZG9scGhpbnNjaGVkdWxlci1zZXJ2aWNlL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9kb2xwaGluc2NoZWR1bGVyL3NlcnZpY2UvemsvQ3VyYXRvclpvb2tlZXBlckNsaWVudC5qYXZh) | `56.09% <0.00%> (-4.88%)` | `6.00% <0.00%> (-1.00%)` | |
   | [...pache/dolphinscheduler/common/utils/FileUtils.java](https://codecov.io/gh/apache/incubator-dolphinscheduler/pull/4042/diff?src=pr&el=tree#diff-ZG9scGhpbnNjaGVkdWxlci1jb21tb24vc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2RvbHBoaW5zY2hlZHVsZXIvY29tbW9uL3V0aWxzL0ZpbGVVdGlscy5qYXZh) | `28.92% <0.00%> (-3.31%)` | `9.00% <0.00%> (ø%)` | |
   | [.../apache/dolphinscheduler/common/utils/OSUtils.java](https://codecov.io/gh/apache/incubator-dolphinscheduler/pull/4042/diff?src=pr&el=tree#diff-ZG9scGhpbnNjaGVkdWxlci1jb21tb24vc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2RvbHBoaW5zY2hlZHVsZXIvY29tbW9uL3V0aWxzL09TVXRpbHMuamF2YQ==) | `44.57% <0.00%> (-2.41%)` | `23.00% <0.00%> (ø%)` | |
   
   ------
   
   [Continue to review full report at Codecov](https://codecov.io/gh/apache/incubator-dolphinscheduler/pull/4042?src=pr&el=continue).
   > **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
   > `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
   > Powered by [Codecov](https://codecov.io/gh/apache/incubator-dolphinscheduler/pull/4042?src=pr&el=footer). Last update [f152cae...802de19](https://codecov.io/gh/apache/incubator-dolphinscheduler/pull/4042?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).
   


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-dolphinscheduler] lenboo commented on a change in pull request #4042: [FIX-3900][server] kill multi yarn app in one job

Posted by GitBox <gi...@apache.org>.
lenboo commented on a change in pull request #4042:
URL: https://github.com/apache/incubator-dolphinscheduler/pull/4042#discussion_r524084237



##########
File path: dolphinscheduler-server/src/main/java/org/apache/dolphinscheduler/server/utils/ProcessUtils.java
##########
@@ -38,368 +41,406 @@
 import java.util.regex.Pattern;
 
 /**
- *  mainly used to get the start command line of a process.
+ * mainly used to get the start command line of a process.
  */
 public class ProcessUtils {
-  /**
-   * logger.
-   */
-  private static final Logger logger = LoggerFactory.getLogger(ProcessUtils.class);
-
-  /**
-   * Initialization regularization, solve the problem of pre-compilation performance,
-   * avoid the thread safety problem of multi-thread operation.
-   */
-  private static final Pattern MACPATTERN = Pattern.compile("-[+|-]-\\s(\\d+)");
-
-  private static final Pattern WINDOWSATTERN = Pattern.compile("(\\d+)");
-
-  /**
-   * build command line characters.
-   * @param commandList command list
-   * @return command
-   */
-  public static String buildCommandStr(List<String> commandList) {
-    String cmdstr;
-    String[] cmd = commandList.toArray(new String[commandList.size()]);
-    SecurityManager security = System.getSecurityManager();
-    boolean allowAmbiguousCommands = false;
-    if (security == null) {
-      allowAmbiguousCommands = true;
-      String value = System.getProperty("jdk.lang.Process.allowAmbiguousCommands");
-      if (value != null) {
-        allowAmbiguousCommands = !"false".equalsIgnoreCase(value);
-      }
+    /**
+     * logger.
+     */
+    private static final Logger logger = LoggerFactory.getLogger(ProcessUtils.class);
+
+    /**
+     * Initialization regularization, solve the problem of pre-compilation performance,
+     * avoid the thread safety problem of multi-thread operation.
+     */
+    private static final Pattern MACPATTERN = Pattern.compile("-[+|-]-\\s(\\d+)");
+
+    private static final Pattern WINDOWSATTERN = Pattern.compile("(\\d+)");
+
+    /**
+     * build command line characters.
+     *
+     * @param commandList command list
+     * @return command
+     */
+    public static String buildCommandStr(List<String> commandList) {
+        String cmdstr;
+        String[] cmd = commandList.toArray(new String[0]);
+        SecurityManager security = System.getSecurityManager();
+        boolean allowAmbiguousCommands = isAllowAmbiguousCommands(security);
+        if (allowAmbiguousCommands) {
+
+            String executablePath = new File(cmd[0]).getPath();
+
+            if (needsEscaping(VERIFICATION_LEGACY, executablePath)) {
+                executablePath = quoteString(executablePath);
+            }
+
+            cmdstr = createCommandLine(
+                VERIFICATION_LEGACY, executablePath, cmd);
+        } else {
+            String executablePath;
+            try {
+                executablePath = getExecutablePath(cmd[0]);
+            } catch (IllegalArgumentException e) {
+
+                StringBuilder join = new StringBuilder();
+                for (String s : cmd) {
+                    join.append(s).append(' ');
+                }
+
+                cmd = getTokensFromCommand(join.toString());
+                executablePath = getExecutablePath(cmd[0]);
+
+                // Check new executable name once more
+                if (security != null) {
+                    security.checkExec(executablePath);
+                }
+            }
+
+            cmdstr = createCommandLine(
+
+                isShellFile(executablePath) ? VERIFICATION_CMD_BAT : VERIFICATION_WIN32, quoteString(executablePath), cmd);
+        }
+        return cmdstr;
     }
-    if (allowAmbiguousCommands) {
-
-      String executablePath = new File(cmd[0]).getPath();
-
-      if (needsEscaping(VERIFICATION_LEGACY, executablePath)) {
-        executablePath = quoteString(executablePath);
-      }
-
-      cmdstr = createCommandLine(
-              VERIFICATION_LEGACY, executablePath, cmd);
-    } else {
-      String executablePath;
-      try {
-        executablePath = getExecutablePath(cmd[0]);
-      } catch (IllegalArgumentException e) {
 
-        StringBuilder join = new StringBuilder();
-        for (String s : cmd) {
-          join.append(s).append(' ');
+    /**
+     * check is allow ambiguous commands
+     *
+     * @param security security manager
+     * @return allow ambiguous command flag
+     */
+    private static boolean isAllowAmbiguousCommands(SecurityManager security) {
+        boolean allowAmbiguousCommands = false;
+        if (security == null) {
+            allowAmbiguousCommands = true;
+            String value = System.getProperty("jdk.lang.Process.allowAmbiguousCommands");
+            if (value != null) {
+                allowAmbiguousCommands = !"false".equalsIgnoreCase(value);
+            }
         }
+        return allowAmbiguousCommands;
+    }
 
-        cmd = getTokensFromCommand(join.toString());
-        executablePath = getExecutablePath(cmd[0]);
+    /**
+     * get executable path.
+     *
+     * @param path path
+     * @return executable path
+     */
+    private static String getExecutablePath(String path) {
+        boolean pathIsQuoted = isQuoted(true, path, "Executable name has embedded quote, split the arguments");

Review comment:
       also magic number.




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-dolphinscheduler] dailidong commented on a change in pull request #4042: [FIX-3900][server] kill multi yarn app in one job

Posted by GitBox <gi...@apache.org>.
dailidong commented on a change in pull request #4042:
URL: https://github.com/apache/incubator-dolphinscheduler/pull/4042#discussion_r526522387



##########
File path: dolphinscheduler-server/src/main/java/org/apache/dolphinscheduler/server/utils/ProcessUtils.java
##########
@@ -38,368 +41,408 @@
 import java.util.regex.Pattern;
 
 /**
- *  mainly used to get the start command line of a process.
+ * mainly used to get the start command line of a process.
  */
 public class ProcessUtils {
-  /**
-   * logger.
-   */
-  private static final Logger logger = LoggerFactory.getLogger(ProcessUtils.class);
-
-  /**
-   * Initialization regularization, solve the problem of pre-compilation performance,
-   * avoid the thread safety problem of multi-thread operation.
-   */
-  private static final Pattern MACPATTERN = Pattern.compile("-[+|-]-\\s(\\d+)");
-
-  private static final Pattern WINDOWSATTERN = Pattern.compile("(\\d+)");
-
-  /**
-   * build command line characters.
-   * @param commandList command list
-   * @return command
-   */
-  public static String buildCommandStr(List<String> commandList) {
-    String cmdstr;
-    String[] cmd = commandList.toArray(new String[commandList.size()]);
-    SecurityManager security = System.getSecurityManager();
-    boolean allowAmbiguousCommands = false;
-    if (security == null) {
-      allowAmbiguousCommands = true;
-      String value = System.getProperty("jdk.lang.Process.allowAmbiguousCommands");
-      if (value != null) {
-        allowAmbiguousCommands = !"false".equalsIgnoreCase(value);
-      }
+    /**
+     * logger.
+     */
+    private static final Logger logger = LoggerFactory.getLogger(ProcessUtils.class);
+
+    /**
+     * Initialization regularization, solve the problem of pre-compilation performance,
+     * avoid the thread safety problem of multi-thread operation.
+     */
+    private static final Pattern MACPATTERN = Pattern.compile("-[+|-]-\\s(\\d+)");
+
+    private static final Pattern WINDOWSATTERN = Pattern.compile("(\\d+)");
+
+    private static final String LOCAL_PROCESS_EXEC = "jdk.lang.Process.allowAmbiguousCommands";
+
+    /**
+     * build command line characters.
+     *
+     * @param commandList command list
+     * @return command
+     */
+    public static String buildCommandStr(List<String> commandList) {
+        String cmdstr;
+        String[] cmd = commandList.toArray(new String[0]);
+        SecurityManager security = System.getSecurityManager();
+        boolean allowAmbiguousCommands = isAllowAmbiguousCommands(security);
+        if (allowAmbiguousCommands) {
+
+            String executablePath = new File(cmd[0]).getPath();
+
+            if (needsEscaping(VERIFICATION_LEGACY, executablePath)) {
+                executablePath = quoteString(executablePath);
+            }
+
+            cmdstr = createCommandLine(
+                VERIFICATION_LEGACY, executablePath, cmd);
+        } else {
+            String executablePath;
+            try {
+                executablePath = getExecutablePath(cmd[0]);
+            } catch (IllegalArgumentException e) {
+
+                StringBuilder join = new StringBuilder();
+                for (String s : cmd) {
+                    join.append(s).append(' ');
+                }
+
+                cmd = getTokensFromCommand(join.toString());
+                executablePath = getExecutablePath(cmd[0]);
+
+                // Check new executable name once more
+                if (security != null) {
+                    security.checkExec(executablePath);
+                }
+            }
+
+            cmdstr = createCommandLine(
+
+                isShellFile(executablePath) ? VERIFICATION_CMD_BAT : VERIFICATION_WIN32, quoteString(executablePath), cmd);
+        }
+        return cmdstr;
     }
-    if (allowAmbiguousCommands) {
-
-      String executablePath = new File(cmd[0]).getPath();
-
-      if (needsEscaping(VERIFICATION_LEGACY, executablePath)) {
-        executablePath = quoteString(executablePath);
-      }
-
-      cmdstr = createCommandLine(
-              VERIFICATION_LEGACY, executablePath, cmd);
-    } else {
-      String executablePath;
-      try {
-        executablePath = getExecutablePath(cmd[0]);
-      } catch (IllegalArgumentException e) {
 
-        StringBuilder join = new StringBuilder();
-        for (String s : cmd) {
-          join.append(s).append(' ');
+    /**
+     * check is allow ambiguous commands
+     *
+     * @param security security manager
+     * @return allow ambiguous command flag
+     */
+    private static boolean isAllowAmbiguousCommands(SecurityManager security) {
+        boolean allowAmbiguousCommands = false;
+        if (security == null) {
+            allowAmbiguousCommands = true;
+            String value = System.getProperty(LOCAL_PROCESS_EXEC);
+            if (value != null) {
+                allowAmbiguousCommands = !Constants.STRING_FALSE.equalsIgnoreCase(value);
+            }
         }
+        return allowAmbiguousCommands;
+    }
 
-        cmd = getTokensFromCommand(join.toString());
-        executablePath = getExecutablePath(cmd[0]);
+    /**
+     * get executable path.
+     *
+     * @param path path
+     * @return executable path
+     */
+    private static String getExecutablePath(String path) {
+        boolean pathIsQuoted = isQuoted(true, path, "Executable name has embedded quote, split the arguments");
+
+        File fileToRun = new File(pathIsQuoted ? path.substring(1, path.length() - 1) : path);
+        return fileToRun.getPath();
+    }
 
-        // Check new executable name once more
-        if (security != null) {
-          security.checkExec(executablePath);
-        }
-      }
+    /**
+     * whether is shell file.
+     *
+     * @param executablePath executable path
+     * @return true if endsWith .CMD or .BAT
+     */
+    private static boolean isShellFile(String executablePath) {
+        String upPath = executablePath.toUpperCase();
+        return (upPath.endsWith(".CMD") || upPath.endsWith(".BAT"));
+    }
 
-      cmdstr = createCommandLine(
+    /**
+     * quote string.
+     *
+     * @param arg argument
+     * @return format arg
+     */
+    private static String quoteString(String arg) {
+        return '"' + arg + '"';
+    }
 
-              isShellFile(executablePath) ? VERIFICATION_CMD_BAT : VERIFICATION_WIN32, quoteString(executablePath), cmd);
+    /**
+     * get tokens from command.
+     *
+     * @param command command
+     * @return token string array
+     */
+    private static String[] getTokensFromCommand(String command) {
+        ArrayList<String> matchList = new ArrayList<>(8);
+        Matcher regexMatcher = LazyPattern.PATTERN.matcher(command);
+        while (regexMatcher.find()) {
+            matchList.add(regexMatcher.group());
+        }
+        return matchList.toArray(new String[0]);
     }
-    return cmdstr;
-  }
-
-  /**
-   * get executable path.
-   *
-   * @param path path
-   * @return executable path
-   */
-  private static String getExecutablePath(String path) {
-    boolean pathIsQuoted = isQuoted(true, path, "Executable name has embedded quote, split the arguments");
-
-    File fileToRun = new File(pathIsQuoted ? path.substring(1, path.length() - 1) : path);
-    return fileToRun.getPath();
-  }
-
-  /**
-   * whether is shell file.
-   *
-   * @param executablePath executable path
-   * @return true if endsWith .CMD or .BAT
-   */
-  private static boolean isShellFile(String executablePath) {
-    String upPath = executablePath.toUpperCase();
-    return (upPath.endsWith(".CMD") || upPath.endsWith(".BAT"));
-  }
-
-  /**
-   * quote string.
-   *
-   * @param arg argument
-   * @return format arg
-   */
-  private static String quoteString(String arg) {
-    StringBuilder argbuf = new StringBuilder(arg.length() + 2);
-    return argbuf.append('"').append(arg).append('"').toString();
-  }
-
-  /**
-   * get tokens from command.
-   *
-   * @param command command
-   * @return token string array
-   */
-  private static String[] getTokensFromCommand(String command) {
-    ArrayList<String> matchList = new ArrayList<>(8);
-    Matcher regexMatcher = LazyPattern.PATTERN.matcher(command);
-    while (regexMatcher.find()) {
-      matchList.add(regexMatcher.group());
+
+    /**
+     * Lazy Pattern.
+     */
+    private static class LazyPattern {
+        /**
+         * Escape-support version:
+         * "(\")((?:\\\\\\1|.)+?)\\1|([^\\s\"]+)";
+         */
+        private static final Pattern PATTERN = Pattern.compile("[^\\s\"]+|\"[^\"]*\"");
     }
-    return matchList.toArray(new String[matchList.size()]);
-  }
-
-  /**
-   * Lazy Pattern.
-   */
-  private static class LazyPattern {
-    // Escape-support version:
-    // "(\")((?:\\\\\\1|.)+?)\\1|([^\\s\"]+)";
-    private static final Pattern PATTERN = Pattern.compile("[^\\s\"]+|\"[^\"]*\"");
-  }
-
-  /**
-   * verification cmd bat.
-   */
-  private static final int VERIFICATION_CMD_BAT = 0;
-
-  /**
-   * verification win32.
-   */
-  private static final int VERIFICATION_WIN32 = 1;
-
-  /**
-   * verification legacy.
-   */
-  private static final int VERIFICATION_LEGACY = 2;
-
-  /**
-   * escape verification.
-   */
-  private static final char[][] ESCAPE_VERIFICATION = {{' ', '\t', '<', '>', '&', '|', '^'},
-
-    {' ', '\t', '<', '>'}, {' ', '\t'}};
-
-  /**
-   * create command line.
-   * @param verificationType  verification type
-   * @param executablePath    executable path
-   * @param cmd               cmd
-   * @return command line
-   */
-  private static String createCommandLine(int verificationType, final String executablePath, final String[] cmd) {
-    StringBuilder cmdbuf = new StringBuilder(80);
-
-    cmdbuf.append(executablePath);
-
-    for (int i = 1; i < cmd.length; ++i) {
-      cmdbuf.append(' ');
-      String s = cmd[i];
-      if (needsEscaping(verificationType, s)) {
-        cmdbuf.append('"').append(s);
-
-        if ((verificationType != VERIFICATION_CMD_BAT) && s.endsWith("\\")) {
-          cmdbuf.append('\\');
+
+    /**
+     * verification cmd bat.
+     */
+    private static final int VERIFICATION_CMD_BAT = 0;
+
+    /**
+     * verification win32.
+     */
+    private static final int VERIFICATION_WIN32 = 1;
+
+    /**
+     * verification legacy.
+     */
+    private static final int VERIFICATION_LEGACY = 2;
+
+    /**
+     * escape verification.
+     */
+    private static final char[][] ESCAPE_VERIFICATION = {{' ', '\t', '<', '>', '&', '|', '^'},
+
+        {' ', '\t', '<', '>'}, {' ', '\t'}};
+
+    /**
+     * create command line.
+     *
+     * @param verificationType verification type
+     * @param executablePath   executable path
+     * @param cmd              cmd
+     * @return command line
+     */
+    private static String createCommandLine(int verificationType, final String executablePath, final String[] cmd) {
+        StringBuilder cmdbuf = new StringBuilder(80);
+
+        cmdbuf.append(executablePath);
+
+        for (int i = 1; i < cmd.length; ++i) {
+            cmdbuf.append(' ');
+            String s = cmd[i];
+            if (needsEscaping(verificationType, s)) {
+                cmdbuf.append('"').append(s);
+
+                if ((verificationType != VERIFICATION_CMD_BAT) && s.endsWith("\\")) {
+                    cmdbuf.append('\\');
+                }
+                cmdbuf.append('"');
+            } else {
+                cmdbuf.append(s);
+            }
         }
-        cmdbuf.append('"');
-      } else {
-        cmdbuf.append(s);
-      }
+        return cmdbuf.toString();
     }
-    return cmdbuf.toString();
-  }
-
-  /**
-   * whether is quoted.
-   * @param noQuotesInside
-   * @param arg
-   * @param errorMessage
-   * @return boolean
-   */
-  private static boolean isQuoted(boolean noQuotesInside, String arg, String errorMessage) {
-    int lastPos = arg.length() - 1;
-    if (lastPos >= 1 && arg.charAt(0) == '"' && arg.charAt(lastPos) == '"') {
-      // The argument has already been quoted.
-      if (noQuotesInside) {
-        if (arg.indexOf('"', 1) != lastPos) {
-          // There is ["] inside.
-          throw new IllegalArgumentException(errorMessage);
+
+    /**
+     * whether is quoted.
+     *
+     * @param noQuotesInside no quotes inside
+     * @param arg            arg
+     * @param errorMessage   error message
+     * @return boolean
+     */
+    private static boolean isQuoted(boolean noQuotesInside, String arg, String errorMessage) {
+        int lastPos = arg.length() - 1;
+        if (lastPos >= 1 && arg.charAt(0) == '"' && arg.charAt(lastPos) == '"') {
+            // The argument has already been quoted.
+            if (noQuotesInside && arg.indexOf('"', 1) != lastPos) {
+                // There is ["] inside.
+                throw new IllegalArgumentException(errorMessage);
+            }
+            return true;
         }
-      }
-      return true;
-    }
-    if (noQuotesInside) {
-      if (arg.indexOf('"') >= 0) {
-        // There is ["] inside.
-        throw new IllegalArgumentException(errorMessage);
-      }
-    }
-    return false;
-  }
-
-  /**
-   * whether needs escaping.
-   *
-   * @param verificationType  verification type
-   * @param arg               arg
-   * @return boolean
-   */
-  private static boolean needsEscaping(int verificationType, String arg) {
-
-    boolean argIsQuoted = isQuoted((verificationType == VERIFICATION_CMD_BAT), arg, "Argument has embedded quote, use the explicit CMD.EXE call.");
-
-    if (!argIsQuoted) {
-      char[] testEscape = ESCAPE_VERIFICATION[verificationType];
-      for (int i = 0; i < testEscape.length; ++i) {
-        if (arg.indexOf(testEscape[i]) >= 0) {
-          return true;
+        if (noQuotesInside && arg.indexOf('"') >= 0) {
+            // There is ["] inside.
+            throw new IllegalArgumentException(errorMessage);
         }
-      }
+        return false;
     }
-    return false;
-  }
-
-  /**
-   * kill yarn application.
-   *
-   * @param appIds      app id list
-   * @param logger      logger
-   * @param tenantCode  tenant code
-   * @param executePath     execute path
-   */
-  public static void cancelApplication(List<String> appIds, Logger logger, String tenantCode, String executePath) {
-    if (appIds.size() > 0) {
-      String appid = appIds.get(appIds.size() - 1);
-      String commandFile = String
-              .format("%s/%s.kill", executePath, appid);
-      String cmd = "yarn application -kill " + appid;
-      try {
-        StringBuilder sb = new StringBuilder();
-        sb.append("#!/bin/sh\n");
-        sb.append("BASEDIR=$(cd `dirname $0`; pwd)\n");
-        sb.append("cd $BASEDIR\n");
-        if (CommonUtils.getSystemEnvPath() != null) {
-          sb.append("source " + CommonUtils.getSystemEnvPath() + "\n");
-        }
-        sb.append("\n\n");
-        sb.append(cmd);
-
-        File f = new File(commandFile);
 
-        if (!f.exists()) {
-          FileUtils.writeStringToFile(new File(commandFile), sb.toString(), StandardCharsets.UTF_8);
+    /**
+     * whether needs escaping.
+     *
+     * @param verificationType verification type
+     * @param arg              arg
+     * @return boolean
+     */
+    private static boolean needsEscaping(int verificationType, String arg) {
+
+        boolean argIsQuoted = isQuoted((verificationType == VERIFICATION_CMD_BAT), arg, "Argument has embedded quote, use the explicit CMD.EXE call.");
+
+        if (!argIsQuoted) {
+            char[] testEscape = ESCAPE_VERIFICATION[verificationType];
+            for (char c : testEscape) {
+                if (arg.indexOf(c) >= 0) {
+                    return true;
+                }
+            }
         }
+        return false;
+    }
 
-        String runCmd = "sh " + commandFile;
-        if (StringUtils.isNotEmpty(tenantCode)) {
-          runCmd = "sudo -u " + tenantCode + " " + runCmd;
+    /**
+     * kill yarn application.
+     *
+     * @param appIds      app id list
+     * @param logger      logger
+     * @param tenantCode  tenant code
+     * @param executePath execute path
+     */
+    public static void cancelApplication(List<String> appIds, Logger logger, String tenantCode, String executePath) {
+        if (CollectionUtils.isNotEmpty(appIds)) {
+
+            for (String appId : appIds) {
+                try {
+                    ExecutionStatus applicationStatus = HadoopUtils.getInstance().getApplicationStatus(appId);
+
+                    if (!applicationStatus.typeIsFinished()) {
+                        String commandFile = String
+                            .format("%s/%s.kill", executePath, appId);
+                        String cmd = "yarn application -kill " + appId;
+                        execYarnKillCommand(logger, tenantCode, appId, commandFile, cmd);
+                    }
+                } catch (Exception e) {
+                    logger.error(String.format("Get yarn application app id [%s] status failed: [%s]", appId, e.getMessage()));
+                }
+            }
         }
+    }
 
-        logger.info("kill cmd:{}", runCmd);
-
-        Runtime.getRuntime().exec(runCmd);
-      } catch (Exception e) {
-        logger.error("kill application error", e);
-      }
+    /**
+     * build kill command for yarn application
+     *
+     * @param logger      logger
+     * @param tenantCode  tenant code
+     * @param appId       app id
+     * @param commandFile command file
+     * @param cmd         cmd
+     */
+    private static void execYarnKillCommand(Logger logger, String tenantCode, String appId, String commandFile, String cmd) {
+        try {
+            StringBuilder sb = new StringBuilder();
+            sb.append("#!/bin/sh\n");
+            sb.append("BASEDIR=$(cd `dirname $0`; pwd)\n");
+            sb.append("cd $BASEDIR\n");
+            if (CommonUtils.getSystemEnvPath() != null) {
+                sb.append("source ").append(CommonUtils.getSystemEnvPath()).append("\n");
+            }
+            sb.append("\n\n");
+            sb.append(cmd);
+
+            File f = new File(commandFile);
+
+            if (!f.exists()) {
+                FileUtils.writeStringToFile(new File(commandFile), sb.toString(), StandardCharsets.UTF_8);
+            }
+
+            String runCmd = String.format("%s %s", Constants.SH, commandFile);
+            if (StringUtils.isNotEmpty(tenantCode)) {
+                runCmd = "sudo -u " + tenantCode + " " + runCmd;
+            }
+
+            logger.info("kill cmd:{}", runCmd);
+            Runtime.getRuntime().exec(runCmd);

Review comment:
       please use OSUtils.exeCmd method instead,thx




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-dolphinscheduler] sonarcloud[bot] removed a comment on pull request #4042: [FIX-3900][server] kill multi yarn app in one job

Posted by GitBox <gi...@apache.org>.
sonarcloud[bot] removed a comment on pull request #4042:
URL: https://github.com/apache/incubator-dolphinscheduler/pull/4042#issuecomment-725829135


   Kudos, SonarCloud Quality Gate passed!
   
   [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/bug.png' alt='Bug' width='16' height='16' />](https://sonarcloud.io/project/issues?id=apache-dolphinscheduler&pullRequest=4042&resolved=false&types=BUG) [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A.png' alt='A' width='16' height='16' />](https://sonarcloud.io/project/issues?id=apache-dolphinscheduler&pullRequest=4042&resolved=false&types=BUG) [0 Bugs](https://sonarcloud.io/project/issues?id=apache-dolphinscheduler&pullRequest=4042&resolved=false&types=BUG)  
   [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/vulnerability.png' alt='Vulnerability' width='16' height='16' />](https://sonarcloud.io/project/issues?id=apache-dolphinscheduler&pullRequest=4042&resolved=false&types=VULNERABILITY) [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A.png' alt='A' width='16' height='16' />](https://sonarcloud.io/project/issues?id=apache-dolphinscheduler&pullRequest=4042&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonarcloud.io/project/issues?id=apache-dolphinscheduler&pullRequest=4042&resolved=false&types=VULNERABILITY) (and [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/security_hotspot.png' alt='Security Hotspot' width='16' height='16' />](https://sonarcloud.io/project/issues?id=apache-dolphinscheduler&pullRequest=4042&resolved=false&types=SECURITY_HOTSPOT) [0 Security Hotspots](https://sonarcloud.io/proje
 ct/issues?id=apache-dolphinscheduler&pullRequest=4042&resolved=false&types=SECURITY_HOTSPOT) to review)  
   [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/code_smell.png' alt='Code Smell' width='16' height='16' />](https://sonarcloud.io/project/issues?id=apache-dolphinscheduler&pullRequest=4042&resolved=false&types=CODE_SMELL) [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A.png' alt='A' width='16' height='16' />](https://sonarcloud.io/project/issues?id=apache-dolphinscheduler&pullRequest=4042&resolved=false&types=CODE_SMELL) [8 Code Smells](https://sonarcloud.io/project/issues?id=apache-dolphinscheduler&pullRequest=4042&resolved=false&types=CODE_SMELL)
   
   [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/CoverageChart/50.png' alt='58.8%' width='16' height='16' />](https://sonarcloud.io/component_measures?id=apache-dolphinscheduler&pullRequest=4042&metric=new_coverage&view=list) [58.8% Coverage](https://sonarcloud.io/component_measures?id=apache-dolphinscheduler&pullRequest=4042&metric=new_coverage&view=list)  
   [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/Duplications/3.png' alt='0.0%' width='16' height='16' />](https://sonarcloud.io/component_measures?id=apache-dolphinscheduler&pullRequest=4042&metric=new_duplicated_lines_density&view=list) [0.0% Duplication](https://sonarcloud.io/component_measures?id=apache-dolphinscheduler&pullRequest=4042&metric=new_duplicated_lines_density&view=list)
   
   


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org