Linux手动构建RPM包

一、前言

  在linux上安装软件和模块很多都是通过rpm包安装的,非常的方便。如果多个主机安装文件和脚本也能用rpm包的方式就好了,节省时间和精力,正好看到了一篇文章,本地构建rpm包,试着学了下,所以写下这篇博客记录构建过程,该博客使用到的主机为Centos7。

二、准备

1.首先,打开一个终端会话,使用root用户创建可用于此项目的普通用户 “student”,并为该用户设置密码。

[root@localhost ~]# useradd student
[root@localhost ~]# passwd student
Changing password for user student.
New password: 
Retype new password: 
passwd: all authentication tokens updated successfully.

2.构建 rpm 包需要 rpm-build 包

[root@localhost ~]# yum install rpm-build -y

3.使用student用户打开另一个终端会话并使用。下载教程用的tar包,

https://pan.baidu.com/s/1b_G5hEi61BNAD9vcOpSykw
提取码:5w9y

    此 tar 包包含将由最终 rpm 程序安装的所有文件和 Bash 脚本。 还有一个完整的 spec 文件,你可以使用它来构建 rpm。使用rz命令或者其他工具上传到home目录下,解压缩 tar 包。

[student@localhost ~]$ cd ; tar -xvf utils.tar
./
./development/
./development/scripts/
./development/scripts/create_motd
./development/scripts/die
./development/scripts/mymotd
./development/scripts/sysdata
./development/spec/
./development/spec/utils.spec
./development/license/
./development/license/Copyright.and.GPL.Notice.txt
./development/license/GPL_LICENSE.txt

    使用 tree 命令验证 ~/development 的目录结构和包含的文件,如下所示:

[student@localhost ~]$ tree development/
development/
├── license
│   ├── Copyright.and.GPL.Notice.txt
│   └── GPL_LICENSE.txt
├── scripts
│   ├── create_motd
│   ├── die
│   ├── mymotd
│   └── sysdata
└── spec
    └── utils.spec

 

mymotd 脚本创建一个发送到标准输出的“当日消息”数据流。 create_motd 脚本运行 mymotd 脚本并将输出重定向到 /etc/motd 文件。 此文件用于向使用 SSH 远程登录的用户显示每日消息。

die 脚本将 kill 命令包装在一些代码中,这些代码可以找到与指定字符串匹配的运行程序并将其终止。 它使用 kill -9 来确保 kill 命令一定会执行。

sysdata 脚本可以显示有关计算机硬件,还有已安装的 Linux 版本,所有已安装的软件包以及硬盘驱动器元数据等数万行数据。 

三、创建构建目录结构

rpmbuild 命令需要非常特定的目录结构。 所以需要手动创建目录

[student@localhost ~]$ tree rpmbuild/
rpmbuild/
├── RPMS
│   └── noarch
├── SOURCES
├── SPECS
└── SRPMS

四、检查 spec 文件

每个 spec 文件都有许多部分,其中一些部分可能会被忽视或省略,取决于 rpm 构建的具体情况。 这个特定的 spec 文件不是工作所需的最小文件的示例,但它是一个包含不需要编译的文件的中等复杂 spec 文件的很好例子。 如果需要编译,它将在 %build 部分中执行,该部分在此 spec 文件中省略掉了,因为它不是必需的。

1.前言

这是 spec 文件中唯一没有标签的部分。 它包含运行命令 rpm -qi [Package Name] 时看到的大部分信息。 每个数据都是一行,由标签和标签值的文本数据组成。

###############################################################################
# Spec file for utils
################################################################################
# Configured to be built by user student or other non-root user
################################################################################
#
Summary: Utility scripts for testing RPM creation
Name: utils
Version: 1.0.0
Release: 1
License: GPL
URL: http://www.both.org
Group: System
Packager: David Both
Requires: bash
Requires: screen
Requires: mc
Requires: dmidecode
BuildRoot: ~/rpmbuild/
# Build with the following syntax:
# rpmbuild --target noarch -bb utils.spec

Summary 标签是包的简短描述。

NameVersion 和 Release 标签用于创建 rpm 文件的名称,如 utils-1.00-1.rpm。通过增加发行版号码和版本号,你可以创建 rpm 包去更新旧版本的。

License 标签定义了发布包的许可证。我总是使用 GPL 的一个变体。指定许可证对于澄清包中包含的软件是开源的这一事实非常重要。这也是我将 License 和 GPL 语句包含在将要安装的文件中的原因。

URL 通常是项目或项目所有者的网页。

Group 标签很有趣,通常用于 GUI 应用程序。 Group 标签的值决定了应用程序菜单中的哪一组图标将包含此包中可执行文件的图标。与 Icon 标签(我们此处未使用)一起使用时,Group 标签允许在应用程序菜单结构中添加用于启动程序的图标和所需信息。

Packager 标签用于指定负责维护和创建包的人员或组织。

Requires 语句定义此 rpm 包的依赖项。每个都是包名。如果其中一个指定的软件包不存在,将尝试在 /etc/yum.repos.d 中定义的某个已定义的存储库中找到它,如果存在则安装它。如果 DNF 找不到一个或多个所需的包,它将抛出一个错误,指出哪些包丢失并终止。

BuildRoot 行指定顶级目录,rpmbuild 工具将在其中找到 spec 文件,并在构建包时在其中创建临时目录。完成的包将存储在我们之前指定的 noarch 子目录中。

注释显示了构建此程序包的命令语法,包括定义了目标体系结构的 –target noarch 选项。因为这些是 Bash 脚本,所以它们与特定的 CPU 架构无关。如果省略此选项,则构建将选用正在执行构建的 CPU 的体系结构。

rpmbuild 程序可以针对许多不同的体系结构,并且使用 --target 选项允许我们在不同的体系结构主机上构建特定体系结构的包,其具有与执行构建的体系结构不同的体系结构。所以我可以在 x86_64 主机上构建一个用于 i686 架构的软件包,反之亦然。

如果你有自己的网站,请将打包者的名称更改为你自己的网站。

2.描述部分(%description

 spec 文件的 %description 部分包含 rpm 包的描述。 它可以很短,也可以包含许多信息。 我们的 %description 部分相当简洁。

%description
A collection of utility scripts for testing RPM creation.

3.准备部分(%prep

%prep 部分是在构建过程中执行的第一个脚本。 在安装程序包期间不会执行此脚本。

这个脚本只是一个 Bash shell 脚本。 它准备构建目录,根据需要创建用于构建的目录,并将相应的文件复制到各自的目录中。 这将包括作为构建的一部分的完整编译所需的源代码。

$RPM_BUILD_ROOT 目录表示已安装系统的根目录。 在 $RPM_BUILD_ROOT 目录中创建的目录是真实文件系统中的绝对路径,例如 /user/local/share/utils/usr/local/bin 等。

对于我们的包,我们没有预编译源,因为我们的所有程序都是 Bash 脚本。 因此,我们只需将这些脚本和其他文件复制到已安装系统的目录中。

请注意,本节末尾的 exit 语句是必需的。

4.文件部分(%files

spec 文件的 %files 这一部分定义了要安装的文件及其在目录树中的位置。 它还指定了要安装的每个文件的文件属性(%attr)以及所有者和组所有者。 文件权限和所有权是可选的,但我建议明确设置它们以消除这些属性在安装时不正确或不明确的任何可能性。 如果目录尚不存在,则会在安装期间根据需要创建目录。

%files
%attr(0744, root, root) /usr/local/bin/*
%attr(0644, root, root) /usr/local/share/utils/*

4.1 安装前(%pre

在我们测试项目的 spec 文件中,此部分为空。 这应该放置那些需要 rpm 中的文件安装前执行的脚本。

4.2 安装后(%post

spec 文件的这一部分是另一个 Bash 脚本。 这个在文件安装后运行。 此部分几乎可以是你需要或想要的任何内容,包括创建文件、运行系统命令以及重新启动服务以在进行配置更改后重新初始化它们。 我们的 rpm 包的 %post 脚本执行其中一些任务。

%post
################################################################################
# Set up MOTD scripts                                                          #
################################################################################
cd /etc
# Save the old MOTD if it exists
if [ -e motd ]
then
   cp motd motd.orig
fi
# If not there already, Add link to create_motd to cron.daily
cd /etc/cron.daily
if [ ! -e create_motd ]
then
   ln -s /usr/local/bin/create_motd
fi
# create the MOTD for the first time
/usr/local/bin/mymotd > /etc/motd

4.3 卸载后(%postun

此部分包含将在卸载 rpm 软件包后运行的脚本。 使用 rpm 或 dnf 删除包会删除文件部分中列出的所有文件,但它不会删除安装后部分创建的文件或链接,因此我们需要在本节中处理。

此脚本通常由清理任务组成,只是清除以前由 rpm 安装的文件,但 rpm 本身无法完成清除。 对于我们的包,它包括删除 %post 脚本创建的链接并恢复 motd 文件的已保存原件。

%postun
# remove installed files and links
rm /etc/cron.daily/create_motd
# Restore the original MOTD if it was backed up
if [ -e /etc/motd.orig ]
then
   mv -f /etc/motd.orig /etc/motd
fi

4.4 清理(%clean

这个 Bash 脚本在 rpm 构建过程之后开始清理。 下面 %clean 部分中的两行删除了 rpm-build 命令创建的构建目录。 在许多情况下,可能还需要额外的清理。

%clean
rm -rf $RPM_BUILD_ROOT/usr/local/bin
rm -rf $RPM_BUILD_ROOT/usr/local/share/utils

4.5 变更日志(%changelog

此可选的文本部分包含 rpm 及其包含的文件的变更列表。最新的变更记录在本部分顶部。使用你自己的姓名和电子邮件地址替换标题行中的数据。

%changelog
* Wed Aug 29 2018 Your Name <Youremail@yourdomain.com>
  - The original package includes several useful scripts. it is
    primarily intended to be used to illustrate the process of
    building an RPM.

五、构建RPM

spec 文件必须位于 rpmbuild 目录树的 SPECS 目录中。 我发现最简单的方法是创建一个指向该目录中实际 spec 文件的链接,以便可以在开发目录中对其进行编辑,而无需将其复制到 SPECS 目录。 将 SPECS 目录设为当前工作目录,然后创建链接。

cd ~/rpmbuild/SPECS/
ln -s ~/development/spec/utils.spec

运行以下命令以构建 rpm。 如果没有错误发生,只需要花一点时间来创建 rpm。

rpmbuild --target noarch -bb utils.spec

检查 ~/rpmbuild/RPMS/noarch 目录以验证新的 rpm 是否存在。

[student@localhost ~]$ cd rpmbuild/RPMS/noarch/
[student@localhost noarch]$ ll
total 20
-rw-rw-r--. 1 student student 19848 Feb 20 10:21 utils-1.0.0-1.noarch.rpm
[student@localhost noarch]$ 

五、测试RPM

以 root 用户身份安装 rpm 以验证它是否正确安装并且文件是否安装在正确的目录中。 rpm 的确切名称将取决于你在前言部分中标签的值,但如果你使用了示例中的值,则 rpm 名称将如下面的示例命令所示:.

[root@localhost noarch]# rpm -ivh utils-1.0.0-1.noarch.rpm 
Preparing...                          ################################# [100%]
Updating / installing...
   1:utils-1.0.0-1                    ################################# [100%]
[root@localhost noarch]# 

检查 /usr/local/bin 以确保新文件存在。 你还应验证是否已创建 /etc/cron.daily中的 create_motd 链接。

使用 rpm -q --changelog utils 命令查看更改日志。 使用 rpm -ql utils 命令(在 ql 中为小写 L )查看程序包安装的文件。

[root@localhost bin]# rpm -q --changelog utils
* Wed Aug 29 2018 <Youremail@yourdomain.com>
- The original package includes several useful scripts. it is
    primarily intended to be used to illustrate the process of
    building an RPM.

[root@localhost bin]# rpm -ql utils
/usr/local/bin/create_motd
/usr/local/bin/die
/usr/local/bin/mymotd
/usr/local/bin/sysdata
/usr/local/share/utils/Copyright.and.GPL.Notice.txt
/usr/local/share/utils/GPL_LICENSE.txt
/usr/local/share/utils/utils.spec

 用ssh工具ssh虚拟机,效果如下。

删除包

rpm -e utils
posted @ 2020-02-20 23:28  HuTiger  阅读(1411)  评论(0编辑  收藏  举报