vagrant-libvirt/entrypoint.sh
Darragh Bailey c28aca9d21
Improve handling when run using root user (#1572)
Allow for the image to be run with the root user if desired, however
change to requiring setting of a variable to allow it to continue as it
may change ownership of files unexpectedly.

Additionally ensure that the workdir passed to docker matches the target
mount path used, in case the realpath to ${PWD} resolves to be different
to it's value resulting in the starting workdir being somewhere
different to the current path on the host.

Fixes: #1442
2022-09-03 11:37:25 +00:00

167 lines
4.4 KiB
Bash
Executable File

#!/bin/bash
set -u -o pipefail
# duplicate stdout as fd 3
exec 3>&1
# redirect stdout to stderr by default
exec 1>&2
vdir="/.vagrant.d"
if [[ ! -d ${vdir} ]]
then
echo "Require the user ~/.vagrant.d to be bind mounted at ${vdir}"
echo
echo "Typically use '-v ~/.vagrant.d:${vdir}' with the docker run command."
exit 2
fi
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 persist boxes and machine index.
#
;;
*)
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
# 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/$vagrantfile" ]]
do
path=${path%/*}
done
if [[ "$path" == "" ]]
then
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 [[ "${IGNORE_RUN_AS_ROOT:-0}" == "0" ]]
then
echo "ERROR! Running as root, this usually means there has been a mistake" \
"in how the image has been launched."
echo "If this is actually intended, please pass '-e IGNORE_RUN_AS_ROOT=1'" \
"via the docker run command to allow execution as root."
echo
echo "Used '${path}' to determine uid/gid, typically starting looking for the" \
"file '$(pwd)/Vagrantfile' or if there is a Vagrantfile in the parent directory" \
"otherwise fall back to owner/group of'$(pwd)'"
exit 2
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
export HOME=/home/${USER}
echo "Starting with UID: ${USER_UID}, GID: ${USER_GID}"
if [[ "${USER_GID}" != "0" ]]
then
if getent group ${GROUP} > /dev/null
then
GROUPCMD=groupmod
else
GROUPCMD=groupadd
fi
${GROUPCMD} -g ${USER_GID} ${GROUP} >/dev/null || exit 3
fi
if [[ "${USER_UID}" != "0" ]]
then
if getent passwd ${USER} > /dev/null
then
USERCMD=usermod
else
USERCMD=useradd
fi
${USERCMD} --shell /bin/bash -u ${USER_UID} -g ${USER_GID} -o -c "" -m ${USER} >/dev/null 2>&1 || exit 3
fi
if [[ "${USER_UID}" != "0" ]]
then
# 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} {} \+
fi
LIBVIRT_SOCK=/var/run/libvirt/libvirt-sock
if [[ ! -S ${LIBVIRT_SOCK} ]]
then
if [[ -z "${IGNORE_MISSING_LIBVIRT_SOCK:-}" ]]
then
echo "Unless you are using this to connect to a remote libvirtd it is"
echo "necessary to mount the libvirt socket in as ${LIBVIRT_SOCK}"
echo
echo "Set IGNORE_MISSING_LIBVIRT_SOCK to silence this warning"
fi
else
LIBVIRT_GID=$(stat -c %g ${LIBVIRT_SOCK})
# only do this if the host uses a non-root group for libvirt
if [[ "${USER_UID}" != "0" ]] && [[ ${LIBVIRT_GID} -ne 0 ]]
then
if getent group libvirt >/dev/null
then
GROUPCMD=groupmod
else
GROUPCMD=groupadd
fi
${GROUPCMD} -g ${LIBVIRT_GID} libvirt >/dev/null || exit 3
usermod -a -G libvirt ${USER} || exit 3
fi
fi
if [[ $# -eq 0 ]]
then
# if no command provided
if [[ "${USER_UID}" != "0" ]]
then
exec gosu ${USER} vagrant help >&3
else
exec vagrant help >&3
fi
fi
if [[ "${USER_UID}" != "0" ]]
then
exec gosu ${USER} "$@" >&3
else
exec "$@" >&3
fi