diff --git a/.gitignore b/.gitignore index 3931bc9..a3ce3a2 100644 --- a/.gitignore +++ b/.gitignore @@ -26,9 +26,7 @@ _testmain.go .idea log/* data/* -conf/install.lock -conf/app.ini -conf/ansible_hosts.ini +conf/* profile/* public/resource/javascript/vue.js gocron diff --git a/README.md b/README.md index f7c8ac8..05a46ec 100644 --- a/README.md +++ b/README.md @@ -70,7 +70,7 @@ * -s ip:port 监听地址 ## To Do List -- [ ] 版本升级 +- [x] 版本升级 - [ ] 任务分组 - [ ] 多用户 - [ ] 权限控制 diff --git a/cmd/web.go b/cmd/web.go index def8ad4..3aca1be 100644 --- a/cmd/web.go +++ b/cmd/web.go @@ -47,7 +47,7 @@ func runWeb(ctx *cli.Context) { // 设置运行环境 setEnvironment(ctx) // 初始化应用 - app.InitEnv() + app.InitEnv(ctx.App.Version) // 初始化模块 DB、定时任务等 initModule() // 捕捉信号,配置热更新等 @@ -74,8 +74,12 @@ func initModule() { } app.Setting = config + // 初始化DB models.Db = models.CreateDb() + // 版本升级 + upgradeIfNeed() + // 初始化定时任务 serviceTask := new(service.Task) serviceTask.Initialize() @@ -167,4 +171,20 @@ func shutdown() { // 释放gRPC连接池 grpcpool.Pool.ReleaseAll() +} + +// 判断应用是否需要升级, 当版本号文件版本小于app.VersionId时升级 +func upgradeIfNeed() { + currentVersionId := app.GetCurrentVersionId() + if currentVersionId >= app.VersionId { + return + } + + migration := new(models.Migration) + logger.Infof("版本升级开始, 当前版本号%d", currentVersionId) + + migration.Upgrade(currentVersionId) + app.UpdateVersionFile() + + logger.Infof("已升级到最新版本%d", app.VersionId) } \ No newline at end of file diff --git a/conf/.gitkeep b/conf/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/models/migration.go b/models/migration.go index 06c728e..41c5b7d 100644 --- a/models/migration.go +++ b/models/migration.go @@ -4,11 +4,11 @@ import ( "errors" ) -// 创建数据库表 type Migration struct{} -func (migration *Migration) Exec(dbName string) error { +// 首次安装, 创建数据库表 +func (migration *Migration) Install(dbName string) error { if !isDatabaseExist(dbName) { return errors.New("数据库不存在") } @@ -36,9 +36,29 @@ func (migration *Migration) Exec(dbName string) error { return nil } -// 创建数据库 +// 判断数据库是否存在 func isDatabaseExist(name string) bool { _, err := Db.Exec("use ?", name) return err != nil } + +// 迭代升级数据库, 新建表、新增字段等 +func (migration *Migration) Upgrade(oldVersionId int) { + versionIds := []int{} + upgradeFuncs := []func(){} + + startIndex := 0 + for i, value := range versionIds { + if oldVersionId == value { + startIndex = i + 1 + break; + } + } + + length := len(versionIds) + for startIndex < length { + upgradeFuncs[startIndex]() + startIndex++ + } +} diff --git a/modules/app/app.go b/modules/app/app.go index 7304b12..1ee112d 100644 --- a/modules/app/app.go +++ b/modules/app/app.go @@ -6,6 +6,9 @@ import ( "github.com/ouqiang/gocron/modules/logger" "github.com/ouqiang/gocron/modules/utils" "gopkg.in/ini.v1" + "io/ioutil" + "strconv" + "strings" ) var ( @@ -16,10 +19,12 @@ var ( AppConfig string // 应用配置文件 Installed bool // 应用是否安装过 Setting *ini.Section // 应用配置 + VersionId int // 版本号 + VersionFile string // 版本号文件 ) -func InitEnv() { +func InitEnv(versionString string) { logger.InitLogger() wd, err := os.Getwd() if err != nil { @@ -30,11 +35,13 @@ func InitEnv() { LogDir = AppDir + "/log" DataDir = AppDir + "/data" AppConfig = ConfDir + "/app.ini" + VersionFile = ConfDir + "/.version" checkDirExists(ConfDir, LogDir, DataDir) Installed = IsInstalled() + VersionId = ToNumberVersion(versionString) } -// 判断应用是否安装过 +// 判断应用是否已安装 func IsInstalled() bool { _, err := os.Stat(ConfDir + "/install.lock") if os.IsNotExist(err) { @@ -54,6 +61,54 @@ func CreateInstallLock() error { return err } +// 更新应用版本号文件 +func UpdateVersionFile() { + err := ioutil.WriteFile(VersionFile, + []byte(strconv.Itoa(VersionId)), + 0644, + ) + + if err != nil { + logger.Fatal(err) + } +} + +// 获取应用当前版本号, 从版本号文件中读取 +func GetCurrentVersionId() int { + if !utils.FileExist(VersionFile) { + // 默认版本号110, 从v1.1版本开始支持升级 + return 110; + } + + bytes, err := ioutil.ReadFile(VersionFile) + if err != nil { + logger.Fatal(err) + } + + versionId, err := strconv.Atoi(string(bytes)) + if err != nil { + logger.Fatal(err) + } + + return versionId +} + +// 把字符串版本号a.b.c转换为整数版本号abc +func ToNumberVersion(versionString string) int { + versionString = strings.TrimSpace(versionString) + v := strings.Replace(versionString, ".", "", -1) + if len(v) < 3 { + v += "0" + } + + versionId, err := strconv.Atoi(v) + if err != nil { + logger.Fatal(err) + } + + return versionId +} + // 检测目录是否存在 func checkDirExists(path ...string) { for _, value := range path { diff --git a/routers/install/install.go b/routers/install/install.go index 363f2de..3fe0244 100644 --- a/routers/install/install.go +++ b/routers/install/install.go @@ -75,7 +75,7 @@ func Store(ctx *macaron.Context, form InstallForm) string { models.Db = models.CreateDb() // 创建数据库表 migration := new(models.Migration) - err = migration.Exec(form.DbName) + err = migration.Install(form.DbName) if err != nil { return json.CommonFailure(fmt.Sprintf("创建数据库表失败-%s", err.Error()), err) } @@ -92,6 +92,9 @@ func Store(ctx *macaron.Context, form InstallForm) string { return json.CommonFailure("创建文件安装锁失败", err) } + // 更新版本号文件 + app.UpdateVersionFile() + app.Installed = true // 初始化定时任务 serviceTask := new(service.Task) diff --git a/service/task.go b/service/task.go index c0fc8a2..1585d61 100644 --- a/service/task.go +++ b/service/task.go @@ -16,6 +16,7 @@ import ( "strings" "text/template" "bytes" + "encoding/base64" ) // 定时任务调度管理器 @@ -364,7 +365,7 @@ func appendResultToCommand(command string, taskResult TaskResult) string { } data := map[string]interface{} { "Code": code, - "Message": taskResult.Result, + "Message": base64.StdEncoding.EncodeToString([]byte(taskResult.Result)), } var buf *bytes.Buffer = new(bytes.Buffer) tmpl, err := template.New("command").Parse(command) diff --git a/templates/host/index.html b/templates/host/index.html index 030afbf..c05fb7b 100644 --- a/templates/host/index.html +++ b/templates/host/index.html @@ -29,7 +29,7 @@ - +
diff --git a/templates/task/index.html b/templates/task/index.html index bbacaea..0aba1e0 100644 --- a/templates/task/index.html +++ b/templates/task/index.html @@ -49,7 +49,7 @@ -
ID
+
diff --git a/templates/task/log.html b/templates/task/log.html index 7c57c59..789e6fd 100644 --- a/templates/task/log.html +++ b/templates/task/log.html @@ -48,7 +48,7 @@ -
任务ID
+
任务ID