跳过导航链接 | |
退出打印视图 | |
应用程序包开发者指南 Oracle Solaris 10 1/13 Information Library (简体中文) |
System V 打包背后的原始概念假定每个系统有一个体系结构。服务器的概念在设计中没有发挥作用。当然,现在一台服务器可以支持多个体系结构,这意味着在一台服务器上可能存在同一个软件的多个副本,每个副本适用于不同的体系结构。虽然 Oracle Solaris 软件包被隔离到建议的文件系统边界内(例如 / 和 /usr),在服务器和每个客户机上均有产品数据库,但并不是所有安装都必须支持此隔离。某些实现支持完全不同的结构,并且隐含一个公共产品数据库。尽管将客户机指向不同的版本是一项非常简单的工作,但将 System V 软件包实际安装到不同的基目录可能给管理员带来困难。
当您设计软件包时,还应该考虑管理员用来引入新的软件版本的常用方法。管理员通常寻求并行安装和测试最新版本与当前安装的版本。该过程涉及到将新版本安装到与当前版本不同的基目录,以及将一些非关键性客户机定向到新版本以便进行测试。随着信心不断增加,管理员将越来越多的客户机重定向到新版本。最终,管理员仅仅为了应对紧急情况而保留旧版本,并最终将其删除。
这意味着以现代异构系统为目标的软件包必须支持真正的重定位:即管理员可以将这些软件包放置到文件系统中的任意合理位置,而仍然可以使用其完整的功能。Solaris 2.5 和兼容发行版提供了许多有用的工具,允许将多个体系结构和版本完全安装到同一个系统中。Solaris 2.4 和兼容发行版也支持真正的重定位,但完成该任务的方法不是很明显。
System V ABI 表明,可重定位软件包背后的原始意图是使安装软件包对于管理员而言更加便利。现在,对可重定位软件包的需求更进了一大步。便利与否不是唯一的问题,更有可能发生的问题是在安装期间,一个活动的软件产品已经安装在缺省目录中。不能处理这种情况的软件包会覆写现有产品,或者安装失败。然而,可处理多个体系结构和多个版本的软件包可以顺利安装,并且为管理员提供与现有管理传统完全兼容的大量选项。
在某些方面,多个体系结构的问题和多个版本的问题是同一问题。必须可以并行安装现有软件包的变体与其他变体,并且能够在不影响功能的情况下将客户机或导出的文件系统的独立使用者定向到其中任一变体。尽管 Sun 已经制定了在服务器上处理多个体系结构的方法,但管理员可以不遵守这些推荐方法。所有软件包都必须能够符合管理员的合理安装期望。
此示例演示一个传统的可重定位软件包内容。该软件包将位于 /opt/SUNWstuf 中,其 pkginfo 文件和 pkgmap 文件可能如下所示。
# pkginfo file PKG=SUNWstuf NAME=software stuff ARCH=sparc VERSION=1.0.0,REV=1.0.5 CATEGORY=application DESC=a set of utilities that do stuff BASEDIR=/opt VENDOR=Sun Microsystems, Inc. HOTLINE=Please contact your local service provider EMAIL= MAXINST=1000 CLASSES=none PSTAMP=hubert990707141632
: 1 1758 1 d none SUNWstuf 0775 root bin 1 d none SUNWstuf/EZstuf 0775 root bin 1 f none SUNWstuf/EZstuf/dirdel 0555 bin bin 40 773 751310229 1 f none SUNWstuf/EZstuf/usrdel 0555 bin bin 40 773 751310229 1 f none SUNWstuf/EZstuf/filedel 0555 bin bin 40 773 751310229 1 d none SUNWstuf/HRDstuf 0775 root bin 1 f none SUNWstuf/HRDstuf/mksmart 0555 bin bin 40 773 751310229 1 f none SUNWstuf/HRDstuf/mktall 0555 bin bin 40 773 751310229 1 f none SUNWstuf/HRDstuf/mkcute 0555 bin bin 40 773 751310229 1 f none SUNWstuf/HRDstuf/mkeasy 0555 bin bin 40 773 751310229 1 i pkginfo 348 28411 760740163 1 i postinstall 323 26475 751309908 1 i postremove 402 33179 751309945 1 i preinstall 321 26254 751310019 1 i preremove 320 26114 751309865
因为每个软件包对象都会安装到 pkginfo 文件中的 BASEDIR 参数所定义的基目录,所以这称为传统方法。例如,pkgmap 文件中的第一个对象被安装到目录 /opt/SUNWstuf。
绝对软件包是安装到特定根 (/) 文件系统的软件包。这些软件包难以从多个版本和体系结构的角度进行处理。通常,所有软件包都应该是可重定位的。然而,有非常充足的理由在可重定位软件包中包括绝对元素。
如果 SUNWstuf 软件包是绝对软件包,则不应该在 pkginfo 文件中定义 BASEDIR 参数,而 pkgmap 文件将如下所示。
: 1 1758 1 d none /opt ? ? ? 1 d none /opt/SUNWstuf 0775 root bin 1 d none /opt/SUNWstuf/EZstuf 0775 root bin 1 f none /opt/SUNWstuf/EZstuf/dirdel 0555 bin bin 40 773 751310229 1 f none /opt/SUNWstuf/EZstuf/usrdel 0555 bin bin 40 773 751310229 1 f none /opt/SUNWstuf/EZstuf/filedel 0555 bin bin 40 773 751310229 1 d none /opt/SUNWstuf/HRDstuf 0775 root bin 1 f none /opt/SUNWstuf/HRDstuf/mksmart 0555 bin bin 40 773 751310229 1 f none /opt/SUNWstuf/HRDstuf/mktall 0555 bin bin 40 773 751310229 1 f none /opt/SUNWstuf/HRDstuf/mkcute 0555 bin bin 40 773 751310229 1 f none /opt/SUNWstuf/HRDstuf/mkeasy 0555 bin bin 40 773 751310229 1 i pkginfo 348 28411 760740163 1 i postinstall 323 26475 751309908 1 i postremove 402 33179 751309945 1 i preinstall 321 26254 751310019 1 i preremove 320 26114 751309865
在此示例中,如果管理员在安装期间指定了一个备用基目录,pkgadd 命令将忽略该目录。此软件包总是安装到目标系统的 /opt/SUNWstuf。
pkgadd 命令的 -R 参数按预期方式工作。例如,
pkgadd -d . -R /export/opt/client3 SUNWstuf
将对象安装在 /export/opt/client3/opt/SUNWstuf 中;但这是此软件包最接近可重定位软件包之处。
请注意,在 pkgmap 文件中,对 /opt 目录使用了问号 (?)。这表明不应该更改现有属性。这并不意味着“使用缺省属性创建目录”,尽管在某些情况下可能发生这种情况。特定于新软件包的任何目录都必须明确指定所有属性。
任何包含可重定位对象的软件包称为可重定位软件包。这可能令人产生误解,因为可重定位软件包可能在其 pkgmap 文件中包含绝对路径。在 pkgmap 文件中使用根 (/) 条目可以增强软件包的可重定位特性。同时具有可重定位条目和根条目的软件包称为复合软件包。
假定 SUNWstuf 软件包中的一个对象是在运行级别 2 执行的启动脚本。文件 /etc/rc2.d/S70dostuf 需要作为该软件包的一部分安装,但不能将其放置到基目录中。假定可重定位软件包是唯一的解决方案,pkginfo 和 pkgmap 可能如下所示。
# pkginfo file PKG=SUNWstuf NAME=software stuff ARCH=sparc VERSION=1.0.0,REV=1.0.5 CATEGORY=application DESC=a set of utilities that do stuff BASEDIR=/ VENDOR=Sun Microsystems, Inc. HOTLINE=Please contact your local service provider EMAIL= MAXINST=1000 CLASSES=none PSTAMP=hubert990707141632
: 1 1758 1 d none opt/SUNWstuf/EZstuf 0775 root bin 1 f none opt/SUNWstuf/EZstuf/dirdel 0555 bin bin 40 773 751310229 1 f none opt/SUNWstuf/EZstuf/usrdel 0555 bin bin 40 773 751310229 1 f none opt/SUNWstuf/EZstuf/filedel 0555 bin bin 40 773 751310229 1 d none opt/SUNWstuf/HRDstuf 0775 root bin 1 f none opt/SUNWstuf/HRDstuf/mksmart 0555 bin bin 40 773 751310229 1 f none opt/SUNWstuf/HRDstuf/mktall 0555 bin bin 40 773 751310229 1 f none opt/SUNWstuf/HRDstuf/mkcute 0555 bin bin 40 773 751310229 1 f none opt/SUNWstuf/HRDstuf/mkeasy 0555 bin bin 40 773 751310229 1 d none etc ? ? ? 1 d none etc/rc2.d ? ? ? 1 f none etc/rc2.d/S70dostuf 0744 root sys 450 223443 1 i pkginfo 348 28411 760740163 1 i postinstall 323 26475 751309908 1 i postremove 402 33179 751309945 1 i preinstall 321 26254 751310019 1 i preremove 320 26114 751309865
此方法和绝对软件包方法之间没有太大差异。实际上,作为绝对软件包使用会更好,因为如果管理员为此软件包提供备用基目录,它将无法正常工作!
实际上,此软件包中只有一个文件需要相对于根保持固定,其余文件都可以任意移动。本节其余部分将讨论如何使用复合软件包解决此问题。
本节描述的方法不适用于所有软件包,但是,在将软件包安装到异构环境期间该方法确实能够改善性能。该方法很少应用于作为 Oracle Solaris OS 的一部分而提供的软件包(捆绑的软件包);不过,非捆绑软件包可以采用非传统打包。
鼓励采用可重定位软件包的原因是支持以下需求:
在添加或删除软件包时,已安装的软件产品的现有理想行为将保持不变。
非随附软件包应该驻留在 /opt 下,以便保证新软件包不会干扰现有产品。
根据软件包对象的绝大部分的安装位置来建立基目录。
如果某个软件包对象安装到基目录以外的其他公共目录(例如 /etc),请在 prototype 文件中将其指定为绝对路径名。
换句话说,因为“可重定位”意味着该对象可以安装到任何位置而仍然能够正常工作,所以不能将 init 在引导时运行的任何启动脚本视为可重定位的!尽管在提供的软件包中将 /etc/passwd 指定为相对路径没有任何问题,但它只有一个安装位置。
如果您要构建一个复合软件包,绝对路径必须以不干扰已安装的现有软件的方式工作。可以完全包含在 /opt 中的软件包可避免此问题,因为不存在形成阻碍的现有文件。当 /etc 中的一个文件包括在软件包中时,您必须确保绝对路径名的行为方式与相对路径名的预期行为方式相同。请考虑下面两个示例。
将一个条目添加到表中,或者对象是可能要由其他程序或软件包修改的一个新表。
将该对象定义为文件类型 e 并定义为属于 build、awk 或 sed 类。执行此任务的脚本必须可与添加自身一样高效地删除自身。
需要将一个条目添加到 /etc/vfstab 中,以便支持新的固态硬盘。
pkgmap 文件中的条目可能是
1 e sed /etc/vfstab ? ? ?
request 脚本询问操作员 /etc/vfstab 是否应该由软件包修改。如果操作员回答“否”,那么 request 脚本将列出有关如何手动完成该工作的说明,并将执行:
echo "CLASSES=none" >> $1
如果操作员回答“是”,那么它将执行:
echo "CLASSES=none sed" >> $1
该命令将激活将要执行必要修改的类操作脚本。sed 类意味着软件包文件 /etc/vfstab 是一个 sed 程序,该程序包含目标系统上同名文件的安装和删除操作。
对象是一个不太可能在以后进行编辑的全新文件,或者它将替换另一个软件包拥有的某个文件。
将软件包对象定义为文件类型 f,并使用能够撤消更改的类操作脚本来安装该对象。
/etc 中需要一个全新的文件来提供必要的信息,以便支持名为 /etc/shdisk.conf 的固态硬盘。pkgmap 文件中的条目可能如下所示:
. . . 1 f newetc /etc/shdisk.conf . . .
类操作脚本 i.newetc 负责安装此文件以及需要安装到 /etc 的所有其他文件。该脚本将执行检查以确保该位置不存在其他文件。如果不存在其他文件,它只是将新文件复制到该位置。如果该位置已经有文件,该脚本将在安装新文件之前备份该文件。脚本 r.newetc 可根据需要删除这些文件并恢复原始文件。以下是安装脚本的关键片段。
# i.newetc while read src dst; do if [ -f $dst ]; then dstfile=`basename $dst` cp $dst $PKGSAV/$dstfile fi cp $src $dst done if [ "${1}" = "ENDOFCLASS" ]; then cd $PKGSAV tar cf SAVE.newetc . $INST_DATADIR/$PKG/install/squish SAVE.newetc fi
请注意,此脚本使用 PKGSAV 环境变量存储将被替换的文件的备份。当参数 ENDOFCLASS 传递给该脚本时,即 pkgadd 命令通知该脚本这些条目是此类中的最后一批条目,此时,该脚本将归档并压缩使用专用压缩程序(存储在软件包的安装目录中)保存的文件。
尽管在软件包更新期间使用 PKGSAV 环境变量不可靠,但如果软件包未更新(例如,未通过修补程序更新),则备份文件将是安全的。下面的删除脚本包含的代码用于处理另一个问题:pkgrm 命令的旧版本不向脚本传递 PKGSAV 环境变量的正确路径。
删除脚本可能如下所示。
# r.newetc # make sure we have the correct PKGSAV if [ -d $PKG_INSTALL_ROOT$PKGSAV ]; then PKGSAV="$PKG_INSTALL_ROOT$PKGSAV" fi # find the unsquish program UNSQUISH_CMD=`dirname $0`/unsquish while read file; do rm $file done if [ "${1}" = ENDOFCLASS ]; then if [ -f $PKGSAV/SAVE.newetc.sq ]; then $UNSQUISH_CMD $PKGSAV/SAVE.newetc fi if [ -f $PKGSAV/SAVE.newetc ]; then targetdir=dirname $file # get the right directory cd $targetdir tar xf $PKGSAV/SAVE.newetc rm $PKGSAV/SAVE.newetc fi fi
此脚本使用软件包数据库的安装目录中的专用卸载算法 (unsquish)。这由 pkgadd 命令在安装时自动完成。所有未被 pkgadd 命令特别识别为仅限于安装的脚本都将保留在此目录中,供 pkgrm 命令使用。您无法肯定该目录位于何处,但您可以确定该目录是无层次的,并且包含该软件包的所有适当信息文件和安装脚本。此脚本根据以下事实查找该目录:即类操作脚本肯定从包含 unsquish 程序的目录中执行。
另外请注意,此脚本并不只是假定目标目录是 /etc。该目录实际上可能是 /export/root/client2/etc。可以用以下两种方式之一构建正确的目录。
使用 ${PKG_INSTALL_ROOT}/etc 构造,或者,
获取由 pkgadd 命令传递的文件目录名(就是此脚本的作用)。
通过对软件包中的每个绝对对象使用此方法,您可以确信当前的理想行为保持不变或者至少是可恢复的。
以下是复合软件包的 pkginfo 和 pkgmap 文件的示例。
PKG=SUNWstuf NAME=software stuff ARCH=sparc VERSION=1.0.0,REV=1.0.5 CATEGORY=application DESC=a set of utilities that do stuff BASEDIR=/opt VENDOR=Sun Microsystems, Inc. HOTLINE=Please contact your local service provider EMAIL= MAXINST=1000 CLASSES=none daemon PSTAMP=hubert990707141632
: 1 1758 1 d none SUNWstuf/EZstuf 0775 root bin 1 f none SUNWstuf/EZstuf/dirdel 0555 bin bin 40 773 751310229 1 f none SUNWstuf/EZstuf/usrdel 0555 bin bin 40 773 751310229 1 f none SUNWstuf/EZstuf/filedel 0555 bin bin 40 773 751310229 1 d none SUNWstuf/HRDstuf 0775 root bin 1 f none SUNWstuf/HRDstuf/mksmart 0555 bin bin 40 773 751310229 1 f none SUNWstuf/HRDstuf/mktall 0555 bin bin 40 773 751310229 1 f none SUNWstuf/HRDstuf/mkcute 0555 bin bin 40 773 751310229 1 f none SUNWstuf/HRDstuf/mkeasy 0555 bin bin 40 773 751310229 1 d none /etc ? ? ? 1 d none /etc/rc2.d ? ? ? 1 e daemon /etc/rc2.d/S70dostuf 0744 root sys 450 223443 1 i i.daemon 509 39560 752978103 1 i pkginfo 348 28411 760740163 1 i postinstall 323 26475 751309908 1 i postremove 402 33179 751309945 1 i preinstall 321 26254 751310019 1 i preremove 320 26114 751309865 1 i r.daemon 320 24573 742152591
尽管 S70dostuf 属于 daemon 类,但指向它的目录(这些目录在安装时已经就位)属于 none 类。即使这些目录对于此软件包是唯一的,您也应该将它们保留在 none 类中。这样做的原因是,这些目录需要首先被创建而且最后删除,而对于 none 类而言始终如此。pkgadd 命令创建这些目录;它们不是从软件包复制的,而且不会传递给将创建的类操作脚本。相反,这些目录由 pkgadd 命令在调用安装类操作脚本之前创建,而 pkgrm 命令会在删除类操作脚本完成之后删除这些目录。
这意味着,如果一个特殊类中的目录包含 none 类中的对象,pkgrm 命令在尝试删除该目录时会失败,因为该目录无法及时变成空目录。如果类 none 的一个对象将插入到某个特殊类的目录中,该目录不会及时出现以便接受该对象。pkgadd 命令将在对象安装期间动态创建该目录,并且可能无法在最终看到 pkgmap 定义时同步该目录的属性。
注 - 在将目录指定给类时,请一定记住创建和删除顺序。