#!  /bin/bash

# ******************************************************************************
# Copyright 2017-2019 Intel Corporation
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ******************************************************************************

# ******************************************************************************
# This script is designed to simulate running as a user with a particular UID
# within a docker container.
#
# Normally a docker container runs as root, which can cause problems with file
# ownership when a host directory tree is mounted into the docker container.
# There are other problems with building and running software as root as
# well.  Good practice when validating software builds in a docker container
# is to run as a normal user, since many (most?) end users will not be building
# and installing software as root.
#
# This script should be run using "docker run", with RUN_UID (set to the user
# you want to run as) passed into the docker container as an environment
# variable.  The script will then add the UID as user "dockuser" to
# /etc/passwd (important for some software, like bazel), add the new dockuser
# to the sudo group (whether or not sudo is installed), and su to a new shell
# as the dockuser (passing in the existing environment, which is important).
#
# If the environment variable RUN_CMD is passed into the docker container, then
# this script will use RUN_CMD as a command to run when su'ing.  If RUN_CMD is
# not defined, then /bin/bash will run, which effectively provides an
# interactive shell in the docker container, for debugging.
# ******************************************************************************

set -e  # Make sure we exit on any command that returns non-zero
set -u  # No unset variables

if [ -z "$RUN_UID" ] ; then

    # >&2 redirects echo output to stderr.
    # See: https://stackoverflow.com/questions/2990414/echo-that-outputs-to-stderr
    ( >&2 echo 'ERROR: Environment variable RUN_UID was not set when run-as-user.sh was run' )
    ( >&2 echo '       Running as default user (root, in docker)' )
    ( >&2 echo ' ' )

    exit 1

else

    # The username used in the docker container to map the caller UID to
    #
    # Note 'dockuser' is used in other scripts, notably Makefile.  If you
    # choose to change it here, then you need to change it in all other
    # scripts, or else the builds will break.
    #
    DOCK_USER='dockuser'

    # We will be su'ing using a non-login shell or command, and preserving
    # the environment.  This is done so that env. variables passed in with
    # "docker run --env ..." are honored.
    # Therefore, we need to reset at least HOME=/root ...
    #
    # Note also that /home/dockuser is used in other scripts, notably
    # Makefile.  If you choose to change it here, then you need to change it
    # in all other scripts, or else the builds will break.
    #
    export HOME="/home/${DOCK_USER}"

    # Make sure the home directory is owned by the new user
    if [ -d "${HOME}" ] ; then
      chown "${RUN_UID}" "${HOME}"
    fi

    # Add a user with UID of person running docker (in ${RUN_UID})
    # If $HOME does not yet exist, then it will be created
    adduser -c 'Docker-User' -u "${RUN_UID}" "${DOCK_USER}"
    passwd -d "${DOCK_USER}"
    # Add dockuser to the sudo group.  Sudo *is* used for installing packages,
    # so make sure dockuser can run sudo without requesting a password.
    usermod -aG wheel "${DOCK_USER}"
    echo '%sudo ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers

    if [ -z "${RUN_CMD+x}" ] ; then  # Launch a shell as dockuser
      echo 'Running interactive shell (/bin/bash) as dockuser'
      su -m "${DOCK_USER}" -c "/bin/bash"
    else                         # Run command as dockuser
      echo "Running command [${RUN_CMD}] as dockuser"
      su -m "${DOCK_USER}" -c "${RUN_CMD}"
    fi

fi