2012年6月27日 星期三

zypper筆記

zypper簡史

zypper是在SUSE Linux下的套件管理程式引擎(ZYpp library, 或是libzypp)最重要的指令。也是PackageKit的後端程式(Back-ends),目的是提供一個高階的套件管理程式,協助使用者解決套件相依性的問題、提供解決方案並且自動化設定。 也就是說,使用指令zypper來控制套件跟使用YaST管理套件是相同的行為。

zypper提供的功能主要有:

  1. 自動化安裝、升級以及移除套件
  2. 能夠管理多個套件庫來源URI(Universal Resource Identifier, 可以是localdir, local ISO, NFS, http, ftp, samba, etc.)
  3. 提供比rpm更彈性的管理、查詢功能。

Repositories

一個SuSE Linux標準的repostories設定檔,是放置在/etc/zypp/repos.d/底下,任何以.repo結尾的檔案都會被視為一個套件庫。以一個普通的SLES11.1.repo為例,格式如下:

[SLES11.1]
name=SLES11.1 repostory
enabled=1
autorefresh=1
baseurl=http://192.168.20.1/SLES11.1/x86_64
path=/
type=yast2
keeppackages=0
  1. zypper使用兩種『名稱』:Alias(別名)與Name(名稱描述)。其中[]內為Alias,name則為名稱描述。
  2. enabled必須設定為1才算啟動,這點與yum的定義剛好相反。
  3. autorefresh定義了是否要自動更新套件庫。以ISO檔或是固定來源(例如SLES)的套件庫可設定為0以節省時間。
  4. baseurl可以是local filesystem, ISO, http, https, ftp, nfs, obs等等。URL的來源不需要指定architecture,這會自動由/etc/zypp/zypper.conf或是/etc/zypp/zypp.conf來決定。
  5. path代表從baseurl底下直接視為此套件庫的根目錄。如果是type是yast2或是rpm-md的話,baseurl底下能找到repodata這個資料夾,此時path即可設定為根目錄(/)。
  6. type定義了套件庫類型。zypper能接受三種套件庫類型:yast2(傳統suse套件庫)、rpm-md(相容yum套件庫)以及plaindir(一個包含rpm檔案的資料夾)。
  7. keeppackages定義了安裝或更新完成後是否要從cache裡刪除檔案。

zypper的指令格式如下:

zypper  [--global-options]  <command>  [--command-options]  [args]
雖然有許多command,但是好記卻是zypper的特點--每一個command都有其縮寫,若能熟練縮寫則能減輕許多負擔。例如addrepos可以簡寫為ar,search可簡寫成se,remove可簡寫成rm。格式順序是重要的,但是不要強記--應以自己理解的步調為主。
這裡列舉幾個常見的Global Options:
  • -h (--help):
  • 顧名思義,列出一些重要的commands/options。
  • -q (--quiet):
  • 安靜模式,最常用於shell script裡放進crontab裡使用。
  • -n (--non-interactive):
  • 使zypper的流程變成自動化,但是未必所有情況都會自動回答yes。
  • --no-gpg-checks:
  • 若遇到需要GPG key驗證的時候,可以略過不進行檢查並繼續執行動作。
  • --gpg-auto-import-keys:
  • 若遇到套件庫要求匯入GPG key時能自動匯入。
請務必注意Global Options必須寫在command之前,若寫在command之後會被視為command-options。例如我想要安裝k3b跟net-snmp並移除emacs,過程中自動回答yes並視需要自動匯入GPG,則應該像是這樣:
zypper -q --gpg-auto-import-keys install -yf -d k3b net-snmp -emacs
這串冗長的指令被install一分為二:左側所有的options都是global-options,右側則都是command-options。新版的libzypp會把--no-gpg-checks與--gpg-auto-import-keys定義為Repository Options,但對於語法沒有衝突。

1. 新增套件庫來源:zypper addrepo(ar)

新增一個http站台為例:

zypper ar -f http://192.168.20.1/SLES11.1/x86_64 SLES11.1
-f (--refresh)加入並且立即更新套件資料庫。沒有-f時,zypper預設是不autorefresh的。
後面的網址部份是baseurl,SLES11.1則是Alias。由於我們沒有設定其他參數,因此其他設定會被指定成預設值,例如:enabled=1,type=yast2以及keeppackages=0。如果想要新增一個本地端的ISO檔作為repo,可以這麼定義:
zypper ar -t yast2 -n "SLES11.1 repostory" "iso:/?iso=/home/maxsolar/tftpboot/ISOs/SLES/SLES11sp1_x86_64.iso" "SLES11.1 iso"
以下分別是local DVD, NFS4, ftp以及https的範例:
zypper ar "dvd:/subdir?devices=/dev/sr0,/dev/sr1" DVD
zypper ar "nfs4://nfs-server/exported/path?mountoptions=ro" NFS
zypper ar "cifs://servername/share/path/on/the/share?user=usern&pass=password" SAMBA
zypper ar "ftp://user:password@server/%2fhome/user/path/to/media/dir" FTP
zypper ar "https://user:password@server/path?proxy=foo&proxyuser=me&proxypass=password" WEB
其中-c (--check)是定義加入此repo時檢查其可用性,如果有位置指定錯誤則會馬上得知。
-n (--name)定義了名稱描述。在不定義name時,name==alias。
alias是必要的參數,他不需要任何其他option來引用他。由於ISO檔的資料是固定不變的,因此不使用-f使其永遠不autorefresh以增進效能。

再看另一個例子:把swyear大大個人維護的repo拿來使用:
zypper ar -cdG -n "swyear opensuse" -p 70 -t rpm-md http://download.opensuse.org/repositories/home:/swyear/SLE_11_SP1/ swyear
  • -d (--disable)
  • 加入但不使用此repo。
  • -G (--no-gpgcheck)
  • 不檢查gpg key。
  • -p (--priority)
  • 指定一個不為0的整數作為優先權。

新增一個repo檔至套件庫:

zypper ar -r SLES11.1-kiso.repo
其實更簡單的方式,就是把這個repo檔直接放到/etc/zypp/repos.d/裡,那麼你幾乎可以忘記這個功能。

2. 查詢套件庫:zypper repos(lr)

現在可以查詢剛剛已經加入套件庫有哪些:

zypper repos
# | Alias                          | Name                               | Enabled | Refresh
--+--------------------------------+------------------------------------+---------+--------
1 | SLES11.1                       | SLES11.1                           | Yes     | Yes
2 | SLES11.1 iso                   | SLES11.1 repository                | Yes     | No
3 | swyear                         | swyear opensuse                    | No      | Yes 

事實上同一套件有可能被多個套件庫所維護。以Debian系列來說,系統預設會安裝版本號最新的套件;而SuSE系列的Linux則是依優先權(priority)來安裝,使用-d來查看所有細節(details):
zypper lr -d
# | Alias                          | Name                               | Enabled | Refresh | Priority | Type   | URI
--+--------------------------------+------------------------------------+---------+---------+----------+--------+--------------------
1 | SLES11.1                       | SLES11.1                           | Yes     | Yes     |   99     | yast2  | http://192.168.20.1/SLES11.1/x86_64/
2 | SLES11.1 iso                   | SLES11.1 repository                | Yes     | No      |   99     | yast2  | dir:///home/maxsolar/tftpboot/ISOs/SLES/SLES11sp1_x86_64.iso
3 | swyear                         | swyear opensuse                    | No      | Yes     |   70     | rpm-md | http://download.opensuse.org/repositories/home:/swyear/SLE_11_SP1/
 
需特別注意priority=1表示最高優先權,若不指定優先權則預設為99。你還需要知道哪些重要的小功能呢?
  • -P (--sort-by-priority):
  • 依優先權排序。
  • -U (--sort-by-uri):
  • 依URI排序。
  • -N (--sort-by-name):
  • 依名稱排序。
  • -e (--export):
  • 將所有套件庫匯出至一個檔案。
zypper lr -e foo.repo

3. 刪除與修改套件庫:zypper removerepo(rr)/modifyrepo(mr)/namerepo(nr)

   3.1 刪除套件庫(removerepo)有三個控制項:id(#)、URI以及Alias,任意一項都可以:

zypper rr 1
等同於
zypper rr SLES11.1
等同於
zypper rr http://192.168.20.1/SLES11.1/x86_64/

   3.2 修改套件庫(modifyrepo)有四個控制項:id(#)、URI、Alias以及name,建議用最直覺的id即可。可以修改的options族繁不及備載,這裡僅列出幾項作拋磚引玉之用:

zypper modifyrepo
  • -e (--enable)與-d(--disable):
  • 啟用與停用。
  • -r (--refresh)與-R(--no-refresh):
  • 啟用/停用自動更新。
  • -p (--priority) <positive-integer>:
  • 設定大於0的整數作為優先權。
  • -n (--name) <name string>:
  • 指定一個字串作為name。
  • -k (--keep-packages)與-K(--no-keep-packages):
  • 安裝/更新後,套件是否保留在cache裡。
  • -a (--all):
  • 將規則套用到所有套件庫。
假設我要把#1變成優先權為10,#2改變name為SLES11_ISO_repo並啟用autorefresh,把#3設定為啟用並且將所有repos都設定keeppackages=1:
zypper mr -p 10 1
zypper mr -rn SLES11_ISO_repo 2
zypper mr -e 3
zypper mr -ka
或許你已經注意到,modifyrepo並不能修改Alias,想要修改Alias必須使用namerepo這個子指令。

   3.3 修改套件庫名稱(namerepo)也有四個控制項:id(#)、URI、Alias以及name,建議用最直覺的id即可。他的目的就只有一個--修改Alias:

zypper nr 2 SLES11_ISO_image

4. 查詢套件:zypper search(se)/info(if)/what-provides(wp)

   4.1 查詢套件(search)的方式相當靈活,在此我先列出常用的options再加以靈活運用:

  • -s (--details):
  • 顯示詳盡訊息
  • -d (--search-descriptions):
  • 連套件描述的文字也納入搜尋。
  • -r (--repo) <alias|name|#|URI>
  • 指定套件庫內容來搜尋。
  • --match-exact <STRING>
  • 指定某一精確的字串來搜尋。
例如我想知道套件名稱有包含snmp的套件:
zypper se snmp -s
kernel的種類太多,只想精確搜尋kernel-syms:
zypper se --match-exact kernel-syms
S | Name        | Summary                              | Type      
--+-------------+--------------------------------------+-----------
  | kernel-syms | Kernel Symbol Versions (modversions) | package   
  | kernel-syms | Kernel Symbol Versions (modversions) | srcpackage
這裡的type與使用zypper repos顯示的type意義是不同的。repos裡的type是套件庫的種類;search裡的type是套件本身的種類,有package(一般正常的rpm檔)、pattern(推薦的套件群組)、product(必須安裝的套件群組)以及srcpackage(原始碼)。此時不指定type時,package為預設類別。 只搜尋#1套件庫,套件描述裡包含kvm的套件呢?
zypper se -r 1 -d kvm
想找kernel開頭的套件:
zypper se kernel-*

   4.2 查詢套件詳細訊息(info)需要給定一個正確的套件名稱,先search之後再使用info是個好方法。

zypper if expect

   4.3 查詢某個檔案或套件事由誰提供(what-provides)

zypper wp libldap-2.4.so.2

5. 安裝套件:zypper install(in)/source-install(si)

   5.1 install的基本格式為

zypper install [options] <name|capability|rpm_file_uri>
安裝swyear提供的k3b到系統上:
zypper in k3b -r swyear
也可以寫成
zypper in swyear:k3b
安裝多個rpm檔:
zypper in http://192.168.20.1/progs/madedit/MadEdit/MadEdit-0.2.9/madedit-0.2.9-1.x86_64.rpm ~/progs/Adobe/AdbeRdr9.4.7-1_i486linux_enu.rpm
安裝同時移除套件:
zypper in vim-enhanced -gcin
安裝某一個缺少檔案所帶來的套件:
zypper in 'libXfixes.so.3'
安裝所有以kernel-開頭的套件:
zypper in kernel-*
強制/重新安裝:
zypper in iperf -f
有些好用的options應該要知道:
  • -f (--force):
  • 強制/重新安裝套件。
  • -y (--no-confirm):
  • 遇到問答一律回答yes。
  • -l (--auto-agree-with-licenses):
  • 自動同意軟體授權同意條款。
  • -R (--no-force-resolution)與--force-resolution:
  • 在interactive模式下,zypper預設會幫我們算出解決方案並執行之(--force-resolution);然而在non-interactive模式下,由於顧慮到系統安全,因此放棄自動執行解決方案(--no-force-resolution)以便讓使用者有機會手動解決問題。
    interactive/non-interactive模式是屬於Global Options,這些options必須要比zypper的command更早被使用。
  • -D (--dry-run):
  • 只做測試,不會真的進行安裝。
  • -d (--download-only):
  • 只下載而不進行安裝。
例如:
zypper --non-interactive --no-gpg-checks in -flR iperf
也就是我執行一個非互動式的安裝,不檢查gpg,強制安裝iperf並同意授權條款,若發生錯誤則仍然自動執行解決方案。

   5.2 source-install相對容易多了,他只要接一個原始碼的套件名稱即可。使用si之前需要先使用search:

zypper se -t srcpackage udev
S | Name | Summary                                           | Type      
--+------+---------------------------------------------------+-----------
  | udev | A rule-based device node and kernel event manager | srcpackage
得知這個原始碼套件名稱就是udev,接著就可以進行安裝。
zypper si udev
si預設會把需要編譯該套件的其他套件一起裝起來。

6. 移除套件:zypper remove(rm)

remove的功能很明確,就是移除套件。下列只有幾個簡單的options可供選擇:

  • -t (--type):
  • 指令套件類別。
    zypper rm -t srcpackage udev
  • -R (--no-force-resolution):
  • 不強制使用解決方案。移除時遇到套件相依性問題,系統預設會使用計算出來的解決方案。想要自己手動選擇方案,需要使用-R。
  • -u (--clean-deps):
  • 一同移除沒被使用到的套件。
  • -D (--dry-run):
  • 純粹只是測試,不進行真正更動。

7. 刷新/清空套件庫:zypper refresh(ref)/clean(cc)

   7.1 利用zypper refresh來更新套件庫的快取。若套件庫被標示為不更新(autorefresh=0)的則不受影響。當使用只執行更新時,其實有四種類型的資料會牽涉其中:

  1. metedata
  2. 包含repository metadata(套件大小、版本、相依性等資訊)以及raw metadata(套件的時間戳記、sha1校驗碼以及位置)。
  3. database
  4. libzypp資料庫。
  5. raw data
  6. 就是rpm, source rpm以及patch等實體檔案。
  7. service
  8. 目前版本的zypper(1.5.1)支援的服務僅有Repository Index Service(RIS),訂閱這個服務可以自動管理所有的套件庫,並且由此服務所建議的方案來維護系統上的套件。
refresh預設只會更新metadata,而這也是大部分系統管理員預期的行為。不同的參數可控制細部的行為,可參閱manpages以取得細節。

   7.2 利用zypper clean來清除套件庫的快取(/var/cache/zypp*)。預設只清除套件本身(raw data),如果想要徹底清除metadata並開始一個新的更新,下列參數可能需要:

  • -m (--metadata)
  • 只清除repository metadata,所有已下載的套件都會被保留。
  • -M (--raw-metadata)
  • 所有metadata都清除,但已下載的套件都會被保留。
  • -a (--all)
  • 所有metadata都清除,連已下載的套件都一併刪除。
因此在網路頻寬充裕的情況下,啟動更新前最佳的模式應該是:
zypper clean -a

8. 更新/列舉更新系統:zypper update(up)/dist-upgrade(dup)

update的行為與dist-upgrate僅差別在範圍大小,參數都是共用的。有幾個參數可以特別注意:

  • -r (--repo)
  • 指定某套件庫來源進行更新。
  • -l (--auto-agree-with-licenses)
  • 自動同意license。通常還會搭配-y表示同意
  • --force-resolution
  • 更新預設的行為是--no-force-resolution,會提示解決方案由使用者決定。使用force表示採用zypper所計算出的最佳解決方案。
  • -D (--dry-run)
  • 一個測試性質的動作,不影響系統狀態。
假設不預先執行zypper refresh,光是執行zypper update就會先執行refresh的動作。update會更新所有metadata,並且更新、下載安裝套件之後,再更新database。
update的行為是更新已安裝的套件,但dist-upgrade的行為著重在系統的升級,例如更新了repo之後,利用dup從SLES11.1升級至SLES11.2,此時會安裝新版本所建議的套件、更新原本安裝的套件,也會移除新版本所廢除的套件。

9. 檢查使用舊套件之程序:zypper ps

在經歷update或是dist-upgrade之後,系統總會提示使用者要執行zypper ps已檢查有哪些套件或檔案已被更新但系統仍持續佔用(occupied)。他沒有參數,只具參考價值;對於仍持續被系統佔用的舊套件只有重開機之後才能使用更新後的套件/檔案。

這份筆記並不適用於zypper 0.5(例如SLES10)。因為SLES10並不讀取repo檔案,zypper的使用效率也很低落;想在SLES10使用zypper必須自行參考他所提供的manpages。

Share