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