From d626559baaa4e6ccb35b3bb0befc9d46b7aa837e Mon Sep 17 00:00:00 2001 From: Luca Di Maio Date: Wed, 1 May 2024 12:38:40 +0200 Subject: [PATCH] init, create: use $CONTAINER_ID to distinguish container's prompts. Use host's hostname by default. This will fix issues with apps not matching StartupWMClass, and other pesky bugs. Fix #62 Fix #728 Fix #994 Fix #1306 Signed-off-by: Luca Di Maio --- distrobox-create | 17 ++++++++++++++--- distrobox-init | 32 +++++++++++++++++++++++++------- 2 files changed, 39 insertions(+), 10 deletions(-) diff --git a/distrobox-create b/distrobox-create index 9567488415..2906ec318b 100755 --- a/distrobox-create +++ b/distrobox-create @@ -181,7 +181,7 @@ Options: --image/-i: image to use for the container default: ${container_image_default} --name/-n: name for the distrobox default: ${container_name_default} - --hostname: hostname for the distrobox default: .$(uname -n) + --hostname: hostname for the distrobox default: $(uname -n) --pull/-p: pull the image even if it exists locally (implies --yes) --yes/-Y: non-interactive, pull images without asking --root/-r: launch podman/docker/lilipod with root privileges. Note that if you need root this is the preferred @@ -466,7 +466,11 @@ fi # set the container hostname to default value if [ -z "${container_hostname}" ]; then - container_hostname="${container_name}.$(uname -n)" + container_hostname="$(uname -n)" + + if [ "${unshare_netns}" -eq 1 ]; then + container_hostname="${container_name}.${container_hostname}" + fi fi # check if container hostname is less than 64 chars to prevent issues @@ -666,7 +670,7 @@ generate_create_command() { --env \"HOME=${container_user_home}\" --env \"container=${container_manager}\" --env \"TERMINFO_DIRS=/usr/share/terminfo:/run/host/usr/share/terminfo\" - --volume /:/run/host:rslave + --env \"CONTAINER_ID=${container_name}\" --volume /tmp:/tmp:rslave --volume \"${distrobox_entrypoint_path}\":/usr/bin/entrypoint:ro --volume \"${distrobox_export_path}\":/usr/bin/distrobox-export:ro @@ -863,6 +867,13 @@ generate_create_command() { /etc/hosts /etc/resolv.conf " + + # If container_hostname is custom, we skip mounting /etc/hostname, else + # we want to keep it in sync + if [ "${container_hostname}" = "$(uname -n)" ]; then + NET_FILES="${NET_FILES} /etc/hostname" + fi + for net_file in ${NET_FILES}; do if [ -e "${net_file}" ]; then result_command="${result_command} diff --git a/distrobox-init b/distrobox-init index b27b144f3f..debf7947cc 100755 --- a/distrobox-init +++ b/distrobox-init @@ -1767,9 +1767,18 @@ printf "distrobox: Setting up distrobox profile...\n" # This ensures compatibility with prompts and tools between toolbx and distrobox touch /run/.toolboxenv -# If we do not have profile files in the home, we should copy the -# skeleton files, if present. -# Ensure we copy only if the dotfile is not already present. +# Ensure we have some basic env variables and prompt as base. +rcfiles=" + /etc/profile + /etc/bash.bashrc + /etc/bashrc + /etc/zshrc +" +for rcfile in $rcfiles; do + if [ -e "${rcfile}" ] && ! grep -q distrobox_profile.sh "${rcfile}"; then + echo "[ -e /etc/profile.d/distrobox_profile.sh ] && . /etc/profile.d/distrobox_profile.sh" >> "${rcfile}" + fi +done mkdir -p /etc/profile.d cat << EOF > /etc/profile.d/distrobox_profile.sh test -z "\$USER" && export USER="\$(id -un 2> /dev/null)" @@ -1798,8 +1807,8 @@ fi # toolbx prompt: https://github.com/containers/toolbox/blob/main/profile.d/toolbox.sh#L47 # this will ensure greater compatibility between the two implementations if [ -f /run/.toolboxenv ]; then - [ "\${BASH_VERSION:-}" != "" ] && PS1="📦[\u@\h \W]\$ " - [ "\${ZSH_VERSION:-}" != "" ] && PS1="📦[%n@%m]%~%# " + [ "\${BASH_VERSION:-}" != "" ] && PS1="📦[\u@\$CONTAINER_ID \W]\$ " + [ "\${ZSH_VERSION:-}" != "" ] && PS1="📦[%n@\$CONTAINER_ID]%~%# " fi # This will ensure we have a first-shell password setup for an user if needed. @@ -2083,6 +2092,9 @@ touch /etc/passwd.done if [ -n "${DISTROBOX_HOST_HOME-}" ] && [ -d "/etc/skel" ]; then printf "distrobox: Setting up skel...\n" + # If we do not have profile files in the home, we should copy the + # skeleton files, if present. + # Ensure we copy only if the dotfile is not already present. skel_files="$(find /etc/skel/ -type f || :)" for skel_file in ${skel_files}; do base_file_name=$(basename "${skel_file}") @@ -2121,17 +2133,18 @@ if [ "${init}" -eq 0 ]; then printf "container_setup_done\n" # Keepalive loop HOST_WATCH=" + /etc/hostname /etc/hosts /etc/localtime /etc/resolv.conf " - id="$(hostname)" + id="${CONTAINER_ID:-}" if [ -e /run/.containerenv ]; then # shellcheck disable=SC1091,SC2034 . /run/.containerenv elif [ -e /.dockerenv ]; then - id="$(curl -s --unix-socket /run/docker.sock http://docker/containers/"$(hostname | cut -d'.' -f1)"/json | + id="$(curl -s --unix-socket /run/docker.sock http://docker/containers/"${CONTAINER_ID:-$(hostname | cut -d'.' -f1)}"/json | grep -Eo '"Id":"[a-zA-Z0-9]{64}",' | cut -d '"' -f4)" fi @@ -2165,6 +2178,11 @@ if [ "${init}" -eq 0 ]; then # We only do this, if the file is actually different umount "${file_watch}" && mount_bind "${file_watch_src}" "${file_watch}" + + # Let's keep in sync host's hostname and container's hostname + if [ "${file_watch}" = "/etc/hostname" ]; then + hostname "$(cat /etc/hostname)" + fi fi fi fi