master
王兵 1 month ago
commit db8b40733b

20
.gitignore vendored

@ -0,0 +1,20 @@
target/
pom.xml.tag
pom.xml.releaseBackup
pom.xml.versionsBackup
pom.xml.next
release.properties
/.idea
*.iml
/.settings
/bin
/gen
/build
/gradle
/classes
.classpath
.project
*.gradle
gradlew
local.properties
node_modules/

@ -0,0 +1,45 @@
#### 使用方法
```java
<build>
<!-- 项目名称 -->
<finalName>${artifactId}</finalName>
<!-- 默认的主代码目录 -->
<sourceDirectory>src/main/java</sourceDirectory>
<!-- 默认的测试代码目录 -->
<testSourceDirectory>src/test/java</testSourceDirectory>
<plugins>
<!-- 一键部署 -->
<plugin>
<groupId>xyz.wbsite</groupId>
<artifactId>deployee-maven-plugin</artifactId>
<version>latest</version>
<configuration>
<targetPath>${build.directory}</targetPath>
<targetFile>${build.finalName}.${project.packaging}</targetFile>
<servers>
<!-- 服务部署信息 -->
<server>
<!-- 服务名称 -->
<name>something</name>
<!-- 服务器远程地址 -->
<ip>10.0.0.1</ip>
<!-- 服务器远程端口 -->
<port>22</port>
<!-- 服务器登录账户 -->
<username>root</username>
<!-- 服务器登录密码 -->
<password>***</password>
<!-- 部署环境 对应spring.profiles.active-->
<deployActive>test</deployActive>
<!-- 部署路径 -->
<deployPath>/www</deployPath>
<!-- 部署端口 -->
<deployPort>8080</deployPort>
</server>
</servers>
</configuration>
</plugin>
</plugins>
</build>
```

@ -0,0 +1,129 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>xyz.wbsite</groupId>
<artifactId>deployee-maven-plugin</artifactId>
<version>2.0.4-SNAPSHOT</version>
<packaging>maven-plugin</packaging>
<description>deployee</description>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<maven.test.skip>true</maven.test.skip>
</properties>
<repositories>
<!-- 将中央仓库地址指向阿里云聚合仓库,提高下载速度 -->
<repository>
<id>aliyun</id>
<name>Aliyun Repository</name>
<layout>default</layout>
<url>https://maven.aliyun.com/repository/public</url>
</repository>
</repositories>
<pluginRepositories>
<!-- 将插件的仓库指向阿里云聚合仓库解决低版本maven下载插件异常或提高下载速度 -->
<pluginRepository>
<id>aliyun</id>
<name>Aliyun Repository</name>
<url>https://maven.aliyun.com/repository/public</url>
<layout>default</layout>
</pluginRepository>
</pluginRepositories>
<!-- 部署配置 -->
<distributionManagement>
<snapshotRepository>
<id>repository</id>
<name>snapshots</name>
<url>http://*.*.*.*:8081/repository/maven-snapshots/</url>
</snapshotRepository>
<repository>
<id>repository</id>
<name>releases</name>
<url>http://*.*.*.*:8081/repository/maven-releases/</url>
</repository>
</distributionManagement>
<dependencies>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-plugin-api</artifactId>
<version>3.6.3</version>
</dependency>
<dependency>
<groupId>org.apache.maven.plugin-tools</groupId>
<artifactId>maven-plugin-annotations</artifactId>
<version>3.5.2</version>
</dependency>
<!-- 执行ssh命令插件 -->
<dependency>
<groupId>ch.ethz.ganymed</groupId>
<artifactId>ganymed-ssh2</artifactId>
<version>262</version>
</dependency>
<dependency>
<groupId>com.jcraft</groupId>
<artifactId>jsch</artifactId>
<version>0.1.54</version>
</dependency>
<!-- 糊涂工具核心,包含常用工具类,避免重复造轮子 -->
<!-- 部分工具依赖第三方包 -->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.0.M3</version>
</dependency>
</dependencies>
<build>
<!-- 项目名称 -->
<finalName>${artifactId}</finalName>
<!-- 默认的主代码目录 -->
<sourceDirectory>src/main/java</sourceDirectory>
<resources>
<resource>
<directory>src/main/resources</directory>
</resource>
</resources>
<plugins>
<plugin>
<artifactId>maven-plugin-plugin</artifactId>
<version>3.6.0</version>
<executions>
<execution>
<id>default-addPluginArtifactMetadata</id>
<phase>package</phase>
<goals>
<goal>addPluginArtifactMetadata</goal>
</goals>
</execution>
<execution>
<id>default-descriptor</id>
<phase>process-classes</phase>
<goals>
<goal>descriptor</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>

@ -0,0 +1,259 @@
package xyz.wbsite.deployee;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.io.resource.ResourceUtil;
import cn.hutool.core.util.StrUtil;
import xyz.wbsite.deployee.config.Server;
import xyz.wbsite.deployee.util.IOUtil;
import xyz.wbsite.deployee.util.NetUtil;
import xyz.wbsite.deployee.util.TaskUtil;
import xyz.wbsite.deployee.util.ssh.JSshClient;
import xyz.wbsite.deployee.util.ssh.SshSimpleProgress;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.Callable;
import java.util.concurrent.TimeUnit;
/**
* @goal deploy
* @execute phase="package"
*/
public class Deploy extends AbstractMojo {
/**
* @parameter defaultValue="${build.directory}"
*/
private String targetPath;
/**
* @parameter defaultValue="${build.finalName}.${packaging}"
*/
private String targetFile;
/**
* @parameter
*/
private Server[] servers;
public void execute() throws MojoExecutionException {
printLog("------------------------------------------------------------------------");
printLog("TargetPath {} ", targetPath);
printLog("TargetFile {} ", targetFile);
if (servers == null || servers.length == 0) {
throw new MojoExecutionException("Server information not configured");
}
for (Server server : servers) {
printLog("Server[{}:{}] start deploying", server.getIp(), server.getDeployPort());
File target = new File(targetPath, targetFile);
if (!target.exists()) {
throw new MojoExecutionException("FileNotFoundException: " + target.getAbsolutePath());
}
JSshClient client = new JSshClient(server.getIp(), Convert.toInt(server.getPort()), server.getUsername(), server.getPassword());
if (client.isLogin()) {
printLog("server[{}] login success.", server.getIp());
} else {
throw new MojoExecutionException(StrUtil.format("server[{}] login failed.", server.getIp()));
}
// 检测环境是否安装
printLog("test environment");
String serverPath = server.getDeployPath() + "/" + server.getName();
printLog(serverPath);
if (!client.exist(serverPath)) {
try {
printLog("start install jre");
printLog("create dir " + serverPath);
boolean dirs = client.createDirs(serverPath);
if (dirs) {
printLog("create dirs[{}] success.", serverPath);
} else {
throw new MojoExecutionException(StrUtil.format("create dirs[{}] failed.", serverPath));
}
InputStream stream = ResourceUtil.getStream("jre.tar.gz");
client.putFile(stream, serverPath + "/jre.tar.gz", new SshSimpleProgress() {
@Override
public void update(int process) {
System.out.print(StrUtil.format("[INFO] upload jre {}", process + "%\r"));
}
});
printLog(StrUtil.format("upload jre {}", "finish"));
printLog("unpackage [jre.tar.gz]");
client.exec("cd {}", serverPath);
client.exec("tar -zxvf {} -C {}", serverPath + "/jre.tar.gz", serverPath);
printLog("delete [jre.tar.gz]");
client.deleteFile(serverPath + "/jre.tar.gz");
printLog("create dir [jar]");
client.createDirs(serverPath + "/jar");
client.createFile(serverPath + "/jar/" + targetFile);
printLog("create sh script");
String sh = IOUtil.toString(ResourceUtil.getStream("service.sh"), StandardCharsets.UTF_8);
sh = StrUtil.replace(sh, "{0}", serverPath);
sh = StrUtil.replace(sh, "{1}", targetFile);
sh = StrUtil.replace(sh, "{2}", server.getDeployActive());
sh = StrUtil.replace(sh, "{3}", server.getDeployPort());
if (StrUtil.isNotBlank(server.getDeployActive())) {
client.write(serverPath + "/service-" + server.getDeployActive() + ".sh", sh);
client.exec("chmod +x {}", serverPath + "/service-" + server.getDeployActive() + ".sh");
// 修复win和unix不兼容字符
client.win2unix(serverPath + "/service-" + server.getDeployActive() + ".sh");
} else {
client.write(serverPath + "/service.sh", sh);
client.exec("chmod +x {}", serverPath + "/service.sh");
// 修复win和unix不兼容字符
client.win2unix(serverPath + "/service.sh");
}
printLog("create service script");
String ss = IOUtil.toString(ResourceUtil.getStream("service.service"), StandardCharsets.UTF_8);
ss = StrUtil.replace(ss, "{0}", serverPath);
ss = StrUtil.replace(ss, "{1}", targetFile);
if (StrUtil.isNotBlank(server.getDeployActive())) {
ss = StrUtil.replace(ss, "{2}", "-" + server.getDeployActive());
} else {
ss = StrUtil.replace(ss, "{2}", "");
}
ss = StrUtil.replace(ss, "{3}", server.getDeployPort());
client.write("/usr/lib/systemd/system/" + server.getName() + ".service", ss);
// 修复win和unix不兼容字符
client.win2unix("/usr/lib/systemd/system/" + server.getName() + ".service");
printLog("create /usr/lib/systemd/system/{}.service success", server.getName());
client.exec("systemctl daemon-reload");
printLog("daemon-reload");
client.exec("systemctl start {}.service", server.getName());
printLog("start {}.service", server.getName());
client.exec("systemctl enable {}.service", server.getName());
printLog("enable {}.service", server.getName());
client.exec("firewall-cmd --add-service=http --permanent");
printLog("enable http service");
client.exec("firewall-cmd --zone=public --add-port={}/tcp --permanent", server.getDeployPort());
printLog("release port {}", server.getDeployPort());
client.exec("firewall-cmd --reload");
printLog("firewall-cmd --reload");
printLog("jre[{}] install success", server.getName());
} catch (IOException e) {
e.printStackTrace();
throw new MojoExecutionException("install jre error");
}
} else {
printLog("jre[{}] has been installed", server.getName());
}
// 上传jar包
client.putFile(target.getAbsolutePath(), serverPath + "/jar/" + targetFile, new SshSimpleProgress() {
@Override
public void update(int process) {
System.out.print(StrUtil.format("[INFO] upload package {}", process + "%\r"));
}
});
printLog(StrUtil.format("upload package {}", "finish"));
printLog("stop service {}", server.getName());
client.exec("systemctl stop {}.service", server.getName());
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
printLog("start service {}", server.getName());
client.exec("systemctl start {}.service", server.getName());
final int[] tagIndex = {0};
TaskUtil.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
System.out.print("[INFO] check service " + StrUtil.repeat('.', 1 + tagIndex[0] % 3) + "\r");
tagIndex[0]++;
}
}, 0, 500);
Object o = TaskUtil.retryTask(new Callable<Object>() {
@Override
public Object call() throws Exception {
if (NetUtil.telnetPort(server.getIp(), Convert.toInt(server.getDeployPort()))) {
TaskUtil.cancel();
System.out.println("[INFO] check service finish");
printLog("[{}] deploy success", server.getName());
printLog("You can execute the following command to operate the service");
printLog("========================================");
printLog(StrUtil.format("systemctl start {}.service", server.getName()));
printLog(StrUtil.format("systemctl stop {}.service", server.getName()));
printLog(StrUtil.format("systemctl status {}.service", server.getName()));
printLog(StrUtil.format("systemctl reload {}.service", server.getName()));
printLog("========================================");
return new Object();
}
return null;
}
}, 100);
if (o == null) {
printLog("[{}] deploy failed", server.getName());
}
}
printLog("all deploy has finish");
printLog("------------------------------------------------------------------------");
}
public static void main(String[] args) {
System.out.println(StrUtil.format("systemctl start {}.service", "tzwy"));
System.out.println(StrUtil.format("systemctl stop {}.service", "tzwy"));
System.out.println(StrUtil.format("systemctl status {}.service", "tzwy"));
System.out.println(StrUtil.format("systemctl reload {}.service", "tzwy"));
}
private void printLog(String context, Object... args) {
getLog().info(StrUtil.format(context, args));
}
public String getTargetPath() {
return targetPath;
}
public void setTargetPath(String targetPath) {
this.targetPath = targetPath;
}
public String getTargetFile() {
return targetFile;
}
public void setTargetFile(String targetFile) {
this.targetFile = targetFile;
}
public Server[] getServers() {
return servers;
}
public void setServers(Server[] servers) {
this.servers = servers;
}
}

@ -0,0 +1,96 @@
package xyz.wbsite.deployee;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.StrUtil;
import xyz.wbsite.deployee.config.Server;
import xyz.wbsite.deployee.util.ssh.SshClient;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
/**
* @goal remove
*/
public class Remove extends AbstractMojo {
/**
* @parameter defaultValue="${build.directory}"
*/
private String targetPath;
/**
* @parameter defaultValue="${build.finalName}.${packaging}"
*/
private String targetFile;
/**
* @parameter
*/
private Server[] servers;
public void execute() throws MojoExecutionException {
printLog("------------------------------------------------------------------------");
printLog("TargetPath " + targetPath);
printLog("TargetFile " + targetFile);
if (servers == null || servers.length == 0) {
throw new MojoExecutionException("Server information not configured");
}
for (Server server : servers) {
printLog("Server[{}:{}] start remove", server.getIp(), server.getDeployPort());
SshClient client = new SshClient(server.getIp(), Convert.toInt(server.getPort()), server.getUsername(), server.getPassword());
printLog("stop service {}", server.getName());
client.exec("systemctl stop {}.service", server.getName());
printLog("disable service {}", server.getName());
client.exec("systemctl disable {}.service", server.getName());
printLog("remove service {}", server.getName());
client.deleteFile("/usr/lib/systemd/system/" + server.getName() + ".service");
printLog("daemon-reload");
client.exec("systemctl daemon-reload");
printLog("remove service {}", server.getName());
String serverPath = server.getDeployPath() + "/" + server.getName();
printLog("delete dir {}", serverPath);
client.deleteDirs(serverPath);
printLog("[{}] remove success", server.getName());
}
printLog("all remove has finish");
printLog("------------------------------------------------------------------------");
}
private void printLog(String context, Object... args) {
getLog().info(StrUtil.format(context, args));
}
public String getTargetPath() {
return targetPath;
}
public void setTargetPath(String targetPath) {
this.targetPath = targetPath;
}
public String getTargetFile() {
return targetFile;
}
public void setTargetFile(String targetFile) {
this.targetFile = targetFile;
}
public Server[] getServers() {
return servers;
}
public void setServers(Server[] servers) {
this.servers = servers;
}
}

@ -0,0 +1,108 @@
package xyz.wbsite.deployee.config;
public class Server {
/**
* @parameter defaultValue="server"
*/
private String name;
/**
* @parameter defaultValue="127.0.0.1"
*/
private String ip;
/**
* @parameter defaultValue="22"
*/
private String port;
/**
* @parameter defaultValue="root"
*/
private String username;
/**
* @parameter
*/
private String password;
/**
* @parameter defaultValue="test"
*/
private String deployActive;
/**
* @parameter defaultValue="/www"
*/
private String deployPath;
/**
* @parameter defaultValue="8080"
*/
private String deployPort;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getIp() {
return ip;
}
public void setIp(String ip) {
this.ip = ip;
}
public String getPort() {
return port;
}
public void setPort(String port) {
this.port = port;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getDeployActive() {
return deployActive;
}
public void setDeployActive(String deployActive) {
this.deployActive = deployActive;
}
public String getDeployPath() {
return deployPath;
}
public void setDeployPath(String deployPath) {
this.deployPath = deployPath;
}
public String getDeployPort() {
return deployPort;
}
public void setDeployPort(String deployPort) {
this.deployPort = deployPort;
}
}

@ -0,0 +1,38 @@
package xyz.wbsite.deployee.util;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.Charset;
/**
* IO
*
* @author wangbing
* @version 0.0.1
* @since 1.8
*/
public class IOUtil extends cn.hutool.core.io.IoUtil {
public static String toString(InputStream input, String encoding) throws IOException {
return toString(input, Charset.forName(encoding));
}
public static String toString(InputStream input, Charset encoding) throws IOException {
byte[] bytes = toByteArray(input);
return new String(bytes, encoding);
}
public static byte[] toByteArray(InputStream input) throws IOException {
ByteArrayOutputStream output = new ByteArrayOutputStream();
try {
copy(input, output);
return output.toByteArray();
} catch (Throwable e) {
throw e;
} finally {
output.close();
}
}
}

@ -0,0 +1,67 @@
package xyz.wbsite.deployee.util;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Socket;
/**
*
*
* @author wangbing
* @version 0.0.1
* @since 1.8
*/
public class NetUtil extends cn.hutool.core.net.NetUtil {
/**
* Ping
*
* @param ip
* @return ping
*/
public static boolean ping(String ip) {
return cn.hutool.core.net.NetUtil.ping(ip, 200);
}
/**
* Ping
*
* @param ip
* @return ping
*/
public static boolean ping(String ip, int timeout) {
return cn.hutool.core.net.NetUtil.ping(ip, timeout);
}
/**
*
*
* @param ip IP
* @param port
*/
public static boolean telnetPort(String ip, int port) {
Socket connect = new Socket();
boolean res = false;
try {
connect.connect(new InetSocketAddress(ip, port), 1000);//建立连接
//能telnet通返回true否则返回false
res = connect.isConnected();//通过现有方法查看连通状态
} catch (IOException e) {
} finally {
try {
connect.close();
} catch (IOException e) {
}
}
return res;
}
/**
*
*/
public static String getHostAddress() {
return getLocalhost().getHostAddress();
}
}

@ -0,0 +1,228 @@
package xyz.wbsite.deployee.util;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.Callable;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
/**
* /
*
* @author wangbing
* @version 0.0.1
* @since 1.8
*/
public class TaskUtil {
private static Timer timer = new Timer("TaskUtil", true);
private static ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor();
/**
* @param task
* @param delay
*/
public static void schedule(TimerTask task, long delay) {
timer.schedule(task, delay);
}
/**
* @param task
* @param time
*/
public static void schedule(TimerTask task, Date time) {
timer.schedule(task, time);
}
/**
* @param task,
* @param delay
* @param period -
*/
public static void schedule(TimerTask task, long delay, long period) {
timer.schedule(task, delay, period);
}
/**
* @param task,
* @param firstTime
* @param period
*/
public static void schedule(TimerTask task, Date firstTime, long period) {
timer.schedule(task, firstTime, period);
}
/**
* @param task,
* @param delay
* @param period -
*/
public static void scheduleAtFixedRate(TimerTask task, long delay, long period) {
timer.scheduleAtFixedRate(task, delay, period);
}
/**
* @param task,
* @param firstTime
* @param period -
*/
public static void scheduleAtFixedRate(TimerTask task, Date firstTime, long period) {
timer.scheduleAtFixedRate(task, firstTime, period);
}
/**
*
*/
public static void cancel() {
timer.cancel();
}
/**
*
*/
public static int purge() {
return timer.purge();
}
/**
* Runnable
*
* @param runnable Runnable
* @param delay (ms)
*/
public static void schedule(Runnable runnable, long delay) {
service.schedule(runnable, delay, TimeUnit.MILLISECONDS);
}
/**
* Runnable
*
* @param runnable Runnable
* @param delay
* @param unit
*/
public static void schedule(Runnable runnable, long delay, TimeUnit unit) {
service.schedule(runnable, delay, unit);
}
/**
* Runnable
*
* @param callable Callable
* @param delay (ms)
*/
public static <V> ScheduledFuture<V> schedule(Callable<V> callable, long delay) {
return service.schedule(callable, delay, TimeUnit.MILLISECONDS);
}
/**
* Runnable
*
* @param callable Callable
* @param delay
* @param unit
*/
public static <V> ScheduledFuture<V> schedule(Callable<V> callable, long delay, TimeUnit unit) {
return service.schedule(callable, delay, unit);
}
/**
* Runnable
*
* @param runnable Runnable
* @param initialDelay
* @param period -
* @param unit
*/
public static ScheduledFuture<?> scheduleAtFixedRate(Runnable runnable, long initialDelay, long period, TimeUnit unit) {
return service.scheduleAtFixedRate(runnable, initialDelay, period, unit);
}
/**
* Runnable
*
* @param runnable Runnable
* @param initialDelay
* @param period -ms
*/
public static ScheduledFuture<?> scheduleAtFixedRate(Runnable runnable, long initialDelay, long period) {
return service.scheduleAtFixedRate(runnable, initialDelay, period, TimeUnit.MILLISECONDS);
}
/**
* Runnable
*
* @param runnable Runnable
* @param initialDelay
* @param delay -
* @param unit
*/
public static ScheduledFuture<?> scheduleWithFixedDelay(Runnable runnable, long initialDelay, long delay, TimeUnit unit) {
return service.scheduleAtFixedRate(runnable, initialDelay, delay, unit);
}
/**
* Runnable
*
* @param runnable Runnable
* @param initialDelay
* @param delay -ms
*/
public static ScheduledFuture<?> scheduleWithFixedDelay(Runnable runnable, long initialDelay, long delay) {
return service.scheduleAtFixedRate(runnable, initialDelay, delay, TimeUnit.MILLISECONDS);
}
/**
* IO
*
* @param runnable
* @param <T>
* @param interval
*/
public static <T> T retryTask(Callable<T> runnable, int maxTryCount, long interval) {
for (int i = 0; i < maxTryCount; i++) {
Future<T> submit = service.submit(runnable);
try {
T t = submit.get();
if (t != null) {
return t;
}
// 控制重试时间间隔
if (i < maxTryCount - 1) {
TimeUnit.MILLISECONDS.sleep(interval);
}
} catch (Exception e) {
e.printStackTrace();
}
}
return null;
}
public static <T> T retryTask(Callable<T> runnable) {
return retryTask(runnable, 3, 3000);
}
public static <T> T retryTask(Callable<T> runnable, int maxTryCount) {
return retryTask(runnable, maxTryCount, 3000);
}
public static void repeatTask(Runnable runnable, int repeatCount) {
repeatTask(runnable, repeatCount, 0);
}
public static void repeatTask(Runnable runnable, int repeatCount, long interval) {
for (int i = 0; i < repeatCount; i++) {
service.submit(runnable);
try {
TimeUnit.MILLISECONDS.sleep(interval);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}

@ -0,0 +1,606 @@
package xyz.wbsite.deployee.util.ssh;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.io.StreamProgress;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.ssh.ChannelType;
import cn.hutool.log.StaticLog;
import com.jcraft.jsch.*;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.Properties;
/**
* ssh
*/
public class JSshClient {
private static final long DEFAULT_TIMEOUT = 5 * 60 * 1000;
/**
* IP
*/
private String ip;
/**
*
*/
private int port;
/**
*
*/
private String username;
/**
*
*/
private String password;
/**
*
*/
private boolean isLogin;
/**
*
*/
private boolean debug;
private String CHAR_SET = "UTF-8";
private Session session;
private ChannelSftp channelSftp;
public JSshClient(String ip, int port) {
this.ip = ip;
this.port = port;
this.login();
}
public JSshClient(String ip, int port, String username, String password) {
this(ip, port, username, password, false);
}
public JSshClient(String ip, int port, String username, String password, boolean debug) {
this.ip = ip;
this.port = port;
this.username = username;
this.password = password;
this.debug = debug;
this.login();
}
public boolean login(String username, String password) {
this.username = username;
this.password = password;
return login();
}
private boolean login() {
try {
if (isLogin) return true;
JSch jsch = new JSch();
session = jsch.getSession(username, ip, port);
session.setPassword(password);
Properties config = new Properties();
config.put("StrictHostKeyChecking", "no");
session.setConfig(config);
printLog("Login...");
try {
session.connect();
isLogin = true;
} catch (JSchException e) {
e.printStackTrace();
printLog("Connect time out");
isLogin = false;
}
return isLogin;
} catch (Exception e) {
printLog("Login failed");
return false;
}
}
public ChannelSftp getScpClient() {
if (channelSftp == null) {
try {
channelSftp = (ChannelSftp) session.openChannel(ChannelType.SFTP.getValue());
channelSftp.connect();
} catch (Exception e) {
e.printStackTrace();
}
}
return channelSftp;
}
public synchronized String exec(String cmd, String... arg) {
return exec(cmd, DEFAULT_TIMEOUT, arg);
}
public synchronized String exec(String cmd, long timeout, String... arg) {
if (!isLogin) return "[error]客户端未登录";
try {
printLog("执行命令:" + StrUtil.format(cmd, arg));
// 打开执行shell指令的通道
ChannelExec channelExec = (ChannelExec) session.openChannel(ChannelType.EXEC.getValue());
channelExec.setCommand(StrUtil.format(cmd, arg));
channelExec.connect();
return getResult(channelExec);
} catch (Exception e) {
e.printStackTrace();
return "[error]";
}
}
/**
*
*
* @param localFile
* @param remoteFile
*/
public boolean putFile(String localFile, String remoteFile) {
return putFile(localFile, remoteFile, new SshSimpleProgress() {
@Override
public void update(int process) {
}
});
}
/**
*
*
* @param localFile
* @param remoteFile
* @param progress
*/
public boolean putFile(String localFile, String remoteFile, SshSimpleProgress progress) {
return putFile(localFile, remoteFile, new SshStreamProgressWrapper(progress));
}
/**
*
*
* @param localFile
* @param remoteFile
* @param progress
*/
public boolean putFile(String localFile, String remoteFile, StreamProgress progress) {
if (!isLogin()) return false;
try {
getScpClient().put(localFile, remoteFile, new SftpProgressMonitor() {
long max;
long sum;
@Override
public void init(int op, String src, String dest, long max) {
progress.start();
this.max = max;
}
@Override
public boolean count(long count) {
sum += count;
progress.progress(this.max, sum);
return sum < max;
}
@Override
public void end() {
progress.finish();
}
}, ChannelSftp.OVERWRITE);
return true;
} catch (SftpException e) {
e.printStackTrace();
System.err.println("upload file failed");
return false;
}
}
/**
*
*
* @param inputStream
* @param remoteFile
*/
public boolean putFile(InputStream inputStream, String remoteFile) {
return putFile(inputStream, remoteFile, new SshSimpleProgress() {
@Override
public void update(int process) {
}
});
}
/**
*
*
* @param inputStream
* @param remoteFile
* @param progress
*/
public boolean putFile(InputStream inputStream, String remoteFile, SshSimpleProgress progress) {
return putFile(inputStream, remoteFile, new SshStreamProgressWrapper(progress));
}
/**
*
*
* @param inputStream
* @param remoteFile
* @param progress
*/
public boolean putFile(InputStream inputStream, String remoteFile, StreamProgress progress) {
if (!isLogin()) return false;
try {
if (this.exist(remoteFile)) this.createFile(remoteFile);
getScpClient().put(inputStream, remoteFile, new SftpProgressMonitor() {
long max;
long sum;
@Override
public void init(int op, String src, String dest, long max) {
progress.start();
this.max = max;
if (max == -1) {
try {
this.max = inputStream.available();
} catch (IOException e) {
e.printStackTrace();
}
}
}
@Override
public boolean count(long count) {
sum += count;
progress.progress(this.max, sum);
return sum < max;
}
@Override
public void end() {
progress.finish();
}
},
ChannelSftp.OVERWRITE);
return true;
} catch (Exception e) {
e.printStackTrace();
System.err.println("upload file failed");
return false;
}
}
/**
*
*
* @param localPath
* @param remotePath
*/
public boolean putFiles(String localPath, String remotePath) {
if (!createDirs(remotePath)) return false;
File local = new File(localPath);
for (File file : local.listFiles()) {
File target = new File(remotePath, file.getName());
String targetPath = target.getPath().replace('\\', '/');
if (file.isFile()) {
if (!putFile(file.getAbsolutePath(), targetPath)) return false;
} else {
if (!putFiles(file.getAbsolutePath(), targetPath)) return false;
}
}
return true;
}
/**
*
*
* @param remoteFile
* @param localFile
*/
public boolean downFile(String remoteFile, String localFile) {
return downFile(remoteFile, new File(localFile));
}
/**
*
*
* @param remoteFile
* @param localFile
*/
public boolean downFile(String remoteFile, File localFile) {
return downFile(remoteFile, localFile, new SshSimpleProgress() {
@Override
public void update(int process) {
}
});
}
/**
*
*
* @param remoteFile
* @param localFile
*/
public boolean downFile(String remoteFile, File localFile, SshSimpleProgress progress) {
return downFile(remoteFile, localFile, new SshStreamProgressWrapper(progress));
}
/**
*
*
* @param remoteFile
* @param localFile
*/
public boolean downFile(String remoteFile, String localFile, SshSimpleProgress progress) {
return downFile(remoteFile, new File(localFile), progress);
}
/**
*
*
* @param remoteFile
* @param localFile
*/
public boolean downFile(String remoteFile, String localFile, StreamProgress progress) {
return downFile(remoteFile, new File(localFile), progress);
}
/**
*
*
* @param remoteFile
* @param localFile
*/
public boolean downFile(String remoteFile, File localFile, StreamProgress progress) {
if (!isLogin()) return false;
try {
InputStream inputStream = getScpClient().get(remoteFile);
// 传输流
IoUtil.copy(inputStream, FileUtil.getOutputStream(localFile), 0, inputStream.available(), progress);
printLog("下载文件" + localFile.getAbsolutePath());
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
public boolean exist(String fileOrPath) {
String exec = this.exec("ls -l " + fileOrPath);
printLog("执行结果:" + exec);
return !exec.startsWith("[error]");
}
public boolean createFile(String file) {
String exec = this.exec("touch " + file);
printLog("执行结果:" + exec);
return !exec.startsWith("[error]");
}
public boolean createDirs(String path) {
String exec = this.exec("mkdir -p " + path);
printLog("执行结果:" + exec);
return !exec.startsWith("[error]");
}
public boolean deleteDirs(String path) {
String exec = this.exec("rm -rf " + path);
printLog("执行结果:" + exec);
return !exec.startsWith("[error]");
}
public boolean deleteFile(String file) {
return deleteDirs(file);
}
public boolean moveFile(String srcPathOrFile, String targetPathOrFile) {
String exec = this.exec(String.format("mv -f %s %s", srcPathOrFile, targetPathOrFile));
printLog("执行结果:" + exec);
return !exec.startsWith("[error]");
}
/**
*
*/
public boolean killByKeyword(String keyword) {
String exec = this.exec("ps -ef | grep " + keyword + " | grep -v grep |awk '{print $2}'| xargs kill -9");
printLog("执行结果:" + exec);
return !exec.startsWith("[error]");
}
/**
*
*/
public boolean killByPort(int port) {
String exec = this.exec("kill -9 $(lsof -i:" + port + " -t)");
printLog("执行结果:" + exec);
return !exec.startsWith("[error]");
}
/**
* /
*/
public boolean chown(String fileOrPath) {
String exec = this.exec("chmod -R 777 " + fileOrPath);
printLog("执行结果:" + exec);
return !exec.startsWith("[error]");
}
/**
* shell
*/
public boolean shell(String shellFile) {
this.exec("chmod +x {}", shellFile);
String exec = this.exec("{}", shellFile);
printLog("执行结果:" + exec);
return !exec.startsWith("[error]");
}
/**
*
*
* @param remoteFile
*/
public String readAsString(String remoteFile) {
return readAsString(remoteFile, StandardCharsets.UTF_8);
}
/**
*
*
* @param remoteFile
* @param charset
*/
public String readAsString(String remoteFile, Charset charset) {
printLog("下载文件:" + remoteFile);
File tempFile = new File(FileUtil.getTmpDir(), IdUtil.fastSimpleUUID());
downFile(remoteFile, tempFile);
return FileUtil.readString(tempFile, charset);
}
/**
*
*
* @param file
* @param content
*/
public boolean write(String file, String content) {
return write(file, content, Charset.defaultCharset());
}
/**
*
*
* @param file
* @param content
*/
public boolean write(String file, String content, Charset charset) {
printLog("写入文件:" + file);
File tempFile = new File(FileUtil.getTmpDir(), IdUtil.fastSimpleUUID());
FileUtil.writeString(content, tempFile, charset);
try {
return this.putFile(tempFile.getAbsolutePath(), file);
} finally {
tempFile.delete();
}
}
/**
*
*
* @param remoteTar .tar.gz
* @param remoteFile *.jpg
*/
public boolean tar(String remoteTar, String remoteFile) {
String exec = this.exec("tar -czf {} {}", remoteTar, remoteFile);
printLog("执行结果:" + exec);
return !exec.startsWith("[error]");
}
/**
*
*
* @param remoteTar .tar.gz
* @param path
*/
public boolean untar(String remoteTar, String path) {
String exec = this.exec("cd {} && tar -xzf {}", path, remoteTar);
printLog("执行结果:" + exec);
return !exec.startsWith("[error]");
}
/**
* WindowsUnix
*
* @param remoteFile
*/
public boolean win2unix(String remoteFile) {
String exec = this.exec("sed -i 's/\r$//' {}", remoteFile);
printLog("执行结果:" + exec);
return !exec.startsWith("[error]");
}
/**
*
*/
private String getResult(ChannelExec channelExec) {
StringBuffer result = new StringBuffer();
try {
byte[] tmp = new byte[1024];
byte[] btmp = new byte[1024];
StringBuffer iptsb = new StringBuffer();
StringBuffer errsb = new StringBuffer();
InputStream iptStream = channelExec.getInputStream();
// 返回结果流命令执行错误的信息通过getErrStream获取
InputStream errStream = channelExec.getErrStream();
try {
while (true) {
//获取命令执行正确的返回信息
while (iptStream.available() > 0) {
int i = iptStream.read(btmp, 0, 1024);
if (i < 0) {
break;
}
iptsb.append(new String(btmp, 0, i));
}
//开始获得SSH命令错误的结果
while (errStream.available() > 0) {
int i = errStream.read(tmp, 0, 1024);
if (i < 0) {
break;
}
errsb.append(new String(tmp, 0, i));
}
if (channelExec.isClosed()) {
break;
}
try {
Thread.sleep(200);
} catch (Exception e) {
e.printStackTrace();
}
}
} finally {
//关闭连接
channelExec.disconnect();
}
if (errsb.length() > 0) {
return "[error]" + errsb.toString();
} else {
return iptsb.toString();
}
} catch (Exception e) {
System.err.println("解析出错:" + e.getMessage());
e.printStackTrace();
}
return result.toString();
}
public boolean close() {
if (channelSftp != null) {
channelSftp.disconnect();
channelSftp = null;
}
if (session != null) {
session.disconnect();
session = null;
}
return true;
}
public boolean isLogin() {
return this.isLogin;
}
private void printLog(String log, String... arg) {
if (debug) {
StaticLog.info("@[{}:{}] " + log, ip, port, arg);
}
}
}

@ -0,0 +1,547 @@
package xyz.wbsite.deployee.util.ssh;
import ch.ethz.ssh2.ChannelCondition;
import ch.ethz.ssh2.Connection;
import ch.ethz.ssh2.SCPClient;
import ch.ethz.ssh2.SCPInputStream;
import ch.ethz.ssh2.SCPOutputStream;
import ch.ethz.ssh2.Session;
import ch.ethz.ssh2.StreamGobbler;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.io.StreamProgress;
import cn.hutool.core.util.ClassUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.Field;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
public class SshClient {
private static final long DEFAULT_TIMEOUT = 5 * 60 * 1000;
/**
* IP
*/
private String ip;
/**
*
*/
private int port;
/**
*
*/
private String username;
/**
*
*/
private String password;
/**
*
*/
private boolean isLogin;
/**
*
*/
private boolean debug;
private String CHAR_SET = "UTF-8";
private Connection connection;
private SCPClient scpClient;
public SshClient(String ip, int port) {
this.ip = ip;
this.port = port;
this.login();
}
public SshClient(String ip, int port, String username, String password) {
this(ip, port, username, password, false);
}
public SshClient(String ip, int port, String username, String password, boolean debug) {
this.ip = ip;
this.port = port;
this.username = username;
this.password = password;
this.debug = debug;
this.login();
}
public boolean login(String username, String password) {
this.username = username;
this.password = password;
return login();
}
private boolean login() {
try {
if (connection != null) close();
connection = new Connection(ip, port);
connection.connect();// 连接
isLogin = connection.authenticateWithPassword(username, password);// 认证
printLog(isLogin ? "登录成功" : "登录失败");
return isLogin;
} catch (IOException e) {
printLog("登录失败");
connection.close();
return false;
}
}
public SCPClient getScpClient() {
if (scpClient == null) {
try {
scpClient = connection.createSCPClient();
} catch (IOException e) {
e.printStackTrace();
}
}
return scpClient;
}
public synchronized String exec(String cmd, String... arg) {
return exec(cmd, DEFAULT_TIMEOUT, arg);
}
public synchronized String exec(String cmd, long timeout, String... arg) {
if (!isLogin) return "[error]客户端未登录";
try {
printLog("执行命令:" + StrUtil.format(cmd, arg));
String execResult = null;
Session session = connection.openSession();
session.execCommand(StrUtil.format(cmd, arg));
session.waitForCondition(ChannelCondition.EXIT_STATUS, timeout);
execResult = getResult(session);
session.close();
return execResult;
} catch (IOException e) {
return "[error]";
}
}
/**
*
*
* @param localFile
* @param remoteFile
*/
public boolean putFile(String localFile, String remoteFile) {
return putFile(localFile, remoteFile, new SshSimpleProgress() {
@Override
public void update(int process) {
}
});
}
/**
*
*
* @param localFile
* @param remoteFile
*/
public boolean putFile(String localFile, String remoteFile, SshSimpleProgress progress) {
return putFile(localFile, remoteFile, new SshStreamProgressWrapper(progress));
}
/**
*
*
* @param localFile
* @param remoteFile
*/
public boolean putFile(String localFile, String remoteFile, StreamProgress progress) {
if (!isLogin()) return false;
try {
File localFileObject = new File(localFile);
File remoteFileObject = new File(remoteFile);
String targetPath = remoteFileObject.getParent().replace('\\', '/');
SCPOutputStream scpOutputStream = getScpClient().put(
remoteFileObject.getName(),
localFileObject.length(),
targetPath,
"0600");
IoUtil.copy(FileUtil.getInputStream(localFileObject), scpOutputStream, 0, localFileObject.length(), progress);
return true;
} catch (IOException e) {
System.err.println("创建 SCPClient 错误");
e.printStackTrace();
return false;
}
}
/**
*
*
* @param inputStream
* @param remoteFile
*/
public boolean putFile(InputStream inputStream, String remoteFile) {
return putFile(inputStream, remoteFile, new SshSimpleProgress() {
@Override
public void update(int process) {
}
});
}
/**
*
*
* @param inputStream
* @param remoteFile
* @param progress
*/
public boolean putFile(InputStream inputStream, String remoteFile, SshSimpleProgress progress) {
return putFile(inputStream, remoteFile, new SshStreamProgressWrapper(progress));
}
/**
*
*
* @param inputStream
* @param remoteFile
* @param progress
*/
public boolean putFile(InputStream inputStream, String remoteFile, StreamProgress progress) {
if (!isLogin()) return false;
try {
File remoteFileObject = new File(remoteFile);
String targetPath = remoteFileObject.getParent().replace('\\', '/');
SCPOutputStream scpOutputStream = getScpClient().put(
remoteFileObject.getName(),
inputStream.available(),
targetPath,
"0600");
IoUtil.copy(inputStream, scpOutputStream, 0, inputStream.available(), progress);
return true;
} catch (IOException e) {
System.err.println("创建 SCPClient 错误");
e.printStackTrace();
return false;
}
}
/**
*
*
* @param localPath
* @param remotePath
*/
public boolean putFiles(String localPath, String remotePath) {
if (!createDirs(remotePath)) return false;
File local = new File(localPath);
for (File file : local.listFiles()) {
File target = new File(remotePath, file.getName());
String targetPath = target.getPath().replace('\\', '/');
if (file.isFile()) {
if (!putFile(file.getAbsolutePath(), targetPath)) return false;
} else {
if (!putFiles(file.getAbsolutePath(), targetPath)) return false;
}
}
return true;
}
/**
*
*
* @param remoteFile
* @param localFile
*/
public boolean downFile(String remoteFile, String localFile) {
return downFile(remoteFile, new File(localFile));
}
/**
*
*
* @param remoteFile
* @param localFile
*/
public boolean downFile(String remoteFile, File localFile) {
return downFile(remoteFile, localFile, new SshSimpleProgress() {
@Override
public void update(int process) {
}
});
}
/**
*
*
* @param remoteFile
* @param localFile
*/
public boolean downFile(String remoteFile, File localFile, SshSimpleProgress progress) {
return downFile(remoteFile, localFile, new SshStreamProgressWrapper(progress));
}
/**
*
*
* @param remoteFile
* @param localFile
*/
public boolean downFile(String remoteFile, String localFile, SshSimpleProgress progress) {
return downFile(remoteFile, new File(localFile), progress);
}
/**
*
*
* @param remoteFile
* @param localFile
*/
public boolean downFile(String remoteFile, String localFile, StreamProgress progress) {
return downFile(remoteFile, new File(localFile), progress);
}
/**
*
*
* @param remoteFile
* @param localFile
*/
public boolean downFile(String remoteFile, File localFile, StreamProgress progress) {
if (!isLogin()) return false;
try {
SCPInputStream scpInputStream = getScpClient().get(remoteFile);
// 文件有效大小默认为0
long available = 0;
// SCPInputStream.available()永远为0
// 因此尝试通过反射获取文件大小
try {
Field remaining = ClassUtil.getDeclaredField(SCPInputStream.class, "remaining");
remaining.setAccessible(true);
available = Convert.toLong(remaining.get(scpInputStream), 0L);
} catch (Exception ignored) {
}
// 传输流
IoUtil.copy(scpInputStream, FileUtil.getOutputStream(localFile), 0, available, progress);
printLog("下载文件" + localFile.getAbsolutePath());
return true;
} catch (IOException ioe) {
ioe.printStackTrace();
return false;
}
}
public boolean exist(String fileOrPath) {
String exec = this.exec("ls -l " + fileOrPath);
printLog("执行结果:" + exec);
return !exec.startsWith("[error]");
}
public boolean createFile(String file) {
String exec = this.exec("touch " + file);
printLog("执行结果:" + exec);
return !exec.startsWith("[error]");
}
public boolean createDirs(String path) {
String exec = this.exec("mkdir -p " + path);
printLog("执行结果:" + exec);
return !exec.startsWith("[error]");
}
public boolean deleteDirs(String path) {
String exec = this.exec("rm -rf " + path);
printLog("执行结果:" + exec);
return !exec.startsWith("[error]");
}
public boolean deleteFile(String file) {
return deleteDirs(file);
}
public boolean moveFile(String srcPathOrFile, String targetPathOrFile) {
String exec = this.exec(String.format("mv -f %s %s", srcPathOrFile, targetPathOrFile));
printLog("执行结果:" + exec);
return !exec.startsWith("[error]");
}
/**
*
*/
public boolean killByKeyword(String keyword) {
String exec = this.exec("ps -ef | grep " + keyword + " | grep -v grep |awk '{print $2}'| xargs kill -9");
printLog("执行结果:" + exec);
return !exec.startsWith("[error]");
}
/**
*
*/
public boolean killByPort(int port) {
String exec = this.exec("kill -9 $(lsof -i:" + port + " -t)");
printLog("执行结果:" + exec);
return !exec.startsWith("[error]");
}
/**
* /
*/
public boolean chown(String fileOrPath) {
String exec = this.exec("chmod -R 777 " + fileOrPath);
printLog("执行结果:" + exec);
return !exec.startsWith("[error]");
}
/**
* shell
*/
public boolean shell(String shellFile) {
this.exec("chmod +x {}", shellFile);
String exec = this.exec("{}", shellFile);
printLog("执行结果:" + exec);
return !exec.startsWith("[error]");
}
/**
*
*
* @param remoteFile
*/
public String readAsString(String remoteFile) {
return readAsString(remoteFile, StandardCharsets.UTF_8);
}
/**
*
*
* @param remoteFile
* @param charset
*/
public String readAsString(String remoteFile, Charset charset) {
printLog("下载文件:" + remoteFile);
File tempFile = new File(FileUtil.getTmpDir(), IdUtil.fastSimpleUUID());
downFile(remoteFile, tempFile);
return FileUtil.readString(tempFile, charset);
}
/**
*
*
* @param file
* @param content
*/
public boolean write(String file, String content) {
return write(file, content, Charset.defaultCharset());
}
/**
*
*
* @param file
* @param content
*/
public boolean write(String file, String content, Charset charset) {
printLog("写入文件:" + file);
File tempFile = new File(FileUtil.getTmpDir(), IdUtil.fastSimpleUUID());
FileUtil.writeString(content, tempFile, charset);
try {
return this.putFile(tempFile.getAbsolutePath(), file);
} finally {
tempFile.delete();
}
}
/**
*
*
* @param remoteTar .tar.gz
* @param remoteFile *.jpg
*/
public boolean tar(String remoteTar, String remoteFile) {
String exec = this.exec("tar -czf {} {}", remoteTar, remoteFile);
printLog("执行结果:" + exec);
return !exec.startsWith("[error]");
}
/**
*
*
* @param remoteTar .tar.gz
* @param path
*/
public boolean untar(String remoteTar, String path) {
String exec = this.exec("cd {} && tar -xzf {}", path, remoteTar);
printLog("执行结果:" + exec);
return !exec.startsWith("[error]");
}
/**
* WindowsUnix
*
* @param remoteFile
*/
public boolean win2unix(String remoteFile) {
String exec = this.exec("sed -i 's/\r$//' {}", remoteFile);
printLog("执行结果:" + exec);
return !exec.startsWith("[error]");
}
/**
*
*/
private String getResult(Session session) {
Integer exitStatus = session.getExitStatus();
StringBuffer result = new StringBuffer();
InputStream in;
if (exitStatus != null && exitStatus != 0) { // 执行失败
result.append("[error]");
in = session.getStderr();
} else { // 执行成功
in = session.getStdout();
}
InputStream stdout = new StreamGobbler(in);
try {
InputStreamReader isr = new InputStreamReader(stdout, CHAR_SET);
char[] bytes = new char[1024];
int bc;
while ((bc = isr.read(bytes)) != -1) {
result.append(bytes, 0, bc);
}
isr.close();
} catch (Exception e) {
System.err.println("解析出错:" + e.getMessage());
e.printStackTrace();
}
return result.toString();
}
public boolean close() {
if (scpClient != null) {
scpClient = null;
}
if (connection != null) {
connection.close();
connection = null;
}
return true;
}
public boolean isLogin() {
return this.isLogin;
}
private void printLog(String log, String... arg) {
if (debug) {
String logPre = StrUtil.format("LOG-[{}:{}] [{}] ", ip, port, DateUtil.now());
System.out.println(logPre + StrUtil.format(log, arg));
}
}
}

@ -0,0 +1,11 @@
package xyz.wbsite.deployee.util.ssh;
public interface SshSimpleProgress {
/**
* (0~100)
*
* @param process
*/
void update(int process);
}

@ -0,0 +1,33 @@
package xyz.wbsite.deployee.util.ssh;
import cn.hutool.core.io.StreamProgress;
/**
* SimpleProgress
*/
public class SshStreamProgressWrapper implements StreamProgress {
private int val;
private SshSimpleProgress progress;
public SshStreamProgressWrapper(SshSimpleProgress progress) {
this.progress = progress;
}
@Override
public void start() {
progress.update(val);
}
@Override
public void progress(long total, long progressSize) {
int newVal = (int) (progressSize * 100.0 / total);
if (newVal > val) {
progress.update(val = newVal);
}
}
@Override
public void finish() {
}
}

Binary file not shown.

@ -0,0 +1,13 @@
[Unit]
Description={0} Service
After=network.target remote-fs.target nss-lookup.target
[Service]
Type=forking
ExecStart={0}/service{2}.sh start
ExecReload={0}/service{2}.sh restart
ExecStop={0}/service{2}.sh stop
PrivateTmp=true
[Install]
WantedBy=multi-user.target

@ -0,0 +1,77 @@
#!/bin/bash
# work path
cd $(dirname $0)
#java home
JAVA_HOME=jre
#jar file
APP_NAME=jar/{1}
#active
ACTIVE={2}
#port
PORT={3}
#more arg
APP_ARG=
usage() {
echo "Usage: sh service-*.sh [start|stop|restart|status]"
exit 1
}
is_exist(){
pid=`ps -ef|grep $APP_NAME|grep -v grep|grep -v /bin/bash|awk '{print $2}' `
if [ -z "${pid}" ]; then
return 1
else
return 0
fi
}
start(){
is_exist
if [ $? -eq "0" ]; then
echo "${APP_NAME} is already running. pid=${pid} ."
else
nohup ${JAVA_HOME}/bin/java -Dfile.encoding=UTF-8 -jar $APP_NAME --spring.profiles.active=$ACTIVE --server.port=${PORT} $APP_ARG > /dev/null 2>&1 &
fi
}
stop(){
is_exist
if [ $? -eq "0" ]; then
kill -9 $pid
else
echo "${APP_NAME} is not running"
fi
}
status(){
is_exist
if [ $? -eq "0" ]; then
echo "${APP_NAME} is running. Pid is ${pid}"
else
echo "${APP_NAME} is NOT running."
fi
}
restart(){
stop
start
}
case "$1" in
"start")
start
;;
"stop")
stop
;;
"status")
status
;;
"restart")
restart
;;
*)
usage
;;
esac
Loading…
Cancel
Save

Powered by TurnKey Linux.