code.gitea.io/gitea@v1.21.7/models/migrations/v1_21/v276.go (about) 1 // Copyright 2023 The Gitea Authors. All rights reserved. 2 // SPDX-License-Identifier: MIT 3 4 package v1_21 //nolint 5 6 import ( 7 "context" 8 "fmt" 9 "path/filepath" 10 "strings" 11 12 "code.gitea.io/gitea/modules/git" 13 giturl "code.gitea.io/gitea/modules/git/url" 14 "code.gitea.io/gitea/modules/setting" 15 16 "xorm.io/xorm" 17 ) 18 19 func AddRemoteAddressToMirrors(x *xorm.Engine) error { 20 type Mirror struct { 21 RemoteAddress string `xorm:"VARCHAR(2048)"` 22 } 23 24 type PushMirror struct { 25 RemoteAddress string `xorm:"VARCHAR(2048)"` 26 } 27 28 if err := x.Sync(new(Mirror), new(PushMirror)); err != nil { 29 return err 30 } 31 32 if err := migratePullMirrors(x); err != nil { 33 return err 34 } 35 36 return migratePushMirrors(x) 37 } 38 39 func migratePullMirrors(x *xorm.Engine) error { 40 type Mirror struct { 41 ID int64 `xorm:"pk autoincr"` 42 RepoID int64 `xorm:"INDEX"` 43 RemoteAddress string `xorm:"VARCHAR(2048)"` 44 RepoOwner string 45 RepoName string 46 } 47 48 sess := x.NewSession() 49 defer sess.Close() 50 51 if err := sess.Begin(); err != nil { 52 return err 53 } 54 55 limit := setting.Database.IterateBufferSize 56 if limit <= 0 { 57 limit = 50 58 } 59 60 start := 0 61 62 for { 63 var mirrors []Mirror 64 if err := sess.Select("mirror.id, mirror.repo_id, mirror.remote_address, repository.owner_name as repo_owner, repository.name as repo_name"). 65 Join("INNER", "repository", "repository.id = mirror.repo_id"). 66 Limit(limit, start).Find(&mirrors); err != nil { 67 return err 68 } 69 70 if len(mirrors) == 0 { 71 break 72 } 73 start += len(mirrors) 74 75 for _, m := range mirrors { 76 remoteAddress, err := getRemoteAddress(m.RepoOwner, m.RepoName, "origin") 77 if err != nil { 78 return err 79 } 80 81 m.RemoteAddress = remoteAddress 82 83 if _, err = sess.ID(m.ID).Cols("remote_address").Update(m); err != nil { 84 return err 85 } 86 } 87 88 if start%1000 == 0 { // avoid a too big transaction 89 if err := sess.Commit(); err != nil { 90 return err 91 } 92 if err := sess.Begin(); err != nil { 93 return err 94 } 95 } 96 } 97 98 return sess.Commit() 99 } 100 101 func migratePushMirrors(x *xorm.Engine) error { 102 type PushMirror struct { 103 ID int64 `xorm:"pk autoincr"` 104 RepoID int64 `xorm:"INDEX"` 105 RemoteName string 106 RemoteAddress string `xorm:"VARCHAR(2048)"` 107 RepoOwner string 108 RepoName string 109 } 110 111 sess := x.NewSession() 112 defer sess.Close() 113 114 if err := sess.Begin(); err != nil { 115 return err 116 } 117 118 limit := setting.Database.IterateBufferSize 119 if limit <= 0 { 120 limit = 50 121 } 122 123 start := 0 124 125 for { 126 var mirrors []PushMirror 127 if err := sess.Select("push_mirror.id, push_mirror.repo_id, push_mirror.remote_name, push_mirror.remote_address, repository.owner_name as repo_owner, repository.name as repo_name"). 128 Join("INNER", "repository", "repository.id = push_mirror.repo_id"). 129 Limit(limit, start).Find(&mirrors); err != nil { 130 return err 131 } 132 133 if len(mirrors) == 0 { 134 break 135 } 136 start += len(mirrors) 137 138 for _, m := range mirrors { 139 remoteAddress, err := getRemoteAddress(m.RepoOwner, m.RepoName, m.RemoteName) 140 if err != nil { 141 return err 142 } 143 144 m.RemoteAddress = remoteAddress 145 146 if _, err = sess.ID(m.ID).Cols("remote_address").Update(m); err != nil { 147 return err 148 } 149 } 150 151 if start%1000 == 0 { // avoid a too big transaction 152 if err := sess.Commit(); err != nil { 153 return err 154 } 155 if err := sess.Begin(); err != nil { 156 return err 157 } 158 } 159 } 160 161 return sess.Commit() 162 } 163 164 func getRemoteAddress(ownerName, repoName, remoteName string) (string, error) { 165 repoPath := filepath.Join(setting.RepoRootPath, strings.ToLower(ownerName), strings.ToLower(repoName)+".git") 166 167 remoteURL, err := git.GetRemoteAddress(context.Background(), repoPath, remoteName) 168 if err != nil { 169 return "", fmt.Errorf("get remote %s's address of %s/%s failed: %v", remoteName, ownerName, repoName, err) 170 } 171 172 u, err := giturl.Parse(remoteURL) 173 if err != nil { 174 return "", err 175 } 176 u.User = nil 177 178 return u.String(), nil 179 }