fix: 调整 playbook 执行日志记录

This commit is contained in:
zhangshuai
2024-10-31 18:07:04 +08:00
parent 97adfa39cd
commit ad63b414bf
4 changed files with 127 additions and 122 deletions

View File

@@ -5,6 +5,7 @@ import com.pty4j.PtyProcessBuilder;
import net.geedge.api.entity.EnvApiYml;
import net.geedge.api.util.AdbCommandBuilder;
import net.geedge.api.util.AdbUtil;
import net.geedge.api.util.CommandExec;
import net.geedge.common.T;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
@@ -40,7 +41,7 @@ public class AdbShellProxyHandler extends TextWebSocketHandler {
super.afterConnectionEstablished(session);
List<String> cmd = AdbCommandBuilder.builder()
.serial(AdbUtil.getInstance(adb).getSerial())
.serial(AdbUtil.getInstance(adb, new CommandExec(null)).getSerial())
.buildShellCommand("shell")
.build();

View File

@@ -7,6 +7,7 @@ import cn.hutool.log.Log;
import jakarta.servlet.http.HttpServletResponse;
import net.geedge.api.entity.EnvApiYml;
import net.geedge.api.util.AdbUtil;
import net.geedge.api.util.CommandExec;
import net.geedge.common.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
@@ -28,9 +29,12 @@ public class APIController {
@Autowired
public APIController(EnvApiYml envApiYml) {
this.adbUtil = AdbUtil.getInstance(envApiYml.getAdb());
this.adbUtil = AdbUtil.getInstance(envApiYml.getAdb(), new CommandExec(null));
}
@Autowired
private EnvApiYml apiYml;
@GetMapping("/status")
public R status() {
return R.ok(adbUtil.status());
@@ -61,7 +65,7 @@ public class APIController {
File tempFile = T.FileUtil.file(Constant.TEMP_PATH, fileName);
try {
AdbUtil.CommandResult result = adbUtil.pull(filePath, tempFile.getAbsolutePath(), false);
AdbUtil.CommandResult result = adbUtil.pull(filePath, tempFile.getAbsolutePath());
if (0 != result.exitCode()) {
throw new APIException(result.output());
}
@@ -104,7 +108,7 @@ public class APIController {
tempFile = T.FileUtil.file(Constant.TEMP_PATH, file.getOriginalFilename());
file.transferTo(tempFile);
AdbUtil.CommandResult result = adbUtil.install(tempFile.getAbsolutePath(), true, true, false);
AdbUtil.CommandResult result = adbUtil.install(tempFile.getAbsolutePath(), true, true);
if (0 != result.exitCode()) {
throw new APIException(result.output());
}
@@ -115,7 +119,7 @@ public class APIController {
}
if (T.StrUtil.isNotEmpty(path)) {
AdbUtil.CommandResult result = adbUtil.install(path, true, true, false);
AdbUtil.CommandResult result = adbUtil.install(path, true, true);
if (0 != result.exitCode()) {
throw new APIException(result.output());
}
@@ -140,7 +144,7 @@ public class APIController {
@PostMapping("/pcap")
public R startTcpdump(@RequestParam(required = false, defaultValue = "") String packageName) {
AdbUtil.CommandResult result = adbUtil.startTcpdump(packageName, false);
AdbUtil.CommandResult result = adbUtil.startTcpdump(packageName);
if (0 != result.exitCode()) {
throw new APIException("exec tcpdump error");
}
@@ -151,7 +155,7 @@ public class APIController {
public synchronized void stopTcpdump(@RequestParam String id,
@RequestParam(required = false, defaultValue = "false") Boolean returnFile,
HttpServletResponse response) throws IOException {
AdbUtil.CommandResult result = adbUtil.stopTcpdump(id, false);
AdbUtil.CommandResult result = adbUtil.stopTcpdump(id);
if (0 != result.exitCode()) {
throw new APIException(result.output());
}
@@ -165,7 +169,7 @@ public class APIController {
if (T.StrUtil.isEmpty(filePath)) {
throw new APIException(RCode.NOT_EXISTS);
}
AdbUtil.CommandResult pulled = adbUtil.pull(filePath, tempFile.getAbsolutePath(), false);
AdbUtil.CommandResult pulled = adbUtil.pull(filePath, tempFile.getAbsolutePath());
if (0 != pulled.exitCode()) {
throw new APIException(pulled.output());
}
@@ -180,7 +184,7 @@ public class APIController {
} finally {
if (T.StrUtil.isNotEmpty(filePath)) {
// remove pcap file
adbUtil.execShellCommand(String.format("shell rm -rf %s", filePath), false);
adbUtil.execShellCommand(String.format("shell rm -rf %s", filePath));
}
}
}
@@ -302,7 +306,7 @@ public class APIController {
} finally {
T.FileUtil.del(destination);
}
PlaybookRunnable playbookRunnable = new PlaybookRunnable(adbUtil, apkFile, playbookAirDir, id, packageName);
PlaybookRunnable playbookRunnable = new PlaybookRunnable(apiYml, apkFile, playbookAirDir, id, packageName);
ThreadUtil.execAsync(playbookRunnable);
return R.ok();
}
@@ -349,7 +353,7 @@ public class APIController {
}
// job dir
File jobResult = T.FileUtil.file(Constant.TEMP_PATH, id);
File zipFile = T.FileUtil.file(Constant.TEMP_PATH, T.StrUtil.concat(true, id, ".zip"));
File zipFile = T.FileUtil.file(Constant.TEMP_PATH, id, T.StrUtil.concat(true, id, ".zip"));
File[] files = jobResult.listFiles(new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
@@ -364,13 +368,14 @@ public class APIController {
public class PlaybookRunnable extends Thread {
private AdbUtil adbUtil;
private EnvApiYml envApiYml;
private String tid;
private File apkFile;
private String packageName;
private File playbookDir;
public PlaybookRunnable(AdbUtil adbUtil, File apkFile, File playbookDir, String tid, String packageName) {
this.adbUtil = adbUtil;
public PlaybookRunnable(EnvApiYml envApiYml, File apkFile, File playbookDir, String tid, String packageName) {
this.envApiYml = envApiYml;
this.tid = tid;
this.apkFile = apkFile;
this.packageName = packageName;
@@ -382,42 +387,40 @@ public class APIController {
File logFile = FileUtil.file(Constant.TEMP_PATH, tid, "result.log");
try {
adbUtil.setLogFile(logFile);
T.FileUtil.appendString(String.format("Running with %s:%s Android Simulator \n", envApiYml.getAdb().getHost(), envApiYml.getAdb().getPort()), logFile, "UTF-8");
adbUtil = new AdbUtil(envApiYml.getAdb(), new CommandExec(logFile));
Map resultMap = T.MapUtil.builder()
.put("status", "running")
.build();
Constant.PLAYBOOK_RUN_RESULT.put(tid, resultMap);
T.FileUtil.appendString(String.format("Running with %s Android Simulator \n", adbUtil.getSerial()), logFile, "UTF-8");
// 1. install apk
AdbUtil.CommandResult install = adbUtil.install(apkFile.getAbsolutePath(), true, true, true);
AdbUtil.CommandResult install = adbUtil.install(apkFile.getAbsolutePath(), true, true);
if (0 != install.exitCode()) {
T.FileUtil.appendString(String.format("ERROR: Install apk failed: exit code %s \n", install.exitCode()), logFile, "UTF-8");
throw new APIException(install.output());
}
// 2. star tcpdump
AdbUtil.CommandResult startTcpdump = adbUtil.startTcpdump(packageName, true);
AdbUtil.CommandResult startTcpdump = adbUtil.startTcpdump(packageName);
if (0 != startTcpdump.exitCode()) {
T.FileUtil.appendString(String.format("ERROR: Start tcpdump failed: exit code %s \n", startTcpdump.exitCode()), logFile, "UTF-8");
throw new APIException("exec tcpdump error");
}
// 3. exec playbook
AdbUtil.CommandResult execResult = adbUtil.execPlaybook(playbookDir.getPath(), true);
AdbUtil.CommandResult execResult = adbUtil.execPlaybook(playbookDir.getPath(), logFile);
if (0 != execResult.exitCode()) {
// exec playbook error, stop tcpdump and delete pcap
T.FileUtil.appendString(String.format("ERROR: Exec playbook failed: exit code %s \n", execResult.exitCode()), logFile, "UTF-8");
AdbUtil.CommandResult stopTcpdump = adbUtil.stopTcpdump(startTcpdump.output(), true);
adbUtil.execShellCommand(String.format("shell rm -rf %s", stopTcpdump.output()), true);
AdbUtil.CommandResult stopTcpdump = adbUtil.stopTcpdump(startTcpdump.output());
adbUtil.execShellCommand(String.format("shell rm -rf %s", stopTcpdump.output()));
throw new APIException("exec playbook error");
}
// 4. stop tcpdump
AdbUtil.CommandResult stopTcpdump = adbUtil.stopTcpdump(startTcpdump.output(), true);
T.FileUtil.appendString(T.StrUtil.concat(true, stopTcpdump.output(), "\n"), logFile, "UTF-8");
AdbUtil.CommandResult stopTcpdump = adbUtil.stopTcpdump(startTcpdump.output());
if (0 != stopTcpdump.exitCode()) {
T.FileUtil.appendString(String.format("ERROR: Stop tcpdump failed: exit code %s \n", stopTcpdump.exitCode()), logFile, "UTF-8");
throw new APIException(stopTcpdump.output());
@@ -430,15 +433,14 @@ public class APIController {
throw new APIException(RCode.NOT_EXISTS);
}
AdbUtil.CommandResult pull = adbUtil.pull(filePath, localPcapFile.getAbsolutePath(), true);
T.FileUtil.appendString(T.StrUtil.concat(true, pull.output(), "\n"), logFile, "UTF-8");
AdbUtil.CommandResult pull = adbUtil.pull(filePath, localPcapFile.getAbsolutePath());
if (0 != pull.exitCode()) {
T.FileUtil.appendString(String.format("ERROR: Pull pcap file failed: exit code %s \n", pull.exitCode()), logFile, "UTF-8");
throw new APIException(pull.output());
}
// 6. delete android pcap
adbUtil.execShellCommand(String.format("shell rm -rf %s", filePath), true);
adbUtil.execShellCommand(String.format("shell rm -rf %s", filePath));
resultMap = T.MapUtil.builder()
.put("status", "done")
@@ -451,7 +453,7 @@ public class APIController {
.build();
Constant.PLAYBOOK_RUN_RESULT.put(tid, resultMap);
} finally {
adbUtil.stopApp(packageName, true);
adbUtil.stopApp(packageName);
T.FileUtil.appendString(String.format("Job succeeded"), logFile, "UTF-8");
}
}

View File

@@ -32,14 +32,11 @@ public class AdbUtil {
private Integer port;
private Integer vncPort;
private File logFile;
private CommandExec commandExec;
private ExecutorService threadPool;
public void setLogFile(File logFile) {
this.logFile = logFile;
}
public String getSerial() {
return T.StrUtil.isNotEmpty(this.serial) ? serial : String.format("%s:%s", this.host, this.port);
@@ -48,11 +45,12 @@ public class AdbUtil {
public record CommandResult(Integer exitCode, String output) {
}
private AdbUtil(EnvApiYml.Adb adb) {
public AdbUtil(EnvApiYml.Adb adb, CommandExec commandExec) {
this.serial = T.StrUtil.emptyToDefault(adb.getSerial(), "");
this.host = adb.getHost();
this.port = adb.getPort();
this.vncPort = adb.getVncPort();
this.commandExec = commandExec;
// adb connect
if (!this.connect()) {
log.error("[connect error, program exit]");
@@ -69,11 +67,11 @@ public class AdbUtil {
return instance;
}
public static AdbUtil getInstance(EnvApiYml.Adb connInfo) {
public static AdbUtil getInstance(EnvApiYml.Adb connInfo, CommandExec commandExec) {
if (instance == null) {
synchronized (AdbUtil.class) {
if (instance == null) {
instance = new AdbUtil(connInfo);
instance = new AdbUtil(connInfo, commandExec);
}
}
}
@@ -93,7 +91,7 @@ public class AdbUtil {
}
} else {
// remote
String result = new CommandExec(logFile ,false).exec(AdbCommandBuilder.builder()
String result = commandExec.exec(AdbCommandBuilder.builder()
.buildConnectCommand(this.host, this.port)
.build());
log.info("[connect] [result: {}]", result);
@@ -111,7 +109,7 @@ public class AdbUtil {
*/
public void init(boolean install) {
// adb root
String result = new CommandExec(logFile ,false).exec(AdbCommandBuilder.builder()
String result = commandExec.exec(AdbCommandBuilder.builder()
.serial(this.getSerial())
.buildRootCommand()
.build()
@@ -120,26 +118,26 @@ public class AdbUtil {
if (install) {
// install droidVNC NG
CommandResult installed = this.install(DEFAULT_DROIDVNC_NG_APK_PATH, true, true,false);
CommandResult installed = this.install(DEFAULT_DROIDVNC_NG_APK_PATH, true, true);
log.info("[init] [install droidVNC NG] [result: {}]", installed);
// 上传默认配置
this.execShellCommand("shell mkdir -p /storage/emulated/0/Android/data/net.christianbeier.droidvnc_ng/files",false);
this.execShellCommand("shell mkdir -p /storage/emulated/0/Android/data/net.christianbeier.droidvnc_ng/files");
this.push(DEFAULT_DROIDVNC_NG_DEFAULTS_JSON_PATH, "/storage/emulated/0/Android/data/net.christianbeier.droidvnc_ng/files/defaults.json");
// 无障碍权限
this.execShellCommand("shell settings put secure enabled_accessibility_services net.christianbeier.droidvnc_ng/.InputService:$(settings get secure enabled_accessibility_services)",false);
this.execShellCommand("shell settings put secure enabled_accessibility_services net.christianbeier.droidvnc_ng/.InputService:$(settings get secure enabled_accessibility_services)");
// 存储空间权限
this.execShellCommand("shell pm grant net.christianbeier.droidvnc_ng android.permission.WRITE_EXTERNAL_STORAGE",false);
this.execShellCommand("shell pm grant net.christianbeier.droidvnc_ng android.permission.WRITE_EXTERNAL_STORAGE");
// 屏幕录制权限
this.execShellCommand("shell appops set net.christianbeier.droidvnc_ng PROJECT_MEDIA allow",false);
this.execShellCommand("shell appops set net.christianbeier.droidvnc_ng PROJECT_MEDIA allow");
// ACTION_STOP
this.execShellCommand("shell am start-foreground-service -n net.christianbeier.droidvnc_ng/.MainService -a net.christianbeier.droidvnc_ng.ACTION_STOP --es net.christianbeier.droidvnc_ng.EXTRA_ACCESS_KEY d042e2b5d5f348588a4e1a243eb7a9a0",false);
this.execShellCommand("shell am start-foreground-service -n net.christianbeier.droidvnc_ng/.MainService -a net.christianbeier.droidvnc_ng.ACTION_STOP --es net.christianbeier.droidvnc_ng.EXTRA_ACCESS_KEY d042e2b5d5f348588a4e1a243eb7a9a0");
}
// ACTION_START
this.execShellCommand("shell am start-foreground-service -n net.christianbeier.droidvnc_ng/.MainService -a net.christianbeier.droidvnc_ng.ACTION_START --es net.christianbeier.droidvnc_ng.EXTRA_ACCESS_KEY d042e2b5d5f348588a4e1a243eb7a9a0",false);
this.execShellCommand("shell am start-foreground-service -n net.christianbeier.droidvnc_ng/.MainService -a net.christianbeier.droidvnc_ng.ACTION_START --es net.christianbeier.droidvnc_ng.EXTRA_ACCESS_KEY d042e2b5d5f348588a4e1a243eb7a9a0");
// 添加自定义链
this.addAswOutputChain();
@@ -179,7 +177,7 @@ public class AdbUtil {
m.put("type", type);
// check root
String checkRootResult = new CommandExec(logFile, false).exec(AdbCommandBuilder.builder()
String checkRootResult = commandExec.exec(AdbCommandBuilder.builder()
.serial(this.getSerial())
.buildCheckRootCommand()
.build()
@@ -195,7 +193,7 @@ public class AdbUtil {
* @return
*/
private AdbDevice getAdbDevice() {
String result = new CommandExec(logFile, false).exec(AdbCommandBuilder.builder()
String result = commandExec.exec(AdbCommandBuilder.builder()
.buildDevicesCommand()
.build()
);
@@ -220,7 +218,7 @@ public class AdbUtil {
* @return
*/
private Map<String, String> getProp() {
String result = new CommandExec(logFile, false).exec(AdbCommandBuilder.builder()
String result = commandExec.exec(AdbCommandBuilder.builder()
.serial(this.getSerial())
.buildGetpropCommand()
.build()
@@ -237,7 +235,7 @@ public class AdbUtil {
}
// 分辨率 Physical size: 1440x3040
String wmSize = new CommandExec(logFile, false).exec(AdbCommandBuilder.builder()
String wmSize = commandExec.exec(AdbCommandBuilder.builder()
.serial(this.getSerial())
.buildWmSizeCommand()
.build()
@@ -251,7 +249,7 @@ public class AdbUtil {
* md5sum
*/
private CommandResult md5sum(String path) {
String result = new CommandExec(logFile, false).exec(AdbCommandBuilder.builder()
String result = commandExec.exec(AdbCommandBuilder.builder()
.serial(this.getSerial())
.buildMd5sumCommand(path)
.build()
@@ -269,7 +267,7 @@ public class AdbUtil {
* 0 success; !0 failed
*/
public CommandResult push(String local, String remote) {
String result = new CommandExec(logFile, false).exec(AdbCommandBuilder.builder()
String result = commandExec.exec(AdbCommandBuilder.builder()
.serial(this.getSerial())
.buildPushCommand(local, remote)
.build()
@@ -282,8 +280,8 @@ public class AdbUtil {
* pull
* 0 success; !0 failed
*/
public CommandResult pull(String remote, String local, boolean isRecordLog) {
String result = new CommandExec(logFile, isRecordLog).exec(AdbCommandBuilder.builder()
public CommandResult pull(String remote, String local) {
String result = commandExec.exec(AdbCommandBuilder.builder()
.serial(this.getSerial())
.buildPullCommand(remote, local)
.build()
@@ -298,7 +296,7 @@ public class AdbUtil {
* stat filename
*/
public List<Map> listDir(String path) {
String result = new CommandExec(logFile, false).exec(AdbCommandBuilder.builder()
String result = commandExec.exec(AdbCommandBuilder.builder()
.serial(this.getSerial())
.buildLsDirCommand(path)
.build()
@@ -336,7 +334,7 @@ public class AdbUtil {
String statCommand = "shell stat -c \"'%N %A %g %u %s %a %X %Y'\" " + statFilePath;
futureList.add(
CompletableFuture.supplyAsync(() -> {
String statResult = new CommandExec(logFile, false).exec(AdbCommandBuilder.builder()
String statResult = commandExec.exec(AdbCommandBuilder.builder()
.serial(this.getSerial())
.buildShellCommand(statCommand.replaceAll("\\\\", "/"))
.build()
@@ -397,7 +395,7 @@ public class AdbUtil {
* @return
*/
public List<Map> listApp(String arg) {
String result = new CommandExec(logFile, false).exec(AdbCommandBuilder.builder()
String result = commandExec.exec(AdbCommandBuilder.builder()
.serial(this.getSerial())
.buildPmListPackagesCommand(arg)
.build()
@@ -413,7 +411,7 @@ public class AdbUtil {
String packageName = T.StrUtil.trim(line.substring(prefix.length()));
if (T.StrUtil.equals(DEFAULT_DROIDVNC_NG_PKG_NAME, packageName)) continue;
String dumpsysResult = new CommandExec(logFile, false).exec(AdbCommandBuilder.builder()
String dumpsysResult = commandExec.exec(AdbCommandBuilder.builder()
.serial(this.getSerial())
.buildShellCommand("shell dumpsys package " + packageName)
.build()
@@ -437,7 +435,7 @@ public class AdbUtil {
String md5Value = md5sumRes.output();
File localApk = T.FileUtil.file(Constant.TEMP_PATH, md5Value + ".apk");
if (!T.FileUtil.exist(localApk)) {
CommandResult pulled = this.pull(finalApkPath, localApk.getAbsolutePath(), false);
CommandResult pulled = this.pull(finalApkPath, localApk.getAbsolutePath());
if (0 != pulled.exitCode()) {
log.warn("[listApp] [pull apk error] [pkg: {}]", packageName);
return null;
@@ -494,8 +492,8 @@ public class AdbUtil {
* install app
* adb install apk
*/
public CommandResult install(String localFilePath, boolean isDebugApk, boolean isReInstall, boolean isRecordLog) {
String result = new CommandExec(logFile, isRecordLog).exec(AdbCommandBuilder.builder()
public CommandResult install(String localFilePath, boolean isDebugApk, boolean isReInstall) {
String result = commandExec.exec(AdbCommandBuilder.builder()
.serial(this.getSerial())
.buildInstallCommand(localFilePath, isDebugApk, isReInstall)
.build());
@@ -509,7 +507,7 @@ public class AdbUtil {
* adb uninstall package_name
*/
public CommandResult uninstall(String packageName) {
String result = new CommandExec(logFile, false).exec(AdbCommandBuilder.builder()
String result = commandExec.exec(AdbCommandBuilder.builder()
.serial(this.getSerial())
.buildUnInstallCommand(packageName)
.build()
@@ -522,8 +520,8 @@ public class AdbUtil {
* stop app
* adb shell am force-stop package_name
*/
public CommandResult stopApp(String packageName, boolean isRecordLog) {
String result = new CommandExec(logFile, isRecordLog).exec(AdbCommandBuilder.builder()
public CommandResult stopApp(String packageName) {
String result = commandExec.exec(AdbCommandBuilder.builder()
.serial(this.getSerial())
.buildStopAppCommand(packageName)
.build()
@@ -539,13 +537,13 @@ public class AdbUtil {
@Deprecated
private void cleanIptables() {
// Delete all rules in chain or all chains
new CommandExec(logFile, false).exec(AdbCommandBuilder.builder()
commandExec.exec(AdbCommandBuilder.builder()
.serial(this.getSerial())
.buildShellCommand("shell iptables -F")
.build()
);
// Delete user-defined chain
new CommandExec(logFile, false).exec(AdbCommandBuilder.builder()
commandExec.exec(AdbCommandBuilder.builder()
.serial(this.getSerial())
.buildShellCommand("shell iptables -X")
.build()
@@ -556,7 +554,7 @@ public class AdbUtil {
* list tcpdump
*/
public List<Map> listTcpdump() {
String result = new CommandExec(logFile, false).exec(AdbCommandBuilder.builder()
String result = commandExec.exec(AdbCommandBuilder.builder()
.serial(this.getSerial())
.buildShellCommand(String.format("shell \"ps -ef | grep tcpdump | grep -v grep | grep capture_ | awk '{print $NF}' \""))
.build());
@@ -591,11 +589,11 @@ public class AdbUtil {
* start Tcpdump
* tcpdump pcap
*/
public CommandResult startTcpdump(String packageName, boolean isRecordLog) {
public CommandResult startTcpdump(String packageName) {
String taskId = T.IdUtil.fastSimpleUUID();
if (T.StrUtil.isNotEmpty(packageName)) {
log.info("[startTcpdump] [capture app package] [pkg: {}]", packageName);
String dumpsysResult = new CommandExec(logFile, isRecordLog).exec(AdbCommandBuilder.builder()
String dumpsysResult = commandExec.exec(AdbCommandBuilder.builder()
.serial(this.getSerial())
.buildShellCommand("shell dumpsys package " + packageName)
.build()
@@ -607,20 +605,20 @@ public class AdbUtil {
.map(s -> T.StrUtil.trim(s).replaceAll("userId=", ""))
.orElseThrow(() -> new APIException("Not found userId by package name. package name: " + packageName));
new CommandExec(logFile, isRecordLog).exec(AdbCommandBuilder.builder()
commandExec.exec(AdbCommandBuilder.builder()
.serial(this.getSerial())
.buildShellCommand(String.format("shell iptables -A OUTPUT -m owner --uid-owner %s -j CONNMARK --set-mark %s", userId, userId))
.build());
new CommandExec(logFile, isRecordLog).exec(AdbCommandBuilder.builder()
commandExec.exec(AdbCommandBuilder.builder()
.serial(this.getSerial())
.buildShellCommand(String.format("shell iptables -A INPUT -m connmark --mark %s -j NFLOG --nflog-group %s", userId, userId))
.build());
new CommandExec(logFile, isRecordLog).exec(AdbCommandBuilder.builder()
commandExec.exec(AdbCommandBuilder.builder()
.serial(this.getSerial())
.buildShellCommand(String.format("shell iptables -A OUTPUT -m connmark --mark %s -j NFLOG --nflog-group %s", userId, userId))
.build());
String ruleList = new CommandExec(logFile, isRecordLog).exec(AdbCommandBuilder.builder()
String ruleList = commandExec.exec(AdbCommandBuilder.builder()
.serial(this.getSerial())
.buildShellCommand("shell iptables -L")
.build());
@@ -628,7 +626,7 @@ public class AdbUtil {
// pcap 格式capture_{userId}_{pcakageName}_{taskId}.pcap
String pcapFilePath = "/data/local/tmp/capture_" + userId + "_" + packageName + "_" + taskId + ".pcap";
new CommandExec(logFile, isRecordLog).execForProcess(AdbCommandBuilder.builder()
commandExec.execForProcess(AdbCommandBuilder.builder()
.serial(this.getSerial())
.buildShellCommand(String.format("shell tcpdump -i nflog:%s -w %s &", userId, pcapFilePath))
.build());
@@ -636,13 +634,13 @@ public class AdbUtil {
log.info("[startTcpdump] [capture all package]");
// pcap 格式capture_all_{taskId}.pcap
String pcapFilePath = "/data/local/tmp/capture_all_" + taskId + ".pcap";
new CommandExec(logFile, isRecordLog).execForProcess(AdbCommandBuilder.builder()
commandExec.execForProcess(AdbCommandBuilder.builder()
.serial(this.getSerial())
.buildShellCommand(String.format("shell tcpdump not port %s -w %s &", this.vncPort, pcapFilePath))
.build());
}
String result = new CommandExec(logFile, isRecordLog).exec(AdbCommandBuilder.builder()
String result = commandExec.exec(AdbCommandBuilder.builder()
.serial(this.getSerial())
.buildShellCommand(String.format("shell \"ps -ef | grep tcpdump | grep -v grep | grep %s | awk '{print $2}' \"", taskId))
.build());
@@ -654,8 +652,8 @@ public class AdbUtil {
* stop tcpdump
* kill -INT {pid}
*/
public CommandResult stopTcpdump(String id, boolean isRecordLog) {
String pcapFilePath = new CommandExec(logFile, isRecordLog).exec(AdbCommandBuilder.builder()
public CommandResult stopTcpdump(String id) {
String pcapFilePath = commandExec.exec(AdbCommandBuilder.builder()
.serial(this.getSerial())
.buildShellCommand(String.format("shell \"ps -ef | grep tcpdump | grep -v grep | grep %s | awk '{print $NF}' \"", id))
.build());
@@ -665,21 +663,21 @@ public class AdbUtil {
String[] split = T.FileUtil.mainName(pcapFilePath).split("_");
String userId = split[1];
log.info("[stopTcpdump] [remove iptables rule] [userId: {}]", userId);
new CommandExec(logFile, isRecordLog).exec(AdbCommandBuilder.builder()
commandExec.exec(AdbCommandBuilder.builder()
.serial(this.getSerial())
.buildShellCommand(String.format("shell iptables -D OUTPUT -m owner --uid-owner %s -j CONNMARK --set-mark %s", userId, userId))
.build());
new CommandExec(logFile, isRecordLog).exec(AdbCommandBuilder.builder()
commandExec.exec(AdbCommandBuilder.builder()
.serial(this.getSerial())
.buildShellCommand(String.format("shell iptables -D INPUT -m connmark --mark %s -j NFLOG --nflog-group %s", userId, userId))
.build());
new CommandExec(logFile, isRecordLog).exec(AdbCommandBuilder.builder()
commandExec.exec(AdbCommandBuilder.builder()
.serial(this.getSerial())
.buildShellCommand(String.format("shell iptables -D OUTPUT -m connmark --mark %s -j NFLOG --nflog-group %s", userId, userId))
.build());
}
}
String result = new CommandExec(logFile, isRecordLog).exec(AdbCommandBuilder.builder()
String result = commandExec.exec(AdbCommandBuilder.builder()
.serial(this.getSerial())
.buildShellCommand(String.format("shell \"ps -ef | grep tcpdump | grep -v grep | grep %s | awk '{print $2}' | xargs kill -INT \"", id))
.build());
@@ -688,7 +686,7 @@ public class AdbUtil {
for (int i = 0; i < 10; i++) {
T.ThreadUtil.sleep(500);
String str = new CommandExec(logFile, isRecordLog).exec(AdbCommandBuilder.builder()
String str = commandExec.exec(AdbCommandBuilder.builder()
.serial(this.getSerial())
.buildShellCommand(String.format("shell \"ps -ef | grep tcpdump | grep -v grep | grep %s \"", id))
.build());
@@ -708,8 +706,8 @@ public class AdbUtil {
/**
* exec shell command
*/
public void execShellCommand(String shellCmd, boolean isRecordLog) {
String result = new CommandExec(logFile, isRecordLog).exec(AdbCommandBuilder.builder()
public void execShellCommand(String shellCmd) {
String result = commandExec.exec(AdbCommandBuilder.builder()
.serial(this.getSerial())
.buildShellCommand(shellCmd)
.build());
@@ -720,7 +718,7 @@ public class AdbUtil {
* exec shell command
*/
public String execShellCommand(String cmd, Integer timeout){
Process process = new CommandExec(logFile, false).execForProcess(AdbCommandBuilder.builder()
Process process = commandExec.execForProcess(AdbCommandBuilder.builder()
.serial(this.getSerial())
.buildShellCommand("shell " + cmd)
.build());
@@ -746,16 +744,16 @@ public class AdbUtil {
*/
private void addAswOutputChain() {
// name=ASW_OUTPUT
this.execShellCommand("shell iptables -N ASW_OUTPUT", false);
this.execShellCommand("shell iptables -N ASW_OUTPUT");
String outputChainResult = new CommandExec(logFile, false).exec(AdbCommandBuilder.builder()
String outputChainResult = commandExec.exec(AdbCommandBuilder.builder()
.serial(this.getSerial())
.buildShellCommand(String.format("shell \"iptables -L OUTPUT --line-numbers | grep ASW_OUTPUT\""))
.build());
log.info("[addAswOutputChain] [ASW_OUTPUT in OUTPUT Chain] [result: {}]", outputChainResult);
if (T.StrUtil.isEmpty(outputChainResult)) {
// ASW_OUTPUT 添加到 OUTPUT 链中
this.execShellCommand("shell iptables -A OUTPUT -j ASW_OUTPUT", false);
this.execShellCommand("shell iptables -A OUTPUT -j ASW_OUTPUT");
}
}
@@ -764,7 +762,7 @@ public class AdbUtil {
* iptables -nL ASW_OUTPUT --line-numbers
*/
public List<Map> listAcl() {
String result = new CommandExec(logFile, false).exec(AdbCommandBuilder.builder()
String result = commandExec.exec(AdbCommandBuilder.builder()
.serial(this.getSerial())
.buildIptablesLnRulesCommand("ASW_OUTPUT")
.build());
@@ -811,7 +809,7 @@ public class AdbUtil {
this.addAswOutputChain();
// add chain ruls
String result = new CommandExec(logFile, false).exec(AdbCommandBuilder.builder()
String result = commandExec.exec(AdbCommandBuilder.builder()
.serial(this.getSerial())
.buildIptablesAddRuleCommand("ASW_OUTPUT", protocol, ip, port)
.build());
@@ -825,7 +823,7 @@ public class AdbUtil {
*/
public void deleteAcl(String protocol, String ip, String port) {
// add chain ruls
String result = new CommandExec(logFile, false).exec(AdbCommandBuilder.builder()
String result = commandExec.exec(AdbCommandBuilder.builder()
.serial(this.getSerial())
.buildIptablesDelRuleCommand("ASW_OUTPUT", protocol, ip, port)
.build());
@@ -837,7 +835,7 @@ public class AdbUtil {
* iptables -F ASW_OUTPUT
*/
public CommandResult flushAcl() {
String result = new CommandExec(logFile, false).exec(AdbCommandBuilder.builder()
String result = commandExec.exec(AdbCommandBuilder.builder()
.serial(this.getSerial())
.buildIptablesFlushRuleCommand("ASW_OUTPUT")
.build());
@@ -859,47 +857,21 @@ public class AdbUtil {
}
class CommandExec {
private File logFile;
private boolean isRecordLog;
public String exec(List<String> command) {
String str = T.RuntimeUtil.execForStr(T.CharsetUtil.CHARSET_UTF_8, command.stream().toArray(String[]::new));
if (isRecordLog) {
T.FileUtil.appendString(T.StrUtil.concat(true, "$ ", command.stream().collect(Collectors.joining(" ")), "\n"), this.logFile, "UTF-8");
T.FileUtil.appendString(T.StrUtil.concat(true, str.stripTrailing(), "\n"), this.logFile, "UTF-8");
}
return str.stripTrailing();
}
public Process execForProcess(List<String> command) {
Process process = T.RuntimeUtil.exec(command.stream().toArray(String[]::new));
return process;
}
public CommandExec(File logFile, boolean isRecordLog) {
this.logFile = logFile;
this.isRecordLog = isRecordLog;
}
}
public CommandResult execPlaybook(String playbookPath, boolean isRecordLog) {
public CommandResult execPlaybook(String playbookPath, File logFile) {
log.info("[execPlaybook] [begin!] [serial:{}]", this.getSerial());
List<String> command = new AdbCommandBuilder("airtest")
.buildRunPlaybook(playbookPath, this.getSerial())
.build();
Process process = new CommandExec(logFile, isRecordLog).execForProcess(command);
Process process = commandExec.execForProcess(command);
ExecutorService executor = Executors.newSingleThreadExecutor();
Future<String> future = executor.submit(() -> T.IoUtil.read(process.getInputStream(), T.CharsetUtil.CHARSET_UTF_8));
try {
int exitCode = process.waitFor();
String result = future.get(10, TimeUnit.SECONDS);
if (isRecordLog){
T.FileUtil.appendString(T.StrUtil.concat(true, "$ ", command.stream().collect(Collectors.joining(" ")), "\n"), this.logFile, "UTF-8");
T.FileUtil.appendString(T.StrUtil.concat(true, result.stripTrailing(), "\n"), this.logFile, "UTF-8");
}
T.FileUtil.appendString(T.StrUtil.concat(true, "$ ", command.stream().collect(Collectors.joining(" ")), "\n"), logFile, "UTF-8");
T.FileUtil.appendString(T.StrUtil.concat(true, result.stripTrailing(), "\n"), logFile, "UTF-8");
return new CommandResult(exitCode, result);
} catch (Exception e) {
process.destroyForcibly();

View File

@@ -0,0 +1,30 @@
package net.geedge.api.util;
import net.geedge.common.T;
import java.io.File;
import java.util.List;
import java.util.stream.Collectors;
public class CommandExec {
private File logFile;
public String exec(List<String> command) {
String str = T.RuntimeUtil.execForStr(T.CharsetUtil.CHARSET_UTF_8, command.stream().toArray(String[]::new));
if (logFile != null) {
T.FileUtil.appendString(T.StrUtil.concat(true, "$ ", command.stream().collect(Collectors.joining(" ")), "\n"), this.logFile, "UTF-8");
T.FileUtil.appendString(T.StrUtil.concat(true, str.stripTrailing(), "\n"), this.logFile, "UTF-8");
}
return str.stripTrailing();
}
public Process execForProcess(List<String> command) {
Process process = T.RuntimeUtil.exec(command.stream().toArray(String[]::new));
return process;
}
public CommandExec(File logFile ) {
this.logFile = logFile;
}
}