mirror of
				https://gitee.com/gitea/gitea
				synced 2025-11-04 16:40:24 +08:00 
			
		
		
		
	Backport #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:
		@@ -183,6 +183,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
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -624,7 +624,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
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -949,37 +949,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
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -31,7 +31,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"
 | 
				
			||||||
@@ -194,11 +193,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)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -14757,6 +14757,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 New Issue
	
	Block a user