1.5.WSLでのsystemctl設定

# 概略
``systemctl``はUnix系OSの``systemd``(システムデーモン)起動・各種サービス制御に使われるコマンドです。以前は``service``コマンドが使用されていましたが現在、ほとんどのLinux系OSでは``systemctl``が使用されています。Ubuntuでも``systemctl``が使用されているのですが、なぜかWSL2ではいまだに``service``コマンドが使用されています。
Genie等のツールで対応するやり方もありますがWSLの今後の動向によっては設定が変わる可能性があるのでここでは下記サイトを参考に手動で``systemctl``を起動時に使用できるように変更します。

[Getting the most of WSL#get-systemd-functional](https://hoverbear.org/blog/getting-the-most-out-of-wsl/#get-systemd-functional)

---
# 設定手順
注：参考にしたサイト[**Getting the most of WSL#get-systemd-functional**](https://hoverbear.org/blog/getting-the-most-out-of-wsl/#get-systemd-functional)からは下記を点を変更しています。

* 参考サイトにも記載がありましたが``daemonize``ツールのインストール場所は``/usr/sbin``ではなく、``/usr/bin``でしたので変更しました。
* ``.systemd-env``ファイルですが、``start-systemd-namespace``で生成する場所はデフォルトユーザ(``develop`` )のホーム、生成後実行するユーザは``root``ですので``root``ユーザのホームとなっていましたので、``/var/tmp``に生成後、実行ユーザ(``root`` )のホーム(``$HOME/.systemd-env`` )に移動するようにしました。

#### 1.daemonize他、必要なライブラリのインストール
下記コマンドにより、必要なライブラリをインストールします。

```bash:
$ sudo apt install -yqq daemonize dbus-user-session
```

#### 2.start-systemd-namespaceバッチ作成
WSL起動時にservice用環境変数を設定するバッチを記載します。

```vim:start-systemd-namespace
$ cat <<-'EOF' | sudo tee -a /usr/sbin/start-systemd-namespace > /dev/null
#!/bin/bash

SYSTEMD_PID=$(ps -ef | grep '/lib/systemd/systemd --system-unit=basic.target$' | grep -v unshare | awk '{print $2}')
if [ -z "$SYSTEMD_PID" ] || [ "$SYSTEMD_PID" != "1" ]; then
    export PRE_NAMESPACE_PATH="$PATH"
    (set -o posix; set) | \
        grep -v "^BASH" | \
        grep -v "^DIRSTACK=" | \
        grep -v "^EUID=" | \
        grep -v "^GROUPS=" | \
        grep -v "^HOME=" | \
        grep -v "^HOSTNAME=" | \
        grep -v "^HOSTTYPE=" | \
        grep -v "^IFS='.*"$'\n'"'" | \
        grep -v "^LANG=" | \
        grep -v "^LOGNAME=" | \
        grep -v "^MACHTYPE=" | \
        grep -v "^NAME=" | \
        grep -v "^OPTERR=" | \
        grep -v "^OPTIND=" | \
        grep -v "^OSTYPE=" | \
        grep -v "^PIPESTATUS=" | \
        grep -v "^POSIXLY_CORRECT=" | \
        grep -v "^PPID=" | \
        grep -v "^PS1=" | \
        grep -v "^PS4=" | \
        grep -v "^SHELL=" | \
        grep -v "^SHELLOPTS=" | \
        grep -v "^SHLVL=" | \
        grep -v "^SYSTEMD_PID=" | \
        grep -v "^UID=" | \
        grep -v "^USER=" | \
        grep -v "^_=" | \
        cat - > "/var/tmp/.systemd-env"
    echo "PATH='$PATH'" >> "/var/tmp/.systemd-env"
    exec sudo /usr/sbin/enter-systemd-namespace "$BASH_EXECUTION_STRING"
fi
if [ -n "$PRE_NAMESPACE_PATH" ]; then
    export PATH="$PRE_NAMESPACE_PATH"
fi
EOF
```

#### 3.enter-systemd-namespaceバッチ作成
root権限で実行するバッチを作成します。

```vim:enter-systemd-namespace
cat <<-'EOF' | sudo tee -a /usr/sbin/enter-systemd-namespace > /dev/null
#!/bin/bash

if [ "$UID" != 0 ]; then
    echo "You need to run $0 through sudo"
    exit 1
fi

mv /var/tmp/.systemd-env $HOME/.
chown root:root $HOME/.systemd-env

SYSTEMD_PID="$(ps -ef | grep '/lib/systemd/systemd --system-unit=basic.target$' | grep -v unshare | awk '{print $2}')"
if [ -z "$SYSTEMD_PID" ]; then
    /usr/bin/daemonize /usr/bin/unshare --fork --pid --mount-proc /lib/systemd/systemd --system-unit=basic.target
    while [ -z "$SYSTEMD_PID" ]; do
        SYSTEMD_PID="$(ps -ef | grep '/lib/systemd/systemd --system-unit=basic.target$' | grep -v unshare | awk '{print $2}')"
    done
fi

if [ -n "$SYSTEMD_PID" ] && [ "$SYSTEMD_PID" != "1" ]; then
    if [ -n "$1" ] && [ "$1" != "bash --login" ] && [ "$1" != "/bin/bash --login" ]; then
        exec /usr/bin/nsenter -t "$SYSTEMD_PID" -a \
            /usr/bin/sudo -H -u "$SUDO_USER" \
            /bin/bash -c 'set -a; source "$HOME/.systemd-env"; set +a; exec bash -c '"$(printf "%q" "$@")"
    else
        exec /usr/bin/nsenter -t "$SYSTEMD_PID" -a \
            /bin/login -p -f "$SUDO_USER" \
            $(/bin/cat "$HOME/.systemd-env" | grep -v "^PATH=")
    fi
    echo "Existential crisis"
fi
EOF
```

#### 4.実行権限調整
下記コマンドで実行権限を付与します。

```bash:実行権限追加
$ sudo chmod +x /usr/sbin/start-systemd-namespace
$ sudo chmod +x /usr/sbin/enter-systemd-namespace
```

#### 5.WSL環境変数の設定
パスワード無しでバッチを実行できるようにsudoersに設定します。

```vim:/etc/sudoers.d/wsl
cat <<-'EOF' | sudo tee -a /etc/sudoers.d/wsl > /dev/null
Defaults        env_keep += WSLPATH
Defaults        env_keep += WSLENV
Defaults        env_keep += WSL_INTEROP
Defaults        env_keep += WSL_DISTRO_NAME
Defaults        env_keep += PRE_NAMESPACE_PATH
%sudo ALL=(ALL) NOPASSWD: /usr/sbin/enter-systemd-namespace
EOF
```

#### 6.WSL起動時設定
WSL起動時に実行するように下記設定をします。

```bash:bash.bashrc
$ sudo sed -i 2a"# Start or enter a PID namespace in WSL2\nsource /usr/sbin/start-systemd-namespace\n" /etc/bash.bashrc
```

#### 7.Windows環境変数設定
Windowsのシステム環境変数をDOS窓を管理権限で開き、下記の通り設定します。

```dosbatch:管理者DOS窓から環境変数設定
> setx WSLENV BASH_ENV/u /M
> setx BASH_ENV /etc/bash.bashrc /M
```

---
# 確認
WSLを一旦停止し、再起動します。
DOS窓から下記コマンドを実行してからWSLコンソールを開きます。

```dosbatch:WSL停止
> wsl --shutdown
```

WSLコンソールから下記コマンドを試してください。

```bash:systemctl確認
$ sudo systemctl status cron.service
● cron.service - Regular background program processing daemon
     Loaded: loaded (/lib/systemd/system/cron.service; enabled; vendor preset: enabled)
     Active: active (running) since Mon 2021-xx-xx 15:56:01 JST; 1min 14s ago
       Docs: man:cron(8)
   Main PID: 368 (cron)
      Tasks: 1 (limit: 30396)
     Memory: 688.0K
     CGroup: /system.slice/cron.service
             └─368 /usr/sbin/cron -f

 x月 xx 15:56:01 DESKTOP-BREF6G7 systemd[1]: Started Regular background program processing daemon.
 x月 xx 15:56:01 DESKTOP-BREF6G7 cron[368]: (CRON) INFO (pidfile fd = 3)
 x月 xx 15:56:01 DESKTOP-BREF6G7 cron[368]: (CRON) INFO (Running @reboot jobs)
```

---

[1.4.Google Driveマウント設定](https://qiita.com/boss_ape/items/74bcad7441417c331205) < 前 **1.5.WSLでのsystemctl設定** 次 > [2.Git / GitHubによる環境ファイル管理](https://qiita.com/boss_ape/items/25cc648beb2519d5e1da)