#!/bin/sh # # Copyright © 2018 Red Hat, Inc. # # 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. # source /etc/os-release release=$VERSION_ID prefix_sudo="" registry="registry.fedoraproject.org" registry_candidate="candidate-registry.fedoraproject.org" toolbox_prompt="🔹[\u@\h \W]\\$ " create() ( tmpfs_size=$((64 * 1024 * 1024)) # 64 MiB working_container_name="fedora-toolbox-working-container-$(uuidgen --time)" if ! $prefix_sudo buildah inspect --type image $toolbox_image >/dev/null 2>&42; then if ! $prefix_sudo buildah from \ --name $working_container_name \ localhost/$base_toolbox_image >/dev/null 2>&42; then if ! $prefix_sudo buildah from \ --name $working_container_name \ $registry/$fgc/$base_toolbox_image >/dev/null 2>&42; then echo "$0: failed to create working container" exit 1 fi fi if ! $prefix_sudo buildah run $working_container_name -- useradd \ --no-create-home \ --shell $SHELL \ --uid $UID \ --groups wheel \ $USER \ >/dev/null 2>&42; then $prefix_sudo buildah rmi $working_container_name >/dev/null 2>&42 echo "$0: failed to create user $USER with UID $UID" exit 1 fi if ! $prefix_sudo buildah run $working_container_name -- passwd -d $USER >/dev/null 2>&42; then $prefix_sudo buildah rmi $working_container_name >/dev/null 2>&42 echo "$0: failed to remove password for user $USER" exit 1 fi if ! $prefix_sudo buildah run $working_container_name -- passwd -d root >/dev/null 2>&42; then $prefix_sudo buildah rmi $working_container_name >/dev/null 2>&42 echo "$0: failed to remove password for user root" exit 1 fi if ! $prefix_sudo buildah config --volume $HOME $working_container_name >/dev/null 2>&42; then $prefix_sudo buildah rmi $working_container_name >/dev/null 2>&42 echo "$0: failed to configure volume for $HOME" exit 1 fi if ! $prefix_sudo buildah config --volume $XDG_RUNTIME_DIR $working_container_name >/dev/null 2>&42; then $prefix_sudo buildah rmi $working_container_name >/dev/null 2>&42 echo "$0: failed to configure volume for /run/user/$UID" exit 1 fi if ! $prefix_sudo buildah config --volume /dev/dri $working_container_name >/dev/null 2>&42; then $prefix_sudo buildah rmi $working_container_name >/dev/null 2>&42 echo "$0: failed to configure volume for /dev/dri" exit 1 fi if ! $prefix_sudo buildah config --user $USER $working_container_name >/dev/null 2>&42; then $prefix_sudo buildah rmi $working_container_name >/dev/null 2>&42 echo "$0: failed to configure the default user as $USER" exit 1 fi if ! $prefix_sudo buildah config --workingdir $HOME $working_container_name >/dev/null 2>&42; then $prefix_sudo buildah rmi $working_container_name >/dev/null 2>&42 echo "$0: failed to configure the initial working directory to $HOME" exit 1 fi if ! $prefix_sudo buildah commit --rm $working_container_name $toolbox_image >/dev/null 2>&42; then $prefix_sudo buildah rmi $working_container_name >/dev/null 2>&42 echo "$0: failed to create image $toolbox_image" exit 1 fi fi if $prefix_sudo podman inspect --type container $toolbox_container >/dev/null 2>&42; then echo "$0: container $toolbox_container already exists" exit 1 fi total_ram=$(awk '( $1 == "MemTotal:" ) { print $2 }' /proc/meminfo 2>&42) # kibibytes if [ "$total_ram" != "" ] && [ $total_ram -eq $total_ram 2>&42 ]; then tmpfs_size=$((total_ram*1024/2)) # bytes fi max_uid_count=65536 max_minus_uid=$((max_uid_count-UID)) uid_plus_one=$((UID+1)) if ! $prefix_sudo podman create \ --group-add wheel \ --hostname toolbox \ --interactive \ --name $toolbox_container \ --network host \ --privileged \ --security-opt label=disable \ --tmpfs /dev/shm:size=$tmpfs_size \ --tty \ --uidmap $UID:0:1 \ --uidmap 0:1:$UID \ --uidmap $uid_plus_one:$uid_plus_one:$max_minus_uid \ --volume $HOME:$HOME \ --volume $XDG_RUNTIME_DIR:$XDG_RUNTIME_DIR \ --volume /dev/dri:/dev/dri \ $toolbox_image \ /bin/sh >/dev/null 2>&42; then echo "$0: failed to create container $toolbox_container" exit 1 fi ) enter() { if ! $prefix_sudo podman start $toolbox_container >/dev/null 2>&42; then echo "$0: failed to start container $toolbox_container" exit 1 fi if ! $prefix_sudo podman exec \ --env COLORTERM=$COLORTERM \ --env DBUS_SESSION_BUS_ADDRESS=$DBUS_SESSION_BUS_ADDRESS \ --env DESKTOP_SESSION=$DESKTOP_SESSION \ --env DISPLAY=$DISPLAY \ --env LANG=$LANG \ --env PS1="$toolbox_prompt" \ --env SHELL=$SHELL \ --env SSH_AUTH_SOCK=$SSH_AUTH_SOCK \ --env TERM=$TERM \ --env VTE_VERSION=$VTE_VERSION \ --env XDG_CURRENT_DESKTOP=$XDG_CURRENT_DESKTOP \ --env XDG_DATA_DIRS=$XDG_DATA_DIRS \ --env XDG_MENU_PREFIX=$XDG_MENU_PREFIX \ --env XDG_RUNTIME_DIR=$XDG_RUNTIME_DIR \ --env XDG_SEAT=$XDG_SEAT \ --env XDG_SESSION_DESKTOP=$XDG_SESSION_DESKTOP \ --env XDG_SESSION_ID=$XDG_SESSION_ID \ --env XDG_SESSION_TYPE=$XDG_SESSION_TYPE \ --env XDG_VTNR=$XDG_VTNR \ --interactive \ --tty \ $toolbox_container \ $SHELL -l 2>&42; then if ! $prefix_sudo podman exec \ --env COLORTERM=$COLORTERM \ --env DBUS_SESSION_BUS_ADDRESS=$DBUS_SESSION_BUS_ADDRESS \ --env DESKTOP_SESSION=$DESKTOP_SESSION \ --env DISPLAY=$DISPLAY \ --env LANG=$LANG \ --env PS1="$toolbox_prompt" \ --env SHELL=$SHELL \ --env SSH_AUTH_SOCK=$SSH_AUTH_SOCK \ --env TERM=$TERM \ --env VTE_VERSION=$VTE_VERSION \ --env XDG_CURRENT_DESKTOP=$XDG_CURRENT_DESKTOP \ --env XDG_DATA_DIRS=$XDG_DATA_DIRS \ --env XDG_MENU_PREFIX=$XDG_MENU_PREFIX \ --env XDG_RUNTIME_DIR=$XDG_RUNTIME_DIR \ --env XDG_SEAT=$XDG_SEAT \ --env XDG_SESSION_DESKTOP=$XDG_SESSION_DESKTOP \ --env XDG_SESSION_ID=$XDG_SESSION_ID \ --env XDG_SESSION_TYPE=$XDG_SESSION_TYPE \ --env XDG_VTNR=$XDG_VTNR \ --interactive \ --tty \ $toolbox_container \ /bin/bash -l 2>&42; then echo "$0: failed to exec $SHELL inside container $toolbox_container" exit 1 fi fi } exit_if_extra_operand() { if [ "$1" != "" ]; then echo "$0: extra operand '$1'" echo "Try '$0 --help' for more information." exit 1 fi } exit_if_unrecognized_option() { echo "$0: unrecognized option '$1'" echo "Try '$0 --help' for more information." exit 1 } usage() { echo "Usage: fedora-toolbox [--container ]" echo " [--release ]" echo " [-v | --verbose]" echo " create [--candidate-registry]" echo " [--image ]" echo " or: fedora-toolbox [--container ]" echo " [--release ]" echo " [-v | --verbose]" echo " enter" echo " or: fedora-toolbox --help" } exec 42>/dev/null while [[ "$1" = -* ]]; do case $1 in --container ) shift if [ "$1" = "" ]; then echo "$0: missing argument for '--container'" echo "Try '$0 --help' for more information." exit 1 fi toolbox_container=$1 ;; -h | --help ) usage exit ;; --release ) shift if [ "$1" = "" ]; then echo "$0: missing argument for '--release'" echo "Try '$0 --help' for more information." exit 1 fi arg=$(echo $1 | sed 's/^F\|^f//') if [ "$arg" = "" ]; then echo "$0: invalid argument for '--release'" echo "Try '$0 --help' for more information." exit 1 fi if ! [ $arg -eq $arg 2>&42 ]; then echo "$0: invalid argument for '--release'" echo "Try '$0 --help' for more information." exit 1 fi if [ $arg -le 0 2>&42 ]; then echo "$0: invalid argument for '--release'" echo "Try '$0 --help' for more information." exit 1 fi release=$arg ;; --sudo ) prefix_sudo="sudo" ;; -v | --verbose ) exec 42>&2 ;; * ) exit_if_unrecognized_option $1 esac shift done fgc="f$release" [ "$toolbox_container" = "" ] && toolbox_container="fedora-toolbox-$USER:$release" base_toolbox_image="fedora-toolbox:$release" toolbox_image="fedora-toolbox-$USER:$release" if [ "$1" = "" ]; then echo "$0: missing command" echo "Try '$0 --help' for more information." exit 1 fi op=$1 shift case $op in create ) while [[ "$1" = -* ]]; do case $1 in --candidate-registry ) registry=$registry_candidate ;; --image ) shift if [ "$1" = "" ]; then echo "$0: missing argument for '--image'" echo "Try '$0 --help' for more information." exit 1 fi toolbox_image=$1 ;; * ) exit_if_unrecognized_option $1 esac shift done exit_if_extra_operand $1 create exit ;; enter ) while [[ "$1" = -* ]]; do case $1 in * ) exit_if_unrecognized_option $1 esac shift done exit_if_extra_operand $1 enter exit ;; * ) echo "$0: unrecognized command '$op'" echo "Try '$0 --help' for more information." exit 1 esac