[agent] [ executor ] - execute shell file

This commit is contained in:
IceDerce
2022-12-11 21:51:41 +08:00
parent 2f5bb078cd
commit 889976f9e2
25 changed files with 404 additions and 136 deletions

View File

@@ -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 {

View File

@@ -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);
}

View File

@@ -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();
}
}

View File

@@ -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());
}
}
}

View File

@@ -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());
}
}

View File

@@ -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());
}
}
}

View File

@@ -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;

View File

@@ -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);
}
}

View File

@@ -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

View File

@@ -1,4 +1,4 @@
package io.wdd.agent.excuetor.redis;
package io.wdd.agent.executor.redis;
import io.wdd.agent.config.beans.executor.CommandLog;

View File

@@ -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());
}
}

View File

@@ -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());
}
}

View File

@@ -1,4 +1,4 @@
package io.wdd.agent.excuetor.thread;
package io.wdd.agent.executor.thread;
import com.google.common.util.concurrent.ThreadFactoryBuilder;

View File

@@ -1,4 +1,4 @@
package io.wdd.agent.excuetor.thread;
package io.wdd.agent.executor.thread;
import java.io.BufferedReader;

View File

@@ -1,4 +1,4 @@
package io.wdd.agent.excuetor.thread;
package io.wdd.agent.executor.thread;
import java.io.BufferedReader;
import java.io.InputStream;

View File

@@ -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;

View File

@@ -0,0 +1,4 @@

View 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

View File

@@ -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

View File

@@ -1,14 +1,47 @@
package io.wdd.agent;
import io.micrometer.core.instrument.FunctionCounter;
import io.wdd.agent.executor.function.CollectAllFunctionToServer;
import io.wdd.agent.executor.shell.FunctionExecutor;
import io.wdd.common.beans.executor.ExecutionMessage;
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.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import java.net.InetAddress;
import java.util.Properties;
import javax.annotation.Resource;
import java.io.File;
import java.nio.file.FileSystems;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Collection;
import java.util.Map;
import java.util.stream.Collectors;
@SpringBootTest
@Slf4j
class AgentApplicationTests {
@Resource
FunctionExecutor functionExecutor;
@Resource
CollectAllFunctionToServer collectAllFunctionToServer;
@Test
void testFileExecute(){
ExecutionMessage executionMessage = ExecutionMessage.builder().type("TestFunction").resultKey("simpleFor-test").contend("123456").build();
functionExecutor.execute(executionMessage);
}
@Test
void contextLoads() {
@@ -19,22 +52,69 @@ class AgentApplicationTests {
try{
Properties props =System.getProperties();
InetAddress ip = InetAddress.getLocalHost();
String localName = ip.getHostName();
String osName = System.getProperty("os.name");
String userName = System.getProperty("user.name");
String osVersion = System.getProperty("os.version");
String osArch = System.getProperty("os.arch");
System.out.println("当前用户:" + userName);
System.out.println("用户的主目录:"+props.getProperty("user.home"));
System.out.println("用户的当前工作目录:"+props.getProperty("user.dir"));
System.out.println("主机名称:" + localName);
System.out.println("主机系统:" + osName);
System.out.println("系统版本:" + osVersion);
System.out.println("系统架构:" + osArch);
Path absolutePath = Paths.get("").toAbsolutePath();
System.out.println("absolutePath = " + absolutePath);
Path toAbsolutePath = Path.of(absolutePath + "/src/test/java/io/wdd/agent").toAbsolutePath();
System.out.println("toAbsolutePath = " + toAbsolutePath);
Path path = FileSystems.getDefault().getPath("");
System.out.println("path.toAbsolutePath() = " + path.toAbsolutePath());
IOFileFilter fileFilter = FileFilterUtils.suffixFileFilter(".sh");
IOFileFilter directoryFileFilter = DirectoryFileFilter.INSTANCE;
Collection<File> functionFileList = FileUtils.listFiles(toAbsolutePath.toFile(), fileFilter, directoryFileFilter);
log.info("all function shell script files are : {}", functionFileList);
long count = functionFileList.stream().map(
file -> {
System.out.println("file.getName() = " + file.getName());
return null;
}
).count();
Map<String, String> collect = functionFileList.stream().collect(Collectors.toMap(
functionFile -> functionFile.getName().split(".")[1],
functionFile -> {
return functionFile.getAbsolutePath();
}
));
log.info("map is {}", collect);
System.out.println("count = " + count);
System.out.println("this.getClass().getName() = " + this.getClass().getName());
System.out.println("this.getClass().getCanonicalName() = " + this.getClass().getCanonicalName());
System.out.println("this.getClass().getPackageName() = " + this.getClass().getPackageName());
// Properties props =System.getProperties();
//
// InetAddress ip = InetAddress.getLocalHost();
// String localName = ip.getHostName();
// String osName = System.getProperty("os.name");
// String userName = System.getProperty("user.name");
// String osVersion = System.getProperty("os.version");
// String osArch = System.getProperty("os.arch");
//
// System.out.println("当前用户:" + userName);
// System.out.println("用户的主目录:"+props.getProperty("user.home"));
// System.out.println("用户的当前工作目录:"+props.getProperty("user.dir"));
// System.out.println("主机名称:" + localName);
// System.out.println("主机系统:" + osName);
// System.out.println("系统版本:" + osVersion);
// System.out.println("系统架构:" + osArch);
} catch (Exception e) {
e.printStackTrace();
}

View File

@@ -1,12 +1,8 @@
package io.wdd.agent;
import io.wdd.agent.excuetor.shell.CommandExecutor;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import io.wdd.agent.executor.shell.CommandExecutor;
import javax.annotation.Resource;
import java.io.IOException;
import java.util.concurrent.ExecutionException;
//@SpringBootTest
public class InitRabbitMQTest {

View File

@@ -0,0 +1,26 @@
package io.wdd.agent;
import java.util.Arrays;
import java.util.stream.Collectors;
public class SimpleTest {
public static void main(String[] args) {
String test = "test.sh";
int lastIndexOf = test.lastIndexOf(".");
String substring = test.substring(0, lastIndexOf);
System.out.println("substring = " + substring);
Arrays.stream(test.split("\\.")).map(
st -> {
System.out.println("st = " + st);
return 1;
}
).collect(Collectors.toList());
}
}

View File