Skip to content

Commit

Permalink
U 优化git clone使用上传的密钥对作为备选密钥
Browse files Browse the repository at this point in the history
  • Loading branch information
vapao committed Jun 2, 2020
1 parent bf469cc commit 207de19
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 12 deletions.
8 changes: 7 additions & 1 deletion spug_api/apps/app/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
# Released under the MIT License.
from django.conf import settings
from apps.app.models import Deploy
from apps.setting.utils import AppSetting
from libs.gitlib import Git
import shutil
import os
Expand All @@ -22,7 +23,12 @@ def parse_envs(text):
def fetch_versions(deploy: Deploy):
git_repo = deploy.extend_obj.git_repo
repo_dir = os.path.join(settings.REPOS_DIR, str(deploy.id))
return Git(git_repo, repo_dir).fetch_branches_tags()
try:
pkey = AppSetting.get('private_key')
except KeyError:
pkey = None
with Git(git_repo, repo_dir, pkey) as git:
return git.fetch_branches_tags()


def remove_repo(deploy_id):
Expand Down
57 changes: 46 additions & 11 deletions spug_api/libs/gitlib.py
Original file line number Diff line number Diff line change
@@ -1,21 +1,27 @@
# Copyright: (c) OpenSpug Organization. https://github.com/openspug/spug
# Copyright: (c) <[email protected]>
# Released under the MIT License.
from git import Repo, RemoteReference, TagReference, InvalidGitRepositoryError
from git import Repo, RemoteReference, TagReference, InvalidGitRepositoryError, GitCommandError
from tempfile import NamedTemporaryFile
import shutil
import os


class Git:
def __init__(self, git_repo, repo_dir):
self.repo = self._get_repo(git_repo, repo_dir)
def __init__(self, git_repo, repo_dir, pkey=None):
self.git_repo = git_repo
self.repo_dir = repo_dir
self.repo = None
self.pkey = pkey
self.fd = None
self.env = {}

def archive(self, filepath, commit):
with open(filepath, 'wb') as f:
self.repo.archive(f, commit)

def fetch_branches_tags(self):
self.repo.remotes.origin.fetch()
self._fetch()
branches, tags = {}, {}
for ref in self.repo.references:
if isinstance(ref, RemoteReference):
Expand All @@ -36,16 +42,32 @@ def fetch_branches_tags(self):
tags = sorted(tags.items(), key=lambda x: x[1]['date'], reverse=True)
return branches, dict(tags)

def _get_repo(self, git_repo, repo_dir):
if os.path.exists(repo_dir):
def _fetch(self):
try:
self.repo.remotes.origin.fetch()
except GitCommandError as e:
if self.env:
self.repo.remotes.origin.fetch(env=self.env)
else:
raise e

def _get_repo(self):
if os.path.exists(self.repo_dir):
try:
return Repo(repo_dir)
return Repo(self.repo_dir)
except InvalidGitRepositoryError:
if os.path.isdir(repo_dir):
shutil.rmtree(repo_dir)
if os.path.isdir(self.repo_dir):
shutil.rmtree(self.repo_dir)
else:
os.remove(repo_dir)
return Repo.clone_from(git_repo, repo_dir)
os.remove(self.repo_dir)
try:
repo = Repo.clone_from(self.git_repo, self.repo_dir)
except GitCommandError as e:
if self.env:
repo = Repo.clone_from(self.git_repo, self.repo_dir, env=self.env)
else:
raise e
return repo

def _get_commits(self, branch, count=10):
commits = []
Expand All @@ -59,3 +81,16 @@ def _get_commits(self, branch, count=10):
'message': commit.message.strip()
})
return commits

def __enter__(self):
if self.pkey:
self.fd = NamedTemporaryFile()
self.fd.write(self.pkey.encode())
self.fd.flush()
self.env = {'GIT_SSH_COMMAND': f'ssh -i {self.fd.name}'}
self.repo = self._get_repo()
return self

def __exit__(self, exc_type, exc_val, exc_tb):
if self.fd:
self.fd.close()

0 comments on commit 207de19

Please sign in to comment.