All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.yes.tools.build.handle.DeployHandle Maven / Gradle / Ivy

There is a newer version: 2.0.4
Show newest version
package org.yes.tools.build.handle;

import com.jcraft.jsch.ChannelExec;
import com.jcraft.jsch.ChannelSftp;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import org.apache.maven.plugin.logging.Log;
import org.yes.tools.build.bo.DeployBo;
import org.yes.tools.build.enums.DeployTypeEnums;
import org.yes.tools.build.utils.EXECChannel;
import org.yes.tools.build.utils.SFTPChannel;
import org.yes.tools.build.utils.TemplateUtils;

import java.io.*;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

/**
 * @author Co.
 * @name DeployHandle
 * @date 2023/9/12 19:12
 */
public class DeployHandle {

    private String mode;

    private DeployBo.Remote remote;
    private DeployBo.CloudImage cloudImage;
    private DeployBo.Project project;

    private Log log;

    public DeployHandle(String mode, DeployBo.Remote remote, DeployBo.CloudImage cloudImage, DeployBo.Project project, Log log) {
        this.mode = mode;
        this.remote = remote;
        this.cloudImage = cloudImage;
        this.project = project;
        this.log = log;
    }

    public void run() throws Exception {
        DeployTypeEnums enumValue = DeployTypeEnums.getEnumValue(mode);
        if (Objects.isNull(enumValue)) {
            throw new Exception("不存在【" + mode + "】模式");
        }
        switch (enumValue) {
            case CLOUD_IMAGE:
                cloudImageDeploy();
                break;
            case LOCAL_IMAGE:
                localImageDeploy();
                break;
            case JAR:
                jarDeploy();
                break;
            default:
                log.error("--------------------------无" + mode + "部署模式----------------------------");
        }
    }

    /**
     * 云镜像部署
     */
    private void cloudImageDeploy() throws Exception {
        String targetPathStr = System.getProperty("user.dir") + "/release/";
        String shPathUrl = targetPathStr + project.getArtifactId() + "/run-service.sh";

//        //生成sh到目录的release目录中
//        log.info("------------------------------正在生成SH文件-----------------------------------");
//        File targetFile = new File(shPathUrl);
//        Template template = TemplateUtils.getTemplate("service.sh.ftl");
//        targetFile.getParentFile().mkdirs();
//        FileOutputStream file = new FileOutputStream(targetFile);
//        OutputStreamWriter out = new OutputStreamWriter(file, "utf-8");
//        Map params = new HashMap<>();
//        params.put("cloudImage", cloudImage);
//        params.put("project", project);
//        template.process(params, out);
//        out.close();

        String servicePathUrl = "/opt/" + project.getArtifactId();
        EXECChannel execChannel = new EXECChannel();
        SFTPChannel sftpChannel = new SFTPChannel();
        try {
            //把sh上传到服务器中
            log.info("------------------------------正在上传服务器-----------------------------------");
            ChannelSftp chSftp = sftpChannel.getChannel(remote, log);
            try {
                chSftp.ls(servicePathUrl);
            } catch (Exception e) {
                chSftp.mkdir(servicePathUrl);
            }
            chSftp.put(shPathUrl, servicePathUrl + "/run-service.sh", ChannelSftp.OVERWRITE);
            chSftp.quit();
            log.info("------------------------------上传服务器成功-----------------------------------");
            //运行sh
            log.info("-------------------------------服务器运行SH-----------------------------------");
            ChannelExec channelExec = execChannel.getChannel(remote, log);
            // 执行脚本命令
            channelExec.setCommand("sh " + servicePathUrl + "/run-service.sh");
            // 获取执行脚本可能出现的错误日志
            channelExec.setErrStream(System.err);
            //脚本执行结果输出,对于程序来说是输入流
            InputStream in = channelExec.getInputStream();
            // 5 秒执行管道超时
            channelExec.connect(5000);
            // 从远程主机读取输入流,获得脚本执行结果
            byte[] tmp = new byte[1024];
            log.info("-------------------------------开始执行--------------------------------------");
            while (true) {
                while (in.available() > 0) {
                    int i = in.read(tmp, 0, 1024);
                    if (i < 0) {
                        break;
                    }
                    //执行结果打印到程序控制台
                    System.out.print(new String(tmp, 0, i));
                }
                if (channelExec.isClosed()) {
                    if (in.available() > 0) {
                        continue;
                    }
                    //获取退出状态,状态0表示脚本被正确执行
                    log.info("------------------------------执行结束--------------------------------------");
                    break;
                }
            }
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage());
        } finally {
            execChannel.closeChannel();
            sftpChannel.closeChannel();
            log.info("--------------------------------发布成功------------------------------------");
        }
    }

    /**
     * 本地镜像部署
     */
    private void localImageDeploy() throws Exception {
        String targetPathStr = System.getProperty("user.dir") + "/release/";
        String filePathUrl = targetPathStr + project.getArtifactId();

//        FileWriter fw = null;
//        BufferedWriter bufw = null;
//        File file = new File(filePathUrl + "/build.sh");
//        try {
//            //创建输出流
//            //true代表追加写入内容至文件末尾
//            fw = new FileWriter(file, true);
//            bufw = new BufferedWriter(fw);
//            //输出
//            String temp = "docker run -d -p %s --network=host --name=%s-%s -e NACOS_ACTIVE=%s -e ACTIVE=%s %s -e TZ=Asia/Shanghai -e JAVA_OPTS=\"%s\" %s:%s\n" +
//                    "echo \"---------------------------------------启动完成--------------------------------\"";
//            bufw.write(String.format(temp, project.getPort().get(0) + ":" + project.getPort().get(0),
//                    project.getArtifactId(),
//                    project.getVersion(),
//                    project.getActive(),
//                    project.getActive(),
//                    project.getDockerParameter(),
//                    project.getJvmParameter(),
//                    project.getArtifactId(),
//                    project.getVersion()));
//            bufw.newLine();
//        } catch (IOException e) {
//            e.printStackTrace();
//        } finally {
//            //出现异常后在finally中关闭输出流
//            if (bufw != null) {
//                bufw.close();
//            }
//            if (fw != null) {
//                fw.close();
//            }
//        }
        String servicePathUrl = "/opt/" + project.getArtifactId();
        EXECChannel execChannel = new EXECChannel();
        SFTPChannel sftpChannel = new SFTPChannel();

        try {
            //把 build.sh DockerFile jar包 上传到服务器
            log.info("------------------------------正在上传服务器-----------------------------------");
            ChannelSftp chSftp = sftpChannel.getChannel(remote, log);
            try {
                chSftp.ls(servicePathUrl);
            } catch (Exception e) {
                chSftp.mkdir(servicePathUrl);
            }
            chSftp.put(filePathUrl + "/build.sh", servicePathUrl + "/build.sh", ChannelSftp.OVERWRITE);
            chSftp.put(filePathUrl + "/Dockerfile", servicePathUrl + "/Dockerfile", ChannelSftp.OVERWRITE);
            chSftp.put(filePathUrl + "/" + project.getArtifactId() + "-" + project.getVersion() + ".jar", servicePathUrl + "/" + project.getArtifactId() + "-" + project.getVersion() + ".jar", ChannelSftp.OVERWRITE);
            chSftp.quit();
            log.info("------------------------------上传服务器成功-----------------------------------");
            //运行build.sh
            log.info("-------------------------------服务器运行SH-----------------------------------");
            ChannelExec channelExec = execChannel.getChannel(remote, log);
            // 执行脚本命令
            channelExec.setCommand("sh " + servicePathUrl + "/build.sh");
            // 获取执行脚本可能出现的错误日志
            channelExec.setErrStream(System.err);
            //脚本执行结果输出,对于程序来说是输入流
            InputStream in = channelExec.getInputStream();
            // 5 秒执行管道超时
            channelExec.connect(5000);
            // 从远程主机读取输入流,获得脚本执行结果
            byte[] tmp = new byte[1024];
            log.info("-------------------------------开始执行--------------------------------------");
            while (true) {
                while (in.available() > 0) {
                    int i = in.read(tmp, 0, 1024);
                    if (i < 0) {
                        break;
                    }
                    //执行结果打印到程序控制台
                    System.out.print(new String(tmp, 0, i));
                }
                if (channelExec.isClosed()) {
                    if (in.available() > 0) {
                        continue;
                    }
                    //获取退出状态,状态0表示脚本被正确执行
                    log.info("------------------------------执行结束--------------------------------------");
                    break;
                }
            }
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage());
        } finally {
            execChannel.closeChannel();
            sftpChannel.closeChannel();
        }
    }


    /**
     * jar包部署
     */
    private void jarDeploy() throws Exception {
        String targetPathStr = System.getProperty("user.dir") + "/release/";
        String filePathUrl = targetPathStr + project.getArtifactId();

//        //生成sh
//        log.info("------------------------------正在生成SH文件-----------------------------------");
//        File targetFile = new File(filePathUrl + "/jar-start.sh");
//        Template template = TemplateUtils.getTemplate("jar.sh.ftl");
//        targetFile.getParentFile().mkdirs();
//        FileOutputStream file = new FileOutputStream(targetFile);
//        OutputStreamWriter out = new OutputStreamWriter(file, "utf-8");
//        Map params = new HashMap<>();
//        params.put("cloudImage", cloudImage);
//        params.put("project", project);
//        template.process(params, out);
//        out.close();
//        downloadJdk(filePathUrl);

        //上传 sh jar包 jdk包

        String servicePathUrl = "/opt/" + project.getArtifactId();
        EXECChannel execChannel = new EXECChannel();
        SFTPChannel sftpChannel = new SFTPChannel();

        try {
            //把 build.sh DockerFile jar包 上传到服务器
            log.info("------------------------------正在上传服务器-----------------------------------");
            ChannelSftp chSftp = sftpChannel.getChannel(remote, log);
            try {
                chSftp.ls(servicePathUrl);
            } catch (Exception e) {
                chSftp.mkdir(servicePathUrl);
            }
            chSftp.put(filePathUrl + "/jar-start.sh", servicePathUrl + "/jar-start.sh", ChannelSftp.OVERWRITE);
            chSftp.put(filePathUrl + "/downloadJdk.sh", "/opt/downloadJdk.sh", ChannelSftp.OVERWRITE);
            chSftp.put(filePathUrl + "/" + project.getArtifactId() + "-" + project.getVersion() + ".jar", servicePathUrl + "/" + project.getArtifactId() + "-" + project.getVersion() + ".jar", ChannelSftp.OVERWRITE);
            chSftp.quit();
            log.info("------------------------------上传服务器成功-----------------------------------");
            //运行sh
            log.info("-------------------------------服务器运行SH-----------------------------------");
            ChannelExec channelExec = execChannel.getChannel(remote, log);
            // 执行脚本命令
            channelExec.setCommand("sh /opt/downloadJdk.sh &&" +
                    "sh " + servicePathUrl + "/jar-start.sh restart");
            // 获取执行脚本可能出现的错误日志
            channelExec.setErrStream(System.err);
            //脚本执行结果输出,对于程序来说是输入流
            InputStream in = channelExec.getInputStream();
            // 5 秒执行管道超时
            channelExec.connect(5000);
            // 从远程主机读取输入流,获得脚本执行结果
            byte[] tmp = new byte[1024];
            log.info("-------------------------------开始执行--------------------------------------");
            while (true) {
                while (in.available() > 0) {
                    int i = in.read(tmp, 0, 1024);
                    if (i < 0) {
                        break;
                    }
                    //执行结果打印到程序控制台
                    System.out.print(new String(tmp, 0, i));
                }
                if (channelExec.isClosed()) {
                    if (in.available() > 0) {
                        continue;
                    }
                    //获取退出状态,状态0表示脚本被正确执行
                    log.info("------------------------------执行结束--------------------------------------");
                    break;
                }
            }
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage());
        } finally {
            execChannel.closeChannel();
            sftpChannel.closeChannel();
        }
    }

    /**
     * 下载jdk
     *
     * @param filePathUrl
     * @throws IOException
     * @throws TemplateException
     */
    void downloadJdk(String filePathUrl) throws IOException, TemplateException {
        File targetFile = new File(filePathUrl + "/downloadJdk.sh");
        Template template = TemplateUtils.getTemplate("downloadJdk.sh.ftl");
        targetFile.getParentFile().mkdirs();
        FileOutputStream file = new FileOutputStream(targetFile);
        OutputStreamWriter out = new OutputStreamWriter(file, "utf-8");
        Map params = new HashMap<>();
        template.process(params, out);
        out.close();
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy