亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区

Chinaunix

標(biāo)題: Linux平臺(tái)軟件管理系統(tǒng)設(shè)計(jì)與規(guī)劃-中級(jí)篇(3)-深入理解和使用yum來管理RPM包 [打印本頁]

作者: duanjigang    時(shí)間: 2012-12-29 13:36
標(biāo)題: Linux平臺(tái)軟件管理系統(tǒng)設(shè)計(jì)與規(guī)劃-中級(jí)篇(3)-深入理解和使用yum來管理RPM包
本帖最后由 duanjigang 于 2013-01-05 11:23 編輯

本篇涉及的內(nèi)容有:
(1): RPM 在 linux系統(tǒng)上如何運(yùn)行淺解與要點(diǎn)總結(jié)
(2): YUM 服務(wù)出現(xiàn)和要素分析
(3): 怎樣搭建和使用 yum 服務(wù)
(4): createrepo 和 RPM 的索引文件分析
(5): yum 本地cache
(6): yum clean 源碼淺析
(7): yum 配置文件詳解
(: yum插件剖析與開發(fā)


========================================
在寫完 “RPM認(rèn)知” 和 ”RPM制作與SPEC文件“ 兩篇后,本來計(jì)劃再整理學(xué)習(xí)下一篇 ”RPM如何在linux系統(tǒng)上工作“的,但是考慮了下,因?yàn)槲覍?duì) RPM 的源碼還沒有閱讀,只能說出
大概的動(dòng)作/流程等,細(xì)節(jié)言不明,難以從開發(fā)人員的角度來分析,只好就粗糙點(diǎn)從運(yùn)維人員的角度來總結(jié)下。

關(guān)于 ”RPM如何在linux系統(tǒng)上工作“的內(nèi)容,就簡單總結(jié)了幾點(diǎn)常用的知識(shí),在本篇開頭來講下。

很慶幸有這個(gè)空閑的周末,蝸居西溪旁,小雨漫天下,臥室微冷,聆聽聽著《夜的鋼琴曲》,慢慢總結(jié)一下這篇,廢話不多,開始。

作者: duanjigang    時(shí)間: 2012-12-29 14:02
本帖最后由 duanjigang 于 2012-12-29 14:10 編輯

從宏觀上來說,linux操作系統(tǒng)(只看OS層面,不談?dòng)布┚褪怯伸o態(tài)的文件系統(tǒng)和動(dòng)態(tài)的進(jìn)程組成的(不知道這樣說合適不合適)。文件系統(tǒng)記錄了 ”我是什么樣的,我有什么“,而進(jìn)程則能夠用文件系統(tǒng)的這些功能動(dòng)態(tài)的改變OS的狀態(tài)或者對(duì)外提供服務(wù)。
  其實(shí)這樣的OS也就能夠運(yùn)行了,為什么還要出現(xiàn)軟件包呢?大概是人們?yōu)榱朔奖愕墓芾聿僮飨到y(tǒng)吧,就跟一個(gè)國家都是零散的百姓而沒有組織機(jī)構(gòu)一樣,那樣會(huì)很難于管理,為此才把地方劃為郡縣,省市,縣,鄉(xiāng),村,甚至大隊(duì)~~。理想狀況下,這樣任意一個(gè)人需要服務(wù),都可以直接找自己歸屬的組織去尋求幫助。工作起來效率提高。
   操作系統(tǒng)當(dāng)然不能夠只是零散的文件組成,也需要對(duì)這些文件/程序進(jìn)行管理,因此,就有了軟件包的概念。某些文件屬于某個(gè)軟件包,某個(gè)軟件包有某些文件。這樣的有序性
是提供了管理效率,但是也是有付出的,那就是存儲(chǔ),需要有額外的空間來記錄文件和包的對(duì)應(yīng)關(guān)系。當(dāng)然,在一個(gè)包內(nèi)部,這是不需要的,因?yàn)槿魏芜诉硕紝儆谒诘倪@個(gè)包,當(dāng)環(huán)境轉(zhuǎn)移到OS層面之后,多個(gè)軟件包要在OS上共存,有序管理,我們不僅要記錄文件到包的關(guān)系,有時(shí)也要記錄包和包之間的關(guān)系。
    逐漸的,當(dāng)這些信息被梳理并且記錄時(shí),就形成了軟件包數(shù)據(jù)庫的概念。對(duì) RPM 而言就是 RPM數(shù)據(jù)庫。

以前沒有包的概念時(shí),是人類直接通過工具操作文件,現(xiàn)在介入了數(shù)據(jù)庫的操作。簡單畫了個(gè)圖,表達(dá)此改變,如下:


自然而然,我們大概也就猜到了 RPM 是如何在OS上工作的: 用戶通過工具(rpm命令)管理軟件包,也就是對(duì)文件系統(tǒng)進(jìn)行增刪查改,在增刪查改的同時(shí)(也可能先于或者晚于),也對(duì)RPM的數(shù)據(jù)庫進(jìn)行了增刪查改操作,總之,RPM數(shù)據(jù)庫是為了方便用戶通過工具來管理系統(tǒng)上的文件系統(tǒng)或者說軟件包。

下面我們列舉下比較重要的幾個(gè)方面,都是跟RPM在OS上的管理相關(guān)的。
作者: duanjigang    時(shí)間: 2012-12-29 14:11
本帖最后由 duanjigang 于 2012-12-29 14:17 編輯

(1)關(guān)于 linux 主機(jī)上的 RPM 數(shù)據(jù)庫

RPM 在 linux 機(jī)器上工作原來是比較明確的,首先有實(shí)際的rpm解壓縮并且安裝后的文件;另外有Rpm 的DB文件,
存儲(chǔ)這些安裝了的 rpm 的信息,這些庫中信息在 RPM進(jìn)行安裝,升級(jí)和卸載時(shí)進(jìn)行更新。

RPM命令對(duì)兩者的操作有: (1):對(duì)DB庫進(jìn)行增刪查該 (2):對(duì)文件系統(tǒng)進(jìn)行增加和刪除和讀取。
結(jié)合起來看:

(1): RPM的安裝/升級(jí),寫入DB庫,寫文件系統(tǒng),生成安裝列表和服務(wù),配置等,執(zhí)行安裝時(shí)腳本。
(2): RPM卸載,刪除DB庫,刪除文件系統(tǒng)中歸屬于該軟件包的文件,執(zhí)行卸載時(shí)腳本。
(3): RPM查詢, 讀取DB庫/文件并且顯示。



RPM 的在主機(jī)上的數(shù)據(jù)庫有好多個(gè),根據(jù)不同的應(yīng)用類型,采用不同的訪問方法,可以看下:

  1. file /var/lib/rpm/* | grep Berkeley
  2. /var/lib/rpm/Basenames:      Berkeley DB (Hash, version 8, native byte-order)
  3. /var/lib/rpm/Conflictname:   Berkeley DB (Hash, version 8, native byte-order)
  4. /var/lib/rpm/Dirnames:       Berkeley DB (Btree, version 9, native byte-order)
  5. /var/lib/rpm/Filemd5s:       Berkeley DB (Hash, version 8, native byte-order)
  6. /var/lib/rpm/Group:          Berkeley DB (Hash, version 8, native byte-order)
  7. /var/lib/rpm/Installtid:     Berkeley DB (Btree, version 9, native byte-order)
  8. /var/lib/rpm/Name:           Berkeley DB (Hash, version 8, native byte-order)
  9. /var/lib/rpm/Packages:       Berkeley DB (Hash, version 8, native byte-order)
  10. /var/lib/rpm/Providename:    Berkeley DB (Hash, version 8, native byte-order)
  11. /var/lib/rpm/Provideversion: Berkeley DB (Btree, version 9, native byte-order)
  12. /var/lib/rpm/Pubkeys:        Berkeley DB (Hash, version 8, native byte-order)
  13. /var/lib/rpm/Requirename:    Berkeley DB (Hash, version 8, native byte-order)
  14. /var/lib/rpm/Requireversion: Berkeley DB (Btree, version 9, native byte-order)
  15. /var/lib/rpm/Sha1header:     Berkeley DB (Hash, version 8, native byte-order)
  16. /var/lib/rpm/Sigmd5:         Berkeley DB (Hash, version 8, native byte-order)
  17. /var/lib/rpm/Triggername:    Berkeley DB (Hash, version 8, native byte-order)
復(fù)制代碼
能夠看到,主要是 HASH 和 BTREE 這兩種訪問方式。(很奇怪,version 8 的是 HASH, version 9的是BTREE ?是應(yīng)用相關(guān),還純粹是作者愛好呢?)

RPM 的所有DB,都是從 /var/lib/rpm/Packages 生成的?梢宰鰝(gè)實(shí)驗(yàn),把除了 Packages 以外的其它文件全部刪掉。
然后重新 rpm --rebuilddb -vv
這些文件都會(huì)一一生成,因?yàn)闃?gòu)成這幾個(gè)新的db文件的信息都在Packages中包含了。(如果你把這個(gè)文件干掉了,那就悲催了,
曾經(jīng)遇到有人把這個(gè)文件給刪掉了,只好從同組配置接近的機(jī)器給他拷貝了一個(gè)os和arch一樣的機(jī)器的Packages,重新生成了下db,還好,能繼續(xù)用,呵呵)。因?yàn)檫@個(gè)文件中記錄了你的機(jī)器安裝的所有RPM和文件列表,一旦這個(gè)文件丟失了,rpm就不知道你的機(jī)器上有哪些rpm了,當(dāng)你通過
rpm -qf path 查詢某個(gè)二進(jìn)制文件屬于哪個(gè)rpm時(shí),也不會(huì)有結(jié)果輸出。


關(guān)于 /var/lib/rpm/Packages 這個(gè) DB 文件的最初來源,我分析(結(jié)合猜測(cè))是這樣的:

首先,在安裝(或者OS安裝時(shí))每一個(gè) rpm 文件的時(shí)候,rpm 命令都會(huì)把要安裝的 rpm 包的信息分析出來,包括我們?cè)诘谝黄吹降乃蠺AG還有文件列表等信息;
然后會(huì)把這些信息寫入 /var/lib/rpm/Packages 文件中,如果這個(gè)文件不存在,就創(chuàng)建;當(dāng)刪除包時(shí),就會(huì)從 /var/lib/rpm/Packages 中
刪除與該包相關(guān)的所有信息。該文件中記錄了所有 rpm 的全量信息,因此,我們通過 rpm 命令查詢時(shí),才能夠看到那么多燦爛和豐富的信息。

以rpm -qf 和 rpm -ql 為例:
比如,為了能從 xshell 拷貝文件到windows機(jī)器,我經(jīng)常會(huì)用 sz/rz命令,但是有些機(jī)器上就是沒這個(gè)命令,
要安裝,又不知道它在哪個(gè)包,怎么辦,這時(shí)就需要用 rpm -qf 來查詢了:

找一臺(tái)安裝了 sz/rz 命令的機(jī)器:

  1. # which sz
  2. /usr/bin/sz
  3. # rpm -qf /usr/bin/sz
  4. lrzsz-0.12.20-22.1
復(fù)制代碼
喔,我們發(fā)現(xiàn)sz和rz是在 lrzsz 這個(gè)包中的,然后在需要的機(jī)器上 rpm/yum 安裝 lrzsz 包即可。

那么,rpm -qf 命令路徑 就能查到這個(gè)命令屬于那個(gè)包,這是怎么做到的呢?

首先我們知道安裝 lrzsz 時(shí) rpm 會(huì)把 這個(gè)包的所有信息寫入 /var/lib/rpm/Packages 文件,這個(gè)包包含的文件列表也會(huì)寫入
到 這個(gè)文件中,然后才會(huì)更新生成 /var/lib/rpm 中的其它DB文件(個(gè)人理解,其它DB文件就是為了查詢加速而用生成的cache.)

然后,當(dāng)執(zhí)行

  1. rpm -qf /usr/bin/sz
復(fù)制代碼
時(shí),rpm 就會(huì)去 /var/lib/rpm/Packages 中(或者其它c(diǎn)ache文件中)查詢包含 /usr/bin/sz 這個(gè)路徑的
包,當(dāng)然就查到了是 lrzsz.

有人說,可能查到多個(gè)包么?這個(gè)是不可能的,因?yàn)?rpm 在安裝 rpm 文件的時(shí)候,也就是往 /var/lib/rpm/Packages
中寫數(shù)據(jù)的時(shí)候,會(huì)檢查這個(gè)rpm 中包含的文件列表是否已經(jīng)在本機(jī)安裝的其它包中出現(xiàn)了,如果找到了,就會(huì)警告: 這個(gè)文件和其它某個(gè)包中的
某某文件沖突了的錯(cuò)誤信息,這個(gè)現(xiàn)象做SA的同學(xué)應(yīng)該都見過。

實(shí)驗(yàn):

  1. ls -alt /var/lib/rpm/Packages
  2. -rw-r--r-- 1 rpm rpm 19234816 Dec 27 09:30 /var/lib/rpm/Packages
復(fù)制代碼
我們能夠看到,這個(gè)文件只對(duì)root 可以寫,我們嘗試改下它的屬性:

  1. chattr +i /var/lib/rpm/Packages
復(fù)制代碼
設(shè)置不可改變屬性,然后嘗試安裝包:

  1. rpm -ivh RPMS/i386/test-baby-1.1-1.i386.rpm
  2. error: cannot open Packages index using db3 - Permission denied (13)
  3. error: cannot open Packages database in /var/lib/rpm
復(fù)制代碼
因?yàn)閞pm 沒有權(quán)限去寫 Packages  這個(gè)數(shù)據(jù)庫文件。

  1. # chattr -i /var/lib/rpm/Packages
  2. rpm -ivh RPMS/i386/test-baby-1.1-1.i386.rpm
  3. Preparing...                ########################################### [100%]
  4.    1:test-baby              ########################################### [100%]
復(fù)制代碼
這下就成功了,再次驗(yàn)證了 rpm 在包安裝時(shí)對(duì) /var/lib/rpm/Packages 的寫操作確實(shí)是存在的。
同樣,你也可以同樣方法測(cè)試下卸載包時(shí)對(duì) /var/lib/rpm/Packages  文件的寫操作是否存
作者: duanjigang    時(shí)間: 2012-12-29 14:20
本帖最后由 duanjigang 于 2012-12-29 14:25 編輯

(2)關(guān)于 /var/log/rpmpkgs 和 /etc/cron.daily/rpm

在linux系統(tǒng)上能夠看到

  1. # rpm -qf /etc/cron.daily/rpm
  2. rpm-4.4.2-37.el5
復(fù)制代碼
/etc/cron.daily/rpm 是 rpm 這個(gè)包帶的一個(gè)每日?qǐng)?zhí)行的crontab任務(wù)。
/etc/crontab 中配置每天4:02執(zhí)行 cron.daily 里面的計(jì)劃任務(wù)。
看下這個(gè)腳本的內(nèi)容:

  1. cat  /etc/cron.daily/rpm
  2. #!/bin/sh

  3. /bin/rpm -qa --qf '%{name}-%{version}-%{release}.%{arch}.rpm\n' 2>&1 \
  4. | /bin/sort > /var/log/rpmpkgs
復(fù)制代碼
就是把 系統(tǒng)上所有 rpm 的列表導(dǎo)出下,排序存儲(chǔ)在  /var/log/rpmpkgs 這個(gè)文件中。
這個(gè)文件有什么作用呢?個(gè)人分析應(yīng)該有以下兩個(gè)作用:

(1): 可以作為rpm -qa 的 cache文件,如果這個(gè)文件在很短時(shí)間內(nèi)剛更新,rpm -qa 直接打印該文件內(nèi)容即可。
(2): 有人可能已經(jīng)想到了,它可以幫助恢復(fù)你的rpm 數(shù)據(jù)庫文件,如果你不小心把 /var/lib/rpm/Packages  弄壞或者丟了,
但是很幸運(yùn),var/log/rpmpkgs 這個(gè)文件還在,而且是比較新的,然后你就可以如下恢復(fù)你的rpm 數(shù)據(jù)庫了。
   
第一: 找到 系統(tǒng)的安裝鏡像包,也就是包含了所有OS的RPM列表。
第二:寫個(gè)腳本,讀取 var/log/rpmpkgs 文件,每行是一個(gè)rpm 文件,進(jìn)行安裝,這里的安裝可不是實(shí)際安裝。而是
        要采用一個(gè)特殊的功能,看下 rpm 的 man 手冊(cè):

  1.         --justdb
  2.               Update only the database, not the filesystem.
復(fù)制代碼
只是更新rpm 的數(shù)據(jù)庫,并不更新系統(tǒng)文件(好像這個(gè)安裝過程也是 --noscripts的,如果你真的走到這一步,可以檢驗(yàn)下,然后告訴我,呵呵)。


作者: duanjigang    時(shí)間: 2012-12-29 14:27
本帖最后由 duanjigang 于 2012-12-29 14:30 編輯

(3) rpm/rpmq/yum/rpmDB hang 住,死鎖的情況

在實(shí)際工作中,有時(shí)會(huì)碰到執(zhí)行rpm/yum 等命令時(shí),沒有任何反應(yīng),進(jìn)程 hang 住的現(xiàn)象,用 strace -p pid 會(huì)發(fā)現(xiàn)進(jìn)程 hang 在對(duì) 對(duì)futex 的操作上,
據(jù)有些文章說這個(gè)是berkeley db 支持多進(jìn)程操作不好導(dǎo)致DB死鎖的結(jié)果。曾經(jīng)嘗試尋找原因,但是未能跟蹤到,只總結(jié)了下解決辦法,希望對(duì)碰到的同學(xué)
有幫助。

首先查看是哪些進(jìn)程,一般無非是 rpm rpmq yum 這三個(gè)其中的若干個(gè),直接

  1. sudo killall -9 yum rpm rpmq;
復(fù)制代碼
然后清除臨時(shí)庫文件:

  1. sudo rm -fr /var/lib/rpm/__db.00*
復(fù)制代碼
這樣就可以了。我一般給同事提供的三板斧就是:

  1. (1): sudo killall -9 rpm rpmq yum  
  2. (2): sudo rm -fr /var/lib/rpm/__db.00*
  3. (3): sudo yum clean all
復(fù)制代碼
當(dāng)然,別的原因?qū)е碌?hang 住情況,就要另當(dāng)別論了。視具體情況處理。


作者: duanjigang    時(shí)間: 2012-12-30 09:33
本帖最后由 duanjigang 于 2012-12-30 17:54 編輯

開始 yum 的介紹
用 yum 服務(wù) 對(duì) RPM 進(jìn)行管理

類似于 RPM 的出現(xiàn)一樣,yum 的出現(xiàn)也是為了方便管理而生,對(duì)于軟件包的管理,采用 rpm 文件來做載體; 安裝,部署等操作時(shí),用 rpm 命令,基本上也夠了。
好多人現(xiàn)在可能還處于這個(gè)狀態(tài),我一年之前也是如此:只知道 rpm 能夠查看 rpm 包信息,安裝,卸載等操作,小日子得過且過也就夠了。后來,接觸的環(huán)境稍微大點(diǎn),就遇到一些問題了,大概總結(jié)了下,面臨的問題已以下幾點(diǎn)最為典型:

(1):作為開發(fā)人員,我只在32位的 rhel5.4 系統(tǒng)上開發(fā),測(cè)試。每次修改代碼后都會(huì)重新 rpmbuild包, 然后把rpm 交給同事去安裝,而且同事的操作步驟大概會(huì)是:先卸載原來的rpm, 清空安裝目錄,然后安裝新的rpm,這期間,他還可能還要備份自己的配置文件。忽然有一天,同事報(bào)告:這臺(tái)機(jī)器不能安裝你的rpm,仔細(xì)一看,是x86_64平臺(tái)的系統(tǒng),或者是4u8的系統(tǒng),也可能是6u3的系統(tǒng)。顯然,這種不同 arch 和 os release version 的環(huán)境,是單用 rpm 面臨一類問題.

(2):某人開發(fā)的 XXOO.rpm 使用了接近十個(gè)第三方庫,運(yùn)行時(shí)依賴于這些庫的so,因此安裝時(shí),也就需要依賴于包含這些庫的rpm包, 嚴(yán)格按照規(guī)范,他在編寫 spec 文件時(shí),寫了N 個(gè) require 依賴,結(jié)果每次部署時(shí),只要運(yùn)行命令:

  1. rpm -ivh XXOO.rpm
復(fù)制代碼
,就會(huì)報(bào)告找不到依賴的若干個(gè)包,面對(duì)這樣的問題,有的聰明一點(diǎn)的部署人員就會(huì)把依賴的包安裝的語句寫在一個(gè)腳本中,先執(zhí)行這個(gè)腳本安裝依賴包,然后再安裝 XXOO 這個(gè)包,這樣做即便能夠解決問題,還是很麻煩,因?yàn)槲覀兡玫絩pm后還要分析它的require list, 人為的標(biāo)明,然后先替他安裝。有木有一種機(jī)制能夠自動(dòng)檢測(cè)XXOO 依賴的 rpm 并且嘗試進(jìn)行安裝呢?

(3):我開發(fā)的軟件生成的 RPM 已經(jīng)有很多版本了,每次為了升級(jí)到最新版,都需要記住最新的 RPM 文件的名字,而且是完整的名字,比如:test-daddy-1.1-1.x86_64.rpm,然后再執(zhí)行

  1. rpm -Uvh http://URL路徑/test-daddy-1.1-1.x86_64.rpm
復(fù)制代碼
才能夠安裝成功,有沒有一種機(jī)制,能夠用很簡單的方式:我只給它 RPM 的名字,就能夠自動(dòng)安裝對(duì)應(yīng)包的最新版 rpm 文件呢,而且還能安裝指定版本的 rpm 呢?

(4):幾臺(tái)機(jī)器需要安裝或者管理 rpm 時(shí),直接 rpm -i 安裝對(duì)應(yīng)OS的包即可,如果成千上萬臺(tái)機(jī)器都需要部署該軟件,而且有不同 os 版本,平臺(tái)不一樣,那該怎么辦?有同學(xué)可能會(huì)自己寫個(gè)腳本拷貝到目標(biāo)機(jī)器去執(zhí)行,自己檢查os和arch,然后安裝對(duì)應(yīng)的rpm,這也是一種辦法,但是有木有更簡潔的方式呢,通用而且靈活,簡易操作?


(5):有時(shí)候我們并不確定要裝哪個(gè)版本的包,只想看看已經(jīng)有哪些 rpm 了,然后再選擇安裝哪個(gè)。。你會(huì)怎么做?登錄rpm服務(wù)器去 find,ls ? 還是高級(jí)點(diǎn),安裝個(gè)lynx,用

  1. lynx --dump http://URL地址
復(fù)制代碼
瀏覽文件列表,然后grep選擇,再 RPM 安裝? 這樣豈不是有些太費(fèi)事?


對(duì)于上面列出的五個(gè)問題(也可能更多),yum 給提供了很好的解決方案,或者說功能接口。我想 yum 的出現(xiàn)也是由于最早的rpm使用者遇到了不止上面的五個(gè)問題等諸多難題后,總結(jié)問題特征,歸納,才設(shè)計(jì)開發(fā)出來的。

下面我們會(huì)以庖丁解牛的方式來給您闡述 yum 的強(qiáng)大功能和涉及到的知識(shí)點(diǎn),或者詳細(xì)或者粗糙,由于我個(gè)人能力有限,就只就自己知道和能夠搜索到的范圍的來說吧,有不對(duì)的地方請(qǐng)盡管指出。
作者: duanjigang    時(shí)間: 2012-12-30 12:00
本帖最后由 duanjigang 于 2012-12-30 18:01 編輯

yum 服務(wù)構(gòu)成的要素

構(gòu)成一個(gè)完整的 yum 服務(wù),需要以下及部分:

(1):  yum 服務(wù)器上的服務(wù)倉庫 (存儲(chǔ)rpm文件和索引文件)
(2):  提供rpm和索引下載的網(wǎng)絡(luò)服務(wù)(http或者ftp服務(wù))
(3):  安裝客戶端的 yum 命令集 (接收用戶輸入,從服務(wù)器檢索/下載文件)
(4):  客戶端配置文件以及擴(kuò)展功能模塊。


用架構(gòu)師大會(huì)的PPT <<2012系統(tǒng)架構(gòu)師大會(huì)-Linux平臺(tái)軟件管理系統(tǒng)設(shè)計(jì)與規(guī)劃.pptx>> 中的一幅圖,來表示下這四個(gè)要素的部署關(guān)系圖:



簡單描述一下一個(gè) rpm 從發(fā)布進(jìn) yum, 到客戶端可用的過程:

yum 中 rpm 從發(fā)布到可用的過程

1. 開發(fā)完成,RPM 已經(jīng)通過 rpmbuild 或者其它工具制作好,把 rpm 放到 yum 服務(wù)器的 rpm 倉庫目錄下 。
2. 在 yum服務(wù)器的 倉庫目錄 (具體目錄位置后面會(huì)講)執(zhí)行 createrepo 命令,該命令會(huì)掃描當(dāng)前目錄(包括子目錄)里面的rpm 文件,記錄rpm 文件的信息,寫入repodata 目錄中的索引文件中。這樣 yum 中就有了新發(fā)布的 rpm 的信息了。
3. 使用者在客戶端安裝了 yum 命令,通過配置 yum 的客戶端配置文件,指定了一個(gè)或者若干個(gè)安裝源, yum 安裝/檢索包時(shí)會(huì)去這些安裝源上檢索索引文件。
4. 使用者在客戶端使用 yum install pkgname 方式安裝包,yum命令 會(huì)把配文件中配置的 yum服務(wù)器的地址(安裝源)作為目標(biāo)服務(wù)器,通過http/ftp/file服務(wù)去 yum 服務(wù)器上下載索引文件,然后在索引文件中查找有無指定的rpm(適合在本系統(tǒng)安裝),找到的話,就按照配置中的路徑組成url地址,下載rpm, 并且在本地安裝。
5. 安裝后,索引文件和rpm包會(huì)cache到本地的cache目錄,方便下次使用,而且把安裝rpm 的信息記錄進(jìn)本地 rpm 的數(shù)據(jù)庫文件中



為了讀者能夠?qū)嶋H操作一把,我們給出一個(gè)實(shí)際的例子:
作者: duanjigang    時(shí)間: 2012-12-30 12:23
本帖最后由 duanjigang 于 2013-01-03 13:21 編輯

搭建yum服務(wù)的簡單實(shí)例

(1): yum 服務(wù)器為 192.168.1.102, 部署網(wǎng)絡(luò)服務(wù)為 httpd, web 根目錄是 /usr/local/cme/web, 監(jiān)聽端口是TCP的81, 把制作好的 rpm test-baby-1.1-1.i386.rpm 放進(jìn)
/usr/local/cme/web/yum/ 目錄下。

(2): 創(chuàng)建索引文件,在/usr/local/cme/web/yum/  目錄下執(zhí)行命令  createrepo, 看到結(jié)果如下:

  1. createrepo --update -d -p -o . .
  2. 1/1 - test-baby-1.1-1.i386.rpm                                                  
  3. Saving Primary metadata
  4. Saving file lists metadata
  5. Saving other metadata
復(fù)制代碼
然后可以看到多了個(gè) repodata 目錄。內(nèi)容如下:

  1. ll repodata/
  2. total 20
  3. -rw-r--r-- 1 root root  271 Dec 29 23:03 filelists.xml.gz
  4. -rw-r--r-- 1 root root  236 Dec 29 23:03 other.xml.gz
  5. -rw-r--r-- 1 root root  755 Dec 29 23:03 primary.xml.gz
  6. -rw-r--r-- 1 root root  951 Dec 29 23:03 repomd.xml
  7. drwxr-xr-x 2 root root 4096 Dec 29 23:03 update-info
復(fù)制代碼
這些就是 createrepo 命令檢索并且讀取 rpm 列表后生成的索引文件。

(3): 配置客戶端的 yum 配置文件,為了為后面的利用智能 DNS 做 yum 優(yōu)化章節(jié)做鋪墊,我們從一開始在網(wǎng)絡(luò)訪問時(shí)就采用域名而不是IP地址的方式,
首先在 客戶端的 /etc/hosts 中配置

  1. 192.168.1.102  yum.test.com
復(fù)制代碼
然后,進(jìn)入 /etc/yum.repos.d 目錄,清空該目錄下的文件(或者備份起來),創(chuàng)建 test.repo 文件內(nèi)容如下:

  1. # cat /etc/yum.repos.d/test.repo
  2. [test]
  3. name=just a test reposity
  4. baseurl=http://yum.test.com:81/yum
  5. enabled=1
  6. gpgcheck=0
  7. gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release
復(fù)制代碼
其中配置的 baseurl 就是告訴 yum 客戶端,檢索 rpm 的路徑是什么,然后 yum 在 list 或者 install 時(shí),就會(huì)嘗試用這個(gè)路徑 + repodata 構(gòu)造一個(gè)索引目錄,然后就能構(gòu)造索引文件路徑,接著下載索引文件,檢索等等,在該例子中索引目錄路徑為:

  1. http://yum.test.com:81/yum/repodata
復(fù)制代碼
(4): 在客戶端執(zhí)行命令

  1. # yum clean all
  2. # yum info test-baby
復(fù)制代碼
能看到輸出如下:

  1. Available Packages
  2. Name   : test-baby
  3. Arch   : i386
  4. Version: 1.1
  5. Release: 1
  6. Size   : 4.4 k
  7. Repo   : test
  8. Summary: GNU test-baby
復(fù)制代碼
顯示了這個(gè)包的信息,注意到: Repo: test 這個(gè)輸出,表明這個(gè)包是從我們配置的 test.repo 中的源上找到的。當(dāng)然你也可以配置多個(gè)源,而且多個(gè)源之間可以有優(yōu)先級(jí)關(guān)系,這些具體配置后面再說。這樣,我們就能檢索到 rpm 了。

(5): 通過命令來安裝:

  1. #sudo yum install test-baby
復(fù)制代碼
輸出如下:

  1. Dependencies Resolved

  2. =============================================================================
  3. Package                 Arch       Version          Repository        Size
  4. =============================================================================
  5. Installing:
  6. test-baby               i386       1.1-1            test              4.4 k

  7. Transaction Summary
  8. =============================================================================
  9. Install      1 Package(s)         
  10. Update       0 Package(s)         
  11. Remove       0 Package(s)         

  12. Total download size: 4.4 k
  13. Is this ok [y/N]: y
  14. Downloading Packages:
  15. (1/1): test-baby-1.1-1.i3 100% |=========================| 4.4 kB    00:00     
  16. Running Transaction Test
  17. Finished Transaction Test
  18. Transaction Test Succeeded
  19. Running Transaction
  20.   Installing: test-baby                    ######################### [1/1]
  21. posttrans_hook----------------------------

  22. Installed: test-baby.i386 0:1.1-1
  23. Complete!
復(fù)制代碼
然后再檢查下:

  1. # rpm -qi test-baby
  2. Name        : test-baby                    Relocations: /usr
  3. Version     : 1.1                               Vendor: (none)
  4. Release     : 1                             Build Date: Thu Dec 27 09:11:07 2012
  5. Install Date: Sat Dec 29 23:23:35 2012      Build Host: localhost.localdomain
  6. Group       : Development/Tools             Source RPM: test-baby-1.1-1.src.rpm
  7. Size        : 9395                             License: GPL
  8. Signature   : (none)
  9. Summary     : GNU test-baby
  10. Description :
  11. The GNU wget program downloads files from the Internet using the command-line.

  12. # tail -1 /var/log/yum.log
  13. Dec 29 23:23:35 Installed: test-baby.i386 1.1-1
復(fù)制代碼
說明 test-baby 確實(shí)安裝成功了。

有幾點(diǎn)要注意下:
(1): 實(shí)驗(yàn)環(huán)境的 yum 服務(wù)器和 客戶端都是 rhel5u4 和 i386 系統(tǒng),你可以試下 服務(wù)器和 客戶端 為不同平臺(tái)或者版本的OS時(shí)情況如何。
(2): test.repo 中配置的網(wǎng)絡(luò)下載服務(wù)是 httpd,你可以試下ftp服務(wù)和本地file 服務(wù)。
(3): 我們?cè)谠摾又兄挥玫搅艘粋(gè)test.repo文件,和 yum.test.com 一個(gè)源,你可以嘗試配置多個(gè)repo 配置和源進(jìn)行測(cè)試看看效果,而且 test.repo 中的其他項(xiàng)也沒進(jìn)行說明。
(4): 在客戶端配置中我們只看到了.repo配置文件,其它的 yum.conf 和 插件配置并沒有提及,后面會(huì)詳述。
(5): 我們?cè)诎惭b的時(shí)候并沒有指定包的版本,而是只指定了包名,多個(gè)版本時(shí),如果要安裝指定版本,yum install 時(shí)要寫明版本。

這樣,一個(gè)基本的yum 系統(tǒng)就搭建起來了。

由淺入深,后面我們會(huì)逐一詳細(xì)的講述上面yum系統(tǒng)中的各個(gè)要素,包括:


(1): createrepo 和 索引文件
(2): yum 的本地 cache
(3): yum clean 源碼小解
(4): yum客戶端配置文件分析: yum.conf 和 *.repo
(5): yum 的插件功能



作者: duanjigang    時(shí)間: 2013-01-03 07:51
本帖最后由 duanjigang 于 2013-01-03 08:51 編輯

之一: createrepo 和 索引文件 探秘

首先重復(fù)下 createrepo 出現(xiàn)的原因: yum 服務(wù)器要提供rpm包的下載服務(wù),服務(wù)器的rpm更新對(duì)于客戶端是未知的,客戶端安裝更新包時(shí)需要找到符合條件的rpm包,而客戶端能夠訪問服務(wù)器的唯一途徑就是ftp或者h(yuǎn)ttp服務(wù),怎樣才能高效的檢索到服務(wù)器上的rpm最新信息呢?前輩們想出了一個(gè)辦法,就是對(duì)服務(wù)器上的所有 rpm 包進(jìn)行索引化,說白了,就是把所有rpm 的信息收集起來,存儲(chǔ)到若干個(gè)小文件中,如果客戶端需要訪問 yum 服務(wù)的話,先把索引文件拿下去在索引文件中檢索,檢索到了,再從服務(wù)器下載文件,安裝。(直接下載所有rpm 文件去檢索的方法肯定是不靠譜的,因?yàn)?rpm 的大小差異很大,但是每個(gè) rpm 的描述信息卻不會(huì)很大).

這樣, createrepo 命令便應(yīng)運(yùn)而生: 檢索指定 rpm 文件的信息生成索引文件。

在前面的例子中,我們都看到了,索引文件會(huì)存儲(chǔ)在一個(gè)叫做 repodata 的目錄中。我們來看個(gè)實(shí)際的例子。

  1. [root@localhost yum]# pwd
  2. /var/www/html/yum
  3. [root@localhost yum]# ls *.rpm
  4. cmeguard-1.1.2-20.i386.rpm  test-cmeadmin-1.1.1-21.i386.rpm
  5. [root@localhost yum]# createrepo --update -d -p .                           
  6. Saving Primary metadata
  7. Saving file lists metadata
  8. Saving other metadata
  9. [root@localhost yum]# ls repodata/
  10. filelists.sqlite.bz2  filelists.xml.gz  other.sqlite.bz2  other.xml.gz  primary.sqlite.bz2  primary.xml.gz  repomd.xml
復(fù)制代碼
看到有 7 個(gè)文件,其實(shí)也就是四個(gè)文件

  1. repomd.xml
  2. primary.xml
  3. other.xml
  4. filelists.xml
復(fù)制代碼
因?yàn)?.xml.gz 文件是對(duì) xml 文件的壓縮,為了減少下載數(shù)據(jù)量(因?yàn)樗饕募南螺d會(huì)占用很大流量的),.sqlite.bz2 文件是對(duì)應(yīng)于 xml 文件的 sqlite 文件壓縮后的文件。
因?yàn)?createrepo 有個(gè)選項(xiàng)是可以把信息存儲(chǔ)成sqlite 數(shù)據(jù)庫格式的(默認(rèn)是xml格式):

  1. -d, --database = generate the sqlite databases.
復(fù)制代碼
每個(gè) xml.gz 和 sqlite.bz2 文件中存儲(chǔ)的原始數(shù)據(jù)是一樣的。

我們先來看看 這幾個(gè)文件都是作甚用的。

repomd.xml:
this is the file that describes the other metadata files. It is like an index file to point to the other files. It contains timestamps and checksums for the other files. This lets a client download this one, small file and know if anything else has changed. This also means that cryptographically (ex: gpg) signing this one file can ensure repository integrity.

說的通俗點(diǎn),這個(gè)文件就是索引文件的索引文件,回到 createrepo 出現(xiàn)的必要性那段: 我想最初的索引文件很可能就是一個(gè)文件,其中記錄了所有包的信息,后來前輩們發(fā)現(xiàn):存在一個(gè)文件中還是有些臃腫,那不如分開吧,把不同類的信息存儲(chǔ)到不同文件中,這樣,高級(jí)一點(diǎn)的索引文件就成了N個(gè)文件,因?yàn)樗砹薔類信息,再后來,前輩們又想:到底有那幾個(gè)索引文件,N個(gè)到底是幾個(gè),這些文件變化木有,誰知道,都要挨個(gè)去檢查么?于是乎,他們又設(shè)計(jì)了一個(gè)文件,用這個(gè)文件來存儲(chǔ)這N個(gè)索引文件的信息,于是乎,repomd.xml 這個(gè)文件
就誕生了~~~ 以后每次檢查索引更新時(shí),只需要先下載服務(wù)器上的這個(gè)文件,從中解析 其它 N 個(gè)文件是否改變的特征,如果有改變(這個(gè)是需要和本地cache索引做對(duì)比的),就下載對(duì)應(yīng)的索引文件,更新本地索引,重新下載包,如果沒改變,就用本地索引或者cache的包。
   這樣做的目的是什么呢?個(gè)人分析最終一個(gè)目標(biāo):就是為了減小從 yum 服務(wù)器 下載到客戶端的網(wǎng)絡(luò)流量,因?yàn)槊看?yum 查詢都可能需要檢索索引的,因此,軟件設(shè)計(jì)時(shí),盡量會(huì)從節(jié)省資源使用考慮,去把下載量降低到最少。

大家一起來看看廬山真面目:

  1. # cat repomd.xml
  2. <?xml version="1.0" encoding="UTF-8"?>
  3. <repomd xmlns="http://linux.duke.edu/metadata/repo">
  4.   <data type="other_db">
  5.     <location href="repodata/other.sqlite.bz2"/>
  6.     <checksum type="sha">2976204b0a2782c6646a0ae60f196292e380d314</checksum>
  7.     <timestamp>1357776838</timestamp>
  8.     <open-checksum type="sha">678b1af45a0cd57d2a040a4332cf867f0c1b9288</open-checksum>
  9.     <database_version>10</database_version>
  10.   </data>
  11.   <data type="other">
  12.     <location href="repodata/other.xml.gz"/>
  13.     <checksum type="sha">714bc82c1dab6cb0ec4a4b7ca57f61efeb02f7ad</checksum>
  14.     <timestamp>1357776838</timestamp>
  15.     <open-checksum type="sha">66810c751bbf93fd44548b7c458ad9ac21e73638</open-checksum>
  16.   </data>
  17.   <data type="filelists_db">
  18.     <location href="repodata/filelists.sqlite.bz2"/>
  19.     <checksum type="sha">7cee73ebffec1c8dcc23ffc9dbab3e4919fbeac0</checksum>
  20.     <timestamp>1357776838</timestamp>
  21.     <open-checksum type="sha">a2a0e5fb9c68b5d0137428bab2a19ebdedf83588</open-checksum>
  22.     <database_version>10</database_version>
  23.   </data>
  24.   <data type="filelists">
  25.     <location href="repodata/filelists.xml.gz"/>
  26.     <checksum type="sha">99c9c6bd6f056a95b164db408b75c4e024173718</checksum>
  27.     <timestamp>1357776838</timestamp>
  28.     <open-checksum type="sha">d4d100a8d52e833579954cf901f845e6bf0e7375</open-checksum>
  29.   </data>
  30.   <data type="primary_db">
  31.     <location href="repodata/primary.sqlite.bz2"/>
  32.     <checksum type="sha">41059e8ff1b76b2cf06dba4f05db6a20fe72056f</checksum>
  33.     <timestamp>1357776838</timestamp>
  34.     <open-checksum type="sha">8baee8d8a213efa1c3cccfefa5a4c16de964704a</open-checksum>
  35.     <database_version>10</database_version>
  36.   </data>
  37.   <data type="primary">
  38.     <location href="repodata/primary.xml.gz"/>
  39.     <checksum type="sha">1f816e4886b0c2bdd378f0d0f876c2666b3bcf86</checksum>
  40.     <timestamp>1357776838</timestamp>
  41.     <open-checksum type="sha">79183262b5e9f945f912a41e23e1555c0f3a71af</open-checksum>
  42.   </data>
  43. </repomd>
復(fù)制代碼
首先,我們能看到它是從 xml 的樹形格式存儲(chǔ)的,每一個(gè) section 定義為一個(gè) data,如本例,包含了六個(gè) data ,也就是六個(gè)文件:

  1. # cat repomd.xml | grep -w "<data"
  2.   <data type="other_db">
  3.   <data type="other">
  4.   <data type="filelists_db">
  5.   <data type="filelists">
  6.   <data type="primary_db">
  7.   <data type="primary">
復(fù)制代碼
可以看到,每一個(gè) section 就是對(duì)一個(gè) 索引文件的描述,我們來深入每一個(gè) data 段來看下:

  1. <data type="primary">
  2.     <location href="repodata/primary.xml.gz"/>
  3.     <checksum type="sha">1f816e4886b0c2bdd378f0d0f876c2666b3bcf86</checksum>
  4.     <timestamp>1357776838</timestamp>
  5.     <open-checksum type="sha">79183262b5e9f945f912a41e23e1555c0f3a71af</open-checksum>
  6.   </data>
復(fù)制代碼
四行數(shù)據(jù),都很容易理解:
href: 該文件的路徑
checksum: 該文件的校驗(yàn)和,采用 sha 的類型校驗(yàn)和,我們都知道文件校驗(yàn)和有crc32,md5sum,sha1,sha2 等方式,這幾種類型校驗(yàn)和的差異可以查閱相關(guān)文檔,還是蠻有意思的,
之前在研究 ICEPATCH2 的時(shí)候,發(fā)現(xiàn) ice 也是用 sha1 值給文件打校驗(yàn)和的。
timestamp 修改時(shí)間戳
open-checksum 跟 checksum 類似吧,我沒有深究。

好了,repomd.xml 文件介紹完了,我們看看其它幾個(gè)文件都是干啥的:
作者: duanjigang    時(shí)間: 2013-01-03 11:48
本帖最后由 duanjigang 于 2013-01-03 12:09 編輯

primary.xml.[gz]

     this file stores the primary metadata information. This includes information such as:

    name, epoch, version, release, architecture
    file size, file location, description, summary, format, checksums header byte-ranges, etc.
    dependencies, provides, conflicts, obsoletes, suggests, recommends
    file lists for the package for CERTAIN files - specifically files matching: /etc*, *bin/*, /usr/lib/sendmail [1]


可以看到 primary.xml 主要存儲(chǔ)包的名字,epoch,version.release等信息。
我們來看下它的內(nèi)容:

  1. $ zcat primary.xml.gz
  2. <?xml version="1.0" encoding="UTF-8"?>
  3. <metadata xmlns="http://linux.duke.edu/metadata/common" xmlns:rpm="http://linux.duke.edu/metadata/rpm" packages="2">
  4. <package type="rpm">
  5.   <name>test-daddy</name>
  6.   <arch>i386</arch>
  7.   <version epoch="0" ver="1.1" rel="1"/>
  8.   <checksum type="sha" pkgid="YES">a9f4ad3086dcfcced210361bc72e4d418144cfcc</checksum>
  9.   <summary>GNU test-daddy</summary>
  10.   <description>The GNU wget program downloads files from the Internet using the command-line.</description>
  11.   <packager/>
  12.   <url/>
  13.   <time file="1357185424" build="1357185424"/>
  14.   <size package="4235" installed="9354" archive="4936"/>
  15.   <location href="test-daddy-1.1-1.i386.rpm"/>
  16.   <format>
  17.     <rpm:license>GPL</rpm:license>
  18.     <rpm:vendor/>
  19.     <rpm:group>Development/Tools</rpm:group>
  20.     <rpm:buildhost>yum.test.com</rpm:buildhost>
  21.     <rpm:sourcerpm>test-daddy-1.1-1.src.rpm</rpm:sourcerpm>
  22.     <rpm:header-range start="280" end="2127"/>
  23.     <rpm:provides>
  24.       <rpm:entry name="test-daddy" flags="EQ" epoch="0" ver="1.1" rel="1"/>
  25.     </rpm:provides>
  26.     <rpm:requires>
  27.       <rpm:entry name="rpmlib(PayloadFilesHavePrefix)" flags="LE" epoch="0" ver="4.0" rel="1" pre="1"/>
  28.       <rpm:entry name="/bin/sh" pre="1"/>
  29.       <rpm:entry name="libc.so.6"/>
  30.       <rpm:entry name="rtld(GNU_HASH)"/>
  31.       <rpm:entry name="baby-is-provided"/>
  32.       <rpm:entry name="libc.so.6(GLIBC_2.0)"/>
  33.       <rpm:entry name="rpmlib(CompressedFileNames)" flags="LE" epoch="0" ver="3.0.4" rel="1" pre="1"/>
  34.     </rpm:requires>
  35.     <file>/usr/bin/test_daddy</file>
  36.   </format>
  37. </package>
  38. <package type="rpm">
  39.   <name>test-girl</name>
  40.   <arch>i386</arch>
  41.   <version epoch="0" ver="1.1" rel="1"/>
  42.   <checksum type="sha" pkgid="YES">82828b38c988399f597cceb14d896de6d36cd1c8</checksum>
  43.   <summary>GNU test-girl</summary>
  44.   <description>The GNU wget program downloads files from the Internet using the command-line.</description>
  45.   <packager/>
  46.   <url/>
  47.   <time file="1357185262" build="1357185262"/>
  48.   <size package="4227" installed="9354" archive="4936"/>
  49.   <location href="test-girl-1.1-1.i386.rpm"/>
  50.   <format>
  51.     <rpm:license>GPL</rpm:license>
  52.     <rpm:vendor/>
  53.     <rpm:group>Development/Tools</rpm:group>
  54.     <rpm:buildhost>yum.test.com</rpm:buildhost>
  55.     <rpm:sourcerpm>test-girl-1.1-1.src.rpm</rpm:sourcerpm>
  56.     <rpm:header-range start="280" end="2119"/>
  57.     <rpm:provides>
  58.       <rpm:entry name="test-girl" flags="EQ" epoch="0" ver="1.1" rel="1"/>
  59.       <rpm:entry name="baby-is-provided"/>
  60.     </rpm:provides>
  61.     <rpm:requires>
  62.       <rpm:entry name="rpmlib(PayloadFilesHavePrefix)" flags="LE" epoch="0" ver="4.0" rel="1" pre="1"/>
  63.       <rpm:entry name="/bin/sh" pre="1"/>
  64.       <rpm:entry name="libc.so.6"/>
  65.       <rpm:entry name="rtld(GNU_HASH)"/>
  66.       <rpm:entry name="libc.so.6(GLIBC_2.0)"/>
  67.       <rpm:entry name="rpmlib(CompressedFileNames)" flags="LE" epoch="0" ver="3.0.4" rel="1" pre="1"/>
  68.     </rpm:requires>
  69.     <file>/usr/bin/test_girl</file>
  70.   </format>
  71. </package>
  72. </metadata>
復(fù)制代碼
不用多言,看到 xml 的內(nèi)容,就已經(jīng)明白了它存儲(chǔ)了 rpm 包的哪些信息。

其它三個(gè)文件
filelists.xml.[gz]
this file stores the complete file and directory listings for the packages. The package is identified by: name, epoch, version, release, architecture and package checksum id.
看下內(nèi)容:

  1. $ zcat filelists.xml.gz
  2. <?xml version="1.0" encoding="UTF-8"?>
  3. <filelists xmlns="http://linux.duke.edu/metadata/filelists" packages="2">
  4. <package pkgid="a9f4ad3086dcfcced210361bc72e4d418144cfcc" name="test-daddy" arch="i386">
  5.   <version epoch="0" ver="1.1" rel="1"/>
  6.   <file>/usr/bin/test_daddy</file>
  7. </package>
  8. <package pkgid="82828b38c988399f597cceb14d896de6d36cd1c8" name="test-girl" arch="i386">
  9.   <version epoch="0" ver="1.1" rel="1"/>
  10.   <file>/usr/bin/test_girl</file>
  11. </package>
  12. <package pkgid="6a6fbc7e58160ffa71b1f91912dc6eaf1cd6e0ae" name="wget" arch="i386">
  13.   <version epoch="0" ver="1.14" rel="1"/>
  14.   <file>/usr/bin/wget</file>
  15.   <file>/usr/etc/wgetrc</file>
  16.   <file>/usr/share/info/wget.info.gz</file>
  17.   <file>/usr/share/locale/be/LC_MESSAGES/wget.mo</file>
  18.   <file>/usr/share/locale/bg/LC_MESSAGES/wget.mo</file>
  19.   <file>/usr/share/locale/ca/LC_MESSAGES/wget.mo</file>
  20.   <file>/usr/share/locale/cs/LC_MESSAGES/wget.mo</file>
  21.   <file>/usr/share/locale/da/LC_MESSAGES/wget.mo</file>
  22.   <file>/usr/share/locale/de/LC_MESSAGES/wget.mo</file>
  23.   <file>/usr/share/locale/el/LC_MESSAGES/wget.mo</file>
  24.   <file>/usr/share/locale/en_GB/LC_MESSAGES/wget.mo</file>
  25.   <file>/usr/share/locale/eo/LC_MESSAGES/wget.mo</file>
  26.   <file>/usr/share/locale/es/LC_MESSAGES/wget.mo</file>
  27.   <file>/usr/share/locale/et/LC_MESSAGES/wget.mo</file>
  28.   <file>/usr/share/locale/eu/LC_MESSAGES/wget.mo</file>
  29.   <file>/usr/share/locale/fi/LC_MESSAGES/wget.mo</file>
  30.   <file>/usr/share/locale/fr/LC_MESSAGES/wget.mo</file>
  31.   <file>/usr/share/locale/ga/LC_MESSAGES/wget.mo</file>
  32.   <file>/usr/share/locale/gl/LC_MESSAGES/wget.mo</file>
  33.   <file>/usr/share/locale/he/LC_MESSAGES/wget.mo</file>
  34.   <file>/usr/share/locale/hr/LC_MESSAGES/wget.mo</file>
  35.   <file>/usr/share/locale/hu/LC_MESSAGES/wget.mo</file>
  36.   <file>/usr/share/locale/id/LC_MESSAGES/wget.mo</file>
  37.   <file>/usr/share/locale/it/LC_MESSAGES/wget.mo</file>
  38.   <file>/usr/share/locale/ja/LC_MESSAGES/wget.mo</file>
  39.   <file>/usr/share/locale/lt/LC_MESSAGES/wget.mo</file>
  40.   <file>/usr/share/locale/nb/LC_MESSAGES/wget.mo</file>
  41.   <file>/usr/share/locale/nl/LC_MESSAGES/wget.mo</file>
  42.   <file>/usr/share/locale/pl/LC_MESSAGES/wget.mo</file>
  43.   <file>/usr/share/locale/pt/LC_MESSAGES/wget.mo</file>
  44.   <file>/usr/share/locale/pt_BR/LC_MESSAGES/wget.mo</file>
  45.   <file>/usr/share/locale/ro/LC_MESSAGES/wget.mo</file>
  46.   <file>/usr/share/locale/ru/LC_MESSAGES/wget.mo</file>
  47.   <file>/usr/share/locale/sk/LC_MESSAGES/wget.mo</file>
  48.   <file>/usr/share/locale/sl/LC_MESSAGES/wget.mo</file>
  49.   <file>/usr/share/locale/sr/LC_MESSAGES/wget.mo</file>
  50.   <file>/usr/share/locale/sv/LC_MESSAGES/wget.mo</file>
  51.   <file>/usr/share/locale/tr/LC_MESSAGES/wget.mo</file>
  52.   <file>/usr/share/locale/uk/LC_MESSAGES/wget.mo</file>
  53.   <file>/usr/share/locale/vi/LC_MESSAGES/wget.mo</file>
  54.   <file>/usr/share/locale/zh_CN/LC_MESSAGES/wget.mo</file>
  55.   <file>/usr/share/locale/zh_TW/LC_MESSAGES/wget.mo</file>
  56.   <file>/usr/share/man/man1/wget.1.gz</file>
  57. </package>
  58. </filelists>
復(fù)制代碼
可以跟 rpm 中的實(shí)際文件列表進(jìn)行對(duì)比下:

  1. $ rpm -qpl ../test-daddy-1.1-1.i386.rpm
  2. /usr/bin/test_daddy
  3. $ rpm -qpl ../test-girl-1.1-1.i386.rpm
  4. /usr/bin/test_girl
  5. $ rpm -qpl ../wget-1.14-1.i386.rpm
  6. /usr/bin/wget
  7. /usr/etc/wgetrc
  8. /usr/share/info/wget.info.gz
  9. /usr/share/locale/be/LC_MESSAGES/wget.mo
  10. /usr/share/locale/bg/LC_MESSAGES/wget.mo
  11. /usr/share/locale/ca/LC_MESSAGES/wget.mo
  12. /usr/share/locale/cs/LC_MESSAGES/wget.mo
  13. /usr/share/locale/da/LC_MESSAGES/wget.mo
  14. /usr/share/locale/de/LC_MESSAGES/wget.mo
  15. /usr/share/locale/el/LC_MESSAGES/wget.mo
  16. /usr/share/locale/en_GB/LC_MESSAGES/wget.mo
  17. /usr/share/locale/eo/LC_MESSAGES/wget.mo
  18. /usr/share/locale/es/LC_MESSAGES/wget.mo
  19. /usr/share/locale/et/LC_MESSAGES/wget.mo
  20. /usr/share/locale/eu/LC_MESSAGES/wget.mo
  21. /usr/share/locale/fi/LC_MESSAGES/wget.mo
  22. /usr/share/locale/fr/LC_MESSAGES/wget.mo
  23. /usr/share/locale/ga/LC_MESSAGES/wget.mo
  24. /usr/share/locale/gl/LC_MESSAGES/wget.mo
  25. /usr/share/locale/he/LC_MESSAGES/wget.mo
  26. /usr/share/locale/hr/LC_MESSAGES/wget.mo
  27. /usr/share/locale/hu/LC_MESSAGES/wget.mo
  28. /usr/share/locale/id/LC_MESSAGES/wget.mo
  29. /usr/share/locale/it/LC_MESSAGES/wget.mo
  30. /usr/share/locale/ja/LC_MESSAGES/wget.mo
  31. /usr/share/locale/lt/LC_MESSAGES/wget.mo
  32. /usr/share/locale/nb/LC_MESSAGES/wget.mo
  33. /usr/share/locale/nl/LC_MESSAGES/wget.mo
  34. /usr/share/locale/pl/LC_MESSAGES/wget.mo
  35. /usr/share/locale/pt/LC_MESSAGES/wget.mo
  36. /usr/share/locale/pt_BR/LC_MESSAGES/wget.mo
  37. /usr/share/locale/ro/LC_MESSAGES/wget.mo
  38. /usr/share/locale/ru/LC_MESSAGES/wget.mo
  39. /usr/share/locale/sk/LC_MESSAGES/wget.mo
  40. /usr/share/locale/sl/LC_MESSAGES/wget.mo
  41. /usr/share/locale/sr/LC_MESSAGES/wget.mo
  42. /usr/share/locale/sv/LC_MESSAGES/wget.mo
  43. /usr/share/locale/tr/LC_MESSAGES/wget.mo
  44. /usr/share/locale/uk/LC_MESSAGES/wget.mo
  45. /usr/share/locale/vi/LC_MESSAGES/wget.mo
  46. /usr/share/locale/zh_CN/LC_MESSAGES/wget.mo
  47. /usr/share/locale/zh_TW/LC_MESSAGES/wget.mo
  48. /usr/share/man/man1/wget.1.gz
復(fù)制代碼
每個(gè) <file> 就是一個(gè)文件。

other.xml.[gz]

this file currently only stores the changelog data from packages. However, this file could be used for any other additional metadata that could be useful for clients.
看下內(nèi)容:

  1. $ zcat other.xml.gz
  2. <?xml version="1.0" encoding="UTF-8"?>
  3. <otherdata xmlns="http://linux.duke.edu/metadata/other" packages="4">
  4. <package pkgid="6a6fbc7e58160ffa71b1f91912dc6eaf1cd6e0ae" name="wget" arch="i386">
  5.   <version epoch="0" ver="1.14" rel="1"/>
  6. </package>
  7. <package pkgid="a9f4ad3086dcfcced210361bc72e4d418144cfcc" name="test-daddy" arch="i386">
  8.   <version epoch="0" ver="1.1" rel="1"/>
  9. </package>
  10. <package pkgid="82828b38c988399f597cceb14d896de6d36cd1c8" name="test-girl" arch="i386">
  11.   <version epoch="0" ver="1.1" rel="1"/>
  12. </package>
  13. <package pkgid="6ce87802e577736bb8b481c157cb9fb8822f8b88" name="wget-debuginfo" arch="i386">
  14.   <version epoch="0" ver="1.14" rel="1"/>
  15. </package>

  16. </otherdata>
復(fù)制代碼

作者: duanjigang    時(shí)間: 2013-01-03 12:25
本帖最后由 duanjigang 于 2013-01-03 13:04 編輯

yum 本地 cache

之所以要把yum 的本地 cache 拿出來單獨(dú)說下,是因?yàn)檫@個(gè)要素不管在 yum 的執(zhí)行流程中,還是在 yum 的日常問題中都很重要。

首先看下本機(jī)的 repo 配置:

  1. # ls /etc/yum.repos.d/*
  2. /etc/yum.repos.d/newtest.repo  /etc/yum.repos.d/test.repo
  3. [root@yum yum]# cat /etc/yum.repos.d/*.repo
  4. [newtest]
  5. name=just a test reposity
  6. baseurl=http://yum.test.com:81/yum
  7. enabled=1
  8. gpgcheck=0
  9. gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release

  10. [test]
  11. name=just a test reposity
  12. baseurl=http://yum.test.com:81/yum
  13. enabled=1
  14. gpgcheck=0
  15. gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release
復(fù)制代碼
我們能夠看到配置了兩個(gè) repo,其中一個(gè)名字為test, 另外一個(gè)為 newtest.

然后再看文件
/etc/yum.conf
中的配置

  1. cachedir=/var/cache/yum
復(fù)制代碼
設(shè)備本地的cache 目錄為
/var/cache/yum 目錄,首先我們清空下該目錄:

  1. # rm -fr /var/cache/yum/*
復(fù)制代碼
然后執(zhí)行命令

  1. #yum list
復(fù)制代碼
看下在 cache 目錄下能生成什么咚咚?

  1. # tree /var/cache/yum/
  2. /var/cache/yum/
  3. |-- newtest
  4. |   |-- cachecookie
  5. |   |-- headers
  6. |   |-- packages
  7. |   |-- primary.xml.gz
  8. |   |-- primary.xml.gz.sqlite
  9. |   `-- repomd.xml
  10. `-- test
  11.     |-- cachecookie
  12.     |-- headers
  13.     |-- packages
  14.     |-- primary.xml.gz
  15.     |-- primary.xml.gz.sqlite
  16.     `-- repomd.xml
復(fù)制代碼
能夠看到,客戶端的兩個(gè)repo 都對(duì)應(yīng)生成了 cache 目錄,每個(gè)cache 的目錄中都有文件 repomd.xml 和 primary.xml 文件或者其 Sqlite 文件。
為了驗(yàn)證下客戶端是否把服務(wù)器上的索引文件下載下來了,我們進(jìn)行對(duì)比:
在客戶端執(zhí)行:

  1. # md5sum repomd.xml
  2. 916b78131cab447e60b17bf01a41240a  repomd.xml
復(fù)制代碼
在服務(wù)器上執(zhí)行:
# md5sum /usr/local/cme/web/yum/repodata/repomd.xml
916b78131cab447e60b17bf01a41240a  /usr/local/cme/web/yum/repodata/repomd.xml
[/code]
可以看到兩者是一致的。驗(yàn)證了 yum 客戶端 cache 服務(wù)器索引到本地的實(shí)事。
另外還有兩個(gè)目錄 headers 和 packages, 可以參考源碼進(jìn)行功能分析。
在此處貌似要補(bǔ)充上 yum 是怎么利用本地 cache 進(jìn)行工作的,這貌似又成了 yum 的源碼分析了,目前這塊偶還未有閱讀到,后面有空再補(bǔ)充吧。

在上一節(jié)中我們只是就 primary.xml 文件進(jìn)行了內(nèi)容分析,這里,在客戶端 cache 中,我們花點(diǎn)時(shí)間看下 sqlite 文件,因?yàn)?yum 中對(duì) rpm 包的信息存儲(chǔ)數(shù)據(jù)庫時(shí)采用的
是文件數(shù)據(jù)庫 sqlite 存儲(chǔ)的。因此我們單獨(dú)拎出來說下.

yum 索引中的 sqlite 文件

以客戶端的 primary.xml.gz.sqlite 為例,用 sqlite3 直接打開 sqlite 文件進(jìn)行查看:

  1. # sqlite3 primary.xml.gz.sqlite
  2. sqlite> .table  
  3. conflicts  db_info    files      obsoletes  packages   provides   requires
  4. sqlite> .schema packages
  5. CREATE TABLE packages (  pkgKey INTEGER PRIMARY KEY,  pkgId TEXT,  name TEXT,  arch TEXT,  version TEXT,  epoch TEXT,  release TEXT,  summary TEXT,  description TEXT,  url TEXT,  time_file TEXT,  time_build TEXT,  rpm_license TEXT,  rpm_vendor TEXT,  rpm_group TEXT,  rpm_buildhost TEXT,  rpm_sourcerpm TEXT,  rpm_header_start TEXT,  rpm_header_end TEXT,  rpm_packager TEXT,  size_package TEXT,  size_installed TEXT,  size_archive TEXT,  location_href TEXT,  location_base TEXT,  checksum_type TEXT,  checksum_value TEXT);
  6. CREATE INDEX packageId ON packages (pkgId);
  7. CREATE INDEX packagename ON packages (name);
  8. CREATE TRIGGER removals AFTER DELETE ON packages  BEGIN    DELETE FROM files WHERE pkgKey = old.pkgKey;    DELETE FROM requires WHERE pkgKey = old.pkgKey;    DELETE FROM provides WHERE pkgKey = old.pkgKey;    DELETE FROM conflicts WHERE pkgKey = old.pkgKey;    DELETE FROM obsoletes WHERE pkgKey = old.pkgKey;  END;
復(fù)制代碼
通過 sqlite 的命令能看到 sqlite 中的所有表,每個(gè)文件是一個(gè)庫,這個(gè)庫中的所有 table 包含的信息,與 我們前面看到的 primary.xml 中的信息是一致的。
只不過采用了不同的存儲(chǔ)方式。
看下 package 表 中的數(shù)據(jù):

sqlite> select * from packages;
1|6a6fbc7e58160ffa71b1f91912dc6eaf1cd6e0ae|wget|i386|1.14|0|1|GNU wget|The GNU wget program downloads files from the Internet using the command-line.||1357187570|1357185960|GPL||Development/Tools|yum.test.com|wget-1.14-1.src.rpm|280|9282||809949|2032999|2039664|wget-1.14-1.i386.rpm||sha|6a6fbc7e58160ffa71b1f91912dc6eaf1cd6e0ae
2|a9f4ad3086dcfcced210361bc72e4d418144cfcc|test-daddy|i386|1.1|0|1|GNU test-daddy|The GNU wget program downloads files from the Internet using the command-line.||1357187570|1357185424|GPL||Development/Tools|yum.test.com|test-daddy-1.1-1.src.rpm|280|2127||4235|9354|4936|test-daddy-1.1-1.i386.rpm||sha|a9f4ad3086dcfcced210361bc72e4d418144cfcc
3|82828b38c988399f597cceb14d896de6d36cd1c8|test-girl|i386|1.1|0|1|GNU test-girl|The GNU wget program downloads files from the Internet using the command-line.||1357187570|1357185262|GPL||Development/Tools|yum.test.com|test-girl-1.1-1.src.rpm|280|2119||4227|9354|4936|test-girl-1.1-1.i386.rpm||sha|82828b38c988399f597cceb14d896de6d36cd1c8
4|6ce87802e577736bb8b481c157cb9fb8822f8b88|wget-debuginfo|i386|1.14|0|1|Debug information for package wget|This package provides debug information for package wget.
Debug information is useful when developing applications that use this
package or when debugging this package.||1357187570|1357185960|GPL||Development/Debug|yum.test.com|wget-1.14-1.src.rpm|280|2043||19714|45564|45836|wget-debuginfo-1.14-1.i386.rpm||sha|6ce87802e577736bb8b481c157cb9fb8822f8b88
5|f377c921e23ba10507de267b345d03d1f32f02a4|test-baby|i386|1.1|0|1|GNU test-baby|The GNU wget program downloads files from the Internet using the command-line.||1356570667|1356570667|GPL||Development/Tools|localhost.localdomain|test-baby-1.1-1.src.rpm|280|2290||4463|9395|5108|test-baby-1.1-1.i386.rpm||sha|f377c921e23ba10507de267b345d03d1f32f02a4
sqlite>


呵呵,看到的數(shù)據(jù)和 xml 文件中的展示的數(shù)據(jù)是一樣的。



作者: duanjigang    時(shí)間: 2013-01-03 13:05
本帖最后由 duanjigang 于 2013-01-03 13:19 編輯

yum clean 分析
提到 yum 的客戶端 cache,又不得不對(duì)yum 中一個(gè)常用的針對(duì)cache 進(jìn)行操作的命令進(jìn)行分析,那就是: yum clean

看下 man 手冊(cè):

  1. clean  Is  used  to  clean  up  various things which accumulate in the yum cache directory over time.
  2.               More complete details can be found in the Clean Options section below.
復(fù)制代碼
看下命令行提示:

  1. # yum clean
  2. Error: clean requires an option: headers, packages, metadata, dbcache, plugins, all
復(fù)制代碼
看到它支持 clean 的對(duì)象有 headers,packages,metadata,dbcache 和 plugins 這幾項(xiàng)。
之前為了解決 yum 插件的clean 問題,簡單分析了下 yum clean 的源碼,附上分析日志如下。

yum clean的源碼,在/usr/share/yum-cli/cli.py 中 882行

  1. def cleanCli(self, userlist):
復(fù)制代碼
函數(shù)中.
支持的參數(shù)有:

  1. yum clean:
  2. header
  3. packages
  4. metadata
  5. dbcache
  6. expire-cache
  7. plugins
復(fù)制代碼
針對(duì)不同的輸入,會(huì)調(diào)用

  1. self.cleanPackages()
  2. self.cleanHeaders()
  3. self.cleanMetadata()
  4. self.cleanSqlite()
復(fù)制代碼
這幾個(gè)函數(shù),刪除不同的項(xiàng)

然后我們?cè)谖募?div id="a9ur7n9vt" class="blockcode">

  1. /usr/lib/python2.4/site-packages/yum/__init__.py
復(fù)制代碼中能夠看到上面幾個(gè)函數(shù)的實(shí)現(xiàn):

  1. def cleanHeaders(self):
  2.         exts = ['hdr']
  3.         return self._cleanFiles(exts, 'hdrdir', 'header')

  4.     def cleanPackages(self):
  5.         exts = ['rpm']
  6.         return self._cleanFiles(exts, 'pkgdir', 'package')
復(fù)制代碼
等等。
這幾個(gè)clean函數(shù)都是通過封裝 __cleanFiles來實(shí)現(xiàn)的,看看這個(gè)函數(shù):

  1. def _cleanFiles(self, exts, pathattr, filetype):
  2.         filelist = []
  3.         removed = 0
  4.         for ext in exts:
  5.             for repo in self.repos.listEnabled():
  6.                 repo.dirSetup()
  7.                 path = getattr(repo, pathattr)
  8.                 if os.path.exists(path) and os.path.isdir(path):
  9.                     filelist = misc.getFileList(path, ext, filelist)

  10.         for item in filelist:
  11.             try:
  12.                 os.unlink(item)
  13.             except OSError, e:
  14.                 self.logger.critical(_('Cannot remove %s file %s'), filetype, item)
  15.                 continue
  16.             else:
  17.                 self.verbose_logger.log(logginglevels.DEBUG_4,
  18.                     _('%s file %s removed'), filetype, item)
  19.                 removed+=1
  20.         msg = _('%d %s files removed') % (removed, filetype)
  21.         return 0, [msg]
復(fù)制代碼
其實(shí)就是去對(duì)應(yīng)的目錄下刪除文件而已。

可以如下測(cè)試:
修改代碼段:

  1. for item in filelist:
  2.             try:
  3.                 print "====:", item
  4.                 os.unlink(item)
復(fù)制代碼
添加打印,保存
然后先 yum list 生成cache
可以 yum list 看下生成的文件

  1. tree
  2. .
  3. |-- ops.5.i386
  4. |   |-- cachecookie
  5. |   |-- packages
  6. |   |-- primary.sqlite
  7. |   `-- repomd.xml
  8. |-- ops.5.noarch
  9. |   |-- cachecookie
  10. |   |-- packages
  11. |   |-- primary.sqlite
  12. |   `-- repomd.xml
  13. `-- rhel.5.i386
  14.     |-- cachecookie
  15.     |-- packages
  16.     |-- primary.sqlite
  17.     `-- repomd.xml
  18. 然后 sudo yum clean all
  19. 輸出如下:
  20. ====: //var/cache/yum/ops.5.noarch/repomd.xml
  21. ====: //var/cache/yum/ops.5.i386/repomd.xml
  22. ====: //var/cache/yum/rhel.5.i386/repomd.xml
  23. ====: //var/cache/yum/ops.5.noarch/cachecookie
  24. ====: //var/cache/yum/ops.5.i386/cachecookie
  25. ====: //var/cache/yum/rhel.5.i386/cachecookie
  26. ====: //var/cache/yum/ops.5.noarch/primary.sqlite
  27. ====: //var/cache/yum/ops.5.i386/primary.sqlite
  28. ====: //var/cache/yum/rhel.5.i386/primary.sqlite
復(fù)制代碼
再去/var/cache/yum下tree下,看不到y(tǒng)um list 后的文件了

yum clean 是這樣實(shí)現(xiàn)的,我想,對(duì)于 install, update 和 list 等操作,如果你要分析源碼的話,可以借鑒 clean 的分析過程。
作者: duanjigang    時(shí)間: 2013-01-04 06:25
本帖最后由 duanjigang 于 2013-01-04 07:31 編輯

杭州好大雪~~繼續(xù)總結(jié)
yum 的 配置文件

yum 的 配置分為三類:

1 全局配置     /etc/yum.conf   -- 配置整個(gè) yum 服務(wù)的一些參數(shù)和options
2 repo 配置   /etc/yum.repos.d/*.repo 配置 yum 訪問時(shí)的repo源和路徑
3 插件配置   /etc/yum/pluginconf.d/*.conf 配置 yum 擴(kuò)展插件


下來依次解釋其內(nèi)容的含義:

/etc/yum.conf
先看下內(nèi)容"

  1. $ cat /etc/yum.conf
  2. [main]
  3. cachedir=/var/cache/yum
  4. keepcache=0
  5. debuglevel=2
  6. logfile=/var/log/yum.log
  7. distroverpkg=redhat-release
  8. tolerant=1
  9. exactarch=1
  10. obsoletes=1
  11. gpgcheck=1
  12. plugins=1
  13. metadata_expire=0

  14. # Default.
  15. # installonly_limit = 3

  16. # PUT YOUR REPOS HERE OR IN separate files named file.repo
  17. # in /etc/yum.repos.d
復(fù)制代碼
cachedir: 前面說過,本地存放cache 的目錄。
keepcache: 在成功安裝rpm后是否保留rpm和header文件,在前面介紹 cachdir 的例子中,我們看到cachedir 中的 header 和 packages 目錄是空的,現(xiàn)在打開keepcache

  1. keepcache=1
復(fù)制代碼
然后重新安裝 test-girl 和 test-daddy 包,之后再看下 cachedir 的內(nèi)容:

  1. # tree /var/cache/yum/
  2. /var/cache/yum/
  3. |-- newtest
  4. |   |-- cachecookie
  5. |   |-- headers
  6. |   |-- packages
  7. |   |-- primary.xml.gz
  8. |   |-- primary.xml.gz.sqlite
  9. |   `-- repomd.xml
  10. `-- test
  11.     |-- cachecookie
  12.     |-- headers
  13.     |   |-- test-daddy-1.1-1.i386.hdr
  14.     |   `-- test-girl-1.1-1.i386.hdr
  15.     |-- packages
  16.     |   |-- test-daddy-1.1-1.i386.rpm
  17.     |   `-- test-girl-1.1-1.i386.rpm
  18.     |-- primary.xml.gz
  19.     |-- primary.xml.gz.sqlite
  20.     `-- repomd.xml
復(fù)制代碼
看到了本地cache 的 hdr 和 rpm 文件了吧。

debuglevel: debug 信息輸出等級(jí),范圍為0-10,默認(rèn)是2
persistdir:  yum 持久化存儲(chǔ)數(shù)據(jù)的存儲(chǔ)目錄,默認(rèn)為 /var/lib/yum
reposdir: 我們都知道,yum的默認(rèn)repo 配置目錄是 /etc/yum.repos.d, 這個(gè)目錄可以通過配置文件中的行

  1. reposdir=dir1,dir2
復(fù)制代碼
來修改,這樣,yum 會(huì)加載這多個(gè)目錄下的*.repo 文件,在加載完這些之后,還要和 /etc/yum.conf 中的 repo 配置項(xiàng)合并,我們能夠看到 /etc/yum.conf 中最后一行有提示:
# PUT YOUR REPOS HERE OR IN separate files named file.repo
# in /etc/yum.repos.d

也就是在告訴使用者:你直接把 *.repo 中的內(nèi)容寫在這里也好。這樣,yum.conf 中的repo 最終會(huì)和 reposdir 中配置的 repo 合并。
從個(gè)人喜好角度講:我更喜歡把*.repo分開,不同的應(yīng)用不同的repo,也方便各自修改,更新,如果都合并到一個(gè)文件 yum.conf 中,更新修改都是這個(gè)文件,涉及到多個(gè)程序修改repo時(shí),還得進(jìn)行互斥操作,比較麻煩。另外,看起來格式也比較亂。

errorlevel:和 Debuglevel 一樣,只不過是錯(cuò)誤信息輸出的配置等級(jí)。
logfile: yum 安裝的日志,
pkgpolicy:包安裝的策略,有兩個(gè)選項(xiàng),newest和last,如果你設(shè)置了多個(gè)repo,并且出現(xiàn)同一個(gè)軟件在不同的repos中同時(shí)存在的情況,yum 應(yīng)該安裝哪一個(gè),如果配置是 newest,則yum會(huì)安裝最新的那個(gè)版本。如果配置是 last,yum 則會(huì)將服務(wù)器 id 以字母表排序,并選擇最后的那個(gè)服務(wù)器上的軟件安裝。一般都是選 newest。
distroverpkg:指定一個(gè)軟件包,yum會(huì)根據(jù)這個(gè)包判斷你的發(fā)行版本,默認(rèn)是redhat-release,也可以是安裝的任何針對(duì)自己發(fā)行版的rpm包。我們?cè)?*.repo中經(jīng)常會(huì)這樣配置:

  1. baseurl=http://xxxx/redhat/$releasever/$basearch/
復(fù)制代碼
其中 $basearch 的值會(huì)為 i386 或者 x86_64,而 $releasever 的取值就是以 distroverpkg 的取值為名稱的rpm的版本號(hào),基本上取值都是 redhat-release
如果你看到你的系統(tǒng)上 redhat-release 的包為:

  1. $ rpm -qa redhat-release
  2. redhat-release-5Server-5.7.0.3
復(fù)制代碼
那么就能斷定 *.repo 中的  $releasever 為5.7了。很多人容易把這個(gè)值理解為獲取的是 /etc/redhat-release 這個(gè)文件中的內(nèi)容,其實(shí)不是,我之前的腳本也是獲取這個(gè)值的。這個(gè)設(shè)計(jì),貌似是個(gè)比較讓人詬病的點(diǎn),碰巧在水木社區(qū)看到一篇帖子,就是惡心這個(gè)設(shè)計(jì)的,轉(zhuǎn)過來跟大家分享下:

http://www.newsmth.net/nForum/#!article/LinuxApp/738396
發(fā)信人: JulyClyde (torred), 信區(qū): LinuxApp
標(biāo)  題: yum的$releasever真是太反動(dòng)了
發(fā)信站: 水木社區(qū) (Fri Oct  9 16:54:21 2009), 站內(nèi)
  
原創(chuàng);網(wǎng)址 http://www.julyclyde.org/?p=275
yum的$releasever真是太反動(dòng)了
  
來看這篇文章的人,大都應(yīng)該同意《Unix編程藝術(shù)》中提到的那些觀點(diǎn)吧。今天就給大家看一個(gè)反例:yum 的 $releasever 變量
  
在 /etc/yum.repos.d/ 目錄下的軟件庫定義文件中,常常會(huì)在 baseurl 的路徑中提到 $releasever 這個(gè)變量,表示當(dāng)前發(fā)行版的大版本號(hào),但大家知道這個(gè)變量是在哪設(shè)置的嗎?我 grep 了整個(gè) etc 目錄都沒找到,還是看了 yum.conf 才知道的,是在 yum.conf 文件里 distroverpkg 選項(xiàng)定義的。但這個(gè)選項(xiàng)就很有問題:
  
    1. distroverpkg 和 releasever 名字不同,且看不出什么聯(lián)系
    2. distroverpkg 的值,并不是明文,而是“redhat-release”。不知道大家看到這個(gè)會(huì)有什么想法,反正我是首先想到了 /etc/redhat-release 文件,但我錯(cuò)了。實(shí)際上指的是 redhat-release 這個(gè)RPM包。所謂“distroverpkg=redhat-release”的意思,其實(shí)是將 $releasever 設(shè)置為 redhat-release 這個(gè)RPM包的版本號(hào)
  
夠變態(tài)吧?別人都是直接賦值,或者 include 一個(gè)各種變量定義的文件進(jìn)來,而yum竟然用某個(gè)包的屬性作為值,違反了“everything is file”的原則。爛!
  
有人為心愛的 RedHat 分辯說是為了升級(jí) redhat-release 包之后可以自動(dòng)升級(jí)整個(gè)系統(tǒng),但事實(shí)證明 RedHat 的選擇一向都是很傻的。為什么不在軟件庫定義文件中 include 一個(gè)表示版本號(hào)的頭文件,每次大升級(jí)的時(shí)候更改這個(gè)文件呢?
  
再舉個(gè)例子:
  
Debian系里面,內(nèi)核包的版本維護(hù)是利用一個(gè)虛擬的 linux-image 包,依賴于某個(gè)風(fēng)格的比如 linux-image-generic 包,而該包又依賴于 linux-image-2.6.28-15-generic,后者就是真正的內(nèi)核包,其版本號(hào)直接寫在包名里。系統(tǒng)升級(jí)的時(shí)候,由于 linux-image 和 linux-image-generic 的依賴關(guān)系變動(dòng),會(huì)依賴于新的 linux-image-2.6.xx-yy-generic 包,自然會(huì)裝上。
  
反觀 RedHat 的做法:各個(gè)內(nèi)核包,只有若干個(gè) kernel-<flavor> 的包名,版本號(hào)作為 RPM 的屬性來實(shí)現(xiàn),但是內(nèi)核這么重大的包又不能輕易用新的代替舊的,于是再給 yum 新增一個(gè) instalonly 插件(注意不是install,而是少一個(gè)l字母)來抑制新 kernel 代替舊 kernel 的動(dòng)作。



exactarch:有兩個(gè)選項(xiàng)1和0,代表是否只升級(jí)和你安裝軟件包c(diǎn)pu體系一致的包,如果設(shè)為1,則如你安裝了一個(gè)i386的rpm,則yum不會(huì)用1686的包來升級(jí)。
retries: 網(wǎng)絡(luò)連接發(fā)生錯(cuò)誤后的重試次數(shù),如果設(shè)為0,則會(huì)無限重試。
tolerent: 也有1和0兩個(gè)選項(xiàng),表示yum是否容忍命令行發(fā)生與軟件包有關(guān)的錯(cuò)誤,比如你要安裝1,2,3三個(gè)包,而其中3此前已經(jīng)安裝了,如果你設(shè)為1,則yum不會(huì)出現(xiàn)錯(cuò)誤信息。默認(rèn)是0。
exclude: 排除某些軟件在升級(jí)名單之外,可以用通配符,列表中各個(gè)項(xiàng)目要用空格隔開。
gpgchkeck: 有1和0兩個(gè)選擇,分別代表是否是否進(jìn)行g(shù)pg校驗(yàn).
alwaysprompt: 安裝時(shí)是否提示,設(shè)置為1就會(huì)提示,需要你在 yum install 時(shí)輸入?yún)?shù) -y,比如

  1. yum install xxoo -y
復(fù)制代碼
如果設(shè)置為0,就不需要附件 -y 輸入了。
obsoletes: 默認(rèn)為1,是否用新的包替換舊的包,比如你在 制作 xxoo 包時(shí),spec 中已經(jīng)標(biāo)明會(huì) obsoletes  掉 ooxx包,別人如果直接
yum update/install ooxx
就會(huì)提示安裝 xxoo包,這個(gè)對(duì)于改名的軟件包非常有用。
timeout : 在http連接時(shí),等待超時(shí)的秒數(shù),如果你的網(wǎng)絡(luò)狀況不好,可以設(shè)置大點(diǎn),默認(rèn)為30,標(biāo)識(shí)超時(shí)為30秒。
另外還有一些比較實(shí)用的配置,比如限制安裝時(shí)帶寬使用的選項(xiàng): throttle  和 bandwith,這個(gè)問題思考好幾次了,終于找到這個(gè)配置了。
想要了解更多配置,可以去yum.conf 的文檔頁查閱:
http://linux.die.net/man/5/yum.conf
我們這里只列舉可一些常見的配置。
作者: duanjigang    時(shí)間: 2013-01-04 14:35
本帖最后由 duanjigang 于 2013-01-04 15:20 編輯

repo配置文件 /etc/yum.repos.d/*.repo

這個(gè)目錄地下的文件是使用 yum 最長用到的配置文件。
我們看一個(gè)例子文件的內(nèi)容:

  1. #cat RHEL.repo
  2. [redhat.$releasever.base.$basearch]
  3. name=redhat
  4. baseurl=http://yum.test.com/redhat/$releasever/iso/$basearch/
  5. gpgcheck=0

  6. [redhat.$releasever.updates.$basearch]
  7. name=redhat updates
  8. baseurl=http://yum.test.com/redhat/$releasever/updates/$basearch/
  9. gpgcheck=0
復(fù)制代碼
可以看到,一個(gè)文件是由一個(gè)或者若干個(gè) reposity 組成的,每個(gè) reposity 保持了傳統(tǒng)的 ini 文件的定義格式。
每個(gè)reposity 至少包含以下信息:

  1. [repositoryid]
  2. name=Some name for this repository
  3. baseurl=url://path/to/repository/
復(fù)制代碼
reposityid 必須是一個(gè)唯一的單詞,也就是說是一個(gè)單詞,不能有空格隔開。
name:對(duì)這個(gè)repo的描述
baseurl 是訪問時(shí)的http地址模版,之所以叫模版,因?yàn)榻M成這個(gè) url 可以是一個(gè)實(shí)際的地址,也可以是變量組成的一個(gè)URL。
這里要注意一點(diǎn),baseurl 的域名都容易理解,是 yum 服務(wù)器的域名,然后后面的目錄路徑寫到什么地步呢?看下文檔原文:
baseurl Must be a URL to the directory where the yum repository's 'repodata' directory lives. Can be an http://, ftp:// or file:// URL
對(duì)了,baseurl 就是要寫到包含索引目錄(repodata)那一層目錄為止,這樣yum 才能根據(jù)既定的協(xié)議去這個(gè)路徑下找 repodata 目錄,找對(duì)應(yīng)的 repomd.xml 文件,否則會(huì)報(bào)錯(cuò)。
可以采用 http/ftp/file 協(xié)議進(jìn)行訪問。

也可以在一個(gè)baseurl 表達(dá)式中指定多個(gè)url,比如:

  1. [repositoryid]
  2. name=Some name for this repository
  3. baseurl=url://server1/path/to/repository/
  4. url://server2/path/to/repository/
  5. url://server3/path/to/repository/
復(fù)制代碼
如果有http認(rèn)證的話,可以寫上用戶名和密碼:

  1. baseurl=http://user:passwd@example.com/
復(fù)制代碼
mirrorlist  指向一個(gè)文件的 url 地址,這個(gè)文件中可以寫多個(gè) baseurl 來給yum 用,組成了一個(gè)mirror list.
enabled  1 或者 0,表示是否啟用。
gpgcheck 1 或者 0,表示對(duì)于從這個(gè)源下載的包是否啟用 gpg signature 校驗(yàn)。
gpgkey  gpgkey 的 URL 地址。

其它的選項(xiàng),可以參考文檔原文,我在此大概貼下:

gpgcakey A URL pointing to the ASCII-armored CA key file for the repository. This is a normal gpg public key - but this key will be used to validate detached signatures of all other keys. The idea is you are asked to confirm import for this key. After that any other gpg key needed for package or repository verification, if it has a detached signature which matches this key will be automatically imported without user confirmation.

exclude Same as the [main] exclude option but only for this repository. Substitution variables, described below, are honored here.

includepkgs Inverse of exclude. This is a list of packages you want to use from a repository. If this option lists only one package then that is all yum will ever see from the repository. Defaults to an empty list. Substitution variables, described below, are honored here.

enablegroups Either '0' or '1'. Determines whether yum will allow the use of package groups for this repository. Default is '1' (package groups are allowed).

failovermethod Either 'roundrobin' or 'priority'.

'roundrobin' randomly selects a URL out of the list of URLs to start with and proceeds through each of them as it encounters a failure contacting the host.

'priority' starts from the first baseurl listed and reads through them sequentially.

failovermethod defaults to 'roundrobin' if not specified.

keepalive Either '1' or '0'. This tells yum whether or not HTTP/1.1 keepalive should be used with this repository. See the global option in the [main] section above for more information.

timeout Overrides the timeout option from the [main] section for this repository.

http_caching Overrides the http_caching option from the [main] section for this repository.

retries Overrides the retries option from the [main] section for this repository.

throttle Overrides the throttle option from the [main] section for this repository.

bandwidth Overrides the bandwidth option from the [main] section for this repository.

sslcacert Overrides the sslcacert option from the [main] section for this repository.

sslverify Overrides the sslverify option from the [main] section for this repository.

sslclientcert Overrides the sslclientcert option from the [main] section for this repository.

sslclientkey Overrides the sslclientkey option from the [main] section for this repository.

metadata_expire Overrides the metadata_expire option from the [main] section for this repository.

mirrorlist_expire Overrides the mirrorlist_expire option from the [main] section for this repository.

proxy URL to the proxy server for this repository. Set to '_none_' to disable the global proxy setting for this repository. If this is unset it inherits it from the global setting

proxy_username username to use for proxy. If this is unset it inherits it from the global setting

proxy_password password for this proxy. If this is unset it inherits it from the global setting

username username to use for basic authentication to a repo or really any url. If this is unset it inherits it from the global setting

password password to use with the username for basic authentication. If this is unset it inherits it from the global setting

cost relative cost of accessing this repository. Useful for weighing one repo's packages as greater/less than any other. defaults to 1000

skip_if_unavailable If set to True yum will continue running if this repository cannot be contacted for any reason. This should be set carefully as all repos are consulted for any given command. Defaults to False



作者: duanjigang    時(shí)間: 2013-01-04 15:21
本帖最后由 duanjigang 于 2013-01-04 15:56 編輯

reposity 訪問的優(yōu)先級(jí)

有時(shí)候,我們會(huì)遇到同一個(gè)包在多個(gè) repo 中存在的情況。大多數(shù)情況都是,同一個(gè)包的不同版本分布在多個(gè)repo中,這時(shí)如果你采用

  1. yum install pkgname
復(fù)制代碼
的方式去安裝的話,因?yàn)?reposity 的默認(rèn)配置中 pkgpolicy 的機(jī)制為 newest, 因此,這樣會(huì)安裝最新版的包,大多數(shù)時(shí)候,問題就是這么產(chǎn)生的,好多人往往不明確自己需要軟件的版本,一個(gè) yum install 就給安裝到了最新版,最后才發(fā)現(xiàn)不是想要的版本,因此,建議安裝時(shí)最好能明確版本,這樣,即使同一個(gè)包在不同 repo 中,也會(huì)找對(duì)應(yīng)的版本去安裝,不至于出錯(cuò)。

另外一種情況是可能同版本的包也位于不同的repo中,按理說這種蛋疼的做法是不允許的,但是有時(shí)候我們還是希望關(guān)注下到底會(huì)安裝哪個(gè) repo 中的包,yum 為此提供了兩種機(jī)制:
cost 和 priorities 插件,其實(shí)這兩者的最終目的都是設(shè)置不同源的訪問優(yōu)先級(jí)。

我們?cè)诖酥徽f下 cost 的用法,priorities 插件留待后面介紹。

cost 的用法也很簡單,就是配置一個(gè) cost = xxx, xxx 為權(quán)值,越小優(yōu)先級(jí)越高,默認(rèn)值是 1000,因此我們配置為1000以內(nèi)的都會(huì)比不配置的優(yōu)先級(jí)高。
看一個(gè)例子:
首先看下 yum 服務(wù)器上的配置,是一個(gè)典型的不規(guī)范yum源:

  1. ls *
  2. repo1:
  3. cmeguard-1.1.2-20.i386.rpm  repodata  test-cmeadmin-1.1.1-21.i386.rpm

  4. repo2:
  5. cmeguard-1.1.2-20.i386.rpm  repodata  test-cmeadmin-1.1.1-21.i386.rpm

  6. repo3:
  7. cmeguard-1.1.2-20.i386.rpm  repodata  test-cmeadmin-1.1.1-21.i386.rpm
復(fù)制代碼
有三個(gè)repo,其中都放置了相同的rpm包,而且同版本。

然后客戶端配置了三個(gè)repo文件:

  1. # ls /etc/yum.repos.d/
  2. yum0.repo  yum1.repo  yum2.repo
  3. cat /etc/yum.repos.d/yum0.repo
  4. [yum2]
  5. name=yum2
  6. baseurl=http://yum.test.com:81/yum/repo1
  7. enabled=1
  8. cost=100
  9. gpgcheck=0
  10. #cat /etc/yum.repos.d/yum1.repo
  11. [yum3]
  12. name=yum3
  13. baseurl=http://yum.test.com:81/yum/repo2
  14. enabled=1
  15. cost=103
  16. gpgcheck=0

  17. #cat /etc/yum.repos.d/yum2.repo
  18. [yum4]
  19. name=yum4
  20. baseurl=http://yum.test.com:81/yum/repo3
  21. enabled=1
  22. cost=105
  23. gpgcheck=0

復(fù)制代碼
三個(gè) repo 中 yum2 的 cost 最小,當(dāng)執(zhí)行

  1. yum install cmeguard
復(fù)制代碼
時(shí),提示如下:

  1. Dependencies Resolved

  2. =========================================================================================================================
  3. Package                      Arch                     Version                            Repository                Size
  4. =========================================================================================================================
  5. Installing:
  6. cmeguard                     i386                     1.1.2-20                        yum2                     9.6 M

  7. Transaction Summary
  8. =========================================================================================================================
  9. Install      1 Package(s)         
  10. Update       0 Package(s)         
  11. Remove       0 Package(s)
復(fù)制代碼
可以看到,是選擇了 yum2 中的包進(jìn)行安裝,驗(yàn)證了 cost 的作用。
以此為例,你可以修改多個(gè) repo的 cost 進(jìn)行優(yōu)先級(jí)的設(shè)置。 需要注意的一點(diǎn)是,repo 的優(yōu)先級(jí)跟 *.repo 的文件名稱無關(guān)。
作者: duanjigang    時(shí)間: 2013-01-04 16:23
本帖最后由 duanjigang 于 2013-01-04 16:44 編輯

repo 配置中的變量

有時(shí)候我們會(huì)看到這樣的 repo 配置:

  1. [redhat.$releasever.iso.$basearch]
  2. name=redhat
  3. baseurl=http://yum.test.com/redhat/$releasever/iso/$basearch/
  4. gpgcheck=0
復(fù)制代碼
這其中 reposityid,name,baseurl 中都可能用到了一系列變量,在實(shí)際執(zhí)行 yum 命令時(shí),這些變量會(huì)被賦值,然后按照實(shí)際的結(jié)果去執(zhí)行。
有時(shí),我們總想知道,這個(gè)變量到底是什么取值,在這段文字中,就針對(duì)這幾個(gè)變量進(jìn)行說明下.

  1.     $releasever This will be replaced with the value of the version of the package listed in distroverpkg. This defaults to the version of 'redhat-release' package.

  2.     $arch This will be replaced with your architecture as listed by os.uname()[4] in Python.

  3.     $basearch This will be replaced with your base architecture in yum. For example, if your $arch is i686 your $basearch will be i386.

  4.     $uuid This will be replaced with a unique but persistent uuid for this machine. The value that is first generated will be stored in /var/lib/yum/uuid and reused until this file is deleted.

  5.     $YUM0-$YUM9 These will be replaced with the value of the shell environment variable of the same name. If the shell environment variable does not exist then the configuration file variable will not be replaced.
復(fù)制代碼
簡單翻譯下:

$releasever:就是yum.conf 中配置的distroverpkg的值對(duì)應(yīng)的rpm包的版本,這個(gè)奇葩配置,前面已經(jīng)說過了。
$arch,就是python代碼中

  1. os.uname()
復(fù)制代碼
的結(jié)果。
$basearch 對(duì)于64位架構(gòu)的機(jī)器就是x86_64, 32位架構(gòu)的就是i386.
$uuid 本機(jī)上產(chǎn)生的一個(gè)持久存儲(chǔ)的uuid值,唯一存在。
$YUM0-$YUM9 根據(jù)環(huán)境變量取值。
后面兩個(gè)變量基本上不會(huì)怎么用到。

最后,我們看幾個(gè)例子,在 我的一臺(tái)機(jī)器上, yum list 看到的輸出如下:

  1. xorg-x11-fonts-Type1.noarch                               7.1-2.1.el5                       redhat.5Server.iso.x86_64
復(fù)制代碼
這個(gè)就是前面的配置

  1. [redhat.$releasever.iso.$basearch]
復(fù)制代碼
展開后的值。

另外,需要注意的是,在4u機(jī)器上,reposityid 這一項(xiàng)中,變量貌似是不支持的。
比如,我在一臺(tái) 4u 的機(jī)器上看到如下輸出:

  1. xterm.i386                               192-8.el4_7.2          $releasever.$bas
復(fù)制代碼
在reposityid 這一項(xiàng),變量沒有被替換,但是在5u和6u的系統(tǒng)是沒問題的。

作者: duanjigang    時(shí)間: 2013-01-04 16:46
本帖最后由 duanjigang 于 2013-01-04 18:59 編輯

下面說下本篇的最后一個(gè)話題,也是比較有意思的一塊:
yum plugin (YUM 的插件)

使用 apach 和 nginx 的人都知道 apache 和 nginx 都具有在不同的調(diào)用點(diǎn)植入插件的功能,這些接口和 netfilter 的 五個(gè) hook 類似。

作為 redhat 系統(tǒng)的包管理命令- yum 也支持插件:一個(gè) python 腳本文件和一個(gè)配置文件,用來擴(kuò)展或者修改 yum 命令的行為,根據(jù)注冊(cè)函數(shù)的名稱來確定這些hook函數(shù)在何時(shí)調(diào)用。

增加 一個(gè) yum 插件需要完成兩件事情:一是開發(fā)對(duì)應(yīng)插件的 python 腳本,二是填寫對(duì)應(yīng)于該插件的配置文件。
插件的存儲(chǔ)默認(rèn)位置是:/usr/lib/yum-plugins/*.py
配置文件的存儲(chǔ)位置是:/etc/yum/pluginconf.d/*.conf

看下一個(gè) rhel 5.7 系統(tǒng)上的插件:

  1. $ ls /usr/lib/yum-plugins/*.py
  2. /usr/lib/yum-plugins/rhnplugin.py  /usr/lib/yum-plugins/subscription-manager.py
  3. /usr/lib/yum-plugins/product-id.py  /usr/lib/yum-plugins/security.py
  4. $ ls /etc/yum/pluginconf.d/
  5. product-id.conf  rhnplugin.conf  security.conf  subscription-manager.conf
復(fù)制代碼
我們都知道,一個(gè)數(shù)據(jù)包在主機(jī)上的網(wǎng)絡(luò)協(xié)議棧中被處理時(shí)會(huì)經(jīng)過很多點(diǎn),netfilter 提供了一種機(jī)制,可以在一些關(guān)鍵的點(diǎn),提供 hook 函數(shù)注冊(cè):用戶按照netfilter 模塊的的定義規(guī)范開發(fā)自己的代碼,編譯生成模塊文件 xx.ko,然后把這個(gè)模塊插入內(nèi)核,如果沒有什么異常的話,每一個(gè)經(jīng)過xxoo.ko注冊(cè)點(diǎn)的網(wǎng)絡(luò)報(bào)文都會(huì)被 xxoo.ko 的 hook 函數(shù)進(jìn)行處理;蛘逥ROP,或者ACCEPT, 或者STOLEN等等?傊ㄟ^這些 hook 點(diǎn)能夠改變報(bào)文的最終目的地或者它在協(xié)議棧中的走向。

和 報(bào)文在協(xié)議棧中的處理一樣,當(dāng)你執(zhí)行一個(gè) yum 命令時(shí),比如安裝一個(gè)軟件包,這個(gè)事情也有很多關(guān)鍵點(diǎn),yum 的開發(fā)者在這些點(diǎn)也預(yù)留了一些外部可以注冊(cè)hook函數(shù)的接口,以方便使用者通過第三方插件的方式改變 yum 的行為和功能。yum 操作中 我們能夠想到的一些點(diǎn)有: yum 初始化,配置文件加載,repo加載,文件下載,安裝/卸載事務(wù)等等。
這對(duì)這些操作點(diǎn),yum 提供了以下幾個(gè) hook 點(diǎn)來方便用戶植入 hook 模塊,細(xì)說如下:

config
插件初始化以后的時(shí)刻,試圖去擴(kuò)展yum 的配置文件和命令行接口的 hook 可以放在這里


postconfig
yum的配置對(duì)象剛剛初始化以后的時(shí)刻,試圖修改或者擴(kuò)展 yum 中的變量的hook可以放在這里。yum-3.1.7 以后才支持該 hook點(diǎn)。

init
在yum 初始化的早起,可以進(jìn)行插件相關(guān)的初始化工作

predownload
包下載之前的時(shí)刻,想要獲取包信息的hook可以放在此處

postdownload
包下載之后的時(shí)刻,想要獲取下載包的錯(cuò)誤信息的hook可以放在此

prereposetup
在 yum 初始化 reposity 之前

postreposetup
在 yum 初始化 reposity 之后

exclude
在包的 inclusion 和 exclusion 處理完之后調(diào)用,想要改變 inclusion 和 exclusion 的 hook 放在此

preresolve
在包決定之前

postresolve
在包決定之后

pretrans
在 update trasanction 之前

posttrans
在 update transation 結(jié)束之后

close
在 yum 正常運(yùn)行結(jié)束之后

clean
在yum clean 之后調(diào)用 (4u的系統(tǒng)自帶yum不支持該hook)

作者: duanjigang    時(shí)間: 2013-01-04 19:02
本帖最后由 duanjigang 于 2013-01-05 11:20 編輯

yum 的 hook 規(guī)范

隨便看一個(gè) 插件的代碼,能發(fā)現(xiàn)hook代碼的規(guī)范:

1): 如果要在 XX點(diǎn)注冊(cè)一個(gè)hook函數(shù),你的python 代碼中的函數(shù)名字應(yīng)該為

  1. XX_hook
復(fù)制代碼
2):每個(gè)hook 函數(shù)都會(huì)帶一個(gè)參數(shù) conduit
一個(gè) conduit 變量在不同的 hook/slot 點(diǎn)包含的數(shù)據(jù)是會(huì)變化的,類似于 netfilter 中的參數(shù) skbuff 一樣,在不同的hook點(diǎn),skbuff 中的指針,變量,或者有效,或者無效,這都要看它所處的位置(slot點(diǎn))。
不同的成員和方法在不同的 slot, 對(duì)于 conduit 也是會(huì)變得,這個(gè)可以參考 yum.plugins.SLOT_TO_CONDUIT這個(gè)字典,所有 condiut 子類的父類都是 PluginConduit


API依賴:

  在不同的yum版本中,支持的插件API和yum API都是會(huì)變化的。因此,為了防止出錯(cuò),并且使用到合適的API,需要在插件的代碼中指明版本號(hào)。當(dāng)前的API版本可以參考:yum.plugins.API_VERSION

插件類型:

目前支持兩種插件類型:

TYPE_CORE 和 TYPE_INTERACTIVE 兩種。

核心插件會(huì)修改yum的基礎(chǔ)功能,比如包排斥列表,依賴和 reposity 加載等。

交互式插件 可以修改yum的用戶界面,比如,交互式插件可以檢查一些錯(cuò)誤,然后退出yum,并且打印提示信息給用戶。

在yum2.6以及以前版本中,交互式插件定義為: TYPE_INTERFACE,不是很清晰,才進(jìn)行了更新。
看一下我寫的一個(gè)例子插件中注冊(cè)插件類型的代碼:

  1. requires_api_version = '2.4'
  2. if yum.plugins.API_VERSION < '2.3':
  3.     from yum.plugins import TYPE_INTERFACE
  4.     plugin_type = (TYPE_INTERFACE,)
  5. else:
  6.     from yum.plugins import TYPE_INTERACTIVE
  7.     plugin_type = (TYPE_INTERACTIVE,)
復(fù)制代碼
其它

可以在yum的任意調(diào)用點(diǎn),調(diào)用yum.plugins.PluginYumExit 來退出yum,并且打印你傳遞信息。

插件的配置文件都是INI格式存儲(chǔ)的,以下接口可以在插件的任何位置調(diào)用,來幫助你加載yum的配置信息(他們都是conduit中可以調(diào)用的):


  1. def confString(self, section, opt, default=None)

  2.     def confInt(self, section, opt, default=None)

  3.     def confFloat(self, section, opt, default=None)

  4.     def confBool(self, section, opt, default=None)
復(fù)制代碼
看名字,猜意思,很容易的。

yum-priorities 插件
yum-priorities 是一個(gè)標(biāo)準(zhǔn)的 yum 插件包,它的目的在于為不同的reposity 設(shè)置各自的優(yōu)先級(jí),優(yōu)先級(jí)在軟件升級(jí)或者安裝時(shí)決定訪問reposity 的順序。
優(yōu)先級(jí)低的repo 中的包不能升級(jí)優(yōu)先級(jí)高的 reposity 中的包所安裝的系統(tǒng)(針對(duì)于同一個(gè)包),同一個(gè)包,會(huì)先選擇優(yōu)先級(jí)較高的repo去選擇安裝。
安裝方法,直接

  1. yum install yum-priorities -y
復(fù)制代碼
即可。會(huì)安裝文件:

  1. /etc/yum/pluginconf.d/priorities.conf
  2. /usr/lib/yum-plugins/priorities.py
  3. /usr/lib/yum-plugins/priorities.pyc
  4. /usr/lib/yum-plugins/priorities.pyo
復(fù)制代碼
對(duì)于 priority 插件來說,每個(gè)repo 的默認(rèn)優(yōu)先級(jí)是99,可以配置的優(yōu)先級(jí)是1到99,你可以在repo的配置中添加一行來定義該repo的優(yōu)先級(jí),比如:

  1. [base]
  2. name=CentOS-$releasever - Base
  3. mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=os
  4. gpgcheck=1
  5. gpgkey=http://mirror.centos.org/centos/RPM-GPG-KEY-centos4
  6. priority=1
復(fù)制代碼
優(yōu)先級(jí)取值越小,級(jí)別越高。
另外有一點(diǎn)要注意,因?yàn)閜ackage 之間可以存在 obsoletes(廢棄的意思)的關(guān)系,也就是說A包在spec 中指定了 obsoletes B 包,那么當(dāng)A和B都發(fā)布后,如果有人

  1. yum install/update B
復(fù)制代碼
包的時(shí)候,如果 /etc/yum.conf 中的 obsoletes 為 1,這時(shí)就會(huì)用A來替換B包,安裝A包。
即使 A 存在于優(yōu)先級(jí)較低的repo中而B存在于優(yōu)先級(jí)較高的repo中,這樣一來的話,priorities 的功能就和  obsoletes 沖突了。
obsoletes 允許更新,而 priorities 不允許更新,為了解決這個(gè)問題,給 priorities 插件引入了一個(gè)選項(xiàng) check_obsoletes
如果你如下配置的話:

  1. cat  /etc/yum/pluginconf.d/priorities.conf
  2. [main]
  3. enabled = 1
  4. check_obsoletes=1
復(fù)制代碼
obsoletes 就會(huì)被 priorities 插件禁掉。這樣互掐的功能,難免讓人覺得有些不爽。
因此,也會(huì)有如下的言論:
http://wiki.centos.org/PackageManagement/Yum/Priorities
Note: The upstream maintainer of yum, Seth Vidal, had the following to say about 'yum priorities' in September 2009:
Gosh, I hope people do not set up yum priorities. There are so many things about
priorities that make me cringe all over. It could just be that it reminds me of
apt 'pinning' and that makes me want to hurl.


作者: duanjigang    時(shí)間: 2013-01-04 19:13
本帖最后由 duanjigang 于 2013-01-04 19:18 編輯

yum 插件例子之一: 在所有 hook 點(diǎn)打印信息

如下是我寫的一個(gè) test 插件的例子,注意在5u7 或者更高版本 OS 上運(yùn)行。
配置如下:

  1. cat /etc/yum/pluginconf.d/test.conf
  2. [main]
  3. enabled=1
復(fù)制代碼
插件代碼如下,就是打印一行信息而已,只不過在所有slot/hook 點(diǎn)都進(jìn)行了注冊(cè):

  1. # cat /usr/lib/yum-plugins/test.py
  2. #!/usr/bin/python -tt
  3. from yum import config
  4. from yum.plugins import PluginYumExit
  5. import yum
  6. import yum.plugins
  7. import yum.config
  8. import rpmUtils.arch

  9. import locale
  10. locale.setlocale(locale.LC_ALL, '')


  11. requires_api_version = '2.4'
  12. if yum.plugins.API_VERSION < '2.3':
  13.     from yum.plugins import TYPE_INTERFACE
  14.     plugin_type = (TYPE_INTERFACE,)
  15. else:
  16.     from yum.plugins import TYPE_INTERACTIVE
  17.     plugin_type = (TYPE_INTERACTIVE,)

  18. def config_hook(conduit):
  19.         print "config_hook-----------------------------"
  20. def postconfig_hook(conduit):
  21.         print "postconfig_hook-----------------------------"

  22. def init_hook(conduit):
  23.         print "init_hook-----------------------------"
  24. def predownload_hook(conduit):
  25.         print "predownload_hook-----------------------------"
  26. def postdownload_hook(conduit):
  27.         print "postdownload_hook-----------------------------"
  28. def prereposetup_hook(conduit):
  29.         print "prereposetup_hook-----------------------------"
  30. def postreposetup_hook(conduit):
  31.         print "postreposetup_hook-----------------------------"
  32.     #raise PluginYumExit('Goodbye')

  33. def preresolve_hook(conduit):
  34.         print "preresolve_hook-----------------------------"
  35. def postresolve_hook(conduit):
  36.         print "postresolve_hook-----------------------------"

  37. def exclude_hook(conduit):
  38.         print "exclude_hook-----------------------------"
  39. def pretrans_hook(conduit):
  40.         print "pretrans_hook----------------------------"
  41. def posttrans_hook(conduit):
  42.         print "posttrans_hook----------------------------"
  43.        
  44. def close_hook(conduit):
  45.         print "close_hook-----------------------------"
  46. #It is  not supported on a rhel4 os
  47. def clean_hook(conduit):
  48.         print "clean_hook-----------------------------"
復(fù)制代碼
你可以通過:
yum list  search info update repolist clean remove install
等操作來檢查打印的信息,同時(shí)也幫助我們理解了 yum 的執(zhí)行流程,什么命令會(huì)進(jìn)行什么操作。
作者: duanjigang    時(shí)間: 2013-01-04 19:19
本帖最后由 duanjigang 于 2013-01-04 19:31 編輯

yum 插件例子之二:downloadonly

該例子演示了 downloadonly 只下載rpm 而不安裝的功能,其中展示了 命令行參數(shù)擴(kuò)展功能,以及內(nèi)置函數(shù)調(diào)用的示例代碼,可以說是一個(gè)不錯(cuò)的例子:

  1. $ cat  /usr/lib/yum-plugins/test.py
  2. #!/usr/bin/python -tt
  3. from yum import config
  4. from yum.plugins import PluginYumExit
  5. import yum
  6. import yum.plugins
  7. import yum.config
  8. import rpmUtils.arch
  9. #print rpmUtils.arch.getBaseArch()
  10. #print rpmUtils.arch.getCanonArch()

  11. # Decent (UK.US English only) number formatting.
  12. import locale
  13. locale.setlocale(locale.LC_ALL, '')

  14. requires_api_version = '2.4'
  15. if yum.plugins.API_VERSION < '2.3':
  16.     from yum.plugins import TYPE_INTERFACE
  17.     plugin_type = (TYPE_INTERFACE,)
  18. else:
  19.     from yum.plugins import TYPE_INTERACTIVE
  20.     plugin_type = (TYPE_INTERACTIVE,)

  21. def config_hook(conduit):
  22.     parser = conduit.getOptParser()
  23.     parser.add_option('', '--downloadonly', dest='dlonly',
  24.       action='store_true', default=False,
  25.       help="don't update, just download,added by duanjigang")
  26.     # Add a boolean option to the [main] section
  27.     config.YumConf.enable_foo = config.BoolOption(False)

  28.     # Add a URL option to repository sections
  29.     config.RepoConf.foo_url = config.UrlOption()

  30.     # Add an option to to [main] and the repository sections. The
  31.     # repository options will inherit the properties of the [main] option
  32.     # and will use the value from [main] if the option is not specified in
  33.     # the repo section.
  34.     config.YumConf.max_foo = config.IntOption(10)
  35.     config.RepoConf.max_foo = config.Inherit(config.YumConf.max_foo)

  36. def init_hook(conduit):
  37.     conf = conduit.getConf()


  38.     # Display the options from the [main] section
  39.     conduit.info(2, "enable_foo = %r" % conf.enable_foo)
  40.     conduit.info(2, "max_foo = %r" % conf.max_foo)

  41.     # Display the options from the repository sections
  42.     for repo in conduit.getRepos().listEnabled():
  43.     #for repo in conduit.getRepos().listEnabled():
  44.         conduit.info(2, "%s.foo_url = %r" % (repo.id, repo.foo_url))
  45.         conduit.info(2, "%s.max_foo = %r" % (repo.id, repo.max_foo))

  46. def postdownload_hook(conduit):
  47.         opts, commands = conduit.getCmdLine()
  48.         if opts.dlonly:
  49.             raise PluginYumExit('exiting because --downloadonly specified--by duanjigang')
復(fù)制代碼
測(cè)試下其中的賦值和打印語句:

  1. $ yum info a | grep redhat
  2. redhat.5Server.iso.x86_64.foo_url = None
  3. redhat.5Server.iso.x86_64.max_foo = 10
  4. redhat.5Server.updates.x86_64.foo_url = None
  5. redhat.5Server.updates.x86_64.max_foo = 10
復(fù)制代碼
看一下命令行選項(xiàng):執(zhí)行
yum --help

后面有輸出一行:

  1. --downloadonly        don't update, just download,added by duanjigang
復(fù)制代碼
是我們?cè)黾拥拿钚袇?shù)。

最后我們測(cè)試下它的 downloadonly 功能:

  1. $ sudo yum install zsh --downloadonly -y
  2. =========================================================================================================================
  3. Package             Arch                   Version                     Repository                                  Size
  4. =========================================================================================================================
  5. Installing:
  6. zsh                 x86_64                 4.2.6-6.el5                 redhat.5Server.iso.x86_64                 1.8 M

  7. Transaction Summary
  8. =========================================================================================================================
  9. Install       1 Package(s)
  10. Upgrade       0 Package(s)

  11. Total size: 1.8 M
  12. Downloading Packages:


  13. exiting because --downloadonly specified--by duanjigang
復(fù)制代碼
驗(yàn)證下:

  1. $ rpm -qa zsh
  2. $ ls  -lat /var/cache/yum/redhat.5Server.iso.x86_64/packages/zsh-4.2.6-6.el5.x86_64.rpm
  3. -rw-r--r-- 1 root root 1835335 Apr  1  2012 /var/cache/yum/redhat.5Server.iso.x86_64/packages/zsh-4.2.6-6.el5.x86_64.rpm
復(fù)制代碼
我們能夠看到 包確實(shí)下載下來了,但是卻沒有安裝,正是我們期望的。


作者: duanjigang    時(shí)間: 2013-01-04 19:34
本帖最后由 duanjigang 于 2013-01-05 11:22 編輯

關(guān)于 yum 插件的更詳細(xì)知識(shí),可以參考以下文檔:

WritingYumPlugins
http://yum.baseurl.org/wiki/WritingYumPlugins

git://yum.baseurl.org / yum-utils.git / tree
http://yum.baseurl.org/gitweb/?p=yum-utils.git;a=tree

yum API 文檔
http://yum.baseurl.org/api/yum-3.2.26/

yum-plugin-priorities
http://wiki.centos.org/PackageManagement/Yum/Priorities



作者: duanjigang    時(shí)間: 2013-01-04 19:42
本帖最后由 duanjigang 于 2013-01-04 19:42 編輯

本篇到此就基本結(jié)束了。
一些說明:

(1):主要線索還是以 yum 的使用為主線,解析組成 yum 服務(wù)的各大要素,以及配置,擴(kuò)展功能等,其中插入了我個(gè)人總結(jié)的一些片段,還有一部分翻譯的官方文檔,
有些地方翻譯或者理解有誤,請(qǐng)及時(shí)斧正,好方便我更新。篇幅上可能有些亂,不過都是挑的重點(diǎn)來寫。

(2): 第一頁中列舉的幾個(gè)問題中,還有一個(gè)很大的問題:多平臺(tái),不同架構(gòu)的包管理,還沒有提及,這個(gè)在后面講述包管理規(guī)范時(shí)會(huì)總結(jié),此處先跳過。

(3):內(nèi)容的組織上,因?yàn)槲覍?duì) python 語言不是很熟悉,yum/rpm的源碼讀了一點(diǎn)點(diǎn),而且主要從事的是運(yùn)維工作,因此好多地方是純粹的使用經(jīng)驗(yàn)分享或者文檔列舉,偶爾有些源碼分析。算不上完整的 yum 架構(gòu)剖析,比如就 yum 的運(yùn)行流程,我只能說個(gè)大概,細(xì)節(jié)還得看代碼。感興趣的同學(xué)可以自己學(xué)習(xí)。還有 createrepo 的效率和改進(jìn)建議等,都是比較有意思和挑戰(zhàn)的問題,這些我沒有列舉出來,因?yàn)槟芰蛘呔τ邢。如果后面有空能?createrepo 和 yum 主體流程 這塊理清的話,再行補(bǔ)充。
有內(nèi)容上不能達(dá)到閱讀者期望的地方,望理解,我們盡力去全面的分析這個(gè)服務(wù)的角角落落。


:wink::wink::wink:
本篇收工
作者: Godbach    時(shí)間: 2013-01-05 12:08
回復(fù) 1# duanjigang
好文章,感謝段總分享。


   
作者: duanjigang    時(shí)間: 2013-01-05 12:12
:wink::wink:
作者: shang2010    時(shí)間: 2013-01-05 12:51
雖然對(duì)我來說,yum 解決一切,

但是對(duì)蘭蘭這種干活很細(xì)致的戶,我還是很愿意拜膜一下的,
是不是工作要用這些哦,這么專業(yè)
作者: send_linux    時(shí)間: 2013-01-05 13:19
感謝分享啊,大家假期都去happy了,段總還這么有毅力和熱情寫這么多內(nèi)容,真的不容易:)
作者: duanjigang    時(shí)間: 2013-01-05 13:36
呵呵,用到了,用到了就花點(diǎn)時(shí)間研究下。嘿嘿
回復(fù) 25# shang2010


   
作者: 斗戰(zhàn)剩佛之道    時(shí)間: 2013-01-05 13:37
本帖最后由 斗戰(zhàn)剩佛之道 于 2013-01-05 13:37 編輯

樓主分析的真心不錯(cuò)  。。 處男貼給你了 ,哈哈
作者: ooooldman    時(shí)間: 2013-01-05 13:44
蘭蘭V5
作者: duanjigang    時(shí)間: 2013-01-05 13:50
tks,處男俺也不敢要啊
回復(fù) 28# 斗戰(zhàn)剩佛之道


   
作者: T-Bagwell    時(shí)間: 2013-01-05 17:53
duanjigang 發(fā)表于 2012-12-30 12:23
搭建yum服務(wù)的簡單實(shí)例

(1): yum 服務(wù)器為 192.168.1.102, 部署網(wǎng)絡(luò)服務(wù)為 httpd, web 根目錄是 /usr/l ...



非常好用
多謝蘭斯特洛夫斯基
作者: duanjigang    時(shí)間: 2013-01-05 18:22
回復(fù) 31# T-Bagwell

謝謝支持,共同交流。
后面更精彩,不要錯(cuò)過喔


   
作者: xiaopan3322    時(shí)間: 2013-01-05 21:26
回復(fù) 1# duanjigang


    哥們來捧場(chǎng)加膜拜了!
作者: 守住每一天    時(shí)間: 2013-01-07 16:17
非常感謝分享,讓我對(duì)YUM又有著全新的認(rèn)識(shí)。講解得非常到位。

提個(gè)問題:
在centos 5.4 6.0共存的環(huán)境中。
6.0偶爾會(huì)有需要yum makecache 才能更新的問題,如何修復(fù) ?
作者: duanjigang    時(shí)間: 2013-01-08 10:54
回復(fù) 34# 守住每一天

你們的 yum server 上 5u 和 6u 分開源了吧?客戶端肯定是一個(gè)配置,通過變量來區(qū)分。
需要make cache 才能用?這個(gè)應(yīng)該不是 yum 本身的 bug, 可能是配置的問題。能不能說的更具體些,詳情。。。

   
作者: 守住每一天    時(shí)間: 2013-01-08 11:23
回復(fù) 35# duanjigang


    在同1個(gè)源里。如:mirrors.domain.com按子目錄即變量來區(qū)分的。

client 配置:
#released updates
[updates]
name=CentOS-$releasever - Updates
baseurl=http://mirrors.domain.com/centos/$releasever/updates/$basearch/
enabled=1
gpgcheck=0

yum:
$ more /etc/yum.conf
[main]
cachedir=/var/cache/yum
keepcache=0
debuglevel=2
logfile=/var/log/yum.log
distroverpkg=redhat-release
tolerant=1
exactarch=1
obsoletes=1
gpgcheck=1
plugins=1
#exclude=*.i?86

# Note: yum-RHN-plugin doesn't honor this.
metadata_expire=1h

installonly_limit = 5

在5上一直正常。偶爾有反饋說6不正常。

作者: duanjigang    時(shí)間: 2013-01-08 14:58
回復(fù) 36# 守住每一天
你的yum 服務(wù)器怎么配置的?我指的是 DocumentRoot 和 rpm 所在位置的路徑。比如我這里的配置:
DocumentRoot 是 /mnt/
redhat包 的路徑是 /mnt/yum/redhat/5/x86_64 和 /mnt/yum/redhat/5/i386 (x86_64和 i386 底下就是repodata 目錄)
我是想看著這樣的配置。


   
作者: 守住每一天    時(shí)間: 2013-01-09 09:47
回復(fù) 37# duanjigang



DocumentRoot /yum

/yum/centos/5/updates/x86_64/RPMS/repodata/
/yum/centos/6/updates/x86_64/Packages/repodata/

每次update repodata這個(gè)目錄即可,對(duì)不?
作者: duanjigang    時(shí)間: 2013-01-09 14:37
回復(fù) 38# 守住每一天

DocumentRoot /yum

/yum/centos/5/updates/x86_64/RPMS/repodata/
/yum/centos/6/updates/x86_64/Packages/repodata/

每次update repodata這個(gè)目錄即可,對(duì)不?

===========================
服務(wù)器上直接在
/yum/centos/5/updates/x86_64

/yum/centos/6/updates/x86_64
下createrepo 即可,然后 repodata 目錄就會(huì)生成在
/yum/centos/5/updates/x86_64

/yum/centos/6/updates/x86_64
下了,這個(gè)目錄是自動(dòng)創(chuàng)建的。
客戶端配置baseurl 路徑為

5U

  1. baseurl=http://xxxx/centos/5/updates/x86_64
復(fù)制代碼
6U

  1. baseurl=http://xxxx/centos/6/updates/x86_64
復(fù)制代碼
即可。
每次更新包了,重新在
/yum/centos/6/updates/x86_64
或者
/yum/centos/5/updates/x86_64
下 createrepo

   
作者: xike2002    時(shí)間: 2013-01-10 14:00
回復(fù) 1# duanjigang

yum安裝軟件的確是很方便,我也一直在用。但是現(xiàn)在我遇到了一個(gè)問題:

正在研究一個(gè)開源的視頻軟件的代碼,代碼是linux環(huán)境下的源碼,但是現(xiàn)在需要在windows下編譯源碼,得到windows下的可執(zhí)行程序。
網(wǎng)上有人推薦使用cygwin和mingGW環(huán)境編譯源碼,他是一套模擬的linux環(huán)境,但是可以編譯出windows下的可執(zhí)行程序。
但是我在編譯的過程它又依賴一些軟件程序,又需要安裝這些軟件,例如GTK、GTK+、還缺少很多,要是都下載源碼安裝的話太麻煩,可是他有沒有
yum這樣的命令,有沒有什么好一點(diǎn)的辦法安裝軟件呢?
作者: duanjigang    時(shí)間: 2013-01-10 16:24
回復(fù) 40# xike2002

回復(fù) 40# xike2002

呵呵,如果開發(fā)的項(xiàng)目為了支持多平臺(tái),我一般會(huì)把依賴的第三方庫源碼拿下來,在多平臺(tái)上首次部署環(huán)境時(shí)編譯這些第三方庫。
cygwin 不太熟悉。抱歉。

   
作者: xike2002    時(shí)間: 2013-01-10 16:44
回復(fù) 41# duanjigang

謝謝樓主,那看來只能下載源碼編譯這些依賴的庫了

   
作者: shenyue_sam    時(shí)間: 2013-01-17 09:35
好文章,感謝樓主。
作者: sunnyhxt    時(shí)間: 2013-01-22 11:01
非常好的文章,找了好多資料都沒有像這樣系統(tǒng)的說明yum的。
作者: starggw    時(shí)間: 2013-01-27 11:36
收藏了 假期的時(shí)候好好看看
作者: shdnzwy    時(shí)間: 2013-02-03 09:36
膜拜   段……王……
作者: a7pufap    時(shí)間: 2013-02-06 19:46
歸屬的組織 only show me !
作者: webdna    時(shí)間: 2013-02-07 10:37
配那么多東西,過幾個(gè)月又升級(jí)版本了,累不累呢?
作者: duanjigang    時(shí)間: 2013-02-08 09:39
回復(fù) 48# webdna
配置的是服務(wù),升級(jí)的是軟件,這兩者沒啥關(guān)系的。
而且軟件升級(jí)是正,F(xiàn)象。不可能一次發(fā)布就永遠(yuǎn)不升級(jí)。。。
這個(gè)服務(wù)其中目標(biāo)之一就是為了方便軟件升級(jí)。


   
作者: 雨點(diǎn)的尾巴    時(shí)間: 2013-02-18 17:26
Mark。太細(xì)致了,膜拜!
作者: CoreCodes    時(shí)間: 2013-02-20 08:52
用過yum 服務(wù)對(duì)rpm包的管理,沒想過更深入的去了解。。。慚愧
作者: zhanglong71    時(shí)間: 2013-02-21 10:15
崇拜一下!
作者: qinyiwang    時(shí)間: 2013-02-26 15:33
支持一下~頂一把
作者: heritrix    時(shí)間: 2013-03-02 10:18
雖然不是很看得懂,頂
作者: heritrix    時(shí)間: 2013-03-02 10:19
謝謝樓主的分享
作者: GIScomputer    時(shí)間: 2013-03-07 17:07
很好,很強(qiáng)大!
作者: duanjigang    時(shí)間: 2013-03-08 20:44
回復(fù) 56# GIScomputer
呵呵,多多交流!


   
作者: allone_2    時(shí)間: 2013-03-11 18:59
不錯(cuò)頂一下
作者: wonghoifung    時(shí)間: 2013-03-28 16:25
先mark再看
作者: fuyafei    時(shí)間: 2013-07-23 17:06
含淚頂樓主,好總結(jié)啊。。剛剛看了一點(diǎn)點(diǎn)rpm包的,受益匪淺啊,繼續(xù)yum學(xué)習(xí)。。樓主灰常感謝你的總結(jié)。。
作者: duanjigang    時(shí)間: 2013-08-10 17:33
:wink: 回復(fù) 59# wonghoifung


   
作者: 930567969    時(shí)間: 2014-01-06 12:59
段兄,這是要逆天啊,快把書里的精要全提取啦
作者: 夕陽下的身影    時(shí)間: 2014-04-18 12:44
{:3_183:} 好貼要頂!
作者: kensniper    時(shí)間: 2014-04-22 20:07
mark 一下,回頭有空再看
作者: Liu_Nick    時(shí)間: 2014-05-14 12:38
解讀下1和0的意思:
enabled=1
gpgcheck=0
作者: duanjigang    時(shí)間: 2014-09-23 12:23
回復(fù) 65# Liu_Nick

enable  = 1標(biāo)識(shí)啟用該項(xiàng),0不啟用
gpgcheck標(biāo)識(shí)是否進(jìn)行g(shù)pg檢查。一般會(huì)提供一個(gè)gpb key的文件。

   




歡迎光臨 Chinaunix (http://www.72891.cn/) Powered by Discuz! X3.2