Поделиться через


Создание настраиваемого дистрибутива Linux для WSL

В этом руководстве описаны действия по созданию и распространению дистрибутива WSL, который является файлом .wsl .

Дистрибутивы WSL имеют две части:

  1. Корневая файловая система (распределен в виде tar-файла)
  2. Запись манифеста (которая содержит метаданные распространения)

Это руководство относится только к WSL версии 2.4.4 и выше.

Примечание.

См. этот репозиторий для инструкций по упаковке дистрибутива на основе appx.

Что такое tar-файлы корневой файловой системы WSL?

Дистрибутивы WSL определяются tar-файлом с расширением .wsl в операционной системе Windows.

TAR-файл (короткий для ленточного архива) — это тип архивного файла, используемого для хранения нескольких файлов в одном файле для упрощения распределения или резервного копирования. TAR-файл содержит корневую файловую систему дистрибутива Linux (все файлы дистрибутива), а также файлы конфигурации WSL. Файлы конфигурации WSL сообщают операционной системе WIndows, как установить и запустить дистрибутив.

После того как у вас есть система Linux, которую вы хотите внести в дистрибутив WSL, выполните приведенные ниже действия, чтобы приступить к работе.

Создание файлов конфигурации WSL

Существует два файла конфигурации, которые следует включить в дистрибутив:

  1. /etc/wsl-distribution.conf: файл, созданный создателем дистрибутива, отвечающий за настройку дистрибутива Linux при первом запуске с помощью WSL.
  2. /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]
enabled = true
icon = /usr/lib/wsl/my-icon.ico

[windowsterminal]
enabled = true
ProfileTemplate = /usr/lib/wsl/terminal-profile.json

Параметры конфигурации файла распространения WSL:

ключ значение по умолчанию заметки
oobe.command строка <none> OOBE означает «опыт вне коробки». Эта команда запускается при первом открытии интерактивной оболочки в дистрибутиве. Если выполнение этой команды возвращает ненулевое значение, оно считается неудачным, и пользователь не сможет открыть оболочку.
oobe.defaultUid целое число <none> Идентификатор пользователя по умолчанию, с которого начинается дистрибутив. Это полезно, когда скрипт oobe.command создает нового пользователя.
oobe.defaultName строка <none> Имя по умолчанию, в которое зарегистрировано распределение. Это имя по умолчанию можно заменить командой: wsl.exe --install <distro> --name <name>
shortcut.icon строка Значок WSL по умолчанию Значок в ярлыке меню "Пуск" для дистрибутива. Должен быть в .ico формате с максимальным размером 10MB
shortcut.enabled булев истина Следует ли создать ярлык в меню Пуск при установке дистрибутива.
windowsterminal.profileTemplate строка <none> Шаблон JSON для создания профиля Windows Terminal для этого дистрибутива.
windowsterminal.enabled булев правда Следует ли создать профиль терминала при установке дистрибутива. Если profileTemplate не задано, будет создан профиль по умолчанию.
windowsterminal.profileTemplate строка Путь к файлу шаблона терминала Шаблон JSON для создания профиля Windows Terminal для этого дистрибутива.

Сначала необходимо создать интерфейс простого запуска (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/sbin/deluser "$username"
    fi
  fi
done

Создайте профиль Терминала Windows

WSL автоматически создает профиль Терминал Windows при установке дистрибутива. В файле конфигурации WSL можно настроить профиль, создаваемый при помощи windowsterminal.profileTemplate, /etc/wsl-distribution.conf.

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 для локальных настроек для каждой дистрибуции

В контексте корневой файловой системы дистрибутива мы рекомендуем настроить параметры systemd, включая то, запускается ли systemd по умолчанию, в локальных параметрах /etc/wsl.conf в зависимости от дистрибутива. См. пример ниже.

# /etc/wsl.conf

[boot]
systemd=true|false

Автор дистрибутива определяет, включен ли systemd по умолчанию, задав boot.systemd значение true (включено) или false (не включено).

Если вы решили включить systemd по умолчанию, ознакомьтесь с рекомендациями Systemd .

Для просмотра всех поддерживаемых параметров смотрите настройку дополнительных параметров в WSL в /etc/wsl.conf.

Создание tar-файла

После размещения файлов распространения и конфигурации можно создать tar-файл с содержимым корневой файловой системы.

Рекомендуемый способ создания tar-файла:

$ cd /path/to/rootfs
$ tar --numeric-owner --absolute-names -c  * | gzip --best > ../install.tar.gz

Корень архива tar должен быть корнем файловой системы (а не каталогом, содержащим корневую файловую систему).

Рекомендуемый формат сжатия — gzip. Другие форматы сжатия несут риск нарушения совместимости с более старыми версиями WSL.

См. рекомендации по файлу конфигурации для получения списка файлов, которые должны и не должны быть включены в конфигурацию.

Чтобы получить tar-файл существующего дистрибутива Linux, найдите инструкции по экспорту контейнера Docker в импортируйте любой дистрибутив Linux для использования с WSL.

После того как архив tar-файла будет готов, см. Тестирование дистрибутива локально, чтобы протестировать его локально.

Создание файла с расширением .wsl

После создания tar-файла для представления пользовательского дистрибутива Linux необходимо изменить расширение файла .tar на расширение .wsl, переименовав его. Переименование этого расширения файла помечает его как дистрибутив WSL. После переименования tar с .tar на .wslфайл будет корректно установлен в Windows при открытии (двойным щелчком) в Проводнике. Запись oobe.defaultName требуется в файле /etc/wsl-distribution.conf для корректной работы процедуры двойного щелчка.

Распространение дистрибутива WSL

Пользователи WSL могут просматривать доступные дистрибутивы, запуская wsl --list --online и напрямую устанавливая их с помощью wsl --install <distroName> (заменив <distroName> фактическим именем дистрибутива Linux. Этот процесс управляется файлом манифеста распространения. Этот файл манифеста можно добавить в дистрибутив Linux клиента, чтобы он был включен в wsl --install параметры команды.

Пользовательский дистрибутив Linux в формате tar, который вы создали и переименовали с расширением файла .wsl, можно распространять по вашему усмотрению. После скачивания пользователь может установить его непосредственно из командной строки с wsl --install --from-file <fileLocation> (заменив <fileLocation> фактическим расположением файла). Кроме того, .wsl файл для настраиваемого дистрибутива WSL можно открыть, дважды щелкнув его.

Сведения о манифесте распределения

Манифест распространения содержит метаданные о дистрибутивах, доступных для установки с помощью wsl --install <distribution>.

Дистрибутивы Linux, основанные на таре, перечислены в 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 --install для всех пользователей WSL

Чтобы сделать дистрибутив WSL доступным для всех пользователей, создайте pull request в репозитории WSL GitHub, который изменяет файл DistributionInfo.json для включения сведений о вашем дистрибутиве.

Этот pull request будет проверен командой WSL.

Добавление вашей дистрибуции в wsl --install для вашего предприятия или бизнес-группы

Вы также можете сделать дистрибутив доступным в wsl --install только для избранной группы, изменив ключи реестра на выбранных устройствах Windows.

Манифест дистрибутива WSL можно переопределить, создав значения реестра в HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Lxss.

  • DistributionListUrl: переопределяет URL-адрес манифеста распространения
  • DistributionListUrlAppend: Добавьте дистрибутивы по этому 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 , чтобы вернуться к официальному манифесту.

Рекомендации по пользовательскому дистрибутиву Linux WSL

Рекомендации по файлу конфигурации

  • Убедитесь, что пользовательский дистрибутив включает /etc/wsl.conf и /etc/wsl-distribution.conf файлы конфигурации. Оба файла должны принадлежать root:root, а их права доступа должны быть 0644.
  • Если параметр oobe.command используется для создания нового пользователя, то для uid и oobe.defaultUid необходимо задать значение 1000.
  • Убедитесь, что в файле конфигурации дистрибутива заданы oobe.defaultName и shortcut.icon: /etc/wsl-distribution.conf
  • Не включайте файл /etc/resolv.conf в корневую файловую систему.
  • Включите корневого пользователя в /etc/passwd. uid для этого корневого пользователя должен быть 0.
  • В /etc/shadowне должно быть хэшей паролей.
  • Архив не должен содержать ядро или initramfs.

Рекомендации по 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