[docker] Refactor container to be more developer-friendly

Clean up the Docker container image to make it more developer-friendly.

- Ensure that all OpenTitan dependencies are available.
- Provide a convenient way to run commands within the container as
  current local user, ensuring that file permissions of mounted volumes
  match.
- Give the user within the container sudo rights, if it wants to use it
  e.g. to install additional packages.
- Provide a convenient way to load additional configuration into the
  environment, e.g. the path to a license server.
- Generally clean up the Dockerfile and make it consistent.
- Remove some additionally installed packages where we don't know what
  they are used for. We can always add them back if we find out the use
  case.
- Use the general mailing list as "maintainer" email address.

Signed-off-by: Philipp Wagner <phw@lowrisc.org>
diff --git a/util/container/Dockerfile b/util/container/Dockerfile
index 9d9e14e..c64eb47 100644
--- a/util/container/Dockerfile
+++ b/util/container/Dockerfile
@@ -20,12 +20,13 @@
 ARG RUST_VERSION
 
 LABEL version="1.0"
-LABEL description="OpenTitan container for hardware development."
-LABEL maintainer="miguelosorio@google.com"
+LABEL description="OpenTitan development container."
+LABEL maintainer="opentitan-dev@opentitan.org"
 
-WORKDIR /tools
+# Use bash as default shell.
+RUN ln -sf /bin/bash /bin/sh
 
-# Add OBS repository to apt sources
+# Add OBS repository to apt sources.
 RUN OBS_URL="https://download.opensuse.org/repositories"; \
     OBS_PATH="/home:/phiwag:/edatools/xUbuntu_18.04"; \
     REPO_URL="${OBS_URL}${OBS_PATH}"; \
@@ -41,68 +42,76 @@
     } && \
     echo "$EDATOOLS_REPO" > "$TMPDIR/obs.list" && \
     mv "$TMPDIR/obs.asc"  /etc/apt/trusted.gpg.d/obs.asc && \
-    mv "$TMPDIR/obs.list" /etc/apt/sources.list.d/edatools.list && \
-    apt-get update
+    mv "$TMPDIR/obs.list" /etc/apt/sources.list.d/edatools.list
 
-# Install (and cleanup) required packages (from apt-requirements.txt)
-# The list of extra packages is leftover from before this Dockerfile used
-# apt-requirements.txt
+# Install system packages
 #
-# This also adds `locales` and `locales-all` so we can set the locale to utf-8
+# Install (and cleanup) required packages (from apt-requirements.txt).
+# Also add some additional packages for the use within this container and for
+# developer convenience:
+# - gosu and sudo are used by the scripting to make the image more convenient
+#   to use.
+# - locales and locales-all are required to set the locale.
+# - minicom and screen are useful to see UART communication.
+# - dc and time are requirements of Synopsys VCS.
 COPY apt-requirements.txt /tmp/apt-requirements.txt
-RUN echo "verilator-${VERILATOR_VERSION}" >>/tmp/apt-requirements.txt && \
-    echo "openocd-${OPENOCD_VERSION}"     >>/tmp/apt-requirements.txt && \
-    sed -i -e '/^$/d' -e '/^#/d' -e 's/#.*//' /tmp/apt-requirements.txt && \
-    xargs apt-get install -y </tmp/apt-requirements.txt && \
-    apt-get update && apt-get install -y \
+RUN echo "verilator-${VERILATOR_VERSION}" >>/tmp/apt-requirements.txt \
+    && echo "openocd-${OPENOCD_VERSION}"     >>/tmp/apt-requirements.txt \
+    && sed -i -e '/^$/d' -e '/^#/d' -e 's/#.*//' /tmp/apt-requirements.txt \
+    && apt-get update \
+    && xargs apt-get install -y </tmp/apt-requirements.txt \
+    && apt-get install -y \
+        sudo \
+        gosu \
         locales \
         locales-all \
-        gnupg2 \
-        libc6-i386 \
-        libtool \
         minicom \
-        screen && \
-    apt-get clean; \
+        screen \
+        dc \
+        time \
+    && apt-get clean; \
     rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* /usr/share/doc/*
 
+# RISC-V device toolchain
+COPY util/get-toolchain.py /tmp/get-toolchain.py
+RUN /tmp/get-toolchain.py -r ${RISCV_TOOLCHAIN_TAR_VERSION} \
+    && rm -f /tmp/get-toolchain.py
+
 # Set Locale to utf-8 everywhere
 ENV LC_ALL en_US.UTF-8
 ENV LANG en_US.UTF-8
 ENV LANGUAGE en_US:en
 
-ENV PATH "/root/.local/bin:${PATH}"
+# Scripting for use within this container.
+COPY util/container/start.sh /start.sh
+COPY util/container/sudoconf /etc/sudoers.d/dev
+
+# Add the development user (UID/GID to be replaced).
+RUN groupadd dev \
+    && useradd --create-home -g dev dev \
+    && usermod -p '*' dev \
+    && passwd -u dev
+
+# All subsequent steps are performed as user.
+USER dev
+
+# Install Rust plus packages.
+COPY sw/vendor/rustup/rustup-init.sh /tmp/rustup-init.sh
+RUN /tmp/rustup-init.sh -y --default-toolchain ${RUST_VERSION}
+
+# Install Python plus packages.
+#
 # Explicitly updating pip and setuptools is required to have these tools
 # properly parse Python-version metadata, which some packages uses to
 # specify that an older version of a package must be used for a certain
 # Python version. If that information is not read, pip installs the latest
 # version, which then fails to run.
-RUN python3 -m pip install --user -U pip setuptools
-
+ENV PATH "/home/dev/.local/bin:${PATH}"
 COPY python-requirements.txt /tmp/python-requirements.txt
-RUN pip3 install --user -r /tmp/python-requirements.txt
+RUN python3 -m pip install --user -U pip setuptools \
+    && python3 -m pip install --user -r /tmp/python-requirements.txt \
+        --no-warn-script-location
 
-COPY util/get-toolchain.py /tmp/get-toolchain.py
-RUN /tmp/get-toolchain.py -r ${RISCV_TOOLCHAIN_TAR_VERSION}
-RUN rm /tmp/python-requirements.txt /tmp/get-toolchain.py
+USER root
 
-COPY sw/vendor/rustup/rustup-init.sh /tmp/rustup-init.sh
-# This file does not create a user, so we install rustup and cargo under
-# /tools.
-ENV RUSTUP_HOME /tools/.rustup 
-ENV CARGO_HOME /tools/.cargo 
-# Permissions are relaxed so that the container user can also download
-# dependencies during build.
-RUN /tmp/rustup-init.sh -y \
-    --default-toolchain ${RUST_VERSION} && \
-    chmod -R o=u ${RUSTUP_HOME} ${CARGO_HOME}
-
-# Use bash as default shell
-RUN ln -sf /bin/bash /bin/sh
-
-# Include tools in PATH.
-ENV PATH "/tools/verilator/${VERILATOR_VERSION}/bin:${CARGO_HOME}/bin:${PATH}"
-
-# Configures default container user.
-ENV USER ot
-
-ENTRYPOINT /bin/bash
+ENTRYPOINT [ "/start.sh" ]
diff --git a/util/container/README.md b/util/container/README.md
index 256984b..b4fa6cc 100644
--- a/util/container/README.md
+++ b/util/container/README.md
@@ -16,8 +16,25 @@
 
 ## Using the Container
 
-To run container in interactive mode:
+Run the container with `docker run`, mapping the current working directory to
+`/home/dev/src`. The user `dev` will have the same user ID as the current user
+on the host (you!), causing all files created by the `dev` user in the container
+to be owned by the current user on the host.
 
-```shell
-$ docker run -it -v $REPO_TOP:/repo -w /repo opentitan --user $(id -u):$(id -g)
+If you'd like to initialize your shell environment in a specific way, you can
+pass an environment variable `USER_CONFIG=/path/to/a/script.sh`. Otherwise,
+remove the `--env USER_CONFIG` argument from the invocation shown below.
+
+The script passed through this mechanism will be sourced. The path of the script
+must be within the container, e.g. in the OpenTitan repository directory.
+
 ```
+docker run -t -i \
+  -v $(pwd):/home/dev/src \
+  --env DEV_UID=$(id -u) --env DEV_GID=$(id -g) \
+  --env USER_CONFIG=/home/dev/src/docker-user-config.sh \
+  opentitan:latest \
+  bash
+```
+
+You can use `sudo` within the container to gain root permissions.
diff --git a/util/container/start.sh b/util/container/start.sh
new file mode 100755
index 0000000..07fde16
--- /dev/null
+++ b/util/container/start.sh
@@ -0,0 +1,17 @@
+#!/bin/bash
+# Copyright lowRISC contributors.
+# Licensed under the Apache License, Version 2.0, see LICENSE for details.
+# SPDX-License-Identifier: Apache-2.0
+
+# Map the "dev" user to an UID passed in as environment variable to ensure
+# files are written by the same UID/GID into mounted volumes.
+DEV_UID=${DEV_UID:-1000}
+DEV_GID=${DEV_GID:-1000}
+groupmod -o -g "$DEV_GID" dev >/dev/null 2>&1
+usermod -o -u "$DEV_UID" dev >/dev/null 2>&1
+
+# Load user configuration.
+test -f "${USER_CONFIG}" && export BASH_ENV=${USER_CONFIG}
+
+cd /home/dev
+exec gosu dev:dev /bin/bash -c "$@"
diff --git a/util/container/sudoconf b/util/container/sudoconf
new file mode 100644
index 0000000..0f89e62
--- /dev/null
+++ b/util/container/sudoconf
@@ -0,0 +1,2 @@
+# Give dev user account root permissions in container
+dev ALL=(ALL) NOPASSWD:ALL