次の方法で共有


WSL 用のカスタム Linux ディストリビューションを構築する

このガイドでは、WSL ディストリビューション ( .wsl ファイル) を作成して配布する手順について説明します。

WSL ディストリビューションには、次の 2 つの部分があります。

  1. ルート ファイルシステム (tar ファイルとして配布)
  2. マニフェスト エントリ (ディストリビューション メタデータを含む)

Note

このガイドは、 WSL リリース 2.4.4 以降にのみ適用されます。

Note

appx ベースのディストリビューション パッケージの手順については このリポジトリを参照してください。

WSL ルート ファイルシステム tar ファイルとは何ですか?

WSL ディストリビューションは、Windows 上の .wsl ファイル拡張子を持つ tar ファイルによって定義されます。

TAR ファイル (テープ アーカイブの略) は、配布やバックアップを容易にするために複数のファイルを 1 つのファイルにまとめるために使用されるアーカイブ ファイルの一種です。 TAR ファイルには、Linux ディストリビューション (すべてのディストリビューション ファイル) のルート ファイル システムと WSL 構成ファイルが含まれています。 WSL 構成ファイルは、WIndows オペレーティング システムにディストリビューションをインストールして起動する方法を指示します。

WSL ディストリビューションにしたい Linux システムが完成したら、次の手順に従って作業を開始します。

WSL 構成ファイルを作成する

ディストリビューションに含める必要がある構成ファイルは 2 つあります。

  1. /etc/wsl-distribution.conf: WSL を使用して初めて起動したときに Linux ディストリビューションを構成する方法を制御するディストリビューション 保守管理者によって作成されたファイル。
  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]
icon = /usr/lib/wsl/my-icon.ico

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

WSL 配布ファイルの構成オプション:

key value default
oobe.command string <none> OOBE は、すぐに使用するエクスペリエンスの略です。 このコマンドは、ユーザーがディストリビューションで対話型シェルを初めて開くと実行されます。 そのコマンドが 0 以外を返した場合、失敗したと見なされ、ユーザーはシェルを開くことができません。
oobe.defaultUid integer <none> ディストリビューションが開始する既定の UID。 これは、 oobe.command スクリプトで新しいユーザーを作成するときに便利です。
oobe.defaultName string <none> ディストリビューションが登録されている既定の名前。 この既定の名前は、次のコマンドに置き換えることができます。 wsl.exe --install <distro> --name <name>
shortcut.icon string 既定の WSL アイコン 配布のスタート メニュー ショートカットのアイコン。 最大サイズが a0/& .ico の形式である必要があります 10MB
'windowsterminal.profileTemplate' string ターミナル テンプレート ファイルへのパス このディストリビューションのWindows ターミナル プロファイルを生成する JSON テンプレート。

ディストリビューションの最初の実行エクスペリエンス (OOBE) を作成する必要があります。 使用できる Bash スクリプトの例を次に示します。 このスクリプトでは、 oobe.defaultUid1000 に設定されていることを前提としています。

#! /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"
    }
  ]
}

このファイルでは、プロファイルの namecommandLineを指定する必要はありません。 これらは、端末プロファイルの生成時に WSL によって自動的に追加されます。

配布ごとにローカル設定の WSL 構成を追加する

ディストリビューション ルート ファイルシステムのコンテキストでは、配布ごとに/etc/wsl.confローカル設定で systemd が既定で開始されるかどうかなど、systemd 設定を構成することをお勧めします。 次の例を見てください。

# /etc/wsl.conf

[boot]
systemd=true|false

配布作成者は、 boot.systemd 値を true (有効) または false (有効ではない) に設定することで、systemd が既定で有効になっているかどうかを判断します。

既定で systemd を有効にすることを選択した場合は、「 ベスト プラクティス」セクション を参照してください。

/etc/wsl.confでサポートされているすべての設定については WSL のAdvanced 設定の構成を参照してください。

tar ファイルを作成する

配布ファイルと構成ファイルが配置されると、ルート ファイルシステムを tar でキャプチャできます。

tar を作成するための推奨される方法を次に示します。

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

tar のルートはファイルシステムのルートである必要があります (ルート ファイルシステムを含むディレクトリではありません)。

推奨される圧縮形式は gzip です。 他の圧縮形式では、古い WSL バージョンとの互換性が損なうリスクがあります。

含める必要があるファイル、または含めるべきではないファイルについては、「 ベスト プラクティス」セクション を参照してください

既存の Linux ディストリビューションの TAR ファイルを取得するには、WSL で使用する Linux ディストリビューションをインポートで Docker コンテナーをエクスポートする方法に関するガイダンスを参照してください。

tar ファイルのアーカイブの準備ができたら、「 配布マニフェストの削除 ローカルで試してください。

wsl ファイル拡張子を作成する

最後の手順では、カスタム Linux ディストリビューションを表す TAR ファイルを作成したら、名前を変更して、 .tar ファイル拡張子を .wsl ファイル拡張子に変更します。 このファイル拡張子の名前を変更すると、WSL ディストリビューションとしてマークされます。 TAR の名前を .tar から .wsl に変更すると、エクスプローラーで開かれた (ダブルクリック) と、ファイルが 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 リポジトリで pull request を開いて ディストリビューション情報を含むように DistributionInfo.json ファイルを変更してください。

このプル要求は、WSL チームによってレビューされます。

企業またはグループの wsl --install にディストリビューションを追加する

選択したマシンのレジストリ キーを編集して、選択したグループにのみ wsl --install でディストリビューションを使用できるようにすることもできます。

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 を削除して公式マニフェストに戻すことができます。

ベスト プラクティス

構成ファイル

  • /etc/wsl.conf/etc/wsl-distribution.conf を含める必要があります。 root:rootが所有する必要があり、アクセス許可は0644
  • oobe.commandを使用して新しいユーザーを作成する場合は、その uid を1000し、その値oobe.defaultUid設定する必要があります。
  • oobe.defaultNameshortcut.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