使用rpmbuild自定義構建rpm包
使用rpmbuild自定義構建rpm包
目前我所知道的 build nginx RPM 的方式(測試過)總共 3 種,大致分為 2 類
- 基於原始碼 build
- 基於已有 rpm 替換
第一種方案的好處就是配置檔案等能始終保持最新的,編譯版本等不受限制;但是從原始碼 build 非常耗時,尤其是網路環境複雜的情況下,沒有高配置國外伺服器很難完成 build,而且要維護 build 所需 spec 檔案等,自己維護這些未必能夠盡善盡美;
第二種方式是建立速度快,build 方式簡單可靠,但是由於是替換方式,所以 rpm 中的配置不一定能夠即使更新,而且只能基於官方build 好以後的二進位制檔案進行替換,如果想要嘗試 master 最新程式碼則無法實現
二、基於原始碼 Build
對於 Centos RPM build 原理方式這裡不再細說,基於原始碼 build 的關鍵就在於 spec 檔案,我嘗試過自己去寫,後來對比一些開源專案的感覺 low 得很,所以以前一直採用一個國外哥們寫的指令碼 buildofollow,noindex" target="_blank">參見這裡 ;這個指令碼不太好的地方是作者已經停止了維護;經過不懈努力,找到了 Fedora 系統的 rpm 倉庫,鼓搗了一陣摸清了套路;以下主要以 Fedora 倉庫為例進行 build
以下 Build 在一臺 Do 8核心 16G VPS 上進行,由於眾所周知的原因,國內 Build 很費勁,一般國外 VPS 都是按小時收費,有個 2 塊錢就夠了
2.1、安裝 build 所需依賴
由於 spec 檔案中定義了依賴於 golang 這個包,所以如果不裝的話會報錯;事實上如果使用剛剛安裝的這個 golang 去 build 還是會掛掉,因為實際編譯要求 golang > 1.7,直接 yum 裝的是 1.6,故下面又使用 gvm 裝了一個 1.8 的 golang,上面的 golang 安裝只是為了通過 spec 檢查
# EPEL yum install epel-release -y # update 系統元件 yum update -y && yum upgrade -y # 安裝基本的編譯依賴 yum install golang go-md2man go-bindata gcc bison git rpm-build vim -y # 安裝 gvm(用於 golang 版本管理) bash < <(curl -s -S -L https://raw.githubusercontent.com/moovweb/gvm/master/binscripts/gvm-installer) source /root/.gvm/scripts/gvm # 安裝 1.8 之前需要先安裝 1.4 gvm install go1.4 -B gvm use go1.4 # 使用 golang 1.8 版本 build gvm install go1.9 gvm use go1.9
2.2、克隆 build 倉庫
Fedora 官方 Kubernetes 倉庫地址在 這裡,如果有版本選擇請自行區分
git clone https://src.fedoraproject.org/git/rpms/nginx.git
2.3、從 spec 獲取所需檔案
克隆好 build 倉庫後首先檢視 kubernetes.spec 檔案,確定 build 所需檔案,spec 檔案如下
%global_hardened_build1 %globalnginx_usernginx # Disable strict symbol checks in the link editor. # See: https://src.fedoraproject.org/rpms/redhat-rpm-config/c/078af19 %undefine _strict_symbol_defs_build %bcond_with geoip # gperftools exist only on selected arches # gperftools *detection* is failing on ppc64*, possibly only configure # bug, but disable anyway. %ifnarch s390 s390x ppc64 ppc64le %global with_gperftools 1 %endif %global with_aio 1 %if 0%{?fedora} > 22 %global with_mailcap_mimetypes 1 %endif
從 spec 檔案中可以看到 build 主要需要兩個倉庫的原始碼,一個是 kubernetes 主倉庫,存放著主要的 build 原始碼;另一個是 contrib 倉庫,存放著一些配置檔案,如 systemd 配置等
接下來從 spec 檔案的 source 段中可以解讀到(source0、source1)最終所需的兩個倉庫壓縮檔名為 kubernetes-SHORTCOMMIT、contrib-SHORTCOMIT,source 段如下
Name:nginx Epoch:1 Version:1.11.1 Release:14%{?dist} Summary:A high performance web server and reverse proxy server Group:System Environment/Daemons # BSD License (two clause) # http://www.freebsd.org/copyright/freebsd-license.html License:BSD URL:http://nginx.org/ Source0:https://nginx.org/download/nginx-%{version}.tar.gz Source10:nginx.service Source11:nginx.logrotate Source12:nginx.conf Source13:nginx-upgrade Source14:nginx-upgrade.8 Source100:index.html Source101:poweredby.png Source102:nginx-logo.png Source103:404.html Source104:50x.html Source200:README.dynamic Source210:UPGRADE-NOTES-1.6-to-1.10
我們準備 build 一個最新的 1.12.1 的 rpm,修改
Name:nginx Epoch:1 Version:1.12.1 Release:14%{?dist}
2.4、準備原始碼
修改好檔案以後,就可以下載原始碼檔案了,原始碼下載不必去克隆 github 專案,直接從 spec 中給出的地址下載即可
cd nginx wget https://nginx.org/download/nginx-1.12.1.tar.gz
2.5、build rpm
在正式開始 build 之前,還有一點需要注意的是 預設的 kubernetes.spec 檔案中指定了該 rpm 依賴於 docker 這個包,在 CentOS 上可能我們會安裝 docker-engine 或者 docker-ce,此時安裝 kubernetes rpm 是無法安裝的,因為他以來的包不存在,解決的辦法就是編譯之前刪除 spec 檔案中的 Requires: docker 即可,最後建立好 build 目錄,並放置好原始碼檔案開始 build 即可,當然 build 可以有不同選擇
由於我是 root 使用者,所以目錄位置在這
實際生產 強烈不推薦使用 root build(操作失誤會損毀宿主機)
我的是一臺臨時 vps,所以無所謂了
mkdir -p /root/rpmbuild/SOURCES/ mv ~/nginx/* /root/rpmbuild/SOURCES/ cd /root/rpmbuild/SOURCES/ # 執行 build rpmbuild -ba nginx.spec
注意,由於我們選擇的版本已經超出了倉庫所支援的最大版本,所以有些 Patch 已經不再適用,如 spec 中的 Patch12、Patch19 會出錯,所需要註釋掉(%prep 段中也有一個)
rpmbuild 可選項有很多,常用的 3 個,可以根據自己實際需要進行 build:
- -ba : build 原始碼包+二進位制包
- -bb : 只 build 二進位制包
- -bs : 只 build 原始碼包
最後 build 完成後如下
[root@test x86_64]# ll total 2480 -rw-r--r-- 1 root root543948 Sep 20 17:21 nginx-1.12.1-14.el7.x86_64.rpm -rw-r--r-- 1 root root 1754960 Sep 20 17:21 nginx-debuginfo-1.12.1-14.el7.x86_64.rpm -rw-r--r-- 1 root root27544 Sep 20 17:21 nginx-mod-http-image-filter-1.12.1-14.el7.x86_64.rpm -rw-r--r-- 1 root root36992 Sep 20 17:21 nginx-mod-http-perl-1.12.1-14.el7.x86_64.rpm -rw-r--r-- 1 root root26628 Sep 20 17:21 nginx-mod-http-xslt-filter-1.12.1-14.el7.x86_64.rpm -rw-r--r-- 1 root root55316 Sep 20 17:21 nginx-mod-mail-1.12.1-14.el7.x86_64.rpm -rw-r--r-- 1 root root78512 Sep 20 17:21 nginx-mod-stream-1.12.1-14.el7.x86_64.rpm