* Sync interval specifed as duration string * Changed mirror interval text * make fmt * Add MinInterval for mirror sync * Use duration internally * Changed min default to 10m * make fmt * Incorrect default * Removed defaults in MustDuration() * Add Mirror interval migration * Default values corrected * Use transaction during migration * Change http 500 to page with error message * Cleanup session.commit()tags/v1.21.12.1
| @@ -461,8 +461,10 @@ PULL = 300 | |||||
| GC = 60 | GC = 60 | ||||
| [mirror] | [mirror] | ||||
| ; Default interval in hours between each check | |||||
| DEFAULT_INTERVAL = 8 | |||||
| ; Default interval as a duration between each check | |||||
| DEFAULT_INTERVAL = 8h | |||||
| ; Min interval as a duration must be > 1m | |||||
| MIN_INTERVAL = 10m | |||||
| [api] | [api] | ||||
| ; Max number of items will response in a page | ; Max number of items will response in a page | ||||
| @@ -102,6 +102,8 @@ var migrations = []Migration{ | |||||
| NewMigration("add show field in user openid table", addUserOpenIDShow), | NewMigration("add show field in user openid table", addUserOpenIDShow), | ||||
| // v26 -> v27 | // v26 -> v27 | ||||
| NewMigration("generate and migrate repo and wiki Git hooks", generateAndMigrateGitHookChains), | NewMigration("generate and migrate repo and wiki Git hooks", generateAndMigrateGitHookChains), | ||||
| // v27 -> v28 | |||||
| NewMigration("change mirror interval from hours to time.Duration", convertIntervalToDuration), | |||||
| } | } | ||||
| // Migrate database to current version | // Migrate database to current version | ||||
| @@ -0,0 +1,56 @@ | |||||
| // Copyright 2017 Gitea. 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" | |||||
| "time" | |||||
| "github.com/go-xorm/xorm" | |||||
| ) | |||||
| func convertIntervalToDuration(x *xorm.Engine) (err error) { | |||||
| type Repository struct { | |||||
| ID int64 | |||||
| OwnerID int64 | |||||
| Name string | |||||
| } | |||||
| type Mirror struct { | |||||
| ID int64 `xorm:"pk autoincr"` | |||||
| RepoID int64 `xorm:"INDEX"` | |||||
| Repo *Repository `xorm:"-"` | |||||
| Interval time.Duration | |||||
| EnablePrune bool `xorm:"NOT NULL DEFAULT true"` | |||||
| Updated time.Time `xorm:"-"` | |||||
| UpdatedUnix int64 `xorm:"INDEX"` | |||||
| NextUpdate time.Time `xorm:"-"` | |||||
| NextUpdateUnix int64 `xorm:"INDEX"` | |||||
| address string `xorm:"-"` | |||||
| } | |||||
| sess := x.NewSession() | |||||
| defer sess.Close() | |||||
| if err := sess.Begin(); err != nil { | |||||
| return err | |||||
| } | |||||
| var mirrors []Mirror | |||||
| err = sess.Table("mirror").Select("*").Find(&mirrors) | |||||
| if err != nil { | |||||
| return fmt.Errorf("Query repositories: %v", err) | |||||
| } | |||||
| for _, mirror := range mirrors { | |||||
| mirror.Interval = mirror.Interval * time.Hour | |||||
| _, err := sess.Id(mirror.ID).Cols("interval").Update(mirror) | |||||
| if err != nil { | |||||
| return fmt.Errorf("update mirror interval failed: %v", err) | |||||
| } | |||||
| } | |||||
| return sess.Commit() | |||||
| } | |||||
| @@ -815,7 +815,7 @@ func MigrateRepository(u *User, opts MigrateRepoOptions) (*Repository, error) { | |||||
| RepoID: repo.ID, | RepoID: repo.ID, | ||||
| Interval: setting.Mirror.DefaultInterval, | Interval: setting.Mirror.DefaultInterval, | ||||
| EnablePrune: true, | EnablePrune: true, | ||||
| NextUpdate: time.Now().Add(time.Duration(setting.Mirror.DefaultInterval) * time.Hour), | |||||
| NextUpdate: time.Now().Add(setting.Mirror.DefaultInterval), | |||||
| }); err != nil { | }); err != nil { | ||||
| return repo, fmt.Errorf("InsertOne: %v", err) | return repo, fmt.Errorf("InsertOne: %v", err) | ||||
| } | } | ||||
| @@ -27,8 +27,8 @@ type Mirror struct { | |||||
| ID int64 `xorm:"pk autoincr"` | ID int64 `xorm:"pk autoincr"` | ||||
| RepoID int64 `xorm:"INDEX"` | RepoID int64 `xorm:"INDEX"` | ||||
| Repo *Repository `xorm:"-"` | Repo *Repository `xorm:"-"` | ||||
| Interval int // Hour. | |||||
| EnablePrune bool `xorm:"NOT NULL DEFAULT true"` | |||||
| Interval time.Duration | |||||
| EnablePrune bool `xorm:"NOT NULL DEFAULT true"` | |||||
| Updated time.Time `xorm:"-"` | Updated time.Time `xorm:"-"` | ||||
| UpdatedUnix int64 `xorm:"INDEX"` | UpdatedUnix int64 `xorm:"INDEX"` | ||||
| @@ -68,7 +68,7 @@ func (m *Mirror) AfterSet(colName string, _ xorm.Cell) { | |||||
| // ScheduleNextUpdate calculates and sets next update time. | // ScheduleNextUpdate calculates and sets next update time. | ||||
| func (m *Mirror) ScheduleNextUpdate() { | func (m *Mirror) ScheduleNextUpdate() { | ||||
| m.NextUpdate = time.Now().Add(time.Duration(m.Interval) * time.Hour) | |||||
| m.NextUpdate = time.Now().Add(m.Interval) | |||||
| } | } | ||||
| func (m *Mirror) readAddress() { | func (m *Mirror) readAddress() { | ||||
| @@ -88,7 +88,7 @@ type RepoSettingForm struct { | |||||
| RepoName string `binding:"Required;AlphaDashDot;MaxSize(100)"` | RepoName string `binding:"Required;AlphaDashDot;MaxSize(100)"` | ||||
| Description string `binding:"MaxSize(255)"` | Description string `binding:"MaxSize(255)"` | ||||
| Website string `binding:"Url;MaxSize(255)"` | Website string `binding:"Url;MaxSize(255)"` | ||||
| Interval int | |||||
| Interval string | |||||
| MirrorAddress string | MirrorAddress string | ||||
| Private bool | Private bool | ||||
| EnablePrune bool | EnablePrune bool | ||||
| @@ -417,10 +417,9 @@ var ( | |||||
| } | } | ||||
| // Mirror settings | // Mirror settings | ||||
| Mirror = struct { | |||||
| DefaultInterval int | |||||
| }{ | |||||
| DefaultInterval: 8, | |||||
| Mirror struct { | |||||
| DefaultInterval time.Duration | |||||
| MinInterval time.Duration | |||||
| } | } | ||||
| // API settings | // API settings | ||||
| @@ -886,14 +885,20 @@ please consider changing to GITEA_CUSTOM`) | |||||
| log.Fatal(4, "Failed to map Cron settings: %v", err) | log.Fatal(4, "Failed to map Cron settings: %v", err) | ||||
| } else if err = Cfg.Section("git").MapTo(&Git); err != nil { | } else if err = Cfg.Section("git").MapTo(&Git); err != nil { | ||||
| log.Fatal(4, "Failed to map Git settings: %v", err) | log.Fatal(4, "Failed to map Git settings: %v", err) | ||||
| } else if err = Cfg.Section("mirror").MapTo(&Mirror); err != nil { | |||||
| log.Fatal(4, "Failed to map Mirror settings: %v", err) | |||||
| } else if err = Cfg.Section("api").MapTo(&API); err != nil { | } else if err = Cfg.Section("api").MapTo(&API); err != nil { | ||||
| log.Fatal(4, "Failed to map API settings: %v", err) | log.Fatal(4, "Failed to map API settings: %v", err) | ||||
| } | } | ||||
| if Mirror.DefaultInterval <= 0 { | |||||
| Mirror.DefaultInterval = 24 | |||||
| sec = Cfg.Section("mirror") | |||||
| Mirror.MinInterval = sec.Key("MIN_INTERVAL").MustDuration(10 * time.Minute) | |||||
| Mirror.DefaultInterval = sec.Key("DEFAULT_INTERVAL").MustDuration(8 * time.Hour) | |||||
| if Mirror.MinInterval.Minutes() < 1 { | |||||
| log.Warn("Mirror.MinInterval is too low") | |||||
| Mirror.MinInterval = 1 * time.Minute | |||||
| } | |||||
| if Mirror.DefaultInterval < Mirror.MinInterval { | |||||
| log.Warn("Mirror.DefaultInterval is less than Mirror.MinInterval") | |||||
| Mirror.DefaultInterval = time.Hour * 8 | |||||
| } | } | ||||
| Langs = Cfg.Section("i18n").Key("LANGS").Strings(",") | Langs = Cfg.Section("i18n").Key("LANGS").Strings(",") | ||||
| @@ -440,7 +440,8 @@ create_repo = Create Repository | |||||
| default_branch = Default Branch | default_branch = Default Branch | ||||
| mirror_prune = Prune | mirror_prune = Prune | ||||
| mirror_prune_desc = Remove any remote-tracking references that no longer exist on the remote | mirror_prune_desc = Remove any remote-tracking references that no longer exist on the remote | ||||
| mirror_interval = Mirror Interval (hour) | |||||
| mirror_interval = Mirror interval (valid time units are "h", "m", "s") | |||||
| mirror_interval_invalid = Mirror interval is not valid | |||||
| mirror_address = Mirror Address | mirror_address = Mirror Address | ||||
| mirror_address_desc = Please include necessary user credentials in the address. | mirror_address_desc = Please include necessary user credentials in the address. | ||||
| mirror_last_synced = Last Synced | mirror_last_synced = Last Synced | ||||
| @@ -111,12 +111,15 @@ func SettingsPost(ctx *context.Context, form auth.RepoSettingForm) { | |||||
| return | return | ||||
| } | } | ||||
| if form.Interval > 0 { | |||||
| interval, err := time.ParseDuration(form.Interval) | |||||
| if err != nil || interval < setting.Mirror.MinInterval { | |||||
| ctx.RenderWithErr(ctx.Tr("repo.mirror_interval_invalid"), tplSettingsOptions, &form) | |||||
| } else { | |||||
| ctx.Repo.Mirror.EnablePrune = form.EnablePrune | ctx.Repo.Mirror.EnablePrune = form.EnablePrune | ||||
| ctx.Repo.Mirror.Interval = form.Interval | |||||
| ctx.Repo.Mirror.NextUpdate = time.Now().Add(time.Duration(form.Interval) * time.Hour) | |||||
| ctx.Repo.Mirror.Interval = interval | |||||
| ctx.Repo.Mirror.NextUpdate = time.Now().Add(interval) | |||||
| if err := models.UpdateMirror(ctx.Repo.Mirror); err != nil { | if err := models.UpdateMirror(ctx.Repo.Mirror); err != nil { | ||||
| ctx.Handle(500, "UpdateMirror", err) | |||||
| ctx.RenderWithErr(ctx.Tr("repo.mirror_interval_invalid"), tplSettingsOptions, &form) | |||||
| return | return | ||||
| } | } | ||||
| } | } | ||||
| @@ -56,7 +56,7 @@ | |||||
| </div> | </div> | ||||
| <div class="inline field {{if .Err_Interval}}error{{end}}"> | <div class="inline field {{if .Err_Interval}}error{{end}}"> | ||||
| <label for="interval">{{.i18n.Tr "repo.mirror_interval"}}</label> | <label for="interval">{{.i18n.Tr "repo.mirror_interval"}}</label> | ||||
| <input id="interval" name="interval" type="number" value="{{.MirrorInterval}}"> | |||||
| <input id="interval" name="interval" value="{{.MirrorInterval}}"> | |||||
| </div> | </div> | ||||
| <div class="field"> | <div class="field"> | ||||
| <label for="mirror_address">{{.i18n.Tr "repo.mirror_address"}}</label> | <label for="mirror_address">{{.i18n.Tr "repo.mirror_address"}}</label> | ||||