在 Ubuntu 中打包为 snap 的应用程序安装(挂载)在该/snap/$SNAPPNAME
位置下。该位置下的所有内容/snap
都挂载为只读文件系统,因此应用程序无法写入该空间,无论是在其他应用程序的目录中还是在自己的目录中。
虽然有一个home
界面snaps 可以指定读/写用户的主目录,它是出于安全原因而保留的,需要用户手动连接(启用)。
那么 snap 中的应用可以在哪里写入其配置、数据和其他文件?是否有 API 可以访问特殊的可写位置?
答案1
当您在 中声明应用程序时snapcraft.yaml
,它会在安装时生成一个二进制包装器并放入 中/snap/bin/
,以您的包和应用程序名称命名(请注意,如果应用程序是一个服务,则这个包装器就是 systemd .service 文件)。
该包装器包含应用程序运行的大部分环境。与此问题最相关的两个环境变量是SNAP_DATA
和SNAP_USER_DATA
。您可以在以下位置找到有关这些变量的更多信息文档,但我也会在这里描述它们:
SNAP_DATA
是系统范围的可写区域(位于 中/var/snap/
)。例如,这可用于托管服务日志。SNAP_USER_DATA
是运行应用程序的用户(特别是/home/<user>/snap/
)主目录中用户特定的可写区域。这可能用于用户特定的配置文件等。
这两个目录对于升级/回滚功能都非常重要,因为它们都是版本化也就是说,给定 snap 的每个修订版本都有这些目录的副本。让我用一个例子来解释一下。
假设你安装了“foo” snap 的第 1 版。这将创建两个目录:
/var/snap/foo/1
(SNAP_DATA
)/home/<user>/snap/foo/1
(SNAP_USER_DATA
)
现在假设“foo”同时使用了这两个。也许它有一个在 中托管数据库的服务SNAP_DATA
,以及一个使用 中的配置文件的二进制文件SNAP_USER_DATA
。
现在“foo”的第 2 个修订版本已经发布,并且会自动更新。首先发生的事情是将/var/snap/foo/1
复制到 中/var/snap/foo/2
,并将/home/<user>/snap/foo/1
复制到 中/home/<user>/snap/foo/2
。然后启动新修订版本。它应该注意到它正在旧数据上运行,并且可能需要运行一些数据库迁移到 中的数据库SNAP_DATA
。它执行完这些操作,然后就运行了。
现在假设这些迁移由于某种原因失败,并且需要回滚此应用程序。它开始使用 /snap/foo 应用程序的旧版本,其中SNAP_DATA
指向/var/snap/foo/1
并且SNAP_USER_DATA
指向/home/<user>/snap/foo/1
。这会在迁移运行之前的旧版本上拾取内容,因为这些操作是在数据的副本上运行的。
长话短说:不要使用接口home
来存储您可以存储在SNAP_DATA
或中的数据SNAP_USER_DATA
,因为它们是升级/回滚策略不可或缺的一部分。充分利用它们!
v2.0.10 更新:
还引入了两个新的数据目录:
SNAP_COMMON
坐在旁边SNAP_DATA
,但具体是未版本化。特定 snap 的每个修订版本都可以访问此目录,因此在升级/回滚等时不会被复制。这可能用于特别大、未版本控制的文件(例如,不是真正特定于版本的原始数据)。SNAP_USER_COMMON
坐在旁边SNAP_USER_DATA
,但又特别未版本化.它可能用于存储每个用户的非特定版本的数据。
v2.15 更新:
放置在其中的文件/snap/bin
不再是定义环境的包装器,而是指向的符号链接/usr/bin/snap
。因此,确定应用程序运行环境的方法是使用snap run --shell <snap>.<app>
,例如:
$ sudo snap install hello-world
$ snap run --shell hello-world
To run a command as administrator (user "root"), use "sudo <command>".
See "man sudo_root" for details.
$ env | grep SNAP
SNAP_USER_COMMON=/home/kyrofa/snap/hello-world/common
SNAP_REEXEC=
SNAP_LIBRARY_PATH=/var/lib/snapd/lib/gl:
SNAP_COMMON=/var/snap/hello-world/common
SNAP_USER_DATA=/home/kyrofa/snap/hello-world/27
SNAP_DATA=/var/snap/hello-world/27
SNAP_REVISION=27
SNAP_NAME=hello-world
SNAP_ARCH=amd64
SNAP_VERSION=6.3
SNAP=/snap/hello-world/27