mirror of
https://github.com/89luca89/distrobox.git
synced 2026-11-02 20:30:16 -06:00
chore(repo): make the go rewrite the root project (#60)
* chore(repo): remove shell implementation * chore(repo): remove bash completion for sub-commands There is no need for separate files as there will be no dedicated binary for sub-commands * chore(repo): remove zsh completion for sub-commands There is no need for separate files as there will be no dedicated binary for sub-commands * chore(repo): delete RFC We are not using RFC at the moment * chore(repo): move golang project to the root * chore(ci): move golang project to the root * chore(repo): use standard .gitignore for golang projects source: https://github.com/github/gitignore/blob/main/Go.gitignore * chore(ci): compatibility CI to handle a golang project * refactor(ci): run shell script checks against the inside-distrobox files * refactor(ci): merge ci.yml workflow into main.yml
This commit is contained in:
1 parent
2631fb48f5
commit
5a9649e6ee
88 files changed
+404
-4427
No files matched your search
@@ -38,7 +38,7 @@ jobs:
|
||||
# Fetch from compatibility table all the distros supported
|
||||
- id: check_file_changed
|
||||
run: |
|
||||
if git diff --name-only HEAD^ HEAD | grep -Ev "host-exec|generate-entry|ephemeral|upgrade" | grep -E "^distrobox|compatibility.md"; then
|
||||
if git diff --name-only HEAD^ HEAD | grep -E '\.go$|go\.mod|go\.sum|Makefile|docs/compatibility\.md|internal/inside-distrobox/assets/'; then
|
||||
echo "::set-output name=distrobox_changed::True"
|
||||
else
|
||||
echo "::set-output name=distrobox_changed::False"
|
||||
@@ -87,6 +87,16 @@ jobs:
|
||||
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
|
||||
- uses: actions/checkout@v6.0.2
|
||||
|
||||
- name: Setup Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version-file: go.mod
|
||||
|
||||
- name: Build distrobox binary
|
||||
run: |
|
||||
make build
|
||||
cp ./bin/distrobox ./distrobox
|
||||
|
||||
# Ensure distrobox create works:
|
||||
- name: Distrobox create
|
||||
shell: 'script -q -e -c "bash {0}"'
|
||||
|
||||
@@ -14,7 +14,50 @@ on:
|
||||
# Allows you to run this workflow manually from the Actions tab
|
||||
workflow_dispatch:
|
||||
|
||||
env:
|
||||
SHELL_SCRIPTS_DIR: internal/inside-distrobox/assets
|
||||
|
||||
jobs:
|
||||
test:
|
||||
name: Test
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@0c366fd6a839edf440554fa01a7085ccba70ac98 # v6.0.1
|
||||
- uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6.3.0
|
||||
with:
|
||||
go-version-file: "go.mod"
|
||||
- run: make
|
||||
|
||||
golangci:
|
||||
name: Golangci-lint
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@0c366fd6a839edf440554fa01a7085ccba70ac98 # v6.0.1
|
||||
- uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6.3.0
|
||||
with:
|
||||
go-version-file: "go.mod"
|
||||
- name: golangci-lint
|
||||
uses: golangci/golangci-lint-action@1e7e51e771db61008b38414a730f564565cf7c20 # v9.2.0
|
||||
with:
|
||||
version: v2.5.0
|
||||
|
||||
fmtcheck:
|
||||
name: Go fmt check
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@0c366fd6a839edf440554fa01a7085ccba70ac98 # v6.0.1
|
||||
- uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6.3.0
|
||||
with:
|
||||
go-version-file: "go.mod"
|
||||
- name: format check
|
||||
run: |
|
||||
make fmt
|
||||
if [ -n "$(git status --porcelain)" ]; then
|
||||
echo "Code is not formatted. Please run 'make fmt' and commit the changes."
|
||||
git --no-pager diff
|
||||
exit 1
|
||||
fi
|
||||
|
||||
dash:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
@@ -24,7 +67,7 @@ jobs:
|
||||
- name: Run dash -n
|
||||
run: |
|
||||
result=0
|
||||
for file in $(find . -type f -not -path "*.git*" -a -not -path "*completions*"); do
|
||||
for file in $(find ${SHELL_SCRIPTS_DIR} -type f); do
|
||||
if file "$file" | grep -qi shell; then
|
||||
echo "### Checking file $file..."
|
||||
dash -n $file
|
||||
@@ -43,7 +86,7 @@ jobs:
|
||||
run: |
|
||||
result=0
|
||||
podman pull docker.io/peterdavehello/shfmt:latest
|
||||
for file in $(find . -type f -not -path "*.git*"); do
|
||||
for file in $(find ${SHELL_SCRIPTS_DIR} -type f); do
|
||||
if file "$file" | grep -qi shell; then
|
||||
echo "### Checking file $file..."
|
||||
podman run --rm -v "$PWD:/mnt" docker.io/peterdavehello/shfmt:latest shfmt -d -s -ci -sr -kp -fn -i=0 -p /mnt/$file
|
||||
@@ -67,7 +110,7 @@ jobs:
|
||||
run: |
|
||||
result=0
|
||||
podman pull docker.io/koalaman/shellcheck:stable
|
||||
for file in $(find . -type f -name ".*" -prune -o -print | grep -v '.git'); do
|
||||
for file in $(find ${SHELL_SCRIPTS_DIR} -type f); do
|
||||
if file "$file" | grep -qi shell; then
|
||||
echo "### Checking file $file..."
|
||||
# Should read the .shellcheckrc file to behave like -s sh -a -o all -Sstyle -Calways -x -e SC2310,SC2311,SC2312
|
||||
@@ -93,6 +136,7 @@ jobs:
|
||||
uses: redhat-plumbers-in-action/differential-shellcheck@v5
|
||||
with:
|
||||
severity: style
|
||||
scan-directory: ${{ env.SHELL_SCRIPTS_DIR }}
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
bashate:
|
||||
@@ -108,7 +152,7 @@ jobs:
|
||||
- name: Run bashate
|
||||
run: |
|
||||
sudo pip3 install -U bashate
|
||||
for file in $(find . -type f -not -path "*.git*"); do
|
||||
for file in $(find ${SHELL_SCRIPTS_DIR} -type f); do
|
||||
if file "$file" | grep -qi shell; then
|
||||
echo "### Checking file $file..."
|
||||
bashate -i E002,E003,E010,E011 --max-line-length 120 $file
|
||||
@@ -137,6 +181,6 @@ jobs:
|
||||
run: |
|
||||
curl -L -O https://github.com/89luca89/shell-funcheck/releases/download/v0.0.1/shell-funcheck-amd64
|
||||
chmod +x ./shell-funcheck-amd64
|
||||
for i in distrobox*; do
|
||||
for i in ${SHELL_SCRIPTS_DIR}/*; do
|
||||
./shell-funcheck-amd64 check "$i"
|
||||
done
|
||||
@@ -1,55 +0,0 @@
|
||||
name: CI (golang)
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
pull_request:
|
||||
paths:
|
||||
- "rewrite/**"
|
||||
- ".github/workflows/rewrite-ci.yml"
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
test:
|
||||
name: Test
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@0c366fd6a839edf440554fa01a7085ccba70ac98 # v6.0.1
|
||||
- uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6.3.0
|
||||
with:
|
||||
go-version-file: "rewrite/go.mod"
|
||||
- run: make
|
||||
working-directory: rewrite
|
||||
|
||||
golangci:
|
||||
name: Golangci-lint
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@0c366fd6a839edf440554fa01a7085ccba70ac98 # v6.0.1
|
||||
- uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6.3.0
|
||||
with:
|
||||
go-version-file: "rewrite/go.mod"
|
||||
- name: golangci-lint
|
||||
uses: golangci/golangci-lint-action@1e7e51e771db61008b38414a730f564565cf7c20 # v9.2.0
|
||||
with:
|
||||
version: v2.5.0
|
||||
working-directory: rewrite
|
||||
|
||||
fmtcheck:
|
||||
name: Go fmt check
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@0c366fd6a839edf440554fa01a7085ccba70ac98 # v6.0.1
|
||||
- uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6.3.0
|
||||
with:
|
||||
go-version-file: "rewrite/go.mod"
|
||||
- name: format check
|
||||
working-directory: rewrite
|
||||
run: |
|
||||
make fmt
|
||||
if [ -n "$(git status --porcelain)" ]; then
|
||||
echo "Code is not formatted. Please run 'make fmt' and commit the changes."
|
||||
git --no-pager diff
|
||||
exit 1
|
||||
fi
|
||||
+28
@@ -1,3 +1,31 @@
|
||||
# Binaries for programs and plugins
|
||||
*.exe
|
||||
*.exe~
|
||||
*.dll
|
||||
*.so
|
||||
*.dylib
|
||||
bin/
|
||||
|
||||
# Test binary, built with `go test -c`
|
||||
*.test
|
||||
|
||||
# Code coverage profiles and other test artifacts
|
||||
*.out
|
||||
coverage.*
|
||||
*.coverprofile
|
||||
profile.cov
|
||||
|
||||
# Dependency directories (remove the comment below to include it)
|
||||
# vendor/
|
||||
|
||||
# Go workspace file
|
||||
go.work
|
||||
go.work.sum
|
||||
|
||||
# env file
|
||||
.env
|
||||
|
||||
# Editor/IDE
|
||||
tags
|
||||
*.vim
|
||||
TODO.txt
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -38,7 +38,7 @@ _generate_from_help() {
|
||||
fi
|
||||
|
||||
if [[ ${prev} == "--image" ]] || [[ ${prev} == "-i" ]]; then
|
||||
COMPREPLY+=($(compgen -W "$(distrobox-create --compatibility)" -- ${cur}))
|
||||
COMPREPLY+=($(compgen -W "$(distrobox create --compatibility)" -- ${cur}))
|
||||
return 0
|
||||
fi
|
||||
|
||||
@@ -50,7 +50,7 @@ _generate_from_help() {
|
||||
[[ ${command} != *"version"* ]] && [[ ${command} != *"help"* ]]; then
|
||||
while IFS= read -r line; do
|
||||
list+="$line "
|
||||
done < <(distrobox-list --no-color | tail -n+2 | cut -d'|' -f2)
|
||||
done < <(distrobox list --no-color | tail -n+2 | cut -d'|' -f2)
|
||||
COMPREPLY=($(compgen -W "${list}" "${cur}"))
|
||||
return 0
|
||||
fi
|
||||
@@ -62,7 +62,7 @@ __distrobox() {
|
||||
VALID_WORDS+=" --version --help"
|
||||
COMPREPLY=($(compgen -W "${VALID_WORDS}" -- "${COMP_WORDS[1]}"))
|
||||
elif [ "${#COMP_WORDS[@]}" -gt "2" ]; then
|
||||
_generate_from_help distrobox-"${COMP_WORDS[1]}"
|
||||
_generate_from_help distrobox "${COMP_WORDS[1]}"
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
# shellcheck disable=all
|
||||
|
||||
if [ -e /usr/share/bash-completion/completions/distrobox ]; then
|
||||
source /usr/share/bash-completion/completions/distrobox
|
||||
fi
|
||||
if [ -e /usr/local/share/bash-completion/completions/distrobox ]; then
|
||||
source /usr/local/share/bash-completion/completions/distrobox
|
||||
fi
|
||||
if [ -e "${HOME}/.local/share/bash-completion/completions/distrobox" ]; then
|
||||
source "${HOME}/.local/share/bash-completion/completions/distrobox"
|
||||
fi
|
||||
|
||||
complete -F _generate_from_help distrobox-assemble
|
||||
@@ -1,13 +0,0 @@
|
||||
# shellcheck disable=all
|
||||
|
||||
if [ -e /usr/share/bash-completion/completions/distrobox ]; then
|
||||
source /usr/share/bash-completion/completions/distrobox
|
||||
fi
|
||||
if [ -e /usr/local/share/bash-completion/completions/distrobox ]; then
|
||||
source /usr/local/share/bash-completion/completions/distrobox
|
||||
fi
|
||||
if [ -e "${HOME}/.local/share/bash-completion/completions/distrobox" ]; then
|
||||
source "${HOME}/.local/share/bash-completion/completions/distrobox"
|
||||
fi
|
||||
|
||||
complete -F _generate_from_help distrobox-create
|
||||
@@ -1,13 +0,0 @@
|
||||
# shellcheck disable=all
|
||||
|
||||
if [ -e /usr/share/bash-completion/completions/distrobox ]; then
|
||||
source /usr/share/bash-completion/completions/distrobox
|
||||
fi
|
||||
if [ -e /usr/local/share/bash-completion/completions/distrobox ]; then
|
||||
source /usr/local/share/bash-completion/completions/distrobox
|
||||
fi
|
||||
if [ -e "${HOME}/.local/share/bash-completion/completions/distrobox" ]; then
|
||||
source "${HOME}/.local/share/bash-completion/completions/distrobox"
|
||||
fi
|
||||
|
||||
complete -F _generate_from_help distrobox-enter
|
||||
@@ -1,13 +0,0 @@
|
||||
# shellcheck disable=all
|
||||
|
||||
if [ -e /usr/share/bash-completion/completions/distrobox ]; then
|
||||
source /usr/share/bash-completion/completions/distrobox
|
||||
fi
|
||||
if [ -e /usr/local/share/bash-completion/completions/distrobox ]; then
|
||||
source /usr/local/share/bash-completion/completions/distrobox
|
||||
fi
|
||||
if [ -e "${HOME}/.local/share/bash-completion/completions/distrobox" ]; then
|
||||
source "${HOME}/.local/share/bash-completion/completions/distrobox"
|
||||
fi
|
||||
|
||||
complete -F _generate_from_help distrobox-ephemeral
|
||||
@@ -1,13 +0,0 @@
|
||||
# shellcheck disable=all
|
||||
|
||||
if [ -e /usr/share/bash-completion/completions/distrobox ]; then
|
||||
source /usr/share/bash-completion/completions/distrobox
|
||||
fi
|
||||
if [ -e /usr/local/share/bash-completion/completions/distrobox ]; then
|
||||
source /usr/local/share/bash-completion/completions/distrobox
|
||||
fi
|
||||
if [ -e "${HOME}/.local/share/bash-completion/completions/distrobox" ]; then
|
||||
source "${HOME}/.local/share/bash-completion/completions/distrobox"
|
||||
fi
|
||||
|
||||
complete -F _generate_from_help distrobox-generate-entry
|
||||
@@ -1,13 +0,0 @@
|
||||
# shellcheck disable=all
|
||||
|
||||
if [ -e /usr/share/bash-completion/completions/distrobox ]; then
|
||||
source /usr/share/bash-completion/completions/distrobox
|
||||
fi
|
||||
if [ -e /usr/local/share/bash-completion/completions/distrobox ]; then
|
||||
source /usr/local/share/bash-completion/completions/distrobox
|
||||
fi
|
||||
if [ -e "${HOME}/.local/share/bash-completion/completions/distrobox" ]; then
|
||||
source "${HOME}/.local/share/bash-completion/completions/distrobox"
|
||||
fi
|
||||
|
||||
complete -F _generate_from_help distrobox-list
|
||||
@@ -1,13 +0,0 @@
|
||||
# shellcheck disable=all
|
||||
|
||||
if [ -e /usr/share/bash-completion/completions/distrobox ]; then
|
||||
source /usr/share/bash-completion/completions/distrobox
|
||||
fi
|
||||
if [ -e /usr/local/share/bash-completion/completions/distrobox ]; then
|
||||
source /usr/local/share/bash-completion/completions/distrobox
|
||||
fi
|
||||
if [ -e "${HOME}/.local/share/bash-completion/completions/distrobox" ]; then
|
||||
source "${HOME}/.local/share/bash-completion/completions/distrobox"
|
||||
fi
|
||||
|
||||
complete -F _generate_from_help distrobox-rm
|
||||
@@ -1,13 +0,0 @@
|
||||
# shellcheck disable=all
|
||||
|
||||
if [ -e /usr/share/bash-completion/completions/distrobox ]; then
|
||||
source /usr/share/bash-completion/completions/distrobox
|
||||
fi
|
||||
if [ -e /usr/local/share/bash-completion/completions/distrobox ]; then
|
||||
source /usr/local/share/bash-completion/completions/distrobox
|
||||
fi
|
||||
if [ -e "${HOME}/.local/share/bash-completion/completions/distrobox" ]; then
|
||||
source "${HOME}/.local/share/bash-completion/completions/distrobox"
|
||||
fi
|
||||
|
||||
complete -F _generate_from_help distrobox-stop
|
||||
@@ -1,13 +0,0 @@
|
||||
# shellcheck disable=all
|
||||
|
||||
if [ -e /usr/share/bash-completion/completions/distrobox ]; then
|
||||
source /usr/share/bash-completion/completions/distrobox
|
||||
fi
|
||||
if [ -e /usr/local/share/bash-completion/completions/distrobox ]; then
|
||||
source /usr/local/share/bash-completion/completions/distrobox
|
||||
fi
|
||||
if [ -e "${HOME}/.local/share/bash-completion/completions/distrobox" ]; then
|
||||
source "${HOME}/.local/share/bash-completion/completions/distrobox"
|
||||
fi
|
||||
|
||||
complete -F _generate_from_help distrobox-upgrade
|
||||
@@ -3,6 +3,26 @@
|
||||
local curcontext="$curcontext" state line
|
||||
typeset -A opt_args
|
||||
|
||||
_distrobox_containers() {
|
||||
local -a containers
|
||||
containers=("${(@f)$(distrobox list | sed 1d | awk -F'|' '{print $2}' | sed 's/^[ \t]*//;s/[ \t]*$//')}")
|
||||
_describe -t containers 'available containers' containers
|
||||
}
|
||||
|
||||
_distrobox_images() {
|
||||
local -a images
|
||||
images=("${(@f)$(distrobox create --compatibility | awk 'NF {print $0}')}")
|
||||
_wanted images expl 'compatible image' compadd -a images
|
||||
}
|
||||
|
||||
_distrobox_running_containers() {
|
||||
local -a containers
|
||||
containers=($(distrobox list | awk -F'|' '$3 ~ /Up/ { gsub(/^[ \t]+|[ \t]+$/, "", $2); print $2 }'))
|
||||
if (( ${#containers} > 0 )); then
|
||||
_describe -t running-containers 'running containers' containers
|
||||
fi
|
||||
}
|
||||
|
||||
_distrobox_commands() {
|
||||
local -a commands
|
||||
commands=(
|
||||
@@ -21,6 +41,299 @@ _distrobox_commands() {
|
||||
_describe -t commands 'distrobox command' commands
|
||||
}
|
||||
|
||||
_distrobox-assemble() {
|
||||
_message -r "Create or remove containers in batches, based on a manifest file."
|
||||
_arguments \
|
||||
'1:command:(create rm)' \
|
||||
'--file[path to the distrobox manifest/ini file]:file:_files' \
|
||||
'(--name -n)'{-n,--name}'[run against a single entry in the manifest/ini file]:entry name:' \
|
||||
'(--replace -R)'{-R,--replace}'[replace already existing distroboxes with matching names]' \
|
||||
'(--dry-run -d)'{-d,--dry-run}'[only print the container manager command generated]' \
|
||||
'(--verbose -v)'{-v,--verbose}'[show more verbosity]' \
|
||||
'(--version -V)'{-V,--version}'[show version]'
|
||||
}
|
||||
|
||||
_distrobox-create() {
|
||||
local -a options
|
||||
local expl
|
||||
local state
|
||||
options=(
|
||||
'(-i --image)'{-i,--image}'[Specify image to use for the container]:image:_distrobox_images'
|
||||
'(-n --name)'{-n,--name}'[Specify name for the distrobox]:distrobox name:'
|
||||
'--hostname[Specify hostname for the distrobox]:hostname:'
|
||||
'(-p --pull)'{-p,--pull}'[Pull the image even if it exists locally (implies --yes)]'
|
||||
'(-Y --yes)'{-Y,--yes}'[Non-interactive, pull images without asking]'
|
||||
'(-r --root)'{-r,--root}'[Launch with root privileges using podman/docker/lilipod]'
|
||||
'(-c --clone)'{-c,--clone}'[Name of the distrobox container to use as base for a new container]:clone container name:'
|
||||
'(-H --home)'{-H,--home}'[Select a custom HOME directory for the container]:path:_files -/'
|
||||
'--volume[Add additional volumes to the container]:volume:_files'
|
||||
'(-a --additional-flags)'{-a,--additional-flags}'[Additional flags to pass to the container manager command]:flags:'
|
||||
'(-ap --additional-packages)'{-ap,--additional-packages}'[Additional packages to install during setup]:package:'
|
||||
'--init-hooks[Commands to execute during container initialization]:command:'
|
||||
'--pre-init-hooks[Commands to execute prior to container initialization]:command:'
|
||||
'(-I --init)'{-I,--init}'[Use an init system inside the container]'
|
||||
'--nvidia[Try to integrate host nVidia drivers into the guest]'
|
||||
'--unshare-devsys[Do not share host devices and sysfs dirs from host]'
|
||||
'--unshare-groups[Do not forward users additional groups into the container]'
|
||||
'--unshare-ipc[Do not share ipc namespace with host]'
|
||||
'--unshare-netns[Do not share the net namespace with host]'
|
||||
'--unshare-process[Do not share process namespace with host]'
|
||||
'--unshare-all[Activate all the unshare flags]'
|
||||
'(-C --compatibility)'{-C,--compatibility}'[Show list of compatible images]'
|
||||
'(-h --help)'{-h,--help}'[Show this message]'
|
||||
'--no-entry[Do not generate a container entry in the application list]'
|
||||
'(-d --dry-run)'{-d,--dry-run}'[Only print the container manager command generated]'
|
||||
'(-v --verbose)'{-v,--verbose}'[Show more verbosity]'
|
||||
'(-V --version)'{-V,--version}'[Show version]'
|
||||
'--absolutely-disable-root-password-i-am-really-positively-sure[Skip user password setup, leaving it blank]'
|
||||
)
|
||||
_message -r "Create new distroboxes."
|
||||
_arguments \
|
||||
'1:containers:->container' \
|
||||
'*:options:->options' \
|
||||
$options[@]
|
||||
}
|
||||
|
||||
_distrobox-enter() {
|
||||
local -a options
|
||||
local expl
|
||||
local state
|
||||
local _db_cc
|
||||
|
||||
_db_cc=("${(@f)$(distrobox list | sed 1d | awk -F'|' '{print $2}' | sed 's/^[ \t]*//;s/[ \t]*$//')}")
|
||||
|
||||
options=(
|
||||
'(--name -n)'{-n,--name}'[name for the distrobox]:container:_distrobox_containers'
|
||||
'--[end arguments and execute the rest as command to execute at login]:command:_command_names'
|
||||
'(--no-tty -T)'{-T,--no-tty}'[do not instantiate a tty]'
|
||||
'(--no-workdir -nw)'{-nw,--no-workdir}'[always start the container from container home directory]'
|
||||
'(--additional-flags -a)'{-a,--additional-flags}'[additional flags to pass to the container manager command]:flags:'
|
||||
'(--help -h)'{-h,--help}'[show this message]'
|
||||
'(--root -r)'{-r,--root}'[launch podman/docker/lilipod with root privileges]'
|
||||
'(--dry-run -d)'{-d,--dry-run}'[only print the container manager command generated]'
|
||||
'(--verbose -v)'{-v,--verbose}'[show more verbosity]'
|
||||
'(--version -V)'{-V,--version}'[show version]'
|
||||
)
|
||||
_message -r "Start and enter a distrobox."
|
||||
if [[ -n "$_db_cc" ]]; then
|
||||
_arguments -C \
|
||||
'1:containers:_distrobox_containers' \
|
||||
$options[@]
|
||||
else
|
||||
_message -r "No containers exist."
|
||||
_arguments $options[@]
|
||||
fi
|
||||
}
|
||||
|
||||
_distrobox-ephemeral() {
|
||||
local -a options
|
||||
local expl
|
||||
local state
|
||||
options=(
|
||||
'(-i --image)'{-i,--image}'[Specify image to use for the container]:image:_distrobox_images'
|
||||
'(-n --name)'{-n,--name}'[Specify name for the distrobox]:distrobox name:'
|
||||
'--hostname[Specify hostname for the distrobox]:hostname:'
|
||||
'(-p --pull)'{-p,--pull}'[Pull the image even if it exists locally (implies --yes)]'
|
||||
'(-Y --yes)'{-Y,--yes}'[Non-interactive, pull images without asking]'
|
||||
'(-r --root)'{-r,--root}'[Launch with root privileges using podman/docker/lilipod]'
|
||||
'(-c --clone)'{-c,--clone}'[Name of the distrobox container to use as base for a new container]:clone container name:'
|
||||
'(-H --home)'{-H,--home}'[Select a custom HOME directory for the container]:path:_files -/'
|
||||
'--volume[Add additional volumes to the container]:volume:_files'
|
||||
'(-a --additional-flags)'{-a,--additional-flags}'[Additional flags to pass to the container manager command]:flags:'
|
||||
'(-ap --additional-packages)'{-ap,--additional-packages}'[Additional packages to install during setup]:package:'
|
||||
'--init-hooks[Commands to execute during container initialization]:command:'
|
||||
'--pre-init-hooks[Commands to execute prior to container initialization]:command:'
|
||||
'(-I --init)'{-I,--init}'[Use an init system inside the container]'
|
||||
'--nvidia[Try to integrate host nVidia drivers into the guest]'
|
||||
'--unshare-devsys[Do not share host devices and sysfs dirs from host]'
|
||||
'--unshare-groups[Do not forward users additional groups into the container]'
|
||||
'--unshare-ipc[Do not share ipc namespace with host]'
|
||||
'--unshare-netns[Do not share the net namespace with host]'
|
||||
'--unshare-process[Do not share process namespace with host]'
|
||||
'--unshare-all[Activate all the unshare flags]'
|
||||
'(-C --compatibility)'{-C,--compatibility}'[Show list of compatible images]'
|
||||
'(-h --help)'{-h,--help}'[Show this message]'
|
||||
'--no-entry[Do not generate a container entry in the application list]'
|
||||
'(-d --dry-run)'{-d,--dry-run}'[Only print the container manager command generated]'
|
||||
'(-v --verbose)'{-v,--verbose}'[Show more verbosity]'
|
||||
'(-V --version)'{-V,--version}'[Show version]'
|
||||
'--absolutely-disable-root-password-i-am-really-positively-sure[Skip user password setup, leaving it blank]'
|
||||
)
|
||||
_message -r "Create temporary distroboxes that are auto destroyed."
|
||||
_arguments \
|
||||
'1:containers:->container' \
|
||||
'*:options:->options' \
|
||||
$options[@]
|
||||
}
|
||||
|
||||
_distrobox-export() {
|
||||
_message -r "Export an app or a binary from the container to the host."
|
||||
_arguments \
|
||||
'(--app -a)'{-a,--app}'[name of the application to export]:application name:' \
|
||||
'(--bin -b)'{-b,--bin}'[absolute path of the binary to export]:path to binary:_files' \
|
||||
'(--delete -d)'{-d,--delete}'[delete exported application or binary]' \
|
||||
'(--export-label -el)'{-el,--export-label}'[label to add to exported application name, use "none" to disable]:label:' \
|
||||
'(--export-path -ep)'{-ep,--export-path}'[path where to export the binary]:export path:_files' \
|
||||
'(--extra-flags -ef)'{-ef,--extra-flags}'[extra flags to add to the command]:extra flags:' \
|
||||
'(--enter-flags -nf)'{-nf,--enter-flags}'[flags to add to distrobox enter]:enter flags:' \
|
||||
'--list-apps[list applications exported from this container]' \
|
||||
'--list-binaries[list binaries exported from this container, use -ep to specify custom paths to search]' \
|
||||
'(--sudo -S)'{-S,--sudo}'[specify if the exported item should be run as sudo]' \
|
||||
'(--help -h)'{-h,--help}'[show this message]' \
|
||||
'(--verbose -v)'{-v,--verbose}'[show more verbosity]' \
|
||||
'(--version -V)'{-V,--version}'[show version]'
|
||||
}
|
||||
|
||||
_distrobox generate-entry() {
|
||||
local expl
|
||||
local -a options
|
||||
local _db_cc
|
||||
_db_cc=("${(@f)$(distrobox list | sed 1d | awk -F'|' '{print $2}' | sed 's/^[ \t]*//;s/[ \t]*$//')}")
|
||||
options=(
|
||||
'(-h --help)'{-h,--help}'[show this message]'
|
||||
'(-a --all)'{-a,--all}'[perform for all distroboxes]'
|
||||
'(-d --delete)'{-d,--delete}'[delete the entry]'
|
||||
'(-i --icon)'{-i,--icon}'[specify a custom icon (default auto)]:icon path:(auto _files)'
|
||||
'(-r --root)'{-r,--root}'[perform on rootful distroboxes]'
|
||||
'(-v --verbose)'{-v,--verbose}'[show more verbosity]'
|
||||
'(-V --version)'{-V,--version}'[show version]'
|
||||
)
|
||||
_message -r "Create a desktop icon for a distrobox"
|
||||
if [[ -n "$_db_cc" ]]; then
|
||||
_arguments \
|
||||
'*:containers:_distrobox_containers' \
|
||||
$options[@]
|
||||
else
|
||||
_message -r "No containers exist."
|
||||
_arguments $options[@]
|
||||
fi
|
||||
}
|
||||
|
||||
_distrobox-host-exec() {
|
||||
_message -r "Execute a command on the host while in a container"
|
||||
_arguments \
|
||||
'*:command:_command' \
|
||||
'(--help -h)'{-h,--help}'[show this message]' \
|
||||
'(--verbose -v)'{-v,--verbose}'[show more verbosity]' \
|
||||
'(--version -V)'{-V,--version}'[show version]' \
|
||||
'(--yes -Y)'{-Y,--yes}'[Automatically answer yes to prompt host-spawn will be installed on the guest system if not detected]'
|
||||
}
|
||||
|
||||
_distrobox-init() {
|
||||
_message -r "Init the distrobox (not to be launched manually)"
|
||||
_arguments \
|
||||
'(--name -n)'{-n,--name}'[user name]:user name:' \
|
||||
'(--user -u)'{-u,--user}'[uid of the user]:uid:' \
|
||||
'(--group -g)'{-g,--group}'[gid of the user]:gid:' \
|
||||
'(--home -d)'{-d,--home}'[path/to/home of the user]:home path:_files' \
|
||||
'(--help -h)'{-h,--help}'[show this message]' \
|
||||
'--additional-packages[packages to install in addition]:packages:' \
|
||||
'(--init -I)'{-I,--init}'[whether to use or not init]' \
|
||||
'--pre-init-hooks[commands to execute prior to init]:commands:' \
|
||||
'--nvidia[try to integrate hosts nVidia drivers in the guest]' \
|
||||
'(--upgrade -U)'{-U,--upgrade}'[run init in upgrade mode]' \
|
||||
'(--verbose -v)'{-v,--verbose}'[show more verbosity]' \
|
||||
'(--version -V)'{-V,--version}'[show version]' \
|
||||
'--:[end arguments execute the rest as command to execute during init]:command:_command'
|
||||
}
|
||||
|
||||
_distrobox-list() {
|
||||
_message -r "List available distroboxes."
|
||||
_arguments \
|
||||
'(--help -h)'{-h,--help}'[show this message]' \
|
||||
'--no-color[disable color formatting]' \
|
||||
'(--root -r)'{-r,--root}'[launch podman/docker/lilipod with root privileges]' \
|
||||
'(--verbose -v)'{-v,--verbose}'[show more verbosity]' \
|
||||
'(--version -V)'{-V,--version}'[show version]'
|
||||
}
|
||||
|
||||
_distrobox-rm() {
|
||||
# expl is an internal zsh array that gets passed to _arguments bts
|
||||
local expl
|
||||
local -a options
|
||||
local _db_cc
|
||||
# Check for existing containers and store the result into var _db_cc
|
||||
_db_cc=("${(@f)$(distrobox list | sed 1d | awk -F'|' '{print $2}' | sed 's/^[ \t]*//;s/[ \t]*$//')}")
|
||||
# Array of optargs to pass to _arguments for matching and completion
|
||||
options=(
|
||||
'(-a --all)'{-a,--all}'[delete all distroboxes]'
|
||||
'(-f --force)'{-f,--force}'[force deletion]'
|
||||
'--rm-home[remove the mounted home if it differs from the host users one]'
|
||||
'(-r --root)'{-r,--root}'[launch podman/docker/lilipod with root privileges]'
|
||||
'(-h --help)'{-h,--help}'[show this message]'
|
||||
'(-v --verbose)'{-v,--verbose}'[show more verbosity]'
|
||||
'(-V --version)'{-V,--version}'[show version]'
|
||||
)
|
||||
_message -r "Delete one or more distroboxes."
|
||||
# If containers exist then do an action
|
||||
if [[ -n "$_db_cc" ]]; then
|
||||
# Match both container names and optargs
|
||||
_arguments \
|
||||
'*:containers:_distrobox_containers' \
|
||||
$options[@]
|
||||
# If no containers exist then do an action
|
||||
else
|
||||
# Display message to user and match optargs only
|
||||
_message -r "No containers exist."
|
||||
_arguments $options[@]
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
_distrobox-stop() {
|
||||
local expl
|
||||
local -a options
|
||||
local _db_rcc
|
||||
|
||||
_db_rcc=($(distrobox list | awk -F'|' '$3 ~ /Up/ { gsub(/^[ \t]+|[ \t]+$/, "", $2); print $2 }'))
|
||||
|
||||
options=(
|
||||
'(-a --all)'{-a,--all}'[stop all distroboxes]'
|
||||
'(-Y --yes)'{-Y,--yes}'[non-interactive, stop without asking]'
|
||||
'(-r --root)'{-r,--root}'[launch podman/docker/lilipod with root privileges]'
|
||||
'(-h --help)'{-h,--help}'[show this message]'
|
||||
'(-v --verbose)'{-v,--verbose}'[show more verbosity]'
|
||||
'(-V --version)'{-V,--version}'[show version]'
|
||||
)
|
||||
|
||||
_message -r "Stop running distrobox containers."
|
||||
if [[ -n "$_db_rcc" ]]; then
|
||||
_arguments -C \
|
||||
'*:containers:_distrobox_running_containers' \
|
||||
$options[@]
|
||||
else
|
||||
_message -r "No running containers."
|
||||
_arguments $options[@]
|
||||
fi
|
||||
}
|
||||
|
||||
_distrobox-upgrade() {
|
||||
local expl
|
||||
local -a options
|
||||
local _db_cc
|
||||
|
||||
_db_cc=("${(@f)$(distrobox list | sed 1d | awk -F'|' '{print $2}' | sed 's/^[ \t]*//;s/[ \t]*$//')}")
|
||||
|
||||
options=(
|
||||
'(-a --all)'{-a,--all}'[upgrade all distroboxes]'
|
||||
'--running[perform only for running distroboxes]'
|
||||
'(-r --root)'{-r,--root}'[launch podman/docker/lilipod with root privileges]'
|
||||
'(-h --help)'{-h,--help}'[show this message]'
|
||||
'(-v --verbose)'{-v,--verbose}'[show more verbosity]'
|
||||
'(-V --version)'{-V,--version}'[show version]'
|
||||
)
|
||||
|
||||
_message -r "Upgrade distroboxes using container's package manager."
|
||||
if [[ -n "$_db_cc" ]]; then
|
||||
_arguments \
|
||||
'*:containers:_distrobox_containers' \
|
||||
$options[@]
|
||||
else
|
||||
_message -r "No containers exist."
|
||||
_arguments $options[@]
|
||||
fi
|
||||
}
|
||||
|
||||
_arguments -C \
|
||||
'1: :_distrobox_commands' \
|
||||
'*:: :->args'
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
#compdef distrobox-assemble
|
||||
|
||||
_message -r "Create or remove containers in batches, based on a manifest file."
|
||||
_arguments \
|
||||
'1:command:(create rm)' \
|
||||
'--file[path to the distrobox manifest/ini file]:file:_files' \
|
||||
'(--name -n)'{-n,--name}'[run against a single entry in the manifest/ini file]:entry name:' \
|
||||
'(--replace -R)'{-R,--replace}'[replace already existing distroboxes with matching names]' \
|
||||
'(--dry-run -d)'{-d,--dry-run}'[only print the container manager command generated]' \
|
||||
'(--verbose -v)'{-v,--verbose}'[show more verbosity]' \
|
||||
'(--version -V)'{-V,--version}'[show version]'
|
||||
@@ -1,46 +0,0 @@
|
||||
#compdef distrobox-create
|
||||
|
||||
_distrobox-create() {
|
||||
local -a options
|
||||
local expl
|
||||
local state
|
||||
# Array of optargs to pass to _arguments for matching and completion
|
||||
options=(
|
||||
'(-i --image)'{-i,--image}'[Specify image to use for the container]:image:_distrobox_images'
|
||||
'(-n --name)'{-n,--name}'[Specify name for the distrobox]:distrobox name:'
|
||||
'--hostname[Specify hostname for the distrobox]:hostname:'
|
||||
'(-p --pull)'{-p,--pull}'[Pull the image even if it exists locally (implies --yes)]'
|
||||
'(-Y --yes)'{-Y,--yes}'[Non-interactive, pull images without asking]'
|
||||
'(-r --root)'{-r,--root}'[Launch with root privileges using podman/docker/lilipod]'
|
||||
'(-c --clone)'{-c,--clone}'[Name of the distrobox container to use as base for a new container]:clone container name:'
|
||||
'(-H --home)'{-H,--home}'[Select a custom HOME directory for the container]:path:_files -/'
|
||||
'--volume[Add additional volumes to the container]:volume:_files'
|
||||
'(-a --additional-flags)'{-a,--additional-flags}'[Additional flags to pass to the container manager command]:flags:'
|
||||
'(-ap --additional-packages)'{-ap,--additional-packages}'[Additional packages to install during setup]:package:'
|
||||
'--init-hooks[Commands to execute during container initialization]:command:'
|
||||
'--pre-init-hooks[Commands to execute prior to container initialization]:command:'
|
||||
'(-I --init)'{-I,--init}'[Use an init system inside the container]'
|
||||
'--nvidia[Try to integrate host nVidia drivers into the guest]'
|
||||
'--unshare-devsys[Do not share host devices and sysfs dirs from host]'
|
||||
'--unshare-groups[Do not forward users additional groups into the container]'
|
||||
'--unshare-ipc[Do not share ipc namespace with host]'
|
||||
'--unshare-netns[Do not share the net namespace with host]'
|
||||
'--unshare-process[Do not share process namespace with host]'
|
||||
'--unshare-all[Activate all the unshare flags]'
|
||||
'(-C --compatibility)'{-C,--compatibility}'[Show list of compatible images]'
|
||||
'(-h --help)'{-h,--help}'[Show this message]'
|
||||
'--no-entry[Do not generate a container entry in the application list]'
|
||||
'(-d --dry-run)'{-d,--dry-run}'[Only print the container manager command generated]'
|
||||
'(-v --verbose)'{-v,--verbose}'[Show more verbosity]'
|
||||
'(-V --version)'{-V,--version}'[Show version]'
|
||||
'--absolutely-disable-root-password-i-am-really-positively-sure[Skip user password setup, leaving it blank]'
|
||||
)
|
||||
# Simple logic
|
||||
_message -r "Create new distroboxes."
|
||||
_arguments \
|
||||
'1:containers:->container' \
|
||||
'*:options:->options' \
|
||||
$options[@]
|
||||
}
|
||||
|
||||
_distrobox-create
|
||||
@@ -1,35 +0,0 @@
|
||||
#compdef distrobox-enter
|
||||
|
||||
_distrobox-enter() {
|
||||
local -a options
|
||||
local expl
|
||||
local state
|
||||
local _db_cc
|
||||
|
||||
_db_cc=("${(@f)$(distrobox list | sed 1d | awk -F'|' '{print $2}' | sed 's/^[ \t]*//;s/[ \t]*$//')}")
|
||||
|
||||
options=(
|
||||
'(--name -n)'{-n,--name}'[name for the distrobox]:container:_distrobox_containers'
|
||||
'--[end arguments and execute the rest as command to execute at login]:command:_command_names'
|
||||
'(--no-tty -T)'{-T,--no-tty}'[do not instantiate a tty]'
|
||||
'(--no-workdir -nw)'{-nw,--no-workdir}'[always start the container from container home directory]'
|
||||
'(--additional-flags -a)'{-a,--additional-flags}'[additional flags to pass to the container manager command]:flags:'
|
||||
'(--help -h)'{-h,--help}'[show this message]'
|
||||
'(--root -r)'{-r,--root}'[launch podman/docker/lilipod with root privileges]'
|
||||
'(--dry-run -d)'{-d,--dry-run}'[only print the container manager command generated]'
|
||||
'(--verbose -v)'{-v,--verbose}'[show more verbosity]'
|
||||
'(--version -V)'{-V,--version}'[show version]'
|
||||
)
|
||||
_message -r "Start and enter a distrobox."
|
||||
if [[ -n "$_db_cc" ]]; then
|
||||
_arguments -C \
|
||||
'1:containers:_distrobox_containers' \
|
||||
$options[@]
|
||||
else
|
||||
_message -r "No containers exist."
|
||||
_arguments $options[@]
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
_distrobox-enter
|
||||
@@ -1,46 +0,0 @@
|
||||
#compdef distrobox-ephemeral
|
||||
|
||||
_distrobox-ephemeral() {
|
||||
local -a options
|
||||
local expl
|
||||
local state
|
||||
# Array of optargs to pass to _arguments for matching and completion
|
||||
options=(
|
||||
'(-i --image)'{-i,--image}'[Specify image to use for the container]:image:_distrobox_images'
|
||||
'(-n --name)'{-n,--name}'[Specify name for the distrobox]:distrobox name:'
|
||||
'--hostname[Specify hostname for the distrobox]:hostname:'
|
||||
'(-p --pull)'{-p,--pull}'[Pull the image even if it exists locally (implies --yes)]'
|
||||
'(-Y --yes)'{-Y,--yes}'[Non-interactive, pull images without asking]'
|
||||
'(-r --root)'{-r,--root}'[Launch with root privileges using podman/docker/lilipod]'
|
||||
'(-c --clone)'{-c,--clone}'[Name of the distrobox container to use as base for a new container]:clone container name:'
|
||||
'(-H --home)'{-H,--home}'[Select a custom HOME directory for the container]:path:_files -/'
|
||||
'--volume[Add additional volumes to the container]:volume:_files'
|
||||
'(-a --additional-flags)'{-a,--additional-flags}'[Additional flags to pass to the container manager command]:flags:'
|
||||
'(-ap --additional-packages)'{-ap,--additional-packages}'[Additional packages to install during setup]:package:'
|
||||
'--init-hooks[Commands to execute during container initialization]:command:'
|
||||
'--pre-init-hooks[Commands to execute prior to container initialization]:command:'
|
||||
'(-I --init)'{-I,--init}'[Use an init system inside the container]'
|
||||
'--nvidia[Try to integrate host nVidia drivers into the guest]'
|
||||
'--unshare-devsys[Do not share host devices and sysfs dirs from host]'
|
||||
'--unshare-groups[Do not forward users additional groups into the container]'
|
||||
'--unshare-ipc[Do not share ipc namespace with host]'
|
||||
'--unshare-netns[Do not share the net namespace with host]'
|
||||
'--unshare-process[Do not share process namespace with host]'
|
||||
'--unshare-all[Activate all the unshare flags]'
|
||||
'(-C --compatibility)'{-C,--compatibility}'[Show list of compatible images]'
|
||||
'(-h --help)'{-h,--help}'[Show this message]'
|
||||
'--no-entry[Do not generate a container entry in the application list]'
|
||||
'(-d --dry-run)'{-d,--dry-run}'[Only print the container manager command generated]'
|
||||
'(-v --verbose)'{-v,--verbose}'[Show more verbosity]'
|
||||
'(-V --version)'{-V,--version}'[Show version]'
|
||||
'--absolutely-disable-root-password-i-am-really-positively-sure[Skip user password setup, leaving it blank]'
|
||||
)
|
||||
# Simple logic
|
||||
_message -r "Create temporary distroboxes that are auto destroyed."
|
||||
_arguments \
|
||||
'1:containers:->container' \
|
||||
'*:options:->options' \
|
||||
$options[@]
|
||||
}
|
||||
|
||||
_distrobox-ephemeral
|
||||
@@ -1,17 +0,0 @@
|
||||
#compdef distrobox-export
|
||||
|
||||
_message -r "Export an app or a binary from the container to the host."
|
||||
_arguments \
|
||||
'(--app -a)'{-a,--app}'[name of the application to export]:application name:' \
|
||||
'(--bin -b)'{-b,--bin}'[absolute path of the binary to export]:path to binary:_files' \
|
||||
'(--delete -d)'{-d,--delete}'[delete exported application or binary]' \
|
||||
'(--export-label -el)'{-el,--export-label}'[label to add to exported application name, use "none" to disable]:label:' \
|
||||
'(--export-path -ep)'{-ep,--export-path}'[path where to export the binary]:export path:_files' \
|
||||
'(--extra-flags -ef)'{-ef,--extra-flags}'[extra flags to add to the command]:extra flags:' \
|
||||
'(--enter-flags -nf)'{-nf,--enter-flags}'[flags to add to distrobox-enter]:enter flags:' \
|
||||
'--list-apps[list applications exported from this container]' \
|
||||
'--list-binaries[list binaries exported from this container, use -ep to specify custom paths to search]' \
|
||||
'(--sudo -S)'{-S,--sudo}'[specify if the exported item should be run as sudo]' \
|
||||
'(--help -h)'{-h,--help}'[show this message]' \
|
||||
'(--verbose -v)'{-v,--verbose}'[show more verbosity]' \
|
||||
'(--version -V)'{-V,--version}'[show version]'
|
||||
@@ -1,35 +0,0 @@
|
||||
#compdef distrobox-generate-entry
|
||||
|
||||
_distrobox-generate-entry() {
|
||||
# expl is an internal zsh array that gets passed to _arguments bts
|
||||
local expl
|
||||
local -a options
|
||||
local _db_cc
|
||||
# Check for existing containers and store the result into var _db_cc
|
||||
_db_cc=("${(@f)$(distrobox list | sed 1d | awk -F'|' '{print $2}' | sed 's/^[ \t]*//;s/[ \t]*$//')}")
|
||||
# Array of optargs to pass to _arguments for matching and completion
|
||||
options=(
|
||||
'(-h --help)'{-h,--help}'[show this message]'
|
||||
'(-a --all)'{-a,--all}'[perform for all distroboxes]'
|
||||
'(-d --delete)'{-d,--delete}'[delete the entry]'
|
||||
'(-i --icon)'{-i,--icon}'[specify a custom icon (default auto)]:icon path:(auto _files)'
|
||||
'(-r --root)'{-r,--root}'[perform on rootful distroboxes]'
|
||||
'(-v --verbose)'{-v,--verbose}'[show more verbosity]'
|
||||
'(-V --version)'{-V,--version}'[show version]'
|
||||
)
|
||||
_message -r "Create a desktop icon for a distrobox"
|
||||
# If containers exist then do an action
|
||||
if [[ -n "$_db_cc" ]]; then
|
||||
# Match both container names and optargs
|
||||
_arguments \
|
||||
'*:containers:_distrobox_containers' \
|
||||
$options[@]
|
||||
# If no containers exist then do an action
|
||||
else
|
||||
# Display message to user and match optargs only
|
||||
_message -r "No containers exist."
|
||||
_arguments $options[@]
|
||||
fi
|
||||
}
|
||||
|
||||
_distrobox-generate-entry
|
||||
@@ -1,9 +0,0 @@
|
||||
#compdef distrobox-host-exec
|
||||
|
||||
_message -r "Execute a command on the host while in a container"
|
||||
_arguments \
|
||||
'*:command:_command' \
|
||||
'(--help -h)'{-h,--help}'[show this message]' \
|
||||
'(--verbose -v)'{-v,--verbose}'[show more verbosity]' \
|
||||
'(--version -V)'{-V,--version}'[show version]' \
|
||||
'(--yes -Y)'{-Y,--yes}'[Automatically answer yes to prompt host-spawn will be installed on the guest system if not detected]'
|
||||
@@ -1,17 +0,0 @@
|
||||
#compdef distrobox-init
|
||||
|
||||
_message -r "Init the distrobox (not to be launched manually)"
|
||||
_arguments \
|
||||
'(--name -n)'{-n,--name}'[user name]:user name:' \
|
||||
'(--user -u)'{-u,--user}'[uid of the user]:uid:' \
|
||||
'(--group -g)'{-g,--group}'[gid of the user]:gid:' \
|
||||
'(--home -d)'{-d,--home}'[path/to/home of the user]:home path:_files' \
|
||||
'(--help -h)'{-h,--help}'[show this message]' \
|
||||
'--additional-packages[packages to install in addition]:packages:' \
|
||||
'(--init -I)'{-I,--init}'[whether to use or not init]' \
|
||||
'--pre-init-hooks[commands to execute prior to init]:commands:' \
|
||||
'--nvidia[try to integrate hosts nVidia drivers in the guest]' \
|
||||
'(--upgrade -U)'{-U,--upgrade}'[run init in upgrade mode]' \
|
||||
'(--verbose -v)'{-v,--verbose}'[show more verbosity]' \
|
||||
'(--version -V)'{-V,--version}'[show version]' \
|
||||
'--:[end arguments execute the rest as command to execute during init]:command:_command'
|
||||
@@ -1,9 +0,0 @@
|
||||
#compdef distrobox-list
|
||||
|
||||
_message -r "List available distroboxes."
|
||||
_arguments \
|
||||
'(--help -h)'{-h,--help}'[show this message]' \
|
||||
'--no-color[disable color formatting]' \
|
||||
'(--root -r)'{-r,--root}'[launch podman/docker/lilipod with root privileges]' \
|
||||
'(--verbose -v)'{-v,--verbose}'[show more verbosity]' \
|
||||
'(--version -V)'{-V,--version}'[show version]'
|
||||
@@ -1,36 +0,0 @@
|
||||
#compdef distrobox-rm
|
||||
|
||||
_distrobox-rm() {
|
||||
# expl is an internal zsh array that gets passed to _arguments bts
|
||||
local expl
|
||||
local -a options
|
||||
local _db_cc
|
||||
# Check for existing containers and store the result into var _db_cc
|
||||
_db_cc=("${(@f)$(distrobox list | sed 1d | awk -F'|' '{print $2}' | sed 's/^[ \t]*//;s/[ \t]*$//')}")
|
||||
# Array of optargs to pass to _arguments for matching and completion
|
||||
options=(
|
||||
'(-a --all)'{-a,--all}'[delete all distroboxes]'
|
||||
'(-f --force)'{-f,--force}'[force deletion]'
|
||||
'--rm-home[remove the mounted home if it differs from the host users one]'
|
||||
'(-r --root)'{-r,--root}'[launch podman/docker/lilipod with root privileges]'
|
||||
'(-h --help)'{-h,--help}'[show this message]'
|
||||
'(-v --verbose)'{-v,--verbose}'[show more verbosity]'
|
||||
'(-V --version)'{-V,--version}'[show version]'
|
||||
)
|
||||
_message -r "Delete one or more distroboxes."
|
||||
# If containers exist then do an action
|
||||
if [[ -n "$_db_cc" ]]; then
|
||||
# Match both container names and optargs
|
||||
_arguments \
|
||||
'*:containers:_distrobox_containers' \
|
||||
$options[@]
|
||||
# If no containers exist then do an action
|
||||
else
|
||||
# Display message to user and match optargs only
|
||||
_message -r "No containers exist."
|
||||
_arguments $options[@]
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
_distrobox-rm
|
||||
@@ -1,31 +0,0 @@
|
||||
#compdef distrobox-stop
|
||||
|
||||
_distrobox-stop() {
|
||||
local expl
|
||||
local -a options
|
||||
local _db_rcc
|
||||
|
||||
_db_rcc=($(distrobox list | awk -F'|' '$3 ~ /Up/ { gsub(/^[ \t]+|[ \t]+$/, "", $2); print $2 }'))
|
||||
|
||||
options=(
|
||||
'(-a --all)'{-a,--all}'[stop all distroboxes]'
|
||||
'(-Y --yes)'{-Y,--yes}'[non-interactive, stop without asking]'
|
||||
'(-r --root)'{-r,--root}'[launch podman/docker/lilipod with root privileges]'
|
||||
'(-h --help)'{-h,--help}'[show this message]'
|
||||
'(-v --verbose)'{-v,--verbose}'[show more verbosity]'
|
||||
'(-V --version)'{-V,--version}'[show version]'
|
||||
)
|
||||
|
||||
_message -r "Stop running distrobox containers."
|
||||
if [[ -n "$_db_rcc" ]]; then
|
||||
_arguments -C \
|
||||
'*:containers:_distrobox_running_containers' \
|
||||
$options[@]
|
||||
else
|
||||
_message -r "No running containers."
|
||||
_arguments $options[@]
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
_distrobox-stop
|
||||
@@ -1,31 +0,0 @@
|
||||
#compdef distrobox-upgrade
|
||||
|
||||
_distrobox-upgrade() {
|
||||
local expl
|
||||
local -a options
|
||||
local _db_cc
|
||||
|
||||
_db_cc=("${(@f)$(distrobox list | sed 1d | awk -F'|' '{print $2}' | sed 's/^[ \t]*//;s/[ \t]*$//')}")
|
||||
|
||||
options=(
|
||||
'(-a --all)'{-a,--all}'[upgrade all distroboxes]'
|
||||
'--running[perform only for running distroboxes]'
|
||||
'(-r --root)'{-r,--root}'[launch podman/docker/lilipod with root privileges]'
|
||||
'(-h --help)'{-h,--help}'[show this message]'
|
||||
'(-v --verbose)'{-v,--verbose}'[show more verbosity]'
|
||||
'(-V --version)'{-V,--version}'[show version]'
|
||||
)
|
||||
|
||||
_message -r "Upgrade distroboxes using container's package manager."
|
||||
if [[ -n "$_db_cc" ]]; then
|
||||
_arguments \
|
||||
'*:containers:_distrobox_containers' \
|
||||
$options[@]
|
||||
else
|
||||
_message -r "No containers exist."
|
||||
_arguments $options[@]
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
_distrobox-upgrade
|
||||
@@ -1,7 +0,0 @@
|
||||
#autoload
|
||||
|
||||
_distrobox_containers() {
|
||||
local -a containers
|
||||
containers=("${(@f)$(distrobox list | sed 1d | awk -F'|' '{print $2}' | sed 's/^[ \t]*//;s/[ \t]*$//')}")
|
||||
_describe -t containers 'available containers' containers
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
#autoload
|
||||
|
||||
_distrobox_images() {
|
||||
local -a images
|
||||
images=("${(@f)$(distrobox-create --compatibility | awk 'NF {print $0}')}")
|
||||
_wanted images expl 'compatible image' compadd -a images
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
#autoload
|
||||
|
||||
_distrobox_running_containers() {
|
||||
local -a containers
|
||||
containers=($(distrobox list | awk -F'|' '$3 ~ /Up/ { gsub(/^[ \t]+|[ \t]+$/, "", $2); print $2 }'))
|
||||
if (( ${#containers} > 0 )); then
|
||||
_describe -t running-containers 'running containers' containers
|
||||
fi
|
||||
}
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -1,3 +0,0 @@
|
||||
*.vim
|
||||
TODO.txt
|
||||
bin/
|
||||
@@ -1,81 +0,0 @@
|
||||
| | |
|
||||
| :----------- | :------------- |
|
||||
| Feature Name | Rewrite in GO |
|
||||
| Start Date | Nov 28th, 2025 |
|
||||
| State | **ACCEPTED** |
|
||||
|
||||
# Summary
|
||||
|
||||
[summary]: #summary
|
||||
|
||||
Rewrite Distrobox from `sh` to `GO`: motivation, core principles and architecture.
|
||||
|
||||
# Motivation
|
||||
|
||||
[motivation]: #motivation
|
||||
|
||||
We want Distrobox to live long and prosper. As the tool is being used by more and more people with diverse
|
||||
environment setup, the need to add support to more stuff is pressing.
|
||||
The key factor to not mess it up it's **maintainability**.
|
||||
|
||||
We believe that by rewriting Distrobox in `GO` we can:
|
||||
* add new features safely, by having extensive testing;
|
||||
* have a better developer experience, through the use of a modern coding and testing toolchain;
|
||||
* engage more with the community, by using a popular programming language;
|
||||
|
||||
# Design
|
||||
|
||||
[design]: #design
|
||||
|
||||
## Core principles
|
||||
* Keep feature parity with the actual Distrobox implementation.
|
||||
* Keep dependency list short.
|
||||
* Enforce conventions with strict linting.
|
||||
* Isolate the shell from core Distrobox logic.
|
||||
* Write humble code.
|
||||
|
||||
## Architecture
|
||||
|
||||
### `cmd/main.go`
|
||||
|
||||
Entrypoint of the application, build and execute the CLI root command.
|
||||
|
||||
### `internal/cli/root.go`
|
||||
|
||||
Root CLI command.
|
||||
|
||||
* Load global configuration from either file or environment variables, and define the defaults.
|
||||
* Define the global flags that are valid for every sub command (example: `--verbose`).
|
||||
* Select, instantiate and run the appropriate sub command.
|
||||
|
||||
### `internal/cli/<command>.go`
|
||||
|
||||
Any command exposed through the CLI (example: `distrobox list`). It's the component that is aware of the shell, and it
|
||||
manipulates Distrobox input/output by parsing the command flags and printing logs appropriately.
|
||||
|
||||
* Define command-specific flags.
|
||||
* Instantiate and execute the relative command package.
|
||||
* Handle command termination.
|
||||
* Define shell printing logic by injecting a custom logger to the command package.
|
||||
* Handle verbosity of the logs to the `stdout`.
|
||||
|
||||
### `pkg/command/<command>.go`
|
||||
|
||||
Implement the Distrobox command logic. It has no knowledge about the environment in which it is executed.
|
||||
|
||||
* Exposes a `Execute()` function that accepts input params as arguments and can return either `error` or the execution result.
|
||||
* A custom logger is injected; a command knows nothing about verbosity, log level and (eventually) pretty printing.
|
||||
|
||||
Commands may also have different needs depending on their behaviour:
|
||||
|
||||
* Some commands are meant to be immediate and return a result (example: `list`); for such commands, the output data is returned in the execution result object.
|
||||
* Some are long-running and require to return progress feedback to the user (example: `create`); such commands will log writes to the provided logger, delegating the presentation to the caller.
|
||||
* Finally, some are _interactive_ and need to interact with the shell (example: `enter`); such command will require as input instances of `io.Reader` and `io.Writer` (that, for the shell scenario, can be bound to `stdin` and `stdout` respectively).
|
||||
|
||||
### `pkg/containermanager/containermanager.go`
|
||||
|
||||
Module that defines the interface for interacting with the actual system container manager.
|
||||
|
||||
### `pkg/containermanager/providers/<provider>.go`
|
||||
|
||||
Actual implementation of a container manager (examples: `docker`, `podman`, `lxc`, etc).
|
||||
@@ -1,711 +0,0 @@
|
||||
#!/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
|
||||
# Expected env variables:
|
||||
# HOME
|
||||
# USER
|
||||
# DISTROBOX_ENTER_PATH
|
||||
# DISTROBOX_HOST_HOME
|
||||
|
||||
# Ensure we have our env variables correctly set
|
||||
[ -z "${USER}" ] && USER="$(id -run)"
|
||||
[ -z "${HOME}" ] && HOME="$(getent passwd "${USER}" | cut -d':' -f6)"
|
||||
[ -z "${SHELL}" ] && SHELL="$(getent passwd "${USER}" | cut -d':' -f7)"
|
||||
|
||||
# Defaults
|
||||
container_name="${CONTAINER_ID:-}"
|
||||
[ -z "${container_name}" ] && container_name="$(grep "name=" /run/.containerenv | cut -d'=' -f2- | tr -d '"')"
|
||||
export_action=""
|
||||
exported_app=""
|
||||
exported_app_label=""
|
||||
exported_bin=""
|
||||
exported_delete=0
|
||||
extra_flags=""
|
||||
enter_flags=""
|
||||
# Use DBX_HOST_HOME if defined, else fallback to HOME
|
||||
# DBX_HOST_HOME is set in case container is created
|
||||
# with custom --home directory
|
||||
host_home="${DISTROBOX_HOST_HOME:-"${HOME}"}"
|
||||
dest_path="${DISTROBOX_EXPORT_PATH:-${host_home}/.local/bin}"
|
||||
is_sudo=0
|
||||
rootful=""
|
||||
sudo_prefix=""
|
||||
verbose=0
|
||||
version="1.8.2.4"
|
||||
|
||||
sudo_askpass_path="${dest_path}/distrobox_sudo_askpass"
|
||||
sudo_askpass_script="#!/bin/sh
|
||||
if command -v zenity 2>&1 > /dev/null; then
|
||||
zenity --password
|
||||
elif command -v kdialog 2>&1 > /dev/null; then
|
||||
kdialog --password 'A password is required...'
|
||||
else
|
||||
exit 127
|
||||
fi"
|
||||
|
||||
# We depend on some commands, let's be sure we have them
|
||||
base_dependencies="basename find grep sed"
|
||||
for dep in ${base_dependencies}; do
|
||||
if ! command -v "${dep}" > /dev/null; then
|
||||
printf >&2 "Missing dependency: %s\n" "${dep}"
|
||||
exit 127
|
||||
fi
|
||||
done
|
||||
|
||||
# show_help will print usage to stdout.
|
||||
# Arguments:
|
||||
# None
|
||||
# Expected global variables:
|
||||
# version: distrobox version
|
||||
# Expected env variables:
|
||||
# None
|
||||
# Outputs:
|
||||
# print usage with examples.
|
||||
show_help()
|
||||
{
|
||||
cat << EOF
|
||||
distrobox version: ${version}
|
||||
|
||||
Usage:
|
||||
|
||||
distrobox-export --app mpv [--extra-flags "flags"] [--enter-flags "flags"] [--delete] [--sudo]
|
||||
distrobox-export --bin /path/to/bin [--export-path ~/.local/bin] [--extra-flags "flags"] [--enter-flags "flags"] [--delete] [--sudo]
|
||||
|
||||
Options:
|
||||
|
||||
--app/-a: name of the application to export or absolute path to desktopfile to export
|
||||
--bin/-b: absolute path of the binary to export
|
||||
--list-apps: list applications exported from this container
|
||||
--list-binaries: list binaries exported from this container, use -ep to specify custom paths to search
|
||||
--delete/-d: delete exported application or binary
|
||||
--export-label/-el: label to add to exported application name.
|
||||
Use "none" to disable.
|
||||
Defaults to (on \$container_name)
|
||||
--export-path/-ep: path where to export the binary
|
||||
--extra-flags/-ef: extra flags to add to the command
|
||||
--enter-flags/-nf: flags to add to distrobox-enter
|
||||
--sudo/-S: specify if the exported item should be run as sudo
|
||||
--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)
|
||||
shift
|
||||
verbose=1
|
||||
;;
|
||||
-V | --version)
|
||||
printf "distrobox: %s\n" "${version}"
|
||||
exit 0
|
||||
;;
|
||||
-a | --app)
|
||||
if [ -n "$2" ]; then
|
||||
export_action="app"
|
||||
exported_app="$2"
|
||||
shift
|
||||
shift
|
||||
fi
|
||||
;;
|
||||
-b | --bin)
|
||||
if [ -n "$2" ]; then
|
||||
export_action="bin"
|
||||
exported_bin="$2"
|
||||
shift
|
||||
shift
|
||||
fi
|
||||
;;
|
||||
--list-apps)
|
||||
export_action="list-apps"
|
||||
exported_bin="null"
|
||||
shift
|
||||
;;
|
||||
--list-binaries)
|
||||
export_action="list-binaries"
|
||||
exported_bin="null"
|
||||
shift
|
||||
;;
|
||||
-S | --sudo)
|
||||
is_sudo=1
|
||||
shift
|
||||
;;
|
||||
-el | --export-label)
|
||||
if [ -n "$2" ]; then
|
||||
exported_app_label="$2"
|
||||
shift
|
||||
shift
|
||||
fi
|
||||
;;
|
||||
-ep | --export-path)
|
||||
if [ -n "$2" ]; then
|
||||
dest_path="$2"
|
||||
shift
|
||||
shift
|
||||
fi
|
||||
;;
|
||||
-ef | --extra-flags)
|
||||
if [ -n "$2" ]; then
|
||||
extra_flags="$2"
|
||||
shift
|
||||
shift
|
||||
fi
|
||||
;;
|
||||
-nf | --enter-flags)
|
||||
if [ -n "$2" ]; then
|
||||
enter_flags="$2"
|
||||
shift
|
||||
shift
|
||||
fi
|
||||
;;
|
||||
-d | --delete)
|
||||
exported_delete=1
|
||||
shift
|
||||
;;
|
||||
-*) # Invalid options.
|
||||
printf >&2 "ERROR: Invalid flag '%s'\n\n" "$1"
|
||||
show_help
|
||||
exit 1
|
||||
;;
|
||||
*) # 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
|
||||
|
||||
# Ensure we can write stuff there
|
||||
if [ ! -e "${dest_path}" ]; then
|
||||
mkdir -p "${dest_path}"
|
||||
fi
|
||||
|
||||
# Check we're running inside a container and not on the host.
|
||||
if [ ! -f /run/.containerenv ] && [ ! -f /.dockerenv ] && [ -z "${container:-}" ]; then
|
||||
printf >&2 "You must run %s inside a container!\n" " $(basename "$0")"
|
||||
exit 126
|
||||
fi
|
||||
|
||||
# Check if we're in a rootful or rootless container.
|
||||
if grep -q "rootless=0" /run/.containerenv 2> /dev/null; then
|
||||
rootful="--root"
|
||||
|
||||
# We need an askpass script for SUDO_ASKPASS, to launch graphical apps
|
||||
# from the drawer
|
||||
if [ ! -e "${sudo_askpass_path}" ]; then
|
||||
echo "${sudo_askpass_script}" > "${sudo_askpass_path}"
|
||||
chmod +x "${sudo_askpass_path}"
|
||||
fi
|
||||
fi
|
||||
|
||||
# We're working with HOME, so we must run as USER, not as root.
|
||||
if [ "$(id -u)" -eq 0 ]; then
|
||||
printf >&2 "You must not run %s as root!\n" " $(basename "$0")"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Ensure we're not receiving more than one action at time.
|
||||
if [ -n "${exported_app}" ] && [ -n "${exported_bin}" ]; then
|
||||
printf >&2 "Error: Invalid arguments, choose only one action below.\n"
|
||||
printf >&2 "Error: You can only export one thing at time.\n"
|
||||
exit 2
|
||||
fi
|
||||
|
||||
# Filter enter_flags and remove redundant options
|
||||
if [ -n "${enter_flags}" ]; then
|
||||
# shellcheck disable=SC2086
|
||||
set -- ${enter_flags}
|
||||
filtered_flags=""
|
||||
# Inform user that certain flags are redundant
|
||||
while [ $# -gt 0 ]; do
|
||||
case "$1" in
|
||||
--root | -r)
|
||||
printf >&2 "Warning: %s argument will be set automatically and should be removed.\n" "${1}"
|
||||
;;
|
||||
--name | -n)
|
||||
printf >&2 "Warning: %s argument will be set automatically and should be removed.\n" "${1}"
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
filtered_flags="${filtered_flags} $1"
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
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"
|
||||
if ! ${sudo_prefix} test > /dev/null 2>&1; then
|
||||
sudo_prefix="sudo"
|
||||
fi
|
||||
|
||||
# Edge case for systems with doas
|
||||
if command -v doas > /dev/null >&1; then
|
||||
sudo_prefix="doas"
|
||||
container_command_suffix="sh -l -c \"'${exported_bin}' ${extra_flags} \$@\""
|
||||
fi
|
||||
|
||||
# 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} "
|
||||
|
||||
if [ -n "${rootful}" ]; then
|
||||
container_command_prefix="env SUDO_ASKPASS=\"${sudo_askpass_path}\" DBX_SUDO_PROGRAM=\"sudo --askpass\" ${container_command_prefix}"
|
||||
fi
|
||||
|
||||
if [ -z "${exported_app_label}" ]; then
|
||||
exported_app_label=" (on ${container_name})"
|
||||
elif [ "${exported_app_label}" = "none" ]; then
|
||||
exported_app_label=""
|
||||
else
|
||||
# Add a leading space so that we can have "NAME LABEL" in the entry
|
||||
exported_app_label=" ${exported_app_label}"
|
||||
fi
|
||||
|
||||
# generate_script will generate a script from template. This script will wrap the
|
||||
# exported binary in order to ensure it will be executed in the right container.
|
||||
# Arguments:
|
||||
# None
|
||||
# Expected global 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 export
|
||||
# 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
|
||||
# Expected env variables:
|
||||
# None
|
||||
# Outputs:
|
||||
# print generated script.
|
||||
generate_script()
|
||||
{
|
||||
cat << EOF
|
||||
#!/bin/sh
|
||||
# distrobox_binary
|
||||
# name: ${container_name}
|
||||
if [ -z "\${CONTAINER_ID}" ]; then
|
||||
exec "${DISTROBOX_ENTER_PATH:-"distrobox-enter"}" ${rootful} -n ${container_name} ${enter_flags} -- ${sudo_prefix} ${container_command_suffix}
|
||||
elif [ -n "\${CONTAINER_ID}" ] && [ "\${CONTAINER_ID}" != "${container_name}" ]; then
|
||||
exec distrobox-host-exec '${dest_path}/$(basename "${exported_bin}")' "\$@"
|
||||
else
|
||||
exec ${sudo_prefix} '${exported_bin}' "\$@"
|
||||
fi
|
||||
EOF
|
||||
return $?
|
||||
}
|
||||
|
||||
# export_binary will export selected binary to destination directory.
|
||||
# the following function will use generate_script to create a shell script in
|
||||
# dest_path that will execute the exported binary in the selected distrobox.
|
||||
#
|
||||
# Arguments:
|
||||
# None
|
||||
# Expected global 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 export
|
||||
# exported_delete: bool delete the binary exported
|
||||
# Expected env variables:
|
||||
# None
|
||||
# Outputs:
|
||||
# a generated_script in dest_path
|
||||
# or error code.
|
||||
export_binary()
|
||||
{
|
||||
# Ensure the binary we're exporting is installed
|
||||
if [ ! -f "${exported_bin}" ]; then
|
||||
printf >&2 "Error: cannot find %s.\n" "${exported_bin}"
|
||||
return 127
|
||||
fi
|
||||
# generate dest_file path
|
||||
dest_file="${dest_path}/$(basename "${exported_bin}")"
|
||||
|
||||
# create the binary destination path if it doesn't exist
|
||||
mkdir -p "${dest_path}"
|
||||
|
||||
# If we're deleting it, just do it and exit
|
||||
if [ "${exported_delete}" -ne 0 ]; then
|
||||
# ensure it's a distrobox exported binary
|
||||
if ! grep -q "distrobox_binary" "${dest_file}"; then
|
||||
printf >&2 "Error: %s is not exported.\n" "${exported_bin}"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if rm -f "${dest_file}"; then
|
||||
printf "%s from %s removed successfully from %s.\nOK!\n" \
|
||||
"${exported_bin}" "${container_name}" "${dest_path}"
|
||||
return 0
|
||||
fi
|
||||
return 1
|
||||
fi
|
||||
|
||||
# test if we have writing rights on the file
|
||||
if ! touch "${dest_file}"; then
|
||||
printf >&2 "Error: cannot create destination file %s.\n" "${dest_file}"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# create the script from template and write to file
|
||||
if generate_script > "${dest_file}"; then
|
||||
chmod +x "${dest_file}"
|
||||
printf "%s from %s exported successfully in %s.\nOK!\n" \
|
||||
"${exported_bin}" "${container_name}" "${dest_path}"
|
||||
return 0
|
||||
fi
|
||||
# Unknown error.
|
||||
return 3
|
||||
}
|
||||
|
||||
# export_application will export input graphical application to the host.
|
||||
# the following function will scan the distrobox for desktop and icon files for
|
||||
# the selected application. It will then put the needed icons in the host's icons
|
||||
# directory and create a new .desktop file that will execute the selected application
|
||||
# in the distrobox.
|
||||
#
|
||||
# Arguments:
|
||||
# None
|
||||
# Expected global 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
|
||||
# Expected env variables:
|
||||
# None
|
||||
# Outputs:
|
||||
# needed icons in /run/host/$host_home/.local/share/icons
|
||||
# needed desktop files in /run/host/$host_home/.local/share/applications
|
||||
# or error code.
|
||||
export_application()
|
||||
{
|
||||
canon_dirs=""
|
||||
|
||||
# In case we're explicitly going for a full desktopfile path
|
||||
if [ -e "${exported_app}" ]; then
|
||||
desktop_files="${exported_app}"
|
||||
else
|
||||
IFS=":"
|
||||
if [ -n "${XDG_DATA_DIRS}" ]; then
|
||||
for xdg_data_dir in ${XDG_DATA_DIRS}; do
|
||||
[ -d "${xdg_data_dir}/applications" ] && canon_dirs="${canon_dirs} ${xdg_data_dir}/applications"
|
||||
done
|
||||
else
|
||||
[ -d /usr/share/applications ] && canon_dirs="/usr/share/applications"
|
||||
[ -d /usr/local/share/applications ] && canon_dirs="${canon_dirs} /usr/local/share/applications"
|
||||
[ -d /var/lib/flatpak/exports/share/applications ] && canon_dirs="${canon_dirs} /var/lib/flatpak/exports/share/applications"
|
||||
fi
|
||||
if [ -n "${XDG_DATA_HOME}" ]; then
|
||||
[ -d "${XDG_DATA_HOME}/applications" ] && canon_dirs="${canon_dirs} ${XDG_DATA_HOME}/applications"
|
||||
else
|
||||
[ -d "${HOME}/.local/share/applications" ] && canon_dirs="${canon_dirs} ${HOME}/.local/share/applications"
|
||||
fi
|
||||
unset IFS
|
||||
|
||||
# In this phase we search for applications to export.
|
||||
# First find command will grep through all files in the canonical directories
|
||||
# and only list files that contain the $exported_app, excluding those that
|
||||
# already contains a distrobox-enter command. So skipping already exported apps.
|
||||
# Second find will list all files that contain the name specified, so that
|
||||
# it is possible to export an app not only by its executable name but also
|
||||
# by its launcher name.
|
||||
desktop_files=$(
|
||||
# shellcheck disable=SC2086
|
||||
find ${canon_dirs} -type f -print -o -type l -print | sed 's/./\\&/g' |
|
||||
xargs -I{} grep -l -e "Exec=.*${exported_app}.*" -e "Name=.*${exported_app}.*" "{}" | sed 's/./\\&/g' |
|
||||
xargs -I{} grep -L -e "Exec=.*${DISTROBOX_ENTER_PATH:-"distrobox.*enter"}.*" "{}" | sed 's/./\\&/g' |
|
||||
xargs -I{} printf "%s¤" "{}"
|
||||
)
|
||||
fi
|
||||
|
||||
# Ensure the app we're exporting is installed
|
||||
# Check that we found some desktop files first.
|
||||
if [ -z "${desktop_files}" ]; then
|
||||
printf >&2 "Error: cannot find any desktop files.\n"
|
||||
printf >&2 "Error: trying to export a non-installed application.\n"
|
||||
return 127
|
||||
fi
|
||||
|
||||
# Find icons by using the Icon= specification. If it's only a name, we'll
|
||||
# search for the file, if it's already a path, just grab it.
|
||||
icon_files=""
|
||||
IFS="¤"
|
||||
for desktop_file in ${desktop_files}; do
|
||||
if [ -z "${desktop_file}" ]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
icon_name="$(grep Icon= "${desktop_file}" | cut -d'=' -f2- | paste -sd "¤" -)"
|
||||
|
||||
for icon in ${icon_name}; do
|
||||
if case "${icon_name}" in "/"*) true ;; *) false ;; esac &&
|
||||
[ -e "${icon_name}" ]; then
|
||||
# In case it's an hard path, conserve it and continue
|
||||
icon_files="${icon_files}¤${icon_name}"
|
||||
else
|
||||
# If it's not an hard path, find all files in the canonical paths.
|
||||
icon_files="${icon_files}¤$(find \
|
||||
/usr/share/icons \
|
||||
/usr/share/pixmaps \
|
||||
/var/lib/flatpak/exports/share/icons -iname "*${icon}*" \
|
||||
-printf "%p¤" 2> /dev/null || :)"
|
||||
fi
|
||||
done
|
||||
|
||||
# remove leading delimiter
|
||||
icon_files=${icon_files#¤}
|
||||
done
|
||||
|
||||
# create applications dir if not existing
|
||||
mkdir -p "/run/host${host_home}/.local/share/applications"
|
||||
|
||||
# copy icons in home directory
|
||||
icon_file_absolute_path=""
|
||||
IFS="¤"
|
||||
for icon_file in ${icon_files}; do
|
||||
if [ -z "${icon_file}" ]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
# replace canonical paths with equivalent paths in HOME
|
||||
icon_home_directory="$(dirname "${icon_file}" |
|
||||
sed "s|/usr/share/|\/run\/host\/${host_home}/.local/share/|g" |
|
||||
sed "s|/var/lib/flatpak/exports/share|\/run\/host\/${host_home}/.local/share/|g" |
|
||||
sed "s|pixmaps|icons|g")"
|
||||
|
||||
# check if we're exporting an icon which is not in a canonical path
|
||||
if [ "${icon_home_directory}" = "$(dirname "${icon_file}")" ]; then
|
||||
icon_home_directory="${host_home}/.local/share/icons/"
|
||||
icon_file_absolute_path="${icon_home_directory}$(basename "${icon_file}")"
|
||||
fi
|
||||
|
||||
# check if we're exporting or deleting
|
||||
if [ "${exported_delete}" -ne 0 ]; then
|
||||
# we need to remove, not export
|
||||
rm -rf "${icon_home_directory:?}"/"$(basename "${icon_file:?}")"
|
||||
continue
|
||||
fi
|
||||
|
||||
# we wanto to export the application's icons
|
||||
mkdir -p "${icon_home_directory}"
|
||||
if [ ! -e "${icon_home_directory}/$(basename "${icon_file}")" ] && [ -e "$(realpath "${icon_file}")" ]; then
|
||||
cp -rf "$(realpath "${icon_file}")" "${icon_home_directory}"
|
||||
fi
|
||||
done
|
||||
|
||||
# create desktop files for the distrobox
|
||||
IFS="¤"
|
||||
for desktop_file in ${desktop_files}; do
|
||||
if [ -z "${desktop_file}" ]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
desktop_original_file="$(basename "${desktop_file}")"
|
||||
desktop_home_file="${container_name}-$(basename "${desktop_file}")"
|
||||
|
||||
# check if we're exporting or deleting
|
||||
if [ "${exported_delete}" -ne 0 ]; then
|
||||
rm -f "/run/host${host_home}/.local/share/applications/${desktop_original_file}"
|
||||
rm -f "/run/host${host_home}/.local/share/applications/${desktop_home_file}"
|
||||
# we're done, go to next
|
||||
continue
|
||||
fi
|
||||
|
||||
# Add command_prefix
|
||||
# Add extra flags
|
||||
# Add closing quote
|
||||
# If a TryExec is present, we have to fake it as it will not work
|
||||
# through the container separation
|
||||
sed "s|^Exec=\(.*\)|Exec=${container_command_prefix} \1 |g" "${desktop_file}" |
|
||||
sed "s|\(%.*\)|${extra_flags} \1|g" |
|
||||
sed "/^TryExec=.*/d" |
|
||||
sed "/^DBusActivatable=true/d" |
|
||||
sed "s|Name.*|&${exported_app_label}|g" \
|
||||
> "/run/host${host_home}/.local/share/applications/${desktop_home_file}"
|
||||
# in the end we add the final quote we've opened in the "container_command_prefix"
|
||||
|
||||
if ! grep -q "StartupWMClass" "/run/host${host_home}/.local/share/applications/${desktop_home_file}"; then
|
||||
printf "StartupWMClass=%s\n" "${exported_app}" >> "\
|
||||
/run/host${host_home}/.local/share/applications/${desktop_home_file}"
|
||||
fi
|
||||
# In case of an icon in a non canonical path, we need to replace the path
|
||||
# in the desktop file.
|
||||
if [ -n "${icon_file_absolute_path}" ]; then
|
||||
sed -i "s|Icon=.*|Icon=${icon_file_absolute_path}|g" \
|
||||
"/run/host${host_home}/.local/share/applications/${desktop_home_file}"
|
||||
# we're done, go to next
|
||||
continue
|
||||
fi
|
||||
|
||||
# In case of an icon in a canonical path, but specified as an absolute
|
||||
# we need to replace the path in the desktop file.
|
||||
sed -i "s|Icon=/usr/share/|Icon=/run/host${host_home}/.local/share/|g" \
|
||||
"/run/host${host_home}/.local/share/applications/${desktop_home_file}"
|
||||
sed -i "s|pixmaps|icons|g" \
|
||||
"/run/host${host_home}/.local/share/applications/${desktop_home_file}"
|
||||
done
|
||||
|
||||
# Update the desktop files database to ensure exported applications will
|
||||
# show up in the taskbar/desktop menu/whatnot right after running this
|
||||
# script.
|
||||
/usr/bin/distrobox-host-exec --yes update-desktop-database "${host_home}/.local/share/applications" > /dev/null 2>&1 || :
|
||||
|
||||
if [ "${exported_delete}" -ne 0 ]; then
|
||||
printf "Application %s successfully un-exported.\nOK!\n" "${exported_app}"
|
||||
printf "%s will disappear from your applications list in a few seconds.\n" "${exported_app}"
|
||||
else
|
||||
printf "Application %s successfully exported.\nOK!\n" "${exported_app}"
|
||||
printf "%s will appear in your applications list in a few seconds.\n" "${exported_app}"
|
||||
fi
|
||||
}
|
||||
|
||||
# list_exported_applications will print all exported applications in canonical directories.
|
||||
# the following function will list exported desktop files from this container.
|
||||
#
|
||||
# Arguments:
|
||||
# None
|
||||
# Expected global variables:
|
||||
# host_home: home path ofr the host, where to search desktop files
|
||||
# CONTAINER_ID: id of the current container
|
||||
# Expected env variables:
|
||||
# None
|
||||
# Outputs:
|
||||
# a list of exported apps
|
||||
# or error code.
|
||||
list_exported_applications()
|
||||
{
|
||||
# In this phase we search for applications exported.
|
||||
# First find command will grep through all files in the canonical directories
|
||||
# and only list files that contain the $DISTROBOX_ENTER_PATH.
|
||||
desktop_files=$(
|
||||
# shellcheck disable=SC2086
|
||||
find "/run/host${host_home}/.local/share/applications" -type f -print -o -type l -print 2> /dev/null | sed 's/./\\&/g' |
|
||||
xargs -I{} grep -l -e "Exec=.*${DISTROBOX_ENTER_PATH:-"distrobox.*enter"}.*" "{}" | sed 's/./\\&/g' |
|
||||
xargs -I{} printf "%s¤" "{}"
|
||||
)
|
||||
|
||||
# Then we try to pretty print them.
|
||||
IFS="¤"
|
||||
for i in ${desktop_files}; do
|
||||
if [ -z "${i}" ]; then
|
||||
continue
|
||||
fi
|
||||
# Get app name, and remove label
|
||||
name="$(grep -Eo 'Name=.*' "${i}" | head -n 1 | cut -d'=' -f2- | sed 's|(.*)||g')"
|
||||
# Print only stuff we exported from this box!
|
||||
if echo "${i}" | grep -q "${CONTAINER_ID}"; then
|
||||
printf "%-20s | %-30s\n" "${name}" "${i}"
|
||||
fi
|
||||
done
|
||||
unset IFS
|
||||
}
|
||||
|
||||
# list_exported_binaries will print all exported binaries.
|
||||
# the following function will list exported desktop files from this container.
|
||||
# If no export-path is specified, it searches in the default path.
|
||||
#
|
||||
# Arguments:
|
||||
# None
|
||||
# Expected global variables:
|
||||
# dest_path: destination path where to search binaries
|
||||
# CONTAINER_ID: id of the current container
|
||||
# Expected env variables:
|
||||
# None
|
||||
# Outputs:
|
||||
# a list of exported apps
|
||||
# or error code.
|
||||
list_exported_binaries()
|
||||
{
|
||||
# In this phase we search for binaries exported.
|
||||
# First find command will grep through all files in the canonical directories
|
||||
# and only list files that contain the comment "# distrobox_binary".
|
||||
binary_files=$(
|
||||
find "${dest_path}" -type f -print 2> /dev/null | sed 's/./\\&/g' |
|
||||
xargs -I{} grep -l -e "^# distrobox_binary" "{}" | sed 's/./\\&/g' |
|
||||
xargs -I{} printf "%s¤" "{}"
|
||||
)
|
||||
|
||||
# Then we try to pretty print them.
|
||||
IFS="¤"
|
||||
for i in ${binary_files}; do
|
||||
if [ -z "${i}" ]; then
|
||||
continue
|
||||
fi
|
||||
# Get original binary name
|
||||
name="$(grep -B1 "fi" "${i}" | grep exec | cut -d' ' -f2)"
|
||||
# Print only stuff we exported from this box!
|
||||
if grep "^# name:.*" "${i}" | grep -q "${CONTAINER_ID}"; then
|
||||
printf "%-20s | %-30s\n" "${name}" "${i}"
|
||||
fi
|
||||
done
|
||||
unset IFS
|
||||
}
|
||||
|
||||
# Main routine
|
||||
case "${export_action}" in
|
||||
app)
|
||||
export_application
|
||||
;;
|
||||
bin)
|
||||
export_binary
|
||||
;;
|
||||
list-apps)
|
||||
list_exported_applications
|
||||
;;
|
||||
list-binaries)
|
||||
list_exported_binaries
|
||||
;;
|
||||
*)
|
||||
printf >&2 "Invalid arguments, choose an action below.\n"
|
||||
show_help
|
||||
exit 2
|
||||
;;
|
||||
esac
|
||||
@@ -1,234 +0,0 @@
|
||||
#!/bin/sh
|
||||
# SPDX-License-Identifier: GPL-3.0-only
|
||||
#
|
||||
# This file is part of the distrobox project:
|
||||
# https://github.com/89luca89/distrobox
|
||||
#
|
||||
# Copyright (C) 2022 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/>.
|
||||
|
||||
# Ensure we have our env variables correctly set
|
||||
[ -z "${USER}" ] && USER="$(id -run)"
|
||||
[ -z "${HOME}" ] && HOME="$(getent passwd "${USER}" | cut -d':' -f6)"
|
||||
[ -z "${SHELL}" ] && SHELL="$(getent passwd "${USER}" | cut -d':' -f7)"
|
||||
|
||||
# Defaults
|
||||
host_command=""
|
||||
non_interactive=0
|
||||
# If we're in a non-interactive shell, let's act accordingly
|
||||
if [ ! -t 1 ] ||
|
||||
! tty > /dev/null 2>&1; then
|
||||
non_interactive=1
|
||||
fi
|
||||
distrobox_host_exec_default_command="${SHELL:-/bin/sh}"
|
||||
host_spawn_version="v1.6.0"
|
||||
download_command=""
|
||||
sudo_command=""
|
||||
verbose=0
|
||||
version="1.8.2.4"
|
||||
|
||||
# show_help will print usage to stdout.
|
||||
# Arguments:
|
||||
# None
|
||||
# Expected global variables:
|
||||
# version: distrobox version
|
||||
# Expected env variables:
|
||||
# None
|
||||
# Outputs:
|
||||
# print usage with examples.
|
||||
show_help()
|
||||
{
|
||||
cat << EOF
|
||||
distrobox version: ${version}
|
||||
|
||||
Usage:
|
||||
|
||||
distrobox-host-exec [command [arguments]]
|
||||
distrobox-host-exec ls
|
||||
distrobox-host-exec bash -l
|
||||
distrobox-host-exec flatpak run org.mozilla.firefox
|
||||
distrobox-host-exec podman ps -a
|
||||
|
||||
|
||||
Options:
|
||||
|
||||
--help/-h: show this message
|
||||
--verbose/-v: show more verbosity
|
||||
--version/-V: show version
|
||||
--yes/-Y: Automatically answer yes to prompt:
|
||||
host-spawn will be installed on the guest system
|
||||
if host-spawn is not detected.
|
||||
This behaviour is default when running in a non-interactive shell.
|
||||
EOF
|
||||
}
|
||||
|
||||
# If we're a symlink to a command, use that as command to exec, and skip arg parsing.
|
||||
if [ "$(basename "${0}")" != "distrobox-host-exec" ]; then
|
||||
host_command="$(basename "${0}")"
|
||||
fi
|
||||
# Parse arguments
|
||||
if [ -z "${host_command}" ]; then
|
||||
# Skip argument parsing if we're a symlink
|
||||
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}"
|
||||
printf "host-spawn: %s\n" "${host_spawn_version}"
|
||||
exit 0
|
||||
;;
|
||||
-Y | --yes)
|
||||
non_interactive=1
|
||||
shift
|
||||
;;
|
||||
--) # End of all options.
|
||||
shift
|
||||
;;
|
||||
-*) # Invalid options.
|
||||
printf >&2 "ERROR: Invalid flag '%s'\n\n" "$1"
|
||||
show_help
|
||||
exit 1
|
||||
;;
|
||||
*)
|
||||
if [ -n "$1" ]; then
|
||||
host_command=$1
|
||||
shift
|
||||
fi
|
||||
break
|
||||
;;
|
||||
esac
|
||||
done
|
||||
fi
|
||||
|
||||
set -o errexit
|
||||
set -o nounset
|
||||
# set verbosity
|
||||
if [ "${verbose}" -ne 0 ]; then
|
||||
set -o xtrace
|
||||
fi
|
||||
|
||||
# Check we're running inside a container and not on the host
|
||||
if [ ! -f /run/.containerenv ] && [ ! -f /.dockerenv ] && [ -z "${container:-}" ]; then
|
||||
printf >&2 "You must run %s inside a container!\n" " $(basename "$0")"
|
||||
exit 126
|
||||
fi
|
||||
|
||||
if [ -z "${host_command}" ]; then
|
||||
host_command="${distrobox_host_exec_default_command}"
|
||||
fi
|
||||
|
||||
if [ "$(id -ru)" -ne 0 ]; then
|
||||
if command -v sudo 2> /dev/null > /dev/null; then
|
||||
sudo_command="sudo"
|
||||
else
|
||||
sudo_command="su -l -c"
|
||||
fi
|
||||
fi
|
||||
|
||||
if command -v curl > /dev/null 2>&1; then
|
||||
download_command="curl -sLfo"
|
||||
elif command -v wget > /dev/null 2>&1; then
|
||||
download_command="wget -qO"
|
||||
fi
|
||||
|
||||
# Normalize architecture name to comply to golang/release naming
|
||||
architecture="$(uname -m)"
|
||||
if echo "${architecture}" | grep -q armv; then
|
||||
architecture="$(echo "${architecture}" | grep -Eo "armv[0-9]+")"
|
||||
fi
|
||||
|
||||
# Setup host-spawn as a way to execute commands back on the host
|
||||
if ! command -v host-spawn > /dev/null ||
|
||||
[ "$(printf "%s\n%s\n" "${host_spawn_version}" "$(host-spawn --version)" |
|
||||
sort -V | head -n 1)" != "${host_spawn_version}" ]; then
|
||||
|
||||
# if non-interactive flag flag hasn't been set
|
||||
if [ "${non_interactive}" -eq 0 ]; then
|
||||
# Prompt to download it.
|
||||
printf "Warning: host-spawn not found or version is too old!\n"
|
||||
printf "Do you want to install host-spawn utility? [Y/n] "
|
||||
read -r response
|
||||
response=${response:-"Y"}
|
||||
else
|
||||
response="yes"
|
||||
fi
|
||||
# Accept only y,Y,Yes,yes,n,N,No,no.
|
||||
case "${response}" in
|
||||
y | Y | Yes | yes | YES)
|
||||
# Download matching version with current distrobox
|
||||
if ! ${download_command} /tmp/host-spawn \
|
||||
"https://github.com/1player/host-spawn/releases/download/${host_spawn_version}/host-spawn-${architecture}"; then
|
||||
|
||||
printf "Error: Cannot download host-spawn\n"
|
||||
exit 1
|
||||
fi
|
||||
if [ -e /tmp/host-spawn ]; then
|
||||
${sudo_command} sh -c "mv /tmp/host-spawn /usr/bin/"
|
||||
${sudo_command} sh -c "chmod +x /usr/bin/host-spawn"
|
||||
fi
|
||||
;;
|
||||
n | N | No | no | NO)
|
||||
printf "Installation aborted, please install host-spawn.\n"
|
||||
exit 0
|
||||
;;
|
||||
*) # Default case: If no more options then break out of the loop.
|
||||
printf >&2 "Invalid input.\n"
|
||||
printf >&2 "The available choices are: y,Y,Yes,yes,YES or n,N,No,no,NO.\nExiting.\n"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
fi
|
||||
|
||||
# This makes host-spawn work on initful containers, where the dbus session is
|
||||
# separate from the host, we point the dbus session straight to the host's socket
|
||||
# in order to talk with the org.freedesktop.Flatpak.Development.HostCommand on the host
|
||||
[ -z "${XDG_RUNTIME_DIR:-}" ] && XDG_RUNTIME_DIR="/run/user/$(id -ru)"
|
||||
[ -z "${DBUS_SESSION_BUS_ADDRESS:-}" ] && DBUS_SESSION_BUS_ADDRESS="unix:path=/run/user/$(id -ru)/bus"
|
||||
XDG_RUNTIME_DIR="/run/host/${XDG_RUNTIME_DIR}"
|
||||
DBUS_SESSION_BUS_ADDRESS="unix:path=/run/host/$(echo "${DBUS_SESSION_BUS_ADDRESS}" | cut -d '=' -f2-)"
|
||||
|
||||
###
|
||||
# This workaround is needed because of a bug in gio (used by xdg-open) where
|
||||
# a race condition happens when allocating a pty, leading to the command
|
||||
# being killed before having time to be executed.
|
||||
#
|
||||
# https://gitlab.gnome.org/GNOME/glib/-/issues/2695
|
||||
# https://github.com/1player/host-spawn/issues/7
|
||||
#
|
||||
# As an (ugly) workaround, we will not allocate a pty for those commands.
|
||||
###
|
||||
# Also, we don't initialize a pty, if we're not in a tty.
|
||||
if [ "$(basename "${host_command}")" = "xdg-open" ] ||
|
||||
[ "$(basename "${host_command}")" = "gio" ] ||
|
||||
[ "$(basename "${host_command}")" = "flatpak" ] ||
|
||||
[ ! -t 1 ] ||
|
||||
! tty > /dev/null 2>&1; then
|
||||
|
||||
host-spawn --no-pty "${host_command}" "$@"
|
||||
# Exit here, we don't continue execution
|
||||
exit $?
|
||||
fi
|
||||
|
||||
host-spawn "${host_command}" "$@"
|
||||
# Exit here, we don't continue execution
|
||||
exit $?
|
||||
File diff suppressed because it is too large.
Load diff
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Reference in new issue
Block a user