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進行安裝測試