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
This commit is contained in:
Darragh Bailey
2021-06-30 17:56:09 +01:00
committed by GitHub
parent 18ebb9d9ed
commit 1f51841678
2 changed files with 61 additions and 29 deletions

View File

@@ -131,8 +131,8 @@ docker run -it --rm \
-e LIBVIRT_DEFAULT_URI \ -e LIBVIRT_DEFAULT_URI \
-v /var/run/libvirt/:/var/run/libvirt/ \ -v /var/run/libvirt/:/var/run/libvirt/ \
-v ~/.vagrant.d:/.vagrant.d \ -v ~/.vagrant.d:/.vagrant.d \
-v $(pwd):$(pwd) \ -v $(realpath "${PWD}"):${PWD} \
-w $(pwd) \ -w $(realpath "${PWD}") \
--network host \ --network host \
vagrantlibvirt/vagrant-libvirt:latest \ vagrantlibvirt/vagrant-libvirt:latest \
vagrant status vagrant status
@@ -141,13 +141,12 @@ docker run -it --rm \
It's possible to define an alias in `~/.bashrc`, for example: It's possible to define an alias in `~/.bashrc`, for example:
```bash ```bash
alias vagrant=' alias vagrant='
mkdir -p ~/.vagrant.d/{boxes,data,tmp}; \
docker run -it --rm \ docker run -it --rm \
-e LIBVIRT_DEFAULT_URI \ -e LIBVIRT_DEFAULT_URI \
-v /var/run/libvirt/:/var/run/libvirt/ \ -v /var/run/libvirt/:/var/run/libvirt/ \
-v ~/.vagrant.d:/.vagrant.d \ -v ~/.vagrant.d:/.vagrant.d \
-v $(pwd):$(pwd) \ -v $(realpath "${PWD}"):${PWD} \
-w $(pwd) \ -w $(realpath "${PWD}") \
--network host \ --network host \
vagrantlibvirt/vagrant-libvirt:latest \ vagrantlibvirt/vagrant-libvirt:latest \
vagrant' vagrant'

View File

@@ -13,43 +13,63 @@ then
exit 2 exit 2
fi 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}) vdir_mnt=$(stat -c %m ${vdir})
case "${vdir_mnt%%/}" in case "${vdir_mnt%%/}" in
/*) /*)
# user mounted vagrant home is not mounted on /, so # user mounted vagrant home is not mounted on /, so
# presumably it is a mount bind or mounted volume and should # 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 -n "${vdir} is not set to a bind mounted volume, may not be able "
echo "to automatically determine suitable uid/gid to execute under." echo -n "to persist the machine index which may result in some unexpected "
if [[ -z "${USER_UID:-}" ]] || [[ -z "${USER_GID:-}" ]] echo "behaviour."
then
echo "USER_UID and USER_GID must be explicitly provided when"
echo "auto-detection is unable to be used"
exit 2
fi
;; ;;
esac esac
USER_UID=${USER_UID:-$(stat -c %u ${vdir})} || exit 3 # To determine default user to use search for the Vagrantfile starting with
USER_GID=${USER_GID:-$(stat -c %g ${vdir})} || exit 3 # the current working directory. If it can't be found, use the owner/group
if [[ ${USER_UID} -eq 0 ]] && [[ -z "${IGNORE_RUN_AS_ROOT:-}" ]] # from the current working directory anyway
vagrantfile="${VAGRANT_VAGRANTFILE:-Vagrantfile}"
path="$(pwd)"
while [[ "$path" != "" && ! -e "$path/$1" ]]
do
path=${path%/*}
done
if [[ "$path" == "" ]]
then then
echo "WARNING! Running as root, if this breaks, you get to keep both pieces" path="$(pwd)"
fi 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 USER=vagrant
export GROUP=users 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 ${USERCMD} --shell /bin/bash -u ${USER_UID} -g ${USER_GID} -o -c "" -m ${USER} >/dev/null 2>&1 || exit 3
fi 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 # make sure the directories can be written to by vagrant otherwise will
# get a start up error # get a start up error
find ${VAGRANT_HOME} -maxdepth 1 ! -exec chown -h ${USER}:${GROUP} {} \+ find ${VAGRANT_HOME} -maxdepth 1 ! -exec chown -h ${USER}:${GROUP} {} \+