SPEC脚本及RPM打包
2014-01-22 11:50
411 查看
1. Makefile示例
2. package/package.sh
3. package/confmanage.spec
4. apache配置
--------------------------------------------------------------------------------------------------------------------------
升级RPM过程调研[转载]
当在用户机器上安装或卸载程序时,能够执行命令将是很有用的。例如,可能需要编辑一个系统配置文件以启用新的服务,或者需要定义一个新用户以拥有正在安装的程序的所有权。
安装和卸载脚本的工作原理看起来很简单,但它们工作原理中的一些意外可能会引起大问题。这里是一些基本信息,可以将下列四节中的任意一个添加到.spec 文件,它列出了在包安装期间各个点上运行的shell 脚本:
%pre 在安装包之前运行
%post 在安装包之后运行
%preun 在卸载包之前运行
%postun 在卸载包之后运行
尤其要注意%install与这些节之间的差异。构建RPM 时,%install 在开发机器上运行;它应该将产品安装在开发机器上或安装到一个构建根目录中。另一方面,这些节指定当用户正在安装或卸载RPM包时将在用户的机器上运行什么。
一种好的技术是使用%pre脚本来检查安装前提条件,它们比RPM可以直接支持的更复杂。 如果不符合前提条件,那么脚本以非零状态退出,而且 RPM 不会继续安装。另外请注意,我们必须小心地使用卸载脚本来撤销安装脚本。
然而实际上没有那么简单:升级使每件事情都变得复杂,现在,让我们着手升级。如果用户只安装和删除自己的包,那么前面的指令将正常工作;但在升级期间,它们会完全失效。以下是 RPM 如何执行升级:
运行新包的 %pre
安装新文件
运行新包的 %post
运行旧包的 %preun
删除新文件未覆盖的所有旧文件
运行旧包的 %postun
如果我们使用5.3.2系列中现有SPEC文件中的脚本来升级,那么RPM最后将运行 %postun 脚本,它将除去我们在安装脚本中所做的所有工作。
rpm为了解决此问题,在其英文文档中提到了可以向脚本来传递一个参数$1,这个参数传递的过程是隐藏的,你只需在%pre,%post,%preun,%postun中使用$1即可($1在shell中就是第一个参数的意思)。这个参数的含义是在执行完此次操作后系统中此软件包的剩余数量是多少,就目前我的理解应该只有0,1,2三种可能。
1.在执行rpm –ivh的安装过程中,如果有同类包存在,则会报错提示无法安装,存在相同的文件。如果没有同类包存在则会执行安装动作,过程如下:
运行新包的%pre $1=1
安装新文件
运行新包的%post $1=1
2.在执行rpm –U的升级过程中,如果没有同类低级包存在,则过程和传递的参数与安装时完全相同,如果有同类低级包存在则会执行升级操作,过程如下:
运行新包的%pre $1=2
安装新文件
运行新包的%post $1=2
运行旧包的%preun $1=1
删除新文件未覆盖的任何旧文件
运行旧包的%postun $1=1
3.在执行rpm –e的删除过程如下:
运行旧包的%preun $1=0
删除文件
运行旧包的%postun $1=0
因此我们可以用传递的参数来判断rpm究竟在进行什么工作,来在脚本内部通过$1进行判断来决定进行什么动作。例如在参数为0的时候才真的执行卸载所要进行的动作。
另外,在升级的时候,RPM还有一项重要的工作要做,这就是妥善处理配置文件(CONFIG FILE)。若直接采用安装方式,则用户已配置好的配置文件就会被覆盖,不符合用户要求。
RPM对某个配置文件,通过比较三种不同的MD5检查和(checksum)来决定如何处理它。这三种不同的MD5检查和是:
1. 原检查和。它是旧版本软件包安装时配置文件的MD5检查和。
2. 当前检查和。它是升级时旧版本配置文件的MD5检查和。
3. 新检查和。它是新版本软件包中配置文件的MD5检查和。
RPM针对以下几种情况分别处理:
1. 当原检查和=X,当前检查和=X,新检查和=X时:
这表明配置文件未曾修改过。此时,RPM会将新的配置文件覆盖掉原文件,而不是对原文件不作处理,原因在于: 虽然文件名和文件内容都没有变化,但文件别的方面的属性(如文件的属主,属组,权限等)却可能改变,所以有必要覆盖一下。
2. 当原检查和=X,当前检查和=X,新检查和=Y时:
这表明原配置文件没有改动过,但是它与新软件包中的配置文件却有所不同。这种情况下,RPM将用新文件覆盖掉旧文件,并且旧文件不作保存(因为它不曾改动过,没有必要保存)。
3. 当原检查和=X,当前检查和=Y,新检查和=X时:
这表明新文件与旧文件内容相同,但当前文件已经作过修改,这些修改对于新版本来说应该是合法的,可以使用的。因此,RPM对当前文件予以保留。
4. 当原检查和=X,当前检查和=Y,新检查和=Y时:
这表明原文件经过修改,现在已与新文件相同,这或许是用户用来修补安全上的漏洞,新版本也作了同样的修改。这种情况下,RPM将新文件覆盖当前文件,避免文件属性方面的不同。
5. 当原检查和=X,当前检查和=Y,新检查和=Z时:
这表明用户已修改了原文件,并且当前内容与新文件内容不同。这种情况下,RPM无法保证新版本软件能正常使用当前的配置文件,所以采用了一个比较明智的办 法,既能保护用户的配置数据,又能保证新版本软件正常。这种作法就是将当前文件换名保存(给原文件名加个.rpmsave的后缀,如原文件名为ABC,则 换名后为ABC.rpmsave),同时安装新文件,并给出警告信息。
6. 当没有原检查和时:
此种情况下,当前检查和与新检查和已无关紧要,这表明没有安装过此配置文件。因为没有安装过此配置文件,所以RPM无法判断当前文件是否被用户修改过。这种情况下,RPM会将当前文件换名保存(原文件名后缀不是加个.rpmsave,而是.rpmorig),同时安装新文件,并给出警告信息。
因此在%files中可以用%config字段将配置文件标识出来,这样在升级的过程中配置文件将被按照上面所描述的方法处理。
%config 文件路径的形式来添加。
all: dist .PHONY: clean clean: distclean dep: dist: distclean dep sh package/package.sh rpmbuild -bb package/confmanage.spec cp /usr/src/redhat/RPMS/i386/confmanage*.i386.rpm dist rm /usr/src/redhat/RPMS/i386/confmanage*.i386.rpm md5sum dist/*.rpm > dist/checksum.txt distclean: rm -f dist/*.rpm dist/*.txt
2. package/package.sh
#!/bin/sh PackageDir="/tmp/BUILD/confmanage" InstallDir="${PackageDir}/usr/local/confmanage" #创建打包目录 rm -fr $PackageDir >/dev/null 2>&1 mkdir -m 755 -p $InstallDir #拷贝需要打包的文件到打包目录 cp -r configs $InstallDir cp -r html $InstallDir cp -r scripts $InstallDir #打包前删除CVS工程文件 find $InstallDir -type d -name CVS -exec rm -fr {} \+ >/dev/null 2>&1
3. package/confmanage.spec
Summary: 3G Configuration Manage Name: confmanage Version: 1.0.3 Release: 1 Vendor: Zed-3, Inc. License: Zed-3, Inc 2013 Group: Applications/ASG BuildRoot: /tmp/BUILD/confmanage %description This package contains 3G Configuration Manage. %post if [ "$1" = "1" ]; then # Run %post of new package during a new install # add user to sudoers if ! grep -q 'apache ALL= NOPASSWD' /etc/sudoers then echo "apache ALL= NOPASSWD: /usr/local/confmanage/scripts/" >>/etc/sudoers elif ! cat /etc/sudoers | grep 'apache ALL= NOPASSWD' | grep -q '/usr/local/confmanage/scripts' then sed -i 's/^apache ALL= NOPASSWD.*$/&\,\/usr\/local\/confmanage\/scripts\//' /etc/sudoers fi #config apache sed -i 's/#Include conf\/extra\/httpd-vhosts.conf/Include conf\/extra\/httpd-vhosts.conf/' /usr/local/httpd/conf/httpd.conf if [ ! -e "/usr/local/httpd/conf/extra/httpd-vhosts.conf.bak" ]; then cp /usr/local/httpd/conf/extra/httpd-vhosts.conf /usr/local/httpd/conf/extra/httpd-vhosts.conf.bak fi cp /usr/local/confmanage/configs/cm.conf /usr/local/httpd/conf/extra/httpd-vhosts.conf service httpd restart >/dev/null 2>&1 chmod +x -R /usr/local/confmanage/scripts elif [ "$1" = "2" ]; then # during upgrade # add user to sudoers if ! grep -q 'apache ALL= NOPASSWD' /etc/sudoers then echo "apache ALL= NOPASSWD: /usr/local/confmanage/scripts/" >>/etc/sudoers elif ! cat /etc/sudoers | grep 'apache ALL= NOPASSWD' | grep -q '/usr/local/confmanage/scripts' then sed -i 's/^apache ALL= NOPASSWD.*$/&\,\/usr\/local\/confmanage\/scripts\//' /etc/sudoers fi #config apache sed -i 's/#Include conf\/extra\/httpd-vhosts.conf/Include conf\/extra\/httpd-vhosts.conf/' /usr/local/httpd/conf/httpd.conf if [ ! -e "/usr/local/httpd/conf/extra/httpd-vhosts.conf.bak" ]; then cp /usr/local/httpd/conf/extra/httpd-vhosts.conf /usr/local/httpd/conf/extra/httpd-vhosts.conf.bak fi cp /usr/local/confmanage/configs/cm.conf /usr/local/httpd/conf/extra/httpd-vhosts.conf service httpd restart >/dev/null 2>&1 chmod +x -R /usr/local/confmanage/scripts else # Invalid $1 value, neither install nor upgrade, abort! exit 1 fi %postun if [ "$1" = "0" ]; then # Run %postun of old package during an erase #delete user to sudoers sed -i '/^apache ALL= NOPASSWD: \/usr\/local\/confmanage\/scripts\/$/d' /etc/sudoers sed -i 's/\,\/usr\/local\/confmanage\/scripts\///' /etc/sudoers #config apache sed -i 's/Include conf\/extra\/httpd-vhosts.conf/#Include conf\/extra\/httpd-vhosts.conf/' /usr/local/httpd/conf/httpd.conf if [ -e "/usr/local/httpd/conf/extra/httpd-vhosts.conf.bak" ]; then mv /usr/local/httpd/conf/extra/httpd-vhosts.conf.bak /usr/local/httpd/conf/extra/httpd-vhosts.conf fi service httpd restart >/dev/null 2>&1 elif [ "$1" = "1" ]; then # during upgrade : else # Invalid $1 value, neither install nor upgrade, abort! exit 1 fi %files %defattr (-,root,root) /usr/local/confmanage/
4. apache配置
Listen 8000 NameVirtualHost *:8000 <VirtualHost *:8000> DocumentRoot "/usr/local/confmanage/html" <Directory /> Options FollowSymLinks AllowOverride None </Directory> <Directory /usr/local/confmanage/html> Options Indexes FollowSymLinks MultiViews AllowOverride All Order allow,deny allow from all </Directory> ServerName www.example.com:8000 ServerAdmin admin@exapmle.com ErrorLog logs/cm.log CustomLog logs/cm.log common <FilesMatch \.php$> SetHandler application/x-httpd-php </FilesMatch> </VirtualHost>
--------------------------------------------------------------------------------------------------------------------------
升级RPM过程调研[转载]
当在用户机器上安装或卸载程序时,能够执行命令将是很有用的。例如,可能需要编辑一个系统配置文件以启用新的服务,或者需要定义一个新用户以拥有正在安装的程序的所有权。
安装和卸载脚本的工作原理看起来很简单,但它们工作原理中的一些意外可能会引起大问题。这里是一些基本信息,可以将下列四节中的任意一个添加到.spec 文件,它列出了在包安装期间各个点上运行的shell 脚本:
%pre 在安装包之前运行
%post 在安装包之后运行
%preun 在卸载包之前运行
%postun 在卸载包之后运行
尤其要注意%install与这些节之间的差异。构建RPM 时,%install 在开发机器上运行;它应该将产品安装在开发机器上或安装到一个构建根目录中。另一方面,这些节指定当用户正在安装或卸载RPM包时将在用户的机器上运行什么。
一种好的技术是使用%pre脚本来检查安装前提条件,它们比RPM可以直接支持的更复杂。 如果不符合前提条件,那么脚本以非零状态退出,而且 RPM 不会继续安装。另外请注意,我们必须小心地使用卸载脚本来撤销安装脚本。
然而实际上没有那么简单:升级使每件事情都变得复杂,现在,让我们着手升级。如果用户只安装和删除自己的包,那么前面的指令将正常工作;但在升级期间,它们会完全失效。以下是 RPM 如何执行升级:
运行新包的 %pre
安装新文件
运行新包的 %post
运行旧包的 %preun
删除新文件未覆盖的所有旧文件
运行旧包的 %postun
如果我们使用5.3.2系列中现有SPEC文件中的脚本来升级,那么RPM最后将运行 %postun 脚本,它将除去我们在安装脚本中所做的所有工作。
rpm为了解决此问题,在其英文文档中提到了可以向脚本来传递一个参数$1,这个参数传递的过程是隐藏的,你只需在%pre,%post,%preun,%postun中使用$1即可($1在shell中就是第一个参数的意思)。这个参数的含义是在执行完此次操作后系统中此软件包的剩余数量是多少,就目前我的理解应该只有0,1,2三种可能。
1.在执行rpm –ivh的安装过程中,如果有同类包存在,则会报错提示无法安装,存在相同的文件。如果没有同类包存在则会执行安装动作,过程如下:
运行新包的%pre $1=1
安装新文件
运行新包的%post $1=1
2.在执行rpm –U的升级过程中,如果没有同类低级包存在,则过程和传递的参数与安装时完全相同,如果有同类低级包存在则会执行升级操作,过程如下:
运行新包的%pre $1=2
安装新文件
运行新包的%post $1=2
运行旧包的%preun $1=1
删除新文件未覆盖的任何旧文件
运行旧包的%postun $1=1
3.在执行rpm –e的删除过程如下:
运行旧包的%preun $1=0
删除文件
运行旧包的%postun $1=0
因此我们可以用传递的参数来判断rpm究竟在进行什么工作,来在脚本内部通过$1进行判断来决定进行什么动作。例如在参数为0的时候才真的执行卸载所要进行的动作。
另外,在升级的时候,RPM还有一项重要的工作要做,这就是妥善处理配置文件(CONFIG FILE)。若直接采用安装方式,则用户已配置好的配置文件就会被覆盖,不符合用户要求。
RPM对某个配置文件,通过比较三种不同的MD5检查和(checksum)来决定如何处理它。这三种不同的MD5检查和是:
1. 原检查和。它是旧版本软件包安装时配置文件的MD5检查和。
2. 当前检查和。它是升级时旧版本配置文件的MD5检查和。
3. 新检查和。它是新版本软件包中配置文件的MD5检查和。
RPM针对以下几种情况分别处理:
1. 当原检查和=X,当前检查和=X,新检查和=X时:
这表明配置文件未曾修改过。此时,RPM会将新的配置文件覆盖掉原文件,而不是对原文件不作处理,原因在于: 虽然文件名和文件内容都没有变化,但文件别的方面的属性(如文件的属主,属组,权限等)却可能改变,所以有必要覆盖一下。
2. 当原检查和=X,当前检查和=X,新检查和=Y时:
这表明原配置文件没有改动过,但是它与新软件包中的配置文件却有所不同。这种情况下,RPM将用新文件覆盖掉旧文件,并且旧文件不作保存(因为它不曾改动过,没有必要保存)。
3. 当原检查和=X,当前检查和=Y,新检查和=X时:
这表明新文件与旧文件内容相同,但当前文件已经作过修改,这些修改对于新版本来说应该是合法的,可以使用的。因此,RPM对当前文件予以保留。
4. 当原检查和=X,当前检查和=Y,新检查和=Y时:
这表明原文件经过修改,现在已与新文件相同,这或许是用户用来修补安全上的漏洞,新版本也作了同样的修改。这种情况下,RPM将新文件覆盖当前文件,避免文件属性方面的不同。
5. 当原检查和=X,当前检查和=Y,新检查和=Z时:
这表明用户已修改了原文件,并且当前内容与新文件内容不同。这种情况下,RPM无法保证新版本软件能正常使用当前的配置文件,所以采用了一个比较明智的办 法,既能保护用户的配置数据,又能保证新版本软件正常。这种作法就是将当前文件换名保存(给原文件名加个.rpmsave的后缀,如原文件名为ABC,则 换名后为ABC.rpmsave),同时安装新文件,并给出警告信息。
6. 当没有原检查和时:
此种情况下,当前检查和与新检查和已无关紧要,这表明没有安装过此配置文件。因为没有安装过此配置文件,所以RPM无法判断当前文件是否被用户修改过。这种情况下,RPM会将当前文件换名保存(原文件名后缀不是加个.rpmsave,而是.rpmorig),同时安装新文件,并给出警告信息。
因此在%files中可以用%config字段将配置文件标识出来,这样在升级的过程中配置文件将被按照上面所描述的方法处理。
%config 文件路径的形式来添加。
相关文章推荐
- RPM打包技术与典型SPEC文件分析
- RPM 打包技术与典型 SPEC 文件分析
- Yum离线安装(一) --- RPM 打包技术与典型 SPEC 文件分析
- rpm 打包原理及 .spec文件
- tar ,cpio打包解压. shell脚本for,while,until循环. rpm包管理,select循环菜单,函数function,yum
- RPM打包技术与典型SPEC文件分析
- 使用spec与fpm 2种方式进行rpm打包
- rpm打包时包含python脚本,需要忽略掉pyc, pyo字节码文件
- rpm spec 打包学习
- RPM打包技术与典型SPEC文件分析
- linux-RPM 打包原理 SPEC 编写规范
- 将 shell 脚本打包到 rpm 包中
- Yum离线安装(一) --- RPM 打包技术与典型 SPEC 文件分析
- RPM 打包技术与典型 SPEC 文件分析
- RPM 打包技术与典型 SPEC 文件分析
- Linux 系统 RPM打包技术和典型SPEC文件分析
- linux-RPM 打包原理 SPEC 编写规范
- RPM 打包技术与典型 SPEC 文件分析
- RPM 打包技术与典型 SPEC 文件分析
- RPM打包技术与典型SPEC文件分析