欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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
相关标签: RPM