问题描述
同事不想自己创建virtualenv并在其自动化过程中从git部署工具。相反,他们希望在共享服务器上预先安装工具。
因此,用户考虑创建一个/opt目录,在其中放置virtualenv,并每小时从git拉取以强制更新python包。目前,用户没有对工具进行版本标记,而是每次都要求pip强制安装。
问题在于竞争条件。如果在pip升级期间由他们的自动化调用工具,由于安装不是原子性的,工具可能会失败 – 我相信pip会先删除整个包。
用户已经考虑了各种解决方法(强制使用flock,使用符号链接以原子方式切换virtualenv,将工具包装在每次使用时在临时目录中创建virtualenv的脚本中…)
用户想知道是否有一种他不知道的最佳实践方法。
解决方案
请注意以下操作注意版本差异及修改前做好备份。
最佳实践:不要在共享的virtualenv上进行自动化部署
在自动化过程中使用共享的virtualenv,并期望virtualenv的内容在自动化过程中(自动)更新,而自动化过程对此没有知识/控制,这不是一个好的实践 – 这会导致各种隐晦/间歇性/难以重现的故障。
因此,用户不应花太多时间来尝试找出在共享的virtualenv中更新您的包的可靠方法,而不会影响自动化任务 – 迟早,它们将受到其他源于相同根本原因的问题的影响 – 使用共享的virtualenv。回想一下使用virtualenv的原因。
为了获得一致的结果,自动化过程应确保在需要时更新virtualenv的内容,并且在执行作业时不会(意外地)更改。这在跨多个独立自动化任务共享的virtualenv中实际上是不可能的。通过协调的作业,共享一个在作业期间以受控方式执行virtualenv更新的公共步骤可能是可能的,以确保作业期间virtualenv的一致性,但在我看来,构建这样复杂的系统并不值得,不共享virtualenv并保持作业的独立性要简单得多。
如果,尽管这些考虑,仍然坚持使用共享的virtualenv,则在(明确定义和公告的)维护窗口之外不要在virtualenv之外进行更新,期间应暂停执行自动化作业。
另外,不对软件包进行版本控制也不是一个好的实践,除非您在每种特定情况下都有非常明确和易于访问的指示,指示使用的确切代码版本(例如提交SHA) – 当出现问题时,您很可能需要该信息来尝试重现问题,调试问题和/或以某种程度的确定性验证修复。
其他解决方案
用户还提到了一些其他解决方案,如强制使用flock、使用符号链接以原子方式切换virtualenv、将工具包装在每次使用时在临时目录中创建virtualenv的脚本中。这些方法可能会在特定情况下起作用,但并不是最佳实践,因为它们可能会增加复杂性并引入其他潜在的问题。因此,我们建议用户遵循最佳实践并避免在共享的virtualenv上进行自动化部署。