forked from gitea/gitea
Add new API endpoints for push mirrors management (#19841)
- Add a new push mirror to specific repository - Sync now ( send all the changes to the configured push mirrors ) - Get list of all push mirrors of a repository - Get a push mirror by ID - Delete push mirror by ID Signed-off-by: Mohamed Sekour <mohamed.sekour@exfo.com> Signed-off-by: Andrew Thornton <art27@cantab.net> Co-authored-by: zeripath <art27@cantab.net>
This commit is contained in:
parent
e819da0837
commit
0e61a74e5a
|
@ -13,6 +13,7 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"code.gitea.io/gitea/models"
|
"code.gitea.io/gitea/models"
|
||||||
|
"code.gitea.io/gitea/models/db"
|
||||||
repo_model "code.gitea.io/gitea/models/repo"
|
repo_model "code.gitea.io/gitea/models/repo"
|
||||||
"code.gitea.io/gitea/models/unittest"
|
"code.gitea.io/gitea/models/unittest"
|
||||||
user_model "code.gitea.io/gitea/models/user"
|
user_model "code.gitea.io/gitea/models/user"
|
||||||
|
@ -47,7 +48,7 @@ func testMirrorPush(t *testing.T, u *url.URL) {
|
||||||
|
|
||||||
doCreatePushMirror(ctx, fmt.Sprintf("%s%s/%s", u.String(), url.PathEscape(ctx.Username), url.PathEscape(mirrorRepo.Name)), user.LowerName, userPassword)(t)
|
doCreatePushMirror(ctx, fmt.Sprintf("%s%s/%s", u.String(), url.PathEscape(ctx.Username), url.PathEscape(mirrorRepo.Name)), user.LowerName, userPassword)(t)
|
||||||
|
|
||||||
mirrors, err := repo_model.GetPushMirrorsByRepoID(srcRepo.ID)
|
mirrors, _, err := repo_model.GetPushMirrorsByRepoID(db.DefaultContext, srcRepo.ID, db.ListOptions{})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Len(t, mirrors, 1)
|
assert.Len(t, mirrors, 1)
|
||||||
|
|
||||||
|
@ -72,7 +73,7 @@ func testMirrorPush(t *testing.T, u *url.URL) {
|
||||||
|
|
||||||
// Cleanup
|
// Cleanup
|
||||||
doRemovePushMirror(ctx, fmt.Sprintf("%s%s/%s", u.String(), url.PathEscape(ctx.Username), url.PathEscape(mirrorRepo.Name)), user.LowerName, userPassword, int(mirrors[0].ID))(t)
|
doRemovePushMirror(ctx, fmt.Sprintf("%s%s/%s", u.String(), url.PathEscape(ctx.Username), url.PathEscape(mirrorRepo.Name)), user.LowerName, userPassword, int(mirrors[0].ID))(t)
|
||||||
mirrors, err = repo_model.GetPushMirrorsByRepoID(srcRepo.ID)
|
mirrors, _, err = repo_model.GetPushMirrorsByRepoID(db.DefaultContext, srcRepo.ID, db.ListOptions{})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Len(t, mirrors, 0)
|
assert.Len(t, mirrors, 0)
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,12 +5,15 @@
|
||||||
package repo
|
package repo
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"code.gitea.io/gitea/models/db"
|
"code.gitea.io/gitea/models/db"
|
||||||
"code.gitea.io/gitea/modules/log"
|
"code.gitea.io/gitea/modules/log"
|
||||||
"code.gitea.io/gitea/modules/timeutil"
|
"code.gitea.io/gitea/modules/timeutil"
|
||||||
|
|
||||||
|
"xorm.io/builder"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ErrPushMirrorNotExist mirror does not exist error
|
// ErrPushMirrorNotExist mirror does not exist error
|
||||||
|
@ -29,6 +32,25 @@ type PushMirror struct {
|
||||||
LastUpdateUnix timeutil.TimeStamp `xorm:"INDEX last_update"`
|
LastUpdateUnix timeutil.TimeStamp `xorm:"INDEX last_update"`
|
||||||
LastError string `xorm:"text"`
|
LastError string `xorm:"text"`
|
||||||
}
|
}
|
||||||
|
type PushMirrorOptions struct {
|
||||||
|
ID int64
|
||||||
|
RepoID int64
|
||||||
|
RemoteName string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (opts *PushMirrorOptions) toConds() builder.Cond {
|
||||||
|
cond := builder.NewCond()
|
||||||
|
if opts.RepoID > 0 {
|
||||||
|
cond = cond.And(builder.Eq{"repo_id": opts.RepoID})
|
||||||
|
}
|
||||||
|
if opts.RemoteName != "" {
|
||||||
|
cond = cond.And(builder.Eq{"remote_name": opts.RemoteName})
|
||||||
|
}
|
||||||
|
if opts.ID > 0 {
|
||||||
|
cond = cond.And(builder.Eq{"id": opts.ID})
|
||||||
|
}
|
||||||
|
return cond
|
||||||
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
db.RegisterModel(new(PushMirror))
|
db.RegisterModel(new(PushMirror))
|
||||||
|
@ -53,45 +75,48 @@ func (m *PushMirror) GetRemoteName() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
// InsertPushMirror inserts a push-mirror to database
|
// InsertPushMirror inserts a push-mirror to database
|
||||||
func InsertPushMirror(m *PushMirror) error {
|
func InsertPushMirror(ctx context.Context, m *PushMirror) error {
|
||||||
_, err := db.GetEngine(db.DefaultContext).Insert(m)
|
_, err := db.GetEngine(ctx).Insert(m)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdatePushMirror updates the push-mirror
|
// UpdatePushMirror updates the push-mirror
|
||||||
func UpdatePushMirror(m *PushMirror) error {
|
func UpdatePushMirror(ctx context.Context, m *PushMirror) error {
|
||||||
_, err := db.GetEngine(db.DefaultContext).ID(m.ID).AllCols().Update(m)
|
_, err := db.GetEngine(ctx).ID(m.ID).AllCols().Update(m)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeletePushMirrorByID deletes a push-mirrors by ID
|
func DeletePushMirrors(ctx context.Context, opts PushMirrorOptions) error {
|
||||||
func DeletePushMirrorByID(ID int64) error {
|
if opts.RepoID > 0 {
|
||||||
_, err := db.GetEngine(db.DefaultContext).ID(ID).Delete(&PushMirror{})
|
_, err := db.GetEngine(ctx).Where(opts.toConds()).Delete(&PushMirror{})
|
||||||
return err
|
return err
|
||||||
|
}
|
||||||
|
return errors.New("repoID required and must be set")
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeletePushMirrorsByRepoID deletes all push-mirrors by repoID
|
func GetPushMirror(ctx context.Context, opts PushMirrorOptions) (*PushMirror, error) {
|
||||||
func DeletePushMirrorsByRepoID(repoID int64) error {
|
mirror := &PushMirror{}
|
||||||
_, err := db.GetEngine(db.DefaultContext).Delete(&PushMirror{RepoID: repoID})
|
exist, err := db.GetEngine(ctx).Where(opts.toConds()).Get(mirror)
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetPushMirrorByID returns push-mirror information.
|
|
||||||
func GetPushMirrorByID(ID int64) (*PushMirror, error) {
|
|
||||||
m := &PushMirror{}
|
|
||||||
has, err := db.GetEngine(db.DefaultContext).ID(ID).Get(m)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
} else if !has {
|
} else if !exist {
|
||||||
return nil, ErrPushMirrorNotExist
|
return nil, ErrPushMirrorNotExist
|
||||||
}
|
}
|
||||||
return m, nil
|
return mirror, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetPushMirrorsByRepoID returns push-mirror information of a repository.
|
// GetPushMirrorsByRepoID returns push-mirror information of a repository.
|
||||||
func GetPushMirrorsByRepoID(repoID int64) ([]*PushMirror, error) {
|
func GetPushMirrorsByRepoID(ctx context.Context, repoID int64, listOptions db.ListOptions) ([]*PushMirror, int64, error) {
|
||||||
|
sess := db.GetEngine(ctx).Where("repo_id = ?", repoID)
|
||||||
|
if listOptions.Page != 0 {
|
||||||
|
sess = db.SetSessionPagination(sess, &listOptions)
|
||||||
|
mirrors := make([]*PushMirror, 0, listOptions.PageSize)
|
||||||
|
count, err := sess.FindAndCount(&mirrors)
|
||||||
|
return mirrors, count, err
|
||||||
|
}
|
||||||
mirrors := make([]*PushMirror, 0, 10)
|
mirrors := make([]*PushMirror, 0, 10)
|
||||||
return mirrors, db.GetEngine(db.DefaultContext).Where("repo_id=?", repoID).Find(&mirrors)
|
count, err := sess.FindAndCount(&mirrors)
|
||||||
|
return mirrors, count, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetPushMirrorsSyncedOnCommit returns push-mirrors for this repo that should be updated by new commits
|
// GetPushMirrorsSyncedOnCommit returns push-mirrors for this repo that should be updated by new commits
|
||||||
|
@ -103,8 +128,8 @@ func GetPushMirrorsSyncedOnCommit(repoID int64) ([]*PushMirror, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// PushMirrorsIterate iterates all push-mirror repositories.
|
// PushMirrorsIterate iterates all push-mirror repositories.
|
||||||
func PushMirrorsIterate(limit int, f func(idx int, bean interface{}) error) error {
|
func PushMirrorsIterate(ctx context.Context, limit int, f func(idx int, bean interface{}) error) error {
|
||||||
return db.GetEngine(db.DefaultContext).
|
return db.GetEngine(ctx).
|
||||||
Where("last_update + (`interval` / ?) <= ?", time.Second, time.Now().Unix()).
|
Where("last_update + (`interval` / ?) <= ?", time.Second, time.Now().Unix()).
|
||||||
And("`interval` != 0").
|
And("`interval` != 0").
|
||||||
OrderBy("last_update ASC").
|
OrderBy("last_update ASC").
|
||||||
|
|
|
@ -8,6 +8,7 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"code.gitea.io/gitea/models/db"
|
||||||
repo_model "code.gitea.io/gitea/models/repo"
|
repo_model "code.gitea.io/gitea/models/repo"
|
||||||
"code.gitea.io/gitea/models/unittest"
|
"code.gitea.io/gitea/models/unittest"
|
||||||
"code.gitea.io/gitea/modules/timeutil"
|
"code.gitea.io/gitea/modules/timeutil"
|
||||||
|
@ -20,20 +21,20 @@ func TestPushMirrorsIterate(t *testing.T) {
|
||||||
|
|
||||||
now := timeutil.TimeStampNow()
|
now := timeutil.TimeStampNow()
|
||||||
|
|
||||||
repo_model.InsertPushMirror(&repo_model.PushMirror{
|
repo_model.InsertPushMirror(db.DefaultContext, &repo_model.PushMirror{
|
||||||
RemoteName: "test-1",
|
RemoteName: "test-1",
|
||||||
LastUpdateUnix: now,
|
LastUpdateUnix: now,
|
||||||
Interval: 1,
|
Interval: 1,
|
||||||
})
|
})
|
||||||
|
|
||||||
long, _ := time.ParseDuration("24h")
|
long, _ := time.ParseDuration("24h")
|
||||||
repo_model.InsertPushMirror(&repo_model.PushMirror{
|
repo_model.InsertPushMirror(db.DefaultContext, &repo_model.PushMirror{
|
||||||
RemoteName: "test-2",
|
RemoteName: "test-2",
|
||||||
LastUpdateUnix: now,
|
LastUpdateUnix: now,
|
||||||
Interval: long,
|
Interval: long,
|
||||||
})
|
})
|
||||||
|
|
||||||
repo_model.InsertPushMirror(&repo_model.PushMirror{
|
repo_model.InsertPushMirror(db.DefaultContext, &repo_model.PushMirror{
|
||||||
RemoteName: "test-3",
|
RemoteName: "test-3",
|
||||||
LastUpdateUnix: now,
|
LastUpdateUnix: now,
|
||||||
Interval: 0,
|
Interval: 0,
|
||||||
|
@ -41,7 +42,7 @@ func TestPushMirrorsIterate(t *testing.T) {
|
||||||
|
|
||||||
time.Sleep(1 * time.Millisecond)
|
time.Sleep(1 * time.Millisecond)
|
||||||
|
|
||||||
repo_model.PushMirrorsIterate(1, func(idx int, bean interface{}) error {
|
repo_model.PushMirrorsIterate(db.DefaultContext, 1, func(idx int, bean interface{}) error {
|
||||||
m, ok := bean.(*repo_model.PushMirror)
|
m, ok := bean.(*repo_model.PushMirror)
|
||||||
assert.True(t, ok)
|
assert.True(t, ok)
|
||||||
assert.Equal(t, "test-1", m.RemoteName)
|
assert.Equal(t, "test-1", m.RemoteName)
|
||||||
|
|
|
@ -393,7 +393,7 @@ func repoAssignment(ctx *Context, repo *repo_model.Repository) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pushMirrors, err := repo_model.GetPushMirrorsByRepoID(repo.ID)
|
pushMirrors, _, err := repo_model.GetPushMirrorsByRepoID(ctx, repo.ID, db.ListOptions{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.ServerError("GetPushMirrorsByRepoID", err)
|
ctx.ServerError("GetPushMirrorsByRepoID", err)
|
||||||
return
|
return
|
||||||
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
// Copyright 2022 The Gitea Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package convert
|
||||||
|
|
||||||
|
import (
|
||||||
|
repo_model "code.gitea.io/gitea/models/repo"
|
||||||
|
"code.gitea.io/gitea/modules/git"
|
||||||
|
api "code.gitea.io/gitea/modules/structs"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ToPushMirror convert from repo_model.PushMirror and remoteAddress to api.TopicResponse
|
||||||
|
func ToPushMirror(pm *repo_model.PushMirror) (*api.PushMirror, error) {
|
||||||
|
repo := pm.GetRepository()
|
||||||
|
remoteAddress, err := getRemoteAddress(repo, pm.RemoteName)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &api.PushMirror{
|
||||||
|
RepoName: repo.Name,
|
||||||
|
RemoteName: pm.RemoteName,
|
||||||
|
RemoteAddress: remoteAddress,
|
||||||
|
CreatedUnix: pm.CreatedUnix.FormatLong(),
|
||||||
|
LastUpdateUnix: pm.LastUpdateUnix.FormatLong(),
|
||||||
|
LastError: pm.LastError,
|
||||||
|
Interval: pm.Interval.String(),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func getRemoteAddress(repo *repo_model.Repository, remoteName string) (string, error) {
|
||||||
|
url, err := git.GetRemoteURL(git.DefaultContext, repo.RepoPath(), remoteName)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
// remove confidential information
|
||||||
|
url.User = nil
|
||||||
|
return url.String(), nil
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
// Copyright 2021 The Gitea Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package structs
|
||||||
|
|
||||||
|
// CreatePushMirrorOption represents need information to create a push mirror of a repository.
|
||||||
|
type CreatePushMirrorOption struct {
|
||||||
|
RemoteAddress string `json:"remote_address"`
|
||||||
|
RemoteUsername string `json:"remote_username"`
|
||||||
|
RemotePassword string `json:"remote_password"`
|
||||||
|
Interval string `json:"interval"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// PushMirror represents information of a push mirror
|
||||||
|
// swagger:model
|
||||||
|
type PushMirror struct {
|
||||||
|
RepoName string `json:"repo_name"`
|
||||||
|
RemoteName string `json:"remote_name"`
|
||||||
|
RemoteAddress string `json:"remote_address"`
|
||||||
|
CreatedUnix string `json:"created"`
|
||||||
|
LastUpdateUnix string `json:"last_update"`
|
||||||
|
LastError string `json:"last_error"`
|
||||||
|
Interval string `json:"interval"`
|
||||||
|
}
|
|
@ -982,6 +982,15 @@ func Routes() *web.Route {
|
||||||
})
|
})
|
||||||
}, reqRepoReader(unit.TypeReleases))
|
}, reqRepoReader(unit.TypeReleases))
|
||||||
m.Post("/mirror-sync", reqToken(), reqRepoWriter(unit.TypeCode), repo.MirrorSync)
|
m.Post("/mirror-sync", reqToken(), reqRepoWriter(unit.TypeCode), repo.MirrorSync)
|
||||||
|
m.Post("/push_mirrors-sync", reqAdmin(), repo.PushMirrorSync)
|
||||||
|
m.Group("/push_mirrors", func() {
|
||||||
|
m.Combo("").Get(repo.ListPushMirrors).
|
||||||
|
Post(bind(api.CreatePushMirrorOption{}), repo.AddPushMirror)
|
||||||
|
m.Combo("/{name}").
|
||||||
|
Delete(repo.DeletePushMirrorByRemoteName).
|
||||||
|
Get(repo.GetPushMirrorByName)
|
||||||
|
}, reqAdmin())
|
||||||
|
|
||||||
m.Get("/editorconfig/{filename}", context.ReferencesGitRepo(), context.RepoRefForAPI, reqRepoReader(unit.TypeCode), repo.GetEditorconfig)
|
m.Get("/editorconfig/{filename}", context.ReferencesGitRepo(), context.RepoRefForAPI, reqRepoReader(unit.TypeCode), repo.GetEditorconfig)
|
||||||
m.Group("/pulls", func() {
|
m.Group("/pulls", func() {
|
||||||
m.Combo("").Get(repo.ListPullRequests).
|
m.Combo("").Get(repo.ListPullRequests).
|
||||||
|
|
|
@ -6,13 +6,25 @@ package repo
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"code.gitea.io/gitea/models"
|
||||||
|
"code.gitea.io/gitea/models/db"
|
||||||
repo_model "code.gitea.io/gitea/models/repo"
|
repo_model "code.gitea.io/gitea/models/repo"
|
||||||
"code.gitea.io/gitea/models/unit"
|
"code.gitea.io/gitea/models/unit"
|
||||||
"code.gitea.io/gitea/modules/context"
|
"code.gitea.io/gitea/modules/context"
|
||||||
|
"code.gitea.io/gitea/modules/convert"
|
||||||
mirror_module "code.gitea.io/gitea/modules/mirror"
|
mirror_module "code.gitea.io/gitea/modules/mirror"
|
||||||
"code.gitea.io/gitea/modules/setting"
|
"code.gitea.io/gitea/modules/setting"
|
||||||
|
api "code.gitea.io/gitea/modules/structs"
|
||||||
|
"code.gitea.io/gitea/modules/util"
|
||||||
|
"code.gitea.io/gitea/modules/web"
|
||||||
|
"code.gitea.io/gitea/routers/api/v1/utils"
|
||||||
|
"code.gitea.io/gitea/services/forms"
|
||||||
|
"code.gitea.io/gitea/services/migrations"
|
||||||
|
mirror_service "code.gitea.io/gitea/services/mirror"
|
||||||
)
|
)
|
||||||
|
|
||||||
// MirrorSync adds a mirrored repository to the sync queue
|
// MirrorSync adds a mirrored repository to the sync queue
|
||||||
|
@ -63,3 +75,317 @@ func MirrorSync(ctx *context.APIContext) {
|
||||||
|
|
||||||
ctx.Status(http.StatusOK)
|
ctx.Status(http.StatusOK)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PushMirrorSync adds all push mirrored repositories to the sync queue
|
||||||
|
func PushMirrorSync(ctx *context.APIContext) {
|
||||||
|
// swagger:operation POST /repos/{owner}/{repo}/push_mirrors-sync repository repoPushMirrorSync
|
||||||
|
// ---
|
||||||
|
// summary: Sync all push mirrored repository
|
||||||
|
// produces:
|
||||||
|
// - application/json
|
||||||
|
// parameters:
|
||||||
|
// - name: owner
|
||||||
|
// in: path
|
||||||
|
// description: owner of the repo to sync
|
||||||
|
// type: string
|
||||||
|
// required: true
|
||||||
|
// - name: repo
|
||||||
|
// in: path
|
||||||
|
// description: name of the repo to sync
|
||||||
|
// type: string
|
||||||
|
// required: true
|
||||||
|
// responses:
|
||||||
|
// "200":
|
||||||
|
// "$ref": "#/responses/empty"
|
||||||
|
// "400":
|
||||||
|
// "$ref": "#/responses/error"
|
||||||
|
// "403":
|
||||||
|
// "$ref": "#/responses/forbidden"
|
||||||
|
|
||||||
|
if !setting.Mirror.Enabled {
|
||||||
|
ctx.Error(http.StatusBadRequest, "PushMirrorSync", "Mirror feature is disabled")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// Get All push mirrors of a specific repo
|
||||||
|
pushMirrors, _, err := repo_model.GetPushMirrorsByRepoID(ctx, ctx.Repo.Repository.ID, db.ListOptions{})
|
||||||
|
if err != nil {
|
||||||
|
ctx.Error(http.StatusNotFound, "PushMirrorSync", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
for _, mirror := range pushMirrors {
|
||||||
|
ok := mirror_service.SyncPushMirror(ctx, mirror.ID)
|
||||||
|
if !ok {
|
||||||
|
ctx.Error(http.StatusInternalServerError, "PushMirrorSync", "error occurred when syncing push mirror "+mirror.RemoteName)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.Status(http.StatusOK)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListPushMirrors get list of push mirrors of a repository
|
||||||
|
func ListPushMirrors(ctx *context.APIContext) {
|
||||||
|
// swagger:operation GET /repos/{owner}/{repo}/push_mirrors repository repoListPushMirrors
|
||||||
|
// ---
|
||||||
|
// summary: Get all push mirrors of the repository
|
||||||
|
// produces:
|
||||||
|
// - application/json
|
||||||
|
// parameters:
|
||||||
|
// - name: owner
|
||||||
|
// in: path
|
||||||
|
// description: owner of the repo
|
||||||
|
// type: string
|
||||||
|
// required: true
|
||||||
|
// - name: repo
|
||||||
|
// in: path
|
||||||
|
// description: name of the repo
|
||||||
|
// type: string
|
||||||
|
// required: true
|
||||||
|
// - name: page
|
||||||
|
// in: query
|
||||||
|
// description: page number of results to return (1-based)
|
||||||
|
// type: integer
|
||||||
|
// - name: limit
|
||||||
|
// in: query
|
||||||
|
// description: page size of results
|
||||||
|
// type: integer
|
||||||
|
// responses:
|
||||||
|
// "200":
|
||||||
|
// "$ref": "#/responses/PushMirrorList"
|
||||||
|
// "400":
|
||||||
|
// "$ref": "#/responses/error"
|
||||||
|
// "403":
|
||||||
|
// "$ref": "#/responses/forbidden"
|
||||||
|
|
||||||
|
if !setting.Mirror.Enabled {
|
||||||
|
ctx.Error(http.StatusBadRequest, "GetPushMirrorsByRepoID", "Mirror feature is disabled")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
repo := ctx.Repo.Repository
|
||||||
|
// Get all push mirrors for the specified repository.
|
||||||
|
pushMirrors, count, err := repo_model.GetPushMirrorsByRepoID(ctx, repo.ID, utils.GetListOptions(ctx))
|
||||||
|
if err != nil {
|
||||||
|
ctx.Error(http.StatusNotFound, "GetPushMirrorsByRepoID", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
responsePushMirrors := make([]*api.PushMirror, 0, len(pushMirrors))
|
||||||
|
for _, mirror := range pushMirrors {
|
||||||
|
m, err := convert.ToPushMirror(mirror)
|
||||||
|
if err == nil {
|
||||||
|
responsePushMirrors = append(responsePushMirrors, m)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
ctx.SetLinkHeader(len(responsePushMirrors), utils.GetListOptions(ctx).PageSize)
|
||||||
|
ctx.SetTotalCountHeader(count)
|
||||||
|
ctx.JSON(http.StatusOK, responsePushMirrors)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetPushMirrorByName get push mirror of a repository by name
|
||||||
|
func GetPushMirrorByName(ctx *context.APIContext) {
|
||||||
|
// swagger:operation GET /repos/{owner}/{repo}/push_mirrors/{name} repository repoGetPushMirrorByRemoteName
|
||||||
|
// ---
|
||||||
|
// summary: Get push mirror of the repository by remoteName
|
||||||
|
// produces:
|
||||||
|
// - application/json
|
||||||
|
// parameters:
|
||||||
|
// - name: owner
|
||||||
|
// in: path
|
||||||
|
// description: owner of the repo
|
||||||
|
// type: string
|
||||||
|
// required: true
|
||||||
|
// - name: repo
|
||||||
|
// in: path
|
||||||
|
// description: name of the repo
|
||||||
|
// type: string
|
||||||
|
// required: true
|
||||||
|
// - name: name
|
||||||
|
// in: path
|
||||||
|
// description: remote name of push mirror
|
||||||
|
// type: string
|
||||||
|
// required: true
|
||||||
|
// responses:
|
||||||
|
// "200":
|
||||||
|
// "$ref": "#/responses/PushMirror"
|
||||||
|
// "400":
|
||||||
|
// "$ref": "#/responses/error"
|
||||||
|
// "403":
|
||||||
|
// "$ref": "#/responses/forbidden"
|
||||||
|
|
||||||
|
if !setting.Mirror.Enabled {
|
||||||
|
ctx.Error(http.StatusBadRequest, "GetPushMirrorByRemoteName", "Mirror feature is disabled")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
mirrorName := ctx.Params(":name")
|
||||||
|
// Get push mirror of a specific repo by remoteName
|
||||||
|
pushMirror, err := repo_model.GetPushMirror(ctx, repo_model.PushMirrorOptions{RepoID: ctx.Repo.Repository.ID, RemoteName: mirrorName})
|
||||||
|
if err != nil {
|
||||||
|
ctx.Error(http.StatusNotFound, "GetPushMirrors", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
m, err := convert.ToPushMirror(pushMirror)
|
||||||
|
if err != nil {
|
||||||
|
ctx.ServerError("GetPushMirrorByRemoteName", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ctx.JSON(http.StatusOK, m)
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddPushMirror adds a push mirror to a repository
|
||||||
|
func AddPushMirror(ctx *context.APIContext) {
|
||||||
|
// swagger:operation POST /repos/{owner}/{repo}/push_mirrors repository repoAddPushMirror
|
||||||
|
// ---
|
||||||
|
// summary: add a push mirror to the repository
|
||||||
|
// consumes:
|
||||||
|
// - application/json
|
||||||
|
// produces:
|
||||||
|
// - application/json
|
||||||
|
// parameters:
|
||||||
|
// - name: owner
|
||||||
|
// in: path
|
||||||
|
// description: owner of the repo
|
||||||
|
// type: string
|
||||||
|
// required: true
|
||||||
|
// - name: repo
|
||||||
|
// in: path
|
||||||
|
// description: name of the repo
|
||||||
|
// type: string
|
||||||
|
// required: true
|
||||||
|
// - name: body
|
||||||
|
// in: body
|
||||||
|
// schema:
|
||||||
|
// "$ref": "#/definitions/CreatePushMirrorOption"
|
||||||
|
// responses:
|
||||||
|
// "201":
|
||||||
|
// "$ref": "#/responses/PushMirror"
|
||||||
|
// "403":
|
||||||
|
// "$ref": "#/responses/forbidden"
|
||||||
|
// "400":
|
||||||
|
// "$ref": "#/responses/error"
|
||||||
|
|
||||||
|
if !setting.Mirror.Enabled {
|
||||||
|
ctx.Error(http.StatusBadRequest, "AddPushMirror", "Mirror feature is disabled")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
pushMirror := web.GetForm(ctx).(*api.CreatePushMirrorOption)
|
||||||
|
CreatePushMirror(ctx, pushMirror)
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeletePushMirrorByRemoteName deletes a push mirror from a repository by remoteName
|
||||||
|
func DeletePushMirrorByRemoteName(ctx *context.APIContext) {
|
||||||
|
// swagger:operation DELETE /repos/{owner}/{repo}/push_mirrors/{name} repository repoDeletePushMirror
|
||||||
|
// ---
|
||||||
|
// summary: deletes a push mirror from a repository by remoteName
|
||||||
|
// produces:
|
||||||
|
// - application/json
|
||||||
|
// parameters:
|
||||||
|
// - name: owner
|
||||||
|
// in: path
|
||||||
|
// description: owner of the repo
|
||||||
|
// type: string
|
||||||
|
// required: true
|
||||||
|
// - name: repo
|
||||||
|
// in: path
|
||||||
|
// description: name of the repo
|
||||||
|
// type: string
|
||||||
|
// required: true
|
||||||
|
// - name: name
|
||||||
|
// in: path
|
||||||
|
// description: remote name of the pushMirror
|
||||||
|
// type: string
|
||||||
|
// required: true
|
||||||
|
// responses:
|
||||||
|
// "204":
|
||||||
|
// "$ref": "#/responses/empty"
|
||||||
|
// "404":
|
||||||
|
// "$ref": "#/responses/notFound"
|
||||||
|
// "400":
|
||||||
|
// "$ref": "#/responses/error"
|
||||||
|
|
||||||
|
if !setting.Mirror.Enabled {
|
||||||
|
ctx.Error(http.StatusBadRequest, "DeletePushMirrorByName", "Mirror feature is disabled")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
remoteName := ctx.Params(":name")
|
||||||
|
// Delete push mirror on repo by name.
|
||||||
|
err := repo_model.DeletePushMirrors(ctx, repo_model.PushMirrorOptions{RepoID: ctx.Repo.Repository.ID, RemoteName: remoteName})
|
||||||
|
if err != nil {
|
||||||
|
ctx.Error(http.StatusNotFound, "DeletePushMirrors", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ctx.Status(http.StatusNoContent)
|
||||||
|
}
|
||||||
|
|
||||||
|
func CreatePushMirror(ctx *context.APIContext, mirrorOption *api.CreatePushMirrorOption) {
|
||||||
|
repo := ctx.Repo.Repository
|
||||||
|
|
||||||
|
interval, err := time.ParseDuration(mirrorOption.Interval)
|
||||||
|
if err != nil || (interval != 0 && interval < setting.Mirror.MinInterval) {
|
||||||
|
ctx.Error(http.StatusBadRequest, "CreatePushMirror", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
address, err := forms.ParseRemoteAddr(mirrorOption.RemoteAddress, mirrorOption.RemoteUsername, mirrorOption.RemotePassword)
|
||||||
|
if err == nil {
|
||||||
|
err = migrations.IsMigrateURLAllowed(address, ctx.ContextUser)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
HandleRemoteAddressError(ctx, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
remoteSuffix, err := util.CryptoRandomString(10)
|
||||||
|
if err != nil {
|
||||||
|
ctx.ServerError("CryptoRandomString", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
pushMirror := &repo_model.PushMirror{
|
||||||
|
RepoID: repo.ID,
|
||||||
|
Repo: repo,
|
||||||
|
RemoteName: fmt.Sprintf("remote_mirror_%s", remoteSuffix),
|
||||||
|
Interval: interval,
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = repo_model.InsertPushMirror(ctx, pushMirror); err != nil {
|
||||||
|
ctx.ServerError("InsertPushMirror", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// if the registration of the push mirrorOption fails remove it from the database
|
||||||
|
if err = mirror_service.AddPushMirrorRemote(ctx, pushMirror, address); err != nil {
|
||||||
|
if err := repo_model.DeletePushMirrors(ctx, repo_model.PushMirrorOptions{ID: pushMirror.ID, RepoID: pushMirror.RepoID}); err != nil {
|
||||||
|
ctx.ServerError("DeletePushMirrors", err)
|
||||||
|
}
|
||||||
|
ctx.ServerError("AddPushMirrorRemote", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
m, err := convert.ToPushMirror(pushMirror)
|
||||||
|
if err != nil {
|
||||||
|
ctx.ServerError("ToPushMirror", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ctx.JSON(http.StatusOK, m)
|
||||||
|
}
|
||||||
|
|
||||||
|
func HandleRemoteAddressError(ctx *context.APIContext, err error) {
|
||||||
|
if models.IsErrInvalidCloneAddr(err) {
|
||||||
|
addrErr := err.(*models.ErrInvalidCloneAddr)
|
||||||
|
switch {
|
||||||
|
case addrErr.IsProtocolInvalid:
|
||||||
|
ctx.Error(http.StatusBadRequest, "CreatePushMirror", "Invalid mirror protocol")
|
||||||
|
case addrErr.IsURLError:
|
||||||
|
ctx.Error(http.StatusBadRequest, "CreatePushMirror", "Invalid Url ")
|
||||||
|
case addrErr.IsPermissionDenied:
|
||||||
|
ctx.Error(http.StatusUnauthorized, "CreatePushMirror", "Permission denied")
|
||||||
|
default:
|
||||||
|
ctx.Error(http.StatusBadRequest, "CreatePushMirror", "Unknown error")
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -169,4 +169,7 @@ type swaggerParameterBodies struct {
|
||||||
|
|
||||||
// in:body
|
// in:body
|
||||||
CreateWikiPageOptions api.CreateWikiPageOptions
|
CreateWikiPageOptions api.CreateWikiPageOptions
|
||||||
|
|
||||||
|
// in:body
|
||||||
|
CreatePushMirrorOption api.CreatePushMirrorOption
|
||||||
}
|
}
|
||||||
|
|
|
@ -345,6 +345,20 @@ type swaggerWikiCommitList struct {
|
||||||
Body api.WikiCommitList `json:"body"`
|
Body api.WikiCommitList `json:"body"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PushMirror
|
||||||
|
// swagger:response PushMirror
|
||||||
|
type swaggerPushMirror struct {
|
||||||
|
// in:body
|
||||||
|
Body api.PushMirror `json:"body"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// PushMirrorList
|
||||||
|
// swagger:response PushMirrorList
|
||||||
|
type swaggerPushMirrorList struct {
|
||||||
|
// in:body
|
||||||
|
Body []api.PushMirror `json:"body"`
|
||||||
|
}
|
||||||
|
|
||||||
// RepoCollaboratorPermission
|
// RepoCollaboratorPermission
|
||||||
// swagger:response RepoCollaboratorPermission
|
// swagger:response RepoCollaboratorPermission
|
||||||
type swaggerRepoCollaboratorPermission struct {
|
type swaggerRepoCollaboratorPermission struct {
|
||||||
|
|
|
@ -90,7 +90,7 @@ func SettingsCtxData(ctx *context.Context) {
|
||||||
}
|
}
|
||||||
ctx.Data["StatsIndexerStatus"] = status
|
ctx.Data["StatsIndexerStatus"] = status
|
||||||
}
|
}
|
||||||
pushMirrors, err := repo_model.GetPushMirrorsByRepoID(ctx.Repo.Repository.ID)
|
pushMirrors, _, err := repo_model.GetPushMirrorsByRepoID(ctx, ctx.Repo.Repository.ID, db.ListOptions{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.ServerError("GetPushMirrorsByRepoID", err)
|
ctx.ServerError("GetPushMirrorsByRepoID", err)
|
||||||
return
|
return
|
||||||
|
@ -284,7 +284,7 @@ func SettingsPost(ctx *context.Context) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
m, err := selectPushMirrorByForm(form, repo)
|
m, err := selectPushMirrorByForm(ctx, form, repo)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.NotFound("", nil)
|
ctx.NotFound("", nil)
|
||||||
return
|
return
|
||||||
|
@ -305,7 +305,7 @@ func SettingsPost(ctx *context.Context) {
|
||||||
// as an error on the UI for this action
|
// as an error on the UI for this action
|
||||||
ctx.Data["Err_RepoName"] = nil
|
ctx.Data["Err_RepoName"] = nil
|
||||||
|
|
||||||
m, err := selectPushMirrorByForm(form, repo)
|
m, err := selectPushMirrorByForm(ctx, form, repo)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.NotFound("", nil)
|
ctx.NotFound("", nil)
|
||||||
return
|
return
|
||||||
|
@ -316,7 +316,7 @@ func SettingsPost(ctx *context.Context) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = repo_model.DeletePushMirrorByID(m.ID); err != nil {
|
if err = repo_model.DeletePushMirrors(ctx, repo_model.PushMirrorOptions{ID: m.ID, RepoID: m.RepoID}); err != nil {
|
||||||
ctx.ServerError("DeletePushMirrorByID", err)
|
ctx.ServerError("DeletePushMirrorByID", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -364,14 +364,14 @@ func SettingsPost(ctx *context.Context) {
|
||||||
SyncOnCommit: form.PushMirrorSyncOnCommit,
|
SyncOnCommit: form.PushMirrorSyncOnCommit,
|
||||||
Interval: interval,
|
Interval: interval,
|
||||||
}
|
}
|
||||||
if err := repo_model.InsertPushMirror(m); err != nil {
|
if err := repo_model.InsertPushMirror(ctx, m); err != nil {
|
||||||
ctx.ServerError("InsertPushMirror", err)
|
ctx.ServerError("InsertPushMirror", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := mirror_service.AddPushMirrorRemote(ctx, m, address); err != nil {
|
if err := mirror_service.AddPushMirrorRemote(ctx, m, address); err != nil {
|
||||||
if err := repo_model.DeletePushMirrorByID(m.ID); err != nil {
|
if err := repo_model.DeletePushMirrors(ctx, repo_model.PushMirrorOptions{ID: m.ID, RepoID: m.RepoID}); err != nil {
|
||||||
log.Error("DeletePushMirrorByID %v", err)
|
log.Error("DeletePushMirrors %v", err)
|
||||||
}
|
}
|
||||||
ctx.ServerError("AddPushMirrorRemote", err)
|
ctx.ServerError("AddPushMirrorRemote", err)
|
||||||
return
|
return
|
||||||
|
@ -1222,13 +1222,13 @@ func SettingsDeleteAvatar(ctx *context.Context) {
|
||||||
ctx.Redirect(ctx.Repo.RepoLink + "/settings")
|
ctx.Redirect(ctx.Repo.RepoLink + "/settings")
|
||||||
}
|
}
|
||||||
|
|
||||||
func selectPushMirrorByForm(form *forms.RepoSettingForm, repo *repo_model.Repository) (*repo_model.PushMirror, error) {
|
func selectPushMirrorByForm(ctx *context.Context, form *forms.RepoSettingForm, repo *repo_model.Repository) (*repo_model.PushMirror, error) {
|
||||||
id, err := strconv.ParseInt(form.PushMirrorID, 10, 64)
|
id, err := strconv.ParseInt(form.PushMirrorID, 10, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
pushMirrors, err := repo_model.GetPushMirrorsByRepoID(repo.ID)
|
pushMirrors, _, err := repo_model.GetPushMirrorsByRepoID(ctx, repo.ID, db.ListOptions{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -106,7 +106,7 @@ func Update(ctx context.Context, pullLimit, pushLimit int) error {
|
||||||
|
|
||||||
pushMirrorsRequested := 0
|
pushMirrorsRequested := 0
|
||||||
if pushLimit != 0 {
|
if pushLimit != 0 {
|
||||||
if err := repo_model.PushMirrorsIterate(pushLimit, func(idx int, bean interface{}) error {
|
if err := repo_model.PushMirrorsIterate(ctx, pushLimit, func(idx int, bean interface{}) error {
|
||||||
if err := handler(idx, bean); err != nil {
|
if err := handler(idx, bean); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -94,7 +94,7 @@ func SyncPushMirror(ctx context.Context, mirrorID int64) bool {
|
||||||
log.Error("PANIC whilst syncPushMirror[%d] Panic: %v\nStacktrace: %s", mirrorID, err, log.Stack(2))
|
log.Error("PANIC whilst syncPushMirror[%d] Panic: %v\nStacktrace: %s", mirrorID, err, log.Stack(2))
|
||||||
}()
|
}()
|
||||||
|
|
||||||
m, err := repo_model.GetPushMirrorByID(mirrorID)
|
m, err := repo_model.GetPushMirror(ctx, repo_model.PushMirrorOptions{ID: mirrorID})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("GetPushMirrorByID [%d]: %v", mirrorID, err)
|
log.Error("GetPushMirrorByID [%d]: %v", mirrorID, err)
|
||||||
return false
|
return false
|
||||||
|
@ -116,7 +116,7 @@ func SyncPushMirror(ctx context.Context, mirrorID int64) bool {
|
||||||
|
|
||||||
m.LastUpdateUnix = timeutil.TimeStampNow()
|
m.LastUpdateUnix = timeutil.TimeStampNow()
|
||||||
|
|
||||||
if err := repo_model.UpdatePushMirror(m); err != nil {
|
if err := repo_model.UpdatePushMirror(ctx, m); err != nil {
|
||||||
log.Error("UpdatePushMirror [%d]: %v", m.ID, err)
|
log.Error("UpdatePushMirror [%d]: %v", m.ID, err)
|
||||||
|
|
||||||
return false
|
return false
|
||||||
|
|
|
@ -8774,6 +8774,233 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/repos/{owner}/{repo}/push_mirrors": {
|
||||||
|
"get": {
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"repository"
|
||||||
|
],
|
||||||
|
"summary": "Get all push mirrors of the repository",
|
||||||
|
"operationId": "repoListPushMirrors",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "owner of the repo",
|
||||||
|
"name": "owner",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "name of the repo",
|
||||||
|
"name": "repo",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "integer",
|
||||||
|
"description": "page number of results to return (1-based)",
|
||||||
|
"name": "page",
|
||||||
|
"in": "query"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "integer",
|
||||||
|
"description": "page size of results",
|
||||||
|
"name": "limit",
|
||||||
|
"in": "query"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"$ref": "#/responses/PushMirrorList"
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"$ref": "#/responses/error"
|
||||||
|
},
|
||||||
|
"403": {
|
||||||
|
"$ref": "#/responses/forbidden"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"post": {
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"repository"
|
||||||
|
],
|
||||||
|
"summary": "add a push mirror to the repository",
|
||||||
|
"operationId": "repoAddPushMirror",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "owner of the repo",
|
||||||
|
"name": "owner",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "name of the repo",
|
||||||
|
"name": "repo",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "body",
|
||||||
|
"in": "body",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/CreatePushMirrorOption"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"201": {
|
||||||
|
"$ref": "#/responses/PushMirror"
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"$ref": "#/responses/error"
|
||||||
|
},
|
||||||
|
"403": {
|
||||||
|
"$ref": "#/responses/forbidden"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/repos/{owner}/{repo}/push_mirrors-sync": {
|
||||||
|
"post": {
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"repository"
|
||||||
|
],
|
||||||
|
"summary": "Sync all push mirrored repository",
|
||||||
|
"operationId": "repoPushMirrorSync",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "owner of the repo to sync",
|
||||||
|
"name": "owner",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "name of the repo to sync",
|
||||||
|
"name": "repo",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"$ref": "#/responses/empty"
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"$ref": "#/responses/error"
|
||||||
|
},
|
||||||
|
"403": {
|
||||||
|
"$ref": "#/responses/forbidden"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/repos/{owner}/{repo}/push_mirrors/{name}": {
|
||||||
|
"get": {
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"repository"
|
||||||
|
],
|
||||||
|
"summary": "Get push mirror of the repository by remoteName",
|
||||||
|
"operationId": "repoGetPushMirrorByRemoteName",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "owner of the repo",
|
||||||
|
"name": "owner",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "name of the repo",
|
||||||
|
"name": "repo",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "remote name of push mirror",
|
||||||
|
"name": "name",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"$ref": "#/responses/PushMirror"
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"$ref": "#/responses/error"
|
||||||
|
},
|
||||||
|
"403": {
|
||||||
|
"$ref": "#/responses/forbidden"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"delete": {
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"repository"
|
||||||
|
],
|
||||||
|
"summary": "deletes a push mirror from a repository by remoteName",
|
||||||
|
"operationId": "repoDeletePushMirror",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "owner of the repo",
|
||||||
|
"name": "owner",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "name of the repo",
|
||||||
|
"name": "repo",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "remote name of the pushMirror",
|
||||||
|
"name": "name",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"204": {
|
||||||
|
"$ref": "#/responses/empty"
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"$ref": "#/responses/error"
|
||||||
|
},
|
||||||
|
"404": {
|
||||||
|
"$ref": "#/responses/notFound"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"/repos/{owner}/{repo}/raw/{filepath}": {
|
"/repos/{owner}/{repo}/raw/{filepath}": {
|
||||||
"get": {
|
"get": {
|
||||||
"produces": [
|
"produces": [
|
||||||
|
@ -14441,6 +14668,29 @@
|
||||||
},
|
},
|
||||||
"x-go-package": "code.gitea.io/gitea/modules/structs"
|
"x-go-package": "code.gitea.io/gitea/modules/structs"
|
||||||
},
|
},
|
||||||
|
"CreatePushMirrorOption": {
|
||||||
|
"type": "object",
|
||||||
|
"title": "CreatePushMirrorOption represents need information to create a push mirror of a repository.",
|
||||||
|
"properties": {
|
||||||
|
"interval": {
|
||||||
|
"type": "string",
|
||||||
|
"x-go-name": "Interval"
|
||||||
|
},
|
||||||
|
"remote_address": {
|
||||||
|
"type": "string",
|
||||||
|
"x-go-name": "RemoteAddress"
|
||||||
|
},
|
||||||
|
"remote_password": {
|
||||||
|
"type": "string",
|
||||||
|
"x-go-name": "RemotePassword"
|
||||||
|
},
|
||||||
|
"remote_username": {
|
||||||
|
"type": "string",
|
||||||
|
"x-go-name": "RemoteUsername"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"x-go-package": "code.gitea.io/gitea/modules/structs"
|
||||||
|
},
|
||||||
"CreateReleaseOption": {
|
"CreateReleaseOption": {
|
||||||
"description": "CreateReleaseOption options when creating a release",
|
"description": "CreateReleaseOption options when creating a release",
|
||||||
"type": "object",
|
"type": "object",
|
||||||
|
@ -17516,6 +17766,41 @@
|
||||||
},
|
},
|
||||||
"x-go-package": "code.gitea.io/gitea/modules/structs"
|
"x-go-package": "code.gitea.io/gitea/modules/structs"
|
||||||
},
|
},
|
||||||
|
"PushMirror": {
|
||||||
|
"description": "PushMirror represents information of a push mirror",
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"created": {
|
||||||
|
"type": "string",
|
||||||
|
"x-go-name": "CreatedUnix"
|
||||||
|
},
|
||||||
|
"interval": {
|
||||||
|
"type": "string",
|
||||||
|
"x-go-name": "Interval"
|
||||||
|
},
|
||||||
|
"last_error": {
|
||||||
|
"type": "string",
|
||||||
|
"x-go-name": "LastError"
|
||||||
|
},
|
||||||
|
"last_update": {
|
||||||
|
"type": "string",
|
||||||
|
"x-go-name": "LastUpdateUnix"
|
||||||
|
},
|
||||||
|
"remote_address": {
|
||||||
|
"type": "string",
|
||||||
|
"x-go-name": "RemoteAddress"
|
||||||
|
},
|
||||||
|
"remote_name": {
|
||||||
|
"type": "string",
|
||||||
|
"x-go-name": "RemoteName"
|
||||||
|
},
|
||||||
|
"repo_name": {
|
||||||
|
"type": "string",
|
||||||
|
"x-go-name": "RepoName"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"x-go-package": "code.gitea.io/gitea/modules/structs"
|
||||||
|
},
|
||||||
"Reaction": {
|
"Reaction": {
|
||||||
"description": "Reaction contain one reaction",
|
"description": "Reaction contain one reaction",
|
||||||
"type": "object",
|
"type": "object",
|
||||||
|
@ -19293,6 +19578,21 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"PushMirror": {
|
||||||
|
"description": "PushMirror",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/PushMirror"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"PushMirrorList": {
|
||||||
|
"description": "PushMirrorList",
|
||||||
|
"schema": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/definitions/PushMirror"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"Reaction": {
|
"Reaction": {
|
||||||
"description": "Reaction",
|
"description": "Reaction",
|
||||||
"schema": {
|
"schema": {
|
||||||
|
@ -19572,7 +19872,7 @@
|
||||||
"parameterBodies": {
|
"parameterBodies": {
|
||||||
"description": "parameterBodies",
|
"description": "parameterBodies",
|
||||||
"schema": {
|
"schema": {
|
||||||
"$ref": "#/definitions/CreateWikiPageOptions"
|
"$ref": "#/definitions/CreatePushMirrorOption"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"redirect": {
|
"redirect": {
|
||||||
|
|
Loading…
Reference in New Issue