如何自己編譯 PPA 上的 source

由於最近在玩 FreeIPA[1] 的關係,就一併研究要怎麼整合到 Homelab 裡,其中一個支援的功能就是讓 Samba[2] 加入 FreeIPA 中[3],雖然官方宣稱這只有在 RHEL 8.1 上才提供的實驗性功能,但該版本使用的 FreeIPA 版本與 Ubuntu 19.10 上提供的 FreeIPA 一樣新,所以我想應該也可以吧。

結果,代誌不是憨人想的這麼簡單[4],FreeIPA 整合的 Kerberos 是 MIT 實作,但 Ubuntu 上的 Samba 整合的卻是 Heimdal 實作[5],這導致 Samba 看不懂 MIT Kerberos 的 ticket 進而無法進行後續的驗證步驟。

不過既然 RHEL 有支援 MIT Kerberos 的 Samba,那麼我也來安裝支援 MIT krb 的 Samba 就好啦,不過翻找了一下網路資源之後發現竟然沒有現成的 ppa[6] 可以用,這下好了,只好自己編譯了,於是我們就來談談,如何從 ppa 中下載 source 並編譯出 deb 包吧。

事前準備

在正式編譯 ppa 上的 source 之前,我們需要做一些準備,所謂「工欲善其事,必先利其器」,我們需要一些工具來下載原始碼以及打包工具:

將 ppa 的 source 加入 APT

我們可以透過把 ppa 加入 APT[7] 的 sources.list 中,來讓 APT 可以協助我們取得原始碼,以 samba 為例,我們先找出目標套件的 APT Source

$ apt show samba
Package: samba
Version: 2:4.10.7+dfsg-0ubuntu2.4
Priority: optional
Section: net
Origin: Ubuntu
Maintainer: Ubuntu Developers <[email protected]>
Original-Maintainer: Debian Samba Maintainers <[email protected]>
Bugs: https://bugs.launchpad.net/ubuntu/+filebug
Installed-Size: 16.4 MB
Pre-Depends: dpkg (>= 1.15.6~)
Depends: ...
Recommends: ...
Enhances: bind9, ntp
Homepage: http://www.samba.org
Task: samba-server, ubuntu-budgie-desktop
Supported: 9m
Download-Size: 976 kB
APT-Sources: http://archive.ubuntu.com/ubuntu eoan-updates/main amd64 Packages
Description: SMB/CIFS file, print, and login server for Unix

N: There is 1 additional record. Please use the '-a' switch to see it
$

我們可以看到 samba 是來自於 http://archive.ubuntu.com/ubuntu eoan-updates/main[8],接下來我們就可以把 source 加到 APT 的 source list 中,這裡有幾個方式可以進行:

透過 add-apt-repository

相對簡單的方式就是透過 add-apt-repository 來協助添加 source list,這個工具有三種用法,下面在範例中介紹:

## 使用完整 deb source 語句
# add-apt-repository -s "deb http://myserver/path/to/repo stable myrepo"
## 加入 ppa
# add-apt-repository -s ppa:user/repository
## 指定 distro component
# add-apt-repository -s multiverse

其中,-s 表示要一併加入 source repo,如此一來就可以透過 apt 下載 source。

若需要安裝 add-apt-repository 的話可以透過 apt install software-properties-common 取得。

但這裡我選擇手動添加,因為 samba 是位於預設套件庫的套件,Ubuntu 會在 APT source list 中加入預設套件庫的位置,並把 source 註解起來,也就是說,我們只要手動打開就可以了。

手動添加 source list

編輯 /etc/apt/source.list,找到剛剛的 eoan-updates main,將 deb-src 取消註解:

...

## Major bug fix updates produced after the final release of the
## distribution.
deb http://archive.ubuntu.com/ubuntu/ eoan-updates main restricted
deb-src http://archive.ubuntu.com/ubuntu/ eoan-updates main restricted

...

完成之後記得使用 apt update 來更新 cache。

Debian package development tools

這個 dpkg suite 可以在稍後協助我們建立 deb 包,安裝方式很簡單,透過 apt 取得即可:

# apt install dpkg-dev

安裝建置用依賴套件

接下來我們還需要在編譯建置套件之前準備好依賴套件,每個套件需要的依賴項都有所不同,我們一樣可以透過 apt 來快速取得建置依賴套件:

# apt build-dep samba

如此一來,所有的前置準備就都做足了,接下來我們來看看要怎麼建立完整的 deb 包吧。

下載 source

下載 source 的部分在前置作業結束之後就變得簡單許多了,只需要靠 APT 就能輕鬆辦到:

$ apt source samba
Reading package lists... Done
NOTICE: 'samba' packaging is maintained in the 'Git' version control system at:
https://salsa.debian.org/samba-team/samba.git
Please use:
git clone https://salsa.debian.org/samba-team/samba.git
to retrieve the latest (possibly unreleased) updates to the package.
Need to get 11.9 MB of source archives.
Get:1 http://archive.ubuntu.com/ubuntu eoan-updates/main samba 2:4.10.7+dfsg-0ubuntu2.4 (dsc) [4215 B]
Get:2 http://archive.ubuntu.com/ubuntu eoan-updates/main samba 2:4.10.7+dfsg-0ubuntu2.4 (tar) [11.6 MB]
Get:3 http://archive.ubuntu.com/ubuntu eoan-updates/main samba 2:4.10.7+dfsg-0ubuntu2.4 (diff) [265 kB]
Fetched 11.9 MB in 4s (3206 kB/s)
dpkg-source: info: extracting samba in samba-4.10.7+dfsg
dpkg-source: info: unpacking samba_4.10.7+dfsg.orig.tar.xz
dpkg-source: info: unpacking samba_4.10.7+dfsg-0ubuntu2.4.debian.tar.xz
dpkg-source: info: using patch list from debian/patches/series
dpkg-source: info: applying 07_private_lib
dpkg-source: info: applying bug_221618_precise-64bit-prototype.patch
...
dpkg-source: info: applying CVE-2019-19344.patch
$

apt source 除了會將原始碼下載回來之外,還會一併將指定的 patch 套用至原始碼中,結束後應該就會得到一個以該套件名與版本號命名的資料夾,這裡是 samba-4.10.7+dfsg,同時還會留下原始碼包以及 deb 包資訊檔(.dsc)。

這裡如果是用 root 身份或 sudo 進行操作的話,APT 會警告無法使用 _apt 使用者進行操作,原因是在下載原始碼包之後,APT 會嘗試切換到 _apt 這個使用者來解開原始碼及套用 patch,為了避免這個操作有負作用所以使用獨立的使用者來進行。

建立 deb 包

在有了原始碼之後,我們可以看到目錄大概是這樣的結構

samba-4.10.7+dfsg/
 |-- debian/
 |    |-- control
 |    |-- rules
 |    | ...
 | ...

其中 debian/ 目錄的功能就是存放與 deb 相關的內容,其中 control 檔表示的就是與 deb 包相關的資訊,包含依賴項目、套件說明等等;而 rules 則是一 Makefile 格式的檔案,裡面描述了打包時詳細需要進行什麼動作,例如編譯方式、需要打包哪些檔案等等。

至於要如何才能建置 deb 包呢? 還記得剛剛準備的 Debian package development tools 嗎,這就是為了這個時候而存在的,步驟也很簡單:

$ cd samba-4.10.7+dfsg/
$ dpkg-buildpackage
...
$ cd ..
$ ls *.deb
ctdb_4.10.7+dfsg-0ubuntu2.4_amd64.deb
libnss-winbind_4.10.7+dfsg-0ubuntu2.4_amd64.deb
libpam-winbind_4.10.7+dfsg-0ubuntu2.4_amd64.deb
libparse-pidl-perl_4.10.7+dfsg-0ubuntu2.4_amd64.deb
libsmbclient-dev_4.10.7+dfsg-0ubuntu2.4_amd64.deb
libsmbclient_4.10.7+dfsg-0ubuntu2.4_amd64.deb
libwbclient-dev_4.10.7+dfsg-0ubuntu2.4_amd64.deb
libwbclient0_4.10.7+dfsg-0ubuntu2.4_amd64.deb
python3-samba_4.10.7+dfsg-0ubuntu2.4_amd64.deb
registry-tools_4.10.7+dfsg-0ubuntu2.4_amd64.deb
samba-common-bin_4.10.7+dfsg-0ubuntu2.4_amd64.deb
samba-common_4.10.7+dfsg-0ubuntu2.4_all.deb
samba-dev_4.10.7+dfsg-0ubuntu2.4_amd64.deb
samba-dsdb-modules_4.10.7+dfsg-0ubuntu2.4_amd64.deb
samba-libs_4.10.7+dfsg-0ubuntu2.4_amd64.deb
samba-testsuite_4.10.7+dfsg-0ubuntu2.4_amd64.deb
samba-vfs-modules_4.10.7+dfsg-0ubuntu2.4_amd64.deb
samba_4.10.7+dfsg-0ubuntu2.4_amd64.deb
smbclient_4.10.7+dfsg-0ubuntu2.4_amd64.deb
winbind_4.10.7+dfsg-0ubuntu2.4_amd64.deb
$

如果沒有發生錯誤的話就可以在上層目錄看到打包好的 deb 檔們了,如此一來我們就完成了這次的目標 —— 從 PPA 上的 source 打包成 deb 了。

dh_missing --fail-missing 錯誤

其實筆者在嘗試的時候有遇到這個錯誤,dh_missing 會檢查 fakeroot[9] 中的檔案是否都已經被包入 deb 中,如果有遺漏的檔案則會拋出錯誤或提醒,如果是不打算包入 deb 的檔案可以在 debian/not-installed 中列出,或是可以透過修改 debian/rules 來改變檢查的方式:

override_dh_missing:
	# dh_missing --fail-missing
	dh_missing --list-missing

不過這個方式表示會跳過檢查,不建議在正式環境中使用,但對於在測試時查看有哪些檔案被遺漏了是很有用的。

安裝 deb 包

安裝其實也是很簡單,使用 dpkg 就可以安裝了:

# dpkg -i *.deb

結語

以上就是從 PPA 中編譯 source 的方式,應該還算是簡單。
之後會再另外撰寫有關於如何透過修改建置 deb 包相關設定來達到我們想要自行編譯支援 MIT Kerberos 版本的 samba,以及如何將這個修改結果上傳到 Launchpad 中讓其他人也可以使用我們修改好的 ppa。
還有或許 FreeIPA 玩出心得之後也許也會再發幾篇文章跟大家分享看看。


  1. 由 Red Hat 支援的一個整合性資訊系統,包含 389 Directory、MIT Kerberos、NTP server、BIND9、Dogtag 等,並提供網頁及 CLI 管理工具。 詳見官網說明↩︎

  2. 為一個開源的 SMB 實作,同時支援了 CIFS/Active Directory 等功能。 ↩︎

  3. 此處指的是 Red Hat 在 RHEL 8.1 中加入的實驗性功能,可以讓 IdM member 以 Samba 提供服務並整合帳號資料到 IdM 中,詳見官方文件↩︎

  4. 應為「代誌毋是憨人想的遐爾簡單」,為一臺灣閩南語經典臺詞,意為事件的發展並不是單純如表面上進行而有了重大的轉折,出自〈鐵獅玉玲瓏〉。 ↩︎

  5. 目前兩大主流 Kerberos 實作為 Heimdal 及 MIT,兩者在支援度及實作細節上互有不同,導致兩者並不能混用。Debian 及 SUSE 系的發行版採用了較為老牌的 Heimdal,而 RH 系的發行版則是投入 MIT 陣營,並為此將與 Heimdal 高度耦合的 Samba 改寫為支援 MIT 的版本。 ↩︎

  6. Ubuntu 的套件管理中,支援個人自行發行套件(Personal Package Archive),其大宗 hosting service 便是 Launchpad↩︎

  7. Advanced Packaging Tools,為 Debian 及其衍生發行版本的軟體包管理器。 ↩︎

  8. 眼尖的讀者可能會發現 apt 其實還有找到其他的記錄,這句 "N: There is 1 additional record. Please use the '-a' switch to see it" 表示同名的套件中還有其他的版本可以列出,只需要使用 apt show -a samba 即可列出所有 samba 的版本及其資訊。 ↩︎

  9. 由於我們並沒有要將編譯好的套件直接安裝到系統中,而是將其安裝到一個假的系統根目錄中,方便我們在打包時可以先以該套件原始的安裝方式釐清檔案們會被安裝到何處,並且只要在打包時維持這些檔案的路徑及權限即可讓 deb 重現這個安裝過程。 ↩︎

因主題更新,留言功能暫時停用中。