Don't use a toolbox container until after it has been configured
It was possible to have 'podman exec' invoked against a toolbox container before the entry point had finished initializing it. This could lead to situations where '$USER' didn't yet exist inside the container when 'podman exec' attempted running a binary as that user, which would end up failing 'toolbox enter'. There are a number of corner cases that need to be kept in mind while implementing any kind of synchronization. First, older containers don't use 'toolbox init-container' as their entry point. This might mean that their start-up can't be synchronized but they should still be kept working in their current state. Second, once a container has been started, subsequent 'podman start' invocations are NOPs. They won't lead to newer instances of the entry point process being launched. Third, the entry point process can crash or get killed due to an out-of-band 'podman stop'. In such cases, 'toolbox enter' should not get confused or deadlocked. It should give a meaningful error message to the user. Fourth, it would be nice to not have to touch the 'create' command so that toolbox containers created with Toolbox 0.0.10 onwards can have their start-up synchronized. This means that the host can't add any new environment variable or bind mount to the container to agree upon a path that's keyed by the container's identity and shared with the host. Given all these considerations, a timed busy loop that looks for the presence of a stamp file, keyed by the entry point's PID, is the most robust solution that can be verified as correct. Anything involving file locks becomes increasingly complicated and hard to verify. Under normal circumstances, the loop isn't expected to last more than a few iterations. In case the entry point dies, the loop will time out after approximately 25 seconds, the same interval as the default for D-Bus method calls. Some changes by Debarshi Ray based on an idea from Jan Hlaváč. https://github.com/containers/toolbox/pull/305
This commit is contained in:
parent
08fa8f5440
commit
d3e0f3df06
1 changed files with 60 additions and 0 deletions
60
toolbox
60
toolbox
|
@ -1043,6 +1043,17 @@ init_container()
|
|||
init_container_uid="$5"
|
||||
init_container_user="$6"
|
||||
|
||||
if [ "$XDG_RUNTIME_DIR" = "" ] 2>&3; then
|
||||
echo "$base_toolbox_command: XDG_RUNTIME_DIR is unset" >&3
|
||||
|
||||
XDG_RUNTIME_DIR=/run/user/"$init_container_uid"
|
||||
echo "$base_toolbox_command: XDG_RUNTIME_DIR set to $XDG_RUNTIME_DIR" >&3
|
||||
|
||||
toolbox_runtime_directory="$XDG_RUNTIME_DIR"/toolbox
|
||||
fi
|
||||
|
||||
init_container_initialized_stamp="$toolbox_runtime_directory"/container-initialized-"$$"
|
||||
|
||||
echo "$base_toolbox_command: creating /run/.toolboxenv" >&3
|
||||
|
||||
if ! touch /run/.toolboxenv 2>&3; then
|
||||
|
@ -1187,6 +1198,13 @@ EOF
|
|||
fi
|
||||
fi
|
||||
|
||||
echo "$base_toolbox_command: finished initializing container" >&3
|
||||
|
||||
if ! touch "$init_container_initialized_stamp" 2>&3; then
|
||||
echo "$base_toolbox_command: failed to create initialization stamp" >&2
|
||||
return 1
|
||||
fi
|
||||
|
||||
echo "$base_toolbox_command: going to sleep" >&3
|
||||
|
||||
exec sleep +Inf
|
||||
|
@ -1320,6 +1338,48 @@ run()
|
|||
fi
|
||||
fi
|
||||
|
||||
echo "$base_toolbox_command: inspecting entry point of container $toolbox_container" >&3
|
||||
|
||||
if ! entry_point=$(podman inspect --format "{{index .Config.Cmd 0}}" --type container "$toolbox_container" 2>&3); then
|
||||
echo "$base_toolbox_command: failed to inspect entry point of container $toolbox_container" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "$base_toolbox_command: entry point of container $toolbox_container is $entry_point" >&3
|
||||
|
||||
if [ "$entry_point" = "toolbox" ] 2>&3; then
|
||||
echo "$base_toolbox_command: waiting for container $toolbox_container to finish initializing" >&3
|
||||
|
||||
if ! entry_point_pid=$(podman inspect --format "{{.State.Pid}}" --type container "$toolbox_container" 2>&3); then
|
||||
echo "$base_toolbox_command: failed to inspect entry point PID of container $toolbox_container" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! is_integer "$entry_point_pid"; then
|
||||
echo "$base_toolbox_command: failed to parse entry point PID of container $toolbox_container" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ "$entry_point_pid" -le 0 ] 2>&3; then
|
||||
echo "$base_toolbox_command: invalid entry point PID of container $toolbox_container" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
container_initialized_stamp="$toolbox_runtime_directory/container-initialized-$entry_point_pid"
|
||||
container_initialized_timeout=25 #s
|
||||
|
||||
i=0
|
||||
while ! [ -f "$container_initialized_stamp" ] 2>&3; do
|
||||
sleep 1 2>&3
|
||||
|
||||
i=$((i + 1))
|
||||
if [ "$i" -eq "$container_initialized_timeout" ] 2>&3; then
|
||||
echo "$base_toolbox_command: failed to initialize container $toolbox_container" >&2
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
if ! podman exec --user root:root "$toolbox_container" touch /run/.toolboxenv 2>&3; then
|
||||
echo "$base_toolbox_command: failed to create /run/.toolboxenv in container $toolbox_container" >&2
|
||||
exit 1
|
||||
|
|
Loading…
Reference in a new issue