linux中rpm设计目标,linux-centos浅谈之rpm和rpmbuild

/usr/var

(5) 创建RPM包的例子

要创建的rpm包为:test-1.0.1-1.el6.i686.rpm,打包的压缩文件为:test-1.0.1.tar.gz。 1.把test-1.0.1.tar.gz拷贝到SOURCE目录底下。

2.转至SPECS目录底下,编写test.spec描述文件,这个文件是创建rpm包最重要的部分,它会制定rpm包里的软件的安装目录,以及安装软件前后要注意的问题,软件的依赖及系统要求。

3.编译RPM,执行命令:rpmbuild –ba test.spec。这样以后,就开始创建rpm包。

4.执行rpmbuild –ba test.spec后,会首先把test-1.0.1.tar.gz解压缩到BUILD目录,BUILDROOT这个目录用来存放执行时存放的临时文件夹,这个目录也很重要,需要把在此目录建立相关目录以及拷贝相关文件信息的脚本写入test.spec文件里,以防编译出错,无法生成RPM包。成功执行完成之后,会在RPMS这个目录生成i686/ test-1.0.1-1.el6.i686.rpm文件。

如下图:

0818b9ca8b590ca3270a3433284dd417.png

(6) 附加SPEC文件

文件是官方发布的anaconda.spec,Anaconda是RedHat、CentOS、Fedora等Linux的安装管理程序,以后还有很重要的应用。分析该文件对系统的定制很有帮助,因文件内容过长,删除后面不太重要的日志部分。

%define livearches %{ix86} x86_64 ppc ppc64

%define _libdir %{_prefix}/lib

Summary: Graphical system installer

Name: anaconda

Version: 13.21.176

Release: 1%{?dist}

License: GPLv2+

Group: Applications/System

URL: http://fedoraproject.org/wiki/Anaconda

# To generate Source0 do:

# git clone http://git.fedorahosted.org/git/anaconda.git

# git checkout -b archive-branch anaconda-%{version}-%{release}

# ./autogen.sh

# ./configure

# make dist

Source0: %{name}-%{version}.tar.bz2

Patch1000: anaconda-centos-installclass.patch

Patch1001: anaconda-centos-upgrade-from-centos.patch

Patch1002: anaconda-centos-droprepos.patch

BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)

# Versions of required components (done so we make sure the buildrequires

# match the requires versions of things).

%define dmver 1.02.17-6

%define gettextver 0.11

%define genisoimagever 1.1.9-4

%define intltoolver 0.31.2-3

%define libnlver 1.0

%define libselinuxver 1.6

%define pykickstartver 1.74.8

%define rpmpythonver 4.2-0.61

%define slangver 2.0.6-2

%define yumver 2.9.2

%define partedver 1.8.1

%define pypartedver 3.0

%define syscfgdatever 1.9.48

%define pythonpyblockver 0.45-2

%define e2fsver 1.41.0

%define nmver 1:0.7.1-3.git20090414

%define dbusver 1.2.3

%define createrepover 0.4.7

%define yumutilsver 1.1.11-3

%define iscsiver 6.2.0.870-3

%define pythoncryptsetupver 0.0.6

%define mehver 0.8

%define sckeyboardver 1.3.1

%define libblkid 2.17.1-1

%define fcoeutilsver 1.0.12-3.20100323git

%define isomd5sumver 1.0.6

BuildRequires: audit-libs-devel

BuildRequires: bzip2-devel

BuildRequires: device-mapper-devel >= %{dmver}

BuildRequires: e2fsprogs-devel >= %{e2fsver}

BuildRequires: elfutils-devel

BuildRequires: gettext >= %{gettextver}

BuildRequires: gtk2-devel

BuildRequires: intltool >= %{intltoolver}

BuildRequires: isomd5sum-devel >= %{isomd5sumver}

BuildRequires: libarchive-devel

BuildRequires: libX11-devel

BuildRequires: libXt-devel

BuildRequires: libXxf86misc-devel

BuildRequires: libblkid-devel >= %{libblkid}

BuildRequires: libcurl-devel

BuildRequires: libnl-devel >= %{libnlver}

BuildRequires: libselinux-devel >= %{libselinuxver}

BuildRequires: libsepol-devel

BuildRequires: libxml2-python

BuildRequires: newt-devel

BuildRequires: pango-devel

BuildRequires: pykickstart >= %{pykickstartver}

BuildRequires: python-devel

BuildRequires: python-urlgrabber >= 3.9.1-5

BuildRequires: rpm-devel

BuildRequires: rpm-python >= %{rpmpythonver}

BuildRequires: slang-devel >= %{slangver}

BuildRequires: xmlto

BuildRequires: yum >= %{yumver}

BuildRequires: zlib-devel

BuildRequires: NetworkManager-devel >= %{nmver}

BuildRequires: NetworkManager-glib-devel >= %{nmver}

BuildRequires: dbus-devel >= %{dbusver}

BuildRequires: system-config-keyboard >= %{sckeyboardver}

%ifarch %livearches

BuildRequires: desktop-file-utils

%endif

BuildRequires: iscsi-initiator-utils-devel >= %{iscsiver}

%ifarch s390 s390x

BuildRequires: s390utils-devel

%endif

Requires: python-meh >= %{mehver}

Requires: policycoreutils

Requires: rpm-python >= %{rpmpythonver}

Requires: comps-extras

Requires: parted >= %{partedver}

Requires: pyparted >= %{pypartedver}

Requires: yum >= %{yumver}

Requires: libxml2-python

Requires: python-urlgrabber >= 3.9.1-5

Requires: system-logos

Requires: pykickstart >= %{pykickstartver}

Requires: system-config-date >= %{syscfgdatever}

Requires: device-mapper >= %{dmver}

Requires: device-mapper-libs >= %{dmver}

Requires: dosfstools

Requires: e2fsprogs >= %{e2fsver}

Requires: gzip

Requires: xz

Requires: libarchive

%ifarch %{ix86} x86_64 ia64

Requires: dmidecode

%endif

Requires: python-pyblock >= %{pythonpyblockver}

Requires: libuser-python

Requires: newt-python

Requires: authconfig

Requires: system-config-firewall-base

Requires: cryptsetup-luks

Requires: python-cryptsetup >= %{pythoncryptsetupver}

Requires: mdadm

Requires: lvm2

Requires: util-linux-ng >= 2.15.1

Requires: system-config-keyboard >= %{sckeyboardver}

Requires: dbus-python

Requires: cracklib-python

Requires: python-nss

Requires: tigervnc-server

%ifarch %livearches

Requires: usermode

Requires: zenity

%endif

Requires: createrepo >= %{createrepover}

Requires: squashfs-tools

Requires: genisoimage >= %{genisoimagever}

%ifarch %{ix86} x86_64

Requires: syslinux >= 3.73

Requires: makebootfat

Requires: device-mapper

%endif

%ifarch s390 s390x

Requires: openssh

%endif

Requires: isomd5sum

Requires: yum-utils >= %{yumutilsver}

Requires: NetworkManager >= %{nmver}

Requires: dhclient

Requires: anaconda-yum-plugins

Requires: libselinux-python >= %{libselinuxver}

Requires: fcoe-utils >= %{fcoeutilsver}

%ifarch %{sparc}

Requires: elftoaout piggyback

%endif

Obsoletes: anaconda-images <= 10

Provides: anaconda-images = %{version}-%{release}

Obsoletes: anaconda-runtime < %{version}-%{release}

Provides: anaconda-runtime = %{version}-%{release}

Obsoletes: booty

%description

The anaconda package contains the program which was used to install your

system. These files are of little use on an already installed system.

%prep

%setup -q

%patch1000 -p1

%patch1001 -p1

%patch1002 -p1

%build

%configure --disable-static

%{__make} %{?_smp_mflags}

%install

%{__rm} -rf %{buildroot}

%{__make} install DESTDIR=%{buildroot}

find %{buildroot} -type f -name "*.la" | xargs %{__rm}

%ifarch %livearches

desktop-file-install --vendor="" --dir=%{buildroot}%{_datadir}/applications %{buildroot}%{_datadir}/applications/liveinst.desktop

%else

%{__rm} -rf %{buildroot}%{_bindir}/liveinst %{buildroot}%{_sbindir}/liveinst

%endif

%find_lang %{name}

%clean

%{__rm} -rf %{buildroot}

%ifarch %livearches

%post

update-desktop-database &> /dev/null || :

%endif

%ifarch %livearches

%postun

update-desktop-database &> /dev/null || :

%endif

%files -f %{name}.lang

%defattr(-,root,root)

%doc COPYING

%doc docs/command-line.txt

%doc docs/install-methods.txt

%doc docs/mediacheck.txt

%doc docs/anaconda-release-notes.txt

/lib/udev/rules.d/70-anaconda.rules

%{_sbindir}/anaconda

%ifarch i386 i486 i586 i686 x86_64

%{_sbindir}/gptsync

%{_sbindir}/showpart

%endif

%{_datadir}/anaconda

%{_prefix}/lib/anaconda

%{_prefix}/lib/anaconda-runtime

%ifarch %livearches

%{_bindir}/liveinst

%{_sbindir}/liveinst

%config(noreplace) %{_sysconfdir}/pam.d/*

%config(noreplace) %{_sysconfdir}/security/console.apps/*

%{_sysconfdir}/X11/xinit/xinitrc.d/*

%{_datadir}/applications/*.desktop

%{_datadir}/icons/hicolor/*

%endif

%changelog

* Sat Jun 23 2012 Karanbir Singh - 13.21.176.1.el6.centos

- Build for CentOS-6.3

(7) 升级RPM包的SPEC文件修改

当在用户机器上安装或卸载程序时,能够执行命令将是很有用的。例如,可能需要编辑一个系统配置文件以启用新的服务,或者需要定义一个新用户以拥有正在安装的程序的所有权。

安装和卸载脚本的工作原理看起来很简单,但它们工作原理中的一些意外可能会引起大问题。这里是一些基本信息,可以将下列四节中的任意一个添加到.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 文件路径的形式来添加。

三、总结

(2)rpm和rpmbuild内容众多丰富,该博客总结部分内容,以便使用时能快速查找到。

(3)若有读者想沟通交流的,可发信息到邮箱yang.ao@i-soft.com.cn。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值