From c7f24abcb02eaddeb8e35278785b878cca3bdc68 Mon Sep 17 00:00:00 2001 From: Luca Di Maio Date: Mon, 25 Mar 2024 19:51:37 +0100 Subject: [PATCH] all: improve functions' documentation Signed-off-by: Luca Di Maio --- distrobox-assemble | 21 ++++++++++++--- distrobox-create | 54 ++++++++++++++++++++++++++++--------- distrobox-enter | 64 ++++++++++++++++++++++++++++++++++++------- distrobox-ephemeral | 9 +++++-- distrobox-export | 66 ++++++++++++++++++++++++++++++++++----------- 5 files changed, 171 insertions(+), 43 deletions(-) diff --git a/distrobox-assemble b/distrobox-assemble index e083d5d72d..eaa4336f69 100755 --- a/distrobox-assemble +++ b/distrobox-assemble @@ -71,9 +71,13 @@ if [ -n "${SUDO_USER}" ] || [ -n "${DOAS_USER}" ]; then exit 1 fi -# Print usage to stdout. +# show_help will print usage to stdout. # Arguments: # None +# Expected global variables: +# version: string distrobox version +# Expected env variables: +# None # Outputs: # print usage with examples. show_help() { @@ -196,7 +200,14 @@ fi # Create distrobox with parameters parsed from ini file. # Arguments: -# name of the distrobox. +# name = name of the distrobox. +# Expected global variables: +# boxname = string name of the target container +# tmpfile = string name of the tmpfile to read +# delete = bool delete container +# replace = bool replace container +# dryrun = bool dryrun (only print, no execute) +# verbose = bool verbose # Outputs: # execution of the proper distrobox-create command. run_distrobox() { @@ -220,7 +231,7 @@ run_distrobox() { # We're going to delete, not create! if [ "${delete}" -ne 0 ] || [ "${replace}" -ne 0 ]; then - printf " - Deleting %s... \n" "${name}" + printf " - Deleting %s...\n" "${name}" if [ "${dryrun}" -eq 0 ]; then # shellcheck disable=SC2086,2248 @@ -233,7 +244,7 @@ run_distrobox() { fi # We're going to create! - printf " - Creating %s... \n" "${name}" + printf " - Creating %s...\n" "${name}" # If distrobox already exist, and we have replace enabled, destroy the container # we have to recreate it. @@ -420,6 +431,8 @@ sanitize_variable() { # Parse input file and call distrobox-create accordingly # Arguments: # path of the manifest file to parse +# Expected global variables: +# tmpfile = string name of the tmpfile to read # Outputs: # None parse_file() { diff --git a/distrobox-create b/distrobox-create index d36c7c0c99..22ca61d885 100755 --- a/distrobox-create +++ b/distrobox-create @@ -228,6 +228,9 @@ EOF # Print list of compatible images to stdou, caching locally in a file. # Arguments: # None +# Expected global variables: +# app_cache_dir = cache dir to write to +# version = distrobox version # Outputs: # print usage with examples. show_compatibility() { @@ -540,12 +543,22 @@ if [ -n "${container_additional_volumes}" ]; then done fi +# Check that we have a complete distrobox installation or +# entrypoint and export will not work. +if [ -z "${distrobox_entrypoint_path}" ] || [ -z "${distrobox_export_path}" ]; then + printf >&2 "Error: no distrobox-init found in %s\n" "${PATH}" + exit 127 +fi + # Clone a container as a snapshot. # Arguments: # None +# Expected global variables: +# container_manager = string container manager to use +# container_clone = string container name to clone # Outputs: # prints the image name of the newly cloned container -clone_container() { +get_clone_image() { # We need to clone a container. # to do this we will commit the container and create a new tag. Then use it # as image for the new container. @@ -584,9 +597,32 @@ clone_container() { # Generate Podman or Docker command to execute. # Arguments: # None +# Expected global variables: +# container_manager = string container manager to use +# container_name = string container name +# container_image = string container image +# container_manager_additional_flags = string container manager additional flags to use +# container_hostname = string container hostname +# container_additional_packages = string additional packages +# container_pre_init_hook = string pre init hooks +# container_init_hook = string init hooks +# container_user_home = string user's home path +# container_user_name = string user's username +# container_user_uid = string user's UID +# container_user_gid = string user's GID +# container_home_prefix = string container's custom home prefix +# container_user_custom_home = string container's custom home path +# init = bool initful +# nvidia = bool nvidia integration +# rootful = bool rootful +# unshare_devsys = bool unshare devsys +# unshare_groups = bool unshare groups +# unshare_ipc = bool unshare ipc +# unshare_netns = bool unshare netns +# unshare_process = bool unshare proc # Outputs: # prints the podman, docker or lilipod command to create the distrobox container -generate_command() { +generate_create_command() { # Set the container hostname the same as the container name. result_command="${container_manager} create" # use the host's namespace for ipc, network, pid, ulimit @@ -854,19 +890,12 @@ generate_command() { printf "%s" "${result_command}" } -# Check that we have a complete distrobox installation or -# entrypoint and export will not work. -if [ -z "${distrobox_entrypoint_path}" ] || [ -z "${distrobox_export_path}" ]; then - printf >&2 "Error: no distrobox-init found in %s\n" "${PATH}" - exit 127 -fi - # dry run mode, just generate the command and print it. No creation. if [ "${dryrun}" -ne 0 ]; then if [ -n "${container_clone}" ]; then container_image="${container_clone}" fi - cmd="$(generate_command)" + cmd="$(generate_create_command)" cmd="$(echo "${cmd}" | sed 's/\t//g')" printf "%s\n" "${cmd}" exit 0 @@ -890,8 +919,9 @@ fi # if we are using the clone flag, let's set the image variable # to the output of container duplication if [ -n "${container_clone}" ]; then - container_image="$(clone_container)" + container_image="$(get_clone_image)" fi + # First, check if the image exists in the host or auto-pull is enabled # If not prompt to download it. if [ "${container_always_pull}" -eq 1 ] || @@ -929,7 +959,7 @@ fi # Generate the create command and run it printf >&2 "Creating '%s' using image %s\t" "${container_name}" "${container_image}" -cmd="$(generate_command)" +cmd="$(generate_create_command)" # Eval the generated command. If successful display an helpful message. # shellcheck disable=SC2086 if eval ${cmd} > /dev/null; then diff --git a/distrobox-enter b/distrobox-enter index d54c096cdf..92018e2e00 100755 --- a/distrobox-enter +++ b/distrobox-enter @@ -23,9 +23,16 @@ # HOME # USER # Optional env variables: +# DBX_CONTAINER_ALWAYS_PULL +# DBX_CONTAINER_CUSTOM_HOME +# DBX_CONTAINER_GENERATE_ENTRY +# DBX_CONTAINER_HOME_PREFIX +# DBX_CONTAINER_HOSTNAME +# DBX_CONTAINER_IMAGE # DBX_CONTAINER_MANAGER # DBX_CONTAINER_NAME # DBX_CONTAINER_CLEAN_PATH +# DBX_NON_INTERACTIVE # DBX_SKIP_WORKDIR # DBX_SUDO_PROGRAM @@ -33,6 +40,19 @@ app_cache_dir=${XDG_CACHE_HOME:-"${HOME}/.cache"}/distrobox trap cleanup TERM INT HUP EXIT +# Generate Podman, Docker or Lilipod command to execute. +# Arguments: +# None +# Expected global variables: +# container_manager = string container manager to use +# container_name = string container name +# app_cache_dir = string cache dire to write file into +# logs_pid = string pid of the podman/docker logs process +# verbose = bool verbose +# Expected env variables: +# None +# Outputs: +# None cleanup() { rm -f "${app_cache_dir}/.${container_name}.fifo" if [ -n "${logs_pid:-}" ]; then @@ -132,6 +152,10 @@ fi # Print usage to stdout. # Arguments: # None +# Expected global variables: +# version = string distrobox version +# Expected env variables: +# USER # Outputs: # print usage with examples. show_help() { @@ -318,19 +342,37 @@ fi # Generate Podman, Docker or Lilipod command to execute. # Arguments: # None +# Expected global variables: +# container_manager = string container manager to use +# container_name = string container name +# container_manager_additional_flags = string container manager additional flags to use +# container_command = string container command to execute +# container_home = string container's home path +# container_path = string container's default PATH variable +# headless = bool headless mode +# skip_workdir = bool skip workdir +# verbose = bool verbose +# unshare_groups +# distrobox_enter_path +# Expected env variables: +# PATH +# USER +# PWD +# XDG_DATA_DIRS +# XDG_CONFIG_DIRS # Outputs: # prints the podman, docker or lilipod command to enter the distrobox container -generate_command() { +generate_enter_command() { result_command="${container_manager} exec" result_command="${result_command} --interactive" result_command="${result_command} --detach-keys=\"\"" + # In case of initful systems or unshared groups, we don't enter directly + # as our user, but we instead enter as root, and then su $USER, in order + # to trigger a proper login if [ "${unshare_groups:-0}" -eq 1 ]; then - # In case of initful systems or unshared groups, we don't enter directly - # as our user, but we instead enter as root, and then su $USER, in order - # to trigger a proper login result_command="${result_command} --user='root'" @@ -342,6 +384,7 @@ generate_command() { fi container_command_login="${container_command_login} -c \"\\\$(getent passwd ${USER} | cut -f 7 -d :) -l\"" if [ -n "${container_command}" ]; then + # escape $ in order to avoid evaluation by the login shell container_command="$(echo "${container_command}" | sed 's/\$/\\\$/g')" container_command="${container_command_login} -c \"${container_command}\"" fi @@ -384,6 +427,7 @@ generate_command() { --env \"CONTAINER_ID=${container_name}\"" result_command="${result_command} --env \"DISTROBOX_ENTER_PATH=${distrobox_enter_path}\"" + # Loop through all the environment vars # and export them to the container. set +o xtrace @@ -437,7 +481,7 @@ generate_command() { # Ensure the standard FHS program paths are in XDG_DATA_DIRS environment standard_paths="/usr/local/share /usr/share" - container_paths="${XDG_DATA_DIRS:=}" + container_paths="${XDG_DATA_DIRS:-}" # add to the XDG_DATA_DIRS only after the host's paths, and only if not already present. for standard_path in ${standard_paths}; do pattern="(:|^)${standard_path}(:|$)" @@ -461,7 +505,7 @@ generate_command() { # Ensure the standard FHS program paths are in XDG_CONFIG_DIRS environment standard_paths="/etc/xdg" - container_paths="${XDG_CONFIG_DIRS:=}" + container_paths="${XDG_CONFIG_DIRS:-}" # add to the XDG_CONFIG_DIRS only after the host's paths, and only if not already present. for standard_path in ${standard_paths}; do pattern="(:|^)${standard_path}(:|$)" @@ -516,8 +560,7 @@ eval "$(${container_manager} inspect --type container --format \ # dry run mode, just generate the command and print it. No execution. if [ "${dryrun}" -ne 0 ]; then - cmd="$(generate_command)" - cmd="$(echo "${cmd}" | sed 's/\t//g')" + cmd="$(generate_enter_command | sed 's/\t//g')" printf "%s\n" "${cmd}" exit 0 fi @@ -567,11 +610,12 @@ fi # If the container is not already running, we need to start if first if [ "${container_status}" != "running" ]; then # If container is not running, start it first + # # Here, we save the timestamp before launching the start command, so we can # be sure we're working with this very same session of logs later. - # log_timestamp="$(date +%FT%T.%N%:z)" ${container_manager} start "${container_name}" > /dev/null + # # Check if the container is going in error status earlier than the # entrypoint if [ "$(${container_manager} inspect \ @@ -633,6 +677,6 @@ if [ "${container_status}" != "running" ]; then fi # Generate the exec command and run it -cmd="$(generate_command)" +cmd="$(generate_enter_command)" # shellcheck disable=SC2086 eval ${cmd} diff --git a/distrobox-ephemeral b/distrobox-ephemeral index 0fa8092eaf..4989b7617c 100755 --- a/distrobox-ephemeral +++ b/distrobox-ephemeral @@ -173,9 +173,14 @@ fi # Generate distrobox-create command to execute. # Arguments: # None +# Expected global variables: +# distrobox_path = string distrobox path +# name = string container name +# extra_flags = string extra flags to inject +# create_flags = string create extra flags to inject # Outputs: # prints the distrobox-create command handling special flags -generate_command() { +generate_ephemeral_create_command() { result_command="${distrobox_path}/distrobox-create" if [ -n "${container_manager_additional_flags}" ]; then result_command="${result_command} \ @@ -206,7 +211,7 @@ cleanup() { "${distrobox_path}"/distrobox-rm ${extra_flags} --force "${name}" --yes } -cmd="$(generate_command)" +cmd="$(generate_ephemeral_create_command)" # shellcheck disable=SC2086 eval ${cmd} # shellcheck disable=SC2086 diff --git a/distrobox-export b/distrobox-export index 5c78679bbc..f047a9ffea 100755 --- a/distrobox-export +++ b/distrobox-export @@ -63,9 +63,13 @@ for dep in ${base_dependencies}; do fi done -# Print usage to stdout. +# show_help will print usage to stdout. # Arguments: # None +# Expected global variables: +# version: string distrobox version +# Expected env variables: +# None # Outputs: # print usage with examples. show_help() { @@ -253,20 +257,6 @@ if [ -z "${container_name}" ]; then container_name=$(uname -n | cut -d'.' -f1) fi -# Command to execute -container_command_suffix="'${exported_bin}' ${extra_flags} \"\$@\"" - -# Check if exported application/binary should be run with sudo privileges -if [ "${is_sudo}" -ne 0 ]; then - sudo_prefix="sudo -S" - - # Edge case for systems without sudo - if command -v su-exec > /dev/null >&1; then - sudo_prefix="su-exec root" - container_command_suffix="sh -l -c \"'${exported_bin}' ${extra_flags} \$*\"" - fi -fi - # Filter enter_flags and remove redundant options if [ -n "${enter_flags}" ]; then # shellcheck disable=SC2086 @@ -291,6 +281,20 @@ if [ -n "${enter_flags}" ]; then enter_flags="${filtered_flags}" fi +# Command to execute +container_command_suffix="'${exported_bin}' ${extra_flags} \"\$@\"" + +# Check if exported application/binary should be run with sudo privileges +if [ "${is_sudo}" -ne 0 ]; then + sudo_prefix="sudo -S" + + # Edge case for systems without sudo + if command -v su-exec > /dev/null >&1; then + sudo_prefix="su-exec root" + container_command_suffix="sh -l -c \"'${exported_bin}' ${extra_flags} \$*\"" + fi +fi + # Prefix to add to an existing command to work through the container container_command_prefix="${DISTROBOX_ENTER_PATH:-"distrobox-enter"} ${rootful} -n ${container_name} ${enter_flags} -- ${sudo_prefix} " @@ -310,6 +314,17 @@ fi # Print generated script from template # Arguments: # none it will use the ones set up globally +# Expected env variables: +# CONTAINER_ID = id of the current container +# container_command_suffix = string to postpone to the command to launch +# container_name = string name of this container +# dest_path = string path where to export the binary +# enter_flags = string extra flags to append to the distrobox enter command +# exported_bin = string path to the binary to exprot +# exported_delete = bool delete the binary exported +# extra_flags = string extra flags to append to the exported app command +# rootful = bool if this is a rootful container +# sudo_prefix = string sudo command to prepend to the exported command # Outputs: # print generated script. generate_script() { @@ -334,6 +349,12 @@ EOF # # Arguments: # none it will use the ones set up globally +# Expected env variables: +# CONTAINER_ID = id of the current container +# container_name = string name of this container +# dest_path = string path where to export the binary +# exported_bin = string path to the binary to exprot +# exported_delete = bool delete the binary exported # Outputs: # a generated_script in dest_path # or error code. @@ -386,6 +407,15 @@ export_binary() { # # Arguments: # none it will use the ones set up globally +# Expected env variables: +# CONTAINER_ID = id of the current container +# container_command_prefix = string to prepend to the command to launch +# container_name = string name of this container +# exported_app = string name of the app to export +# exported_app_label = string label to use to mark the exported app +# exported_delete = bool if we want to delete or not +# extra_flags = string extra flags to append to the exported app command +# host_home = home path ofr the host, where to search desktop files # Outputs: # needed icons in /run/host/$host_home/.local/share/icons # needed desktop files in /run/host/$host_home/.local/share/applications @@ -572,6 +602,9 @@ export_application() { # # Arguments: # none +# Expected env variables: +# host_home = home path ofr the host, where to search desktop files +# CONTAINER_ID = id of the current container # Outputs: # a list of exported apps # or error code. @@ -604,6 +637,9 @@ list_exported_applications() { # # Arguments: # none +# Expected env variables: +# dest_path = destination path where to search binaries +# CONTAINER_ID = id of the current container # Outputs: # a list of exported apps # or error code.