• python在容器内克隆拉取git私有仓库


    前言

    目前有个python应用需要在容器镜像内拉取git私有仓库的代码,一开始的想法是用GitPython,折腾一番ssh私钥和known_hosts问题后,发现还是在镜像中封装个git最省事,然后用subprocess调用系统命令,镜像体积也没有想象中增加特别多。

    准备ssh私钥和known_hosts文件

    应用内通过repo的ssh url克隆和拉取仓库,所以ssh私钥和known_hosts要封装到镜像中。

    1. 生成ssh密钥文件。一般来说提示输入直接回车即可。生成的$HOME/.ssh/id_ed25519为私钥文件,是需要拷贝到镜像中的。$HOME/.ssh/id_ed25519.pub为公钥文件,文件内容需要添加到远程仓库的ssh密钥配置中。
    ssh-keygen -t ed25519
    
    1. 准备known_hosts文件,文件内容可以从其它主机拷贝一份。其实ssh密钥文件也可以从其它主机拷贝,只要对应的公钥在git远程仓库的ssh配置中即可。known_hosts文件内容示例。
    gitee.com ssh-ed25519 AxxxxxxxxxxxxxxxxxxxxN
    

    在项目目录中创建一个名为.ssh的目录,然后把id_ed25519known_hosts文件拷贝到这个目录下,并修改文件权限为600。这个目录待会需要封装到镜像中。

    chmod 600 id_ed25519 known_hosts
    

    编写python代码

    这里只是个demo,拉取私有仓库的代码到本地,然后拷贝出需要的目录或文件。注意代码里面用的都是容器内路径。

    import subprocess
    import os
    import shutil
    
    repo_url = "git@gitee.com:zhangsan/scout.git"
    repo_dir = "/tmp/scout"
    
    def repo_clone():
        cmd = f"git clone --depth=1 --single-branch {repo_url} {repo_dir}"
        if os.path.exists(repo_dir):
            print(f"{repo_dir} has exist")
            return
        runcmd(cmd)
    
    def repo_pull():
        cmd = f"cd {repo_dir};git pull"
        runcmd(cmd)
    
        if not os.path.exists(f"{repo_dir}/prod"):
            print(f"{repo_dir}/prod is not exist")
            return
        dest_path = "/home/zhangsan/app/prod"
        if not os.path.exists(dest_path):
            os.makedirs(dest_path)
        shutil.copytree(f"{repo_dir}/prod", dest_path, dirs_exist_ok=True)
    
    def runcmd(command):
        ret = subprocess.run(
            command, 
            shell=True,
            stdout=subprocess.PIPE,
            stderr=subprocess.STDOUT,
            encoding="utf-8",
            timeout=10,
            )
        
        if ret.returncode == 0:
            print("success")
            print(ret.stdout)
        else:
            print(f"fail code: {ret.returncode}")
            print(ret.stdout)
    
    if __name__ == "__main__":
        repo_clone()
        repo_pull()
    

    Dockerfile

    目录层级如下

    .
    ├── app
    │   └── demo.py
    ├── Dockerfile
    └── .ssh
        ├── id_ed25519
        └── known_hosts
    

    编写Dockerfile文件

    FROM python:3.8-alpine
    # 1. 修改apline镜像源
    # 2. 安装git和ssh客户端并删除apk缓存
    # 3. 创建普通用户及其用户组
    RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.tuna.tsinghua.edu.cn/g' /etc/apk/repositories \
            && apk add --no-cache git openssh \
            && rm -rf /tmp/* /root/.cache /var/cache/apk/* \
            && addgroup -g 1010 zhangsan \
            && adduser -s /bin/sh -G zhangsan -u 10101 -h /home/zhangsan zhangsan -D
    
    # 将相关文件添加到镜像中
    ADD --chown=zhangsan:zhangsan .ssh /home/zhangsan/.ssh
    ADD --chown=zhangsan:zhangsan app /home/zhangsan/app
    
    # 指定运行用户, 工作目录和启动命令
    USER zhangsan
    WORKDIR /home/zhangsan/app
    CMD python3 demo.py
    

    打包docker镜像

    docker build -t pygit:0.0.1 .
    

    测试,创建一个临时容器

    docker run -it --rm --name pygit pygit:0.0.1 sh
    

    在测试容器内测试能否正常执行

    python3 demo.py
    
  • 相关阅读:
    【元胞自动机】格子波尔兹曼模型及其应用研究(Matlab代码实现)
    Android入门第13天-动态创建CheckBox
    超全整理,性能测试——数据库索引问题定位+分析(详细)
    vulnhub靶场 Kioptrix-level-1
    基于YOLOv8深度学习的脑肿瘤智能检测系统【python源码+Pyqt5界面+数据集+训练代码】深度学习实战、目标检测、智慧医疗
    Jpa JdbcTemplate 批量插入效率对比
    C#面:C#面向对象的思想主要包括什么?
    EasyDSS平台其他协议的视频可正常播放,WebRTC却无法播放是什么原因?
    【云原生】FlexCloud可视化操作用户体验
    Qt文件系统
  • 原文地址:https://www.cnblogs.com/XY-Heruo/p/17941013