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  }