mirror of
				https://gitee.com/gitea/gitea
				synced 2025-11-04 16:40:24 +08:00 
			
		
		
		
	Add MirrorInterval to the API (#14163)
* Added MirrorInterval to the API * Remove MirrorInterval from CreateRepository * Removed Duplicate UpdateMirror Function * Updated Error Logging * Update Log Message for is not Mirror Co-authored-by: 6543 <6543@obermui.de> * Delete Debug Statement that snuck in Co-authored-by: zeripath <art27@cantab.net> * Add Check for If Interval is too small * Output to API Call * Add Error Object when time is Less than Min Interval * Frequency Error Message Co-authored-by: zeripath <art27@cantab.net> * Allow Zero Mirror Interval Co-authored-by: 6543 <6543@obermui.de> Co-authored-by: zeripath <art27@cantab.net>
This commit is contained in:
		@@ -979,6 +979,7 @@ type CreateRepoOptions struct {
 | 
				
			|||||||
	AutoInit       bool
 | 
						AutoInit       bool
 | 
				
			||||||
	Status         RepositoryStatus
 | 
						Status         RepositoryStatus
 | 
				
			||||||
	TrustModel     TrustModelType
 | 
						TrustModel     TrustModelType
 | 
				
			||||||
 | 
						MirrorInterval string
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// GetRepoInitFile returns repository init files
 | 
					// GetRepoInitFile returns repository init files
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -68,16 +68,17 @@ type MigrateRepoForm struct {
 | 
				
			|||||||
	// required: true
 | 
						// required: true
 | 
				
			||||||
	UID int64 `json:"uid" binding:"Required"`
 | 
						UID int64 `json:"uid" binding:"Required"`
 | 
				
			||||||
	// required: true
 | 
						// required: true
 | 
				
			||||||
	RepoName     string `json:"repo_name" binding:"Required;AlphaDashDot;MaxSize(100)"`
 | 
						RepoName       string `json:"repo_name" binding:"Required;AlphaDashDot;MaxSize(100)"`
 | 
				
			||||||
	Mirror       bool   `json:"mirror"`
 | 
						Mirror         bool   `json:"mirror"`
 | 
				
			||||||
	Private      bool   `json:"private"`
 | 
						Private        bool   `json:"private"`
 | 
				
			||||||
	Description  string `json:"description" binding:"MaxSize(255)"`
 | 
						Description    string `json:"description" binding:"MaxSize(255)"`
 | 
				
			||||||
	Wiki         bool   `json:"wiki"`
 | 
						Wiki           bool   `json:"wiki"`
 | 
				
			||||||
	Milestones   bool   `json:"milestones"`
 | 
						Milestones     bool   `json:"milestones"`
 | 
				
			||||||
	Labels       bool   `json:"labels"`
 | 
						Labels         bool   `json:"labels"`
 | 
				
			||||||
	Issues       bool   `json:"issues"`
 | 
						Issues         bool   `json:"issues"`
 | 
				
			||||||
	PullRequests bool   `json:"pull_requests"`
 | 
						PullRequests   bool   `json:"pull_requests"`
 | 
				
			||||||
	Releases     bool   `json:"releases"`
 | 
						Releases       bool   `json:"releases"`
 | 
				
			||||||
 | 
						MirrorInterval string `json:"mirror_interval"`
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Validate validates the fields
 | 
					// Validate validates the fields
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -91,6 +91,13 @@ func innerToRepo(repo *models.Repository, mode models.AccessMode, isParent bool)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	numReleases, _ := models.GetReleaseCountByRepoID(repo.ID, models.FindReleasesOptions{IncludeDrafts: false, IncludeTags: true})
 | 
						numReleases, _ := models.GetReleaseCountByRepoID(repo.ID, models.FindReleasesOptions{IncludeDrafts: false, IncludeTags: true})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						mirrorInterval := ""
 | 
				
			||||||
 | 
						if repo.IsMirror {
 | 
				
			||||||
 | 
							if err := repo.GetMirror(); err == nil {
 | 
				
			||||||
 | 
								mirrorInterval = repo.Mirror.Interval.String()
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return &api.Repository{
 | 
						return &api.Repository{
 | 
				
			||||||
		ID:                        repo.ID,
 | 
							ID:                        repo.ID,
 | 
				
			||||||
		Owner:                     ToUser(repo.Owner, mode != models.AccessModeNone, mode >= models.AccessModeAdmin),
 | 
							Owner:                     ToUser(repo.Owner, mode != models.AccessModeNone, mode >= models.AccessModeAdmin),
 | 
				
			||||||
@@ -134,5 +141,6 @@ func innerToRepo(repo *models.Repository, mode models.AccessMode, isParent bool)
 | 
				
			|||||||
		AllowSquash:               allowSquash,
 | 
							AllowSquash:               allowSquash,
 | 
				
			||||||
		AvatarURL:                 repo.AvatarLink(),
 | 
							AvatarURL:                 repo.AvatarLink(),
 | 
				
			||||||
		Internal:                  !repo.IsPrivate && repo.Owner.Visibility == api.VisibleTypePrivate,
 | 
							Internal:                  !repo.IsPrivate && repo.Owner.Visibility == api.VisibleTypePrivate,
 | 
				
			||||||
 | 
							MirrorInterval:            mirrorInterval,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -33,4 +33,5 @@ type MigrateOptions struct {
 | 
				
			|||||||
	PullRequests    bool
 | 
						PullRequests    bool
 | 
				
			||||||
	ReleaseAssets   bool
 | 
						ReleaseAssets   bool
 | 
				
			||||||
	MigrateToRepoID int64
 | 
						MigrateToRepoID int64
 | 
				
			||||||
 | 
						MirrorInterval  string `json:"mirror_interval"`
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -142,6 +142,7 @@ func (g *GiteaLocalUploader) CreateRepo(repo *base.Repository, opts base.Migrate
 | 
				
			|||||||
		Private:        repo.IsPrivate,
 | 
							Private:        repo.IsPrivate,
 | 
				
			||||||
		Wiki:           opts.Wiki,
 | 
							Wiki:           opts.Wiki,
 | 
				
			||||||
		Releases:       opts.Releases, // if didn't get releases, then sync them from tags
 | 
							Releases:       opts.Releases, // if didn't get releases, then sync them from tags
 | 
				
			||||||
 | 
							MirrorInterval: opts.MirrorInterval,
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	g.repo = r
 | 
						g.repo = r
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -127,12 +127,33 @@ func MigrateRepositoryGitData(ctx context.Context, u *models.User, repo *models.
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if opts.Mirror {
 | 
						if opts.Mirror {
 | 
				
			||||||
		if err = models.InsertMirror(&models.Mirror{
 | 
							mirrorModel := models.Mirror{
 | 
				
			||||||
			RepoID:         repo.ID,
 | 
								RepoID:         repo.ID,
 | 
				
			||||||
			Interval:       setting.Mirror.DefaultInterval,
 | 
								Interval:       setting.Mirror.DefaultInterval,
 | 
				
			||||||
			EnablePrune:    true,
 | 
								EnablePrune:    true,
 | 
				
			||||||
			NextUpdateUnix: timeutil.TimeStampNow().AddDuration(setting.Mirror.DefaultInterval),
 | 
								NextUpdateUnix: timeutil.TimeStampNow().AddDuration(setting.Mirror.DefaultInterval),
 | 
				
			||||||
		}); err != nil {
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if opts.MirrorInterval != "" {
 | 
				
			||||||
 | 
								parsedInterval, err := time.ParseDuration(opts.MirrorInterval)
 | 
				
			||||||
 | 
								if err != nil {
 | 
				
			||||||
 | 
									log.Error("Failed to set Interval: %v", err)
 | 
				
			||||||
 | 
									return repo, err
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								if parsedInterval == 0 {
 | 
				
			||||||
 | 
									mirrorModel.Interval = 0
 | 
				
			||||||
 | 
									mirrorModel.NextUpdateUnix = 0
 | 
				
			||||||
 | 
								} else if parsedInterval < setting.Mirror.MinInterval {
 | 
				
			||||||
 | 
									err := fmt.Errorf("Interval %s is set below Minimum Interval of %s", parsedInterval, setting.Mirror.MinInterval)
 | 
				
			||||||
 | 
									log.Error("Interval: %s is too frequent", opts.MirrorInterval)
 | 
				
			||||||
 | 
									return repo, err
 | 
				
			||||||
 | 
								} else {
 | 
				
			||||||
 | 
									mirrorModel.Interval = parsedInterval
 | 
				
			||||||
 | 
									mirrorModel.NextUpdateUnix = timeutil.TimeStampNow().AddDuration(parsedInterval)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if err = models.InsertMirror(&mirrorModel); err != nil {
 | 
				
			||||||
			return repo, fmt.Errorf("InsertOne: %v", err)
 | 
								return repo, fmt.Errorf("InsertOne: %v", err)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -91,6 +91,7 @@ type Repository struct {
 | 
				
			|||||||
	AllowSquash               bool             `json:"allow_squash_merge"`
 | 
						AllowSquash               bool             `json:"allow_squash_merge"`
 | 
				
			||||||
	AvatarURL                 string           `json:"avatar_url"`
 | 
						AvatarURL                 string           `json:"avatar_url"`
 | 
				
			||||||
	Internal                  bool             `json:"internal"`
 | 
						Internal                  bool             `json:"internal"`
 | 
				
			||||||
 | 
						MirrorInterval            string           `json:"mirror_interval"`
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// CreateRepoOption options when creating repository
 | 
					// CreateRepoOption options when creating repository
 | 
				
			||||||
@@ -168,6 +169,8 @@ type EditRepoOption struct {
 | 
				
			|||||||
	AllowSquash *bool `json:"allow_squash_merge,omitempty"`
 | 
						AllowSquash *bool `json:"allow_squash_merge,omitempty"`
 | 
				
			||||||
	// set to `true` to archive this repository.
 | 
						// set to `true` to archive this repository.
 | 
				
			||||||
	Archived *bool `json:"archived,omitempty"`
 | 
						Archived *bool `json:"archived,omitempty"`
 | 
				
			||||||
 | 
						// set to a string like `8h30m0s` to set the mirror interval time
 | 
				
			||||||
 | 
						MirrorInterval *string `json:"mirror_interval,omitempty"`
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// CreateBranchRepoOption options when creating a branch in a repository
 | 
					// CreateBranchRepoOption options when creating a branch in a repository
 | 
				
			||||||
@@ -249,15 +252,16 @@ type MigrateRepoOptions struct {
 | 
				
			|||||||
	AuthPassword string `json:"auth_password"`
 | 
						AuthPassword string `json:"auth_password"`
 | 
				
			||||||
	AuthToken    string `json:"auth_token"`
 | 
						AuthToken    string `json:"auth_token"`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Mirror       bool   `json:"mirror"`
 | 
						Mirror         bool   `json:"mirror"`
 | 
				
			||||||
	Private      bool   `json:"private"`
 | 
						Private        bool   `json:"private"`
 | 
				
			||||||
	Description  string `json:"description" binding:"MaxSize(255)"`
 | 
						Description    string `json:"description" binding:"MaxSize(255)"`
 | 
				
			||||||
	Wiki         bool   `json:"wiki"`
 | 
						Wiki           bool   `json:"wiki"`
 | 
				
			||||||
	Milestones   bool   `json:"milestones"`
 | 
						Milestones     bool   `json:"milestones"`
 | 
				
			||||||
	Labels       bool   `json:"labels"`
 | 
						Labels         bool   `json:"labels"`
 | 
				
			||||||
	Issues       bool   `json:"issues"`
 | 
						Issues         bool   `json:"issues"`
 | 
				
			||||||
	PullRequests bool   `json:"pull_requests"`
 | 
						PullRequests   bool   `json:"pull_requests"`
 | 
				
			||||||
	Releases     bool   `json:"releases"`
 | 
						Releases       bool   `json:"releases"`
 | 
				
			||||||
 | 
						MirrorInterval string `json:"mirror_interval"`
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// TokenAuth represents whether a service type supports token-based auth
 | 
					// TokenAuth represents whether a service type supports token-based auth
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -141,6 +141,7 @@ func Migrate(ctx *context.APIContext, form api.MigrateRepoOptions) {
 | 
				
			|||||||
		PullRequests:   form.PullRequests,
 | 
							PullRequests:   form.PullRequests,
 | 
				
			||||||
		Releases:       form.Releases,
 | 
							Releases:       form.Releases,
 | 
				
			||||||
		GitServiceType: gitServiceType,
 | 
							GitServiceType: gitServiceType,
 | 
				
			||||||
 | 
							MirrorInterval: form.MirrorInterval,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if opts.Mirror {
 | 
						if opts.Mirror {
 | 
				
			||||||
		opts.Issues = false
 | 
							opts.Issues = false
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -9,6 +9,7 @@ import (
 | 
				
			|||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
	"net/http"
 | 
						"net/http"
 | 
				
			||||||
	"strings"
 | 
						"strings"
 | 
				
			||||||
 | 
						"time"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"code.gitea.io/gitea/models"
 | 
						"code.gitea.io/gitea/models"
 | 
				
			||||||
	"code.gitea.io/gitea/modules/context"
 | 
						"code.gitea.io/gitea/modules/context"
 | 
				
			||||||
@@ -501,6 +502,12 @@ func Edit(ctx *context.APIContext, opts api.EditRepoOption) {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if opts.MirrorInterval != nil {
 | 
				
			||||||
 | 
							if err := updateMirrorInterval(ctx, opts); err != nil {
 | 
				
			||||||
 | 
								return
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ctx.JSON(http.StatusOK, convert.ToRepo(ctx.Repo.Repository, ctx.Repo.AccessMode))
 | 
						ctx.JSON(http.StatusOK, convert.ToRepo(ctx.Repo.Repository, ctx.Repo.AccessMode))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -783,6 +790,38 @@ func updateRepoArchivedState(ctx *context.APIContext, opts api.EditRepoOption) e
 | 
				
			|||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// updateMirrorInterval updates the repo's mirror Interval
 | 
				
			||||||
 | 
					func updateMirrorInterval(ctx *context.APIContext, opts api.EditRepoOption) error {
 | 
				
			||||||
 | 
						repo := ctx.Repo.Repository
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if opts.MirrorInterval != nil {
 | 
				
			||||||
 | 
							if !repo.IsMirror {
 | 
				
			||||||
 | 
								err := fmt.Errorf("repo is not a mirror, can not change mirror interval")
 | 
				
			||||||
 | 
								ctx.Error(http.StatusUnprocessableEntity, err.Error(), err)
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if err := repo.GetMirror(); err != nil {
 | 
				
			||||||
 | 
								log.Error("Failed to get mirror: %s", err)
 | 
				
			||||||
 | 
								ctx.Error(http.StatusInternalServerError, "MirrorInterval", err)
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if interval, err := time.ParseDuration(*opts.MirrorInterval); err == nil {
 | 
				
			||||||
 | 
								repo.Mirror.Interval = interval
 | 
				
			||||||
 | 
								if err := models.UpdateMirror(repo.Mirror); err != nil {
 | 
				
			||||||
 | 
									log.Error("Failed to Set Mirror Interval: %s", err)
 | 
				
			||||||
 | 
									ctx.Error(http.StatusUnprocessableEntity, "MirrorInterval", err)
 | 
				
			||||||
 | 
									return err
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								log.Trace("Repository %s/%s Mirror Interval was Updated to %s", ctx.Repo.Owner.Name, repo.Name, interval)
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								log.Error("Wrong format for MirrorInternal Sent: %s", err)
 | 
				
			||||||
 | 
								ctx.Error(http.StatusUnprocessableEntity, "MirrorInterval", err)
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Delete one repository
 | 
					// Delete one repository
 | 
				
			||||||
func Delete(ctx *context.APIContext) {
 | 
					func Delete(ctx *context.APIContext) {
 | 
				
			||||||
	// swagger:operation DELETE /repos/{owner}/{repo} repository repoDelete
 | 
						// swagger:operation DELETE /repos/{owner}/{repo} repository repoDelete
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -13263,6 +13263,11 @@
 | 
				
			|||||||
        "internal_tracker": {
 | 
					        "internal_tracker": {
 | 
				
			||||||
          "$ref": "#/definitions/InternalTracker"
 | 
					          "$ref": "#/definitions/InternalTracker"
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
 | 
					        "mirror_interval": {
 | 
				
			||||||
 | 
					          "description": "set to a string like `8h30m0s` to set the mirror interval time",
 | 
				
			||||||
 | 
					          "type": "string",
 | 
				
			||||||
 | 
					          "x-go-name": "MirrorInterval"
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
        "name": {
 | 
					        "name": {
 | 
				
			||||||
          "description": "name of the repository",
 | 
					          "description": "name of the repository",
 | 
				
			||||||
          "type": "string",
 | 
					          "type": "string",
 | 
				
			||||||
@@ -14248,6 +14253,10 @@
 | 
				
			|||||||
          "type": "boolean",
 | 
					          "type": "boolean",
 | 
				
			||||||
          "x-go-name": "Mirror"
 | 
					          "x-go-name": "Mirror"
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
 | 
					        "mirror_interval": {
 | 
				
			||||||
 | 
					          "type": "string",
 | 
				
			||||||
 | 
					          "x-go-name": "MirrorInterval"
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
        "private": {
 | 
					        "private": {
 | 
				
			||||||
          "type": "boolean",
 | 
					          "type": "boolean",
 | 
				
			||||||
          "x-go-name": "Private"
 | 
					          "x-go-name": "Private"
 | 
				
			||||||
@@ -14323,6 +14332,10 @@
 | 
				
			|||||||
          "type": "boolean",
 | 
					          "type": "boolean",
 | 
				
			||||||
          "x-go-name": "Mirror"
 | 
					          "x-go-name": "Mirror"
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
 | 
					        "mirror_interval": {
 | 
				
			||||||
 | 
					          "type": "string",
 | 
				
			||||||
 | 
					          "x-go-name": "MirrorInterval"
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
        "private": {
 | 
					        "private": {
 | 
				
			||||||
          "type": "boolean",
 | 
					          "type": "boolean",
 | 
				
			||||||
          "x-go-name": "Private"
 | 
					          "x-go-name": "Private"
 | 
				
			||||||
@@ -15307,6 +15320,10 @@
 | 
				
			|||||||
          "type": "boolean",
 | 
					          "type": "boolean",
 | 
				
			||||||
          "x-go-name": "Mirror"
 | 
					          "x-go-name": "Mirror"
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
 | 
					        "mirror_interval": {
 | 
				
			||||||
 | 
					          "type": "string",
 | 
				
			||||||
 | 
					          "x-go-name": "MirrorInterval"
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
        "name": {
 | 
					        "name": {
 | 
				
			||||||
          "type": "string",
 | 
					          "type": "string",
 | 
				
			||||||
          "x-go-name": "Name"
 | 
					          "x-go-name": "Name"
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user