-
-
Notifications
You must be signed in to change notification settings - Fork 5.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add simple update checker to Gitea #17212
Changes from 18 commits
e7467b5
b73aa6c
b6ef89b
5d13cb5
c1aa2fb
57dc076
6df9747
28c36c7
2fcd728
c1b875e
e67c006
b891967
fd13167
dd118f4
4e80fb0
0cfd1d8
13c631b
fc77ce3
0b2de8a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 | ||
techknowlogick marked this conversation as resolved.
Show resolved
Hide resolved
|
||
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) | ||
techknowlogick marked this conversation as resolved.
Show resolved
Hide resolved
|
||
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 { | ||
techknowlogick marked this conversation as resolved.
Show resolved
Hide resolved
|
||
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 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I really dislike the idea to return current version if there is a failure. It breaks the meaning the the function Anyway, if you feel it's OK, since it doesn't do harm to the logic ..... |
||
} | ||
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) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. i18n? |
||
</div> | ||
{{end}} | ||
<h4 class="ui top attached header"> | ||
{{.i18n.Tr "admin.dashboard.statistic"}} | ||
</h4> | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I also think store the version into database is unnecessary. Just send http request every check is better.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We are storing in the database because we don't want to DDOS ourselves when everyone goes to admin dashboard. Even if we get beefy servers, the user dashboard will always be slower because an HTTP check would need to happen. By storing it in the DB we will eventually be able to add a check to send out an email to admins when a new update happens.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On option is storing the remote version into Gitea local cache in memory.
Another option is using database (this PR).
Both are fine to me.