]> source.dussan.org Git - gitea.git/commitdiff
When updating mirror repo intervals by API reschedule next update too (#19429) (...
authorzeripath <art27@cantab.net>
Wed, 20 Apr 2022 14:04:26 +0000 (15:04 +0100)
committerGitHub <noreply@github.com>
Wed, 20 Apr 2022 14:04:26 +0000 (16:04 +0200)
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>
modules/structs/repo.go
routers/api/v1/repo/repo.go
routers/web/repo/setting.go
templates/swagger/v1_json.tmpl

index 680277ea609a74306a11b9f1a1df89f44cb49543..178704ab4faa52f1ae9109e3a4459e9e4d9927cf 100644 (file)
@@ -183,6 +183,8 @@ type EditRepoOption struct {
        Archived *bool `json:"archived,omitempty"`
        // set to a string like `8h30m0s` to set the mirror interval time
        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
index 340ba0f6d53f52046e0ed9e55a2b86121162ebac..af8b06ed2a4a47f7843a37e201d0cdb818835b12 100644 (file)
@@ -624,7 +624,7 @@ func Edit(ctx *context.APIContext) {
        }
 
        if opts.MirrorInterval != nil {
-               if err := updateMirrorInterval(ctx, opts); err != nil {
+               if err := updateMirror(ctx, opts); err != nil {
                        return
                }
        }
@@ -949,37 +949,67 @@ func updateRepoArchivedState(ctx *context.APIContext, opts api.EditRepoOption) e
        return nil
 }
 
-// updateMirrorInterval updates the repo's mirror Interval
-func updateMirrorInterval(ctx *context.APIContext, opts api.EditRepoOption) error {
+// updateMirror updates a repo's mirror Interval and EnablePrune
+func updateMirror(ctx *context.APIContext, opts api.EditRepoOption) error {
        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 !repo.IsMirror {
-                       err := fmt.Errorf("repo is not a mirror, can not change mirror interval")
-                       ctx.Error(http.StatusUnprocessableEntity, err.Error(), err)
-                       return err
-               }
-               mirror, err := repo_model.GetMirrorByRepoID(repo.ID)
+
+               // MirrorInterval should be a duration
+               interval, err := time.ParseDuration(*opts.MirrorInterval)
                if err != nil {
-                       log.Error("Failed to get mirror: %s", err)
-                       ctx.Error(http.StatusInternalServerError, "MirrorInterval", err)
+                       log.Error("Wrong format for MirrorInternal Sent: %s", err)
+                       ctx.Error(http.StatusUnprocessableEntity, "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)
+
+               // 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
 }
 
index b7269b67186ca852e4d0e367a505366ac99112ca..f89bffb00f114d2e5cc006bebd4a31090e95c339 100644 (file)
@@ -31,7 +31,6 @@ import (
        "code.gitea.io/gitea/modules/repository"
        "code.gitea.io/gitea/modules/setting"
        "code.gitea.io/gitea/modules/structs"
-       "code.gitea.io/gitea/modules/timeutil"
        "code.gitea.io/gitea/modules/typesniffer"
        "code.gitea.io/gitea/modules/util"
        "code.gitea.io/gitea/modules/validation"
@@ -194,11 +193,7 @@ func SettingsPost(ctx *context.Context) {
                } else {
                        ctx.Repo.Mirror.EnablePrune = form.EnablePrune
                        ctx.Repo.Mirror.Interval = interval
-                       if interval != 0 {
-                               ctx.Repo.Mirror.NextUpdateUnix = timeutil.TimeStampNow().AddDuration(interval)
-                       } else {
-                               ctx.Repo.Mirror.NextUpdateUnix = 0
-                       }
+                       ctx.Repo.Mirror.ScheduleNextUpdate()
                        if err := repo_model.UpdateMirror(ctx.Repo.Mirror); err != nil {
                                ctx.Data["Err_Interval"] = true
                                ctx.RenderWithErr(ctx.Tr("repo.mirror_interval_invalid"), tplSettingsOptions, &form)
index bba728363a3e5fff0cdf5553fa10eefcdf7c3deb..1085dcba4ecda65ac8cee23b78ce3b6928b67a3b 100644 (file)
           "type": "string",
           "x-go-name": "Description"
         },
+        "enable_prune": {
+          "description": "enable prune - remove obsolete remote-tracking references",
+          "type": "boolean",
+          "x-go-name": "EnablePrune"
+        },
         "external_tracker": {
           "$ref": "#/definitions/ExternalTracker"
         },