RPM打包用户指南
程序员文章站
2022-05-29 11:07:06
...
基于CentOS 7系列的软件工程在开发完成之后,总有一个如何发布的问题,通常的选择是以RPM资源包的形式发布,这需要开发者额外开发rpm打包脚本(project.spec),但在实际开发过程中几乎每次新工程代码发布流程总是遇到各种坑,诸多不顺。下面以一个简单脚本的打包流程为例梳理整个打包流程。
1. 安装工具
[[email protected] ~]$ which rpmbuild
/usr/bin/rpmbuild
[[email protected] ~]$ rpm -q -f /usr/bin/rpmbuild
rpm-build-4.11.3-17.el7.x86_64
打包需要事先在CentOS中安装相应的rpm-build包。
2. 环境配置
首先,检查topdir顶层目录配置。其中RPM相关的配置项在/usr/lib/rpm目录下:
[[email protected] ~]$ grep -rn _topdir /usr/lib/rpm/*
/usr/lib/rpm/macros:159:%_builddir %{_topdir}/BUILD
/usr/lib/rpm/macros:214:%_rpmdir %{_topdir}/RPMS
/usr/lib/rpm/macros:222:%_sourcedir %{_topdir}/SOURCES
/usr/lib/rpm/macros:226:%_specdir %{_topdir}/SPECS
/usr/lib/rpm/macros:229:%_srcrpmdir %{_topdir}/SRPMS
/usr/lib/rpm/macros:232:%_buildrootdir %{_topdir}/BUILDROOT
/usr/lib/rpm/macros:241:%_topdir %{getenv:HOME}/rpmbuild
其实topdir可以指定到任意目录,这个顶层目录作为之后打包发布的顶层目录,可配置为:
echo '%_topdir %(echo $HOME)/rpmbuild' > ~/.rpmmacros
然后,创建打包目录,采纳默认的顶层目录为/home_dir/rpmbuild,在该顶层目录下面创建如下目录结构:
mkdir -p ~/rpmbuild/{BUILD,RPMS,SOURCES,SPECS,SRPMS}
到此,打包环境准备完成,之后便是经常出错的打包脚本开发阶段。
3. 一个简单shell脚本打包成RPM包
首先,整个目录结构组织形式如下:
[[email protected] rpmbuild]$ tree
.
├── BUILD <--编译目录
│ ├── bridge-daemon.init
│ └── bridge-daemon.spec
├── BUILDROOT <--临时安装目录,rpmbuild打包该目录生成RPM资源包
├── RPMS <--生成的RPM资源包存放路径
│ └── x86_64
│ └── bridge-daemon-0.0.1-el7.x86_64.rpm
├── SOURCES <--源码目录
├── SPECS <--打包脚本默认路径(可按需存放到其他路径)
└── SRPMS <--SourceRPM包路径,用于发布源代码
7 directories, 3 files
其中System V初始化脚本如下所示,同时满足:
将bridge-daemon设置成开机自启服务
通过System V管理bridge-daemon的整个生命周期
[[email protected] BUILD]$ cat bridge-daemon.init
#!/bin/bash
export LANG=C
. /etc/init.d/functions
umask 133
start() {
action "Prepare bridge-daemon: "
BR=bridge-daemon
if [ -d /sys/class/net/$BR/bridge/. ]; then
ifconfig $BR down
brctl delbr $BR
else
brctl addbr $BR
ifconfig $BR 192.16.0.1/20 up
fi
if [ $? != 0 ] ; then
exit 1
fi
}
stop() {
action "Stop bridge-daemon bridge!"
BR=bridge-daemon
if [ -d /sys/class/net/$BR/bridge/. ]; then
ifconfig $BR down
brctl delbr $BR
fi
}
restart() {
stop
start
}
status() {
action "Checking bridge-daemon status: "
ifconfig | grep bridge-daemon
}
case "$1" in
start)
start
;;
stop)
stop
;;
restart)
restart
;;
status)
status
;;
*)
echo $"Usage: bridge-daemon {start|stop|restart|status}"
exit 1
esac
exit $?
4. SPEC打包规则文件
RPM打包最重要的开发工作便是负责RPM执行动作的SPEC脚本的开发,其有一套自定义的语法规则,特别是一些全局变量的定义,相关配置项在/usr/lib/rpm目录下。SPEC开发过程中遇到非常多的全局%variable定义,正是这些变量导致了几乎每次新发布总会踩到一些坑,并且有些变量在各Linux平台下不通用,各有各的定义。其中常用变量定义如下:
[[email protected] BUILD]$ cat bridge-daemon.spec
Summary: Prepare net environment #介绍域,包名、版本等信息
Name: bridge-daemon
Version: 0.0.1
Release: el7
License: GPL
Group: System Environment/Base
ExclusiveArch: x86_64
%description
bridge-daemon prepare net bridge environment
%define __spec_install_pre /bin/true #为了保留BUILDROOT目录下的中间产物
%prep #准备阶段,主要是为后续执行的准备工作
mkdir -p %{buildroot}%{_sysconfdir}/rc.d/init.d
install -c -m 755 $OLDPWD/bridge-daemon.init %{buildroot}%{_sysconfdir}/rc.d/init.d/bridge-daemon
exit 0
%build #编译阶段,比如编译C工程的configure,make等操作
%install #安装阶段
%clean #一个良好的习惯就是清理临时安装目录
rm -rf %{buildroot}
%files #待安装文件列表
%{_sysconfdir}
%post #安装后执行的脚本域
/sbin/chkconfig --add bridge-daemon
/sbin/chkconfig bridge-daemon on
echo "running post scriplet"
/sbin/service bridge-daemon start
%pre #安装前执行的脚本域
if [ $1 -eq 2 ]; then
/sbin/service bridge-daemon stop >/dev/null 2>&1
fi
%preun #卸载前(pre-uninstall)执行的脚本域
if [ $1 -eq 0 ]; then
/sbin/service bridge-daemon stop
fi
%changelog
* Tue Jun 27 2017 Elvis Huang <[email protected]>
- Initial rpm packaging for bridge-daemon
最后执行动作生成RPM资源包:
[[email protected] BUILD]$ rpmbuild -bb bridge-daemon.spec
检查资源包内容:
[[email protected] x86_64]$ rpm -qpl bridge-daemon-0.0.1-el7.x86_64.rpm
/etc
/etc/rc.d
/etc/rc.d/init.d
/etc/rc.d/init.d/bridge-daemon
至此,RPM打包流程介绍完毕。之后便是熟悉的通过RPM发布的资源安装管理
[[email protected] x86_64]$ sudo rpm -ivh bridge-daemon-0.0.1-el7.x86_64.rpm
Preparing... ################################# [100%]
Updating /installing... 1:bridge-daemon-0.0.1-el7 #############[100%]
running post scriplet
Starting bridge-daemon (via systemctl): [ OK ]
[[email protected] x86_64]$ ifconfig
bridge-daemon: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.16.0.1 netmask 255.255.240.0 broadcast 192.16.15.255
inet6 fe80::54e1:bcff:fecf:c701 prefixlen 64 scopeid 0x20<link>
ether 56:e1:bc:cf:c7:01 txqueuelen 0 (Ethernet)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 27 bytes 3924 (3.8 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 0 (Local Loopback)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
上一篇: 制作src.rpm包(龙芯适用)