From 1f5184167895ff1a8b18443009acde54fb87a568 Mon Sep 17 00:00:00 2001 From: Darragh Bailey Date: Wed, 30 Jun 2021 17:56:09 +0100 Subject: [PATCH] Use working directory for user/group resolution (#1320) To handle where the ~/.vagrant.d global state directory for a user doesn't exist, and thus specifying it as part of the docker run command will result in the docker daemon creating it with root ownership. Switch to using the working directory for user/group resolution, searching for the Vagrantfile in the starting path and then working up the tree. If it's not found default to the original starting path. Combined with checking if the mounted vdir is empty, use the resolved user/group based on the Vagrantfile and working directory to modify the newly created directory to belong to the running user. Subsequently ensure that the directories referenced via symlinks are created if they don't exist. Fixes: #1191 Closes: #1254 --- README.md | 9 +++--- entrypoint.sh | 81 ++++++++++++++++++++++++++++++++++++--------------- 2 files changed, 61 insertions(+), 29 deletions(-) diff --git a/README.md b/README.md index c0f49f4..d426f5d 100644 --- a/README.md +++ b/README.md @@ -131,8 +131,8 @@ docker run -it --rm \ -e LIBVIRT_DEFAULT_URI \ -v /var/run/libvirt/:/var/run/libvirt/ \ -v ~/.vagrant.d:/.vagrant.d \ - -v $(pwd):$(pwd) \ - -w $(pwd) \ + -v $(realpath "${PWD}"):${PWD} \ + -w $(realpath "${PWD}") \ --network host \ vagrantlibvirt/vagrant-libvirt:latest \ vagrant status @@ -141,13 +141,12 @@ docker run -it --rm \ It's possible to define an alias in `~/.bashrc`, for example: ```bash alias vagrant=' - mkdir -p ~/.vagrant.d/{boxes,data,tmp}; \ docker run -it --rm \ -e LIBVIRT_DEFAULT_URI \ -v /var/run/libvirt/:/var/run/libvirt/ \ -v ~/.vagrant.d:/.vagrant.d \ - -v $(pwd):$(pwd) \ - -w $(pwd) \ + -v $(realpath "${PWD}"):${PWD} \ + -w $(realpath "${PWD}") \ --network host \ vagrantlibvirt/vagrant-libvirt:latest \ vagrant' diff --git a/entrypoint.sh b/entrypoint.sh index db37a7f..c57bbda 100755 --- a/entrypoint.sh +++ b/entrypoint.sh @@ -13,43 +13,63 @@ then exit 2 fi -for dir in boxes data tmp -do - # if the directory hasn't been explicitly mounted over, remove it. - if [[ -e "/vagrant/${dir}/.remove" ]] - then - rm -rf /vagrant/${dir} - ln -s ${vdir}/${dir} /vagrant/${dir} - fi -done - vdir_mnt=$(stat -c %m ${vdir}) case "${vdir_mnt%%/}" in /*) # user mounted vagrant home is not mounted on /, so # presumably it is a mount bind or mounted volume and should - # be able to determine suitable uid/gid + # be able to persist boxes and machine index. + # ;; *) - echo "${vdir} is not set to a bind mounted volume, will not be able" - echo "to automatically determine suitable uid/gid to execute under." - if [[ -z "${USER_UID:-}" ]] || [[ -z "${USER_GID:-}" ]] - then - echo "USER_UID and USER_GID must be explicitly provided when" - echo "auto-detection is unable to be used" - - exit 2 - fi + echo -n "${vdir} is not set to a bind mounted volume, may not be able " + echo -n "to persist the machine index which may result in some unexpected " + echo "behaviour." ;; esac -USER_UID=${USER_UID:-$(stat -c %u ${vdir})} || exit 3 -USER_GID=${USER_GID:-$(stat -c %g ${vdir})} || exit 3 -if [[ ${USER_UID} -eq 0 ]] && [[ -z "${IGNORE_RUN_AS_ROOT:-}" ]] +# To determine default user to use search for the Vagrantfile starting with +# the current working directory. If it can't be found, use the owner/group +# from the current working directory anyway +vagrantfile="${VAGRANT_VAGRANTFILE:-Vagrantfile}" +path="$(pwd)" +while [[ "$path" != "" && ! -e "$path/$1" ]] +do + path=${path%/*} +done + +if [[ "$path" == "" ]] then - echo "WARNING! Running as root, if this breaks, you get to keep both pieces" + path="$(pwd)" fi +USER_UID=${USER_UID:-$(stat -c %u ${path})} || exit 3 +USER_GID=${USER_GID:-$(stat -c %g ${path})} || exit 3 +if [[ ${USER_UID} -eq 0 ]] +then + if [[ -z "${IGNORE_RUN_AS_ROOT:-}" ]] + then + echo "WARNING! Running as root, if this breaks, you get to keep both pieces" + fi +else + vdir_uid=$(stat -c %u ${vdir}) + if [[ "${vdir_uid}" != "${USER_UID}" ]] + then + if [[ -z "$(ls -A ${vdir})" ]] + then + # vdir has just been created and is owned by the wrong user + # modify the ownership to allow the required directories to + # be created + chown ${USER_UID}:${USER_GID} ${vdir} + else + echo -n "ERROR: Attempting to use a directory on ${vdir} that is not " + echo -n "owned by the user that owns ${path}/${vagrantfile} is not " + echo "supported!" + + exit 2 + fi + fi +fi export USER=vagrant export GROUP=users @@ -78,6 +98,19 @@ then ${USERCMD} --shell /bin/bash -u ${USER_UID} -g ${USER_GID} -o -c "" -m ${USER} >/dev/null 2>&1 || exit 3 fi +# Perform switching in of boxes, data directory containing machine index +# and temporary directory from the user mounted environment +for dir in boxes data tmp +do + # if the directory hasn't been explicitly mounted over, remove it. + if [[ -e "/vagrant/${dir}/.remove" ]] + then + rm -rf /vagrant/${dir} + [[ ! -e ${vdir}/${dir} ]] && gosu ${USER} mkdir ${vdir}/${dir} + ln -s ${vdir}/${dir} /vagrant/${dir} + fi +done + # make sure the directories can be written to by vagrant otherwise will # get a start up error find ${VAGRANT_HOME} -maxdepth 1 ! -exec chown -h ${USER}:${GROUP} {} \+