Browse Source

Mirror sync interval specified as duration string (#1407)

* 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()
Jonas 2 years ago
parent
commit
54f0293f0a

+ 4 - 2
conf/app.ini

@@ -461,8 +461,10 @@ PULL = 300
461 461
 GC = 60
462 462
 
463 463
 [mirror]
464
-; Default interval in hours between each check
465
-DEFAULT_INTERVAL = 8
464
+; Default interval as a duration between each check
465
+DEFAULT_INTERVAL = 8h
466
+; Min interval as a duration must be > 1m
467
+MIN_INTERVAL = 10m
466 468
 
467 469
 [api]
468 470
 ; Max number of items will response in a page

+ 2 - 0
models/migrations/migrations.go

@@ -102,6 +102,8 @@ var migrations = []Migration{
102 102
 	NewMigration("add show field in user openid table", addUserOpenIDShow),
103 103
 	// v26 -> v27
104 104
 	NewMigration("generate and migrate repo and wiki Git hooks", generateAndMigrateGitHookChains),
105
+	// v27 -> v28
106
+	NewMigration("change mirror interval from hours to time.Duration", convertIntervalToDuration),
105 107
 }
106 108
 
107 109
 // Migrate database to current version

+ 56 - 0
models/migrations/v27.go

@@ -0,0 +1,56 @@
1
+// Copyright 2017 Gitea. 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
+	"fmt"
9
+	"time"
10
+
11
+	"github.com/go-xorm/xorm"
12
+)
13
+
14
+func convertIntervalToDuration(x *xorm.Engine) (err error) {
15
+	type Repository struct {
16
+		ID      int64
17
+		OwnerID int64
18
+		Name    string
19
+	}
20
+	type Mirror struct {
21
+		ID          int64       `xorm:"pk autoincr"`
22
+		RepoID      int64       `xorm:"INDEX"`
23
+		Repo        *Repository `xorm:"-"`
24
+		Interval    time.Duration
25
+		EnablePrune bool `xorm:"NOT NULL DEFAULT true"`
26
+
27
+		Updated        time.Time `xorm:"-"`
28
+		UpdatedUnix    int64     `xorm:"INDEX"`
29
+		NextUpdate     time.Time `xorm:"-"`
30
+		NextUpdateUnix int64     `xorm:"INDEX"`
31
+
32
+		address string `xorm:"-"`
33
+	}
34
+
35
+	sess := x.NewSession()
36
+	defer sess.Close()
37
+
38
+	if err := sess.Begin(); err != nil {
39
+		return err
40
+	}
41
+
42
+	var mirrors []Mirror
43
+	err = sess.Table("mirror").Select("*").Find(&mirrors)
44
+	if err != nil {
45
+		return fmt.Errorf("Query repositories: %v", err)
46
+	}
47
+	for _, mirror := range mirrors {
48
+		mirror.Interval = mirror.Interval * time.Hour
49
+		_, err := sess.Id(mirror.ID).Cols("interval").Update(mirror)
50
+		if err != nil {
51
+			return fmt.Errorf("update mirror interval failed: %v", err)
52
+		}
53
+	}
54
+
55
+	return sess.Commit()
56
+}

+ 1 - 1
models/repo.go

@@ -815,7 +815,7 @@ func MigrateRepository(u *User, opts MigrateRepoOptions) (*Repository, error) {
815 815
 			RepoID:      repo.ID,
816 816
 			Interval:    setting.Mirror.DefaultInterval,
817 817
 			EnablePrune: true,
818
-			NextUpdate:  time.Now().Add(time.Duration(setting.Mirror.DefaultInterval) * time.Hour),
818
+			NextUpdate:  time.Now().Add(setting.Mirror.DefaultInterval),
819 819
 		}); err != nil {
820 820
 			return repo, fmt.Errorf("InsertOne: %v", err)
821 821
 		}

+ 3 - 3
models/repo_mirror.go

@@ -27,8 +27,8 @@ type Mirror struct {
27 27
 	ID          int64       `xorm:"pk autoincr"`
28 28
 	RepoID      int64       `xorm:"INDEX"`
29 29
 	Repo        *Repository `xorm:"-"`
30
-	Interval    int         // Hour.
31
-	EnablePrune bool        `xorm:"NOT NULL DEFAULT true"`
30
+	Interval    time.Duration
31
+	EnablePrune bool `xorm:"NOT NULL DEFAULT true"`
32 32
 
33 33
 	Updated        time.Time `xorm:"-"`
34 34
 	UpdatedUnix    int64     `xorm:"INDEX"`
@@ -68,7 +68,7 @@ func (m *Mirror) AfterSet(colName string, _ xorm.Cell) {
68 68
 
69 69
 // ScheduleNextUpdate calculates and sets next update time.
70 70
 func (m *Mirror) ScheduleNextUpdate() {
71
-	m.NextUpdate = time.Now().Add(time.Duration(m.Interval) * time.Hour)
71
+	m.NextUpdate = time.Now().Add(m.Interval)
72 72
 }
73 73
 
74 74
 func (m *Mirror) readAddress() {

+ 1 - 1
modules/auth/repo_form.go

@@ -88,7 +88,7 @@ type RepoSettingForm struct {
88 88
 	RepoName      string `binding:"Required;AlphaDashDot;MaxSize(100)"`
89 89
 	Description   string `binding:"MaxSize(255)"`
90 90
 	Website       string `binding:"Url;MaxSize(255)"`
91
-	Interval      int
91
+	Interval      string
92 92
 	MirrorAddress string
93 93
 	Private       bool
94 94
 	EnablePrune   bool

+ 13 - 8
modules/setting/setting.go

@@ -417,10 +417,9 @@ var (
417 417
 	}
418 418
 
419 419
 	// Mirror settings
420
-	Mirror = struct {
421
-		DefaultInterval int
422
-	}{
423
-		DefaultInterval: 8,
420
+	Mirror struct {
421
+		DefaultInterval time.Duration
422
+		MinInterval     time.Duration
424 423
 	}
425 424
 
426 425
 	// API settings
@@ -886,14 +885,20 @@ please consider changing to GITEA_CUSTOM`)
886 885
 		log.Fatal(4, "Failed to map Cron settings: %v", err)
887 886
 	} else if err = Cfg.Section("git").MapTo(&Git); err != nil {
888 887
 		log.Fatal(4, "Failed to map Git settings: %v", err)
889
-	} else if err = Cfg.Section("mirror").MapTo(&Mirror); err != nil {
890
-		log.Fatal(4, "Failed to map Mirror settings: %v", err)
891 888
 	} else if err = Cfg.Section("api").MapTo(&API); err != nil {
892 889
 		log.Fatal(4, "Failed to map API settings: %v", err)
893 890
 	}
894 891
 
895
-	if Mirror.DefaultInterval <= 0 {
896
-		Mirror.DefaultInterval = 24
892
+	sec = Cfg.Section("mirror")
893
+	Mirror.MinInterval = sec.Key("MIN_INTERVAL").MustDuration(10 * time.Minute)
894
+	Mirror.DefaultInterval = sec.Key("DEFAULT_INTERVAL").MustDuration(8 * time.Hour)
895
+	if Mirror.MinInterval.Minutes() < 1 {
896
+		log.Warn("Mirror.MinInterval is too low")
897
+		Mirror.MinInterval = 1 * time.Minute
898
+	}
899
+	if Mirror.DefaultInterval < Mirror.MinInterval {
900
+		log.Warn("Mirror.DefaultInterval is less than Mirror.MinInterval")
901
+		Mirror.DefaultInterval = time.Hour * 8
897 902
 	}
898 903
 
899 904
 	Langs = Cfg.Section("i18n").Key("LANGS").Strings(",")

+ 2 - 1
options/locale/locale_en-US.ini

@@ -440,7 +440,8 @@ create_repo = Create Repository
440 440
 default_branch = Default Branch
441 441
 mirror_prune = Prune
442 442
 mirror_prune_desc = Remove any remote-tracking references that no longer exist on the remote
443
-mirror_interval = Mirror Interval (hour)
443
+mirror_interval = Mirror interval (valid time units are "h", "m", "s")
444
+mirror_interval_invalid = Mirror interval is not valid
444 445
 mirror_address = Mirror Address
445 446
 mirror_address_desc = Please include necessary user credentials in the address.
446 447
 mirror_last_synced = Last Synced

+ 7 - 4
routers/repo/setting.go

@@ -111,12 +111,15 @@ func SettingsPost(ctx *context.Context, form auth.RepoSettingForm) {
111 111
 			return
112 112
 		}
113 113
 
114
-		if form.Interval > 0 {
114
+		interval, err := time.ParseDuration(form.Interval)
115
+		if err != nil || interval < setting.Mirror.MinInterval {
116
+			ctx.RenderWithErr(ctx.Tr("repo.mirror_interval_invalid"), tplSettingsOptions, &form)
117
+		} else {
115 118
 			ctx.Repo.Mirror.EnablePrune = form.EnablePrune
116
-			ctx.Repo.Mirror.Interval = form.Interval
117
-			ctx.Repo.Mirror.NextUpdate = time.Now().Add(time.Duration(form.Interval) * time.Hour)
119
+			ctx.Repo.Mirror.Interval = interval
120
+			ctx.Repo.Mirror.NextUpdate = time.Now().Add(interval)
118 121
 			if err := models.UpdateMirror(ctx.Repo.Mirror); err != nil {
119
-				ctx.Handle(500, "UpdateMirror", err)
122
+				ctx.RenderWithErr(ctx.Tr("repo.mirror_interval_invalid"), tplSettingsOptions, &form)
120 123
 				return
121 124
 			}
122 125
 		}

+ 1 - 1
templates/repo/settings/options.tmpl

@@ -56,7 +56,7 @@
56 56
 					</div>
57 57
 					<div class="inline field {{if .Err_Interval}}error{{end}}">
58 58
 						<label for="interval">{{.i18n.Tr "repo.mirror_interval"}}</label>
59
-						<input id="interval" name="interval" type="number" value="{{.MirrorInterval}}">
59
+						<input id="interval" name="interval" value="{{.MirrorInterval}}">
60 60
 					</div>
61 61
 					<div class="field">
62 62
 						<label for="mirror_address">{{.i18n.Tr "repo.mirror_address"}}</label>