当前,每次通过Jenkins + Ansible运行构建时,我们都在重新创建虚拟环境并重新安装requirements.txt文件中列出的所有依赖项。

这非常慢并且无法扩展好。我们如何改善和加快流程?我们可以重用虚拟环境吗?


我们尚未实现的最新想法是在Jenkins工作区之外构建虚拟环境,基于project + branch命名虚拟环境,然后保持每个虚拟环境要求的MD5总和。然后,在下一次构建环境之前,我们计算该分支中当前需求的MD5总和,并以此MD5总和查找现有的虚拟环境。如果找到了具有此总和的现有环境,请重新使用它。我们不确定这是否是解决问题的最佳方法。

评论

这不是特定于virtualenv的解决方案,但是您可以考虑在预先安装和预先配置了virtualenv的docker或vagrant映像中运行构建。

#1 楼

通常,使您的构建成为幂等的最佳做法。遗留工件只会为依赖关系管理问题提供机会,而以弹性方式解决这些问题正是您使用构建服务器的原因。我建议您看一下为什么您的Python构建运行如此缓慢-如果您发现这是由于每个项目中的程序包过多导致的,那么这可能是可优化的。如果您发现这是由于服务器性能问题引起的,则可以使用更多资源轻松修复这些问题。如果发现网络吞吐量阻止了您,请考虑使用构件存储库在本地缓存程序包。但是,构建持久性virtualenvs似乎是解决问题的良方,这些问题在移至另一台服务器时可能无法预料,并且很难进行故障排除。

#2 楼

我要在@esoterydactyl给出的答案中添加更多的故事,以防万一它被太多人所困扰。

而不是一个整体的构建过程,也许您想要构建可以版本化并部署到您的工作空间,而无需所有中间构建步骤。 Docker是一种打包解决方案,在这种情况下非常流行。您也可以使用.deb或.rpm或非Docker tarball,或者制作CF“ StemCells”甚至是zip文件。还请考虑Python现在已经预构建了“ wheel”程序包。在开发沙箱和CI工作区之间的差异中将会出现-pulling乐趣。因此,该软件包必须支持dev笔记本电脑沙箱和Jenkins工作区安装。
build-deps软件包必须具有自己的CI生成/测试/打包/发布管道。但是,它可以减少周期频率,而没有人对它(或其任何组件)进行任何更改。
这是捆绑的示例。例如,如果您要修补CVE,则必须修补所有使用该捆绑软件的东西。部署它绝不会比其他任何事情都困难,因此,当您的CI构建速度很快时,请不要停止工作。 CI需要CD,或者您可能要交付生产不可部署的软件。
如果要制作自己的预构建工件,则需要基础结构来承载工件存储库和版本控制方案。

增量解决方案将是解决这些问题的最少数量,从而显着提高构建周期的速度。这就是为什么维护本地pypi存储库并添加Jenkins作业以构建并向其推送包的原因。我知道这听起来很痛苦,但是想像一下,如果您必须管理所有东西的内部软件开发,就可以通过pip进行安装?

#3 楼

您可能需要看一下ShiningPanda插件。

它允许在特定的python虚拟环境中运行构建步骤,如果不存在则自动创建,如果已经存在则重新使用。虚拟环境位于工作空间外部,但是可以对其进行命名并使其显示为该工作空间内具有该名称的目录。

要解决依赖项,您只需插入执行以下操作的构建步骤:在拉出工作区(可能会带来您的pip install -r requirements.txt文件)之后但在需要使用虚拟环境的任何其他构建步骤之前,需要的requirements.txt变体。

同一个虚拟环境可以用于同一构建的多个步骤(按名称),并且一个构建可以具有多个虚拟环境(如果需要)。但是AFAIK不能在不同的内部版本中重复使用相同的虚拟环境,每个内部版本都有自己的副本。

该插件具有一个配置,可以在使用该环境的任何构建步骤中清除/清除环境/需要的时候。显然,您不希望始终启用此功能,因为它会使可重用性失效。

IMHO最好与带有固定包版本(例如pip-tools生成的requirements.txt文件)的Name文件配合使用。

更新:最近我在Windows上遇到了与插件有关的问题:我在不同的Jenkins文件夹中有多个作业,但是具有相同的作业名称和相同的插件配置(尤其是Advanced部分中的非空Name)。事实证明,所有作业实际上都是共享一个环境(并且彼此过渡),我不得不在各个作业中为\Jenkins\shiningpanda\jobs\<job_name_hash>\virtualenvs\<venv_name_path_hash>\切换为唯一值。显然,这2个名称用于从虚拟环境路径生成2个散列,因此,相同的名称->相同的路径:

q4312079q

因此,如果您具有相同的工作名称,如果您确实想要的话,实际上您可以共享相同的环境:)