Enabling systemd in WSL 2 on Windows 11 22H2 without Insider

     

TLDR

Install the latest WSL release, then add the following to /etc/wsl.conf in your WSL distro(s):

[boot]
systemd=true

Cheers!

Intro

Windows Subsystem for Linux version 2, or better known as WSL 2 is freakin’ awesome, a couple of ridiculous issues aside, like IPv6 being broken to this day. Even though it actually worked in WSL 1.

Anyway, I was dealing with my Ansible playbooks the other day, and this time I was on Windows and using WSL 2 with Docker for my needs. It’s a pretty handy setup, and I really appreciate that things are becoming easier and easier. Except for one thing:

TASK [update : Enable dnf-automatic] *******************************************
fatal: [rocky9]: FAILED! => {"changed": false, "msg": "Service is in unknown state", "status": {}}

Huh, that’s weird, but let the other tests run.

RUNNING HANDLER [update : Restart cron service] ********************************
fatal: [ubuntu2204]: FAILED! => {"changed": false, "cmd": "/usr/bin/systemctl", "msg": "System has not been booted with systemd as init system (PID 1). Can't operate.\nFailed to connect to bus: Host is down", "rc": 1, "stderr": "System has not been booted with systemd as init system (PID 1). Can't operate.\nFailed to connect to bus: Host is down\n", "stderr_lines": ["System has not been booted with systemd as init system (PID 1). Can't operate.", "Failed to connect to bus: Host is down"], "stdout": "", "stdout_lines": []}

Oops, that’s new. What’s with the WSL instance?

$ systemctl status
System has not been booted with systemd as init system (PID 1). Can't operate.
Failed to connect to bus: Host is down

Oh. Right, this isn’t Linux, this is just WSL. No systemd. Almost forgot.

WSL

But wait, I think I saw something on this matter. Yup, I did.

Yay, so why doesn’t this work for me?

Ensure you are running the right version of WSL: Version 0.67.6 and above. This version of WSL is now available in the Microsoft Store to users on Windows Insiders build for initial testing, and then after a few weeks we will make it available to all users to ensure quality.

Yeah, right, we all know that “few weeks”. Too bad. What’s my version anyway?

PS C:\Users\noobient> wsl --version
Invalid command line option: --version

Yaay. So I’m not even on the Store version of WSL. Let’s upgrade to that first:

wsl --update

Now try again:

PS C:\Users\noobient> wsl --version
WSL version: 0.66.2.0
Kernel version: 5.15.57.1
WSLg version: 1.0.42
MSRDC version: 1.2.3401
Direct3D version: 1.606.4
DXCore version: 10.0.25131.1002-220531-1700.rs-onecore-base2-hyp
Windows version: 10.0.22621.608

Well, that’s better, but still far from “0.67.6 and above”. So how do I get this version? Well, according to Microsoft, join to the Insiders (no way), or wait (no way). But wait, aren’t Microsoft open-sourcing everything these days? Ha, they do.

Woo, now we’re talking! Let’s grab the latest release, do it! Don’t let that “ARM64” part confuse you, it’s because these installers apparently include the binaries for BOTH architectures.

Hell yes, smash that update button. Needless to say, it’s gonna kill all your running instances. Now let’s check that version again:

PS C:\Users\noobient> wsl --version
WSL version: 0.68.4.0
Kernel version: 5.15.68.1
WSLg version: 1.0.44
MSRDC version: 1.2.3401
Direct3D version: 1.606.4
DXCore version: 10.0.25131.1002-220531-1700.rs-onecore-base2-hyp
Windows version: 10.0.22621.608

Awesome. Sooo now I have systemd in WSL, right?

$ systemctl status
System has not been booted with systemd as init system (PID 1). Can't operate.
Failed to connect to bus: Host is down

Hmm… oh, nevermind, you should restart WSL completely first. Or something.

wsl --shutdown

And this is the part where my comp crashed 😀 No worries, only some parts of this post were lost! So anyway, after the reboot:

$ systemctl status
System has not been booted with systemd as init system (PID 1). Can't operate.
Failed to connect to bus: Host is down

Oh boy.

systemd

So after all, I missed one part of the Microsoft announcement. Add this to /etc/wsl.conf in your WSL distro(s):

[boot]
systemd=true

Now terminate your instace (or just do a complete shutdown with --shutdown):

PS C:\Users\noobient> wsl --list
Windows Subsystem for Linux Distributions:
Ubuntu-20.04 (Default)
docker-desktop-data
docker-desktop
Ubuntu-18.04
Ubuntu-22.04
PS C:\Users\noobient> wsl --terminate Ubuntu-22.04
The operation completed successfully.

Now, ONCE MORE check if we finally have systemd or not:

$ systemctl status
● tomahawk
    State: degraded
     Jobs: 0 queued
   Failed: 3 units
    Since: Tue 2022-10-11 16:36:47 CEST; 5s ago
   CGroup: /
           ├─user.slice
...

YESS. Don’t worry about that “degraded” state, apparently WSL will do this, but otherwise you should be good to go. For instance, check another service:

$ systemctl status cron
● cron.service - Regular background program processing daemon
     Loaded: loaded (/lib/systemd/system/cron.service; enabled; vendor preset: enabled)
     Active: active (running) since Tue 2022-10-11 16:36:47 CEST; 16s ago
       Docs: man:cron(8)
   Main PID: 349 (cron)
      Tasks: 1 (limit: 19138)
     Memory: 424.0K
     CGroup: /system.slice/cron.service
             └─349 /usr/sbin/cron -f -P

Oct 11 16:36:47 tomahawk systemd[1]: Started Regular background program processing daemon.
Oct 11 16:36:47 tomahawk cron[349]: (CRON) INFO (pidfile fd = 3)
Oct 11 16:36:47 tomahawk cron[349]: (CRON) INFO (Running @reboot jobs)

All is well. The day is saved.

Windows

I only have Windows 11 22H2 at hand, so I’m not sure if it works on earlier versions or not. Your best bet is to use the latest version.

Ansible

After all, all this hassle came from my issues with Ansible. Once all these things are patched up, all you have to do is follow the docs, so add those command, tmpfs and volumes options to your molecule.yml, like so:

  - name: ubuntu2204
    image: ubuntu:22.04
    command: /sbin/init
    tmpfs:
      - /run
      - /tmp
    volumes:
      - /sys/fs/cgroup:/sys/fs/cgroup:ro

And your systemd-related tasks will immediately start working:

TASK [update : Enable dnf-automatic] *******************************************
changed: [rocky9]

Easy as pie!