1:编译源码
这里拿HDP3.1.5的hbase_2_1_6来举例子
编译详细步骤请看如下链接
https://blog.csdn.net/qq_37865420/article/details/106123779
更多的困难是网络原因,其中最终的编译执行命令如下
nohup mvn package -DskipTests assembly:single validate -Denforcer.skip=true >../mvnLog 2>&1 &
编译成功后,在habse-assembly目录下有一个tar.gz包
其余的组件也得编译。
源码中有assembly模块的基本编译完在此目录下都会生成一个tar.gz包
再拿Phoenix来举个例子
源码目录如下
编译
mvn clean package -DskipTests
编译后如下,也有个tar.gz
HDP3.1.5各组件编译出的tar.gz包我们先留着,一会要用
2:获取旧版本源文件目录
这里拿了个HDP3.1.0版本来举例子
如下是 HDP3.1.0下hbase_3_1_0_0_78-2.0.2.3.1.0.0-78版本的rpm包列表,可以看到,除过第一个最大的rpm包,还有另外的六个比较小的rpm包
所谓源文件目录就是从rpm包获取到的一个目录,就是上图所指的usr*一系列目录。我们需要利用这些目录为下一步中制作新版本3.1.5RPM打包目录做准备
怎么获得这些目录呢?
这里有两个命令需要记一下
2.1:rpm包获取对应的源文件目录
源文件目录:其实就是之前HDP3.1.0这种旧版本rpm打包前的文件目录
rpm2cpio hbase_3_1_0_0_78-2.0.2.3.1.0.0-78.noarch.rpm | cpio -div
这样子就会获得一个usr目录,就像上图中usr1目录一样。
其余的usr_*目录是我将剩余的rpm包获得的usr目录改名字以便区分
2.2:rpm包获取对应的.spec文件
.spec文件:这个spec文件是指的之前HDP3.1.0这种旧版本rpm打包前参考的脚本,里面包含很多宏定义以及步骤化的指令,当然也可以包含linux文件操作命令,后续会详解
rpmrebuild -e -p --spec-only=hbase_3_1_0_0_78-master-2.0.2.3.1.0.0-78.spec hbase_3_1_0_0_78-master-2.0.2.3.1.0.0-78.noarch.rpm
执行完上述命令后会进入一个vim编辑器,我们:wq保存当前目录即可
就会生成hbase_3_1_0_0_78-master-2.0.2.3.1.0.0-78.spec
文件了
有了这两个东西,怎么用的,这里给大家先提下
usr目录用来用作对比,然后将之前编译好的源码tar.gz解压,构建一个相同文件目录的usr目录,最终进行3.1.5的rpm制作
spec文件用作改写,来生成我们HDP3.1.5独有的spec文件 ,最终进行3.1.5的rpm制作
顺便提一下,上面rpm2cpio与rpmrebuild命令如果command not found的话,就需要你安装了
3:创建RPM打包目录
这个目录我选择手动创建(网上说可以使用工具自动生成,懒得整,自己make就行)
在用户家目录创建rpmbuild目录,在该目录下生成如下6个目录
目录名 | 说明 |
---|---|
BUILD | 编译rpm包的临时目录 |
BUILDROOT | 编译后生成的软件临时安装目录 |
RPMS | 最终生成的可安装rpm包的所在目录 |
SOURCES | 所有源代码和补丁文件的存放目录 |
SPECS | 存放SPEC文件的目录(重要) |
SRPMS | 软件最终的rpm源码格式存放路径 |
4:rpm打包流程概述
这里说明下哈,上述目录树是常规打rpm包的目录,大概流程如下
4.1:常规打rpm包流程
- 将源码塞进SOURCES目录下
- 直接编写SPEC文件
- 然后直接开始打rpm包(rpmbuild命令)
- 他会按照spec文件的脚本内容先将源码解压到BUILD目录中
- 然后再BUILD目录下进行编译
- 之后将编译完需要的文件copy到BUILDROOT目录下并制作rpm包
- 最后将BUILDROOT目录下内容自动清除
4.2:改进方式
但是3.1这里有问题
一是自动编译HDP3.1.5的过程不可控,二是SPEC文件编写困难
所以本文采用一种捷径方式
- 梳理老版本rpm抽取出的usr源文件目录;
- 将源码编译完后的目录进行改造,构建一个新版本的源文件目录并放置在BUILD目录下;
- 对照老版本的SPEC文件,进行新版本SPEC文件的改写
- 执行改写的spec文件(rpmbuild),在RPMS中获得对应架构的rpm包
5:自定义BUILD目录
这里就是像上面流程中所说的那样,对照老版本rpm抽取出的usr源文件目录对源码编译完成后的目录(第1大步的tar.gz解压后的文件)进行改造。
怎么改造呢,下面拿hbase来举个例子
如下图,HDP3.1.0版本中的hbase是2.0.2版本,rpm包有7个,一个最大的主rpm包,剩余为7个比较小的rpm包
我们在2.1步骤中已经使用rpm2cpio命令获得了他们对应的usr目录,这里将usr目录进行了重命名方便区别,如下图
5.1:梳理HDP3.1.0rpm包的源文件目录
我们尝试用tree命令看下最大的那个rpm包生成的usr1目录
usr1/
└── hdp
└── 3.1.0.0-78
├── etc
│ ├── default
│ │ └── hbase
│ ├── hbase
│ │ └── conf.dist
│ │ ├── hadoop-metrics2-hbase.properties
│ │ ├── hbase-env.cmd
│ │ ├── hbase-env.sh
│ │ ├── hbase-policy.xml
│ │ ├── hbase-site.xml
│ │ ├── log4j.properties
│ │ └── regionservers
│ └── security
│ └── limits.d
│ └── hbase.nofiles.conf
└── hbase
├── bin
│ ├── considerAsDead.sh
│ ├── draining_servers.rb
│ ├── get-active-master.rb
│ ├── hbase
│ ├── hbase-cleanup.sh
│ ├── hbase.cmd
│ ├── hbase-common.sh
│ ├── hbase-config.cmd
│ ├── hbase-config.sh
│ ├── hbase-daemon.sh
│ ├── hbase.distro
│ ├── hbase-jruby
│ ├── hirb.rb
│ ├── region_mover.rb
│ ├── region_status.rb
│ ├── replication
│ │ └── copy_tables_desc.rb
│ ├── shutdown_regionserver.rb
│ ├── start-hbase.cmd
│ ├── stop-hbase.cmd
│ └── test
│ └── process_based_cluster.sh
├── conf -> /etc/hbase/conf
├── doc
│ ├── LICENSE.txt
│ ├── NOTICE.txt
│ └── README.txt
├── etc
│ └── rc.d
│ └── init.d
│ └── 其余rpm包的源文件安装
├── hbase-webapps
│ ├── master
│ │ ├── index.html
│ │ └── WEB-INF
│ │ └── web.xml
│ ├── regionserver
│ │ ├── index.html
│ │ └── WEB-INF
│ │ └── web.xml
│ ├── rest
│ │ ├── index.html
│ │ └── WEB-INF
│ │ └── web.xml
│ ├── static
│ │ ├── css
│ │ │ ├── bootstrap.css
│ │ │ ├── bootstrap.min.css
│ │ │ ├── bootstrap-theme.css
│ │ │ ├── bootstrap-theme.min.css
│ │ │ └── hbase.css
│ │ ├── fonts
│ │ │ ├── glyphicons-halflings-regular.eot
│ │ │ ├── glyphicons-halflings-regular.svg
│ │ │ ├── glyphicons-halflings-regular.ttf
│ │ │ └── glyphicons-halflings-regular.woff
│ │ ├── hbase_logo_med.gif
│ │ ├── hbase_logo.png
│ │ ├── hbase_logo_small.png
│ │ ├── js
│ │ │ ├── bootstrap.js
│ │ │ ├── bootstrap.min.js
│ │ │ ├── jquery.min.js
│ │ │ └── tab.js
│ │ └── jumping-orca_rotated_12percent.png
│ └── thrift
│ ├── index.html
│ └── WEB-INF
│ └── web.xml
├── include
│ └── thrift
│ ├── hbase1.thrift
│ └── hbase2.thrift
├── lib
│ ├── animal-sniffer-annotations-1.17.jar
│ ├── XXX.jar
│ ├── ruby
│ │ ├── hbase
│ │ │ ├── admin.rb
│ │ │ ├── hbase.rb
│ │ │ ├── quotas.rb
│ │ │ ├── replication_admin.rb
│ │ │ ├── rsgroup_admin.rb
│ │ │ ├── security.rb
│ │ │ ├── table.rb
│ │ │ ├── taskmonitor.rb
│ │ │ └── visibility_labels.rb
│ │ ├── hbase_constants.rb
│ │ ├── irb
│ │ │ └── hirb.rb
│ │ ├── jruby-complete-9.1.13.0.jar
│ │ ├── shell
│ │ │ ├── commands
│ │ │ │ ├── add_labels.rb
│ │ │ │ ├── XXX.rb
│ │ │ ├── commands.rb
│ │ │ └── formatter.rb
│ │ └── shell.rb
│ ├── shaded-clients
│ │ ├── hbase-shaded-client-2.1.6.3.1.5.1-2.jar
│ │ ├── hbase-shaded-client-byo-hadoop-2.1.6.3.1.5.1-2.jar
│ │ └── hbase-shaded-mapreduce-2.1.6.3.1.5.1-2.jar
│ ├── snappy-java-1.0.5.jar
│ ├── spymemcached-2.12.2.jar
│ ├── stax2-api-3.1.4.jar
│ ├── validation-api-1.1.0.Final.jar
│ ├── woodstox-core-5.0.3.jar
│ ├── xz-1.0.jar
│ ├── zkcli
│ │ └── jline-0.9.94.jar
│ ├── zookeeper-3.4.6.3.1.5.1-2.jar
│ └── zookeeper.jar -> zookeeper-3.4.6.3.1.5.1-2.jar
├── logs
│ └── hbase -> /var/log/hbase
├── man
│ └── man1
└── pids
└── hbase -> /var/run/hbase
上图就是5.1中梳理的最大rpm包对应源文件目录
其中在这个usr/hdp/3.1.0.0-78/hbase目录下
conf目录是ln -s /etc/hbase/conf conf这样创建的
然后etc/rc.d/init.d/中其实是空的,但我为什么写了其余rpm包的源文件安装
这句话呢,就是因为在5.1中梳理的是老版本最大的rpm对应的usr1目录,而其余的usr_doc,usr_master,usr_regionserver,udr_rest,usr_thrift,usr_thrift2
六个文件目录如下
5.2:梳理HDP3.1.5源码编译目录
我们源码解压后是HDP3.1.5的hbase2.1.6版本的目录,如下
有bin/,conf/,hbase-webapps/,lib/,再是一些说明文档
5.3:对比新老版本目录结构
基本可以看到源码编译目录其实跟旧版本rpm包提取的文件目录里usr/hdp/3.1.0.0-78/hbase部分结构基本吻合
旧版本中除过doc目录中是在/usr/hdp/3.1.0.0-78/hbase/doc下直接生成说明文档外,其余小的rpm包对应的都是在/usr/hdp/3.1.0.0-78/hbase/etc/下有配置文件的
所以一共七个源文件目录,六个小的都是配置文件跟说明文档,添加到最大的rpm对应的目录中即是最终的一个完整目录了。
我们可以将按照5.1步骤中的旧版本目录文件结构,对新版本进行如上目录的搭建,结果肯定也能形成一个完整的目录了,将此新版本对应的完整目录作为4.2步骤中所说的自定义目录,放到BUILD中去,执行相应的spec脚本文件,就应该可以打出hbase-2.1.6(HDP-3.1.5)的RPM包了
5.4:自定义目录具体操作
5.4.1:创建hbase最大的rpm包对应BUILD中的目录
- 在BUILD目录下创建hbase_3_1_5_1_2-2.1.6.3.1.5.1-2.noarch目录并创建hbase,etc目录
cd ~/rpmbuild/BUILD
mkdir hbase_3_1_5_1_2-2.1.6.3.1.5.1-2.noarch/usr/hdp/3.1.5.1-2/hbase
mkdir hbase_3_1_5_1_2-2.1.6.3.1.5.1-2.noarch/usr/hdp/3.1.5.1-2/etc
(创建这个目录是因为5.2步骤中有etc目录,我们这里也照猫画虎,然后将旧版本的目录内容cp过来) - 将新版本编译目录(5.2步骤中)整个cp到上面的hbase目录中去
- 这里我还创建了与usr同级别的两个目录
mkdir hbase_3_1_5_1_2-2.1.6.3.1.5.1-2.noarch/etc
mkdir hbase_3_1_5_1_2-2.1.6.3.1.5.1-2.noarch/var
5.4.1:创建hbase其余六个rpm包对应BUILD中目录
但是发现HDP3.1.5源码编译的那个目录中没有HDP3.1.0.0-78中的那些小rpm包对应的配置文件呀,这就犯难了
最后实在没办法,就打算在3.1.5新版本中也重新打6个小的rpm包,用到的配置文件跟说明文档就从老版本3.1.0中去取,对应的也像上面,在BUILD目录下创建其余六个rpm对应的BUILD目录(我们不难看出,其实BUILD目录下一个目录代表最后生成一个rpm包)
具体操作如下
cd ~/rpmbuild/BUILD
mkdir hbase_3_1_5_1_2-doc-2.1.6.3.1.5.1-2.noarch/usr/hdp/3.1.5.1-2/hbase
mkdir hbase_3_1_5_1_2-master-2.1.6.3.1.5.1-2.noarch/usr/hdp/3.1.5.1-2/hbase
mkdir hbase_3_1_5_1_2-regionserver-2.1.6.3.1.5.1-2.noarch/usr/hdp/3.1.5.1-2/hbase
mkdir hbase_3_1_5_1_2-rest-2.1.6.3.1.5.1-2.noarch/usr/hdp/3.1.5.1-2/hbase
mkdir hbase_3_1_5_1_2-thrift-2.1.6.3.1.5.1-2.noarch/usr/hdp/3.1.5.1-2/hbase
mkdir hbase_3_1_5_1_2-thrift2-2.1.6.3.1.5.1-2.noarch/usr/hdp/3.1.5.1-2/hbase
最后就直接将3.1.0版本中那几个小rpm包的配置文件都copy过来放到上面3.1.5新创建的对应目录中去
6:SPEC文件编写
SPEC文件语法查看
https://blog.csdn.net/wjlkoorey/article/details/52012971
https://blog.csdn.net/get_set/article/details/53453320
看完之后语法基本就懂了,但是我在这里依据hbase这个目录精简下spec的用法,只挑些我在实际研发中用的比较频繁的总结下
首先要知道,spec文件是在rpmbuild/SPECS目录下。
我们回想下rpmbuild目录结构
6.1 rpmbuild目录
默认位置 | 宏代码 | 名称 | 用途 |
---|---|---|---|
~/rpmbuild/SPECS | %_specdir | Spec 文件目录 | 保存 RPM 包配置(.spec)文件 |
~/rpmbuild/SOURCES | %_sourcedir | 源代码目录 | 保存源码包(如 .tar 包)和所有 patch 补丁 |
~/rpmbuild/BUILD | %_builddir | 构建目录 | 源码包被解压至此,并在该目录的子目录完成编译 |
~/rpmbuild/BUILDROOT | %_buildrootdir | 最终安装目录 | 保存 %install 阶段安装的文件 |
~/rpmbuild/RPMS | %_rpmdir | 标准 RPM 包目录 | 生成/保存二进制 RPM 包 |
~/rpmbuild/SRPMS | %_srcrpmdir | 源代码 RPM 包目录 | 生成/保存源码 RPM 包(SRPM) |
上表中宏代码的意思是这些目录在spec文件中如何表示的。
6.2 spec文件阶段
阶段 | 读取的目录 | 写入的目录 | 具体动作 |
---|---|---|---|
%prep | %_sourcedir | %_builddir | 读取位于 `%_sourcedir 目录的源代码和 patch 。之后,解压源代码至 %_builddir 的子目录并应用所有 patch |
%build | %_builddir | %_builddir | 编译位于 %_builddir 构建目录下的文件。通过执行类似 ./configure && make 的命令实现。 |
%install | %_builddir | %_buildrootdir | 读取位于 %_builddir 构建目录下的文件并将其安装至 %_buildrootdir 目录。这些文件就是用户安装 RPM 后,最终得到的文件。注意一个奇怪的地方: 最终安装目录 不是 构建目录。通过执行类似 make install 的命令实现。 |
%check | %_builddir | %_builddir | 检查软件是否正常运行。通过执行类似 make test 的命令实现。很多软件包都不需要此步。 |
bin | %_buildrootdir | %_rpmdir | 读取位于 %_buildrootdir 最终安装目录下的文件,以便最终在 %_rpmdir 目录下创建 RPM 包。在该目录下,不同架构的 RPM 包会分别保存至不同子目录, noarch 目录保存适用于所有架构的 RPM 包。这些 RPM 文件就是用户最终安装的 RPM 包。 |
src | %_sourcedir | %_srcrpmdir | 创建源码 RPM 包(简称 SRPM,以.src.rpm 作为后缀名),并保存至 %_srcrpmdir 目录。SRPM 包通常用于审核和升级软件包。 |
上表中说明了spec文件中几个重要的阶段变量,依次为%prep、%build、%install
换句话说,spec文件写好后,rpmbuild xxx.spec的执行逻辑就是按照上面的三个步骤进行的
其实这里也跟上面4.1步骤基本一致
%prep会将SOURCES目录中的源码进行解压,并拷贝到BUILD目录下
%build会将BUILD目录下的源码文件进行编译生成一个文件
%install做的事情就是将BUILD目录中编译并构建好的文件安装至BUILDROOT目录下
而就我们来说
我们已经将%prep、%build所做的事情都做了,只需要在BUILD目录中检查检查,没问题之后直接在spec文件中执行剩余的%install步骤即可完成打包
6.3 demo参考
如下是一个hbase_3_1_5_1_2-doc-2.1.6.3.1.5.1-2.spec的demo
# BUILD中构建的目录就是{name}-{version},注意创建的时候按此规范
Name: hbase_3_1_5_1_2-doc
Version: 2.1.6.3.1.5.1
Release: 2
Summary: Hbase Documentation
Group: Documentation
# BuildArch 打包架构,有noarch,x86_64,这里跟BUILD目录中的文件后缀也要保持一致
BuildArch: noarch
License:GPL
URL:www.asiainfo.com
# description不能缺失
%description
Documentation for Hbase
# 前面的%prep、%build省略了
%install
#install -d $RPM_BUILD_ROOT/
# 将刚刚BUILD中构建的目录进行cp -a,复制到BUILDROOT目录中,$RPM_BUILD_ROOT会自动识别
cp -a /root/rpmbuild/BUILD/hbase_3_1_5_1_2-doc-2.1.6.3.1.5.1-2.noarch/* $RPM_BUILD_ROOT/
# 这里files也必须写上,因为它主要用来说明会将BUILDROOT目录下的哪些文件和目录最终打包到rpm包里。
%files
#底下的/目录默认是/rpmbuild/BUILDROOT/目录
/usr/*
#用于设置默认文件权限,通常可以在 %files 的开头看到它。注意,如果不需要修改权限,则不需要使用它。其格式为:%defattr(<文件权限>, <用户>, <用户组>, <目录权限>),第 4 个参数通常会省略。常规用法为 %defattr(-,root,root,-),其中 “-” 表示默认权限。
%defattr (-,root,root)
# 这是最后一个阶段,主要记录的每次打包时的修改变更日志
%changelog
就像doc的这个spec一样,将其余六个rpm包进行如上操作,最终在~rpmbuild/SPECS目录下有7个spec文件
7:构建RPM
一旦 SPEC 编写完毕,请执行以下命令来构建 SRPM 和 RPM 包:
rpmbuild -bb xxx.spec
如果成功,RPM 会保存至 ~/rpmbuild/RPMS中,生成对应架构BuildArch的目录(noarch或x86_64),目录下即是rpm包
拿hbase来举例子,最大的那个rpm包执行时间是好几个小时,建议使用nohup挂在后台执行,执行结果监控nohup.out即可
其余六个执行速度秒成功
8:部署安装测试
8.1:修改yum源
如果基于Ambari的话
你可以重新构建BUILD中的目录,重新编写SPEC中的文件,将构建目录以及spec文件中的版本改为你现在测试环境中的版本(例如3.1.0),但是注意实际上还是拿3.1.5源码编译好的目录进行构建,也就说lib文件中的jar包还是新版本,只不过外面包装了一层旧版本的衣服。最后将打好的rpm包cp到你现在测试环境的yum源中
8.2:ambari重新安装服务
基于Ambari测试的话,将ambari中的hbase服务删除掉然后重新从yum源安装新版本的hbase,如果安装成功就可以进行功能测试了
8.3:rpm安装测试
顾名思义,rpm -i xxx.rpm进行安装测试