使用 GitLab CI 通过 python 脚本部署到 FTP

Posted

技术标签:

【中文标题】使用 GitLab CI 通过 python 脚本部署到 FTP【英文标题】:Deploy to FTP via python script with GitLab CI 【发布时间】:2021-12-08 16:24:08 【问题描述】:

我是 GitLab 的新手。我正在构建我的第一个管道,以将我的 GitLab 项目的内容部署到具有 TLS 加密的 FTP 服务器。我编写了一个 Python 脚本,使用 ftplib 将文件上传到 FTP 服务器,当我在本地 Windows 机器上运行它时,它可以完美运行。该脚本将项目的全部内容上传到 FTP 服务器上的文件夹。现在我试图通过调用项目的 .gitlab-ci.yml 文件中的脚本来让它在 GitLab 上工作。脚本和 yml 文件都位于我的 GitLab 项目的顶层。目前设置非常简单:

image: python:latest

deploy:
    stage: deploy
    script: 
        - python ftpupload.py
    only:
        - main

但是,上传总是超时并显示以下错误消息:

  File "/usr/local/lib/python3.9/ftplib.py", line 156, in connect
    self.sock = socket.create_connection((self.host, self.port), self.timeout,
  File "/usr/local/lib/python3.9/socket.py", line 843, in create_connection
    raise err
  File "/usr/local/lib/python3.9/socket.py", line 831, in create_connection
    sock.connect(sa)
TimeoutError: [Errno 110] Connection timed out
Cleaning up file based variables
ERROR: Job failed: exit code 1

这是在 Python 脚本中建立连接的基本设置,该脚本在本地运行良好,但在 GitLab 上失败:

class ReusedSslSocket(ssl.SSLSocket):
    def unwrap(self):
        pass


class MyFTP_TLS(ftplib.FTP_TLS):
    """Explicit FTPS, with shared TLS session"""
    def ntransfercmd(self, cmd, rest=None):
        conn, size = ftplib.FTP.ntransfercmd(self, cmd, rest)
        if self._prot_p:
            conn = self.context.wrap_socket(conn,
                                            server_hostname=self.host,
                                            session=self.sock.session)  # reuses TLS session            
            conn.__class__ = ReusedSslSocket  # we should not close reused ssl socket when file transfers finish
        return conn, size

session = MyFTP_TLS(server, username, password, timeout=None)
session.prot_p()

我知道我可以在 GitLab CI 中使用其他工具,例如 lftp 和 git-ftp,但是我已经在 Python 脚本中构建了很多自定义功能并且希望使用它。如何在 GitLab CI 中成功部署脚本?提前感谢您的帮助!

【问题讨论】:

欢迎来到 SO 和 GitLab!这是在 GitLab.com 上运行,还是在您自己管理的 GitLab 上运行?如果是 GitLab.com,我很确定共享运行器将无法打开 SFTP 到任意地址 - 否则该服务可能会被滥用以安装 DoS/DDoS 攻击。您必须在可以访问目标 FTP 服务器的计算机上 install 和 register 您自己的跑步者。 谢谢,@mike!好点,有道理。这是我公司的自我管理 GitLab 实例。执行这项工作的跑步者是我的组织在各个组中使用的共享跑步者之一。也许我需要我自己的专用跑步者为我的团队?我会试试的。谢谢! 是的,试试看。由于它是您自己公司的基础架构,因此希望您可以控制运行器计算机和 FTP 服务器之间的网络限制(或向网络管理员提出案例)。为了帮助说服他们:不需要打开 GitLab 服务器和 FTP 服务器之间的访问权限,只有跑步者会连接。 谢谢,@mike!像您建议的那样创建一个专门的小组跑步者是可行的。 FTP 连接现在可以与 group runner 完美配合。非常感谢您的帮助! 【参考方案1】: 推荐的答案 GitLab

这要求GitLab Runner(执行管道)能够与您的 FTP 服务器建立 SFTP 连接。

Shared runners 可能被锁定为仅连接到 GitLab 服务器(以防止攻击向量)。

要解决这个问题,install 你自己的跑步者和register 你的 GitLab。

【讨论】:

以上是关于使用 GitLab CI 通过 python 脚本部署到 FTP的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 gitlab-ci 作业推送到 gitlab 存储库?

gitlab-ci.yaml:在多行 python docker 镜像中运行 python

Gitlab-CI自动化打包之Runner配置和CI脚本说明

获取使用 .gitlab-ci.yml 运行的 Windows Docker 容器

使用“:”的脚本命令导致 .gitlab-ci.yml 执行错误

无法在 Gitlab CI 中使用 pip3 安装 python3 PyQt5 模块