包装和运送python库和脚本,专业的方式

时间:2011-04-14 09:49:25

标签: python

我的任务是打包和发送商业应用程序包,其中包括:

  1. 一个python库(由我们开发)
  2. 一些python程序,取决于上面的库
  3. 我们未开发的其他库,但它们是我们库的依赖项。
  4. 一个完整的python安装(python 2.6)
  5. 其他语言的其他内容,库和程序。这里不是问题,因为它们没有被上述机器所吸引,而且目前的运输过程已经有效。
  6. 捆绑包出货到Linux,OSX和Windows。在Linux上,它以简单的tar.gz形式发布。用户只需在source中解压缩tar.gz和.bashrc提供的bash脚本,以便正确设置环境。在Mac上,这是一个dmg。在窗户上,我不知道。 Windows家伙今天不在这里,但我看到的是以某种方式创建了一个exe。

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

    我们的Python库

    我们不想发布消息来源,因此我们只想提供已编译的python文件。一个更好的策略,使它们更加防篡改是受欢迎的,即使它涉及一些深度黑客攻击(例如,我曾经看到魔术从.zip导入的东西被“损坏”ad-hoc)。目前该库没有C级代码或类似的平台相关代码,但这很快就会改变。因此,我们必须提供特定于平台的编译.so以及pyc。

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

    我们的Python程序

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

    其他图书馆

    我们的库依赖于我们必须发布的第三方库,因此用户启动并运行时没有依赖性。显然,这些库将由我们安装在bundle中,但是我们必须希望这些库在构建期间不会在某处存储安装路径,因为这会使它们不可重定位。

    我们的python

    我们将发布我们的python版本,我们假设用户将运行以访问我们的脚本。这是因为我们想确保运行python版本。此外,我们可能会修改可执行文件或标准库。我们可能会担心这个python与标准python的交互,如果用户想要我们的python上的特定库,它将必须在我们的捆绑包中安装它,而不是在库的标准位置。

    请求

    我需要考虑这个任务。我已经看过它,但从未亲自完成,所以我需要你的观点。我上面提到的是我认为事情应该如何运作,根据事情现在如何运作,但它可能是错误的。欢迎任何成功部署的提示,怪癖,建议或策略。鉴于问题的复杂性,根据我能得到的最佳答案,我已经宣布了很高的奖励。

9 个答案:

答案 0 :(得分:15)

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

这只是Linux,所以我专注于那个。我们需要发布mySQL,lighttpd,python,memcached,一些第三方Python模块和一些自定义脚本的特定自定义版本。我们需要毫无问题地启动所有这些服务,并让用户使用常规initscripts控制它们。它应该在一堆流行的发行版上工作正常,因此不应该依赖于发行版特定的东西。

我做的如下。

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

    现在,我们将为客户端提供自解压。run文件。他们运行它,得到一些问题,它会在/opt下创建一个目录,其中包含我们的应用程序及其所有依赖项。将修改init脚本以在启动时启动我们的应用程序,事情将按预期工作。

    我认为第4步可以让你自由地安装你想要的任何东西,但是你想要的东西可以正常工作。

答案 1 :(得分:5)

您可以使用Makeself,就像tar.gz一样,但会生成.sh,它会自行提取并允许执行自定义安装脚本(不要问我关于Windows)。这样可以避免捆绑已安装的Python,这几乎肯定不会起作用 - 您可以包含安装程序。

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

答案 2 :(得分:5)

我不太明白您的用户最终如何使用该程序,所以如果这没用,请道歉。

您是否看过py2exepy2app?他们会让你在Windows和OS X上创建一个更加模糊的可执行文件,这可能更容易。更少的依赖关系和出错的事情。

我们使用py2exe部署了一个内部公司范围的应用程序,这很简单。无论用户有什么其他蟒蛇或没有我们的脚本是一个简单的向导安装程序,并且可靠地工作。它包括我们必须捆绑的许多Python和C库,以及一个python解释器。然而,我们并没有试图隐藏内容,只是让它变得容易。

答案 3 :(得分:3)

我遇到了同样的问题,但是我能找到的大多数信息只是关于python包。我还没有完整的解决方案,但我有一些建议。

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

  2. 考虑使用像DEB或RPM这样的包格式而不是tar.gz for linux。这将允许您解决依赖关系(如果有)并且可以使更新过程更容易。

  3. 即使您,想要将您的应用程序作为tar.gz发布,我建议您为此应用程序构建一个包。不一定是针对用户,而是针对您构建环境时应该在客户站点上运行的环境。它将允许更容易地测试和构建和更新环境。

答案 4 :(得分:3)

这取决于您的目标市场。在专业化的利基行业中,物品的分布方式更加多样化。在大量商品化的领域,我希望本机操作系统包(至少如果我是客户)。我倾向于将部署包的质量作为一般软件质量的指示。我将本机OS软件包与其他格式相比更高的质量,主要是因为依赖信息可以完整。这使得更容易进行一些合规性测试和变更管理。

原生OS包

  • 对于Unices,请考虑创建本机OS包。它们通过合规性,变更管理,依赖关系管理等流程提供更好的集成和可视性。
  • 对于OSX,其他人已经建议使用py2app。您也可以使用MacPorts包格式或Fink包格式。
  • 对于Windows,其他人已经建议使用py2exe。

重新定位和配置要求

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

共享库

  • 如果我没记错的话,你会想确保从lib中删除任何rpath个条目,因为这可能会影响他们重新定位的能力。
  • 本机操作系统打包应该有助于共享库所需的任何依赖项。

答案 5 :(得分:2)

执行此操作的正确方法(不使用自己的Python)是创建Python Eggs,然后可以由Python包管理器安装,如easy_installpip。设置和安装由setup.py执行,这只是一个Python脚本,因此您可以根据需要包含所有类型的非标准设置过程。

使用pip时,可以很容易地在virtualenv中安装鸡蛋,这会使其与用户的Python安装(除了解释器二进制本身之外)隔离开来。

答案 6 :(得分:2)

对于Windows,我这样做:

  1. 像这样使用cx_freeze

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

    这会创建带有runnable程序的目录 您可以使用其他打包应用程序,例如PyInstaller(Windows,Linux),Py2Exe(Windows)或Py2App(Mac),但我使用Cx_freeze获得了最佳结果(可能是你提到的所有平台)。它也得到了非常好的支持,并且仍在积极维护。

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

  3. 在干净的操作系统安装中,在VMware虚拟机中对其进行测试,以确定。

  4. 实际上,这很容易做到,我不知道要添加什么。


    修改:您还可以在Windows上使用Portable Python作为捆绑环境。

答案 7 :(得分:1)

据我所知,Python是通过msi文件分发的。我似乎也很自然地创建了一个msi安装程序。要创建msi文件,您可以使用例如Windows Installer Extensions工具包。如果您创建自己的msi并将其他msi包含在您的msi中,那么在您自己的msi安装例程中安装python包会遇到麻烦,因为Windows一次只允许一次安装。 最简单的方法是将python msi重新打包到您自己的msi中并分发这个。您可以将msi反编译为xml文件,该文件可用于创建带有dark的新msi,这是Windows Installer Extensions工具包的一部分。

如果您通过tar文件管理它来部署整个套件,那么如果pyhthon和其他东西是xcopy可部署的,那么在Windows上应该可以使用zip文件。当您必须执行某些操作(如设置注册表项,环境变量,创建快捷方式)时,您应该使用msi,因为它是为此任务设计的。但要注意:Msi是一个难题。如果你需要快速获得一些东西,你应该检查一下zip文件和一些脚本可以获得多少。 基于msi的安装将使服务和修补变得更加容易,但要了解这些高级功能,您需要花费几周的时间来学习它。

答案 8 :(得分:0)

虽然这个问题得到了很好的解答,但我仍然希望将其与我的帖子相关联,因为我们遇到了同样的问题。有些人可能会发现它很有用CX_Freeze Linux Python Packaging