持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第31天,点击查看活动详情
大家好~我是小方,欢迎大家关注笋货测试笔记体完记得俾个like呀
回顾
上篇中,我们已经介绍了subprocess
模块,并完成了初始化项目其中一种方式-http拉取,今天我们来讲下ssh拉取git项目~
前期了解
-
我们知道拉取代码有两种方式,一种是https,另一种则是ssh;
-
https拉取代码时,输入对应仓库的git账号和密码进行认证,认证通过才能拉取项目
-
而SSH,本地生成公钥、私钥,公钥配置在对应的账号/仓库中,当需要拉取代码时,远程发送一个随机字符串,本地用私钥将这个随机字符串进行加密,发送到远程,远程通过存放的公钥进行解密,如果解密后与源字符串相同,就可以拉取项目
那问题来了,ssh的私钥和公钥是如何生成的呢?直接输入这个命令即可
ssh-keygen -t rsa -C "xxxx@qq.com"
红色框住分别为私钥和公钥
那数据工厂这边是要怎么生成的呢?总不能这么麻烦的啊!
paramiko模块
ssh公钥和私钥,大部分人用的是Crypto.PublicKey
包中的RSA类来模拟ssh生成秘钥,后来跟一位热心的小伙伴闲聊后,发现paramiko
可以满足我们的需求
先来安装一下
pip3 install paramiko
实现过程:
- config.py文件配置公钥和私钥路径
- 代码实现
import paramiko
from config import FilePath
def generate_ssh_key():
key = paramiko.RSAKey.generate(4096)
# 私钥生成
key.write_private_key_file(FilePath.RSA_PRI_KEY)
# 公钥生成
rsa_pub_key = f"{key.get_name()} {key.get_base64()} FunDataFactory"
with open(FilePath.RSA_PUB_KEY, 'w') as f:
f.write(rsa_pub_key)
if __name__ == '__main__':
generate_ssh_key()
上面的代码比较简单,先不解释啦有兴趣的同学可以学学这个去到项目跟目录,直接命令paramiko
模块,记得这段代码要放在项目的跟目录哦python3 create_key.py
即可生成公钥和私钥
.gitignore
文件,忽略上传公钥和私钥
git clone ssh实现
平常我们配置ssh,直接敲命令生成公钥和私钥,公钥和私钥放在.ssh
文件里,这时候直接git clone
就可以生效了,但是现在我们的公钥和私钥生成方式跟之前不大一样,所以这里git clone
时,需要指定私钥的路径
git clone remote_url.git --config core.sshCommand="ssh -i ~/.ssh/id_rsa"
代码封装一下命令
@staticmethod
def git_clone_ssh(git_branch, git_url):
"""
ssh克隆
:param git_branch: 分支名
:param git_url: 代码地址
:return:
"""
Git.log.info("ssh克隆开始")
command_str = f"cd {FilePath.BASE_DIR}\n" \
f'git clone -b {git_branch} {git_url} --config core.sshCommand="ssh -i {FilePath.RSA_PRI_KEY}"\n'
CmdUtils.cmd(command_str)
Git.log.info("ssh克隆结束")
最后,测试一下,在账号里配置一下公钥
先手动测试一下命令,首次克隆时会有这个提示语,输入
yes
即可,这个点,我们后续优化一下
代码测试,成功克隆项目
初始化项目接口
写到这里的话,我们已经把拉取项目的逻辑写好了,万事俱备只欠东风~初始化项目的话,我们直接入参一个项目id,然后通过id查询数据库的项目信息进行拉取。
ProjectDao.py
新增查询项目详情逻辑
@classmethod
@record_log
def project_detail(cls, id: int, user: dict) -> DataFactoryProject:
"""获取项目详情"""
with Session() as session:
ProjectRoleDao.read_permission(id, user)
project = session.query(DataFactoryProject).filter(DataFactoryProject.id == id,
DataFactoryProject.del_flag == 0).first()
if project is None:
raise NormalException("项目不存在")
return project
前面几期有介绍到,初始化项目需要的项目查看权限即可,所以这里要加上read_permission
逻辑
project.py
新增路由函数
@router.get('/init', name="初始化项目", response_model=ResponseDto)
def init_project(id: int, user= Depends(Auth())):
try:
project = ProjectDao.project_detail(id, user)
project_path = os.path.join(FilePath.BASE_DIR, project.git_project)
if os.path.isdir(project_path):
raise Exception("项目已存在, 请执行刷新项目!")
# 拉取项目
if project.pull_type == 0:
Git.git_clone_http(project.git_branch, project.git_url, project.git_account, AesUtils.decrypt(project.git_password))
else:
Git.git_clone_ssh(project.git_branch, project.git_url)
return ResponseDto(msg = "初始化成功")
except Exception as e:
raise NormalException(str(e))
首先通过项目id查出项目相关信息,再判断是否已经存在项目,存在抛出异常,然后根据拉取拉取方式走不同的拉取命令,这里要注意的是,由于密码是加密的,所以取出来的时候,要解密AesUtils.decrypt
编写完后,记得重启服务~
测试环节
将img
这个项目同步下来(http方式)
http克隆成功
ssh方式同步
ssh克隆成功
已存在img
项目,进行刷新
总结
今天讲了ssh克隆代码,截止目前,我们的初始化项目已经开发完毕了,下一期我们开始来编写相关的前端页面
- 项目地址
- 今日代码提交
- 后端:2ba8578