十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Nix 2.20.0 发布详解:eval-system、mounted-ssh-ng、nix hash convert 与 CLI 重构全解析

Nix 2.20.0 发布详解:eval-system、mounted-ssh-ng、nix hash convert 与 CLI 重构全解析 Nix 2.20.0 发布详解eval-system、mounted-ssh-ng、nix hash convert 与 CLI 重构全解析【免费下载链接】nixNix, the purely functional package manager项目地址: https://gitcode.com/gh_mirrors/ni/nix导读Nix 2.20.02024-01-29 发布是一次功能与工程质量并重的重要版本涵盖求值语义、远程构建、存储后端、CLI 重构与错误信息体验等多个维度新增eval-system设置以解耦求值系统与调度系统、引入mounted-ssh-ng://存储类型、将散列格式base32更名为nix32并把nix show-config/nix doctor重组为nix config show/nix config check。阅读本文后你将掌握这些新特性的设计动机、实际用法、迁移路径以及它们对应的源码级实现原理。本文以仓库内的 Release 2.20.0 发布说明 为主体骨架并结合 src/nix 命令实现、src/libexpr 求值器实现与 src/libstore 存储层源码进行交叉印证。一、求值与调度解耦新增eval-system设置1.1 背景与动机在 2.20 之前system设置同时承担两个职责既决定builtins.currentSystem的值又影响派生式的调度决策Nix 会选择哪些机器来构建派生式。这在在一台机器上求值、到另一种架构的远程构建器上构建的场景中会造成问题——覆盖system会诱使 Nix 在本地构建本不该本地构建的派生式。2.20.0 新增的eval-system选项将二者解耦它只覆盖builtins.currentSystem的值完全不干预调度。正如发布说明所指出的这比覆盖system更有用因为你可以把求值得到的派生式交给能处理给定系统的远程构建器。1.2 语义与默认值关键语义必须严格遵守否则会产生破坏性变更仅当eval-system为非空字符串时才生效为空默认值时回退到system的值与 2.20 之前的行为完全一致因此不存在兼容性破坏。1.3 源码实现该设置定义于 eval-settings.hhSettingstd::string currentSystem{ this, , eval-system, R( This option defines builtins.currentSystem in the Nix language if it is set as a non-empty string. Otherwise, if it is defined as the empty string (the default), the value of the [system](#conf-system) configuration setting is used instead. ... )};从源码可以看到eval-system的默认值为空字符串且其文档明确强调Unlikesystem, this setting does not change what kind of derivations can be built locally与system不同该设置不会改变本地可构建的派生式类型。getCurrentSystem()方法同文件第 183 行声明实现了eval-system与system之间的默认值回退逻辑即eval-system非空时用它否则用system。1.4 实际用法# 在 x86_64 机器上求值 aarch64 的派生式但调度逻辑不受影响 nix eval --eval-system aarch64-linux nixpkgs#legacyPackages.aarch64-linux.hello.drvPath # 结合远程构建器使用 nix build --eval-system aarch64-linux --builders ssh://builderarm-host aarch64-linux ...二、存储层新成员mounted-ssh-ng 存储2.1 特性概述2.20.0 引入了新的存储类型mounted-ssh-ng://[username]hostname它允许对远程机器上的 Nix 存储进行完全访问同时额外要求该存储已挂载到本地文件系统中。挂载动作不由 Nix 管理需要用户手动完成例如通过 SSHFS 或 NFS。这一点在 mounted-ssh-store.md 中有明确说明。2.2 设计动机两个层面的收益从 mounted-ssh-store.md 的说明可以总结出两个核心收益性能优化既然存储已挂载到本地文件系统就不必把 NARNix 归档序列化后通过 Nix 通道传输可以直接通过挂载点访问文件系统数据能力扩展本地文件系统还被用来实现原本不可能的操作。例如当持久化 GC 根与远程存储在同一个文件系统上时可以创建持久化 GC 根——远程侧会创建必要的符号链接以避免竞态条件。2.3 与其他存储类型的对比存储类型远程访问本地挂载要求典型场景ssh:///ssh-ng://通过 SSH 协议访问无普通远程构建、复制mounted-ssh-ng://通过 SSH 协议访问有SSHFS/NFS 等需要 GC 根、追求更高吞吐的远程存储操作2.4 使用示例# 假设远程存储已通过 SSHFS 挂载到 /mnt/remote-nix nix store gc --store mounted-ssh-ng://builderremote-host nix copy --to mounted-ssh-ng://builderremote-host ...完整的存储类型说明可参考 help-stores.md。三、CLI 重构nix config show与nix config check3.1 重命名内容为与其他命令行接口保持一致2.20.0 将两个命令更名nix show-config→nix config shownix doctor→nix config check3.2 源码印证命令注册位于 config.ccstatic auto rCmdConfig registerCommandCmdConfig(config); static auto rShowConfig registerCommand2CmdConfigShow({config, show});config check的实现位于 config-check.ccstatic auto rCmdConfigCheck registerCommand2CmdConfigCheck({config, check});旧命令名并未立刻消失在 main.cc 中show-config被注册为指向config show的Deprecated 别名旧用法仍可用但会提示弃用。# 新命令 nix config show nix config check # 旧命令已弃用但 2.20 仍可用 nix show-config nix doctor四、散列工具升级nix hash convert与nix32命名4.1 新命令nix hash convert2.20.0 新增nix hash convert取代旧的nix hash to-*子命令。旧命令仍然可用但会发出弃用警告。迁移对照如下原发布说明的完整对照表旧命令新命令nix hash to-base16 $hash1 $hash2nix hash convert --to base16 $hash1 $hash2nix hash to-base32 $hash1 $hash2nix hash convert --to nix32 $hash1 $hash2nix hash to-base64 $hash1 $hash2nix hash convert --to base64 $hash1 $hash2nix hash to-sri $hash1 $hash2nix hash convert --to sri $hash1 $hash2或直接nix hash convert $hash1 $hash2注意nix hash convert默认不带--to输出 SRI 格式因此最后一个场景甚至可以省略--to sri。4.2 源码实现命令注册代码位于 hash.cc{convert, []() { return make_refCmdHashConvert(); }}, {to-base16, []() { return make_refCmdToBase(HashFormat::Base16); }}, {to-base32, []() { return make_refCmdToBase(HashFormat::Nix32); }}, {to-base64, []() { return make_refCmdToBase(HashFormat::Base64); }}, {to-sri, []() { return make_refCmdToBase(HashFormat::SRI); }},注意第 270 行旧的to-base32子命令在内部已经被映射到HashFormat::Nix32与 4.3 节的命名统一相呼应。同时源码中通过warn(The old format conversion subcommands ofnix hashwere deprecated in favor ofnix hash convert.)实现弃用警告。nix hash convert的详细用法可查看 hash-convert.md。4.3 散列格式重命名base32→nix32由于 Nix 的 Base32 实现使用了 Nix 特有的字符集与标准 Base32 不同base32这一名称具有误导性因此更名为nix32。这意味着新代码中应使用nix32作为格式名涉及散列格式的配置与脚本需要同步更新名称。nix hash convert --to nix32 hash五、远程构建与复制行为变更5.1nix copy到ssh-ng存储需显式-s行为变更向ssh-ng存储执行nix copy时现在必须显式传递--substitute-on-destination简称-s才会在远程存储上**替换substitute**路径而非直接复制这与向其他类型远程存储复制时的行为保持一致。在 2.20 之前该行为由builders-use-substitutes设置控制且--substitute-on-destination会被忽略。如果你的工作流依赖旧行为请迁移为显式传参# 旧行为由 builders-use-substitutes 控制 # 新行为显式指定 nix copy --to ssh-ng://builderremote-host -s path5.2 通过 daemon 构建时包含 cgroup 统计2.20.0 起通过 Nix daemon 构建以及使用ssh-ng进行远程构建时Nix 也会报告 cgroup 统计信息前提是连接双方都使用 Nix 2.20 或更新版本。这意味着远程构建与守护进程构建的资源监控数据得以补齐与本地构建的观测能力对齐。六、搜索、安全与评估相关改进6.1nix search要求非空搜索正则nix search现在强制要求传入搜索正则。若要列出所有包请使用^nix search nixpkgs ^ nix search nixpkgs python6.2allowed-uris支持无斜杠的完整 scheme 匹配allowed-uris选项现在可以匹配 URI 中的完整 scheme即使该 scheme 的 URI 不含://。例如在allowed-uris中指定github:则所有以github:开头的 URI 都会被允许。此前该能力仅适用于使用://语法的 scheme。# nix.conf 示例 allowed-uris github: https://example.com/6.3 Import-from-derivation 在构建存储中构建派生式使用--eval-store时import一个派生式IFD现在会在构建存储即storeNix 选项中指定的存储中构建该派生式。由于结果 Nix 表达式必须复制回求值存储才能被导入这要求求值存储信任构建存储的签名。七、错误信息体验全面改进2.20.0 在错误报告方面有一批聚焦的改进从源码角度可以确认这些改动集中在 libexpr 的错误处理与打印路径上。7.1 强制转换错误包含失败值error: cannot coerce a TYPE to a string消息现在会附带引发错误的值# 之前 error: cannot coerce a set to a string # 之后 error: cannot coerce a set to a string: { aesSupport «thunk»; avx2Support «thunk»; avx512Support «thunk»; avxSupport «thunk»; canExecute «thunk»; config «thunk»; darwinArch «thunk»; darwinMinVersion «thunk»; darwinMinVersionVariable «thunk»; darwinPlatform «thunk»; «84 attributes elided»}7.2 类型错误包含失败值类似地value is an integer while a list was expected这类错误现在也会包含失败值# 之前 error: value is a set while a string was expected # 之后 error: expected a string but found a set: { ghc810 «thunk»; ghc8102Binary «thunk»; ghc8107 «thunk»; ghc8107Binary «thunk»; ghc865Binary «thunk»; ghc90 «thunk»; ghc902 «thunk»; ghc92 «thunk»; ghc924Binary «thunk»; ghc925 «thunk»; «17 attributes elided»}7.3 源码位置更一致地出现在错误中错误消息现在更一致地包含源码位置信息。对于以下代码let attr {foo bar;}; key {}; in attr.${key}之前只显示无帮助的error: … while evaluating an attribute name error: value is a set while a string was expected现在会精确定位问题值所在位置error: … while evaluating an attribute name at bad.nix:4:11: 3| key {}; 4| in attr.${key} | ^ 5| error: expected a string but found a set7.4with表达式错误定位改进with表达式使用非 attrset 值解析变量时现在会报告正确位置nix-repl with 1; a error: … while evaluating the first subexpression of a with expression at «string»:1:1: 1| with 1; a | ^ error: expected a set but found an integer7.5 函数打印更详细nix repl、nix eval、builtins.trace以及大多数打印值的地方现在会包含函数名和源码位置信息$ nix repl nixpkgs nix-repl builtins.map «primop map» nix-repl builtins.map lib.id «partially applied primop map» nix-repl builtins.trace lib.id my-value trace: «lambda id /nix/store/kgr5lnaiiv08wb7k324yv1i1npjmrvjc-source/lib/trivial.nix:26:5» my-value7.6 修复部分栈溢出段错误max-call-depth嵌套函数调用数量现在受到限制用于检测并报告无限函数调用递归。默认最大调用深度为10,000可通过max-call-depth配置项调整。这取代了原先的stack overflow (possible infinite recursion)消息。源码中该设置的默认值定义于 eval-settings.hhSettingunsigned int maxCallDepth{ this, 10000, max-call-depth, The maximum function call depth to allow before erroring.};# 按需调整最大调用深度 nix eval --option max-call-depth 50000 --expr ...八、nix profile与nix store add改进8.1nix profile支持人类可读名称引用元素nix profile的list、remove、upgrade子命令现在使用名称而非索引来引用已安装的包。Profile 元素名称在安装包时生成并在包被移除前保持不变nix profile list # 假设某元素名为 hello nix profile remove hello nix profile upgrade hello⚠️ 兼容性警告记录 profile 内容的manifest.nix文件格式已改变。当你修改 profile 时Nix 会自动将 profile 升级到新版本此后该 profile 将无法再被旧版 Nix 使用。升级前请确认团队环境中的 Nix 版本。8.2nix store add新增--hash-algo标志nix store add获得了--hash-algo标志补上了旧 CLI 中缺失的功能并与计划中nix hash convert、nix hash path的同类标志保持一致nix store add --hash-algo sha256 ./some-file九、稳定性与健壮性改进9.1 Flake 操作不再因.gitignore的flake.lock失败nix develop等 Flake 操作在flake.lock文件被.gitignore忽略的 Git 仓库中执行时不再失败。此前这会触发错误2.20.0 修复了该问题对应 issue #8854 与 PR #9324。9.2 Nix 命令现在响应 Ctrl-C此前许多 Nix 命令包括nix develop、nix flake update等在执行各类操作时按 Ctrl-C 会无限期挂起。2.20.0 修复了若干信号处理器问题后Nix 命令会在按下 Ctrl-C 后快速退出。十、升级与迁移速查旧用法新用法nix show-confignix config show旧名保留为弃用别名nix doctornix config checknix hash to-base16 $hnix hash convert --to base16 $hnix hash to-base32 $hnix hash convert --to nix32 $hnix hash to-base64 $hnix hash convert --to base64 $hnix hash to-sri $hnix hash convert $h默认 SRI散列格式base32散列格式nix32依赖builders-use-substitutes控制nix copy显式传入-s/--substitute-on-destination参考与延伸阅读发布说明原文rl-2.20.mdeval-system设置源码eval-settings.hhmax-call-depth设置源码eval-settings.hhmounted-ssh-ng://存储说明mounted-ssh-store.md存储类型总览help-stores.mdnix config命令实现config.cc / config-check.ccnix hash命令实现hash.cc、用法文档hash-convert.md其他版本发布说明索引release-notes 索引【免费下载链接】nixNix, the purely functional package manager项目地址: https://gitcode.com/gh_mirrors/ni/nix创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表