When updating mirror repo intervals by API reschedule next update too (#19429)
When a mirror repo interval is updated by the UI it is rescheduled with that interval however the API does not do this. The API also lacks the enable_prune option. This PR adds this functionality in to the API Edit Repo endpoint. Signed-off-by: Andrew Thornton <art27@cantab.net>
This commit is contained in:
parent
a56fcdfa8f
commit
409ff55a29
4 changed files with 61 additions and 29 deletions
|
@ -187,6 +187,8 @@ type EditRepoOption struct {
|
||||||
Archived *bool `json:"archived,omitempty"`
|
Archived *bool `json:"archived,omitempty"`
|
||||||
// set to a string like `8h30m0s` to set the mirror interval time
|
// set to a string like `8h30m0s` to set the mirror interval time
|
||||||
MirrorInterval *string `json:"mirror_interval,omitempty"`
|
MirrorInterval *string `json:"mirror_interval,omitempty"`
|
||||||
|
// enable prune - remove obsolete remote-tracking references
|
||||||
|
EnablePrune *bool `json:"enable_prune,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// GenerateRepoOption options when creating repository using a template
|
// GenerateRepoOption options when creating repository using a template
|
||||||
|
|
|
@ -614,7 +614,7 @@ func Edit(ctx *context.APIContext) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if opts.MirrorInterval != nil {
|
if opts.MirrorInterval != nil {
|
||||||
if err := updateMirrorInterval(ctx, opts); err != nil {
|
if err := updateMirror(ctx, opts); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -943,37 +943,67 @@ func updateRepoArchivedState(ctx *context.APIContext, opts api.EditRepoOption) e
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// updateMirrorInterval updates the repo's mirror Interval
|
// updateMirror updates a repo's mirror Interval and EnablePrune
|
||||||
func updateMirrorInterval(ctx *context.APIContext, opts api.EditRepoOption) error {
|
func updateMirror(ctx *context.APIContext, opts api.EditRepoOption) error {
|
||||||
repo := ctx.Repo.Repository
|
repo := ctx.Repo.Repository
|
||||||
|
|
||||||
|
// only update mirror if interval or enable prune are provided
|
||||||
|
if opts.MirrorInterval == nil && opts.EnablePrune == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// these values only make sense if the repo is a mirror
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
// get the mirror from the repo
|
||||||
|
mirror, err := repo_model.GetMirrorByRepoID(repo.ID)
|
||||||
|
if err != nil {
|
||||||
|
log.Error("Failed to get mirror: %s", err)
|
||||||
|
ctx.Error(http.StatusInternalServerError, "MirrorInterval", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// update MirrorInterval
|
||||||
if opts.MirrorInterval != nil {
|
if opts.MirrorInterval != nil {
|
||||||
if !repo.IsMirror {
|
|
||||||
err := fmt.Errorf("repo is not a mirror, can not change mirror interval")
|
// MirrorInterval should be a duration
|
||||||
ctx.Error(http.StatusUnprocessableEntity, err.Error(), err)
|
interval, err := time.ParseDuration(*opts.MirrorInterval)
|
||||||
return err
|
|
||||||
}
|
|
||||||
mirror, err := repo_model.GetMirrorByRepoID(repo.ID)
|
|
||||||
if err != nil {
|
if 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 {
|
|
||||||
mirror.Interval = interval
|
|
||||||
mirror.Repo = repo
|
|
||||||
if err := repo_model.UpdateMirror(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)
|
log.Error("Wrong format for MirrorInternal Sent: %s", err)
|
||||||
ctx.Error(http.StatusUnprocessableEntity, "MirrorInterval", err)
|
ctx.Error(http.StatusUnprocessableEntity, "MirrorInterval", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Ensure the provided duration is not too short
|
||||||
|
if interval != 0 && interval < setting.Mirror.MinInterval {
|
||||||
|
err := fmt.Errorf("invalid mirror interval: %s is below minimum interval: %s", interval, setting.Mirror.MinInterval)
|
||||||
|
ctx.Error(http.StatusUnprocessableEntity, "MirrorInterval", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
mirror.Interval = interval
|
||||||
|
mirror.Repo = repo
|
||||||
|
mirror.ScheduleNextUpdate()
|
||||||
|
log.Trace("Repository %s Mirror[%d] Set Interval: %s NextUpdateUnix: %s", repo.FullName(), mirror.ID, interval, mirror.NextUpdateUnix)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// update EnablePrune
|
||||||
|
if opts.EnablePrune != nil {
|
||||||
|
mirror.EnablePrune = *opts.EnablePrune
|
||||||
|
log.Trace("Repository %s Mirror[%d] Set EnablePrune: %t", repo.FullName(), mirror.ID, mirror.EnablePrune)
|
||||||
|
}
|
||||||
|
|
||||||
|
// finally update the mirror in the DB
|
||||||
|
if err := repo_model.UpdateMirror(mirror); err != nil {
|
||||||
|
log.Error("Failed to Set Mirror Interval: %s", err)
|
||||||
|
ctx.Error(http.StatusUnprocessableEntity, "MirrorInterval", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -32,7 +32,6 @@ import (
|
||||||
"code.gitea.io/gitea/modules/repository"
|
"code.gitea.io/gitea/modules/repository"
|
||||||
"code.gitea.io/gitea/modules/setting"
|
"code.gitea.io/gitea/modules/setting"
|
||||||
"code.gitea.io/gitea/modules/structs"
|
"code.gitea.io/gitea/modules/structs"
|
||||||
"code.gitea.io/gitea/modules/timeutil"
|
|
||||||
"code.gitea.io/gitea/modules/typesniffer"
|
"code.gitea.io/gitea/modules/typesniffer"
|
||||||
"code.gitea.io/gitea/modules/util"
|
"code.gitea.io/gitea/modules/util"
|
||||||
"code.gitea.io/gitea/modules/validation"
|
"code.gitea.io/gitea/modules/validation"
|
||||||
|
@ -195,11 +194,7 @@ func SettingsPost(ctx *context.Context) {
|
||||||
} else {
|
} else {
|
||||||
ctx.Repo.Mirror.EnablePrune = form.EnablePrune
|
ctx.Repo.Mirror.EnablePrune = form.EnablePrune
|
||||||
ctx.Repo.Mirror.Interval = interval
|
ctx.Repo.Mirror.Interval = interval
|
||||||
if interval != 0 {
|
ctx.Repo.Mirror.ScheduleNextUpdate()
|
||||||
ctx.Repo.Mirror.NextUpdateUnix = timeutil.TimeStampNow().AddDuration(interval)
|
|
||||||
} else {
|
|
||||||
ctx.Repo.Mirror.NextUpdateUnix = 0
|
|
||||||
}
|
|
||||||
if err := repo_model.UpdateMirror(ctx.Repo.Mirror); err != nil {
|
if err := repo_model.UpdateMirror(ctx.Repo.Mirror); err != nil {
|
||||||
ctx.Data["Err_Interval"] = true
|
ctx.Data["Err_Interval"] = true
|
||||||
ctx.RenderWithErr(ctx.Tr("repo.mirror_interval_invalid"), tplSettingsOptions, &form)
|
ctx.RenderWithErr(ctx.Tr("repo.mirror_interval_invalid"), tplSettingsOptions, &form)
|
||||||
|
|
|
@ -15084,6 +15084,11 @@
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"x-go-name": "Description"
|
"x-go-name": "Description"
|
||||||
},
|
},
|
||||||
|
"enable_prune": {
|
||||||
|
"description": "enable prune - remove obsolete remote-tracking references",
|
||||||
|
"type": "boolean",
|
||||||
|
"x-go-name": "EnablePrune"
|
||||||
|
},
|
||||||
"external_tracker": {
|
"external_tracker": {
|
||||||
"$ref": "#/definitions/ExternalTracker"
|
"$ref": "#/definitions/ExternalTracker"
|
||||||
},
|
},
|
||||||
|
|
Reference in a new issue