Skip to content

Commit

Permalink
Move tools & configs from /home/user/ to /home/tooling/ (redhat-devel…
Browse files Browse the repository at this point in the history
…oper#525)

* Use bash-completions package

Signed-off-by: Andrew Obuchowicz <[email protected]>

* Don't modify ~/.bashrc, use /etc/profile.d/ instead

Signed-off-by: Andrew Obuchowicz <[email protected]>

* Build stow from sources

Signed-off-by: Andrew Obuchowicz <[email protected]>

* Move tools & configs from /home/user/ to /home/tooling/

Signed-off-by: Andrew Obuchowicz <[email protected]>

* Fix for multiple $KUBEDOCK_PARAMS

Signed-off-by: Andrew Obuchowicz <[email protected]>

* Install vim

Signed-off-by: Andrew Obuchowicz <[email protected]>

* Don't stow .viminfo

Signed-off-by: Andrew Obuchowicz <[email protected]>

* Ensure ~/.bashrc and ~/.bash_profile exist when persistUserHome enabled

Signed-off-by: Andrew Obuchowicz <[email protected]>

* Remove obsolete bash prompt creation from UDI entrypoint

Signed-off-by: Andrew Obuchowicz <[email protected]>

* Don't fail entrypoint if kubeconfig could not be found

Signed-off-by: Andrew Obuchowicz <[email protected]>

* chore: define user directory for binaries

Signed-off-by: Andrew Obuchowicz <[email protected]>

* Ensure mountpoint test doesn't cause entrypoint to fail

Signed-off-by: Andrew Obuchowicz <[email protected]>

* Update devspaces-udi/etc/entrypoint.sh

Co-authored-by: Valerii Svydenko <[email protected]>

* Remove redundant creation of Go bin directory

Signed-off-by: Andrew Obuchowicz <[email protected]>

* Remove redundant /home/tooling/ creation

Signed-off-by: Andrew Obuchowicz <[email protected]>

* Pre-create common tooling config directories

Signed-off-by: Andrew Obuchowicz <[email protected]>

* Update devspaces-udi/etc/entrypoint.sh

Co-authored-by: Angel Misevski <[email protected]>

* Disable code ready builder repo after building stow

We disable the code ready builder repo on each architecture to prevent
accidentally pulling in the wrong packages. For example, the maven-resolver
package differs between the rhel 8 app stream repo & the code ready builder repo
which leads to maven being unable to download artifacts.

Signed-off-by: Andrew Obuchowicz <[email protected]>

* Fix for incorrect python module

Signed-off-by: Andrew Obuchowicz <[email protected]>

* Update devspaces-udi/Dockerfile

Co-authored-by: Angel Misevski <[email protected]>

* Update devspaces-udi/Dockerfile

Co-authored-by: Angel Misevski <[email protected]>

* Ensure PATH contains /home/user/ and /home/tooling/ entries

Signed-off-by: Andrew Obuchowicz <[email protected]>

* fixup! Disable code ready builder repo after building stow

* Create ~/.java/current/ symbolic links in /home/tooling/ instead of /home/user/

In order for stow in the UDI's entrypoint to complete successfully,
any files present in /home/user/ (that are not in the .stow-local-ignore)
must not also exist in /home/tooling/, otherwise a conflict would occur.

Since the symbolic link creation from JAVA_HOME_8/11/17 occurs before stow
is executed, the symbolic link must be created from JAVA_HOME_8/11/17 -> /home/tooling/
to prevent a stow conflict.

Stow will then create a symbolic link from
/home/tooling/.java/current/ -> /home/user/.java/current/ so that JAVA_HOME remains valid.

Signed-off-by: Andrew Obuchowicz <[email protected]>

* Update devspaces-udi/Dockerfile

* Update devspaces-udi/Dockerfile

* fixup! Disable code ready builder repo after building stow

---------

Signed-off-by: Andrew Obuchowicz <[email protected]>
Co-authored-by: Nick Boldt <[email protected]>
Co-authored-by: Valerii Svydenko <[email protected]>
Co-authored-by: Angel Misevski <[email protected]>
  • Loading branch information
4 people committed Nov 22, 2023
1 parent ffb4e6c commit 1aa65ca
Show file tree
Hide file tree
Showing 5 changed files with 132 additions and 46 deletions.
72 changes: 58 additions & 14 deletions devspaces-udi/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ RUN \
########################################################################
dnf -y -q install golang make gzip which openshift-clients && \
# BEGIN Gopls
mkdir /home/user/go/bin -p && \
mkdir /home/tooling/go/bin -p && \
cd $REMOTE_SOURCES_DIR/gopls/app/gopls && \
# gopls must refer to tools as local dependency, which is located one dir above in the project
echo 'replace golang.org/x/tools => ../' >> go.mod && \
Expand All @@ -34,7 +34,6 @@ RUN \
# END Gopls

# BEGIN Kubedock
mkdir /home/user/go/bin -p && \
cd $REMOTE_SOURCES_DIR/kubedock/app && \
# build kubedock application with dependencies resolved by Cachito
source $REMOTE_SOURCES_DIR/kubedock/cachito.env && \
Expand All @@ -44,7 +43,7 @@ RUN \
-X github.com/joyrex2001/kubedock/internal/config.Image=joyrex2001/kubedock:0.11.0" && \
CGO_ENABLED=0 go build -ldflags "${LDFLAGS}" -o kubedock && \
chmod +x ./kubedock && \
./kubedock version
./kubedock version && \
# END Kubedock

# CRW-3193 disable until we have a camel-k sample again
Expand All @@ -55,12 +54,24 @@ RUN \
# ./kamel version && \
# END Kamel

# BEGIN stow
dnf -y -q install perl texinfo texinfo-tex git && \
cd $REMOTE_SOURCES_DIR/stow/app && \
mkdir -p $REMOTE_SOURCES_DIR/stow/app/build && \
autoreconf -iv && \
./configure --prefix=$REMOTE_SOURCES_DIR/stow/app/build && \
make install && \
cd $REMOTE_SOURCES_DIR/stow/app/build/bin/ && \
./stow --version
# END stow

# https://registry.access.redhat.com/ubi8-minimal
FROM ubi8-minimal:8.9-1029
USER root

ENV \
HOME=/home/user \
# We install everything to /home/tooling/ as /home/user/ may get overwritten, see github.com/eclipse/che/issues/22412
HOME=/home/tooling \
NODEJS_VERSION="18" \
PYTHON_VERSION="3.11" \
PHP_VERSION="7.4" \
Expand All @@ -73,13 +84,16 @@ ENV \
JAVA_HOME_8=/usr/lib/jvm/java-1.8.0-openjdk \
JAVA_HOME="/home/user/.java/current" \
GOBIN="/home/user/go/bin/" \
PATH="/home/user/.local/bin:/home/user/.java/current/bin:/home/user/node_modules/.bin/:/home/user/.npm-global/bin/:/opt/app-root/src/.npm-global/bin/:/usr/share/maven/bin:/usr/bin:/home/user/go/bin:${PATH:-/bin:/usr/bin}" \
# We have $PATH entries in /home/tooling/ (in addition to /home/user/) to ensure binaries can be found in case /home/user/ has been ovewritten and stow has not yet run in the entrypoint
PATH="/home/user/.local/bin:/home/user/.java/current/bin:/home/user/node_modules/.bin/:/home/user/.npm-global/bin/:/opt/app-root/src/.npm-global/bin/:/usr/share/maven/bin:/usr/bin:/home/user/go/bin::/home/tooling/.local/bin:/home/tooling/.java/current/bin:/home/tooling/node_modules/.bin/:/home/tooling/.npm-global/bin/:/home/tooling/go/bin:${PATH:-/bin:/usr/bin}" \
MANPATH="/usr/share/man:${MANPATH}" \
JAVACONFDIRS="/etc/java${JAVACONFDIRS:+:}${JAVACONFDIRS:-}" \
XDG_CONFIG_DIRS="/etc/xdg:${XDG_CONFIG_DIRS:-/etc/xdg}" \
XDG_DATA_DIRS="/usr/share:${XDG_DATA_DIRS:-/usr/local/share:/usr/share}" \
M2_HOME="/usr/share/maven" \
PKG_CONFIG_PATH="/usr/lib64/pkgconfig${PKG_CONFIG_PATH:+:${PKG_CONFIG_PATH}}" \
KUBECONFIG=/home/user/.kube/config \
PROFILE_EXT=/etc/profile.d/udi_environment.sh \
# Rootless podman install #1:
# Set up environment variables to note that this is
# not starting with usernamespace and default to
Expand All @@ -103,11 +117,13 @@ LABEL summary="$SUMMARY" \
io.openshift.expose-services="" \
usage=""

RUN mkdir -p /home/tooling/
ADD etc/storage.conf $HOME/.config/containers/storage.conf
ADD etc/entrypoint.sh /entrypoint.sh
COPY $REMOTE_SOURCES $REMOTE_SOURCES_DIR
RUN echo 'alias docker=podman' >> /home/user/.bashrc
COPY --chown=0:0 etc/podman-wrapper.sh /usr/bin/
RUN mkdir -p /home/tooling/
COPY --chown=0:0 etc/.stow-local-ignore /home/tooling/

# NOTE: uncomment for local build. Must also set full registry path in FROM to registry.redhat.io or registry.access.redhat.com
# enable rhel 8 content sets (from Brew) to resolve buildah
Expand All @@ -120,7 +136,10 @@ COPY --chown=0:0 etc/podman-wrapper.sh /usr/bin/
RUN \
# install all the rpms and modules
microdnf install -y dnf && \
dnf -y -q module reset container-tools maven nodejs python3.11 php; \
# Disable codeready-builder repos to prevent accidentally installing incorrect packages
dnf -y -q install 'dnf-command(config-manager)' && \
dnf config-manager --set-disabled codeready-* && \
dnf -y -q module reset container-tools maven nodejs php; \
dnf -y -q module install container-tools:rhel8 maven:3.6 nodejs:$NODEJS_VERSION php:$PHP_VERSION && \
dnf -y -q install --setopt=tsflags=nodocs \
golang \
Expand All @@ -135,7 +154,7 @@ RUN \
libssh-devel libffi-devel redhat-rpm-config cargo openssl-devel pkg-config jq \
podman buildah skopeo fuse-overlayfs \
e2fsprogs libatomic_ops git openssl-devel ca-certificates \
bash tar gzip unzip bzip2 which shadow-utils findutils wget curl sudo git git-lfs procps-ng tree \
bash bash-completion tar gzip unzip bzip2 which shadow-utils findutils wget curl sudo git git-lfs procps-ng tree vim \
# For OpenShift Client 4 (oc): rhocp-4.12-for-rhel-8-x86_64-rpms
# must hard code a version because otherwise CVP/Brew fails with: Failed component comparison for components: openshift-clients
# https://rhsm-pulp.corp.redhat.com/content/dist/layered/rhel8/x86_64/ocp-tools/4.12/os/Packages/o/odo-3.9.0-1.el8.x86_64.rpm
Expand All @@ -157,8 +176,14 @@ RUN \
mkdir -p /opt && \
# add user and configure it
useradd -u 1000 -G wheel,root -d /home/user --shell /bin/bash -m user && \
# Bash-related files are backed up to /home/tooling/ in case they are deleted when persistUserHome is enabled.
cp /home/user/.bashrc /home/tooling/.bashrc && \
cp /home/user/.bash_profile /home/tooling/.bash_profile && \
# $PROFILE_EXT contains all additions made to the bash environment
touch ${PROFILE_EXT} && \
# Setup $PS1 for a consistent and reasonable prompt
echo "export PS1='\W \`git branch --show-current 2>/dev/null | sed -r -e \"s@^(.+)@\(\1\) @\"\`$ '" >> "${HOME}"/.bashrc && \
touch /etc/profile.d/udi_prompt.sh && \
echo "export PS1='\W \`git branch --show-current 2>/dev/null | sed -r -e \"s@^(.+)@\(\1\) @\"\`$ '" >> /etc/profile.d/udi_prompt.sh && \
# Change permissions to let any arbitrary user
mkdir -p /projects && \
for f in "${HOME}" "/etc/passwd" "/etc/group" "/projects"; do \
Expand All @@ -171,7 +196,9 @@ RUN \
> ${HOME}/passwd.template && \
cat /etc/group | \
sed s#root:x:0:#root:x:0:0,\${USER_ID}:#g \
> ${HOME}/group.template
> ${HOME}/group.template && \
# Define user directory for binaries
mkdir -p /home/tooling/.local/bin

RUN \
## Rootless podman install #2: install podman buildah skopeo e2fsprogs (above)
Expand All @@ -192,12 +219,21 @@ RUN \
## Rootless podman install #6: rename podman to allow the execution of 'podman run' using
## kubedock but 'podman build' using podman.orig
mv /usr/bin/podman /usr/bin/podman.orig && \
# set up go/bin folder
mkdir /home/user/go/bin -p
# Docker alias
echo 'alias docker=podman' >> ${PROFILE_EXT}

RUN \
# configure runtimes
########################################################################
# Common tooling configuration directories
########################################################################
mkdir -p /home/tooling/.m2 && \
mkdir -p /home/tooling/.config/pip && \
mkdir -p /home/tooling/.cargo && \
mkdir -p /home/tooling/certs && \
mkdir -p /home/tooling/.composer && \
mkdir -p /home/tooling/.nuget && \
########################################################################
# Java
########################################################################
mkdir -p ${HOME}/.java/current && \
Expand Down Expand Up @@ -248,7 +284,7 @@ RUN \
echo -n "/usr/local/bin/pytest: "; /usr/local/bin/pytest --version && \
echo -n "/usr/local/bin/yq: "; /usr/local/bin/yq --version && \
# set up ~/.venv
mkdir -p /home/user; cd /home/user; /usr/bin/python${PYTHON_VERSION} -m venv .venv && \
cd /home/tooling; /usr/bin/python${PYTHON_VERSION} -m venv .venv && \
echo "<== Create python symlinks (or display existing ones)"
# TODO: to enable flake8 as default linter, add this to project's .vscode/settings.json file
# {
Expand Down Expand Up @@ -329,6 +365,13 @@ xdebug.log=\${HOME}/xdebug.log" >> /etc/php.ini && \
# see container.yaml
COPY --from=go-builder $REMOTE_SOURCES_DIR/gopls/app/gopls/gopls $HOME/go/bin/gopls
COPY --from=go-builder $REMOTE_SOURCES_DIR/kubedock/app/kubedock $HOME/go/bin/kubedock
COPY --from=go-builder $REMOTE_SOURCES_DIR/stow/app/build/bin/ /usr/bin/
COPY --from=go-builder $REMOTE_SOURCES_DIR/stow/app/build/share/ /usr/share/

# Create symbolic links from /home/tooling/ -> /home/user/
RUN stow . -t /home/user/ -d /home/tooling/ --no-folding && \
# .viminfo cannot be a symbolic link for security reasons, so copy it to /home/user/
cp /home/tooling/.viminfo /home/user/.viminfo


########################################################################
Expand Down Expand Up @@ -392,8 +435,9 @@ RUN \
echo "========"

# A last pass to make sure that an arbitrary user can write in $HOME
RUN mkdir -p /home/user && chgrp -R 0 /home && chmod -R g=u /home
RUN chgrp -R 0 /home && chmod -R g=u /home

ENV HOME=/home/user
ENTRYPOINT [ "/entrypoint.sh" ]
WORKDIR /projects
CMD tail -f /dev/null
7 changes: 7 additions & 0 deletions devspaces-udi/container.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -64,3 +64,10 @@ remote_sources:
ref: 9d21955b52e4905d916d24e724dcad195aef3515
pkg_managers:
- gomod

- name: stow
remote_source:
repo: https://github.com/aspiers/stow
ref: 4ef5eca4a9d107b24e712bb4c2c91f47e7e0fb85
pkg_managers: []
flags: ["include-git-dir"]
3 changes: 3 additions & 0 deletions devspaces-udi/content_sets.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,16 @@ x86_64:
- rhel-8-for-x86_64-appstream-rpms
- ocp-tools-4.12-for-rhel-8-x86_64-rpms
- rhocp-4.12-for-rhel-8-x86_64-rpms
- codeready-builder-for-rhel-8-x86_64-rpms
s390x:
- rhel-8-for-s390x-baseos-rpms
- rhel-8-for-s390x-appstream-rpms
- ocp-tools-4.12-for-rhel-8-s390x-rpms
- rhocp-4.12-for-rhel-8-s390x-rpms
- codeready-builder-for-rhel-8-s390x-rpms
ppc64le:
- rhel-8-for-ppc64le-baseos-rpms
- rhel-8-for-ppc64le-appstream-rpms
- ocp-tools-4.12-for-rhel-8-ppc64le-rpms
- rhocp-4.12-for-rhel-8-ppc64le-rpms
- codeready-builder-for-rhel-8-ppc64le-rpms
7 changes: 7 additions & 0 deletions devspaces-udi/etc/.stow-local-ignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# .viminfo cannot be a symlink for security reasons
\.viminfo

# We store bash related files in /home/tooling/ so they aren't overriden if persistUserHome is enabled
# but we don't want them to be symbolic links (or to cause stow conflicts). They will be copied to /home/user/ manually.
\.bashrc
\.bash_profile
89 changes: 57 additions & 32 deletions devspaces-udi/etc/entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -42,31 +42,24 @@ if [ -f "${HOME}"/.venv/bin/activate ]; then
source "${HOME}"/.venv/bin/activate
fi

#############################################################################
# Setup $PS1 for a consistent and reasonable prompt
#############################################################################
if [ -w "${HOME}" ] && [ ! -f "${HOME}"/.bashrc ]; then
echo "PS1='[\u@\h \W]\$ '" >> "${HOME}"/.bashrc
fi

#############################################################################
# use java 8 if USE_JAVA8 is set to 'true',
# use java 17 if USE_JAVA17 is set to 'true',
# by default it is java 11
#############################################################################
rm -rf "${HOME}"/.java/current
mkdir -p "${HOME}"/.java/current
rm -rf /home/tooling/.java/current
mkdir -p /home/tooling/.java/current
if [ "${USE_JAVA8}" == "true" ] && [ ! -z "${JAVA_HOME_8}" ]; then
ln -s "${JAVA_HOME_8}"/* "${HOME}"/.java/current
ln -s "${JAVA_HOME_8}"/* /home/tooling/.java/current
echo "Java environment set to ${JAVA_HOME_8}"
elif [ "${USE_JAVA17}" == "true" ] && [ ! -z "${JAVA_HOME_17}" ]; then
ln -s "${JAVA_HOME_17}"/* "${HOME}"/.java/current
ln -s "${JAVA_HOME_17}"/* /home/tooling/.java/current
echo "Java environment set to ${JAVA_HOME_17}"
else
# End of Support for OpenJDK 11 in October 2024
# https://access.redhat.com/articles/1299013
echo "TODO: it needs to set JDK 17 as default before OpenJDK 11 hits EOL in October 2024"
ln -s "${JAVA_HOME_11}"/* "${HOME}"/.java/current
ln -s "${JAVA_HOME_11}"/* /home/tooling/.java/current
echo "Java environment set to ${JAVA_HOME_11}"
fi

Expand All @@ -83,41 +76,73 @@ if [[ "${KUBEDOCK_ENABLED:-false}" == "true" ]]; then
echo "Kubedock is enabled (env variable KUBEDOCK_ENABLED is set to true)."

SECONDS=0
until [ -f /home/user/.kube/config ]; do
if (( SECONDS > 10 )); then
echo "Giving up..."
exit 1
KUBEDOCK_TIMEOUT=${KUBEDOCK_TIMEOUT:-10}
until [ -f $KUBECONFIG ]; do
if (( SECONDS > KUBEDOCK_TIMEOUT )); then
break
fi
echo "Kubeconfig doesn't exist yet. Waiting..."
sleep 1
done
echo "Kubeconfig found."

KUBEDOCK_PARAMS=${KUBEDOCK_PARAMS:-"--reverse-proxy"}
if [ -f $KUBECONFIG ]; then
echo "Kubeconfig found."

echo "Starting kubedock with params \"${KUBEDOCK_PARAMS}\"..."

kubedock server "${KUBEDOCK_PARAMS}" > /tmp/kubedock.log 2>&1 &

echo "Done."
KUBEDOCK_PARAMS=${KUBEDOCK_PARAMS:-"--reverse-proxy --kubeconfig $KUBECONFIG"}

echo "Replacing podman with podman-wrapper.sh..."
echo "Starting kubedock with params \"${KUBEDOCK_PARAMS}\"..."

mkdir -p /home/user/.local/bin/
ln -f -s /usr/bin/podman-wrapper.sh /home/user/.local/bin/podman
kubedock server ${KUBEDOCK_PARAMS} > /tmp/kubedock.log 2>&1 &

export TESTCONTAINERS_RYUK_DISABLED="true"
export TESTCONTAINERS_CHECKS_DISABLE="true"
echo "Done."

echo "Done."
echo
echo "Replacing podman with podman-wrapper.sh..."

ln -f -s /usr/bin/podman-wrapper.sh /home/tooling/.local/bin/podman

export TESTCONTAINERS_RYUK_DISABLED="true"
export TESTCONTAINERS_CHECKS_DISABLE="true"

echo "Done."
echo
else
echo "Could not find Kubeconfig at $KUBECONFIG"
echo "Giving up..."
fi
else
echo
echo "Kubedock is disabled. It can be enabled with the env variable \"KUBEDOCK_ENABLED=true\""
echo "set in the workspace Devfile or in a Kubernetes ConfigMap in the developer namespace."
echo
mkdir -p /home/user/.local/bin/
ln -f -s /usr/bin/podman.orig /home/user/.local/bin/podman
ln -f -s /usr/bin/podman.orig /home/tooling/.local/bin/podman
fi

#############################################################################
# Stow: If persistUserHome is enabled, then the contents of /home/user/
# will be mounted by a PVC and overwritten. In this case, we use stow to
# create symbolic links from /home/tooling/ -> /home/user/.
# Required for https://github.com/eclipse/che/issues/22412
#############################################################################

# /home/user/ will be mounted to by a PVC if persistUserHome is enabled
# We need to override the `set -e` from this script by ensuring the mountpoint command returns 0,
# but we also need to capture the exit code of mountpoint
HOME_USER_MOUNTED=0
mountpoint -q /home/user/ || HOME_USER_MOUNTED=$?

# This file will be created after stowing, to guard from executing stow everytime the container is started
STOW_COMPLETE=/home/user/.stow_completed

if [ $HOME_USER_MOUNTED -eq 0 ] && [ ! -f $STOW_COMPLETE ]; then
# Create symbolic links from /home/tooling/ -> /home/user/
stow . -t /home/user/ -d /home/tooling/ --no-folding -v 2 > /tmp/stow.log 2>&1
# Vim does not permit .viminfo to be a symbolic link for security reasons, so manually copy it
cp --no-clobber /home/tooling/.viminfo /home/user/.viminfo
# We have to restore bash-related files back onto /home/user/ (since they will have been overwritten by the PVC)
# but we don't want them to be symbolic links (so that they persist on the PVC)
cp --no-clobber /home/tooling/.bashrc /home/user/.bashrc
cp --no-clobber /home/tooling/.bash_profile /home/user/.bash_profile
touch $STOW_COMPLETE
fi

exec "$@"

0 comments on commit 1aa65ca

Please sign in to comment.