136 lines
3.9 KiB
Python
136 lines
3.9 KiB
Python
|
from workers import task
|
||
|
from .models import *
|
||
|
from time import sleep
|
||
|
from random import randint
|
||
|
from tempfile import TemporaryDirectory
|
||
|
from . import settings
|
||
|
from .api import *
|
||
|
from os import path
|
||
|
import re
|
||
|
import subprocess
|
||
|
import traceback
|
||
|
|
||
|
class MigrationError(Exception):
|
||
|
pass
|
||
|
|
||
|
def handle_migration(repository):
|
||
|
gitea = GiteaAPI(repository.migration.gitea_token)
|
||
|
gitlab = GitlabAPI(repository.migration.gitlab_token)
|
||
|
|
||
|
match = re.search('^([^/]+)/',repository.path_with_namespace)
|
||
|
if match is None:
|
||
|
raise MigrationError("Could not get organization")
|
||
|
else:
|
||
|
organization = match.group(1)
|
||
|
|
||
|
match = re.search('([^/]+)$', repository.path_with_namespace)
|
||
|
if match is None:
|
||
|
raise MigrationError("Could not get repo name")
|
||
|
else:
|
||
|
reponame = match.group(1)
|
||
|
|
||
|
# Create organization if necessary
|
||
|
if organization == repository.migration.username:
|
||
|
organization = None
|
||
|
|
||
|
if organization is None:
|
||
|
response = gitea.get("/orgs/%s" % organization)
|
||
|
|
||
|
if response.status_code != 200:
|
||
|
response = gitea.post("/orgs", json={
|
||
|
"full_name" : organization,
|
||
|
"username" : organization,
|
||
|
})
|
||
|
|
||
|
if response.status_code != 201:
|
||
|
raise MigrationError("Could not create organization: %s" % (response.text) )
|
||
|
|
||
|
owner = organization or repository.migration.username
|
||
|
|
||
|
# Create repo if necessary
|
||
|
if organization is None:
|
||
|
response = gitea.post('/user/repos', data={
|
||
|
'auto_init': False,
|
||
|
'default_branch': 'master',
|
||
|
'description': "Automatically created",
|
||
|
'name': reponame,
|
||
|
})
|
||
|
else:
|
||
|
response = gitea.post('/org/%s/repos' % organization, data={
|
||
|
'name': reponame,
|
||
|
'private': True,
|
||
|
})
|
||
|
|
||
|
if response.status_code == 409:
|
||
|
pass # exists
|
||
|
elif response.status_code != 201:
|
||
|
raise MigrationError("Could not create repo: %s" % (response.text))
|
||
|
|
||
|
gitlab_remote = settings.GITLAB_REPO_URL % (
|
||
|
repository.migration.username,
|
||
|
repository.migration.gitlab_token,
|
||
|
repository.path_with_namespace
|
||
|
)
|
||
|
|
||
|
gitea_remote = settings.GITEA_REPO_URL % (
|
||
|
repository.migration.username,
|
||
|
repository.migration.gitea_token,
|
||
|
repository.path_with_namespace
|
||
|
)
|
||
|
|
||
|
# Migrate
|
||
|
with TemporaryDirectory() as tempdir:
|
||
|
gitdir = path.join(tempdir,'git')
|
||
|
|
||
|
try:
|
||
|
subprocess.check_call([
|
||
|
'git','clone','--mirror',
|
||
|
gitlab_remote,
|
||
|
gitdir
|
||
|
])
|
||
|
except subprocess.CalledProcessError:
|
||
|
raise MigrationError("Could not clone")
|
||
|
|
||
|
try:
|
||
|
subprocess.check_call([
|
||
|
'git', '-C', gitdir,
|
||
|
'remote','add',
|
||
|
'gitea', gitea_remote
|
||
|
])
|
||
|
except subprocess.CalledProcessError:
|
||
|
raise MigrationError("Could not set remote")
|
||
|
|
||
|
try:
|
||
|
subprocess.check_call([
|
||
|
'git', '-C', gitdir,
|
||
|
'push', '--all', 'gitea'
|
||
|
])
|
||
|
except subprocess.CalledProcessError:
|
||
|
raise MigrationError("Could not push")
|
||
|
|
||
|
return Status.SUCCESS
|
||
|
|
||
|
@task()
|
||
|
def migrate_repository(repository_id):
|
||
|
try:
|
||
|
repository = Repository.objects.select_related('migration').get(pk=repository_id)
|
||
|
except Repository.DoesNotExist:
|
||
|
return
|
||
|
|
||
|
print(">>> Migrating repository %s..." % (repository.path_with_namespace), end="\n\n")
|
||
|
|
||
|
repository.result = Status.IN_PROGRESS
|
||
|
repository.save()
|
||
|
|
||
|
# Might take a while
|
||
|
try:
|
||
|
result = handle_migration(repository)
|
||
|
repository.result = result
|
||
|
except Exception as e:
|
||
|
result = Status.ERROR
|
||
|
repository.result = result
|
||
|
repository.error_message = traceback.format_exc()
|
||
|
finally:
|
||
|
repository.save()
|
||
|
print(end="\n\n")
|