系列文章目录
rpmbuild基础知识
文章目录
- 系列文章目录
- 前言
- 一、rpmbuild相关操作
- 1、安装rpmbuild命令
- 2、安装spec文件检查工具
- 3、查看rpmbuild版本
- 4、编译工具安装
- 5、修改rpm制作包的默认路径
- 二、资源准备
- 1、创建rpmbuild工作目录
- 2、目录作用解释
- 3、下载redis源码包
- 4、上传redis.conf文件
- 5、上传创建redis实例脚本和创建分布式集群脚本
- 三、构建过程
- 1、redis.spec文件
- 2、修改用户自定义宏相关文件rpmmacros
- 3、创建RPM包签名
- 4、构建带签名的RPM包
- 5、查看结果
- 四、结果演示
- 1、安装构建完成的RPM包
- 2、创建redis实例
- 3、查看RPM包签名到期时间
- 4、卸载redis-rpm包
- 总结
前言
承接rpmbuild基础知识章节和对应的背景要求,开始着手下载redis源码包、编写spec文件、构建出符合要求的redis安装包,具体方法如下所示。
提示:以下构建文件及方式已在centos 7 x86_64系统架构上测试运行,一切均正常
一、rpmbuild相关操作
1、安装rpmbuild命令
[root@python2 ~]# yum install -y rpm-build
[root@python2 ~]# yum install rpmdevtools
2、安装spec文件检查工具
[root@python2 ~]# yum install rpmlint -y
如果返回错误/警告,使用 “-i” 选项查看更详细的信
[root@python2 ~]# rpmlint -i program.spec
也可以使用 rpmlint 测试已构建的 RPM 包,检查 SPEC/RPM/SRPM 是否存在错误。你需要在发布软件包之前,解决这些警告。此页面 提供一些常见问题的解释。如果你位于 SPEC 目录中,请执行:
[root@python2 ~]# rpmlint NAME.spec ../RPMS/*/NAME*.rpm ../SRPMS/NAME*.rpm
3、查看rpmbuild版本
[root@python2 ~]# rpmbuild --version
RPM version 4.11.3
4、编译工具安装
# 编译工具
[root@python2 ~]# yum install -y gcc make gcc-c++
5、修改rpm制作包的默认路径
[root@python2 ~]# echo "%_topdir /export/rpmbuild" >> /root/.rpmmacros
%_topdir /export/rpmbuild #/root/.rpmmacros文件是存储各种宏定义,比如_topdir宏的值来自定义打包路径
二、资源准备
1、创建rpmbuild工作目录
手动创建
[root@python2 ~]# mkdir -p /export/rpmbuild/{BUILD,BUILDROOT,RPMS,SOURCES,SPECS,SRPMS}
rpmdevtools 命令创建
[root@python2 ~]# cd /export/
[root@python2 ~]# rpmdev-setuptree
[root@python2 ~]# cd /export/rpmbuild && ls
BUILD RPMS SOURCES SPECS SRPMS
2、目录作用解释
默认位置 | 宏代码 | 名称 | 用途 |
---|---|---|---|
/export/rpmbuild/SPECS | %_specdir | 文件目录 | 保存 RPM 包配置(.spec)文件 |
/export/rpmbuild/SOURCES | %_sourcedir | 源代码目录 | 保存源码包(如 .tar 包)和所有 patch 补丁 |
/export/rpmbuild/BUILD | %_builddir | 构建目录 | 源码包被解压至此,并在该目录的子目录完成编译 |
/export/rpmbuild/BUILDROOT | %_buildrootdir | 最终安装目录 | 保存 %install 阶段安装的文件 |
/export/rpmbuild/RPMS | %_rpmdir | 标准 RPM 包目录 | 生成/保存二进制 RPM 包 |
/export/rpmbuild/SRPMS | %_srcrpmdir | 源代码 RPM 包目录 | 生成/保存源码 RPM 包(SRPM) |
3、下载redis源码包
将源码包下载至SOURCES目录,专门用于存放源文件
[root@python2 ~]# cd /export/rpmbuild/SOURCES
[root@python2 ~]# wget https://download.redis.io/releases/redis-5.0.9.tar.gz
4、上传redis.conf文件
[root@python2 ~]# cd /export/rpmbuild/SOURCES
[root@python2 ~]# rz
此处替换为自己环境现有的redis.conf文件即可
5、上传创建redis实例脚本和创建分布式集群脚本
将这两个脚本封装到rpm包中去,安装之后可快速执行脚本产生redis实例,并构建出相应的分布式集群
[root@python2 ~]# cd /export/rpmbuild/SOURCES
[root@python2 ~]# rz
create_port_redisconf.sh
#!/bin/bash
# help
useage() {
echo -e "useage: $0 [ port ] [[yes|no cluster] default no]
eg:$0 7889 no|yes\n"
exit 2
}
redis_cluster_conf() {
# redis config file
cat > ${redis_dir}/conf/${port}/redis_${port}.conf << EOF
include ${redis_dir}/conf/redis.conf
daemonize yes
cluster-enabled yes
cluster-config-file "nodes.conf"
cluster-node-timeout 15000
pidfile "${redis_dir}/logs/redis_${port}.pid"
logfile "${redis_dir}/logs/redis_${port}.log"
appendonly no
dir "${redis_dir}/conf/${port}"
port ${port}
# Generated by CONFIG REWRITE
timeout 600
tcp-keepalive 3600
save 900 1
save 300 10
save 60 10000
client-output-buffer-limit normal 0 0 0
repl-timeout 180
repl-backlog-size 50mb
client-output-buffer-limit slave 0 0 0
EOF
}
redis_standard_conf(){
# redis config file
cat > ${redis_dir}/conf/${port}/redis_${port}.conf << EOF
include ${redis_dir}/conf/redis.conf
daemonize yes
pidfile "${redis_dir}/logs/redis_${port}.pid"
logfile "${redis_dir}/logs/redis_${port}.log"
appendonly no
dir "${redis_dir}/conf/${port}"
port ${port}
# Generated by CONFIG REWRITE
timeout 600
tcp-keepalive 3600
save 900 1
save 300 10
save 60 10000
client-output-buffer-limit normal 0 0 0
repl-timeout 180
repl-backlog-size 50mb
client-output-buffer-limit slave 0 0 0
EOF
}
#
if [[ $# -eq 1 && $1 -gt 0 ]] || [[ $# -eq 2 ]];then
port=$1
is_cluster=$2
redis_dir='/export/server/redis'
# create port dir
[ -d ${redis_dir}/conf/${port} ] || mkdir -p ${redis_dir}/conf/${port}
[ -f ${redis_dir}/conf/${port}/redis_${port}.conf ] && echo "${redis_dir}/conf/${port}/redis_${port}.conf File is exits!" && exit 2
#
if echo "${is_cluster[@]}" | grep -w "yes" &>/dev/null;then
# create redis config file
redis_cluster_conf
else
# create redis config file
redis_standard_conf
fi
# create start service file
cat > ${redis_dir}/service_${port}.sh << EOF
#!/bin/bash
# help
useage() {
echo -e "useage: \$0 [ start | stop | restart ]
eg:\$0 start\\n"
exit 2
}
start() {
${redis_dir}/bin/redis-server ${redis_dir}/conf/${port}/redis_${port}.conf
}
stop() {
kill -9 \`cat ${redis_dir}/logs/redis_${port}.pid\`
}
if [[ \$# -eq 1 ]];then
case \$1 in
start)
start
;;
stop)
stop
;;
restart)
stop
start
;;
*)
useage
;;
esac
else
useage
fi
EOF
# add x mode
chmod +x ${redis_dir}/service_${port}.sh
else
useage
fi
create_clusterRedis.sh
#!/bin/bash
redis_home='/export/server/redis'
# help
useage() {
echo -e "useage: $0 [ host1:port host1:port ... ]
eg:$0 127.0.0.1:7001 127.0.0.1:7002 ...\n"
exit 2
}
create() {
${redis_home}/bin/redis-cli --cluster create --cluster-replicas 1 $*
}
if [[ $# -gt 1 ]];then
echo $*
create $*
else
useage
fi
至此,准备工作已完成,下面开始编写spec文件并构建RPM包
三、构建过程
提醒: 详细的rpmbuild相关宏定义、变量定义、构建分成的阶段等文档,在此处不进行细说,自行查看文章顶端的rpmbuild基础知识链接即可
1、redis.spec文件
[root@python2 ~]# cd /export/rpmbuild/SPEC/
[root@python2 SPEC/]# vim redis.spec
#自定义宏,相当于Linux中"Key-Value"变量形式
#--->名称
%define Name redis
#--->版本
%define Version 5.0.9
#--->本rpm包中需更换的配置文件
%define CONFIGFILE redis.conf
#--->本rpm包默认安装的路径
%define InstallPath /export/server/redis
#-->rpm包封装进去的脚本
%define create_port create_port_conf.sh
%define create_cluster create_cluster.sh
%define _build_id_links none
# 软件包的名称
Name: %{Name}
# 软件包的版本
Version: %{Version}
# 软件包发布序列号,1表示第几次打包 %{?dist} 会再包名中添加操作系统系统
Release: 1
# 软件包的概要信息,不要超过50个
Summary: The redis for centos 7 x86_64.
# 软件授权方式
License: BSD
# 软件分类
Group:System Middleware
# 源代码软件包的官方地址或源码包的下载地址
URL: https://download.redis.io/releases/redis-5.0.9.tar.gz
# 源代码软件包的名字
Source0: %{Name}-%{Version}.tar.gz
Source1: %{CONFIGFILE}
Source2: %{create_port}
Source3: %{create_cluster}
# install使用的虚拟目录,安装后就在该目录下打包
BuildRoot: %_topdir/BUILDROOT
#制作过程中用到的软件包
BuildRequires: gcc,automake,autoconf,libtool,make
Requires: bash,jemalloc
#软件包详细描述信息
%description
This is %{Name}
%pre
if getent passwd %{Name} > /dev/null; then
echo "user %{Name} already exist,The installation operation will continue!!!"
else
useradd %{Name} -s /sbin/nologin
fi
# 安装前的准备工作,一般用于解压源码包
%prep
#解压并cd到相关目录 tar xf SOURCES/redis-5.0.9.tar.gz -C BUILD && cd BUILD
%setup -q
# 源码编译 make
%build
make %{?_smp_mflags}
# 源码安装
#目前还是在/export/rpmbuild/BUILD/目录中,执行以下操作
#rm -rf /export/rpmbuild/BUILDROOT
#mkdir -p /export/rpmbuild/BUILDROOT/export/server/redis/{bin,conf,data,logs,script}
%install
%{_rm} -rf %{buildroot} # 清理之前的安装
# 使用 make install 来自动安装到指定目录,替代手动复制文件的步骤
make install PREFIX=%{buildroot}%{InstallPath}
# 创建目录结构,如果make install没有创建(通常不需要,除非有特殊需求)
mkdir -p %{buildroot}%{InstallPath}/{conf,data,logs,script}
# 如果需要,创建必要的符号链接(检查是否已经由 make install 创建)
# ln -s %{buildroot}%{InstallPath}/bin/redis-server %{buildroot}%{InstallPath}/bin/redis-sentinel
# 复制自定义的或额外的配置文件和脚本
cp -rp %{SOURCE1} %{buildroot}%{InstallPath}/conf/
cp -rp %{SOURCE2} %{buildroot}%{InstallPath}/script/
cp -rp %{SOURCE3} %{buildroot}%{InstallPath}/script/
chmod +x %{buildroot}%{InstallPath}/script/*
# 设置文件和目录的所有权
chown -R redis.redis %{buildroot}%{InstallPath}
#卸载前需要做的任务 如:停止任务
%preun
if [ $1 -eq 0 ]; then
echo "Automatically stopping all Redis services..."
for script in %{InstallPath}/service_*.sh; do
if [[ $script =~ service_([0-9]+)\.sh ]]; then
sh $script stop
fi
done
# RPM 卸载操作,备份或移动目录
mkdir -p /export/backup/
if [ -d %{InstallPath} ]; then
cp -rp %{InstallPath} /export/backup/
fi
echo "Redis data has been backed up to /export/backup/."
userdel -r redis
echo "Redis user has been deleted"
fi
#设置文件属性,包含编译文件需要生成的目录、文件以及分配所对应的权限
%files
%defattr(-,redis,redis,-)
%dir %{InstallPath}
%dir %{InstallPath}/bin
%dir %{InstallPath}/conf
%dir %{InstallPath}/data
%dir %{InstallPath}/logs
%dir %{InstallPath}/script
%{InstallPath}/bin/*
%{InstallPath}/conf/*
%{InstallPath}/script/*
#变更日志 第一行的变更时间格式 由date '+* %a %b %d %Y %T %z' 在命令获取然后粘贴即可
%changelog
* Fri Jul 05 2024 14:57:39 +0800
- Initial redis 5.0.9 RPM release
2、修改用户自定义宏相关文件rpmmacros
因为上述的redis.spec文件中引用了不少的宏变量,因此需要在此处定义
[root@python2 ~]# cat /root/.rpmmacros
%_topdir /export/rpmbuild
%_rm /usr/bin/rm
%_signature gpg
%_gpg_path /root/.gnupg/
%_gpg_name rpmbuild
%_gpgbin /usr/bin/gpg
3、创建RPM包签名
该流程和方法详情见文章顶部<rpmbuild基础知识>链接,查看RPM包签名流程部分即可
4、构建带签名的RPM包
#进入到SPEC文件目录下
[root@python2 rpmbuild]# cd SPECS/
[root@python2 SPECS]# ll
total 8
-rw-r--r-- 1 root root 4423 Jul 5 15:03 redis.spec
#执行构建命令
[root@python2 SPECS]# useradd redis -s /sbin/nologin #先创建出redis用户,否则构建会报错
Creating mailbox file: File exists
[root@python2 SPECS]# rpmbuild --sign --bb redis.spec #--sign 指的是构建RPM时指定RPM包签名
#构建过程
[root@python2 SPECS]# rpmbuild --sign --bb redis.spec
+ umask 022
+ cd /export/rpmbuild/BUILD
+ cd /export/rpmbuild/BUILD
+ rm -rf redis-5.0.9
+ /usr/bin/gzip -dc /export/rpmbuild/SOURCES/redis-5.0.9.tar.gz
+ /usr/bin/tar -xf -
+ STATUS=0
+ '[' 0 -ne 0 ']'
+ cd redis-5.0.9
+ /usr/bin/chmod -Rf a+rX,u+w,g-w,o-w .
+ exit 0
+ umask 022
+ cd /export/rpmbuild/BUILD
+ cd redis-5.0.9
+ make
CC Makefile.dep
...... #全部过程就不在此展示了
9100 blocks
+ /usr/lib/rpm/check-buildroot
+ /usr/lib/rpm/redhat/brp-compress
+ /usr/lib/rpm/redhat/brp-strip-static-archive /usr/bin/strip
+ /usr/lib/rpm/brp-python-bytecompile /usr/bin/python 1
+ /usr/lib/rpm/redhat/brp-python-hardlink
+ /usr/lib/rpm/redhat/brp-java-repack-jars
+ umask 022
+ cd /export/rpmbuild/BUILD
+ cd redis-5.0.9
+ /usr/bin/rm -rf /export/rpmbuild/BUILDROOT/redis-5.0.9-1.x86_64
+ exit 0
Enter pass phrase: #这块是签名所要输入的密码地方,然后rpm包才真正的签名成功
Pass phrase is good.
/export/rpmbuild/RPMS/x86_64/redis-5.0.9-1.x86_64.rpm:
/export/rpmbuild/RPMS/x86_64/redis-debuginfo-5.0.9-1.x86_64.rpm:
5、查看结果
[root@python2 SPECS]# cd ../RPMS/x86_64/
[root@python2 x86_64]# ll
total 7300
-rw-r--r-- 1 root root 1364252 Jul 5 21:48 redis-5.0.9-1.x86_64.rpm #这个才是构建出来的RPM包
-rw-r--r-- 1 root root 6107072 Jul 5 21:48 redis-debuginfo-5.0.9-1.x86_64.rpm
至此,通过SPEC文件构建rpm包已完成,具体的rpmbuild指令及spec文件中定义的宏,都可以去查看文章顶部的<rpmbuild基础知识>学习了解到
四、结果演示
1、安装构建完成的RPM包
[root@python2 x86_64]# ll
total 7300
-rw-r--r-- 1 root root 1364252 Jul 5 21:48 redis-5.0.9-1.x86_64.rpm
-rw-r--r-- 1 root root 6107072 Jul 5 21:48 redis-debuginfo-5.0.9-1.x86_64.rpm
[root@python2 x86_64]# rpm -ivh redis-5.0.9-1.x86_64.rpm
Preparing... ################################# [100%]
user redis already exist,The installation operation will continue!!!
Updating / installing...
1:redis-5.0.9-1 ################################# [100%]
2、创建redis实例
#查看安装后的目录结构
[root@python2 redis]# tree
.
├── bin
│ ├── redis-benchmark
│ ├── redis-check-aof
│ ├── redis-check-rdb
│ ├── redis-cli
│ ├── redis-sentinel -> redis-server
│ └── redis-server
├── conf
│ └── redis.conf
├── data
├── logs
└── script
├── create_clusterRedis.sh
└── create_port_Redisconf.sh
5 directories, 9 files
#创建一个端口为7889的redis实例并启动
[root@python2 redis]# sh script/create_port_confRedis.sh 7889 yes
[root@python2 redis]# sh service_7889.sh start
[root@python2 redis]# ps -ef |grep redis
root 11929 1 0 21:54 ? 00:00:00 /export/server/redis/bin/redis-server *:7889 [cluster]
root 11934 1173 0 21:54 pts/0 00:00:00 grep --color=auto redis
#再次查看Redis目录结构
[root@python2 redis]# tree .
.
├── bin
│ ├── redis-benchmark
│ ├── redis-check-aof
│ ├── redis-check-rdb
│ ├── redis-cli
│ ├── redis-sentinel -> redis-server
│ └── redis-server
├── conf
│ ├── 7889
│ │ ├── nodes.conf
│ │ └── redis_7889.conf
│ └── redis.conf
├── data
├── logs
│ ├── redis_7889.log
│ └── redis_7889.pid
├── script
│ ├── create_clusterRedis.sh
│ └── create_port_confRedis.sh
└── service_7889.sh
6 directories, 14 files
由此可见,创建redis实例前后,目录结构也发生了变化,而且redis实例也启动成功,但这个只是单节点的,要想创建一个redis分布式集群,还需要执行 create_clusterRedis.sh ip:port,xx,xx,xx,xx,xx yes才可以,不再详细描述!
3、查看RPM包签名到期时间
#查看签名到期时间
#获取到rpm包中的签名ID eb5c386d788b960f
[root@python2 .gnupg]# rpm -qpi /export/rpmbuild/RPMS/x86_64/redis-5.0.9-1.x86_64.rpm
Name : redis
Version : 5.0.9
Release : 1
Architecture: x86_64
Install Date: (not installed)
Group : System Middleware
Size : 6280870
License : BSD
Signature : RSA/SHA1, Fri 05 Jul 2024 05:02:58 PM CST, Key ID eb5c386d788b960f
Source RPM : redis-5.0.9-1.src.rpm
Build Date : Fri 05 Jul 2024 05:02:46 PM CST
Build Host : python2
Relocations : (not relocatable)
URL : https://download.redis.io/releases/redis-5.0.9.tar.gz
Summary : The redis for centos 7 x86_64.
Description : This is redis
#根据ID查看到期时间
[root@python2 .gnupg]# gpg --list-keys eb5c386d788b960f
pub 4096R/788B960F 2024-07-05 [expires: 2026-07-05]
uid rpmbuild (GPG-RPM-KEY) <rootwxd@163.com>
sub 4096R/4CE2423E 2024-07-05 [expires: 2025-07-05]
4、卸载redis-rpm包
卸载也很顺利,没有任何问题
[root@python2 redis]# rpm -qa |grep redis
redis-5.0.9-1.x86_64
[root@python2 redis]# rpm -e redis-5.0.9-1.x86_64
Automatically stopping all Redis services...
Redis data has been backed up to /export/backup/.
userdel: /var/spool/mail/redis not owned by redis, not removing
Redis user has been deleted
至此,Redis-5.0.9版本的rpm包构建完成,并且也成功的部署到了线上,目前已运行了两周,并未发现任何问题
总结
要想看懂这篇文章,必须先把文章顶部引用的链接文章看几遍并读懂它,然后回过头来再看本文章,就会轻松很多,第一个中间件已通过rpmbuild的形式构建完成,勤能补拙,以描述的背景为例,多加练习构造出合适的rpm包,不仅比源码安装方便还更加利于管理,这样的安装方式谁能不爱呢!!!