3afb2bc4c7
Instead of overwhelming the user with the entire reference documentation, highlight some of the more common commands that a new user is likely to be interested in. This is concise enough to not annoy seasoned users who might have just committed a typo. This should smoothen the onboarding experience by making the commands self-documenting. https://github.com/debarshiray/toolbox/issues/59
1411 lines
44 KiB
Bash
Executable file
1411 lines
44 KiB
Bash
Executable file
#!/bin/sh
|
||
#
|
||
# Copyright © 2018 – 2019 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.
|
||
#
|
||
|
||
|
||
exec 3>/dev/null
|
||
|
||
arguments=""
|
||
base_toolbox_command=$(basename "$0" 2>&3)
|
||
base_toolbox_image=""
|
||
environment_variables="COLORTERM \
|
||
DBUS_SESSION_BUS_ADDRESS \
|
||
DESKTOP_SESSION \
|
||
DISPLAY \
|
||
LANG \
|
||
SHELL \
|
||
SSH_AUTH_SOCK \
|
||
TERM \
|
||
VTE_VERSION \
|
||
XDG_CURRENT_DESKTOP \
|
||
XDG_DATA_DIRS \
|
||
XDG_MENU_PREFIX \
|
||
XDG_RUNTIME_DIR \
|
||
XDG_SEAT \
|
||
XDG_SESSION_DESKTOP \
|
||
XDG_SESSION_ID \
|
||
XDG_SESSION_TYPE \
|
||
XDG_VTNR"
|
||
fgc=""
|
||
|
||
podman_pid=""
|
||
prefix_sudo=""
|
||
registry="registry.fedoraproject.org"
|
||
registry_candidate="candidate-registry.fedoraproject.org"
|
||
release=""
|
||
release_default=""
|
||
spinner_animation="[>----] [=>---] [==>--] [===>-] [====>] [----<] [---<=] [--<==] [-<===] [<====]"
|
||
spinner_template="toolbox-spinner-XXXXXXXXXX"
|
||
tab="$(printf '\t')"
|
||
toolbox_container=""
|
||
toolbox_container_default=""
|
||
toolbox_container_prefix_default=""
|
||
toolbox_image=""
|
||
toolbox_prompt="🔹[\u@\h \W]\\$ "
|
||
user_id_real=$(id -ru 2>&3)
|
||
verbose=false
|
||
|
||
|
||
LGC='\033[1;32m' # Light Green Color
|
||
LBC='\033[1;34m' # Light Blue Color
|
||
NC='\033[0m' # No Color
|
||
|
||
|
||
has_prefix()
|
||
(
|
||
str="$1"
|
||
prefix="$2"
|
||
|
||
ret_val=1
|
||
|
||
case "$str" in
|
||
"$prefix"* )
|
||
ret_val=0
|
||
;;
|
||
* )
|
||
ret_val=1
|
||
;;
|
||
esac
|
||
|
||
return $ret_val
|
||
)
|
||
|
||
|
||
has_substring()
|
||
(
|
||
haystack="$1"
|
||
needle="$2"
|
||
|
||
ret_val=1
|
||
|
||
case "$haystack" in
|
||
*"$needle"* )
|
||
ret_val=0
|
||
;;
|
||
* )
|
||
ret_val=1
|
||
;;
|
||
esac
|
||
|
||
return $ret_val
|
||
)
|
||
|
||
|
||
is_integer()
|
||
{
|
||
[ "$1" != "" ] && [ "$1" -eq "$1" ] 2>&3
|
||
return $?
|
||
}
|
||
|
||
|
||
save_positional_parameters()
|
||
{
|
||
for i; do
|
||
printf "%s\\n" "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" 2>&3
|
||
done
|
||
echo " "
|
||
}
|
||
|
||
|
||
spinner_start()
|
||
(
|
||
directory="$1"
|
||
message="$2"
|
||
|
||
if $verbose; then
|
||
rm --force --recursive "$directory" 2>&3
|
||
return 0
|
||
fi
|
||
|
||
if ! touch "$directory/spinner-start" 2>&3; then
|
||
echo "$base_toolbox_command: unable to start spinner: spinner start file couldn't be created" >&2
|
||
return 1
|
||
fi
|
||
|
||
printf "%s" "$message"
|
||
tput civis 2>&3
|
||
|
||
exec 4>"$directory/spinner-start"
|
||
if ! flock 4 2>&3; then
|
||
echo "$base_toolbox_command: unable to start spinner: spinner lock couldn't be acquired" >&2
|
||
return 1
|
||
fi
|
||
|
||
(
|
||
while [ -f "$directory/spinner-start" ]; do
|
||
echo "$spinner_animation" | sed "s/ /\n/g" 2>&3 | while read -r frame; do
|
||
if ! [ -f "$directory/spinner-start" ] 2>&3; then
|
||
break
|
||
fi
|
||
|
||
printf "%s" "$frame"
|
||
|
||
frame_len=${#frame}
|
||
i=0
|
||
while [ "$i" -lt "$frame_len" ]; do
|
||
printf "\b"
|
||
i=$((i + 1))
|
||
done
|
||
|
||
sleep 1
|
||
done
|
||
done
|
||
|
||
printf "\033[2K" # delete entire line regardless of cursor position
|
||
printf "\r"
|
||
tput cnorm 2>&3
|
||
) &
|
||
|
||
return 0
|
||
)
|
||
|
||
|
||
spinner_stop()
|
||
(
|
||
$verbose && return
|
||
directory="$1"
|
||
|
||
exec 4>"$directory/spinner-start"
|
||
|
||
if ! rm "$directory/spinner-start" 2>&3; then
|
||
echo "$base_toolbox_command: unable to stop spinner: spinner start file couldn't be removed" >&2
|
||
return
|
||
fi
|
||
|
||
if ! flock 4 2>&3; then
|
||
echo "$base_toolbox_command: unable to stop spinner: spinner lock couldn't be acquired" >&2
|
||
return
|
||
fi
|
||
|
||
rm --force --recursive "$directory" 2>&3
|
||
)
|
||
|
||
|
||
check_image_for_volumes()
|
||
(
|
||
image="$1"
|
||
|
||
echo "$base_toolbox_command: checking if image $image has volumes for host bind mounts" >&3
|
||
|
||
if volumes=$($prefix_sudo podman inspect \
|
||
--format "{{.Config.Volumes}}" \
|
||
--type image \
|
||
"$image" 2>&3); then
|
||
if echo "$volumes" | grep "/dev/dri\|/dev/fuse" >/dev/null 2>&3; then
|
||
echo "$base_toolbox_command: image $image has volumes for host bind mounts:" >&3
|
||
echo "$base_toolbox_command: $volumes" >&3
|
||
echo "$base_toolbox_command: consider re-creating image $image" >&3
|
||
fi
|
||
fi
|
||
)
|
||
|
||
|
||
configure_working_container()
|
||
(
|
||
working_container_name="$1"
|
||
kcm_ccache_configuration="$2"
|
||
|
||
if [ "$(readlink /home)" = var/home ] ; then
|
||
need_home_link=true
|
||
else
|
||
need_home_link=false
|
||
fi
|
||
|
||
if $need_home_link ; then
|
||
if ! $prefix_sudo buildah run "$working_container_name" -- \
|
||
sh -c 'rmdir /home && mkdir -m 0755 -p /var/home && ln -s var/home /home' 2>&3; then
|
||
$prefix_sudo buildah rm "$working_container_name" >/dev/null 2>&3
|
||
echo "$base_toolbox_command: failed to make /home a symlink" >&2
|
||
return 1
|
||
fi
|
||
fi
|
||
|
||
if [ "$kcm_ccache_configuration" != "" ] 2>&3; then
|
||
if ! $prefix_sudo buildah copy "$working_container_name" \
|
||
"$kcm_ccache_configuration" \
|
||
/etc/krb5.conf.d >/dev/null 2>&3; then
|
||
$prefix_sudo buildah rm "$working_container_name" >/dev/null 2>&3
|
||
echo "$base_toolbox_command: failed to set KCM as the default Kerberos credential cache" >&2
|
||
return 1
|
||
fi
|
||
fi
|
||
|
||
if ! $prefix_sudo buildah run "$working_container_name" -- useradd \
|
||
--home-dir "$HOME" \
|
||
--no-create-home \
|
||
--shell "$SHELL" \
|
||
--uid "$user_id_real" \
|
||
--groups wheel \
|
||
"$USER" \
|
||
>/dev/null 2>&3; then
|
||
echo "$base_toolbox_command: failed to create user $USER with UID $user_id_real" >&2
|
||
return 1
|
||
fi
|
||
|
||
if ! $prefix_sudo buildah run "$working_container_name" -- passwd -d "$USER" >/dev/null 2>&3; then
|
||
echo "$base_toolbox_command: failed to remove password for user $USER" >&2
|
||
return 1
|
||
fi
|
||
|
||
if ! $prefix_sudo buildah run "$working_container_name" -- passwd -d root >/dev/null 2>&3; then
|
||
echo "$base_toolbox_command: failed to remove password for user root" >&2
|
||
return 1
|
||
fi
|
||
|
||
if ! $prefix_sudo buildah config \
|
||
--label "com.github.debarshiray.toolbox=true" \
|
||
"$working_container_name" >/dev/null 2>&3; then
|
||
echo "$base_toolbox_command: failed to add com.github.debarshiray.toolbox=true" >&2
|
||
return 1
|
||
fi
|
||
|
||
if ! $prefix_sudo buildah config --user "$USER" "$working_container_name" >/dev/null 2>&3; then
|
||
echo "$base_toolbox_command: failed to configure the default user as $USER" >&2
|
||
return 1
|
||
fi
|
||
|
||
if ! $prefix_sudo buildah config --workingdir "$HOME" "$working_container_name" >/dev/null 2>&3; then
|
||
echo "$base_toolbox_command: failed to configure the initial working directory to $HOME" >&2
|
||
return 1
|
||
fi
|
||
|
||
return 0
|
||
)
|
||
|
||
|
||
create_environment_options()
|
||
{
|
||
echo "$environment_variables" \
|
||
| sed "s/ \+/\n/g" 2>&3 \
|
||
| {
|
||
environment_options=""
|
||
echo "$base_toolbox_command: creating list of environment variables to forward" >&3
|
||
value=""
|
||
while read -r variable; do
|
||
eval value="$""$variable"
|
||
echo "$base_toolbox_command: $variable=$value" >&3
|
||
environment_options="$environment_options --env=$variable=$value"
|
||
done
|
||
|
||
environment_options=${environment_options#" "}
|
||
echo "$base_toolbox_command: created options for environment variables to forward" >&3
|
||
echo "$environment_options" >&3
|
||
echo "$environment_options"
|
||
}
|
||
}
|
||
|
||
|
||
create_toolbox_image_name()
|
||
(
|
||
# Based on the ResolveName function implemented in:
|
||
# https://github.com/containers/buildah/blob/master/util/util.go
|
||
|
||
if image_reference_can_be_id "$base_toolbox_image"; then
|
||
if base_toolbox_image_id=$($prefix_sudo podman inspect \
|
||
--format "{{.Id}}" \
|
||
--type image \
|
||
"$base_toolbox_image" 2>&3); then
|
||
if has_prefix "$base_toolbox_image_id" "$base_toolbox_image"; then
|
||
echo "$base_toolbox_image-$USER:latest"
|
||
return 0
|
||
fi
|
||
fi
|
||
fi
|
||
|
||
basename=$(image_reference_get_basename "$base_toolbox_image")
|
||
if [ "$basename" = "" ] 2>&3; then
|
||
return 100
|
||
fi
|
||
|
||
tag=$(image_reference_get_tag "$base_toolbox_image")
|
||
if [ "$tag" = "" ] 2>&3; then
|
||
echo "$basename-$USER"
|
||
else
|
||
echo "$basename-$USER:$tag"
|
||
fi
|
||
|
||
return 0
|
||
)
|
||
|
||
|
||
get_host_version_id()
|
||
(
|
||
# shellcheck disable=SC1091
|
||
. /etc/os-release
|
||
echo "$VERSION_ID"
|
||
)
|
||
|
||
|
||
image_reference_can_be_id()
|
||
(
|
||
image="$1"
|
||
|
||
echo "$image" | grep "^[a-f0-9]\{6,64\}$" >/dev/null 2>&3
|
||
return $?
|
||
)
|
||
|
||
|
||
image_reference_get_basename()
|
||
(
|
||
image="$1"
|
||
|
||
domain=$(image_reference_get_domain "$image")
|
||
remainder=${image#$domain}
|
||
path=${remainder%:*}
|
||
basename=${path##*/}
|
||
echo "$basename"
|
||
)
|
||
|
||
|
||
image_reference_get_domain()
|
||
(
|
||
image="$1"
|
||
|
||
image_reference_has_domain "$image" && domain=${image%%/*}
|
||
echo "$domain"
|
||
)
|
||
|
||
|
||
image_reference_get_tag()
|
||
(
|
||
image="$1"
|
||
|
||
domain=$(image_reference_get_domain "$image")
|
||
remainder=${image#$domain}
|
||
|
||
tag=""
|
||
if (echo "$remainder" | grep ":" >/dev/null 2>&3); then
|
||
tag=${remainder#*:}
|
||
fi
|
||
|
||
echo "$tag"
|
||
)
|
||
|
||
|
||
image_reference_has_domain()
|
||
(
|
||
# Based on the splitDockerDomain function implemented in:
|
||
# https://github.com/docker/distribution/blob/master/reference/normalize.go
|
||
|
||
image="$1"
|
||
|
||
if ! (echo "$image" | grep "/" >/dev/null 2>&3); then
|
||
return 1
|
||
fi
|
||
|
||
prefix=${image%%/*}
|
||
if ! (echo "$prefix" | grep "[.:]" >/dev/null 2>&3) && [ "$prefix" != "localhost" ] 2>&3; then
|
||
return 1
|
||
fi
|
||
|
||
return 0
|
||
)
|
||
|
||
|
||
images_get_details()
|
||
(
|
||
images="$1"
|
||
|
||
if ! echo "$images" | while read -r image; do
|
||
[ "$image" = "" ] 2>&3 && continue
|
||
|
||
if ! $prefix_sudo podman images \
|
||
--format "{{.ID}} {{.Repository}}:{{.Tag}} {{.Created}}" \
|
||
--noheading \
|
||
"$image" 2>&3; then
|
||
echo "$base_toolbox_command: failed to get details for image $image" >&2
|
||
return 1
|
||
fi
|
||
done; then
|
||
return 1
|
||
fi
|
||
|
||
return 0
|
||
)
|
||
|
||
|
||
pull_base_toolbox_image()
|
||
(
|
||
has_domain=false
|
||
|
||
if image_reference_can_be_id "$base_toolbox_image"; then
|
||
echo "$base_toolbox_command: looking for image $base_toolbox_image" >&3
|
||
|
||
if $prefix_sudo podman inspect --type image "$base_toolbox_image" >/dev/null 2>&3; then
|
||
return 0
|
||
fi
|
||
fi
|
||
|
||
image_reference_has_domain "$base_toolbox_image" && has_domain=true
|
||
|
||
if ! $has_domain; then
|
||
echo "$base_toolbox_command: looking for image localhost/$base_toolbox_image" >&3
|
||
|
||
if $prefix_sudo buildah pull localhost/$base_toolbox_image >/dev/null 2>&3; then
|
||
return 0
|
||
fi
|
||
fi
|
||
|
||
if $has_domain; then
|
||
base_toolbox_image_full="$base_toolbox_image"
|
||
else
|
||
base_toolbox_image_full="$registry/$fgc/$base_toolbox_image"
|
||
fi
|
||
|
||
echo "$base_toolbox_command: looking for image $base_toolbox_image_full" >&3
|
||
|
||
if spinner_directory=$(mktemp --directory --tmpdir $spinner_template 2>&3); then
|
||
spinner_message="$base_toolbox_command: pulling $base_toolbox_image_full: "
|
||
if ! spinner_start "$spinner_directory" "$spinner_message"; then
|
||
spinner_directory=""
|
||
fi
|
||
else
|
||
echo "$base_toolbox_command: unable to start spinner: spinner directory not created" >&2
|
||
spinner_directory=""
|
||
fi
|
||
|
||
$prefix_sudo buildah pull $base_toolbox_image_full >/dev/null 2>&3
|
||
ret_val=$?
|
||
|
||
if [ "$spinner_directory" != "" ]; then
|
||
spinner_stop "$spinner_directory"
|
||
fi
|
||
|
||
return $ret_val
|
||
)
|
||
|
||
|
||
create()
|
||
(
|
||
dbus_system_bus_address="unix:path=/var/run/dbus/system_bus_socket"
|
||
kcm_ccache_configuration=""
|
||
kcm_socket=""
|
||
kcm_socket_bind=""
|
||
tmpfs_size=$((64 * 1024 * 1024)) # 64 MiB
|
||
working_container_name="toolbox-working-container-$(uuidgen --time)"
|
||
|
||
# shellcheck disable=SC2153
|
||
if [ "$DBUS_SYSTEM_BUS_ADDRESS" != "" ]; then
|
||
dbus_system_bus_address=$DBUS_SYSTEM_BUS_ADDRESS
|
||
fi
|
||
dbus_system_bus_path=$(echo "$dbus_system_bus_address" | cut --delimiter = --fields 2 2>&3)
|
||
dbus_system_bus_path=$(readlink --canonicalize "$dbus_system_bus_path" 2>&3)
|
||
|
||
# Note that 'systemctl show ...' doesn't terminate with a non-zero exit
|
||
# code when used with an unknown unit. eg.:
|
||
# $ systemctl show --value --property Listen foo
|
||
# $ echo $?
|
||
# 0
|
||
if ! kcm_socket_listen=$(systemctl show --value --property Listen sssd-kcm.socket 2>&3); then
|
||
echo "$base_toolbox_command: failed to use 'systemctl show'" >&3
|
||
kcm_socket_listen=""
|
||
elif [ "$kcm_socket_listen" = "" ] 2>&3; then
|
||
echo "$base_toolbox_command: failed to read property Listen from sssd-kcm.socket" >&3
|
||
else
|
||
echo "$base_toolbox_command: checking value $kcm_socket_listen of property Listen in sssd-kcm.socket" >&3
|
||
|
||
if ! (echo "$kcm_socket_listen" | grep " (Stream)$" >/dev/null 2>&3); then
|
||
echo "$base_toolbox_command: unknown socket in sssd-kcm.socket" >&2
|
||
echo "$base_toolbox_command: expected SOCK_STREAM" >&2
|
||
kcm_socket_listen=""
|
||
elif ! (echo "$kcm_socket_listen" | grep "^/" >/dev/null 2>&3); then
|
||
echo "$base_toolbox_command: unknown socket in sssd-kcm.socket" >&2
|
||
echo "$base_toolbox_command: expected file system socket in the AF_UNIX family" >&2
|
||
kcm_socket_listen=""
|
||
fi
|
||
fi
|
||
|
||
echo "$base_toolbox_command: parsing value $kcm_socket_listen of property Listen in sssd-kcm.socket" >&3
|
||
|
||
if [ "$kcm_socket_listen" != "" ] 2>&3; then
|
||
kcm_ccache_configuration="/etc/krb5.conf.d/kcm_default_ccache"
|
||
kcm_socket=${kcm_socket_listen%" (Stream)"}
|
||
kcm_socket_bind="--volume $kcm_socket:$kcm_socket"
|
||
fi
|
||
|
||
echo "$base_toolbox_command: checking if image $toolbox_image already exists" >&3
|
||
|
||
if ! $prefix_sudo podman inspect --type image $toolbox_image >/dev/null 2>&3; then
|
||
if ! pull_base_toolbox_image; then
|
||
echo "$base_toolbox_command: failed to pull base image $base_toolbox_image" >&2
|
||
exit 1
|
||
fi
|
||
|
||
if image_reference_has_domain "$base_toolbox_image"; then
|
||
base_toolbox_image_full="$base_toolbox_image"
|
||
else
|
||
if ! base_toolbox_image_full=$($prefix_sudo podman inspect \
|
||
--format "{{index .RepoTags 0}}" \
|
||
--type image \
|
||
"$base_toolbox_image" 2>&3); then
|
||
echo "$base_toolbox_command: failed to get RepoTag for base image $base_toolbox_image" >&2
|
||
exit 1
|
||
fi
|
||
|
||
echo "$base_toolbox_command: base image $base_toolbox_image resolved to $base_toolbox_image_full" >&3
|
||
fi
|
||
|
||
echo "$base_toolbox_command: trying to create working container $working_container_name" >&3
|
||
|
||
if spinner_directory=$(mktemp --directory --tmpdir $spinner_template 2>&3); then
|
||
spinner_message="$base_toolbox_command: creating working container: "
|
||
if ! spinner_start "$spinner_directory" "$spinner_message"; then
|
||
spinner_directory=""
|
||
fi
|
||
else
|
||
echo "$base_toolbox_command: unable to start spinner: spinner directory not created" >&2
|
||
spinner_directory=""
|
||
fi
|
||
|
||
$prefix_sudo buildah from --name "$working_container_name" "$base_toolbox_image_full" >/dev/null 2>&3
|
||
ret_val=$?
|
||
|
||
if [ "$spinner_directory" != "" ]; then
|
||
spinner_stop "$spinner_directory"
|
||
fi
|
||
|
||
if [ $ret_val -ne 0 ]; then
|
||
echo "$base_toolbox_command: failed to create working container" >&2
|
||
exit 1
|
||
fi
|
||
|
||
echo "$base_toolbox_command: trying to configure working container $working_container_name" >&3
|
||
|
||
if spinner_directory=$(mktemp --directory --tmpdir $spinner_template 2>&3); then
|
||
spinner_message="$base_toolbox_command: configuring working container: "
|
||
if ! spinner_start "$spinner_directory" "$spinner_message"; then
|
||
spinner_directory=""
|
||
fi
|
||
else
|
||
echo "$base_toolbox_command: unable to start spinner: spinner directory not created" >&2
|
||
spinner_directory=""
|
||
fi
|
||
|
||
configure_working_container "$working_container_name" "$kcm_ccache_configuration"
|
||
ret_val=$?
|
||
|
||
if [ "$spinner_directory" != "" ]; then
|
||
spinner_stop "$spinner_directory"
|
||
fi
|
||
|
||
if [ $ret_val -ne 0 ]; then
|
||
$prefix_sudo buildah rm "$working_container_name" >/dev/null 2>&3
|
||
exit 1
|
||
fi
|
||
|
||
echo "$base_toolbox_command: trying to create image $toolbox_image" >&3
|
||
|
||
if spinner_directory=$(mktemp --directory --tmpdir $spinner_template 2>&3); then
|
||
spinner_message="$base_toolbox_command: creating image $toolbox_image: "
|
||
if ! spinner_start "$spinner_directory" "$spinner_message"; then
|
||
spinner_directory=""
|
||
fi
|
||
else
|
||
echo "$base_toolbox_command: unable to start spinner: spinner directory not created" >&2
|
||
spinner_directory=""
|
||
fi
|
||
|
||
$prefix_sudo buildah commit --rm "$working_container_name" "$toolbox_image" >/dev/null 2>&3
|
||
ret_val=$?
|
||
|
||
if [ "$spinner_directory" != "" ]; then
|
||
spinner_stop "$spinner_directory"
|
||
fi
|
||
|
||
if [ $ret_val -ne 0 ]; then
|
||
$prefix_sudo buildah rm "$working_container_name" >/dev/null 2>&3
|
||
echo "$base_toolbox_command: failed to create image $toolbox_image" >&2
|
||
exit 1
|
||
fi
|
||
|
||
echo "$base_toolbox_command: created image $toolbox_image" >&3
|
||
fi
|
||
|
||
check_image_for_volumes "$toolbox_image"
|
||
|
||
echo "$base_toolbox_command: checking if container $toolbox_container already exists" >&3
|
||
|
||
if $prefix_sudo podman inspect --type container $toolbox_container >/dev/null 2>&3; then
|
||
echo "$base_toolbox_command: container $toolbox_container already exists" >&2
|
||
exit 1
|
||
fi
|
||
|
||
total_ram=$(awk '( $1 == "MemTotal:" ) { print $2 }' /proc/meminfo 2>&3) # kibibytes
|
||
if is_integer "$total_ram"; then
|
||
tmpfs_size=$((total_ram * 1024 / 2)) # bytes
|
||
fi
|
||
|
||
max_uid_count=65536
|
||
max_minus_uid=$((max_uid_count - user_id_real))
|
||
uid_plus_one=$((user_id_real + 1))
|
||
|
||
echo "$base_toolbox_command: trying to create container $toolbox_container" >&3
|
||
|
||
if spinner_directory=$(mktemp --directory --tmpdir $spinner_template 2>&3); then
|
||
spinner_message="$base_toolbox_command: creating container $toolbox_container: "
|
||
if ! spinner_start "$spinner_directory" "$spinner_message"; then
|
||
spinner_directory=""
|
||
fi
|
||
else
|
||
echo "$base_toolbox_command: unable to start spinner: spinner directory not created" >&2
|
||
spinner_directory=""
|
||
fi
|
||
|
||
# shellcheck disable=SC2086
|
||
$prefix_sudo podman create \
|
||
--group-add wheel \
|
||
--hostname toolbox \
|
||
--name $toolbox_container \
|
||
--network host \
|
||
--pid host \
|
||
--privileged \
|
||
--security-opt label=disable \
|
||
--tmpfs /dev/shm:size=$tmpfs_size \
|
||
--uidmap "$user_id_real":0:1 \
|
||
--uidmap 0:1:"$user_id_real" \
|
||
--uidmap "$uid_plus_one":"$uid_plus_one":"$max_minus_uid" \
|
||
$kcm_socket_bind \
|
||
--volume "$HOME":"$HOME":rslave \
|
||
--volume "$XDG_RUNTIME_DIR":"$XDG_RUNTIME_DIR" \
|
||
--volume "$dbus_system_bus_path":"$dbus_system_bus_path" \
|
||
--volume /dev/bus:/dev/bus \
|
||
--volume /dev/dri:/dev/dri \
|
||
--volume /dev/fuse:/dev/fuse \
|
||
--volume /media:/media:rslave \
|
||
--volume /mnt:/mnt:rslave \
|
||
--volume /run/media:/run/media:rslave \
|
||
$toolbox_image \
|
||
sleep +Inf >/dev/null 2>&3
|
||
ret_val=$?
|
||
|
||
if [ "$spinner_directory" != "" ]; then
|
||
spinner_stop "$spinner_directory"
|
||
fi
|
||
|
||
if [ $ret_val -ne 0 ]; then
|
||
echo "$base_toolbox_command: failed to create container $toolbox_container" >&2
|
||
exit 1
|
||
fi
|
||
|
||
echo "Created toolbox container: $toolbox_container"
|
||
|
||
enter_command=""
|
||
if [ "$toolbox_container" = "$toolbox_container_default" ] 2>&3; then
|
||
enter_command="$base_toolbox_command enter"
|
||
elif [ "$toolbox_container" = "$toolbox_container_prefix_default:$release" ] 2>&3; then
|
||
enter_command="$base_toolbox_command enter --release $release"
|
||
else
|
||
enter_command="$base_toolbox_command enter --container $toolbox_container"
|
||
fi
|
||
|
||
echo "Enter with: $enter_command"
|
||
)
|
||
|
||
|
||
enter()
|
||
(
|
||
shell_to_exec=/bin/bash
|
||
|
||
echo "$base_toolbox_command: checking if container $toolbox_container exists" >&3
|
||
|
||
if ! toolbox_image=$($prefix_sudo podman inspect \
|
||
--format "{{.ImageName}}" \
|
||
--type container \
|
||
$toolbox_container 2>&3); then
|
||
echo "$base_toolbox_command: container $toolbox_container not found" >&2
|
||
echo "Use the 'create' command to create a toolbox." >&2
|
||
echo "Try '$base_toolbox_command --help' for more information." >&2
|
||
exit 1
|
||
fi
|
||
|
||
echo "$base_toolbox_command: container $toolbox_container was created from image $toolbox_image" >&3
|
||
|
||
[ "$toolbox_image" != "" ] 2>&3 && check_image_for_volumes "$toolbox_image"
|
||
|
||
echo "$base_toolbox_command: trying to start container $toolbox_container" >&3
|
||
|
||
if ! $prefix_sudo podman start $toolbox_container >/dev/null 2>&3; then
|
||
echo "$base_toolbox_command: failed to start container $toolbox_container" >&2
|
||
exit 1
|
||
fi
|
||
|
||
if [ "$DBUS_SYSTEM_BUS_ADDRESS" != "" ]; then
|
||
set_dbus_system_bus_address="--env DBUS_SYSTEM_BUS_ADDRESS=$DBUS_SYSTEM_BUS_ADDRESS"
|
||
fi
|
||
|
||
set_environment=$(create_environment_options)
|
||
|
||
echo "$base_toolbox_command: looking for $SHELL in container $toolbox_container" >&3
|
||
|
||
if $prefix_sudo podman exec $toolbox_container test -f "$SHELL" 2>&3; then
|
||
shell_to_exec=$SHELL
|
||
else
|
||
echo "$base_toolbox_command: $SHELL not found in $toolbox_container; using $shell_to_exec instead" >&3
|
||
fi
|
||
|
||
echo "$base_toolbox_command: trying to exec $shell_to_exec in container $toolbox_container" >&3
|
||
|
||
# shellcheck disable=SC2016
|
||
# for the command passed to capsh
|
||
# shellcheck disable=SC2086
|
||
$prefix_sudo podman exec \
|
||
$set_dbus_system_bus_address \
|
||
$set_environment \
|
||
--interactive \
|
||
--tty \
|
||
"$toolbox_container" \
|
||
capsh --caps="" -- -c 'cd "$1"; export PS1="$2"; shift 2; exec "$@"' \
|
||
/bin/sh \
|
||
"$PWD" \
|
||
"$toolbox_prompt" \
|
||
"$shell_to_exec" -l 2>&3
|
||
)
|
||
|
||
|
||
list_images()
|
||
(
|
||
if ! images_old=$($prefix_sudo podman images \
|
||
--filter "label=com.redhat.component=fedora-toolbox" \
|
||
--format "{{.Repository}}:{{.Tag}}" 2>&3); then
|
||
echo "$base_toolbox_command: failed to list images with com.redhat.component=fedora-toolbox" >&2
|
||
return 1
|
||
fi
|
||
|
||
if ! images=$($prefix_sudo podman images \
|
||
--filter "label=com.github.debarshiray.toolbox=true" \
|
||
--format "{{.Repository}}:{{.Tag}}" 2>&3); then
|
||
echo "$base_toolbox_command: failed to list images with com.github.debarshiray.toolbox=true" >&2
|
||
return 1
|
||
fi
|
||
|
||
images=$(printf "%s\n%s\n" "$images_old" "$images" | sort 2>&3 | uniq 2>&3)
|
||
if ! details=$(images_get_details "$images"); then
|
||
return 1
|
||
fi
|
||
|
||
if ! output=$(echo "$details" \
|
||
| sed "s/ \{2,\}/\t/g" 2>&3 \
|
||
| column --separator "$tab" --table --table-columns "IMAGE ID,IMAGE NAME,CREATED" 2>&3); then
|
||
echo "$base_toolbox_command: failed to parse list of images" >&2
|
||
return 1
|
||
fi
|
||
|
||
if [ "$output" != "" ]; then
|
||
# shellcheck disable=SC2059
|
||
printf "${LBC}Images created by toolbox${NC}\n"
|
||
echo "$output"
|
||
fi
|
||
|
||
return 0
|
||
)
|
||
|
||
|
||
containers_get_details()
|
||
(
|
||
containers="$1"
|
||
|
||
if ! echo "$containers" | while read -r container; do
|
||
[ "$container" = "" ] 2>&3 && continue
|
||
|
||
if ! $prefix_sudo podman ps --all \
|
||
--filter "name=$container" \
|
||
--format "{{.ID}} {{.Names}} {{.Created}} {{.Status}} {{.Image}}" 2>&3; then
|
||
echo "$base_toolbox_command: failed to get details for container $container" >&2
|
||
return 1
|
||
fi
|
||
done; then
|
||
return 1
|
||
fi
|
||
|
||
return 0
|
||
)
|
||
|
||
|
||
list_containers()
|
||
(
|
||
if ! containers_old=$($prefix_sudo podman ps \
|
||
--all \
|
||
--filter "label=com.redhat.component=fedora-toolbox" \
|
||
--format "{{.Names}}" 2>&3); then
|
||
echo "$base_toolbox_command: failed to list containers with com.redhat.component=fedora-toolbox" >&2
|
||
return 1
|
||
fi
|
||
|
||
if ! containers=$($prefix_sudo podman ps \
|
||
--all \
|
||
--filter "label=com.github.debarshiray.toolbox=true" \
|
||
--format "{{.Names}}" 2>&3); then
|
||
echo "$base_toolbox_command: failed to list containers with com.github.debarshiray.toolbox=true" >&2
|
||
return 1
|
||
fi
|
||
|
||
containers=$(printf "%s\n%s\n" "$containers_old" "$containers" | sort 2>&3 | uniq 2>&3)
|
||
if ! details=$(containers_get_details "$containers"); then
|
||
return 1
|
||
fi
|
||
|
||
if ! output=$(echo "$details" \
|
||
| sed "s/ \{2,\}/\t/g" 2>&3 \
|
||
| column \
|
||
--separator "$tab" \
|
||
--table \
|
||
--table-columns "CONTAINER ID,CONTAINER NAME,CREATED,STATUS,IMAGE NAME" 2>&3); then
|
||
echo "$base_toolbox_command: failed to parse list of containers" >&2
|
||
return 1
|
||
fi
|
||
|
||
if [ "$output" != "" ]; then
|
||
# shellcheck disable=SC2059
|
||
printf "${LBC}Containers created by toolbox${NC}\n"
|
||
echo "$output" | head --lines 1 2>&3
|
||
|
||
echo "$output" | tail --lines +2 2>&3 \
|
||
| (
|
||
while read -r container; do
|
||
id=$(echo "$container" | cut --delimiter " " --fields 1 2>&3)
|
||
is_running=$($prefix_sudo podman inspect "$id" --format "{{.State.Running}}" 2>&3)
|
||
if $is_running; then
|
||
# shellcheck disable=SC2059
|
||
printf "${LGC}$container${NC}\n"
|
||
else
|
||
echo "$container"
|
||
fi
|
||
done
|
||
)
|
||
fi
|
||
|
||
return 0
|
||
)
|
||
|
||
|
||
remove_containers()
|
||
(
|
||
ids=$1
|
||
all=$2
|
||
force=$3
|
||
|
||
ret_val=0
|
||
|
||
$force && force_option="--force"
|
||
|
||
if $all; then
|
||
if ! ids_old=$($prefix_sudo podman ps \
|
||
--all \
|
||
--filter "label=com.redhat.component=fedora-toolbox" \
|
||
--format "{{.ID}}" 2>&3); then
|
||
echo "$base_toolbox_command: failed to list containers with com.redhat.component=fedora-toolbox" >&2
|
||
return 1
|
||
fi
|
||
|
||
if ! ids=$($prefix_sudo podman ps \
|
||
--all \
|
||
--filter "label=com.github.debarshiray.toolbox=true" \
|
||
--format "{{.ID}}" 2>&3); then
|
||
echo "$base_toolbox_command: failed to list containers with com.github.debarshiray.toolbox=true" >&2
|
||
return 1
|
||
fi
|
||
|
||
ids=$(printf "%s\n%s\n" "$ids_old" "$ids" | sort 2>&3 | uniq 2>&3)
|
||
if [ "$ids" != "" ]; then
|
||
ret_val=$(echo "$ids" \
|
||
| (
|
||
while read -r id; do
|
||
if ! $prefix_sudo podman rm $force_option "$id" >/dev/null 2>&3; then
|
||
echo "$base_toolbox_command: failed to remove container $id" >&2
|
||
ret_val=1
|
||
fi
|
||
done
|
||
|
||
echo "$ret_val"
|
||
)
|
||
)
|
||
fi
|
||
else
|
||
ret_val=$(echo "$ids" \
|
||
| sed "s/ \+/\n/g" 2>&3 \
|
||
| (
|
||
while read -r id; do
|
||
if ! labels=$($prefix_sudo podman inspect \
|
||
--format "{{.Config.Labels}}" \
|
||
--type container \
|
||
"$id" 2>&3); then
|
||
echo "$base_toolbox_command: failed to inspect $id" >&2
|
||
ret_val=1
|
||
continue
|
||
fi
|
||
|
||
if ! has_substring "$labels" "com.github.debarshiray.toolbox" \
|
||
&& ! has_substring "$labels" "com.redhat.component:fedora-toolbox"; then
|
||
echo "$base_toolbox_command: $id is not a toolbox container" >&2
|
||
ret_val=1
|
||
continue
|
||
fi
|
||
|
||
if ! $prefix_sudo podman rm $force_option "$id" >/dev/null 2>&3; then
|
||
echo "$base_toolbox_command: failed to remove container $id" >&2
|
||
ret_val=1
|
||
fi
|
||
done
|
||
|
||
echo "$ret_val"
|
||
)
|
||
)
|
||
fi
|
||
|
||
return "$ret_val"
|
||
)
|
||
|
||
|
||
remove_images()
|
||
(
|
||
ids=$1
|
||
all=$2
|
||
force=$3
|
||
|
||
ret_val=0
|
||
|
||
$force && force_option="--force"
|
||
|
||
if $all; then
|
||
if ! ids_old=$($prefix_sudo podman images \
|
||
--filter "label=com.redhat.component=fedora-toolbox" \
|
||
--format "{{.ID}}" 2>&3); then
|
||
echo "$0: failed to list images with com.redhat.component=fedora-toolbox" >&2
|
||
return 1
|
||
fi
|
||
|
||
if ! ids=$($prefix_sudo podman images \
|
||
--all \
|
||
--filter "label=com.github.debarshiray.toolbox=true" \
|
||
--format "{{.ID}}" 2>&3); then
|
||
echo "$0: failed to list images with com.github.debarshiray.toolbox=true" >&2
|
||
return 1
|
||
fi
|
||
|
||
ids=$(printf "%s\n%s\n" "$ids_old" "$ids" | sort 2>&3 | uniq 2>&3)
|
||
if [ "$ids" != "" ]; then
|
||
ret_val=$(echo "$ids" \
|
||
| (
|
||
while read -r id; do
|
||
if ! $prefix_sudo podman rmi $force_option "$id" >/dev/null 2>&3; then
|
||
echo "$base_toolbox_command: failed to remove image $id" >&2
|
||
ret_val=1
|
||
fi
|
||
done
|
||
|
||
echo "$ret_val"
|
||
)
|
||
)
|
||
fi
|
||
else
|
||
ret_val=$(echo "$ids" \
|
||
| sed "s/ \+/\n/g" 2>&3 \
|
||
| (
|
||
while read -r id; do
|
||
if ! labels=$($prefix_sudo podman inspect \
|
||
--format "{{.Labels}}" \
|
||
--type image \
|
||
"$id" 2>&3); then
|
||
echo "$base_toolbox_command: failed to inspect $id" >&2
|
||
ret_val=1
|
||
continue
|
||
fi
|
||
|
||
if ! has_substring "$labels" "com.github.debarshiray.toolbox" \
|
||
&& ! has_substring "$labels" "com.redhat.component:fedora-toolbox"; then
|
||
echo "$base_toolbox_command: $id is not a toolbox image" >&2
|
||
ret_val=1
|
||
continue
|
||
fi
|
||
|
||
if ! $prefix_sudo podman rmi $force_option "$id" >/dev/null 2>&3; then
|
||
echo "$base_toolbox_command: failed to remove image $id" >&2
|
||
ret_val=1
|
||
fi
|
||
done
|
||
|
||
echo "$ret_val"
|
||
)
|
||
)
|
||
fi
|
||
|
||
return "$ret_val"
|
||
)
|
||
|
||
|
||
exit_if_extra_operand()
|
||
{
|
||
if [ "$1" != "" ]; then
|
||
echo "$base_toolbox_command: extra operand '$1'" >&2
|
||
echo "Try '$base_toolbox_command --help' for more information." >&2
|
||
exit 1
|
||
fi
|
||
}
|
||
|
||
|
||
exit_if_missing_argument()
|
||
{
|
||
if [ "$2" = "" ]; then
|
||
echo "$base_toolbox_command: missing argument for '$1'" >&2
|
||
echo "Try '$base_toolbox_command --help' for more information." >&2
|
||
exit 1
|
||
fi
|
||
}
|
||
|
||
|
||
exit_if_non_positive_argument()
|
||
{
|
||
if ! is_integer "$2"; then
|
||
echo "$base_toolbox_command: invalid argument for '$1'" >&2
|
||
echo "Try '$base_toolbox_command --help' for more information." >&2
|
||
exit 1
|
||
fi
|
||
if [ "$2" -le 0 ] 2>&3; then
|
||
echo "$base_toolbox_command: invalid argument for '$1'" >&2
|
||
echo "Try '$base_toolbox_command --help' for more information." >&2
|
||
exit 1
|
||
fi
|
||
}
|
||
|
||
|
||
exit_if_unrecognized_option()
|
||
{
|
||
echo "$base_toolbox_command: unrecognized option '$1'" >&2
|
||
echo "Try '$base_toolbox_command --help' for more information." >&2
|
||
exit 1
|
||
}
|
||
|
||
|
||
# shellcheck disable=SC2120
|
||
forward_to_host()
|
||
(
|
||
eval "set -- $arguments"
|
||
|
||
if [ "$DBUS_SYSTEM_BUS_ADDRESS" != "" ]; then
|
||
set_dbus_system_bus_address="--env=DBUS_SYSTEM_BUS_ADDRESS=$DBUS_SYSTEM_BUS_ADDRESS"
|
||
fi
|
||
|
||
set_environment=$(create_environment_options)
|
||
|
||
echo "$base_toolbox_command: forwarding to host:" >&3
|
||
echo "$base_toolbox_command: $0" >&3
|
||
for i in "$@"; do
|
||
echo "$base_toolbox_command: $i" >&3
|
||
done
|
||
|
||
# shellcheck disable=SC2086
|
||
flatpak-spawn $set_dbus_system_bus_address $set_environment --host "$0" "$@" 2>&3
|
||
)
|
||
|
||
|
||
update_container_and_image_names()
|
||
{
|
||
[ "$release" = "" ] 2>&3 && release="$release_default"
|
||
|
||
if [ "$base_toolbox_image" = "" ] 2>&3; then
|
||
base_toolbox_image="fedora-toolbox:$release"
|
||
else
|
||
release=$(image_reference_get_tag "$base_toolbox_image")
|
||
[ "$release" = "" ] 2>&3 && release="$release_default"
|
||
fi
|
||
|
||
fgc="f$release"
|
||
echo "$base_toolbox_command: Fedora generational core is $fgc" >&3
|
||
|
||
echo "$base_toolbox_command: base image is $base_toolbox_image" >&3
|
||
|
||
toolbox_image=$(create_toolbox_image_name)
|
||
if ! (
|
||
ret_val=$?
|
||
if [ "$ret_val" -ne 0 ] 2>&3; then
|
||
if [ "$ret_val" -eq 100 ] 2>&3; then
|
||
echo "$base_toolbox_command: failed to get the basename of base image $base_toolbox_image" >&2
|
||
else
|
||
echo "$base_toolbox_command: failed to create an ID for the customized user-specific image" >&2
|
||
fi
|
||
|
||
exit 1
|
||
fi
|
||
|
||
exit 0
|
||
); then
|
||
exit 1
|
||
fi
|
||
|
||
echo "$base_toolbox_command: customized user-specific image is $toolbox_image" >&3
|
||
|
||
[ "$toolbox_container" = "" ] && toolbox_container="$toolbox_image"
|
||
echo "$base_toolbox_command: container is $toolbox_container" >&3
|
||
}
|
||
|
||
|
||
usage()
|
||
{
|
||
echo "Usage: toolbox [-v | --verbose]"
|
||
echo " create [--candidate-registry]"
|
||
echo " [--container <name>]"
|
||
echo " [--image <name>]"
|
||
echo " [--release <release>]"
|
||
echo " or: toolbox [-v | --verbose]"
|
||
echo " enter [--container <name>]"
|
||
echo " [--release <release>]"
|
||
echo " or: toolbox [-v | --verbose]"
|
||
echo " list [-c | --containers]"
|
||
echo " [-i | --images]"
|
||
echo " or: toolbox rm [-a | --all]"
|
||
echo " [-f | --force] [<container> ...]"
|
||
echo " or: toolbox rmi [-a | --all]"
|
||
echo " [-f | --force] [<image> ...]"
|
||
echo " or: toolbox --help"
|
||
}
|
||
|
||
|
||
arguments=$(save_positional_parameters "$@")
|
||
|
||
release_default=$(get_host_version_id)
|
||
toolbox_container_prefix_default="fedora-toolbox-$USER"
|
||
toolbox_container_default="$toolbox_container_prefix_default:$release_default"
|
||
|
||
while has_prefix "$1" -; do
|
||
case $1 in
|
||
-h | --help )
|
||
usage
|
||
exit
|
||
;;
|
||
--sudo )
|
||
prefix_sudo="sudo"
|
||
;;
|
||
-v | --verbose )
|
||
exec 3>&2
|
||
verbose=true
|
||
;;
|
||
* )
|
||
exit_if_unrecognized_option "$1"
|
||
esac
|
||
shift
|
||
done
|
||
|
||
if [ -f /run/.containerenv ] 2>&3; then
|
||
if ! command -v flatpak-spawn >/dev/null 2>&3; then
|
||
echo "$base_toolbox_command: flatpak-spawn not found" >&2
|
||
exit 1
|
||
fi
|
||
|
||
echo "$base_toolbox_command: looking for podman PID" >&3
|
||
|
||
pid_i=$$
|
||
while [ "$pid_i" -gt 1 ] 2>&3; do
|
||
cmdline=$(sed "s/\x0/ /g" /proc/$pid_i/cmdline 2>&3)
|
||
if has_prefix "$cmdline" "podman exec "; then
|
||
podman_pid=$pid_i
|
||
break
|
||
fi
|
||
|
||
pid_i=$(ps -p $pid_i -o ppid= 2>&3 | sed "s/ //" 2>&3)
|
||
if ! is_integer "$pid_i"; then
|
||
echo "$base_toolbox_command: invalid parent PID" >&2
|
||
break
|
||
fi
|
||
done
|
||
|
||
if ! is_integer "$podman_pid"; then
|
||
echo "$base_toolbox_command: invalid podman PID" >&2
|
||
podman_pid=""
|
||
fi
|
||
|
||
if [ "$podman_pid" = "" ]; then
|
||
echo "$base_toolbox_command: cannot be used outside podman exec" >&2
|
||
exit 1
|
||
fi
|
||
|
||
echo "$base_toolbox_command: podman PID is $podman_pid" >&3
|
||
fi
|
||
|
||
if [ "$1" = "" ]; then
|
||
echo "$base_toolbox_command: missing command" >&2
|
||
echo >&2
|
||
echo "These are some common commands:" >&2
|
||
echo "create Create a new toolbox container" >&2
|
||
echo "enter Enter an existing toolbox container" >&2
|
||
echo "list List all existing toolbox containers and images" >&2
|
||
echo >&2
|
||
echo "Try '$base_toolbox_command --help' for more information." >&2
|
||
exit 1
|
||
fi
|
||
|
||
op=$1
|
||
shift
|
||
|
||
case $op in
|
||
create )
|
||
if is_integer "$podman_pid"; then
|
||
# shellcheck disable=SC2119
|
||
forward_to_host
|
||
else
|
||
while has_prefix "$1" -; do
|
||
case $1 in
|
||
--candidate-registry )
|
||
registry=$registry_candidate
|
||
;;
|
||
--container )
|
||
shift
|
||
exit_if_missing_argument --container "$1"
|
||
toolbox_container=$1
|
||
;;
|
||
--image )
|
||
shift
|
||
exit_if_missing_argument --image "$1"
|
||
base_toolbox_image=$1
|
||
;;
|
||
--release )
|
||
shift
|
||
exit_if_missing_argument --release "$1"
|
||
arg=$(echo "$1" | sed "s/^F\|^f//" 2>&3)
|
||
exit_if_non_positive_argument --release "$arg"
|
||
release=$arg
|
||
;;
|
||
* )
|
||
exit_if_unrecognized_option "$1"
|
||
esac
|
||
shift
|
||
done
|
||
exit_if_extra_operand "$1"
|
||
update_container_and_image_names
|
||
create
|
||
fi
|
||
exit
|
||
;;
|
||
enter )
|
||
if is_integer "$podman_pid"; then
|
||
# shellcheck disable=SC2119
|
||
forward_to_host
|
||
else
|
||
while has_prefix "$1" -; do
|
||
case $1 in
|
||
--container )
|
||
shift
|
||
exit_if_missing_argument --container "$1"
|
||
toolbox_container=$1
|
||
;;
|
||
--release )
|
||
shift
|
||
exit_if_missing_argument --release "$1"
|
||
arg=$(echo "$1" | sed "s/^F\|^f//" 2>&3)
|
||
exit_if_non_positive_argument --release "$arg"
|
||
release=$arg
|
||
;;
|
||
* )
|
||
exit_if_unrecognized_option "$1"
|
||
esac
|
||
shift
|
||
done
|
||
exit_if_extra_operand "$1"
|
||
update_container_and_image_names
|
||
enter
|
||
fi
|
||
exit
|
||
;;
|
||
list )
|
||
if is_integer "$podman_pid"; then
|
||
# shellcheck disable=SC2119
|
||
forward_to_host
|
||
else
|
||
ls_images=false
|
||
ls_containers=false
|
||
while has_prefix "$1" -; do
|
||
case $1 in
|
||
-c | --containers )
|
||
ls_containers=true
|
||
;;
|
||
-i | --images )
|
||
ls_images=true
|
||
;;
|
||
* )
|
||
exit_if_unrecognized_option "$1"
|
||
esac
|
||
shift
|
||
done
|
||
exit_if_extra_operand "$1"
|
||
|
||
if ! $ls_containers && ! $ls_images; then
|
||
ls_containers=true
|
||
ls_images=true
|
||
fi
|
||
|
||
if $ls_images; then
|
||
if ! images=$(list_images); then
|
||
exit 1
|
||
fi
|
||
fi
|
||
|
||
if $ls_containers; then
|
||
if ! containers=$(list_containers); then
|
||
exit 1
|
||
fi
|
||
fi
|
||
|
||
$ls_images && [ "$images" != "" ] && echo "$images"
|
||
$ls_containers && [ "$containers" != "" ] && echo "$containers"
|
||
fi
|
||
exit
|
||
;;
|
||
rm | rmi )
|
||
if is_integer "$podman_pid"; then
|
||
# shellcheck disable=SC2119
|
||
forward_to_host
|
||
else
|
||
rm_all=false
|
||
rm_force=false
|
||
while has_prefix "$1" -; do
|
||
case $1 in
|
||
-a | --all )
|
||
rm_all=true
|
||
;;
|
||
-f | --force )
|
||
rm_force=true
|
||
;;
|
||
* )
|
||
exit_if_unrecognized_option "$1"
|
||
esac
|
||
shift
|
||
done
|
||
|
||
rm_ids=""
|
||
if $rm_all; then
|
||
exit_if_extra_operand "$1"
|
||
else
|
||
exit_if_missing_argument "$op" "$1"
|
||
while [ "$1" != "" ]; do
|
||
rm_ids="$rm_ids $1"
|
||
shift
|
||
done
|
||
fi
|
||
|
||
rm_ids=$(echo "$rm_ids" | sed "s/^ \+//" 2>&3)
|
||
|
||
if [ "$op" = "rm" ]; then
|
||
remove_containers "$rm_ids" "$rm_all" "$rm_force"
|
||
else
|
||
remove_images "$rm_ids" "$rm_all" "$rm_force"
|
||
fi
|
||
fi
|
||
exit
|
||
;;
|
||
* )
|
||
echo "$base_toolbox_command: unrecognized command '$op'" >&2
|
||
echo "Try '$base_toolbox_command --help' for more information." >&2
|
||
exit 1
|
||
esac
|