Centos RPM安装包制作

1. 准备

操作系统: CentOS7

安装rpm制作工具

sudo yum install -y rpmdevtools

准备:

  • 可执行程序:main
  • systemd配置: myrpm.service

程序和配置文件见参考附录

2. 打包

可以选择其中一种方式打包:

  • 默认打包:适合快速入门。
  • 自定义打包:适合灵活配置参数。

以制作Systemd服务安装包为例演示打包过程。

2.1 默认打包

2.1.1 初始化

使用构建命令创建打包过程中的目录

rpmdev-setuptree

命名执行成功后会在当前用户/home/用户名目录下创建rpmbuild目录
在这里插入图片描述

这里就不对这些目录进行详细介绍了,如果想要了解详细请看 这里

我们将上一步准备好的可执行程序main和systemd配置文件myrpm.service放入到生成的BUILD目录中,如下

在这里插入图片描述

2.1.2 编写构建指令文件

我们在SPECS下创建一个名为myrpm.specs的文件

touch ~/rpmbuild/SPECS/myrpm.specs

编辑该文件输入下面内容

Name: myrpm
Version: 1.0.0
Release: 1%{?dist}
Summary: Test rpm build
License: free
Requires: glibc >= 2.17
%description
my rpm package test

%install
mkdir -p ${RPM_BUILD_ROOT}/usr/local/myrpm/
mkdir -p ${RPM_BUILD_ROOT}/usr/lib/systemd/system/

cp -f main ${RPM_BUILD_ROOT}/usr/local/myrpm/main
cp -f myrpm.service ${RPM_BUILD_ROOT}/usr/lib/systemd/system/myrpm.service

# 安装完成后执行
%post
systemctl daemon-reload

# 卸载前执行
%preun
systemctl stop myrpm.service
systemctl disable myrpm.service
systemctl daemon-reload
systemctl reset-failed

# 卸载后文件删除完成后触发
%postun

# 规定那些文件必须放入安装程序中,如果没有就报错,清单中的文件将在卸载时被删除。
%files
%defattr(-,root,root)
/usr/local/myrpm/main
/usr/lib/systemd/system/myrpm.service
# 如果有需要保留的配置在卸载或升级时不删除可以使用下面语法
# %config(noreplace) /usr/local/myrpm/config.yaml

文件开始的一系列定义如Name之类配置我就不详细介绍,根据自己的程序需要调整相应的内容就行。
其他内容根据需要请见 3. 构建文件解析章节

注意若程序需要有一些文件在卸载或升级时不想删除时候可以使用 %config(noreplace) 指令标记 [7]

2.1.3 打包

打包过程使用

rpmbuild -bb SPECS/myrpm.specs

一会后打包就完成了

在这里插入图片描述
打包完成后目录结构如下

在这里插入图片描述

安装包生成于RPMS目录下。

2.2 自定义打包

2.2.1 自定义工作目录

rpmdev-setuptree工具默认将在当前用户目录下的创建rpmbuild目录,这种方式不够灵活。

下面介绍一种可以自定义任意目录为rpmbuild目录的方式。

例如需要指定/www/rpmbuild作为打包目录,由于没有了rpmdev-setuptree,我们需要手动创建rpmbuild内部的目录结构

mkdir /www/rpmbuild
cd /www/rpmbuild

构建目录结构:

cd /www/rpmbuild

mkdir BUILD
mkdir BUILDROOT
mkdir RPMS
mkdir SOURCES
mkdir SPECS
mkdir SRPMS

打包和SPEC文件流程和之前的描述的一致,在打包命令上有些不同。

rpmbuild -bb --define "_topdir /www/rpmbuild"  SPECS/myrpm.specs

需要额外定义一个名为_topdir变量,通过该变量指定打包目录位置。

2.2.2 自定义架构

对于需要打包成不同平台的情况,还可以追加--target参数:

x86架构64位:

rpmbuild -bb   SPECS/myrpm.specs --target x86_64

x86架构32位:

rpmbuild -bb   SPECS/myrpm.specs --target i386

ARM架构64位:

rpmbuild -bb   SPECS/myrpm.specs --target aarch64

2.3 测试

安装

sudo rpm -ivh RPMS/x86_64/myrpm-1.0.0-1.el7.x86_64.rpm 

启动服务

sudo systemctl start myrpm

查看日志打印

journalctl -f -u myrpm

在这里插入图片描述

关闭服务

sudo systemctl stop myrpm

卸载软件

sudo rpm -evh myrpm

卸载后我们在通过ls命令查看一下我们之前创建的位置,可以发现目录和文件已经删除。

3. 构建文件解析

3.1 安装阶段

安装阶段就是%install之后执行的脚本,主要工作就是创建目录,然后把相应的文件放到指定目录中去。

mkdir -p ${RPM_BUILD_ROOT}/usr/local/myrpm/
mkdir -p ${RPM_BUILD_ROOT}/usr/lib/systemd/system/
  • 首先创建安装目录,通过 ${RPM_BUILD_ROOT} + 绝对路径 来表示我们希望安装到的操作系统内位置

例如: ${RPM_BUILD_ROOT}/usr/local/myrpm/表示安装后的操作系统的/usr/local/myrpm/路径。

  • 接下来就是把我们准备的文件从BUILD目录拷贝到刚才创建的相应目录中去
cp -f main ${RPM_BUILD_ROOT}/usr/local/myrpm/main
cp -f myrpm.service ${RPM_BUILD_ROOT}/usr/lib/systemd/system/myrpm.service

在打包安装过程中打包程序会自动切换目录到BUILD所以我们直接使用相对路径进行文件的复制。
cp -f main .... 就表示从BUILD/main

3.2 安装完成阶段

安装完成阶段也就是执行%post后面的脚本。

由于是systemd服务的安装,在我们把文件复制到指定位置之后需要调用systemd的命令重新加载服务。

systemctl daemon-reload

所以这里只有一行,就是用于重新加载服务。

3.3 卸载

卸载阶段就是当我们执行rpm -e命令时候,首先执行%preun ,然后对文件清单中的文件进行删除,文件删除结束后再执行%postun脚本。

这里我们在卸载前先停止服务(防止文件句柄打开无法删除文件),然后重新加载下Systemd服务

systemctl stop myrpm.service
systemctl disable myrpm.service
systemctl daemon-reload
systemctl reset-failed

3.4 打包文件检查

在打包之前对文件再进行一次检查,也就是$files,如果列表中的文件没有在安装路径中找到那么就会报错。
我们这里只有两个文件要复制,所以填入了两个文件的绝对路径,在文件列表的文件将会在卸载阶段被删除。

/usr/local/myrpm/main
/usr/lib/systemd/system/myrpm.service

加入我们把myrpm.service删除,并且注释掉cp命令,然后在构建那么就会失败

在这里插入图片描述

3.5 自定义打包后的文件名

也可以定义环境变量来自定义打包后的文件名,例如

...
%define _rpmfilename %%{NAME}.%%{VERSION}.el7.%%{ARCH}.rpm
....

上述的%%{NAME} 是引用上下文中的环境变量也就是 .specs文件中定义的Name属性。

RPM的默认值为

%%{ARCH}/%%{NAME}-%%{VERSION}-%%{RELEASE}.%%{ARCH}.rpm

5. 高级

5.1 关闭压缩

当文件中存在较大的文件每次rpmbuild时都会对文件进行gzip压缩,导致每次打包时间过长,在制作测试过程中非常耗时,可以通过下面两个宏定义设置压缩算法为不压缩[9]

%define _source_payload w0.gzdio
%define _binary_payload w0.gzdio

注意:%define 作为宏无法注释,若需要恢复压缩,请删除定义。

例如:

...

License:           MIT

# 取消压缩
%define _source_payload w0.gzdio
%define _binary_payload w0.gzdio

%description
Simple rpm demonstration.

...

5.2 卸载不删除配置文件

软件安装后的配置文件:

  • 经过用户修改则不删除,升级时也不替换。
  • 未经修改则删除,升级时备份并替换。

%files 阶段中使用%config(noreplace) 标记需要保护文件 [7]

%files
%config(noreplace) /etc/app/application.yaml

例如:

%files
%defattr(-,root,root)
/usr/local/myrpm/main
/usr/lib/systemd/system/myrpm.service
%config(noreplace) /etc/myrpm/application.yaml

5.3 判断升级/卸载

在软件升级时不希望删除数据文件,而在卸载时删除,RPM会在每个阶段中预置环境变量用于说明当前所处状态,读取变量并通过脚本判断[10]
在这里插入图片描述
例如:

%postun
# 卸载时删除文件,升级时忽略
if [ $1 -lt 0 ]; then
   echo "delete file...."
fi

A. 附录

A.1 可执行程序

main.go

package main

import (
	"log"
	"os"
	"os/signal"
	"time"
)

func main() {
	c := make(chan os.Signal)
	signal.Notify(c)
	tick := time.Tick(time.Second)
	for {
		select {
		case <-tick:
			log.Println("")
		case s := <-c:
			log.Printf("程序关闭 Signal [%v]", s)
			return
		}
	}
}

编译,得到main

go build main.go

A.2 Systemd服务配置

myrpm.service

[Unit]
Description=my rpm services
After=network.target

[Service]
WorkingDirectory=/usr/local/myrpm
ExecStart=/usr/local/myrpm/main
Type=simple
PIDFile=/usr/local/myrpm/myrpm.pid
Restart=always
RestartSec=5

[Install]
WantedBy=default.target

5. 参考文献

[1]. rpmbuild制作rpm 包 . 双斜杠少年 . https://blog.csdn.net/u012373815/article/details/73257754
[2]. go-应用-打包-rpm-发布 . 点点滴滴 . http://www.tang-lei.com/2019/09/05/go-%E5%BA%94%E7%94%A8-%E6%89%93%E5%8C%85-rpm-%E5%8F%91%E5%B8%83/
[3]. golang 使用 rpm 包交付部署 . 鼎铭 . 2018-04-02 . https://studygolang.com/articles/12731
[4]. Redhat . https://rpm-packaging-guide.github.io/
[5]. 博客园 . 使用spec文件语法创建一个rpm . rebeca8 . 2017.08 . https://www.cnblogs.com/zafu/p/7423758.html
[6]. 博客园 . RPM 包的构建 - SPEC 基础知识 . Michael翔 . 2019.03 . https://www.cnblogs.com/michael-xiang/p/10480809.html
[7]. pureage . RPM 中的 %config 和 %config(noreplace) . 纯真年代 . 2014.04 . https://pureage.info/2014/04/30/noreplace-in-rpm-spec-file.html
[8]. rpm . https://rpm.org/index.html
[9]. stackoverflow . rpmbuild change compression format . Aaron D. Marasco . 2023.05 . https://stackoverflow.com/questions/9292243/rpmbuild-change-compression-format
[10]. CSDN . Spec文件中判断是升级or卸载 . Mr_buffoon . 2018.07 . https://blog.csdn.net/mrbuffoon/article/details/81105169

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值