当您的主目录不在 /home 下时,您如何*实际上*运行 Snap 包?

int*_*ect 6 mount home-directory snap

我的主目录位于/z/home/$USER,而不是 at /home/$USER,因此我可以在 ZFS 上拥有它。

这让 Snap 软件包无休止地感到不安。当我尝试运行它们时,它们说:

抱歉,当前不支持 /home 之外的主目录。有关详细信息,请参阅https://forum.snapcraft.io/t/11209

当我转到该 URL 时,我得到了一种解决方法,但没有详细描述以实际实施:

如果用户的主目录在 /home 之外,则 Snapd 当前不支持运行快照。这在这里讨论。

解决方法是将挂载 /home 之外的主目录绑定到 /home。

链接的线程退化为关于正确支持任意主目录的设计应该是什么的讨论,并且对我来说如何实现所描述的解决方法并不是很明显。我尝试绑定安装/z/home/$USER也出现在/home/$USER,并告诉 Snap 那是我的主目录,但我想运行的 Snap 包仍然坚持我的主目录是坏的并且拒绝运行:

$ sudo mkdir /home/$USER
$ sudo chown ${USER}:${USER} /home/$USER
$ sudo mount --bind /z/home/$USER /home/$USER
$ HOME=/home/$USER any-snap-package 
Sorry, home directories outside of /home are not currently supported. 
See https://forum.snapcraft.io/t/11209 for details.
Run Code Online (Sandbox Code Playgroud)

究竟如何实施 Michael Vogt 在链接的 Snapcraft 论坛帖子中描述的解决方法?或者解决方法实际上不起作用?

int*_*ect 1

似乎snap直接从您的主目录的位置获取信息/etc/passwd,而不是从任何其他来源获取信息。我已经能够大部分工作的一种解决方法是使用 Docker 容器来替换/etc/passwdsnap的角度来看,其中一个表示我的主目录是/home/$USER

我确信有一种更轻量级的方法可以做到这一点(也许只是 chroot?),这将消除我在容器内工作所需的其他一些snap解决方法的需要,而且我还没有尝试过minetest,但这是我编写的脚本,可以运行teatimeSnap,而无需实际移动我的主目录。基本上,它启动一个容器snapd,其中所有位置都snapd保持从外部安装的状态,但使用新安装的基本状态进行初始化snapd(这就是它需要local-persistDocker 卷驱动程序的原因)。然后它snap像您一样在容器中运行,所有 X11 和 DBUS 管道都已连接,以便teatime可以显示其窗口和桌面通知。

#!/usr/bin/env bash

# teatime.sh: Run the teatime snap in a Docker container
# Requires local-persist driver installed in Docker: https://github.com/MatchbookLab/local-persist
# Installs it if not available.

set -ex

IMAGE_NAME="snapdock"
CONTAINER_NAME="snaphost"
STORAGE_ROOT="/var/lib/snapdock"
PASSWD_FILE="$HOME/etc/passwd.docker"

if [[ ! -f "${PASSWD_FILE}" ]] ; then
    # The /etc/passwd that claims we have a normal home directory doesn't exist.
    # We need to make it.
    mkdir -p "$(dirname "${PASSWD_FILE}")"

    cat "/etc/passwd" | sed "s_${HOME}_/home/${USER}_g" > "${PASSWD_FILE}"
fi


if ! (docker images "${IMAGE_NAME}" | grep "${IMAGE_NAME}" >/dev/null) ; then
    # There's no image ready. We need to make one
    WORKDIR="$(mktemp -d)"
    cd "${WORKDIR}"
    cat >Dockerfile <<EOF
FROM ubuntu:18.04
# Based on https://github.com/ogra1/snapd-docker/blob/master/build.sh
ENV container docker
ENV PATH "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin"
ENV LANG C.UTF-8
ENV LC_ALL C.UTF-8
RUN DEBIAN_FRONTEND=noninteractive apt-get -q -y update && \
    DEBIAN_FRONTEND=noninteractive apt-get -q -y upgrade && \
    DEBIAN_FRONTEND=noninteractive apt-get -q -y install \
        fuse \
        snapd \
        snap-confine \
        squashfuse \
        sudo && \
    apt-get clean && \
    dpkg-divert --local --rename --add /sbin/udevadm && \
    ln -s /bin/true /sbin/udevadm
VOLUME ["/sys/fs/cgroup"]
STOPSIGNAL SIGRTMIN+3
CMD ["/sbin/init"]
EOF
    docker build . -t "${IMAGE_NAME}"
    cd -
    rm -Rf "${WORKDIR}"
fi

if ! which docker-volume-local-persist >/dev/null ; then
    # We need the local-persist driver installed into Docker.

    WORKDIR="$(mktemp -d)"
    cd "${WORKDIR}"
    curl -fsSL "https://raw.githubusercontent.com/MatchbookLab/local-persist/45c5c344d5dfd358c28d7148be48302d20456fac/scripts/install.sh" >install.sh
    chmod +x install.sh
    cat install.sh
    sudo install.sh
    cd -
    rm -Rf "${WORKDIR}"
fi

if ! (docker ps --filter "name=${CONTAINER_NAME}" | grep "${CONTAINER_NAME}" >/dev/null) ; then
    # Container is not running. Start it.

    if [[ ! -e "${STORAGE_ROOT}" ]] ; then
        # Make sure we have the directories to mount          
        mkdir -p "${STORAGE_ROOT}/lib"
        mkdir -p "${STORAGE_ROOT}/cache"
        mkdir -p "${STORAGE_ROOT}/systemd"
        mkdir -p "${STORAGE_ROOT}/snap"
        sudo chown -R root:root "${STORAGE_ROOT}"
    fi

    # Start the container
    docker run --rm --network=host --cap-add SYS_ADMIN --security-opt apparmor:unconfined --security-opt seccomp:unconfined --volume="$(echo ~:/home/${USER})"  --volume="${PASSWD_FILE}:/etc/passwd:ro" --volume="/etc/group:/etc/group:ro" --volume="/etc/shadow:/etc/shadow:ro" --volume="/etc/sudoers.d:/etc/sudoers.d:ro" --volume="/tmp/.X11-unix:/tmp/.X11-unix:rw" --volume="/sys/fs/cgroup:/sys/fs/cgroup:ro" --volume="/lib/modules:/lib/modules:ro" --device=/dev/fuse --tmpfs /run --tmpfs /run/lock --volume="/run/user/$(id -u):/run/user/$(id -u):rw" --tmpfs /tmp --volume="${STORAGE_ROOT}/lib/:/var/lib/snapd:rw" --volume="${STORAGE_ROOT}/cache/:/var/cache/snapd:rw" --mount "type=volume,volume-driver=local-persist,src=installed-snaps-systemd,target=/etc/systemd/system,volume-opt=mountpoint=${STORAGE_ROOT}/systemd" --mount "type=volume,volume-driver=local-persist,src=installed-snaps-snap,target=/snap,volume-opt=mountpoint=${STORAGE_ROOT}/snap" -it --name="${CONTAINER_NAME}" -d "${IMAGE_NAME}" >/dev/null

    # Wait for it to come up
    sleep 5

fi

# Make sure the snap is installed
docker exec snaphost snap install teatime
# Try and fail to run it as root to avoid complaints about not being able to capture mountpoints when we run it as us.
docker exec snaphost teatime || true
# Run it as us with X11 and Dbus set up
docker exec -d --user="$(id -u ${USER})" --env="DISPLAY" --env="DBUS_SESSION_BUS_ADDRESS" snaphost teatime
Run Code Online (Sandbox Code Playgroud)