Skip to content

Commit

Permalink
more dynamic homedir handling
Browse files Browse the repository at this point in the history
  • Loading branch information
nitzmahone committed Mar 18, 2022
1 parent 5c90378 commit 55c6c3d
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 22 deletions.
3 changes: 1 addition & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,7 @@ RUN /output/install-from-bindep \

# In OpenShift, container will run as a random uid number and gid 0. Make sure things
# are writeable by the root group.
RUN sed -i 's/:root:\/root:/:root:\/home\/runner:/g' /etc/passwd \
&& for dir in \
RUN for dir in \
/home/runner \
/home/runner/.ansible \
/home/runner/.ansible/tmp \
Expand Down
66 changes: 46 additions & 20 deletions utils/entrypoint.sh
Original file line number Diff line number Diff line change
@@ -1,29 +1,55 @@
#!/usr/bin/env bash

# In OpenShift, containers are run as a random high number uid
# that doesn't exist in /etc/passwd, but Ansible module utils
# require a named user. So if we're in OpenShift, we need to make
# one before Ansible runs.
if [[ (`id -u` -ge 500 || -z "${CURRENT_UID}") ]]; then

# Only needed for RHEL 8. Try deleting this conditional (not the code)
# sometime in the future. Seems to be fixed on Fedora 32
# If we are running in rootless podman, this file cannot be overwritten
ROOTLESS_MODE=$(cat /proc/self/uid_map | head -n1 | awk '{ print $2; }')
if [[ "$ROOTLESS_MODE" -eq "0" ]]; then
cat << EOF > /etc/passwd
root:x:0:0:root:/root:/bin/bash
runner:x:`id -u`:`id -g`:,,,:/home/runner:/bin/bash
EOF
fi
# We need to fix a number of problems here that manifest under different container runtimes. If we're running
# as a legit default user that has an entry in /etc/passwd and a valid homedir that's not `/`, we're all good.
# If the username/uid we're running under is not represented in /etc/passwd and/or doesn't have a homedir that's not
# `/` (eg, the container was run with --user and some dynamic unmapped UID from the host with primary GID 0), we need to
# correct that. Some things (eg podman/cri-o today) already create an /etc/passwd entry on the fly in this case, but
# they set the homedir to `/`, which causes potential collisions with mounted/mapped volumes. For consistency, we'll
# just always set every dynamically-created user's homedir to `/home/runner`, which we've already configured in a way
# that should always work (eg, ug+rwx and all dirs owned by the root group).

# if current user is not listed in /etc/passwd, add an entry with username==uid, primary gid 0, and homedir /home/runner

# if current user is in /etc/passwd but $HOME == `/`, rewrite that user's homedir in /etc/passwd to /home/runner and
# export HOME=/home/runner for this session only- all new sessions, eg created by exec, should set HOME to match the
# current value in /etc/passwd going forward.

# if any of this business fails, we probably want to fail fast
if [ -n "$EP_DEBUG" ]; then
set -eux
echo 'hello from entrypoint'
else
set -e
fi

# FIXME junk output
if ! getent passwd $(whoami || id -u) ; then
if [ -n "$EP_DEBUG" ]; then
echo "hacking missing uid $(id -u) into /etc/passwd"
fi
echo "$(id -u):x:$(id -u):0:container user $(id -u):/home/runner:/bin/bash" >> /etc/passwd
export HOME=/home/runner
fi

cat <<EOF > /etc/group
root:x:0:runner
runner:x:`id -g`:
EOF
# FIXME junk output
MYHOME=`getent passwd $(whoami) | cut -d: -f6`

# FIXME: we also want to check the case of a generated user who podman set their homedir to WORKDIR; maybe anything with a high UID, or ?
if [ "$MYHOME" != "$HOME" ] || [ $(id -u) -ge 500 ] && [ "$MYHOME" != "/home/runner" ]; then
if [ -n "$EP_DEBUG" ]; then
echo "replacing homedir for user $(whoami)"
fi
# sed -i wants to create a tempfile next to the original, which won't work with /etc permissions in many cases,
# so just do it in memory and overwrite the existing file if we succeeded
NEWPW=$(sed -r "s/(^$(whoami):(.*:){4})(.*:)/\1\/home\/runner:/g" /etc/passwd)
echo "$NEWPW" > /etc/passwd
# ensure the envvar matches what we just set in /etc/passwd for this session; future sessions set automatically
export HOME=/home/runner
fi

# FIXME: validate group entries?

if [[ -n "${LAUNCHED_BY_RUNNER}" ]]; then
# Special actions to be compatible with old ansible-runner versions, 2.1.x specifically
RUNNER_CALLBACKS=$(python3 -c "from ansible_runner.display_callback.callback import awx_display; print(awx_display.__file__)")
Expand Down

0 comments on commit 55c6c3d

Please sign in to comment.