本章介绍如何为软件包创建可选信息文件和安装脚本。第 2 章中讨论了生成软件包的最低要求,而本章将讨论可以生成到软件包的附加功能。此附加功能基于您在计划如何设计软件包时所考虑的准则。有关更多信息,请参见生成软件包之前的注意事项。
以下是本章中概述信息的列表。
以下任务图描述了您可以生成到软件包的可选功能。
表 3–1 创建信息文件和安装脚本(任务图)
任务 |
说明 |
参考 |
---|---|---|
1. 创建信息文件 |
定义软件包相关性 利用软件包相关性的定义,可以指定您的软件包是否与以前的版本兼容,是否依赖于其他软件包,或者其他软件包是否依赖于您的软件包。 | |
编写版权信息 copyright 文件为您的软件应用程序提供法律保护。 | ||
在目标系统上保留额外空间 space 文件在目标系统上留出了空间块,使您可以在安装期间创建未在 pkgmap 文件中定义的文件。 | ||
2. 创建安装脚本 |
获取来自安装人员的信息 使用 request 脚本可以获取来自软件包安装人员的信息。 | |
收集安装所需的文件系统数据 使用 checkinstall 脚本可以执行目标系统的分析,并为安装设置正确的环境或完全停止安装。 | ||
编写过程脚本 使用过程脚本可在安装或删除过程的特定阶段提供自定义的安装说明。 | ||
编写类操作脚本 使用类操作脚本可指定在安装和删除软件包期间对特定软件包对象组执行的一组指令。 |
此节讨论可选软件包信息文件。使用这些文件,您可以定义软件包相关性,提供版权信息,以及在目标系统上保留额外空间。
您需要确定您的软件包是否依赖于其他软件包,以及是否有任何其他软件包依赖于您的软件包。可使用以下两个可选软件包信息文件定义软件包相关性和不兼容性:compver 和 depend。
通过提供 compver 文件,您可以指定与正在安装的软件包兼容的以前软件包版本。
通过提供 depend 文件,您可以定义与您的软件包相关联的三种相关性类型。这些相关性类型如下所示:
只有当无法提供 depend 文件的软件包依赖于您的软件包时,才应使用反向相关性类型。
depend 文件只解析最基本的相关性。如果您的软件包依赖于一个特定文件、其内容或者其行为,则 depend 文件不能提供足够的精确度。在这种情况下,应该使用 request 脚本或 checkinstall 脚本进行详细的相关性检查。checkinstall 脚本也是唯一能够完全停止软件包安装过程的脚本。
请确认 depend 和 compver 文件在 prototype 文件中有对应条目。文件类型应该是 i(表示软件包信息文件)。
有关更多信息,请参阅 depend(4) 和 compver(4) 手册页。
如果存在您软件包的以前版本,并且您需要指定新软件包与其兼容,请使用您喜爱的文本编辑器创建名为 compver 的文件。
列出与您的软件包兼容的版本。使用以下格式:
string string . . . |
对于每个兼容软件包,string 值与在 pkginfo 文件中指定给 VERSION 参数的值完全相同。
保存所做更改,然后退出编辑器。
如果您的软件包依赖于其他软件包的存在、其他软件包依赖于您的软件包的存在,或者您的软件包与另一个软件包不兼容,请使用您喜爱的文本编辑器创建名为 depend 的文件。
为每种相关性添加一个条目。使用以下格式:
type pkg-abbrev pkg-name (arch) version (arch) version . . . |
定义相关性类型。必须为以下字符之一: P(先决软件包)、I(不兼容软件包)或 R(反向相关性)。
指定软件包缩写,例如 SUNWcadap。
指定软件包全名,例如 Chip designers need CAD application software to design abc chips. Runs only on xyz hardware and is installed in the usr partition.
可选。指定运行软件包的硬件类型。例如,sparc 或 x86。如果您指定体系结构,必须使用括号作为分界符。
可选。指定 pkginfo 文件中为 VERSION 参数所赋的值。
有关更多信息,请参见 depend(4)。
保存所做更改,然后退出编辑器。
完成以下任务之一:
如果您要创建其他信息文件和安装脚本,请跳至下一任务:如何编写版权信息。
如果您未创建 prototype 文件,请完成如何使用 pkgproto 命令创建 prototype 文件过程。跳至步骤 7。
如果您已经创建了 prototype 文件,请编辑该文件,并为刚刚创建的每个文件添加一个条目。
生成您的软件包。
如果需要,请参见如何生成软件包。
在此示例中,有四个软件包版本: 1.0、1.1、2.0 和新软件包 3.0。新软件包与所有三个以前版本兼容。最新版本的 compver 文件可能如下所示:
release 3.0 release 2.0 version 1.1 1.0 |
这些条目不必按版本大小顺次排序。但是,它们应与每个软件包的 pkginfo 文件中 VERSION 参数的定义完全匹配。在此示例中,软件包设计人员对于前三个版本使用了不同的格式。
此示例假定样例软件包 SUNWcadap 要求 SUNWcsr 和 SUNWcsu 软件包已经安装在目标系统上。SUNWcadap 的 depend 文件如下所示:
P SUNWcsr Core Solaris, (Root) P SUNWcsu Core Solaris, (Usr) |
在生成软件包之后,请安装该软件包以确认它已正确安装并验证其完整性。第 4 章介绍了这些任务,并提供了有关如何将经过验证的软件包转换为分发介质的逐步说明。
您需要确定软件包是否应该在安装时显示版权信息。如果是,请创建 copyright 文件。
应该包括 copyright 文件,以便为您的软件应用程序提供法律保护。请与您公司的法律部门协商,以确定版权信息的准确措词。
要提供版权信息,必须创建名为 copyright 的文件。在安装期间,信息将完全按照文件中的形式显示(无格式设置)。有关更多信息,请参见 copyright(4) 手册页。
请确认 copyright 文件在 prototype 文件中有对应条目。文件类型应该是 i(表示软件包信息文件)。
使用您喜爱的文本编辑器创建名为 copyright 的文件。
根据您希望在安装软件包时显示的信息键入版权信息的文本。
保存所做更改,然后退出编辑器。
完成以下任务之一:
如果您要创建其他信息文件和安装脚本,请跳至下一任务:如何在目标系统上保留额外空间。
如果您未创建 prototype 文件,请完成如何使用 pkgproto 命令创建 prototype 文件过程。跳至步骤 5。
如果您已经创建了 prototype 文件,请编辑该文件,并为刚刚创建的信息文件添加一个条目。
生成您的软件包。
如果需要,请参见如何生成软件包。
Copyright (c) 2003 Company Name All Rights Reserved This product is protected by copyright and distributed under licenses restricting copying, distribution, and decompilation. |
在生成软件包之后,请安装该软件包以确认它已正确安装并验证其完整性。第 4 章介绍了这些任务,并提供了有关如何将经过验证的软件包转换为分发介质的逐步说明。
您需要确定软件包在目标系统上是否需要额外磁盘空间。此空间是除软件包对象所需空间之外的空间。如果是,请创建 space 信息文件。此任务不同于在安装时创建空文件和目录,如定义要在安装时创建的其他对象所述。
pkgadd 命令可根据 pkgmap 文件中的对象定义确保有安装软件包所需的足够磁盘空间。但是,除了 pkgmap 文件中定义的对象所需的磁盘空间之外,软件包还可能需要更多空间。例如,软件包可能在安装后创建一个文件,该文件中可能包含数据库、日志文件,或者某个不断占用更多磁盘空间的文件。为了保证为软件包保留了空间,您应该引入一个指定磁盘空间需求的 space 文件。pkgadd 命令可检查在 space 文件中指定的额外空间。有关更多信息,请参阅 space(4) 手册页。
请确认 space 文件在 prototype 文件中有对应条目。文件类型应该是 i(表示软件包信息文件)。
使用您喜爱的文本编辑器创建名为 space 的文件。
指定软件包所需的所有额外磁盘空间需求。使用以下格式:
pathname blocks inodes |
指定目录名,该目录可能是也可能不是文件系统的挂载点。
指定您希望保留的 512 字节块的数目。
指定所需的 inode 的数目。
有关更多信息,请参见 space(4) 手册页。
保存所做更改,然后退出编辑器。
完成以下任务之一。
如果您要创建安装脚本,请跳至下一任务:如何编写 request 脚本。
如果您未创建 prototype 文件,请完成如何使用 pkgproto 命令创建 prototype 文件中的过程。跳至步骤 5。
如果您已经创建了 prototype 文件,请编辑该文件,并为刚刚创建的信息文件添加一个条目。
生成您的软件包。
如果需要,请参见如何生成软件包。
以下 space 示例文件指定了将在目标系统的 /opt 目录中保留 1000 个 512 字节块和 1 个 inode。
/opt 1000 1 |
在生成软件包之后,请安装该软件包以确认它已正确安装并验证其完整性。第 4 章介绍了这些任务,并提供了有关如何将经过验证的软件包转换为分发介质的逐步说明。
此节讨论可选的软件包安装脚本。pkgadd 命令可自动执行使用软件包信息文件作为输入安装软件包时所需的所有操作。您不必提供任何软件包安装脚本。不过,如果您要为软件包创建自定义的安装过程,可以使用安装脚本来实现。安装脚本:
必须可由 Bourne shell (sh) 执行
必须包含 Bourne shell 命令和文本
不必包含 #!/bin/sh shell 标识符
不必是可执行文件
可使用四种类型的安装脚本执行自定义的操作:
request 脚本请求来自正在安装软件包的管理员的数据,以指定或重新定义环境变量。
checkinstall 脚本检查目标系统上是否有所需数据,可设置或修改软件包环境变量,以及确定安装是否继续。
checkinstall 脚本自 Solaris 2.5 及兼容发行版开始可用。
过程脚本指定在安装或删除软件包之前或之后将调用的过程。四个过程脚本是 preinstall 、postinstall、preremove 和 postremove。
类操作脚本定义了应该在安装或删除期间应用于某类文件的一个操作或一组操作。您可以定义自己的类。或者,可以使用四个标准类(sed、awk、build 和 preserve)之一。
您使用的脚本类型取决于安装过程中何时需要该脚本的操作。软件包安装后,pkgadd 命令执行以下步骤:
执行 request 脚本。
执行 checkinstall 脚本。
checkinstall 脚本收集文件系统数据,并可创建或修改环境变量定义来控制后续安装。有关软件包环境变量的更多信息,请参见软件包环境变量。
为要安装的每个类安装软件包对象。
这些文件的安装按逐个类进行,并相应执行类操作脚本。所处理的类列表及其安装顺序最初由 pkginfo 文件中的 CLASSES 参数定义。不过,request 脚本或 checkinstall 脚本可更改 CLASSES 参数的值。有关安装期间如何处理类的更多信息,请参见软件包安装期间如何处理类。
为每个类删除软件包对象
删除也按逐个类进行。删除脚本按照与安装时相反的顺序,根据 CLASSES 参数定义的序列进行处理。有关安装期间如何处理类的更多信息,请参见软件包安装期间如何处理类。
删除硬链接。
删除常规文件。
删除符号链接、设备和命名管道。
request 脚本不会在软件包删除时进行处理。但是,该脚本的输出会保留在已安装的软件包中,供删除脚本使用。request 脚本的输出是环境变量列表。
以下环境变量组对所有安装脚本可用。某些环境变量可由 request 脚本或 checkinstall 脚本修改。
除了必需的参数之外,request 脚本或 checkinstall 脚本可设置或修改 pkginfo 文件中的任何标准参数。pkginfo(4) 手册页中详细介绍了标准安装参数。
只能在 Solaris 2.5 发行版和兼容发行版及之后的发行版中修改 BASEDIR 参数。
您可定义自己的安装环境变量,方法是在 pkginfo 文件中为这些变量赋值。这种环境变量只能含字母数字字符,且首字母必须大写。这些环境变量中的任何一个都可由 request 脚本或 checkinstall 脚本更改。
request 脚本和 checkinstall 脚本都可以定义新的环境变量,方法是为其赋值并将其放在安装环境中。
下表列出了通过环境对所有安装脚本可用的环境变量。这些环境变量都不能由脚本修改。
环境变量 |
说明 |
---|---|
CLIENT_BASEDIR |
相对于目标系统的基目录。BASEDIR 是从安装系统(一般是服务器)引用特定软件包对象时使用的变量,而 CLIENT_BASEDIR 是用于包括客户机系统中放置的文件的路径。如果 BASEDIR 存在,则 CLIENT_BASEDIR 存在,而且在没有 PKG_INSTALL_ROOT 时与 BASEDIR 完全相同。 |
INST_DATADIR |
正在被读取的软件包所处的目录。如果正从磁带读取软件包,此变量将是一个临时目录位置,其中软件包被转换为目录格式。换句话说,假定软件包没有扩展名(例如 SUNWstuff.d),则当前软件包的 request 脚本将位于 $INST_DATADIR/$PKG/install。 |
PATH |
sh 在调用脚本时查找命令所用的搜索列表。 PATH 通常设置为 /sbin:/usr/sbin:/usr/bin:/usr/sadm/install/bin。 |
PKGINST |
正在安装的软件包的实例标识符。如果尚未安装软件包的其他实例,则该值是软件包缩写(例如 SUNWcadap)。否则,该值是带后缀的软件包缩写,例如 SUNWcadap.4。 |
PKGSAV |
可保存文件以供删除脚本使用的目录,或以前保存的文件所在的目录。仅在 Solaris 2.5 发行版和兼容发行版中可用。 |
PKG_CLIENT_OS |
安装软件包的客户机的操作系统。此变量的值是 Solaris。 |
PKG_CLIENT_VERSION |
x.y 格式的 Solaris 版本。 |
PKG_CLIENT_REVISION |
Solaris 内部版本修订版。 |
PKG_INSTALL_ROOT |
将软件包安装到的目标系统上的根文件系统。只有当带有 -R 选项调用 pkgadd 和 pkgrm 命令时,此变量才存在。这种有条件的存在有利于在过程脚本中以 ${PKG_INSTALL_ROOT}/somepath 格式使用该变量。 |
PKG_NO_UNIFIED |
当带有 -M 和 -R 选项调用 pkgadd 和 pkgrm 命令时设置的环境变量。此环境变量被传递给属于软件包环境的任何软件包安装脚本或软件包命令。 |
UPDATE |
该环境变量在大多数安装环境下不存在。如果此变量确实存在(值为 yes),则表明以下两种情况之一。一种情况是系统上已安装了名称、版本和体系结构均相同的软件包。另一种情况是,该软件包正在根据管理员的指令覆写已安装的同名软件包。在这些情况中,始终会使用原始基目录。 |
有关更多信息,请参见 pkginfo(1) 手册页、pkgparam(1) 手册页和第 4 章。
代码 |
含义 |
---|---|
0 |
脚本成功完成。 |
1 |
致命错误。安装过程在此时终止。 |
2 |
警告或可能的错误状态。安装会继续。在完成之时将显示一条警告消息。 |
3 |
pkgadd 命令完全停止。只有 checkinstall 脚本会返回此代码。 |
10 |
当完成所有选定软件包的安装时,应该重新引导系统。(此值应该添加到一位数退出代码之一。) |
20 |
在完成当前软件包的安装时应立即重新引导系统。(此值应该添加到一位数退出代码之一。) |
有关安装脚本返回的退出代码的示例,请参见第 5 章。
随您的软件包一起提供的所有安装脚本均应在 prototype 文件中有一个条目。文件类型应该是 i(表示软件包安装脚本)。
request 脚本是软件包可直接与安装该软件包的管理员进行交互的唯一途径。例如,该脚本可用于询问管理员是否安装软件包的可选组件。
request 脚本的输出必须是环境变量及其值的列表。此列表可以包括在 pkginfo 文件中创建的任一参数以及 CLASSES 和 BASEDIR 参数。该列表还可引入尚未在其他位置定义的环境变量。不过,适用情况下,pkginfo 文件应该始终提供缺省值。有关软件包环境变量的更多信息,请参见软件包环境变量。
当 request 脚本为环境变量赋值时,它必须使这些值对 pkgadd 命令和其他软件包脚本可用。
request 脚本不能修改任何文件。该脚本仅与正在安装软件包的管理员交互,并根据这种交互创建环境变量赋值的列表。request 脚本以非特权用户 install 身份运行(如果存在该用户)。否则,该脚本将以 root 身份执行。
pkgadd 命令使用一个用于命名 request 脚本的响应文件的参数调用该脚本。响应文件存储管理员的响应。
在软件包删除期间,request 脚本不会执行。不过,该脚本指定的环境变量将被保存,并在软件包删除期间可用。
应该将环境变量赋值添加到安装环境(通过将其写入到响应文件),供 pkgadd 命令和其他打包脚本使用(对于该脚本称为 $1)。
request 脚本不能修改除 CLASSES 和 BASEDIR 参数之外的系统环境变量和标准安装环境变量。该脚本可以修改您创建的其他任何环境变量。
request 脚本只能在 Solaris 2.5 和兼容发行版及之后的发行版中修改 BASEDIR 参数。
对于 request 脚本可以处理的每个环境变量,应该在 pkginfo 文件中为其指定一个缺省值。
输出列表的格式应该是 PARAM=value。例如:
CLASSES=none class1 |
管理员的终端被定义为 request 脚本的标准输入。
不要在 request 脚本中对目标系统执行任何特殊分析。根据该分析测试系统中是否存在特定二进制文件或特定行为以及设置环境变量都是有风险的。无法保证 request 脚本在安装时实际执行。安装软件包的管理员可能提供将插入环境变量的响应文件,而不会调用 request 脚本。如果 request 脚本还评估目标文件系统,该评估可能不会发生。为了进行特殊处理而对目标系统进行的分析最好留给 checkinstall 脚本完成。
如果将安装软件包的管理员可能使用 JumpStartTM 产品,那么不能以交互方式安装该软件包。此时您不应该为软件包提供 request 脚本,或者您需要与管理员沟通,希望他们应该在安装之前使用 pkgask 命令。pkgask 命令存储管理员对 request 脚本的响应。有关 pkgask 命令的更多信息,请参见 pkgask(1M) 手册页。
使用您喜爱的文本编辑器创建名为 request 的文件。
完成时保存所做更改并退出编辑器。
完成以下任务之一。
如果您要创建其他安装脚本,请跳至下一任务:如何收集文件系统数据。
如果您未创建 prototype 文件,请完成如何使用 pkgproto 命令创建 prototype 文件过程。跳至步骤 5。
如果您已经创建了 prototype 文件,请编辑该文件,并为刚刚创建的安装脚本添加一个条目。
生成您的软件包。
如果需要,请参见如何生成软件包。
当 request 脚本为环境变量赋值时,它必须使这些值对 pkgadd 命令可用。此示例显示了为以下四个环境变量执行该任务的 request 脚本片段: CLASSES、NCMPBIN、 EMACS 和 NCMPMAN。假定之前已使用该脚本在与管理员的交互会话中定义了这些变量。
# make environment variables available to installation # service and any other packaging script we might have cat >$1 <<! CLASSES=$CLASSES NCMPBIN=$NCMPBIN EMACS=$EMACS NCMPMAN=$NCMPMAN ! |
在生成软件包之后,请安装该软件包以确认它已正确安装并验证其完整性。第 4 章介绍了这些任务,并提供了有关如何将经过验证的软件包转换为分发介质的逐步说明。
checkinstall 脚本在可选的 request 脚本执行之后不久执行。checkinstall 脚本以 install 用户身份运行(如果存在这样的用户),或者以 nobody 用户身份运行。checkinstall 脚本没有更改文件系统数据的权限。不过,它可以根据所收集的信息创建或修改环境变量,以控制所发生的安装的过程。该脚本还能够完全停止安装过程。
checkinstall 脚本旨在对文件系统执行基本检查,这些检查无法使用 pkgadd 命令正常执行。例如,此脚本可用于提前检查以确定当前软件包中是否有任何文件将覆写现有文件,或者将管理常规软件相关性。depend 文件只管理软件包级别的相关性。
与 request 脚本不同,无论是否提供了响应文件,checkinstall 脚本都会执行。存在该脚本并不表明软件包是交互式软件包。可使用 checkinstall 脚本的情形包括 request 脚本被禁用或管理交互无法实现。
checkinstall 脚本自 Solaris 2.5 及兼容发行版开始可用。
checkinstall 脚本不能修改任何文件。此脚本只分析系统的状态,并根据该交互创建环境变量赋值的列表。要强制执行此限制,checkinstall 脚本以非特权用户 install 身份执行(如果存在该用户)。否则,此脚本将以非特权用户 nobody 身份执行。checkinstall 脚本没有超级用户权限。
pkgadd 命令使用一个用于命名 checkinstall 脚本的响应文件的参数调用该脚本。脚本的响应文件用于存储管理员的响应。
在软件包删除期间,checkinstall 脚本不会执行。不过,该脚本指定的环境变量将被保存,并在软件包删除期间可用。
应该将环境变量赋值添加到安装环境(通过将其写入到响应文件),供 pkgadd 命令和其他打包脚本使用(对于该脚本称为 $1)。
checkinstall 脚本不能修改除 CLASSES 和 BASEDIR 参数之外的系统环境变量和标准安装环境变量。该脚本可以修改您创建的其他任何环境变量。
对于 checkinstall 脚本可以处理的每个环境变量,应该在 pkginfo 文件中为其指定一个缺省值。
输出列表的格式应该是 PARAM=value。例如:
CLASSES=none class1 |
在 checkinstall 脚本执行期间不允许与管理员交互。所有管理员交互仅限于 request 脚本。
使用您喜爱的文本编辑器创建名为 checkinstall 的文件。
完成时保存所做更改并退出编辑器。
完成以下任务之一。
如果您要创建其他安装脚本,请跳至下一任务:如何编写过程脚本。
如果您未创建 prototype 文件,请完成如何使用 pkgproto 命令创建 prototype 文件过程。跳至步骤 5。
如果您已经创建了 prototype 文件,请编辑该文件,并为刚刚创建的安装脚本添加一个条目。
生成您的软件包。
如果需要,请参见如何生成软件包。
此 checkinstall 示例脚本将检查是否安装了 SUNWcadap 软件包所需的数据库软件。
# checkinstall script for SUNWcadap # # This confirms the existence of the required specU database # First find which database package has been installed. pkginfo -q SUNWspcdA # try the older one if [ $? -ne 0 ]; then pkginfo -q SUNWspcdB # now the latest if [ $? -ne 0 ]; then # oops echo "No database package can be found. Please install the" echo "SpecU database package and try this installation again." exit 3 # Suspend else DBBASE="`pkgparam SUNWsbcdB BASEDIR`/db" # new DB software fi else DBBASE="`pkgparam SUNWspcdA BASEDIR`/db" # old DB software fi # Now look for the database file we will need for this installation if [ $DBBASE/specUlatte ]; then exit 0 # all OK else echo "No database file can be found. Please create the database" echo "using your installed specU software and try this" echo "installation again." exit 3 # Suspend fi |
在生成软件包之后,请安装该软件包以确认它已正确安装并验证其完整性。第 4 章介绍了这些任务,并提供了有关如何将经过验证的软件包转换为分发介质的逐步说明。
过程脚本提供了将在软件包安装或删除期间的特定点执行的一组指令。根据这些指令将执行的时间,必须将四个过程脚本命名为预定义的名称之一。这些脚本不带参数执行。
在开始安装类之前运行。该脚本不应安装任何文件。
在安装了所有卷之后运行。
在开始删除类之前运行。该脚本不应删除任何文件。
在删除了所有类之后运行。
过程脚本以 uid=root 和 gid=other 执行。
每个脚本应该能够多次执行,因为该脚本针对软件包的每个卷都执行一次。这意味着使用同一输入执行脚本任意次数时,会产生与只执行脚本一次相同的结果。
用于安装不在 pkgmap 文件中的软件包对象的每个过程脚本必须使用 installf 命令通知软件包数据库它正在添加或修改路径名。完成所有添加或修改之后,应带有 -f 选项调用此命令。只有 postinstall 和 postremove 脚本可以按这种方式安装软件包对象。有关更多信息,请参见 installf(1M) 手册页和第 5 章。
在过程脚本执行期间不允许与管理员交互。所有管理员交互仅限于 request 脚本。
用于删除未从 pkgmap 文件安装的文件的每个过程脚本必须使用 removef 命令通知软件包数据库它正在删除路径名。完成删除之后,应带有 -f 选项调用此命令。有关详细信息和示例,请参见 removef(1M) 手册页和第 5 章。
必须使用 installf 和 removef 命令,因为过程脚本不会自动与 pkgmap 文件中列出的任何路径名相关联。
使用您喜爱的文本编辑器创建一个或多个过程脚本。
必须将过程脚本命名为预定义的名称之一: preinstall、postinstall、 preremove 或 postremove。
保存所做更改,然后退出编辑器。
完成以下任务之一。
如果您要创建类操作脚本,请跳至下一任务:如何编写类操作脚本。
如果您未创建 prototype 文件,请完成如何使用 pkgproto 命令创建 prototype 文件过程。跳至步骤 5。
如果您已经创建了 prototype 文件,请编辑该文件,并为刚刚创建的每个安装脚本添加一个条目。
生成您的软件包。
如果需要,请参见如何生成软件包。
在生成软件包之后,请安装该软件包以确认它已正确安装并验证其完整性。第 4 章介绍了这些任务,并提供了有关如何将经过验证的软件包转换为分发介质的逐步说明。
对象类允许在安装或删除时对一组软件包对象执行一系列操作。您需要在 prototype 文件中将对象指定给一个类。必须为所有软件包对象指定类,但是缺省情况下将为无需特殊操作的对象指定 none 类。
在 pkginfo 文件中定义的安装参数 CLASSES 是将安装的类的列表(包括 none 类)。
pkgmap 文件中定义的、属于未在 pkginfo 文件的此参数中列出的类的对象将不会被安装。
CLASSES 列表确定安装顺序。类 none 总是首先安装(如果有)而且最后删除。因为目录是所有其他文件系统对象的基础支持结构,因此应将所有目录指定给 none 类。通常使用 none 类是最安全的,虽然也可能有例外情况。此策略可确保在创建目录包含的对象之前创建目录。此外,不会在一个目录清空之前尝试删除该目录。
下面描述了安装类时发生的系统操作。操作针对软件包的每个卷都会重复执行一次(在该卷进行安装时)。
pkgadd 命令创建操作脚本处理的路径名列表。此列表的每一行都包含源路径名和目标路径名,由空格分隔。源路径名指明要安装的对象在安装卷上所处的位置。目标路径名指明应将该对象安装到的目标系统上的位置。列表的内容受以下条件限制:
如果没有针对某个特定类的安装提供类操作脚本,则生成的列表中的路径名将会从卷复制到相应的目标位置。
执行类操作脚本(如果存在)。
将会使用包含项目 1 中生成的列表的标准输入调用类操作脚本。如果该卷是软件包的最后一个卷,或者该类中不再有对象存在,则将使用单个参数 ENDOFCLASS 执行该脚本。
即使软件包中不存在该类的常规文件,也会使用一个空列表和 ENDOFCLASS 参数至少调用类操作脚本一次。
pkgadd 命令执行内容和属性审计,并创建硬链接。
成功执行项目 2 或 3 之后,pkgadd 命令将审计路径名列表的内容和属性信息。pkgadd 命令会自动创建与类关联的链接。将为生成的列表中的所有路径名更正检测到的属性不一致性。
对象是按逐个类删除的。对于软件包存在但未在 CLASSES 参数中列出的类将首先被删除(例如,使用 installf 命令安装的对象)。CLASSES 参数中列出的类按相反顺序删除。none 类总是最后删除。下面描述了删除类时发生的系统操作:
pkgrm 命令创建一个路径名列表。
pkgrm 命令创建属于指定类的已安装路径名的列表。其他软件包引用的路径名将会从列表中排除,除非其文件类型为 e。e 文件类型表示该文件应该在安装或删除时进行编辑。
如果正被删除的软件包在安装期间修改了任何类型为 e 的文件,该软件包应只删除它添加的行。请勿删除一个非空的可编辑文件。删除软件包添加的行。
如果不存在类操作脚本,将会删除路径名。
如果您的软件包没有类的删除类操作脚本,将会删除 pkgrm 命令生成的列表中的所有路径名。
文件类型为 e(可编辑)的文件不会指定给类和关联的类操作脚本。这些文件将在此时被删除,即使路径名与其他软件包共享。
如果类操作脚本存在,将会执行该脚本。
pkgrm 命令使用包含项目 1 中生成的列表的脚本标准输入来调用类操作脚本。
pkgrm 命令执行审计。
成功执行类操作脚本之后,pkgrm 命令会从软件包数据库删除对路径名的引用,除非路径名由其他软件包引用。
类操作脚本定义一组将在安装或删除软件包期间执行的操作。将会根据其类定义对一组路径名执行这些操作。有关类操作脚本的示例,请参见第 5 章。
类操作脚本根据它将处理的类以及这些操作是在软件包安装还是删除期间发生来命名。下表中显示了两种名称格式:
名称格式 |
说明 |
---|---|
i.class |
在软件包安装期间,对指定类中的路径名进行处理 |
r.class |
在软件包删除期间,对指定类中的路径名进行处理 |
例如,名为 manpage 的类的安装脚本名称将是 i.manpage,删除脚本名称将是 r.manpage。
这种文件名格式不适用于属于 sed、awk 或 build 系统类的文件。有关这些特殊类的更多信息,请参见特殊系统类。
将会为当前卷上指定类的所有文件执行脚本。
pkgadd 和 pkgrm 命令创建 pkgmap 文件中列出的属于该类的所有对象的列表。因此,类操作脚本只能处理在 pkgmap 中定义的属于特定类的路径名。
当最后一次执行类操作脚本时(即不再有属于该类的文件),将会使用关键字参数 ENDOFCLASS 执行类操作脚本一次。
在类操作脚本执行期间不允许与管理员交互。
如果一个软件包分布在多个卷上,则类操作脚本将针对至少包含属于类的一个文件的每个卷执行一次。因此,每个脚本必须能够多次执行。这意味着使用同一输入执行脚本任意次数时,必须产生与只执行脚本一次相同的结果。
当文件属于具有类操作脚本的类时,脚本必须安装该文件。pkgadd 命令不安装有类操作脚本的文件,虽然它确实执行安装验证。
类操作脚本绝不应添加、删除或修改不出现在 pkgadd 命令生成的列表中的路径名或系统属性。有关此列表的更多信息,请参见软件包安装期间如何处理类中的项目 1。
当脚本发现 ENDOFCLASS 参数时,会将后续处理操作(例如清除)放到脚本中。
所有管理员交互仅限于 request 脚本。请勿尝试使用类操作脚本从管理员获取信息。
提供一种使用 sed 指令在安装和删除软件包时编辑文件的方法。
提供一种使用 awk 指令在安装和删除软件包时编辑文件的方法。
提供一种使用 Bourne shell 命令动态构建或修改文件的方法。
提供一种保留不应被将来的软件包安装覆写的文件的方法。
提供与清单相关联的服务管理工具 (Service Management Facility, SMF) 服务的自动安装和卸载。manifest 类应用于软件包中的所有 SMF 清单。
如果一个软件包中的多个文件需要的特殊处理可完全通过 sed、awk 或 sh 命令定义,则使用系统类安装的速度比使用多个类及其对应类操作脚本更快。
sed 类提供了一种修改目标系统上现有对象的方法。如果存在属于 sed 类的文件,sed 类操作脚本将在安装时自动执行。sed 类操作脚本的名称应该与对其执行指令的文件的名称相同。
sed 类操作脚本按以下格式提供 sed 指令:
两个命令指定应执行指令的时间。位于 !install 命令之后的 sed 指令在软件包安装期间执行。位于 !remove 命令之后的 sed 指令在软件包删除期间执行。这些命令在文件中的使用顺序无关紧要。
有关 sed 指令的更多信息,请参见 sed(1) 手册页。有关 sed 类操作脚本的示例,请参见第 5 章。
awk 类提供了一种修改目标系统上现有对象的方法。这些修改将以 awk 类操作脚本中的 awk 指令实现。
如果存在属于 awk 类的文件,awk 类操作脚本将在安装时自动执行。这类文件包含如下格式的 awk 类脚本指令:
两个命令指定应执行指令的时间。位于 !install 命令之后的 awk 指令在软件包安装期间执行。位于 !remove 命令之后的指令在软件包删除期间执行。可按照任意顺序使用这些命令。
awk 类操作脚本的名称应该与对其执行指令的文件的名称相同。
待修改的文件用作 awk 命令的输入,该脚本的输出最终将替换原始对象。使用该语法可能不会将环境变量传递给 awk 命令。
有关 awk 指令的更多信息,请参见 awk(1) 手册页。
build 类可通过执行 Bourne shell 指令创建或修改软件包对象文件。这些指令作为软件包对象提供。如果该软件包对象属于 build 类,这些指令将会在安装时自动运行。
build 类操作脚本的名称应该与对其执行指令的文件的名称相同。该名称还必须可由 sh 命令执行。该脚本的输出将成为生成或修改后的文件新版本。如果脚本未生成任何输出,表明没有创建或修改该文件。因此,该脚本可以修改或创建文件本身。
例如,如果软件包提供了一个缺省文件 /etc/randomtable,并且目标系统上尚不存在该文件,则 prototype 文件条目可能如下所示:
e build /etc/randomtable ? ? ? |
软件包对象 /etc/randomtable 可能如下所示:
!install # randomtable builder if [ -f $PKG_INSTALL_ROOT/etc/randomtable ]; then echo "/etc/randomtable is already in place."; else echo "# /etc/randomtable" > $PKG_INSTALL_ROOT/etc/randomtable echo "1121554 # first random number" >> $PKG_INSTALL_ROOT/etc/randomtable fi !remove # randomtable deconstructor if [ -f $PKG_INSTALL_ROOT/etc/randomtable ]; then # the file can be removed if it's unchanged if [ egrep "first random number" $PKG_INSTALL_ROOT/etc/randomtable ]; then rm $PKG_INSTALL_ROOT/etc/randomtable; fi fi |
有关使用 build 类的另一个示例,请参见第 5 章。
preserve 类通过确定在安装软件包时是否要覆写现有文件来保留软件包对象文件。使用 preserve 类脚本时的两种可能情况是:
如果将安装的文件在目标目录中尚不存在,通常将安装该文件。
如果将安装的文件存在于目标目录中,将显示一条消息指出该文件已存在,此时将不会安装该文件。
preserve 脚本会将上述两种情况的结果都视为成功。只有在第二种情况中当文件无法复制到目标目录时才会失败。
自 Solaris 7 发行版开始,i.preserve 脚本以及该脚本的一个副本 i.CONFIG.prsv 以及其他类操作脚本都可在 /usr/sadm/install/scripts 目录中找到。
可修改该脚本以包括您希望保留的一个或多个文件名。
manifest 类会自动安装或卸载与 SMF 清单相关联的服务管理工具 (Service Management Facility, SMF) 服务。如果您不熟悉 SMF,请参见《系统管理指南:基本管理》中的第 16 章 “管理服务(概述)”,获取有关如何使用 SMF 来管理服务的信息。
软件包中的的所有服务清单都应由类 manifest 来标识。安装和移除服务清单的类操作脚本包含在软件包子系统中。调用 pkgadd(1M) 时,会导入此服务清单。调用 pkgrm(1M) 时,会删除服务清单中禁用的实例。还会删除清单中没有保留实例的所有服务。如果将 -R 选项提供给 pkgadd(1M) 或 pkgrm(1M),在系统下一次以备用引导路径重新引导时,才会完成这些服务清单操作。
以下软件包信息文件中的部分代码显示了 manifest 类的用法。
# packaging files i pkginfo i copyright i depend i preinstall i postinstall i i.manifest i r.manifest # # source locations relative to the prototype file # d none var 0755 root sys d none var/svc 0755 root sys d none var/svc/manifest 0755 root sys d none var/svc/manifest/network 0755 root sys d none var/svc/manifest/network/rpc 0755 root sys f manifest var/svc/manifest/network/rpc/smserver.xml 0444 root sys
在 prototype 文件中为软件包对象指定所需类名。
例如,将对象指定给 application 和 manpage 类将如下所示:
f manpage /usr/share/man/manl/myappl.1l f application /usr/bin/myappl |
在 pkginfo 文件中修改 CLASSES 参数,使其包含要在软件包中使用的类名。
例如,application 和 manpage 类的条目将如下所示:
CLASSES=manpage application none |
none 类始终最先安装,最后删除,无论它在 CLASSES 参数的定义中位置如何。
如果您要为属于 sed、awk 或 build 类的文件创建类操作脚本,请将包含软件包对象的目录设置为当前工作目录。
为属于 sed、awk 或 build 类的文件创建类操作脚本或软件包对象。
例如,名为 application 的类的安装脚本将命名为 i.application,而其删除脚本将命名为 r.application。
切记,当一个文件属于具有类操作脚本的类时,脚本必须安装该文件。pkgadd 命令不安装有类操作脚本的文件,虽然它确实执行安装验证。如果您定义了一个类但是没有提供类操作脚本,则对该类执行的唯一操作是将组件从安装介质复制到目标系统(缺省 pkgadd 行为)。
完成以下任务之一:
如果您未创建 prototype 文件,请完成如何使用 pkgproto 命令创建 prototype 文件过程,然后跳至步骤 7。
如果您已经创建了 prototype 文件,请编辑该文件,并为刚刚创建的每个安装脚本添加一个条目。
生成您的软件包。
如果需要,请参见如何生成软件包。
在生成软件包之后,请安装该软件包以确认它已正确安装并验证其完整性。第 4 章介绍了如何执行此任务,并提供了有关如何将经过验证的软件包转换为分发介质的逐步说明。
创建带签名软件包的过程涉及若干步骤,您需要领会一些新概念和术语。本节提供有关带签名的软件包、其术语以及证书管理的信息。此外还提供了有关如何创建带签名的软件包的逐步骤过程。
带签名的软件包是一种具有数字签名(下面定义的 PEM 编码 PKCS7 数字签名)的标准流格式软件包,该签名用于验证:
软件包是否来自对其进行签名的实体
软件包是否的确由该实体签名
软件包是否在该实体对其签名之后未进行修改
对软件包进行签名的实体是否为受信任实体
除了签名,带签名的软件包与不带签名的软件包完全相同。带签名的软件包与不带签名的软件包二进制兼容。因此,带签名的软件包可用于打包工具的旧版本。但是,在这种情况下签名会被忽略。
带签名的打包技术引入了一些新的术语和缩写,下表中介绍了这些内容。
在创建带签名的软件包之前,您必须有软件包密钥库。此软件包密钥库以对象形式包含证书。软件包密钥库中存在两种类型的对象:
受信任证书包含属于其他实体的一个公钥证书。之所以这样命名受信任证书,是因为密钥库属主相信证书中的公钥确实属于由证书的“主题”(所有者)指定的身份。证书的颁发者通过对证书进行签名来确保证书的真实性。
用户密钥用于存放敏感的加密密钥信息。加密密钥信息以受保护的格式存储,可防止进行未经授权的访问。用户密钥中既包含用户的私钥又包含与私钥相对应的公钥证书。
创建带签名的软件包时将使用用户密钥。
缺省情况下,软件包密钥库存储在 /var/sadm/security 目录中。缺省情况下各用户也可将自己的密钥库存储在 $HOME/.pkg/security 目录中。
在磁盘上,软件包密钥库可以采用两种格式: 多文件格式和单文件格式。多文件格式将其对象存储在多个文件中。每种类型的对象存储在单独的文件中。必须使用相同的口令短语对所有这些文件进行加密。单文件密钥库将其所有对象存储在文件系统上的单个文件中。
用于管理证书和软件包密钥库的主要实用程序是 pkgadm 命令。以下各小节介绍了用于管理软件包密钥库的更为常见的任务。
可以使用 pkgadm 命令将受信任证书添加到软件包密钥库。证书可以是 PEM 或 DER 格式。例如:
$ pkgadm addcert -t /tmp/mytrustedcert.pem |
在此示例中,名为 mytrustedcert.pem 的 PEM 格式证书会添加到软件包密钥库中。
pkgadm 命令不会生成用户证书或私钥。用户证书和私钥通常从证书颁发机构(例如 Verisign)获得。此外也可作为自行签名的证书在本地生成。一旦获取了私钥和证书,即可使用 pkgadm 命令将其导入到软件包密钥库中。例如:
pkgadm addcert -n myname -e /tmp/myprivkey.pem /tmp/mypubcert.pem |
在此示例中,使用了以下选项:
-n myname |
标识软件包密钥库中您希望处理的实体 (myname)。myname 实体成为对象存储时所用的别名。 |
-e /tmp/myprivkey.pem |
指定包含私钥的文件。在本例中,文件是 myprivkey.pem,位于 /tmp 目录。 |
/tmp/mypubcert.pem |
指定名为 mypubcert.pem 的 PEM 格式证书文件。 |
$ pkgadm listcert |
此命令显示软件包密钥库中的受信任证书和私钥。
pkgadm 命令可用于从软件包密钥库中删除受信任证书和私钥。
删除用户证书时,必须指定证书/密钥对的别名。例如:
$ pkgadm removecert -n myname |
证书的别名是证书的通用名称,可使用 pkgadm listcert 命令标识。例如,以下命令删除一个名为 Trusted CA Cert 1 的受信任证书:
$ pkgadm removecert -n "Trusted CA Cert 1" |
如果使用同一别名存储了受信任证书和用户证书,则指定 -n 选项时会将其同时删除。
创建带签名的软件包的过程涉及三个基本步骤:
创建不带签名的目录格式的软件包。
将签名证书、CA 证书和私钥导入到软件包密钥库。
使用步骤 2 的证书对步骤 1 中创建的软件包进行签名。
打包工具不会创建证书。必须从证书颁发机构(例如 Verisign 或 Thawte)获取这些证书。
以下过程介绍了创建带签名软件包的每个步骤。
创建不带签名的目录格式的软件包过程与创建常规软件包的过程相同,如本手册前面所述。以下过程介绍如何创建此不带签名的目录格式的软件包。如果您需要更多信息,请参阅前面关于生成软件包的各节。
pkginfo 文件应该包含以下基本内容:
PKG=SUNWfoo BASEDIR=/ NAME=My Test Package ARCH=sparc VERSION=1.0.0 CATEGORY=application |
prototye 文件应该包含以下基本内容:
$cat prototype i pkginfo d none usr 0755 root sys d none usr/bin 0755 root bin f none usr/bin/myapp=/tmp/myroot/usr/bin/myapp 0644 root bin |
列出对象源目录的内容。
例如:
$ ls -lR /tmp/myroot |
/tmp/myroot: total 16 drwxr-xr-x 3 abc other 177 Jun 2 16:19 usr /tmp/myroot/usr: total 16 drwxr-xr-x 2 abc other 179 Jun 2 16:19 bin /tmp/myroot/usr/bin: total 16 -rw------- 1 abc other 1024 Jun 2 16:19 myapp |
创建不带签名的软件包。
pkgmk -d `pwd` |
输出可能如下所示:
## Building pkgmap from package prototype file. ## Processing pkginfo file. WARNING: parameter <PSTAMP> set to "syrinx20030605115507" WARNING: parameter <CLASSES> set to "none" ## Attempting to volumize 3 entries in pkgmap. part 1 -- 84 blocks, 7 entries ## Packaging one part. /tmp/SUNWfoo/pkgmap /tmp/SUNWfoo/pkginfo /tmp/SUNWfoo/reloc/usr/bin/myapp ## Validating control scripts. ## Packaging complete. |
软件包现在会存在于当前目录中。
要导入的证书和私钥必须以 PEM 或 DER 编码的 X.509 证书和私钥形式存在。此外,必须先将任何将您的签名证书与证书颁发机构证书相关联的中间或“链”证书导入到软件包密钥库中,然后才能对软件包进行签名。
各证书颁发机构可能会颁发不同格式的证书。要将证书和私钥从 PKCS12 文件提取到 PEM 编码的 X.509 文件(适于导入到软件包密钥库),请使用免费软件转换实用程序,例如 OpenSSL。
如果您的私钥进行了加密(通常应该如此),系统将提示您输入口令短语。此外,还将提示您输入口令以保护生成的软件包密钥库。您可以选择不提供任何口令,但是这样做会导致软件包密钥库不会加密。
以下过程介绍了证书格式正确时,如何使用 pkgadm 命令导入证书。
导入在 PEM 或 DER 编码的 X.509 证书文件中找到的所有证书颁发机构证书。
例如,要导入在 ca.pem 文件中找到的所有证书颁发机构证书,应键入以下内容:
$ pkgadm addcert -k ~/mykeystore -ty ca.pem |
输出可能如下所示:
Trusting certificate <VeriSign Class 1 CA Individual \ Subscriber-Persona Not Validated> Trusting certificate </C=US/O=VeriSign, Inc./OU=Class 1 Public \ Primary Certification Authority Type a Keystore protection Password. Press ENTER for no protection password (not recommended): For Verification: Type a Keystore protection Password. Press ENTER for no protection password (not recommended): Certificate(s) from <ca.pem> are now trusted |
为了将您的签名密钥导入到软件包密钥库,必须提供别名,供以后签名软件包时使用。如果您要从软件包密钥库中删除密钥,也可能会使用该别名。
例如,要从 sign.pem 文件中导入您的签名密钥,应键入以下内容:
$ pkgadm addcert -k ~/mykeystore -n mycert sign.pem |
输出可能如下所示:
Enter PEM passphrase: Enter Keystore Password: Successfully added Certificate <sign.pem> with alias <mycert> |
检验证书是否在软件包密钥库中。
例如,要在密钥库中查看在上一步骤中创建的证书,应键入以下内容:
$ pkgadm listcert -k ~/mykeystore |
一旦将证书导入到软件包密钥库,即可对软件包签名。实际的软件包签名工作是使用 pkgtrans 命令完成的。
使用 pkgtrans 命令对软件包签名。提供不带签名的软件包的位置,并提供用于签名软件包的密钥别名。
例如,使用前面过程中的示例,您应键入以下内容创建名为 SUNWfoo.signed 的带签名软件包:
$ pkgtrans -g -k ~/mykeystore -n mycert . ./SUNWfoo.signed SUNWfoo |
此命令的输出可能如下所示:
Retrieving signing certificates from keystore </home/user/mykeystore> Enter keystore password: Generating digital signature for signer <Test User> Transferring <SUNWfoot> package instance |
带签名的软件包会在 SUNWfoo.signed 文件中创建且采用软件包流格式。此带签名的软件包适合于通过 pkgadd 命令和 URL 复制到 Web 站点并进行安装。