新闻详情

新闻详情

首页 / 资讯中心 / 详情

Nixpkgs vmTools 完全指南:在 QEMU/KVM 虚拟机中构建与测试 Nix 软件包

发布时间:2026/9/13 14:12:18来源:尧图网络
Nixpkgs vmTools 完全指南:在 QEMU/KVM 虚拟机中构建与测试 Nix 软件包
Nixpkgs vmTools 完全指南在 QEMU/KVM 虚拟机中构建与测试 Nix 软件包【免费下载链接】nixpkgsNix Packages collection NixOS项目地址: https://gitcode.com/GitHub_Trending/ni/nixpkgs本篇指南以 Nixpkgs 的 vmTools 官方文档 为核心结合 vmTools 源码实现 与 测试用例系统讲解如何利用pkgs.vmTools在 QEMU/KVM 虚拟机中构建软件包、在非 NixOS 发行版镜像内编译、提取 ISO 文件系统内容以及生成可交互调试的磁盘镜像。读完本文你将掌握createEmptyImage、runInLinuxVM、runInLinuxImage、extractFs、diskImageFuns等全部核心 API 的参数、用法与底层原理并能直接将其应用到自己的 Nix 表达式中。vmTools 是什么一套面向高级构建场景的虚拟机工具集vmTools是 Nixpkgs 提供的一组与虚拟机相关的工具用于帮助在更高级的场景下构建某些软件包。它的入口定义在 pkgs/top-level/all-packages.nixvmTools callPackage ../build-support/vm { };也就是说pkgs.vmTools实际由 pkgs/build-support/vm/default.nix 实现。该模块完整导出了下列成员见源码末尾的inherit列表createEmptyImage— 生成空白磁盘镜像的 bash 脚本片段runInLinuxVM— 在 Linux 虚拟机中运行任意 derivationextractFs/extractMTDfs— 提取 ISO 等文件的文件系统内容到 Nix storerunInLinuxImage— 在指定的发行版镜像内构建使用镜像自带的/bin、/usr/bin工具makeImageTestScript— 生成在指定镜像中启动交互式会话的脚本diskImageFuns/diskImageExtraFuns/diskImages— 预定义 Linux 发行版镜像的构建函数与默认镜像以及buildRPM、fillDiskWithRPMs、fillDiskWithDebs、rpmClosureGenerator、debClosureGenerator、makeImageFromRPMDist、makeImageFromDebDist等镜像组装基础设施典型的应用场景包括把在 Nix 沙箱里无法复现的构建如依赖非 NixOS 发行版二进制工具链的软件搬进虚拟机执行、在 Fedora/Ubuntu/Debian 等真实发行版环境里跑测试以及把 ISO 安装盘中的文件提取出来直接使用。vmTools 的可配置接口从 default.nix 的参数可以看出vmTools还提供了一组可覆盖的接口参数参数默认值说明customQemunull自定义 QEMU 可执行文件非空时替代默认的buildPackages.qemu_kvmkernellinux虚拟机使用的内核 derivationkernelImagekernel.target内核输出中可启动镜像文件的名称如bzImage、Image若kernel没有target属性会直接报错提示kernelModuleskernel提供lib/modules给 VM initrd 的包可用pkgs.aggregateModules [...]覆盖以便在不更换启动内核的情况下把额外内核模块送进 VMstoreDirbuiltins.storeDirNix store 路径默认即宿主机 store 路径rootModules见源码initrd 中加载的根文件系统模块包括virtio_pci、virtio_mmio、virtio_blk、virtio_balloon、virtio_rng、ext4、virtiofs、crc32c等此外整个 vmTools 采用stdenv、bash、busybox、cpio、dpkg、e2fsprogs、mtdutils、rpm、virtiofsd等 Nixpkgs 包搭建 VM 运行环境镜像内容则通过fetchurl从各发行版官方仓库获取。vmTools.createEmptyImage生成空白磁盘镜像createEmptyImage是一个bash 脚本片段fragment其作用是在指定位置产生一个磁盘镜像文件供后续附加到虚拟机中。参数说明参数是否必填默认值说明size必填—磁盘大小单位为 MiB1024×1024 字节fullName必填—写入${destination}/nix-support/full-name的名称destination可选$out镜像文件的写入位置源码剖析脚本片段到底做了什么对应实现位于 default.nixcreateEmptyImage { size, fullName, destination ? $out, }: mkdir -p ${destination} diskImage${destination}/disk-image.qcow2 ${qemu}/bin/qemu-img create -f qcow2 $diskImage ${toString size}M mkdir ${destination}/nix-support echo ${fullName} ${destination}/nix-support/full-name ;可以看到它做了三件事创建目标目录用qemu-img create -f qcow2创建一个大小由size单位 MiB拼成1024M这样的参数决定的qcow2 格式镜像固定命名为disk-image.qcow2写入nix-support/full-name元数据文件记录镜像的全名。注意它返回的是一段脚本文本不是 derivation。这正是它通常被赋值给preVM使用的原因——preVM就是一段在宿主机上、虚拟机启动之前求值的 shell 命令详见下文runInLinuxVM的vmRunCommand中eval $preVM的调用。实操示例创建 1 GiB 空白镜像{ pkgs }: with pkgs; with vmTools; runInLinuxVM ( hello.overrideAttrs (_: { preVM createEmptyImage { size 1024; fullName vm-image; }; }) )vmTools.runInLinuxVM在 QEMU/KVM 虚拟机中运行任意 derivationrunInLinuxVM是 vmTools 的核心函数它把任意 derivation 放进一台由 QEMU/KVM 驱动的 Linux 虚拟机中执行。默认的虚拟机形态tmpfs 根文件系统 共享 Nix store默认情况下虚拟机没有磁盘镜像根文件系统是一个tmpfs对应源码 stage1 中的mount -t tmpfs none /fsNix store 通过 virtiofs 与宿主机共享源码中使用-device vhost-user-fs-pci,chardevstore,tagstore与mount -t virtiofs store /fs${storeDir}建立共享宿主机的临时目录也通过第二个 virtiofs 卷tag 为xchg挂载到 VM 内的/tmp/xchg用于回传构建退出码等数据。因此任何纯 Nix derivation 都可以原样在 VM 里运行不需要修改构建脚本。这正是 test.nix 中buildHelloInVM runInLinuxVM hello;、buildPatchelfInVM runInLinuxVM patchelf;这类直接包一层用法的前提。失败调试-K/--keep-failed与run-vm脚本如果构建失败且 Nix 以-K/--keep-failed选项运行那么临时构建目录中会留下一个名为run-vm的脚本。运行它即可重新启动这台 VM进入交互式环境排查问题。这个脚本的生成逻辑在源码 default.nixvmRunCommand会把启动 QEMU 的完整命令含 virtiofsd 守护进程的启动、等待 socket 创建等写入./run-vm并chmod x构建时直接source ./run-vm。VM 内的 stage2 脚本default.nix还有一层贴心逻辑如果发现镜像上已存在/.debug标记就不再重复执行原构建而是直接进入交互式 bashexec ${busybox}/bin/setsid ${bashInteractive}/bin/bash并提示(To run the original builder: $origBuilder $origArgs)。换句话说第一次进入调试是执行构建之后再次进入就直接给 shell。参数说明参数是否必填默认值说明preVM可选—在宿主机上、VM 启动之前求值的 shell 命令memSize可选512VM 内存大小单位 MiB1024×1024 字节diskImage可选—附加到/dev/sda的文件系统镜像注意当前实现期望镜像内含一个文件系统而不是带分区表的完整磁盘镜像从 default.nix 的实现看runInLinuxVM通过lib.overrideDerivation重写 derivation设置requiredSystemFeatures [ kvm ]Nix 会据此把构建调度到支持 KVM 的机器上把builder替换成一段 bash 脚本即vmRunCommand通过env.QEMU_OPTS注入-m memSize以及memory-backend-memfd、shareon等内存配置shareon是 virtiofs 共享 store 所必需的保留原builder与args为origBuilder/origArgs供 VM 内部继续执行原构建。源码还支持通过enableParallelBuilding自动配置多核当其为1时QEMU 会按NIX_BUILD_CORES或nproc追加-smp cpusN参数上限 255 个 vCPU见 default.nix。示例 1在 VM 中构建 hello{ pkgs }: with pkgs; with vmTools; runInLinuxVM hello示例 2在 VM 中构建并加大内存{ pkgs }: with pkgs; with vmTools; runInLinuxVM ( hello.overrideAttrs (_: { memSize 1024; }) )提示memSize等属性是 derivation 的属性所以要通过overrideAttrs注入这正是文档示例使用hello.overrideAttrs (_: { memSize 1024; })的原因。示例 3配合createEmptyImage使用磁盘镜像preVM中调用createEmptyImage会隐式设置diskImage变量脚本片段里diskImage${destination}/disk-image.qcow2使 VM 拥有持久磁盘{ pkgs }: with pkgs; with vmTools; runInLinuxVM ( hello.overrideAttrs (_: { preVM createEmptyImage { size 1024; fullName vm-image; }; }) )vmTools.extractFs与vmTools.extractMTDfs提取文件系统内容extractFs从 ISO 等文件中提取内容extractFs接收一个文件例如 ISO 镜像把它的文件系统内容解包并放入 Nix store。其实现位于 default.nix本质上是在runInLinuxVM中运行一段stdenv.mkDerivation先通过kmod加载loop、ext4、hfs、hfsplus、squashfs、iso9660、ufs、cramfs等内核模块使 VM 内核对各种文件系统都有读取能力用mount -o loop,ro把目标文件挂载到tmp若传入fs则加上-t fs指定文件系统类型且优先尝试ufstype44bsd挂载选项用cp -Rv tmp/* $out/把内容复制进 derivation 输出。参数说明参数是否必填默认值说明file必填—要提取的文件路径当前实现期望文件内含一个文件系统而非带分区表的完整磁盘镜像fs可选—文件内容的文件系统类型会传给mount -t示例提取 ISO 内容{ pkgs }: with pkgs; with vmTools; extractFs { file ./image.iso; }extractMTDfs基于 Memory Technology Device 的提取extractMTDfs与extractFs类似但使用Memory Technology DeviceMTD来读取目标文件。对应实现见 default.nix它在 VM 内加载mtd、mtdram、mtdchar、mtdblock、jffs2、zlib等模块用mtdram total_size131072模拟 128 MiB 的 RAM MTD 设备然后dd if${file} of/dev/mtd0把文件写入设备最后mount /dev/mtdblock0并复制内容。该函数适用于 JFFS2 等以 MTD 为载体的固件/文件系统镜像。vmTools.runInLinuxImage在发行版镜像内部构建runInLinuxImage与runInLinuxVM类似但不再使用 Nix store 里的 stdenv 工具链而是改用指定文件系统镜像中/bin、/usr/bin等路径提供的工具——这通常是一个遵循FHSFilesystem Hierarchy Standard的 Linux 发行版根文件系统。底层实现要点从 default.nix 可以看到它的关键差异设置mountDisk true让 VM 把磁盘镜像挂载为根文件系统stage1 中mount /dev/${hd} /fs通过preVM用qemu-img create -b origImage -f qcow2基于原镜像创建一个copy-on-writeCoW临时镜像避免写入原镜像若diskImage是一个目录则自动定位其中的disk-image.qcow2通过postHook在进入构建后把PATH设为/usr/bin:/bin:/usr/sbin:/sbin、SHELL设为/bin/sh把环境切换到发行版原生的工具链将fixupPhase置为true跳过 patchelf 等 Nix 特有阶段——因为目标产物要交给发行版环境使用。用法示例test.nix 给出了标准用法先构建好一个diskImages镜像再在stdenv.mkDerivation中通过diskImage、diskImageFormat、memSize指定运行环境{ pkgs }: let inherit (pkgs.vmTools) diskImages runInLinuxImage; in runInLinuxImage ( pkgs.stdenv.mkDerivation { inherit (pkgs.patchelf) pname version src; diskImage diskImages.debian13x86_64; diskImageFormat qcow2; memSize 512; } )在 Fedora 镜像内构建 hello 同理只需把diskImage换成diskImages.fedora42x86_64见 test.nix。测试文件还验证了镜像内dpkg与perl的真实可用性checkPerlInstalledInDebian见 test.nix可作为镜像构建是否成功的验收参考。vmTools.makeImageTestScript为镜像生成交互式测试脚本makeImageTestScript为给定镜像生成一个脚本运行该脚本可以在该镜像中启动交互式会话。其实现位于 default.nix生成的脚本接受一个参数CoW 临时文件路径若该文件不存在则基于镜像的disk-image.qcow2创建一个 copy-on-write 副本然后设置空的origBuilder/origArgs这样 stage2 会直接进入交互式 shell通过mountDisk1挂载镜像为根文件系统并启动 QEMU。示例 1Fedora 43 交互式会话{ pkgs }: pkgs.vmTools.makeImageTestScript pkgs.vmTools.diskImages.fedora43x86_64示例 2Ubuntu 24.04 交互式会话{ pkgs }: pkgs.vmTools.makeImageTestScript pkgs.vmTools.diskImages.ubuntu2404x86_64生成的脚本用法为./script copy-on-write-temp-file。整套预定义镜像对应的测试脚本都被列在 test.nix 中方便逐个验证。预定义发行版镜像diskImageFuns、diskImageExtraFuns与diskImagesdiskImageFuns是一组函数用于构建一套预定义的最小 Linux 发行版镜像。这套镜像由源码中的rpmDistrosRPM 系与debDistrosDpkg 系两大数据集驱动见 default.nix。可用镜像一览发行版可用镜像Fedorafedora42x86_64、fedora43x86_64Rocky Linuxrocky9x86_64、rocky10x86_64AlmaLinuxalma9x86_64、alma10x86_64Oracle Linuxoracle9x86_64Amazon Linuxamazon2023x86_64Ubuntuubuntu2204i386、ubuntu2204x86_64、ubuntu2404x86_64Debiandebian11i386、debian11x86_64、debian12i386、debian12x86_64、debian13i386、debian13x86_64注意镜像名称与具体发行版版本一一对应且以fetchurl固定了仓库元数据 hash。以 Ubuntu 为例源码同时定义了ubuntu2604x86_64等较新条目具体可用集合请以当前仓库 default.nix 的rpmDistros/debDistros为准。RPM 系镜像通过rpmClosureGeneratorfillDiskWithRPMs生成Fedora/Rocky/Alma/Oracle 均使用各自的 BaseOS AppStream 元数据Dpkg 系镜像则通过debClosureGeneratorfillDiskWithDebs生成Debian 使用 snapshot.debian.org 快照Ubuntu 使用 snapshot.ubuntu.com 快照。参数说明参数是否必填默认值说明size可选4096镜像大小单位 MiB即默认 4 GiBextraPackages可选—需要额外加入镜像的发行版软件包名称列表除了这两个公开参数源码实现还暴露了packages整体覆盖默认软件包集合、preInstall/postInstall安装前后钩子、QEMU_OPTS、memSize、runScripts、unifiedSystemDir等底层参数见makeImageFromRPMDist/makeImageFromDebDist的定义。各发行版的默认基础包集合也定义在源码中baseRHELFamilyPackages包含 autoconf、automake、gcc-c、rpm、rpm-build 等default.nixcommonDebPackages则包含 dpkg、libc6-dev、g、make、coreutils、login、passwd 等default.nix。示例8 GiB 且带 Firefox 的 Ubuntu 24.04 镜像{ pkgs }: pkgs.vmTools.diskImageFuns.ubuntu2404x86_64 { extraPackages [ firefox ]; size 8192; }diskImageExtraFuns与diskImages两个便捷简写diskImageExtraFuns是vmTools.diskImageFuns.attr { extraPackages ...; }的简写其实现为f { inherit extraPackages; }见 default.nix即每个属性直接接收一个包名列表{ pkgs }: pkgs.vmTools.diskImageExtraFuns.fedora43x86_64 [ vim ]diskImages则是vmTools.diskImageFuns.attr { }的简写——即以默认参数实例化全部镜像见 default.nix。上文runInLinuxImage与makeImageTestScript示例中使用的diskImages.debian13x86_64、diskImages.fedora43x86_64正来源于此。结语vmTools 的适用边界与调试建议综合官方文档与源码实现使用 vmTools 时有几点值得记住纯 Nix 构建优先用runInLinuxVM默认 tmpfs 根文件系统 virtiofs 共享 Nix store 的架构让任何纯 derivation 无需改动即可在 VM 内运行且天然继承了 Nix 的可复现性。需要发行版原生环境时用runInLinuxImage它会通过 CoW 镜像保护原镜像不被写入并把PATH、SHELL切换到镜像内 FHS 布局的工具链适合构建 RPM/deb 或验证软件在特定发行版上的行为。镜像生成链条完整透明从fetchurl抓取发行版仓库元数据经rpmClosureGenerator/debClosureGenerator生成闭包表达式再到fillDiskWithRPMs/fillDiskWithDebs在 VM 内解包安装整条流水线都可以在 pkgs/build-support/vm/default.nix 中逐段查阅。遇到构建失败不要慌用nix build -K保留构建目录然后运行遗留的run-vm脚本即可进入 VM 交互式 shellstage2 的第二次进入直接给 shell机制会让调试体验顺畅许多。注意 KVM 前提runInLinuxVM要求机器具备 KVM 能力requiredSystemFeatures [ kvm ]本地或 CI 环境需要相应支持。如需查看更多官方说明可回到 vmTools 章节文档 及其所在的 构建帮助文档目录并结合 vmTools 测试集 把每个 API 的用法跑一遍这是最快的内化路径。【免费下载链接】nixpkgsNix Packages collection NixOS项目地址: https://gitcode.com/GitHub_Trending/ni/nixpkgs创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

Springboot+Vue秒杀系统设计与实现:Redis预减库存与RabbitMQ异步下单 2026/9/13 14:45:21

Springboot+Vue秒杀系统设计与实现:Redis预减库存与RabbitMQ异步下单

简介:这是一份基于Spring Boot和Vue的秒杀系统毕业设计项目包,面向Java学习者、毕业设计学生以及需要前后端分离实战案例的开发者。项目源码已经过导师指导与答辩评审,定位在高并发抢购场景的完整教学与演示,覆盖后端接口、前端页…

阅读更多 →
SSM框架游戏论坛源码解析:三层架构、部署与答辩全流程 2026/9/13 14:45:21

SSM框架游戏论坛源码解析:三层架构、部署与答辩全流程

简介:这份SSM游戏论坛源码与毕业设计论文文档,面向准备Java Web毕业设计或课程设计的学生,也适合希望快速上手SSM(SpringSpringMVCMyBatis)整合开发的Java学习者。项目以游戏贴吧为场景,完整实现用户注册登…

阅读更多 →
DeepEval Traced Evals 实战指南:将指标挂载到 Trace 与 Span 的单轮评估范式 2026/9/13 14:45:21

DeepEval Traced Evals 实战指南:将指标挂载到 Trace 与 Span 的单轮评估范式

DeepEval Traced Evals 实战指南:将指标挂载到 Trace 与 Span 的单轮评估范式 【免费下载链接】deepeval The LLM Evaluation Framework 项目地址: https://gitcode.com/GitHub_Trending/de/deepeval Traced Evals 是 DeepEval 在应用具备可观测性&#xff0…

阅读更多 →
Kubo(Go 版 IPFS)AI 开发协作指南:AGENTS.md 核心规范、构建测试工作流与稳定性红线 2026/9/13 14:45:21

Kubo(Go 版 IPFS)AI 开发协作指南:AGENTS.md 核心规范、构建测试工作流与稳定性红线

Kubo(Go 版 IPFS)AI 开发协作指南:AGENTS.md 核心规范、构建测试工作流与稳定性红线 【免费下载链接】kubo IPFS implementation in Go: a daemon that stores and serves content-addressed data, with a CLI, HTTP Gateway, and RPC API …

阅读更多 →
完整搞定 Windows 11 装软件与系统清理:WinUtil 上手与避坑清单 2026/9/13 14:45:21

完整搞定 Windows 11 装软件与系统清理:WinUtil 上手与避坑清单

完整搞定 Windows 11 装软件与系统清理:WinUtil 上手与避坑清单 【免费下载链接】winutil Chris Titus Techs Windows Utility - Install Programs, Tweaks, Fixes, and Updates 项目地址: https://gitcode.com/GitHub_Trending/wi/winutil 新电脑到手&#…

阅读更多 →
机械臂阻抗控制参数物理可行域与在线投影方法 2026/9/13 14:42:21

机械臂阻抗控制参数物理可行域与在线投影方法

简介:本资源是一套面向机器人控制方向研究者与自动化专业学生的MATLAB阻抗控制仿真源码,聚焦机械臂与环境交互中的柔顺性调控问题,适用于高校课程设计、科研原型验证及工程算法预研等场景。压缩包共124个文件,含96个.mat数据文件&…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞