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:
parent
3abea9e9eb
commit
7576e37a65
10 changed files with 115 additions and 21 deletions
|
@ -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 a new issue