diff options
author | techknowlogick <techknowlogick@gitea.io> | 2021-10-16 02:14:34 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-10-16 02:14:34 -0400 |
commit | 8edda8b446200545b36432b57d00cd1972a5cb7e (patch) | |
tree | 2d4b6dd12a1f247d0e1b2459350b14e963f1b162 | |
parent | e18ea9e3491e872d0a0736322ace4def5680432c (diff) | |
download | gitea-8edda8b446200545b36432b57d00cd1972a5cb7e.tar.gz gitea-8edda8b446200545b36432b57d00cd1972a5cb7e.zip |
Add simple update checker to Gitea (#17212)
* Add simple update checker to Gitea
* update struct and remove comments
* fix lint
* Update custom/conf/app.example.ini
* Update docs/content/doc/advanced/config-cheat-sheet.en-us.md
Co-authored-by: delvh <dev.lh@web.de>
* Update custom/conf/app.example.ini
Co-authored-by: delvh <dev.lh@web.de>
* Update docs/content/doc/advanced/config-cheat-sheet.en-us.md
Co-authored-by: delvh <dev.lh@web.de>
* Update docs/content/doc/advanced/config-cheat-sheet.en-us.md
Co-authored-by: Steven <61625851+justusbunsi@users.noreply.github.com>
* Update docs/content/doc/advanced/config-cheat-sheet.en-us.md
* Update modules/cron/tasks_extended.go
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
* Update custom/conf/app.example.ini
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
* take PR feedback into account and display banner on admin dashboard for alerts
* Add more detailed message
* placate lint
* update per feedback
Co-authored-by: delvh <dev.lh@web.de>
Co-authored-by: Steven <61625851+justusbunsi@users.noreply.github.com>
Co-authored-by: 6543 <6543@obermui.de>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
-rw-r--r-- | custom/conf/app.example.ini | 13 | ||||
-rw-r--r-- | docs/content/doc/advanced/config-cheat-sheet.en-us.md | 13 | ||||
-rw-r--r-- | models/migrations/migrations.go | 2 | ||||
-rw-r--r-- | models/migrations/v199.go | 23 | ||||
-rw-r--r-- | models/update_checker.go | 121 | ||||
-rw-r--r-- | modules/cron/tasks_extended.go | 19 | ||||
-rw-r--r-- | routers/web/admin/admin.go | 2 | ||||
-rw-r--r-- | templates/admin/dashboard.tmpl | 5 |
8 files changed, 195 insertions, 3 deletions
diff --git a/custom/conf/app.example.ini b/custom/conf/app.example.ini index 07ca9f8409..bdc42480e4 100644 --- a/custom/conf/app.example.ini +++ b/custom/conf/app.example.ini @@ -1927,6 +1927,19 @@ PATH = ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Check for new Gitea versions +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;[cron.update_checker] +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;ENABLED = false +;RUN_AT_START = false +;ENABLE_SUCCESS_NOTICE = false +;SCHEDULE = @every 168h +;HTTP_ENDPOINT = https://dl.gitea.io/gitea/version.json + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Git Operation timeout in seconds ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;[git.timeout] diff --git a/docs/content/doc/advanced/config-cheat-sheet.en-us.md b/docs/content/doc/advanced/config-cheat-sheet.en-us.md index f02d8cbc37..251f6bd51a 100644 --- a/docs/content/doc/advanced/config-cheat-sheet.en-us.md +++ b/docs/content/doc/advanced/config-cheat-sheet.en-us.md @@ -23,8 +23,8 @@ or any corresponding location. When installing from a distribution, this will typically be found at `/etc/gitea/conf/app.ini`. The defaults provided here are best-effort (not built automatically). They are -accurately recorded in [app.example.ini](https://github.com/go-gitea/gitea/blob/master/custom/conf/app.example.ini) -(s/master/\<tag|release\>). Any string in the format `%(X)s` is a feature powered +accurately recorded in [app.example.ini](https://github.com/go-gitea/gitea/blob/main/custom/conf/app.example.ini) +(s/main/\<tag|release\>). Any string in the format `%(X)s` is a feature powered by [ini](https://github.com/go-ini/ini/#recursive-values), for reading values recursively. Values containing `#` or `;` must be quoted using `` ` `` or `"""`. @@ -824,9 +824,16 @@ NB: You must have `DISABLE_ROUTER_LOG` set to `false` for this option to take ef - `ENABLED`: **false**: Enable service. - `RUN_AT_START`: **false**: Run tasks at start up time (if ENABLED). - `NO_SUCCESS_NOTICE`: **false**: Set to true to switch off success notices. -- `SCHEDULE`: **@every 128h**: Cron syntax for scheduling a work, e.g. `@every 128h`. +- `SCHEDULE`: **@every 168h**: Cron syntax to set how often to check. - `OLDER_THAN`: **@every 8760h**: any action older than this expression will be deleted from database, suggest using `8760h` (1 year) because that's the max length of heatmap. +#### Cron - Check for new Gitea versions ('cron.update_checker') +- `ENABLED`: **false**: Enable service. +- `RUN_AT_START`: **false**: Run tasks at start up time (if ENABLED). +- `ENABLE_SUCCESS_NOTICE`: **true**: Set to false to switch off success notices. +- `SCHEDULE`: **@every 168h**: Cron syntax for scheduling a work, e.g. `@every 168h`. +- `HTTP_ENDPOINT`: **https://dl.gitea.io/gitea/version.json**: the endpoint that Gitea will check for newer versions + ## Git (`git`) - `PATH`: **""**: The path of git executable. If empty, Gitea searches through the PATH environment. diff --git a/models/migrations/migrations.go b/models/migrations/migrations.go index ef0c071417..3a41cf8891 100644 --- a/models/migrations/migrations.go +++ b/models/migrations/migrations.go @@ -350,6 +350,8 @@ var migrations = []Migration{ NewMigration("Add renamed_branch table", addRenamedBranchTable), // v198 -> v199 NewMigration("Add issue content history table", addTableIssueContentHistory), + // v199 -> v200 + NewMigration("Add remote version table", addRemoteVersionTable), } // GetCurrentDBVersion returns the current db version diff --git a/models/migrations/v199.go b/models/migrations/v199.go new file mode 100644 index 0000000000..64b21172c1 --- /dev/null +++ b/models/migrations/v199.go @@ -0,0 +1,23 @@ +// Copyright 2021 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package migrations + +import ( + "fmt" + + "xorm.io/xorm" +) + +func addRemoteVersionTable(x *xorm.Engine) error { + type RemoteVersion struct { + ID int64 `xorm:"pk autoincr"` + Version string `xorm:"VARCHAR(50)"` + } + + if err := x.Sync2(new(RemoteVersion)); err != nil { + return fmt.Errorf("Sync2: %v", err) + } + return nil +} diff --git a/models/update_checker.go b/models/update_checker.go new file mode 100644 index 0000000000..5b4fce69ec --- /dev/null +++ b/models/update_checker.go @@ -0,0 +1,121 @@ +// Copyright 2021 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package models + +import ( + "encoding/json" + "fmt" + "io/ioutil" + "net/http" + + "code.gitea.io/gitea/models/db" + "code.gitea.io/gitea/modules/proxy" + "code.gitea.io/gitea/modules/setting" + + "github.com/hashicorp/go-version" +) + +// RemoteVersion stores the remote version from the JSON endpoint +type RemoteVersion struct { + ID int64 `xorm:"pk autoincr"` + Version string `xorm:"VARCHAR(50)"` +} + +func init() { + db.RegisterModel(new(RemoteVersion)) +} + +// GiteaUpdateChecker returns error when new version of Gitea is available +func GiteaUpdateChecker(httpEndpoint string) error { + httpClient := &http.Client{ + Transport: &http.Transport{ + Proxy: proxy.Proxy(), + }, + } + + req, err := http.NewRequest("GET", httpEndpoint, nil) + if err != nil { + return err + } + resp, err := httpClient.Do(req) + if err != nil { + return err + } + defer resp.Body.Close() + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return err + } + + type v struct { + Latest struct { + Version string `json:"version"` + } `json:"latest"` + } + ver := v{} + err = json.Unmarshal(body, &ver) + if err != nil { + return err + } + + return UpdateRemoteVersion(ver.Latest.Version) + +} + +// UpdateRemoteVersion updates the latest available version of Gitea +func UpdateRemoteVersion(version string) (err error) { + sess := db.NewSession(db.DefaultContext) + defer sess.Close() + if err = sess.Begin(); err != nil { + return err + } + + currentVersion := &RemoteVersion{ID: 1} + has, err := sess.Get(currentVersion) + if err != nil { + return fmt.Errorf("get: %v", err) + } else if !has { + currentVersion.ID = 1 + currentVersion.Version = version + + if _, err = sess.InsertOne(currentVersion); err != nil { + return fmt.Errorf("insert: %v", err) + } + return nil + } + + if _, err = sess.Update(&RemoteVersion{ID: 1, Version: version}); err != nil { + return err + } + + return sess.Commit() +} + +// GetRemoteVersion returns the current remote version (or currently installed verson if fail to fetch from DB) +func GetRemoteVersion() string { + e := db.GetEngine(db.DefaultContext) + v := &RemoteVersion{ID: 1} + _, err := e.Get(&v) + if err != nil { + // return current version if fail to fetch from DB + return setting.AppVer + } + return v.Version +} + +// GetNeedUpdate returns true whether a newer version of Gitea is available +func GetNeedUpdate() bool { + curVer, err := version.NewVersion(setting.AppVer) + if err != nil { + // return false to fail silently + return false + } + remoteVer, err := version.NewVersion(GetRemoteVersion()) + if err != nil { + // return false to fail silently + return false + } + return curVer.LessThan(remoteVer) +} diff --git a/modules/cron/tasks_extended.go b/modules/cron/tasks_extended.go index 680f83e50c..6645e71d2c 100644 --- a/modules/cron/tasks_extended.go +++ b/modules/cron/tasks_extended.go @@ -131,6 +131,24 @@ func registerDeleteOldActions() { }) } +func registerUpdateGiteaChecker() { + type UpdateCheckerConfig struct { + BaseConfig + HTTPEndpoint string + } + RegisterTaskFatal("update_checker", &UpdateCheckerConfig{ + BaseConfig: BaseConfig{ + Enabled: true, + RunAtStart: false, + Schedule: "@every 168h", + }, + HTTPEndpoint: "https://dl.gitea.io/gitea/version.json", + }, func(ctx context.Context, _ *models.User, config Config) error { + updateCheckerConfig := config.(*UpdateCheckerConfig) + return models.GiteaUpdateChecker(updateCheckerConfig.HTTPEndpoint) + }) +} + func initExtendedTasks() { registerDeleteInactiveUsers() registerDeleteRepositoryArchives() @@ -142,4 +160,5 @@ func initExtendedTasks() { registerDeleteMissingRepositories() registerRemoveRandomAvatars() registerDeleteOldActions() + registerUpdateGiteaChecker() } diff --git a/routers/web/admin/admin.go b/routers/web/admin/admin.go index ce177ea090..ca5b157523 100644 --- a/routers/web/admin/admin.go +++ b/routers/web/admin/admin.go @@ -125,6 +125,8 @@ func Dashboard(ctx *context.Context) { ctx.Data["PageIsAdmin"] = true ctx.Data["PageIsAdminDashboard"] = true ctx.Data["Stats"] = models.GetStatistic() + ctx.Data["NeedUpdate"] = models.GetNeedUpdate() + ctx.Data["RemoteVersion"] = models.GetRemoteVersion() // FIXME: update periodically updateSystemStatus() ctx.Data["SysStatus"] = sysStatus diff --git a/templates/admin/dashboard.tmpl b/templates/admin/dashboard.tmpl index de01f95eab..79f031882e 100644 --- a/templates/admin/dashboard.tmpl +++ b/templates/admin/dashboard.tmpl @@ -3,6 +3,11 @@ {{template "admin/navbar" .}} <div class="ui container"> {{template "base/alert" .}} + {{if .NeedUpdate}} + <div class="ui negative message flash-error"> + <p>"Gitea {{.RemoteVersion | Str2html}} is now available, you are running {{.AppVer | Str2html}}. Check the <a href="https://blog.gitea.io">blog</a> for more details.</p> + </div> + {{end}} <h4 class="ui top attached header"> {{.i18n.Tr "admin.dashboard.statistic"}} </h4> |