RedHat系列软件打包实例(二)

  上一篇算是对RPM软件一个简单的入门介绍。这一篇文章里,将对spec文件的各个参数进行较详细的探究和学习。其次,我们也将对strtest软件包进行改造,让它变的在Linux平台更“专业”像样一点。

1.修改strtest文件

  这里,我们对strtest的源代码进行修改,让它变成一个类似于后台服务进程一样的。
  当然不想弄一个复杂的服务端出来,因为这里只是进行验证测试:就让strtest心跳2s输出自己还活着的信息。由于现在的系统服务管理经过一段时间无力的抵制和抗议之后,全部屈服成systemd的了,所以这边也添加一个systemd的服务管理单元。
  src/str.cpp的代码内容如下(原谅我一个披着CPP的纯C)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
[makerpm@localhost SPECS]$ cat ~/dist/strtest-1.0.2/src/str.cpp 
#include "str.h"
#include <unistd.h>
#include <stdio.h>
#include <time.h>
#include <sys/time.h>

const char* logfile = "/var/log/strtest.log";

int main(int argc , char **argv) {

struct timeval tv;
time_t timet;
struct tm* timep;
FILE* fp = fopen(logfile,"a");

if(!fp) {
fprintf(stderr,"Open logfile[%s] failed!\n", logfile);
return -1;
}

time(&timet);
timep = localtime(&timet);

fprintf(fp, "[%d-%d-%d %d:%d:%d]Starting service [%s] ...\n", timep->tm_year, timep->tm_mon, timep->tm_mday,
timep->tm_hour, timep->tm_min, timep->tm_sec, argv[0]);

while(true) {
fprintf(fp, "service[%s], I am alive --", argv[0]);
if(!gettimeofday(&tv, NULL)) {
fprintf(fp, "system time info:%ds-%dus\n", tv.tv_sec, tv.tv_usec);
}
fflush(fp);
sleep(2);
}

fclose(fp);
return 0;
}

2.添加strtest的systemd管理单元

2.1编写service文件

  systemd依赖于service文件管理服务,放置在/usr/lib/systemd/目录下,注意的是,systemd管理单元应当是操作系统的一部分,而不是strtest软件代码的一部分,不应当打包到源代码下面,而应该将下面的strtest.service放到和strtest-1.0.2.tar.bz2一样的~/rpmbuild/SOURCES/目录下面。(这个service文件是抄袭的openssh滴!)关于systemd的相关信息,后面可能还会再学习整理,这里先不细究。

1
2
3
4
5
6
7
8
9
10
11
12
13
[makerpm@localhost SOURCES]$ cat strtest.service 
[Unit]
Description=Strtest server daemon

[Service]
ExecStart=/usr/bin/strtest $OPTIONS
ExecReload=/bin/kill -HUP $MAINPID
KillMode=process
Restart=on-failure
RestartSec=42s

[Install]
WantedBy=multi-user.target

2.2 修正spec文件

  修改strtest的源代码,对spec文件没有影响(主要是版本号和修改日志等无关紧要的)。目前主要修改使得strtest.service打包进去:
  在%install部分,添加如下内容

1
2
3
# 用于安装systemd服务
install -d -m755 $RPM_BUILD_ROOT/%{_unitdir}
install -m644 %{SOURCE1} $RPM_BUILD_ROOT/%{_unitdir}/strtest.service

然后在%file部分,添加如下内容

1
%{_unitdir}/strtest.service

OK, we all done!

2.3 演示效果

  打包,然后更新strtest软件后,如预期的,它华丽丽地工作啦!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
 user@localhost  ~  sudo systemctl start strtest
user@localhost  ~  sudo systemctl status strtest
● strtest.service - Strtest server daemon
Loaded: loaded (/usr/lib/systemd/system/strtest.service; disabled; vendor preset: disabled)
Active: active (running) since Thu 2015-10-01 23:50:10 CST; 7s ago
Main PID: 45603 (strtest)
CGroup: /system.slice/strtest.service
└─45603 /usr/bin/strtest

Oct 01 23:50:10 localhost.localdomain systemd[1]: Started Strtest server daemon.
Oct 01 23:50:10 localhost.localdomain systemd[1]: Starting Strtest server daemon...
user@localhost  ~  sudo tail -f /var/log/strtest.log
[115-9-1 23:50:10]Starting service [/usr/bin/strtest] ...
service[/usr/bin/strtest], I am alive --system time info:1443714610s-509937us
service[/usr/bin/strtest], I am alive --system time info:1443714612s-511546us
service[/usr/bin/strtest], I am alive --system time info:1443714614s-512393us
service[/usr/bin/strtest], I am alive --system time info:1443714616s-513700us

3.spec文件的其它特性

3.1 patch补丁包

  觉得patch功能是这里面最重要的功能,因为你没有办法控制upstream的软件包,所以你的修改需要以补丁的形势和upstream的软件包共存。下面将我们的strtest添加一些补丁信息
Patch0

3.2 其它标签

BuildArch: noarch
BuildRequires:编译软件包所需的依赖包列表,以逗号分隔
Requires: 安装软件包时所需的依赖包列表,以逗号分隔(大多数情况下,rpmbuild 会自动探测依赖,所以可能不需要 Requires 标签)
prep:
file