个性化定制RPM包

详细介绍 rpm 包制作的步骤。


开始

本小节将介绍两种制作RPM包的方法,分别是:

  • 使用rpmbuild + Mock制作rpm包

  • FPM制作rpm包

如果对rpm相关知识不太了解的,可先看下max-rpm,是由redhat员工编写的rpm手册,前半部分是讲rpm基础知识,后半部分是介绍如何制作rpm包.

本文的rpm包下载地址

使用rpmbuild构建rpm包

注意

不要使用root用户构建rpm,不要使用root用户构建rpm,不要使用root用户构建rpm

安装rpmbuild

yum install rpm-build rpmdevtools

查看宏变量

rpmbuild定义了很多内置的宏变量,可用于在spec文件中引用,我们需要且重视的一个宏变量就是_topdir,请确保其指向的是当前用户下的rpmbuild目录而不是其他目录。

查看默认的宏变量有如下三种方法:

rpmbuild --showrc |grep _topdir

rpm --eval %{_topdir}

rpmbuild --eval %{_topdir}

下面列举出一下常用的宏变量指向的目录路径:

rpmbuild --eval '%_topdir'   ------>  /home/echoxu/rpmbuild
rpmbuild --eval '%_localstatedir'  ------>    /var
rpmbuild --eval '%_builddir'   ------>  /home/echoxu/rpmbuild/BUILD
rpmbuild --eval '%_sysconfdir'  ------>       /etc
rpmbuild --eval '%_sbindir'   ------>    /usr/sbin
rpmbuild --eval '%_libdir'   ------>   /usr/lib64
rpmbuild --eval '%{_tmppath}'  ------>      /var/tmp
rpmbuild --eval '%{_datadir}'  ------>    /usr/share

修改宏变量

用命令echo '%_topdir /home/echoxu/rpmbuild' > ~/.rpmmacros即可修改_topdir宏变量指向的路径

生成rpmbuild目录结构

使用rpmdev-setuptree 会自动生成构建rpm所需的目录,当然也可通过命令mkdir -pv rpmworkshop/{BUILD,RPMS,SOURCES,SPECS,SRPMS}手动创建 ,ps: 上面的rpmdev-setuptree命令是由rpmdevtools提供的。

默认会在当前用户家目录下生成如下目录:

├── BUILD      # 源码包解压后存放的路径以及编译相关源码包时的工作目录
├── BUILDROOT   #  虚拟安装目录
├── RPMS        # 生成的二进制格式的RPM包存放的位置;
├── SOURCES     # 构建rpm包时用到的源码包及辅助文件存放的位置
├── SPECS       # spec文件存放的位置
└── SRPMS        # 生成的src格式的RPM包存放的位置

构建rpm基础操作

准备工作做完后下面进入实战,以构建nginx-rpm为例,如下是构建rpm基础操作:

1: 将nginx.1.16.0.tar.gz及nginx.init等文件放置在SOURCES目录中;

2: 在SPECS目录中创建nginx.spec文件;

3: 检查依赖rpmbuild –nobuild nginx.spec

4: 用rpmbuild -bp nginx.spec测试%prep阶段是否有错误;

5: 用rpmbuild -bc nginx.spec测试%build阶段是否有错误;

6: 用rpmbuild -bi nginx.spec测试%install阶段是否有错误;

7: 用rpmbuild -bl nginx.spec测试%files阶段是否有错误;

8: 用rpmbuild -ba nginx.spec构建二进制包及rpm-src包.

提示

上面的4,5,6,7操作非必须.

SPEC语法介绍

在正式构建rpm之前,先来了解下spec语法,下面是一个基本的spec文件结构:

Name:
Version:
Release: 1%{?dist}              # 根据此项可进行rpm升级操作,?代表有dist值就使用没有则不使用dist变量
Summary:
Group:                          # /usr/share/doc/rpm-4.11.3/GROUPS中可以查看
License:
URL:
pagkager: echoxu xjh@xujianhui.cn
Vendor: https://www.echoxu.cn
Source0: https://nginx.org/download/%{Name}-%{Version}.tar.gz     # 并不会从互联网下载,只是去查找%{Name}-%{Version}.tar.gz
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX                  # 虚拟安装根目录,由于将rpm包安装在此处,目录结构和rpm真实安装后的目录结构相同,如:/var/tmp/nginx-1.16.0-root/usr/local/nginx
BuildRequires:                  # 构建rpm时所依赖的包
Requires:                   # 安装rpm时所依赖的包
%description            # "rpm -qi" 查询时所显示的内容

%prep                   # 准备阶段,如解压缩源码文件,复制文件等操作
%setup -q                # 不显示输出内容,进入并解压源码包

%build                   # 执行configure”和“make”操作
%configure
make -j 4 %{?_smp_mflags}             #利用多核进行编译,类似于make -j 4

%install                        # 临时安装软件到 $RPM_BUILD_ROOT中,也是前面指定的BuildRoot值 ,man install查看install帮助手册
rm -rf $RPM_BUILD_ROOT
make install DESTDIR=$RPM_BUILD_ROOT

%clean                          # 清理临时安装目录
rm -rf $RPM_BUILD_ROOT
rm -rf $BUILD

%pre                            # 制作完成后的rpm在其安装之前要执行的脚本

%post                           # 安装完成后执行的脚本

%preun                          # 卸载开始之前执行的脚本

%postun                         # 卸载完成后要执行的脚本

%files                          # 收集BuildRoot里的文件并打包进rpm包,除了debug文件
%defattr(-,root,root,-)

%doc                            # 作为文档使用,/usr/share下

%changelog                      # 更新日志

构建nrpm包过程

  • 准备源材料,包括: nginx-1.16.0.tar.gz等
[echoxu@mysql rpmbuild]$ tree SOURCES
SOURCES
├── gperftools-2.7.tar.gz
├── libunwind-1.3.1.tar.gz
├── nginx-1.16.0.tar.gz
├── nginx.conf
├── nginx.init
├── nginxLogrotate
├── openssl-1.1.1b.tar.gz
├── pcre-8.43.tar.gz
└── zlib-1.2.11.tar.gz

  • 编写nginx.init、nginxLogrotate、nginx.spec、nginx.opt文件

  • 使用 `rpmbuild -ba nginx.spec`构建rpm

libunwind.spec

# This SPEC File Is Only For Centos7

####  Start Define Global variables  ####
####  End Define Global variables  ####

####  Start Get Linux Release Version number  ####
# like centos 7.4 ==> get 4 ==> .el7.4
%if 0%{?rhel} == 7
BuildRequires: redhat-lsb-core
%define _group Development/Tools
%define epoch 1
Epoch: %{epoch}
Requires(pre): shadow-utils
Requires: systemd
BuildRequires: systemd
%define os_minor %(lsb_release -rs | cut -d '.' -f 2)
%if %{os_minor} >= 4
Requires: openssl >= 1.0.2
BuildRequires: openssl-devel >= 1.0.2
%define dist .el7_4
%else
Requires: openssl >= 1.0.1
BuildRequires: openssl-devel >= 1.0.1
%define dist .el7
%endif
%endif
####  End Get Linux Release Version number  ####

####  Start Define libunwind Install Compile Parameters  ####

%define main_version 1.3.1
%define main_release 1%{?dist}

# /home/echoxu/rpmbuild/BUILD/libunwind-1.3.1
%define bdir %{_builddir}/%{name}-%{main_version}

#%define BASE_CONFIGURE_ARGS $(echo "-refix=%{libunwind_home}/libunwind-%{main_version})


####  End Define libunwind Install Compile Parameters  ####


#### Start  Basic Define ####

Summary: define a portable and efficient C programming interface (API) to determine the call-chain of a program
Name: libunwind
Version: %{main_version}
Release: %{main_release}
Vendor: echoxu, Personal.
URL: https://www.echoxu.cn
Group: %{_group}

Source0: https://github.com/libunwind/libunwind/releases/download/v1.3.1/%{name}-%{version}.tar.gz
License: MIT

BuildRoot: %{_tmppath}/%{name}-%{main_version}-%{main_release}-root

Provides: C API

%description
The primary goal of this project is to define a portable and efficient C programming interface (API) to determine the call-chain of a program. The API additionally provides the means to manipulate the preserved (callee-saved) state of each call-frame and to resume execution at any point in the call-chain (non-local goto). The API supports both local (same-process) and remote (across-process) operation. As such, the API is useful in a number of applications

#### End  Basic Define ####

%prep
%setup -q
#cp %{SOURCE0} .

%build
./configure --libdir=/usr/local/lib --includedir=/usr/local/include/libunwind
make %{?_smp_mflags}

%install
%{__rm} -rf $RPM_BUILD_ROOT
%{__make} DESTDIR=$RPM_BUILD_ROOT INSTALLDIRS=vendor install

%clean
%{__rm} -rf $RPM_BUILD_ROOT
%{__rm} -rf %{_builddir}

%files
%defattr(-,root,root)
/usr/local/include/libunwind/
/usr/local/lib/

%pre

%post
echo /usr/local/lib > /etc/ld.so.conf.d/libunwind.conf
#ldconfig  1 > /dev/null 2>&1
ldconfig
#ln -s /usr/local/libunwind/include/ /usr/include/libunwind
%preun
rm -rf /etc/ld.so.conf.d/libunwind.conf
%postun

%changelog
* Mon May 13 2019 echoxu <xjh@xujianhui.com>
- 1.3.1
- make rpm package for libunwind


gperftools.spec

# This SPEC File Is Only For Centos7

####  Start Define Global variables  ####
####  End Define Global variables  ####

####  Start Get Linux Release Version number  ####
# like centos 7.4 ==> get 4 ==> .el7.4
%if 0%{?rhel} == 7
BuildRequires: redhat-lsb-core
%define _group Development/Tools
%define epoch 1
Epoch: %{epoch}
Requires(pre): shadow-utils
Requires: systemd
BuildRequires: systemd
%define os_minor %(lsb_release -rs | cut -d '.' -f 2)
%if %{os_minor} >= 4
Requires: openssl >= 1.0.2
BuildRequires: openssl-devel >= 1.0.2
%define dist .el7_4
%else
Requires: openssl >= 1.0.1
BuildRequires: openssl-devel >= 1.0.1
%define dist .el7
%endif
%endif
####  End Get Linux Release Version number  ####

####  Start Define gperftools Install Compile Parameters  ####

%define main_version 2.7
%define main_release 1%{?dist}

# /home/echoxu/rpmbuild/BUILD/gperftools-2.7
%define bdir %{_builddir}/%{name}-%{main_version}

#%define BASE_CONFIGURE_ARGS $(echo "-refix=%{gperftools_home}/gperftools-%{main_version})


####  End Define gperftools Install Compile Parameters  ####


#### Start  Basic Define ####

Summary: high-performance multi-threaded malloc
Name: gperftools
Version: %{main_version}
Release: %{main_release}
Vendor: echoxu, Personal.
URL: https://www.echoxu.cn
Group: %{_group}

Source0: https://github.com/gperftools/gperftools/releases/download/%{name}-%{version}.tar.gz
License: BSD

BuildRoot: %{_tmppath}/%{name}-%{main_version}-%{main_release}-root
Requires:  libunwind >= 1.3.1
Provides:  fastest malloc

%description
gperftools is a collection of a high-performance multi-threaded
malloc() implementation, plus some pretty nifty performance analysis
tools


#### End  Basic Define ####

%prep
%setup -q

%build
./configure  --enable-frame-pointers
make %{?_smp_mflags}

%install
%{__rm} -rf $RPM_BUILD_ROOT
%{__make} DESTDIR=$RPM_BUILD_ROOT INSTALLDIRS=vendor install

%clean
%{__rm} -rf $RPM_BUILD_ROOT
%{__rm} -rf %{_builddir}

%files
%defattr(-,root,root)
/usr/local/bin/
/usr/local/include/google/
/usr/local/include/gperftools/
/usr/local/lib/
#%doc /usr/local/share/doc/gperftools/
%doc /usr/local/share/man/man1/pprof.1
%exclude /usr/local/share/doc/gperftools/

%pre

%post
echo /usr/local/lib > /etc/ld.so.conf.d/libtcmalloc.conf
ldconfig

%preun
rm -rf /etc/ld.so.conf.d/libtcmalloc.conf

%postun

%changelog
* Tue May 14 2019 echoxu <xjh@xujianhui.com>
- 2.7
- make rpm package for gperftools


nginx.spec

# This SPEC File Is Only For Centos7
####  Start Define Global variables  ####
# Define nginx_homeDir、nginx_User、nginx_group And logrotate user
%define nginx_home  /home/APPDeploy
%define nginx_user APPDeploy
%define nginx_group APPDeploy
%define nginx_loggroup adm
%define nginx_tools /home/APPDeploy/tools
%define pcreV   pcre-8.42
%define opensslV   openssl-1.0.2p
%define zlibV   zlib-1.2.11
####  End Define Global variables  ####

####  Start Get Linux Release Version number  ####
# like centos 7.4 ==> get 4 ==> .el7.4
%if 0%{?rhel} == 7
BuildRequires: redhat-lsb-core
%define _group Applications/Internet
%define epoch 1
Epoch: %{epoch}
Requires(pre): shadow-utils
Requires: systemd
BuildRequires: systemd
%define os_minor %(lsb_release -rs | cut -d '.' -f 2)
%if %{os_minor} >= 4
Requires: openssl >= 1.0.2
BuildRequires: openssl-devel >= 1.0.2
%define dist .el7_4
%else
Requires: openssl >= 1.0.1
BuildRequires: openssl-devel >= 1.0.1
%define dist .el7
%endif
%endif
####  End Get Linux Release Version number  ####

####  Start Define Nginx Install Compile Parameters  ####

%define main_version 1.16.0
%define main_release 1%{?dist}

# /home/echoxu/rpmbuild/BUILD/nginx-1.16.0
%define bdir %{_builddir}/%{name}-%{main_version}

%define WITH_CC_OPT $(echo %{optflags} $(pcre-config --cflags)) -fPIC
%define WITH_LD_OPT -Wl,-z,relro -Wl,-z,now -pie

%define BASE_CONFIGURE_ARGS $(echo "--prefix=%{nginx_home}/nginx-%{main_version} --sbin-path=%{nginx_home}/nginx-%{main_version}/sbin/nginx  --conf-path=%{nginx_home}/nginx-%{main_version}/conf/nginx.conf --error-log-path=%{nginx_home}/nginx-%{main_version}/logs/error.log --http-log-path=%{nginx_home}/nginx-%{main_version}/logs/access.log --pid-path=%{nginx_home}/nginx-%{main_version}/run/nginx.pid --lock-path=%{nginx_home}/nginx-%{main_version}/run/nginx.lock --http-client-body-temp-path=%{nginx_home}/nginx-%{main_version}/cache/client_temp --http-proxy-temp-path=%{nginx_home}/nginx-%{main_version}/cache/proxy_temp --http-fastcgi-temp-path=%{nginx_home}/nginx-%{main_version}/cache/fastcgi_temp --http-uwsgi-temp-path=%{nginx_home}/nginx-%{main_version}/cache/uwsgi_temp --http-scgi-temp-path=%{nginx_home}/nginx-%{main_version}/cache/scgi_temp --user=%{nginx_user} --group=%{nginx_group}   --with-http_gunzip_module --with-http_gzip_static_module --with-http_mp4_module  --with-http_realip_module --with-http_secure_link_module  --with-http_ssl_module --with-http_stub_status_module --with-http_sub_module --with-http_v2_module  --with-google_perftools_module")


####  End Define Nginx Install Compile Parameters  ####


#### Start  Basic Define ####

Summary: High performance web server
Name: nginx
Version: %{main_version}
Release: %{main_release}
Vendor: echoxu, Personal.
URL: https://www.echoxu.cn
Group: %{_group}

Source0: %{name}-%{version}.tar.gz
Source1: nginx.conf
Source2: nginx.init
Source3: nginxLogrotate
Source4: docV1.conf
Source5: fastcgiOPT.conf
Source6: proxy.conf
Source7: systemOPT.sh
License: BSD

BuildRoot: %{_tmppath}/%{name}-%{main_version}-%{main_release}-root
BuildRequires: zlib-devel
BuildRequires: pcre-devel
BuildRequires: gperftools
Provides: webserver

%description
nginx [engine x] is an HTTP and reverse proxy server, as well as
a mail proxy server.

#### End  Basic Define ####

%prep
# 加上opt nginx src的操作以及安装pcre、zlib、openssl、libwuwind等操作
%setup -q

cp src/core/nginx.h  src/core/nginx.h.bak
sed -i '/define NGINX_VERSION/{s#1\.14\.2#1\.1\.28#}' src/core/nginx.h
sed -i  '/define NGINX_VER/{s#nginx#WBS#}' src/core/nginx.h
sed -i  '/define NGINX_VAR/{s#\"NGINX\"#\"WBS\"#}' src/core/nginx.h
cp  src/http/ngx_http_header_filter_module.c  src/http/ngx_http_header_filter_module.c.bak
sed -i 's/Server: nginx/Server: WBS/' src/http/ngx_http_header_filter_module.c
cp  src/http/ngx_http_special_response.c  src/http/ngx_http_special_response.c.bak
sed -i  '/"<hr><center>nginx<\/center>" CRLF/{s#nginx#WBS#}'  src/http/ngx_http_special_response.c

%build
./configure %{BASE_CONFIGURE_ARGS} \
   --with-cc-opt="%{WITH_CC_OPT}" \
   --with-ld-opt="%{WITH_LD_OPT}"
 #   --with-debug
make %{?_smp_mflags}

%install
%{__rm} -rf $RPM_BUILD_ROOT
%{__make} DESTDIR=$RPM_BUILD_ROOT INSTALLDIRS=vendor install
%{__mkdir} -p $RPM_BUILD_ROOT/home/APPDeploy/nginx-1.16.0/sbin
%{__mkdir} -p $RPM_BUILD_ROOT/home/APPDeploy/nginx-1.16.0/html
%{__mkdir} -p $RPM_BUILD_ROOT/home/APPDeploy/nginx-1.16.0/conf
%{__mkdir} -p $RPM_BUILD_ROOT/home/APPDeploy/nginx-1.16.0/logs
%{__mkdir} -p $RPM_BUILD_ROOT/home/APPDeploy/nginx-1.16.0/run
%{__mkdir} -p $RPM_BUILD_ROOT/home/APPDeploy/nginx-1.16.0/cache
%{__mkdir} -p $RPM_BUILD_ROOT/home/APPDeploy/nginx-1.16.0/cache/client_temp
%{__mkdir} -p $RPM_BUILD_ROOT/home/APPDeploy/nginx-1.16.0/cache/proxy_temp
%{__mkdir} -p $RPM_BUILD_ROOT/home/APPDeploy/nginx-1.16.0/cache/fastcgi_temp
%{__mkdir} -p $RPM_BUILD_ROOT/home/APPDeploy/nginx-1.16.0/cache/uwsgi_temp
%{__mkdir} -p $RPM_BUILD_ROOT/home/APPDeploy/nginx-1.16.0/cache/scgi_temp
%{__mkdir} -p $RPM_BUILD_ROOT/home/APPDeploy/nginx-1.16.0/conf/conf.d
%{__install} -m 644 -p %{SOURCE1}   $RPM_BUILD_ROOT/home/APPDeploy/nginx-1.16.0/conf/
# install SYSV init stuff
%{__mkdir} -p $RPM_BUILD_ROOT%{_initrddir}
%{__install} -m755 -p %{SOURCE2} $RPM_BUILD_ROOT%{_initrddir}/nginx
%{__mkdir} -p $RPM_BUILD_ROOT%{_sysconfdir}/logrotate.d/nginx
%{__install} -m 644 -p %{SOURCE3}  $RPM_BUILD_ROOT%{_sysconfdir}/logrotate.d/nginx/nginxLogrotate
%{__mkdir} -p  $RPM_BUILD_ROOT/tmp/tcmalloc
%{__install} -m 644 -p %{SOURCE4}   $RPM_BUILD_ROOT/home/APPDeploy/nginx-1.16.0/conf/conf.d
%{__install} -m 644 -p %{SOURCE5}   $RPM_BUILD_ROOT/home/APPDeploy/nginx-1.16.0/conf
%{__install} -m 644 -p %{SOURCE6}   $RPM_BUILD_ROOT/home/APPDeploy/nginx-1.16.0/conf
%{__install} -m 755 -p %{SOURCE7}   $RPM_BUILD_ROOT/home/APPDeploy/nginx-1.16.0/conf/systemOPT.sh

%clean
%{__rm} -rf $RPM_BUILD_ROOT
#%{__rm} -rf %{srcDir}
%{__rm} -rf %{_builddir}


%files
%attr(0755,APPDeploy,APPDeploy) /home/APPDeploy/nginx-1.16.0/sbin/nginx
%attr(0644,APPDeploy,APPDeploy) /home/APPDeploy/nginx-1.16.0/html/50x.html
%attr(0644,APPDeploy,APPDeploy) /home/APPDeploy/nginx-1.16.0/html/index.html
%attr(0644,APPDeploy,APPDeploy) %config(noreplace)  /home/APPDeploy/nginx-1.16.0/conf/fastcgi.conf
%attr(0644,APPDeploy,APPDeploy) %config(noreplace)  /home/APPDeploy/nginx-1.16.0/conf/fastcgi.conf.default
%attr(0644,APPDeploy,APPDeploy) %config(noreplace)  /home/APPDeploy/nginx-1.16.0/conf/fastcgi_params
%attr(0644,APPDeploy,APPDeploy) %config(noreplace)  /home/APPDeploy/nginx-1.16.0/conf/fastcgi_params.default
%attr(0644,APPDeploy,APPDeploy) %config(noreplace)  /home/APPDeploy/nginx-1.16.0/conf/koi-utf
%attr(0644,APPDeploy,APPDeploy) %config(noreplace)  /home/APPDeploy/nginx-1.16.0/conf/koi-win
%attr(0644,APPDeploy,APPDeploy) %config(noreplace)  /home/APPDeploy/nginx-1.16.0/conf/mime.types
%attr(0644,APPDeploy,APPDeploy) %config(noreplace)  /home/APPDeploy/nginx-1.16.0/conf/mime.types.default
%attr(0644,APPDeploy,APPDeploy) %config(noreplace)  /home/APPDeploy/nginx-1.16.0/conf/nginx.conf
%attr(0644,APPDeploy,APPDeploy) %config(noreplace)  /home/APPDeploy/nginx-1.16.0/conf/nginx.conf.default
%attr(0644,APPDeploy,APPDeploy) %config(noreplace)  /home/APPDeploy/nginx-1.16.0/conf/scgi_params
%attr(0644,APPDeploy,APPDeploy) %config(noreplace)  /home/APPDeploy/nginx-1.16.0/conf/scgi_params.default
%attr(0644,APPDeploy,APPDeploy) %config(noreplace)  /home/APPDeploy/nginx-1.16.0/conf/uwsgi_params
%attr(0644,APPDeploy,APPDeploy) %config(noreplace)  /home/APPDeploy/nginx-1.16.0/conf/uwsgi_params.default
%attr(0644,APPDeploy,APPDeploy) %config(noreplace)  /home/APPDeploy/nginx-1.16.0/conf/win-utf
%attr(0644,APPDeploy,APPDeploy) %config(noreplace)  /home/APPDeploy/nginx-1.16.0/conf/fastcgiOPT.conf
%attr(0644,APPDeploy,APPDeploy) %config(noreplace)  /home/APPDeploy/nginx-1.16.0/conf/proxy.conf
%attr(0644,APPDeploy,APPDeploy) %config(noreplace)  /home/APPDeploy/nginx-1.16.0/conf/conf.d/docV1.conf
%attr(0755,root,root) %config(noreplace) /home/APPDeploy/nginx-1.16.0/conf/systemOPT.sh
%attr(0755,APPDeploy,APPDeploy) %dir  /home/APPDeploy/nginx-1.16.0/conf
%attr(0755,APPDeploy,APPDeploy) %dir   /home/APPDeploy/nginx-1.16.0/logs
%attr(0755,APPDeploy,APPDeploy) %dir   /home/APPDeploy/nginx-1.16.0/run
%attr(0755,APPDeploy,APPDeploy)        /home/APPDeploy/nginx-1.16.0/cache/
%attr(0755,APPDeploy,APPDeploy) %dir   /home/APPDeploy/nginx-1.16.0/conf/conf.d
%{_initrddir}/nginx
%{_sysconfdir}/logrotate.d/nginx/nginxLogrotate
%attr(0755,APPDeploy,APPDeploy) %dir /tmp/tcmalloc


%pre
# Add the "nginx" user
getent group %{nginx_group} >/dev/null || groupadd -r %{nginx_group}
getent passwd %{nginx_user} >/dev/null || \
    useradd -r -g %{nginx_group} -s /bin/bash \
    -d %{nginx_home} -c "nginx user"  %{nginx_user}
exit 0

%post

# add capbility for APPDeploy user and register the nginx service
if [ $1 -eq 1 ]; then
/usr/bin/chown  -R APPDeploy.APPDeploy /home/APPDeploy
/usr/sbin/setcap  cap_net_bind_service=+eip /home/APPDeploy/nginx-1.16.0/sbin/nginx
/sbin/chkconfig --add nginx
/usr/bin/echo "59 23 * * *  root  /usr/sbin/logrotate -f /etc/logrotate.d/nginx/nginxLogrotate" >>  /etc/crontab
fi

%preun

if [ $1 -eq 0 ]; then
/usr/bin/systemctl stop nginx > /dev/null 2>&1
/sbin/chkconfig --del nginx
fi

%postun

if [ $1 -eq 0 ]; then
    /usr/sbin/userdel -r APPDeploy  > /dev/null 2>&1
    rm -rf /etc/logrotate.d/nginx
    rm -rf /tmp/tcmalloc*
    /usr/bin/sed  -i '/nginxLogrotate$/d' /etc/crontab
    /usr/bin/echo "Thanks for using nginx!"
fi
%changelog
* Tue May 14 2019 echoxu  <xjh@xujianhui.cn>
- 1.16.0
- make rpm package for nginx
- add capbility for nginx,let nginx user(not root) can run in 80 port
- add nginx.init, use "systemctl start nginx" to start nginx
- add nginxLogrotate scripts
- add tcmalloc for nginx
- add fastcgi and proxy opt


nginxLogrotate

/home/APPDeploy/nginx-1.16.0/logs/*.log {
        daily
        missingok
        rotate 30
        compress
        delaycompress
        dateext
        #dateformat %Y_%m_ %d_%s
        notifempty
        create 644 APPDeploy APPDeploy
        sharedscripts
        postrotate
                if [ -f /home/APPDeploy/nginx-1.16.0/run/nginx.pid ]; then
                        kill -USR1 `cat /home/APPDeploy/nginx-1.16.0/run/nginx.pid`
                fi
        endscript
}

nginx.init

#!/bin/sh
#
# nginx - this script starts and stops the nginx daemon
#
# chkconfig:  2345 40 60
# description:  NGINX is an HTTP(S) server, HTTP(S) reverse \
#               proxy and IMAP/POP3 proxy server
# processname: nginx

# Source function library.

. /etc/rc.d/init.d/functions

# Source networking configuration.

. /etc/sysconfig/network

# Check that networking is up.
[${NETWORKING}= “no” ] && exit 0

#Set args
nginx_sbin=/home/APPDeploy/nginx-1.16.0/sbin/nginx
prog=$(basename $nginx_sbin)
nginx_config=/home/APPDeploy/nginx-1.16.0/conf/nginx.conf
nginx_pid=/home/APPDeploy/nginx-1.16.0/run/nginx.pid
lockfile=/home/APPDeploy/nginx-1.16.0/run/nginx.lock
RETVAL=0
count=`ps aux|grep nginx |grep -v grep |wc -l`
# Start nginx daemons functions.
start() {
    if [ ! -f "$nginx_pid" ];then
        su - APPDeploy -c "$nginx_sbin -c $nginx_config"
        RETVAL=$?
        if [ "$RETVAL" -eq 0 ];then
            touch $lockfile
            action "nginx is started!"  /bin/true
            return $RETVAL
         else
               action "nginx is started"   /bin/false
               return $RETVAL
         fi
    else
        echo -e "nginx is running \n"
        return 0
    fi

}

# Stop nginx daemons functions.
stop() {
    if [ -f "$nginx_pid" ];then
        su - APPDeploy -c "$nginx_sbin  -s 'stop'"
        #killproc $prog -QUIT
        RETVAL=$?
        if [ "$RETVAL" -eq 0 ];then
                rm -f $lockfile $nginx_pid&&action "nginx is stopped!"  /bin/true
                return $RETVAL
        else
                action "nginx is stopped!"  /bin/false
                return $RETVAL
        fi
    else
        echo -e "nginx is not running \n"
        RETVAL=$?
    fi
}
case "$1" in
    start)
        start
        ;;
    stop)
        stop
        ;;
    reload)
        stop
        sleep 1
        start
        ;;
    restart)
        stop
        sleep 1
        start
        ;;
    *)
        echo $"Usage: $0 {start|stop|restart|reload}"
        exit 1
esac
exit $RETVAL


使用gpg方式生成签名密钥

  • 使用gpg --gen-key生成秘钥
[echoxu@mysql ~]$ gpg --gen-key
gpg (GnuPG) 2.0.22; Copyright (C) 2013 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

请选择您要使用的密钥种类:
   (1) RSA and RSA (default)
   (2) DSA and Elgamal
   (3) DSA (仅用于签名)
   (4) RSA (仅用于签名)
您的选择?
RSA 密钥长度应在 1024 位与 4096 位之间。
您想要用多大的密钥尺寸?(2048)
您所要求的密钥尺寸是 2048 位
请设定这把密钥的有效期限。
         0 = 密钥永不过期
      <n>  = 密钥在 n 天后过期
      <n>w = 密钥在 n 周后过期
      <n>m = 密钥在 n 月后过期
      <n>y = 密钥在 n 年后过期
密钥的有效期限是?(0)
密钥永远不会过期
以上正确吗?(y/n)y

You need a user ID to identify your key; the software constructs the user ID
from the Real Name, Comment and Email Address in this form:
    "Heinrich Heine (Der Dichter) <heinrichh@duesseldorf.de>"

真实姓名:echoxu
电子邮件地址:myjerrysuu@163.com
注释:RPM-GPG-KEY
您选定了这个用户标识:
    “echoxu (RPM-GPG-KEY) <myjerrysuu@163.com>”

更改姓名(N)、注释(C)、电子邮件地址(E)或确定(O)/退出(Q)?o
您需要一个密码来保护您的私钥。

我们需要生成大量的随机字节。这个时候您可以多做些琐事(像是敲打键盘、移动
鼠标、读写硬盘之类的),这会让随机数字发生器有更好的机会获得足够的熵数。
......,./++++++----

我们需要生成大量的随机字节。这个时候您可以多做些琐事(像是敲打键盘、移动
鼠标、读写硬盘之类的),这会让随机数字发生器有更好的机会获得足够的熵数。
gpg: /home/echoxu/.gnupg/trustdb.gpg:建立了信任度数据库
gpg: 密钥 C8E9DD0A 被标记为绝对信任
公钥和私钥已经生成并经签名。

gpg: 正在检查信任度数据库
gpg: 需要 3 份勉强信任和 1 份完全信任,PGP 信任模型
gpg: 深度:0 有效性:  1 已签名:  0 信任度:0-,0q,0n,0m,0f,1u
pub   2048R/C8E9DD0A 2019-05-22
密钥指纹 = 572E 239F C774 031C CD9D  845F 6CD2 45E5 C8E9 DD0A
uid                  echoxu (RPM-GPG-KEY) <myjerrysuu@163.com>
sub   2048R/327AD9F2 2019-05-22

在生成随机数时卡住问题:

新建个终端连接执行sudo yum -y install rng-tools

sudo rngd -r /dev/urandom

  • gpg --list-keys查看公钥,gpg --list-secret-keys查看私钥
[echoxu@mysql ~]$ gpg --list-keys
gpg: 正在检查信任度数据库
gpg: 需要 3 份勉强信任和 1 份完全信任,PGP 信任模型
gpg: 深度:0 有效性:  1 已签名:  0 信任度:0-,0q,0n,0m,0f,1u
/home/echoxu/.gnupg/pubring.gpg
-------------------------------
pub   2048R/53339AFE 2019-05-22
uid                  echoxu (RPM-GPG-KEY) <myjerrysuu@163.com>
sub   2048R/1D14CCA4 2019-05-22

其中1D14CCA4为私钥ID,53339AFE为公钥ID。

删除秘钥需要先删除私钥,命令:gpg --delete-secret-keys 1D14CCA4,然后再删除公钥:gpg --delete-keys 53339AFE

  • 导出公钥

格式: gpg 参数 keyID FileName

gpg -a --export 53339AFE > RPM-GPG-KEY-Echoxu

  • 在~/.rpmmacros宏中定义加密密钥

vim ~/.rpmmacros

添加:

# %_signature => This will always be gpg
# %_gpg_path  => Enter full path to .gnupg in your home directory
# %_gpg_name  => Use the Real Name you used to create your key
# %_gpbin     => run `which gpg` (without ` marks) to get full path

%_signature gpg
%_gpg_path /home/echoxu/.gnupg
%_gpg_name echoxu
%_gpgbin /usr/bin/gpg
  • 为rpm包添加签名

需要先安装rpm-sign

sudo yum install rpm-sign

rpm --addsign ~/rpmbuild/RPMS/x86_64/nginx-1.16.0-1.el7_4.x86_64.rpm

上面的命令会要求你输入密码,输入你创建gpg-key时的密码即可.

或者可以直接在制作rpm包时生成签名:

rpmbuild -ba --sign SPECS/nginx.spec

  • 安装rpm包者需导入公钥

sudo rpm --import RPM-GPG-KEY-Echoxu

  • 查看在rpm DB中的public key

rpm -q gpg-pubkey --qf '%{name}-%{version}-%{release} --> %{summary}\n'

  • 验证rpm包
[echoxu@mysql ~]$  rpm --checksig ~/rpmbuild/RPMS/x86_64/nginx-1.16.0-1.el7_4.x86_64.rpm
/home/echoxu/rpmbuild/RPMS/x86_64/nginx-1.16.0-1.el7_4.x86_64.rpm: rsa sha1 (md5) pgp md5 确定
  • 重新安装带签名的rpm包
[echoxu@mysql ~]$ sudo rpm -ivh ~/rpmbuild/RPMS/x86_64/nginx-1.16.0-1.el7_4.x86_64.rpm
准备中...                          ################################# [100%]
正在升级/安装...
   1:nginx-1:1.16.0-1.el7_4           ################################# [100%]
[echoxu@mysql ~]$ rpm -qi nginx
Name        : nginx
Epoch       : 1
Version     : 1.16.0
Release     : 1.el7_4
Architecture: x86_64
Install Date: 2019年05月22日 星期三 21时04分07秒
Group       : Applications/Internet
Size        : 7569811
License     : BSD
Signature   : RSA/SHA1, 2019年05月22日 星期三 20时50分11秒, Key ID df579aab53339afe
Source RPM  : nginx-1.16.0-1.el7_4.src.rpm
Build Date  : 2019年05月22日 星期三 09时14分55秒
Build Host  : mysql
Relocations : (not relocatable)
Vendor      : echoxu, Personal.
URL         : https://www.echoxu.cn
Summary     : High performance web server
Description :
nginx [engine x] is an HTTP and reverse proxy server, as well as
a mail proxy server.

发现Signature这栏多了一些信息,到此给rpm包签名就完成了.

报错问题汇总

  • 不生成debuginfo包

echo '%debug_package %{nil}' >> ~/.rpmmacros

  • 报错1:

ERROR 0002: file '/usr/local/lib/libunwind-x86_64.so.8.0.1' contains an invalid rpath '/usr/local/lib' in [/usr/local/lib]

解决办法:

~/.rpmmacros中注释如下代码:

#%__arch_install_post \
    #[ "%{buildarch}" = "noarch" ] || QA_CHECK_RPATHS=1 ; \
    #case "${QA_CHECK_RPATHS:-}" in [1yY]*) /usr/lib/rpm/check-rpaths ;; esac \
    #/usr/lib/rpm/check-buildroot
  • 报错2:

发现已安装(但未打包的)文件: /usr/local/include/libunwind-common.h

解决办法:

第一种方法(推荐):

在libunwind.spec的%files中添加如下代码:

/usr/local/include/

/usr/local/lib/

第二种方法:

vim /usr/lib/rpm/macros

注释如下代码

%__check_files %{_rpmconfigdir}/check-files %{buildroot}

下面是一些常用rpmsrc包的下载地址:

centos提供的7.4的rpmsrc

centos提供的7.5的rpmsrc

mysqlSrc_github

mariadbSrc

zabbixSrc

zabbixSrc_github

mysql官方提供的rpmSrc

pkgs提供的mysqlSrc

上次更新:
贡献者: iEchoxu