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

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

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

这让 Snap 软件包非常烦躁。当我尝试运行它们时,它们显示:

抱歉,目前不支持 /home 之外的主目录。请参阅https://forum.snapcraft.io/t/11209了解详情。

当我访问该 URL 时,我得到了一个解决方法,但没有足够详细的描述来实际实施:

如果用户的主目录不在 /home 中,Snapd 目前不支持运行 snap。此处讨论了这个问题这里

一种解决方法是将 /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.

那么,究竟如何才能实现 Michael Vogt 在链接的 Snapcraft 论坛帖子中描述的解决方法呢?或者说该解决方法实际上不起作用?

答案1

似乎snap直接从/etc/passwd而不是任何其他来源获取有关您的主目录位置的信息。我能够找到的一个最有效的解决方法是使用 Docker 容器/etc/passwdsnap的角度替换 ,并将其替换为一个表示我的主目录是 的容器/home/$USER

我确信有一种更轻量的方法可以做到这一点(也许只是一个 chroot?),这将消除一些其他我需要一种解决方法来snap在容器内工作,我还没有尝试过minetest,但这是我编写的脚本,它可以运行 Snap,teatime而我不必实际移动我的主目录。基本上,它在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

相关内容