I decided to use douban website again and found its sub-site on Reading is quite nice. Almost all books have a page on the website and you can register on the page and announce that "I'm reading this book".
So here is my home page on douban. Recently I have read The Lord of the Rings, More Joel on Software (in Chinese) and The Unknown Lincoln (by Dale Carnegie).
(Douban is a Chinese website, and I wonder if there is a similar English one?)
The Lord of the Rings
As said by all, a great book. And no doubt that I've only understood a small part of it. There is a whole and complete world in the book series. Five-star on this book.
More Joel on Software
A quite insightful book about software industry and software development. Good for subway reading :) Four-star.
The Unknown Lincoln
I got a lot from the book about Lincoln and US history. About Lincoln's life, about Mrs. Lincoln and about the Civil War. And the book is written in a very good style. Five star.
I'm reading Nineteen Eighty -Four recently. I have a strange empathy with it, naturally, given my circumstance :(
Monday, July 19, 2010
Thursday, July 15, 2010
at WindRiver
I have graduated from Beihang University and been at Wind River now. I'm at the Beijing office and work on Wind River Linux. The work here has quite some similarity with my experience at Foresight Linux. And I'm very happy about it.
Maybe I should also state as other blogs:
Maybe I should also state as other blogs:
This is my personal blog and things said here do not represent the position of my employer.
Labels:
life
Monday, March 22, 2010
where conary is different from slackware
[This is a reply to Grissiom post about slackware's package-management]
Foresight Linux 跟 Slackware Linux 的根本不同在于两者的定位不同,Foresight 的目标是一个简单易用的桌面系统,而 Slackware 应该是给 geek 用的。所以,好多争论其实是没有意义的。
而 conary 跟 slackware 的包管理,也有着完全不同的目标。conary 的重点在于自动化(automatic),跟 slackware 是背道而驰。所以对两者的比较只能是技术上的讨论,无法说谁优谁劣。
下边是具体内容。
管理文件就不用说了,每一个包管理都有这个功能 (否则可以称之为 Windows)。
依赖处理
======
Slackware 是不处理依赖的,而 conary 就强在处理依赖上。conary 把整个系统都归在自己的管理下,不仅能处理单个包的依赖,还能保证整个系统都处于 consistent 的状态。
能做到这一点,是因为 conary 里面 group 的概念。一个 group 本质上只是包含一堆包的一个包。注意,对 conary 来说,group 也是一个软件包。能对普通包进行的操作,也能在 group 上进行。而基于 conary 的发行版,其整个系统是由一个 group 定义的,通常叫做 group-什么什么-dist,比如 group-gnome-dist (定义 GNOME 版 Foresight 的 group)、group-xfce-dist (定义 XFCE 版 Foresight 的 group)。正因为此,conary 能够管理整个系统,使得系统范围内的依赖关系都是良好的。
另外一点,conary 是在文件级别处理依赖的 (跟 slackware 是两个极端)。上篇文章提过了,这里不再赘述。
自动还是不自动?
============
可以看出,slackware 进行各种操作主要是靠用户运行各种(自创或者外来的)脚本。毫无疑问,这样非常"爽",符合 hacker 精神 (我也喜欢 :-)。
不过这种方式对于系统管理员 (要维护大量的机器) 来说,无疑是个噩梦,会"极大的束缚生产力"。作为一个 SA,他必须为自己的各种任务创造各种各样的脚本,或者从别的 SA 那借鉴一些轮子 (因为大家的许多任务还是差不多的嘛)。这些脚本或者命令都是人工管理的,维护成本会很高。如果 SA 跳槽了,新来的 SA 八成是个杯具...
与此相反,conary 的设计哲学是,common 的情景都由它来做,然后 SA 把需要特殊注意的事情说明白,就行了。所以在 conary 系统上,会看到各种操作都是能简单就简单,能用模板就用模板。
举例来说
======
比如打包的时候,许多软件都是同样的 configure; make; make install,所以 conary 提供了一个 recipe template,叫 AutoPackageRecipe,表示用 autotools 来打包的软件就可以用这个模板。只需要给 conary 一个 tarball,它会自动调用模板里定义的 Configure/Make/MakeInstall 函数来打包。请参考 Foresight Linux 的 automake 包。注意它根本没有指明如何 make、如何 install。
再举一个极端的例子。用于指定 tarball 位置的 URL,原则也是能简则简:
* 添加一个tarball,用 addArchive 函数。'正常'的写法是:
addArchive('ftp://ftp.gnu.org/gnu/automake/automake-1.11.tar.bz2')
* 如果遵循好的编程习惯,最好写成:
addArchive('ftp://ftp.gnu.org/gnu/automake/automake-%(version)s.tar.bz2')
* 但是,其实只需要一个目录,conary 会自动去找压缩包:
addArchive('ftp://ftp.gnu.org/gnu/automake/')
* 其实... conary 能识别一系列的 mirror (/etc/conary/mirros/),所以只需要这样就行了:
addArchive('mirror://gnu/automake/')
或者 addArchive('mirror://gnu/%(name)s/')
这只是一个细节问题,但它反映了 conary 行事的惯例。上边的例子同样可以参考 automake 包。
常用操作
=====
可以看到,slackware 中许多操作都是'简单'的 grep/find 等命令的组合,而 conary 系统中,则是用 conary 提供的一系列命令。conary 提供了命令行的接口,以方便 scripting;而且也提供 API 接口,可以在代码中调用,比如 PackageKit 的 conary 后端,注意这一行,
from conary import dbstore, queryrep, versions, updatecmd
在命令行下:
* 查询一个 package 包含了哪些文件
conary query gedit --ls
* 查询某个文件是由哪个包提供的
conary query --path /usr/bin/gedit
* 查询一个包有哪些依赖,提供了哪些依赖
conary query --deps gedit
* 检查一个包是不是完好无损
conary verify gedit
* 查询源里边包的信息
conary repquery gedit
等等...
关于回滚
=====
回滚只是 conary 细粒度依赖处理的一个表现而已。conary 能保证系统处在一个已知的、确定的状态中 (consistent),回滚无非是在当前状态跟上一个状态的转变。
比如安装了一个包(volti),它同时带来了好多依赖(pyalsaaudio, python-xlib)。稍后的回滚能撤销整个操作,也就是不仅会删除 volti,随它而来的 pyalsaaudio 和 python-xlib 也会被同时删除。再比如系统范围的 updateall,被回滚的话,会被整个撤销。在其他的包管理下,就只能来个 for 循环,统统 downgrade 回旧版本了。
conary 提供了 sync 命令,能把一个包同步到某个版本去。注意 group 也是一个包,所以如果 sync 的对象是 group-x-dist 的话,能保证整个系统都处于指定版本上。软件包的任何损坏 (比如不同版本的库被错误安到了一块),都可以侦探出来 (上边提到的 conary verify),都可以修复。这个特点是简单粗暴的卸载重装无法比拟的。
"Each one uses different package formats that cannot understand each other"
=======
conary 能够理解 rpm 和 deb 格式,能够把这些格式的包转换成 conary 系统可用的包。比如这个 linuxqq 的包,是直接用了腾讯发布的 rpm 包 (没有经过再次编译)。比如这个 picasa 包,是用了 deb 包,也没有再次编译。比如这个 libgnome 包,用了 src.rpm,利用 rpm 的 spec,重新编译形成 conary 包。
Foresight Linux 跟 Slackware Linux 的根本不同在于两者的定位不同,Foresight 的目标是一个简单易用的桌面系统,而 Slackware 应该是给 geek 用的。所以,好多争论其实是没有意义的。
而 conary 跟 slackware 的包管理,也有着完全不同的目标。conary 的重点在于自动化(automatic),跟 slackware 是背道而驰。所以对两者的比较只能是技术上的讨论,无法说谁优谁劣。
下边是具体内容。
管理文件就不用说了,每一个包管理都有这个功能 (否则可以称之为 Windows)。
依赖处理
======
Slackware 是不处理依赖的,而 conary 就强在处理依赖上。conary 把整个系统都归在自己的管理下,不仅能处理单个包的依赖,还能保证整个系统都处于 consistent 的状态。
能做到这一点,是因为 conary 里面 group 的概念。一个 group 本质上只是包含一堆包的一个包。注意,对 conary 来说,group 也是一个软件包。能对普通包进行的操作,也能在 group 上进行。而基于 conary 的发行版,其整个系统是由一个 group 定义的,通常叫做 group-什么什么-dist,比如 group-gnome-dist (定义 GNOME 版 Foresight 的 group)、group-xfce-dist (定义 XFCE 版 Foresight 的 group)。正因为此,conary 能够管理整个系统,使得系统范围内的依赖关系都是良好的。
另外一点,conary 是在文件级别处理依赖的 (跟 slackware 是两个极端)。上篇文章提过了,这里不再赘述。
自动还是不自动?
============
可以看出,slackware 进行各种操作主要是靠用户运行各种(自创或者外来的)脚本。毫无疑问,这样非常"爽",符合 hacker 精神 (我也喜欢 :-)。
不过这种方式对于系统管理员 (要维护大量的机器) 来说,无疑是个噩梦,会"极大的束缚生产力"。作为一个 SA,他必须为自己的各种任务创造各种各样的脚本,或者从别的 SA 那借鉴一些轮子 (因为大家的许多任务还是差不多的嘛)。这些脚本或者命令都是人工管理的,维护成本会很高。如果 SA 跳槽了,新来的 SA 八成是个杯具...
与此相反,conary 的设计哲学是,common 的情景都由它来做,然后 SA 把需要特殊注意的事情说明白,就行了。所以在 conary 系统上,会看到各种操作都是能简单就简单,能用模板就用模板。
举例来说
======
比如打包的时候,许多软件都是同样的 configure; make; make install,所以 conary 提供了一个 recipe template,叫 AutoPackageRecipe,表示用 autotools 来打包的软件就可以用这个模板。只需要给 conary 一个 tarball,它会自动调用模板里定义的 Configure/Make/MakeInstall 函数来打包。请参考 Foresight Linux 的 automake 包。注意它根本没有指明如何 make、如何 install。
再举一个极端的例子。用于指定 tarball 位置的 URL,原则也是能简则简:
* 添加一个tarball,用 addArchive 函数。'正常'的写法是:
addArchive('
addArchive('
addArchive('
或者 addArchive('mirror://gnu/%(name)s/')
这只是一个细节问题,但它反映了 conary 行事的惯例。上边的例子同样可以参考 automake 包。
常用操作
=====
可以看到,slackware 中许多操作都是'简单'的 grep/find 等命令的组合,而 conary 系统中,则是用 conary 提供的一系列命令。conary 提供了命令行的接口,以方便 scripting;而且也提供 API 接口,可以在代码中调用,比如 PackageKit 的 conary 后端,注意这一行,
from conary import dbstore, queryrep, versions, updatecmd
在命令行下:
* 查询一个 package 包含了哪些文件
conary query gedit --ls
* 查询某个文件是由哪个包提供的
conary query --path /usr/bin/gedit
* 查询一个包有哪些依赖,提供了哪些依赖
conary query --deps gedit
* 检查一个包是不是完好无损
conary verify gedit
* 查询源里边包的信息
conary repquery gedit
等等...
关于回滚
=====
回滚只是 conary 细粒度依赖处理的一个表现而已。conary 能保证系统处在一个已知的、确定的状态中 (consistent),回滚无非是在当前状态跟上一个状态的转变。
比如安装了一个包(volti),它同时带来了好多依赖(pyalsaaudio, python-xlib)。稍后的回滚能撤销整个操作,也就是不仅会删除 volti,随它而来的 pyalsaaudio 和 python-xlib 也会被同时删除。再比如系统范围的 updateall,被回滚的话,会被整个撤销。在其他的包管理下,就只能来个 for 循环,统统 downgrade 回旧版本了。
conary 提供了 sync 命令,能把一个包同步到某个版本去。注意 group 也是一个包,所以如果 sync 的对象是 group-x-dist 的话,能保证整个系统都处于指定版本上。软件包的任何损坏 (比如不同版本的库被错误安到了一块),都可以侦探出来 (上边提到的 conary verify),都可以修复。这个特点是简单粗暴的卸载重装无法比拟的。
"Each one uses different package formats that cannot understand each other"
=======
conary 能够理解 rpm 和 deb 格式,能够把这些格式的包转换成 conary 系统可用的包。比如这个 linuxqq 的包,是直接用了腾讯发布的 rpm 包 (没有经过再次编译)。比如这个 picasa 包,是用了 deb 包,也没有再次编译。比如这个 libgnome 包,用了 src.rpm,利用 rpm 的 spec,重新编译形成 conary 包。
Sunday, March 7, 2010
what's good about conary
试图总结一下 conary 到底有什么独特之处... 不过我对其他的包管理不是很熟悉,所以不太好总结。
这样,以下内容基本上是这篇文章的意译。
包管理,也就是管理系统上所有其他软件的一个软件。但 conary 不只是一个包管理软件,更是一个强大的对软件系统的版本管理系统。
===========
第一个问题,如何组织软件源(repository)
在 deb/rpm 系统上,一个 repository 无非是某个服务器上的一个目录,其中存放着软件包(一些文件)。文件的命名无非就是"软件名",加上"软件版本"(当然一般还有其他部分,稍后再提)。
问题来自于文件的命名是任意的,手动的。比如有两个软件源,都提供了firefox-3.0 这个包,那么包管理就会搜索到两个"相同"的包,可能产生冲突。
而 conary 不这样处理软件源,conary 的 repository 并不是一个静态的目录,而是一个有版本的动态的分支。整个软件源都是处在版本控制下的,随着其中软件的更新,不断的向前发展,而不是像磁盘文件系统上的一个目录,新版本的文件会覆盖旧文件。
当然,conary 里面的包名字也必须有好几个部分,比如名字加版本。但这些都是由 conary 自动管理,没有手动的过程,conary 能保证两个不同的包,用户能识别出它们确实是不一样的。比如有两个 deb 的源,apt.joeschmoe.com 和 apt.joesmith.com,它们有同一个版本的 liferea,那包名可能是一样的,就会有问题,而 conary 不会遇到这个矛盾,因为,软件源的域名其实也是包名字的一部分。
如果 deb 要以域名来辨别不同的包,那只能把域名写到文件名里面,结果必然是,软件包的名字变得特别长。正因为 conary 下的“包”并不是以文件形式存在的,才能做到上边这一点。
而问题没有到此为止,一般发行版会支持多个硬件平台 (至少有 32 位或 64 位之分吧)。deb/rpm 的做法是什么?只能把 arch 写进文件名里面。结果就是这样的,liferea-1.2.2-2.el5.rf.x86_64.rpm。能看出跟 liferea-1.2.2-2.el5.rf.x86-64.rpm 的区别吗?
conary 也需要支持不用的 arch,包名字也会包含 x86, x86_64 等等。但由于 conary 的“自动管理”,默认情况下这些额外信息是被隐藏的。有时候一个简单的"liferea"就能识别一个包,有时候需要 "liferea=1.0"才能识别, 有时候需要 "liferea=foresight.rpath.org@fl:2-devel" (以区别 "liferea=foresight.rpath.org@fl:2-qa", 或者 "liferea=jesse.rpath.org@fl:2-devel"),有时候甚至需要"liferea=foresight.rpath.org@fl:2-devel/1.7.3-0.1-2",而这就是 conary 里面包的 full-name 的样子。
===========
正由于以上这些,conary 不需要复杂的 sources.list。如果你想从我的个人软件源安装 liferea,在 deb 世界里需要把我的源添加到 sources.list 里边,这样 apt 才能自动从那里查找更新。
而对于 conay, 只需要安装 liferea=jesse.rpath.org@fl:2-devel,conary 会记住这个源,以后只会从这里查找更新,即使 foresight 的官方源里面有更新的版本,也不会影响你的系统。
===========
细粒度的依赖关系
解决依赖是包管理的另一个基本作用,对于 deb/rpm 来说,依赖是定义在包的层面的,带来的一个问题是,有时候要安装某个包,需要先安装一系列的依赖,它们的体积加起来可能很大。另一个问题是,更新的时候,整个包都要重新下载,而好多时候这是不需要的,比如 man page 和一些图片,可能并没有任何变化。
conary 是在文件层次上解决依赖的,所以,一个包并不依赖于另"一个包",而是依赖某个文件的存在。conary 把包划分成几个部分,比如 :runtime, :doc, 或者 :devel,安装依赖包、更新包都是基于这个子部分的,用不到或没有变化的部分就不用下载。好处是可以节省带宽,节省硬盘空间,节省电力,节省能源...
而且这带来了另一个可能:系统可以定制得很小,能够把不需要的都删掉。比如最近我们在裁减 GNOME Developer Kit 的大小,在脚本里有这一句:
r.removeComponents(['doc', 'supdoc', 'build-tree', 'devellib', 'devel'],
'group-gnome-dist')
这样就把所有的文档、开发相关的文件移除了。
当然,deb 和 rpm 也能把一个包划分开 (也就是那些 -devel 包的由来)。问题是,手动。打包的开发者必须在 spec 文件里手动指明哪些文件是 liferea-doc 的,哪些是 liferea-devel 包的。但 conary 能自动完成这些,安装到 /etc 的,一般就是 :config 部分的;在 /user/share/man/ 下的,应该就是 :doc。conary 能识别出 general case 来,开发者只需要做剩下的那一点。
===========
回滚。由于整个系统都是在 conary 的版本管理之下,所以 conary 支持包管理操作的回滚。这个特性是最容易记住的,所以不细说了。
===========
给 conary 打包非常容易,所有的打包过程,都由简短的 python 脚本定义。在我看来,比 rpm 的 spec 文件清晰的多。而且像前面提到的,一般来说,开发者只处理特殊情况就行了,负担会大大减小。
===========
所以,无论对用户还是对开发者,conary 都是个不错的选择。
现在对用户存在的一个大问题呢,就是 conary 还缺少一个足够简单、但又能发挥其威力的前端,PackageKit 是当前的选择,但是还有很多的工作要做。
想进一步了解的话,请登陆 #foresight (freenode)。
这样,以下内容基本上是这篇文章的意译。
包管理,也就是管理系统上所有其他软件的一个软件。但 conary 不只是一个包管理软件,更是一个强大的对软件系统的版本管理系统。
===========
第一个问题,如何组织软件源(repository)
在 deb/rpm 系统上,一个 repository 无非是某个服务器上的一个目录,其中存放着软件包(一些文件)。文件的命名无非就是"软件名",加上"软件版本"(当然一般还有其他部分,稍后再提)。
问题来自于文件的命名是任意的,手动的。比如有两个软件源,都提供了firefox-3.0 这个包,那么包管理就会搜索到两个"相同"的包,可能产生冲突。
而 conary 不这样处理软件源,conary 的 repository 并不是一个静态的目录,而是一个有版本的动态的分支。整个软件源都是处在版本控制下的,随着其中软件的更新,不断的向前发展,而不是像磁盘文件系统上的一个目录,新版本的文件会覆盖旧文件。
当然,conary 里面的包名字也必须有好几个部分,比如名字加版本。但这些都是由 conary 自动管理,没有手动的过程,conary 能保证两个不同的包,用户能识别出它们确实是不一样的。比如有两个 deb 的源,apt.joeschmoe.com 和 apt.joesmith.com,它们有同一个版本的 liferea,那包名可能是一样的,就会有问题,而 conary 不会遇到这个矛盾,因为,软件源的域名其实也是包名字的一部分。
如果 deb 要以域名来辨别不同的包,那只能把域名写到文件名里面,结果必然是,软件包的名字变得特别长。正因为 conary 下的“包”并不是以文件形式存在的,才能做到上边这一点。
而问题没有到此为止,一般发行版会支持多个硬件平台 (至少有 32 位或 64 位之分吧)。deb/rpm 的做法是什么?只能把 arch 写进文件名里面。结果就是这样的,liferea-1.2.2-2.el5.rf.x86_64.rpm。能看出跟 liferea-1.2.2-2.el5.rf.x86-64.rpm 的区别吗?
conary 也需要支持不用的 arch,包名字也会包含 x86, x86_64 等等。但由于 conary 的“自动管理”,默认情况下这些额外信息是被隐藏的。有时候一个简单的"liferea"就能识别一个包,有时候需要 "liferea=1.0"才能识别, 有时候需要 "liferea=foresight.rpath.org@fl:2-devel" (以区别 "liferea=foresight.rpath.org@fl:2-qa", 或者 "liferea=jesse.rpath.org@fl:2-devel"),有时候甚至需要"liferea=foresight.rpath.org@fl:2-devel/1.7.3-0.1-2",而这就是 conary 里面包的 full-name 的样子。
===========
正由于以上这些,conary 不需要复杂的 sources.list。如果你想从我的个人软件源安装 liferea,在 deb 世界里需要把我的源添加到 sources.list 里边,这样 apt 才能自动从那里查找更新。
而对于 conay, 只需要安装 liferea=jesse.rpath.org@fl:2-devel,conary 会记住这个源,以后只会从这里查找更新,即使 foresight 的官方源里面有更新的版本,也不会影响你的系统。
===========
细粒度的依赖关系
解决依赖是包管理的另一个基本作用,对于 deb/rpm 来说,依赖是定义在包的层面的,带来的一个问题是,有时候要安装某个包,需要先安装一系列的依赖,它们的体积加起来可能很大。另一个问题是,更新的时候,整个包都要重新下载,而好多时候这是不需要的,比如 man page 和一些图片,可能并没有任何变化。
conary 是在文件层次上解决依赖的,所以,一个包并不依赖于另"一个包",而是依赖某个文件的存在。conary 把包划分成几个部分,比如 :runtime, :doc, 或者 :devel,安装依赖包、更新包都是基于这个子部分的,用不到或没有变化的部分就不用下载。好处是可以节省带宽,节省硬盘空间,节省电力,节省能源...
而且这带来了另一个可能:系统可以定制得很小,能够把不需要的都删掉。比如最近我们在裁减 GNOME Developer Kit 的大小,在脚本里有这一句:
r.removeComponents(['doc', 'supdoc', 'build-tree', 'devellib', 'devel'],
'group-gnome-dist')
这样就把所有的文档、开发相关的文件移除了。
当然,deb 和 rpm 也能把一个包划分开 (也就是那些 -devel 包的由来)。问题是,手动。打包的开发者必须在 spec 文件里手动指明哪些文件是 liferea-doc 的,哪些是 liferea-devel 包的。但 conary 能自动完成这些,安装到 /etc 的,一般就是 :config 部分的;在 /user/share/man/ 下的,应该就是 :doc。conary 能识别出 general case 来,开发者只需要做剩下的那一点。
===========
回滚。由于整个系统都是在 conary 的版本管理之下,所以 conary 支持包管理操作的回滚。这个特性是最容易记住的,所以不细说了。
===========
给 conary 打包非常容易,所有的打包过程,都由简短的 python 脚本定义。在我看来,比 rpm 的 spec 文件清晰的多。而且像前面提到的,一般来说,开发者只处理特殊情况就行了,负担会大大减小。
===========
所以,无论对用户还是对开发者,conary 都是个不错的选择。
现在对用户存在的一个大问题呢,就是 conary 还缺少一个足够简单、但又能发挥其威力的前端,PackageKit 是当前的选择,但是还有很多的工作要做。
想进一步了解的话,请登陆 #foresight (freenode)。
Subscribe to:
Posts (Atom)
