Skip to content

Commit

Permalink
support environment variables to change defaults (#207)
Browse files Browse the repository at this point in the history
* support environment variables to change defaults
* CI: test both podman and docker using new ENV variable

Implement use of environment variables to change defaults like:

 - container manager
 - default image to use
 - default name to use
 - interactivity

Variables will be respectively:

- DBX_CONTAINER_MANAGER
- DBX_CONTAINER_IMAGE
- DBX_CONTAINER_NAME
- DBX_NON_INTERACTIVE

This work opens also support for configuration rc-style files, in order of 
importance:

- /usr/share/distrobox/distrobox.conf
- /etc/distrobox/distrobox.conf
- ${HOME}/.config/distrobox/distrobox.conf
- ${HOME}/.distroboxrc
  • Loading branch information
89luca89 authored Mar 20, 2022
1 parent 0bbfcf6 commit 7203563
Show file tree
Hide file tree
Showing 8 changed files with 342 additions and 125 deletions.
19 changes: 14 additions & 5 deletions .github/workflows/compatibility.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,74 +44,83 @@ jobs:
max-parallel: 8
matrix:
distribution: ${{fromJSON(needs.setup.outputs.targets)}}
container_manager: ["podman", "docker"]
env:
DBX_CONTAINER_MANAGER: ${{ matrix.container_manager }}

steps:
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
- uses: actions/checkout@v2

# Ensure distrobox create works:
- name: Distrobox create
shell: 'script -q -e -c "bash {0}"'
run: |
image=${{ matrix.distribution }}
container_name="$(basename "${image}" | sed -E 's/[:.]/-/g')"
./distrobox create --yes -i "${image}" --name "${container_name}"
# Ensure distrobox enter and init works:
- name: Distrobox enter - init
shell: 'script -q -e -c "bash {0}"'
run: |
image=${{ matrix.distribution }}
container_name="$(basename "${image}" | sed -E 's/[:.]/-/g')"
./distrobox enter --name "${container_name}" -- whoami
# Ensure distrobox enter and init works:
- name: Distrobox enter - user
shell: 'script -q -e -c "bash {0}"'
run: |
image=${{ matrix.distribution }}
container_name="$(basename "${image}" | sed -E 's/[:.]/-/g')"
# Assert that distrobox exported binary indeed works
set -x
command_output="$(./distrobox enter --name "${container_name}" -- whoami | tr -d '\r')"
command_output="$(./distrobox enter --name "${container_name}" -- whoami | tr -d '\r' | tr -d '^@')"
expected_output="$(whoami)"
if [ "$command_output" != "$expected_output" ]; then
exit 1
fi
# Ensure distrobox enter and init works:
- name: Distrobox enter - command
shell: 'script -q -e -c "bash {0}"'
run: |
image=${{ matrix.distribution }}
container_name="$(basename "${image}" | sed -E 's/[:.]/-/g')"
# Assert that distrobox exported binary indeed works
set -x
command_output="$(./distrobox enter --name "${container_name}" -- uname -n | tr -d '\r')"
command_output="$(./distrobox enter --name "${container_name}" -- uname -n | tr -d '\r' | tr -d '^@')"
expected_output="${container_name}.$(uname -n)"
if [ "$command_output" != "$expected_output" ]; then
exit 1
fi
# Ensure distrobox export works:
- name: Distrobox export
shell: 'script -q -e -c "bash {0}"'
run: |
image=${{ matrix.distribution }}
container_name="$(basename "${image}" | sed -E 's/[:.]/-/g')"
./distrobox enter "${container_name}" -- distrobox-export --bin /bin/uname --export-path /tmp/
# Assert that distrobox exported binary indeed works
set -x
command_output="$(/tmp/uname -n | tr -d '\r')"
command_output="$(/tmp/uname -n | tr -d '\r' | tr -d '^@')"
expected_output="${container_name}.$(uname -n)"
if [ "$command_output" != "$expected_output" ]; then
exit 1
fi
# Ensure distrobox export works:
- name: Distrobox export - sudo
shell: 'script -q -e -c "bash {0}"'
run: |
image=${{ matrix.distribution }}
container_name="$(basename "${image}" | sed -E 's/[:.]/-/g')"
./distrobox enter "${container_name}" -- distrobox-export --sudo --bin /bin/uname --export-path /tmp/
# Assert that distrobox exported binary indeed works
set -x
command_output="$(/tmp/uname -n | tr -d '\r')"
command_output="$(/tmp/uname -n | tr -d '\r' | tr -d '^@')"
expected_output="${container_name}.$(uname -n)"
if [ "$command_output" != "$expected_output" ]; then
exit 1
Expand All @@ -122,7 +131,7 @@ jobs:
run: |
image=${{ matrix.distribution }}
container_name="$(basename "${image}" | sed -E 's/[:.]/-/g')"
./distrobox list | grep "${container_name}" | grep "${image}" | grep Up
./distrobox list | grep "${container_name}" | grep "${image}" | grep -E "Up|running"
# Ensure distrobox stop works:
- name: Distrobox stop
Expand Down
76 changes: 58 additions & 18 deletions distrobox-create
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@
# HOME
# USER
# Optional env variables:
# DBX_CONTAINER_CUSTOM_HOME
# DBX_CONTAINER_IMAGE
# DBX_CONTAINER_MANAGER
# DBX_CONTAINER_NAME
# DBX_NON_INTERACTIVE

Expand All @@ -41,16 +43,18 @@ fi

# Defaults
container_clone=""
container_image="${DBX_CONTAINER_IMAGE:-""}"
container_image=""
container_image_default="registry.fedoraproject.org/fedora-toolbox:35"
container_init_hook=""
container_manager="autodetect"
container_manager_additional_flags=""
container_name="${DBX_CONTAINER_NAME:-""}"
container_name=""
container_user_custom_home=""
container_user_gid="$(id -rg)"
container_user_home="${HOME:-"/"}"
container_user_name="${USER}"
container_user_uid="$(id -ru)"
non_interactive=0
# Use cd + dirname + pwd so that we do not have relative paths in mount points
# We're not using "realpath" here so that symlinks are not resolved this way
# "realpath" would break situations like Nix or similar symlink based package
Expand All @@ -61,12 +65,30 @@ distrobox_export_path="$(cd "$(dirname "${0}")" && pwd)/distrobox-export"
# in PATH for them.
[ ! -e "${distrobox_entrypoint_path}" ] && distrobox_entrypoint_path="$(command -v distrobox-init)"
[ ! -e "${distrobox_export_path}" ] && distrobox_export_path="$(command -v distrobox-export)"
non_interactive="${DBX_NON_INTERACTIVE:-0}"
dryrun=0
init=0
verbose=0
version="1.2.14"

# Source configuration files, this is done in an hierarchy so local files have
# priority over system defaults
# leave priority to environment variables.
config_files="
/usr/share/distrobox/distrobox.conf
/etc/distrobox/distrobox.conf
${HOME}/.config/distrobox/distrobox.conf
${HOME}/.distroboxrc
"
for config_file in ${config_files}; do
# shellcheck disable=SC1090
[ -e "${config_file}" ] && . "${config_file}"
done
[ -n "${DBX_CONTAINER_CUSTOM_HOME}" ] && container_user_custom_home="${DBX_CONTAINER_CUSTOM_HOME}"
[ -n "${DBX_CONTAINER_IMAGE}" ] && container_image="${DBX_CONTAINER_IMAGE}"
[ -n "${DBX_CONTAINER_MANAGER}" ] && container_manager="${DBX_CONTAINER_MANAGER}"
[ -n "${DBX_CONTAINER_NAME}" ] && container_name="${DBX_CONTAINER_NAME}"
[ -n "${DBX_NON_INTERACTIVE}" ] && non_interactive="${DBX_NON_INTERACTIVE}"

# Print usage to stdout.
# Arguments:
# None
Expand Down Expand Up @@ -199,7 +221,7 @@ while :; do
*) # Default case: If no more options then break out of the loop.
# If we have a flagless option and container_name is not specified
# then let's accept argument as container_name
if [ -z "${container_name}" ] && [ -n "$1" ]; then
if [ -n "$1" ]; then
container_name="$1"
shift
else
Expand Down Expand Up @@ -242,22 +264,40 @@ fi

# We depend on a container manager let's be sure we have it
# First we use podman, else docker
container_manager="podman"
case "${container_manager}" in
autodetect)
if command -v podman >/dev/null; then
container_manager="podman"
elif command -v docker >/dev/null; then
container_manager="docker"
else
container_manager="not_found"
fi
;;
podman)
container_manager="podman"
;;
docker)
container_manager="docker"
;;
*)
printf >&2 "Invalid input %s.\n" "${container_manager}"
printf >&2 "The available choices are: 'autodetect', 'podman', 'docker'\n"
container_manager="not_found"
;;
esac

# Be sure we have a container manager to work with.
if ! command -v "${container_manager}" >/dev/null; then
# If no podman, try docker.
container_manager="docker"
if ! command -v docker >/dev/null; then
# Error: we need at least one between docker or podman.
printf >&2 "Missing dependency: we need a container manager.\n"
printf >&2 "Please install one of podman or docker.\n"
printf >&2 "You can follow the documentation on:\n"
printf >&2 "\tman distrobox-compatibility\n"
printf >&2 "or:\n"
printf >&2 "\thttps://github.com/89luca89/distrobox/blob/main/docs/compatibility.md\n"
if [ "${dryrun}" -eq 0 ]; then
exit 127
fi
# Error: we need at least one between docker or podman.
printf >&2 "Missing dependency: we need a container manager.\n"
printf >&2 "Please install one of podman or docker.\n"
printf >&2 "You can follow the documentation on:\n"
printf >&2 "\tman distrobox-compatibility\n"
printf >&2 "or:\n"
printf >&2 "\thttps://github.com/89luca89/distrobox/blob/main/docs/compatibility.md\n"
if [ "${dryrun}" -eq 0 ]; then
exit 127
fi
fi
# add verbose if -v is specified
Expand Down
74 changes: 53 additions & 21 deletions distrobox-enter
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
# SHELL
# Optional env variables:
# DBX_CONTAINER_NAME
# DBX_CONTAINER_MANAGER

trap '[ "$?" -ne 0 ] && printf "\nAn error occurred\n"' EXIT

Expand All @@ -40,13 +41,14 @@ fi

# Defaults
container_command="${SHELL:-"bash"}"
container_manager="autodetect"
container_name="fedora-toolbox-35"
# Work around for shells that are not in the container's file system, nor PATH.
# For example in hosts that do not follow FHS, like NixOS or for shells in custom
# exotic paths.
container_command="$(basename "${container_command}") -l"
container_manager_additional_flags=""
container_name="${DBX_CONTAINER_NAME:-""}"
container_name_default="fedora-toolbox-35"

# Use cd + dirname + pwd so that we do not have relative paths in mount points
# We're not using "realpath" here so that symlinks are not resolved this way
# "realpath" would break situations like Nix or similar symlink based package
Expand All @@ -57,6 +59,22 @@ headless=0
verbose=0
version="1.2.14"

# Source configuration files, this is done in an hierarchy so local files have
# priority over system defaults
# leave priority to environment variables.
config_files="
/usr/share/distrobox/distrobox.conf
/etc/distrobox/distrobox.conf
${HOME}/.config/distrobox/distrobox.conf
${HOME}/.distroboxrc
"
for config_file in ${config_files}; do
# shellcheck disable=SC1090
[ -e "${config_file}" ] && . "${config_file}"
done
[ -n "${DBX_CONTAINER_MANAGER}" ] && container_manager="${DBX_CONTAINER_MANAGER}"
[ -n "${DBX_CONTAINER_NAME}" ] && container_name="${DBX_CONTAINER_NAME}"

# Print usage to stdout.
# Arguments:
# None
Expand Down Expand Up @@ -133,7 +151,7 @@ while :; do
*) # Default case: If no more options then break out of the loop.
# If we have a flagless option and container_name is not specified
# then let's accept argument as container_name
if [ -z "${container_name}" ] && [ -n "$1" ]; then
if [ -n "$1" ]; then
container_name="$1"
shift
else
Expand All @@ -152,22 +170,40 @@ fi

# We depend on a container manager let's be sure we have it
# First we use podman, else docker
container_manager="podman"
case "${container_manager}" in
autodetect)
if command -v podman >/dev/null; then
container_manager="podman"
elif command -v docker >/dev/null; then
container_manager="docker"
else
container_manager="not_found"
fi
;;
podman)
container_manager="podman"
;;
docker)
container_manager="docker"
;;
*)
printf >&2 "Invalid input %s.\n" "${container_manager}"
printf >&2 "The available choices are: 'autodetect', 'podman', 'docker'\n"
container_manager="not_found"
;;
esac

# Be sure we have a container manager to work with.
if ! command -v "${container_manager}" >/dev/null; then
# If no podman, try docker.
container_manager="docker"
if ! command -v docker >/dev/null; then
# Error: we need at least one between docker or podman.
printf >&2 "Missing dependency: we need a container manager.\n"
printf >&2 "Please install one of podman or docker.\n"
printf >&2 "You can follow the documentation on:\n"
printf >&2 "\tman distrobox-compatibility\n"
printf >&2 "or:\n"
printf >&2 "\thttps://github.com/89luca89/distrobox/blob/main/docs/compatibility.md\n"
if [ "${dryrun}" -eq 0 ]; then
exit 127
fi
# Error: we need at least one between docker or podman.
printf >&2 "Missing dependency: we need a container manager.\n"
printf >&2 "Please install one of podman or docker.\n"
printf >&2 "You can follow the documentation on:\n"
printf >&2 "\tman distrobox-compatibility\n"
printf >&2 "or:\n"
printf >&2 "\thttps://github.com/89luca89/distrobox/blob/main/docs/compatibility.md\n"
if [ "${dryrun}" -eq 0 ]; then
exit 127
fi
fi
# Small performance optimization, using podman socket shaves
Expand All @@ -188,10 +224,6 @@ fi
if [ "${verbose}" -ne 0 ]; then
container_manager="${container_manager} --log-level debug"
fi
# Set default container_name if no one is specified.
if [ -z "${container_name}" ]; then
container_name="${container_name_default}"
fi

# Generate Podman or Docker command to execute.
# Arguments:
Expand Down
1 change: 0 additions & 1 deletion distrobox-init
Original file line number Diff line number Diff line change
Expand Up @@ -512,7 +512,6 @@ if ! grep -q "^${container_user_name}:" /etc/passwd; then
if ! useradd \
--home-dir "${container_user_home}" \
--no-create-home \
--badname \
--shell "${SHELL:-"/bin/bash"}" \
--uid "${container_user_uid}" \
--gid "${container_user_gid}" \
Expand Down
Loading

0 comments on commit 7203563

Please sign in to comment.