FYI Yu Changyuan <[email protected]> 于 2020年1月11日周六 13:36写道:
> > 大概一年前,[NixOS更换了预编译二进制包的CDN][1],导致国内下载Nix的预编译包非常慢(虽然以前也没快到哪里去),大多时候只有几十K。国内目前没有现成的NixOS镜像,因此想探索一套建NixOS镜像的方法。下面是这段时间我的一些想法,并做了一些实验,欢迎大家提出建议和意见。 > > 关于如何建立NixOS镜像,网上已经有一些讨论: > - [https://nixos.org/nix-dev/2016-October/022029.html][2] > - [https://github.com/NixOS/nixpkgs/issues/32659][3] > - [https://github.com/tuna/issues/issues/323][4] > - [https://github.com/ustclug/mirrorrequest/issues/165][5] > > ## 需要镜像的内容 > > > NixOS通过Nix进行包管理。一般来说,使用Nix安装软件需要下载[Nix频道][6]的相关数据和对应的预编译二进制包。其中Nix频道的数据主要包括了一组Nix表达式(一系列用Nix语言编写的文本文件),这些表达式完整的对Nix的包进行了描述。Nix表达式是通过[git][7]进行管理的,因此会持续更新。 > > Nix频道的数据位于[https://nixos.org/channels/][8] > ,里面包括多个不同的频道,对应不同的NixOS版本,以及非NixOS的Nix包的版本。目前NixOS版本的19.09,对于的频道URL是[ > https://nixos.org/channels/nixos-19.09][9],该URL通过重定向,指向当前NixOS > 19.09验证过的最新的一组数据。具体包括以下内容: > - nixexprs.tar.xz:打包过的Nix表达式,对所有的包进行了描述; > - binary-cache-url:当前Nix表达式包对应的预编译包的下载地址; > - git-revision:当前Nix表达式对应的git版本; > - src-url:当前Nix表达式在hydra上对应的URL; > - store-paths.xz:当前Nix表达式包含的包列表(未包含一些底层间接依赖的包)。 > > 除了上述文件外,还有一些iso和ova文件,可用于安装NixOS。但对于日常NixOS以及Nix的使用来说,并非是必须的。 > > 预编译包可通过Nix频道的binary-cache-url文件查询。目前来说,官方的预编译包位于[https://cache.nixos.org > ][10]。该URL不提供浏览器访问的界面,一般通过Nix包管理器提供的一系列命令进行访问。 > > > ## Nix频道的镜像 > > > Nix频道的镜像比较简单,定期下载从感兴趣的频道URL下载相关文件即可。唯一需要注意的是,需要先获取重定向之后的URL,然后下载,避免下载的文件版本不一致。 > > ## 二进制缓冲的镜像 > > > 预编译的二进制包的镜像相对比较复杂,考虑到不同版本间包存在一定重复情况,需要避免重复下载。总体来说,对于某个版本的Nix频道,可以根据`store-paths.xz`的内容,获取需要下载的包的列表,从`binary-cache-url`指定的URL,依次下载。为了 > 便于管理,每个版本的Nix频道可以对应一个目录用于保存预编译的包。对于Nix来说,每个这样的目录都是一个合法的[Nix存储(Nix > store)][11],可以通过一系列命令进行操作。 > > 具体可以按照如下步骤进行操作: > > 1. 重复包的处理 > * 依次对store-paths.xz内的每个包,通过`nix > path-info`查询该包是否已经包含在其他本地Nix存储(通过`--store`参数指定本地Nix存储的路径)中存在; > * 若存在,则通过`nix path-info > > -r`获取该包以及其所有依赖对应的路径,通过`ln`命令,在目标目录(即新的Nix存储的目录),建立相关`nar`文件和`narinfo`文件的硬链接; > > 2. 重复的依赖包的处理 > 有部分底层的依赖包,也是重复的,可能在上一步未能链接到新的Nix存储中。但从目前的情况看,这种应该情况比较少,暂时略过这步。 > > 3. 新增包的下载 > * 通过命令`xzcat store-paths.xz | xargs nix copy --from > BINARY_CACHE_URL --to file://LOCAL_STORE`进行下载; > * 命令中的`BINARY_CACHE_URL`为文件`binary_cache_url`的内容,一般为` > https://cache.nixos.org`; > * 命令中的`LOCAL_STORE`为需要下载的新的Nix存储的路径; > * `nix`命令会跳过本地已有的包; > > ## 提供服务 > > > 下载好Nix频道的文件以及对应的二进制缓冲后,可以通过HTTP服务方式,对外提供镜像。对于每个Nix频道来说,对外提供的镜像需要包括2个URL,即Nix频道的URL和二进制缓冲的URL。 > > * HTTP服务器仅需要提供本地文件下载服务即可; > * > Nix频道镜像的URL指向最新的本地Nix频道的文件。需要注意的是,其中`binary_cache_url`文件需要修改,改为本地镜像的二进制缓冲URL; > * > 二进制缓冲镜像的URL指向Nix频道对应的本地的Nix存储的路径。亦可以考虑类似`overlayfs`的方式,把所有本地的Nix存储合并起来,提供服务。 > > ## 过期数据的清理 > > 1. 对于Nix频道和二进制缓冲的数据,定期删除对应目录即可; > 2. 对于本机的Nix存储(`/nix/store`),定期执行`nix-collect-garbage -d`即可。 > > ## 一些实验数据 > > 下面是这几天对`nixos-19.09`频道进行实验,统计的一些数据: > > * `store-paths.xz`行数约38K; > * 对应的Nix存储(通过`nix copy`下载): > * 约45K个`narinfo`文件(大多数小于1K); > * 约45K个`nar`文件(xz压缩格式),大小不一; > * >10K的约34K个; > * >1M的约5K个; > * >10M的约1K个; > * >100M的约150个; > * 最大的约900M; > * 一共80G。 > * 2020年1月11日的`store-paths.xz`有37969行,其中36187行和2020年1月6日的相同: > * 约99%的包是不变的; > * 考虑到底层依赖的包,这个比例应该更高。 > > ## 参考 > > [1]: > https://discourse.nixos.org/t/the-nixos-cache-is-now-hosted-by-fastly/1061 > [2]: https://nixos.org/nix-dev/2016-October/022029.html > [3]: https://github.com/NixOS/nixpkgs/issues/32659 > [4]: https://github.com/tuna/issues/issues/323 > [5]: https://github.com/ustclug/mirrorrequest/issues/165 > [6]: https://nixos.wiki/wiki/Nix_channels > [7]: https://github.com/NixOS/nixpkgs > [8]: https://nixos.org/channels/ > [9]: https://nixos.org/channels/nixos-19.09 > [10]: https://cache.nixos.org > [11]: https://nixos.org/nix/manual/#ch-about-nix > > -- > -- You received this message because you are subscribed to the Google > Groups Shanghai Linux User Group group. To post to this group, send email > to [email protected]. To unsubscribe from this group, send email to > [email protected]. For more options, visit this group at > https://groups.google.com/d/forum/shlug?hl=zh-CN > --- > 您收到此邮件是因为您订阅了 Google 网上论坛的“Shanghai Linux User Group”群组。 > 要退订此群组并停止接收此群组的电子邮件,请发送电子邮件到[email protected]。 > 要在网络上查看此讨论,请访问 > https://groups.google.com/d/msgid/shlug/CALP3OrVXopd7pno5h5Q4iCtynw%2B2Y4DWOTx0s2CHftJe%3DGXyxg%40mail.gmail.com > 。 > -- -- You received this message because you are subscribed to the Google Groups Shanghai Linux User Group group. To post to this group, send email to [email protected]. To unsubscribe from this group, send email to [email protected]. For more options, visit this group at https://groups.google.com/d/forum/shlug?hl=zh-CN --- 您收到此邮件是因为您订阅了 Google 网上论坛的“Shanghai Linux User Group”群组。 要退订此群组并停止接收此群组的电子邮件,请发送电子邮件到[email protected]。 要在网络上查看此讨论,请访问 https://groups.google.com/d/msgid/shlug/CAG%2Bqr1H6-v0rnRAkPk6rj3jyWoAdy0L9pa_rW3%3DvGtDRU3sOvg%40mail.gmail.com。
