U 优化git clone使用上传的密钥对作为备选密钥

pull/115/head
vapao 2020-06-02 20:03:01 +08:00
parent bf469cc043
commit 207de1941e
2 changed files with 53 additions and 12 deletions

View File

@ -3,6 +3,7 @@
# Released under the MIT License. # Released under the MIT License.
from django.conf import settings from django.conf import settings
from apps.app.models import Deploy from apps.app.models import Deploy
from apps.setting.utils import AppSetting
from libs.gitlib import Git from libs.gitlib import Git
import shutil import shutil
import os import os
@ -22,7 +23,12 @@ def parse_envs(text):
def fetch_versions(deploy: Deploy): def fetch_versions(deploy: Deploy):
git_repo = deploy.extend_obj.git_repo git_repo = deploy.extend_obj.git_repo
repo_dir = os.path.join(settings.REPOS_DIR, str(deploy.id)) 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): def remove_repo(deploy_id):

View File

@ -1,21 +1,27 @@
# Copyright: (c) OpenSpug Organization. https://github.com/openspug/spug # Copyright: (c) OpenSpug Organization. https://github.com/openspug/spug
# Copyright: (c) <spug.dev@gmail.com> # Copyright: (c) <spug.dev@gmail.com>
# Released under the MIT License. # 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 shutil
import os import os
class Git: class Git:
def __init__(self, git_repo, repo_dir): def __init__(self, git_repo, repo_dir, pkey=None):
self.repo = self._get_repo(git_repo, repo_dir) 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): def archive(self, filepath, commit):
with open(filepath, 'wb') as f: with open(filepath, 'wb') as f:
self.repo.archive(f, commit) self.repo.archive(f, commit)
def fetch_branches_tags(self): def fetch_branches_tags(self):
self.repo.remotes.origin.fetch() self._fetch()
branches, tags = {}, {} branches, tags = {}, {}
for ref in self.repo.references: for ref in self.repo.references:
if isinstance(ref, RemoteReference): if isinstance(ref, RemoteReference):
@ -36,16 +42,32 @@ class Git:
tags = sorted(tags.items(), key=lambda x: x[1]['date'], reverse=True) tags = sorted(tags.items(), key=lambda x: x[1]['date'], reverse=True)
return branches, dict(tags) return branches, dict(tags)
def _get_repo(self, git_repo, repo_dir): def _fetch(self):
if os.path.exists(repo_dir): 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: try:
return Repo(repo_dir) return Repo(self.repo_dir)
except InvalidGitRepositoryError: except InvalidGitRepositoryError:
if os.path.isdir(repo_dir): if os.path.isdir(self.repo_dir):
shutil.rmtree(repo_dir) shutil.rmtree(self.repo_dir)
else: else:
os.remove(repo_dir) os.remove(self.repo_dir)
return Repo.clone_from(git_repo, 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): def _get_commits(self, branch, count=10):
commits = [] commits = []
@ -59,3 +81,16 @@ class Git:
'message': commit.message.strip() 'message': commit.message.strip()
}) })
return commits 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()