Ubuntu20.04 LTS と WSL2を試してみたところ snapコマンドが上手く利用できなかったのでそのまとめ
WSL2
もともとWSL2もInsider Previewを利用して試していたけど, とうとうGA版がリリースされたということで改めて試してみた.
WSL2の利用方法は Insider Previewの頃と変わらず. Insider Previewを利用せずともWSL2が利用できるようになった.
WSL2におけるsnapdとsystemd
Ubuntuの新しいパッケージ管理システムであるsnap. ところが WSL2上のUbuntuではsnapコマンドが実行できない.
$snap install hello-world error: cannot communicate with server: Post http://localhost/v2/snaps/hello-world: dial unix /run/snapd.socket: connect: no such file or directory
原因は snapコマンドが systemdに依存しており,WSL2ではsystemdが起動していないこと. snapコマンドはsnapdと通信して動作するが,snapdはsystemdサービスとして動作するので systemdが動作していないとsnapdも動作せず,snapコマンドは正常に実行できない.
$ cat /etc/systemd/system/multi-user.target.wants/snapd.service [Unit] Description=Snap Daemon Requires=snapd.socket OnFailure=snapd.failure.service # This is handled by snapd # X-Snapd-Snap: do-not-start [Service] # Disabled because it breaks lxd # (https://bugs.launchpad.net/snapd/+bug/1709536) #Nice=-5 OOMScoreAdjust=-900 ExecStart=/usr/lib/snapd/snapd EnvironmentFile=-/etc/environment Restart=always WatchdogSec=5m Type=notify SuccessExitStatus=42 RestartPreventExitStatus=42 KillMode=process [Install] WantedBy=multi-user.target
WSL2ではsystemdはinitシステムとして動作していない. WSL2ではWindowsとのを実現するために独自のセットアップを実行しており, Ubuntuなどで採用されているsystemdは利用されていない. このため,systemctlコマンドなどは動作しない.
$ systemctl status snapd System has not been booted with systemd as init system (PID 1). Can't operate. Failed to connect to bus: Host is down
WSL2上でsystemdを実行する
無理矢理systemdを起動してあげることで対処する. この記事に従いsystemdを起動すると systemctlが利用できるようになるし,snapdも動作するようになる.
$ systemctl status snapd ● snapd.service - Snap Daemon Loaded: loaded (/lib/systemd/system/snapd.service; enabled; vendor preset: enabled) Active: active (running) since Sun 2020-05-24 13:46:21 JST; 5min ago TriggeredBy: ● snapd.socket Main PID: 444 Tasks: 27 (limit: 30645) Memory: 170.6M CGroup: /user.slice/user-1000.slice/session-c2.scope/system.slice/snapd.service └─444 /usr/lib/snapd/snapd 5月 24 13:50:47 DESKTOP-JCB3AFB snapd[801]: rip 0x5580ad845031 5月 24 13:50:47 DESKTOP-JCB3AFB snapd[801]: rflags 0x286 5月 24 13:50:47 DESKTOP-JCB3AFB snapd[801]: cs 0x33 5月 24 13:50:47 DESKTOP-JCB3AFB snapd[801]: fs 0x0 5月 24 13:50:47 DESKTOP-JCB3AFB snapd[801]: gs 0x0 5月 24 13:50:47 DESKTOP-JCB3AFB systemd[1]: snapd.service: Main process exited, code=exited, status=2/INVALIDARGUMENT 5月 24 13:50:47 DESKTOP-JCB3AFB systemd[1]: snapd.service: Failed with result 'watchdog'. 5月 24 13:50:48 DESKTOP-JCB3AFB systemd[1]: snapd.service: Scheduled restart job, restart counter is at 2. 5月 24 13:50:48 DESKTOP-JCB3AFB systemd[1]: Stopped Snap Daemon. 5月 24 13:50:48 DESKTOP-JCB3AFB systemd[1]: Starting Snap Daemon...
あとは 通常通りsnapコマンドを実行すればいいだけ. ただし,当然ながらsystemdはあまり正常な状態ではないようで, systemctl restartなどでsnapdを含む適当サービスを再起動するとエラーになる.
$ sudo systemctl restart snapd [sudo] thaim のパスワード: Warning! D-Bus connection terminated. Failed to restart snapd.service: 接続が相手からリセットされました See system logs and 'systemctl status snapd.service' for details.
一応snapコマンドでhello-worldをインストール・実行できたのである程度は動作する,はず. ただし,現状では可能な限りsnapコマンドは利用しない方がよさそう.
参考
- WSLのアーキテクチャ
- initプロセスを含めてWSLのアーキテクチャについてわかりやすい説明がある
- WSL2でSystemdを使うハック
- WSL2でsystemdを起動する手順のまとめ
- オリジナルの内容は Ubuntu Community DiscourseのUsing snapd in WSL2
- systemctl doesn't work #1579
- 昔からWSL上でsystemdが動作していない問題は認識されているが対応されていない