Plamo Linux 8.xでIncusを使用してUbuntu 22.04のGUIアプリを動かす

# はじめに
Plamo Linuxを愛する皆さんの中にはUbuntuでは動くのにPlamoで動かせない、または動かすのに苦労することで悩んだ経験がある方もいらっしゃるのではないかと思います。

Ubutu用のバイナリをdeb形式で配布しているアプリには、debファイルを解凍してPlamo形式のディレクトリ配置にすれば問題なく動くものも存在します。
(例: Google Chrome、Microsoft Edge)

しかし、要求されるPythonのバージョン不一致や、何故だか分からないけどPlamoでは動かないアプリも存在します。

この記事ではIncusを使用してホストPlamoでゲストUbuntu 22.04のGUIアプリとしてGIMPを動かすこと、日本語入力ができること、音が鳴ることを目標にします。

GPU関連の相性や設定などもあるかもしれませんが、SteamやOpenVINO AI Plugins for GIMPも動かせました。

![スクリーンショット_2024-06-22_22-21-32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/177889/c650e0e6-7e79-e1b4-3e6b-86e9807af86e.png)
![スクリーンショット_2024-06-23_21-00-32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/177889/1e0aee78-1e94-c06b-4501-21afc23294e3.png)


この記事はの次の記事を参考にしました。
https://qiita.com/usagr10asu1/items/a720f9e664e5948c4e31
https://wiki.archlinux.jp/index.php/LXD

私はIncus初心者です。質問を頂いても答えられないことの方が多いですが、Plamo LinuxのMLにはIncusの達人もいらっしゃいますので、もしかしたら教えてもらえるかもしれません。

# Incusのインストール
次のURLにPlamo用のincusがあります。最新版を入手してください。
http://repository.plamolinux.org/pub/linux/Plamo/Plamo-8.x/x86_64/contrib/container/

ここでは執筆時点の最新版であるincus-6.0.0-x86_64-B1.tzstを入手します。
```powershell
wget http://repository.plamolinux.org/pub/linux/Plamo/Plamo-8.x/x86_64/contrib/container/incus-6.0.0-x86_64-B1.tzst
````
入手したincusをインストールします。
```powershell
sudo installpkg incus-6.0.0-x86_64-B1.tzst
```
また、lxcとlxcfsがインストールされていない場合はインストールします。
次のURLにPlamo用のlxcとlxcfsがあります。最新版を入手してください。
https://repository.plamolinux.org/pub/linux/Plamo/Plamo-8.x/x86_64/plamo/16_virtualization/

ここでは執筆時点の最新版であるlxc-6.0.0-x86_64-B1.tzstとlxcfs-6.0.0-x86_64-B1.tzstを入手します。
```powershell
wget https://repository.plamolinux.org/pub/linux/Plamo/Plamo-8.x/x86_64/plamo/16_virtualization/lxc-6.0.0-x86_64-B1.tzst
```
```powershell
wget https://repository.plamolinux.org/pub/linux/Plamo/Plamo-8.x/x86_64/plamo/16_virtualization/lxcfs-6.0.0-x86_64-B1.tzst
```
入手したlxcとlxcfsをインストールします。
```powershell
sudo installpkg lxc-6.0.0-x86_64-B1.tzst lxcfs-6.0.0-x86_64-B1.tzst
```
dnsmasqもインストールされていなければインストールします。
次のURLにPlamo用のdnsmasqがあります。最新版を入手してください。
https://repository.plamolinux.org/pub/linux/Plamo/Plamo-8.x/x86_64/plamo/08_daemons/

ここでは執筆時点の最新版であるdnsmasq-2.89-x86_64-B1.tzstを入手します。
```powershell
wget https://repository.plamolinux.org/pub/linux/Plamo/Plamo-8.x/x86_64/plamo/08_daemons/dnsmasq-2.89-x86_64-B1.tzst
```
入手したdnsmasqをインストールします。
```powershell
sudo installpkg dnsmasq-2.89-x86_64-B1.tzst
```

# Incusの初期設定
まずIncusデーモンを起動します。
```powershell
sudo /etc/rc.d/init.d/incus start
```

初期設定をします。筆者は「新しい loop デバイスのサイズ」以外はデフォルトにしました。
```powershell
sudo incus admin init
```
```shell-session
クラスタリングを使用しますか? (yes/no) [default=no]:
新しいストレージプールのの設定をしますか? (yes/no) [default=yes]:
Name of the new storage pool [default=default]:
使用するストレージバックエンド名 (dir, lvm, lvmcluster, btrfs) [default=btrfs]:
新たに BTRFS プールを作成しますか? (yes/no) [default=yes]:
既存の空のブロックデバイス（ディスクやパーティションなど）を使用しますか? (yes/no) [default=no]:
新しい loop デバイスのサイズ (GiB) (1GiB minimum) [default=30GiB]: 200GiB
新しいローカルネットワークブリッジを作成しますか? (yes/no) [default=yes]:
新しいブリッジは何という名前にしますか? [default=incusbr0]:
どの IPv4 アドレスを使いますか? (CIDR subnet notation,“aut” or“non”) [default=auto]:to]:
どの IPv6 アドレスを使いますか? (CIDR subnet notation,“aut” or“non”) [default=auto]:to]:
Would you like the server to be available over the network? (yes/no) [default=no]: 
キャッシュされた古いイメージを自動的に更新しますか? (yes/no) [default=yes]: 
YAML 形式の初期設定値を表示しますか? (yes/no) [default=no]: 
```
使用しているユーザをincusグループに所属させます。
ここではtakahiroユーザをincusグループに所属させます。適宜置き換えてください。
```powershell
sudo usermod -aG incus takahiro
```
サブUIDとサブGIDの設定をします。
ここではユーザtakahiroとrootにそれぞれ100000から65536個のサブUIDとサブGIDを設定しています。
takahiroはご自分のユーザ名に置き換えてください。

まずはサブUIDです。
```powershell
sudo vim /etc/subuid
```
```shell-session
takahiro:100000:65536
root:100000:65536
```
サブGIDです。
```powershell
sudo vim /etc/subgid
```
```shell-session
takahiro:100000:65536
root:100000:65536
```
設定を確実に有効にするため、ここでシステムを再起動します。
```powershell
sudo reboot
```

# Incusコンテナの作成
Incusコンテナの作成をします。
この記事ではゲストの名前をubuntu-containerにします。
incusコマンドでホストからゲストの設定をしています。
```powershell
incus launch images:ubuntu/22.04 ubuntu-container
```
ゲストのUbuntuをアップデートします。
```powershell
incus exec ubuntu-container -- /bin/bash -c "apt update && apt full-upgrade -y && apt autoremove -y"
```
ゲストのUbuntuを再起動します。
```powershell
incus exec ubuntu-container -- reboot
```

# Incusコンテナの設定
<!--
ホストのUIDとGIDを確認します。
```powershell
id
```
```shell-session
uid=1000(takahiro) gid=100(users) groups=100(users),
以下省略
```
ホストで使用するユーザ(筆者の環境ではtakahiro)のUIDが1000、GIDが100だと確認できました。
次にゲストで使用するユーザ(ubuntu)のUIDとGIDを確認します。
```powershell
incus exec ubuntu-container -- id ubuntu
```
```shell-session
uid=1000(ubuntu) gid=1000(ubuntu) groups=1000(ubuntu),27(sudo),44(video)
```
ゲストのUIDとGIDはともに1000だと確認できました。

ゲストの内部IDとホストのIDをマッピングします。
```powershell
printf "uid 1000 1000\ngid 100 1000" | incus config set ubuntu-container raw.idmap -
```
-->
デバイスの設定を行ないます。
まずゲスト内に/mnt/xorg1/というディレクトリを追加します。
```powershell
incus exec ubuntu-container -- mkdir -p /mnt/xorg1/
```
次のコマンドでエディタを開いてデバイスの設定を行ないます。
```powershell
incus config edit ubuntu-container
```
deviceのセクションを以下のように記述します。
```shell-session
devices:
  Xsocket:
    bind: container 
    connect: unix:/tmp/.X11-unix/X0
    gid: "1000"
    listen: unix:/mnt/xorg1/X0
    mode: "0777"
    security.gid: "1000"
    security.uid: "1000"
    type: proxy
    uid: "1000"
  mygpu:
    gid: "44"
    type: gpu
  pa:
    path: /tmp/.pulse-native
    source: /run/user/1000/pulse/native
    type: disk
```
記述の説明をします。
Xsocketデバイスの
```shell-session
    connect: unix:/tmp/.X11-unix/X0
```
```shell-session
    listen: unix:/mnt/xorg1/X0
```
の2箇所のX0の部分は、ホストの/tmp/.X11-unix/ディレクトリの内容に依存します。
ホストで実行する次のコマンド
```powershell
ls /tmp/.X11-unix/
```
の結果が
```shell-session
X0=
```
であれば、Xsocketデバイスの設定には
```shell-session
    connect: unix:/tmp/.X11-unix/X0
```
```shell-session
    listen: unix:/mnt/xorg1/X0
```
と記述し、ホストの/tmp/.X11-unix/ディレクトリの中身が
```shell-session
X1=
```
であれば、Xsocketデバイスの設定には
```shell-session
    connect: unix:/tmp/.X11-unix/X1
```
```shell-session
    listen: unix:/mnt/xorg1/X1
```
と記述します。

mygpuデバイスの
```shell-session
    gid: "44"
```
の44は、ゲスト内のvideoグループのGIDに一致させます。
ホストで以下のコマンドを実行するとGIDを調べることができます。
```powershell
incus exec ubuntu-container -- getent group video
```
```shell-session
video:x:44:ubuntu
```
44がvideoグループのGIDになります。

# Incusコンテナにパッケージをインストール
X Window Systemやフォント、インプットメソッド、GIMPと音声再生のためSoxのインストールまで行ないます。
```powershell
incus exec ubuntu-container -- bash -c "apt install -y x11-apps pulseaudio dbus-x11 language-pack-ja fonts-noto-cjk-extra task-japanese-gnome-desktop language-pack-gnome-ja-base language-pack-gnome-ja gnome-user-docs-ja gnome-control-center fonts-noto-color-emoji manpages-ja fcitx5-mozc ibus-mozc wget sox gedit gimp"
```

# Incusコンテナのサウンドの設定
サウンドの設定を行ないます。
```powershell
incus exec ubuntu-container -- /bin/bash -c 'sed -i "s/; enable-shm = yes/enable-shm = no/g" /etc/pulse/client.conf'
```
```powershell
incus exec ubuntu-container -- /bin/bash -c "echo export PULSE_SERVER=unix:/tmp/.pulse-native | tee --append /home/ubuntu/.profile"
```

# Incusコンテナの日本語環境を設定
以下のコマンド群を実行します。
```powershell
incus exec ubuntu-container -- /bin/bash -c "update-locale LANG=ja_JP.UTF-8"
```
```powershell
incus exec ubuntu-container -- /bin/bash -c "timedatectl set-timezone Asia/Tokyo"
```
```powershell
incus exec ubuntu-container -- /bin/bash -c 'localectl set-locale LANG=ja_JP.UTF-8 LANGUAGE="ja_JP:ja"'
```
```powershell
incus exec ubuntu-container -- /bin/bash -c "echo export LANG=ja_JP.UTF8 | tee --append /home/ubuntu/.profile"
```
```powershell
incus exec ubuntu-container -- /bin/bash -c "localectl set-x11-keymap jp jp106"
```
```powershell
incus exec ubuntu-container -- /bin/bash -c 'sh -c "dbus-uuidgen > /var/lib/dbus/machine-id"'
```
ここでゲストのubuntu-containerのユーザubuntuのシェルに入ります。
```powershell
incus exec ubuntu-container  -- /bin/su - ubuntu
```
次はゲストのubuntuユーザのシェルです。
```powershell
ubuntu@ubuntu-container:~$ im-config -n fcitx5
ubuntu@ubuntu-container:~$ source /etc/default/locale
ubuntu@ubuntu-container:~$ vim .profile 
```
.profileに以下の記述を追加します。
```shell-session
export GTK_IM_MODULE=fcitx5
export QT_IM_MODULE=fcitx5
export XMODIFIERS=@im=fcitx5
export DefaultIMModule=fcitx5
if [ $SHLVL = 1 ] ; then
  (fcitx5 > /dev/null 2>&1 &)
  xset -r 49  > /dev/null 2>&1
fi

export DISPLAY=:0
export NO_AT_BRIDGE=1
```
ここでゲストを再起動します。
コンテナのシェルを実行していれば次のようにします。
```powershell
ubuntu@ubuntu-container:~$ sudo reboot
```
# IncusコンテナのGUIアプリを起動して設定の続きを行なう
ゲストのGUIアプリを実行してインプットメソッドの設定を行ないます。

まずホストで次のコマンドを実行します。
このコマンドは、ゲストのGUIアプリを使用したい場合、X Window Systemの起動や再起動する毎に行なう必要があります。
自動で行ないたい場合は各自で適宜設定してください。
```powershell
xhost +local:
```

続けて次のコマンドを実行します。
このコマンドは、ゲストのGUIアプリを使用したい場合、ゲストの起動や再起動する毎に行なう必要があります。
自動で行ないたい場合は各自で適宜設定してください。
X0の部分は上記の説明と同様にホストの/tmp/.X11-unix/ディレクトリ以下の結果によって異なります。
```powershell
incus exec ubuntu-container -- sudo --user=ubuntu --login ln -s /mnt/xorg1/X0 /tmp/.X11-unix/X0
```
ゲストのgnome-language-selectorを実行します。
追加のパッケージのインストールを求められた場合はインストールしようとするとエラーが起こる可能性があります。
筆者はエラーが出ても無視し、求められたパッケージを後でaptでインストールしました。
```powershell
incus exec ubuntu-container -- sudo --user=ubuntu --login gnome-language-selector
```
![スクリーンショット_2024-06-23_10-29-33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/177889/77c736ec-8df1-92a4-dd11-54f1f68476ed.png)
キーボード入力に使うIMシステムをFcitx5に設定します。

# GIMPの起動
GIMPを起動してみます。
```powershell
incus exec ubuntu-container -- sudo --user=ubuntu --login gimp
```
![スクリーンショット_2024-06-23_15-25-17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/177889/cf0c3d19-b645-a815-c2bc-c91e61068ae8.png)
GIMPが起動しました。

# 日本語入力できることを確認
geditを起動し、Ctrl + Spaceで日本語入力モードにし、入力してみます。
```powershell
incus exec ubuntu-container -- sudo --user=ubuntu --login gedit
```
![スクリーンショット_2024-06-23_16-00-53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/177889/2af8b625-6f46-cff4-6bce-08c2e5489097.png)


# 音が鳴ることを確認
サンプル音源を入手します。
```powershell
incus exec ubuntu-container -- sudo --user=ubuntu --login wget http://freewavesamples.com/files/Kurzweil-K2000-Dual-Bass-C1.wav
```
再生してみます。
```powershell
incus exec ubuntu-container -- sudo --user=ubuntu --login play /home/ubuntu/Kurzweil-K2000-Dual-Bass-C1.wav
```
音が鳴ったでしょうか？