Skip to content

Commit 960c322

Browse files
authored
Refactor update checker to use AppState (#17387)
We have the `AppState` module now, it can store app related data easily. We do not need to create separate tables for each feature. So the update checker can use `AppState` instead of a one-row dedicate table. And the code of update checker is moved from `models` to `modules`.
1 parent 67561e7 commit 960c322

File tree

6 files changed

+48
-61
lines changed

6 files changed

+48
-61
lines changed

models/migrations/migrations.go

+3-1
Original file line numberDiff line numberDiff line change
@@ -351,9 +351,11 @@ var migrations = []Migration{
351351
// v198 -> v199
352352
NewMigration("Add issue content history table", addTableIssueContentHistory),
353353
// v199 -> v200
354-
NewMigration("Add remote version table", addRemoteVersionTable),
354+
NewMigration("No-op (remote version is using AppState now)", addRemoteVersionTableNoop),
355355
// v200 -> v201
356356
NewMigration("Add table app_state", addTableAppState),
357+
// v201 -> v202
358+
NewMigration("Drop table remote_version (if exists)", dropTableRemoteVersion),
357359
}
358360

359361
// GetCurrentDBVersion returns the current db version

models/migrations/v199.go

+2-11
Original file line numberDiff line numberDiff line change
@@ -5,19 +5,10 @@
55
package migrations
66

77
import (
8-
"fmt"
9-
108
"xorm.io/xorm"
119
)
1210

13-
func addRemoteVersionTable(x *xorm.Engine) error {
14-
type RemoteVersion struct {
15-
ID int64 `xorm:"pk autoincr"`
16-
Version string `xorm:"VARCHAR(50)"`
17-
}
18-
19-
if err := x.Sync2(new(RemoteVersion)); err != nil {
20-
return fmt.Errorf("Sync2: %v", err)
21-
}
11+
func addRemoteVersionTableNoop(x *xorm.Engine) error {
12+
// we used to use a table `remote_version` to store information for updater, now we use `AppState`, so this migration task is a no-op now.
2213
return nil
2314
}

models/migrations/v201.go

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// Copyright 2021 The Gitea Authors. All rights reserved.
2+
// Use of this source code is governed by a MIT-style
3+
// license that can be found in the LICENSE file.
4+
5+
package migrations
6+
7+
import (
8+
"xorm.io/xorm"
9+
)
10+
11+
func dropTableRemoteVersion(x *xorm.Engine) error {
12+
// drop the orphaned table introduced in `v199`, now the update checker also uses AppState, do not need this table
13+
_ = x.DropTables("remote_version")
14+
return nil
15+
}

modules/cron/tasks_extended.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"code.gitea.io/gitea/models"
1212
repo_module "code.gitea.io/gitea/modules/repository"
1313
"code.gitea.io/gitea/modules/setting"
14+
"code.gitea.io/gitea/modules/updatechecker"
1415
)
1516

1617
func registerDeleteInactiveUsers() {
@@ -145,7 +146,7 @@ func registerUpdateGiteaChecker() {
145146
HTTPEndpoint: "https://dl.gitea.io/gitea/version.json",
146147
}, func(ctx context.Context, _ *models.User, config Config) error {
147148
updateCheckerConfig := config.(*UpdateCheckerConfig)
148-
return models.GiteaUpdateChecker(updateCheckerConfig.HTTPEndpoint)
149+
return updatechecker.GiteaUpdateChecker(updateCheckerConfig.HTTPEndpoint)
149150
})
150151
}
151152

models/update_checker.go renamed to modules/updatechecker/update_checker.go

+23-46
Original file line numberDiff line numberDiff line change
@@ -2,29 +2,28 @@
22
// Use of this source code is governed by a MIT-style
33
// license that can be found in the LICENSE file.
44

5-
package models
5+
package updatechecker
66

77
import (
88
"encoding/json"
9-
"fmt"
109
"io/ioutil"
1110
"net/http"
1211

13-
"code.gitea.io/gitea/models/db"
12+
"code.gitea.io/gitea/modules/appstate"
1413
"code.gitea.io/gitea/modules/proxy"
1514
"code.gitea.io/gitea/modules/setting"
1615

1716
"github.com/hashicorp/go-version"
1817
)
1918

20-
// RemoteVersion stores the remote version from the JSON endpoint
21-
type RemoteVersion struct {
22-
ID int64 `xorm:"pk autoincr"`
23-
Version string `xorm:"VARCHAR(50)"`
19+
// CheckerState stores the remote version from the JSON endpoint
20+
type CheckerState struct {
21+
LatestVersion string
2422
}
2523

26-
func init() {
27-
db.RegisterModel(new(RemoteVersion))
24+
// Name returns the name of the state item for update checker
25+
func (r *CheckerState) Name() string {
26+
return "update-checker"
2827
}
2928

3029
// GiteaUpdateChecker returns error when new version of Gitea is available
@@ -49,60 +48,33 @@ func GiteaUpdateChecker(httpEndpoint string) error {
4948
return err
5049
}
5150

52-
type v struct {
51+
type respType struct {
5352
Latest struct {
5453
Version string `json:"version"`
5554
} `json:"latest"`
5655
}
57-
ver := v{}
58-
err = json.Unmarshal(body, &ver)
56+
respData := respType{}
57+
err = json.Unmarshal(body, &respData)
5958
if err != nil {
6059
return err
6160
}
6261

63-
return UpdateRemoteVersion(ver.Latest.Version)
62+
return UpdateRemoteVersion(respData.Latest.Version)
6463

6564
}
6665

6766
// UpdateRemoteVersion updates the latest available version of Gitea
6867
func UpdateRemoteVersion(version string) (err error) {
69-
sess := db.NewSession(db.DefaultContext)
70-
defer sess.Close()
71-
if err = sess.Begin(); err != nil {
72-
return err
73-
}
74-
75-
currentVersion := &RemoteVersion{ID: 1}
76-
has, err := sess.Get(currentVersion)
77-
if err != nil {
78-
return fmt.Errorf("get: %v", err)
79-
} else if !has {
80-
currentVersion.ID = 1
81-
currentVersion.Version = version
82-
83-
if _, err = sess.InsertOne(currentVersion); err != nil {
84-
return fmt.Errorf("insert: %v", err)
85-
}
86-
return nil
87-
}
88-
89-
if _, err = sess.Update(&RemoteVersion{ID: 1, Version: version}); err != nil {
90-
return err
91-
}
92-
93-
return sess.Commit()
68+
return appstate.AppState.Set(&CheckerState{LatestVersion: version})
9469
}
9570

9671
// GetRemoteVersion returns the current remote version (or currently installed verson if fail to fetch from DB)
9772
func GetRemoteVersion() string {
98-
e := db.GetEngine(db.DefaultContext)
99-
v := &RemoteVersion{ID: 1}
100-
_, err := e.Get(&v)
101-
if err != nil {
102-
// return current version if fail to fetch from DB
103-
return setting.AppVer
73+
item := new(CheckerState)
74+
if err := appstate.AppState.Get(item); err != nil {
75+
return ""
10476
}
105-
return v.Version
77+
return item.LatestVersion
10678
}
10779

10880
// GetNeedUpdate returns true whether a newer version of Gitea is available
@@ -112,7 +84,12 @@ func GetNeedUpdate() bool {
11284
// return false to fail silently
11385
return false
11486
}
115-
remoteVer, err := version.NewVersion(GetRemoteVersion())
87+
remoteVerStr := GetRemoteVersion()
88+
if remoteVerStr == "" {
89+
// no remote version is known
90+
return false
91+
}
92+
remoteVer, err := version.NewVersion(remoteVerStr)
11693
if err != nil {
11794
// return false to fail silently
11895
return false

routers/web/admin/admin.go

+3-2
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import (
2626
"code.gitea.io/gitea/modules/queue"
2727
"code.gitea.io/gitea/modules/setting"
2828
"code.gitea.io/gitea/modules/timeutil"
29+
"code.gitea.io/gitea/modules/updatechecker"
2930
"code.gitea.io/gitea/modules/web"
3031
"code.gitea.io/gitea/services/forms"
3132
"code.gitea.io/gitea/services/mailer"
@@ -125,8 +126,8 @@ func Dashboard(ctx *context.Context) {
125126
ctx.Data["PageIsAdmin"] = true
126127
ctx.Data["PageIsAdminDashboard"] = true
127128
ctx.Data["Stats"] = models.GetStatistic()
128-
ctx.Data["NeedUpdate"] = models.GetNeedUpdate()
129-
ctx.Data["RemoteVersion"] = models.GetRemoteVersion()
129+
ctx.Data["NeedUpdate"] = updatechecker.GetNeedUpdate()
130+
ctx.Data["RemoteVersion"] = updatechecker.GetRemoteVersion()
130131
// FIXME: update periodically
131132
updateSystemStatus()
132133
ctx.Data["SysStatus"] = sysStatus

0 commit comments

Comments
 (0)