Feature/unify commands (#77)

* list: add functionality to list running or created distroboxes

* rm: add functionality remove created distroboxes

* main: add wrapper to use distrobox commands without hyphens #59

* main: improve argument handling, allow only commands designed to work on host

* install: fix to include plain distrobox command

* Update README to include new commands
This commit is contained in:
Luca Di Maio
2021-12-31 16:42:31 +01:00
committed by GitHub
parent 770f67a8ec
commit 4eb724ce38
6 changed files with 383 additions and 19 deletions
+39 -10
View File
@@ -28,6 +28,8 @@ graphical apps (X11/Wayland), and audio.
* [Outside the distrobox](#outside-the-distrobox)
+ [Create the distrobox](#create-the-distrobox)
+ [Enter the distrobox](#enter-the-distrobox)
+ [List containers](#list-containers)
+ [Remove containers](#remove-containers)
* [Inside the distrobox](#inside-the-distrobox)
+ [Application and service exporting](#application-and-service-exporting)
- [Init the distrobox](#init-the-distrobox)
@@ -55,13 +57,17 @@ It implements the same concepts introduced by https://github.com/containers/tool
All the props go to them as they had the great idea to implement this stuff.
It is divided into 4 parts:
It is divided into 6 commands:
- `distrobox-create` - creates the container
- `distrobox-enter` - to enter the container
- `distrobox-list` - to list containers created with distrobox
- `distrobox-rm` - to delete a container created with distrobox
- `distrobox-init` - it's the entrypoint of the container (not meant to be used manually)
- `distrobox-export` - it is meant to be used inside the container, useful to export apps and services from the container to the host
It also includes a little wrapper to launch commands with `distrobox COMMAND` instead of calling the single files.
## Why?
- Provide a mutable environment on an immutable OS, like Endless OS, Fedora Silverblue, OpenSUSE MicroOS or SteamOS3
@@ -249,6 +255,37 @@ Options:
This is used to enter the distrobox itself. Personally, I just create multiple profiles in my `gnome-terminal` to have multiple distros accessible.
### List containers
distrobox-list lists available distroboxes. It detects them and lists them separately
from the rest of normal podman or docker containers.
Usage:
distrobox-list
Options:
--help/-h: show this message
--verbose/-v: show more verbosity
--version/-V: show version
### Remove containers
distrobox-rm delete one of the available distroboxes.
Usage:
distrobox-rm --name container-name [--force]
Options:
--name/-n: name for the distrobox
--force/-f: force deletion
--help/-h: show this message
--verbose/-v: show more verbosity
--version/-V: show version
## Inside the distrobox
### Application and service exporting
@@ -391,7 +428,7 @@ or if you want to select a custom directory to install without sudo:
`curl -s https://raw.githubusercontent.com/89luca89/distrobox/main/install | sh -s -- -p ~/.local/bin`
Else you can clone the project using `git clone` or using the `download zip` voice after clicking the green button above.
Else you can clone the project using `git clone` or using the latest release [HERE](https://github.com/89luca89/distrobox/releases/latest).
Enter the directory and run `./install`, by default it will attempt to install in `/usr/local/bin`, you can specify another directory if needed with `./install -p ~/.local/bin`
@@ -462,14 +499,6 @@ in simple (and scriptable) steps.
`podman system df -v` or `docker system df -v`
- You can check running `distrobox` using:
`podman ps -a` or `docker ps -a`
- You can remove a `distrobox` using
`podman rm distrobox_name` or `docker rm distrobox_name`
## Using podman inside a distrobox
If `distrobox` is using `podman` as the container engine, you can use `podman socket` to
Executable
+68
View File
@@ -0,0 +1,68 @@
#!/bin/sh
# SPDX-License-Identifier: GPL-3.0-only
#
# This file is part of the distrobox project: https://github.com/89luca89/distrobox
#
# Copyright (C) 2021 distrobox contributors
#
# distrobox is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 3
# as published by the Free Software Foundation.
#
# distrobox is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with distrobox; if not, see <http://www.gnu.org/licenses/>.
# POSIX
set -o errexit
set -o nounset
# Print usage to stdout.
# Arguments:
# None
# Outputs:
# print usage with examples.
show_help() {
cat <<EOF
Choose one of the available commands
create
enter
list
rm
EOF
}
if [ $# -eq 0 ]; then
show_help
exit
fi
distrobox_path="$(dirname "${0}")"
distrobox_command="${1}"
shift
# Simple wrapper to the distrobox utilities.
# We just detect the 1st argument and launch the matching distrobox utility.
case "${distrobox_command}" in
create)
"${distrobox_path}"/distrobox-create "$@"
;;
enter)
"${distrobox_path}"/distrobox-enter "$@"
;;
list)
"${distrobox_path}"/distrobox-list "$@"
;;
rm)
"${distrobox_path}"/distrobox-rm "$@"
;;
*) # Default case: If no more options then break out of the loop.
printf >&2 "Error: invalid command\n"
show_help
exit 1
;;
esac
+2 -7
View File
@@ -251,12 +251,6 @@ generate_command() {
--security-opt label=disable
--user root:root"
# let's check if we can include distrobox-export or not
if [ -n "${distrobox_export_path}" ]; then
result_command="${result_command}
--volume ${distrobox_export_path}:/usr/bin/distrobox-export:ro"
fi
# Mount useful stuff inside the container.
# We also mount host's root filesystem to /run/host, to be able to syphon
# dynamic configurations from the host.
@@ -269,6 +263,7 @@ generate_command() {
--env HOME=${container_user_home}
--volume ${container_user_home}:${container_user_home}:rslave
--volume ${distrobox_entrypoint_path}:/usr/bin/entrypoint:ro
--volume ${distrobox_export_path}:/usr/bin/distrobox-export:ro
--volume /:/run/host:rslave
--volume /dev:/dev:rslave
--volume /sys:/sys:rslave
@@ -337,7 +332,7 @@ generate_command() {
# Check that we have a complete distrobox installation or
# entrypoint and export will not work.
if [ -z "${distrobox_entrypoint_path}" ]; then
if [ -z "${distrobox_entrypoint_path}" ] || [ -z "${distrobox_export_path}" ]; then
printf >&2 "Error: no distrobox-init found in %s\n" "${PATH}"
exit 127
fi
Executable
+127
View File
@@ -0,0 +1,127 @@
#!/bin/sh
# SPDX-License-Identifier: GPL-3.0-only
#
# This file is part of the distrobox project: https://github.com/89luca89/distrobox
#
# Copyright (C) 2021 distrobox contributors
#
# distrobox is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 3
# as published by the Free Software Foundation.
#
# distrobox is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with distrobox; if not, see <http://www.gnu.org/licenses/>.
# POSIX
# Defaults
verbose=0
version="1.2.6"
# Print usage to stdout.
# Arguments:
# None
# Outputs:
# print usage with examples.
show_help() {
cat <<EOF
distrobox version: ${version}
distrobox-list lists available distroboxes. It detects them and lists them separately
from the rest of normal podman or docker containers.
Usage:
distrobox-list
Options:
--help/-h: show this message
--verbose/-v: show more verbosity
--version/-V: show version
EOF
}
# Parse arguments
while :; do
case $1 in
-h | --help)
# Call a "show_help" function to display a synopsis, then exit.
show_help
exit 0
;;
-v | --verbose)
verbose=1
shift
;;
-V | --version)
printf "distrobox: %s\n" "${version}"
exit 0
;;
--) # End of all options.
shift
break
;;
*) # Default case: If no more options then break out of the loop.
break ;;
esac
done
set -o errexit
set -o nounset
# set verbosity
if [ "${verbose}" -ne 0 ]; then
set -o xtrace
fi
# We depend on a container manager let's be sure we have it
# First we use podman, else docker
container_manager="podman"
# Be sure we have a container manager to work with.
if ! command -v podman >/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"
exit 127
fi
fi
# add verbose if -v is specified
if [ "${verbose}" -ne 0 ]; then
container_manager="${container_manager} --log-level debug"
fi
# List containers using custom format that inclused MOUNTS
# we do this as we can detect the custom mounts done by distrobox to distringuish
# between a normal podman or docker container and a distrobox one.
container_list=$(${container_manager} ps -a --no-trunc --format "{{.ID}}|{{.Image}}|{{.Names}}|{{.State}}|{{.Mounts}}")
IFS='
'
# Header of the output
printf " %-12s | %-25s | %-30s | %-30s\n" "ID" "IMAGE" "STATUS" "NAME"
for container in ${container_list}; do
# Check if the current container has a custom mount point for distrobox.
if [ -z "${container##*/usr/bin/distrobox*}" ]; then
# Extract the information for the single container to pretty print it
container_id="$(echo "${container}" | cut -d'|' -f1 | cut -c1-12)"
container_name="$(echo "${container}" | cut -d'|' -f3)"
container_status="$(echo "${container}" | cut -d'|' -f4)"
container_image="$(echo "${container}" | cut -d'|' -f2)"
# If the container is Up and Running, print it in green
if [ -z "${container_status##*Up*}" ] || [ -z "${container_status##*running*}" ]; then
printf "\033[32m %-12s | %-25s | %-30s | %-30s\n\033[0m" "${container_id}" "${container_name}" "${container_status}" "${container_image}"
# Else, print it in yellow
else
printf "\033[33m %-12s | %-25s | %-30s | %-30s\n\033[0m" "${container_id}" "${container_name}" "${container_status}" "${container_image}"
fi
fi
done
Executable
+145
View File
@@ -0,0 +1,145 @@
#!/bin/sh
# SPDX-License-Identifier: GPL-3.0-only
#
# This file is part of the distrobox project: https://github.com/89luca89/distrobox
#
# Copyright (C) 2021 distrobox contributors
#
# distrobox is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 3
# as published by the Free Software Foundation.
#
# distrobox is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with distrobox; if not, see <http://www.gnu.org/licenses/>.
# POSIX
# Defaults
container_name="${DB_CONTAINER_NAME:-""}"
verbose=0
force=0
version="1.2.6"
# Print usage to stdout.
# Arguments:
# None
# Outputs:
# print usage with examples.
show_help() {
cat <<EOF
distrobox version: ${version}
distrobox-rm delete one of the available distroboxes.
Usage:
distrobox-rm --name container-name [--force]
Options:
--name/-n: name for the distrobox
--force/-f: force deletion
--help/-h: show this message
--verbose/-v: show more verbosity
--version/-V: show version
EOF
}
# Parse arguments
while :; do
case $1 in
-h | --help)
# Call a "show_help" function to display a synopsis, then exit.
show_help
exit 0
;;
-v | --verbose)
verbose=1
shift
;;
-V | --version)
printf "distrobox: %s\n" "${version}"
exit 0
;;
-f | --force)
force=1
shift
;;
-n | --name)
if [ -n "$2" ]; then
container_name="$2"
shift
shift
fi
;;
--) # End of all options.
shift
break
;;
*) # Default case: If no more options then break out of the loop.
break ;;
esac
done
# Ensure the foundamental variables are set and not empty, we will not proceed if
# they are not all set.
[ -z "${container_name}" ] && printf "Error: Invalid arguments, missing container name\n" && exit 2
set -o errexit
set -o nounset
# set verbosity
if [ "${verbose}" -ne 0 ]; then
set -o xtrace
fi
# We depend on a container manager let's be sure we have it
# First we use podman, else docker
container_manager="podman"
# Be sure we have a container manager to work with.
if ! command -v podman >/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"
exit 127
fi
fi
# add verbose if -v is specified
if [ "${verbose}" -ne 0 ]; then
container_manager="${container_manager} --log-level debug"
fi
# Inspect the container we're working with.
container_status="$(${container_manager} inspect --type container \
"${container_name}" --format '{{.State.Status}}')"
container_exists="$?"
# Does the container exists? check if inspect reported errors
if [ "${container_exists}" -gt 0 ]; then
# If not, prompt to create it first
printf >&2 "Cannot find container %s, does it exist?\n" "${container_name}"
exit 1
fi
# If the container is not already running, we need to start if first
if [ "${container_status}" = "running" ]; then
printf >&2 "Starting container %s\n" "${container_name}"
if ! ${container_manager} stop "${container_name}"; then
printf >&2 "Could not stop container %s\n" "${container_name}"
printf >&2 "Please stop container %s before deletion\n" "${container_name}"
exit 1
fi
fi
container_delete_command="${container_manager} rm"
if [ "${force}" -ne 0 ]; then
container_delete_command="${container_delete_command} --force"
fi
${container_delete_command} "${container_name}"
+2 -2
View File
@@ -85,7 +85,7 @@ if [ -f "${curr_dir}/distrobox-enter" ]; then
if [ -d "${curr_dir}/.git" ] && command -v git >/dev/null; then
release_ver="git-$(git rev-parse HEAD)"
fi
for file in distrobox-*; do
for file in distrobox*; do
cp "${file}" "${dest_path}"
chmod 0755 "${dest_path}/${file}"
done
@@ -106,7 +106,7 @@ else
# uncompress
tar xvf "${release_name}"
# deploy our files
for file in "distrobox-$(echo "${release_name}" | sed 's/.tar.gz//g')"/distrobox-*; do
for file in "distrobox-$(echo "${release_name}" | sed 's/.tar.gz//g')"/distrobox*; do
cp "${file}" "${dest_path}"
chmod 0755 "${dest_path}/$(basename "${file}")"
done