2020年11月4日 星期三

Linux rpm build (3) .service 開機可自動執行

參考來源:

Linux systemd 系統服務管理基礎教學與範例

如何在Linux上將任意應用程式變成開機可自動執行


Systemd 基本服務管理

在 Systemd 中每一個系統服務就稱為一個服務單位(unit),而服務單位又可以區分為 service、socket、target、path、snapshot、timer 等多種不同的類型(type),

我們可以從設定檔的附檔名來判斷該服務單位所屬的類型,最常見的就是以 .service 結尾的系統服務,大部分的伺服器都是屬於這種。


如果要管理 Systemd 中的各種服務,可以使用 systemctl 這個指令,配合各種操作指令來進行各種操作。


systemctl 操作指令 服務名稱.service

若要啟動系統服務,可以使用 start 操作指令,例如啟動 accusys.service:

當我們在指定服務名稱時,可以將結尾的 .service 省略,這樣可以少打一些字,例如:


# 套用Systemd Unit的設定檔變更

在新增、或是修改Systemd Unit的設定檔後,要在終端機執行以下指令才會重新載入:

sudo systemctl daemon-reload


# 啟動 service

sudo systemctl start accusys


# 顯示 service 服務狀態

systemctl status accusys


# 停止 service 服務

sudo systemctl stop accusys


# 設定開機自動啟動 service

sudo systemctl enable accusy


# 取消開機自動啟動 service

sudo systemctl disable accusys


# 檢查 service 服務是否正在運行

systemctl is-active accusys


# 檢查 service 服務是否有設定開機自動啟動

systemctl is-enabled accusys


# 檢查 service 服務是否啟動失敗

systemctl is-failed accusys


列出 Systemd 所有服務

若想要列出所有已啟動的服務,可以使用 list-units 操作指令:


# 列出所有已啟動的服務

systemctl list-units


# 查看服務內部設定檔

systemctl cat accusys.service


---------------------------------------------------------------->

[Unit]

Description=Accusys GUI GS

After=network.target

 

[Service]

# User=user

# Group=group

# WorkingDirectory=/path/to/folder

ExecStart=/lib/modules/3.10.0-514.el7.x86_64/kernel/drivers/scsi/accusys/RGX_GS_3.6.8/DTRGuiSrv_64

Restart=always

RestartSec=10s


# Environment="VARIABLE_1=VALUE_1" "VARIABLE_2=VALUE_2"

# Environment="VARIABLE_3=VALUE_3" "VARIABLE_4=VALUE_4"

 

[Install]

WantedBy=multi-user.target

<----------------------------------------------------------------


[Unit]區塊中,我們撰寫了兩個項目。

Description用來設定這個Systemd Service Unit設定檔案的描述,可以讓管理員在日後查看時還能想起這個Systemd Service Unit的目的是什麼。

另一個After項目可以用來指定一個Systemd Target Unit,可以確保目前正在設定的這個Unit,會在Systemd Target Unit運行完後再運行。

如果是用來提供Web服務的應用程式,那麼通常就必須要在作業系統環境的網路功能被啟用之後才能夠正常啟動,

所以After項目設定為network.target可以確保該程式在第一次執行時候就順利啟動。


[Service]區塊中有五個使用井字號#註解掉的項目,這些先不要管它,稍候會再提到。

ExecStart項目可以用來設定當這個Systemd Service Unit項目啟動時要執行的應用程式(需使用完整絕對路徑),並且如果需要的話,

可以利用空白字元來分隔多個不同的引數。若是這個程式需要搭配shell的命令列功能(例如變數、管線等)來執行,

那就使用如以下的方式先執行shell之後,再運行shell的命令吧!


ExecStart=/bin/bash -c 'shell命令'

Restart項目可以設定ExecStart所執行的程式要在什麼樣的情況被關閉時,以相同的指令再重新執行一次。有效的設定值如下:


no:不重啟。(預設值)

always:不管什麼原因都會重啟。

on-success:只在成功運行結束後(也就是行程回傳的Exit Status為0的時候)才進行重啟。(這蠻少用)

on-failure:在運行失敗後(行程回傳的Exit Status非為0、被使用Kill信號強制關閉、逾時或是餵狗沒反應時)才進行重啟。

on-abnormal:在意外地運行失敗後(被使用Kill信號強制關閉、逾時或是餵狗沒反應時)才進行重啟。

on-abort:被使用Kill信號強制關閉時才進行重啟。

on-watchdog:餵狗沒反應時才進行重啟。

上述提到的「逾時」,可以在[Service]區塊中用TimeoutSec項目來設定程式在執行多久後算是逾時,一般我們是用不到這個機制啦!

而「餵狗」則是使用Systemd提供的看門狗(Watchdog)機制,使程式在固定時間內(可以在[Service]區塊中用WatchdogSec項目來設定),

必須主動呼叫Systemd函式庫的sd_notify函數,以利Systemd判斷該程式是否還是正常運作的狀態,一般我們也是用不到這個機制的啦!


至於RestartSec這個項目,就是設定程式在被關閉後,到下次自動重啟的間隔時間,預設是100ms(毫秒)。

最後的[Install]區塊中,只有WantedBy這一個設定項目,它可以用來指定一個Systemd Target Unit,讓目前正在設定的這個Unit,

會在運行該Systemd Target Unit時,也跟著被運行。

接著來談談被註解掉的項目,首先是User和Group這兩個項目,它們可以分別用來設定要運行ExecStart項目所指定的程式時所使用的使用者名稱和群組名稱。

另外如果程式的運行必須仰賴工作目錄的支援的話,就要使用WorkingDirectory項目來手動指定程式工作目錄的路徑。

而如果要替執行的程式設定環境變數的話,可以透過一個或是數個Environment項目來設定,一個Environment項目可以設定多個環境變數。



Linux rpm build (2) - RPM 如何打包

相關參考網址:

RPM 打包︰由一竅不通到動手濫用

RPM打包原理、示例、詳解及備查


** rpmbuild 建置指令

rpmbuild -bb accusys.spec


** 撰寫 rpm SPEC

---------------------------------------------------------------->

# Some metadata required by an RPM package

Name: accusys

Summary: Install Accusys linux driver and GUI.

Version: 1.0

Release: 1

License: GPLv2


%description

Install Accusys driver for "DaVinci-Resolve-Linux-16.0-CentOS_7.3"

Install Accusys GUI GC and GS.


# Get the kernel headers version installed, not based on uname.

%define kversion %(rpm -q kernel%{?bt_ext}-devel | sort --version-sort | tail -1 | sed 's/kernel%{?bt_ext}-devel-//')

%define RGX_GC RGX_GC_3.6.8

%define RGX_GS RGX_GS_3.6.8


%install

mkdir -p %{buildroot}/lib/modules/`uname -r`/extra/accusys

cp -pdf /home/Sam/rpmbuild/SOURCES/ACS6x.ko %{buildroot}/lib/modules/`uname -r`/extra/accusys/ACS6x.ko

chmod 755 %{buildroot}/lib/modules/`uname -r`/extra/accusys/ACS6x.ko

cp -pdfr /home/Sam/rpmbuild/SOURCES/%{RGX_GS} %{buildroot}/lib/modules/`uname -r`/extra/accusys/%{RGX_GS}

cp -pdfr /home/Sam/rpmbuild/SOURCES/%{RGX_GC} %{buildroot}/lib/modules/`uname -r`/extra/accusys/%{RGX_GC}

mkdir -p %{buildroot}/usr/lib/systemd/system

cat <<EOF> %{buildroot}/usr/lib/systemd/system/accusys.service

[Unit]

Description=Accusys GUI GS

After=network.target

 

[Service]

# User=user

# Group=group

# WorkingDirectory=/path/to/folder

ExecStart=/lib/modules/3.10.0-514.el7.x86_64/extra/accusys/RGX_GS_3.6.8/DTRGuiSrv_64

Restart=always

RestartSec=10s


[Install]

WantedBy=multi-user.target

EOF


%post

depmod

systemctl start accusys

systemctl status accusys

systemctl enable accusys


%preun

systemctl stop accusys

systemctl disable accusys


%postun

depmod


%files

/lib/modules/%{kversion}/extra/accusys/ACS6x.ko

/lib/modules/%{kversion}/extra/accusys/%{RGX_GS}

/lib/modules/%{kversion}/extra/accusys/%{RGX_GC}

/usr/lib/systemd/system/accusys.service

<----------------------------------------------------------------


SPEC 檔︰ 參數定義


** SPEC 檔︰表頭 (Preamble) 的基本內容

Name:           所包裝軟件的名稱。

Summary:        軟件的簡短介紹。

Version:        軟件的版本編號。

Release:        同一版本軟件的發佈次數。預設為 1%{?dist},每打包一次應該 +1,直到版本編號更新為止。

License:        軟件的使用授權模式,像是「GPLv3」或者「MIT」之類。


URL:            軟件的官方網站。

Source0:        下載軟件源代碼的路徑或完整網址。如果有多於一個,可繼續用 Source1, Source2, … SourceX 去定義。

Patch0:         下載第一個源代碼補丁的網址。只在有需要時定義。同樣可以有 Patch1, Patch2, … PatchX。

BuildArch:      如果只支援在特定硬體架構編譯,需要在這裏定義,像是「x86_64」之類。

BuildRequires:  定義編譯軟件所需要的套件。需要用逗號或空白分隔套件名稱,亦可以分開多次定義 BuildRequires。

Requires:       定義執行軟件所需要的套件。需要用逗號或空白分隔套件名稱,亦可以分開多次定義 BuildRequires。

ExcludeArch:    如果軟件不能在特定架硬件架構下運作,需要在此定義。


** SPEC 檔︰內文 (Body) 的基本內容

%install:       安裝編譯好軟件的 shell 程序。一般包括將你要安裝的執行檔、軟件庫、設定檔、說明文件等等,

                由編譯的資料匣(如 %_builddir)移放到 %buildroot 去。

                在理想的世界裏,是預備好 ~/rpmbuild/BUILDROOT 的資料匣結構,然後把檔案由 ~/rpmbuild/BUILD 搬到 ~/rpmbuild/BUILDROOT 的程序。

%check:         檢查軟件的 shell 程序,一般擺放 unit test 的指令。

%files:         需要打包的檔案列表,每行一個定義,可以使用 bash 通用的「*」萬用字元 。

                留意這裏的檔案路徑以 %buildroot 定義的資料匣為根目錄,換言之沒放在這裏的檔案,是無法被打包的。

%changelog:     軟件變化的紀錄,定義不同版本 (version) 或建置版本 (build) 的變化。


在軟體包安裝之前( %pre)或之後( %post)執行

在軟體包卸載之前( %preun)或之後( %postun)執行

在事務開始( %pretrans)或結束( %posttrans)時執行















2020年11月3日 星期二

Linux rpm build (1) - rpmbulid

    rpm命令使用簡介

    什麼是rpm?

    rpm是RPM package manager的縮寫,最早由RedHat公司提出的軟體包標準,後來隨著rpm的不斷髮展而又增加許多功能,

    逐漸的成為linux公認的軟體包管理標準。支援該格式的廠商有RedHat linux、suse linux、Mandriva linux。


    rpm命令十分強大,那麼rpm命令究竟有什麼功能呢?

    1 查詢已安裝在linux系統中的rpm軟體包的資訊

    2 查詢rpm軟體包安裝檔案的資訊

    3 安裝rpm軟體包到當前linux系統

    4 從linux系統中解除安裝已安裝的rpm軟體包

    5 升級當前linux系統的rpm軟體包

    (1)#rpm -qa       後面不接引數用於檢視系統中已經安裝的所有的rpm

    (2)#rpm -q rpm    用於檢視系統中是否安裝了該軟體包,如果安裝了,系統會顯示完整的包名;如果沒有安裝,系統會提示”package bas is not installed”。

    (3)#rpm -qi rpm   用於檢視系統中已經安裝的rpm包的完整資訊,包括該包的版本資訊,安裝時間和大小等。

    (4)#rpm -ql rpm   用於檢視該軟體包都安裝到了那些位置。

    (5)#rpm -qf 檔名  用於檢視某個檔案使用那個rpm包安裝的。

    (6)#rpm -qpi rpm  和#rpm -qpl分別用於檢視沒有安裝的包的資訊,注意下和(4)、(5)的區別。

    (7)#rpm -ivh      用於安裝rpm軟體包,i代表安裝、v代表視覺化安裝、h代表安裝的時候顯示進度。

    (8)#rpm –force -irpm 用於強制安裝rpm軟體包,–force引數用於安裝存在依存關係的rpm包。不過一般我們並不怎做,解決依存關係的較好的方法是使用#rpm -i 命令一起安裝。

    (9)#rpm -e rpm    用於刪除rpm軟體包。

              #rpm -e –nodeps rpm 用於刪除存在依存關係的軟體包,該命令可以將和該包存在依存關係的所有的軟體包統統刪除。

   (10)#rpm -Urpm     用於對rpm包的升級。


    **解壓縮rpm檔

    在 Redhat 系列的發行版內, 所有安裝的套件都會打包成 rpm 檔, 安裝時只要安裝一個檔案便可以, 就如同 Debian 的 deb 檔,

    使用 rpm 安裝套件十分方便, 但有時只想解開 rpm 檔的內容, 而不要安裝套件, 這時可以用 rpm2cpio cpio 指令。

    解開 rpm 不像解開 deb 可以用單一指令完成, 需要先用 rpm2cpio 轉換 rpm 成為 cpio 格式, 再用 cpio 解開,

    這個動作可以透過管線 (pipe) 完成。

    例如有一個 example.rpm 要解開, 指令是這樣:

    # rpm2cpio example.rpm | cpio -idmv

    以上指令會將 example.rpm 的內容解開到當前目錄。


    ** rpmbuild  手動建立自己的rpm

    動手打包前,首先得安裝相關的軟件。我們需要使用的程式是 rpmbuild

    如果你是 RHEL、CentOS

    sudo yum install rpm-build


    如果你是 Ubuntu 或者 Debian 的用戶,

    sudo apt-get install rpm

    

    安裝之後,我們來試一試 rpmbuild是否存在︰

    rpmbuild --version

    RPM version 4.4.2.3



文章參考:

https://codertw.com/%E5%89%8D%E7%AB%AF%E9%96%8B%E7%99%BC/392870/

https://www.opencli.com/linux/extract-rpm-files