背景说明
最近参与到公司的白盒交换机项目中,需要编译ONL和sonic,其中软件源的设置让我非常头疼,编译依赖有很大的问题。决定深入学习一下Linux软件源.主机环境为ubuntu16.04.
软件库存储文件*.list
ubuntu使用apt来管理软件包,apt将软件库存储在如下文件中:
1 | /etc/apt/sources.list |
可以通过man sources.lis来查看apt的完整存储机制。
sources.list格式和写法
- 以
#
开头的行是注释行 - 以deb或deb-src开头的是
apt respository
,具体格式为: - deb:二进制包仓库
- deb-src:二进制包的源码库,不自己看程序或者编译,deb-src可以不要。
- URI: 库所在的地址,可以是网络地址,也可以是本地的镜像地址
- codename:ubuntu版本的代号,可以通过命令
lsb_release -a
来查看当前系统的代号 - components:软件的性质(free或non-free等)
ubuntu系统代号
codename是ubuntu不同版本的代号
版本号 | 代号(codename) |
---|---|
10.04 | lucid |
12.04 | precise |
14.04 | trusty |
14.10 | utopic |
16.04 | xenial |
18.04 | bionic |
deb说明
deb后面的内容有三大部分:deb URI section1 section2
以deb http://us.archive.ubuntu.com/ubuntu/ xenial main restricted
为例进行说明。
URI是库所在的地址,支持http,fpt以及本地路径,访问http://us.archive.ubuntu.com/ubuntu/
可以看到如下信息:dists
和pool
这两个目录比较重要。dists
目录包含了当前库的所有软件包的索引。这些索引通过codename分布在不同的文件夹中。例如xenial
所在的目录。
上图中的文件夹名其实就是对应了section1,我们可以根据需要填写不同的section1.
这里面的文件都是用以下格式命名的:
1 | codename |
打开其中一个任一文件夹,例如xenial-updates
:
里面有main,multiverse,restricted,universe
文件夹,这些文件夹对应deb后面的section2,里面包含了不同软件包的索引。它们的区别在于:
1 | main:完全的自由软件 |
打开main目录下的binary-i386子目录下的Packages.gz文件,可以看到如下内容:
说明:Packages.gz这个文件其实就是一个“索引”文件,里面记录了各种包的包名(Package)、运行平台(Architecture)、版本号(Version)、依赖关系(Depends)、deb包地址(Filename)等。Filename指向的是源服务器pool目录下的某个deb。猜测:apt-get install
某个软件是,其实就是基于这些Packages.gz来计算依赖关系,然后根据其中的filename地址来下载所需的deb,最后执行dpkg -i pacckage.deb
来完成软件包的安装。
替换源
先将默认的sources.list进行备份,然后仿照下表修改源:
1 | # 默认注释了源码镜像以提高 apt update 速度,如有需要可自行取消注释 |
国内镜像网站
这里推荐两个国内镜像网站,一个是清华源,一个是阿里源
找到对应的源后,清华源可以点击源名称后的问号获取源路径,阿里源可以点击源名称所在行的帮助获取源路径。
注意事项:
清华源中源路径默认使用https,需要安装apt-transport-https软件包,否则修改为http进行使用
unmet dependencies
在执行命令apt-get -y build-dep linux
时出现unmet dependencies
错误,如下图所示:
解决方法:
在镜像服务器上可以查询到2.99版本存在,将apt-get
命令换成aptitude
命令,使用apt-get install -y apt-utils aptitude
安装aptitude
Hash Sum Mismatch
在使用阿里源编译sonic源码的时候(debian:stretch),出现Hash Sum Mismatch
的报错。如下图所示:
有些网络服务商,特别是一些小区网络的服务商,为了减少流量费用和提高对常见网络资源的访问速度,很多都搞了这么个东西出来
但是他们的缓存策略有问题,只比对文件路径,不考虑域名/IP地址,也没怎么考虑过文件内容更新后的同步,即缓存服务器上的内容和实际文件的内容可能不一致。
即对于http://example.com/a/b/c.dat这么一个文件,如果被收入缓存,那么你访问其他任意域名下的/a/b/c.dat文件都会去读取被缓存的文件。如果http://example.com/a/b/c.dat有了改变,缓存服务器上的对应文件不一定能跟着更新。
而ubuntu大部分源的文件路径是一致的,所以如果163源中的 http://mirrors.163.com/ubuntu/dists/tru … ources.bz2 被收入缓存,那么你访问官方源 http://archive.ubuntu.com/ubuntu/dists/ … ources.bz2 时,由于路径都是/ubuntu/dists/trusty/main/source/Sources.bz2,还是获取的是缓存服务器上的缓存文件。这个可用wget验证。如果缓存服务器上文件过时了,就会出现Hash Sum Mismatch。
解决方法:
1.更换源,换成清华源就没问题了
2.使用https协议
关于pypi国内源
哈,顺便在这里提一下pip的国内源啦,就不单独写篇文章了。
python使用pip作为包管理工具,类似于debian/ubuntu的apt-get/aptitude和redhat的yum。国内镜像网站可以在上面找到。替换方法如下:
临时使用:
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple some-package
设为默认:
升级 pip 到最新的版本 (>=10.0.0) 后进行配置:
1 | pip install pip -U |
如果您到 pip 默认源的网络连接较差,临时使用本镜像站来升级 pip:pip install -i https://pypi.tuna.tsinghua.edu.cn/simple pip -U
如果不升级pip,那么可以修改pip的配置文件:
修改 ~/.pip/pip.conf (没有就创建一个文件夹及文件)
内容如下:
1 | [global] |
参考资料:
ubuntu论坛