Skip to content

Commit

Permalink
scp发布优化
Browse files Browse the repository at this point in the history
  • Loading branch information
hale.huo committed May 8, 2021
1 parent 0beb498 commit af93076
Show file tree
Hide file tree
Showing 11 changed files with 98 additions and 63 deletions.
3 changes: 1 addition & 2 deletions conf-sample.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ mailHost: smtp.163.com # 邮件服务器地址
mailPort: 465 # 邮件端口
mailUser: [email protected] # 邮件发送账户
mailPWD: xxx # 邮件授权密码
mailTo: [email protected] # 邮件发送地址,多个用;分割

appDir: ../apps # 要发布的应用目录
appDir: ../deploy_apps # 要发布的应用目录
hostName: http://localhost:8090 # 服务域名
84 changes: 60 additions & 24 deletions fe/page/project-add.html
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,15 @@
<div class="layui-inline">
<label class="layui-form-label">空间</label>
<div class="layui-input-inline">
<input type="text" name="namespace" lay-verify="required" autocomplete="off" class="layui-input">
<input type="text" name="namespace" lay-verify="required" autocomplete="off" class="layui-input" placeholder="项目分组">
</div>
</div>
<!-- <div class="layui-inline">
<label class="layui-form-label">子环境</label>
<div class="layui-input-inline">
<input type="text" name="clone" autocomplete="off" class="layui-input" placeholder="可选,字母或数字">
</div>
</div> -->
</div>
<div class="layui-form-item">
<label class="layui-form-label">发布方式</label>
Expand All @@ -55,29 +61,59 @@
<fieldset class="layui-elem-field layui-field-title" style="margin-top: 20px;">
<legend>任务配置</legend>
</fieldset>
<div class="layui-form-item">
<label class="layui-form-label">配置文件</label>
<div class="layui-input-block">
<textarea name="config" placeholder="请输入内容" class="layui-textarea" rows="20">
module.exports = {
apps : [{
script: 'index.js',
watch: '.'
}],

deploy : {
production : {
user : 'SSH_USERNAME',
host : 'SSH_HOSTMACHINE',
ref : 'origin/master',
repo : 'GIT_REPOSITORY',
path : 'DESTINATION_PATH',
'pre-deploy-local': '',
'post-deploy' : 'npm install && pm2 reload ecosystem.config.js --env production',
'pre-setup': 'npm config set registry https://registry.npm.taobao.org'
}
}
};</textarea>
<div class="layui-row">
<div class="layui-col-xs6 layui-col-sm6 layui-col-md6">
<div class="layui-form-item">
<label class="layui-form-label">配置文件</label>
<div class="layui-input-block">
<textarea name="config" placeholder="请输入内容" class="layui-textarea" rows="20">
module.exports = {
apps : [{
script: 'index.js',
watch: '.'
}],

deploy : {
production : {
user : 'SSH_USERNAME',
host : 'SSH_HOSTMACHINE',
ref : 'origin/master',
repo : 'GIT_REPOSITORY',
path : 'DESTINATION_PATH',
'pre-deploy-local': '',
'post-deploy' : 'npm install && pm2 reload ecosystem.config.js --env production',
'pre-setup': 'npm config set registry https://registry.npm.taobao.org'
}
}
};</textarea>
</div>
</div>
</div>
<div class="layui-col-xs6 layui-col-sm6 layui-col-md6">
<div class="layui-card">
<div class="layui-card-header">pm2配置说明</div>
<div class="layui-card-body">
<p><a href="https://pm2.keymetrics.io/docs/usage/deployment/" style="color: #01AAED;">见官方文档</a>
</p>
</div>
</div>
<div class="layui-card">
<div class="layui-card-header">scp配置说明</div>
<div class="layui-card-body">
<ul>
<li>user:用户名</li>
<li>host[]:主机地址</li>
<li>ref:分支</li>
<li>repo:仓库地址</li>
<li>path:项目部署路径,需要包含项目目录</li>
<li>preBuild:编译前置</li>
<li>build:编译命令</li>
<li>preDeploy:发布前置</li>
<li>postDeploy:发布命令</li>
<li>rsyncArgs:rsync参数</li>
</ul>
</div>
</div>
</div>
</div>
<div class="layui-form-item">
Expand Down
8 changes: 7 additions & 1 deletion fe/page/project-edit.html
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,12 @@
<input type="text" name="namespace" lay-verify="required" autocomplete="off" class="layui-input">
</div>
</div>
<!-- <div class="layui-inline">
<label class="layui-form-label">子环境</label>
<div class="layui-input-inline">
<input type="text" name="clone" autocomplete="off" class="layui-input" placeholder="可选,字母或数字">
</div>
</div> -->
</div>
<div class="layui-form-item">
<!-- 不可更改 -->
Expand Down Expand Up @@ -82,7 +88,7 @@
<li>host[]:主机地址</li>
<li>ref:分支</li>
<li>repo:仓库地址</li>
<li>path:项目部署路径</li>
<li>path:项目部署路径,需要包含项目目录</li>
<li>preBuild:编译前置</li>
<li>build:编译命令</li>
<li>preDeploy:发布前置</li>
Expand Down
3 changes: 3 additions & 0 deletions fe/page/projects.html
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@
{ type: "checkbox", width: 50 },
{ field: 'id', width: 80, title: 'ID', sort: true },
{ field: 'name', title: '项目名' },
// { field: 'clone', title: '子环境' },
{ field: 'status', title: '状态', sort: true },
{ field: 'env', title: '环境' },
{ field: 'namespace', title: '空间' },
Expand Down Expand Up @@ -151,6 +152,7 @@
//获取子页面的元素,进行数据渲染
body.find("input[name=id]").val(data.id);
body.find("input[name=name]").val(data.name);
body.find("input[name=clone]").val(data.clone);
body.find('select[name=env]').val(data.env);
body.find('input[name=namespace]').val(data.namespace);
body.find('textarea[name=config]').val(data.config);
Expand Down Expand Up @@ -189,6 +191,7 @@
//获取子页面的元素,进行数据渲染
body.contents().find("input[name=id]").val(data.id);
body.contents().find("input[name=name]").val(data.name);
body.contents().find("input[name=clone]").val(data.clone);
body.contents().find('input[name=env]').val(data.env);
body.contents().find('input[name=namespace]').val(data.namespace);
body.contents().find('textarea[name=config]').val(data.config);
Expand Down
2 changes: 1 addition & 1 deletion fe/page/quick-release.html
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@
const element = res.data[value];
var opt = "<optgroup label='" + value + "'>" + value;
element.forEach(item => {
opt += "<option value='" + item.name + "|" + item.deployType + "'>" + item.name + "</option>";
opt += "<option value='" + item.name + "|" + item.deployType + "'>" + item.name +(item.clone? "-" + item.clone:"") + "</option>";
});
opt += "</optgroup>";
$("#proList").append(opt);
Expand Down
1 change: 1 addition & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ func init() {
Conf, err = util.GetConf("./conf.yaml")
util.Conf = Conf
if err != nil {
log.Println("failed to open conf.yaml")
panic(err)
}
db.DB, err = gorm.Open(Conf.Dialects, Conf.Dbpath)
Expand Down
45 changes: 14 additions & 31 deletions pkg/exec/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ type (
PreBuild(deployConfig project.DeployConfig, projectName string) ([]byte, error)
Build(deployConfig project.DeployConfig, projectName string) ([]byte, error)
SyncCode(deployConfig project.DeployConfig, projectName string) ([]byte, error)
PreDeploy(deployConfig project.DeployConfig, projectName string) ([]byte, error)
PostDeploy(deployConfig project.DeployConfig, projectName string) ([]byte, error)
// PreDeploy(deployConfig project.DeployConfig, projectName string) ([]byte, error)
PostDeploy(deployConfig project.DeployConfig) ([]byte, error)
SendMessage(task task.Task)
}
)
Expand Down Expand Up @@ -62,6 +62,9 @@ func (u *execService) DeployControl(projectObj project.Project, taskID int) ([]b

// 1.克隆代码
projectDirName := fmt.Sprintf("%s", projectObj.Name)
// if projectObj.Clone != "" {
// projectDirName = fmt.Sprintf("%s-%s", projectObj.Name, projectObj.Clone)
// }
log.Println("克隆项目名:", projectDirName)
if exists := util.PathExists(path.Join(util.Conf.APPDir, projectDirName)); exists == false {
// 分支,gitrepo,
Expand Down Expand Up @@ -110,19 +113,9 @@ func (u *execService) DeployControl(projectObj project.Project, taskID int) ([]b
}
buffer.Write(output)

// 5.重启服务前置
if deployConfig.PreDeploy != "" {
output, err = u.PreDeploy(deployConfig, projectDirName)
if err != nil {
buffer.Write([]byte(err.Error()))
return buffer.Bytes(), err
}
buffer.Write(output)
}

// 6.同步代码到远程应用服务器后执行命令,如重启
// 5.同步代码到远程应用服务器后执行命令,如重启
if deployConfig.PostDeploy != "" {
output, err = u.PostDeploy(deployConfig, projectDirName)
output, err = u.PostDeploy(deployConfig)
if err != nil {
log.Println("远程命令执行异常:", err)
buffer.Write([]byte(err.Error()))
Expand Down Expand Up @@ -164,7 +157,7 @@ func (u *execService) CloneRepo(deployConfig project.DeployConfig, projectName s

// GitPull
func (u *execService) GitPull(deployConfig project.DeployConfig, projectName string) ([]byte, error) {
gitpull := fmt.Sprintf("cd %s; git pull origin %s; git log --oneline -1", path.Join(util.Conf.APPDir, projectName), deployConfig.Ref)
gitpull := fmt.Sprintf("cd %s; git pull origin %s; git log --oneline -2", path.Join(util.Conf.APPDir, projectName), deployConfig.Ref)
cmdOut, err := u.CmdSync(gitpull)
if err != nil {
log.Println("拉取代码失败:", err)
Expand Down Expand Up @@ -204,8 +197,8 @@ func (u *execService) SyncCode(deployConfig project.DeployConfig, projectName st
go func(host string, ch chan []byte, errCh chan error) {
// 用户名@IP:远程目录
remotePath := fmt.Sprintf("%s@%s:%s", deployConfig.User, host, deployConfig.Path)
// rsync参数,宿主机项目,目标机地址
cmd3 := fmt.Sprintf("rsync -av %s %s %s", deployConfig.RsyncArgs, path.Join(util.Conf.APPDir, projectName), remotePath)
// rsync参数,宿主机项目,目标目录
cmd3 := fmt.Sprintf("rsync -a %s %s/ %s", deployConfig.RsyncArgs, path.Join(util.Conf.APPDir, projectName), remotePath)
log.Println("同步代码:", cmd3)
cmdput, err := u.CmdSync(cmd3)
if err != nil {
Expand Down Expand Up @@ -238,27 +231,17 @@ L:
return buffer.Bytes(), outErr
}

// PreDeploy
func (u *execService) PreDeploy(deployConfig project.DeployConfig, projectName string) ([]byte, error) {
build := fmt.Sprintf("cd %s; %s", path.Join(util.Conf.APPDir, projectName), deployConfig.PreDeploy)
cmdOut, err := u.CmdSync(build)
if err != nil {
log.Println("应用服务器重启前置:", err)
return nil, err
}
return cmdOut, nil
}

// PostDeploy 远程应用服务器上发布 用户自定义命令:比如重启服务
// 利用ssh在远程服务器上执行
func (u *execService) PostDeploy(deployConfig project.DeployConfig, projectName string) ([]byte, error) {
func (u *execService) PostDeploy(deployConfig project.DeployConfig) ([]byte, error) {
hostLen := len(deployConfig.Host)
ch := make(chan []byte, hostLen)
// errch := make(chan error) //不需要缓冲,只要接收到一个错误就退出
for _, host := range deployConfig.Host {
go func(host string, ch chan []byte) {
// 用户名@IP 命令
ssh := fmt.Sprintf("ssh %s@%s \"cd %s; %s\"", deployConfig.User, host, path.Join(deployConfig.Path, projectName), deployConfig.PostDeploy)
// ssh user@remoteNode "cd /home ; ls"
// 用户名,IP,项目目录,前置命令, 命令
ssh := fmt.Sprintf("ssh %s@%s \"cd %s; %s; %s\"", deployConfig.User, host, deployConfig.Path, deployConfig.PreDeploy, deployConfig.PostDeploy)
cmdput, err := u.CmdSync(ssh)
if err != nil {
log.Println("postDeploy过程 远程命令执行失败:", err)
Expand Down
3 changes: 3 additions & 0 deletions pkg/project/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,9 @@ func NameListV2(c *gin.Context) {
for _, val := range list {
m := make(map[string]string)
m["title"] = "[" + val.Namespace + "]" + val.Name
// if val.Clone != "" {
// m["title"] = "[" + val.Namespace + "]" + val.Name + "-" + val.Clone
// }
m["value"] = val.Name
nameList = append(nameList, m)
}
Expand Down
5 changes: 3 additions & 2 deletions pkg/project/project-model.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@ package project
import "time"

type Project struct {
ID int `json:"id" gorm:"AUTO_INCREMENT;primary_key"`
Name string `json:"name" gorm:"type:varchar(20);unique_index"`
ID int `json:"id" gorm:"AUTO_INCREMENT;primary_key"`
Name string `json:"name" gorm:"type:varchar(20);unique_index"`
// Clone string `json:"clone" gorm:"type:varchar(20);comment:'同项目不同环境'"`
Status int `json:"status" gorm:"default:1;not null;comment:'1正常,0删除'"`
Env string `json:"env"`
Namespace string `json:"namespace"`
Expand Down
2 changes: 1 addition & 1 deletion tests/message_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ func TestDingTalk2(t *testing.T) {
func TestEmail(t *testing.T) {
Conf, _ := util.GetConf("../conf.yaml")
util.Conf = Conf
mailTo := strings.Split(Conf.MailTo, ";")
mailTo := strings.Split("[email protected];[email protected]", ";")
t.Log("mailTo", mailTo)
messageService := message.NewMessage()
err := messageService.SendEmail("朱雀", "测试", mailTo)
Expand Down
5 changes: 4 additions & 1 deletion util/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ type Config struct {
MailTo string `yaml:"mailTo"` // 邮件发送地址
DelayDeploy int `yaml:"delayDeploy"` // 延时发布时间,单位秒。默认5分钟
JWTSecret string `yaml:"JWTSecret"` // jwt安全密匙
HostName string `yaml:"hostName"` //服务地址
HostName string `yaml:"hostName"` // 服务地址,用于重置密码邮件中的链接
APPDir string `yaml:"appDir"` // 要发布的应用存储目录
}

Expand Down Expand Up @@ -58,6 +58,9 @@ func GetConf(filename string) (*Config, error) {
if c.Dialects == "" {
c.Dialects = "sqlite3"
}
if c.Env == "" {
c.Env = "prod"
}
return c, nil
}

Expand Down

0 comments on commit af93076

Please sign in to comment.