From ef2e9c9b67e03b941ac3e8b6c2a77d4b1d564351 Mon Sep 17 00:00:00 2001 From: Wenjun Ruan Date: Fri, 1 Dec 2023 21:49:28 +0800 Subject: [PATCH] Set the tenant as the owner in final stage (#15256) --- .../exception/FileOperateException.java | 29 +++++++++++ .../common/utils/FileUtils.java | 48 +++++++++++++------ .../BaseLinuxShellInterceptorBuilder.java | 5 +- .../api/shell/IShellInterceptorBuilder.java | 4 +- .../bash/BashShellInterceptorBuilder.java | 3 +- .../shell/sh/ShShellInterceptorBuilder.java | 3 +- .../utils/TaskExecutionCheckerUtils.java | 9 ---- 7 files changed, 74 insertions(+), 27 deletions(-) create mode 100644 dolphinscheduler-common/src/main/java/org/apache/dolphinscheduler/common/exception/FileOperateException.java diff --git a/dolphinscheduler-common/src/main/java/org/apache/dolphinscheduler/common/exception/FileOperateException.java b/dolphinscheduler-common/src/main/java/org/apache/dolphinscheduler/common/exception/FileOperateException.java new file mode 100644 index 0000000000..8099ebea73 --- /dev/null +++ b/dolphinscheduler-common/src/main/java/org/apache/dolphinscheduler/common/exception/FileOperateException.java @@ -0,0 +1,29 @@ +/* + * 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.common.exception; + +public class FileOperateException extends BaseException { + + public FileOperateException(String message) { + super(message); + } + + public FileOperateException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/dolphinscheduler-common/src/main/java/org/apache/dolphinscheduler/common/utils/FileUtils.java b/dolphinscheduler-common/src/main/java/org/apache/dolphinscheduler/common/utils/FileUtils.java index abbfdbfcd3..a995b29dd6 100644 --- a/dolphinscheduler-common/src/main/java/org/apache/dolphinscheduler/common/utils/FileUtils.java +++ b/dolphinscheduler-common/src/main/java/org/apache/dolphinscheduler/common/utils/FileUtils.java @@ -25,6 +25,8 @@ import static org.apache.dolphinscheduler.common.constants.Constants.RESOURCE_VI import static org.apache.dolphinscheduler.common.constants.Constants.UTF_8; import static org.apache.dolphinscheduler.common.constants.DateConstants.YYYYMMDDHHMMSS; +import org.apache.dolphinscheduler.common.exception.FileOperateException; + import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.SystemUtils; @@ -323,23 +325,41 @@ public class FileUtils { return crcString; } - public static void setFileOwner(Path filePath, String fileOwner) throws InterruptedException, IOException { - // We use linux command to set the file owner, since jdk api will not use sudo. - String command = String.format("sudo chown %s %s", fileOwner, filePath.toString()); - Runtime.getRuntime().exec(command); - Process process = Runtime.getRuntime().exec(command); - if (0 != process.waitFor()) { - throw new RuntimeException("Set file: " + filePath + " to owner: " + fileOwner + " failed"); + public static void setFileOwner(Path filePath, String fileOwner) throws FileOperateException { + try { + // We use linux command to set the file owner, since jdk api will not use sudo. + String command = String.format("sudo chown %s %s", fileOwner, filePath.toString()); + Runtime.getRuntime().exec(command); + Process process = Runtime.getRuntime().exec(command); + int exitCode = process.waitFor(); + if (0 != exitCode) { + throw new FileOperateException( + "Set file: " + filePath + " to owner: " + fileOwner + " failed, existCode(" + exitCode + ")"); + } + } catch (FileOperateException ex) { + throw ex; + } catch (Exception ex) { + throw new FileOperateException("Set directory: " + filePath + " to owner: " + fileOwner + " failed"); + } } - public static void setDirectoryOwner(Path filePath, String fileOwner) throws IOException, InterruptedException { - // We use linux command to set the file owner, since jdk api will not use sudo. - String command = String.format("sudo chown -R %s %s", fileOwner, filePath.toString()); - Runtime.getRuntime().exec(command); - Process process = Runtime.getRuntime().exec(command); - if (0 != process.waitFor()) { - throw new RuntimeException("Set directory: " + filePath + " to owner: " + fileOwner + " failed"); + public static void setDirectoryOwner(Path filePath, String fileOwner) throws FileOperateException { + try { + // We use linux command to set the file owner, since jdk api will not use sudo. + String command = String.format("sudo chown -R %s %s", fileOwner, filePath.toString()); + Runtime.getRuntime().exec(command); + Process process = Runtime.getRuntime().exec(command); + int exitCode = process.waitFor(); + if (0 != exitCode) { + throw new FileOperateException("Set directory: " + filePath + " to owner: " + fileOwner + + " failed, existCode(" + exitCode + ")"); + } + } catch (FileOperateException ex) { + throw ex; + } catch (Exception ex) { + throw new FileOperateException("Set directory: " + filePath + " to owner: " + fileOwner + " failed"); + } } diff --git a/dolphinscheduler-task-plugin/dolphinscheduler-task-api/src/main/java/org/apache/dolphinscheduler/plugin/task/api/shell/BaseLinuxShellInterceptorBuilder.java b/dolphinscheduler-task-plugin/dolphinscheduler-task-api/src/main/java/org/apache/dolphinscheduler/plugin/task/api/shell/BaseLinuxShellInterceptorBuilder.java index 5816681e75..3c24977c4a 100644 --- a/dolphinscheduler-task-plugin/dolphinscheduler-task-api/src/main/java/org/apache/dolphinscheduler/plugin/task/api/shell/BaseLinuxShellInterceptorBuilder.java +++ b/dolphinscheduler-task-plugin/dolphinscheduler-task-api/src/main/java/org/apache/dolphinscheduler/plugin/task/api/shell/BaseLinuxShellInterceptorBuilder.java @@ -17,6 +17,7 @@ package org.apache.dolphinscheduler.plugin.task.api.shell; +import org.apache.dolphinscheduler.common.exception.FileOperateException; import org.apache.dolphinscheduler.common.utils.FileUtils; import org.apache.dolphinscheduler.common.utils.PropertyUtils; import org.apache.dolphinscheduler.plugin.task.api.utils.AbstractCommandExecutorConstants; @@ -64,8 +65,10 @@ public abstract class BaseLinuxShellInterceptorBuilder generateBootstrapCommand() { + protected List generateBootstrapCommand() throws FileOperateException { if (sudoEnable) { + // Set the tenant owner as the working directory + FileUtils.setDirectoryOwner(Paths.get(shellDirectory), runUser); return bootstrapCommandInSudoMode(); } return bootstrapCommandInNormalMode(); diff --git a/dolphinscheduler-task-plugin/dolphinscheduler-task-api/src/main/java/org/apache/dolphinscheduler/plugin/task/api/shell/IShellInterceptorBuilder.java b/dolphinscheduler-task-plugin/dolphinscheduler-task-api/src/main/java/org/apache/dolphinscheduler/plugin/task/api/shell/IShellInterceptorBuilder.java index cab50e3bdf..8e6cf5c42f 100644 --- a/dolphinscheduler-task-plugin/dolphinscheduler-task-api/src/main/java/org/apache/dolphinscheduler/plugin/task/api/shell/IShellInterceptorBuilder.java +++ b/dolphinscheduler-task-plugin/dolphinscheduler-task-api/src/main/java/org/apache/dolphinscheduler/plugin/task/api/shell/IShellInterceptorBuilder.java @@ -17,6 +17,8 @@ package org.apache.dolphinscheduler.plugin.task.api.shell; +import org.apache.dolphinscheduler.common.exception.FileOperateException; + import java.io.IOException; import java.util.Map; @@ -48,5 +50,5 @@ public interface IShellInterceptorBuilder bootstrapCommand = generateBootstrapCommand(); return new BashShellInterceptor(bootstrapCommand, shellDirectory); diff --git a/dolphinscheduler-task-plugin/dolphinscheduler-task-api/src/main/java/org/apache/dolphinscheduler/plugin/task/api/shell/sh/ShShellInterceptorBuilder.java b/dolphinscheduler-task-plugin/dolphinscheduler-task-api/src/main/java/org/apache/dolphinscheduler/plugin/task/api/shell/sh/ShShellInterceptorBuilder.java index 8f15b543d0..c74551b6c1 100644 --- a/dolphinscheduler-task-plugin/dolphinscheduler-task-api/src/main/java/org/apache/dolphinscheduler/plugin/task/api/shell/sh/ShShellInterceptorBuilder.java +++ b/dolphinscheduler-task-plugin/dolphinscheduler-task-api/src/main/java/org/apache/dolphinscheduler/plugin/task/api/shell/sh/ShShellInterceptorBuilder.java @@ -17,6 +17,7 @@ package org.apache.dolphinscheduler.plugin.task.api.shell.sh; +import org.apache.dolphinscheduler.common.exception.FileOperateException; import org.apache.dolphinscheduler.plugin.task.api.shell.BaseLinuxShellInterceptorBuilder; import java.io.IOException; @@ -32,7 +33,7 @@ public class ShShellInterceptorBuilder } @Override - public ShShellInterceptor build() throws IOException { + public ShShellInterceptor build() throws IOException, FileOperateException { generateShellScript(); List bootstrapCommand = generateBootstrapCommand(); return new ShShellInterceptor(bootstrapCommand, shellDirectory); diff --git a/dolphinscheduler-worker/src/main/java/org/apache/dolphinscheduler/server/worker/utils/TaskExecutionCheckerUtils.java b/dolphinscheduler-worker/src/main/java/org/apache/dolphinscheduler/server/worker/utils/TaskExecutionCheckerUtils.java index 322e16bc2b..195e4d3a0a 100644 --- a/dolphinscheduler-worker/src/main/java/org/apache/dolphinscheduler/server/worker/utils/TaskExecutionCheckerUtils.java +++ b/dolphinscheduler-worker/src/main/java/org/apache/dolphinscheduler/server/worker/utils/TaskExecutionCheckerUtils.java @@ -92,10 +92,6 @@ public class TaskExecutionCheckerUtils { taskExecutionContext.setAppInfoPath(FileUtils.getAppInfoPath(execLocalPath)); Path executePath = Paths.get(taskExecutionContext.getExecutePath()); FileUtils.createDirectoryIfNotPresent(executePath); - if (OSUtils.isSudoEnable() - && !TenantConstants.DEFAULT_TENANT_CODE.equals(taskExecutionContext.getTenantCode())) { - FileUtils.setDirectoryOwner(executePath, taskExecutionContext.getTenantCode()); - } } catch (Throwable ex) { throw new TaskException("Cannot create process execute dir", ex); } @@ -136,11 +132,6 @@ public class TaskExecutionCheckerUtils { Path localFileAbsolutePath = Paths.get(execLocalPath, fileName); storageOperate.download(actualTenant, fullName, localFileAbsolutePath.toString(), true); log.info("Download resource file {} under: {} successfully", fileName, localFileAbsolutePath); - if (OSUtils.isSudoEnable() && !TenantConstants.DEFAULT_TENANT_CODE.equals(tenant)) { - FileUtils.setFileOwner(localFileAbsolutePath, taskExecutionContext.getTenantCode()); - log.info("Set file {} owner to {} successfully", localFileAbsolutePath, - taskExecutionContext.getTenantCode()); - } WorkerServerMetrics .recordWorkerResourceDownloadTime(System.currentTimeMillis() - resourceDownloadStartTime); WorkerServerMetrics.recordWorkerResourceDownloadSize(Files.size(localFileAbsolutePath));