Java ssh实现远程服务器部署

pom依赖【Java ssh实现远程服务器部署】<dependency><groupId>ch.ethz.ganymed</groupId><artifactId>ganymed-ssh2</artifactId><version>build210</version></dependency> 
BtpAbstractService类/** * <p>Title: abstract service</p> * <p>Author: lehoon</p> * <p>Date: 2022/2/28 16:48</p> */@Slf4jpublic abstract class BtpAbstractService {protected String deployPath;protected String deployBasePath;//service operate requestprotected BtpDeployServiceBaseEntity serviceBaseEntity;public BtpAbstractService(BtpDeployServiceBaseEntity serviceBaseEntity) {this.serviceBaseEntity = serviceBaseEntity;}protected boolean isDeployBasePathEnvEmpty() {deployBasePath = StringUtils.trimToEmpty(getDeployBasePath());return StringUtils.isBlank(deployBasePath);}protected String getDeployBasePath() {return getEnvByName(BtpDeployNodeEnvType.BTP_DEPLOY_NODE_ENV_TYPE_DEPLOY_HOMEPATH.getValue());}protected String getEnvByName(String name) {if (serviceBaseEntity == null || CollectionUtil.isEmpty(serviceBaseEntity.getEnvMap())) return null;if (serviceBaseEntity.getEnvMap().containsKey(name)) return serviceBaseEntity.getEnvMap().get(name).getEnvValue();return null;}protected void updateDeployPath() {deployPath = String.format("%s/%s", fixFsFilePath(deployBasePath), serviceBaseEntity.getServiceId());}protected boolean checkNodeNetState() {return TcpHelper.isRemoteAlive(serviceBaseEntity.getNodeHost(), serviceBaseEntity.getNodePort());}protected String shellDisableEchoCmd() {return " >> /dev/null 2>&1";}protected void sleepCmd() {sleep(500);}protected void sleep3() {sleep(2000);}protected void sleep5() {sleep(5000);}protected void sleep(int timeout) {try {Thread.sleep(timeout);} catch (InterruptedException e) {}}protected String fixFsFilePath(String path) {if (path == null || path.length() == 0) return "";if (!path.endsWith("/")) return path;return path.substring(0, path.length() - 1);}protected boolean isDeployBasePathValid() {return deployBasePath != null && deployBasePath.startsWith("/");}abstract protected void preCheck() throws BtpDeployException;abstract protected void nextCheck() throws BtpDeployException;abstract protected void process() throws BtpDeployException;abstract protected void rollBack() throws BtpDeployException;} 
BtpAbstractSSHService类/** * <p>Title: ssh 操作</p> * <p>Description: </p> * <p>Author: lehoon</p> * <p>Date: 2022/1/20 15:38</p> */@Slf4jpublic abstract class BtpAbstractSSHService extends BtpAbstractService {//ssh connectionprotected Connection connection = null;public BtpAbstractSSHService(BtpDeployServiceBaseEntity serviceBaseEntity) {super(serviceBaseEntity);}public void service() throws BtpDeployException {preCheck();try {login(1000);} catch (BtpDeployException e) {log.error("登陆远程服务器失败. ", e);throw e;}try {nextCheck();sleep3();process();disConnect();} catch (BtpDeployException e) {log.error("部署服务操作失败, 错误信息,", e);rollBack();disConnect();throw e;} finally {disConnect();}}public void disConnect() {if (connection == null) return;connection.close();connection = null;}/*** 登陆远程服务器* @param timeout* @throws Exception*/public void login(int timeout) throws BtpDeployException {connection = new Connection(serviceBaseEntity.getNodeHost(), serviceBaseEntity.getNodePort());try {connection.connect(null, timeout, 0);boolean isAuthenticate = connection.authenticateWithPassword(serviceBaseEntity.getUserName(), serviceBaseEntity.getPassword());if (!isAuthenticate) {throw new BtpDeployException("用户名密码错误,登陆失败");}} catch (IOException e) {log.error("登陆远程服务器失败,", e);if (e.getCause().getMessage().indexOf("method password not supported") != -1) {throw new BtpDeployException("远程服务器不支持密码认证, 请修改ssh配置文件");}throw new BtpDeployException("登陆远程服务器失败, 请检查原因");} catch (Exception e){throw new BtpDeployException("登陆远程服务器失败, 请检查原因");}}private void checkConnectState() throws IOException {if (connection == null) throw new IOException("未与服务器建立连接, 不能执行命令.");if (!connection.isAuthenticationComplete()) throw new IOException("与服务器连接认证未通过, 不能执行命令.");}private String readCmdResult(InputStream inputStream) {StringBuilder result = new StringBuilder(1024);try {InputStream stdout = new StreamGobbler(inputStream);BufferedReader br = new BufferedReader(new InputStreamReader(stdout));String cmdResLine = null;while (true) {cmdResLine = br.readLine();if (cmdResLine == null) {break;}result.Append(cmdResLine);}} catch (IOException e) {log.error("读取远程服务器shell指令结果失败, ", e);}return result.toString();}public boolean executeCmd(String cmd) throws BtpDeploySSHExecException {try {return execute1(cmd);} catch (Exception e) {log.error(e.getMessage());throw new BtpDeploySSHExecException(e.getMessage());}}private Session openSession() throws Exception {checkConnectState();try {return connection.openSession();} catch (Exception e) {e.printStackTrace();log.error(e.getMessage());throw new Exception("打开终端执行环境会话失败,执行命令失败.");}}/*** 执行命令* @param cmd* @return* @throws IOException*/public String execute(String cmd) throws Exception {sleepCmd();Session session = openSession();preHandleSession(session);session.execCommand(cmd);String result = readCmdResult(session.getStdout());log.info("执行命令execute[{}],返回结果为[{}]",cmd, result);session.close();return result;}public boolean execute1(String cmd) throws Exception {sleepCmd();Session session = openSession();preHandleSession(session);session.execCommand(cmd);String result = readCmdResult(session.getStdout());log.info("执行命令execute1[{}],返回结果为[{}]", cmd, result);int code = 0;try {code = session.getExitStatus();log.info("执行命令execute1[{}],操作码为[{}],返回结果为[{}]", cmd, code, result);} catch (Exception e) {log.error("执行命令出错", e.fillInStackTrace());} finally {if (session != null) session.close();}return code == 0;}/*** 创建目录* @param dir* @return*/public String mkdir(String dir) throws BtpDeploySSHExecException {String cmd = String.format("mkdir -p %s", dir);try {return execute(cmd);} catch (Exception e) {log.error("创建目录失败,", e);throw new BtpDeploySSHExecException(e.getMessage());}}public boolean mkdir1(String dir) throws BtpDeploySSHExecException {String cmd = String.format("mkdir -p %s", dir);return executeCmd(cmd);}public boolean createDirectory(String directory) throws BtpDeploySSHExecException{return mkdir1(directory);}/*** 解压zip文件到指定目录* @param zipSrc* @param distDir* @return*/public boolean unzip(String zipSrc, String distDir) throws BtpDeploySSHExecException {String cmd = String.format("unzip -oq %s -d %s", zipSrc, distDir);return executeCmd(cmd);}/*** 修改文件内容* @param src* @param dist* @param filePath* @return* @throws Exception*/public String replaceInFile(String src, String dist, String filePath) throws BtpDeploySSHExecException {String cmd = String.format("sed -i 's/%s/%s/' %s", src, dist, filePath);try {return execute(cmd);} catch (Exception e) {log.error("修改文件内容失败", e);throw new BtpDeploySSHExecException();}}public boolean rmdir(String filePath) throws BtpDeploySSHExecException {if (filePath == null || filePath.length() == 0) return false;for (String path : SAFE_DELETE_FILESYSTEM_PATH_DEFAULT) {if (path.equalsIgnoreCase(filePath)) throw new BtpDeploySSHExecException(String.format("目录[%s]不允许删除", filePath));}String cmd = String.format("rm -rf %s", filePath);return executeCmd(cmd);}protected boolean deleteDirectory(String directory) throws BtpDeploySSHExecException {if (directory == null || directory.length() == 0 || "/".equalsIgnoreCase(directory)) return true;String cmd = String.format("rm -rf %s", directory);return executeCmd(cmd);}/*** 删除文件* @return* @throws IOException*/protected boolean deleteFile(String filePath) throws BtpDeploySSHExecException {if (filePath == null || filePath.length() == 0 || "/".equalsIgnoreCase(filePath)) return true;String cmd = String.format("rm -rf %s", filePath);return executeCmd(cmd);}protected boolean deleteFile1(String filePath) {try {return deleteFile(filePath);} catch (BtpDeploySSHExecException e) {return false;}}/*** 文件拷贝:war包+策略zip文件* src=https://www.isolves.com/it/cxkf/yy/JAVA/2022-03-17/路径+文件名;des=目的路径** */public void copyDoucment(String src, String des)throws BtpDeploySSHExecException {if (connection == null) throw new BtpDeploySSHExecException("未与服务器建立连接, 不能执行上传文件命令.");try {SCPClient scpClient = connection.createSCPClient();scpClient.put(src, des);} catch (IOException e) {log.error("上传文件到远程服务器失败,", e);throw new BtpDeploySSHExecException();}}/*** 进入指定目录并返回目录名称* @param basePath* @return* @throws IOException*/public String cmdPwd(String basePath) throws BtpDeploySSHExecException {String cmd = String.format("cd %s && pwd", basePath);try {return execute(cmd);} catch (Exception e) {log.error(String.format("切换文件目录失败,目录[%s]不存在", basePath), e);throw new BtpDeploySSHExecException();}}public String moveFile(String oldPath, String newPath) throws BtpDeploySSHExecException {String cmd = String.format("mv %s %s", oldPath, newPath);try {return execute(cmd);} catch (Exception e) {log.error(String.format("移动文件失败,原文件[%s]目标目录[%s]不存在", oldPath, newPath), e);throw new BtpDeploySSHExecException();}}public String lsCmd(String filePath) throws BtpDeploySSHExecException {String cmd = String.format("ls %s", filePath);try {return execute(cmd);} catch (Exception e) {log.error(String.format("获取文件路径失败,文件[%s]不存在", filePath), e);throw new BtpDeploySSHExecException();}}public boolean checkFileExist(String filePath) throws BtpDeploySSHExecException {String checkFilePath = lsCmd(filePath);if (filePath.equalsIgnoreCase(checkFilePath)) {return true;}return false;}/*** 上传文件到远程服务器* @param localFileName* @param remotePath* @param remoteFileName* @throws IOException*/public void uploadFileToRemote(String localFileName, String remotePath, String remoteFileName)throws BtpDeploySSHExecException {if (connection == null) throw new BtpDeploySSHExecException("未与服务器建立连接, 不能执行上传文件命令.");try {SCPClient scpClient = connection.createSCPClient();// 建立SCP客户端:就是为了安全远程传输文件scpClient.put(localFileName, remoteFileName, remotePath, "0600");} catch (IOException e) {log.error("上传文件到远程服务器失败,", e);throw new BtpDeploySSHExecException();}}public boolean uploadFile2Remote(String localFileName, String remotePath, String remoteFileName) {try {uploadFileToRemote(localFileName, remotePath, remoteFileName);return true;} catch (Exception e) {return false;}}protected boolean checkDeployBasePathExist() throws BtpDeploySSHExecException {String tempPathPwd = cmdPwd(deployBasePath);if (StringUtils.isBlank(tempPathPwd)) {log.info("远程服务器上部署根目录在远程服务器上不存在, {}", deployBasePath);return false;}deployBasePath = tempPathPwd;return true;}protected boolean checkDeployPathExist() throws BtpDeploySSHExecException {String tempPathPwd = cmdPwd(deployPath);if (StringUtils.isBlank(tempPathPwd)) {log.info("远程服务器上部署目录在远程服务器上不存在{}", deployPath);return false;}deployPath = tempPathPwd;return true;}protected boolean dos2unix(String filePath) throws BtpDeploySSHExecException {if (filePath == null || filePath.length() == 0) return false;String cmd = String.format("dos2unix %s", filePath);return executeCmd(cmd);}protected String getFileName(String filename) {if (filename == null || filename.length() == 0) return null;return filename.substring(0, filename.lastIndexOf("."));}private void preHandleSession(Session session) throws IOException {session.requestPTY("vt100");}private static List


推荐阅读