rpmbuild制作包的详细过程

2023-10-28

https://www.cnblogs.com/schangech/p/5641108.html

https://www.ibm.com/developerworks/cn/linux/l-rpm/

一:目录结构生成

1、工具安装rpmdevtools。yum install rpmdevtools

2、配置文件针对rpmdevtools

[root@localhost aa]# cat ~/.rpmmacros

%_topdir %(echo $PWD)/rpmbuild

%_smp_mflags %( \
    [ -z "$RPM_BUILD_NCPUS" ] \\\
        && RPM_BUILD_NCPUS="`/usr/bin/nproc 2>/dev/null || \\\
                             /usr/bin/getconf _NPROCESSORS_ONLN`"; \\\
    if [ "$RPM_BUILD_NCPUS" -gt 16 ]; then \\\
        echo "-j16"; \\\
    elif [ "$RPM_BUILD_NCPUS" -gt 3 ]; then \\\
        echo "-j$RPM_BUILD_NCPUS"; \\\
    else \\\
        echo "-j3"; \\\
    fi )

%__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

3、生成对应的文件https://linux.die.net/man/1/rpmdev-newspec

 配置模板路径:ls /etc/rpmdevtools/

3.1、rpmdev-setuptree 生成对应的目录树

[root@localhost aa]# tree
.
└── rpmbuild
    ├── BUILD
    ├── RPMS
    ├── SOURCES
    ├── SPECS
    └── SRPMS

6 directories, 0 files

3.2、rpmdev-newinit,它可以方便的生成/etc/init.d/下面的启动脚本  

cd /etc/init.d/

rpmdev-newinit app

mv app.init app

chmod 755 app

二:打包过程

   1、目录介绍

BUILD:源代码解压以后放的位置,只需提供BUILD目录,具体里面放什么,不用我们管,所以真正的制作车间是BUILD目录。
BUILDROOT:假根,使用install临时安装到这个目录,把这个目录当作根来用的,所以在这个目录下的目录文件,才是真正的目录文件。当打包完成后,在清理阶段,这个目录将被删除。
RPMS:制作完成后的rpm包存放目录,为特定平台指定子目录(i386,i686,ppc)。
SOURCES:收集的源文件,源材料,补丁文件等存放位置。
SPECS:存放spec文件,作为制作rpm包的领岗文件,文件以.spec结尾。
SRPMS:src格式的rpm包位置 ,既然是src格式的包,就没有平台的概念了

2、打包过程

基本格式:rpmbuild [options] [spec文档|tarball包(或者压缩包—以.gz或.xz或.bz2结尾的)|源码包]
options有下面的几种选择:
1.-bp #只执行spec的%pre段(解开源码包并打补丁,即只做准备)
2.-bc #执行spec的%pre和%build 段(准备并编译)
3.-bi #执行spec中%pre,%build与%install(准备,编译并安装)
4.-bl #检查spec中的%file段(查看文件是否齐全)
5.-ba #建立源码与二进制包(常用):即编译后做成*.rpm和*.src.rpm
6.-bb #只建立二进制包(常用):即编译后做成*.rpm
7.-bs #只建立源码包:即只做成*.src.rpm
-tc -ti -ta -tb -ts 的功能类似,只是所需参数由spec文件变成tar包。
a    构建二进制包和源代码包(在执行 %prep, %build, %install 之后)
b    构建二进制包(在执行 %prep, %build, %install 之后)
p    执行 spec 文件的"%prep"阶段。这通常等价于解包源代码并应用补丁。
c    执行 spec 文件的"%build"阶段(在执行了 %prep 之后)。这通常等价于执行了"make"。
i    执行 spec 文件的"%install"阶段(在执行了 %prep, %build 之后)。这通常等价于执行了"make install"。
l    执行一次"列表检查"。spec 文件的"%files"段落中的宏被扩展,检测是否每个文件都存在。
s    只构建源代码包

3、spec详解

3.1

https://www.cnblogs.com/schangech/p/5641108.html

https://blog.csdn.net/Michaelwubo/article/details/105886315

1、if结构
引用
%if %{str}
%else
动作
%endif
其中%{str}是条件,0为假,非0为真。
2、?:结构
引用
%{?变量:动作1}动作2
其中{}用于控制范围,而“?”号和“:”号是分割符,如果要判断条件是非的情况,可以在“?”号前加“!”号。
此条件与前面的%if有点不同,其只判断变量是否定义,定义了就为真,否则就为假,即使变量定义为0,也为真,并运行后面的语句。






关键字
spec脚本包括很多关键字,主要有:
引用
Name: 软件包的名称,后面可使用%{name}的方式引用
Summary: 软件包的内容概要
Version: 软件的实际版本号,例如:1.0.1等,后面可使用%{version}引用
Release: 发布序列号,例如:1linuxing等,标明第几次打包,后面可使用%{release}引用
Group: 软件分组,建议使用标准分组
License: 软件授权方式,通常就是GPL
Source: 源代码包,可以带多个用Source1、Source2等源,后面也可以用%{source1}、%{source2}引用
BuildRoot: 这个是安装或编译时使用的“虚拟目录”,考虑到多用户的环境,一般定义为:
%{_tmppath}/%{name}-%{version}-%{release}-root
或
%{_tmppath}/%{name}-%{version}-%{release}-buildroot-%(%{__id_u} -n}
该参数非常重要,因为在生成rpm的过程中,执行make install时就会把软件安装到上述的路径中,在打包的时候,同样依赖“虚拟目录”为“根目录”进行操作。
后面可使用$RPM_BUILD_ROOT 方式引用。
URL: 软件的主页
Vendor: 发行商或打包组织的信息,例如RedFlag Co,Ltd
Disstribution: 发行版标识
Patch: 补丁源码,可使用Patch1、Patch2等标识多个补丁,使用%patch0或%{patch0}引用
Prefix: %{_prefix} 这个主要是为了解决今后安装rpm包时,并不一定把软件安装到rpm中打包的目录的情况。这样,必须在这里定义该标识,并在编写%install脚本的时候引用,才能实现rpm安装时重新指定位置的功能
Prefix: %{_sysconfdir} 这个原因和上面的一样,但由于%{_prefix}指/usr,而对于其他的文件,例如/etc下的配置文件,则需要用%{_sysconfdir}标识
Build Arch: 指编译的目标处理器架构,noarch标识不指定,但通常都是以/usr/lib/rpm/marcros中的内容为默认值
Requires: 该rpm包所依赖的软件包名称,可以用>=或<=表示大于或小于某一特定版本,例如:
libpng-devel >= 1.0.20 zlib
※“>=”号两边需用空格隔开,而不同软件名称也用空格分开
还有例如PreReq、Requires(pre)、Requires(post)、Requires(preun)、Requires(postun)、BuildRequires等都是针对不同阶段的依赖指定
Provides: 指明本软件一些特定的功能,以便其他rpm识别
Packager: 打包者的信息
%description 软件的详细说明


spec脚本主体
spec脚本的主体中也包括了很多关键字和描述,下面会一一列举。我会把一些特别需要留意的地方标注出来。
%prep 预处理脚本
%setup -n %{name}-%{version} 把源码包解压并放好
通常是从/usr/src/asianux/SOURCES里的包解压到/usr/src/asianux/BUILD/%{name}-%{version}中。
一般用%setup -c就可以了,但有两种情况:一就是同时编译多个源码包,二就是源码的tar包的名称与解压出来的目录不一致,此时,就需要使用-n参数指定一下了。
%patch 打补丁
通常补丁都会一起在源码tar.gz包中,或放到SOURCES目录下。一般参数为:
%patch -p1 使用前面定义的Patch补丁进行,-p1是忽略patch的第一层目录
%Patch2 -p1 -b xxx.patch 打上指定的补丁,-b是指生成备份文件
◎补充一下
引用
%setup 不加任何选项,仅将软件包打开。
%setup -n newdir 将软件包解压在newdir目录。
%setup -c 解压缩之前先产生目录。
%setup -b num 将第num个source文件解压缩。
%setup -T 不使用default的解压缩操作。
%setup -T -b 0 将第0个源代码文件解压缩。
%setup -c -n newdir 指定目录名称newdir,并在此目录产生rpm套件。
%patch 最简单的补丁方式,自动指定patch level。
%patch 0 使用第0个补丁文件,相当于%patch ?p 0。
%patch -s 不显示打补丁时的信息。
%patch -T 将所有打补丁时产生的输出文件删除。

%configure 这个不是关键字,而是rpm定义的标准宏命令。意思是执行源代码的configure配置
在/usr/src/asianux/BUILD/%{name}-%{version}目录中进行 ,使用标准写法,会引用/usr/lib/rpm/marcros中定义的参数。
另一种不标准的写法是,可参考源码中的参数自定义,例如:
引用
CFLAGS="$RPM_OPT_FLAGS" CXXFLAGS="$RPM_OPT_FLAGS" ./configure --prefix=%{_prefix}
%build 开始构建包
在/usr/src/asianux/BUILD/%{name}-%{version}目录中进行make的工作 ,常见写法:
引用
make %{?_smp_mflags} OPTIMIZE="%{optflags}"
都是一些优化参数,定义在/usr/lib/rpm/marcros中
%install 开始把软件安装到虚拟的根目录中
在/usr/src/asianux/BUILD/%{name}-%{version}目录中进行make install的操作。这个很重要,因为如果这里的路径不对的话,则下面%file中寻找文件的时候就会失败。 常见内容有:
%makeinstall 这不是关键字,而是rpm定义的标准宏命令。也可以使用非标准写法:
引用
make DESTDIR=$RPM_BUILD_ROOT install
或 引用
make prefix=$RPM_BUILD_ROOT install
需要说明的是,这里的%install主要就是为了后面的%file服务的。所以,还可以使用常规的系统命令:
引用
install -d $RPM_BUILD_ROOT/
cp -a * $RPM_BUILD_ROOT/

%clean 清理临时文件
通常内容为:
引用
[ "$RPM_BUILD_ROOT" != "/" ] && rm -rf "$RPM_BUILD_ROOT"
rm -rf $RPM_BUILD_DIR/%{name}-%{version}

※注意区分$RPM_BUILD_ROOT和$RPM_BUILD_DIR:
$RPM_BUILD_ROOT是指开头定义的BuildRoot,而$RPM_BUILD_DIR通常就是指/usr/src/asianux/BUILD,其中,前面的才是%file需要的。
%pre rpm安装前执行的脚本
%post rpm安装后执行的脚本
%preun rpm卸载前执行的脚本
%postun rpm卸载后执行的脚本
 
%preun %postun 的区别是什么呢?
前者在升级的时候会执行,后者在升级rpm包的时候不会执行

%files 定义那些文件或目录会放入rpm中
这里会在虚拟根目录下进行,千万不要写绝对路径,而应用宏或变量表示相对路径。 如果描述为目录,表示目录中除%exclude外的所有文件。
%defattr (-,root,root) 指定包装文件的属性,分别是(mode,owner,group),-表示默认值,对文本文件是0644,可执行文件是0755

%exclude 列出不想打包到rpm中的文件
※小心,如果%exclude指定的文件不存在,也会出错的。
%changelog 变更日志

※特别需要注意的是:%install部分使用的是绝对路径,而%file部分使用则是相对路径,虽然其描述的是同一个地方。千万不要写错。


就是%file中必须明白,用的是相对目录 引用
%files
%defattr(-,root,root)
%{_bindir}
%{_libdir}
%{_datadir}
%exclude %{_libdir}/debug

制作补丁
详细看参考: [原]使用diff同patch工具
如何编写%file段
由于必须在%file中包括所有套件中的文件,所以,我们需要清楚编译完的套件到底包括那些文件?
常见的做法是,人工模拟一次编译的过程:
 这样,整个套件的内容就会被放到/usr/local/xxx中,可根据情况编写%file和%exclude段。

※当然,这个只能对源码按GNU方式编写,并使用GNU autotool创建的包有效,若自定义Makefile则不能一概而论。
关于rpm中的执行脚本
如果正在制作的rpm包是准备作为放到系统安装光盘中的话,则需要考虑rpm中定义的脚本是否有问题。由于系统在安装的时候只是依赖于一个小环境进行,而该环境与实际安装完的环境有很大的区别,所以,大部分的脚本在该安装环境中都是无法生效,甚至会带来麻烦的。
所以,对于这样的,需要放到安装光盘中的套件,不加入执行脚本是较佳的方法。
另外,为提供操作中可参考的信息,rpm还提供了一种信号机制:不同的操作会返回不同的信息,并放到默认变量$1中。
 

引用
0代表卸载、1代表安装、2代表升级

  3.2https://www.cnblogs.com/bluevitality/p/6513097.html

#自定义宏,相当于Linux中"Key-Value"变量形式
%define Name nginx  #--->  名称
%define Version 1.2.2  #--->  版本
%define CONFIGFILE 1.conf   #--->   本rpm包中需更换的配置文件......
%define InstallPath /usr/local/nginx  #--->   本rpm包默认安装的路径
 
#定义软件包信息,即:"rpm -qi name.rpm " 查看到的内容
Name:           %{Name}   #--->   引用宏
Version:        %{Version}   #--->   引用宏
Release:        1%{?dist}   #--->   引用宏(自带宏)
Summary:        ....................................... #--->  一些描述信息
License:        GPLv2  #--->  授权协议
URL:            inmoonlight@.163.com
buildroot:      %{_topdir}/BUILDROOT   #--->  指定生产车间(非常重要,因在生成rpm过程中执行make install时会把软件安装到此路径,打包时同样依此目录为“根目录”进行操作)
Source0:        %{Name}-%{Version}.tar.gz   #---> 指定源码编译的文件,默认路径:%{_topdir}/SOURCES  
SOURCE1:        %{CONFIGFILE}  #---> 指定要替换的配置文件,默认路径:%{_topdir}/SOURCES  
BuildRequires:      gcc,make,automake,binutils  #--->  软件依赖信息
Requires:      bash >= 2.0 #--->  定义软件依赖信息,该rpm包所依赖的软件包名称,可用>=或<=表示大或小于特定版本
%description
This is %{Name} .....Just a test rpm suite.............
 
#安装前的准备工作,此处可写入执行脚本
%pre
useradd %{Name} -s /sbin/nologin
 
#安装前的准备:此段默认将Source目录内的源码包在BUILD目录解压为%{Name}-%{Version}格式的目录
%prep
%setup -q -n %{Name}-%{Version}  #---> 参数:-c 解压缩之前先产生目录,-n newdir 将软件包解压在newdir目录
 
#定义config动作
%build
./configure --prefix=%{InstallPath} --user=%{Name} --group=%{Name} 
make %{?_smp_mflags}
 
#定义执行make install时的动作
%install
rm -rf %{buildroot} #---> 删除生产车间内的残留文件
%{__make} install DESTDIR=%{buildroot} #---> 将软件安装至指定的目录
%{__install} -p -D -m 0755  %{SOURCE1} %{buildroot}/usr/local/nginx/conf/%{CONFIGFILE} #--->  替换指定的配置文件
 
#赋予文件的默认权限及设置需在RPM包中保留的文件
%files
%doc
%defattr(-,root,root,-)  #---> 指定包装文件属性,分别是(mode,owner,group),- 表示默认值,文本文件是0644,可执行文件0755
%attr(0755,root,root) /usr/local/nginx/sbin/nginx  #--->  针对单一文件设置权限
%{_prefix}/*
%{_prefix}/local/nginx/conf/%{CONFIGFILE}
 
#制作完成后的清理工作
%clean
rm -rf %{buildroot}
 
#安装后的执行工作,此处可写入执行脚本
%post
chkconfig --add nginx
chkconfig --level 345 nginx on
 
#变更日志
%changelog
 
#---------------------------------------------------------------------------------------------
#    2.1 介绍区域的SOURCE0下增加如下
#    Source0:        %{name}-%{version}.tar.gz 
#    Source1:        index.html 
#    Source2:        init.nginx 
#    Source3:        fastcgi_params 
#    Source4:        nginx.conf 
 
#    2.2 安装区域增加如下
#    make install DESTDIR=%{buildroot} 
#    %{__install} -p -D %{SOURCE1} %{buildroot}/usr/html/index.html  #%{__install}这个宏代表install命令
#    %{__install} -p -D -m 0755 %{SOURCE2} %{buildroot}/etc/rc.d/init.d/nginx 
#    %{__install} -p -D %{SOURCE3} %{buildroot}/etc/nginx/fastcgi_params 
#    %{__install} -p -D %{SOURCE4} %{buildroot}/etc/nginx/nginx.conf 

3.3制作rpm步骤

我们在企业中有的软件基本都是编译的,我们每次安装都得编译,那怎么办呢?那就根据我们的需求制作RPM安装包吧。先来说说基本布骤:

1.Planning what you want             计划做什么rpm包。软件的?库的?

2.Gathering the software to package  收集原材料,即收集源码包

3.Patch the software as need         如果需要打补丁,收集补丁文件。此布骤不是必须

4.Outling any dependenies      确定依赖关系包

------------------  上述动作可由我们手动编译一次软件来确定  -------------------

5.Building RPMs                      开始动手制作RPM包

5.1 Set up the directory stucture 设定好目录结构,我们在这些目录中制作我们的RPM包,我们需要下列目录

 BUILD 源代码解压后的存放目录

 RPMS    制作完成后的RPM包存放目录,里面有与平台相关的子目录

 SOURCES 收集的源材料,补丁的存放位置

 SPECS   SPEC文件存放目录

 SRMPS   存放SRMPS生成的目录

5.2 Place the Sources in the right directory   把源材料放到正确的位置

5.3 Create a spec file that tell rpmbuild command what to do 创建spec文件,这是纲领文件,rpmbuild命令根据spec文件来制作合适的rpm包

5.4 Build the source and binary RPMS 制作src或二进制rpm包

6.Test RPMS 测试制作的PRM包

7.Add signature for RPM  为RPM包签名

3.4制作rpm实例

我还是用连贯的 话为大家叙述一遍吧,我们首先确实我们要为什么做rpm包,通常我们是为一些软件,比如httpd,nginx等,然后去收集这些软件包的源代码,如果有 需要的话也收集这些补丁文件,手动编译安装一下这个软件(当然如果是不需要编译的就不用演练了),确定依赖的软件包,并记录下来,下面开始准备制作 tengine的PRM包吧:

1.建立一个普通用户,有普通用户来制作rpm,用root的可能会因为代码问题导致毁灭的后果

useradd ibuler 
su - ibuler 
2.确定我们在 哪个目录下制作RPM,通常这个目录我们topdir,这个需要在宏配置文件中指定,这个配置文件称为macrofiles,它们通常为 /usr/lib/rpm/macros:/usr/lib/rpm/macros.*:~/.rpmmacros,这个在rhel 5.8中可以通过rpmbuild --showrc | grep macrofiles  查看,6.3的我使用这个找不到,但使用是一样的。你可以通过rpmbuild --showrc | grep topdir 查看你系统默认的工作车间 

rpmbuild --showrc | grep topdir 
 
-14: _builddir  %{_topdir}/BUILD 
-14: _buildrootdir  %{_topdir}/BUILDROOT 
-14: _rpmdir    %{_topdir}/RPMS 
-14: _sourcedir %{_topdir}/SOURCES 
-14: _specdir   %{_topdir}/SPECS 
-14: _srcrpmdir %{_topdir}/SRPMS 
-14: _topdir    %{getenv:HOME}/rpmbuild 
我们还是自定义工作目录(或车间)吧

vi ~/.rpmmacros 
%_topdir        /home/ibuler/rpmbuild    ##目录可以自定义 
 
mkdir ~/rpmbuild  
3.在topdir下建立需要的目录

cd ~/rpmbuild  
mkdir -pv {BUILD,BUILDROOT,RPMS,SOURCES,SPECS,SRPMS} 
4.把收集的源码放到SOURCES下

cp /tmp/tengine-1.4.2.tar.gz SOURCES  ##事先放好的
5.在SPECS下建立重要的spec文件

cd SPECS 
vi tengine.spec          ##内容见后讲解,rhel6.3会自动生成模板 
6.用rpmbuild命令制作rpm包,rpmbuild命令会根据spec文件来生成rpm包 

rpmbuild  
-ba 既生成src.rpm又生成二进制rpm 
-bs 只生成src的rpm 
-bb 只生二进制的rpm 
-bp 执行到pre 
-bc 执行到 build段 
-bi 执行install段 
-bl 检测有文件没包含 
我们可以一步步试,先rpmbuild -bp ,再-bc 再-bi 如果没问题,rpmbuild -ba 生成src包与二进制包吧

7.安装测试有没有问题,能否正常安装运行,能否正常升级,卸载有没有问题

root用户测试安装:

cd /tmp
cp /home/ibuler/rpmbuild/RPMS/x86_64/tengine-1.4.2-1.el6.x86_64.rpm /tmp  
rpm -ivh tengine-1.4.2-1.el6.x86_64.rpm  ##测试安装 
rpm -e tengine                           ##测试卸载,如果版本号比原来的高,升级测试 
8.如果没问题为rpm包签名吧,防止有人恶意更改    ##这个先不写了,有点晚了,以后补上

到此整个流程完毕。下面来说说其中最最重要的spec的格式,先说最简单的,最容易实现的

到此一个简单的tengine RPM包制作好了。

3.5RPM包制作拓展

下面我们来拓展一下,比如:我们想为tengine增加控制脚本,可以通过 start|stop控制,我们还想更换一下默认的首页index.html,默认的fastcgi_params是不能直接连接php的,所以我们替换 为新的配置文件,我们也可以用设置好的nginx.conf替换原来的nginx.conf。基于上述步骤下面继续

1.把修改后的首页文件index.html,控制脚本init.nginx,fastCGI配置文件fastcgi_params,Nginx配置文件nginx.conf 放到SOURCES中 。 

[ibuler@ng1 rpmbuild]$ ls SOURCES/ 
fastcgi_params  index.html  init.nginx  nginx.conf  tengine-1.4.2.tar.gz 
2 编辑tengine.spec,修改

2.1 介绍区域的SOURCE0下增加如下

Source0:        %{name}-%{version}.tar.gz 
Source1:        index.html 
Source2:        init.nginx 
Source3:        fastcgi_params 
Source4:        nginx.conf 
2.2 安装区域增加如下

make install DESTDIR=%{buildroot} 
%{__install} -p -D %{SOURCE1} %{buildroot}/usr/html/index.html  #%{__install}这个宏代表install命令
%{__install} -p -D -m 0755 %{SOURCE2} %{buildroot}/etc/rc.d/init.d/nginx 
%{__install} -p -D %{SOURCE3} %{buildroot}/etc/nginx/fastcgi_params 
%{__install} -p -D %{SOURCE4} %{buildroot}/etc/nginx/nginx.conf 
2.3 脚本区域增加如下

%post 
if [ $1 == 1 ];then 
        /sbin/chkconfig --add nginx 
fi 
2.4 %file区域增加如下

%files 
%defattr (-,root,root,0755) 
/etc/ 
/usr/ 
/var/ 
%config(noreplace) /etc/nginx/nginx.conf  #%config表明这是个配置文件noplace表明不能替换
%config(noreplace) /etc/nginx/fastcgi_params 
%doc /usr/html/index.html  #%doc表明这个是文档
%attr(0755,root,root) /etc/rc.d/init.d/nginx #%attr后面的是权限,属主,属组
3. 生成rpm文件测试

rpmbuild -ba tengine.spec 
4. 安装测试 

到此RPM包制作完毕,你可以根据你的需求制作RPM包吧。

3.6 RPM包签名 https://blog.csdn.net/Michaelwubo/article/details/105843605

生成秘钥过程,由于gpg在生成密码会卡死,需要很久的一段时间随机串,为了加快有两种办法
1、https://blog.csdn.net/ck784101777/article/details/101212318
mv /dev/random /dev/random.bak
ln -s /dev/urandom /dev/random
2、yum install rng-tools
   rng -r /dev/urandom


3、[root@localhost noarch]#  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.

Please select what kind of key you want:
   (1) RSA and RSA (default)
   (2) DSA and Elgamal
   (3) DSA (sign only)
   (4) RSA (sign only)
Your selection? 1
RSA keys may be between 1024 and 4096 bits long.
What keysize do you want? (2048) 
Requested keysize is 2048 bits
Please specify how long the key should be valid.
         0 = key does not expire
      <n>  = key expires in n days
      <n>w = key expires in n weeks
      <n>m = key expires in n months
      <n>y = key expires in n years
Key is valid for? (0) 0
Key does not expire at all
Is this correct? (y/N) y

GnuPG needs to construct a user ID to identify your key.

Real name: wu_bo3
Email address: wu_bo3@hoperun.com
Comment: hello world
You selected this USER-ID:
    "wu_bo3 (hello world) <wu_bo3@hoperun.com>"

Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? O
You need a Passphrase to protect your secret key.

We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.
We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.
gpg: key B48D71E8 marked as ultimately trusted
public and secret key created and signed.

gpg: checking the trustdb
gpg: 3 marginal(s) needed, 1 complete(s) needed, PGP trust model
gpg: depth: 0  valid:   2  signed:   0  trust: 0-, 0q, 0n, 0m, 0f, 2u
pub   2048R/B48D71E8 2020-04-29
      Key fingerprint = 0C74 0495 E9E1 5E48 4AF4  E84A 5DFE 5970 B48D 71E8
uid                  wu_bo3 (hello world) <wu_bo3@hoperun.com>
sub   2048R/B4B2166F 2020-04-29

4、获取列表
[root@localhost noarch]#  gpg --list-keys
/root/.gnupg/pubring.gpg
------------------------
pub   2048R/ED2593A4 2020-04-29
uid                  wu_bo (hello world) <wu_bo@hoperun.com>
sub   2048R/9991B3E2 2020-04-29

pub   2048R/B48D71E8 2020-04-29
uid                  wu_bo3 (hello world) <wu_bo3@hoperun.com>
sub   2048R/B4B2166F 2020-04-29
第一行显示公钥文件和所在的位置。
pub 行描述的是公钥大小(2048)/公钥 id(DDAAB5A8),公钥产生日期(2020-04-29)。
uid 行描述的是由名称、备注和邮件地址组成的字符串。
sub 行表述的是公钥的子钥(可以不用关心)。

5、导出公钥以供大家使用验证
gpg --export -a "wu_bo" > RPM-GPG-KEY-wu_bo
6、编缉 .rpmmacros说明我们用哪一个密钥加密,我们用root加密的那就在/root下编辑
  [root@localhost noarch]# cat ~/.rpmmacros 

%_topdir %(echo $PWD)/rpmbuild
%_gpg_name wu_bo

%_smp_mflags %( \
    [ -z "$RPM_BUILD_NCPUS" ] \\\
        && RPM_BUILD_NCPUS="`/usr/bin/nproc 2>/dev/null || \\\
                             /usr/bin/getconf _NPROCESSORS_ONLN`"; \\\
    if [ "$RPM_BUILD_NCPUS" -gt 16 ]; then \\\
        echo "-j16"; \\\
    elif [ "$RPM_BUILD_NCPUS" -gt 3 ]; then \\\
        echo "-j$RPM_BUILD_NCPUS"; \\\
    else \\\
        echo "-j3"; \\\
    fi )

%__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
7、为rpm包加签名
  rpm --addsign  jettech-indexhtml-7-9.el7.noarch.rpm  
Enter pass phrase:   ##输入密钥
Pass phrase is good. 
centos-indexhtml-7-9.el7.noarch.rpm: 
到此签名添加成功,下面来验证
8、讲刚才导出的公钥导入rpm中
rpm --import RPM-GPG-KEY-wu_bo
9、验证
[root@localhost noarch]# rpm --checksig jettech-indexhtml-7-9.el7.noarch.rpm 
centos-indexhtml-7-9.el7.noarch.rpm: rsa sha1 (md5) pgp md5 OK
Group:

软件包所属类别,具体类别有:

Amusements/Games (娱乐/游戏)

Amusements/Graphics(娱乐/图形)

Applications/Archiving (应用/文档)

Applications/Communications(应用/通讯)

Applications/Databases (应用/数据库)

Applications/Editors (应用/编辑器)

Applications/Emulators (应用/仿真器)

Applications/Engineering (应用/工程)

Applications/File (应用/文件)

Applications/Internet (应用/因特网)

Applications/Multimedia(应用/多媒体)

Applications/Productivity (应用/产品)

Applications/Publishing(应用/印刷)

Applications/System(应用/系统)

Applications/Text (应用/文本)

Development/Debuggers (开发/调试器)

Development/Languages (开发/语言)

Development/Libraries (开发/函数库)

Development/System (开发/系统)

Development/Tools (开发/工具)

Documentation (文档)

System Environment/Base(系统环境/基础)

System Environment/Daemons (系统环境/守护)

System Environment/Kernel (系统环境/内核)

System Environment/Libraries (系统环境/函数库)

System Environment/Shells (系统环境/接口)

User Interface/Desktops(用户界面/桌面)

User Interface/X (用户界面/X窗口)

User Interface/X Hardware Support (用户界面/X硬件支持)
测试通过实例
cat rpmbuild/SPECS/tengine.spec
# This is a sample spec file for test rpm package
%define _prefix    /usr/local/nginx
%define _user      nobody
%define _user_uid  99
%define _group     nobody
%define _group_uid 99
%define _sbin_path      /usr/sbin
 
%define name      Tengine
%define summary   Tengine for Webserver
%define version   2.1.2
%define release   1
%define license   GPL
%define group     Application/WebServer
%define source    tengine-%{version}.tar.gz
%define url       http://tengine.taobao.org/
%define vendor    Taobao
%define packager  webuser
 
Name:           tengine
Version:        2.1.2  
Vendor:         Taobao
Release:    1
Summary:    GUN Tengine2.1.2
 
Group:      Application/WebServer
License:    GPL
URL:            http://tengine.taobao.org/ 
Source0:    tengine-%{version}.tar.gz
Source1:        index.html
Source2:        nginx
Source3:        fastcgi_params
Source4:        nginx.conf
Packager:       webuser
#BuildRoot: /www/rpmbuild/%{name}-%{version}-%{release}-rpmbuild
BuildRoot:      %{_tmppath}/%{name}-%{version}-%{release}-root 
 
#BuildRequires: gcc>=4.4.7, gcc-c++>=4.4.7, zlib-devel>=1.2.3, pcre-devel>=8.12, openssl-devel>=1.0.1e, autoconf>=2.63, automake>=1.11.1
#BuildRequires:  mhash-devel
#BuildRequires:  libxml2-devel
#BuildRequires:  libxslt-devel
#BuildRequires:  libgd-devel
#
#Requires:  gcc>=4.4.7, gcc-c++>=4.4.7, zlib-devel>=1.2.3, pcre-devel>=8.12, openssl-devel>=1.0.1e, autoconf>=2.63, automake>=1.11.1
#Requires:      mhash-devel
#Requires:      libxml2-devel
#Requires:      libxslt-devel
#Requires:      libgd-devel
 
%description
The GNU Tengine WEB Server program. 
 
 
%prep
%setup -q -n tengine-%{version}
 
%build
./configure \
  --user=nobody \
  --group=nobody \
  --prefix=/usr/local/nginx \
  --with-ipv6 \
  --with-debug \
  --with-http_sub_module \
  --with-http_stub_status_module \
  --with-http_ssl_module \
  --with-http_spdy_module \
  --with-http_v2_module \
  --with-http_realip_module \
  --with-http_gzip_static_module \
  --with-http_auth_request_module \
  --with-http_perl_module \
  --with-pcre \
  --add-module=../ngx_cache_purge-2.3  
make
 
 
%install
rm -rf %{buildroot}
make install DESTDIR=%{buildroot}
%{__install} -p -D %{SOURCE1} %{buildroot}/usr/local/nginx/html/index.html
%{__install} -p -D -m 0755 %{SOURCE2} %{buildroot}/etc/rc.d/init.d/nginx
%{__install} -p -D %{SOURCE3} %{buildroot}/usr/local/nginx/conf/fastcgi_params
%{__install} -p -D %{SOURCE4} %{buildroot}/usr/local/nginx/conf/nginx.conf
 
mkdir -p %{buildroot}/%{_initrddir}
(
cat <<'EOF'
#!/bin/bash
# tengine Startup script for the tengine HTTP Server
# this script create it by Luo Hui at 2008.11.11.
# if you find any errors on this scripts,please contact Luo Hui.
# and send mail to farmer.luo at gmail dot com.
#
# chkconfig: - 85 15
# description: tengine is a high-performance web and proxy server.
# processname: tengine
# tengine pidfile: /var/run/tengine.pid
# tengine config: /usr/local/tengine/conf/nginx.conf
  
  
nginxd=%{_prefix}/sbin/nginx
nginx_config=%{_prefix}/conf/nginx.conf
nginx_pid=/var/run/tengine.pid
  
RETVAL=0
prog="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
  
[ -x $nginxd ] || exit 0
  
ulimit -HSn 65535
  
  
# Start tengine daemons functions.
nginx_start() {
  
        if [ -e $nginx_pid ];then
                echo "tengine already running...."
                exit 1
        fi
  
        if [ ! -d %{_prefix}/logs ];then
                mkdir -p %{_prefix}/logs
        fi
  
        if [ ! -d %{_prefix}/tmp ]; then
                mkdir -p %{_prefix}/tmp
        fi
  
        if [ -e $nginx_pid ];then
                echo "tengine already running...."
                exit 1
        fi
  
        echo -n $"Starting $prog: "
        daemon $nginxd -c ${nginx_config}
        RETVAL=$?
        echo
        [ $RETVAL = 0 ] && touch /var/lock/subsys/tengine
        return $RETVAL
  
}
  
  
# Stop tengine daemons functions.
nginx_stop() {
        echo -n $"Stopping $prog: "
        killproc $nginxd
        RETVAL=$?
        echo
        [ $RETVAL = 0 ] && rm -f /var/lock/subsys/tengine $nginx_pid
}
  
  
# reload tengine service functions.
nginx_reload() {
  
        echo -n $"Reloading $prog: "
        #kill -HUP `cat ${nginx_pid}`
        killproc $nginxd -HUP
        RETVAL=$?
        echo
  
}
  
# See how we were called.
case "$1" in
start)
        nginx_start
        ;;
  
stop)
        nginx_stop
        ;;
  
reload)
        nginx_reload
        ;;
  
restart)
        nginx_stop
        nginx_start
        ;;
  
status)
        status $prog
        RETVAL=$?
        ;;
*)
        echo $"Usage: tengine {start|stop|restart|reload|status|help}"
        exit 1
esac
  
exit $RETVAL
EOF
) >%{buildroot}/%{_initrddir}/tengine
 
chmod 755 %{buildroot}/%{_initrddir}/tengine
 
%clean
rm -rf %{buildroot}
 
%pre
grep -q ^%{_group}: /etc/group || %{_sbin_path}/groupadd -g %{_group_gid} %{_group}
grep -q ^%{_user}: /etc/passwd || %{_sbin_path}/useradd -g %{_group} -u %{_user_uid} -d %{_prefix} -s /sbin/nologin -M %{_user}
 
%post
chkconfig --add tengine
chkconfig --level 345 tengine on
  
  
%preun
chkconfig --del tengine
  
  
#%postun
#if [ $1 = 0 ]; then
#        userdel %{_user} > /dev/null 2>&1 || true
#fi
 
%files
%defattr(-,root,root,-)
%dir %{_prefix}/
%attr(0755,%{_user},%{_group}) %dir %{_prefix}/logs
%dir %{_prefix}/modules
%dir %{_prefix}/sbin
%dir %{_prefix}/conf
%dir %{_prefix}/html
%{_prefix}/sbin/nginx
%{_prefix}/sbin/dso_tool
%{_prefix}/conf/module_stubs
%{_prefix}/conf/fastcgi.conf
%{_prefix}/conf/fastcgi_params.default
%{_prefix}/conf/win-utf
%{_prefix}/conf/koi-utf
%{_prefix}/conf/nginx.conf.default
%{_prefix}/conf/fastcgi.conf.default
%config(noreplace) %{_prefix}/conf/fastcgi_params
%{_prefix}/conf/koi-win
%{_prefix}/conf/mime.types
%config(noreplace) %{_prefix}/conf/nginx.conf
%{_prefix}/conf/mime.types.default
%{_prefix}/conf/scgi_params
%{_prefix}/conf/scgi_params.default
%{_prefix}/conf/uwsgi_params
%{_prefix}/conf/uwsgi_params.default
%{_prefix}/html/50x.html
%{_prefix}/html/index.html
/usr/lib64/perl5/perllocal.pod
/usr/local/lib64/perl5/auto/nginx/.packlist
/usr/local/lib64/perl5/auto/nginx/nginx.bs
/usr/local/lib64/perl5/auto/nginx/nginx.so
/usr/local/lib64/perl5/nginx.pm
%{_prefix}/conf/browsers
%{_prefix}/include/nginx.h
%{_prefix}/include/ngx_alloc.h
%{_prefix}/include/ngx_array.h
%{_prefix}/include/ngx_atomic.h
%{_prefix}/include/ngx_auto_config.h
%{_prefix}/include/ngx_auto_headers.h
%{_prefix}/include/ngx_buf.h
%{_prefix}/include/ngx_channel.h
%{_prefix}/include/ngx_conf_file.h
%{_prefix}/include/ngx_config.h
%{_prefix}/include/ngx_connection.h
%{_prefix}/include/ngx_core.h
%{_prefix}/include/ngx_crc.h
%{_prefix}/include/ngx_crc32.h
%{_prefix}/include/ngx_crypt.h
%{_prefix}/include/ngx_cycle.h
%{_prefix}/include/ngx_errno.h
%{_prefix}/include/ngx_event.h
%{_prefix}/include/ngx_event_busy_lock.h
%{_prefix}/include/ngx_event_connect.h
%{_prefix}/include/ngx_event_openssl.h
%{_prefix}/include/ngx_event_pipe.h
%{_prefix}/include/ngx_event_posted.h
%{_prefix}/include/ngx_event_timer.h
%{_prefix}/include/ngx_file.h
%{_prefix}/include/ngx_files.h
%{_prefix}/include/ngx_gcc_atomic_x86.h
%{_prefix}/include/ngx_hash.h
%{_prefix}/include/ngx_http.h
%{_prefix}/include/ngx_http_busy_lock.h
%{_prefix}/include/ngx_http_cache.h
%{_prefix}/include/ngx_http_config.h
%{_prefix}/include/ngx_http_core_module.h
%{_prefix}/include/ngx_http_perl_module.h
%{_prefix}/include/ngx_http_reqstat.h
%{_prefix}/include/ngx_http_request.h
%{_prefix}/include/ngx_http_script.h
%{_prefix}/include/ngx_http_spdy.h
%{_prefix}/include/ngx_http_spdy_module.h
%{_prefix}/include/ngx_http_ssi_filter_module.h
%{_prefix}/include/ngx_http_ssl_module.h
%{_prefix}/include/ngx_http_upstream.h
%{_prefix}/include/ngx_http_upstream_round_robin.h
%{_prefix}/include/ngx_http_v2.h
%{_prefix}/include/ngx_http_v2_module.h
%{_prefix}/include/ngx_http_variables.h
%{_prefix}/include/ngx_inet.h
%{_prefix}/include/ngx_linux.h
%{_prefix}/include/ngx_linux_config.h
%{_prefix}/include/ngx_list.h
%{_prefix}/include/ngx_log.h
%{_prefix}/include/ngx_md5.h
%{_prefix}/include/ngx_murmurhash.h
%{_prefix}/include/ngx_open_file_cache.h
%{_prefix}/include/ngx_os.h
%{_prefix}/include/ngx_palloc.h
%{_prefix}/include/ngx_parse.h
%{_prefix}/include/ngx_pipe.h
%{_prefix}/include/ngx_proc.h
%{_prefix}/include/ngx_process.h
%{_prefix}/include/ngx_process_cycle.h
%{_prefix}/include/ngx_proxy_protocol.h
%{_prefix}/include/ngx_queue.h
%{_prefix}/include/ngx_radix_tree.h
%{_prefix}/include/ngx_rbtree.h
%{_prefix}/include/ngx_regex.h
%{_prefix}/include/ngx_resolver.h
%{_prefix}/include/ngx_segment_tree.h
%{_prefix}/include/ngx_setaffinity.h
%{_prefix}/include/ngx_setproctitle.h
%{_prefix}/include/ngx_sha1.h
%{_prefix}/include/ngx_shmem.h
%{_prefix}/include/ngx_shmtx.h
%{_prefix}/include/ngx_slab.h
%{_prefix}/include/ngx_socket.h
%{_prefix}/include/ngx_string.h
%{_prefix}/include/ngx_sysinfo.h
%{_prefix}/include/ngx_syslog.h
%{_prefix}/include/ngx_thread.h
%{_prefix}/include/ngx_time.h
%{_prefix}/include/ngx_times.h
%{_prefix}/include/ngx_trie.h
%{_prefix}/include/ngx_user.h
/usr/local/share/man/man3/nginx.3pm
%{_initrddir}/tengine
%doc /usr/local/nginx/html/index.html
%attr(0775,root,root) /etc/rc.d/init.d/nginx
 
%changelog
* Mon Jul 4 2016 Beijing <schangech@gmail.com>
- ver 2.1.2

3.7 做好的rpm包放进仓库 可以进行yum安装 发布rpm包 

https://blog.csdn.net/weixin_34107739/article/details/93128861

https://blog.csdn.net/wutangkafei1990/article/details/49449537/ 

     
 sudo yum install createrepo httpd -y 或sudo yum install createrepo nginx -y

https://blog.csdn.net/Michaelwubo/article/details/105878807
(创建本地源repodata作为软件的仓库)

nginx 的配置文件nginx.conf

    location /{
        #echo_sleep 10;
        #root html;
        root html/centos7/x86_64/;
            autoindex on;
            autoindex_exact_size off;
            autoindex_localtime on;
        #index index.html;
        #echo_sleep 2;
    }

/usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf 

[root@localhost aaa]# ls /usr/local/nginx/html/centos7/x86_64/
RPM-GPG-KEY-wubo  file_tree-1.0-1.el7.x86_64.rpm  file_tree-debuginfo-1.0-1.el7.x86_64.rpm  repodata


sudo cp file_tree-1.0-1.el6.x86_64.rpm /usr/local/nginx/html/centos7/x86_64/
首次:sudo createrepo -v /usr/local/nginx/html/centos7/x86_64/

或 createrepo -pdo  /usr/local/nginx/html/centos7/x86_64/ /usr/local/nginx/html/centos7/x86_64/
1/1 - file_tree-1.0-1.el6.x86_64.rpm

cp RPM-GPG-KEY-wubo /usr/local/nginx/html/centos7/x86_64/

第二次:createrepo –update /var/ftp/pub/testing/ 对http服务器上的yum源进行更新,每次有包的变动都要更新,这样客户才会知道新包的存在。

#yum clean all ,清空yum缓存

#yum update server,即可对server进行更新。

Saving Primary metadata
Saving file lists metadata
Saving other metadata

sudo cp ~/RPM-GPG-KEY-wubo /usr/local/nginx/html/centos7/x86_64/
加入yum源:
[yum]
name=yum
baseurl=http://ip:port/pub/testing  #本地file:///var/www/html/repo/
enabled=1
gpgkey=http://ip:port/pub/testing/RPM-GPG-KEY-wubo

#gpgkey=file:///var/www/html/repo/RPM-GPG-KEY-wubo 

 

[base]:容器名称,一定要放在[]中。
name:容器说明,可以自己随便写。
mirrorlist:镜像站点,这个可以注释掉。
baseurl:我们的 yum 源服务器的地址。默认是 CentOS 官方的 yum 源服务器,是可以使用的。如果你觉得慢,则可以改成你喜欢的 yum 源地址。
enabled:此容器是否生效,如果不写或写成 enabled 则表示此容器生效,写成 enable=0 则表示此容器不生效。
gpgcheck:如果为 1 则表示 RPM 的数字证书生效;如果为 0 则表示 RPM 的数字证书不生效。
gpgkey:数字证书的公钥文件保存位置

baseurl=http://mirror.centos.org/centos/$releasever/os/$basearch/      中 $releasever 和 $basearch的值是
$releasever是系统版本使用  cat /etc/yum/vars/releasever =>7.5.1804
$basearch是操作系统位数使用 arch 命令查看


验证:

rpm --import /var/www/html/repo/RPM-GPG-KEY-wubo #必须执行
yum repolist       #查看yum源中是否有软件包
sudo yum install file_tree -y
OK,发布成功~

 

==============================================================

https://blog.csdn.net/weixin_34107739/article/details/93128861

每个 RPM 软件包由三个基本组件组成:
1. 元数据 – 关于软件包的数据:软件包名称、版本、发布、构建程序、日期、依赖关系等。
2. 文件 – 软件包提供的文件存档(包括文件属性)
3. 脚本 – 安装、更新和 / 或删除软件包时,执行这些脚本
当构建 RPM 软件包时,需要指定软件包的元数据,需要提供存档中的文件以及当需要嵌入或卸载软件包时
应运行的脚本。文件在软件包文件中存储为cpio存档。使用rpm2cpio命令可用于将其抽取到当前工作目录,以查看包文件,例如:rpm2cpio package-1.2.3-4.el6.x86_64.rpm | cpio -id

RPM 软件包规则:
若要构建RPM软件包,您需要内部版本规则文件或spec文件。Spec文件是包含关于如何构建可安装的RPM软件包的信息的文本文件。其大致分为五部分:
1. 列出关于软件包的元数据(名称、版本、许可证等)
2. 构建说明,详细说明如何编写和准备软件
3. 脚本小程序,详细说明安装、卸载或升级时要运行的命令
4. 清单,软件包文件列表及其关于软件包安装的权限
5. changelog ,记录对此RPM软件包所做的更改

rpmbuild 步骤:
1. 准备
2. 构建
3. 安装
4. 打包完成的 RPM
5. 清理

试做一个小的RPM包,环境RHEL6.2,留下作为笔记。
一、相关目录
~/rpmbuild/SOURCES/ 存放源码压缩包和补丁文件
~/rpmbuild/BUILD/ 存放源码
~/rpmbuild/SPECS/ 存放spec文件
~/rpmbuild/RPMS/ 最终RPM包
相关命令:rpmbuild
二、准备GPG签名密钥
[kevin@desktop25 SPECS]$ sudo yum install pinentry-gui -y
[kevin@desktop25 work]$ gpg --gen-key
一直往下就行,内容随意,密码自定。后面会提示输入密码,确认密码。确认然密码等待随机数,这时鼠标随意移动生成随机数。我这里yong密码kevin生成密钥:
@查看密钥:
[kevin@desktop25 SPECS]$ gpg --list-key
/home/kevin/.gnupg/pubring.gpg
------------------------------
pub   2048R/8156471D 2012-03-07
uid                  kevin (kevin) <kevin@kevin.org>
sub   2048R/641335E8 2012-03-07
@导出公共密钥:
[kevin@desktop25 SPECS]$ gpg -a -o ~/RPM-GPG-KEY-kevin --export 8156471D
@将以下内容添加到 ~/.rpmmacros 文件(用系统的密钥 ID 替换该八个字符密钥 ID ),因此, RPM 将用您在上面创建的密钥签署软件包。
[kevin@desktop25 SPECS]$ echo '%_gpg_name 8156471D' > ~/.rpmmacros 

二、写个小例子:显示当前目录下的文件及目录树(引用linuxsir上一脚本,谢谢作者)
[kevin@desktop25 work]$ vim file_tree
——————————————————————————————
#!/bin/bash

redir ()
{
        #tab是真正的步长计算器
        tab=$tab$singletab
        line=${tab%"$singletab"}"|-------"

        #local比较关键,它规定了count是当前的参数列表值
        local count=$#

        for file in "$@"; do
                thisfile=${thisfile:-$PWD}/$file

                #判断当前文件是否为目录,如果是就开始递归   
                if [ -d "$thisfile" ]; then
                        
                        #如果当前目录是分枝列表的最底层,则需进行特殊处理。
                        if [ $count -eq 1 ]; then
                                echo -e $line$file/
                                #将前一个|符号去掉,看看目录树就知道为什么了。
                                tab=${tab%"$singletab"}"\t"
                                redir $(ls $thisfile)
                        else

                                echo -e $line$file/
                                redir $(ls $thisfile)
                        fi
                        
                else
                        echo -e $line$file
                fi
                
                thisfile=${thisfile%/*}
                let count=count-1       
        done
        
        #这一步比较有意思,因为从递归出来的tab结尾可能是TAB也可能是$singletab,所以分成两步来去掉。
        tab=${tab%"\t"}
        tab=${tab%"|"}
        line=${tab%"$singletab"}"|-------"
}


singletab="|\t"
userinput="$@"
if ls $userinput; then

        for file in ${userinput:-.}; do
                echo $file
                echo '|'
                if [ -d "$file" ]; then
                        cd $file
                        redir $(ls)
                        cd ..
                fi
        done
else
        echo "$userinput is wrong"
fi
——————————————————————————————
[kevin@desktop25 work]$ chmod +x file_tree 
[kevin@desktop25 work]$ mkdir file_tree-1.0
[kevin@desktop25 work]$ mv file_tree file_tree-1.0/
[kevin@desktop25 work]$ tar -zcf file_tree-1.0.tar.gz file_tree-1.0/
[kevin@desktop25 work]$ vim file_tree.spec
——————————————————————————————
Name:           file_tree    
Version:        1.0    
Release:        1%{?dist}    
Summary:        list files in current folder.    

Group:          file_tree    (所属团体)
License:        GPL    (协议)
URL:            http://192.168.0.25/testing    
Source0:        %{name}-%{version}.tar.gz    (源包的名字)
BuildRoot:      %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX)

BuildRequires:  /bin/rm,/bin/mkdir,/bin/cp    (所需命令)
Requires:       /bin/bash,/bin/date    (所需命令)

%description    
list files in current folder.

%prep
%setup -q


%build (注意这里删除了下面两行 configure 和 make)

%install
rm -rf $RPM_BUILD_ROOT
#make install DESTDIR=$RPM_BUILD_ROOT    (记得注释掉)
mkdir -p $RPM_BUILD_ROOT/usr/local/bin    (创建安装目录)
cp file_tree $RPM_BUILD_ROOT/usr/local/bin    (拷贝文件到目录)


%clean
rm -rf $RPM_BUILD_ROOT


%files
%defattr(-,root,root,-)
#%doc
%attr(0755,root,root)/usr/local/bin/file_tree    (加上脚本的权限)

%changelog    (软件说明)
*Wed Mar 7 2012 kevin<chu345258361@gmail.com>
-Inital RPM
-Added /usr/local/bin/file_tree
——————————————————————————————
[kevin@desktop25 work]$ sudo yum install rpmbuild -y
[kevin@desktop25 work]$ rpmbuild ~    (运行 rpmbuild 命令将创建
RPM 软件包所需的目录结构。)
[kevin@desktop25 work]$ cp file_tree.spec ~/rpmbuild/SPECS/
[kevin@desktop25 work]$ cp file_tree-1.0.tar.gz ~/rpmbuild/SOURCES/
[kevin@desktop25 work]$ cd ~/rpmbuild/SPECS/
[kevin@desktop25 SPECS]$

 

rpm build期间可以指定--sign来直接得到签名了的rpm包

 rpmbuild --sign -ba file_tree.spec 

 

以下均可

rpm --addsign file_tree-1.0.1.rpm
rpm --resign file_tree-1.0.1.rpm

注意:无论是先打包后签名还是打包时直接签名, 验签时都显示"pgp 确定"
对未签名的rpm包进行签名,签名后的文件与签名前的相比只是在文件头部(添加)修改了一些信息, 签名后大了344个字节

输入密码:未报错,OK。
[kevin@desktop25 SPECS]$ pwd
/home/kevin/rpmbuild/SPECS
[kevin@desktop25 SPECS]$ ls ../RPMS/x86_64/
file_tree-1.0-1.el6.x86_64.rpm
生成rpm包 file_tree-1.0-1.el6.x86_64.rpm 。
通过安装密钥和软件包并运行命令来测试软件包:
[kevin@desktop25 x86_64]$ sudo rpm --import ~/RPM-GPG-KEY-kevin 
[kevin@desktop25 x86_64]$ cd ~/rpmbuild/RPMS/x86_64/
[kevin@desktop25 x86_64]$ rpm -ivh file_tree-1.0-1.el6.x86_64.rpm 
[kevin@desktop25 x86_64]$ file_tree     (输入命令file_tree显示当前文件)
OK

四、发布RPM软件包
[kevin@desktop25 x86_64]$ sudo yum install createrepo -y
(创建本地源repodata作为软件的仓库)
[kevin@desktop25 x86_64]$ sudo mkdir /var/ftp/pub/testing
[kevin@desktop25 x86_64]$ sudo cp file_tree-1.0-1.el6.x86_64.rpm /var/ftp/pub/testing/
[kevin@desktop25 x86_64]$ sudo createrepo -v /var/ftp/pub/testing/
1/1 - file_tree-1.0-1.el6.x86_64.rpm

Saving Primary metadata
Saving file lists metadata
Saving other metadata

[kevin@desktop25 x86_64]$ sudo cp ~/RPM-GPG-KEY-kevin /var/ftp/pub/testing/
加入yum源:
[yum]
name=yum
baseurl=http://192.168.0.25/pub/testing
enabled=1
gpgkey=http://192.168.0.25/pub/testing/RPM-GPG-KEY-kevin

验证:
[kevin@desktop20 ~]$ sudo yum install file_tree -y
OK,发布成功~

 

=======================================================================

签名打包整体流程

#rpm-digital-signature.sh

# How to sign your custom RPM package with GPG key

# Step: 1
# Generate gpg key pair (public key and private key)
#
# You will be prompted with a series of questions about encryption.
# Simply select the default values presented. You will also be asked
# to create a Real Name, Email Address and Comment (comment optional).
# 
# If you get the following response:
# -----------------------------------------------------------------------
# We need to generate a lot of random bytes. It is a good idea to perform
# some other action (type on the keyboard, move the mouse, utilize the
# disks) during the prime generation; this gives the random number
# generator a better chance to gain enough entropy.
# -----------------------------------------------------------------------
# Open up a separate terminal, ssh into your server and run this command:
# ls -R /

gpg --gen-key

# Step: 2
# Verify your gpg keys were created

gpg --list-keys

# Step: 3
# Export your public key from your key ring to a text file.
#
# You will use the information for Real Name and Email you used to
# create your key. I used Fernando Aleman and faleman@email.com

gpg --export -a 'Fernando Aleman' > RPM-GPG-KEY-wu_bo3

# Step: 4
# Import your public key to your RPM DB
#
# If you plan to share your custom built RPM packages with others, make sure
# to have your public key file available online so others can verify RPMs

sudo rpm --import RPM-GPG-KEY-wu_bo3

# Step: 5
# Verify the list of gpg public keys in RPM DB

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

# Step: 6
# Configure your ~/.rpmmacros file
#
# You can use the following command to edit if you are on the server:
# vi ~/.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 /root/.gnupg
%_gpg_name wu_bo3
%_gpgbin /usr/bin/gpg

# Step: 7
# Sign your custom RPM package
#
# You can sign each RPM file individually:

rpm --addsign file_tree-1.0.el7.x86_64.rpm

# Or you can `cd` into your RPMS folder and sign them all:

rpm --addsign *.rpm

# Step: 8
# Check the signature to make sure it was signed
#
# Watch for 'gpg OK' as in this example:
# file_tree-1.0.el7.x86_64.rpm
: (sha1) dsa sha1 md5 gpg OK

rpm --checksig file_tree-1.0.el7.x86_64.rpm


# Tip!
# Sign package during build
#
# To sign a package while it's being built, simply add '--sign'

rpmbuild -ba --sign file_tree.spec

=================================================

 1 操作步骤:
 2 制作rpm包的服务器:
 3 
 4 由于制作rpm包的用户打算使用rpmuser用户,所以可以将gpg的一系统操作在rpmuser下进行,我使用的是root,然后再将/root/.gnupg/拷贝到/home/rpmuser/.gnugp/ 再改chown -R rpmuser:rpmuser /home/rpmuser/.gnugp/
 5 
 6 1)gpg --gen-key
 7 
 8 pg: /root/.gnupg/trustdb.gpg: trustdb created
 9 gpg: key 2D50D623 marked as ultimately trusted
10 public and secret key created and signed.
11 
12 2)gpg --list-keys
13 [root@localhost rpmbuild]# gpg --list-keys
14 /root/.gnupg/pubring.gpg
15 ------------------------
16 pub   1024R/2D50D623 2018-08-06
17 uid                  FeiTian (FeiTian Released) <sales@ftsafe.com>
18 sub   1024R/FF885B48 2018-08-06
19 
20 
21 3)gpg --export -a 2D50D623 > RPM-GPG-KEY
22 
23 4)配置 ~/.rpmmacros file
24 # vim ~/.rpmmacros
25 #
26 # %_signature => This will always be gpg
27 # %_gpg_path  => Enter full path to .gnupg in your home directory
28 # %_gpg_name  => Use the Real Name you used to create your key
29 # %_gpbin     => run `which gpg` (without ` marks) to get full path 
30 
31 %_signature gpg
32 %_gpg_path /root/.gnupg
33 %_gpg_name Fernando Aleman
34 %_gpgbin /usr/bin/gpg
35 
36 
37 5)为DIY的包签名
38 rpm --addsign git-1.7.7.3-1.el6.x86_64.rpm
39 或
40 rpm --addsign *.rpm
41 root下对未签名的rpm包进行签名,签名后的文件与签名前的相比只是在文件头部(添加)修改了一些信息, 签名后大了344个字节。
42 然后rpmuser下的操作却整个包没有相同的地方。
43 
44 6)rpm build期间可以指定--sign来直接得到签名了的rpm包
45 rpmbuild -ba --sign SPECS/hello.spec
46 
47 
48 
49 
50 
51 
52 下载rpm者其他试用者也就是其他服务器节点:
53 1)导入发布者公钥RPM-GPG-KEY
54 sudo rpm --import RPM-GPG-KEY
55 
56 2)Verify the list of gpg public keys in RPM DB。查看当前服务器导入了那些gpg公钥信息
57 rpm -q gpg-pubkey --qf '%{name}-%{version}-%{release} --> %{summary}\n'
58 
59 3)成功导入公钥后才能验签 (观察'gpg OK')---先打包后签名的rpm包
60 [root@localhost GPG]# rpm --checksig /usr/local/hello-0.1-1.x86_64.rpm
61 /usr/local/hello-0.1-1.x86_64.rpm: rsa sha1 (md5) pgp md5 确定
62 否则,提示不正确                        ---先打包后签名的rpm包
63 [root@localhost GPG]# rpm --checksig /usr/local/hello-0.1-1.x86_64.rpm
64 /usr/local/hello-0.1-1.x86_64.rpm: RSA sha1 (MD5) PGP md5 不正确
65 
66 
67 
68 注意:无论是先打包后签名     还是    打包时直接签名,       验签时都显示"pgp 确定"
69 [root@localhost GPG]# rpm --checksig  ./hello-0.1-1.x86_64.rpm.signed_first_rpm_second_sign
70 ./hello-0.1-1.x86_64.rpm.signed_first_rpm_second_sign: rsa sha1 (md5) pgp md5 确定
71 [root@localhost GPG]# 
72 [root@localhost GPG]# 
73 [root@localhost GPG]# 
74 [root@localhost GPG]# rpm --checksig  ./hello-0.1-1.x86_64.rpm_rpmbuild_with--sign 
75 ./hello-0.1-1.x86_64.rpm_rpmbuild_with--sign: rsa sha1 (md5) pgp md5 确定

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

rpmbuild制作包的详细过程 的相关文章

  • linux grep 多个文件,Linux多文件查找工具之grep

    1 简介 grep全称Global Regular Expression Print 全局正则表达式打印 在这里面提到了三个关键词 我们逐个进行分析 这样有助于我们理解 grep这个命令的作用 1 global说明该命令可以用于所有用户 交
  • VHDL——含异步清零和同步使能的加法计数器源程序

    library ieee use ieee std logic 1164 all use ieee std logic arith all use ieee std logic unsigned all entity counter is
  • Kubernetes YAML 文件 详细解释

    To deploy Dashboard execute following command kubectl apply f https raw githubusercontent com kubernetes dashboard v1 10
  • C语言实现冒泡排序和快速排序

    写在前面的话 以排升序为例 目录 冒泡排序 单趟 循环 优化 快速排序 单趟 递归 优化 不足 冒泡排序 通过重复地走访过要排序的元素列 依次比较两个相邻的元素 如果顺序错误就把他们交换过来 走访元素的工作是重复地进行 直到没有相邻元素需要
  • mongodb搭建Replica Set

    1 创建数据文件夹 mkdir p data master mkdir p data slaver mkdir p data arbiter 效果 data 文件夹包含 arbiter master slaver 三个文件夹 2 创建日志存
  • STM32无人机-四轴四元数姿态解算与卡尔曼滤波

    四轴四元数姿态解算 MPU6050是一种非常流行的空间运动传感器芯片 可以获取器件当前的三个加速度分量和三个旋转角速度 什么是四元数 这部分很难 新手知道四元数的功能是将 6 轴传感器数据转化为三轴姿态角度数据即可 四元数解算程序店家已经封
  • 机器学习——决策树+剪枝(适用ID3与C4.5)

    问 标准的ID3算法支持剪枝操作 答 错误 标准的ID3算法不支持剪枝操作 该算法通过递归地构建决策树 在每个节点上使用信息增益作为判定条件进行特征选择 直到遍历完所有特征或者将数据集划分为同一类别的样本 ID3算法容易产生过拟合现象 剪枝
  • 记录一次NestedScrollView嵌套RecyclerView再嵌套RecyclerView的坑

    由于要做一些复杂的界面 需要在NestedScrollView下嵌套RecyclerView 在RecyclerView的条目中又有一个横向的RecyclerView 在 gt Android 7 0系统当中运行是显示正常的 但是在低于7
  • ctfshow 限时活动 红包挑战7和红包挑战8详细答案和见解

    ctfshow 利用create function函数 并绕过base64编码 highlight file FILE error reporting 0 extract GET create function name base64 en
  • 大数据工程师和Java后台开发的技术要求区别

    每家公司对大数据工作和java开发的要求不尽相同 目前长期从事数据库管理 挖掘 编程工作的人 包括传统的量化分析师 hadoop方面的工程师 以及任何在工作中需要通过数据来进行判断决策的管理者 比如某些领域的运营经理等 都可以尝试大数据工程
  • linux:命令行 &&与

    参考 Linux 命令行 与 简书 总结 command1 command2 只有前面命令执行成功 后面命令才继续执行 shell中 左边的命令 命令1 返回真 即返回0 成功被执行 后 右边的命令 命令2 才能够被执行 command1
  • mtk camera 移植步骤

    mtk camera 移植步骤 1 Kernel层驱动代码文件添加 mediatek custom doov92 wet tdd kernel imgsensor 下添加imx179 mipi raw 2lane 目录如下 imx179 m
  • 视频监控系统时间显示常见故障分析 及时间同步解决方案

    分别任职湖北三峡职业技术学院电子信息学院教研室主任 宜昌市教育技术装备站网络中心主任 宜昌市公安局科研所所长 视频监控系统是指综合应用视音频监控 通信 计算机网络等技术监视设防区域 并实时显示 记录现场图像的电子系统或网络 系统可以在非常事
  • Ubuntu 22.04部署Kubernetes 1.25

    Ubuntu 22 04部署Kubernetes 1 25 基本环境 系统和软件版本 master节点ip 安装过程 1 准备工作 1 1 修改主机名 1 2 关闭swap分区 1 3 关闭防火墙 1 4 重启电脑 确认swap和防火墙均已
  • angular组件封装

    1 这个公共组件的封装 2 c dropdown component ts import Component OnInit Input EventEmitter Output ViewChild from angular core Comp
  • 08LinuxC线程学习之pthread_join函数以及根据参2获取返回值的案例

    1 pthread join函数 int pthread join pthread t thread void retval 功能 阻塞等待线程退出 获取线程退出状态 其作用 对应进程中 waitpid 函数 成功 0 失败 错误号 参1
  • 1033. 旧键盘打字

    1033 旧键盘打字 20 时间限制 200 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 CHEN Yue 旧键盘上坏了几个键 于是在敲一段文字的时候 对应的字符就不会出现 现在给出应该输
  • 【笔记】Nginx+Ngrok实现80端口服务器+80端口内网穿透

    安装ngrok 笔记 ngrok安装方法 安装完毕后ngrok默认将服务器的80端口占用 这时 需要修改启动脚本 vim etc init d ngrokd 找到如下部分 nohup sudo bin ngrokd tlsKey serve
  • 【每日一题】-金牌榜排序

    文章目录 题目描述 输入 输出 样例 解析 代码 题目描述 2012伦敦奥运会即将到来 大家都非常关注奖牌榜的情况 现在我们假设奖牌榜的排名规则如下 1 首先gold medal 数量多的排在前面 2 其次silver medal 数量多的
  • SpringBoot中 Lua函数操作redis

    Lua Lua 是一个简洁 轻量 可扩展的脚本语言 它的特性有 轻量 源码包只有核心库 编译后体积很小 高效 由 ANSI C 写的 启动快 运行快 内嵌 可内嵌到各种编程语言或系统中运行 提升静态语言的灵活性 如 OpenResty 就是

随机推荐

  • xman的思维导图快捷键_这个良心好用的思维导图软件,居然不用氪金充钱

    今天给大家介绍一款免费的在线思维导图工具 GitMind 提供了丰富的功能和模板 可免费导出 JPG PNG 图片 PDF 文档以及 TXT 文本等多种格式 此外 GitMind 还集成了制作流程图的能力 网站展示的流程图示例有泳道图 拓扑
  • Springboot项目使用达梦数据库

    下载达梦数据库驱动 Dm7JdbcDriver16 jar 执行maven命令把驱动包打入本地maven仓库 mvn install install file DgroupId com dm DartifactId DmJdbcDriver
  • 学校计算机如何脱控,学校机房脱控方法(已控状态)/极域电子教室脱离老师控制图文教程...

    老师没控制的时候 刀友应该都会断掉控制吧 我就不说了 就说说老师老师已经控制了该如何脱离控制 拔网线比较麻烦就不说了 以下操作之前先检查极域电子教室 右键右下角极域电子教室端 打开设置 把禁止结束学生端进程前面的勾去掉 把断网锁屏前面的勾去
  • 部署ELFK

    目录 ELFK ES logstash filebeat kibana 环境准备 所有节点 Elasticsearch 集群部署 在Node1 Node2节点上操作 修改elasticsearch主配置文件 es 性能调优参数 启动elas
  • Marriage is Stable

    http acm hdu edu cn showproblem php pid 1522 Problem Description Albert Brad Chuck are happy bachelors who are in love w
  • JVM--三大子系统详解

    首先需要了解java的命令 javac 将java文件编译为 class文件 里面是一些二进制文件 javap c 将 class文件变为反汇编 例如 javap c hello class gt demo txt 可以将class文件转化
  • GPIO介绍

    目录 一 GPIO是什么 二 STM32引脚分类 三 GPIO内部结构 四 GPIO的工作模式 4 1 输入模式 模拟 上拉 下拉 浮空 4 2 输出模式 推挽 开漏 4 3 复用功能 推挽 开漏 4 4 模拟输入输出 上下拉无影响 一 G
  • c语言将csv文件存储到数组,读取CSV文件并将值存储到数组中

    青春有我 我最喜欢的CSV解析器是一个内置在 NET库中的解析器 这是Microsoft VisualBasic命名空间中隐藏的宝藏 下面是一个示例代码 using Microsoft VisualBasic FileIO var path
  • ConcurrentHashMap 的实现原理

    目录 常见问题 1 concurrentHashMap特点 2 concurrentHashMap如何保证效率高 又安全的 1 构造函数 2 put方法 2 1 initTable 2 2 addCount方法 3 get方法 常见问题 1
  • 【SpinalHDL】Windows10系统搭建SpinalHDL 开发环境

    本文主要记载如何从零开始在win平台搭建SpinalHDL开发环境并跑通第一个spinal project demo 1 环境准备 1 1 软件下载 首先列出需要安装的软件 并逐一对这些软件的功能和其必要性进行说明 需要安装的软件 IDEA
  • 继电器的过流过压保护(自恢复保险丝)

    简述 继电器广泛应用于消费电子产业和工业设备中 它具有控制系统 又称输入回路 和被控制系统 又称输出回路 它实际上是用较小的电流去控制较大电流的一种 自动开关 故在电路中起着自动调节 安全保护 转换电路等作用 继电器可能因为过流或者过压而损
  • arduino/mixly TFT显示SD卡的图片

    一 器材 SD卡模块 1 8寸TFT屏 ST7735 arduino uno开发板 SD卡 二 接线 TFT屏 arduino uno GND GND VCC 5V SCL D13 SDA D11 RES D8 DC D10 CS D9 B
  • Java锁机制

    Java锁主要是为了解决线程安全问题 当多个线程共享同一个变量时可能会出现同时修改变量的情况 这样会导致最终计算结果错误 未解决该问题 Java提供了各种锁来确保数据能够被正常修改和访问 最常用的比如synchronized 一 互斥同步
  • python计算机视觉学习第三章——图像到图像的映射

    目录 引言 一 单应性变换 1 1 直接线性变换算法 1 2 仿射变换 二 图像扭曲 2 1 图像中的图像 2 2 分段仿射扭曲 2 2 图像配准 三 创建全景图 3 1 RANSAC 随机一致性采样 3 2 拼接图像 四 总结 引言 本章
  • [4G&5G专题-119]:5G培训应用篇-4-5G典型行业应用的解决方案(车联网、智慧医疗、智能教育、智能电网)

    目录 前言 前言 1 总目录 前言 2 本章 第1章 5G行业应用介绍 第2章 车联网解决方案 2 1 车联网概述 2 2 车联网需求分析 2 3 车联网解决方案 第3章 智慧医疗解决方案 第4章 智能教育解决方案 第5章 智能电网解决方案
  • Mybatis配置多数据源

    前言 Spring Boot项目使用Mybatis 既要从上游系统同步数据 又要操作本系统的数据库 所以需要引入双数据源 配置Mybatis 步骤 一 配置双数据源 连接数据库 1 禁用Spring Boot数据源的自动装配 在启动类 Sp
  • 请求调页存储管理方式的模拟 含详细代码和实验结果截图

    请求调页存储管理方式的模拟 实验目的 通过对页面 页表 地址转换和页面置换过程的模拟 加深对请求调页系统的原理和实现过程的理解 实验内容 假设每个页面中可存放10条指令 分配给一作业的内存块数为4 用C语言模拟一作业的执行过程 该作业共有3
  • 为什么Hadoop集群中机器台数多反而执行速度慢?

    这里我对这个现象给出解释 由于水平有限 发现错误 请及时留言 或站内和我联系 这里假设集群中有slave1 slave2 slave3三个节点 其中slave3工作效率低 一共有6个任务 需要去做 slave1和slave2执行一个任务是1
  • 104个精选计算机毕业设计项目,助你制作出色的程序,一定要试试

    对于即将面临毕业设计的计算机专业的同学们 如何选题和完成毕设项目成为一个重要而又棘手的问题 今天给大四的同学分享毕业设计项目 希望对正在为毕业设计发愁的小伙伴有帮助 一 成品列表 以下所有springboot框架项目的源码博主已经打包好上传
  • rpmbuild制作包的详细过程

    https www cnblogs com schangech p 5641108 html https www ibm com developerworks cn linux l rpm 一 目录结构生成 1 工具安装rpmdevtool