【編者的話】rpm(red hat package manager)是用於 linux 分發版的最常見的軟體包管理器。因為它允許分發已編譯的軟體,所以使用者只用乙個命令就可以安裝軟體。而rpm包的構建相當繁瑣,並且對環境的要求比較高, 本文作者介紹了如何借助docker來構建可以適用多個平台的rpm包。
在乙個內部專案中,我一直在思考如何通過非ci工具/流程生成rpm包,我想手動生成rpm包,這樣我可以測試它們是否能正常安裝,並用於正常的冒煙測試(譯者注:冒煙測試就是在每日構建完成後,對系統的基本功能進行簡單的測試。這種測試強調功能的覆蓋率,而不對功能的正確性進行驗證)。
在我們的ci流程中,docker算是個全能手,所以我也在想能否將docker映象和rpm結合起來。理想的情況下,讓rpm與docker整合, 這樣,建立rpm包的過程其實就是在構建乙個docker映象。基本上,rpm包的%prep部分的構建可以在乙個特殊的docker映象中快速完成,然 後將生成的rpm包返回給主機。
這種方式的的優點在於,你的rpm包是在乙個相對封閉且可再生的環境中構建的,所以你可以快速的為centos、fedora、rhel等其它系統構建rpm包。
我相信還有其它的一些變通方法也可以完成這樣的工作,比如chroot之類的。但如果在rpm中內建這種打包機制(通過chroot/docker或者別的容器技術抽象而來的系統來完成打包工作)的話,我想會更好。
由於我的專案還沒有完成,所以我只是對我的想法進行了驗證:簡單構建乙個包含依賴的映象。
這是乙個使用pbr生成版本 的python專案。 首先我在build目錄中生成乙個tarball,然後得到生成的版本號,緊接著修改spec檔案中的版本號,然後開始用新的tar包和spec檔案構建 映象。最後執行映象,並掛載卷(volume)到本地目錄。當執行容器中的start.sh指令碼之後,映象就執行起來了。
start.sh相當簡單。 它構建好rpm包後,以root身份把它拷貝到卷目錄下, 還可以從主機上將它拷貝到output目錄。我沒有將它拷貝或者說更新到類似swift之類的物件儲存系統,因為我還要在ci中使用它,所以就使用本地檔案拷貝了。
在specs/project.spec以及 sources/* 是標準rpm包需要的spec檔案,原始檔和patc**件。需要做的唯一一件事是定義%define_version巨集,並在spec檔案中使用它。下面是我的一些指令碼。
主指令碼build.sh。 可以從ci中執行。
#dockerfile,為docker 快取做了一些優化:!/bin/
bash
set-
exfproject
=myproject
curdir=$
(dirname$(
readlink
-f $0
))topdir=$
(git
rev-
parse
--show
-topklevel
2>
/dev/
null)rm
-rf $
/.build
/rpm
mkdir
-p $
/.build
/rpm/cp
-r $
/sources $
/.build
/rpm
pushd $
>
/dev/
null
python setup
.py sdist
--dist
-dir$/.
build
/rpm
/sources
/saladier_version=$
(sed-n
'/^version/ '$.
egg-
info
/pkg
-info
)popd
>
/dev/
null
sed-
e "s/%define _version.*/%define _version $/"$/
specs/$
.spec
>
\ $
/.build
/rpm
/specs/$
.spec
docker build
-t chmouel
/buildrpm $
docker run
-v $curdir
/.build
:/data -it chmouel/
buildrpm
if[[
-n $
]];thenrm-
rf $
/rpm
cp-a $/.
build
/output $
/rpm
fi
以及從容器中執行的start.sh指令碼:
#指令碼可能無法直接在你的環境中使用,但至少能讓你了解這個idea。!/bin/
bash
#script
run inside the container
rpmbuild
-ba rpmbuild
/specs
/project
.spec
||exit1[[
-d /data
]]||
exit
0sudorm-
rf /
data
/output
sudocp-
a rpmbuild
/rpms
/noarch
/data
/output
windows 使用docker構建映象
一定要注意 先改下docker desktop的setting。不然生成映象直接 全都放到c盤。開啟cmd,到dockerfile的路徑 請把dockerfile單獨放到乙個目錄 使用docker build t image name 這個 就是當前目錄,然後就是漫長的等待。建立乙個基於某映象的容器...
docker構建映象
做映象就是構建映象!提交容器更改,生成新的映象!docker commit 容器名 新映象的名字 tag 例如 將web2容器提交為乙個新的映象,新映象的名字為nginx 1.1 在docker中映象的儲存方式是分層儲存的!每個映象都會有不同層數!映象的層數只能增加不能減少!映象是唯讀的!裡面的記憶...
docker構建映象
建立docker映象有兩種方法。1。docker commit 這種不推薦,就不介紹了。2。用docker build命令和dockerfile檔案 下面構建乙個nginx小應用。建立資料夾 mkdir static web 進入這個資料夾 cd static web 建立dockerfile檔案 ...