You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 

81 lines
2.8 KiB

#!/usr/bin/env python
import time
import os
from subprocess import run, DEVNULL
import tarfile
import gitlab
import paramiko
from rich.progress import Progress
progress = Progress(transient=True)
progress.start()
ssh = paramiko.SSHClient()
ssh.load_system_host_keys()
# TODO: Change the next six lines to match your needs.
GITLAB_HOST = 'https://gitlab.com'
GITLAB_TOKEN = 'PersonalAccessToken_api'
GITBLIT_HOST = 'gitblit' # Change: Gitblit host address
GITBLIT_PORT = 29419 # Change: Gitblit ssh port
GITBLIT_USER = 'user'
GITBLIT_DIR = '/' # or 'project_name/' or f'~{GITBLIT_USER}' for private
# No changes needed
GITBLIT_URI = f'ssh://{GITBLIT_USER}@{GITBLIT_HOST}:{GITBLIT_PORT}'
gl = gitlab.Gitlab(GITLAB_HOST, private_token=GITLAB_TOKEN)
ssh.connect(GITBLIT_HOST, port=GITBLIT_PORT)
os.makedirs('./exports', exist_ok=True)
os.makedirs('./repos', exist_ok=True)
progress.log('Fetching project list...')
for project in progress.track(gl.projects.list(all=True)):
if os.path.exists(f'repos/{project.path}.done'):
progress.log(f'{project.name}: Already exported and cloned')
continue
progress.log(f'{project.name}: Creating export...')
export = project.exports.create()
export.refresh()
while export.export_status != 'finished':
time.sleep(0.25)
export.refresh()
progress.log(f'{project.name}: Downloading export...')
with open(f'exports/{project.path}.tgz', 'wb') as f:
export.download(streamed=True, action=f.write)
progress.log(f'Preparing {project.name} for re-import')
with tarfile.open(f'exports/{project.path}.tgz', 'r:gz') as t:
progress.log(f'{project.name}: Extracting ./project.bundle...')
try:
t.extract('./project.bundle')
except KeyError:
continue
progress.log(f'{project.name}: Cloning into bare repository...')
ret = run(['/usr/bin/git', 'clone', '--mirror', './project.bundle',
f'repos/{project.path}'],
stderr=DEVNULL, stdout=DEVNULL)
progress.log(f'{project.name}: Creating new repository...')
ssh.exec_command(f'gb repos new {GITBLIT_DIR}/{project.path}')
progress.log(f'{project.name}: Setting remote...')
ret = run(['/usr/bin/git', '--git-dir', f'repos/{project.path}',
'remote', 'set-url', 'origin',
f'{GITBLIT_URI}/{GITBLIT_DIR}/{project.path}'],
stderr=DEVNULL, stdout=DEVNULL)
progress.log(f'{project.name}: Pushing local repository to remote...')
ret = run(['/usr/bin/git', '--git-dir', f'repos/{project.path}',
'push'],
stderr=DEVNULL, stdout=DEVNULL)
os.remove('./project.bundle')
os.rename(f'repos/{project.path}', f'repos/{project.path}.done')
progress.stop()