打包和发送python库和脚本,专业的方式

我有包装和运输商业应用程序包的任务,其中包括:

  1. 一个python库(由我们开发)
  2. 一些python程序依赖于上面的库
  3. 额外的图书馆不是由我们开发的,但依赖于我们的图书馆。
  4. 一个完整的python安装(python 2.6)
  5. 额外的东西,库和其他语言的程序。 这里不用担心,因为他们没有挂钩上述机器,目前的运输过程已经运作。

该软件包已发布到Linux,OSX和Windows。 在Linux上,它分布为一个简单的tar.gz. 用户只需解压缩tar.gz文件,并在.bashrc提供一个提供的bash脚本,以便正确设置环境。 在Mac上,这是一个伤害。 在窗户上,我不知道。 窗户的家伙今天不在这里,但我看到的是一个EXE是以某种方式创build的。

现在我将更详细地解释以上几点。

我们的Python库

我们不想给出源,所以我们只想提供编译好的python文件。 一个更好的策略,使他们更篡改是值得欢迎的,即使它涉及一些深入的黑客攻击(例如,我曾经看到魔术完成从一个.zip这是“腐败”特设)import的东西。 图书馆目前没有C级代码或类似的平台相关代码,但是这将很快改变。 因此,我们将不得不提供特定于平台的编译.so和pyc。

显然,这个图书馆将与我们的其他应用程序一起在包装中发货。 因此它将被安装在下载的软件包上。 由于这个原因,它必须是完全可重定位的,并且用户必须以某种方式(手动或通过我们的env脚本)将未解包的包的位置添加到PYTHONPATH中,以便解释器能够find它。

我们的Python程序

我们将在我们的软件包中发布应用程序,这些应用程序将取决于我们的库。 这些应用程序的代码必须是用户可见的(以便他可以学习如何使用库接口),或者不可见(对于那些我们要保持闭源的应用程序),所以需要双重方法。

额外的库

我们的图书馆取决于我们将不得不运送的第三方图书馆,以便用户在没有任何依赖性的情况下运行。 显然,这些库将被我们安装在捆绑包中,但是我们必须希望这些库不会在构build过程中将安装path存储在某处,因为这会使它们不可重定位。

我们的python

我们将运送我们的python版本,我们假定用户将运行以访问我们的脚本。 这是因为我们想要确保运行的python版本。 另外,我们可能会修改一下可执行文件或标准库。 我们可能会担心这个python和标准python的交互作用,如果用户想在我们的python上使用特定的库,它将不得不在我们的捆绑软件包中安装它,而不是在库的标准位置。

请求

我需要围绕这个任务进行思考。 我已经看到了它,但从来没有亲自做过,所以我需要你的观点。 上面提到的是我认为事情应该如何工作,根据现在的情况如何,但这可能是错误的。 任何暗示,怪癖,build议或策略的成功部署是受欢迎的。 考虑到这个问题的复杂性,根据我所能得到的最佳答案,我已经宣布了很高的奖励。

这不是一个完整的答案,而只是一堆想法。 我为客户编写了一个安装程序,其中包含了可能对您有用的一些想法。

这只是Linux,所以我专注于这一点。 我们需要发布mySQL,lighttpd,python,memcached,几个第三方Python模块和一些自定义脚本的特定定制版本。 我们需要启动所有这些服务,没有任何问题,让用户使用常规的启动脚本来控制它们。 它应该适用于一些stream行的发行版,因此不应该依赖发行版特定的东西。

我所做的是如下。

  1. 创build一个500MB(我不记得大小)文件,并将其格式化为一个ext3fs文件系统。
  2. 使用回送设备将其安装在一个点上。
  3. 在安装点上运行deb-bootstrap来创build一个定制的Debian安装。
  4. 在分区内部Chroot,然后运行了一堆脚本,它们在我们所有的依赖项上进行了apt-get安装,安装了应用程序所需的所有egg和其他软件包,将应用程序本身安装在/ opt(在chroot中)安装supervisord(进行stream程pipe理)并进行设置。 现在,这个分区是一个完全独立的Linux文件系统,包含应用程序和运行它所需的一切。 你可以把它转储到任何地方,chroot里面,启动应用程序。 它与外部世界唯一的依赖关系是它将用于服务的端口和supervisord控制套接字。 这是主要的一点。 我们能够准确地包含我们需要的东西(仅编译文件,.pycs等),而不必担心标准安装工具的任何限制。
  5. 在此之后,我们打包了一些额外的脚本,将进入外部操作系统。 这些都是为我们必须支持的每个发行版而定制的。 这部分是特定的发行版。 有些脚本会进入/etc/init.d并且有些脚本会在开始时设置数据库和内容。
  6. 然后,我们使用makeself创build整个文件系统的存档。 它会校验和所有的东西,并提供一个自解压存档,如果运行将解压到/opt主机上的整个事情,chroot目录内,并运行一个安装脚本,会问用户几个问题,如db用户名/密码等设置。 之后,它将获取我在步骤5中提到的脚本,并将它们放在主机操作系统上。

启动会简单地插入分区并启动supervisord。 然后,它会照顾启动我们所关心的所有服务。 closures应用程序只是连接到运行supervisord并运行一个命令。 我们用initscript包装这样的用户体验就像UNIX一样。

现在,我们会给客户自我提取。 run文件。 他们会运行它,会问一些问题,它会在/opt下创build一个目录,其中包含我们的应用程序和所有依赖关系。 初始化脚本将被修改,以在启动时启动我们的应用程序,事情将按预期工作。

我想第4步给你自由安装任何你想要的,但是你想这样的事情会正常工作。

你可以使用Makefile ,就像tar.gz一样,但是会产生一个自解压的.sh文件,允许执行一个自定义的安装脚本(不要问我关于Windows的问题)。 这样可以避免捆绑一个几乎可以肯定不会工作的已安装的Python,而是可以包含一个安装程序。

你的代码和你开发的依赖项应该被包含在sdist创build的包中,这个包可以通过PIP安装,并且可以很容易的安装到基于你的python的virtualenv中。 在你的Manifest.in中,你可以很容易地只包含pyc文件和其他所有必需的东西,并排除py文件,所以没有人看到你的来源。 依赖项将通过下载自动安装,但是可以通过将它们包含在归档文件中来避免,如依赖项。 只要把它们放到一个目录中,并添加“-f file:path_to_your_directory”给你的PIP调用。

我不太了解你的用户如何最终使用该程序,所以如果这没有用的道歉。

你有没有看过py2exe和py2app ? 他们会让你在Windows和OS X上创build一个更加混淆的可执行文件,这可能更容易一些。 更less的依赖和出错的东西。

我们使用py2exe部署了一个内部的公司范围的应用程序,这是微不足道的。 不pipe用户有或没有我们的脚本的其他python是一个简单的向导安装程序,并可靠地工作。 它包括我们必须捆绑的一些Python和C库,以及一个Python解释器。 但是,我们并不想隐藏内容,只是简单的。

我有同样的问题,但是我能find的大部分信息只是关于python包。 我还没有完整的解决scheme,但我有一些build议。

  1. 记住python解释器的潜在依赖关系,例如。 在Linux上python取决于glibc。 尝试静态编译它,或者使用一个非常常见的glibc版本。 你可能想看看ActiveState的python发行版 ; 问题是他们想要很多钱。

  2. 考虑使用像DEB或RPM这样的包格式,而不是tar.gz。 这将允许您解决依赖关系,如果有的话会使更新过程更容易。

  3. 就像你一样,想分发你的应用程序作为tar.gz,我会build议为这个应用程序build立一个包。 不一定是为用户,而是为了当你build立的环境,这应该在客户的网站上运行。 这将允许更容易地testing和build立和更新环境。

这将取决于您的目标市场。 在专门的利基产业中,分配东西的方式更多。 在大量商品化的领域,我期望本地OS包(至less如果我是一个客户)。 我倾向于将部署包的质量作为一般软件质量的指示。 我将本地操作系统软件包与其他格式相比质量更高,因为依赖性信息可以完整。 这使得更容易进行一些合规testing和变更pipe理。

本地OS软件包

  • 对于Unices,考虑创build本地OS包。 它们提供了更好的集成和可视性,例如合规性,变更pipe理,依赖性pipe理等。
  • 对于OSX,其他人已经提出了py2app。 您也可以使用MacPorts包格式或Fink包格式。
  • 对于Windows,其他人已经build议py2exe。

搬迁和configuration要求

  • 把你的Python可执行文件放在.../libexec 。 这可以防止意外被调用。
  • 更改Python可执行文件的名称以防止混淆。 即。 /usr/local/libexec/<pkg>_python
  • 分发bin的.py ,使它们易于重定位。 您可以在安装时将Magic Cookie更改为通过安装脚本安装Python的位置。 你需要的唯一的代码是一个调用你的lib这是一个pyc的行。
  • 将你的库安装在/usr/local/lib/app_python/site_package/...下的正确位置,你不需要使用PYTHONPATH

共享库

  • 如果我没有记错的话,你会想确保你从libs中删除任何rpath条目,因为这可能会导致他们被重定位的能力。
  • 本地操作系统打包应该帮助共享库需要的任何依赖。

这样做的正确方法是(无需运送自己的Python)创buildPython Eggs ,然后可以通过Python包pipe理器(如easy_installpip来安装它。 安装和安装由setup.py执行,它只是一个Python脚本,所以如果需要的话,可以包含各种非标准的安装程序。

当使用pip ,很容易在virtualenv中安装egg,这会使它与用户的Python安装(解释器二进制本身除外)隔离。

对于Windows,我正在这样做:

  1. 像这样使用cx_freeze :

     c:\Python27\Scripts\cxfreeze.bat source.py --target-dir=Bin --base-name=Win32GUI --icon=icon.ico --target-name=Executable.exe 

    这创build了可运行程序的目录。
    你可以使用PyInstaller (Windows,Linux), Py2Exe (Windows)或Py2App (Mac)等其他打包应用程序,但是使用Cx_freeze (可能是所有平台)都可以得到最好的结果。 它也有很好的支持,并仍然积极维护。

  2. 使用Inno Setup (Windows)打包一切。
    您可以使用任何方法来创build您喜欢的安装程序。 我不熟悉其他平台。

  3. 在干净的操作系统安装中testing它在VMware虚拟机中是确定的。

其实这个很容易做,我不确定要添加什么。


编辑:您也可以在Windows上使用可移植的Python为您的捆绑环境。

据我所见Python是通过msi文件分发的。 我也很自然地创build了一个msi安装程序。 要创buildmsi文件,您可以使用例如Windows安装程序扩展工具包。 如果您创build自己的msi并将其他msi添加到您的msi中,那么您将在自己的msi安装例程中安装pyhthon软件包时遇到麻烦,因为Windows一次只允许安装一个。 最简单的方法是将python msi重新打包成你自己的msi并分发这个msi。 您可以将msi反编译为xml文件,该文件可用于创build一个全新的msi,该文件是Windows安装程序扩展工具包的一部分。

如果你pipe理它通过一个tar文件来部署你的整个套件,它应该可以在Windows上使用一个zip文件,如果pyhthon和其他的东西是xcopy可configuration。 当您必须执行一些操作时,例如设置registry项,环境variables,创build快捷方式,您应该使用msi,因为它是为此任务而devise的。 但要注意的是,Msi是一个难题。 如果你需要快速得到一些东西,你应该检查你可以得到一个zip文件和一些脚本。 基于msi的安装将使服务和修补更容易,但要欣赏这些先进的function,你需要投入几个星期来学习它。

虽然这个答案很好,但我仍然想把这个链接到我的post,因为我们有同样的问题。 有些人可能会觉得它有用CX_Freeze Linux Python包装