Hua Jiang
3 years ago
committed by
GitHub
2 changed files with 61 additions and 221 deletions
@ -1,205 +0,0 @@ |
|||||||
/* |
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
|
||||||
* contributor license agreements. See the NOTICE file distributed with |
|
||||||
* this work for additional information regarding copyright ownership. |
|
||||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
|
||||||
* (the "License"); you may not use this file except in compliance with |
|
||||||
* the License. You may obtain a copy of the License at |
|
||||||
* |
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
* |
|
||||||
* Unless required by applicable law or agreed to in writing, software |
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS, |
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
||||||
* See the License for the specific language governing permissions and |
|
||||||
* limitations under the License. |
|
||||||
*/ |
|
||||||
|
|
||||||
package org.apache.dolphinscheduler.plugin.task.python; |
|
||||||
|
|
||||||
import java.util.Arrays; |
|
||||||
import org.apache.dolphinscheduler.plugin.task.api.AbstractCommandExecutor; |
|
||||||
import org.apache.dolphinscheduler.spi.task.request.TaskRequest; |
|
||||||
import org.apache.dolphinscheduler.spi.utils.StringUtils; |
|
||||||
|
|
||||||
import org.apache.commons.io.FileUtils; |
|
||||||
|
|
||||||
import java.io.BufferedReader; |
|
||||||
import java.io.File; |
|
||||||
import java.io.FileInputStream; |
|
||||||
import java.io.IOException; |
|
||||||
import java.io.InputStreamReader; |
|
||||||
import java.nio.charset.StandardCharsets; |
|
||||||
import java.nio.file.Files; |
|
||||||
import java.nio.file.Paths; |
|
||||||
import java.util.concurrent.LinkedBlockingQueue; |
|
||||||
import java.util.function.Consumer; |
|
||||||
import java.util.regex.Pattern; |
|
||||||
|
|
||||||
import org.slf4j.Logger; |
|
||||||
import org.slf4j.LoggerFactory; |
|
||||||
|
|
||||||
/** |
|
||||||
* python command executor |
|
||||||
*/ |
|
||||||
public class PythonCommandExecutor extends AbstractCommandExecutor { |
|
||||||
|
|
||||||
/** |
|
||||||
* logger |
|
||||||
*/ |
|
||||||
private static final Logger logger = LoggerFactory.getLogger(PythonCommandExecutor.class); |
|
||||||
|
|
||||||
/** |
|
||||||
* python |
|
||||||
*/ |
|
||||||
public static final String PYTHON = "python"; |
|
||||||
|
|
||||||
private static final Pattern PYTHON_PATH_PATTERN = Pattern.compile("/bin/python[\\d.]*$"); |
|
||||||
|
|
||||||
/** |
|
||||||
* constructor |
|
||||||
* |
|
||||||
* @param logHandler log handler |
|
||||||
* @param taskRequest TaskRequest |
|
||||||
* @param logger logger |
|
||||||
*/ |
|
||||||
public PythonCommandExecutor(Consumer<LinkedBlockingQueue<String>> logHandler, |
|
||||||
TaskRequest taskRequest, |
|
||||||
Logger logger) { |
|
||||||
super(logHandler, taskRequest, logger); |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
/** |
|
||||||
* build command file path |
|
||||||
* |
|
||||||
* @return command file path |
|
||||||
*/ |
|
||||||
@Override |
|
||||||
protected String buildCommandFilePath() { |
|
||||||
return String.format("%s/py_%s.command", taskRequest.getExecutePath(), taskRequest.getTaskAppId()); |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* create command file if not exists |
|
||||||
* |
|
||||||
* @param execCommand exec command |
|
||||||
* @param commandFile command file |
|
||||||
* @throws IOException io exception |
|
||||||
*/ |
|
||||||
@Override |
|
||||||
protected void createCommandFileIfNotExists(String execCommand, String commandFile) throws IOException { |
|
||||||
logger.info("tenantCode :{}, task dir:{}", taskRequest.getTenantCode(), taskRequest.getExecutePath()); |
|
||||||
|
|
||||||
if (!Files.exists(Paths.get(commandFile))) { |
|
||||||
logger.info("generate command file:{}", commandFile); |
|
||||||
|
|
||||||
StringBuilder sb = new StringBuilder(); |
|
||||||
sb.append("#-*- encoding=utf8 -*-\n"); |
|
||||||
|
|
||||||
sb.append("\n\n"); |
|
||||||
sb.append(execCommand); |
|
||||||
logger.info(sb.toString()); |
|
||||||
|
|
||||||
// write data to file
|
|
||||||
FileUtils.writeStringToFile(new File(commandFile), |
|
||||||
sb.toString(), |
|
||||||
StandardCharsets.UTF_8); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* get the absolute path of the Python command |
|
||||||
* note : |
|
||||||
* common.properties |
|
||||||
* PYTHON_HOME configured under common.properties is Python absolute path, not PYTHON_HOME itself |
|
||||||
* <p> |
|
||||||
* for example : |
|
||||||
* your PYTHON_HOM is /opt/python3.7/ |
|
||||||
* you must set PYTHON_HOME is /opt/python3.7/python under nder common.properties |
|
||||||
* dolphinscheduler.env.path file. |
|
||||||
* |
|
||||||
* @param envPath env path |
|
||||||
* @return python home |
|
||||||
*/ |
|
||||||
private static String getPythonHome(String envPath) { |
|
||||||
// BufferedReader br = null;
|
|
||||||
StringBuilder sb = new StringBuilder(); |
|
||||||
try (BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(envPath)));) { |
|
||||||
String line; |
|
||||||
while ((line = br.readLine()) != null) { |
|
||||||
if (line.contains(PythonConstants.PYTHON_HOME)) { |
|
||||||
sb.append(line); |
|
||||||
break; |
|
||||||
} |
|
||||||
} |
|
||||||
String result = sb.toString(); |
|
||||||
if (StringUtils.isEmpty(result)) { |
|
||||||
return null; |
|
||||||
} |
|
||||||
String[] arrs = result.split(PythonConstants.EQUAL_SIGN); |
|
||||||
if (arrs.length == 2) { |
|
||||||
return arrs[1]; |
|
||||||
} |
|
||||||
} catch (IOException e) { |
|
||||||
logger.error("read file failure", e); |
|
||||||
} |
|
||||||
return null; |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Gets the command path to which Python can execute |
|
||||||
* @return python command path |
|
||||||
*/ |
|
||||||
@Override |
|
||||||
protected String commandInterpreter() { |
|
||||||
String pythonHome = getPythonHome(taskRequest.getEnvFile()); |
|
||||||
|
|
||||||
if (StringUtils.isNotBlank(taskRequest.getEnvironmentConfig())) { |
|
||||||
pythonHome = getPythonHomeFromEnvironmentConfig(taskRequest.getEnvironmentConfig()); |
|
||||||
} |
|
||||||
|
|
||||||
return getPythonCommand(pythonHome); |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* get python command |
|
||||||
* |
|
||||||
* @param pythonHome python home |
|
||||||
* @return python command |
|
||||||
*/ |
|
||||||
public static String getPythonCommand(String pythonHome) { |
|
||||||
if (StringUtils.isEmpty(pythonHome)) { |
|
||||||
return PYTHON; |
|
||||||
} |
|
||||||
File file = new File(pythonHome); |
|
||||||
if (file.exists() && file.isFile()) { |
|
||||||
return pythonHome; |
|
||||||
} |
|
||||||
if (PYTHON_PATH_PATTERN.matcher(pythonHome).find()) { |
|
||||||
return pythonHome; |
|
||||||
} |
|
||||||
return Paths.get(pythonHome, "/bin/python").toString(); |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* get python home from the environment config |
|
||||||
* |
|
||||||
* @param environmentConfig env config |
|
||||||
* @return python home |
|
||||||
*/ |
|
||||||
public static String getPythonHomeFromEnvironmentConfig(String environmentConfig) { |
|
||||||
String[] lines = environmentConfig.split("\n"); |
|
||||||
|
|
||||||
String pythonHomeConfig = Arrays.stream(lines).filter(line -> line.contains(PythonConstants.PYTHON_HOME)).findFirst().get(); |
|
||||||
|
|
||||||
if (StringUtils.isEmpty(pythonHomeConfig)) { |
|
||||||
return null; |
|
||||||
} |
|
||||||
String[] arrs = pythonHomeConfig.split(PythonConstants.EQUAL_SIGN); |
|
||||||
if (arrs.length == 2) { |
|
||||||
return arrs[1]; |
|
||||||
} |
|
||||||
return null; |
|
||||||
} |
|
||||||
} |
|
Loading…
Reference in new issue