部署rpm打包环境
安装rpm-build的相关rpm包
yum -y install rpm-build rpmdevtools
生成打包目录结构
[root@centos7 ~]# rpmdev-setuptree
[root@centos7 rpmbuild]# ls /root/rpmbuild/
BUILD BUILDROOT RPMS SOURCES SPECS SRPMS
目录解释:
BUILD:源码解压后存放的目录
RPMS:制作完成后的RPM存放目录
SOURCES:存放源文件,配置文件,补丁文件等放置的目录
SPECS:存放SPEC文件,制作RPM包的目录
SRPMS:src格式的RPM包目录
BUILDROOT:虚拟安装目录,在整个install的过程中临时安装到此目录,把这个目录当做根来使用。所有在这个目录下的文件才是真正的目录文件,最后SPEC文件中有清理阶段,这个目录下的内容将被删除。
改变打包目录
在上面章节我们默认生成的rpmbuild目录在/root目录下,如果我们想将构建RPM包的打包目录改变其它目录,可以参照如下方式进行:
例如,我们将rpmbuild目录移动到/home目录:
[root@centos7 ~]# mv /root/rpmbuild /home
[root@centos7 ~]# vi /root/.rpmmacros
[root@centos7 ~]# vi /root/.rpmmacros
# 这里改变%_topdir的目录为新移动的rpm构建目录
%_topdir /home/rpmbuild
%_smp_mflags %( \
[ -z "$RPM_BUILD_NCPUS" ] \\\
&& RPM_BUILD_NCPUS="`/usr/bin/nproc 2>/dev/null || \\\
/usr/bin/getconf _NPROCESSORS_ONLN`"; \\\
if [ "$RPM_BUILD_NCPUS" -gt 16 ]; then \\\
echo "-j16"; \\\
elif [ "$RPM_BUILD_NCPUS" -gt 3 ]; then \\\
echo "-j$RPM_BUILD_NCPUS"; \\\
else \\\
echo "-j3"; \\\
fi )
%__arch_install_post \
[ "%{buildarch}" = "noarch" ] || QA_CHECK_RPATHS=1 ; \
case "${QA_CHECK_RPATHS:-}" in [1yY]*) /usr/lib/rpm/check-rpaths ;; esac \
/usr/lib/rpm/check-buildroot
%debug_package %{nil}
改变后,我们可以通过如下的命令查看工作目录的路径:
[root@centos7 rpmbuild]# rpmbuild --showrc | grep topdir
-14: _builddir %{_topdir}/BUILD
-14: _buildrootdir %{_topdir}/BUILDROOT
-14: _rpmdir %{_topdir}/RPMS
-14: _sourcedir %{_topdir}/SOURCES
-14: _specdir %{_topdir}/SPECS
-14: _srcrpmdir %{_topdir}/SRPMS
-14: _topdir /home/yushengyin/rpmbuild
SPEC文件参数详解
spec文件是整个RPM包建立过程的中心,它的作用就如同编译程序时的Makefile文件。
Spec文件参数
spec文件包含建立一个RPM包必需的信息,包括哪些文件是包的一部分以及它们安装在哪个目录下。这个文件一般分为如下的几节:
(1) Preamle(序言)
序言包含用户请求包的信息时所显示的内容。它可以包含包的功能描述、包的软件版本、版权信息和所属的包组等。Summary 是一行关于该软件包的描述,Name 是该软件包的基名,Version 是该软件的版本号,Release 是 RPM 本身的版本号,如果修复了 spec 文件中的一个错误并发布了该软件同一版本的新 RPM,就应该增加发行版号。License 应该给出一些许可术语(如:"GPL"、"Commercial"、"Shareware"),Group 标识软件类型。那些试图帮助人们管理 RPM 的程序通常按照组列出 RPM。您可以在usr/share/doc/rpm-4.0.4/GROUPS 文件看到一个 Red Hat 使用的组列表(假设您安装的 RPM 版本是 4.0.4)。但是您还可以使用那些组名以外的名称。Source0、Source1等等给这些源文件命名(通常为 tar.gz 文件)。%{name} 和 %{version} 是 RPM 宏,它们扩展成为头中定义的 rpm 名称和版本。
要注意的是,你不要在 Source 语句中包含任何路径。缺省情况下,RPM 会在 /usr/src/redhat/SOURCES 中寻找文件,请将您的源文件复制或链接到那里。(要使 spec 文件尽量可移植的话,应当尽量避免嵌入自己开发机器上的假想路径。其他开发人员就可以指示 RPM 在别的目录下查找源文件,而不用修改您的 spec 文件。)
接下来的部分从 %description 行开始。您应该在这里提供该软件更多的描述,这样任何人使用 rpm -qi 查询您的软件包时都可以看到它。您可以解释这个软件包做什么,描述任何警告或附加的配置指令,等等。
(2) Prep节 %prep
Prep 节进行实际的打包准备工作,它是使用节前缀%prep表示的。一般而言,这一节的主要工作是检查标签语法是否正确,删除旧的软件源程序,对包含源程序的 tar文件进行解码。如果包含补丁(patch)文件,将补丁文件应用到解开的源码中。它一般包含%setup与%patch两个命令。%setup用于将软件源码包解开,执行%patch可将补丁文件加入解开的源程序中。
%setup
-n newdir---------将压缩的软件源程序在newdir目录下解开。
-c ---------------在解开源程序之前先创建目录。
-b num------------在包含多个源程序时,将第num个源程序解压缩。
-T----------------不使用缺省的解压缩操作。
例如:
%setup -T -b 0
/*解开第一个源程序文件。*/
%setup -c -n newdir
/*创建目录newdir,并在此目录之下解开源程序。*/
%patch
%patchN-------这里N是数字,表示使用第N个补丁文件,等价于%patch -P N
-p0-----------指定使用第一个补丁文件,-p1指定使用第二个补丁文件。 -s------------在使用补丁时,不显示任何信息。
-b name-------在加入补丁文件之前,将源文件名上加入name。若为指定此参数,则缺省源文件加入.orig。
-T------------将所有打补丁时产生的输出文件删除。
(3) Build节 %build
这一节主要用于编译源码,它是使用节前缀%build表示的。这一节一般由多个make命令组成。
(4) Install节 %install
这一节主要用于完成实际安装软件必须执行的命令,它是使用节前缀%install表示的。这一节一般是由make install指令构成,但是有时也会包含cp、mv、install等指令。
这一节还能指定在用户安装的系统上,包安装时运行的脚本。这样的脚本称为安装(卸载)脚本。它可以指定包安装前、包安装后、包除去前、包除去后的系统必须运行的外壳程序段。在用户安装的系统上,为了验证一个包是否已经成功安装的验证脚本也可由这一节指定。
(5) Clean节 %clean
这一节所描述的内容表示在完成包建立的工作之后,自动执行此节下的脚本进行附加的清除工作,它是使用节前缀%clean表示的。一般而言,这一节的内容是简单地使用rm -rf $RPM_BUILD_ROOT命令,不需要指定此节的其它内容。
(6) 文件列表 %files
这一节指定构成包的文件的列表,它是使用节前缀%files表示的。此外,它还包含一系列宏控制安装后的文件属性和配置信息。
%files 列出应该捆绑到 RPM 中的文件,并能够可选地设置许可权和其它信息。在 %files 中,您可以使用 %defattr 来定义缺省的许可权、所有者和组;%defattr(-,root,root) 会安装 root 用户拥有的所有文件,使用当 RPM 从构建系统捆绑它们时它们所具有的任何许可权。
可以用 %attr(permissions,user,group) 覆盖个别文件的所有者和许可权。可以在 %files 中用一行包括多个文件。可以通过在行中添加%doc 或 %config 来标记文件。%doc 告诉 RPM 这是一个文档文件,因此如果用户安装软件包时使用 --excludedocs,将不安装该文件。您也可以在 %doc 下不带路径列出文件名,RPM 会在构建目录下查找这些文件并在 RPM 文件中包括它们,并把它们安装到 /usr/share/doc/%{name}-%{version}。以 %doc 的形式包括 README 和 ChangeLog 这样的文件是个好主意。
%config 告诉 RPM 这是一个配置文件。在升级时,RPM 将会试图避免用 RPM 打包的缺省配置文件覆盖用户仔细修改过的配置。
注意:如果在 %files 下列出一个目录名,RPM 会包括该目录下的所有文件。通常这不是您想要的,特别对于 /bin 这样的目录。
(7) 改动日志 %changlog
这一节主要描述软件的开发记录,它是使用节前缀%changlog表示的。这个段的内容是为了开发人员能详细的了解该软件的开发过程,对于包的维护极有好处。
SPEC文件详解
RPM包的SPEC文件有许多配置信息,包含:软件基础信息、安装卸载前后执行的脚本、对源码包打补丁、解压、编译、安装等。
SPEC文件中包含了很多关键字,具体参考如下:
Name: 软件包的名称,在后面的变量中即可使用%{name}的方式引用
Summary: 软件包的内容
Version: 软件的实际版本号,例如:1.12.1等,后面可使用%{version}引用
Release: 发布序列号,例如:1%{?dist},标明第几次打包,后面可使用%{release}引用
Group: 软件分组,建议使用:Applications/System
License: 软件授权方式GPLv2
Source: 源码包,可以带多个用Source1、Source2等源,后面也可以用%{source1}、%{source2}引用
BuildRoot: 这个是安装或编译时使用的临时目录,即模拟安装完以后生成的文件目录:%_topdir/BUILDROOT 后面可使用$RPM_BUILD_ROOT 方式引用。
URL: 软件的URI
Vendor: 打包组织或者人员
Patch: 补丁源码,可使用Patch1、Patch2等标识多个补丁,使用%patch0或%{patch0}引用
Prefix: %{_prefix} 这个主要是为了解决今后安装rpm包时,并不一定把软件安装到rpm中打包的目录的情况。这样,必须在这里定义该标识,并在编写%install脚本的时候引用,才能实现rpm安装时重新指定位置的功能
Prefix: %{_sysconfdir} 这个原因和上面的一样,但由于%{_prefix}指/usr,而对于其他的文件,例如/etc下的配置文件,则需要用%{_sysconfdir}标识
Requires: 该rpm包所依赖的软件包名称,可以用>=或<=表示大于或小于某一特定版本,例如:
libxxx-devel >= 1.1.1 openssl-devel 。 注意:“>=”号两边需用空格隔开,而不同软件名称也用空格分开
%description: 软件的详细说明
%define: 预定义的变量,例如定义日志路径: _logpath /var/log/weblog
%prep: 预备参数,通常为 %setup -q
%build: 编译参数 ./configure --user=nginx --group=nginx --prefix=/usr/local/nginx/……
%install: 安装步骤,此时需要指定安装路径,创建编译时自动生成目录,复制配置文件至所对应的目录中
%pre: 安装前需要做的任务,如:创建用户
%post: 安装后需要做的任务 如:自动启动的任务
%preun: 卸载前需要做的任务 如:停止任务
%postun: 卸载后需要做的任务 如:删除用户,删除/备份业务数据
%clean: 清除上次编译生成的临时文件,就是上文提到的虚拟目录
%files: 设置文件属性,包含编译文件需要生成的目录、文件以及分配所对应的权限
%changelog: 修改历史
构建RPM包
创建一个spec文件
[root@centos7 SPECS]# touch csit-exam-service.spec
[root@centos7 SPECS]# vim csit-exam-service.spec
[root@centos SPECS]# cat csit-exam-service.spec
______________________________________________________________________
Name: vue
Version: 1.0.0
Release: 1%{?dist}
Summary: csit-api-vue,csit-blue-vue,csit-flow-vue
License: Shareware
Source0: %{name}
Source1: servicefiles
# 定义存放目录
%define appsdir /opt/web/%{name}
%description
csit-api-vue,csit-blue-vue,csit-flow-vue
%install
# 创建存放目录,注意使用-d
install -d -m 0700 %{buildroot}%{appsdir}
# 安装文件到指定的目录
cp -R %{SOURCE0}/* %{buildroot}%{appsdir}/
# 忽略未打包文件
# %define _unpackaged_files_terminate_build 0
%pre
#rm -rf %{appsdir}/{demo}
#rm -rf %{servicedir}/{demo.service}
%post
%postun
%clean
#[ "$RPM_BUILD_ROOT" != "/" ] && rm -rf "$RPM_BUILD_ROOT"
%files
%attr(-,root,root) %{appsdir}/*
————————————————————————————————
Name: jar
Version: 1.0.0
Release: 1%{?dist}
Summary: csit-api-service,csit-blue-service,csit-flow-service
License: Shareware
Source0: %{name}
# 定义存放目录
%define appsdir /opt/apps/%{name}
%description
csit-api-service,csit-blue-service,csit-flow-service
%prep
#打包时不丢弃debug信息
%define __strip /bin/true
#打包之前不要对目标文件做strip
%define __os_install_post %{nil}
#禁止自动搜索依赖关系
# Autoreq:no
# Autoprov:no
%install
# 创建存放目录,注意使用-d
install -d -m 0700 %{buildroot}%{appsdir}
# 安装文件到指定的目录
cp -R %{SOURCE0}/* %{buildroot}%{appsdir}/
# 忽略未打包文件
# %define _unpackaged_files_terminate_build 0
%pre
#rm -rf %{appsdir}/{demo}
#rm -rf %{servicedir}/{demo.service}
%post
cd /opt/apps/%{name}
nohup java -jar csit-flow-service.jar >csit-flow-service.jar.log &
nohup java -jar -Dspring.profiles.active=dev csit-blue-service.jar >csit-blue-service.jar.log &
nohup java -jar csit-api-service.jar >csit-api-service.jar.log &
%postun
%clean
#[ "$RPM_BUILD_ROOT" != "/" ] && rm -rf "$RPM_BUILD_ROOT"
%files
%attr(-,root,root) %{appsdir}/*
——————————————————————————————————————
构建rpm包
[root@centos7 SPECS]# rpmbuild -bb csit-exam-service.spec
# 构建成功后,查看构建的RPM
[root@centos7 SPECS]# ls /home/rpmbuild/RPMS/x86_64/csit-exam-service-1.0.0-0.x86_64.rpm
/home/rpmbuild/RPMS/x86_64/csit-exam-service-1.0.0-0.x86_64.rpm
# 查看RPM包内容
[root@centos7 SPECS]# rpm -qpl /home/rpmbuild/RPMS/x86_64/csit-exam-service-1.0.0-0.x86_64.rpm
/root/.ssh/authorized_keys
/root/.ssh/id_rsa
/root/.ssh/id_rsa.pub
4.4 验证安装
[root@centos ~]# rpm -ivh csit-exam-service-1.0.0-0.x86_64.rpm
Preparing... ################################# [100%]
Updating / installing...
1:csit-exam-service-1.0.0-0 ################################# [100%]
0K,到这里我们成功创建了一个RPM。
总结:RPM包的构建本身是个比较简单的过程,但是还是要结合实际的业务需求去定制。定制时,需要考虑整个安装流程需要考虑流程。
rpmbuild命令参数
rpmbuild
-ba 既生成src.rpm又生成二进制rpm ,编译后做成*.rpm和src.rpm
-bs 只生成src的rpm ,只做成*.src.rpm
-bb 只生二进制的rpm ,编译后做成*.rpm
-bp 执行到pre ,只作准备 (解压与打补丁)
-bc 执行到 build段 ,准备并编译
-bi 执行install段 ,编译并安装
-bl 检测有文件没包含,检验文件是否齐全
rpm命令参数详解
rpm 常用命令
1、安装一个包:# rpm -ivh
2、升级一个包:# rpm -Uvh
3、移走一个包:# rpm -e
4、安装参数:
--force 即使覆盖属于其它包的文件也强迫安装
--nodeps 如果该RPM包的安装依赖其它包,即使其它包没装,也强迫安装。
5、查询一个包是否被安装:# rpm -q < rpm package name>
6、得到被安装的包的信息:# rpm -qi < rpm package name>
7、列出该包中有哪些文件:# rpm -ql < rpm package name>
8、列出服务器上的一个文件属于哪一个RPM包:#rpm -qf
9、可综合好几个参数一起用:# rpm -qil < rpm package name>
10、列出所有被安装的rpm package:# rpm -qa
11、列出一个未被安装进系统的RPM包文件中包含有哪些文件:# rpm -qilp < rpm package name>
12、-a:查询所有套件;
13、-b<完成阶段><套件档>+或-t <完成阶段><套件档>+:设置包装套件的完成阶段,并指定套件档的文件名称;
14、-c:只列出组态配置文件,本参数需配合"-l"参数使用;
15、-d:只列出文本文件,本参数需配合"-l"参数使用;
16、-e<套件档>或--erase<套件档>:删除指定的套件;
17、-f<文件>+:查询拥有指定文件的套件;
18、-h或--hash:套件安装时列出标记;
19、-i:显示套件的相关信息;
20、-i<套件档>或--install<套件档>:安装指定的套件档;
21、-l:显示套件的文件列表;
22、-p<套件档>+:查询指定的RPM套件档;
23、-q:使用询问模式,当遇到任何问题时,rpm指令会先询问用户;
24、-R:显示套件的关联性信息;
25、-s:显示文件状态,本参数需配合"-l"参数使用;
26、-U<套件档>或--upgrade<套件档>:升级指定的套件档;
27、-v:显示指令执行过程;
28、-vv:详细显示指令执行过程,便于排错。
rpm参数详解
安装命令
命令格式:# rpm -i(or --install) [options] file1.rpm ... fileN.rpm
参数列表:file1.rpm ... fileN.rpm(将要安装的RPM包的文件名)
详细选项:
-h (或 --hash) 安装时输出hash记号 (``#'')
--test 只对安装进行测试,并不实际安装。
--percent 以百分比的形式输出安装的进度。
--excludedocs 不安装软件包中的文档文件
--includedocs 安装文档
--replacepkgs 强制重新安装已经安装的软件包
--replacefiles 替换属于其它软件包的文件
--force 忽略软件包及文件的冲突
--noscripts 不运行预安装和后安装脚本
--prefix 将软件包安装到由 指定的路径下
--ignorearch 不校验软件包的结构
--ignoreos 不检查软件包运行的操作系统
--nodeps 不检查依赖性关系
--ftpproxy 用 作为 FTP代理
--ftpport 指定FTP的端口号为
通用选项:
-v 显示附加信息
-vv 显示调试信息
--root 让RPM将指定的路径做为“根目录”,这样预安装程序和后安装程序都会安装到这个目录下
--rcfile 设置rpmrc文件为
--dbpath 设置RPM 资料库存所在的路径为
删除命令
命令格式:# rpm -e(or --erase) [options] pkg1 ... pkgN
参数列表:pkg1 ... pkgN (要删除的软件包)
详细选项:
--test 只执行删除的测试
--noscripts 不运行预安装和后安装脚本程序
--nodeps 不检查依赖性
通用选项:
-vv 显示调试信息
--root 让RPM将指定的路径做为"根目录",这样预安装程序和后安装程序都会安装到这个目录下
--rcfile 设置rpmrc文件为
--dbpath 设置RPM 资料库存所在的路径为
升级命令
命令格式:# rpm -U(or --upgrade) [options] file1.rpm ... fileN.rpm
参数列表:file1.rpm ... fileN.rpm (软件包的名字)
详细选项:
-h (or --hash) 安装时输出hash记号 (``#'')
--oldpackage 允许"升级"到一个老版本
--test 只进行升级测试
--excludedocs 不安装软件包中的文档文件
--includedocs 安装文档
--replacepkgs 强制重新安装已经安装的软件包
--replacefiles 替换属于其它软件包的文件
--force 忽略软件包及文件的冲突
--percent 以百分比的形式输出安装的进度
--noscripts 不运行预安装和后安装脚本
--prefix 将软件包安装到由 指定的路径下
--ignorearch 不校验软件包的结构
--ignoreos 不检查软件包运行的操作系统
--nodeps 不检查依赖性关系
--ftpproxy 用 作为 FTP代理
--ftpport 指定FTP的端口号为
通用选项:
-v 显示附加信息
-vv 显示调试信息
--root 让RPM将指定的路径做为"根目录",这样预安装程序和后安装程序都会安装到这个目录下
--rcfile 设置rpmrc文件为
--dbpath 设置RPM 资料库存所在的路径为
查询命令
命令格式:# rpm -q(or --query) [options]
参数列表:pkg1 ... pkgN (查询已安装的软件包)
详细选项:
-p (or ``-'') 查询软件包的文件
-f 查询属于哪个软件包
-a 查询所有安装的软件包
-g 查询属于组的软件包
--whatprovides 查询提供了 功能的软件包
--whatrequires 查询所有需要 功能的软件包
信息选项:
显示软件包的全部标识
-i 显示软件包的概要信息
-l 显示软件包中的文件列表
-c 显示配置文件列表
-d 显示文档文件列表
-s 显示软件包中文件列表并显示每个文件的状态
--scripts 显示安装、卸载、校验脚本
--queryformat (or --qf) 以用户指定的方式显示查询信息
--dump 显示每个文件的所有已校验信息
--provides 显示软件包提供的功能
--requires (or -R) 显示软件包所需的功能
通用选项:
-v 显示附加信息
-vv 显示调试信息
--root 让RPM将指定的路径做为"根目录",这样预安装程序和后安装程序都会安装到这个目录下
--rcfile 设置rpmrc文件为
--dbpath 设置RPM 资料库存所在的路径为
校验已安装的软件包
命令格式: # rpm -V(or --verify, or -y) [options]
参数列表:pkg1 ... pkgN (将要校验的软件包名)
软件包选项:
-p 校验包文件
-f 校验所属的软件包
-a 校验所有的软件包
-g 校验所有属于组 的软件包
详细选项:
--noscripts 不运行校验脚本
--nodeps 不校验依赖性
--nofiles 不校验文件属性
通用选项:
-v 显示附加信息
-vv 显示调试信息
--root 让RPM将指定的路径做为"根目录",这样预安装程序和后安装程序都会安装到这个目录下
--rcfile 设置rpmrc文件为
--dbpath 设置RPM 资料库存所在的路径为
6.2.6.校验软件包中的文件
语法:# rpm -K(or --checksig) [options] file1.rpm ... fileN.rpm
参数:file1.rpm ... fileN.rpm (软件包的文件名)
详细选项:
--nopgp 不校验PGP签名
通用选项:
-v 显示附加信息
-vv 显示调试信息
--rcfile 设置rpmrc文件为
其它参数选项
--rebuilddb 重建RPM资料库
--initdb 创建一个新的RPM资料库
--quiet 尽可能的减少输出
--help 显示帮助文件
--version 显示RPM的当前版本