SPEC脚本及RPM打包

1. Makefile示例

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 文件路径的形式来添加。

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值