HDP3.1.5源碼編譯打rpm包全流程講解

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中的目錄

  1. 在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過來)
  2. 將新版本編譯目錄(5.2步驟中)整個cp到上面的hbase目錄中去
  3. 這裏我還創建了與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進行安裝測試

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章