适用场景:把GitLab从服务器A迁移到服务器B,代码中的方式会让项目的提交记录也完整迁移到目标服务器,所以不用担心提交记录丢失。
会持续分享人生感悟、工作技巧、技术原理、拿来即用的实用代码,欢迎关注、点赞、收藏!
一:迁移思路
1.1 批量迁移gitlab用户
1.2 批量迁移gitlab项目
1.3 批量为用户授权项目权限
1.4 批量同步项目的webhook配置(可选)
1.5 批量给项目创建test分支(可选)
二:编程语言
python
三:安装依赖
pip install python-gitlab
四:代码
4.1 批量迁移gitlab用户
import gitlab
import os
import subprocess
# 在此处替换为源服务器和目标服务器的GitLab URL和访问令牌
# 源GitLab配置信息
server_source_url = 'http://source.com'
server_source_token = 'source_token'
# 目标gitlab配置信息
server_target_url = 'http://target.com'
server_target_token = 'target_token'
# 连接到源服务器的GitLab实例
gitlab_source = gitlab.Gitlab(server_source_url, private_token=server_source_token)
# 连接到目标服务器的GitLab实例
gitlab_target = gitlab.Gitlab(server_target_url, private_token=server_target_token)
# 在目标服务器上创建相同的用户
def create_target_users_by_source_users():
# 获取源服务器上的所有用户
source_users = gitlab_source.users.list(all=True)
# 在目标服务器上创建相同的用户
for source_user in source_users:
# 如果在gitlab_target.users中存在,则跳过该用户
if(gitlab_target.users.list(username=source_user.username)):
print(f"用户{source_user.username}已存在,跳过该用户")
continue
pwd = ''
# 跳过某些不需要复制的用户
if (source_user.username == 'root'
or source_user.username == 'ghost'):
continue
# 打印用户信息
print(source_user.email, source_user.username, source_user.name)
# 此处需要替换为新用户的密码
if(source_user.username == 'xxx'):
pwd='xxx'
elif(source_user.username == 'xxx'):
pwd='xxx'
user_data = {
'email': source_user.email,
'password': pwd, # 在此处替换为新用户的密码
'username': source_user.username,
'name': source_user.name
}
gitlab_target.users.create(user_data)
# 批量迁移gitlab用户
create_target_users_by_source_users()
4.2 批量迁移gitlab项目
import gitlab
import os
import subprocess
# 在此处替换为源服务器和目标服务器的GitLab URL和访问令牌
# 源GitLab配置信息
server_source_url = 'http://source.com'
server_source_token = 'source_token'
# 目标gitlab配置信息
server_target_url = 'http://target.com'
server_target_token = 'target_token'
# 连接到源服务器的GitLab实例
gitlab_source = gitlab.Gitlab(server_source_url, private_token=server_source_token)
# 连接到目标服务器的GitLab实例
gitlab_target = gitlab.Gitlab(server_target_url, private_token=server_target_token)
# 把 原gitlab 中的项目上传到 目标gitlab:先把项目克隆到本地,然后推送到目标gitlab,此方式会携带历史提交记录,所以不用担心提交记录丢失
def create_target_projects_by_source_projects():
# 从源gitlab上下载所有的代码项目
source_projects = gitlab_source.projects.list(all=True)
# 遍历下载的项目,推送到目标gitlab仓库
for source_project in source_projects:
try:
# 打印项目信息
print(source_project.name, source_project.id)
# 在 目标gitlab创建同名仓库
target_project = gitlab_target.projects.create(
{'name': source_project.name})
# 克隆源gitlab项目及所有分支到本地,这里需要替换为本地有效的路径
local_path = f'E:\Codes\copy_gitlab_code\{source_project.name}'
subprocess.run(['git', 'clone', '--mirror',
source_project.http_url_to_repo, local_path])
# 进入本地项目目录
os.chdir(local_path)
# 将本地项目推送到目标gitlab的仓库
subprocess.run(['git', 'remote', 'add', 'destination',
target_project.http_url_to_repo])
subprocess.run(['git', 'push', 'destination', '--all'])
subprocess.run(['git', 'push', 'destination', '--tags'])
except Exception as e:
print("####################"+source_project.name +
"发生异常,异常内容如下####################")
print(f"{str(e)}")
continue
# 批量迁移gitlab项目
create_target_projects_by_source_projects()
4.3 批量为用户授权项目权限
import gitlab
import os
import subprocess
# 在此处替换为源服务器和目标服务器的GitLab URL和访问令牌
# 源GitLab配置信息
server_source_url = 'http://source.com'
server_source_token = 'source_token'
# 目标gitlab配置信息
server_target_url = 'http://target.com'
server_target_token = 'target_token'
# 连接到源服务器的GitLab实例
gitlab_source = gitlab.Gitlab(server_source_url, private_token=server_source_token)
# 连接到目标服务器的GitLab实例
gitlab_target = gitlab.Gitlab(server_target_url, private_token=server_target_token)
# 将源服务器上的每个项目的成员和权限同步到目标服务器
def create_target_members():
# 获取源服务器上的所有项目
source_projects = gitlab_source.projects.list(all=True)
# 将源服务器上的每个项目的成员和权限同步到目标服务器
for source_project in source_projects:
# 获取原项目的成员
members_a = source_project.members.list(all=True)
print(f"正在处理项目: {source_project.name},项目ID: {source_project.id},成员数量: {len(members_a)}")
# 在目标服务器上查找对应的项目
try:
# 使用项目名来查找对应的项目
target_project = next(filter(lambda p: p.name == source_project.name, gitlab_target.projects.list(all=True)))
except StopIteration:
print(f"Project {source_project.name} not found on target server.")
continue
# 遍历源项目的成员,将他们添加到目标项目
for member in members_a:
try:
# 使用用户名查找目标服务器上的用户ID
target_user = gitlab_target.users.list(username=member.username)[0]
except IndexError:
print(f"User {member.username} not found on target server.")
continue
try:
# 尝试添加成员到目标项目
target_project.members.create({
'user_id': target_user.id,
'access_level': member.access_level
})
print(f"Added member {member.username} to project {target_project.name} with access level {member.access_level}")
except gitlab.exceptions.GitlabCreateError as e:
print(f"Could not add member {member.username} to project {target_project.name}: {e}")
# 批量为用户授权项目权限
create_target_members()
4.4 批量同步项目的webhook配置(可选)
import gitlab
import os
import subprocess
# 在此处替换为源服务器和目标服务器的GitLab URL和访问令牌
# 源GitLab配置信息
server_source_url = 'http://source.com'
server_source_token = 'source_token'
# 目标gitlab配置信息
server_target_url = 'http://target.com'
server_target_token = 'target_token'
# 连接到源服务器的GitLab实例
gitlab_source = gitlab.Gitlab(server_source_url, private_token=server_source_token)
# 连接到目标服务器的GitLab实例
gitlab_target = gitlab.Gitlab(server_target_url, private_token=server_target_token)
# 把源服务器上项目的webhook配置信息同步到目标服务器
def create_target_webhooks():
# 从源服务器上获取所有项目
source_projects = gitlab_source.projects.list(all=True)
# 遍历项目
for source_project in source_projects:
print(f"正在处理项目: {source_project.name},项目ID: {source_project.id}")
# 在目标服务器上查找对应的项目
try:
# 使用项目名来查找对应的项目
target_project = next(filter(lambda p: p.name == source_project.name, gitlab_target.projects.list(all=True)))
# 获取源服务器项目的所有webhooks
webhooks = source_project.hooks.list()
# 同步每个webhook到目标服务器对应项目
for hook in webhooks:
# 打印webhook的url/push_events/issues_events/merge_requests_events
print(f"Webhook: {hook.url}/{hook.push_events}/{hook.issues_events}/{hook.merge_requests_events}")
# 创建新的webhook配置到目标服务器对应的项目
data = {
'url': hook.url,
'push_events': hook.push_events,
'issues_events': hook.issues_events,
'merge_requests_events': hook.merge_requests_events,
}
target_project.hooks.create(data)
except StopIteration:
print(f"Project {source_project.name} not found on target server.")
continue
# 批量同步项目的webhook配置
create_target_webhooks()
4.5 批量给项目创建test分支(可选)
import gitlab
import os
import subprocess
# 在此处替换为源服务器和目标服务器的GitLab URL和访问令牌
# 源GitLab配置信息
server_source_url = 'http://source.com'
server_source_token = 'source_token'
# 目标gitlab配置信息
server_target_url = 'http://target.com'
server_target_token = 'target_token'
# 连接到源服务器的GitLab实例
gitlab_source = gitlab.Gitlab(server_source_url, private_token=server_source_token)
# 连接到目标服务器的GitLab实例
gitlab_target = gitlab.Gitlab(server_target_url, private_token=server_target_token)
# 判断每个代码仓库是否有test分支,如果没有则从master创建test分支
def create_test_branch():
# 获取源服务器上的所有项目
projects = gitlab_target.projects.list(all=True)
# 循环遍历每个项目
for project in projects:
# 获取当前项目的分支列表
branches = project.branches.list()
# 检查test分支是否存在
test_branch_exists = False
for branch in branches:
if branch.name == 'test':
test_branch_exists = True
break
# 如果test分支不存在,则从master分支创建test分支
if not test_branch_exists:
try:
project.branches.create({'branch': 'test', 'ref': 'master'})
print(f"Created 'test' branch in project: {project.name}")
except gitlab.exceptions.GitlabCreateError as e:
print(f"Failed to create 'test' branch in project: {project.name}. Error: {e}")
# 批量给项目创建test分支
create_test_branch()
此专栏会分享在日常工作中遇到的具体问题的解决方案和拿来即用的代码,欢迎关注!