Virtualenv: -可重定位的替代方案

创建于 2020-02-10  ·  43评论  ·  资料来源: pypa/virtualenv

我使用了--relocatable标志。 新版本20.0没有此标志。 现在如何创建可重定位的环境?

question

最有用的评论

我们使用--relocatable将venv捆绑在rpm中。 virtualenv在$ DESTDIR中创建,最后在/opt/company

所有43条评论

可重定位标志始终处于试验阶段,从未真正起作用。 我们不再支持它,并且该功能已被完全删除(因此是主要版本)。 说明您的用例,我们也许可以建议一种替代方法。

CMD export branch && cd /build_dir && \
 apt-get update -y && apt-get upgrade -y && \
 pip3 install virtualenv && \
 virtualenv --always-copy --python=python3 env && \
 git clone http://user:pass@gitlab/dev/repo.git && \
 cd /build_dir/veil-repo/code/veil-common && \
 git checkout $branch && \
 python3 install.py -p /build_dir/veil-repo/code/cli-app/ -v /build_dir/env && \
 python3 install.py -p /build_dir/veil-repo/code/controller/ -v /build_dir/env && \
 python3 install.py -p /build_dir/veil-repo/code/node/ -v /build_dir/env && \
 cd /build_dir/ && \
 ./env/bin/pip3 install -r requirements.txt && \
 virtualenv --relocatable env

这是Dockerfile的摘录。 如果删除--relocatable标志,代码是否可以正常工作? 也就是说,我需要创建自己的隔离环境,可以以任何方式复制该环境。

在码头工人内部,我想说的是90%。 但是要确保您必须与谁维护该docker代码保持联系,可能确实在我们处理可重定位代码的方式上存在细微的差异。

有时我们使用此功能是因为我们的CI系统会在长名称的目录中创建virtualenv。 名称太长,以致#!太长,我们无法在env中执行脚本。

@ Nitori-在这种情况下,建议使用python -m格式调用工具general

这还算公平。 尽管许多Python程序包表现不佳,并且不允许这样调用它们。

@ Nitori-即使是这种情况,您也可以始终通过二进制文件夹中的python解释器通过调用可执行文件来强制执行调用; 例如

{venv}/bin/python {venv}/bin/bad-bad-tool

其中{venv}可以任意长👍

在我公司,我们在管道中使用--relocatable标志来帮助我们重用virtualenv并节省时间-我们使用GitLab,在早期步骤中构建virtualenv,将其保存为工件,然后重用它来运行一堆并行测试。

我们打算固定virtualenv的版本,但是由于一个错误,我们最终拉到了最新的版本,因此我们的管道今天早上中断了。 我们已修复了该错误,使其得以固定,现在一切都在运行,并且我们将找到一种方法来解决被删除的标志。 但是,即使问题已经解决,我想在这里也要传达我的经验,并且我不希望继续前进。

使用新的应用程序数据播种器创建一个virtualenv只需不到100毫秒,因此这种方法在您的用例中是首选。

我们使用--relocatable将venv捆绑在rpm中。 virtualenv在$ DESTDIR中创建,最后在/opt/company

这是我的情况。

因此,能够将生成的路径预先传递给最终目标会有所帮助吗?

@gaborbernat是的!

仍然需要@ gaborbernat ,virtualenv必须在构建阶段中使用,然后才能部署到最终位置。

不确定这里有什么好的解决方案🤔我愿意接受提案。

对于这种情况, @ gaborbernat的标准行为是区分builddir和前缀。

virtualenv具有DEST_DIR参数,在这种情况下可能会引起误解。 DEST_DIR是实际的venv位置,实际上是前缀(就像/ usr,/ usr / local等一样)。 因此,也许记录virtualenv LOCATION应该更清楚。

然后,您可以添加默认为/--destdir--root选项。 这样,virtualenv可以在destdir (有点像chroot)中隔离工作。 我不知道python,pip和其他脚本将如何应对。

AFAIK问题在于,所有生成的控制台脚本在创建Shebang期间都会对路径进行硬编码。 没有标准的方法来使这些带有shebang的生成的控制台脚本在构建期间和部署后的运行期间都能工作。 除非在构建之后有人修复了shebang。 但这现在超出了创建虚拟环境的范围,因此超出了我们的控制范围。

@gaborbernat您的意思是我们应该在setuptools中实现它? 什么shebang可以在构建时隔离使用,也可以在运行时在目标位置使用?

我正在考虑编写一个virtualenv-relocate脚本,该脚本在现有的virtualenv上编辑shebang,从而使其在新位置中可用。 就像是 :

$ virtualenv-relocate /build/dir/venv /opt/company/app/venv
Rewriting shebang of bin/pip.
Rewriting shebang of bin/pip3.5.
...
$

我也不认为setuptools是一个好地方。 此功能应该成为构建系统的一部分,该构建系统在位置A中进行构建,然后部署到位置B。

好吧,C项目允许通过简单地编辑PATH和LD_LIBRARY_PATH来隔离构建。 无论您使用哪种构建系统。

我不熟悉C如何实现这一目标,也许有人可以解释,链接到它? 之前发生的事情在这里https://github.com/pypa/virtualenv/blob/legacy/virtualenv.py#L1880 -L1894; 我们基本上一直在尝试建立一些相对路径:脚本和pth / egg-files。

我的存储库还使用--relocatable,并且我正在使用脚本(在创建可重定位虚拟环境之后)将其他库复制到virtualenv。 这样,就可以创建完全可重定位的virtualenv了。 例如,我们在Windows上使用它,并将virtualenv添加到我们的安装程序中。 安装后,python3程序与打包的virtualenv可以正常工作。

同样的用例也可以在Mac和Linux上为我们使用。

@ Gagi2k您在这里所做的一切已经表明了当前可重定位实现的脆弱性; 在创建环境后,您需要执行一些其他脚本以使其完全可重定位。 问题在于如何使软件包完全可重定位在很大程度上取决于目标环境。 因此,这里的想法是,virtualenv本身放弃了试图使其环境完全可重定位的尝试(因为在许多情况下它无法成功)……而是将工作完全委派给了编写此自定义脚本的人员,从而实现了这一目标; 具有目标环境知识的脚本,因此确切知道要使内容可重定位需要进行哪些更改以及需要进行多少更改。

是的,很公平。

我的问题或多或少是我现在需要重新创建之前提供的功能,并在所有平台上进行测试,再加上几个发行版,以与旧功能完全相同。

我想我现在将尝试使用较旧的virtualenv版本,直到我或其他人有时间实现此目的。

@ Gagi2k参见我上面关于virtualenv-relocate项目构想的评论。 我很乐意与他人合作。 https://github.com/spotify/dh-virtualenv/可能是一个很好的起点。

@bersace thx,我现在已经复制了旧代码,并从中创建了一个独立的python脚本。 我想我现在将其用作嵌入式解决方案,但我很乐意将来改用其他东西或贡献我拥有的脚本。

您愿意分享@ Gagi2k吗?

@bersace仍在进行中: https : //codereview.qt-project.org/c/qt/qtivi/+/290859

整个virtualenv 20更新导致的问题比预期的要多。 重用旧功能以使脚本可重定位并不是什么大问题,但是由于它现在基于venv并带有pyvenv.cfg,因此变得更加复杂。 例如在Windows上,旧的virtualenv将许多基本py文件复制到/ lib / python(或符号链接)。 现在它们根本没有被复制,但是pyvenv只是指向原始位置。 原始位置更新后,您的virtualenv需要处理它,并且您希望所需要的一切仍然存在。 更大的问题是https://bugs.python.org/issue39469 ,这使得很难将它传递给一个相对位置,您可以在其中设置所有内容以使可重定位的virtualenv ...

就目前而言,我不认为可以做到(没有pyvenv.cfg支持)。

@gaborbernat我可能会误用virtualenv的原始意图,但是为您的应用程序提供您自己的python3副本的正式方法是什么,因为您想让人们使用pip扩展它?

@ Gagi2k我确定我在这里错过了一些东西; 但是您能否不仅在给定计算机上的安装阶段更改pyenv.cfg hone

@gaborbernat我可能会误用virtualenv的原始意图,但是为您的应用程序提供您自己的python3副本的正式方法是什么,因为您想让人们使用pip扩展它?

虚拟环境被设计为始终引用计算机上的某些python解释器。 基本假设是您在计算机上拥有一个完全正常工作的python环境,并且您只想为其拥有多个单独的site-packages 。 我可以在制作环节没有完全明确的看到一些值(现在是完全明确的路径),但是如果你要沿着这条道路,为什么不干脆一路兼用PyInstallerPEX与打包代码python可执行文件在先,没有任何容易中断的引用?

@gaborbernat当然可以,最大的问题是大多数用户习惯于在安装后重命名该文件夹,并且该文件夹可以正常工作...
但是我刚刚发现,设置PYTHONHOME也可以解决问题,至少在Windows上我可以在不参考原始安装的情况下运行它。

pex看起来很有趣,我会仔细研究一下,以获取提示。

@gaborbernat仍然,如何在builddir中构建virtualenv并将其以.deb或.rpm交付?

@gaborbernat当然可以,最大的问题是大多数用户习惯于在安装后重命名该文件夹,并且该文件夹可以正常工作...

不知道为什么他们期望这样。 从来没有这样。 即使使用可重定位标志,在某些情况下也是如此。 因此,为什么它被v20砍掉了。

@gaborbernat仍然,如何在builddir中构建virtualenv并将其以.deb或.rpm交付?

@bersace,这取决于您的许多用例。 deb / rpm是否保证python在目标计算机上的相同位置可用? 如果是这样,只需在安装过程中修复shebang路径👍

@gaborbernat取决于系统python足以确保python在特定位置。

在postinst上修改已安装的文件是一个非常糟糕的主意。 这就要求从dpkg领域中排除所有脚本,因此dpkg不会在升级时碰到它们。 那是不可接受的。

AFIAK,最好的解决方案是virtualenv-change-prefix ,该文件将编辑所有shebang以便删除destdir ,然后在归档最终软件包之前执行。

@bersace ,您将shebangs设置为什么?

@gaborbernat绝对目标位置。 例如#!/opt/company/app/venv/bin/python

这意味着现在不支持将该程序包部署到/以外的新refroot,不是吗?

@gaborbernat是的,设计

这与relocatable有所不同。 目的不是使venv是相对的,而是要区分builddir(debian / build / ...或%builddir)和rundir(/)。

由于我们这边没有可行的项目,请关闭此页面。 我建议在这里继续讨论,或在virtualenv之上尝试解决该问题的潜在项目。

实际上,一种替代方法是某种程度上依赖供应商,而不对它们进行版本控制。

就我而言,我必须压缩一个具有所需依赖项的python软件包,并将其作为“归档”传递给Yarn上的Spark,以支持我的程序在分布式Spark集群上运行。 尽管此操作可以由Anaconda完成,但是企业软件无法在我的公司中使用。 relocatable过去可以解决此问题,但现在消失了。

就我而言,我必须压缩一个具有所需依赖项的python软件包,并将其作为“归档”传递给Yarn上的Spark,以支持我的程序在分布式Spark集群上运行。 尽管此操作可以由Anaconda完成,但是企业软件无法在我的公司中使用。 relocatable过去可以解决此问题,但现在消失了。

@jackhhh ,您好,您是否找到现有用例的解决方法?
我们遇到了同样的问题。

此页面是否有帮助?
0 / 5 - 0 等级