From f3ba3e922dde7d12999a90d6cee15805a56cc7ff Mon Sep 17 00:00:00 2001 From: JakobDev <jakobdev@gmx.de> Date: Wed, 24 Jan 2024 03:32:57 +0100 Subject: [PATCH] Don't run push mirrors for archived repos (#27140) Fixes https://codeberg.org/forgejo/forgejo/issues/612 At the moment push mirrors are still run if a repo is archived. This PR fixes this. --- models/repo/pushmirror.go | 7 +- options/locale/locale_en-US.ini | 1 + routers/api/v1/api.go | 8 +- routers/web/repo/setting/setting.go | 10 +- templates/repo/settings/options.tmpl | 346 ++++++++++++++------------- 5 files changed, 191 insertions(+), 181 deletions(-) diff --git a/models/repo/pushmirror.go b/models/repo/pushmirror.go index 24c58faf84..bf134abfb1 100644 --- a/models/repo/pushmirror.go +++ b/models/repo/pushmirror.go @@ -121,8 +121,11 @@ func GetPushMirrorsSyncedOnCommit(ctx context.Context, repoID int64) ([]*PushMir // PushMirrorsIterate iterates all push-mirror repositories. func PushMirrorsIterate(ctx context.Context, limit int, f func(idx int, bean any) error) error { sess := db.GetEngine(ctx). - Where("last_update + (`interval` / ?) <= ?", time.Second, time.Now().Unix()). - And("`interval` != 0"). + Table("push_mirror"). + Join("INNER", "`repository`", "`repository`.id = `push_mirror`.repo_id"). + Where("`push_mirror`.last_update + (`push_mirror`.`interval` / ?) <= ?", time.Second, time.Now().Unix()). + And("`push_mirror`.`interval` != 0"). + And("`repository`.is_archived = ?", false). OrderBy("last_update ASC") if limit > 0 { sess = sess.Limit(limit) diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index 9a06bb0952..3bf8aa3845 100644 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -2377,6 +2377,7 @@ settings.archive.error = An error occurred while trying to archive the repo. See settings.archive.error_ismirror = You cannot archive a mirrored repo. settings.archive.branchsettings_unavailable = Branch settings are not available if the repo is archived. settings.archive.tagsettings_unavailable = Tag settings are not available if the repo is archived. +settings.archive.mirrors_unavailable = Mirrors are not available if the repo is archived. settings.unarchive.button = Unarchive repo settings.unarchive.header = Unarchive this repo settings.unarchive.text = Unarchiving the repo will restore its ability to receive commits and pushes, as well as new issues and pull-requests. diff --git a/routers/api/v1/api.go b/routers/api/v1/api.go index 8d7669762b..cb1803f7c6 100644 --- a/routers/api/v1/api.go +++ b/routers/api/v1/api.go @@ -1181,13 +1181,13 @@ func Routes() *web.Route { Delete(reqToken(), reqRepoWriter(unit.TypeReleases), repo.DeleteReleaseByTag) }) }, reqRepoReader(unit.TypeReleases)) - m.Post("/mirror-sync", reqToken(), reqRepoWriter(unit.TypeCode), repo.MirrorSync) - m.Post("/push_mirrors-sync", reqAdmin(), reqToken(), repo.PushMirrorSync) + m.Post("/mirror-sync", reqToken(), reqRepoWriter(unit.TypeCode), mustNotBeArchived, repo.MirrorSync) + m.Post("/push_mirrors-sync", reqAdmin(), reqToken(), mustNotBeArchived, repo.PushMirrorSync) m.Group("/push_mirrors", func() { m.Combo("").Get(repo.ListPushMirrors). - Post(bind(api.CreatePushMirrorOption{}), repo.AddPushMirror) + Post(mustNotBeArchived, bind(api.CreatePushMirrorOption{}), repo.AddPushMirror) m.Combo("/{name}"). - Delete(repo.DeletePushMirrorByRemoteName). + Delete(mustNotBeArchived, repo.DeletePushMirrorByRemoteName). Get(repo.GetPushMirrorByName) }, reqAdmin(), reqToken()) diff --git a/routers/web/repo/setting/setting.go b/routers/web/repo/setting/setting.go index e721b7c739..fc1403b3cc 100644 --- a/routers/web/repo/setting/setting.go +++ b/routers/web/repo/setting/setting.go @@ -185,7 +185,7 @@ func SettingsPost(ctx *context.Context) { ctx.Redirect(repo.Link() + "/settings") case "mirror": - if !setting.Mirror.Enabled || !repo.IsMirror { + if !setting.Mirror.Enabled || !repo.IsMirror || repo.IsArchived { ctx.NotFound("", nil) return } @@ -278,7 +278,7 @@ func SettingsPost(ctx *context.Context) { ctx.Redirect(repo.Link() + "/settings") case "mirror-sync": - if !setting.Mirror.Enabled || !repo.IsMirror { + if !setting.Mirror.Enabled || !repo.IsMirror || repo.IsArchived { ctx.NotFound("", nil) return } @@ -306,7 +306,7 @@ func SettingsPost(ctx *context.Context) { ctx.Redirect(repo.Link() + "/settings") case "push-mirror-update": - if !setting.Mirror.Enabled { + if !setting.Mirror.Enabled || repo.IsArchived { ctx.NotFound("", nil) return } @@ -343,7 +343,7 @@ func SettingsPost(ctx *context.Context) { ctx.Redirect(repo.Link() + "/settings") case "push-mirror-remove": - if !setting.Mirror.Enabled { + if !setting.Mirror.Enabled || repo.IsArchived { ctx.NotFound("", nil) return } @@ -372,7 +372,7 @@ func SettingsPost(ctx *context.Context) { ctx.Redirect(repo.Link() + "/settings") case "push-mirror-add": - if setting.Mirror.DisableNewPush { + if setting.Mirror.DisableNewPush || repo.IsArchived { ctx.NotFound("", nil) return } diff --git a/templates/repo/settings/options.tmpl b/templates/repo/settings/options.tmpl index 8456bb409b..07b2f58d53 100644 --- a/templates/repo/settings/options.tmpl +++ b/templates/repo/settings/options.tmpl @@ -79,206 +79,212 @@ {{ctx.Locale.Tr "repo.settings.mirror_settings"}} </h4> <div class="ui attached segment"> - {{if $newMirrorsEntirelyEnabled}} - {{ctx.Locale.Tr "repo.settings.mirror_settings.docs"}} - <a target="_blank" rel="noopener noreferrer" href="https://docs.gitea.com/usage/repo-mirror#pushing-to-a-remote-repository">{{ctx.Locale.Tr "repo.settings.mirror_settings.docs.doc_link_title"}}</a><br><br> - {{ctx.Locale.Tr "repo.settings.mirror_settings.docs.pull_mirror_instructions"}} - <a target="_blank" rel="noopener noreferrer" href="https://docs.gitea.com/usage/repo-mirror#pulling-from-a-remote-repository">{{ctx.Locale.Tr "repo.settings.mirror_settings.docs.doc_link_pull_section"}}</a><br> - {{else if $onlyNewPushMirrorsEnabled}} - {{ctx.Locale.Tr "repo.settings.mirror_settings.docs.disabled_pull_mirror.instructions"}} - {{ctx.Locale.Tr "repo.settings.mirror_settings.docs.more_information_if_disabled"}} - <a target="_blank" rel="noopener noreferrer" href="https://docs.gitea.com/usage/repo-mirror#pulling-from-a-remote-repository">{{ctx.Locale.Tr "repo.settings.mirror_settings.docs.doc_link_title"}}</a><br> - {{else if $onlyNewPullMirrorsEnabled}} - {{ctx.Locale.Tr "repo.settings.mirror_settings.docs.disabled_push_mirror.instructions"}} - {{ctx.Locale.Tr "repo.settings.mirror_settings.docs.disabled_push_mirror.pull_mirror_warning"}} - {{ctx.Locale.Tr "repo.settings.mirror_settings.docs.more_information_if_disabled"}} - <a target="_blank" rel="noopener noreferrer" href="https://docs.gitea.com/usage/repo-mirror#pulling-from-a-remote-repository">{{ctx.Locale.Tr "repo.settings.mirror_settings.docs.doc_link_title"}}</a><br><br> - {{ctx.Locale.Tr "repo.settings.mirror_settings.docs.disabled_push_mirror.info"}} - {{if $existingPushMirror}} - {{ctx.Locale.Tr "repo.settings.mirror_settings.docs.can_still_use"}} - {{end}} + {{if .Repository.IsArchived}} + <div class="ui warning message gt-text-center"> + {{ctx.Locale.Tr "repo.settings.archive.mirrors_unavailable"}} + </div> {{else}} - {{ctx.Locale.Tr "repo.settings.mirror_settings.docs.no_new_mirrors"}} {{ctx.Locale.Tr "repo.settings.mirror_settings.docs.can_still_use"}}<br> - {{end}} - <table class="ui table"> - {{if $existingPushMirror}} - <thead> - <tr> - <th style="width:40%">{{ctx.Locale.Tr "repo.settings.mirror_settings.mirrored_repository"}}</th> - <th>{{ctx.Locale.Tr "repo.settings.mirror_settings.direction"}}</th> - <th>{{ctx.Locale.Tr "repo.settings.mirror_settings.last_update"}}</th> - <th></th> - </tr> - </thead> + {{if $newMirrorsEntirelyEnabled}} + {{ctx.Locale.Tr "repo.settings.mirror_settings.docs"}} + <a target="_blank" rel="noopener noreferrer" href="https://docs.gitea.com/usage/repo-mirror#pushing-to-a-remote-repository">{{ctx.Locale.Tr "repo.settings.mirror_settings.docs.doc_link_title"}}</a><br><br> + {{ctx.Locale.Tr "repo.settings.mirror_settings.docs.pull_mirror_instructions"}} + <a target="_blank" rel="noopener noreferrer" href="https://docs.gitea.com/usage/repo-mirror#pulling-from-a-remote-repository">{{ctx.Locale.Tr "repo.settings.mirror_settings.docs.doc_link_pull_section"}}</a><br> + {{else if $onlyNewPushMirrorsEnabled}} + {{ctx.Locale.Tr "repo.settings.mirror_settings.docs.disabled_pull_mirror.instructions"}} + {{ctx.Locale.Tr "repo.settings.mirror_settings.docs.more_information_if_disabled"}} + <a target="_blank" rel="noopener noreferrer" href="https://docs.gitea.com/usage/repo-mirror#pulling-from-a-remote-repository">{{ctx.Locale.Tr "repo.settings.mirror_settings.docs.doc_link_title"}}</a><br> + {{else if $onlyNewPullMirrorsEnabled}} + {{ctx.Locale.Tr "repo.settings.mirror_settings.docs.disabled_push_mirror.instructions"}} + {{ctx.Locale.Tr "repo.settings.mirror_settings.docs.disabled_push_mirror.pull_mirror_warning"}} + {{ctx.Locale.Tr "repo.settings.mirror_settings.docs.more_information_if_disabled"}} + <a target="_blank" rel="noopener noreferrer" href="https://docs.gitea.com/usage/repo-mirror#pulling-from-a-remote-repository">{{ctx.Locale.Tr "repo.settings.mirror_settings.docs.doc_link_title"}}</a><br><br> + {{ctx.Locale.Tr "repo.settings.mirror_settings.docs.disabled_push_mirror.info"}} + {{if $existingPushMirror}} + {{ctx.Locale.Tr "repo.settings.mirror_settings.docs.can_still_use"}} + {{end}} + {{else}} + {{ctx.Locale.Tr "repo.settings.mirror_settings.docs.no_new_mirrors"}} {{ctx.Locale.Tr "repo.settings.mirror_settings.docs.can_still_use"}}<br> {{end}} - {{if $modifyBrokenPullMirror}} - {{/* even if a repo is a pull mirror (IsMirror=true), the PullMirror might still be nil if the mirror migration is broken */}} + <table class="ui table"> + {{if $existingPushMirror}} + <thead> + <tr> + <th style="width:40%">{{ctx.Locale.Tr "repo.settings.mirror_settings.mirrored_repository"}}</th> + <th>{{ctx.Locale.Tr "repo.settings.mirror_settings.direction"}}</th> + <th>{{ctx.Locale.Tr "repo.settings.mirror_settings.last_update"}}</th> + <th></th> + </tr> + </thead> + {{end}} + {{if $modifyBrokenPullMirror}} + {{/* even if a repo is a pull mirror (IsMirror=true), the PullMirror might still be nil if the mirror migration is broken */}} + <tbody> + <tr> + <td colspan="4"> + <div class="text red gt-py-4 gt-border-secondary-bottom">{{ctx.Locale.Tr "repo.settings.mirror_settings.direction.pull"}}: {{ctx.Locale.Tr "error.occurred"}}</div> + </td> + </tr> + </tbody> + {{else if $isWorkingPullMirror}} <tbody> <tr> - <td colspan="4"> - <div class="text red gt-py-4 gt-border-secondary-bottom">{{ctx.Locale.Tr "repo.settings.mirror_settings.direction.pull"}}: {{ctx.Locale.Tr "error.occurred"}}</div> + <td>{{.PullMirror.RemoteAddress}}</td> + <td>{{ctx.Locale.Tr "repo.settings.mirror_settings.direction.pull"}}</td> + <td>{{DateTime "full" .PullMirror.UpdatedUnix}}</td> + <td class="right aligned"> + <form method="post" class="gt-dib"> + {{.CsrfTokenHtml}} + <input type="hidden" name="action" value="mirror-sync"> + <button class="ui primary tiny button inline text-thin">{{ctx.Locale.Tr "repo.settings.sync_mirror"}}</button> + </form> </td> </tr> - </tbody> - {{else if $isWorkingPullMirror}} - <tbody> - <tr> - <td>{{.PullMirror.RemoteAddress}}</td> - <td>{{ctx.Locale.Tr "repo.settings.mirror_settings.direction.pull"}}</td> - <td>{{DateTime "full" .PullMirror.UpdatedUnix}}</td> - <td class="right aligned"> - <form method="post" class="gt-dib"> - {{.CsrfTokenHtml}} - <input type="hidden" name="action" value="mirror-sync"> - <button class="ui primary tiny button inline text-thin">{{ctx.Locale.Tr "repo.settings.sync_mirror"}}</button> - </form> - </td> - </tr> - <tr> - <td colspan="4"> - <form class="ui form" method="post"> - {{template "base/disable_form_autofill"}} - {{.CsrfTokenHtml}} - <input type="hidden" name="action" value="mirror"> - <div class="inline field {{if .Err_EnablePrune}}error{{end}}"> - <label>{{ctx.Locale.Tr "repo.mirror_prune"}}</label> - <div class="ui checkbox"> - <input id="enable_prune" name="enable_prune" type="checkbox" {{if .PullMirror.EnablePrune}}checked{{end}}> - <label>{{ctx.Locale.Tr "repo.mirror_prune_desc"}}</label> - </div> - </div> - <div class="inline field {{if .Err_Interval}}error{{end}}"> - <label for="interval">{{ctx.Locale.Tr "repo.mirror_interval" .MinimumMirrorInterval}}</label> - <input id="interval" name="interval" value="{{.PullMirror.Interval}}"> - </div> - {{$address := MirrorRemoteAddress $.Context .Repository .PullMirror.GetRemoteName false}} - <div class="field {{if .Err_MirrorAddress}}error{{end}}"> - <label for="mirror_address">{{ctx.Locale.Tr "repo.mirror_address"}}</label> - <input id="mirror_address" name="mirror_address" value="{{$address.Address}}" required> - <p class="help">{{ctx.Locale.Tr "repo.mirror_address_desc"}}</p> - </div> - <details class="ui optional field" {{if or .Err_Auth $address.Username}}open{{end}}> - <summary class="gt-p-2"> - {{ctx.Locale.Tr "repo.need_auth"}} - </summary> - <div class="gt-p-2"> - <div class="inline field {{if .Err_Auth}}error{{end}}"> - <label for="mirror_username">{{ctx.Locale.Tr "username"}}</label> - <input id="mirror_username" name="mirror_username" value="{{$address.Username}}" {{if not .mirror_username}}data-need-clear="true"{{end}}> - </div> - <div class="inline field {{if .Err_Auth}}error{{end}}"> - <label for="mirror_password">{{ctx.Locale.Tr "password"}}</label> - <input id="mirror_password" name="mirror_password" type="password" placeholder="{{if $address.Password}}{{ctx.Locale.Tr "repo.mirror_password_placeholder"}}{{else}}{{ctx.Locale.Tr "repo.mirror_password_blank_placeholder"}}{{end}}" value="" {{if not .mirror_password}}data-need-clear="true"{{end}} autocomplete="off"> - </div> - <p class="help">{{ctx.Locale.Tr "repo.mirror_password_help"}}</p> - </div> - </details> - - {{if .LFSStartServer}} - <div class="inline field"> - <label>{{ctx.Locale.Tr "repo.mirror_lfs"}}</label> - <div class="ui checkbox"> - <input id="mirror_lfs" name="mirror_lfs" type="checkbox" {{if .PullMirror.LFS}}checked{{end}}> - <label>{{ctx.Locale.Tr "repo.mirror_lfs_desc"}}</label> - </div> - </div> - <div class="field {{if .Err_LFSEndpoint}}error{{end}}"> - <label for="mirror_lfs_endpoint">{{ctx.Locale.Tr "repo.mirror_lfs_endpoint"}}</label> - <input id="mirror_lfs_endpoint" name="mirror_lfs_endpoint" value="{{.PullMirror.LFSEndpoint}}" placeholder="{{ctx.Locale.Tr "repo.migrate_options_lfs_endpoint.placeholder"}}"> - <p class="help">{{ctx.Locale.Tr "repo.mirror_lfs_endpoint_desc" "https://github.com/git-lfs/git-lfs/blob/main/docs/api/server-discovery.md#server-discovery" | Str2html}}</p> - </div> - {{end}} - <div class="field"> - <button class="ui primary button">{{ctx.Locale.Tr "repo.settings.update_mirror_settings"}}</button> - </div> - </form> - </td> - </tr> - </tbody> - <thead><tr><th colspan="4"></th></tr></thead> - {{end}}{{/* end if: IsMirror */}} - <tbody> - {{range .PushMirrors}} - <tr> - <td class="gt-word-break">{{.RemoteAddress}}</td> - <td>{{ctx.Locale.Tr "repo.settings.mirror_settings.direction.push"}}</td> - <td>{{if .LastUpdateUnix}}{{DateTime "full" .LastUpdateUnix}}{{else}}{{ctx.Locale.Tr "never"}}{{end}} {{if .LastError}}<div class="ui red label" data-tooltip-content="{{.LastError}}">{{ctx.Locale.Tr "error"}}</div>{{end}}</td> - <td class="right aligned"> - <button - class="ui tiny button show-modal" - data-modal="#push-mirror-edit-modal" - data-tooltip-content="{{ctx.Locale.Tr "repo.settings.mirror_settings.push_mirror.edit_sync_time"}}" - data-modal-push-mirror-edit-id="{{.ID}}" - data-modal-push-mirror-edit-interval="{{.Interval}}" - data-modal-push-mirror-edit-address="{{.RemoteAddress}}" - > - {{svg "octicon-pencil" 14}} - </button> - <form method="post" class="gt-dib"> - {{$.CsrfTokenHtml}} - <input type="hidden" name="action" value="push-mirror-sync"> - <input type="hidden" name="push_mirror_id" value="{{.ID}}"> - <button class="ui primary tiny button" data-tooltip-content="{{ctx.Locale.Tr "repo.settings.sync_mirror"}}">{{svg "octicon-sync" 14}}</button> - </form> - <form method="post" class="gt-dib"> - {{$.CsrfTokenHtml}} - <input type="hidden" name="action" value="push-mirror-remove"> - <input type="hidden" name="push_mirror_id" value="{{.ID}}"> - <button class="ui basic red tiny button" data-tooltip-content="{{ctx.Locale.Tr "remove"}}">{{svg "octicon-trash" 14}}</button> - </form> - </td> - </tr> - {{else}} - <tr> - <td>{{ctx.Locale.Tr "repo.settings.mirror_settings.push_mirror.none"}}</td> - </tr> - {{end}} - {{if (not .DisableNewPushMirrors)}} <tr> <td colspan="4"> <form class="ui form" method="post"> {{template "base/disable_form_autofill"}} {{.CsrfTokenHtml}} - <input type="hidden" name="action" value="push-mirror-add"> - <div class="field {{if .Err_PushMirrorAddress}}error{{end}}"> - <label for="push_mirror_address">{{ctx.Locale.Tr "repo.settings.mirror_settings.push_mirror.remote_url"}}</label> - <input id="push_mirror_address" name="push_mirror_address" value="{{.push_mirror_address}}" required> + <input type="hidden" name="action" value="mirror"> + <div class="inline field {{if .Err_EnablePrune}}error{{end}}"> + <label>{{ctx.Locale.Tr "repo.mirror_prune"}}</label> + <div class="ui checkbox"> + <input id="enable_prune" name="enable_prune" type="checkbox" {{if .PullMirror.EnablePrune}}checked{{end}}> + <label>{{ctx.Locale.Tr "repo.mirror_prune_desc"}}</label> + </div> + </div> + <div class="inline field {{if .Err_Interval}}error{{end}}"> + <label for="interval">{{ctx.Locale.Tr "repo.mirror_interval" .MinimumMirrorInterval}}</label> + <input id="interval" name="interval" value="{{.PullMirror.Interval}}"> + </div> + {{$address := MirrorRemoteAddress $.Context .Repository .PullMirror.GetRemoteName false}} + <div class="field {{if .Err_MirrorAddress}}error{{end}}"> + <label for="mirror_address">{{ctx.Locale.Tr "repo.mirror_address"}}</label> + <input id="mirror_address" name="mirror_address" value="{{$address.Address}}" required> <p class="help">{{ctx.Locale.Tr "repo.mirror_address_desc"}}</p> </div> - <details class="ui optional field" {{if or .Err_PushMirrorAuth .push_mirror_username}}open{{end}}> + <details class="ui optional field" {{if or .Err_Auth $address.Username}}open{{end}}> <summary class="gt-p-2"> {{ctx.Locale.Tr "repo.need_auth"}} </summary> <div class="gt-p-2"> - <div class="inline field {{if .Err_PushMirrorAuth}}error{{end}}"> - <label for="push_mirror_username">{{ctx.Locale.Tr "username"}}</label> - <input id="push_mirror_username" name="push_mirror_username" value="{{.push_mirror_username}}"> + <div class="inline field {{if .Err_Auth}}error{{end}}"> + <label for="mirror_username">{{ctx.Locale.Tr "username"}}</label> + <input id="mirror_username" name="mirror_username" value="{{$address.Username}}" {{if not .mirror_username}}data-need-clear="true"{{end}}> </div> - <div class="inline field {{if .Err_PushMirrorAuth}}error{{end}}"> - <label for="push_mirror_password">{{ctx.Locale.Tr "password"}}</label> - <input id="push_mirror_password" name="push_mirror_password" type="password" value="{{.push_mirror_password}}" autocomplete="off"> + <div class="inline field {{if .Err_Auth}}error{{end}}"> + <label for="mirror_password">{{ctx.Locale.Tr "password"}}</label> + <input id="mirror_password" name="mirror_password" type="password" placeholder="{{if $address.Password}}{{ctx.Locale.Tr "repo.mirror_password_placeholder"}}{{else}}{{ctx.Locale.Tr "repo.mirror_password_blank_placeholder"}}{{end}}" value="" {{if not .mirror_password}}data-need-clear="true"{{end}} autocomplete="off"> </div> + <p class="help">{{ctx.Locale.Tr "repo.mirror_password_help"}}</p> </div> </details> - <div class="field"> + + {{if .LFSStartServer}} + <div class="inline field"> + <label>{{ctx.Locale.Tr "repo.mirror_lfs"}}</label> <div class="ui checkbox"> - <input id="push_mirror_sync_on_commit" name="push_mirror_sync_on_commit" type="checkbox" {{if .push_mirror_sync_on_commit}}checked{{end}}> - <label for="push_mirror_sync_on_commit">{{ctx.Locale.Tr "repo.mirror_sync_on_commit"}}</label> + <input id="mirror_lfs" name="mirror_lfs" type="checkbox" {{if .PullMirror.LFS}}checked{{end}}> + <label>{{ctx.Locale.Tr "repo.mirror_lfs_desc"}}</label> </div> </div> - <div class="inline field {{if .Err_PushMirrorInterval}}error{{end}}"> - <label for="push_mirror_interval">{{ctx.Locale.Tr "repo.mirror_interval" .MinimumMirrorInterval}}</label> - <input id="push_mirror_interval" name="push_mirror_interval" value="{{if .push_mirror_interval}}{{.push_mirror_interval}}{{else}}{{.DefaultMirrorInterval}}{{end}}"> + <div class="field {{if .Err_LFSEndpoint}}error{{end}}"> + <label for="mirror_lfs_endpoint">{{ctx.Locale.Tr "repo.mirror_lfs_endpoint"}}</label> + <input id="mirror_lfs_endpoint" name="mirror_lfs_endpoint" value="{{.PullMirror.LFSEndpoint}}" placeholder="{{ctx.Locale.Tr "repo.migrate_options_lfs_endpoint.placeholder"}}"> + <p class="help">{{ctx.Locale.Tr "repo.mirror_lfs_endpoint_desc" "https://github.com/git-lfs/git-lfs/blob/main/docs/api/server-discovery.md#server-discovery" | Str2html}}</p> </div> + {{end}} <div class="field"> - <button class="ui primary button">{{ctx.Locale.Tr "repo.settings.mirror_settings.push_mirror.add"}}</button> + <button class="ui primary button">{{ctx.Locale.Tr "repo.settings.update_mirror_settings"}}</button> </div> </form> </td> </tr> - {{end}} - </tbody> - </table> + </tbody> + <thead><tr><th colspan="4"></th></tr></thead> + {{end}}{{/* end if: IsMirror */}} + <tbody> + {{range .PushMirrors}} + <tr> + <td class="gt-word-break">{{.RemoteAddress}}</td> + <td>{{ctx.Locale.Tr "repo.settings.mirror_settings.direction.push"}}</td> + <td>{{if .LastUpdateUnix}}{{DateTime "full" .LastUpdateUnix}}{{else}}{{ctx.Locale.Tr "never"}}{{end}} {{if .LastError}}<div class="ui red label" data-tooltip-content="{{.LastError}}">{{ctx.Locale.Tr "error"}}</div>{{end}}</td> + <td class="right aligned"> + <button + class="ui tiny button show-modal" + data-modal="#push-mirror-edit-modal" + data-tooltip-content="{{ctx.Locale.Tr "repo.settings.mirror_settings.push_mirror.edit_sync_time"}}" + data-modal-push-mirror-edit-id="{{.ID}}" + data-modal-push-mirror-edit-interval="{{.Interval}}" + data-modal-push-mirror-edit-address="{{.RemoteAddress}}" + > + {{svg "octicon-pencil" 14}} + </button> + <form method="post" class="gt-dib"> + {{$.CsrfTokenHtml}} + <input type="hidden" name="action" value="push-mirror-sync"> + <input type="hidden" name="push_mirror_id" value="{{.ID}}"> + <button class="ui primary tiny button" data-tooltip-content="{{ctx.Locale.Tr "repo.settings.sync_mirror"}}">{{svg "octicon-sync" 14}}</button> + </form> + <form method="post" class="gt-dib"> + {{$.CsrfTokenHtml}} + <input type="hidden" name="action" value="push-mirror-remove"> + <input type="hidden" name="push_mirror_id" value="{{.ID}}"> + <button class="ui basic red tiny button" data-tooltip-content="{{ctx.Locale.Tr "remove"}}">{{svg "octicon-trash" 14}}</button> + </form> + </td> + </tr> + {{else}} + <tr> + <td>{{ctx.Locale.Tr "repo.settings.mirror_settings.push_mirror.none"}}</td> + </tr> + {{end}} + {{if (not .DisableNewPushMirrors)}} + <tr> + <td colspan="4"> + <form class="ui form" method="post"> + {{template "base/disable_form_autofill"}} + {{.CsrfTokenHtml}} + <input type="hidden" name="action" value="push-mirror-add"> + <div class="field {{if .Err_PushMirrorAddress}}error{{end}}"> + <label for="push_mirror_address">{{ctx.Locale.Tr "repo.settings.mirror_settings.push_mirror.remote_url"}}</label> + <input id="push_mirror_address" name="push_mirror_address" value="{{.push_mirror_address}}" required> + <p class="help">{{ctx.Locale.Tr "repo.mirror_address_desc"}}</p> + </div> + <details class="ui optional field" {{if or .Err_PushMirrorAuth .push_mirror_username}}open{{end}}> + <summary class="gt-p-2"> + {{ctx.Locale.Tr "repo.need_auth"}} + </summary> + <div class="gt-p-2"> + <div class="inline field {{if .Err_PushMirrorAuth}}error{{end}}"> + <label for="push_mirror_username">{{ctx.Locale.Tr "username"}}</label> + <input id="push_mirror_username" name="push_mirror_username" value="{{.push_mirror_username}}"> + </div> + <div class="inline field {{if .Err_PushMirrorAuth}}error{{end}}"> + <label for="push_mirror_password">{{ctx.Locale.Tr "password"}}</label> + <input id="push_mirror_password" name="push_mirror_password" type="password" value="{{.push_mirror_password}}" autocomplete="off"> + </div> + </div> + </details> + <div class="field"> + <div class="ui checkbox"> + <input id="push_mirror_sync_on_commit" name="push_mirror_sync_on_commit" type="checkbox" {{if .push_mirror_sync_on_commit}}checked{{end}}> + <label for="push_mirror_sync_on_commit">{{ctx.Locale.Tr "repo.mirror_sync_on_commit"}}</label> + </div> + </div> + <div class="inline field {{if .Err_PushMirrorInterval}}error{{end}}"> + <label for="push_mirror_interval">{{ctx.Locale.Tr "repo.mirror_interval" .MinimumMirrorInterval}}</label> + <input id="push_mirror_interval" name="push_mirror_interval" value="{{if .push_mirror_interval}}{{.push_mirror_interval}}{{else}}{{.DefaultMirrorInterval}}{{end}}"> + </div> + <div class="field"> + <button class="ui primary button">{{ctx.Locale.Tr "repo.settings.mirror_settings.push_mirror.add"}}</button> + </div> + </form> + </td> + </tr> + {{end}} + </tbody> + </table> + {{end}} </div> {{end}}