为 WSL 生成自定义 Linux 分发版
本指南将演练创建和分发 WSL 分发(文件 .wsl
)的步骤。
WSL 分发有两个部分:
- 根文件系统(以 tar 文件的形式分发)
- 清单条目(其中包含分发元数据)
注意
本指南仅适用于 WSL 版本 2.4.4 及更高版本。
注意
有关上一个基于 appx 的分发打包说明,请参阅 此存储库 。
什么是 WSL 根文件系统 tar 文件?
WSL 分发版由具有 Windows 文件扩展名的 .wsl
tar 文件定义。
TAR 文件(磁带存档简称)是一种存档文件,用于将多个文件存储在单个文件中,以便更轻松地分发或备份。 TAR 文件包含 Linux 分发版(所有分发文件)以及 WSL 配置文件的根文件系统。 WSL 配置文件告知 WIndows 操作系统如何安装和启动分发版。
拥有想要进入 WSL 分发版的 Linux 系统后,请按照以下步骤开始操作。
创建 WSL 配置文件
分发应包括两个配置文件:
/etc/wsl-distribution.conf
:由分发维护者创建的文件,负责控制首次使用 WSL 启动时应如何配置 Linux 分发版。/etc/wsl.conf
:包含特定于用户的全局系统设置的文件,并控制分发的启动方式。 详细了解 WSL 配置文件。
添加 WSL 分发配置文件
分发配置文件 /etc/wsl-distribution.conf
定义在用户首次启动时应如何配置 Linux 分发版。 此文件可用于以交互方式创建用户帐户、显示许可协议等。
下面是一个示例 /etc/wsl-distribution.conf
文件:
# /etc/wsl-distribution.conf
[oobe]
command = /etc/oobe.sh
defaultUid = 1000
defaultName = my-distro
[shortcut]
icon = /usr/lib/wsl/my-icon.ico
[windowsterminal]
ProfileTemplate = /usr/lib/wsl/terminal-profile.json
WSL 分发文件配置选项:
key | value | default | 说明 |
---|---|---|---|
oobe.command |
string | <none> |
OOBE 代表现装体验。 此命令在用户首次在分发版中打开交互式 shell 时运行。 如果该命令返回非零,则被视为失败,并且用户将无法打开 shell。 |
oobe.defaultUid |
integer | <none> |
分发以默认 UID 开头。 当脚本创建新用户时 oobe.command ,这非常有用。 |
oobe.defaultName |
string | <none> |
分发所注册的默认名称。 此默认名称可以替换为命令: wsl.exe --install <distro> --name <name> |
shortcut.icon |
string | 默认 WSL 图标 | 分发的“开始”菜单快捷方式中的图标。 必须 .ico 采用最大大小为 的格式 10MB |
“windowsterminal.profileTemplate” | string | 终端模板文件的路径 | 用于为此分发生成Windows 终端配置文件的 JSON 模板。 |
你需要为分发创建现装体验(OOBE) 首次运行体验。 下面是可以使用的示例 bash 脚本。 此脚本假定设置为oobe.defaultUid
1000
:
#! /bin/bash
set -ue
DEFAULT_GROUPS='adm,cdrom,sudo,dip,plugdev'
DEFAULT_UID='1000'
echo 'Please create a default UNIX user account. The username does not need to match your Windows username.'
echo 'For more information visit: https://aka.ms/wslusers'
if getent passwd "$DEFAULT_UID" > /dev/null ; then
echo 'User account already exists, skipping creation'
exit 0
fi
while true; do
# Prompt from the username
read -p 'Enter new UNIX username: ' username
# Create the user
if /usr/sbin/adduser --uid "$DEFAULT_UID" --quiet --gecos '' "$username"; then
if /usr/sbin/usermod "$username" -aG "$DEFAULT_GROUPS"; then
break
else
/usr/bin/deluser "$username"
fi
fi
done
生成Windows 终端配置文件
安装分发版时,WSL 自动生成Windows 终端配置文件。 分发维护人员可以通过在 WSL 配置文件/etc/wsl-distribution.conf
中设置 windowsterminal.profileTemplate
来自定义生成的配置文件。
json 文件遵循 终端配置文件 json 格式。 下面是一个示例配置文件:
{
"profiles": [
{
"antialiasingMode": "aliased",
"fontWeight": "bold",
"colorScheme": "Postmodern Tango Light"
}
],
"schemes": [
{
"name": "Postmodern Tango Light",
"black": "#0C0C0C",
"red": "#C50F1F",
"green": "#13A10E",
"yellow": "#C19C00",
"blue": "#0037DA",
"purple": "#881798",
"cyan": "#3A96DD",
"white": "#CCCCCC",
"brightBlack": "#767676",
"brightRed": "#E74856",
"brightGreen": "#16C60C",
"brightYellow": "#F9F1A5",
"brightBlue": "#3B78FF",
"brightPurple": "#B4009E",
"brightCyan": "#61D6D6",
"brightWhite": "#F2F2F2"
}
]
}
此文件不需要指定配置文件 name
,也 commandLine
不需要指定配置文件。 生成终端配置文件时,WSL 会自动添加这些配置文件。
为每个分布区添加本地设置的 WSL 配置
在分发根文件系统的上下文中,我们建议你配置系统设置,包括默认是否以按分布方式在本地设置中/etc/wsl.conf
启动系统设置。 请参阅以下示例。
# /etc/wsl.conf
[boot]
systemd=true|false
分发作者通过将值设置为 boot.systemd
true
(enabled)或 false
(未启用)来确定系统是默认启用的。
有关所有受支持的设置,/etc/wsl.conf
请参阅 WSL 中的高级设置配置。
创建 tar 文件
分发和配置文件到位后,可以在 tar 中捕获根文件系统。
下面是创建 tar 的建议方法:
$ cd /path/to/rootfs
$ tar --numeric-owner --absolute-names -c * | gzip --best > ../install.tar.gz
tar 的根目录应该是文件系统的根(而不是包含根文件系统的目录)。
建议的压缩格式为 gzip。 其他压缩格式可能会破坏与旧版 WSL 版本的兼容性。
若要获取现有 Linux 分发版的 TAR 文件,请查找有关如何在导入任何 Linux 分发版中 导出 Docker 容器以用于 WSL 的指导。
tar 文件存档准备就绪后,请参阅 替代分发清单 以在本地试用。
创建 .wsl 文件扩展名
最后一步是创建一个 TAR 文件来表示自定义 Linux 分发版,方法是通过重命名文件扩展名将 .tar
文件扩展名 .wsl
更改为文件扩展名。 重命名此文件扩展名会将它标记为 WSL 分发版。 将 TAR 重命名为 <.wsl
a0/> 后,在文件资源管理器中打开(双击)时,该文件将在 Windows 上正确安装。 此/etc/wsl-distribution.conf
双击体验在文件中需要一个oobe.defaultName
条目才能正常工作
分发 WSL 分发
WSL 用户可以通过运行 wsl --list --online
查看可用的分发版,并可以直接 wsl --install <distroName>
安装它们(替换为 Linux 分发版的实际名称)。 此过程由分发清单文件控制。 可以将此清单文件添加到客户 Linux 分发版,以便将其包含在命令选项中 wsl --install
。
但是,可以使用文件扩展名创建和重命名 .wsl
的自定义 Linux 分发 TAR。 下载后,用户可以直接从命令行 wsl --install --from-file <fileLocation>
安装它(替换为文件的实际位置)。 或者, .wsl
可以通过双击它打开自定义 WSL 分发的文件。
分发清单详细信息
分发 清单 包含有关可通过 wsl --install <distribution>
安装分发版的元数据。
基于 TAR 的分发版按以下格式列出 ModernDistribution
:
"ModernDistributions": {
"<flavor>": [
{
"Name": "<version name>",
"FriendlyName": "<friendly name>",
"Default": true | false,
"Amd64Url": {
"Url": "<tar url>",
"Sha256": "<tar sha265 hash>"
},
"Arm64Url": {
"Url": "<tar url>",
"Sha256": "<tar sha265 hash>"
}
}
}
每个 flavor
条目都包含一个可安装分发版的列表。 可以通过风格名称(即安装默认条目)或版本名称来安装分发版。
查看命令如何使用 wsl --install
以下清单:
{
"ModernDistributions": {
"my-distro": [
{
"Name": "my-distro-v3",
"Default": true,
"FriendlyName": "My distribution version 3 (latest)"
[...]
},
{
"Name": "my-distro-v2",
"Default": false,
"FriendlyName": "My distribution version 2"
[...]
}
}
}
示例安装命令:
$ wsl --install my-distro # Installs 'my-distro-v3' since it's the default for 'my-distro' flavor
$ wsl --install my-distro-v3 # Installs 'my-distro-v3' explicitly
$ wsl --install my-distro-v2 # Installs 'my-distro-v2' explicitly
为所有 WSL 用户添加发行版wsl --install
若要使 WSL 发行版可供所有用户使用,请在 WSL GitHub 存储库上打开拉取请求,修改DistributionInfo.json文件以包含发行版信息。
WSL 团队将审查此拉取请求。
将发行版添加到 wsl --install
企业或组
还可以通过在所选计算机上编辑注册表项,使发行版仅可用于 wsl --install
选择组。
可以通过在其中 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Lxss
创建注册表值来重写 WSL 分发清单。
DistributionListUrl
:重写分发清单 URLDistributionListUrlAppend
:将清单 URL 中的分发版添加到可安装分发版列表
这两个注册表值都是字符串(REG_SZ),应采用 URL 格式。
从 WSL 2.4.4 开始, file://
支持协议以简化本地测试。 预期格式为: file:///C:/path/to/file
测试本地分发
若要测试分发 tar,可以使用以下示例 powershell 脚本通过新的分发替代分发清单。 首先将以下脚本保存为 override-manifest.ps1
:
#Requires -RunAsAdministrator
[cmdletbinding(PositionalBinding = $false)]
param (
[Parameter(Mandatory = $true)][string]$TarPath,
[string]$Flavor = "test-distro",
[string]$Version = "test-distro-v1",
[string]$FriendlyName = "Test distribution version 1")
Set-StrictMode -Version latest
$TarPath = Resolve-Path $TarPath
$hash = (Get-Filehash $TarPath -Algorithm SHA256).Hash
$manifest= @{
ModernDistributions=@{
"$Flavor" = @(
@{
"Name" = "$Version"
Default = $true
FriendlyName = "$FriendlyName"
Amd64Url = @{
Url = "file://$TarPath"
Sha256 = "0x$hash"
}
})
}
}
$manifestFile = "$PSScriptRoot/manifest.json"
$manifest | ConvertTo-Json -Depth 5 | Out-File -encoding ascii $manifestFile
Set-ItemProperty -Path "HKLM:SOFTWARE\Microsoft\Windows\CurrentVersion\Lxss" -Name DistributionListUrl -Value "file://$manifestFile" -Type String -Force
然后,通过在提升的 powershell 中运行以下命令来配置本地清单:
.\override-manifest.ps1 -TarPath /path/to/tar
完成后,应会看到以下输出 wsl.exe --list --online
$ wsl --list --online
The following is a list of valid distributions that can be installed.
Install using 'wsl.exe --install <Distro>'.
NAME FRIENDLY NAME
test-distro-v1 Test distribution version 1
然后,可以运行 wsl.exe --install test-distro-v1
以尝试安装新分发版。
完成后,可以删除 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Lxss\DistributionListUrl
以还原到官方清单。
最佳做法
配置文件
/etc/wsl.conf
并/etc/wsl-distribution.conf
应包含。 它们应归其root:root
所有,其权限应为0644
- 如果
oobe.command
用于创建新用户,则其 uid 应1000
设置为该值,应oobe.defaultUid
设置为该值。 oobe.defaultName
且shortcut.icon
应在/etc/wsl-distribution.conf
/etc/resolv.conf
不应包含在根文件系统- 应有根用户
/etc/passwd
,并且其 uid 应为0
- 中不应有密码哈希
/etc/shadow
- 存档不应包含内核或 initramfs
Systemd
如果启用了 systemd,则应禁用或屏蔽可能导致 WSL 问题的单元。 以下已知会导致 WSL 分发中问题的单位(适用于系统和用户单位):
- systemd-resolved.service
- systemd-networkd.service
- NetworkManager.service
- systemd-tmpfiles-setup.service
- systemd-tmpfiles-clean.service
- systemd-tmpfiles-clean.timer
- systemd-tmpfiles-setup-dev-early.service
- systemd-tmpfiles-setup-dev.service
- tmp.mount