[agent] [ executor ] - execute shell file
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
package io.wdd.agent.config.message.handler;
|
||||
|
||||
import io.wdd.agent.excuetor.shell.CommandExecutor;
|
||||
import io.wdd.agent.excuetor.shell.FunctionExecutor;
|
||||
import io.wdd.agent.executor.shell.CommandExecutor;
|
||||
import io.wdd.agent.executor.shell.FunctionExecutor;
|
||||
import io.wdd.common.beans.executor.ExecutionMessage;
|
||||
import io.wdd.common.beans.rabbitmq.OctopusMessage;
|
||||
import io.wdd.common.beans.rabbitmq.OctopusMessageType;
|
||||
@@ -9,7 +9,7 @@ import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
import static io.wdd.agent.excuetor.function.CollectAllFunctionToServer.ALL_FUNCTIONS;
|
||||
import static io.wdd.agent.executor.function.CollectAllFunctionToServer.ALL_FUNCTIONS;
|
||||
|
||||
@Component
|
||||
public class OMHandlerExecutor extends AbstractOctopusMessageHandler {
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
package io.wdd.agent.excuetor.function;
|
||||
|
||||
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
@Component
|
||||
@Lazy
|
||||
public class CollectAllFunctionToServer {
|
||||
|
||||
|
||||
public static Set<String> ALL_FUNCTIONS = new HashSet<>(128);
|
||||
|
||||
/**
|
||||
* store the Octopus Agent Functions and Reflection Class Path
|
||||
* key: function name
|
||||
* value: function class relative path
|
||||
*
|
||||
*/
|
||||
public static HashMap<String, String> FUNCTION_REFLECTION = new HashMap<>(128);
|
||||
|
||||
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
package io.wdd.agent.excuetor.function;
|
||||
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Component
|
||||
@Lazy
|
||||
@Slf4j
|
||||
public class TestFunction {
|
||||
|
||||
public void execute(String streamKey) {
|
||||
|
||||
|
||||
this.getClass().getName()
|
||||
|
||||
|
||||
ProcessBuilder processBuilder = new ProcessBuilder();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
|
||||
|
||||
wget -O
|
||||
@@ -1,34 +0,0 @@
|
||||
package io.wdd.agent.excuetor.shell;
|
||||
|
||||
import io.wdd.common.beans.executor.ExecutionMessage;
|
||||
import io.wdd.common.handler.MyRuntimeException;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import static io.wdd.agent.excuetor.function.CollectAllFunctionToServer.FUNCTION_REFLECTION;
|
||||
|
||||
@Service
|
||||
@Slf4j
|
||||
public class FunctionExecutor {
|
||||
|
||||
public void execute(ExecutionMessage executionMessage) {
|
||||
|
||||
String resultKey = executionMessage.getResultKey();
|
||||
|
||||
String functionClassPath = FUNCTION_REFLECTION.get(executionMessage.getContend());
|
||||
|
||||
Method execute = null;
|
||||
|
||||
try {
|
||||
execute = Class.forName(functionClassPath).getMethod("execute", String.class);
|
||||
ReflectionUtils.invokeMethod(execute, functionClassPath, resultKey);
|
||||
|
||||
} catch (NoSuchMethodException | ClassNotFoundException e) {
|
||||
throw new MyRuntimeException(" Function Executor Reflection Error ! {} + {}", e.getCause(), e.getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
package io.wdd.agent.executor.config;
|
||||
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Component
|
||||
public class FunctionReader {
|
||||
|
||||
|
||||
public List<List<String>> ReadFileToCommandList(String functionFilePath) {
|
||||
|
||||
// https://www.digitalocean.com/community/tutorials/java-read-file-line-by-line
|
||||
|
||||
List<List<String>> result = null;
|
||||
|
||||
try {
|
||||
|
||||
BufferedReader bufferedReader = new BufferedReader(new FileReader(functionFilePath));
|
||||
String line = bufferedReader.readLine();
|
||||
|
||||
if (line != null) {
|
||||
result = new ArrayList<>(64);
|
||||
}
|
||||
|
||||
while (line != null) {
|
||||
if (!StringUtils.isEmpty(line)) {
|
||||
result.add(this.SplitLineToCommandList(line));
|
||||
}
|
||||
line = bufferedReader.readLine();
|
||||
}
|
||||
|
||||
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
public List<String> SplitLineToCommandList(String commandLine) {
|
||||
|
||||
return Arrays.stream(commandLine.split(" ")).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
package io.wdd.agent.executor.config;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.URISyntaxException;
|
||||
|
||||
public class GetClassPath {
|
||||
|
||||
public static final File getFileForClass(Class<?> clazz) {
|
||||
File file;
|
||||
|
||||
try {
|
||||
file = new File(clazz.getProtectionDomain().getCodeSource().getLocation().toURI().getPath());
|
||||
|
||||
} catch (URISyntaxException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
return file;
|
||||
}
|
||||
|
||||
public static final String getBasePathForClass(Class<?> clazz) {
|
||||
File file;
|
||||
try {
|
||||
String basePath = null;
|
||||
file = new File(clazz.getProtectionDomain().getCodeSource().getLocation().toURI().getPath());
|
||||
|
||||
|
||||
if (file.isFile() || file.getPath().endsWith(".jar") || file.getPath().endsWith(".zip")) {
|
||||
basePath = file.getParent();
|
||||
} else {
|
||||
basePath = file.getPath();
|
||||
}
|
||||
|
||||
// fix to run inside eclipse
|
||||
if (basePath.endsWith(File.separator + "lib") || basePath.endsWith(File.separator + "bin")
|
||||
|| basePath.endsWith("bin" + File.separator) || basePath.endsWith("lib" + File.separator)) {
|
||||
basePath = basePath.substring(0, basePath.length() - 4);
|
||||
}
|
||||
// fix to run inside netbean
|
||||
if (basePath.endsWith(File.separator + "build" + File.separator + "classes")) {
|
||||
basePath = basePath.substring(0, basePath.length() - 14);
|
||||
}
|
||||
// end fix
|
||||
if (!basePath.endsWith(File.separator)) {
|
||||
basePath = basePath + File.separator;
|
||||
}
|
||||
return basePath;
|
||||
} catch (URISyntaxException e) {
|
||||
throw new RuntimeException("Cannot firgue out base path for class: " + clazz.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package io.wdd.agent.excuetor.config;
|
||||
package io.wdd.agent.executor.config;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
@@ -0,0 +1,63 @@
|
||||
package io.wdd.agent.executor.function;
|
||||
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.apache.commons.io.filefilter.DirectoryFileFilter;
|
||||
import org.apache.commons.io.filefilter.FileFilterUtils;
|
||||
import org.apache.commons.io.filefilter.IOFileFilter;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import java.io.File;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Component
|
||||
@Lazy
|
||||
@Slf4j
|
||||
public class CollectAllFunctionToServer {
|
||||
|
||||
|
||||
public static Set<String> ALL_FUNCTIONS = new HashSet<>(128);
|
||||
|
||||
/**
|
||||
* store the Octopus Agent Functions and Reflection Class Path
|
||||
* key: function name
|
||||
* value: function shell script relative path
|
||||
*
|
||||
*/
|
||||
public static HashMap<String, String> FUNCTION_REFLECTION = new HashMap<>(128);
|
||||
|
||||
|
||||
@PostConstruct
|
||||
private void CollectAllFunctionShellScriptName(){
|
||||
|
||||
// scan current package files name and store them to FUNCTION_REFLECTION
|
||||
|
||||
|
||||
Path absolutePath = Paths.get("").toAbsolutePath();
|
||||
|
||||
Path currentDirectory = Path.of(absolutePath + "/src/main/java/io/wdd/agent/executor/function").toAbsolutePath();
|
||||
|
||||
|
||||
IOFileFilter fileFilter = FileFilterUtils.suffixFileFilter(".sh");
|
||||
IOFileFilter directoryFileFilter = DirectoryFileFilter.INSTANCE;
|
||||
|
||||
Collection<File> functionFileList = FileUtils.listFiles(currentDirectory.toFile(), fileFilter, directoryFileFilter);
|
||||
|
||||
log.debug("all function shell script files are : {}", functionFileList);
|
||||
|
||||
Map<String, String> collect = functionFileList.stream().collect(Collectors.toMap(
|
||||
functionFile -> functionFile.getName().split("\\.")[0],
|
||||
functionFile -> functionFile.getAbsolutePath()
|
||||
));
|
||||
|
||||
FUNCTION_REFLECTION.putAll(collect);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
|
||||
|
||||
wget https://raw.githubusercontent.com/zeaslity/ProjectOctopus/main/source/src/main/java/io/wdd/source/shell/test.sh -O /host/root/test.sh
|
||||
|
||||
chmod +x /host/root/test.sh
|
||||
|
||||
/host/root/test.sh
|
||||
@@ -1,4 +1,4 @@
|
||||
package io.wdd.agent.excuetor.redis;
|
||||
package io.wdd.agent.executor.redis;
|
||||
|
||||
|
||||
import io.wdd.agent.config.beans.executor.CommandLog;
|
||||
@@ -1,9 +1,9 @@
|
||||
package io.wdd.agent.excuetor.shell;
|
||||
package io.wdd.agent.executor.shell;
|
||||
|
||||
import com.google.common.io.ByteStreams;
|
||||
import io.wdd.agent.excuetor.redis.StreamSender;
|
||||
import io.wdd.agent.excuetor.thread.DaemonLogThread;
|
||||
import io.wdd.agent.excuetor.thread.LogToStreamSender;
|
||||
import io.wdd.agent.executor.redis.StreamSender;
|
||||
import io.wdd.agent.executor.thread.DaemonLogThread;
|
||||
import io.wdd.agent.executor.thread.LogToStreamSender;
|
||||
import io.wdd.common.beans.executor.ExecutionMessage;
|
||||
import io.wdd.common.handler.MyRuntimeException;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@@ -15,8 +15,6 @@ import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
|
||||
@Configuration
|
||||
@@ -54,7 +52,7 @@ public class CommandExecutor {
|
||||
}
|
||||
|
||||
|
||||
private void processExecute(String streamKey, ProcessBuilder processBuilder){
|
||||
public void processExecute(String streamKey, ProcessBuilder processBuilder){
|
||||
|
||||
processBuilder.redirectErrorStream(true);
|
||||
processBuilder.inheritIO();
|
||||
@@ -75,8 +73,7 @@ public class CommandExecutor {
|
||||
|
||||
|
||||
} catch (IOException | InterruptedException e) {
|
||||
|
||||
throw new MyRuntimeException("{} + {}", e.getCause(), e.getMessage());
|
||||
log.error("Shell command error ! {} + {}", e.getCause(), e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
package io.wdd.agent.executor.shell;
|
||||
|
||||
import io.wdd.agent.executor.config.FunctionReader;
|
||||
import io.wdd.common.beans.executor.ExecutionMessage;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static io.wdd.agent.executor.function.CollectAllFunctionToServer.FUNCTION_REFLECTION;
|
||||
|
||||
@Service
|
||||
@Slf4j
|
||||
public class FunctionExecutor {
|
||||
|
||||
@Resource
|
||||
FunctionReader functionReader;
|
||||
|
||||
@Resource
|
||||
CommandExecutor commandExecutor;
|
||||
|
||||
public void execute(ExecutionMessage executionMessage) {
|
||||
|
||||
String resultKey = executionMessage.getResultKey();
|
||||
|
||||
String functionShellScriptFileName = FUNCTION_REFLECTION.get(executionMessage.getType());
|
||||
|
||||
this.execute(resultKey, functionShellScriptFileName);
|
||||
|
||||
/*Method execute = null;
|
||||
|
||||
try {
|
||||
execute = Class.forName(functionShellScriptFileName).getMethod("execute", String.class);
|
||||
ReflectionUtils.invokeMethod(execute, functionShellScriptFileName, resultKey);
|
||||
|
||||
} catch (NoSuchMethodException | ClassNotFoundException e) {
|
||||
throw new MyRuntimeException(" Function Executor Reflection Error ! {} + {}", e.getCause(), e.getMessage());
|
||||
}*/
|
||||
|
||||
}
|
||||
|
||||
|
||||
private void execute(String streamKey, String functionFileName) {
|
||||
|
||||
List<List<String>> commandList = functionReader.ReadFileToCommandList(functionFileName);
|
||||
|
||||
log.info("all commands are {}", commandList);
|
||||
|
||||
commandList.stream().map(
|
||||
command -> {
|
||||
commandExecutor.execute(streamKey, command);
|
||||
return 1;
|
||||
}
|
||||
).collect(Collectors.toList());
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package io.wdd.agent.excuetor.thread;
|
||||
package io.wdd.agent.executor.thread;
|
||||
|
||||
import com.google.common.util.concurrent.ThreadFactoryBuilder;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package io.wdd.agent.excuetor.thread;
|
||||
package io.wdd.agent.executor.thread;
|
||||
|
||||
|
||||
import java.io.BufferedReader;
|
||||
@@ -1,4 +1,4 @@
|
||||
package io.wdd.agent.excuetor.thread;
|
||||
package io.wdd.agent.executor.thread;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.InputStream;
|
||||
@@ -1,14 +1,13 @@
|
||||
package io.wdd.agent.excuetor.web;
|
||||
package io.wdd.agent.executor.web;
|
||||
|
||||
|
||||
import io.wdd.agent.excuetor.shell.CommandExecutor;
|
||||
import io.wdd.agent.executor.shell.CommandExecutor;
|
||||
import io.wdd.common.beans.response.R;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
|
||||
4
agent/src/main/resources/application-k3s.yaml
Normal file
4
agent/src/main/resources/application-k3s.yaml
Normal file
@@ -0,0 +1,4 @@
|
||||
|
||||
|
||||
|
||||
|
||||
16
agent/src/main/resources/application-local.yaml
Normal file
16
agent/src/main/resources/application-local.yaml
Normal file
@@ -0,0 +1,16 @@
|
||||
spring:
|
||||
cloud:
|
||||
nacos:
|
||||
config:
|
||||
group: local
|
||||
config-retry-time: 3000
|
||||
file-extension: yaml
|
||||
max-retry: 3
|
||||
# server-addr: 43.154.83.213:21060
|
||||
# server-addr: 140.238.52.228:21060
|
||||
server-addr: https://nacos.107421.xyz:443
|
||||
timeout: 5000
|
||||
config-long-poll-timeout: 5000
|
||||
extension-configs:
|
||||
- group: local
|
||||
data-id: common-local.yaml
|
||||
@@ -2,20 +2,21 @@ spring:
|
||||
application:
|
||||
name: octopus-agent
|
||||
profiles:
|
||||
active: local
|
||||
active: k3s
|
||||
cloud:
|
||||
nacos:
|
||||
config:
|
||||
group: local
|
||||
group: k3s
|
||||
config-retry-time: 3000
|
||||
file-extension: yaml
|
||||
max-retry: 3
|
||||
# server-addr: 43.154.83.213:21060
|
||||
# server-addr: 140.238.52.228:21060
|
||||
# server-addr: 43.154.83.213:21060
|
||||
# server-addr: 140.238.52.228:21060
|
||||
server-addr: https://nacos.107421.xyz:443
|
||||
timeout: 5000
|
||||
config-long-poll-timeout: 5000
|
||||
extension-configs:
|
||||
- group: local
|
||||
data-id: common-local.yaml
|
||||
- group: k3s
|
||||
data-id: common-k3s.yaml
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user