为什么我们在 XenServer 开发中使用 OPAM
这是一篇来自 OPAM 用户的客座文章,讲述了他们如何使用它。如果您想发布关于您自己使用情况的文章,请告知我们。
XenServer 使用了 Xen 项目的 "Xapi 工具栈": 一套主要用 OCaml 编写的工具,它
- 管理具有共享存储和网络的 Xen 主机集群
- 允许在主机之间迁移正在运行的虚拟机(有或无存储),并最大程度地减少停机时间
- 在主机故障后自动重启虚拟机(高可用性)
- 允许跨站点灾难恢复
- 通过滚动池升级简化维护
- 收集性能统计数据以进行历史分析和警报
- 具有一个功能齐全的基于 XML-RPC 的 API,供诸如 XenCenter、Xen Orchestra、OpenStack 和 CloudStack 等客户端使用
Xapi 工具栈由大量独立开发和单独版本化的库和组件构建而成。我们可以轻松地与其他开源项目(如 Mirage)共享代码,但是这种灵活性也带来了一定的成本:当一个二进制文件(例如“xapi”(集群管理器))依赖于 45 个独立的库时,我们如何快速设置构建环境?我们需要哪些库?我们如何应用更新?如果我们更改了其中一个库(例如进行错误修复),我们应该重建哪些部分?这就是 OPAM(源代码包管理器)让一切变得简单的地方。
使用 OPAM 安装构建环境特别容易。例如,在 CentOS 6.5 虚拟机中,首先安装 OPAM
然后
$ opam init --comp=4.01.0
$ eval `opam config env`
接下来,使用类似以下的命令安装 xapi 需要的 C 库和开发工具
$ sudo yum install `opam install xapi -e centos`
最后,构建 xapi 本身
$ opam install xapi
∗ install obuild 0.1.1 [required by cdrom, nbd]
∗ install base-no-ppx base [required by lwt]
∗ install cmdliner 0.9.7 [required by nbd, tar-format]
∗ install camlp4 4.01.0 [required by nbd]
∗ install ocamlfind 1.5.5 [required by xapi]
∗ install xmlm 1.2.0 [required by xapi-libs-transitional, rpc, xen-api-client]
∗ install uuidm 0.9.5 [required by xapi-forkexecd]
∗ install type_conv 111.13.00 [required by rpc]
∗ install syslog 1.4 [required by xapi-forkexecd]
∗ install ssl 0.4.7 [required by xapi]
∗ install ounit 2.0.0 [required by xapi]
∗ install omake 0.9.8.6-0.rc1 [required by xapi]
∗ install oclock 0.4.0 [required by xapi]
∗ install libvhd 0.9.0 [required by xapi]
∗ install fd-send-recv 1.0.1 [required by xapi]
∗ install cppo 1.1.2 [required by ocplib-endian]
∗ install cdrom 0.9.1 [required by xapi]
∗ install base-bytes legacy [required by ctypes, re]
∗ install sexplib 111.17.00 [required by cstruct]
∗ install fieldslib 109.20.03 [required by cohttp]
∗ install lwt 2.4.7 [required by tar-format, nbd, rpc, xen-api-client]
∗ install xapi-stdext 0.12.0 [required by xapi]
∗ install stringext 1.2.0 [required by uri]
∗ install re 1.3.0 [required by xapi-forkexecd, tar-format, xen-api-client]
∗ install ocplib-endian 0.8 [required by cstruct]
∗ install ctypes 0.3.4 [required by opasswd]
∗ install xenctrl 0.9.26 [required by xapi]
∗ install rpc 1.5.1 [required by xapi]
∗ install xapi-inventory 0.9.1 [required by xapi]
∗ install uri 1.7.2 [required by xen-api-client]
∗ install cstruct 1.5.0 [required by tar-format, nbd, xen-api-client]
∗ install opasswd 0.9.3 [required by xapi]
∗ install xapi-rrd 0.9.1 [required by xapi-idl, xapi-rrd-transport]
∗ install cohttp 0.10.1 [required by xen-api-client]
∗ install xenstore 1.2.5 [required by xapi]
∗ install tar-format 0.2.1 [required by xapi]
∗ install nbd 1.0.2 [required by xapi]
∗ install io-page 1.2.0 [required by xapi-rrd-transport]
∗ install crc 0.9.0 [required by xapi-rrd-transport]
∗ install xen-api-client 0.9.7 [required by xapi]
∗ install message-switch 0.10.4 [required by xapi-idl]
∗ install xenstore_transport 0.9.4 [required by xapi-libs-transitional]
∗ install mirage-profile 0.4 [required by xen-gnt]
∗ install xapi-idl 0.9.19 [required by xapi]
∗ install xen-gnt 2.2.0 [required by xapi-rrd-transport]
∗ install xapi-forkexecd 0.9.2 [required by xapi]
∗ install xapi-rrd-transport 0.7.2 [required by xapi-rrdd-plugin]
∗ install xapi-tapctl 0.9.2 [required by xapi]
∗ install xapi-netdev 0.9.1 [required by xapi]
∗ install xapi-libs-transitional 0.9.6 [required by xapi]
∗ install xapi-rrdd-plugin 0.6.0 [required by xapi]
∗ install xapi 1.9.56
===== ∗ 52 =====
Do you want to continue ? [Y/n] y
显然,手动完成所有这些操作非常繁琐!
OPAM 也使得迭代开发变得非常容易。考虑一个需要更改 公共接口 的场景。如果没有 OPAM,我们必须手动找出需要重建哪些组件——这既费时又容易出错。当我们想要进行一些本地更改时,我们只需克隆仓库并告诉 OPAM 将包“固定”到本地检出。OPAM 将负责仅重建依赖的包
$ git clone git://github.com/xapi-project/xcp-idl
... make some local changes ...
$ opam pin add xapi-idl ./xcp-idl
$ opam install xapi
...
xapi-idl needs to be reinstalled.
The following actions will be performed:
↻ recompile xapi-idl 0.9.19*
↻ recompile xapi-rrd-transport 0.7.2 [uses xapi-idl]
↻ recompile xapi-forkexecd 0.9.2 [uses xapi-idl]
↻ recompile xapi-tapctl 0.9.2 [uses xapi-forkexecd]
↻ recompile xapi-netdev 0.9.1 [uses xapi-forkexecd]
↻ recompile xapi-libs-transitional 0.9.6 [uses xapi-forkexecd]
↻ recompile xapi-rrdd-plugin 0.6.0 [uses xapi-idl]
↻ recompile xapi 1.9.56 [uses xapi-idl]
===== ↻ 8 =====
Do you want to continue ? [Y/n]
如果您只想固定到某个分支(例如 master),则会更容易
$ opam pin add xapi-idl git://github.com/xapi-project/xcp-idl
在测试错误修复时能够快速迭代非常重要——OPAM 也使得这一点变得容易。在对“固定”的仓库进行更改后,用户只需键入
$ opam update -u
并且只有受影响的组件将被重建。
OPAM 允许我们创建自己的“开发远程”,其中包含我们库的最新、最前沿版本。要安装这些不稳定的版本,我们只需键入
$ opam remote add xapi-project git://github.com/xapi-project/opam-repo-dev
$ opam update -u
=-=- Updating package repositories =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
[xapi-project] git://github.com/xapi-project/opam-repo-dev already up-to-date
[default] /home/djs/ocaml/opam-repository synchronized
Updates available for 4.01.0, apply them with 'opam upgrade':
=== ∗ 1 ↻ 6 ↗ 6 ===
The following actions will be performed:
∗ install xapi-backtrace 0.2 [required by xapi-idl, xapi-stdext]
↗ upgrade xenctrl 0.9.26 to 0.9.28
↗ upgrade xapi-stdext 0.12.0 to 0.13.0
↻ recompile xapi-rrd 0.9.1 [uses xapi-stdext]
↻ recompile xapi-inventory 0.9.1 [uses xapi-stdext]
↗ upgrade xapi-idl 0.9.19 to 0.9.21
↻ recompile xapi-rrd-transport 0.7.2 [uses xapi-idl]
↻ recompile xapi-forkexecd 0.9.2 [uses xapi-idl, xapi-stdext]
↗ upgrade xapi-libs-transitional 0.9.6 to 0.9.7
↻ recompile xapi-tapctl 0.9.2 [uses xapi-stdext]
↻ recompile xapi-netdev 0.9.1 [uses xapi-stdext]
↗ upgrade xapi-rrdd-plugin 0.6.0 to 0.6.1
↗ upgrade xapi 1.9.56 to 1.9.58
===== ∗ 1 ↻ 6 ↗ 6 =====
Do you want to continue ? [Y/n]
当一组链接的更改准备推送到远程时,我们可以进行单个拉取请求来更新一组组件,这将触发 travis 集成测试。
总结
Xapi 工具栈由大量独立版本化和发布的库构建而成,其中许多库与其他项目(如 Mirage)共享。这些库易于单独构建和测试,但依赖项的数量庞大使得构建整个项目变得困难——这就是 opam 真正闪光的地方。Opam 通过以下方式简化了我们的日常工作:
- 当依赖项更改时自动重建依赖软件
- 允许我们在开发团队之间共享包含最新软件的“开发远程”
- 允许我们使用
git push
“发布”一组协调的版本,然后通过 travis 触发集成测试
如果您有很多 OCaml 代码需要构建,请尝试使用 OPAM!