Chinaunix首页 | 论坛 | 博客
  • 博客访问: 30002719
  • 博文数量: 2065
  • 博客积分: 10377
  • 博客等级: 上将
  • 技术积分: 21525
  • 用 户 组: 普通用户
  • 注册时间: 2008-11-04 17:50
文章分类

全部博文(2065)

文章存档

2012年(2)

2011年(19)

2010年(1160)

2009年(969)

2008年(153)

分类: LINUX

2010-10-08 23:21:06

linux创建RPM

时间:2010-10-8

1、  回顾一下RPM相关内容

那么什么是 RPM 呢?说的简单一点, RPM 是以一种数据库记录的方式来将你所需要的套件安装到你的 Linux 主机的一套管理程序。他最大的特点就是将您要安装的套件先编译过( 如果需要的话 )并且打包好了,透过包装好的套件里头预设的数据库记录,记录这个套件要安装的时候必须要的相依属性模块( 就是你的 Linux 主机需要先存在的几个必须的套件 ),当安装在你的 Linux 主机时, RPM 会先依照套件里头的纪录数据查询 Linux 主机的相依属性套件是否满足,若满足则予以安装,若不满足则不予安装。那么安装的时候就将该套件的信息整个写入 RPM 的数据库中,以便未来的查询、验证与反安装!这样一来的优点是:

  1. 由于已经编译完成并且打包完毕,所以安装上很方便( 不需要再重新编译 )
  2. 由于套件的信息都已经记录在 Linux 主机的数据库上,很方便查询、升级与反安装;

但是这也造成很大的困扰,由于 RPM 程序是已经包装好的数据,也就是说,里面的数据已经都『编译完成』了!所以,安装的时候一定需要当初安装时的主机环境才能安装,也就是说,当初建立这个套件的安装环境必须也要在你的主机上面出现才行!

缺点是:

1.      安装的环境必须与打包时的环境需求一致或相当;

2.      需要满足套件的相依属性需求;

3.      反安装时需要特别小心,最底层的套件不可先移除,否则可能造成整个系统的问题!

说明:特别是第三点到时自动化的设计中考虑到将软件包卸载的时候一定要注意一下这个问题这里面有一个先后顺序问题。

 

暴力安装法带的参数如下:

--nodeps 使用时机:如果您在安装某个套件时,老是发现 rpm 告诉你『有属性相依的套件尚未安装』,而您又想要直接强制安装这个套件时,可以加上 --nodeps 告知 RPM 不要去检查套件的相依性。
危险性:套件会有相依性的原因是因为彼此会使用到对方的机制或功能,如果强制安装而不考虑套件的属性相依,则可能会造成该套件的无法正常使用!

--nomd5 使用时间:不想检查 RPM 档案所含的 MD5 信息时。
说明:还记得我们在前一章有提到的 MD5 这个指纹辨识吧?!没错,这里指的就是不要检查 RPM 套件的 MD5 信息。但除非您很清楚这个套件的来源,否则不建议使用这个参数。 --noscripts 使用时机:不想让该套件自行启用或者自行执行某些系统指令。
说明RPM 的优点除了可以将档案放置到定位之外,还可以自动执行一些前置作业的指令,例如数据库的初始化。如果您不想要让 RPM 帮您自动执行这一类型的指令,就加上他吧! --replacefiles 使用时机:如果在安装的过程当中出现了『某个档案已经被安装在您的系统上面』的信息,又或许出现版本不合的讯息( confilcting files )时,可以使用这个参数来直接覆盖档案。 危险性:覆盖的动作是无法复原的!所以,您必须要很清楚的知道被覆盖的档案是真的不重要喔!否则会欲哭无泪!

--replacepkgs 使用时机:重新安装某个已经安装过的套件!

--force 这个参数其实就是 --replacefiles --replacepkgs 的综合体!

--test 使用时机:想要测试一下该套件是否可以被安装到使用者的 Linux 环境当中。范例为:
rpm -ivh pkgname.i386.rpm –test

 

 

RPM升级与更新

-Uvh 后面接的套件即使没有安装过,则系统将予以直接安装;若后面接的套件有安装过旧版,则系统自动更新至新版;

-Fvh 如果后面接的套件并未安装到您的 Linux 系统上,则该套件不会被安装;亦即只有安装至您 Linux 系统内的套件会被『升级』!

 

 

 

2、  打包鸟哥上面的那个简单示例先了解下打包的流程

操作步骤如下

STEP1. 编写我们的脚本

[root@test root]# cd /usr/src/redhat/SOURCES
[root@test SOURCES]# vi showvbird.sh
#!/bin/bash
# This file is just used to demo the RPM packaging.
# the only thing is showing the hostname.
HOST=`/bin/hostname`
/bin/echo $HOST
 
[root@test SOURCES]# chmod 755 showvbird.sh
[root@test SOURCES]# tar –zcvf showvbird.tar.gz showvbird.sh
# 注意了,我们必需要将他打包才行!

 

注意:只有showvbird.tar.gz这样的档案才行!请注意,这个showvbird.tar.gz档案『必需』放置在SOURCES目录之下!(完整路径为:/usr/src/redhat/SOURCES

 

STEP2. 编写*.spec档案文件

[root@test root]# cd /usr/src/redhat/SPECS
[root@test SPECS]# vi showvbird.spec
Summary:   This is a demo RPM package.
Name:      showvbird
Version:   1.0
Release:   1
Copyright: GPL
Group:     VBird's Home
Source:    showvbird.tar.gz   <==这个就是刚刚建立起来的Tarball档案!
Url:      
Packager:  VBird

%description
This package is just a demo RPM.

%prep
%setup –c
%install
install -m 755 showvbird.sh /usr/local/bin/showvbird.sh

%files
/usr/local/bin/showvbird.sh

 

 

STEP3. 编译并打包成为RPM

[root @test SPECS]# rpmbuild -bb showvbird.spec
….()
Wrote: /usr/src/redhat/RPMS/i586/showvbird-1.0-1.i586.rpm

 

STEP4. 再来安装一下看看吧

rpm –ivh /usr/src/RPM/RPMS/i586/showvbird-1.0-1.i586.rpm

 

安装完毕之后就可以直接使用这个SHELL脚本了:showvbird.sh

 

心得:将来把自动化的SH直接打包成一段RPM文件吧。另外将socket这部分的代码也封装进来做成一个RPM包装完之后就可以直接跑起来放在系统进程里面去!

 

 

 

3. 测试一下

自己编写一段python脚本。里面启一个socket进程。然后制作成RPM包的方式安装

操作步骤如下

STEP1. 编写我们的脚本

[root@test root]# cd /usr/src/redhat/SOURCES
[root@test SOURCES]# vi  socketserver.sh
if __name__ == '__main__': 

   import socket 

   sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 

   sock.bind(('localhost', 8001)) 

   sock.listen(5) 

   while True: 

      connection,address = sock.accept() 

      try: 

         connection.settimeout(5) 

         buf = connection.recv(1024) 

         if buf == '1': 

            connection.send('welcome to server!') 

         else: 

            connection.send('please go out!') 

      except socket.timeout: 

         print 'time out' 

      connection.close()   
[root@test SOURCES]# 利用pyinstaller 将其制作成可独立运行的程序
[root@test SOURCES]# tar –zcvf socketserver.tar.gz  socketserver  (将这个tar.gz放在这个目录 )
# 注意了,我们必需要将他打包才行!

 

注意:只有socketserver.tar.gz这样的档案才行!请注意,这个socketserver.tar.gz档案『必需』放置在SOURCES目录之下!(完整路径为:/usr/src/redhat/SOURCES

 

STEP2. 编写*.spec档案文件

[root@test root]# cd /usr/src/redhat/SPECS
[root@test SPECS]# vi showvbird.spec
Summary:   This is a demo RPM package.
Name:      showvbird
Version:   1.0
Release:   1
Copyright: GPL
Group:     VBird's Home
Source:    showvbird.tar.gz   <==这个就是刚刚建立起来的Tarball档案!
Url:      
Packager:  VBird

%description
This package is just a demo RPM.

%prep
%setup –c
%install
install -m 755 showvbird.sh /usr/local/bin/showvbird.sh

%files
/usr/local/bin/showvbird.sh

说明:这里面一定要注意Source段里面的tar包一定得是在/usr/src/redhat/SOURCES 此目录下面进行压缩的。即它解压缩的过程中得在这个目录能够找到哦!要不然就报错了说找不到文件!

 

 

STEP3. 编译并打包成为RPM

[root @test SPECS]# rpmbuild -bb showvbird.spec
….()
Wrote: /usr/src/redhat/RPMS/i586/showvbird-1.0-1.i586.rpm

 

STEP4. 再来安装一下看看吧

rpm –ivh /usr/src/RPM/RPMS/i586/showvbird-1.0-1.i586.rpm

 

安装完毕之后就可以直接使用这个SHELL脚本了:showvbird.sh

 

 

-----------------------------安装python程序成RPM包的结论---------------------------------------------------

1.       首先将程序利用pyinstaller 做成可执行程序。相当于sh加了755权限一样

2.       制作RPM包。

 

 

3.       介绍一下*. Spec 文件配置相关信息

实际过程中,最关键的地方,是要清楚虚拟路径的位置,以及宏的定义。

spec脚本包括很多关键字,主要有:

引用

Name: 软件包的名称,后面可使用%{name}的方式引用
Summary:
软件包的内容概要
Version:
软件的实际版本号,例如:1.0.1等,后面可使用%{version}引用
Release:
发布序列号,例如:1linuxing等,标明第几次打包,后面可使用%{release}引用
Group:
软件分组,建议使用标准分组
License:
软件授权方式,通常就是GPL
Source:
源代码包,可以带多个用Source1Source2等源,后面也可以用%{source1}%{source2}引用
BuildRoot:
这个是安装或编译时使用的虚拟目录,考虑到多用户的环境,一般定义为:
%{_tmppath}/%{name}-%{version}-%{release}-root

%{_tmppath}/%{name}-%{version}-%{release}-buildroot-%(%{__id_u} -n}
该参数非常重要,因为在生成rpm的过程中,执行make install时就会把软件安装到上述的路径中,在打包的时候,同样依赖虚拟目录根目录进行操作。
后面可使用$RPM_BUILD_ROOT 方式引用。
URL:
软件的主页
Vendor:
发行商或打包组织的信息,例如RedFlag Co,Ltd
Disstribution:
发行版标识
Patch:
补丁源码,可使用Patch1Patch2等标识多个补丁,使用%patch0%{patch0}引用
Prefix: %{_prefix}
这个主要是为了解决今后安装rpm包时,并不一定把软件安装到rpm中打包的目录的情况。这样,必须在这里定义该标识,并在编写%install脚本的时候引用,才能实现rpm安装时重新指定位置的功能
Prefix: %{_sysconfdir}
这个原因和上面的一样,但由于%{_prefix}/usr,而对于其他的文件,例如/etc下的配置文件,则需要用%{_sysconfdir}标识
Build Arch:
指编译的目标处理器架构,noarch标识不指定,但通常都是以/usr/lib/rpm/marcros中的内容为默认值

Requires:
rpm包所依赖的软件包名称,可以用>=<=表示大于或小于某一特定版本,例如:
libpng-devel >= 1.0.20 zlib
※“>=”
号两边需用空格隔开,而不同软件名称也用空格分开
还有例如PreReqRequires(pre)Requires(post)Requires(preun)Requires(postun)BuildRequires等都是针对不同阶段的依赖指定

Provides:
指明本软件一些特定的功能,以便其他rpm识别
Packager:
打包者的信息
%description
软件的详细说明

 

spec脚本的主体中也包括了很多关键字和描述,下面会一一列举。我会把一些特别需要留意的地方标注出来。
%prep
预处理脚本
%setup -n %{name}-%{version}
把源码包解压并放好
通常是从/usr/src/asianux/SOURCES里的包解压到/usr/src/asianux/BUILD/%{name}-%{version}中。
一般用%setup -c就可以了,但有两种情况:一就是同时编译多个源码包,二就是源码的tar包的名称与解压出来的目录不一致,此时,就需要使用-n参数指定一下了。
%patch
打补丁
通常补丁都会一起在源码tar.gz包中,或放到SOURCES目录下。一般参数为:
%patch -p1
使用前面定义的Patch补丁进行,-p1是忽略patch的第一层目录
%Patch2 -p1 -b xxx.patch
打上指定的补丁,-b是指生成备份文件
补充一下

引用

%setup 不加任何选项,仅将软件包打开。
%setup -n newdir
将软件包解压在newdir目录。
%setup -c
解压缩之前先产生目录。
%setup -b num
将第numsource文件解压缩。
%setup -T
不使用default的解压缩操作。
%setup -T -b 0
将第0个源代码文件解压缩。
%setup -c -n newdir
指定目录名称newdir,并在此目录产生rpm套件。
%patch
最简单的补丁方式,自动指定patch level
%patch 0
使用第0个补丁文件,相当于%patch ?p 0
%patch -s
不显示打补丁时的信息。
%patch -T
将所有打补丁时产生的输出文件删除。
%configure
这个不是关键字,而是rpm定义的标准宏命令。意思是执行源代码的configure配置
/usr/src/asianux/BUILD/%{name}-%{version}目录中进行 ,使用标准写法,会引用/usr/lib/rpm/marcros中定义的参数。
另一种不标准的写法是,可参考源码中的参数自定义,例如:

引用

CFLAGS="$RPM_OPT_FLAGS" CXXFLAGS="$RPM_OPT_FLAGS" ./configure --prefix=%{_prefix}
%build
开始构建包
/usr/src/asianux/BUILD/%{name}-%{version}目录中进行make的工作 ,常见写法:

引用

make %{?_smp_mflags} OPTIMIZE="%{optflags}"


都是一些优化参数,定义在/usr/lib/rpm/marcros
%install
开始把软件安装到虚拟的根目录中
/usr/src/asianux/BUILD/%{name}-%{version}目录中进行make install的操作。这个很重要,因为如果这里的路径不对的话,则下面%file中寻找文件的时候就会失败。 常见内容有:
%makeinstall
这不是关键字,而是rpm定义的标准宏命令。也可以使用非标准写法:

引用

make DESTDIR=$RPM_BUILD_ROOT install

引用

make prefix=$RPM_BUILD_ROOT install
需要说明的是,这里的%install主要就是为了后面的%file服务的。所以,还可以使用常规的系统命令:

引用

install -d $RPM_BUILD_ROOT/
cp -a * $RPM_BUILD_ROOT/
%clean
清理临时文件
通常内容为:

引用

[ "$RPM_BUILD_ROOT" != "/" ] && rm -rf "$RPM_BUILD_ROOT"
rm -rf $RPM_BUILD_DIR/%{name}-%{version}
注意区分$RPM_BUILD_ROOT$RPM_BUILD_DIR
$RPM_BUILD_ROOT
是指开头定义的BuildRoot,而$RPM_BUILD_DIR通常就是指/usr/src/asianux/BUILD,其中,前面的才是%file需要的。
%pre rpm
安装前执行的脚本
%post rpm
安装后执行的脚本
%preun rpm
卸载前执行的脚本
%postun rpm
卸载后执行的脚本

%preun %postun 的区别是什么呢?

前者在升级的时候会执行,后者在升级rpm包的时候不会执行

%files
定义那些文件或目录会放入rpm
这里会在虚拟根目录下进行,千万不要写绝对路径,而应用宏或变量表示相对路径。 如果描述为目录,表示目录中除%exclude外的所有文件。
%defattr (-,root,root)
指定包装文件的属性,分别是(mode,owner,group)-表示默认值,对文本文件是0644,可执行文件是0755

%exclude
列出不想打包到rpm中的文件
小心,如果%exclude指定的文件不存在,也会出错的。
%changelog
变更日志

 

 

阅读(966) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~