|
|
@@ -1,294 +0,0 @@
|
|
|
-package cn.reghao.bnt.deployer.util;
|
|
|
-
|
|
|
-import cn.reghao.bnt.deployer.model.RemoteHost;
|
|
|
-import cn.reghao.bnt.deployer.model.UserInfoImpl;
|
|
|
-import cn.reghao.jutil.jdk.shell.ShellResult;
|
|
|
-import cn.reghao.jutil.jdk.io.TextFile;
|
|
|
-import com.jcraft.jsch.*;
|
|
|
-import lombok.extern.slf4j.Slf4j;
|
|
|
-
|
|
|
-import java.io.*;
|
|
|
-import java.util.ArrayList;
|
|
|
-import java.util.List;
|
|
|
-import java.util.Objects;
|
|
|
-
|
|
|
-/**
|
|
|
- * @author reghao
|
|
|
- * @date 2024-02-19 11:38:54
|
|
|
- */
|
|
|
-@Slf4j
|
|
|
-public class Sftp {
|
|
|
- private final TextFile textFile = new TextFile();
|
|
|
- private final String bash = "/usr/bin/bash";
|
|
|
-
|
|
|
- public Session getSession(RemoteHost remoteHost) throws Exception {
|
|
|
- String host = remoteHost.getHost();
|
|
|
- int port = remoteHost.getPort();
|
|
|
- String username = remoteHost.getUsername();
|
|
|
- String password = remoteHost.getPassword();
|
|
|
- String prikeyPath = remoteHost.getPrikeyPath();
|
|
|
-
|
|
|
- JSch jsch = new JSch();
|
|
|
- Session session;
|
|
|
- if (port <= 0) {
|
|
|
- //连接服务器,采用默认端口
|
|
|
- session = jsch.getSession(username, host);
|
|
|
- } else {
|
|
|
- //采用指定的端口连接服务器
|
|
|
- session = jsch.getSession(username, host, port);
|
|
|
- }
|
|
|
-
|
|
|
- //如果服务器连接不上,则抛出异常
|
|
|
- if (session == null) {
|
|
|
- throw new Exception("session is null");
|
|
|
- }
|
|
|
-
|
|
|
- if (password != null) {
|
|
|
- //设置登陆主机的密码
|
|
|
- session.setPassword(password);
|
|
|
- //设置第一次登陆的时候提示,可选值:(ask | yes | no)
|
|
|
- session.setConfig("StrictHostKeyChecking", "no");
|
|
|
- } else if (prikeyPath != null) {
|
|
|
- session.setConfig("PreferredAuthentications", "publickey");
|
|
|
- session.setConfig("userauth.gssapi-with-mic", "no");
|
|
|
- session.setConfig("StrictHostKeyChecking", "ask");
|
|
|
- session.setUserInfo(new UserInfoImpl(""));
|
|
|
- jsch.addIdentity(prikeyPath);
|
|
|
-
|
|
|
- session.setConfig("UseDNS", "no");
|
|
|
- session.setConfig("kex", "diffie-hellman-group1-sha1,"
|
|
|
- + "diffie-hellman-group-exchange-sha1,"
|
|
|
- + "diffie-hellman-group-exchange-sha256");
|
|
|
- } else {
|
|
|
- throw new Exception("password and private key not exist either");
|
|
|
- }
|
|
|
-
|
|
|
- session.connect(30_000);
|
|
|
- return session;
|
|
|
- }
|
|
|
-
|
|
|
- public void upload(Session session, String local, String destDir) throws JSchException, SftpException, IOException {
|
|
|
- // 创建 sftp 通信通道
|
|
|
- Channel channel = session.openChannel("sftp");
|
|
|
- channel.connect(5_000);
|
|
|
- ChannelSftp sftp = (ChannelSftp) channel;
|
|
|
- sftp.cd(destDir);
|
|
|
- File localFile = new File(local);
|
|
|
- if (localFile.isFile()) {
|
|
|
- putFile(localFile, destDir, sftp);
|
|
|
- } else {
|
|
|
- for (File file : Objects.requireNonNull(localFile.listFiles())) {
|
|
|
- if (file.isFile()) {
|
|
|
- putFile(file, destDir, sftp);
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- if (channel.isConnected()) {
|
|
|
- channel.disconnect();
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- private void putFile(File localFile, String destDir, ChannelSftp sftp) throws IOException, SftpException {
|
|
|
- String filename = localFile.getName();
|
|
|
- String remoteFilePath = String.format("%s/%s", destDir, filename);
|
|
|
- OutputStream outstream = sftp.put(remoteFilePath);
|
|
|
-
|
|
|
- InputStream instream = new FileInputStream(localFile);
|
|
|
- byte[] bytes = new byte[1024];
|
|
|
- int n;
|
|
|
- while ((n = instream.read(bytes)) != -1) {
|
|
|
- outstream.write(bytes, 0, n);
|
|
|
- }
|
|
|
-
|
|
|
- outstream.flush();
|
|
|
- outstream.close();
|
|
|
- instream.close();
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 在远程机器上创建目录(等价于 mkdir -p)
|
|
|
- *
|
|
|
- * @param
|
|
|
- * @return
|
|
|
- * @date 2024-02-20 09:20:11
|
|
|
- */
|
|
|
- public boolean mkdir(Session session, String remotePath) throws SftpException, JSchException {
|
|
|
- boolean exist = true;
|
|
|
- // 创建 sftp 通信通道
|
|
|
- Channel channel = session.openChannel("sftp");
|
|
|
- channel.connect(5_000);
|
|
|
- ChannelSftp sftp = (ChannelSftp) channel;
|
|
|
-
|
|
|
- List<String> list = new ArrayList<>();
|
|
|
- String[] arr = remotePath.split("/");
|
|
|
- for (int i = 0; i < arr.length; i++) {
|
|
|
- String path = "/" + arr[i];
|
|
|
- if (i-1 > 0) {
|
|
|
- list.add(list.get(i-1) + path);
|
|
|
- } else {
|
|
|
- list.add(path);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- for (String path : list) {
|
|
|
- try {
|
|
|
- sftp.stat(path);
|
|
|
- } catch (SftpException e) {
|
|
|
- exist = false;
|
|
|
- sftp.mkdir(path);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- return exist;
|
|
|
- }
|
|
|
-
|
|
|
- public ShellResult exec(Session session, String command) throws JSchException, IOException {
|
|
|
- StringBuilder sb = new StringBuilder();
|
|
|
- // 创建 exec 通信通道
|
|
|
- ChannelExec channel = (ChannelExec) session.openChannel("exec");
|
|
|
- channel.setCommand(command);
|
|
|
- channel.setInputStream(null);
|
|
|
- channel.setErrStream(System.err);
|
|
|
- InputStream input = channel.getInputStream();
|
|
|
- InputStream error = channel.getErrStream();
|
|
|
-
|
|
|
- // timeout 设置为 10 分钟
|
|
|
- channel.connect(600_000);
|
|
|
- /*byte[] tmp = new byte[1024];
|
|
|
- int i = 0;
|
|
|
- while (true) {
|
|
|
- while (input.available() > 0) {
|
|
|
- i = input.read(tmp, 0, 1024);
|
|
|
- if (i < 0) {
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- if (channel.isClosed()) {
|
|
|
- if (input.available() > 0) {
|
|
|
- continue;
|
|
|
- }
|
|
|
-
|
|
|
- log.info("channel closed with status: {}", channel.getExitStatus());
|
|
|
- break;
|
|
|
- }
|
|
|
-
|
|
|
- try {
|
|
|
- Thread.sleep(1000);
|
|
|
- } catch(Exception e) {
|
|
|
- e.printStackTrace();
|
|
|
- }
|
|
|
- }
|
|
|
- sb.append(new String(tmp, 0, i));
|
|
|
- */
|
|
|
- // stdin
|
|
|
- BufferedReader inputReader = new BufferedReader(new InputStreamReader(input));
|
|
|
- String line;
|
|
|
- while((line = inputReader.readLine()) != null) {
|
|
|
- sb.append(line).append(System.lineSeparator());
|
|
|
- }
|
|
|
-
|
|
|
- // stderr
|
|
|
- StringBuilder sb1 = new StringBuilder();
|
|
|
- BufferedReader errorReader = new BufferedReader(new InputStreamReader(error));
|
|
|
- String line1;
|
|
|
- while((line1 = errorReader.readLine()) != null) {
|
|
|
- sb1.append(line1).append(System.lineSeparator());
|
|
|
- }
|
|
|
-
|
|
|
- int statusCode = channel.getExitStatus();
|
|
|
- ShellResult shellResult = new ShellResult(statusCode);
|
|
|
- if (statusCode == 0) {
|
|
|
- shellResult.setResult(sb.toString());
|
|
|
- } else {
|
|
|
- shellResult.setResult(sb1.toString());
|
|
|
- }
|
|
|
-
|
|
|
- if (channel.isConnected()) {
|
|
|
- channel.disconnect();
|
|
|
- }
|
|
|
-
|
|
|
- return shellResult;
|
|
|
- }
|
|
|
-
|
|
|
- public List<RemoteHost> getRemoteHost(String filePath) {
|
|
|
- List<String> list = textFile.read(filePath);
|
|
|
- List<RemoteHost> remoteHosts = new ArrayList<>();
|
|
|
- for (int i = 1; i < list.size(); i++) {
|
|
|
- // 从 csv 文件的第二行开始读, 第一行为注释
|
|
|
- String line = list.get(i);
|
|
|
- String[] arr = line.split(",");
|
|
|
- if (arr.length == 4) {
|
|
|
- String host = arr[0];
|
|
|
- int port = Integer.parseInt(arr[1]);
|
|
|
- String username = arr[2];
|
|
|
- String password = arr[3];
|
|
|
- remoteHosts.add(new RemoteHost(host, port, username, password, null));
|
|
|
- } else if (arr.length == 5) {
|
|
|
- String host = arr[0];
|
|
|
- int port = Integer.parseInt(arr[1]);
|
|
|
- String username = arr[2];
|
|
|
- String prikeyPath = arr[4];
|
|
|
- remoteHosts.add(new RemoteHost(host, port, username, null, prikeyPath));
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- return remoteHosts;
|
|
|
- }
|
|
|
-
|
|
|
- public void deploy(String localDir, String remoteDir, RemoteHost remoteHost) throws Exception {
|
|
|
- Session session = getSession(remoteHost);
|
|
|
- boolean exist = mkdir(session, remoteDir);
|
|
|
- if (exist) {
|
|
|
- String command = String.format("cd %s && %s shutdown.sh", remoteDir, bash);
|
|
|
- ShellResult shellResult = exec(session, command);
|
|
|
- if (!shellResult.isSuccess()) {
|
|
|
- log.info("shutdown application failed\nexitCode: {}\nresult:\n{}", shellResult.getExitCode(), shellResult.getResult());
|
|
|
- System.exit(-1);
|
|
|
- } else {
|
|
|
- log.info("shutdown application successfully");
|
|
|
- }
|
|
|
- } else {
|
|
|
- log.info("remote dir {} created", remoteDir);
|
|
|
- }
|
|
|
-
|
|
|
- upload(session, localDir, remoteDir);
|
|
|
- log.info("files uploaded");
|
|
|
-
|
|
|
- String command = String.format("cd %s && %s start.sh", remoteDir, bash);
|
|
|
- ShellResult shellResult = exec(session, command);
|
|
|
- if (!shellResult.isSuccess()) {
|
|
|
- log.info("start application failed\nexitCode: {}\nresult:\n{}", shellResult.getExitCode(), shellResult.getResult());
|
|
|
- System.exit(-1);
|
|
|
- } else {
|
|
|
- log.info("start application successfully");
|
|
|
- }
|
|
|
-
|
|
|
- if (session.isConnected()) {
|
|
|
- session.disconnect();
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- public void exec(RemoteHost remoteHost, String command) throws Exception {
|
|
|
- Session session = getSession(remoteHost);
|
|
|
- ShellResult shellResult = exec(session, command);
|
|
|
- log.info("\nexitCode: {}\nresult:\n{}", shellResult.getExitCode(), shellResult.getResult());
|
|
|
-
|
|
|
- if (session.isConnected()) {
|
|
|
- session.disconnect();
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- public static void main(String[] args) throws Exception {
|
|
|
- String host = "192.168.0.180";
|
|
|
- int port = 22;
|
|
|
- String username = "root";
|
|
|
- String password = "gsh";
|
|
|
- RemoteHost remoteHost = new RemoteHost(host, port, username, password, null);
|
|
|
-
|
|
|
- String command = "docker ps -a";
|
|
|
- Sftp sftp = new Sftp();
|
|
|
- sftp.exec(remoteHost, command);
|
|
|
- }
|
|
|
-}
|