forked from gitea/gitea
		
	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`.
This commit is contained in:
		
							parent
							
								
									67561e79f1
								
							
						
					
					
						commit
						960c322586
					
				| @ -351,9 +351,11 @@ var migrations = []Migration{ | ||||
| 	// v198 -> v199 | ||||
| 	NewMigration("Add issue content history table", addTableIssueContentHistory), | ||||
| 	// v199 -> v200 | ||||
| 	NewMigration("Add remote version table", addRemoteVersionTable), | ||||
| 	NewMigration("No-op (remote version is using AppState now)", addRemoteVersionTableNoop), | ||||
| 	// v200 -> v201 | ||||
| 	NewMigration("Add table app_state", addTableAppState), | ||||
| 	// v201 -> v202 | ||||
| 	NewMigration("Drop table remote_version (if exists)", dropTableRemoteVersion), | ||||
| } | ||||
| 
 | ||||
| // GetCurrentDBVersion returns the current db version | ||||
|  | ||||
| @ -5,19 +5,10 @@ | ||||
| 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) | ||||
| 	} | ||||
| func addRemoteVersionTableNoop(x *xorm.Engine) error { | ||||
| 	// 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. | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
							
								
								
									
										15
									
								
								models/migrations/v201.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								models/migrations/v201.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,15 @@ | ||||
| // 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 ( | ||||
| 	"xorm.io/xorm" | ||||
| ) | ||||
| 
 | ||||
| func dropTableRemoteVersion(x *xorm.Engine) error { | ||||
| 	// drop the orphaned table introduced in `v199`, now the update checker also uses AppState, do not need this table | ||||
| 	_ = x.DropTables("remote_version") | ||||
| 	return nil | ||||
| } | ||||
| @ -11,6 +11,7 @@ import ( | ||||
| 	"code.gitea.io/gitea/models" | ||||
| 	repo_module "code.gitea.io/gitea/modules/repository" | ||||
| 	"code.gitea.io/gitea/modules/setting" | ||||
| 	"code.gitea.io/gitea/modules/updatechecker" | ||||
| ) | ||||
| 
 | ||||
| func registerDeleteInactiveUsers() { | ||||
| @ -145,7 +146,7 @@ func registerUpdateGiteaChecker() { | ||||
| 		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) | ||||
| 		return updatechecker.GiteaUpdateChecker(updateCheckerConfig.HTTPEndpoint) | ||||
| 	}) | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -2,29 +2,28 @@ | ||||
| // Use of this source code is governed by a MIT-style | ||||
| // license that can be found in the LICENSE file. | ||||
| 
 | ||||
| package models | ||||
| package updatechecker | ||||
| 
 | ||||
| import ( | ||||
| 	"encoding/json" | ||||
| 	"fmt" | ||||
| 	"io/ioutil" | ||||
| 	"net/http" | ||||
| 
 | ||||
| 	"code.gitea.io/gitea/models/db" | ||||
| 	"code.gitea.io/gitea/modules/appstate" | ||||
| 	"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)"` | ||||
| // CheckerState stores the remote version from the JSON endpoint | ||||
| type CheckerState struct { | ||||
| 	LatestVersion string | ||||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	db.RegisterModel(new(RemoteVersion)) | ||||
| // Name returns the name of the state item for update checker | ||||
| func (r *CheckerState) Name() string { | ||||
| 	return "update-checker" | ||||
| } | ||||
| 
 | ||||
| // GiteaUpdateChecker returns error when new version of Gitea is available | ||||
| @ -49,60 +48,33 @@ func GiteaUpdateChecker(httpEndpoint string) error { | ||||
| 		return err | ||||
| 	} | ||||
| 
 | ||||
| 	type v struct { | ||||
| 	type respType struct { | ||||
| 		Latest struct { | ||||
| 			Version string `json:"version"` | ||||
| 		} `json:"latest"` | ||||
| 	} | ||||
| 	ver := v{} | ||||
| 	err = json.Unmarshal(body, &ver) | ||||
| 	respData := respType{} | ||||
| 	err = json.Unmarshal(body, &respData) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 
 | ||||
| 	return UpdateRemoteVersion(ver.Latest.Version) | ||||
| 	return UpdateRemoteVersion(respData.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() | ||||
| 	return appstate.AppState.Set(&CheckerState{LatestVersion: version}) | ||||
| } | ||||
| 
 | ||||
| // 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 | ||||
| 	item := new(CheckerState) | ||||
| 	if err := appstate.AppState.Get(item); err != nil { | ||||
| 		return "" | ||||
| 	} | ||||
| 	return v.Version | ||||
| 	return item.LatestVersion | ||||
| } | ||||
| 
 | ||||
| // GetNeedUpdate returns true whether a newer version of Gitea is available | ||||
| @ -112,7 +84,12 @@ func GetNeedUpdate() bool { | ||||
| 		// return false to fail silently | ||||
| 		return false | ||||
| 	} | ||||
| 	remoteVer, err := version.NewVersion(GetRemoteVersion()) | ||||
| 	remoteVerStr := GetRemoteVersion() | ||||
| 	if remoteVerStr == "" { | ||||
| 		// no remote version is known | ||||
| 		return false | ||||
| 	} | ||||
| 	remoteVer, err := version.NewVersion(remoteVerStr) | ||||
| 	if err != nil { | ||||
| 		// return false to fail silently | ||||
| 		return false | ||||
| @ -26,6 +26,7 @@ import ( | ||||
| 	"code.gitea.io/gitea/modules/queue" | ||||
| 	"code.gitea.io/gitea/modules/setting" | ||||
| 	"code.gitea.io/gitea/modules/timeutil" | ||||
| 	"code.gitea.io/gitea/modules/updatechecker" | ||||
| 	"code.gitea.io/gitea/modules/web" | ||||
| 	"code.gitea.io/gitea/services/forms" | ||||
| 	"code.gitea.io/gitea/services/mailer" | ||||
| @ -125,8 +126,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() | ||||
| 	ctx.Data["NeedUpdate"] = updatechecker.GetNeedUpdate() | ||||
| 	ctx.Data["RemoteVersion"] = updatechecker.GetRemoteVersion() | ||||
| 	// FIXME: update periodically | ||||
| 	updateSystemStatus() | ||||
| 	ctx.Data["SysStatus"] = sysStatus | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 wxiaoguang
						wxiaoguang