1. 程式人生 > >利用二進位制檔案製作自己的Debian軟體安裝包

利用二進位制檔案製作自己的Debian軟體安裝包

在使用Ubuntu系統的時候,我們已經習慣了使用Debian風格的軟體安裝方式。即使用apt-get install命令安轉或dpkg -i *.deb的方式安裝debena軟體包。但有時程式沒有放到Ubuntu的源伺服器上且不提供deb軟體包。很多程式直接提供壓縮包,解壓即可使用。不過本人有嚴重的強迫症,喜歡遵循事務原本的規則,希望軟體都可以通過apt-get 或 dpkg -i 的方式進行安裝,這樣也方便統一管理。所以研究一下,在這裡記錄下來。本文前半部分會介紹debian軟體包相關的東西和打包方法,後半部分則嘗試將Tomcat 9 打包成Debian軟體包安裝到系統中。

(一)看一看Debian軟體包

其實Debian軟體包類似一個壓縮包,它就是將程式的檔案按照需要的路徑放到相關的資料夾裡,然後達成一個包。這和我們都熟悉的tar命令打包集器類似。我們可以使用dpkg -x命令將.deb包解壓到一個資料夾裡。

[email protected]:/home/root# dpkg -x code_1.28.2-1539735992_amd64.deb code

我這裡面解開的是微軟出品的Visual Studio Code的deb包,可以在官方的網站上下載到。我們就以他為參考看一下,進入到code資料夾看看:

[email protected]:/home/root# cd code
[email protected]
:/home/root/code# ls -l total 4 drwxr-xr-x 3 root root 4096 Oct 16 17:26 usr

可以看到他下面就是有一個usr的資料夾,就是和我們的跟目錄下的usr資料夾對應的,VS Code的應用程式就放在/usr/share/code下面,我們來看一下:

[email protected]:/home/root/code# cd usr/share/code/
[email protected]:/home/root/code/usr/share/code# ls -l
total 119904
drwxr-xr-x 2 root root     4096 Oct 16 17:26 bin
-rw-r--r-- 1 root root    26693 Sep 11 00:03 blink_image_resources_200_percent.pak
-rwxr-xr-x 1 root root 81203480 Sep 11 03:03 code
-rw-r--r-- 1 root root       15 Oct 16 17:24 content_resources_200_percent.pak
-rw-r--r-- 1 root root  8709456 Sep 11 00:08 content_shell.pak
-rw-r--r-- 1 root root 10197040 Mar  6  2018 icudtl.dat
-rw-r--r-- 1 root root   801200 Apr  5  2018 libffmpeg.so
-rwxr-xr-x 1 root root 19666248 Sep 11 03:03 libnode.so
drwxr-xr-x 2 root root     4096 Oct 16 17:26 locales
-rw-r--r-- 1 root root   221973 Sep 11 00:15 natives_blob.bin
-rw-r--r-- 1 root root   164181 Sep 11 02:59 pdf_viewer_resources.pak
drwxr-xr-x 3 root root     4096 Oct 16 17:26 resources
-rw-r--r-- 1 root root  1532052 Sep 11 00:17 snapshot_blob.bin
-rw-r--r-- 1 root root   152522 Sep 11 00:07 ui_resources_200_percent.pak
-rw-r--r-- 1 root root    57761 Sep 11 00:08 views_resources_200_percent.pak

可以看到安裝以後的檔案其實就是以安裝的格式存放在這裡的。

這是我們可能會有一個疑問,那就是難道deb軟體包就這樣簡單嘛?那豈不是就是和tar命令的功能相同了,還有必要弄什麼dpkg嘛。答案當然是否定的。其實Debian軟體包裡還有個DEBIAN的目錄,負責存放一下軟體的資訊和相關工作。而Debian系統和dpkg工具主要是讀取DEBIAN目錄下的軟體資訊,記錄裡面的資訊來進行安裝和刪除工作的。DEBIAN目錄沒有使用dpkg -x命令解壓出來,我們需要使用dpkg -e命令來專門解壓.deb檔案包裡的DEBIAN目錄下的東西:

[email protected]:/home/root# dpkg -e code_1.28.2-1539735992_amd64.deb code/DEBIAN

我們來看一下這裡面都放了一些什麼東西:

[email protected]:/home/root# cd code/DEBIAN/
[email protected]:/home/root/code/DEBIAN# ls -l
total 16
-rw-r--r-- 1 root root  719 Oct 16 17:07 control
-rwxr-xr-x 1 root root 2909 Oct 16 17:07 postinst
-rwxr-xr-x 1 root root  189 Oct 16 17:07 postrm
-rwxr-xr-x 1 root root  274 Oct 16 17:07 prerm

可以看到有一個control檔案和三個指令碼檔案。我們看一下control 檔案:

[email protected]:/home/root/code/DEBIAN# vi control
Package: code
Version: 1.28.2-1539735992
Section: devel
Depends: libnotify4, libnss3 (>= 2:3.26), gnupg, apt, libxkbfile1, libgconf-2-4, libsecret-1-0, libgtk-3-0 (>= 3.10.0), libxss1
Priority: optional
Architecture: amd64
Maintainer: Microsoft Corporation <[email protected]>
Homepage: https://code.visualstudio.com/
Installed-Size: 190982
Provides: visual-studio-code
Conflicts: visual-studio-code
Replaces: visual-studio-code
Description: Code editing. Redefined.
 Visual Studio Code is a new choice of tool that combines the simplicity of a code editor with what developers need for the core edit-build-debug cycle. See https://code.visualstudio.com/docs/setup/linux for installation instructions and FAQ.

可以看到裡面有一些軟體的相關資訊,比如軟體包的名字,叫code,它的版本是1.28.2等等,這些內容我們會在後面具體介紹。另外還有三個指令碼,我們就不具體看他們的內容了,但是知道他們是需要被執行的,什麼時候執行就在下面具體的來說。那麼到此為止,我們就解開了這個deb包裡面的所有內容,也就是說,這就是Debian軟體包所需要的所有內容了。

(二)Debian軟體包的結構

好了,我們簡單的利用VS Code的deb包研究了一下,那現在就記錄一下研究的成果,給出具體的Debian軟體包的結構:

*.deb
|
| # Debian 軟體包資訊目錄
|———— DEBIAN/
|    |———— control    # 資訊檔案,記錄著軟體包的相關資訊
|    |———— preinst    # 指令碼檔案,在軟體安裝之前執行
|    |———— postinst   # 指令碼檔案,在軟體安裝結束後執行
|    |———— prerm      # 指令碼檔案,刪除軟體之前執行
|    |———— postrm     # 指令碼檔案,刪除軟體之後執行
|    |———— copyright  # 版權資訊檔案
|    |———— changlog   # 版本改動日誌檔案
|    |———— ...        # 還有一些檔案,重要性不高不所以在此列出
|
| # Linux 根目錄同結構目錄
|———— etc/
|———— usr/
|———— lib/
|———— opt/
|———— tmp/
|———— ...

(三)control檔案的具體內容

我們看到了對於我們自己製作自用的Debian軟體安裝包來說,只有5個檔案是我們需要考慮的,即contro,preinst,postinst,prerm,postrm。其中preinst,postinst,prerm,postrm這四個檔案為安裝和刪除前後需要執行的指令碼,需要根據具體軟體填寫對應的安裝流程即可。而control檔案是記錄軟體安裝包資訊的檔案,原則上以key-value的形式存在。我們在上面看到VS Code的contrll檔案裡寫了很多東西,它基本上是以key: value的格式存在的。這裡面給出key的具體描述的列表:

關鍵字 解釋 備註
Source 軟體包的原始碼名稱 小寫英文數字和簡單符號,不能有空格
Package 軟體包的名稱 小寫英文數字和簡單符號,不能有空格
Version 軟體的版本
Section 軟體的類別 可以寫入比如mail, text, devel,多個要素用逗號隔開
Depends 軟體的依賴庫 多個要素用逗號隔開,要求的版本用小括號標註,如 libnss3 (>= 2:3.26)
Priority 軟體對於系統的重要程度 可以填入required, standard, optional, extra
Architecture 軟體所支援的平臺架構 可以填入i386,amd64
Maintainer 軟體維護者的資訊
Homepage 軟體的網站主頁
Installed-Size 軟體安裝後佔用的空間
Recommends       推薦安裝的其他軟體包和庫檔案
Essential 是否是系統最基本的軟體包 可以填入yes, no,填入yes後不可解除安裝
Description 軟體的描述資訊

(四)製作Debian軟體包的步驟

下面來總結一下製作Debian軟體包的具體步驟:

(1)把要安裝的軟體執行程式放置在與linux根目錄相同的目錄結構裡。

(2)在同一級目錄下建立DEBIAN目錄,在DEBIAN目錄下建立相關檔案,並填寫相關資訊。

(3)打包成Debian軟體包,可以使用dpkg -b命令。

(五)嘗試製作Tomcat 9 的Debian軟體安裝包

接下來我們就來嘗試製作一個Tomcat 9 的Debian軟體安裝包。Ubuntu雲上的Tomcat只到8.5,不是最新的9版本,Tomcat官方也沒有9的.deb包,只有tar.gz的軟體壓縮包。

(1)首先下載Tomcat 9的壓縮包到機器上,並解壓。

[email protected]:/home/root/tomcat-pk# tar -zxf apache-tomcat-9.0.12.tar.gz

建立一個目錄用於部署Debian軟體包:

[email protected]:/home/root/tomcat-pk# mkdir tomcat-debian

(2)接下來把Tomcat 9 的程式都copy進來,我們按照tomcat 8 的相同位置放置。

第一步copy可執行檔案,tomcat8的可執行檔案放在 /usr/share/tomcat8/bin下面,所以我們類似,先來建立目錄:

[email protected]:/home/root/tomcat-pk# cd tomcat-debian/
[email protected]:/home/root/tomcat-pk/tomcat-debian# mkdir -p usr/share/tomcat9

然後將bin下面的東西全部拷過去:

[email protected]:/home/root/tomcat-pk/tomcat-debian# cp -r ../apache-tomcat-9.0.12/bin/ usr/share/tomcat9/

刪除掉windows下的批處理檔案:

[email protected]:/home/root/tomcat-pk/tomcat-debian# rm usr/share/tomcat9/bin/*.bat

這時候我們需要注意,這些可執行檔案的所有者都是root使用者,而我們最終是希望使用tomcat9這個使用者來啟動tomcat,並且我們不準備更改這些可執行指令碼的所有者。所以我們需要給這些指令碼新增其他使用者的可讀取和可執行許可權:

[email protected]:/home/root/tomcat-pk/tomcat-debian# chmod -R o+r,o+x usr/share/tomcat9/bin

第二步copy配置檔案,我們仿照tomcat8的目錄結構將配置檔案放置在/etc/tomcat9下面,首先來建立這個資料夾:

[email protected]:/home/root/tomcat-pk/tomcat-debian# mkdir -p etc/tomcat9

然後將配置檔案拷貝過來:

[email protected]:/home/root/tomcat-pk/tomcat-debian# cp ../apache-tomcat-9.0.12/conf/* etc/tomcat9/

對於這些配置檔案來說,我們希望它不能被使用者讀取和更改,所以我們更改他的所屬使用者和組:

[email protected]:/home/root/tomcat-pk/tomcat-debian# chown tomcat9:tomcat etc/tomcat9/*

第三步copy主目錄下面的檔案,我們先來建立tomcat9的主目錄:

[email protected]:/home/root/tomcat-pk/tomcat-debian# mkdir -p var/lib/tomcat9

緊接著我們拷貝Java庫檔案,按照tomcat8的目錄結構,Java庫檔案是放置在 /usr/share/java下面的,同所有Java庫檔案放在一起,並且在 /usr/share/tomcat8/lib下面每個檔案都建立了軟連線鏈到那裡。但是我個人不喜歡這樣做tomcat的專屬Java庫檔案就放在它自己的目錄下面好了:

[email protected]:/home/root/tomcat-pk/tomcat-debian# cp -r ../apache-tomcat-9.0.12/lib var/lib/tomcat9/

我們最好為它新增其他使用者可以讀取和可執行許可權:

[email protected]:/home/root/tomcat-pk/tomcat-debian# chmod -R o+r,o+x var/lib/tomcat9/lib

然後我們拷貝webapp檔案,就在他下面,不需要做任何更改:

[email protected]:/home/root/tomcat-pk/tomcat-debian# cp -r ../apache-tomcat-9.0.12/webapps var/lib/tomcat9/

但是我們需要更改它的所有者和組為tomcat:

[email protected]:/home/root/tomcat-pk/tomcat-debian# chown tomcat9:tomcat var/lib/tomcat9/webapps

這裡面有個tomcat的預設主頁APP,有需要的話也需要更改使用者和組,至於docs和example用處不大:

[email protected]:/home/root/tomcat-pk/tomcat-debian# chown -R tomcat9:tomcat var/lib/tomcat9/webapps/ROOT/
[email protected]:/home/root/tomcat-pk/tomcat-debian# chown -R tomcat9:tomcat var/lib/tomcat9/webapps/manager/
[email protected]:/home/root/tomcat-pk/tomcat-debian# chown -R tomcat9:tomcat var/lib/tomcat9/webapps/host-manager/

還需要拷貝一下temp資料夾,參照tomcat8的目錄結構,臨時資料夾是在/tmp/tomcat8-temp下面,這個資料夾會隨著開關機清楚,因此我們也不需要拷貝,只需要記住在啟動tomcat的時候建立他就行了。

最後是copy程式的log資料夾和work資料夾,由於是全新的包,所以這兩個資料夾下面沒有東西,我們只需要建立即可,但同時不要忘記修改許可權:

[email protected]:/home/root/tomcat-pk/tomcat-debian# mkdir -p var/log/tomcat9
[email protected]:/home/root/tomcat-pk/tomcat-debian# chown tomcat9:tomcat var/log/tomcat9/
[email protected]:/home/root/tomcat-pk/tomcat-debian# mkdir -p var/cache/tomcat9
[email protected]:/home/root/tomcat-pk/tomcat-debian# chown tomcat9:tomcat var/cache/tomcat9/

我們將tomcat9按照分散式的結構放置好了,但是為了能保證它正常運作,我們還需要為各個目錄建立一個軟連線,統一連結到主目錄下面去:

[email protected]:/home/root/tomcat-pk/tomcat-debian# cd var/lib/tomcat9/
[email protected]:/home/root/tomcat-pk/tomcat-debian/var/lib/tomcat9# ln -s /usr/share/tomcat9/bin bin
[email protected]:/home/root/tomcat-pk/tomcat-debian/var/lib/tomcat9# ln -s /etc/tomcat9 conf
[email protected]:/home/root/tomcat-pk/tomcat-debian/var/lib/tomcat9# ln -s /var/log/tomcat9 logs
[email protected]:/home/root/tomcat-pk/tomcat-debian/var/lib/tomcat9# ln -s /var/cache/tomcat9 work
[email protected]:/home/root/tomcat-pk/tomcat-debian/var/lib/tomcat9# ln -s /tmp/tomcat9-temp temp

另外,如果你想要新增Tomcat 9 到service系統,就需要在etc/init.d/下面新增服務指令碼:

[email protected]:/home/root/tomcat-pk/tomcat-debian# mkdir -p etc/init.d
[email protected]:/home/root/tomcat-pk/tomcat-debian# touch etc/init.d/tomcat9
[email protected]:/home/root/tomcat-pk/tomcat-debian# mkdir -p etc/default
[email protected]:/home/root/tomcat-pk/tomcat-debian# touch etc/default/tomcat9

我們可以移植tomcat8相同目錄下的對應指令碼,不過需要做相應的改動,而且我覺得tomcat8得指令碼寫的太長太繁瑣了,所以我自己做了適當修改,寫在下面:

#!/bin/bash

start_sh() {
    cd /var/lib/tomcat9/bin
    ./catalina.sh start || exit 1
}
stop_sh() {
    cd /var/lib/tomcat9/bin
    ./catalina.sh stop || exit 1
}

case "$1" in
    start)
        start_sh
    ;;
    stop)
        stop_sh
    ;;
esac

exit 0

最後我們在執行一下du -sk命令看一下軟體的大小,便於填寫資訊:

[email protected]:/home/root/tomcat-pk/tomcat-debian# du -sk
15612	.

(3)接下來我們要進行DEBIAN資訊設定。

首先建立相關的目錄和檔案:

[email protected]:/home/root/tomcat-pk/tomcat-debian# mkdir DEBIAN
[email protected]:/home/root/tomcat-pk/tomcat-debian# cd DEBIAN/
[email protected]:/home/root/tomcat-pk/tomcat-debian/DEBIAN# touch control
[email protected]:/home/root/tomcat-pk/tomcat-debian/DEBIAN# touch preinst
[email protected]:/home/root/tomcat-pk/tomcat-debian/DEBIAN# touch postinst
[email protected]:/home/root/tomcat-pk/tomcat-debian/DEBIAN# touch prerm
[email protected]:/home/root/tomcat-pk/tomcat-debian/DEBIAN# touch postrm
[email protected]:/home/root/tomcat-pk/tomcat-debian/DEBIAN# chmod 755 p*

首先需要要填入control檔案的相關資訊,其中安裝大小那一欄就填入上面得到的數字,如下:

Package:tomcat9
Version:9.1.2
Section:web
Depends:
Priority:optional
Maintainer: noone
Architecture:amd64
Installed-Size:15612
Description:Apache Tomcat 9 debian installition package.

我們需要為安裝做一些工作,這些工作在安裝前後來做均可,這裡選擇在安裝前來做,所以我們編輯一下preinst這個指令碼。

-我們希望建立一個新使用者tomcat9,用它來啟動tomcat。如下:

#!/bin/bash
#
# Tomcat 9 installition script. Configurations before installition.

TOMCAT9_GROUP=tomcat
TOMCAT9_USER=tomcat9

# Create the tomcat group.
create_tomcat_group_sh() {
    ( cat /etc/group | grep -w ${TOMCAT9_GROUP} ) > /dev/null
    [ $? -eq 0 ] && sudo groupdel ${TOMCAT9_GROUP}
    sudo groupadd --system ${TOMCAT9_GROUP}
    [ $? -eq 0 ] || ( echo "ERROR: faild to create group \"${TOMCAT9_GROUP}\"."; exit 1 )
}

# Create the tomcat user.
create_tomcat_user_sh() {
    ( cat /etc/passwd | grep -w ${TOMCAT9_USER} ) > /dev/null
    [ $? -eq 0 ] && sudo userdel ${TOMCAT9_USER}
    useradd --system --groups ${TOMCAT9_GROUP} --home-dir /var/lib/tomcat9 --shell /bin/false ${TOMCAT9_USER}
    [ $? -eq 0 ] || ( echo "ERROR: faild to create user \"${TOMCAT9_USER}\"."; groupdel tomcat; exit 1 )
}

# Start this script process here.
# Check if the root privileges.
[ `id -u` -ne 0 ] && ( "ERROR: You need root privileges to run this script"; exit 1 )

create_tomcat_group_sh
create_tomcat_user_sh

exit 0

然後再安裝後我們還有一些工作要做,將我們寫的啟動指令碼註冊到系統的service中去,編輯postinst這個指令碼,如下:

#!/bin/bash
#
# Tomcat 9 installition script. Configurations after installition.

# Regist tomcat9 to system service.
create_tomcat9_service_sh() {
    sudo update-rc.d tomcat9 defaults
    [ $? -eq 0 ] || echo "WARNING: faild to create service tomcat9."
}


# Start this script process here.
# Check if the root privileges.
[ `id -u` -ne 0 ] && ( "ERROR: You need root privileges to run this script"; exit 1 )

create_tomcat9_service_sh

exit 0

同樣的,我們有一些工作是需要再刪除軟體之前進行的,我們把他解除安裝prerm這個指令碼中。

-我們要停止正在進行的tomcat服務。

-還要刪除我們建立的軟連線,並且從系統服務中將tomcat9剝離出去,如下:

#!/bin/bash
# 
# Tomcat 9 installition script. Configurations before removing.

# Stop tomcat9 service.
stop_tomcat9_service_sh() {
    TOMCAT9_PID=`ps -u tomcat9 | grep java`
    [ -n ${TOMCAT9_PID} ] && kill -9 ${TOMCAT9_PID%% \?*} && rm -f /var/run/tomcat9.pid
    ps -fe | grep "org.apache.catalina.startup.Bootstrap" | grep -v grep | grep -v init > /dev/null
    [ $? -eq 0 ] && ( "ERROR: You need root privileges to run this script"; exit 1 )
}

# Delete tomcat9 from system service.
delete_tomcat9_service_sh() {
    sudo update-rc.d -f tomcat9 remove
    [ $? -eq 0 ] || echo "WARNING: faild to delete service tomcat9."
}

# Start this script process here.
# Check if the root privileges.
[ `id -u` -ne 0 ] && ( "ERROR: You need root privileges to run this script"; exit 1 )

stop_tomcat9_service_sh
delete_tomcat9_service_sh

exit 0

最後,我們再刪除工作完成之後也將tomcat的使用者和使用者組一併刪除,解除安裝postrm指令碼中:

#!/bin/bash
# 
# Tomcat 9 installition script. Configurations after removing.

TOMCAT9_GROUP=tomcat
TOMCAT9_USER=tomcat9

# Remove tomcat 9 group.
reomve_tomcat9_group_sh() {
    ( cat /etc/group | grep -w ${TOMCAT9_GROUP} ) > /dev/null
    [ $? -eq 0 ] && sudo groupdel ${TOMCAT9_GROUP}
    [ $? -eq 0 ] || echo "WARNING: faild to delete group \"${TOMCAT9_GROUP}\"."
}

# Remove tomcat 9 user.
remove_tomcat9_user_sh() {
    ( cat /etc/passwd | grep -w ${TOMCAT9_USER} ) > /dev/null
    [ $? -eq 0 ] && sudo userdel ${TOMCAT9_USER}
    [ $? -eq 0 ] || echo "WARNING: faild to delete user \"${TOMCAT9_USER}\"."
}

# Delete all files in target directory.
delete_tomcat9_folder_sh() {
    rm -rf /var/lib/tomcat9
    rm -rf /var/log/tomcat9
    rm -rf /var/cacht/tomcat9
    rm -rf /tmp/tomcat9-temp
}

# Start this script process here.
# Check if the root privileges.
[ `id -u` -ne 0 ] && ( "ERROR: You need root privileges to run this script"; exit 1 )

remove_tomcat9_user_sh
reomve_tomcat9_group_sh
delete_tomcat9_folder_sh

exit 0

好了,該做的工作都完成了,接下來我們就將我們的檔案打包:

[email protected]:/home/root/tomcat-pk/tomcat-debian# dpkg -b . ../apache-tomcat-9.1.2.deb
dpkg-deb: building package 'tomcat9' in '../apache-tomcat-9.1.2.deb'.

我們來嘗試安裝一下它:

[email protected]:/home/root/tomcat-pk/tomcat-debian# dpkg -i ../apache-tomcat-9.1.2.deb 
Selecting previously unselected package tomcat9.
(Reading database ... 252977 files and directories currently installed.)
Preparing to unpack apache-tomcat-9.1.2.deb ...
Unpacking tomcat9 (9.1.2) ...
Setting up tomcat9 (9.1.2) ...
Processing triggers for systemd (237-3ubuntu10.3) ...
Processing triggers for ureadahead (0.100.0-20) ...