#!/bin/bash # A script for launching 'RHEL 7 in a Box' on a DLS workstation # NOTE that changes to this file should also be propgated to .devcontainer.json image=ghcr.io/dls-controls/dev-c7 version=latest hostname=$(hostname) changed=false pull=false rhel=8 delete=false gui=false mount_only=false install_devcontainer_json=false network="--net=host" userns="--userns=keep-id" logging="" # -l loads profile and bashrc command="/bin/bash -l" commandargs= while getopts "mglrdphs:i:v:cnI" arg; do case $arg in l) logging="set -x" # enable logging ;; r) changed=true userns="" ;; g) changed=true gui=true ;; p) pull=true changed=true ;; s) hostname=$OPTARG changed=true ;; i) image=$OPTARG changed=true ;; n) network="--network=podman" changed=true ;; v) version=$OPTARG changed=true ;; c) commandargs=YES command="/bin/bash -lc " break ;; d) delete=true ;; I) install_devcontainer_json=true ;; *) echo " usage: c7 [options] Launches a developer container that simulates a DLS RHEL7 workstation. Options: -h show this help -l Enable logging -p pull an updated version of the image first -i image specify the container image (default: "${image}") -v version specify the image version (default: "${version}") -s host set a hostname for your container (default: ${hostname}) -d delete previous container and start afresh -n run in podman virtual network instead of the host network -c command run a command in the container (must be last option) -I Install .devcontainer/devcontainer.json in the current directory for vscode -g enable X11 GUI for containers launched via ssh (only required with -r) -r run as root " exit 0 ;; esac done shift $((OPTIND-1)) if [[ ${install_devcontainer_json} == true ]] ; then mkdir -p .devcontainer cd .devcontainer wget -nv https://raw.githubusercontent.com/dls-controls/dev-c7/main/.devcontainer/devcontainer.json echo echo "Installed devcontainer.json. Try 'Reopen in Container' or 'Reload Window'." exit 0 fi if ! grep overlay ~/.config/containers/storage.conf &> /dev/null; then echo "ERROR: dev-c7 requires overlay filesystem." echo "Please see https://dls-controls.github.io/dev-c7/main/how-to/podman.html" exit 1 fi if [[ -e /etc/centos-release ]] ; then echo "ERROR: already in the a devcontainer" exit 1 fi if ${delete} ; then podman rm -ft0 dev-c7 changed=false fi if [[ $(podman version -f {{.Version}}) == 1.* ]] ; then echo "WARNING: this is a RHEL7 machine - EXPERIMENTAL SUPPORT ONLY" echo " WARNING: You will run as root in the container and will not be able to use group permissions " rhel=7 fi environ=" -e CONTAINER_NAME=dev-c7 -e DEV_PROMPT=C7 -e DISPLAY -e HOME -e USER -e SSH_AUTH_SOCK -e TERM=xterm-256color " volumes=" -v /scratch:/scratch -v /dls:/dls:shared -v /dls_sw:/dls_sw:shared -v /home:/home:shared -v /run/user/$(id -u):/run/user/$(id -u) " devices="-v /dev/ttyS0:/dev/ttyS0" opts="${network} --hostname ${hostname} --security-opt=label=disable" # Get around the issue of /tmp being mounted noexec by creating our own tmpfs opts="${opts} --mount type=tmpfs,destination=/tmp" # the identity settings enable secondary groups in the container if [[ ${rhel} == 8 ]] ; then identity="${userns} --annotation run.oci.keep_original_groups=1" fi # this runtime is also required for secondary groups if which crun &> /dev/null ; then runtime="--runtime /usr/bin/crun" identity="${identity} --storage-opt ignore_chown_errors=true" fi container_name=dev-c7 # setup X11 to work even if you launched dev-c7 from an ssh shell # NOTE: this does not appear to be needed - I believe because the # container uses keep-id the X11 auth passes through SSH OK. if [[ ${gui} == "true" ]] ; then XSOCK=/tmp/.X11-unix # X11 socket (but we mount the whole of tmp) XAUTH=/tmp/.container.xauth.$USER touch $XAUTH xauth nlist $DISPLAY | sed -e 's/^..../ffff/' | xauth -f $XAUTH nmerge - chmod 777 $XAUTH x11=" -v $XAUTH:$XAUTH -e XAUTHORITY=$XAUTH " opts="${opts} ${x11}" echo "X11 over ssh compatibility mode" fi ################################################################################ # Start the container in the background and then launch an interactive bash # session in the container. This means that all invocations of this script # share the same container. Also changes to the container filesystem are # preserved unless an explict 'podman rm dev-c7' is invoked. ################################################################################ running=false if [[ -n $(podman ps -q -f name=${container_name}) ]]; then # container already running so no prep required if ${changed} ; then echo "ERROR: cannot change properties on a running container." echo "Use -d option to delete the current container." exit 1 fi running=true version_tag=$(podman inspect --format='{{index .Config.Labels "org.opencontainers.image.version"}}' dev-c7) echo "Attaching to existing dev-c7 container version ${version_tag:- Unknown} ..." elif [[ -n $(podman ps -qa -f name=${container_name}) ]]; then # start the stopped container echo "Restarting stopped dev-c7 container ..." podman start ${container_name} elif [[ ${running} == "false" ]]; then # check for updates if requested/required if ! podman image exists ${image}:${version} ; then pull=true fi if ${pull} ; then podman pull ${image}:${version}; echo fi # Create a new background container making process 1 wait indefinitely. # Prior to sleep we update the default shell to be bash, # this is because podman adds a user in etc/passwd but fails to honor # /etc/adduser.conf version_tag=$(podman inspect --format='{{index .Labels "org.opencontainers.image.version"}}' ghcr.io/dls-controls/dev-c7:${version}) echo "Creating new dev-c7 container version ${version_tag:- Unknown} ..." ${logging} # At runtime we launch bash in the container and perform the following: # Restore bash as the default shell in etc/passwd # Reinstall git-core to overcome issue of https plugin missing # Remove the git safe directory check to match the behaviour of RHEL7 git podman run -dit --name ${container_name} ${runtime} ${environ}\ ${identity} ${volumes} ${devices} ${opts} ${image}:${version} \ bash -c "sudo sed -i s#/bin/sh#/bin/bash# /etc/passwd ; sudo yum -y reinstall git-core ; git config --global --add safe.directory '*' ; bash" fi # Execute a shell in the container - this allows multiple shells and avoids # using process 1 so users can exit the shell without killing the container if [[ -n ${commandargs} ]] ; then ${logging} podman exec -itw $(pwd) ${container_name} ${command} "$*" else ${logging} podman exec -itw $(pwd) ${container_name} ${command} fi