第626回の
ホストをできるだけキレイに保つために
Steamのインストーラーはソースが公開されているものの、
これまでにも第416回や第433回、
あらかじめ第521回の
steamコンテナの準備
では早速steamコンテナを作ってみましょう。今回は手作業で随時設定していますが、
コンテナの作成: $ lxc launch ubuntu:20.04 steam $ lxc exec steam -- sh -c \ "apt update && apt full-upgrade -y && apt autoremove -y" UID/GIDの設定: $ lxc config set steam raw.idmap 'both 1000 1000' パッケージのインストール: $ lxc exec steam -- dpkg --add-architecture i386 $ lxc exec steam -- sh -c 'apt update && apt install -y \ x11-apps mesa-utils libgl1-mesa-glx:i386 \ libcanberra-gtk-module:i386 pulseaudio dbus-x11 \ language-pack-ja fonts-noto-cjk-extra \ fonts-noto-color-emoji' 日本語環境の設定: $ lxc exec steam -- update-locale LANG=ja_JP.UTF-8 $ lxc exec steam -- timedatectl set-timezone Asia/Tokyo
今回はraw.
」
Steamクライアントをインストールするために、
次にコンテナの中からホストのサウンドサーバーにアクセスできるようにしておきましょう。単にUnixドメインソケットをそのままコンテナの中に見せているだけです。
$ lxc exec steam -- sed -i "s/; enable-shm = yes/enable-shm = no/g" /etc/pulse/client.conf $ lxc exec steam -- sh -c "echo export PULSE_SERVER=unix:/tmp/.pulse-native | tee --append /home/ubuntu/.profile" $ lxc config device add steam pa disk source=/run/user/1000/pulse/native path=/tmp/.pulse-native
さらにコンテナからホストのXサーバーとGPUデバイスにアクセスできるようにします。
$ lxc exec steam -- usermod -aG video ubuntu $ lxc config set steam environment.DISPLAY :0 $ lxc config device add steam xorg disk \ source=/tmp/.X11-unix/X0 path=/tmp/.X11-unix/X0 $ lxc config device add steam mygpu gpu \ gid=`getent group video | cut -d: -f3`
第532回の/tmp/
」
同様の理由でコンテナの自動起動を停止しておいたほうが無難でしょう。後ほどSteamを起動するタイミングでコンテナも起動するスクリプトを作ります。
$ lxc config set steam boot.autostart false
steamのインストール
ようやくsteamをインストールできます。今回もSteam公式のパッケージをダウンロード&インストールします。
$ lxc exec steam -- \ wget https://steamcdn-a.akamaihd.net/client/installer/steam.deb $ lxc exec steam -- apt install -y ./steam.deb
これまでの設定を反映するために、
$ lxc restart steam
まずは動作確認のために端末からSteamを起動してみます。
$ lxc exec steam -- sudo --user=ubuntu --login steam
ubuntuアカウントでログインして、steam
コマンドを実行しているだけです。うまくいけばディスプレイにSteamクライアントが表示されるのではないでしょうか。もし表示されない場合は、/tmp/
」/dev/
」
Steamクライアント起動後の初回設定やProtonの有効化については、
画面右上の最大化ボタンから
ちなみに画面右上の閉じるボタンを押すと、
ゲームコントローラー(JoyStick)デバイスの対応
ここまでの時点でキーボードによるゲームのプレイは可能になっています。ただしアクション系のゲームを楽しもうと思うと、
Linuxで一般的に使えるゲームコントローラーはUSBで接続する有線タイプと、
第475回の
一般的にJoyStickデバイスが接続されると/dev/
」
しかしながらアプリケーション側で、/dev/
」
Steamの場合は、/dev/
」/dev/
」
これらのデバイスファイルはいずれもudev経由で作成します。しかしながら、
まずはPS4コントローラーを接続した状態で、
$ lsusb Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub Bus 001 Device 002: ID 8087:0a2b Intel Corp. Bus 001 Device 003: ID 054c:05c4 Sony Corp. DualShock 4 [CUH-ZCT1x] Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub Bus 004 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub Bus 003 Device 002: ID 046d:c52b Logitech, Inc. Unifying Receiver Bus 003 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
上記だと054c:05c4
」ベンダーID:プロダクトID
」
$ lxc config device add steam sony \ unix-hotplug vendorid=054c productid=05c4
この状態で一度、
$ lxc exec steam -- ls -l /dev/input/ total 0 crw-rw---- 1 root root 13, 84 Jul 4 01:40 event20 crw-rw---- 1 root root 13, 85 Jul 4 01:40 event21 crw-rw---- 1 root root 13, 86 Jul 4 01:40 event22 crw-rw-r-- 1 root root 13, 0 Jul 4 01:40 js0 crw-rw---- 1 root root 13, 33 Jul 4 01:40 mouse1 $ lxc exec steam -- ls -l /dev/hidraw* ls: cannot access '/dev/hidraw0': No such file or directory ls: cannot access '/dev/hidraw1': No such file or directory crw------- 1 root root 239, 2 Jul 4 01:40 /dev/hidraw2
ちなみにPS4コントローラーはタッチパッド部分がマウスとして認識されるため、
また、/dev/
」/dev/
」/dev/
」/dev/
」/dev/
」
さて、
コンテナの中と外で先ほど追加されたデバイスファイルのパーミッションを比較してみましょう。上記にコンテナの中のパーミッションが記載されているため、
$ ls -l /dev/input/js0 crw-rw-r--+ 1 root input 13, 0 7月 4 01:40 /dev/input/js0 $ ls -l /dev/hidraw* crw------- 1 root root 239, 0 7月 4 00:40 /dev/hidraw0 crw------- 1 root root 239, 1 7月 4 00:40 /dev/hidraw1 crw------- 1 root root 239, 2 7月 4 01:40 /dev/hidraw2
すぐにわかるのはホスト上だと/dev/
」+
」+
」
具体的な設定内容はgetfacl
コマンドで確認できます。
$ getfacl -p /dev/input/js0 # file: /dev/input/js0 # owner: root # group: input user::rw- user:shibata:rw- group::rw- mask::rw- other::r--
つまり通常のパーミッションとは別にユーザー
JoyStickデバイスはudevルールによりこのACLが設定されるような仕組みになっています。udevルールファイルにおけるTAG+="uaccess"
」
しかしながらLXDのインスタンスの中ではこのACLの設定が行われません+
」/dev/
」/dev/
」
さらにSteamは/dev/
」/dev/
」TAG+="uaccess"
」/dev/
」
さて、
- Steamクライアントを実行するユーザーはinputグループに所属する
/dev/
のグループオーナーをinputにしておき、hidraw2 グループが読み書きできるようにしておく
後者については、/dev/
」TAG+="uaccess"
」
「/dev/
」/dev/
」
$ lxc exec steam -- usermod -aG input ubuntu $ lxc exec steam -- chmod g+rw /dev/hidraw2 $ lxc exec steam -- chgrp input /dev/hidraw2
一度、

起動スクリプトとデスクトップファイルの作成
さてここまで話をもとに、
- steamクライアントが起動していなかったら起動する
- JoyStickデバイスが見えなかったら、
接続もしくは再接続を促す - JoyStickデバイスのパーミッションを適切に起動する
- コンテナの中のsteamクライアントを起動する
次のコマンドでホスト上に起動スクリプトを作成します。
$ cat <<'EOF' > steam-launcher #!/bin/sh CONTAINER="$1" TITLE="Steam Launcher" if [ -z "${CONTAINER}" ]; then notify-send "${TITLE}" "Please specify container name" exit 1 fi # check and start container status=$(lxc list --format csv -c s "^${CONTAINER}$") if [ "$status" != "RUNNING" ]; then lxc start "${CONTAINER}" lxc exec "${CONTAINER}" -- cloud-init status --wait status=$(lxc list --format csv -c s "^${CONTAINER}$") if [ "$status" != "RUNNING" ]; then notify-send "${TITLE}" "Failed to start \"${CONTAINER}\" container" exit 1 fi fi JOYSTICK="" for d in $(lxc exec "${CONTAINER}" -- sh -c 'ls /dev/input/js*' 2>/dev/null) ; do if lxc exec "${CONTAINER}" -- test -c "$d" ; then DEVPATH=$(lxc exec "${CONTAINER}" -- udevadm info -q path "$d" | sed 's,input/.*$,,') for h in $(lxc exec "${CONTAINER}" -- sh -c 'ls /dev/hidraw*' 2>/dev/null) ; do if [ "$(lxc exec "${CONTAINER}" -- udevadm info -q path "$h" | sed 's,hidraw/.*$,,')" = "${DEVPATH}" ]; then lxc exec "${CONTAINER}" -- chmod g+rw "$h" lxc exec "${CONTAINER}" -- chgrp input "$h" JOYSTICK="$h" fi done fi done if [ -z "${JOYSTICK}" ]; then notify-send "${TITLE}" "Not found JoyStick device. Please re-plug JoyStick." exit 1 fi lxc exec "${CONTAINER}" -- sudo --user=ubuntu --login steam EOF
GitHub Gistにも同じ内容のデータをアップロードしてありますので、
本スクリプトは
うまく動かなかったときは、notify-send
」
コンテナの状態はlxc list --format csv -c s コンテナ名
」--format csv
」--columns s
-c s
)」で表示するフィールドを制限できます。詳しいことはlxc help list
」
コンテナが起動していない場合は、cloud-init status --wait
」
コンテナが起動したあとは、
うまく動くようなら、
$ sudo cp steam-launcher /usr/local/bin/
実際に使ってみるとわかるのですが、
デスクトップファイルの作成
次にこのスクリプトを実行するデスクトップファイルを作成します。デスクトップファイルを作成しておくと、
まずはデスクトップファイルに表示するアイコンを、
$ lxc file pull \ steam/home/ubuntu/.local/share/Steam/tenfoot/resource/images/steam_home.png \ ~/.local/share/icons/
次にデスクトップファイルを作成します。
$ cat <<'EOF' > steam.desktop [Desktop Entry] Name=Steam on LXD Comment=Play games on Steam Exec=/usr/local/bin/steam-launcher steam Icon=/home/shibata/.local/share/icons/steam_home.png Terminal=false Type=Application Categories=Game; [Desktop Action stop-container] Nmae=Stop Steam container Exec=lxc stop steam
内容はそこまで難しいものではないはずです。ちなみにUbuntu 20.steam-launcher
の前にgamemoderun
を追加すればゲームモードが有効化されるのですが、
stop-containerはSteamコンテナを停止するためのアクションです。このようなアクションはデスクトップアイコンを右クリックすることで選択できます。たとえば一旦ログアウトしたあと、steam-launcher
の中でSteamクライアント終了後は常にSteamコンテナを終了しても実現できるのですが、
最後にデスクトップファイルを適切な場所にインストールしておきます。
$ desktop-file-install --dir ~/.local/share/applications/ steam.desktop
Super+Aでアクティビティの検索画面を開き


あとは普通のSteamと同じように動くはずです。今回紹介した手順はSteamに関係なく、