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:
Paul Barton 2021-01-02 23:47:47 +00:00 committed by GitHub
parent 3abea9e9eb
commit 7576e37a65
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 115 additions and 21 deletions

View file

@ -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

View file

@ -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

View file

@ -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,
} }
} }

View file

@ -33,4 +33,5 @@ type MigrateOptions struct {
PullRequests bool PullRequests bool
ReleaseAssets bool ReleaseAssets bool
MigrateToRepoID int64 MigrateToRepoID int64
MirrorInterval string `json:"mirror_interval"`
} }

View file

@ -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

View file

@ -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)
} }

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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"