如何在 Oracle Solaris 11 上创建软件包并将其发布到 IPS 信息库

2011 年 11 月

作者:Glynn Foster

如何创建适用于 Oracle Solaris 11 的软件包并将其发布到网络软件包信息库中。


Oracle Solaris 11 采用了一种新方法来进行生命周期和软件包管理,极大地简化了系统软件的管理过程,有助于降低操作系统维护的风险,包括减少意外停机和计划停机。使用映像包管理系统 (IPS),管理员可以使用大幅改进和现代化的过程从本地连接或远程软件包信息库安装和更新软件。

希望将类似本文的技术文章发送到您的收件箱吗?请订阅系统社区新闻快讯 — 仅包含面向系统管理员和开发人员的技术内容。

在本文中,我们将探讨如何创建可以在 Oracle Solaris 11 系统上安装使用的软件包并将其发布到 IPS 库中。我们将以流行的开源版本控制系统 Bazaar 为例来展开讨论。

欲了解 IPS 之详情,请查阅 Oracle 技术网上 IPS 技术聚焦页面中的丰富内容。另请参阅 Oracle Solaris 11 映像包管理系统速查表

软件包创建过程概述

本文稍后将深入探讨创建软件包并将其发布到 IPS 库的具体过程,在这之前,我们先概要介绍一下将执行的步骤。

  1. 构建源代码。

    根据您要打包的软件,该步骤可能需要建立构建环境并运行脚本来收集有关系统状态的一些基本信息,从而确保安装好相关软件包,确保拥有可用编译器,并确定在文件系统中安装软件相关文件的最佳方式。对于此步骤,我们不会探讨太过具体的细节,因为此步骤可能因将要打包的软件的不同而千变万化。我们将在自己的本地工作区 $HOME 中构建我们的软件。

  2. 创建 IPS 软件包清单。

    此步骤主要是创建 IPS 清单,IPS 清单用于描述如何将各部分内容共同组织成软件包,包括以下基本信息:软件包名称和版本、作为软件包的组成部分而要安装的文件或其他内容、在安装软件包之前须满足的其他软件依赖项。

  3. 建立 IPS 信息库。

    我们使用一个软件包信息库来托管所有软件包,各个系统可通过连接到这个软件包信息库来安装软件。软件包信息库可以在本地通过文件系统进行访问,也可以通过 http://https:// 连接经由网络远程访问。本文通过 http:// 来使用一个软件包信息库,并且使用服务管理工具 (SMF) 来管理该信息库。

  4. 将软件包发布到信息库中。

    在创建软件包清单、提供软件包信息库以托管该软件包之后,整个过程的最后一步是,将该软件包发布到信息库中,这样各系统可通过连接到该信息库来安装这个软件包。

第 1 步:构建源代码

Bazaar 是一个基于 Python 的应用软件,其源代码可从 http://launchpad.net/bzr/2.4/2.4.1/+download/bzr-2.4.1.tar.gz 下载。

我们将对源压缩包进行解压缩,运行配置脚本,将该软件安装到工作区的一个临时位置,这个临时位置与我们的最终目标文件系统相分离。通过这种方法,我们可以确定哪些文件和目录应成为我们软件包的一部分。这个临时位置有时称作proto 区域

# cd $HOME
# mkdir proto_install
# wget http://launchpad.net/bzr/2.4/2.4.1/+download/bzr-2.4.1.tar.gz
# tar -zxf bzr-2.4.1.tar.gz
# ls
bzr-2.4.1/         proto_install/

现在我们来了解一下 Bazaar 的源目录。

# cd bzr-2.4.1
# ls
apport/            contrib./    man1/              README
BRANCH.TODO        COPYING.txt  MANIFEST.in        README_BDIST_RPM
bzr/               doc/         NEWS               setup.py
bzr.ico            INSTALL      po/                TODO
bzrlib             Makefile     profile_imports.po tools/

Bazaar 使用标准 Python 机制 setup.py 进行自我配置、构建和安装。为了启动构建,我们可以使用 setup.py 安装目标,并为其提供我们的 proto 区域位置以及我们想在文件系统上进行安装的最终目标的“前缀”位置,在本例,这两者分别是 $HOME/proto_install/usr

构建 Bazaar 时需要一个 C 编译器(为方便起见,在本例中我们选用了 GNU GCC 编译器)和必要的开发头部,我们可以使用 Package Manager 来快速安装它们。

# pkg install developer/gcc-3 system/header
# python setup.py install --root=$HOME/proto_install --prefix=/usr

这些命令执行完毕并且成功进行构建之后,我们快速浏览 proto_install 的内容:

# cd $HOME
# cd proto_install
# ls
bin/  lib/  man/
# cd bin
# ls
bzr

我们可以看到,在 bin 目录中,现在有一个刚建好的 bzr 二进制文件,我们可以通过设置合适的 PYTHONPATH 环境变量来直接运行这个文件,如清单 1 所示。

清单 1:运行 bzr 二进制文件
# export PYTHONPATH=$HOME/proto_install/usr/lib/python2.6/site-packages/
# ./bzr
Bazaar 2.4.1 - a free distributed version-control tool
http://bazaar-canonical.com/

Basic commands:
  bzr init           makes this directory a versioned branch
  bzr branch         makes a copy of another branch

  bzr add            makes files or directories versioned
  bzr ignore         ignore a file or pattern
  bzr mv             move or rename a versioned file

  bzr status         summarize changes in working copy
  bzr diff           show detailed diffs

  bzr merge          pull in changes from another branch
  bzr commit         save some or all changes
  bzr send           send changes via email

  bzr log            show history of changes
  bzr check          validate storage

  bzr help init      more help on e.g. init command
  bzr help commands  list all commands
  bzr help topics    list all help topics

现在我们准备进行下一步,将通过刚才安装到 proto_install 区域中的文件来创建一个 IPS 软件包。

第 2 步:创建 IPS 软件包清单

我们先了解一下现有的清单,然后再创建自己的清单。

关于软件包清单

每个 IPS 软件包的背后都有一个清单,提供有关该软件包的一些基本元数据(名称、说明、版本、类别等等)、包含哪些文件和目录,以及该软件包需要安装哪些依赖项。软件包可以指定重启哪些服务以便对系统上的一些配置进行刷新。它们还可以指定对于特定的硬件驱动程序要更新哪些别名,以及在软件包安装过程中要创建哪些用户和组。

为了熟悉软件包清单,我们可以使用 pkg contents 命令列出与 gzip 软件包关联的清单并将该清单输出到 gzip.p5m 文件中(p5m 是我们用于软件包清单的一个标准文件扩展名约定),如清单 2 所示。

清单 2:列出软件包清单
# cd $HOME
# pkg contents -m gzip > gzip.p5m
# cat gzip.p5m
set name=pkg.fmri value=pkg://solaris/compress/gzip@1.3.5,5.11-0.174.0.0.0.0.504:20110920T223615Z
set name=info.source-url value=http://alpha.gnu.org/gnu/gzip/gzip-1.3.5.tar.gz
set name=pkg.summary value="GNU Zip (gzip)"
set name=pkg.description value="The GNU Zip (gzip) compression utility"
set name=info.classification value="org.opensolaris.category.2008:Applications/System Utilities"
set name=org.opensolaris.arc-caseid value=PSARC/2000/488
set name=info.upstream-url value=http://directory.fsf.org/GNU/gzip.html
set name=org.opensolaris.consolidation value=userland
license 91533ecafdca90d38563499351a030e497bc9dae chash=33000d74d113ed003308b6b2c6f6565597517ab8 license=GPLv2 pkg.csize=657 pkg.size=1278
set name=variant.arch value=i386 value=sparc
depend fmri=pkg:/system/library@0.5.11-0.172.0.0.0.0.17571 type=require
depend fmri=pkg:/shell/bash@4.1.9-0.172 type=require
dir group=sys mode=0755 owner=root path=usr
dir group=bin mode=0755 owner=root path=usr/bin
dir group=sys mode=0755 owner=root path=usr/share
dir facet.doc.info=true group=bin mode=0755 owner=root path=usr/share/info
dir facet.doc.man=true group=bin mode=0755 owner=root path=usr/share/man
dir facet.doc.man=true group=bin mode=0755 owner=root path=usr/share/man/man1
...

从清单 2 可以看到,每行通过一系列操作 规定了软件包的各个部分。所有操作都有一种简洁的表达方式:

<action_name> <attribute1=value1> <attribute2=value2> ...

表 1 列出了软件包清单创建过程中可以使用的操作。

表 1 软件包清单操作
操作名称说明
set指定软件包的一些基本元数据,如名称、说明、分类等等。
license指定与软件包相关联的许可,以及(举例来说)在软件包安装之前是否必须进行许可确认。
file指定该软件包要安装的一个文件。file 操作的属性指定一些基本权限以及该文件的安装位置。
dir指定该软件包要安装的一个目录。dir 操作的属性指定一些基本权限以及该目录的安装位置。
link指定一个符号链接。如果您想让一个链接指向一个首选版本的二进制文件,例如,/usr/bin/python 链接到 /usr/bin/python2.5,也可以使用 link 操作来管理中介链接。
hardlink指定一个硬链接。
depend指定软件包与其他软件的任何依赖项。可以指定不同类型的依赖项,包括:对其他软件包的简单的必需依赖项、可选依赖项,以及表示如果已安装了另一软件则不能安装该软件包的依赖项。要获得依赖项类型的完整列表,请参见使用映像包管理系统打包并提供软件指南。
driver指定一个要安装的设备驱动程序以及任何要配置的别名。实际驱动程序二进制文件应使用 file 操作来安装。
user指定要创建的用户帐户。user 操作的属性指定用户名、口令、主目录以及其他信息。
group指定要创建的组。group 操作的属性指定组名称和组 ID。
legacy指定由于 SVR4 兼容性的原因应在传统软件包数据库中安装相关信息,从而确保可以安装须满足特定的依赖项的老旧软件包。

软件包清单一般可分为三个部分:

  • 软件包元数据
  • 软件包内容
  • 软件包依赖项

当我们开始为自己的软件包生成清单时,将依次配置这些不同的部分。

指定软件包元数据。

我们使用 set 操作来设置某些软件包元数据。例如,我们将设置一些重要项(见表 2),稍后在需要时再填入其他项。

表 2 用于指定元数据的属性
属性名称说明
pkg.fmri软件包名称和版本
pkg.description软件包说明
pkg.summary软件包摘要
variant.arch该软件包支持的架构
info.classificationPackage Manager 图形客户端中对软件包进行排序所使用的分类方案

在本例中,我们在一个名为 bzr.mog 的文件中提供以下详细信息。我们将使用 mog 文件扩展名来表示其内容需要经过另一个处理步骤之后我们才会将其放入清单中。

清单 3:提供元数据
# cat > bzr.mog << EOF
set name=pkg.fmri value=developer/versioning/bzr@2.4.1,0.1
set name=pkg.description value="Bazaar (bzr) Source Version Control System"
set name=pkg.summary value="Bazaar is a source version control system that helps to track project changes over time"
set name=variant.arch value=$(ARCH)
set name=info.classification value="org.opensolaris.category.2008:Development/Source Code Management"
EOF
# ls
bzr-2.4.1/         gzip.p5m
bzr.mog            proto_install/

我们很快地讨论一下最后两行内容。Variant 是 IPS 的一个特性,允许在软件包信息库中的一个软件包中包括多种架构,目的是减少绝大部分内容相同只不过是为了不同的架构而构建的多个软件包所占用的空间量。在本例,我们可以手动提供 i386sparc,但是更有用的方法是使用宏,我们在过程稍后将取代这个宏。

Classification 确定软件包在 Package Manager 图形界面中的显示方式。在使用映像包管理系统打包并提供软件指南的附录中详细描述了一系列 classification。

指定软件包内容

我们的清单创建过程的下一步是,指定该软件包应安装哪些文件、目录、链接和硬链接。在这一步中,我们使用 pkgsend generate 命令分析整个 proto 区域,递归列出其中所含相应清单操作内容,然后通过 pkgfmt 实用工具传递该输出以便提供更好格式的内容,如清单 4 所示。

清单 4:分析整个 Proto 区域
# pkgsend generate proto_install | pkgfmt > bzr.p5m.1
# cat bzr.p5m.1
dir  path=usr owner=root group=bin mode=0755
dir  path=usr/bin owner=root group=bin mode=0755
file usr/bin/bzr path=usr/bin/bzr owner=root group=bin mode=0755
dir  path=usr/lib owner=root group=bin mode=0755
dir  path=usr/lib/python2.6 owner=root group=bin mode=0755
dir  path=usr/lib/python2.6/site-packages owner=root group=bin mode=0755
file usr/lib/python2.6/site-packages/bzr-2.4.1-py2.6.egg-info \
    path=usr/lib/python2.6/site-packages/bzr-2.4.1-py2.6.egg-info owner=root \
    group=bin mode=0644
dir  path=usr/lib/python2.6/site-packages/bzrlib owner=root group=bin mode=0755
file usr/lib/python2.6/site-packages/bzrlib/__init__.py \
    path=usr/lib/python2.6/site-packages/bzrlib/__init__.py owner=root \
    group=bin mode=0644
file usr/lib/python2.6/site-packages/bzrlib/__init__.pyc \
    path=usr/lib/python2.6/site-packages/bzrlib/__init__.pyc owner=root \
    group=bin mode=0644
....
file usr/lib/python2.6/site-packages/bzrlib/xml_serializer.pyc \
    path=usr/lib/python2.6/site-packages/bzrlib/xml_serializer.pyc owner=root \
    group=bin mode=0644
dir  path=usr/man owner=root group=bin mode=0755
dir  path=usr/man/man1 owner=root group=bin mode=0755
file usr/man/man1/bzr.1 path=usr/man/man1/bzr.1 owner=root group=bin mode=0644

注意,在清单 4 中可以看到许多 dir 操作和 file 操作。特别是对于 file 操作,可以看到指定了两个路径:一条路径通往我们要将该软件包安装到的文件系统上的最终位置,另一条路径通往 proto_install 区域中的位置,如下面的代码段所示:

file usr/lib/python2.6/site-packages/bzrlib/__init__.py \     path=usr/lib/python2.6/site-packages/bzrlib/__init__.py owner=root \
    group=bin mode=0644

这很有用,因为我们可以直接修改文件和目录的安装位置,而不必在 proto_install 区域进行同样的一连串修改。

现在到时候了,我们来看看该软件包中将包括哪些内容。在发布该软件包之前,我们可以选择删除一些我们不想安装的内容,还可以改正任何对于文件系统上的最终安装位置而言不一致或不正确的权限设置。

我们无需直接修改清单进行这些更改,只需使用 pkgmogrify 提供我们想进行的一系列转换。这些转换可以在我们前面所说的 bzr.mog 文件中指定。之后,我们可以合并这两个文件的内容,如清单 5 所示。

清单 5:使用 pkgmogrify 指定转换
# pkgmogrify -DARCH=`uname -p` bzr.p5m.1 bzr.mog | pkgfmt > bzr.p5m.2
# cat bzr.p5m.2
set name=pkg.fmri value=developer/versioning/bzr@2.4.1,0.1
set name=pkg.description value="Bazaar (bzr) Source Version Control System"
set name=pkg.summary value="Bazaar is a source version control system that helps to track project changes over time"
set name=variant.arch value=i386
set name=info.classification value="org.opensolaris.category.2008:Development/Source Code Management"
dir  path=usr owner=root group=bin mode=0755
dir  path=usr/bin owner=root group=bin mode=0755
file usr/bin/bzr path=usr/bin/bzr owner=root group=bin mode=0755
dir  path=usr/lib owner=root group=bin mode=0755
dir  path=usr/lib/python2.6 owner=root group=bin mode=0755
dir  path=usr/lib/python2.6/site-packages owner=root group=bin mode=0755
file usr/lib/python2.6/site-packages/bzr-2.4.1-py2.6.egg-info \
    path=usr/lib/python2.6/site-packages/bzr-2.4.1-py2.6.egg-info owner=root \
    group=bin mode=0644
....
file usr/lib/python2.6/site-packages/bzrlib/xml_serializer.pyc \
    path=usr/lib/python2.6/site-packages/bzrlib/xml_serializer.pyc owner=root \
    group=bin mode=0644
dir  path=usr/man owner=root group=bin mode=0755
dir  path=usr/man/man1 owner=root group=bin mode=0755
file usr/man/man1/bzr.1 path=usr/man/man1/bzr.1 owner=root group=bin mode=0644

# ls
bzr-2.4.1/         bzr.p5m.2
bzr.mog            gzip.p5m
bzr.p5m.1          proto_install/

在这一步中,我们还有机会定义我们的架构宏 $(ARCH)

我们已成功确定了软件包内容,现在进行下一步,指定我们要包括的软件包依赖项。

指定软件包依赖项

如前文所述,在创建新的软件包时,可以指定许多软件包依赖项。在本例中,我们只关注 require 类型的依赖项,即为了让 Bazaar 正常运行而必须安装的那些软件包。有关其他依赖项类型,可以参考使用映像包管理系统打包并提供软件指南。

幸运的是,我们可以使用 pkgdepend generate 命令自动完成这一步:

# pkgdepend generate -md proto_install bzr.p5m.2 | pkgfmt > bzr.p5m.3
# ls
bzr-2.4.1/         bzr.p5m.3
bzr.mog            gzip.p5m
bzr.p5m.1          proto_install/
bzr.p5m.2

在这一步中,我们使用了前面生成的软件包清单内容,并且我们针对该清单中列出的每个文件,对位于 proto_install 区域中的实际文件进行了更多的分析。这一步用许多不同的分析方法自动确定需要哪些文件依赖项,例如用于编译二进制文件的 ELF 头部、shell 脚本中的 #! 引用,以及用于 Python 文件的 import 语句。

浏览生成的文件 bzr.p5m.3,可以看到类似于清单 6 所示的一些额外的行。

清单 6:额外的依赖项
depend type=require fmri=__TBD \ 
   pkg.debug.depend.reason=usr/lib/python2.6/site-packages/bzrlib/tests/ssl_certs/create_ssls.py \
    pkg.debug.depend.type=python \
    pkg.debug.depend.file=cStringIO.py \
    pkg.debug.depend.file=cStringIO.pyc \
    pkg.debug.depend.file=cStringIO.pyo \
    pkg.debug.depend.file=cStringIO.so \
    pkg.debug.depend.file=cStringIO/__init__.py \
    pkg.debug.depend.file=cStringIOmodule.so \
    pkg.debug.depend.path=usr/lib/python2.6 \
    pkg.debug.depend.path=usr/lib/python2.6/lib-dynload \
    pkg.debug.depend.path=usr/lib/python2.6/lib-old \
    pkg.debug.depend.path=usr/lib/python2.6/lib-tk \
    pkg.debug.depend.path=usr/lib/python2.6/plat-sunos5 \
    pkg.debug.depend.path=usr/lib/python2.6/site-packages \
    pkg.debug.depend.path=usr/lib/python2.6/site-packages/bzrlib/tests/ssl_certs \
    pkg.debug.depend.path=usr/lib/python2.6/vendor-packages \
    pkg.debug.depend.path=usr/lib/python2.6/vendor-packages/gst-0.10 \
    pkg.debug.depend.path=usr/lib/python2.6/vendor-packages/gtk-2.0 \
    pkg.debug.depend.path=usr/lib/python26.zip

在清单 6 显示的输出中,我们可以看到 create_ssls.py 文件依赖于许多其他 Python 文件:cStringIO.pycStringIO.pyccStringIO.pyo,等等。下面我们用 pkgdepend resolve 命令将这些文件依赖项解析为早前已安装的软件包依赖项:

# pkgdepend resolve -m bzr.p5m.3
# ls
bzr-2.4.1/         bzr.p5m.3
bzr.mog            bzr.p5m.3.res
bzr.p5m.1          gzip.p5m
bzr.p5m.2          proto_install/

片刻后生成 bzr.p5m.3.res 文件,该文件现已成功地将文件依赖项解析到软件包中,如清单 7 所示。

清单 7:解析文件依赖项
# tail bzr.p5m.3
....
file usr/lib/python2.6/site-packages/bzrlib/xml_serializer.pyc \
    path=usr/lib/python2.6/site-packages/bzrlib/xml_serializer.pyc owner=root \
    group=bin mode=0644
dir  path=usr/man owner=root group=bin mode=0755
dir  path=usr/man/man1 owner=root group=bin mode=0755
file usr/man/man1/bzr.1 path=usr/man/man1/bzr.1 owner=root group=bin mode=0644
depend fmri=pkg:/runtime/python-26@2.6.4-0.174.0.0.0.0.504 type=require
depend fmri=pkg:/system/library/gcc-3-runtime@3.4.3-0.174.0.0.0.0.504 type=require

现在我们已成功完成了本步骤,软件包清单的所有以下基本元素已就位:元数据、文件和目录内容、软件包依赖项。

检查最终清单

我们现在拥有了最终的清单,最好先检查一下这个清单,然后再将该清单及软件包内容发布到软件包信息库中。这项工作可以手动完成,也可以使用 pkglint 工具完成,这个工具有助于根据软件包中已发布的其他软件包进行一致性检查,它会创建一个本地内容缓存并据其进行有效性检查。

这里我们不探讨检查软件包的细节,我们想说的是可以使用以下命令进行简单的验证检查:

# pkglint -c ./lint-cache -r http://pkg.oracle.com/solaris/release bzr.p5m.3.res
# ls
bzr-2.4.1/         bzr.p5m.3.res
bzr.mog            gzip.p5m
bzr.p5m.1          lint-cache/
bzr.p5m.2          proto_install/
bzr.p5m.3

通常,在您要安装软件包的系统上,文件权限有所不同,需要进行权限更改。另外,诸如手册页面或系统配置之类内容的默认文件位置也可能不同。如果您需要解决这类问题,可以在发布前对软件包清单应用其他转换。

本例需要在我们的原始 bzr.mog 文件中添加以下转换,将手册页面位置指定为 /usr/share/man 并更改 /usr 的组权限:

<transform dir path=usr/man -> edit path usr/man usr/share/man>
<transform dir path=usr/man/man1 -> edit path usr/man/man1 usr/share/man/man1>
<transform file -> edit path usr/share/man1 usr/share/man/man1>
<transform dir path=usr$ -> edit group bin sys>

回顾清单创建过程

我们可以在任何阶段重新开始这一过程,直到对自己的最终文件输出感到满意。我们来回顾一下这一过程。

首先我们使用 pkgsend generate 命令创建初始清单,这个命令搜索我们的 proto 区域寻找我们想包括在软件包中的文件和目录。

# pkgsend generate proto_install | pkgfmt > bzr.p5m.1

然后我们使用 pkgmogrify 命令添加软件包元数据以及我们想对软件包内容进行的任何转换。

# pkgmogrify -DARCH=`uname -p` bzr.p5m.1 bzr.mog | pkgfmt > bzr.p5m.2

随后我们使用 pkgdepend generate 命令找出我们可能具有的任何文件依赖项,该命令检查 proto 区域中包含的文件列表,确定该文件系统上的哪些文件是必需的。

# pkgdepend generate -md proto_install bzr.p5m.2 | pkgfmt > bzr.p5m.3

最后,我们使用 pkgdepend resolve 命令获得这些文件依赖项并将它们解析成软件包依赖项。

# pkgdepend resolve -m bzr.p5m.3

第 3 步:建立 IPS 信息库

下一步是创建和配置一个 IPS 信息库以便托管我们软件包。对于创建 IPS 信息库,我们有许多不同的方法,例如我们可以创建基于文件系统的信息库,或者创建可通过 http://https:// 来访问的信息库。但在本例中,我们将使用 SMF 新建一个可通过 http:// 访问的 IPS 信息库服务,在遇到故障时,这个服务可以自动重启,这要归功于 SMF 服务重启功能。

首先要创新一个新的 ZFS 数据集以便容纳我们的库。使用 ZFS 数据集在存储方面带来了更大的灵活性,可以适应 IPS 软件包信息库不断增大的情况,支持对备份进行快照、克隆或将其发送到另一台服务器。为此,我们使用 zfs create 命令在名为 rpool 的已有 root zpool 中新建一个名为 repository 的数据集:

# zfs create rpool/export/repository

现在我们用 pkgrepo create 命令在这个 ZFS 数据集中创建一个 IPS 信息库:

# pkgrepo create /export/repository
# ls /export/repository
pkg5.repository

从上面显示的结果中可以看出,现在我们有了一个新的信息库,目前为空。如果我们只想拥有一个基于文件系统的可用信息库,到了这一步我们就可以停止了,但是对于本例,我们想拥有一个可通过 http:// 来访问的信息库。这里需要知道的是,尽管我们已创建了一个位置来存放我们的 IPS 信息库,但 IPS 信息库服务本身尚未启动。

创建初始库之后,我们需要设置一些不同的的属性来反映我们环境。我们使用 pkgrepo set 命令设置该软件包信息库的前缀:

# pkgrepo set -s /export/repository publisher/prefix=bazaar

然后我们对该 SMF 服务设置一些不同的属性:信息库本身的位置以及信息库位于的端口,此外我们还更改状态以确保在发布过程中我们能够写入该信息库。

# svccfg -s application/pkg/server setprop \  pkg/inst_root=/export/repository
# svccfg -s application/pkg/server setprop pkg/port=9001
# svccfg -s application/pkg/server setprop pkg/readyonly=false

现在我们需要用 svcadm 命令来启动该 SMF 服务:

# svcadm enable application/pkg/server
# svcs application/pkg/server
STATE         STIME    FMRI
online        2:16:21  svc:/application/pkg/server:default

现在我们有了一个正在运行的服务,我们可以使用 pkgrepo info 命令来获得有关该信息库的一些信息:

# pkgrepo info -s http://localhost:9001
PUBLISHER  PACKAGES  STATUS        UPDATED
bazaar     0         online        2011-10-10T13:16:21.193453Z

可以看到,该信息库目前尚不含任何软件包。现在我们可以继续下一步,将我们的软件包发布到这个信息库中。

第 4 步:将软件包发布到信息库中

现在我们到了这一步,可以将我们的软件包发布到信息库中。为此,我们使用 pkgsend publish 命令:

# pkgsend publish -s http://localhost:9001 -d proto_install bzr.p5m.3.res		
PUBLISHED
pkg://bazaar/developer/versioning/bzr-2.4.1,0.1:10111010T144709Z

可以看到,我们的软件包已成功发布。现在可以再次查看该信息库的状态:

# pkgrepo info -s http://localhost:9001
PUBLISHER   PACKAGES  STATUS        UPDATED
bazaar      1         online        2011-10-10T14:47:29.298624Z

可以看到,这个信息库中现在有了一个可用软件包。我们可以将这个信息库添加到我们配置中,然后通过这个信息库来安装一个软件包,如清单 8 所示。

清单 8:添加信息库并通过该信息库安装软件包
# pkg set-publisher -p http://localhost:9001
Added publisher(s): bazaar

# pkg info -r bzr
         Name: developer/versioning/bzr
       Summary: Bazaar is a source version control system that helps to track project changes over time
   Description: Bazaar (bzr) Source Version Control System
      Category: Development/Source Code Management
         State: Not installed
     Publisher: bazaar
       Version: 2.4.1
 Build Release: 0.1
        Branch: None
Packaging Date: October 10, 2011 02:47:09 PM 
          Size: 25.64 MB
          FMRI: pkg://bazaar/developer/versioning/bzr@2.4.1,0.1:20111010T144709Z

# pkg install bzr
           Packages to install:  1
       Create boot environment: No
Create backup boot environment: No

DOWNLOAD                                 PKGS     FILES    XFER (MB)
Completed                                 1/1 1617/1617      7.0/7.0

PHASE                                        ACTIONS
Install Phase                              1693/1693 

PHASE                                          ITEMS
Package State Update Phase                       1/1 
Image State Update Phase                         2/2

可以看到,该软件包能够成功安装,至此,我们应确保再次将该信息库设置为只读状态:

# svccfg -s application/pkg/server setprop pkg/readyonly=false
# svccfg refresh application/pkg/server
# svcadm restart application/pkg/server

总结

映像包管理系统是 Oracle Solaris 11 在软件管理方面的一个重大进步,它提供了一种通过网络发布和安装软件的十分先进的自动化方法,让许多不同的客户端能够通过网络发布和安装软件。在了解一些基本知识后,您就可以轻松创建自己的软件包,可以减少软件更新过程中的错误,并且可以为您的数据中心提供更加可靠和一致的体验。

更多信息

下面是其他一些资源:

修订版 1.0,2011 年 11 月 3 日