Make it work inside the toolbox container itself
A truly seamless developer experience requires erasing the divide between the host and the toolbox container as much as possible. Currently, various tools don't work at all when used from inside the toolbox because they expect to be run on the host. eg., flatpak, podman, and the toolbox script itself. This puts a significant enough cognitive burden on the developer. At the very least, the human operator needs to keep track of the context in which those commands are being issued. To make things better, the toolbox script has been made aware of the context in which it is running. If it detects that it's running inside the toolbox container, denoted by a 'podman exec ...' parent process and the presence of /run/.containerenv, then it tries to forward its own invocation to the host over D-Bus using 'flatpak-spawn --host' [1]. This uses the HostCommand method on the org.freedesktop.Flatpak D-Bus service underneath to do the forwarding. The process offering the org.freedesktop.Flatpak service doesn't have some variables, like COLORTERM and TERM, set in its environment, and their absence hinders the use of interactive shells. This is addressed by tunneling the same set of environment variables that are also passed to podman. [1] http://docs.flatpak.org/en/latest/flatpak-command-reference.html#flatpak-spawn https://github.com/debarshiray/toolbox/pull/54
This commit is contained in:
parent
a09692aa8b
commit
5b3d234c9e
1 changed files with 137 additions and 74 deletions
211
toolbox
211
toolbox
|
@ -18,6 +18,7 @@
|
|||
|
||||
exec 42>/dev/null
|
||||
|
||||
arguments="$@"
|
||||
base_toolbox_command=$(basename "$0" 2>&42)
|
||||
base_toolbox_image=""
|
||||
environment_variables="COLORTERM \
|
||||
|
@ -43,6 +44,7 @@ fgc=""
|
|||
. /etc/os-release
|
||||
release=$VERSION_ID
|
||||
|
||||
podman_pid=""
|
||||
prefix_sudo=""
|
||||
registry="registry.fedoraproject.org"
|
||||
registry_candidate="candidate-registry.fedoraproject.org"
|
||||
|
@ -546,6 +548,19 @@ exit_if_unrecognized_option()
|
|||
}
|
||||
|
||||
|
||||
forward_to_host()
|
||||
(
|
||||
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: $0 $arguments" >&42
|
||||
flatpak-spawn $set_dbus_system_bus_address $set_environment --host "$0" $arguments 2>&42
|
||||
)
|
||||
|
||||
|
||||
update_container_and_image_names()
|
||||
{
|
||||
base_toolbox_image="fedora-toolbox:$release"
|
||||
|
@ -590,6 +605,42 @@ while has_prefix "$1" -; do
|
|||
shift
|
||||
done
|
||||
|
||||
if [ -f /run/.containerenv ] 2>&42; then
|
||||
if ! which flatpak-spawn >/dev/null 2>&42; then
|
||||
echo "$base_toolbox_command: flatpak-spawn not found"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "$base_toolbox_command: looking for podman PID" >&42
|
||||
|
||||
pid_i=$$
|
||||
while [ "$pid_i" -gt 1 ] 2>&42; do
|
||||
cmdline=$(cat /proc/$pid_i/cmdline 2>&42 | sed "s/\x0/ /g" 2>&42)
|
||||
if has_prefix "$cmdline" "podman exec "; then
|
||||
podman_pid=$pid_i
|
||||
break
|
||||
fi
|
||||
|
||||
pid_i=$(ps -p $pid_i -o ppid= 2>&42 | sed "s/ //" 2>&42)
|
||||
if ! is_integer "$pid_i"; then
|
||||
echo "$base_toolbox_command: invalid parent PID"
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
if ! is_integer "$podman_pid"; then
|
||||
echo "$base_toolbox_command: invalid podman PID"
|
||||
podman_pid=""
|
||||
fi
|
||||
|
||||
if [ "$podman_pid" = "" ]; then
|
||||
echo "$base_toolbox_command: cannot be used outside podman exec"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "$base_toolbox_command: podman PID is $podman_pid" >&42
|
||||
fi
|
||||
|
||||
if [ "$1" = "" ]; then
|
||||
echo "$base_toolbox_command: missing command"
|
||||
echo "Try '$base_toolbox_command --help' for more information."
|
||||
|
@ -601,88 +652,100 @@ shift
|
|||
|
||||
case $op in
|
||||
create )
|
||||
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"
|
||||
toolbox_image=$1
|
||||
;;
|
||||
--release )
|
||||
shift
|
||||
exit_if_missing_argument --release "$1"
|
||||
arg=$(echo $1 | sed "s/^F\|^f//" 2>&42)
|
||||
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
|
||||
if is_integer "$podman_pid"; then
|
||||
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"
|
||||
toolbox_image=$1
|
||||
;;
|
||||
--release )
|
||||
shift
|
||||
exit_if_missing_argument --release "$1"
|
||||
arg=$(echo $1 | sed "s/^F\|^f//" 2>&42)
|
||||
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 )
|
||||
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>&42)
|
||||
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
|
||||
if is_integer "$podman_pid"; then
|
||||
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>&42)
|
||||
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 )
|
||||
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 is_integer "$podman_pid"; then
|
||||
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
|
||||
if ! $ls_containers && ! $ls_images; then
|
||||
ls_containers=true
|
||||
ls_images=true
|
||||
fi
|
||||
|
||||
$ls_images && list_images
|
||||
$ls_containers && list_containers
|
||||
fi
|
||||
|
||||
$ls_images && list_images
|
||||
$ls_containers && list_containers
|
||||
exit
|
||||
;;
|
||||
* )
|
||||
|
|
Loading…
Reference in a new issue