我想修改已安装的 Flatpak 的运行方式,以便podman
Flatpak 使用的容器在 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 轻松地逐一编辑这些文件,但如果我想编写此编辑脚本怎么办?
我想我需要的是:
- 一种查找
.desktop
给定 Flatpak 的已安装文件的方法,以便我可以使用 bash 脚本编辑它们 .desktop
即使在 Flatpak 升级更改文件后,也可以使我对此类文件的编辑保持不变.desktop
- 无需用户执行任何手动步骤
(假设我无法使用套接字激活,因为 podman 容器不支持它。)
答案1
对我的 dbus 会话总线的一点监视揭示了与 vscodium Flatpak 容器相关的大量流量。但经过一番谷歌搜索后,我了解到如果 systemd 正在运行——这对我来说是——任何Flatpak 容器将在启动时向 systemd 发送一条消息,这意味着我们可以使用systemd配置文件配置所需的自动启动行为。
这就是我所做的。此解决方案说明了创建 systemd 配置文件的两种可能方法:
- 一个简单的文件,或者
- 目录中的文件
.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 容器也停止。所以我无法让容器自动关闭,但这是一个可选要求。