编写向 Flatpaks 添加预运行挂钩的脚本

编写向 Flatpaks 添加预运行挂钩的脚本

我想修改已安装的 Flatpak 的运行方式,以便podmanFlatpak 使用的容器在 Flatpak 运行之前运行(最好在 Flatpak 完成运行后关闭,但这是可选的)。这样做的目的是节省资源——podman容器不需要一直运行。

例如,我想explainshell在 VSCode 启动时启动一个容器。

为了涵盖从命令行运行 Flatpaks 的情况,这很简单 - 我可以只alias flatpak使用一个flatpak-wrapper脚本,然后在该flatpak-wrapper脚本中拦截flatpak run我关心的调用,podman run在必要时运行命令,然后运行原始请求flatpak run命令。

然而,.desktop通过 flatpak 安装的文件比较棘手,因为它们包含硬编码的/usr/bin/flatpak调用,这显然不受 shell 别名的影响。我可以.desktop通过 KDE UI 轻松地逐一编辑这些文件,但如果我想编写此编辑脚本怎么办?

我想我需要的是:

  1. 一种查找.desktop给定 Flatpak 的已安装文件的方法,以便我可以使用 bash 脚本编辑它们
  2. .desktop即使在 Flatpak 升级更改文件后,也可以使我对此类文件的编辑保持不变.desktop- 无需用户执行任何手动步骤

(假设我无法使用套接字激活,因为 podman 容器不支持它。)

答案1

对我的 dbus 会话总线的一点监视揭示了与 vscodium Flatpak 容器相关的大量流量。但经过一番谷歌搜索后,我了解到如果 systemd 正在运行——这对我来说是——任何Flatpak 容器将在启动时向 systemd 发送一条消息,这意味着我们可以使用systemd配置文件配置所需的自动启动行为。

这就是我所做的。此解决方案说明了创建 systemd 配置文件的两种可能方法:

  1. 一个简单的文件,或者
  2. 目录中的文件.d- 这更适合脚本创建,因为这样它们可以使用不会与任何其他脚本冲突的唯一文件名。
[greenrd@fedora ~]$ mkdir .config/systemd/user

.service为 podman 容器生成 systemd文件。我们将重新启动策略设置为“否”,因为稍后我们的 Uphold 将负责重新启动它。

我使用tee它是为了在安装之前可以查看它,因为我是在命令提示符下手动执行此操作的。在脚本中,这不是必需的。

[greenrd@fedora ~]$ podman generate systemd --restart-policy=no explainshell |tee es.service
WARN[0000] Container 2f9dd483eed9f6a5705dc142e65c55103c25f8884aa51e3b0e400686f8640b31 has restart policy "always" which can lead to issues on shutdown: consider recreating the container without a restart policy and use systemd's restart mechanism instead 
# container-2f9dd483eed9f6a5705dc142e65c55103c25f8884aa51e3b0e400686f8640b31.service
# autogenerated by Podman 4.5.1
# Fri Jun 16 21:19:03 BST 2023

[Unit]
Description=Podman container-2f9dd483eed9f6a5705dc142e65c55103c25f8884aa51e3b0e400686f8640b31.service
Documentation=man:podman-generate-systemd(1)
Wants=network-online.target
After=network-online.target
RequiresMountsFor=/run/user/1000/containers

[Service]
Environment=PODMAN_SYSTEMD_UNIT=%n
Restart=no
TimeoutStopSec=70
ExecStart=/usr/bin/podman start 2f9dd483eed9f6a5705dc142e65c55103c25f8884aa51e3b0e400686f8640b31
ExecStop=/usr/bin/podman stop  \
        -t 10 2f9dd483eed9f6a5705dc142e65c55103c25f8884aa51e3b0e400686f8640b31
ExecStopPost=/usr/bin/podman stop  \
        -t 10 2f9dd483eed9f6a5705dc142e65c55103c25f8884aa51e3b0e400686f8640b31
PIDFile=/run/user/1000/containers/overlay-containers/2f9dd483eed9f6a5705dc142e65c55103c25f8884aa51e3b0e400686f8640b31/userdata/conmon.pid
Type=forking

[Install]
WantedBy=default.target

让我们删除启动时自动启动的行为:

[greenrd@fedora ~]$ sed -i -e '/WantedBy=default\.target/d' es.service

并删除重新启动配置,因为Upholds下面应该处理这个问题:

[greenrd@fedora ~]$ sed -i -e '/Restart=/d' es.service

看起来不错 - 让我们安装它:

[greenrd@fedora ~]$ mv es.service .config/systemd/user/explainshell.service

并添加依赖关系 - 我发现使用范围忙碌:

[greenrd@fedora ~]$ cat <<EOF >.config/systemd/user/app-com.vscodium.codium-.scope.d/my-ublue.conf
> [Unit]
Upholds=explainshell.service
> EOF

最后,让 systemd 知道我们的新配置文件:

[greenrd@fedora ~]$ systemctl --user daemon-reload

好的,这可行,但容器在 vscodium 退出后仍然存在:

[greenrd@fedora ~]$ podman ps
CONTAINER ID  IMAGE                                    COMMAND               CREATED       STATUS             PORTS                   NAMES
9b733a307e42  quay.io/fedora/fedora:38                 -v --name greenrd...  2 days ago    Up 2 days                                  fedora
ef21c84a47eb  ghcr.io/ublue-os/boxkit:latest           -v --name greenrd...  2 days ago    Up 2 days                                  boxkit
2f9dd483eed9  ghcr.io/idank/idank/explainshell:master  make serve            45 hours ago  Up About a minute  0.0.0.0:5000->5000/tcp  explainshell

事实上,vscodium 还没有完全消亡。有一些僵尸进程和一些其他进程仍然存在。奇怪的。让我们杀掉他们吧:

[greenrd@fedora ~]$ killall codium
[greenrd@fedora ~]$ killall codium
[greenrd@fedora ~]$ killall -KILL codium
codium: no process found

但explainshell容器仍然存在:

[greenrd@fedora ~]$ podman ps
CONTAINER ID  IMAGE                                    COMMAND               CREATED       STATUS        PORTS                   NAMES
9b733a307e42  quay.io/fedora/fedora:38                 -v --name greenrd...  2 days ago    Up 2 days                             fedora
ef21c84a47eb  ghcr.io/ublue-os/boxkit:latest           -v --name greenrd...  2 days ago    Up 2 days                             boxkit
2f9dd483eed9  ghcr.io/idank/idank/explainshell:master  make serve            45 hours ago  Up 3 minutes  0.0.0.0:5000->5000/tcp  explainshell

为了尝试解决这个问题,我尝试添加

After=explainshell.service
PropagatesStopTo=explainshell.service

my-ublue.conf。然而,不幸的是,Flatpak 创建的初始作用域是暂时的,因此它会停止并立即导致explainshell 容器也停止。所以我无法让容器自动关闭,但这是一个可选要求。

相关内容