[
  {
    "path": ".gitattributes",
    "content": "* text=auto eol=lf\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/bug_report.md",
    "content": "---\nname: Bug report\nabout: Create a report to help us improve\ntitle: \"[Error]\"\nlabels: bug\nassignees: ''\n\n---\n\nPlease, before opening a bug:\n\n- make sure you've read the documentation.\n- Ensure there isn't already an open issue about this.\n- Ensure there isn't already a closed/resolved issue about this.\n\n**Describe the bug**\nA clear and concise description of what the bug is.\n\n**To Reproduce**\nSteps to reproduce the behavior\n\n**Expected behavior**\nA clear and concise description of what you expected to happen.\n\n**Logs**\nRun the commands with `--verbose` and post the log here as a file upload\nAttach also the output of `podman logs` or `docker logs`, possibly with `--latest` flag\n\n**Desktop (please complete the following information):**\n\n- Are you using podman, docker or lilipod?\n- Which version or podman, docker or lilipod?\n- Which version of distrobox?\n- Which host distribution?\n- How did you install distrobox?\n\n**Additional context**\nAdd any other context about the problem here.\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/discussion-issue-template.md",
    "content": "---\nname: Discussion issue template\nabout: Describe this issue template's purpose here.\ntitle: \"[Discussion]\"\nlabels: question\nassignees: ''\n\n---\n\nIs your feature request related to a problem? Please describe.\nA clear and concise description of what the problem is. Ex. I'm always frustrated when [...]\n\nDescribe the solution you'd like\nA clear and concise description of what you want to happen.\n\nDescribe alternatives you've considered\nA clear and concise description of any alternative solutions or features you've considered.\n\nAdditional context\nAdd any other context or screenshots about the feature request here.\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/feature_request.md",
    "content": "---\nname: Feature request\nabout: Suggest an idea for this project\ntitle: \"[Suggestion]\"\nlabels: enhancement\nassignees: ''\n\n---\n\n**Is your feature request related to a problem? Please describe.**\nA clear and concise description of what the problem is. Ex. I'm always frustrated when [...]\n\n**Describe the solution you'd like**\nA clear and concise description of what you want to happen.\n\n**Describe alternatives you've considered**\nA clear and concise description of any alternative solutions or features you've considered.\n\n**Additional context**\nAdd any other context or screenshots about the feature request here.\n"
  },
  {
    "path": ".github/dependabot.yml",
    "content": "version: 2\nupdates:\n  - package-ecosystem: \"github-actions\"\n    directory: \"/\"\n    schedule:\n      interval: \"monthly\"\n"
  },
  {
    "path": ".github/workflows/compatibility.yml",
    "content": "---\n# This is a basic workflow to help you get started with Actions\n\nname: CI\n\n# Controls when the workflow will run\non:\n  # Triggers the workflow on push or pull request events but only for the master branch\n  push:\n    branches: [main]\n  pull_request:\n    branches: [main]\n    types: [opened, synchronize, ready_for_review, edited, labeled]\n\n  # Allows you to run this workflow manually from the Actions tab\n  workflow_dispatch:\n    inputs:\n      run_always:\n        description: 'Run even if no files are changed'\n        required: true\n        type: boolean\n# Check if we indeed modified distrobox stuff\njobs:\n  check_changes:\n    runs-on: ubuntu-latest\n    if: >-\n      contains( github.event.pull_request.labels.*.name, 'CI') ||\n      github.ref == 'refs/heads/main'\n    outputs:\n      distrobox_changed: ${{ steps.check_file_changed.outputs.distrobox_changed }}\n    steps:\n\n      - uses: actions/checkout@v6\n        with:\n          # Checkout as many commits as needed for the diff\n          fetch-depth: 2\n\n      # Fetch from compatibility table all the distros supported\n      - id: check_file_changed\n        run: |\n          if git diff --name-only HEAD^ HEAD | grep -Ev \"host-exec|generate-entry|ephemeral|upgrade\" | grep -E \"^distrobox|compatibility.md\"; then\n            echo \"::set-output name=distrobox_changed::True\"\n          else\n            echo \"::set-output name=distrobox_changed::False\"\n          fi\n\n  # Prepare distros matrix\n  setup:\n    runs-on: ubuntu-latest\n    needs: check_changes\n    outputs:\n      targets: ${{ steps.set-matrix.outputs.targets }}\n    if: >-\n      needs.check_changes.outputs.distrobox_changed == 'True' ||\n      github.event.inputs.run_always == 'True'\n    steps:\n\n      - uses: actions/checkout@v6\n\n      # Fetch from compatibility table all the distros supported\n      - id: set-matrix\n        run: |\n            skip_list=\"bazzite|chimera|slackware|stream8|ublue|neon|steamos\"\n\n            echo \"::set-output name=targets::$(sed -n -e '/| Alma/,/| Void/ p' docs/compatibility.md |\n            cut -d'|' -f 4 |\n            sed 's/<br>/\\n/g' |\n            tr -d ' ' |\n            sed '/^[[:space:]]*$/d' |\n            sort -u | grep -Ev \"${skip_list}\" |\n            jq -R -s -c 'split(\"\\n\")[:-1]')\"\n\n  run:\n    runs-on: ubuntu-latest\n    needs: setup\n    timeout-minutes: 30\n    strategy:\n      fail-fast: false\n      matrix:\n        distribution: ${{fromJSON(needs.setup.outputs.targets)}}\n        container_manager: [\"podman\"] #, \"docker\"]\n    env:\n      XDG_CACHE_HOME: \"/tmp/\"\n      DBX_CONTAINER_MANAGER: ${{ matrix.container_manager }}\n\n    steps:\n      # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it\n      - uses: actions/checkout@v6\n\n      # Ensure distrobox create works:\n      - name: Distrobox create\n        shell: 'script -q -e -c \"bash {0}\"'\n        run: |\n          image=${{ matrix.distribution }}\n          container_name=\"$(basename \"${image}\" | sed -E 's/[:.]/-/g')\"\n          ${DBX_CONTAINER_MANAGER} pull \"${image}\"\n          # ./distrobox create --yes --absolutely-disable-root-password-i-am-really-positively-sure -i \"${image}\" --name \"${container_name}\"\n          case \"${container_name}\" in\n            *init*)\n              echo \"SYSTEMD DETECTED: creating container with --init...\"\n              ./distrobox create --yes -i \"${image}\" --hostname \"${container_name}\" --name \"${container_name}\" --init --unshare-all\n              ;;\n            *)\n              ./distrobox create --yes -i \"${image}\" --hostname \"${container_name}\" --name \"${container_name}\"\n              ;;\n          esac\n\n      # Ensure distrobox enter and init works:\n      - name: Distrobox enter - init\n        shell: 'script -q -e -c \"bash {0}\"'\n        run: |\n          image=${{ matrix.distribution }}\n          container_name=\"$(basename \"${image}\" | sed -E 's/[:.]/-/g')\"\n          case \"${container_name}\" in\n            *init*)\n              echo \"SYSTEMD DETECTED: performing systemctl check...\"\n              ./distrobox enter --name \"${container_name}\" -- systemctl is-system-running | grep -E \"degraded|running|starting\"\n              ;;\n            *)\n              ./distrobox enter --name \"${container_name}\" -- whoami\n              ;;\n          esac\n\n      # Ensure distrobox enter and init works:\n      - name: Distrobox enter - user\n        shell: 'script -q -e -c \"bash {0}\"'\n        run: |\n          image=${{ matrix.distribution }}\n          container_name=\"$(basename \"${image}\" | sed -E 's/[:.]/-/g')\"\n          # Assert that distrobox exported binary indeed works\n          set -x\n          command_output=\"$(./distrobox enter --name \"${container_name}\" -- whoami | tr -d '\\r' | tr -d '^@')\"\n          expected_output=\"$(whoami)\"\n          if [ \"$command_output\" != \"$expected_output\" ]; then\n            exit 1\n          fi\n\n      # Ensure distrobox enter and init works:\n      - name: Distrobox enter - command\n        shell: 'script -q -e -c \"bash {0}\"'\n        run: |\n          image=${{ matrix.distribution }}\n          container_name=\"$(basename \"${image}\" | sed -E 's/[:.]/-/g')\"\n          # Assert that distrobox exported binary indeed works\n          set -x\n          command_output=\"$(./distrobox enter --name \"${container_name}\" -- uname -n | tr -d '\\r' | tr -d '^@')\"\n          expected_output=\"${container_name}\"\n          if [ \"$command_output\" != \"$expected_output\" ]; then\n            exit 1\n          fi\n\n      # Ensure distrobox export works:\n      - name: Distrobox export\n        shell: 'script -q -e -c \"bash {0}\"'\n        run: |\n          image=${{ matrix.distribution }}\n          container_name=\"$(basename \"${image}\" | sed -E 's/[:.]/-/g')\"\n          ./distrobox enter \"${container_name}\" -- distrobox-export --bin /bin/uname --export-path ${HOME}/\n          # Assert that distrobox exported binary indeed works\n          set -x\n          command_output=\"$(${HOME}/uname -n | tr -d '\\r' | tr -d '^@')\"\n          expected_output=\"${container_name}\"\n          if [ \"$command_output\" != \"$expected_output\" ]; then\n            exit 1\n          fi\n\n      # Ensure distrobox export works:\n      - name: Distrobox export - sudo\n        if: matrix.container_manager != 'docker'\n        shell: 'script -q -e -c \"bash {0}\"'\n        run: |\n          image=${{ matrix.distribution }}\n          container_name=\"$(basename \"${image}\" | sed -E 's/[:.]/-/g')\"\n          ./distrobox enter \"${container_name}\" -- distrobox-export --sudo --bin /bin/uname --export-path ${HOME}/\n          # Assert that distrobox exported binary indeed works\n          set -x\n          command_output=\"$(${HOME}/uname -n | tr -d '\\r' | tr -d '^@')\"\n          expected_output=\"${container_name}\"\n          if [ \"$command_output\" != \"$expected_output\" ]; then\n            exit 1\n          fi\n\n      # Ensure distrobox upgrade works:\n      - name: Distrobox upgrade\n        run: |\n          image=${{ matrix.distribution }}\n          container_name=\"$(basename \"${image}\" | sed -E 's/[:.]/-/g')\"\n          ./distrobox upgrade \"${container_name}\"\n\n      # Ensure distrobox list works:\n      - name: Distrobox list\n        run: |\n          image=${{ matrix.distribution }}\n          container_name=\"$(basename \"${image}\" | sed -E 's/[:.]/-/g')\"\n          ./distrobox list | grep \"${container_name}\" | grep \"${image}\" | grep -E \"Up|running\"\n\n      # Ensure distrobox stop works:\n      - name: Distrobox stop\n        run: |\n          image=${{ matrix.distribution }}\n          container_name=\"$(basename \"${image}\" | sed -E 's/[:.]/-/g')\"\n          ./distrobox stop --yes \"${container_name}\"\n\n      # Ensure distrobox rm works:\n      - name: Distrobox logs\n        if: ${{ always() }}\n        run: |\n          image=${{ matrix.distribution }}\n          container_name=\"$(basename \"${image}\" | sed -E 's/[:.]/-/g')\"\n          $DBX_CONTAINER_MANAGER logs \"${container_name}\"\n\n      # Ensure distrobox rm works:\n      - name: Distrobox rm\n        if: ${{ always() }}\n        run: |\n          image=${{ matrix.distribution }}\n          container_name=\"$(basename \"${image}\" | sed -E 's/[:.]/-/g')\"\n          ./distrobox rm --force \"${container_name}\"\n          $DBX_CONTAINER_MANAGER rmi -f \"${image}\"\n"
  },
  {
    "path": ".github/workflows/main.yml",
    "content": "# This is a basic workflow to help you get started with Actions\n\nname: Lint\n\n# Controls when the workflow will run\non:\n  # Triggers the workflow on push or pull request events but only for the main branch\n  push:\n    branches: [main]\n  pull_request:\n    branches: [main]\n    types: [opened, synchronize, ready_for_review, edited]\n\n  # Allows you to run this workflow manually from the Actions tab\n  workflow_dispatch:\n\njobs:\n  dash:\n    runs-on: ubuntu-latest\n\n    steps:\n      - uses: actions/checkout@v6\n\n      - name: Run dash -n\n        run: |\n          result=0\n          for file in $(find . -type f -not -path \"*.git*\" -a -not -path \"*completions*\"); do\n            if file \"$file\" | grep -qi shell; then\n              echo \"### Checking file $file...\"\n              dash -n $file\n              result=$(( result + $? ))\n            fi\n          done\n          exit $result\n\n  shfmt:\n    runs-on: ubuntu-latest\n\n    steps:\n      - uses: actions/checkout@v6\n\n      - name: Run shfmt\n        run: |\n          result=0\n          podman pull docker.io/peterdavehello/shfmt:latest\n          for file in $(find . -type f -not -path \"*.git*\"); do\n            if file \"$file\" | grep -qi shell; then\n              echo \"### Checking file $file...\"\n              podman run --rm -v \"$PWD:/mnt\" docker.io/peterdavehello/shfmt:latest shfmt -d -s -ci -sr -kp -fn -i=0 -p /mnt/$file\n              result=$(( result + $? ))\n            fi\n          done\n          exit $result\n\n\n  shellcheck:\n    runs-on: ubuntu-latest\n\n    steps:\n      - uses: actions/checkout@v6\n\n      # Exclude from bashate the following rules:\n      #   - SC2310 we don't want to exit if errors happen inside a check, that's why we have a check...\n      #   - SC2311 don't care if we inherit errexit inside substitutions, we do checks for that.\n      #   - SC2312 we already check errors and adding \"|| true\" everywhere hinders readability.\n      - name: Run shellcheck\n        run: |\n          result=0\n          podman pull docker.io/koalaman/shellcheck:stable\n          for file in $(find . -type f -name \".*\" -prune -o -print | grep -v '.git'); do\n            if file \"$file\" | grep -qi shell; then\n              echo \"### Checking file $file...\"\n              # Should read the .shellcheckrc file to behave like  -s sh -a -o all -Sstyle -Calways -x -e SC2310,SC2311,SC2312\n              podman run --rm -v \"$PWD:/mnt\" docker.io/koalaman/shellcheck:stable -a -Sstyle -Calways $file\n              result=$(( result + $? ))\n            fi\n          done\n          exit $result\n\n  differential-shellcheck:\n    runs-on: ubuntu-latest\n\n    permissions:\n      contents: read\n      security-events: write\n\n    steps:\n      - uses: actions/checkout@v6\n        with:\n          fetch-depth: 0\n\n      - name: Run Differential ShellCheck\n        uses: redhat-plumbers-in-action/differential-shellcheck@v5\n        with:\n          severity: style\n          token: ${{ secrets.GITHUB_TOKEN }}\n\n  bashate:\n    runs-on: ubuntu-latest\n\n    steps:\n      - uses: actions/checkout@v6\n      # Exclude from bashate the following rules:\n      #   - E002 we use tab indentation as suggested by shfmt.\n      #   - E003 we use tab indentation as suggested by shfmt.\n      #   - E010 for readability allow if/then and for/do to be on different lines.\n      #   - E011 for readability allow if/then and for/do to be on different lines.\n      - name: Run bashate\n        run: |\n          sudo pip3 install -U bashate\n          for file in $(find . -type f -not -path \"*.git*\"); do\n            if file \"$file\" | grep -qi shell; then\n              echo \"### Checking file $file...\"\n               bashate -i E002,E003,E010,E011 --max-line-length 120 $file\n              result=$(( result + $? ))\n            fi\n          done\n          exit $result\n\n  markdownlint:\n    runs-on: ubuntu-latest\n\n    steps:\n      - uses: actions/checkout@v6\n\n      - name: Run markdownlint\n        run: |\n          sudo npm install -g markdownlint-cli\n          markdownlint $(find . -name '*.md' | grep -vF './.git')\n\n  codespell:\n    runs-on: ubuntu-latest\n\n    steps:\n      - uses: actions/checkout@v6\n\n      - uses: codespell-project/actions-codespell@v2\n        with:\n          skip: .git,*.pdf,*.1,*.css,*.lock\n\n  shell-funcheck:\n    runs-on: ubuntu-latest\n\n    steps:\n      - uses: actions/checkout@v6\n\n      - name: Run shell-funcheck\n        run: |\n          curl -L -O https://github.com/89luca89/shell-funcheck/releases/download/v0.0.1/shell-funcheck-amd64\n          chmod +x ./shell-funcheck-amd64\n          for i in distrobox*; do\n          ./shell-funcheck-amd64 check \"$i\"\n          done\n"
  },
  {
    "path": ".github/workflows/manpages.yml",
    "content": "---\n# This is a basic workflow to help you get started with Actions\n\nname: Docs\n\n# Controls when the workflow will run\non:\n  # Triggers the workflow on push or pull request events but only for the master branch\n  push:\n    branches: [main]\n\n  # Allows you to run this workflow manually from the Actions tab\n  workflow_dispatch:\n\njobs:\n\n  # Check changes, cancel job is not.\n  check_changes:\n    runs-on: ubuntu-latest\n    outputs:\n      distrobox_changed: ${{ steps.check_file_changed.outputs.distrobox_changed }}\n    steps:\n\n      - uses: actions/checkout@v6\n        with:\n          # Checkout as many commits as needed for the diff\n          repository: 89luca89/distrobox\n          ref: main\n          persist-credentials: false\n          fetch-depth: 2\n          token: ${{ secrets.GITHUB_TOKEN }}\n\n      # Fetch from compatibility table all the distros supported\n      - id: check_file_changed\n        run: |\n          if git diff --name-only HEAD^ HEAD  | grep -E \"^docs|gen-man\"; then\n            echo \"::set-output name=distrobox_changed::True\"\n          else\n            echo \"::set-output name=distrobox_changed::False\"\n          fi\n\n  gen_man:\n    runs-on: ubuntu-latest\n    needs: check_changes\n    if: needs.check_changes.outputs.distrobox_changed == 'True'\n    permissions:\n      contents: write\n    steps:\n\n      - uses: actions/checkout@v6\n        with:\n          token: ${{ secrets.PAT }}\n\n      # Fetch from compatibility table all the distros supported\n      - id: generate\n        run: |\n          VERSION=3.6.1\n          RELEASE=\"jgm/pandoc/releases/download/${VERSION}/pandoc-${VERSION}-1-amd64.deb\"\n          NAME=$(echo $RELEASE | rev | cut -d'/' -f1 | rev)\n\n          curl -L https://github.com/$RELEASE -o $NAME\n          sudo apt-get update\n          sudo apt-get install -y ./$NAME\n          sudo apt-get install -y ronn\n\n          rm -f $NAME\n\n          man/gen-man\n\n      - uses: stefanzweifel/git-auto-commit-action@v7\n        with:\n          branch: main\n          commit_message: Automatic Man Page Update\n          commit_options: '--no-verify --signoff'\n          commit_user_name: distrobox-docs-bot\n          commit_user_email: distrobox-docs-bot@users.noreply.github.com\n          commit_author: distrobox-docs-bot <actions@github.com>\n"
  },
  {
    "path": ".gitignore",
    "content": "tags\n*.vim\nTODO.txt\n"
  },
  {
    "path": ".markdownlint.yaml",
    "content": "---\nMD013:\n  line_length: 120\n  code_blocks: false\n  tables: false\n  headings: false\n  headers: false\nMD025: false\nMD033: false\nMD041: false\nMD045: false\nMD059: false\n"
  },
  {
    "path": ".shellcheckrc",
    "content": "# Overrides the shell detected from the shebang. This is useful for files meant to be included (and thus lacking a shebang), or possibly as a more targeted alternative to 'disable=SC2039'.\nshell=sh\n\n# Always allow ShellCheck to open arbitrary files from 'source' statements.\nexternal-sources=true\n\n# Enable all optional checks\nenable=all\n\n# This function is invoked in an 'if' condition so set -e will be disabled. Invoke separately if failures should cause the script to exit.\n# - We don't want to exit if errors happen inside a check, that's why we have a check...\ndisable=SC2310\n\n# Bash implicitly disabled set -e for this function invocation because it's inside a command substitution. Add set -e; before it or enable inherit_errexit.\n# - Don't care if we inherit errexit inside substitutions, we do checks for that.\ndisable=SC2311\n\n# Consider invoking this command separately to avoid masking its return value (or use '|| true' to ignore).\n# - We already check errors and adding \"|| true\" everywhere hinders readability.\ndisable=SC2312\n"
  },
  {
    "path": "CODE_OF_CONDUCT.md",
    "content": "# Code of Conduct\n\nLet's just all be nice to each other and ourselves. Do we really need this?\n\nJust follow them:\n\n![wholesome](https://i.kym-cdn.com/photos/images/newsfeed/001/407/983/841.jpg)\n\n## Let's just all be wholesome to each other please\n"
  },
  {
    "path": "CONTRIBUTING.md",
    "content": "# Contributing to Distrobox\n\nWe greatly appreciate your input! We want to make contributing to this project\nas easy and transparent as possible, whether it's:\n\n- Reporting a bug\n- Discussing the current state of the code\n- Submitting a fix\n- Proposing new features\n\n## Creating a Pull Requests\n\nPull requests are the best way to propose changes to the codebase.  \nWe actively welcome your pull requests:\n\n1. Fork the repo and create your branch from `main`.\n2. If you've added code that should be tested, add tests.\n3. If you've changed APIs, update the documentation.\n4. Ensure the test suite passes.\n5. Make sure your code lints.\n6. Issue that pull request!\n\n## Any contributions you make will be under the GPLv3 Software License\n\nIn short, when you submit code changes, your submissions are understood to be\nunder the same [GPLv3 License](https://choosealicense.com/licenses/gpl-3.0/) that\ncovers the project.\nFeel free to contact the maintainers if that's a concern.\n\n## Suggestions\n\nSuggestions are welcome, be sure:\n\n- It is not already being discussed in the [issue tracker](https://github.com/89luca89/distrobox/issues)\n  - If it has and is marked as OPEN, go ahead and share your own\n    thoughts about the topic!\n  - If it has and is marked as CLOSED, please read the ticket and depending on\n    whether the suggestion was accepted consider if it is worth opening\n    a new issue or not.\n- Consider if the suggestion is not too out of scope of the project.\n- Mark them with a [Suggestion] in the title.\n\n## Report bugs using GitHub's [issues](https://github.com/89luca89/distrobox/issues)\n\nWe use GitHub issues to track public bugs.\nReport a bug by\n[opening a new issue](https://github.com/89luca89/distrobox/issues); it's that easy!\n\n### Write bug reports with detail, background, and sample code\n\n**A good bug report** should have:\n\n- Check that the bug is not already discussed in the [issue tracker](https://github.com/89luca89/distrobox/issues)\n- See our [documentation](https://github.com/89luca89/distrobox/tree/main/docs)\n  if there are some steps that could help you solve your issue\n- Mark them with an [Error] in the title\n- A quick summary and/or background\n- Steps to reproduce\n  - Be specific!\n  - Provide logs (terminal output, runs with verbose mode)\n- What you expected would happen\n- What actually happens\n- Notes (possibly including why you think this might be happening, or stuff you\n  tried that didn't work)\n\n## Use a Consistent Coding Style\n\n- check if files have some problems with POSIX using the following:\n\n```shell\nfor file in $(find . -type f -not -path \"*.git*\"); do\n    if file \"$file\" | grep -qi shell; then\n      echo \"### Checking file $file...\"\n      dash -n $file\n      result=$(( result + $? ))\n      echo \"Result: $result\"\n    fi\ndone\n```\n\n  Here we're using `dash` to verify if there are any non-POSIX code inside the\n  scripts. Distrobox aims to be POSIX compliant so it's important to use a\n  strict POSIX compliant shell to verify. `dash` is available in all major distributions'\n  repositories.\n\n- use `shellcheck` to check for posix compliance and bashisms using:\n  - install from: [HERE](https://github.com/koalaman/shellcheck)\n    following [this](https://github.com/koalaman/shellcheck#installing)\n  - `shellcheck -s sh -a -o all -Sstyle -Calways -x -e SC2310,SC2311,SC2312`\n- use `shfmt` to style the code using:\n  - install from [HERE](https://github.com/mvdan/sh) using `go install mvdan.cc/sh/v3/cmd/shfmt@latest`\n  - `shfmt shfmt -d -s -ci -sr -kp`\n- use `bashate` to check the code:\n  - install using `pip3 install bashate`\n  - `bashate -i E002,E003,E010,E011 --max-line-length 120`\n- use `markdownlint`\n  - install using `npm -i -g markdownlint-cli`\n  - run `markdownlint $(find . -name '*.md' | grep -vF './.git')`\n- Legibility of the code is more important than code golfing, try to be\n  expressive in the code\n- Try to **follow the happy path**:\n  - [This guide](https://maelvls.dev/go-happy-line-of-sight/) is for golang,\n    but it's a very insightful source to follow\n- Error checking is important! Ensure to LBYL (Look Before You Leap), check for\n  variables and for code success exit codes\n- If a command or function can fail, ensure you check the outcome:\n  - `if ! my_function; then ...`\n    this is important to handle errors gracefully and to potentially warn users\n    of what's happening\n- Use snake_case for variable naming. Keep variable names lowercase if they are\n  not an environment variable\n- Don't hesitate to comment your code! We're placing high importance on this to\n  maintain the code readable and understandeable\n- Update documentation to reflect your changes - Manual pages can be found in\n  directory `docs`\n\nIf you are using Visual Studio Code, there are [plugins](https://marketplace.visualstudio.com/items?itemName=timonwong.shellcheck)\nthat include all this functionality and throw a warning if you're doing\nsomething wrong.\nIf you are using Vim or Emacs there are plenty of linters and checkers that will\nintegrate with the 2 tools listed above.\n\n## License\n\nBy contributing, you agree that your contributions will be licensed under\nits GPLv3 License.\n\n## References\n\nThis document was adapted from the open-source contribution guidelines\nfor [Facebook's Draft](https://github.com/facebook/draft-js/blob/a9316a723f9e918afde44dea68b5f9f39b7d9b00/CONTRIBUTING.md).\n"
  },
  {
    "path": "COPYING.md",
    "content": "# GNU GENERAL PUBLIC LICENSE\n\nVersion 3, 29 June 2007\n\nCopyright (C) 2007 Free Software Foundation, Inc.\n<https://fsf.org/>\n\nEveryone is permitted to copy and distribute verbatim copies of this\nlicense document, but changing it is not allowed.\n\n## Preamble\n\nThe GNU General Public License is a free, copyleft license for\nsoftware and other kinds of works.\n\nThe licenses for most software and other practical works are designed\nto take away your freedom to share and change the works. By contrast,\nthe GNU General Public License is intended to guarantee your freedom\nto share and change all versions of a program--to make sure it remains\nfree software for all its users. We, the Free Software Foundation, use\nthe GNU General Public License for most of our software; it applies\nalso to any other work released this way by its authors. You can apply\nit to your programs, too.\n\nWhen we speak of free software, we are referring to freedom, not\nprice. Our General Public Licenses are designed to make sure that you\nhave the freedom to distribute copies of free software (and charge for\nthem if you wish), that you receive source code or can get it if you\nwant it, that you can change the software or use pieces of it in new\nfree programs, and that you know you can do these things.\n\nTo protect your rights, we need to prevent others from denying you\nthese rights or asking you to surrender the rights. Therefore, you\nhave certain responsibilities if you distribute copies of the\nsoftware, or if you modify it: responsibilities to respect the freedom\nof others.\n\nFor example, if you distribute copies of such a program, whether\ngratis or for a fee, you must pass on to the recipients the same\nfreedoms that you received. You must make sure that they, too, receive\nor can get the source code. And you must show them these terms so they\nknow their rights.\n\nDevelopers that use the GNU GPL protect your rights with two steps:\n(1) assert copyright on the software, and (2) offer you this License\ngiving you legal permission to copy, distribute and/or modify it.\n\nFor the developers' and authors' protection, the GPL clearly explains\nthat there is no warranty for this free software. For both users' and\nauthors' sake, the GPL requires that modified versions be marked as\nchanged, so that their problems will not be attributed erroneously to\nauthors of previous versions.\n\nSome devices are designed to deny users access to install or run\nmodified versions of the software inside them, although the\nmanufacturer can do so. This is fundamentally incompatible with the\naim of protecting users' freedom to change the software. The\nsystematic pattern of such abuse occurs in the area of products for\nindividuals to use, which is precisely where it is most unacceptable.\nTherefore, we have designed this version of the GPL to prohibit the\npractice for those products. If such problems arise substantially in\nother domains, we stand ready to extend this provision to those\ndomains in future versions of the GPL, as needed to protect the\nfreedom of users.\n\nFinally, every program is threatened constantly by software patents.\nStates should not allow patents to restrict development and use of\nsoftware on general-purpose computers, but in those that do, we wish\nto avoid the special danger that patents applied to a free program\ncould make it effectively proprietary. To prevent this, the GPL\nassures that patents cannot be used to render the program non-free.\n\nThe precise terms and conditions for copying, distribution and\nmodification follow.\n\n### TERMS AND CONDITIONS\n\n#### 0. Definitions\n\n\"This License\" refers to version 3 of the GNU General Public License.\n\n\"Copyright\" also means copyright-like laws that apply to other kinds\nof works, such as semiconductor masks.\n\n\"The Program\" refers to any copyrightable work licensed under this\nLicense. Each licensee is addressed as \"you\". \"Licensees\" and\n\"recipients\" may be individuals or organizations.\n\nTo \"modify\" a work means to copy from or adapt all or part of the work\nin a fashion requiring copyright permission, other than the making of\nan exact copy. The resulting work is called a \"modified version\" of\nthe earlier work or a work \"based on\" the earlier work.\n\nA \"covered work\" means either the unmodified Program or a work based\non the Program.\n\nTo \"propagate\" a work means to do anything with it that, without\npermission, would make you directly or secondarily liable for\ninfringement under applicable copyright law, except executing it on a\ncomputer or modifying a private copy. Propagation includes copying,\ndistribution (with or without modification), making available to the\npublic, and in some countries other activities as well.\n\nTo \"convey\" a work means any kind of propagation that enables other\nparties to make or receive copies. Mere interaction with a user\nthrough a computer network, with no transfer of a copy, is not\nconveying.\n\nAn interactive user interface displays \"Appropriate Legal Notices\" to\nthe extent that it includes a convenient and prominently visible\nfeature that (1) displays an appropriate copyright notice, and (2)\ntells the user that there is no warranty for the work (except to the\nextent that warranties are provided), that licensees may convey the\nwork under this License, and how to view a copy of this License. If\nthe interface presents a list of user commands or options, such as a\nmenu, a prominent item in the list meets this criterion.\n\n#### 1. Source Code\n\nThe \"source code\" for a work means the preferred form of the work for\nmaking modifications to it. \"Object code\" means any non-source form of\na work.\n\nA \"Standard Interface\" means an interface that either is an official\nstandard defined by a recognized standards body, or, in the case of\ninterfaces specified for a particular programming language, one that\nis widely used among developers working in that language.\n\nThe \"System Libraries\" of an executable work include anything, other\nthan the work as a whole, that (a) is included in the normal form of\npackaging a Major Component, but which is not part of that Major\nComponent, and (b) serves only to enable use of the work with that\nMajor Component, or to implement a Standard Interface for which an\nimplementation is available to the public in source code form. A\n\"Major Component\", in this context, means a major essential component\n(kernel, window system, and so on) of the specific operating system\n(if any) on which the executable work runs, or a compiler used to\nproduce the work, or an object code interpreter used to run it.\n\nThe \"Corresponding Source\" for a work in object code form means all\nthe source code needed to generate, install, and (for an executable\nwork) run the object code and to modify the work, including scripts to\ncontrol those activities. However, it does not include the work's\nSystem Libraries, or general-purpose tools or generally available free\nprograms which are used unmodified in performing those activities but\nwhich are not part of the work. For example, Corresponding Source\nincludes interface definition files associated with source files for\nthe work, and the source code for shared libraries and dynamically\nlinked subprograms that the work is specifically designed to require,\nsuch as by intimate data communication or control flow between those\nsubprograms and other parts of the work.\n\nThe Corresponding Source need not include anything that users can\nregenerate automatically from other parts of the Corresponding Source.\n\nThe Corresponding Source for a work in source code form is that same\nwork.\n\n#### 2. Basic Permissions\n\nAll rights granted under this License are granted for the term of\ncopyright on the Program, and are irrevocable provided the stated\nconditions are met. This License explicitly affirms your unlimited\npermission to run the unmodified Program. The output from running a\ncovered work is covered by this License only if the output, given its\ncontent, constitutes a covered work. This License acknowledges your\nrights of fair use or other equivalent, as provided by copyright law.\n\nYou may make, run and propagate covered works that you do not convey,\nwithout conditions so long as your license otherwise remains in force.\nYou may convey covered works to others for the sole purpose of having\nthem make modifications exclusively for you, or provide you with\nfacilities for running those works, provided that you comply with the\nterms of this License in conveying all material for which you do not\ncontrol copyright. Those thus making or running the covered works for\nyou must do so exclusively on your behalf, under your direction and\ncontrol, on terms that prohibit them from making any copies of your\ncopyrighted material outside their relationship with you.\n\nConveying under any other circumstances is permitted solely under the\nconditions stated below. Sublicensing is not allowed; section 10 makes\nit unnecessary.\n\n#### 3. Protecting Users' Legal Rights From Anti-Circumvention Law\n\nNo covered work shall be deemed part of an effective technological\nmeasure under any applicable law fulfilling obligations under article\n11 of the WIPO copyright treaty adopted on 20 December 1996, or\nsimilar laws prohibiting or restricting circumvention of such\nmeasures.\n\nWhen you convey a covered work, you waive any legal power to forbid\ncircumvention of technological measures to the extent such\ncircumvention is effected by exercising rights under this License with\nrespect to the covered work, and you disclaim any intention to limit\noperation or modification of the work as a means of enforcing, against\nthe work's users, your or third parties' legal rights to forbid\ncircumvention of technological measures.\n\n#### 4. Conveying Verbatim Copies\n\nYou may convey verbatim copies of the Program's source code as you\nreceive it, in any medium, provided that you conspicuously and\nappropriately publish on each copy an appropriate copyright notice;\nkeep intact all notices stating that this License and any\nnon-permissive terms added in accord with section 7 apply to the code;\nkeep intact all notices of the absence of any warranty; and give all\nrecipients a copy of this License along with the Program.\n\nYou may charge any price or no price for each copy that you convey,\nand you may offer support or warranty protection for a fee.\n\n#### 5. Conveying Modified Source Versions\n\nYou may convey a work based on the Program, or the modifications to\nproduce it from the Program, in the form of source code under the\nterms of section 4, provided that you also meet all of these\nconditions:\n\n- a) The work must carry prominent notices stating that you modified\n    it, and giving a relevant date.\n- b) The work must carry prominent notices stating that it is\n    released under this License and any conditions added under\n    section 7. This requirement modifies the requirement in section 4\n    to \"keep intact all notices\".\n- c) You must license the entire work, as a whole, under this\n    License to anyone who comes into possession of a copy. This\n    License will therefore apply, along with any applicable section 7\n    additional terms, to the whole of the work, and all its parts,\n    regardless of how they are packaged. This License gives no\n    permission to license the work in any other way, but it does not\n    invalidate such permission if you have separately received it.\n- d) If the work has interactive user interfaces, each must display\n    Appropriate Legal Notices; however, if the Program has interactive\n    interfaces that do not display Appropriate Legal Notices, your\n    work need not make them do so.\n\nA compilation of a covered work with other separate and independent\nworks, which are not by their nature extensions of the covered work,\nand which are not combined with it such as to form a larger program,\nin or on a volume of a storage or distribution medium, is called an\n\"aggregate\" if the compilation and its resulting copyright are not\nused to limit the access or legal rights of the compilation's users\nbeyond what the individual works permit. Inclusion of a covered work\nin an aggregate does not cause this License to apply to the other\nparts of the aggregate.\n\n#### 6. Conveying Non-Source Forms\n\nYou may convey a covered work in object code form under the terms of\nsections 4 and 5, provided that you also convey the machine-readable\nCorresponding Source under the terms of this License, in one of these\nways:\n\n- a) Convey the object code in, or embodied in, a physical product\n    (including a physical distribution medium), accompanied by the\n    Corresponding Source fixed on a durable physical medium\n    customarily used for software interchange.\n- b) Convey the object code in, or embodied in, a physical product\n    (including a physical distribution medium), accompanied by a\n    written offer, valid for at least three years and valid for as\n    long as you offer spare parts or customer support for that product\n    model, to give anyone who possesses the object code either (1) a\n    copy of the Corresponding Source for all the software in the\n    product that is covered by this License, on a durable physical\n    medium customarily used for software interchange, for a price no\n    more than your reasonable cost of physically performing this\n    conveying of source, or (2) access to copy the Corresponding\n    Source from a network server at no charge.\n- c) Convey individual copies of the object code with a copy of the\n    written offer to provide the Corresponding Source. This\n    alternative is allowed only occasionally and noncommercially, and\n    only if you received the object code with such an offer, in accord\n    with subsection 6b.\n- d) Convey the object code by offering access from a designated\n    place (gratis or for a charge), and offer equivalent access to the\n    Corresponding Source in the same way through the same place at no\n    further charge. You need not require recipients to copy the\n    Corresponding Source along with the object code. If the place to\n    copy the object code is a network server, the Corresponding Source\n    may be on a different server (operated by you or a third party)\n    that supports equivalent copying facilities, provided you maintain\n    clear directions next to the object code saying where to find the\n    Corresponding Source. Regardless of what server hosts the\n    Corresponding Source, you remain obligated to ensure that it is\n    available for as long as needed to satisfy these requirements.\n- e) Convey the object code using peer-to-peer transmission,\n    provided you inform other peers where the object code and\n    Corresponding Source of the work are being offered to the general\n    public at no charge under subsection 6d.\n\nA separable portion of the object code, whose source code is excluded\nfrom the Corresponding Source as a System Library, need not be\nincluded in conveying the object code work.\n\nA \"User Product\" is either (1) a \"consumer product\", which means any\ntangible personal property which is normally used for personal,\nfamily, or household purposes, or (2) anything designed or sold for\nincorporation into a dwelling. In determining whether a product is a\nconsumer product, doubtful cases shall be resolved in favor of\ncoverage. For a particular product received by a particular user,\n\"normally used\" refers to a typical or common use of that class of\nproduct, regardless of the status of the particular user or of the way\nin which the particular user actually uses, or expects or is expected\nto use, the product. A product is a consumer product regardless of\nwhether the product has substantial commercial, industrial or\nnon-consumer uses, unless such uses represent the only significant\nmode of use of the product.\n\n\"Installation Information\" for a User Product means any methods,\nprocedures, authorization keys, or other information required to\ninstall and execute modified versions of a covered work in that User\nProduct from a modified version of its Corresponding Source. The\ninformation must suffice to ensure that the continued functioning of\nthe modified object code is in no case prevented or interfered with\nsolely because modification has been made.\n\nIf you convey an object code work under this section in, or with, or\nspecifically for use in, a User Product, and the conveying occurs as\npart of a transaction in which the right of possession and use of the\nUser Product is transferred to the recipient in perpetuity or for a\nfixed term (regardless of how the transaction is characterized), the\nCorresponding Source conveyed under this section must be accompanied\nby the Installation Information. But this requirement does not apply\nif neither you nor any third party retains the ability to install\nmodified object code on the User Product (for example, the work has\nbeen installed in ROM).\n\nThe requirement to provide Installation Information does not include a\nrequirement to continue to provide support service, warranty, or\nupdates for a work that has been modified or installed by the\nrecipient, or for the User Product in which it has been modified or\ninstalled. Access to a network may be denied when the modification\nitself materially and adversely affects the operation of the network\nor violates the rules and protocols for communication across the\nnetwork.\n\nCorresponding Source conveyed, and Installation Information provided,\nin accord with this section must be in a format that is publicly\ndocumented (and with an implementation available to the public in\nsource code form), and must require no special password or key for\nunpacking, reading or copying.\n\n#### 7. Additional Terms\n\n\"Additional permissions\" are terms that supplement the terms of this\nLicense by making exceptions from one or more of its conditions.\nAdditional permissions that are applicable to the entire Program shall\nbe treated as though they were included in this License, to the extent\nthat they are valid under applicable law. If additional permissions\napply only to part of the Program, that part may be used separately\nunder those permissions, but the entire Program remains governed by\nthis License without regard to the additional permissions.\n\nWhen you convey a copy of a covered work, you may at your option\nremove any additional permissions from that copy, or from any part of\nit. (Additional permissions may be written to require their own\nremoval in certain cases when you modify the work.) You may place\nadditional permissions on material, added by you to a covered work,\nfor which you have or can give appropriate copyright permission.\n\nNotwithstanding any other provision of this License, for material you\nadd to a covered work, you may (if authorized by the copyright holders\nof that material) supplement the terms of this License with terms:\n\n- a) Disclaiming warranty or limiting liability differently from the\n    terms of sections 15 and 16 of this License; or\n- b) Requiring preservation of specified reasonable legal notices or\n    author attributions in that material or in the Appropriate Legal\n    Notices displayed by works containing it; or\n- c) Prohibiting misrepresentation of the origin of that material,\n    or requiring that modified versions of such material be marked in\n    reasonable ways as different from the original version; or\n- d) Limiting the use for publicity purposes of names of licensors\n    or authors of the material; or\n- e) Declining to grant rights under trademark law for use of some\n    trade names, trademarks, or service marks; or\n- f) Requiring indemnification of licensors and authors of that\n    material by anyone who conveys the material (or modified versions\n    of it) with contractual assumptions of liability to the recipient,\n    for any liability that these contractual assumptions directly\n    impose on those licensors and authors.\n\nAll other non-permissive additional terms are considered \"further\nrestrictions\" within the meaning of section 10. If the Program as you\nreceived it, or any part of it, contains a notice stating that it is\ngoverned by this License along with a term that is a further\nrestriction, you may remove that term. If a license document contains\na further restriction but permits relicensing or conveying under this\nLicense, you may add to a covered work material governed by the terms\nof that license document, provided that the further restriction does\nnot survive such relicensing or conveying.\n\nIf you add terms to a covered work in accord with this section, you\nmust place, in the relevant source files, a statement of the\nadditional terms that apply to those files, or a notice indicating\nwhere to find the applicable terms.\n\nAdditional terms, permissive or non-permissive, may be stated in the\nform of a separately written license, or stated as exceptions; the\nabove requirements apply either way.\n\n#### 8. Termination\n\nYou may not propagate or modify a covered work except as expressly\nprovided under this License. Any attempt otherwise to propagate or\nmodify it is void, and will automatically terminate your rights under\nthis License (including any patent licenses granted under the third\nparagraph of section 11).\n\nHowever, if you cease all violation of this License, then your license\nfrom a particular copyright holder is reinstated (a) provisionally,\nunless and until the copyright holder explicitly and finally\nterminates your license, and (b) permanently, if the copyright holder\nfails to notify you of the violation by some reasonable means prior to\n60 days after the cessation.\n\nMoreover, your license from a particular copyright holder is\nreinstated permanently if the copyright holder notifies you of the\nviolation by some reasonable means, this is the first time you have\nreceived notice of violation of this License (for any work) from that\ncopyright holder, and you cure the violation prior to 30 days after\nyour receipt of the notice.\n\nTermination of your rights under this section does not terminate the\nlicenses of parties who have received copies or rights from you under\nthis License. If your rights have been terminated and not permanently\nreinstated, you do not qualify to receive new licenses for the same\nmaterial under section 10.\n\n#### 9. Acceptance Not Required for Having Copies\n\nYou are not required to accept this License in order to receive or run\na copy of the Program. Ancillary propagation of a covered work\noccurring solely as a consequence of using peer-to-peer transmission\nto receive a copy likewise does not require acceptance. However,\nnothing other than this License grants you permission to propagate or\nmodify any covered work. These actions infringe copyright if you do\nnot accept this License. Therefore, by modifying or propagating a\ncovered work, you indicate your acceptance of this License to do so.\n\n#### 10. Automatic Licensing of Downstream Recipients\n\nEach time you convey a covered work, the recipient automatically\nreceives a license from the original licensors, to run, modify and\npropagate that work, subject to this License. You are not responsible\nfor enforcing compliance by third parties with this License.\n\nAn \"entity transaction\" is a transaction transferring control of an\norganization, or substantially all assets of one, or subdividing an\norganization, or merging organizations. If propagation of a covered\nwork results from an entity transaction, each party to that\ntransaction who receives a copy of the work also receives whatever\nlicenses to the work the party's predecessor in interest had or could\ngive under the previous paragraph, plus a right to possession of the\nCorresponding Source of the work from the predecessor in interest, if\nthe predecessor has it or can get it with reasonable efforts.\n\nYou may not impose any further restrictions on the exercise of the\nrights granted or affirmed under this License. For example, you may\nnot impose a license fee, royalty, or other charge for exercise of\nrights granted under this License, and you may not initiate litigation\n(including a cross-claim or counterclaim in a lawsuit) alleging that\nany patent claim is infringed by making, using, selling, offering for\nsale, or importing the Program or any portion of it.\n\n#### 11. Patents\n\nA \"contributor\" is a copyright holder who authorizes use under this\nLicense of the Program or a work on which the Program is based. The\nwork thus licensed is called the contributor's \"contributor version\".\n\nA contributor's \"essential patent claims\" are all patent claims owned\nor controlled by the contributor, whether already acquired or\nhereafter acquired, that would be infringed by some manner, permitted\nby this License, of making, using, or selling its contributor version,\nbut do not include claims that would be infringed only as a\nconsequence of further modification of the contributor version. For\npurposes of this definition, \"control\" includes the right to grant\npatent sublicenses in a manner consistent with the requirements of\nthis License.\n\nEach contributor grants you a non-exclusive, worldwide, royalty-free\npatent license under the contributor's essential patent claims, to\nmake, use, sell, offer for sale, import and otherwise run, modify and\npropagate the contents of its contributor version.\n\nIn the following three paragraphs, a \"patent license\" is any express\nagreement or commitment, however denominated, not to enforce a patent\n(such as an express permission to practice a patent or covenant not to\nsue for patent infringement). To \"grant\" such a patent license to a\nparty means to make such an agreement or commitment not to enforce a\npatent against the party.\n\nIf you convey a covered work, knowingly relying on a patent license,\nand the Corresponding Source of the work is not available for anyone\nto copy, free of charge and under the terms of this License, through a\npublicly available network server or other readily accessible means,\nthen you must either (1) cause the Corresponding Source to be so\navailable, or (2) arrange to deprive yourself of the benefit of the\npatent license for this particular work, or (3) arrange, in a manner\nconsistent with the requirements of this License, to extend the patent\nlicense to downstream recipients. \"Knowingly relying\" means you have\nactual knowledge that, but for the patent license, your conveying the\ncovered work in a country, or your recipient's use of the covered work\nin a country, would infringe one or more identifiable patents in that\ncountry that you have reason to believe are valid.\n\nIf, pursuant to or in connection with a single transaction or\narrangement, you convey, or propagate by procuring conveyance of, a\ncovered work, and grant a patent license to some of the parties\nreceiving the covered work authorizing them to use, propagate, modify\nor convey a specific copy of the covered work, then the patent license\nyou grant is automatically extended to all recipients of the covered\nwork and works based on it.\n\nA patent license is \"discriminatory\" if it does not include within the\nscope of its coverage, prohibits the exercise of, or is conditioned on\nthe non-exercise of one or more of the rights that are specifically\ngranted under this License. You may not convey a covered work if you\nare a party to an arrangement with a third party that is in the\nbusiness of distributing software, under which you make payment to the\nthird party based on the extent of your activity of conveying the\nwork, and under which the third party grants, to any of the parties\nwho would receive the covered work from you, a discriminatory patent\nlicense (a) in connection with copies of the covered work conveyed by\nyou (or copies made from those copies), or (b) primarily for and in\nconnection with specific products or compilations that contain the\ncovered work, unless you entered into that arrangement, or that patent\nlicense was granted, prior to 28 March 2007.\n\nNothing in this License shall be construed as excluding or limiting\nany implied license or other defenses to infringement that may\notherwise be available to you under applicable patent law.\n\n#### 12. No Surrender of Others' Freedom\n\nIf conditions are imposed on you (whether by court order, agreement or\notherwise) that contradict the conditions of this License, they do not\nexcuse you from the conditions of this License. If you cannot convey a\ncovered work so as to satisfy simultaneously your obligations under\nthis License and any other pertinent obligations, then as a\nconsequence you may not convey it at all. For example, if you agree to\nterms that obligate you to collect a royalty for further conveying\nfrom those to whom you convey the Program, the only way you could\nsatisfy both those terms and this License would be to refrain entirely\nfrom conveying the Program.\n\n#### 13. Use with the GNU Affero General Public License\n\nNotwithstanding any other provision of this License, you have\npermission to link or combine any covered work with a work licensed\nunder version 3 of the GNU Affero General Public License into a single\ncombined work, and to convey the resulting work. The terms of this\nLicense will continue to apply to the part which is the covered work,\nbut the special requirements of the GNU Affero General Public License,\nsection 13, concerning interaction through a network will apply to the\ncombination as such.\n\n#### 14. Revised Versions of this License\n\nThe Free Software Foundation may publish revised and/or new versions\nof the GNU General Public License from time to time. Such new versions\nwill be similar in spirit to the present version, but may differ in\ndetail to address new problems or concerns.\n\nEach version is given a distinguishing version number. If the Program\nspecifies that a certain numbered version of the GNU General Public\nLicense \"or any later version\" applies to it, you have the option of\nfollowing the terms and conditions either of that numbered version or\nof any later version published by the Free Software Foundation. If the\nProgram does not specify a version number of the GNU General Public\nLicense, you may choose any version ever published by the Free\nSoftware Foundation.\n\nIf the Program specifies that a proxy can decide which future versions\nof the GNU General Public License can be used, that proxy's public\nstatement of acceptance of a version permanently authorizes you to\nchoose that version for the Program.\n\nLater license versions may give you additional or different\npermissions. However, no additional obligations are imposed on any\nauthor or copyright holder as a result of your choosing to follow a\nlater version.\n\n#### 15. Disclaimer of Warranty\n\nTHERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY\nAPPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT\nHOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM \"AS IS\" WITHOUT\nWARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT\nLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\nA PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND\nPERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE\nDEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR\nCORRECTION.\n\n#### 16. Limitation of Liability\n\nIN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING\nWILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR\nCONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,\nINCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES\nARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT\nNOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR\nLOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM\nTO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER\nPARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.\n\n#### 17. Interpretation of Sections 15 and 16\n\nIf the disclaimer of warranty and limitation of liability provided\nabove cannot be given local legal effect according to their terms,\nreviewing courts shall apply local law that most closely approximates\nan absolute waiver of all civil liability in connection with the\nProgram, unless a warranty or assumption of liability accompanies a\ncopy of the Program in return for a fee.\n\nEND OF TERMS AND CONDITIONS\n\n### How to Apply These Terms to Your New Programs\n\nIf you develop a new program, and you want it to be of the greatest\npossible use to the public, the best way to achieve this is to make it\nfree software which everyone can redistribute and change under these\nterms.\n\nTo do so, attach the following notices to the program. It is safest to\nattach them to the start of each source file to most effectively state\nthe exclusion of warranty; and each file should have at least the\n\"copyright\" line and a pointer to where the full notice is found.\n\n        <one line to give the program's name and a brief idea of what it does.>\n        Copyright (C) <year>  <name of author>\n\n        This program is free software: you can redistribute it and/or modify\n        it under the terms of the GNU General Public License as published by\n        the Free Software Foundation, either version 3 of the License, or\n        (at your option) any later version.\n\n        This program is distributed in the hope that it will be useful,\n        but WITHOUT ANY WARRANTY; without even the implied warranty of\n        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n        GNU General Public License for more details.\n\n        You should have received a copy of the GNU General Public License\n        along with this program.  If not, see <https://www.gnu.org/licenses/>.\n\nAlso add information on how to contact you by electronic and paper\nmail.\n\nIf the program does terminal interaction, make it output a short\nnotice like this when it starts in an interactive mode:\n\n        <program>  Copyright (C) <year>  <name of author>\n        This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.\n        This is free software, and you are welcome to redistribute it\n        under certain conditions; type `show c' for details.\n\nThe hypothetical commands \\`show w' and \\`show c' should show the\nappropriate parts of the General Public License. Of course, your\nprogram's commands might be different; for a GUI interface, you would\nuse an \"about box\".\n\nYou should also get your employer (if you work as a programmer) or\nschool, if any, to sign a \"copyright disclaimer\" for the program, if\nnecessary. For more information on this, and how to apply and follow\nthe GNU GPL, see <https://www.gnu.org/licenses/>.\n\nThe GNU General Public License does not permit incorporating your\nprogram into proprietary programs. If your program is a subroutine\nlibrary, you may consider it more useful to permit linking proprietary\napplications with the library. If this is what you want to do, use the\nGNU Lesser General Public License instead of this License. But first,\nplease read <https://www.gnu.org/licenses/why-not-lgpl.html>.\n"
  },
  {
    "path": "Containerfile",
    "content": "FROM  docker.io/mgoltzsche/podman:latest\n\nCOPY ./distrobox* /usr/bin/\n"
  },
  {
    "path": "completions/bash/distrobox",
    "content": "# shellcheck disable=all\n\n_generate_from_help() {\n\tcommand=$1\n\t# if command does not exist, try with `distrobox subcommand`\n\tif ! $command --help >/dev/null 2>/dev/null ; then\n\t\tcommand=\"$(echo $command | tr '-' ' ')\"\n\tfi\n\n\tlocal list cur prev totalopts opts diropts\n\n\tCOMPREPLY=()\n\n\tcur=\"${COMP_WORDS[COMP_CWORD]}\"\n\tprev=\"${COMP_WORDS[COMP_CWORD - 1]}\"\n\topts=\"$($command --help 2>/dev/null | sed 's|^\\t||g' | grep '^--' | cut -d':' -f1 | tr '/' ' ' | tr '\\n' ' ')\"\n\ttotalopts=\"$(echo $opts | tr ' ' '|')\"\n\tdiropts=\"-H|--home|--volume\"\n\tfileopts=\"--file\"\n\n\tif [[ ${prev} =~ ${diropts} ]]; then\n\t\tmapfile -t COMPREPLY < <(\n\t\t\tIFS=$'\\n'\n\t\t\trealpath $(compgen -d -- ${cur}) 2>/dev/null\n\t\t)\n\t\tcompopt -o filenames\n\t\treturn 0\n\tfi\n\n\tif [[ ${prev} =~ ${fileopts} ]]; then\n\t\tCOMPREPLY=($(compgen -f -- ${cur}))\n\t\tcompopt -o filenames\n\t\treturn 0\n\tfi\n\tif [[ ${prev} == \"assemble\" ]]; then\n\t\tCOMPREPLY+=($(compgen -W \"create rm\" -- ${cur}))\n\t\treturn 0\n\tfi\n\n\tif [[ ${prev} == \"--image\" ]] || [[ ${prev} == \"-i\" ]]; then\n\t\tCOMPREPLY+=($(compgen -W \"$(distrobox-create --compatibility)\" -- ${cur}))\n\t\treturn 0\n\tfi\n\n\tif [[ ${cur} == -* ]]; then\n\t\tCOMPREPLY+=($(compgen -W \"${opts}\" -- ${cur}))\n\t\treturn 0\n\telif [[ ${command} != *\"create\"* ]] && [[ ${command} != *\"ephemeral\"* ]] &&\n\t\t[[ ${command} != *\"list\"* ]] && [[ ${command} != *\"assemble\"* ]] &&\n\t\t[[ ${command} != *\"version\"* ]] && [[ ${command} != *\"help\"* ]]; then\n\t\twhile IFS= read -r line; do\n\t\t\tlist+=\"$line \"\n\t\tdone < <(distrobox-list --no-color | tail -n+2 | cut -d'|' -f2)\n\t\tCOMPREPLY=($(compgen -W \"${list}\" \"${cur}\"))\n\t\treturn 0\n\tfi\n}\n\n__distrobox() {\n\tif [ \"${#COMP_WORDS[@]}\" == \"2\" ]; then\n\t\tVALID_WORDS=$(distrobox | tail -n+4 | tr -d '|' | xargs echo)\n\t\tVALID_WORDS+=\" --version --help\"\n\t\tCOMPREPLY=($(compgen -W \"${VALID_WORDS}\" -- \"${COMP_WORDS[1]}\"))\n\telif [ \"${#COMP_WORDS[@]}\" -gt \"2\" ]; then\n\t\t_generate_from_help distrobox-\"${COMP_WORDS[1]}\"\n\tfi\n}\n\ncomplete -F __distrobox distrobox\n"
  },
  {
    "path": "completions/bash/distrobox-assemble",
    "content": "# shellcheck disable=all\n\nif [ -e /usr/share/bash-completion/completions/distrobox ]; then\n\tsource /usr/share/bash-completion/completions/distrobox\nfi\nif [ -e /usr/local/share/bash-completion/completions/distrobox ]; then\n\tsource /usr/local/share/bash-completion/completions/distrobox\nfi\nif [ -e \"${HOME}/.local/share/bash-completion/completions/distrobox\" ]; then\n\tsource \"${HOME}/.local/share/bash-completion/completions/distrobox\"\nfi\n\ncomplete -F _generate_from_help distrobox-assemble\n"
  },
  {
    "path": "completions/bash/distrobox-create",
    "content": "# shellcheck disable=all\n\nif [ -e /usr/share/bash-completion/completions/distrobox ]; then\n\tsource /usr/share/bash-completion/completions/distrobox\nfi\nif [ -e /usr/local/share/bash-completion/completions/distrobox ]; then\n\tsource /usr/local/share/bash-completion/completions/distrobox\nfi\nif [ -e \"${HOME}/.local/share/bash-completion/completions/distrobox\" ]; then\n\tsource \"${HOME}/.local/share/bash-completion/completions/distrobox\"\nfi\n\ncomplete -F _generate_from_help distrobox-create\n"
  },
  {
    "path": "completions/bash/distrobox-enter",
    "content": "# shellcheck disable=all\n\nif [ -e /usr/share/bash-completion/completions/distrobox ]; then\n\tsource /usr/share/bash-completion/completions/distrobox\nfi\nif [ -e /usr/local/share/bash-completion/completions/distrobox ]; then\n\tsource /usr/local/share/bash-completion/completions/distrobox\nfi\nif [ -e \"${HOME}/.local/share/bash-completion/completions/distrobox\" ]; then\n\tsource \"${HOME}/.local/share/bash-completion/completions/distrobox\"\nfi\n\ncomplete -F _generate_from_help distrobox-enter\n"
  },
  {
    "path": "completions/bash/distrobox-ephemeral",
    "content": "# shellcheck disable=all\n\nif [ -e /usr/share/bash-completion/completions/distrobox ]; then\n\tsource /usr/share/bash-completion/completions/distrobox\nfi\nif [ -e /usr/local/share/bash-completion/completions/distrobox ]; then\n\tsource /usr/local/share/bash-completion/completions/distrobox\nfi\nif [ -e \"${HOME}/.local/share/bash-completion/completions/distrobox\" ]; then\n\tsource \"${HOME}/.local/share/bash-completion/completions/distrobox\"\nfi\n\ncomplete -F _generate_from_help distrobox-ephemeral\n"
  },
  {
    "path": "completions/bash/distrobox-generate-entry",
    "content": "# shellcheck disable=all\n\nif [ -e /usr/share/bash-completion/completions/distrobox ]; then\n\tsource /usr/share/bash-completion/completions/distrobox\nfi\nif [ -e /usr/local/share/bash-completion/completions/distrobox ]; then\n\tsource /usr/local/share/bash-completion/completions/distrobox\nfi\nif [ -e \"${HOME}/.local/share/bash-completion/completions/distrobox\" ]; then\n\tsource \"${HOME}/.local/share/bash-completion/completions/distrobox\"\nfi\n\ncomplete -F _generate_from_help distrobox-generate-entry\n"
  },
  {
    "path": "completions/bash/distrobox-list",
    "content": "# shellcheck disable=all\n\nif [ -e /usr/share/bash-completion/completions/distrobox ]; then\n\tsource /usr/share/bash-completion/completions/distrobox\nfi\nif [ -e /usr/local/share/bash-completion/completions/distrobox ]; then\n\tsource /usr/local/share/bash-completion/completions/distrobox\nfi\nif [ -e \"${HOME}/.local/share/bash-completion/completions/distrobox\" ]; then\n\tsource \"${HOME}/.local/share/bash-completion/completions/distrobox\"\nfi\n\ncomplete -F _generate_from_help distrobox-list\n"
  },
  {
    "path": "completions/bash/distrobox-rm",
    "content": "# shellcheck disable=all\n\nif [ -e /usr/share/bash-completion/completions/distrobox ]; then\n\tsource /usr/share/bash-completion/completions/distrobox\nfi\nif [ -e /usr/local/share/bash-completion/completions/distrobox ]; then\n\tsource /usr/local/share/bash-completion/completions/distrobox\nfi\nif [ -e \"${HOME}/.local/share/bash-completion/completions/distrobox\" ]; then\n\tsource \"${HOME}/.local/share/bash-completion/completions/distrobox\"\nfi\n\ncomplete -F _generate_from_help distrobox-rm\n"
  },
  {
    "path": "completions/bash/distrobox-stop",
    "content": "# shellcheck disable=all\n\nif [ -e /usr/share/bash-completion/completions/distrobox ]; then\n\tsource /usr/share/bash-completion/completions/distrobox\nfi\nif [ -e /usr/local/share/bash-completion/completions/distrobox ]; then\n\tsource /usr/local/share/bash-completion/completions/distrobox\nfi\nif [ -e \"${HOME}/.local/share/bash-completion/completions/distrobox\" ]; then\n\tsource \"${HOME}/.local/share/bash-completion/completions/distrobox\"\nfi\n\ncomplete -F _generate_from_help distrobox-stop\n"
  },
  {
    "path": "completions/bash/distrobox-upgrade",
    "content": "# shellcheck disable=all\n\nif [ -e /usr/share/bash-completion/completions/distrobox ]; then\n\tsource /usr/share/bash-completion/completions/distrobox\nfi\nif [ -e /usr/local/share/bash-completion/completions/distrobox ]; then\n\tsource /usr/local/share/bash-completion/completions/distrobox\nfi\nif [ -e \"${HOME}/.local/share/bash-completion/completions/distrobox\" ]; then\n\tsource \"${HOME}/.local/share/bash-completion/completions/distrobox\"\nfi\n\ncomplete -F _generate_from_help distrobox-upgrade\n"
  },
  {
    "path": "completions/zsh/_distrobox",
    "content": "#compdef distrobox\n\nlocal curcontext=\"$curcontext\" state line\ntypeset -A opt_args\n\n_distrobox_commands() {\n  local -a commands\n  commands=(\n    'assemble:Handle distrobox assembly tasks'\n    'create:Create a new distrobox container'\n    'enter:Enter an existing distrobox container'\n    'list:List all distrobox containers'\n    'ls:Alias for list'\n    'rm:Remove a distrobox container'\n    'stop:Stop a running distrobox container'\n    'upgrade:Upgrade a distrobox container'\n    'ephemeral:Create a temporary distrobox container'\n    'generate-entry:Generate a desktop entry for a distrobox container'\n    'version:Show distrobox version'\n  )\n  _describe -t commands 'distrobox command' commands\n}\n\n_arguments -C \\\n  '1: :_distrobox_commands' \\\n  '*:: :->args'\n\ncase $state in\n  args)\n    case $line[1] in\n      assemble)\n        _distrobox-assemble\n        ;;\n      create)\n        _distrobox-create\n        ;;\n      enter)\n        _distrobox-enter\n        ;;\n      list|ls)\n        _distrobox-list\n        ;;\n      rm)\n        _distrobox-rm\n        ;;\n      stop)\n        _distrobox-stop\n        ;;\n      upgrade)\n        _distrobox-upgrade\n        ;;\n      ephemeral)\n        _distrobox-ephemeral\n        ;;\n      generate-entry)\n        _distrobox-generate-entry\n        ;;\n      version)\n        # No additional completions needed for version\n        ;;\n    esac\nesac\n"
  },
  {
    "path": "completions/zsh/_distrobox-assemble",
    "content": "#compdef distrobox-assemble\n\n_message -r \"Create or remove containers in batches, based on a manifest file.\"\n_arguments \\\n  '1:command:(create rm)' \\\n  '--file[path to the distrobox manifest/ini file]:file:_files' \\\n  '(--name -n)'{-n,--name}'[run against a single entry in the manifest/ini file]:entry name:' \\\n  '(--replace -R)'{-R,--replace}'[replace already existing distroboxes with matching names]' \\\n  '(--dry-run -d)'{-d,--dry-run}'[only print the container manager command generated]' \\\n  '(--verbose -v)'{-v,--verbose}'[show more verbosity]' \\\n  '(--version -V)'{-V,--version}'[show version]'\n"
  },
  {
    "path": "completions/zsh/_distrobox-create",
    "content": "#compdef distrobox-create\n\n_distrobox-create() {\n    local -a options\n    local expl\n    local state\n    # Array of optargs to pass to _arguments for matching and completion\n    options=(\n        '(-i --image)'{-i,--image}'[Specify image to use for the container]:image:_distrobox_images'\n        '(-n --name)'{-n,--name}'[Specify name for the distrobox]:distrobox name:'\n        '--hostname[Specify hostname for the distrobox]:hostname:'\n        '(-p --pull)'{-p,--pull}'[Pull the image even if it exists locally (implies --yes)]'\n        '(-Y --yes)'{-Y,--yes}'[Non-interactive, pull images without asking]'\n        '(-r --root)'{-r,--root}'[Launch with root privileges using podman/docker/lilipod]'\n        '(-c --clone)'{-c,--clone}'[Name of the distrobox container to use as base for a new container]:clone container name:'\n        '(-H --home)'{-H,--home}'[Select a custom HOME directory for the container]:path:_files -/'\n        '--volume[Add additional volumes to the container]:volume:_files'\n        '(-a --additional-flags)'{-a,--additional-flags}'[Additional flags to pass to the container manager command]:flags:'\n        '(-ap --additional-packages)'{-ap,--additional-packages}'[Additional packages to install during setup]:package:'\n        '--init-hooks[Commands to execute during container initialization]:command:'\n        '--pre-init-hooks[Commands to execute prior to container initialization]:command:'\n        '(-I --init)'{-I,--init}'[Use an init system inside the container]'\n        '--nvidia[Try to integrate host nVidia drivers into the guest]'\n        '--unshare-devsys[Do not share host devices and sysfs dirs from host]'\n        '--unshare-groups[Do not forward users additional groups into the container]'\n        '--unshare-ipc[Do not share ipc namespace with host]'\n        '--unshare-netns[Do not share the net namespace with host]'\n        '--unshare-process[Do not share process namespace with host]'\n        '--unshare-all[Activate all the unshare flags]'\n        '(-C --compatibility)'{-C,--compatibility}'[Show list of compatible images]'\n        '(-h --help)'{-h,--help}'[Show this message]'\n        '--no-entry[Do not generate a container entry in the application list]'\n        '(-d --dry-run)'{-d,--dry-run}'[Only print the container manager command generated]'\n        '(-v --verbose)'{-v,--verbose}'[Show more verbosity]'\n        '(-V --version)'{-V,--version}'[Show version]'\n        '--absolutely-disable-root-password-i-am-really-positively-sure[Skip user password setup, leaving it blank]'\n    )\n    # Simple logic\n    _message -r \"Create new distroboxes.\"\n    _arguments \\\n      '1:containers:->container' \\\n      '*:options:->options' \\\n      $options[@]\n}\n\n_distrobox-create\n"
  },
  {
    "path": "completions/zsh/_distrobox-enter",
    "content": "#compdef distrobox-enter\n\n_distrobox-enter() {\n    local -a options\n    local expl\n    local state\n    local _db_cc\n\n    _db_cc=(\"${(@f)$(distrobox list | sed 1d | awk -F'|' '{print $2}' | sed 's/^[ \\t]*//;s/[ \\t]*$//')}\")\n\n    options=(\n      '(--name -n)'{-n,--name}'[name for the distrobox]:container:_distrobox_containers'\n      '--[end arguments and execute the rest as command to execute at login]:command:_command_names'\n      '(--no-tty -T)'{-T,--no-tty}'[do not instantiate a tty]'\n      '(--no-workdir -nw)'{-nw,--no-workdir}'[always start the container from container home directory]'\n      '(--additional-flags -a)'{-a,--additional-flags}'[additional flags to pass to the container manager command]:flags:'\n      '(--help -h)'{-h,--help}'[show this message]'\n      '(--root -r)'{-r,--root}'[launch podman/docker/lilipod with root privileges]'\n      '(--dry-run -d)'{-d,--dry-run}'[only print the container manager command generated]'\n      '(--verbose -v)'{-v,--verbose}'[show more verbosity]'\n      '(--version -V)'{-V,--version}'[show version]'\n    )\n    _message -r \"Start and enter a distrobox.\"\n    if [[ -n \"$_db_cc\" ]]; then\n      _arguments -C \\\n        '1:containers:_distrobox_containers' \\\n        $options[@]\n    else\n      _message -r \"No containers exist.\"\n      _arguments $options[@]\n    fi\n\n}\n\n_distrobox-enter\n"
  },
  {
    "path": "completions/zsh/_distrobox-ephemeral",
    "content": "#compdef distrobox-ephemeral\n\n_distrobox-ephemeral() {\n    local -a options\n    local expl\n    local state\n    # Array of optargs to pass to _arguments for matching and completion\n    options=(\n        '(-i --image)'{-i,--image}'[Specify image to use for the container]:image:_distrobox_images'\n        '(-n --name)'{-n,--name}'[Specify name for the distrobox]:distrobox name:'\n        '--hostname[Specify hostname for the distrobox]:hostname:'\n        '(-p --pull)'{-p,--pull}'[Pull the image even if it exists locally (implies --yes)]'\n        '(-Y --yes)'{-Y,--yes}'[Non-interactive, pull images without asking]'\n        '(-r --root)'{-r,--root}'[Launch with root privileges using podman/docker/lilipod]'\n        '(-c --clone)'{-c,--clone}'[Name of the distrobox container to use as base for a new container]:clone container name:'\n        '(-H --home)'{-H,--home}'[Select a custom HOME directory for the container]:path:_files -/'\n        '--volume[Add additional volumes to the container]:volume:_files'\n        '(-a --additional-flags)'{-a,--additional-flags}'[Additional flags to pass to the container manager command]:flags:'\n        '(-ap --additional-packages)'{-ap,--additional-packages}'[Additional packages to install during setup]:package:'\n        '--init-hooks[Commands to execute during container initialization]:command:'\n        '--pre-init-hooks[Commands to execute prior to container initialization]:command:'\n        '(-I --init)'{-I,--init}'[Use an init system inside the container]'\n        '--nvidia[Try to integrate host nVidia drivers into the guest]'\n        '--unshare-devsys[Do not share host devices and sysfs dirs from host]'\n        '--unshare-groups[Do not forward users additional groups into the container]'\n        '--unshare-ipc[Do not share ipc namespace with host]'\n        '--unshare-netns[Do not share the net namespace with host]'\n        '--unshare-process[Do not share process namespace with host]'\n        '--unshare-all[Activate all the unshare flags]'\n        '(-C --compatibility)'{-C,--compatibility}'[Show list of compatible images]'\n        '(-h --help)'{-h,--help}'[Show this message]'\n        '--no-entry[Do not generate a container entry in the application list]'\n        '(-d --dry-run)'{-d,--dry-run}'[Only print the container manager command generated]'\n        '(-v --verbose)'{-v,--verbose}'[Show more verbosity]'\n        '(-V --version)'{-V,--version}'[Show version]'\n        '--absolutely-disable-root-password-i-am-really-positively-sure[Skip user password setup, leaving it blank]'\n    )\n    # Simple logic\n    _message -r \"Create temporary distroboxes that are auto destroyed.\"\n    _arguments \\\n      '1:containers:->container' \\\n      '*:options:->options' \\\n      $options[@]\n}\n\n_distrobox-ephemeral\n"
  },
  {
    "path": "completions/zsh/_distrobox-export",
    "content": "#compdef distrobox-export\n\n_message -r \"Export an app or a binary from the container to the host.\"\n_arguments \\\n  '(--app -a)'{-a,--app}'[name of the application to export]:application name:' \\\n  '(--bin -b)'{-b,--bin}'[absolute path of the binary to export]:path to binary:_files' \\\n  '(--delete -d)'{-d,--delete}'[delete exported application or binary]' \\\n  '(--export-label -el)'{-el,--export-label}'[label to add to exported application name, use \"none\" to disable]:label:' \\\n  '(--export-path -ep)'{-ep,--export-path}'[path where to export the binary]:export path:_files' \\\n  '(--extra-flags -ef)'{-ef,--extra-flags}'[extra flags to add to the command]:extra flags:' \\\n  '(--enter-flags -nf)'{-nf,--enter-flags}'[flags to add to distrobox-enter]:enter flags:' \\\n  '--list-apps[list applications exported from this container]' \\\n  '--list-binaries[list binaries exported from this container, use -ep to specify custom paths to search]' \\\n  '(--sudo -S)'{-S,--sudo}'[specify if the exported item should be run as sudo]' \\\n  '(--help -h)'{-h,--help}'[show this message]' \\\n  '(--verbose -v)'{-v,--verbose}'[show more verbosity]' \\\n  '(--version -V)'{-V,--version}'[show version]'\n"
  },
  {
    "path": "completions/zsh/_distrobox-generate-entry",
    "content": "#compdef distrobox-generate-entry\n\n_distrobox-generate-entry() {\n    # expl is an internal zsh array that gets passed to _arguments bts\n    local expl\n    local -a options\n    local _db_cc\n    # Check for existing containers and store the result into var _db_cc\n    _db_cc=(\"${(@f)$(distrobox list | sed 1d | awk -F'|' '{print $2}' | sed 's/^[ \\t]*//;s/[ \\t]*$//')}\")\n    # Array of optargs to pass to _arguments for matching and completion\n    options=(\n        '(-h --help)'{-h,--help}'[show this message]'\n        '(-a --all)'{-a,--all}'[perform for all distroboxes]'\n        '(-d --delete)'{-d,--delete}'[delete the entry]'\n        '(-i --icon)'{-i,--icon}'[specify a custom icon (default auto)]:icon path:(auto _files)'\n        '(-r --root)'{-r,--root}'[perform on rootful distroboxes]'\n        '(-v --verbose)'{-v,--verbose}'[show more verbosity]'\n        '(-V --version)'{-V,--version}'[show version]'\n    )\n    _message -r \"Create a desktop icon for a distrobox\"\n    # If containers exist then do an action\n    if [[ -n \"$_db_cc\" ]]; then\n      # Match both container names and optargs\n      _arguments \\\n        '*:containers:_distrobox_containers' \\\n        $options[@]\n    # If no containers exist then do an action\n    else\n      # Display message to user and match optargs only\n      _message -r \"No containers exist.\"\n      _arguments $options[@]\n    fi\n}\n\n_distrobox-generate-entry\n"
  },
  {
    "path": "completions/zsh/_distrobox-host-exec",
    "content": "#compdef distrobox-host-exec\n\n_message -r \"Execute a command on the host while in a container\"\n_arguments \\\n  '*:command:_command' \\\n  '(--help -h)'{-h,--help}'[show this message]' \\\n  '(--verbose -v)'{-v,--verbose}'[show more verbosity]' \\\n  '(--version -V)'{-V,--version}'[show version]' \\\n  '(--yes -Y)'{-Y,--yes}'[Automatically answer yes to prompt host-spawn will be installed on the guest system if not detected]'\n"
  },
  {
    "path": "completions/zsh/_distrobox-init",
    "content": "#compdef distrobox-init\n\n_message -r \"Init the distrobox (not to be launched manually)\"\n_arguments \\\n  '(--name -n)'{-n,--name}'[user name]:user name:' \\\n  '(--user -u)'{-u,--user}'[uid of the user]:uid:' \\\n  '(--group -g)'{-g,--group}'[gid of the user]:gid:' \\\n  '(--home -d)'{-d,--home}'[path/to/home of the user]:home path:_files' \\\n  '(--help -h)'{-h,--help}'[show this message]' \\\n  '--additional-packages[packages to install in addition]:packages:' \\\n  '(--init -I)'{-I,--init}'[whether to use or not init]' \\\n  '--pre-init-hooks[commands to execute prior to init]:commands:' \\\n  '--nvidia[try to integrate hosts nVidia drivers in the guest]' \\\n  '(--upgrade -U)'{-U,--upgrade}'[run init in upgrade mode]' \\\n  '(--verbose -v)'{-v,--verbose}'[show more verbosity]' \\\n  '(--version -V)'{-V,--version}'[show version]' \\\n  '--:[end arguments execute the rest as command to execute during init]:command:_command'\n"
  },
  {
    "path": "completions/zsh/_distrobox-list",
    "content": "#compdef distrobox-list\n\n_message -r \"List available distroboxes.\"\n_arguments \\\n  '(--help -h)'{-h,--help}'[show this message]' \\\n  '--no-color[disable color formatting]' \\\n  '(--root -r)'{-r,--root}'[launch podman/docker/lilipod with root privileges]' \\\n  '(--verbose -v)'{-v,--verbose}'[show more verbosity]' \\\n  '(--version -V)'{-V,--version}'[show version]'\n"
  },
  {
    "path": "completions/zsh/_distrobox-rm",
    "content": "#compdef distrobox-rm\n\n_distrobox-rm() {\n    # expl is an internal zsh array that gets passed to _arguments bts\n    local expl\n    local -a options\n    local _db_cc\n    # Check for existing containers and store the result into var _db_cc\n    _db_cc=(\"${(@f)$(distrobox list | sed 1d | awk -F'|' '{print $2}' | sed 's/^[ \\t]*//;s/[ \\t]*$//')}\")\n    # Array of optargs to pass to _arguments for matching and completion\n    options=(\n        '(-a --all)'{-a,--all}'[delete all distroboxes]'\n        '(-f --force)'{-f,--force}'[force deletion]'\n        '--rm-home[remove the mounted home if it differs from the host users one]'\n        '(-r --root)'{-r,--root}'[launch podman/docker/lilipod with root privileges]'\n        '(-h --help)'{-h,--help}'[show this message]'\n        '(-v --verbose)'{-v,--verbose}'[show more verbosity]'\n        '(-V --version)'{-V,--version}'[show version]'\n    )\n    _message -r \"Delete one or more distroboxes.\"\n    # If containers exist then do an action\n    if [[ -n \"$_db_cc\" ]]; then\n      # Match both container names and optargs\n      _arguments \\\n        '*:containers:_distrobox_containers' \\\n        $options[@]\n    # If no containers exist then do an action\n    else\n      # Display message to user and match optargs only\n      _message -r \"No containers exist.\"\n      _arguments $options[@]\n    fi\n\n}\n\n_distrobox-rm\n"
  },
  {
    "path": "completions/zsh/_distrobox-stop",
    "content": "#compdef distrobox-stop\n\n_distrobox-stop() {\n    local expl\n    local -a options\n    local _db_rcc\n\n     _db_rcc=($(distrobox list | awk -F'|' '$3 ~ /Up/ { gsub(/^[ \\t]+|[ \\t]+$/, \"\", $2); print $2 }'))                                                                     \n\n    options=(\n        '(-a --all)'{-a,--all}'[stop all distroboxes]'\n        '(-Y --yes)'{-Y,--yes}'[non-interactive, stop without asking]'\n        '(-r --root)'{-r,--root}'[launch podman/docker/lilipod with root privileges]'\n        '(-h --help)'{-h,--help}'[show this message]'\n        '(-v --verbose)'{-v,--verbose}'[show more verbosity]'\n        '(-V --version)'{-V,--version}'[show version]'\n    )\n\n    _message -r \"Stop running distrobox containers.\"\n    if [[ -n \"$_db_rcc\" ]]; then\n      _arguments -C \\\n        '*:containers:_distrobox_running_containers' \\\n        $options[@]\n    else\n      _message -r \"No running containers.\"\n      _arguments $options[@]\n    fi\n\n}\n\n_distrobox-stop\n"
  },
  {
    "path": "completions/zsh/_distrobox-upgrade",
    "content": "#compdef distrobox-upgrade\n\n_distrobox-upgrade() {\n    local expl\n    local -a options\n    local _db_cc\n\n    _db_cc=(\"${(@f)$(distrobox list | sed 1d | awk -F'|' '{print $2}' | sed 's/^[ \\t]*//;s/[ \\t]*$//')}\")\n    \n    options=(\n        '(-a --all)'{-a,--all}'[upgrade all distroboxes]'\n        '--running[perform only for running distroboxes]'\n        '(-r --root)'{-r,--root}'[launch podman/docker/lilipod with root privileges]'\n        '(-h --help)'{-h,--help}'[show this message]'\n        '(-v --verbose)'{-v,--verbose}'[show more verbosity]'\n        '(-V --version)'{-V,--version}'[show version]'\n    )\n\n    _message -r \"Upgrade distroboxes using container's package manager.\"\n    if [[ -n \"$_db_cc\" ]]; then\n      _arguments \\\n        '*:containers:_distrobox_containers' \\\n        $options[@]\n    else\n      _message -r \"No containers exist.\"\n      _arguments $options[@]\n    fi\n\n}\n\n_distrobox-upgrade\n"
  },
  {
    "path": "completions/zsh/_distrobox_containers",
    "content": "#autoload\n\n_distrobox_containers() {\n    local -a containers\n    containers=(\"${(@f)$(distrobox list | sed 1d | awk -F'|' '{print $2}' | sed 's/^[ \\t]*//;s/[ \\t]*$//')}\")\n    _describe -t containers 'available containers' containers\n}\n"
  },
  {
    "path": "completions/zsh/_distrobox_images",
    "content": "#autoload\n\n_distrobox_images() {\n    local -a images\n    images=(\"${(@f)$(distrobox-create --compatibility | awk 'NF {print $0}')}\")\n    _wanted images expl 'compatible image' compadd -a images\n}\n"
  },
  {
    "path": "completions/zsh/_distrobox_running_containers",
    "content": "#autoload\n\n_distrobox_running_containers() {\n    local -a containers\n    containers=($(distrobox list | awk -F'|' '$3 ~ /Up/ { gsub(/^[ \\t]+|[ \\t]+$/, \"\", $2); print $2 }'))\n    if (( ${#containers} > 0 )); then\n      _describe -t running-containers 'running containers' containers\n    fi\n}\n"
  },
  {
    "path": "distrobox",
    "content": "#!/bin/sh\n# SPDX-License-Identifier: GPL-3.0-only\n#\n# This file is part of the distrobox project:\n#    https://github.com/89luca89/distrobox\n#\n# Copyright (C) 2021 distrobox contributors\n#\n# distrobox is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 3\n# as published by the Free Software Foundation.\n#\n# distrobox is distributed in the hope that it will be useful, but\n# WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n# General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with distrobox; if not, see <http://www.gnu.org/licenses/>.\n\n# POSIX\nset -o errexit\nset -o nounset\n\nversion=\"1.8.2.4\"\n\n# show_help will print usage to stdout.\n# Arguments:\n#   None\n# Expected global variables:\n#   version: distrobox version\n# Expected env variables:\n#   None\n# Outputs:\n#   print usage with examples.\nshow_help()\n{\n\tcat << EOF\ndistrobox version: ${version}\n\nChoose one of the available commands:\n\tassemble\n\tcreate\n\tenter\n\tlist | ls\n\trm\n\tstop\n\tupgrade\n\tephemeral\n\tgenerate-entry\n\tversion\n\thelp\nEOF\n}\n\nif [ $# -eq 0 ]; then\n\tshow_help\n\texit\nfi\n\ndistrobox_path=\"$(dirname \"${0}\")\"\ndistrobox_command=\"${1}\"\nshift\n\n# Simple wrapper to the distrobox utilities.\n# We just detect the 1st argument and launch the matching distrobox utility.\ncase \"${distrobox_command}\" in\n\tassemble)\n\t\t\"${distrobox_path}\"/distrobox-assemble \"$@\"\n\t\t;;\n\tcreate)\n\t\t\"${distrobox_path}\"/distrobox-create \"$@\"\n\t\t;;\n\tenter)\n\t\t\"${distrobox_path}\"/distrobox-enter \"$@\"\n\t\t;;\n\tls | list)\n\t\t\"${distrobox_path}\"/distrobox-list \"$@\"\n\t\t;;\n\tstop)\n\t\t\"${distrobox_path}\"/distrobox-stop \"$@\"\n\t\t;;\n\trm)\n\t\t\"${distrobox_path}\"/distrobox-rm \"$@\"\n\t\t;;\n\tupgrade)\n\t\t\"${distrobox_path}\"/distrobox-upgrade \"$@\"\n\t\t;;\n\tgenerate-entry)\n\t\t\"${distrobox_path}\"/distrobox-generate-entry \"$@\"\n\t\t;;\n\tephemeral)\n\t\t\"${distrobox_path}\"/distrobox-ephemeral \"$@\"\n\t\t;;\n\t-V | --version | version)\n\t\tprintf \"distrobox: %s\\n\" \"${version}\"\n\t\texit 0\n\t\t;;\n\thelp | --help | -h)\n\t\tshow_help\n\t\texit 0\n\t\t;;\n\t*) # Default case: If no more options then break out of the loop.\n\t\tprintf >&2 \"Error: invalid command\\n\"\n\t\tshow_help\n\t\texit 1\n\t\t;;\nesac\n"
  },
  {
    "path": "distrobox-assemble",
    "content": "#!/bin/sh\n# SPDX-License-Identifier: GPL-3.0-only\n#\n# This file is part of the distrobox project:\n#    https://github.com/89luca89/distrobox\n#\n# Copyright (C) 2021 distrobox contributors\n#\n# distrobox is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 3\n# as published by the Free Software Foundation.\n#\n# distrobox is distributed in the hope that it will be useful, but\n# WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n# General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with distrobox; if not, see <http://www.gnu.org/licenses/>.\n\n# Ensure we have our env variables correctly set\n[ -z \"${USER}\" ] && USER=\"$(id -run)\"\n[ -z \"${HOME}\" ] && HOME=\"$(getent passwd \"${USER}\" | cut -d':' -f6)\"\n[ -z \"${SHELL}\" ] && SHELL=\"$(getent passwd \"${USER}\" | cut -d':' -f7)\"\n\n# POSIX\n#\ndefault_input_file=\"./distrobox.ini\"\ndelete=-1\ndistrobox_path=\"$(dirname \"${0}\")\"\ndryrun=0\nboxname=\"\"\ninput_file=\"\"\nreplace=0\nroot_flag=\"\"\n# tmpfile will be used as a little buffer to pass variables without messing up\n# quoting and escaping\ntmpfile=\"$(mktemp -u)\"\ntmp_download_file=\"$(mktemp -u)\"\nverbose=0\nversion=\"1.8.2.4\"\n# initializing block of variables used in the manifest\nadditional_flags=\"\"\nadditional_packages=\"\"\nentry=\"\"\nhome=\"\"\nhostname=\"\"\nimage=\"\"\nclone=\"\"\ninit=\"\"\ninit_hooks=\"\"\nnvidia=\"\"\npre_init_hooks=\"\"\npull=\"\"\nroot=\"\"\nstart_now=\"\"\nunshare_groups=\"\"\nunshare_ipc=\"\"\nunshare_netns=\"\"\nunshare_process=\"\"\nunshare_devsys=\"\"\nunshare_all=\"\"\nvolume=\"\"\nexported_apps=\"\"\nexported_bins=\"\"\nexported_bins_path=\"${HOME}/.local/bin\"\n\n# Cleanup tmpfiles on exit\ntrap 'rm -f ${tmpfile} ${tmp_download_file}' EXIT\n\n# Despite of running this script via SUDO/DOAS being not supported (the\n# script itself will call the appropriate tool when necessary), we still want\n# to allow people to run it as root, logged in in a shell, and create rootful\n# containers.\n#\n# SUDO_USER is a variable set by SUDO and can be used to check whether the script was called by it. Same thing for DOAS_USER, set by DOAS.\nif [ -n \"${SUDO_USER}\" ] || [ -n \"${DOAS_USER}\" ]; then\n\tprintf >&2 \"Running %s via SUDO/DOAS is not supported.\" \"$(basename \"${0}\")\"\n\tprintf >&2 \"Instead, please try using root=true property in the distrobox.ini file.\\n\"\n\texit 1\nfi\n\n# Source configuration files, this is done in an hierarchy so local files have\n# priority over system defaults\n# leave priority to environment variables.\n#\n# On NixOS, for the distrobox derivation to pick up a static config file shipped\n# by the package maintainer the path must be relative to the script itself.\nself_dir=\"$(dirname \"$(realpath \"$0\")\")\"\nnix_config_file=\"${self_dir}/../share/distrobox/distrobox.conf\"\n\nconfig_files=\"\n\t${nix_config_file}\n\t/usr/share/distrobox/distrobox.conf\n\t/usr/share/defaults/distrobox/distrobox.conf\n\t/usr/etc/distrobox/distrobox.conf\n\t/usr/local/share/distrobox/distrobox.conf\n\t/etc/distrobox/distrobox.conf\n\t${XDG_CONFIG_HOME:-\"${HOME}/.config\"}/distrobox/distrobox.conf\n\t${HOME}/.distroboxrc\n\"\nfor config_file in ${config_files}; do\n\t# Shellcheck will give error for sourcing a variable file as it cannot follow\n\t# it. We don't care so let's disable this linting for now.\n\t# shellcheck disable=SC1090\n\t[ -e \"${config_file}\" ] && . \"$(realpath \"${config_file}\")\"\ndone\n\n[ -n \"${DBX_VERBOSE}\" ] && verbose=\"${DBX_VERBOSE}\"\n\n# Fixup variable=[true|false], in case we find it in the config file(s)\n[ \"${verbose}\" = \"true\" ] && verbose=1\n[ \"${verbose}\" = \"false\" ] && verbose=0\n\n# show_help will print usage to stdout.\n# Arguments:\n#   None\n# Expected global variables:\n#   version: string distrobox version\n# Expected env variables:\n#   None\n# Outputs:\n#   print usage with examples.\nshow_help()\n{\n\tcat << EOF\ndistrobox version: ${version}\n\nUsage:\n\n\tdistrobox assemble create\n\tdistrobox assemble rm\n\tdistrobox assemble create --file /path/to/file.ini\n\tdistrobox assemble rm --file /path/to/file.ini\n\tdistrobox assemble create --replace --file /path/to/file.ini\n\nOptions:\n\n\t--file:\t\t\tpath or URL to the distrobox manifest/ini file\n\t--name/-n:\t\trun against a single entry in the manifest/ini file\n\t--replace/-R:\t\treplace already existing distroboxes with matching names\n\t--dry-run/-d:\t\tonly print the container manager command generated\n\t--verbose/-v:\t\tshow more verbosity\n\t--version/-V:\t\tshow version\nEOF\n}\n\n# Parse arguments\nwhile :; do\n\tcase $1 in\n\t\tcreate)\n\t\t\tdelete=0\n\t\t\tshift\n\t\t\t;;\n\t\trm)\n\t\t\tdelete=1\n\t\t\tshift\n\t\t\t;;\n\t\t--file)\n\t\t\t# Call a \"show_help\" function to display a synopsis, then exit.\n\t\t\tif [ -n \"$2\" ]; then\n\t\t\t\tinput_file=\"${2}\"\n\t\t\t\tshift\n\t\t\t\tshift\n\t\t\tfi\n\t\t\t;;\n\t\t-n | --name)\n\t\t\t# Call a \"show_help\" function to display a synopsis, then exit.\n\t\t\tif [ -n \"$2\" ]; then\n\t\t\t\tboxname=\"${2}\"\n\t\t\t\tshift\n\t\t\t\tshift\n\t\t\tfi\n\t\t\t;;\n\t\t-h | --help)\n\t\t\t# Call a \"show_help\" function to display a synopsis, then exit.\n\t\t\tshow_help\n\t\t\texit 0\n\t\t\t;;\n\t\t-d | --dry-run)\n\t\t\tshift\n\t\t\tdryrun=1\n\t\t\t;;\n\t\t-v | --verbose)\n\t\t\tverbose=1\n\t\t\tshift\n\t\t\t;;\n\t\t-R | --replace)\n\t\t\treplace=1\n\t\t\tshift\n\t\t\t;;\n\t\t-V | --version)\n\t\t\tprintf \"distrobox: %s\\n\" \"${version}\"\n\t\t\texit 0\n\t\t\t;;\n\t\t--) # End of all options.\n\t\t\tshift\n\t\t\tbreak\n\t\t\t;;\n\t\t-*) # Invalid options.\n\t\t\tprintf >&2 \"ERROR: Invalid flag '%s'\\n\\n\" \"$1\"\n\t\t\tshow_help\n\t\t\texit 1\n\t\t\t;;\n\t\t*) # Default case: If no more options then break out of the loop.\n\t\t\t# If we have a flagless option and container_name is not specified\n\t\t\t# then let's accept argument as container_name\n\t\t\tif [ -n \"$1\" ]; then\n\t\t\t\tinput_file=\"$1\"\n\t\t\t\tshift\n\t\t\telse\n\t\t\t\tbreak\n\t\t\tfi\n\t\t\t;;\n\tesac\ndone\n\nset -o errexit\nset -o nounset\n# set verbosity\nif [ \"${verbose}\" -ne 0 ]; then\n\tset -o xtrace\nfi\n\n# check if we're getting the right inputs\nif [ \"${delete}\" -eq -1 ]; then\n\tprintf >&2 \"Please specify create or rm.\\n\"\n\tshow_help\n\texit 1\nfi\n\n# Fallback to distrobox.ini if no file is passed\nif [ -z \"${input_file}\" ]; then\n\tinput_file=\"${default_input_file}\"\nfi\n\n# Check if file effectively exists\nif [ ! -e \"${input_file}\" ]; then\n\n\tif command -v curl > /dev/null 2>&1; then\n\t\tdownload=\"curl --connect-timeout 3 --retry 1 -sLo\"\n\telif command -v wget > /dev/null 2>&1; then\n\t\tdownload=\"wget --timeout=3 --tries=1 -qO\"\n\tfi\n\n\tif ! ${download} - \"${input_file}\" > \"${tmp_download_file}\"; then\n\t\tprintf >&2 \"File %s does not exist.\\n\" \"${input_file}\"\n\t\texit 1\n\telse\n\t\tinput_file=\"${tmp_download_file}\"\n\tfi\nfi\n\n# run_distrobox will create distrobox with parameters parsed from ini file.\n# Arguments:\n#   name: name of the distrobox.\n# Expected global variables:\n#   boxname: string name of the target container\n#   tmpfile: string name of the tmpfile to read\n#   delete:  bool delete container\n#   replace: bool replace container\n#   dryrun:  bool dryrun (only print, no execute)\n#   verbose: bool verbose\n# Expected env variables:\n#   None\n# Outputs:\n#   execution of the proper distrobox-create command.\nrun_distrobox()\n{\n\tname=\"${1}\"\n\tadditional_flags=\"\"\n\tadditional_packages=\"\"\n\tentry=\"\"\n\thome=\"\"\n\thostname=\"\"\n\timage=\"\"\n\tclone=\"\"\n\tinit=\"\"\n\tinit_hooks=\"\"\n\tnvidia=\"\"\n\tpre_init_hooks=\"\"\n\tpull=\"\"\n\troot=\"\"\n\tstart_now=\"\"\n\tunshare_groups=\"\"\n\tunshare_ipc=\"\"\n\tunshare_netns=\"\"\n\tunshare_process=\"\"\n\tunshare_devsys=\"\"\n\tunshare_all=\"\"\n\tvolume=\"\"\n\texported_apps=\"\"\n\texported_bins=\"\"\n\texported_bins_path=\"${HOME}/.local/bin\"\n\n\t# Skip item if --name used and no match is found\n\tif [ \"${boxname}\" != \"\" ] && [ \"${boxname}\" != \"${name}\" ]; then\n\t\trm -f \"${tmpfile}\"\n\t\treturn\n\tfi\n\n\t# Source the current block variables\n\tif [ -e \"${tmpfile}\" ]; then\n\t\t# shellcheck disable=SC1090\n\t\t. \"${tmpfile}\" && rm -f \"${tmpfile}\"\n\tfi\n\n\tif [ -n \"${root}\" ] && [ \"${root}\" -eq 1 ]; then\n\t\troot_flag=\"--root\"\n\tfi\n\n\t# We're going to delete, not create!\n\tif [ \"${delete}\" -ne 0 ] || [ \"${replace}\" -ne 0 ]; then\n\t\tprintf \" - Deleting %s...\\n\" \"${name}\"\n\n\t\tif [ \"${dryrun}\" -eq 0 ]; then\n\t\t\t# shellcheck disable=SC2086,2248\n\t\t\t\"${distrobox_path}\"/distrobox rm ${root_flag} -f \"${name}\" > /dev/null || :\n\t\tfi\n\n\t\tif [ \"${delete}\" -ne 0 ]; then\n\t\t\treturn\n\t\tfi\n\tfi\n\n\t# We're going to create!\n\tprintf \" - Creating %s...\\n\" \"${name}\"\n\n\t# If distrobox already exist, and we have replace enabled, destroy the container\n\t# we have to recreate it.\n\t# shellcheck disable=SC2086,2248\n\tif \"${distrobox_path}\"/distrobox-list ${root_flag} | grep -qw \" ${name} \" && [ \"${dryrun}\" -eq 0 ]; then\n\t\tprintf >&2 \"%s already exists\\n\" \"${name}\"\n\t\treturn 0\n\tfi\n\n\t# Now we dynamically generate the distrobox-create command based on the\n\t# declared flags.\n\tresult_command=\"${distrobox_path}/distrobox-create --yes\"\n\tif [ \"${verbose}\" -ne 0 ]; then\n\t\tresult_command=\"${result_command} -v\"\n\tfi\n\tif [ -n \"${name}\" ]; then\n\t\tresult_command=\"${result_command} --name $(sanitize_variable \"${name}\")\"\n\tfi\n\tif [ -n \"${image}\" ]; then\n\t\tresult_command=\"${result_command} --image $(sanitize_variable \"${image}\")\"\n\tfi\n\tif [ -n \"${clone}\" ]; then\n\t\tresult_command=\"${result_command} --clone $(sanitize_variable \"${clone}\")\"\n\tfi\n\tif [ -n \"${init}\" ] && [ \"${init}\" -eq 1 ]; then\n\t\tresult_command=\"${result_command} --init\"\n\tfi\n\tif [ -n \"${root}\" ] && [ \"${root}\" -eq 1 ]; then\n\t\tresult_command=\"${result_command} --root\"\n\tfi\n\tif [ -n \"${pull}\" ] && [ \"${pull}\" -eq 1 ]; then\n\t\tresult_command=\"${result_command} --pull\"\n\tfi\n\tif [ -n \"${entry}\" ] && [ \"${entry}\" -eq 0 ]; then\n\t\tresult_command=\"${result_command} --no-entry\"\n\tfi\n\tif [ -n \"${nvidia}\" ] && [ \"${nvidia}\" -eq 1 ]; then\n\t\tresult_command=\"${result_command} --nvidia\"\n\tfi\n\tif [ -n \"${unshare_netns}\" ] && [ \"${unshare_netns}\" -eq 1 ]; then\n\t\tresult_command=\"${result_command} --unshare-netns\"\n\tfi\n\tif [ -n \"${unshare_groups}\" ] && [ \"${unshare_groups}\" -eq 1 ]; then\n\t\tresult_command=\"${result_command} --unshare-groups\"\n\tfi\n\tif [ -n \"${unshare_ipc}\" ] && [ \"${unshare_ipc}\" -eq 1 ]; then\n\t\tresult_command=\"${result_command} --unshare-ipc\"\n\tfi\n\tif [ -n \"${unshare_process}\" ] && [ \"${unshare_process}\" -eq 1 ]; then\n\t\tresult_command=\"${result_command} --unshare-process\"\n\tfi\n\tif [ -n \"${unshare_devsys}\" ] && [ \"${unshare_devsys}\" -eq 1 ]; then\n\t\tresult_command=\"${result_command} --unshare-devsys\"\n\tfi\n\tif [ -n \"${unshare_all}\" ] && [ \"${unshare_all}\" -eq 1 ]; then\n\t\tresult_command=\"${result_command} --unshare-all\"\n\tfi\n\tif [ -n \"${home}\" ]; then\n\t\tresult_command=\"${result_command} --home $(sanitize_variable \"${home}\")\"\n\tfi\n\tif [ -n \"${hostname}\" ]; then\n\t\tresult_command=\"${result_command} --hostname $(sanitize_variable \"${hostname}\")\"\n\tfi\n\tif [ -n \"${init_hooks}\" ]; then\n\t\tIFS=\"¤\"\n\t\targs=\": ;\"\n\t\tseparator=\"\"\n\t\tfor arg in ${init_hooks}; do\n\t\t\tif [ -z \"${arg}\" ]; then\n\t\t\t\tcontinue\n\t\t\tfi\n\n\t\t\t# Convert back from base64\n\t\t\targ=\"$(echo \"${arg}\" | base64 -d)\"\n\t\t\targs=\"${args} ${separator} ${arg}\"\n\n\t\t\t# Prepare for the next line, if we already have a ';' or '&&', do nothing\n\t\t\t# else prefer adding '&&'\n\t\t\tif ! echo \"${arg}\" | grep -qE ';[[:space:]]{0,1}$' &&\n\t\t\t\t! echo \"${arg}\" | grep -qE '&&[[:space:]]{0,1}$'; then\n\t\t\t\tseparator=\"&&\"\n\t\t\telse\n\t\t\t\tseparator=\"\"\n\t\t\tfi\n\t\tdone\n\t\tresult_command=\"${result_command} --init-hooks $(sanitize_variable \"${args}\")\"\n\tfi\n\t# Replicable flags\n\tif [ -n \"${pre_init_hooks}\" ]; then\n\t\tIFS=\"¤\"\n\t\targs=\": ;\"\n\t\tseparator=\"\"\n\t\tfor arg in ${pre_init_hooks}; do\n\t\t\tif [ -z \"${arg}\" ]; then\n\t\t\t\tcontinue\n\t\t\tfi\n\n\t\t\t# Convert back from base64\n\t\t\targ=\"$(echo \"${arg}\" | base64 -d)\"\n\t\t\targs=\"${args} ${separator} ${arg}\"\n\n\t\t\t# Prepare for the next line, if we already have a ';' or '&&', do nothing\n\t\t\t# else prefer adding '&&'\n\t\t\tif ! echo \"${arg}\" | grep -qE ';[[:space:]]{0,1}$' &&\n\t\t\t\t! echo \"${arg}\" | grep -qE '&&[[:space:]]{0,1}$'; then\n\t\t\t\tseparator=\"&&\"\n\t\t\telse\n\t\t\t\tseparator=\"\"\n\t\t\tfi\n\t\tdone\n\t\tresult_command=\"${result_command} --pre-init-hooks $(sanitize_variable \"${args}\")\"\n\tfi\n\tif [ -n \"${additional_packages}\" ]; then\n\t\tIFS=\"¤\"\n\t\targs=\"\"\n\t\tfor packages in ${additional_packages}; do\n\t\t\tif [ -z \"${packages}\" ]; then\n\t\t\t\tcontinue\n\t\t\tfi\n\t\t\targs=\"${args} ${packages}\"\n\t\tdone\n\t\tresult_command=\"${result_command} --additional-packages $(sanitize_variable \"${args}\")\"\n\tfi\n\tif [ -n \"${volume}\" ]; then\n\t\tIFS=\"¤\"\n\t\tfor vol in ${volume}; do\n\t\t\tif [ -z \"${vol}\" ]; then\n\t\t\t\tcontinue\n\t\t\tfi\n\t\t\tresult_command=\"${result_command} --volume $(sanitize_variable \"${vol}\")\"\n\t\tdone\n\tfi\n\tif [ -n \"${additional_flags}\" ]; then\n\t\tIFS=\"¤\"\n\t\tfor flag in ${additional_flags}; do\n\t\t\tif [ -z \"${flag}\" ]; then\n\t\t\t\tcontinue\n\t\t\tfi\n\t\t\tresult_command=\"${result_command} --additional-flags $(sanitize_variable \"${flag}\")\"\n\t\tdone\n\tfi\n\tif [ \"${dryrun}\" -ne 0 ]; then\n\t\tresult_command=\"${result_command} --dry-run\"\n\tfi\n\n\t# Execute the distrobox-create command\n\teval \"${result_command}\"\n\n\tif [ \"${dryrun}\" -ne 0 ]; then\n\t\treturn\n\tfi\n\n\t# If we need to start immediately, do it, so that the container\n\t# is ready to be entered.\n\tif [ -n \"${start_now}\" ] && [ \"${start_now}\" -eq 1 ]; then\n\t\t# Here we execute the `distrobox enter` command with a `/dev/null` stdin.\n\t\t# This is due to the fact that this command is very likely to be executed inside\n\t\t# the read loop in the prse_file function. This way we avoid stdin to be swallowed by\n\t\t# this command execution. This is valid for all the `distrobox enter` calls from now on.\n\t\t#\n\t\t# shellcheck disable=SC2086,2248\n\t\t\"${distrobox_path}\"/distrobox enter ${root_flag} \"${name}\" -- touch /dev/null < /dev/null\n\tfi\n\n\t# if there are exported bins and apps declared, let's export them\n\tif [ -n \"${exported_apps}\" ] || [ -n \"${exported_bins}\" ]; then\n\t\t# First we start the container\n\t\t# shellcheck disable=SC2086,2248\n\t\t\"${distrobox_path}\"/distrobox enter ${root_flag} \"${name}\" -- touch /dev/null < /dev/null\n\n\t\tIFS=\"¤\"\n\t\tfor apps in ${exported_apps}; do\n\t\t\t# Split the string by spaces\n\t\t\tIFS=\" \"\n\t\t\tfor app in ${apps}; do\n\t\t\t\t# Export the app\n\t\t\t\t# shellcheck disable=SC2086,2248\n\t\t\t\t\"${distrobox_path}\"/distrobox enter ${root_flag} \"${name}\" -- distrobox-export --app \"${app}\" < /dev/null\n\t\t\tdone\n\t\tdone\n\n\t\tIFS=\"¤\"\n\t\tfor bins in ${exported_bins}; do\n\t\t\t# Split the string by spaces\n\t\t\tIFS=\" \"\n\t\t\tfor bin in ${bins}; do\n\t\t\t\t# Export the bin\n\t\t\t\t# shellcheck disable=SC2086,2248\n\t\t\t\t\"${distrobox_path}\"/distrobox enter ${root_flag} \"${name}\" -- distrobox-export --bin \"${bin}\" \\\n\t\t\t\t\t--export-path \"${exported_bins_path}\" < /dev/null\n\t\t\tdone\n\t\tdone\n\tfi\n}\n\n# encode_variable will encode an input in base64, removing surrounding single/double quotes.\n# Arguments:\n#   variable: string\n# Expected global variables:\n#   None\n# Expected env variables:\n#   None\n# Outputs:\n#   a value string encoded in base64\nencode_variable()\n{\n\tvariable=\"${1}\"\n\t# remove surrounding quotes possibly added by the user\n\tif echo \"${variable}\" | grep -qE '^\"'; then\n\t\tvariable=\"$(echo \"${variable}\" | sed -e 's/^\"//' -e 's/\"$//')\"\n\telif echo \"${variable}\" | grep -qE \"^'\"; then\n\t\tvariable=\"$(echo \"${variable}\" | sed -e \"s/^'//\" -e \"s/'$//\")\"\n\tfi\n\n\techo \"${variable}\" | base64 -w 0\n}\n\n# sanitize_variable will sanitize an input, add single/double quotes and escapes\n# Arguments:\n#   variable: string\n# Expected global variables:\n#   None\n# Expected env variables:\n#   None\n# Outputs:\n#   a value string sanitized\nsanitize_variable()\n{\n\tvariable=\"${1}\"\n\n\t# If there are spaces but no quotes, let's add them\n\tif echo \"${variable}\" | grep -q \" \" &&\n\t\t! echo \"${variable}\" | grep -Eq \"^'|^\\\"\"; then\n\n\t\t# if we have double quotes we should wrap the whole line in single quotes\n\t\t# in order to not \"undo\" them\n\t\tif echo \"${variable}\" | grep -q '\"'; then\n\t\t\tvariable=\"'${variable}'\"\n\t\telse\n\t\t\tvariable=\"\\\"${variable}\\\"\"\n\t\tfi\n\tfi\n\n\t# Return\n\techo \"${variable}\"\n}\n\n# parse_file will read and parse input file and call distrobox-create accordingly\n# Arguments:\n#   file: string path of the manifest file to parse\n# Expected global variables:\n#   tmpfile: string name of the tmpfile to read\n# Expected env variables:\n#   None\n# Outputs:\n#   None\nparse_file()\n{\n\tfile=\"${1}\"\n\tname=\"\"\n\n\tIFS='\n\t'\n\twhile read -r line; do\n\t\t# Remove comments and trailing spaces\n\t\tline=\"$(echo \"${line}\" |\n\t\t\tsed 's/\\t/ /g' |\n\t\t\tsed 's/^#.*//g' |\n\t\t\tsed 's/].*#.*//g' |\n\t\t\tsed 's/ #.*//g' |\n\t\t\tsed 's/\\s*$//g')\"\n\n\t\tif [ -z \"${line}\" ]; then\n\t\t\t# blank line, skip\n\t\t\tcontinue\n\t\tfi\n\n\t\t# Detect start of new section\n\t\tif [ \"$(echo \"${line}\" | cut -c 1)\" = '[' ]; then\n\t\t\t# We're starting a new section\n\t\t\tif [ -n \"${name}\" ]; then\n\t\t\t\t# We've finished the previous section, so this is the time to\n\t\t\t\t# perform the distrobox command, before going to the new section.\n\t\t\t\trun_distrobox \"${name}\"\n\t\t\tfi\n\n\t\t\t# Remove brackets and spaces\n\t\t\tname=\"$(echo \"${line}\" | tr -d '][ ')\"\n\t\t\tcontinue\n\t\tfi\n\n\t\t# Get key-values from the file\n\t\tkey=\"$(echo \"${line}\" | cut -d'=' -f1 | tr -d ' ')\"\n\t\tvalue=\"$(echo \"${line}\" | cut -d'=' -f2-)\"\n\n\t\t# Normalize true|false to 0|1\n\t\t[ \"${value}\" = \"true\" ] && value=1\n\t\t[ \"${value}\" = \"false\" ] && value=0\n\n\t\t# Sanitize value, by whitespaces, quotes and escapes\n\t\tif [ \"${key}\" = \"init_hooks\" ] || [ \"${key}\" = \"pre_init_hooks\" ]; then\n\t\t\t# in case of shell commands (so the hooks) we prefer to pass the variable\n\t\t\t# around encoded, so that we don't accidentally execute stuff\n\t\t\t# and, we will execute sanitize_variable on the final string flag at the\n\t\t\t# end, instead of key/value base.\n\t\t\tvalue=\"$(encode_variable \"${value}\")\"\n\t\telse\n\t\t\tvalue=\"$(sanitize_variable \"${value}\")\"\n\t\tfi\n\n\t\t# Save options to tempfile, to source it later\n\t\ttouch \"${tmpfile}\"\n\t\tif [ -n \"${key}\" ] && [ -n \"${value}\" ]; then\n\t\t\tif grep -q \"^${key}=\" \"${tmpfile}\"; then\n\t\t\t\t# make keys cumulative\n\t\t\t\tvalue=\"\\${${key}}¤${value}\"\n\t\t\tfi\n\t\t\techo \"${key}=${value}\" >> \"${tmpfile}\"\n\t\tfi\n\tdone < \"${file}\"\n\t# Execute now one last time for the last block\n\trun_distrobox \"${name}\"\n}\n\n# read_section reads the content of a section from a TOML file.\n# Arguments:\n#   section: Name of the section to find (string).\n#   file: Path to the file to search into (string).\n# Expected global variables:\n#   None.\n# Expected env variables:\n#   None.\n# Outputs:\n#   Writes the found section body to stdout.\n# Exit behavior / errors:\n#   Does not exit non‑zero on missing section; caller should treat empty output as needed.\nread_section()\n{\n\tsection=\"$1\"\n\tfile=\"$2\"\n\tawk -v sec=\"[${section}]\" '\n    $0 == sec {show=1; next}\n    show && /^\\[/ {exit}\n    show && NF {print}\n  ' \"${file}\"\n}\n\n# resolve_includes Resolve 'include' keys in a manifest by inlining referenced sections.\n# Arguments:\n#   input_file: Path to the original manifest file that may contain 'include' keys.\n#   output_file: Path to the file where the resolved manifest will be written (if empty, a temp file is used).\n# Expected global variables:\n#   read_section (function)  - used to extract referenced section bodies from input_file.\n#   replace_line (function)  - used to replace include lines with extracted content.\n# Expected env variables:\n#   TMPDIR (optional) - may influence mktemp location.\n# Outputs:\n#   Prints the path to the output file to stdout when completed.\n# Exit behavior / errors:\n#   Exits with status 1 and writes to stderr on missing definitions, circular includes, or helper failures.\nresolve_includes()\n{\n\tinput_file=\"$1\"\n\toutput_file=\"$2\"\n\tinclude_stack=\"\"\n\n\t# At the starting point, the output file is equal to input_file\n\t# Later on, the output file will be edited as includes will be resolved\n\tcat \"${input_file}\" > \"${output_file}\"\n\n\tn=0\n\twhile true; do\n\t\ttotal_lines=$(wc -l < \"${output_file}\")\n\t\t[ \"${n}\" -gt \"${total_lines}\" ] && break\n\n\t\tline=$(sed -n \"$((n + 1))p\" \"${output_file}\")\n\n\t\t# Detected begin of a section: clear the include stack and go on\n\t\tif [ \"$(echo \"${line}\" | cut -c 1)\" = '[' ]; then\n\t\t\tinclude_stack=\"\"\n\t\t\tn=$((n + 1))\n\t\t\tcontinue\n\t\tfi\n\n\t\t# Match key=value from the current line\n\t\tkey=\"$(echo \"${line}\" | cut -d'=' -f1 | tr -d ' ')\"\n\t\tvalue=\"$(echo \"${line}\" | cut -d'=' -f2-)\"\n\n\t\tif [ \"${key}\" = \"include\" ]; then\n\t\t\t# Detect circular references while including other distrobox definitions\n\t\t\t# The reference stack is handled as a string of shape [name].[name].[name]\n\t\t\tif expr \"${include_stack}\" : \".*\\[${value}\\]\" > /dev/null; then\n\t\t\t\tprintf >&2 \"ERROR circular reference detected: including [%s] again after %s\\n\" \"${value}\" \"${include_stack}\"\n\t\t\t\texit 1\n\t\t\telse\n\t\t\t\tinclude_stack=\"[${value}]¤${include_stack}\"\n\t\t\tfi\n\n\t\t\t# Read the definition for the distrobox to include from the original file\n\t\t\t# and replace the current line with the found lines.\n\t\t\t# The line counter is not incremented to allow recursive include resolution\n\t\t\tinc=$(read_section \"$(echo \"${value}\" | tr -d '\"')\" \"${input_file}\")\n\t\t\tif [ -z \"${inc}\" ]; then\n\t\t\t\tprintf >&2 \"ERROR cannot include '%s': definition not found\\n\" \"${value}\"\n\t\t\t\texit 1\n\t\t\tfi\n\t\t\tl=$((n + 1))\n\t\t\treplace_line \"${l}\" \"${inc}\" \"${output_file}\" \"${output_file}\" > /dev/null\n\n\t\t\tcontinue\n\t\tfi\n\n\t\t# Nothing to do, increment counter and go on\n\t\tn=$((n + 1))\n\n\tdone\n\n\techo \"${output_file}\"\n\n}\n\n# replace_line Replace a 1-based numbered line in a file with provided (possibly multiline) text.\n# Arguments:\n#   line_number: 1-based index of the line to replace.\n#   new_value: String to insert (may contain newlines).\n#   input_file: Path to the original file to read from.\n#   output_file: Path to write the resulting file (if empty, a temp file will be created).\n# Expected global variables:\n#   None.\n# Expected env variables:\n#   TMPDIR (optional) - may influence mktemp location.\n# Outputs:\n#   Prints the path to the output file to stdout when complete.\n# Exit behavior / errors:\n#   Exits with status 1 on fatal errors (e.g., mktemp failure).\nreplace_line()\n{\n\tline_number=\"$1\"\n\tnew_value=\"$2\"\n\tinput_file=\"$3\"\n\toutput_file=\"$4\"\n\n\t# if no output file, use a temp file\n\tif [ -z \"${output_file}\" ]; then\n\t\toutput_file=$(mktemp -u)\n\tfi\n\n\ttmpfile=$(mktemp) || exit 1\n\n\t# Split the file into two parts around the line to replace and combine with new_value\n\t# Print lines before line_number\n\tsed \"$((line_number - 1))q\" \"${input_file}\" > \"${tmpfile}\"\n\n\t# Append the new_value\n\tprintf \"%s\\n\" \"${new_value}\" >> \"${tmpfile}\"\n\n\t# Append lines after line_number\n\tsed -n \"$((line_number + 1)),\\$p\" \"${input_file}\" >> \"${tmpfile}\"\n\n\t# Replace original file with tmpfile\n\tmv \"${tmpfile}\" \"${output_file}\"\n\n\techo \"${output_file}\"\n}\n\n# Exec\nexpanded_file=$(mktemp -u)\nresolve_includes \"${input_file}\" \"${expanded_file}\" > /dev/null\nparse_file \"${expanded_file}\"\n"
  },
  {
    "path": "distrobox-create",
    "content": "#!/bin/sh\n# SPDX-License-Identifier: GPL-3.0-only\n#\n# This file is part of the distrobox project:\n#    https://github.com/89luca89/distrobox\n#\n# Copyright (C) 2021 distrobox contributors\n#\n# distrobox is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 3\n# as published by the Free Software Foundation.\n#\n# distrobox is distributed in the hope that it will be useful, but\n# WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n# General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with distrobox; if not, see <http://www.gnu.org/licenses/>.\n\n# POSIX\n# Expected env variables:\n#\tHOME\n#\tUSER\n# Optional env variables:\n#\tDBX_CONTAINER_ALWAYS_PULL\n#\tDBX_CONTAINER_CUSTOM_HOME\n#\tDBX_CONTAINER_HOME_PREFIX\n#\tDBX_CONTAINER_IMAGE\n#\tDBX_CONTAINER_MANAGER\n#\tDBX_CONTAINER_NAME\n#\tDBX_CONTAINER_HOSTNAME\n#\tDBX_CONTAINER_GENERATE_ENTRY\n#\tDBX_NON_INTERACTIVE\n#\tDBX_VERBOSE\n#\tDBX_SUDO_PROGRAM\n#\tDBX_USERNS_NOLIMIT\n\n# Despite of running this script via SUDO/DOAS being not supported (the\n# script itself will call the appropriate tool when necessary), we still want\n# to allow people to run it as root, logged in in a shell, and create rootful\n# containers.\n#\n# SUDO_USER is a variable set by SUDO and can be used to check whether the script was called by it. Same thing for DOAS_USER, set by DOAS.\nif {\n\t[ -n \"${SUDO_USER}\" ] || [ -n \"${DOAS_USER}\" ]\n} && [ \"$(id -ru)\" -eq 0 ]; then\n\tprintf >&2 \"Running %s via SUDO/DOAS is not supported. Instead, please try running:\\n\" \"$(basename \"${0}\")\"\n\tprintf >&2 \"  %s --root %s\\n\" \"$(basename \"${0}\")\" \"$*\"\n\texit 1\nfi\n\n# Ensure we have our env variables correctly set\n[ -z \"${USER}\" ] && USER=\"$(id -run)\"\n[ -z \"${HOME}\" ] && HOME=\"$(getent passwd \"${USER}\" | cut -d':' -f6)\"\n[ -z \"${SHELL}\" ] && SHELL=\"$(getent passwd \"${USER}\" | cut -d':' -f7)\"\n\n# Defaults\ncontainer_additional_packages=\"\"\ncontainer_additional_volumes=\"\"\ncontainer_always_pull=0\ncontainer_clone=\"\"\ncontainer_generate_entry=1\ncontainer_home_prefix=\"\"\ncontainer_image=\"\"\ncontainer_image_default=\"registry.fedoraproject.org/fedora-toolbox:latest\"\ncontainer_init_hook=\"\"\ncontainer_manager=\"autodetect\"\ncontainer_manager_additional_flags=\"\"\ncontainer_platform=\"\"\ncontainer_name=\"\"\ncontainer_name_default=\"my-distrobox\"\ncontainer_hostname=\"\"\ncontainer_pre_init_hook=\"\"\ncontainer_user_custom_home=\"\"\ncontainer_user_gid=\"$(id -rg)\"\ncontainer_user_home=\"${HOME:-\"/\"}\"\ncontainer_user_name=\"${USER}\"\ncontainer_user_uid=\"$(id -ru)\"\ndryrun=0\ninit=0\nnon_interactive=0\nnvidia=0\nnopasswd=0\nunshare_ipc=0\nunshare_groups=0\nunshare_netns=0\nunshare_process=0\nunshare_devsys=0\n\n# Use cd + dirname + pwd so that we do not have relative paths in mount points\n# We're not using \"realpath\" here so that symlinks are not resolved this way\n# \"realpath\" would break situations like Nix or similar symlink based package\n# management.\ndistrobox_entrypoint_path=\"$(cd \"$(dirname \"${0}\")\" && pwd)/distrobox-init\"\ndistrobox_export_path=\"$(cd \"$(dirname \"${0}\")\" && pwd)/distrobox-export\"\ndistrobox_genentry_path=\"$(cd \"$(dirname \"${0}\")\" && pwd)/distrobox-generate-entry\"\ndistrobox_hostexec_path=\"$(cd \"$(dirname \"${0}\")\" && pwd)/distrobox-host-exec\"\n# In case some of the scripts are not in the same path as create, let's search\n# in PATH for them.\n[ ! -e \"${distrobox_entrypoint_path}\" ] && distrobox_entrypoint_path=\"$(command -v distrobox-init)\"\n[ ! -e \"${distrobox_export_path}\" ] && distrobox_export_path=\"$(command -v distrobox-export)\"\n[ ! -e \"${distrobox_genentry_path}\" ] && distrobox_genentry_path=\"$(command -v distrobox-generate-entry)\"\n[ ! -e \"${distrobox_hostexec_path}\" ] && distrobox_hostexec_path=\"$(command -v distrobox-host-exec)\"\n# If the user runs this script as root in a login shell, set rootful=1.\n# There's no need for them to pass the --root flag option in such cases.\n[ \"${container_user_uid}\" -eq 0 ] && rootful=1 || rootful=0\nuserns_nolimit=0\nverbose=0\nversion=\"1.8.2.4\"\n\napp_cache_dir=${XDG_CACHE_HOME:-\"${HOME}/.cache\"}/distrobox\n\n# Source configuration files, this is done in an hierarchy so local files have\n# priority over system defaults\n# leave priority to environment variables.\n#\n# On NixOS, for the distrobox derivation to pick up a static config file shipped\n# by the package maintainer the path must be relative to the script itself.\nself_dir=\"$(dirname \"$(realpath \"$0\")\")\"\nnix_config_file=\"${self_dir}/../share/distrobox/distrobox.conf\"\n\nconfig_files=\"\n\t${nix_config_file}\n\t/usr/share/distrobox/distrobox.conf\n\t/usr/share/defaults/distrobox/distrobox.conf\n\t/usr/etc/distrobox/distrobox.conf\n\t/usr/local/share/distrobox/distrobox.conf\n\t/etc/distrobox/distrobox.conf\n\t${XDG_CONFIG_HOME:-\"${HOME}/.config\"}/distrobox/distrobox.conf\n\t${HOME}/.distroboxrc\n\"\nfor config_file in ${config_files}; do\n\t# Shellcheck will give error for sourcing a variable file as it cannot follow\n\t# it. We don't care so let's disable this linting for now.\n\t# shellcheck disable=SC1090\n\t[ -e \"${config_file}\" ] && . \"$(realpath \"${config_file}\")\"\ndone\n# If we're running this script as root -- as in logged in in the shell as root\n# user, and not via SUDO/DOAS --, we don't need to set distrobox_sudo_program\n# as it's meaningless for this use case.\nif [ \"${container_user_uid}\" -ne 0 ]; then\n\t# If the DBX_SUDO_PROGRAM/distrobox_sudo_program variable was set by the\n\t# user, use its value instead of \"sudo\". But only if not running the script\n\t# as root (UID 0).\n\tdistrobox_sudo_program=${DBX_SUDO_PROGRAM:-${distrobox_sudo_program:-\"sudo\"}}\nfi\n\n[ -n \"${DBX_CONTAINER_ALWAYS_PULL}\" ] && container_always_pull=\"${DBX_CONTAINER_ALWAYS_PULL}\"\n[ -n \"${DBX_CONTAINER_CUSTOM_HOME}\" ] && container_user_custom_home=\"${DBX_CONTAINER_CUSTOM_HOME}\"\n[ -n \"${DBX_CONTAINER_HOME_PREFIX}\" ] && container_home_prefix=\"${DBX_CONTAINER_HOME_PREFIX}\"\n[ -n \"${DBX_CONTAINER_IMAGE}\" ] && container_image=\"${DBX_CONTAINER_IMAGE}\"\n[ -n \"${DBX_CONTAINER_MANAGER}\" ] && container_manager=\"${DBX_CONTAINER_MANAGER}\"\n[ -n \"${DBX_CONTAINER_NAME}\" ] && container_name=\"${DBX_CONTAINER_NAME}\"\n[ -n \"${DBX_CONTAINER_HOSTNAME}\" ] && container_hostname=\"${DBX_CONTAINER_HOSTNAME}\"\n[ -n \"${DBX_CONTAINER_GENERATE_ENTRY}\" ] && container_generate_entry=\"${DBX_CONTAINER_GENERATE_ENTRY}\"\n[ -n \"${DBX_NON_INTERACTIVE}\" ] && non_interactive=\"${DBX_NON_INTERACTIVE}\"\n[ -n \"${DBX_VERBOSE}\" ] && verbose=\"${DBX_VERBOSE}\"\n[ -n \"${DBX_USERNS_NOLIMIT}\" ] && userns_nolimit=\"${DBX_USERNS_NOLIMIT}\"\n\n# Fixup variable=[true|false], in case we find it in the config file(s)\n[ \"${non_interactive}\" = \"true\" ] && non_interactive=1\n[ \"${non_interactive}\" = \"false\" ] && non_interactive=0\n[ \"${verbose}\" = \"true\" ] && verbose=1\n[ \"${verbose}\" = \"false\" ] && verbose=0\n[ \"${userns_nolimit}\" = \"true\" ] && userns_nolimit=1\n[ \"${userns_nolimit}\" = \"false\" ] && userns_nolimit=0\n\n# show_help will print usage to stdout.\n# Arguments:\n#   None\n# Expected global variables:\n#   version: string distrobox version\n#   container_image_default: string default container image to use\n#   container_name_default:  string default container name to use\n# Expected env variables:\n#   None\n# Outputs:\n#   print usage with examples.\nshow_help()\n{\n\tcat << EOF\ndistrobox version: ${version}\n\nUsage:\n\n\tdistrobox create --image alpine:latest --name test --init-hooks \"touch /var/tmp/test1 && touch /var/tmp/test2\"\n\tdistrobox create --image fedora:39 --name test --additional-flags \"--env MY_VAR-value\"\n\tdistrobox create --image fedora:39 --name test --volume /opt/my-dir:/usr/local/my-dir:rw --additional-flags \"--pids-limit 100\"\n\tdistrobox create -i docker.io/almalinux/8-init --init --name test --pre-init-hooks \"dnf config-manager --enable powertools && dnf -y install epel-release\"\n\tdistrobox create --clone fedora-39 --name fedora-39-copy\n\tdistrobox create --image alpine my-alpine-container\n\tdistrobox create --image registry.fedoraproject.org/fedora-toolbox:latest --name fedora-toolbox-latest\n\tdistrobox create --pull --image centos:stream9 --home ~/distrobox/centos9\n\tdistrobox create --image alpine:latest --name test2 --additional-packages \"git tmux vim\"\n\tdistrobox create --image ubuntu:22.04 --name ubuntu-nvidia --nvidia\n\n\tDBX_NON_INTERACTIVE=1 DBX_CONTAINER_NAME=test-alpine DBX_CONTAINER_IMAGE=alpine distrobox-create\n\nOptions:\n\n\t--image/-i:\t\timage to use for the container\tdefault: ${container_image_default}\n\t--name/-n:\t\tname for the distrobox          default: ${container_name_default}\n\t--hostname:\t\thostname for the distrobox      default: $(uname -n)\n\t--pull/-p:\t\tpull the image even if it exists locally (implies --yes)\n\t--yes/-Y:\t\tnon-interactive, pull images without asking\n\t--root/-r:\t\tlaunch podman/docker/lilipod with root privileges. This is the only supported way to run with root\n\t\t\t\tprivileges. Do not use \"sudo distrobox\". If you need to specify a different program (e.g. 'doas') for root privileges,\n\t\t\t\tuse the DBX_SUDO_PROGRAM environment variable or the 'distrobox_sudo_program' config variable.\n\t--clone/-c:\t\tname of the distrobox container to use as base for a new container\n\t\t\t\tthis will be useful to either rename an existing distrobox or have multiple copies\n\t\t\t\tof the same environment.\n\t--home/-H:\t\tselect a custom HOME directory for the container. Useful to avoid host's home littering with temp files.\n\t--volume:\t\tadditional volumes to add to the container\n\t--additional-flags/-a:\tadditional flags to pass to the container manager command\n\t--additional-packages/-ap:\tadditional packages to install during initial container setup\n\t--init-hooks:\t\tadditional commands to execute at the end of container initialization\n\t--pre-init-hooks:\tadditional commands to execute at the start of container initialization\n\t--init/-I:\t\tuse init system (like systemd) inside the container.\n\t\t\t\tthis will make host's processes not visible from within the container. (assumes --unshare-process)\n\t\t\t\tmay require additional packages depending on the container image: https://github.com/89luca89/distrobox/blob/main/docs/useful_tips.md#using-init-system-inside-a-distrobox\n\t--nvidia:\t\ttry to integrate host's nVidia drivers in the guest\n\t--platform:\t\tspecify which platform to use, eg: linux/arm64\n\t--unshare-devsys:          do not share host devices and sysfs dirs from host\n\t--unshare-groups:          do not forward user's additional groups into the container\n\t--unshare-ipc:          do not share ipc namespace with host\n\t--unshare-netns:        do not share the net namespace with host\n\t--unshare-process:          do not share process namespace with host\n\t--unshare-all:          activate all the unshare flags below\n\t--compatibility/-C:\tshow list of compatible images\n\t--help/-h:\t\tshow this message\n\t--no-entry:\t\tdo not generate a container entry in the application list\n\t--dry-run/-d:\t\tonly print the container manager command generated\n\t--verbose/-v:\t\tshow more verbosity\n\t--version/-V:\t\tshow version\n\n\t--absolutely-disable-root-password-i-am-really-positively-sure: ⚠️ ⚠️  when setting up a rootful distrobox, this will skip user password setup, leaving it blank. ⚠️ ⚠️\n\nCompatibility:\n\n\tfor a list of compatible images and container managers, please consult the man page:\n\t\tman distrobox-compatibility\n\tor run\n\t\tdistrobox create --compatibility\n\tor consult the documentation page on: https://github.com/89luca89/distrobox/blob/main/docs/compatibility.md\nEOF\n}\n\n# show_compatibility will print the list of compatible images to stdout, caching locally in a file.\n# Arguments:\n#   None\n# Expected global variables:\n#   app_cache_dir: cache dir to write to\n#   version:       distrobox version\n# Expected env variables:\n#   None\n# Outputs:\n#   print usage with examples.\nshow_compatibility()\n{\n\tif [ ! -e \"${app_cache_dir}/distrobox-compatibility-${version}\" ] ||\n\t\t[ ! -s \"${app_cache_dir}/distrobox-compatibility-${version}\" ]; then\n\t\tmkdir -p \"${app_cache_dir}\"\n\n\t\t# If we don't have a cache file, we need connectivity. Ensure we have\n\t\t# one and return error if not.\n\t\tif ! curl -s \"https://github.com\" > /dev/null; then\n\t\t\tprintf >&2 \"ERROR: no cache file and no connectivity found, cannot retrieve compatibility list.\\n\"\n\t\t\texit 1\n\t\tfi\n\t\t# We want to download the correspondent version of the compatibility table and extract a list from it.\n\t\t# Always use the docs as source of truth for this.\n\t\tcurl -s \\\n\t\t\t\"https://raw.githubusercontent.com/89luca89/distrobox/${version}/docs/compatibility.md\" |\n\t\t\tsed -n -e '/| Alma/,/| Void/ p' |\n\t\t\tcut -d '|' -f 4 |\n\t\t\tsed 's|<br>|\\n|g' |\n\t\t\ttr -d ' ' |\n\t\t\tsort -u > \"${app_cache_dir}/distrobox-compatibility-${version}\"\n\tfi\n\tcat \"${app_cache_dir}/distrobox-compatibility-${version}\"\n}\n\n# Parse arguments\nwhile :; do\n\tcase $1 in\n\t\t-h | --help)\n\t\t\t# Call a \"show_help\" function to display a synopsis, then exit.\n\t\t\tshow_help\n\t\t\texit 0\n\t\t\t;;\n\t\t-v | --verbose)\n\t\t\tverbose=1\n\t\t\tshift\n\t\t\t;;\n\t\t-V | --version)\n\t\t\tprintf \"distrobox: %s\\n\" \"${version}\"\n\t\t\texit 0\n\t\t\t;;\n\t\t--no-entry)\n\t\t\tshift\n\t\t\tcontainer_generate_entry=0\n\t\t\t;;\n\t\t-d | --dry-run)\n\t\t\tshift\n\t\t\tdryrun=1\n\t\t\t;;\n\t\t-r | --root)\n\t\t\tshift\n\t\t\trootful=1\n\t\t\t;;\n\t\t--absolutely-disable-root-password-i-am-really-positively-sure)\n\t\t\tshift\n\t\t\tnopasswd=1\n\t\t\t;;\n\t\t-I | --init)\n\t\t\tshift\n\t\t\tinit=1\n\t\t\tunshare_groups=1\n\t\t\tunshare_process=1\n\t\t\t;;\n\t\t--unshare-ipc)\n\t\t\tshift\n\t\t\tunshare_ipc=1\n\t\t\t;;\n\t\t--unshare-groups)\n\t\t\tshift\n\t\t\tunshare_groups=1\n\t\t\t;;\n\t\t--unshare-netns)\n\t\t\tshift\n\t\t\tunshare_netns=1\n\t\t\t;;\n\t\t--unshare-process)\n\t\t\tshift\n\t\t\tunshare_process=1\n\t\t\t;;\n\t\t--unshare-devsys)\n\t\t\tshift\n\t\t\tunshare_devsys=1\n\t\t\t;;\n\t\t--unshare-all)\n\t\t\tshift\n\t\t\tunshare_devsys=1\n\t\t\tunshare_groups=1\n\t\t\tunshare_ipc=1\n\t\t\tunshare_netns=1\n\t\t\tunshare_process=1\n\t\t\t;;\n\t\t-C | --compatibility)\n\t\t\tshow_compatibility\n\t\t\texit 0\n\t\t\t;;\n\t\t-i | --image)\n\t\t\tif [ -n \"$2\" ]; then\n\t\t\t\tcontainer_image=\"$2\"\n\t\t\t\tshift\n\t\t\t\tshift\n\t\t\tfi\n\t\t\t;;\n\t\t-n | --name)\n\t\t\tif [ -n \"$2\" ]; then\n\t\t\t\tcontainer_name=\"$2\"\n\t\t\t\tshift\n\t\t\t\tshift\n\t\t\tfi\n\t\t\t;;\n\t\t--hostname)\n\t\t\tif [ -n \"$2\" ]; then\n\t\t\t\tcontainer_hostname=\"$2\"\n\t\t\t\tshift\n\t\t\t\tshift\n\t\t\tfi\n\t\t\t;;\n\t\t-c | --clone)\n\t\t\tif [ -n \"$2\" ]; then\n\t\t\t\tcontainer_clone=\"$2\"\n\t\t\t\tshift\n\t\t\t\tshift\n\t\t\tfi\n\t\t\t;;\n\t\t-H | --home)\n\t\t\tif [ -n \"$2\" ]; then\n\t\t\t\t# Remove trailing slashes\n\t\t\t\tcontainer_user_custom_home=\"$(echo \"$2\" | sed 's:/*$::')\"\n\t\t\t\tshift\n\t\t\t\tshift\n\t\t\tfi\n\t\t\t;;\n\t\t-p | --pull)\n\t\t\tcontainer_always_pull=1\n\t\t\tshift\n\t\t\t;;\n\t\t--nvidia)\n\t\t\tshift\n\t\t\tnvidia=1\n\t\t\t;;\n\t\t-Y | --yes)\n\t\t\tnon_interactive=1\n\t\t\tshift\n\t\t\t;;\n\t\t--volume)\n\t\t\tif [ -n \"$2\" ]; then\n\t\t\t\tcontainer_additional_volumes=\"${container_additional_volumes} ${2}\"\n\t\t\t\tshift\n\t\t\t\tshift\n\t\t\tfi\n\t\t\t;;\n\t\t--platform)\n\t\t\tif [ -n \"$2\" ]; then\n\t\t\t\tcontainer_platform=\"--platform=${2}\"\n\t\t\t\tshift\n\t\t\t\tshift\n\t\t\tfi\n\t\t\t;;\n\t\t-a | --additional-flags)\n\t\t\tif [ -n \"$2\" ]; then\n\t\t\t\tcontainer_manager_additional_flags=\"${container_manager_additional_flags} ${2}\"\n\t\t\t\tshift\n\t\t\t\tshift\n\t\t\tfi\n\t\t\t;;\n\t\t-ap | --additional-packages)\n\t\t\tif [ -n \"$2\" ]; then\n\t\t\t\tcontainer_additional_packages=\"${container_additional_packages} ${2}\"\n\t\t\t\tshift\n\t\t\t\tshift\n\t\t\tfi\n\t\t\t;;\n\t\t--init-hooks)\n\t\t\tif [ -n \"$2\" ]; then\n\t\t\t\tcontainer_init_hook=\"$2\"\n\t\t\t\tshift\n\t\t\t\tshift\n\t\t\tfi\n\t\t\t;;\n\t\t--pre-init-hooks)\n\t\t\tif [ -n \"$2\" ]; then\n\t\t\t\tcontainer_pre_init_hook=\"${2}\"\n\t\t\t\tshift\n\t\t\t\tshift\n\t\t\tfi\n\t\t\t;;\n\t\t--) # End of all options.\n\t\t\tshift\n\t\t\tbreak\n\t\t\t;;\n\t\t-*) # Invalid options.\n\t\t\tprintf >&2 \"ERROR: Invalid flag '%s'\\n\\n\" \"$1\"\n\t\t\tshow_help\n\t\t\texit 1\n\t\t\t;;\n\t\t*) # Default case: If no more options then break out of the loop.\n\t\t\t# If we have a flagless option and container_name is not specified\n\t\t\t# then let's accept argument as container_name\n\t\t\tif [ -n \"$1\" ]; then\n\t\t\t\tcontainer_name=\"$1\"\n\t\t\t\tshift\n\t\t\telse\n\t\t\t\tbreak\n\t\t\tfi\n\t\t\t;;\n\tesac\ndone\n\nset -o errexit\nset -o nounset\n# set verbosity\nif [ \"${verbose}\" -ne 0 ]; then\n\tset -o xtrace\nfi\n\n# If no clone option and no container image, let's choose a default image to use.\n# Fedora toolbox is a sensitive default\nif [ -z \"${container_clone}\" ] && [ -z \"${container_image}\" ]; then\n\tcontainer_image=\"${container_image_default}\"\nfi\n\n# If no name is specified and we're using the default container_image, then let's\n# set a default name for the container, that is distinguishable from the default\n# toolbx one. This will avoid problems when using both toolbx and distrobox on\n# the same system.\nif [ -z \"${container_name}\" ] && [ \"${container_image}\" = \"${container_image_default}\" ]; then\n\tcontainer_name=\"${container_name_default}\"\nfi\n\n# If no container_name is declared, we build our container name starting from the\n# container image specified.\n#\n# Examples:\n#\talpine -> alpine\n#\tubuntu:20.04 -> ubuntu-20.04\n#\tregistry.fedoraproject.org/fedora-toolbox:39 -> fedora-toolbox-39\n#\tghcr.io/void-linux/void-linux:latest-full-x86_64 -> void-linux-latest-full-x86_64\nif [ -z \"${container_name}\" ]; then\n\tcontainer_name=\"$(basename \"${container_image}\" | sed -E 's/[:.]/-/g')\"\nfi\n\n# set the container hostname to default value\nif [ -z \"${container_hostname}\" ]; then\n\tcontainer_hostname=\"$(uname -n)\"\n\n\tif [ \"${unshare_netns}\" -eq 1 ]; then\n\t\tcontainer_hostname=\"${container_name}.${container_hostname}\"\n\tfi\nfi\n\n# check if container hostname is less than 64 chars to prevent issues\nif [ \"$(printf \"%s\" \"${container_hostname}\" | wc -m)\" -gt 64 ]; then\n\tprintf >&2 \"ERROR: Invalid hostname '%s', longer than 64 characters\\n\" \"${container_hostname}\"\n\tprintf >&2 \"ERROR: Use use --hostname argument to set it manually\\n\"\n\texit 1\nfi\n\n# We depend on a container manager let's be sure we have it\n# First we use podman, else docker, else lilipod\ncase \"${container_manager}\" in\n\tautodetect)\n\t\tif command -v podman > /dev/null; then\n\t\t\tcontainer_manager=\"podman\"\n\t\telif command -v podman-launcher > /dev/null; then\n\t\t\tcontainer_manager=\"podman-launcher\"\n\t\telif command -v docker > /dev/null; then\n\t\t\tcontainer_manager=\"docker\"\n\t\telif command -v lilipod > /dev/null; then\n\t\t\tcontainer_manager=\"lilipod\"\n\t\tfi\n\t\t;;\n\tpodman)\n\t\tcontainer_manager=\"podman\"\n\t\t;;\n\tpodman-launcher)\n\t\tcontainer_manager=\"podman-launcher\"\n\t\t;;\n\tlilipod)\n\t\tcontainer_manager=\"lilipod\"\n\t\t;;\n\tdocker)\n\t\tcontainer_manager=\"docker\"\n\t\t;;\n\t*)\n\t\tprintf >&2 \"Invalid input %s.\\n\" \"${container_manager}\"\n\t\tprintf >&2 \"The available choices are: 'autodetect', 'podman', 'docker', 'lilipod'\\n\"\n\t\t;;\nesac\n\n# Be sure we have a container manager to work with.\nif ! command -v \"${container_manager}\" > /dev/null && [ \"${dryrun}\" -eq 0 ]; then\n\t# Error: we need at least one between docker, podman or lilipod.\n\tprintf >&2 \"Missing dependency: we need a container manager.\\n\"\n\tprintf >&2 \"Please install one of podman,  docker or lilipod.\\n\"\n\tprintf >&2 \"You can follow the documentation on:\\n\"\n\tprintf >&2 \"\\tman distrobox-compatibility\\n\"\n\tprintf >&2 \"or:\\n\"\n\tprintf >&2 \"\\thttps://github.com/89luca89/distrobox/blob/main/docs/compatibility.md\\n\"\n\texit 127\nfi\n# add  verbose if -v is specified\nif [ \"${verbose}\" -ne 0 ]; then\n\tcontainer_manager=\"${container_manager} --log-level debug\"\nfi\n\n# prepend sudo (or the specified sudo program) if we want our container manager to be rootful\nif [ \"${rootful}\" -ne 0 ]; then\n\tcontainer_manager=\"${distrobox_sudo_program-} ${container_manager}\"\nfi\n\n# if nopasswd, then let the init know via a mountpoint\nif [ \"${nopasswd}\" -ne 0 ]; then\n\tcontainer_manager_additional_flags=\"${container_manager_additional_flags}\n\t\t\t--volume /dev/null:/run/.nopasswd:ro\"\nfi\n\n# Signal rootless mode explicitly so distrobox-init does not rely solely on\n# the /etc/shadow heuristic, which gives false positives on Docker Desktop\n# (macOS) where the container always has root access to the VM filesystem.\nif [ \"${rootful}\" -eq 0 ]; then\n\tcontainer_manager_additional_flags=\"${container_manager_additional_flags}\n\t\t\t--volume /dev/null:/run/.distrobox.rootless:ro\"\nfi\n\n# inject additional volumes if specified\nif [ -n \"${container_additional_volumes}\" ]; then\n\tfor volume in ${container_additional_volumes}; do\n\t\tcontainer_manager_additional_flags=\"${container_manager_additional_flags}\n\t\t\t--volume ${volume}\"\n\tdone\nfi\n\n# Check that we have a complete distrobox installation or\n# entrypoint and export will not work.\nif [ -z \"${distrobox_entrypoint_path}\" ] || [ -z \"${distrobox_export_path}\" ]; then\n\tprintf >&2 \"Error: no distrobox-init found in %s\\n\" \"${PATH}\"\n\texit 127\nfi\n\n# get_clone_image will return the image name of a cloned existing container taken\n# as input.\n# Arguments:\n#   None\n# Expected global variables:\n#   container_manager: string container manager to use\n#   container_clone: string container name to clone\n# Expected env variables:\n#   None\n# Outputs:\n#   prints the image name of the newly cloned container\nget_clone_image()\n{\n\t# We need to clone a container.\n\t# to do this we will commit the container and create a new tag. Then use it\n\t# as image for the new container.\n\t#\n\t# to perform this we first ensure the source container exists and that the\n\t# source container is stopped, else the clone will not work,\n\tcontainer_source_status=\"$(${container_manager} inspect --type container \\\n\t\t--format '{{.State.Status}}' \"${container_clone}\")\"\n\t# If the container is not already running, we need to start if first\n\tif [ \"${container_source_status}\" = \"running\" ]; then\n\t\tprintf >&2 \"Container %s is running.\\nPlease stop it first.\\n\" \"${container_clone}\"\n\t\tprintf >&2 \"Cannot clone a running container.\\n\"\n\t\treturn 1\n\tfi\n\n\t# Now we can extract the container ID and commit it to use as source image\n\t# for the new container.\n\tcontainer_source_id=\"$(${container_manager} inspect --type container \\\n\t\t--format '{{.ID}}' \"${container_clone}\")\"\n\tcontainer_commit_tag=\"$(echo \"${container_clone}:$(date +%F)\" | tr '[:upper:]' '[:lower:]')\"\n\n\t# Commit current container state to a new image tag\n\tprintf >&2 \"Duplicating %s...\\n\" \"${container_clone}\"\n\tif ! ${container_manager} container commit \\\n\t\t\"${container_source_id}\" \"${container_commit_tag}\" > /dev/null; then\n\n\t\tprintf >&2 \"Cannot clone container: %s\\n\" \"${container_clone}\"\n\t\treturn 1\n\tfi\n\n\t# Return the image tag to use for the new container creation.\n\tprintf \"%s\" \"${container_commit_tag}\"\n\treturn 0\n}\n\n# generate_create_command will produce a Podman or Docker command to execute.\n# Arguments:\n#   None\n# Expected global variables:\n#   container_manager: string container manager to use\n#   container_name: string container name\n#   container_image: string container image\n#   container_manager_additional_flags: string container manager additional flags to use\n#   container_hostname: string container hostname\n#   container_additional_packages: string additional packages\n#   container_pre_init_hook: string pre init hooks\n#   container_init_hook: string init hooks\n#   container_user_home: string user's home path\n#   container_user_name: string user's username\n#   container_user_uid: string user's UID\n#   container_user_gid: string user's GID\n#   container_home_prefix: string container's custom home prefix\n#   container_user_custom_home: string container's custom home path\n#   init: bool initful\n#   nvidia: bool nvidia integration\n#   rootful: bool rootful\n#   unshare_devsys: bool unshare devsys\n#   unshare_groups: bool unshare groups\n#   unshare_ipc: bool unshare ipc\n#   unshare_netns: bool unshare netns\n#   unshare_process: bool unshare proc\n# Expected env variables:\n#   None\n# Outputs:\n#   prints the podman, docker or lilipod command to create the distrobox container\ngenerate_create_command()\n{\n\t# On macOS, Docker Desktop mounts all paths as private in its Linux VM,\n\t# so rslave/rshared bind propagation is not supported.\n\tif [ \"$(uname -s)\" = \"Darwin\" ]; then\n\t\trslave=\"\"\n\telse\n\t\trslave=\":rslave\"\n\tfi\n\n\t# Set the container hostname the same as the container name.\n\tresult_command=\"${container_manager} create\"\n\tresult_command=\"${result_command} ${container_platform}\"\n\t# use the host's namespace for ipc, network, pid, ulimit\n\tresult_command=\"${result_command}\n\t\t--hostname \\\"${container_hostname}\\\"\n\t\t--name \\\"${container_name}\\\"\n\t\t--privileged\n\t\t--security-opt label=disable\n\t\t--security-opt apparmor=unconfined\n\t\t--pids-limit=-1\n\t\t--user root:root\"\n\n\tif [ \"${unshare_ipc}\" -eq 0 ]; then\n\t\tresult_command=\"${result_command}\n\t\t\t--ipc host\"\n\tfi\n\n\tif [ \"${unshare_netns}\" -eq 0 ]; then\n\t\tresult_command=\"${result_command}\n\t\t\t--network host\"\n\tfi\n\n\tif [ \"${unshare_process}\" -eq 0 ]; then\n\t\tresult_command=\"${result_command}\n\t\t\t--pid host\"\n\tfi\n\t# Mount useful stuff inside the container.\n\t# We also mount host's root filesystem to /run/host, to be able to syphon\n\t# dynamic configurations from the host.\n\t#\n\t# Mount user home, dev and host's root inside container.\n\t# This grants access to external devices like usb webcams, disks and so on.\n\t#\n\t# Mount also the distrobox-init utility as the container entrypoint.\n\t# Also mount in the container the distrobox-export and distrobox-host-exec\n\t# utilities.\n\tresult_command=\"${result_command}\n\t\t--label \\\"manager=distrobox\\\"\n\t\t--label \\\"distrobox.unshare_groups=${unshare_groups}\\\"\n\t\t--env \\\"SHELL=$(basename \"${SHELL:-\"/bin/bash\"}\")\\\"\n\t\t--env \\\"HOME=${container_user_home}\\\"\n\t\t--env \\\"container=${container_manager}\\\"\n\t\t--env \\\"TERMINFO_DIRS=/usr/share/terminfo:/run/host/usr/share/terminfo\\\"\n\t\t--env \\\"CONTAINER_ID=${container_name}\\\"\n\t\t--volume /tmp:/tmp${rslave}\n\t\t--volume \\\"${distrobox_entrypoint_path}\\\":/usr/bin/entrypoint:ro\n\t\t--volume \\\"${distrobox_export_path}\\\":/usr/bin/distrobox-export:ro\n\t\t--volume \\\"${distrobox_hostexec_path}\\\":/usr/bin/distrobox-host-exec:ro\n\t\t--volume \\\"${container_user_home}\\\":\\\"${container_user_home}\\\"${rslave}\"\n\n\t# Due to breaking change in https://github.com/opencontainers/runc/commit/d4b670fca6d0ac606777376440ffe49686ce15f4\n\t# now we cannot mount /:/run/host as before, as it will try to mount RO partitions as RW thus breaking things.\n\t# This will ensure we will mount directories one-by-one thus avoiding this problem.\n\t#\n\t# This happens ONLY with podman+runc, docker and lilipod are unaffected, so let's do this only if we have podman AND runc.\n\tif echo \"${container_manager}\" | grep -q \"podman\" && ${container_manager} info 2> /dev/null | grep -q runc > /dev/null 2>&1; then\n\t\tfor rootdir in /*; do\n\n\t\t\t# Skip symlinks\n\t\t\tif [ -L \"${rootdir}\" ]; then\n\t\t\t\tcontinue\n\t\t\tfi\n\n\t\t\t# Find if the directory belongs to a RO mount, if do, mount it as RO+Rslave\n\t\t\tif findmnt --notruncate --noheadings --list --output OPTIONS --target \"${rootdir}\" |\n\t\t\t\ttr ',' '\\n' | grep -q \"^ro$\"; then\n\n\t\t\t\tresult_command=\"${result_command}\n\t\t\t\t--volume ${rootdir}:/run/host${rootdir}:ro${rslave}\"\n\t\t\t\tcontinue\n\t\t\tfi\n\n\t\t\t# Else we mount it RW+Rslave\n\t\t\tresult_command=\"${result_command}\n\t\t\t\t--volume ${rootdir}:/run/host${rootdir}${rslave}\"\n\t\tdone\n\telse\n\t\t# We're either on podman+crun, docker or lilipod, let's keep old behaviour\n\t\tresult_command=\"${result_command}\n\t\t\t--volume /:/run/host/${rslave}\"\n\n\tfi\n\n\tif [ \"${unshare_devsys}\" -eq 0 ]; then\n\t\tresult_command=\"${result_command}\n\t\t\t--volume /dev:/dev${rslave}\n\t\t\t--volume /sys:/sys${rslave}\"\n\tfi\n\n\t# In case of initful containers, we implement a series of mountpoint in order\n\t# for systemd to work properly inside a container.\n\t# The following are a flag-based implementation of what podman's --systemd flag\n\t# does under the hood, as explained in their docs here:\n\t#   https://docs.podman.io/en/latest/markdown/options/systemd.html\n\t#\n\t# set the default stop signal to SIGRTMIN+3.\n\t# mount tmpfs file systems on the following directories\n\t#\t/run\n\t#\t/run/lock\n\t#\t/tmp\n\t#\t/var/lib/journal\n\t#\t/sys/fs/cgroup/systemd <- this one is done by cgroupns=host\n\tif [ \"${init}\" -eq 1 ] && echo \"${container_manager}\" | grep -q \"docker\"; then\n\t\t# In case of docker we're actually rootful, so we need to use hosts cgroups\n\t\tresult_command=\"${result_command}\n\t\t\t--cgroupns host\"\n\tfi\n\tif [ \"${init}\" -eq 1 ] && echo \"${container_manager}\" | grep -vq \"podman\"; then\n\t\t# In case of all other non-podman container managers, we can do this\n\t\tresult_command=\"${result_command}\n\t\t\t--stop-signal SIGRTMIN+3\n\t\t\t--mount type=tmpfs,destination=/run\n\t\t\t--mount type=tmpfs,destination=/run/lock\n\t\t\t--mount type=tmpfs,destination=/var/lib/journal\"\n\tfi\n\n\t# This fix is needed so that the container can have a separate devpts instance\n\t# inside\n\t# This will mount an empty /dev/pts, and the init will take care of mounting\n\t# a new devpts with the proper flags set\n\t# Mounting an empty volume there, is needed in order to ensure that no package\n\t# manager tries to fiddle with /dev/pts/X that would not be writable by them\n\t#\n\t# This implementation is done this way in order to be compatible with both\n\t# docker and podman\n\tif [ \"${unshare_devsys}\" -eq 0 ]; then\n\t\tresult_command=\"${result_command}\n\t\t\t--volume /dev/pts\n\t\t\t--volume /dev/null:/dev/ptmx\"\n\tfi\n\n\t# This fix is needed as on Selinux systems, the host's selinux sysfs directory\n\t# will be mounted inside the rootless container.\n\t#\n\t# This works around this and allows the rootless container to work when selinux\n\t# policies are installed inside it.\n\t#\n\t# Ref. Podman issue 4452:\n\t#    https://github.com/containers/podman/issues/4452\n\tif [ -e \"/sys/fs/selinux\" ]; then\n\t\tresult_command=\"${result_command}\n\t\t\t--volume /sys/fs/selinux\"\n\tfi\n\n\t# This fix is needed as systemd (or journald) will try to set ACLs on this\n\t# path. For now overlayfs and fuse.overlayfs are not compatible with ACLs\n\t#\n\t# This works around this using an unnamed volume so that this path will be\n\t# mounted with a normal non-overlay FS, allowing ACLs and preventing errors.\n\t#\n\t# This work around works in conjunction with distrobox-init's package manager\n\t# setups.\n\t# So that we can use pre/post hooks for package managers to present to the\n\t# systemd install script a blank path to work with, and mount the host's\n\t# journal path afterwards.\n\tresult_command=\"${result_command}\n\t\t\t--volume /var/log/journal\"\n\n\t# In some systems, for example using sysvinit, /dev/shm is a symlink\n\t# to /run/shm, instead of the other way around.\n\t# Resolve this detecting if /dev/shm is a symlink and mount original\n\t# source also in the container.\n\tif [ -L \"/dev/shm\" ] && [ \"${unshare_ipc}\" -eq 0 ]; then\n\t\tresult_command=\"${result_command}\n\t\t\t--volume $(realpath /dev/shm):$(realpath /dev/shm)\"\n\tfi\n\n\t# Ensure that both all container managers (not only podman) support forwarding of RedHat subscription-manager\n\t# This is needed in order to have a working subscription forwarded into the container,\n\t# this will ensure that rhel-9-for-x86_64-appstream-rpms and rhel-9-for-x86_64-baseos-rpms repos\n\t# will be available in the container, so that distrobox-init will be able to\n\t# install properly all the dependencies like mesa drivers.\n\t#\n\t# /run/secrets is a standard location for RHEL containers, that is being pointed by\n\t# /etc/rhsm-host by default.\n\tRHEL_SUBSCRIPTION_FILES=\"\n\t\t/etc/pki/entitlement/:/run/secrets/etc-pki-entitlement:ro\n\t\t/etc/rhsm/:/run/secrets/rhsm:ro\n\t\t/etc/yum.repos.d/redhat.repo:/run/secrets/redhat.repo:ro\n\t\"\n\tfor rhel_file in ${RHEL_SUBSCRIPTION_FILES}; do\n\t\tif [ -e \"$(echo \"${rhel_file}\" | cut -d':' -f1)\" ]; then\n\t\t\tresult_command=\"${result_command}\n\t\t\t\t--volume ${rhel_file}\"\n\t\tfi\n\tdone\n\n\t# If we have a home prefix to use, ano no custom home set, then we set\n\t# the custom home to be PREFIX/CONTAINER_NAME\n\tif [ -n \"${container_home_prefix}\" ] && [ -z \"${container_user_custom_home}\" ]; then\n\t\tcontainer_user_custom_home=\"${container_home_prefix}/${container_name}\"\n\tfi\n\n\t# If we have a custom home to use,\n\t#\t1- override the HOME env variable\n\t#\t2- export the DISTROBOX_HOST_HOME env variable pointing to original HOME\n\t# \t3- mount the custom home inside the container.\n\tif [ -n \"${container_user_custom_home}\" ]; then\n\t\tif [ ! -d \"${container_user_custom_home}\" ]; then\n\t\t\tif ! mkdir -p \"${container_user_custom_home}\"; then\n\t\t\t\tprintf >&2 \"Do you have permission to write to %s?\\n\" \"${container_user_custom_home}\"\n\t\t\t\texit 1\n\t\t\tfi\n\t\tfi\n\t\tresult_command=\"${result_command}\n\t\t\t--env \\\"HOME=${container_user_custom_home}\\\"\n\t\t\t--env \\\"DISTROBOX_HOST_HOME=${container_user_home}\\\"\n\t\t\t--volume \\\"${container_user_custom_home}:${container_user_custom_home}${rslave}\\\"\"\n\tfi\n\n\t# Mount also the /var/home dir on ostree based systems\n\t# do this only if $HOME was not already set to /var/home/username\n\tif [ \"${container_user_home}\" != \"/var/home/${container_user_name}\" ] &&\n\t\t[ -d \"/var/home/${container_user_name}\" ]; then\n\n\t\tresult_command=\"${result_command}\n\t\t\t--volume \\\"/var/home/${container_user_name}\\\":\\\"/var/home/${container_user_name}\\\"${rslave}\"\n\tfi\n\n\t# Mount also the XDG_RUNTIME_DIR to ensure functionality of the apps.\n\t# This is skipped in case of initful containers, so that a dedicated\n\t# systemd user session can be used.\n\tif [ -d \"/run/user/${container_user_uid}\" ] && [ \"${init}\" -eq 0 ]; then\n\t\tresult_command=\"${result_command}\n\t\t\t--volume /run/user/${container_user_uid}:/run/user/${container_user_uid}${rslave}\"\n\tfi\n\n\t# These are dynamic configs needed by the container to function properly\n\t# and integrate with the host\n\t#\n\t# We're doing this now instead of inside the init because some distros will\n\t# have symlinks places for these files that use absolute paths instead of\n\t# relative paths.\n\t# This is the bare minimum to ensure connectivity inside the container.\n\t# These files, will then be kept updated by the main loop every 15 seconds.\n\tif [ \"${unshare_netns}\" -eq 0 ]; then\n\t\tNET_FILES=\"\n\t\t\t/etc/hosts\n\t\t\t/etc/resolv.conf\n\t\t\"\n\n\t\t# If container_hostname is custom, we skip mounting /etc/hostname, else\n\t\t# we want to keep it in sync\n\t\tif [ \"${container_hostname}\" = \"$(uname -n)\" ]; then\n\t\t\tNET_FILES=\"${NET_FILES} /etc/hostname\"\n\t\tfi\n\n\t\tfor net_file in ${NET_FILES}; do\n\t\t\tif [ -e \"${net_file}\" ]; then\n\t\t\t\tresult_command=\"${result_command}\n\t\t\t\t\t--volume ${net_file}:${net_file}:ro\"\n\t\t\tfi\n\t\tdone\n\tfi\n\n\t# These flags are not supported by docker, so we use them only if our\n\t# container manager is podman.\n\tif echo \"${container_manager}\" | grep -q \"podman\"; then\n\t\t# If possible, always prefer crun, as it allows keeping original groups.\n\t\t# useful for rootless containers.\n\t\tif command -v crun > /dev/null 2>&1; then\n\t\t\tresult_command=\"${result_command}\n\t\t\t\t--runtime=crun\"\n\t\tfi\n\t\tresult_command=\"${result_command}\n\t\t\t--annotation run.oci.keep_original_groups=1\n\t\t\t--ulimit host\"\n\n\t\tif [ \"${init}\" -eq 1 ]; then\n\t\t\tresult_command=\"${result_command}\n\t\t\t\t--systemd=always\"\n\t\tfi\n\n\t\t# Use keep-id only if going rootless.\n\t\tif [ \"${rootful}\" -eq 0 ]; then\n\t\t\tresult_command=\"${result_command}\n\t\t\t\t--userns keep-id\"\n\n\t\t\t# Test if podman supports keep-id:size=\n\t\t\tif podman run --rm --userns=keep-id:size=65536 \"${container_image}\" /bin/true > /dev/null 2>&1 || [ \"$?\" -eq 127 ]; then\n\t\t\t\thas_keepid_size=1\n\t\t\telse\n\t\t\t\thas_keepid_size=0\n\t\t\tfi\n\n\t\t\t# Add :size=65536 if wanted\n\t\t\tif [ \"${has_keepid_size}\" -eq 1 ] && [ \"${userns_nolimit}\" -eq 0 ]; then\n\t\t\t\tresult_command=\"${result_command}:size=65536\"\n\t\t\tfi\n\t\tfi\n\tfi\n\n\t# Add additional flags\n\tresult_command=\"${result_command}\n\t\t${container_manager_additional_flags}\"\n\n\t# Now execute the entrypoint, refer to `distrobox-init -h` for instructions\n\t#\n\t# Be aware that entrypoint corresponds to distrobox-init, the copying of it\n\t# inside the container is moved to distrobox-enter, in the start phase.\n\t# This is done to make init, export and host-exec location independent from\n\t# the host, and easier to upgrade.\n\t#\n\t# We set the entrypoint _before_ running the container image so that\n\t# we can override any user provided entrypoint if need be\n\tresult_command=\"${result_command}\n\t--entrypoint /usr/bin/entrypoint\n\t${container_image}\n\t\t--verbose\n\t\t--name \\\"${container_user_name}\\\"\n\t\t--user ${container_user_uid}\n\t\t--group ${container_user_gid}\n\t\t--home \\\"${container_user_custom_home:-\"${container_user_home}\"}\\\"\n\t\t--init \\\"${init}\\\"\n\t\t--nvidia \\\"${nvidia}\\\"\n\t\t--pre-init-hooks \\\"${container_pre_init_hook}\\\"\n\t\t--additional-packages \\\"${container_additional_packages}\\\"\n\t\t-- '${container_init_hook}'\n\t\"\n\t# use container_user_custom_home if defined, else fallback to normal home.\n\n\t# Return generated command.\n\tprintf \"%s\" \"${result_command}\"\n}\n\n# dry run mode, just generate the command and print it. No creation.\nif [ \"${dryrun}\" -ne 0 ]; then\n\tif [ -n \"${container_clone}\" ]; then\n\t\tcontainer_image=\"${container_clone}\"\n\tfi\n\tcmd=\"$(generate_create_command)\"\n\tcmd=\"$(echo \"${cmd}\" | sed 's/\\t//g')\"\n\tprintf \"%s\\n\" \"${cmd}\"\n\texit 0\nfi\n\n# Check if the container already exists.\n# If it does, notify the user and exit.\nif ${container_manager} inspect --type container \"${container_name}\" > /dev/null 2>&1; then\n\tprintf \"Distrobox named '%s' already exists.\\n\" \"${container_name}\"\n\tprintf \"To enter, run:\\n\\n\"\n\t# If it's a rootful container AND user is not logged as root.\n\tif [ \"${rootful}\" -eq 1 ] && [ \"${container_user_uid}\" -ne 0 ]; then\n\t\tprintf \"distrobox enter --root %s\\n\\n\" \"${container_name}\"\n\t# If user is logged as root OR it's a rootless container.\n\telif [ \"${container_user_uid}\" -eq 0 ] || [ \"${rootful}\" -eq 0 ]; then\n\t\tprintf \"distrobox enter %s\\n\\n\" \"${container_name}\"\n\tfi\n\texit 0\nfi\n\n# if we are using the clone flag, let's set the image variable\n# to the output of container duplication\nif [ -n \"${container_clone}\" ]; then\n\tif ! echo \"${container_manager}\" | grep -Eq \"podman|docker\"; then\n\t\tprintf >&2 \"ERROR: clone is only supported with docker and podman\\n\"\n\t\texit 127\n\tfi\n\tcontainer_image=\"$(get_clone_image)\"\nfi\n\n# First, check if the image exists in the host or auto-pull is enabled\n# If not prompt to download it.\nif [ \"${container_always_pull}\" -eq 1 ] ||\n\t! ${container_manager} inspect --type image \"${container_image}\" > /dev/null 2>&1; then\n\n\t# If we do auto-pull, don't ask questions\n\tif [ \"${non_interactive}\" -eq 1 ] || [ \"${container_always_pull}\" -eq 1 ]; then\n\t\tresponse=\"yes\"\n\telse\n\t\t# Prompt to download it.\n\t\tprintf >&2 \"Image %s not found.\\n\" \"${container_image}\"\n\t\tprintf >&2 \"Do you want to pull the image now? [Y/n]: \"\n\t\tread -r response\n\t\tresponse=\"${response:-\"Y\"}\"\n\tfi\n\n\t# Accept only y,Y,Yes,yes,n,N,No,no.\n\tcase \"${response}\" in\n\t\ty | Y | Yes | yes | YES)\n\t\t\t# Pull the image\n\t\t\t# shellcheck disable=SC2086\n\t\t\t${container_manager} pull ${container_platform} \"${container_image}\"\n\t\t\t;;\n\t\tn | N | No | no | NO)\n\t\t\tprintf >&2 \"next time, run this command first:\\n\"\n\t\t\tprintf >&2 \"\\t%s pull %s\\n\" \"${container_manager}\" \"${container_image}\"\n\t\t\texit 0\n\t\t\t;;\n\t\t*) # Default case: If no more options then break out of the loop.\n\t\t\tprintf >&2 \"Invalid input.\\n\"\n\t\t\tprintf >&2 \"The available choices are: y,Y,Yes,yes,YES or n,N,No,no,NO.\\nExiting.\\n\"\n\t\t\texit 1\n\t\t\t;;\n\tesac\nfi\n\n# Generate the create command and run it\nprintf >&2 \"Creating '%s' using image %s\\t\" \"${container_name}\" \"${container_image}\"\ncmd=\"$(generate_create_command)\"\n# Eval the generated command. If successful display an helpful message.\n# shellcheck disable=SC2086\nif eval ${cmd} > /dev/null; then\n\tprintf >&2 \"\\033[32m [ OK ]\\n\\033[0mDistrobox '%s' successfully created.\\n\" \"${container_name}\"\n\tprintf >&2 \"To enter, run:\\n\\n\"\n\t# If it's a rootful container AND user is not logged as root.\n\tif [ \"${rootful}\" -eq 1 ] && [ \"${container_user_uid}\" -ne 0 ]; then\n\t\tprintf \"distrobox enter --root %s\\n\\n\" \"${container_name}\"\n\t# If user is logged as root OR it's a rootless container.\n\telif [ \"${container_user_uid}\" -eq 0 ] || [ \"${rootful}\" -eq 0 ]; then\n\t\tprintf \"distrobox enter %s\\n\\n\" \"${container_name}\"\n\tfi\n\n\t# We've created the box, let's also create the entry\n\tif [ \"${rootful}\" -eq 0 ]; then\n\t\tif [ \"${container_generate_entry}\" -ne 0 ]; then\n\t\t\t\"${distrobox_genentry_path}\" \"${container_name}\"\n\t\tfi\n\tfi\nelse\n\terror=\"$?\"\n\tprintf >&2 \"\\033[31m [ ERR ]\\033[0m failed to create container.\\n\"\n\texit \"${error}\"\nfi\n"
  },
  {
    "path": "distrobox-enter",
    "content": "#!/bin/sh\n# SPDX-License-Identifier: GPL-3.0-only\n#\n# This file is part of the distrobox project:\n#    https://github.com/89luca89/distrobox\n#\n# Copyright (C) 2021 distrobox contributors\n#\n# distrobox is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 3\n# as published by the Free Software Foundation.\n#\n# distrobox is distributed in the hope that it will be useful, but\n# WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n# General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with distrobox; if not, see <http://www.gnu.org/licenses/>.\n\n# POSIX\n# Expected env variables:\n#\tHOME\n#\tUSER\n# Optional env variables:\n#\tDBX_CONTAINER_ALWAYS_PULL\n#\tDBX_CONTAINER_CUSTOM_HOME\n#\tDBX_CONTAINER_GENERATE_ENTRY\n#\tDBX_CONTAINER_HOME_PREFIX\n#\tDBX_CONTAINER_HOSTNAME\n#\tDBX_CONTAINER_IMAGE\n#\tDBX_CONTAINER_MANAGER\n#\tDBX_CONTAINER_NAME\n#\tDBX_CONTAINER_CLEAN_PATH\n#\tDBX_NON_INTERACTIVE\n#\tDBX_VERBOSE\n#\tDBX_SKIP_WORKDIR\n#\tDBX_SUDO_PROGRAM\n\n# Ensure we have our env variables correctly set\n[ -z \"${USER}\" ] && USER=\"$(id -run)\"\n[ -z \"${HOME}\" ] && HOME=\"$(getent passwd \"${USER}\" | cut -d':' -f6)\"\n[ -z \"${SHELL}\" ] && SHELL=\"$(getent passwd \"${USER}\" | cut -d':' -f7)\"\n\napp_cache_dir=${XDG_CACHE_HOME:-\"${HOME}/.cache\"}/distrobox\n\ntrap cleanup TERM INT HUP EXIT\n\n# cleanup will remove fifo and temp files, and print to stdout\n# container's logs in case of error and verbose.\n# Arguments:\n#   None\n# Expected global variables:\n#   container_manager: string container manager to use\n#   container_name: string container name\n#   app_cache_dir: string cache dire to write file into\n#   logs_pid: string pid of the podman/docker logs process\n#   verbose: bool verbose\n# Expected env variables:\n#   None\n# Outputs:\n#   None\ncleanup()\n{\n\trm -f \"${app_cache_dir}/.${container_name}.fifo\"\n\tif [ -n \"${logs_pid:-}\" ]; then\n\t\tkill \"${logs_pid:-}\" 2> /dev/null || :\n\tfi\n\tif [ \"${verbose}\" -eq 1 ]; then\n\t\t${container_manager} logs \"${container_name}\"\n\tfi\n}\n\n# Despite of running this script via SUDO/DOAS being not supported (the\n# script itself will call the appropriate tool when necessary), we still want\n# to allow people to run it as root, logged in in a shell, and create rootful\n# containers.\n#\n# SUDO_USER is a variable set by SUDO and can be used to check whether the script was called by it. Same thing for DOAS_USER, set by DOAS.\nif {\n\t[ -n \"${SUDO_USER}\" ] || [ -n \"${DOAS_USER}\" ]\n} && [ \"$(id -ru)\" -eq 0 ]; then\n\tprintf >&2 \"Running %s via SUDO/DOAS is not supported. Instead, please try running:\\n\" \"$(basename \"${0}\")\"\n\tprintf >&2 \"  %s --root %s\\n\" \"$(basename \"${0}\")\" \"$*\"\n\texit 1\nfi\n\n# Defaults\n# by default we use getent to get the login shell of the user and use that\ncontainer_custom_command=0\ncontainer_command_user=\"$(echo \"${USER}\" | sed 's|\\\\|\\\\\\\\|g')\"\ncontainer_image_default=\"registry.fedoraproject.org/fedora-toolbox:latest\"\ncontainer_manager=\"autodetect\"\ncontainer_manager_additional_flags=\"\"\ncontainer_name=\"\"\ncontainer_name_default=\"my-distrobox\"\nnon_interactive=0\n\n# Use cd + dirname + pwd so that we do not have relative paths in mount points\n# We're not using \"realpath\" here so that symlinks are not resolved this way\n# \"realpath\" would break situations like Nix or similar symlink based package\n# management.\ndistrobox_enter_path=\"$(cd \"$(dirname \"$0\")\" && pwd)/distrobox-enter\"\ndryrun=0\nheadless=0\n# If the user runs this script as root in a login shell, set rootful=1.\n# There's no need for them to pass the --root flag option in such cases.\n[ \"$(id -ru)\" -eq 0 ] && rootful=1 || rootful=0\nskip_workdir=0\nverbose=0\nclean_path=0\nversion=\"1.8.2.4\"\n\n# Source configuration files, this is done in an hierarchy so local files have\n# priority over system defaults\n# leave priority to environment variables.\n#\n# On NixOS, for the distrobox derivation to pick up a static config file shipped\n# by the package maintainer the path must be relative to the script itself.\nself_dir=\"$(dirname \"$(realpath \"$0\")\")\"\nnix_config_file=\"${self_dir}/../share/distrobox/distrobox.conf\"\n\nconfig_files=\"\n\t${nix_config_file}\n\t/usr/share/distrobox/distrobox.conf\n\t/usr/share/defaults/distrobox/distrobox.conf\n\t/usr/etc/distrobox/distrobox.conf\n\t/usr/local/share/distrobox/distrobox.conf\n\t/etc/distrobox/distrobox.conf\n\t${XDG_CONFIG_HOME:-\"${HOME}/.config\"}/distrobox/distrobox.conf\n\t${HOME}/.distroboxrc\n\"\nfor config_file in ${config_files}; do\n\t# Shellcheck will give error for sourcing a variable file as it cannot follow\n\t# it. We don't care so let's disable this linting for now.\n\t# shellcheck disable=SC1090\n\t[ -e \"${config_file}\" ] && . \"$(realpath \"${config_file}\")\"\ndone\n# If we're running this script as root -- as in, logged in in the shell as root\n# user, and not via SUDO/DOAS --, we don't need to set distrobox_sudo_program\n# as it's meaningless for this use case.\nif [ \"$(id -ru)\" -ne 0 ]; then\n\t# If the DBX_SUDO_PROGRAM/distrobox_sudo_program variable was set by the\n\t# user, use its value instead of \"sudo\". But only if not running the script\n\t# as root (UID 0).\n\tdistrobox_sudo_program=${DBX_SUDO_PROGRAM:-${distrobox_sudo_program:-\"sudo\"}}\nfi\n\n[ -n \"${DBX_CONTAINER_MANAGER}\" ] && container_manager=\"${DBX_CONTAINER_MANAGER}\"\n[ -n \"${DBX_CONTAINER_NAME}\" ] && container_name=\"${DBX_CONTAINER_NAME}\"\n[ -n \"${DBX_CONTAINER_CLEAN_PATH}\" ] && clean_path=1\n[ -n \"${DBX_SKIP_WORKDIR}\" ] && skip_workdir=\"${DBX_SKIP_WORKDIR}\"\n[ -n \"${DBX_NON_INTERACTIVE}\" ] && non_interactive=\"${DBX_NON_INTERACTIVE}\"\n[ -n \"${DBX_VERBOSE}\" ] && verbose=\"${DBX_VERBOSE}\"\n\n# Fixup variable=[true|false], in case we find it in the config file(s)\n[ \"${non_interactive}\" = \"true\" ] && non_interactive=1\n[ \"${non_interactive}\" = \"false\" ] && non_interactive=0\n[ \"${verbose}\" = \"true\" ] && verbose=1\n[ \"${verbose}\" = \"false\" ] && verbose=0\n\n# show_help will print usage to stdout.\n# Arguments:\n#   None\n# Expected global variables:\n#   version: distrobox version\n# Expected env variables:\n#   None\n# Outputs:\n#   print usage with examples.\nshow_help()\n{\n\tcat << EOF\ndistrobox version: ${version}\n\nUsage:\n\n\tdistrobox-enter --name fedora-39 -- bash -l\n\tdistrobox-enter my-alpine-container -- sh -l\n\tdistrobox-enter --additional-flags \"--preserve-fds\" --name test -- bash -l\n\tdistrobox-enter --additional-flags \"--env MY_VAR=value\" --name test -- bash -l\n\tMY_VAR=value distrobox-enter --additional-flags \"--preserve-fds\" --name test -- bash -l\n\nOptions:\n\n\t--name/-n:\t\tname for the distrobox\t\t\t\t\t\tdefault: my-distrobox\n\t--/-e:\t\t\tend arguments execute the rest as command to execute at login\tdefault: default ${USER}'s shell\n\t--clean-path:\t\treset PATH inside container to FHS standard\n\t--no-tty/-T:\t\tdo not instantiate a tty\n\t--no-workdir/-nw:\talways start the container from container's home directory\n\t--additional-flags/-a:\tadditional flags to pass to the container manager command\n\t--help/-h:\t\tshow this message\n\t--root/-r:\t\tlaunch podman/docker/lilipod with root privileges. Note that if you need root this is the preferred\n\t\t\t\tway over \"sudo distrobox\" (note: if using a program other than 'sudo' for root privileges is necessary,\n\t\t\t\tspecify it through the DBX_SUDO_PROGRAM env variable, or 'distrobox_sudo_program' config variable)\n\t--dry-run/-d:\t\tonly print the container manager command generated\n\t--verbose/-v:\t\tshow more verbosity\n\t--version/-V:\t\tshow version\nEOF\n}\n\n# Parse arguments\nwhile :; do\n\tcase $1 in\n\t\t-h | --help)\n\t\t\t# Call a \"show_help\" function to display a synopsis, then exit.\n\t\t\tshow_help\n\t\t\texit 0\n\t\t\t;;\n\t\t-v | --verbose)\n\t\t\tshift\n\t\t\tverbose=1\n\t\t\t;;\n\t\t-T | -H | --no-tty)\n\t\t\tshift\n\t\t\theadless=1\n\t\t\t;;\n\t\t-r | --root)\n\t\t\tshift\n\t\t\trootful=1\n\t\t\t;;\n\t\t-V | --version)\n\t\t\tprintf \"distrobox: %s\\n\" \"${version}\"\n\t\t\texit 0\n\t\t\t;;\n\t\t-d | --dry-run)\n\t\t\tshift\n\t\t\tdryrun=1\n\t\t\t;;\n\t\t-nw | --no-workdir)\n\t\t\tshift\n\t\t\tskip_workdir=1\n\t\t\t;;\n\t\t-n | --name)\n\t\t\tif [ -n \"$2\" ]; then\n\t\t\t\tcontainer_name=\"$2\"\n\t\t\t\tshift\n\t\t\t\tshift\n\t\t\tfi\n\t\t\t;;\n\t\t-a | --additional-flags)\n\t\t\tif [ -n \"$2\" ]; then\n\t\t\t\tif [ -z \"${container_manager_additional_flags=}\" ]; then\n\t\t\t\t\tcontainer_manager_additional_flags=\"$(echo \"${2}\" | sed -E \"s/(--[a-zA-Z]+) ([^ ]+)/\\1=\\2/g\" | sed 's/ --/\\n--/g')\"\n\t\t\t\telse\n\t\t\t\t\tcontainer_manager_additional_flags=\"${container_manager_additional_flags}\n\t\t\t\t\t$(echo \"${2}\" | sed -E \"s/(--[a-zA-Z]+) ([^ ]+)/\\1=\\2/g\" | sed 's/ --/\\n--/g')\"\n\t\t\t\tfi\n\t\t\t\tshift\n\t\t\t\tshift\n\t\t\tfi\n\t\t\t;;\n\t\t-Y | --yes)\n\t\t\tnon_interactive=1\n\t\t\tshift\n\t\t\t;;\n\t\t-e | --exec | --)\n\t\t\tcontainer_custom_command=1\n\t\t\tshift\n\t\t\t# We pass the rest of arguments as $@ at the end\n\t\t\tbreak\n\t\t\t;;\n\t\t--clean-path)\n\t\t\tshift\n\t\t\tclean_path=1\n\t\t\t;;\n\t\t-*) # Invalid options.\n\t\t\tprintf >&2 \"ERROR: Invalid flag '%s'\\n\\n\" \"$1\"\n\t\t\tshow_help\n\t\t\texit 1\n\t\t\t;;\n\t\t*) # Default case: If no more options then break out of the loop.\n\t\t\t# If we have a flagless option and container_name is not specified\n\t\t\t# then let's accept argument as container_name\n\t\t\tif [ -n \"$1\" ]; then\n\t\t\t\tcontainer_name=\"$1\"\n\t\t\t\tshift\n\t\t\telse\n\t\t\t\tbreak\n\t\t\tfi\n\t\t\t;;\n\tesac\ndone\n\nset -o errexit\nset -o nounset\n# set verbosity\nif [ \"${verbose}\" -ne 0 ]; then\n\tset -o xtrace\nfi\n\nif [ -z \"${container_name}\" ]; then\n\tcontainer_name=\"${container_name_default}\"\nfi\n\nif [ ! -t 0 ] || [ ! -t 1 ]; then\n\theadless=1\nfi\n# We depend on a container manager let's be sure we have it\n# First we use podman, else docker, else lilipod\ncase \"${container_manager}\" in\n\tautodetect)\n\t\tif command -v podman > /dev/null; then\n\t\t\tcontainer_manager=\"podman\"\n\t\telif command -v podman-launcher > /dev/null; then\n\t\t\tcontainer_manager=\"podman-launcher\"\n\t\telif command -v docker > /dev/null; then\n\t\t\tcontainer_manager=\"docker\"\n\t\telif command -v lilipod > /dev/null; then\n\t\t\tcontainer_manager=\"lilipod\"\n\t\tfi\n\t\t;;\n\tpodman)\n\t\tcontainer_manager=\"podman\"\n\t\t;;\n\tpodman-launcher)\n\t\tcontainer_manager=\"podman-launcher\"\n\t\t;;\n\tlilipod)\n\t\tcontainer_manager=\"lilipod\"\n\t\t;;\n\tdocker)\n\t\tcontainer_manager=\"docker\"\n\t\t;;\n\t*)\n\t\tprintf >&2 \"Invalid input %s.\\n\" \"${container_manager}\"\n\t\tprintf >&2 \"The available choices are: 'autodetect', 'podman', 'docker', 'lilipod'\\n\"\n\t\t;;\nesac\n\n# Be sure we have a container manager to work with.\nif ! command -v \"${container_manager}\" > /dev/null && [ \"${dryrun}\" -eq 0 ]; then\n\t# Error: we need at least one between docker, podman or lilipod.\n\tprintf >&2 \"Missing dependency: we need a container manager.\\n\"\n\tprintf >&2 \"Please install one of podman, docker or lilipod.\\n\"\n\tprintf >&2 \"You can follow the documentation on:\\n\"\n\tprintf >&2 \"\\tman distrobox-compatibility\\n\"\n\tprintf >&2 \"or:\\n\"\n\tprintf >&2 \"\\thttps://github.com/89luca89/distrobox/blob/main/docs/compatibility.md\\n\"\n\texit 127\nfi\n\n# add  verbose if -v is specified\nif [ \"${verbose}\" -ne 0 ]; then\n\tcontainer_manager=\"${container_manager} --log-level debug\"\nfi\n\n# prepend sudo (or the specified sudo program) if we want our container manager to be rootful\nif [ \"${rootful}\" -ne 0 ]; then\n\tcontainer_manager=\"${distrobox_sudo_program-} ${container_manager}\"\nfi\n\n# generate_enter_command will produce a Podman, Docker or Lilipod command to execute to enter the container.\n# Arguments:\n#   None\n# Expected global variables:\n#   container_manager: string container manager to use\n#   container_name: string container name\n#   container_manager_additional_flags: string container manager additional flags to use\n#   container_home: string container's home path\n#   container_path: string container's default PATH variable\n#   headless: bool headless mode\n#   skip_workdir: bool skip workdir\n#   verbose: bool verbose\n#   unshare_groups\n#   distrobox_enter_path\n# Expected env variables:\n#   PATH\n#   USER\n#   PWD\n#   XDG_DATA_DIRS\n#   XDG_CONFIG_DIRS\n# Outputs:\n#   prints the podman, docker or lilipod command to enter the distrobox container\ngenerate_enter_command()\n{\n\tresult_command=\"exec\"\n\tresult_command=\"${result_command}\n\t\t--interactive\"\n\tresult_command=\"${result_command}\n\t\t--detach-keys=\"\n\n\t# In case of initful systems or unshared groups, we don't enter directly\n\t# as our user, but we instead enter as root, and then su $USER, in order\n\t# to trigger a proper login\n\tif [ \"${unshare_groups:-0}\" -eq 1 ]; then\n\t\tresult_command=\"${result_command}\n\t\t\t--user=root\"\n\telse\n\t\tresult_command=\"${result_command}\n\t\t\t--user=${USER}\"\n\tfi\n\n\t# For some usage, like use in service, or launched by non-terminal\n\t# eg. from desktop files, TTY can fail to instantiate, and fail to enter\n\t# the container.\n\t# To work around this, --headless let's you skip the --tty flag and make it\n\t# work in tty-less situations.\n\t# Disable tty also if we're NOT in a tty (test -t 0, test -t 1).\n\tif [ \"${headless}\" -eq 0 ]; then\n\t\tresult_command=\"${result_command}\n\t\t\t--tty\"\n\tfi\n\n\t# Entering container using our user and workdir.\n\t# Start container from working directory. Else default to home. Else do /.\n\t# Since we are entering from host, drop at workdir through '/run/host'\n\t# which represents host's root inside container. Any directory on host\n\t# even if not explicitly mounted is bound to exist under /run/host.\n\t# Since user $HOME is very likely present in container, enter there directly\n\t# to avoid confusing the user about shifted paths.\n\t# pass distrobox-enter path, it will be used in the distrobox-export tool.\n\tif [ \"${skip_workdir}\" -eq 0 ]; then\n\t\tworkdir=\"${PWD:-${container_home:-\"/\"}}\"\n\t\tif [ -n \"${workdir##*\"${container_home}\"*}\" ]; then\n\t\t\tworkdir=\"/run/host${workdir}\"\n\t\tfi\n\telse\n\t\t# Skipping workdir we just enter $HOME of the container.\n\t\tworkdir=\"${container_home}\"\n\tfi\n\n\tresult_command=\"${result_command}\n\t\t--workdir=${workdir}\"\n\tresult_command=\"${result_command}\n\t\t--env=PWD=${workdir}\"\n\tresult_command=\"${result_command}\n\t\t--env=CONTAINER_ID=${container_name}\"\n\tresult_command=\"${result_command}\n\t\t--env=DISTROBOX_ENTER_PATH=${distrobox_enter_path}\"\n\n\t# Loop through all the environment vars\n\t# and export them to the container.\n\tset +o xtrace\n\t# disable logging for this snippet, or it will be too talkative.\n\t# We filter the environment so that we do not have strange variables or\n\t# multiline.\n\t# We also NEED to ignore the HOME variable, as this is set at create time\n\t# and needs to stay that way to use custom home dirs. or it will be too talkative.\n\tresult_command=\"${result_command}\n\t\t$(printenv | grep '=' | grep -Ev '\"|`|\\$' |\n\t\tgrep -Ev '^(CONTAINER_ID|FPATH|HOST|HOSTNAME|HOME|PATH|PROFILEREAD|PWD|SHELL|XDG_SEAT|XDG_VTNR|XDG_.*_DIRS|^_)' |\n\t\tsed 's/ /\\ /g' | sed 's/^\\(.*\\)$/--env=\\1/g')\"\n\n\t# Start with the $PATH set in the container's config\n\tcontainer_paths=\"${container_path:-\"\"}\"\n\t# Ensure the standard FHS program paths are in PATH environment\n\tstandard_paths=\"/usr/local/sbin /usr/local/bin /usr/sbin /usr/bin /sbin /bin\"\n\n\tif [ \"${clean_path}\" -eq 1 ]; then\n\t\t# only add the standard paths\n\t\tfor standard_path in ${standard_paths}; do\n\t\t\tif [ -z \"${container_paths}\" ]; then\n\t\t\t\tcontainer_paths=\"${standard_path}\"\n\t\t\telse\n\t\t\t\tcontainer_paths=\"${container_paths}:${standard_path}\"\n\t\t\tfi\n\t\tdone\n\telse\n\t\t# collect standard paths not existing from host PATH\n\t\tfor standard_path in ${standard_paths}; do\n\t\t\tpattern=\"(:|^)${standard_path}(:|$)\"\n\t\t\tif ! echo \"${PATH}\" | grep -Eq \"${pattern}\"; then\n\t\t\t\tif [ -z \"${container_paths}\" ]; then\n\t\t\t\t\tcontainer_paths=\"${standard_path}\"\n\t\t\t\telse\n\t\t\t\t\tcontainer_paths=\"${container_paths}:${standard_path}\"\n\t\t\t\tfi\n\t\t\tfi\n\t\tdone\n\t\t# append additional standard paths to host PATH to get final container_paths\n\t\tif [ -n \"${container_paths}\" ]; then\n\t\t\tcontainer_paths=\"${PATH}:${container_paths}\"\n\t\telse\n\t\t\tcontainer_paths=\"${PATH}\"\n\t\tfi\n\n\t\t# Ensure /usr/local/{s,}bin appears before /usr/{s,}bin in PATH.\n\t\t# This follows FHS conventions: /usr/local should override /usr,\n\t\t# and ensures distrobox wrappers in /usr/local/bin are found first.\n\t\treordered_paths=\"\"\n\t\tIFS_OLD=\"${IFS}\"\n\t\tIFS=\":\"\n\t\tfor p in ${container_paths}; do\n\t\t\tcase \"${p}\" in\n\t\t\t\t/usr/local/bin | /usr/local/sbin)\n\t\t\t\t\t# skip, will be re-inserted before their /usr counterpart\n\t\t\t\t\t;;\n\t\t\t\t/usr/bin)\n\t\t\t\t\t# insert /usr/local/bin right before /usr/bin\n\t\t\t\t\treordered_paths=\"${reordered_paths:+${reordered_paths}:}/usr/local/bin:${p}\"\n\t\t\t\t\t;;\n\t\t\t\t/usr/sbin)\n\t\t\t\t\t# insert /usr/local/sbin right before /usr/sbin\n\t\t\t\t\treordered_paths=\"${reordered_paths:+${reordered_paths}:}/usr/local/sbin:${p}\"\n\t\t\t\t\t;;\n\t\t\t\t*)\n\t\t\t\t\treordered_paths=\"${reordered_paths:+${reordered_paths}:}${p}\"\n\t\t\t\t\t;;\n\t\t\tesac\n\t\tdone\n\t\tIFS=\"${IFS_OLD}\"\n\n\t\t# If /usr/bin or /usr/sbin were not in PATH, the corresponding\n\t\t# /usr/local paths were skipped above. Re-add them if missing.\n\t\tfor lp in /usr/local/bin /usr/local/sbin; do\n\t\t\tpattern=\"(:|^)${lp}(:|$)\"\n\t\t\tif ! echo \"${reordered_paths}\" | grep -Eq \"${pattern}\"; then\n\t\t\t\treordered_paths=\"${lp}:${reordered_paths}\"\n\t\t\tfi\n\t\tdone\n\t\tcontainer_paths=\"${reordered_paths}\"\n\tfi\n\n\tresult_command=\"${result_command}\n\t\t--env=PATH=${container_paths}\"\n\n\t# Ensure the standard FHS program paths are in XDG_DATA_DIRS environment\n\tstandard_paths=\"/usr/local/share /usr/share\"\n\tcontainer_paths=\"${XDG_DATA_DIRS:-}\"\n\t# add to the XDG_DATA_DIRS only after the host's paths, and only if not already present.\n\tfor standard_path in ${standard_paths}; do\n\t\tpattern=\"(:|^)${standard_path}(:|$)\"\n\t\tif [ -z \"${container_paths}\" ]; then\n\t\t\tcontainer_paths=\"${standard_path}\"\n\t\telif ! echo \"${container_paths}\" | grep -Eq \"${pattern}\"; then\n\t\t\tcontainer_paths=\"${container_paths}:${standard_path}\"\n\t\tfi\n\tdone\n\tresult_command=\"${result_command}\n\t\t--env=XDG_DATA_DIRS=${container_paths}\"\n\n\t# This correctly sets the XDG_* dirs to the container_home\n\t# it will be $HOME if using regular home dirs\n\t# if will be $container_home if using a custom home during create\n\tresult_command=\"${result_command}\n\t\t--env=XDG_CACHE_HOME=${container_home}/.cache\n\t\t--env=XDG_CONFIG_HOME=${container_home}/.config\n\t\t--env=XDG_DATA_HOME=${container_home}/.local/share\n\t\t--env=XDG_STATE_HOME=${container_home}/.local/state\"\n\n\t# Ensure the standard FHS program paths are in XDG_CONFIG_DIRS environment\n\tstandard_paths=\"/etc/xdg\"\n\tcontainer_paths=\"${XDG_CONFIG_DIRS:-}\"\n\t# add to the XDG_CONFIG_DIRS only after the host's paths, and only if not already present.\n\tfor standard_path in ${standard_paths}; do\n\t\tpattern=\"(:|^)${standard_path}(:|$)\"\n\t\tif [ -z \"${container_paths}\" ]; then\n\t\t\tcontainer_paths=\"${standard_path}\"\n\t\telif ! echo \"${container_paths}\" | grep -Eq \"${pattern}\"; then\n\t\t\tcontainer_paths=\"${container_paths}:${standard_path}\"\n\t\tfi\n\tdone\n\tresult_command=\"${result_command}\n\t\t--env=XDG_CONFIG_DIRS=${container_paths}\"\n\n\t# re-enable logging if it was enabled previously.\n\tif [ \"${verbose}\" -ne 0 ]; then\n\t\tset -o xtrace\n\tfi\n\n\t# Add additional flags\n\tif [ -n \"${container_manager_additional_flags}\" ]; then\n\t\tresult_command=\"${result_command}\n\t\t\t${container_manager_additional_flags}\"\n\tfi\n\n\t# Run selected container with specified command.\n\tresult_command=\"${result_command}\n\t\t${container_name}\"\n\n\t# Return generated command.\n\t# here we remove tabs as an artifact of using indentation in code to improve\n\t# readability\n\tprintf \"%s\\n\" \"${result_command}\" | tr -d '\\t'\n}\n\ncontainer_home=\"${HOME}\"\ncontainer_path=\"${PATH}\"\nunshare_groups=0\n\n################################################################################\n# In this section we will manipulate the positional parameters\n# in order to generate our long docker/podman/lilipod command to execute.\n#\n# We use positional parameters in order to have the shell manage escaping and spaces\n# so we remove the problem of we having to handle them.\n#\n# 1 - handle absence of custom command, we will need to add a getent command to\n#     execute the right container's user's shell\n# 2 - in case of unshared groups (or initful) we need to trigger a proper login\n#     using `su`, so we will need to manipulate these arguments accorodingly\n# 3 - prepend our generated command\n#     to do this, we use `tac` so we reverse loop it and prepend each argument.\n# 4 - now that we're done, we can prepend our container_command\n#     we will need to use `rev` to reverse it as we reverse loop and prepend each\n#     argument\n################################################################################\n#\n# Setup default commands if none are specified\n# execute a getent command using the /bin/sh shell\n# to find out the default shell of the user, and\n# do a login shell with it (eg: /bin/bash -l)\nif [ \"${container_custom_command}\" -eq 0 ]; then\n\tset - \"$@\" \"/bin/sh\" \"-c\" \"\\$(getent passwd '${container_command_user}' | cut -f 7 -d :) -l\"\nfi\n\n# If we have a command and we're unsharing groups, we need to execute those\n# command using su $container_command_user\n# if we're in a tty, also allocate one\nif [ \"${unshare_groups:-0}\" -eq 1 ]; then\n\t# shellcheck disable=SC2089,SC2016\n\tset -- \"-c\" '\"$0\" \"$@\"' -- \"$@\"\n\tset -- \"-s\" \"/bin/sh\" \"$@\"\n\tif [ \"${headless}\" -eq 0 ]; then\n\t\tset -- \"--pty\" \"$@\"\n\tfi\n\tset -- \"-m\" \"$@\"\n\tset -- \"${container_command_user}\" \"$@\"\n\tset -- \"su\" \"$@\"\nfi\n\n################################################################################\n# Execution section\n################################################################################\n\n# dry run mode, just generate the command and print it. No execution.\nif [ \"${dryrun}\" -ne 0 ]; then\n\tcmd=\"$(generate_enter_command | sed 's/\\t//g')\"\n\tprintf \"%s %s\\n\" \"${cmd}\" \"$*\"\n\texit 0\nfi\n\n# Now inspect the container we're working with.\ncontainer_status=\"unknown\"\neval \"$(${container_manager} inspect --type container --format \\\n\t'container_status={{.State.Status}};\n\tunshare_groups={{ index .Config.Labels \"distrobox.unshare_groups\" }};\n\t{{range .Config.Env}}{{if and (ge (len .) 5) (eq (slice . 0 5) \"HOME=\")}}container_home={{slice . 5 | printf \"%q\"}}{{end}}{{end}};\n\t{{range .Config.Env}}{{if and (ge (len .) 5) (eq (slice . 0 5) \"PATH=\")}}container_path={{slice . 5 | printf \"%q\"}}{{end}}{{end}}' \\\n\t\"${container_name}\")\"\n\n# Check if the container is even there\nif [ \"${container_status}\" = \"unknown\" ]; then\n\t# If not, prompt to create it first\n\t# If we're not-interactive, just don't ask questions\n\tif [ \"${non_interactive}\" -eq 1 ]; then\n\t\tresponse=\"yes\"\n\telse\n\t\tprintf >&2 \"Create it now, out of image %s? [Y/n]: \" \"${container_image_default}\"\n\t\tread -r response\n\t\tresponse=\"${response:-\"Y\"}\"\n\tfi\n\n\t# Accept only y,Y,Yes,yes,n,N,No,no.\n\tcase \"${response}\" in\n\t\ty | Y | Yes | yes | YES)\n\t\t\t# Ok, let's create the container with just 'distrobox create $container_name\n\t\t\tcreate_command=\"$(dirname \"${0}\")/distrobox-create\"\n\t\t\tif [ \"${rootful}\" -ne 0 ]; then\n\t\t\t\tcreate_command=\"${create_command} --root\"\n\t\t\tfi\n\n\t\t\tcreate_command=\"${create_command} --yes -i ${container_image_default} -n ${container_name}\"\n\n\t\t\tprintf >&2 \"Creating the container %s\\n\" \"${container_name}\"\n\n\t\t\tif [ \"${dryrun}\" -ne 1 ]; then\n\t\t\t\t${create_command}\n\t\t\tfi\n\t\t\t;;\n\t\tn | N | No | no | NO)\n\t\t\tprintf >&2 \"Ok. For creating it, run this command:\\n\"\n\t\t\tprintf >&2 \"\\tdistrobox create <name-of-container> --image <remote>/<docker>:<tag>\\n\"\n\t\t\texit 0\n\t\t\t;;\n\t\t*) # Default case: If no more options then break out of the loop.\n\t\t\tprintf >&2 \"Invalid input.\\n\"\n\t\t\tprintf >&2 \"The available choices are: y,Y,Yes,yes,YES or n,N,No,no,NO.\\nExiting.\\n\"\n\t\t\texit 1\n\t\t\t;;\n\tesac\nfi\n\n# If the container is not already running, we need to start if first\nif [ \"${container_status}\" != \"running\" ]; then\n\t# If container is not running, start it first\n\t#\n\t# Here, we save the timestamp before launching the start command, so we can\n\t# be sure we're working with this very same session of logs later.\n\tlog_timestamp=\"$(date -u +%FT%T).000000000+00:00\"\n\t${container_manager} start \"${container_name}\" > /dev/null\n\t#\n\t# Check if the container is going in error status earlier than the\n\t# entrypoint\n\tif [ \"$(${container_manager} inspect \\\n\t\t--type container \\\n\t\t--format \"{{.State.Status}}\" \"${container_name}\")\" != \"running\" ]; then\n\n\t\tprintf >&2 \"\\033[31m Error: could not start entrypoint.\\n\\033[0m\"\n\t\tcontainer_manager_log=\"$(${container_manager} logs \"${container_name}\")\"\n\t\tprintf >&2 \"%s\\n\" \"${container_manager_log}\"\n\t\texit 1\n\tfi\n\n\tprintf >&2 \"%-40s\\t\" \"Starting container...\"\n\tmkdir -p \"${app_cache_dir}\"\n\trm -f \"${app_cache_dir}/.${container_name}.fifo\"\n\tmkfifo \"${app_cache_dir}/.${container_name}.fifo\"\n\twhile true; do\n\t\t# Exit early in case of crashed/stopped container during setup\n\t\tif [ \"$(${container_manager} inspect --type container --format '{{.State.Status}}' \"${container_name}\")\" != \"running\" ]; then\n\t\t\tprintf >&2 \"\\nContainer Setup Failure!\\n\"\n\t\t\texit 1\n\t\tfi\n\t\t# save starting loop timestamp in temp variable, we'll use it\n\t\t# after to let logs command minimize possible holes\n\t\t${container_manager} logs --since \"${log_timestamp}\" -f \"${container_name}\" \\\n\t\t\t> \"${app_cache_dir}/.${container_name}.fifo\" 2>&1 &\n\t\tlogs_pid=\"$!\"\n\n\t\t# read logs from log_timestamp to now, line by line\n\t\twhile IFS= read -r line; do\n\t\t\tcase \"${line}\" in\n\t\t\t\t\"+\"*)\n\t\t\t\t\t# Ignoring logging commands\n\t\t\t\t\t;;\n\t\t\t\t\"Error:\"*)\n\t\t\t\t\tprintf >&2 \"\\033[31m %s\\n\\033[0m\" \"${line}\"\n\t\t\t\t\texit 1\n\t\t\t\t\t;;\n\t\t\t\t\"Warning:\"*)\n\t\t\t\t\tprintf >&2 \"\\n\\033[33m %s\\033[0m\" \"${line}\"\n\t\t\t\t\t;;\n\t\t\t\t\"distrobox:\"*)\n\t\t\t\t\tcurrent_line=\"$(echo \"${line}\" | cut -d' ' -f2-)\"\n\t\t\t\t\t# Save current line in the status, to avoid printing the same line multiple times\n\t\t\t\t\tprintf >&2 \"\\033[32m [ OK ]\\n\\033[0m%-40s\\t\" \"${current_line}\"\n\t\t\t\t\t;;\n\t\t\t\t\"container_setup_done\"*)\n\t\t\t\t\tprintf >&2 \"\\033[32m [ OK ]\\n\\033[0m\"\n\t\t\t\t\tkill \"${logs_pid}\" > /dev/null 2>&1\n\t\t\t\t\tbreak 2\n\t\t\t\t\t;;\n\t\t\t\t*) ;;\n\t\t\tesac\n\t\tdone < \"${app_cache_dir}/.${container_name}.fifo\"\n\tdone\n\t# cleanup fifo\n\trm -f \"${app_cache_dir}/.${container_name}.fifo\"\n\tprintf >&2 \"\\nContainer Setup Complete!\\n\"\nfi\n\n# Generate the exec command and run it\ncmd=\"$(generate_enter_command | awk '{a[i++]=$0} END {for (j=i-1; j>=0;) print a[j--]}')\"\n# Reverse it so we can reverse loop and prepend the command's arguments\n# to our positional parameters\nIFS='\n'\nfor arg in ${cmd}; do\n\tset - \"${arg}\" \"$@\"\ndone\n\n# Prepend the container manager command\n# reverse it first, so we can loop backward as we're prepending not appending\nIFS=' '\nfor arg in $(echo \"${container_manager}\" | rev); do\n\targ=\"$(echo \"${arg}\" | rev)\"\n\tset - \"${arg}\" \"$@\"\ndone\n\nexec \"$@\"\n"
  },
  {
    "path": "distrobox-ephemeral",
    "content": "#!/bin/sh\n# SPDX-License-Identifier: GPL-3.0-only\n#\n# This file is part of the distrobox project:\n#    https://github.com/89luca89/distrobox\n#\n# Copyright (C) 2021 distrobox contributors\n#\n# distrobox is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 3\n# as published by the Free Software Foundation.\n#\n# distrobox is distributed in the hope that it will be useful, but\n# WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n# General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with distrobox; if not, see <http://www.gnu.org/licenses/>.\n\n# POSIX\n# Optional env variables:\n#\tDBX_CONTAINER_MANAGER\n#\tDBX_CONTAINER_NAME\n#\tDBX_VERBOSE\n#\tDBX_SUDO_PROGRAM\n\n# Despite of running this script via SUDO/DOAS being not supported (the\n# script itself will call the appropriate tool when necessary), we still want\n# to allow people to run it as root, logged in in a shell, and create rootful\n# containers.\n#\n# SUDO_USER is a variable set by SUDO and can be used to check whether the script was called by it. Same thing for DOAS_USER, set by DOAS.\nif {\n\t[ -n \"${SUDO_USER}\" ] || [ -n \"${DOAS_USER}\" ]\n} && [ \"$(id -ru)\" -eq 0 ]; then\n\tprintf >&2 \"Running %s via SUDO/DOAS is not supported. Instead, please try running:\\n\" \"$(basename \"${0}\")\"\n\tprintf >&2 \"  %s --root %s\\n\" \"$(basename \"${0}\")\" \"$*\"\n\texit 1\nfi\n\n# Ensure we have our env variables correctly set\n[ -z \"${USER}\" ] && USER=\"$(id -run)\"\n[ -z \"${HOME}\" ] && HOME=\"$(getent passwd \"${USER}\" | cut -d':' -f6)\"\n[ -z \"${SHELL}\" ] && SHELL=\"$(getent passwd \"${USER}\" | cut -d':' -f7)\"\n\ntrap cleanup TERM INT HUP\n\nname=$(mktemp -u distrobox-XXXXXXXXXX)\ncontainer_command=\"\"\ncreate_flags=\"\"\ndistrobox_path=\"$(dirname \"${0}\")\"\nextra_flags=\"\"\n# If the user runs this script as root in a login shell, set rootful=1.\n# There's no need for them to pass the --root flag option in such cases.\n[ \"$(id -ru)\" -eq 0 ] && rootful=1 || rootful=0\nverbose=0\nversion=\"1.8.2.4\"\ncontainer_additional_packages=\"\"\ncontainer_init_hook=\" \"\ncontainer_manager_additional_flags=\"\"\ncontainer_pre_init_hook=\" \"\n\n# Source configuration files, this is done in an hierarchy so local files have\n# priority over system defaults\n# leave priority to environment variables.\n#\n# On NixOS, for the distrobox derivation to pick up a static config file shipped\n# by the package maintainer the path must be relative to the script itself.\nself_dir=\"$(dirname \"$(realpath \"$0\")\")\"\nnix_config_file=\"${self_dir}/../share/distrobox/distrobox.conf\"\n\nconfig_files=\"\n\t${nix_config_file}\n\t/usr/share/distrobox/distrobox.conf\n\t/usr/share/defaults/distrobox/distrobox.conf\n\t/usr/etc/distrobox/distrobox.conf\n\t/usr/local/share/distrobox/distrobox.conf\n\t/etc/distrobox/distrobox.conf\n\t${XDG_CONFIG_HOME:-\"${HOME}/.config\"}/distrobox/distrobox.conf\n\t${HOME}/.distroboxrc\n\"\nfor config_file in ${config_files}; do\n\t# Shellcheck will give error for sourcing a variable file as it cannot follow\n\t# it. We don't care so let's disable this linting for now.\n\t# shellcheck disable=SC1090\n\t[ -e \"${config_file}\" ] && . \"$(realpath \"${config_file}\")\"\ndone\n\n[ -n \"${DBX_VERBOSE}\" ] && verbose=\"${DBX_VERBOSE}\"\n\n# Fixup variable=[true|false], in case we find it in the config file(s)\n[ \"${verbose}\" = \"true\" ] && verbose=1\n[ \"${verbose}\" = \"false\" ] && verbose=0\n\n# show_help will print usage to stdout.\n# Arguments:\n#   None\n# Expected global variables:\n#   version: distrobox version\n# Expected env variables:\n#   None\n# Outputs:\n#   print usage with examples.\nshow_help()\n{\n\tcat << EOF\ndistrobox version: ${version}\n\nUsage:\n\n\tdistrobox-ephemeral [--root/-r]\n\nOptions:\n\n\t--root/-r:\t\tlaunch podman/docker/lilipod with root privileges. Note that if you need root this is the preferred\n\t\t\t\tway over \"sudo distrobox\" (note: if using a program other than 'sudo' for root privileges is necessary,\n\t\t\t\tspecify it through the DBX_SUDO_PROGRAM env variable, or 'distrobox_sudo_program' config variable)\n\t--verbose/-v:\t\tshow more verbosity\n\t--help/-h:\t\tshow this message\n\t--/-e:\t\t\tend arguments execute the rest as command to execute at login\tdefault: default ${USER}'s shell\n\t--version/-V:\t\tshow version\n\nSee also:\n\n\tdistrobox-ephemeral also inherits all the flags from distrobox-create:\nEOF\n}\n\n# Parse arguments\nwhile :; do\n\tcase $1 in\n\t\t-h | --help)\n\t\t\t# Call a \"show_help\" function to display a synopsis, then exit.\n\t\t\tshow_help\n\t\t\t\"${distrobox_path}\"/distrobox-create --help | tail -n +2\n\t\t\texit 0\n\t\t\t;;\n\t\t-r | --root)\n\t\t\tshift\n\t\t\trootful=1\n\t\t\t;;\n\t\t-v | --verbose)\n\t\t\tverbose=1\n\t\t\tshift\n\t\t\t;;\n\t\t-V | --version)\n\t\t\tprintf \"distrobox: %s\\n\" \"${version}\"\n\t\t\texit 0\n\t\t\t;;\n\t\t-e | --exec | --)\n\t\t\tshift\n\t\t\tcontainer_command=\"-- $*\"\n\t\t\tbreak\n\t\t\t;;\n\t\t-n | --name)\n\t\t\t# Ignore --name on ephemeral\n\t\t\tif [ -n \"$2\" ]; then\n\t\t\t\tname=\"${2}\"\n\t\t\t\tshift\n\t\t\t\tshift\n\t\t\tfi\n\t\t\t;;\n\t\t-a | --additional-flags)\n\t\t\tif [ -n \"$2\" ]; then\n\t\t\t\tcontainer_manager_additional_flags=\"${container_manager_additional_flags} ${2}\"\n\t\t\t\tshift\n\t\t\t\tshift\n\t\t\tfi\n\t\t\t;;\n\t\t-ap | --additional-packages)\n\t\t\tif [ -n \"$2\" ]; then\n\t\t\t\tcontainer_additional_packages=\"${container_additional_packages} ${2}\"\n\t\t\t\tshift\n\t\t\t\tshift\n\t\t\tfi\n\t\t\t;;\n\t\t--init-hooks)\n\t\t\tif [ -n \"$2\" ]; then\n\t\t\t\tcontainer_init_hook=\"$2\"\n\t\t\t\tshift\n\t\t\t\tshift\n\t\t\tfi\n\t\t\t;;\n\t\t--pre-init-hooks)\n\t\t\tif [ -n \"$2\" ]; then\n\t\t\t\tcontainer_pre_init_hook=\"${2}\"\n\t\t\t\tshift\n\t\t\t\tshift\n\t\t\tfi\n\t\t\t;;\n\t\t*) # Default case: If no more options then break out of the loop.\n\t\t\t# If we have a flagless option and container_name is not specified\n\t\t\t# then let's accept argument as container_name\n\t\t\tif [ -n \"$1\" ]; then\n\t\t\t\tcreate_flags=\"${create_flags} $1\"\n\t\t\t\tshift\n\t\t\telse\n\t\t\t\tbreak\n\t\t\tfi\n\t\t\t;;\n\tesac\ndone\n\nset -o nounset\n# set verbosity\nif [ \"${verbose}\" -ne 0 ]; then\n\tset -o xtrace\n\textra_flags=\"${extra_flags} --verbose\"\nfi\n\n# prepend sudo (or the specified sudo program) if we want our container manager to be rootful\nif [ \"${rootful}\" -ne 0 ]; then\n\textra_flags=\"${extra_flags} --root\"\nfi\n\n# generate_ephemeral_create_command will produce a distrobox-create command to execute.\n# Arguments:\n#   None\n# Expected global variables:\n#   distrobox_path = string distrobox path\n#   name         = string container name\n#   extra_flags  = string extra flags to inject\n#   create_flags = string create extra flags to inject\n# Expected env variables:\n#   None\n# Outputs:\n#   prints the distrobox-create command handling special flags\ngenerate_ephemeral_create_command()\n{\n\tresult_command=\"${distrobox_path}/distrobox-create\"\n\tif [ -n \"${container_manager_additional_flags}\" ]; then\n\t\tresult_command=\"${result_command} \\\n\t\t\t--additional-flags \\\"${container_manager_additional_flags}\\\"\"\n\tfi\n\tif [ -n \"${container_additional_packages}\" ]; then\n\t\tresult_command=\"${result_command} \\\n\t\t\t--additional-packages \\\"${container_additional_packages}\\\"\"\n\tfi\n\tif [ -n \"${container_init_hook}\" ]; then\n\t\tresult_command=\"${result_command} \\\n\t\t\t--init-hooks \\\"${container_init_hook}\\\"\"\n\tfi\n\tif [ -n \"${container_pre_init_hook}\" ]; then\n\t\tresult_command=\"${result_command} \\\n\t\t\t--pre-init-hooks \\\"${container_pre_init_hook}\\\"\"\n\tfi\n\tresult_command=\"${result_command} \\\n\t\t${extra_flags} ${create_flags} --yes --name ${name}\"\n\n\t# Return generated command.\n\tprintf \"%s\" \"${result_command}\"\n}\n\n# cleanup will ensure we remove the ephemeral container\n# Arguments:\n#   None\n# Expected global variables:\n#   name: string the name of the container\n#   extra_flags: string extra flags to append to the distrobox command\n#   distrobox_path: string path to the distrobox script\n# Expected env variables:\n#   None\n# Outputs:\n#   None\ncleanup()\n{\n\ttrap - TERM INT HUP\n\t# shellcheck disable=SC2086\n\t\"${distrobox_path}\"/distrobox-rm ${extra_flags} --force \"${name}\" --yes\n}\n\ncmd=\"$(generate_ephemeral_create_command)\"\n# shellcheck disable=SC2086\neval ${cmd}\n# shellcheck disable=SC2086\n\"${distrobox_path}\"/distrobox-enter ${extra_flags} \"${name}\" ${container_command}\nexit_code=\"$?\"\n\ncleanup\n\nexit \"${exit_code}\"\n"
  },
  {
    "path": "distrobox-export",
    "content": "#!/bin/sh\n# SPDX-License-Identifier: GPL-3.0-only\n#\n# This file is part of the distrobox project:\n#    https://github.com/89luca89/distrobox\n#\n# Copyright (C) 2021 distrobox contributors\n#\n# distrobox is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 3\n# as published by the Free Software Foundation.\n#\n# distrobox is distributed in the hope that it will be useful, but\n# WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n# General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with distrobox; if not, see <http://www.gnu.org/licenses/>.\n\n# POSIX\n# Expected env variables:\n#\tHOME\n#\tUSER\n#\tDISTROBOX_ENTER_PATH\n#\tDISTROBOX_HOST_HOME\n\n# Ensure we have our env variables correctly set\n[ -z \"${USER}\" ] && USER=\"$(id -run)\"\n[ -z \"${HOME}\" ] && HOME=\"$(getent passwd \"${USER}\" | cut -d':' -f6)\"\n[ -z \"${SHELL}\" ] && SHELL=\"$(getent passwd \"${USER}\" | cut -d':' -f7)\"\n\n# Defaults\ncontainer_name=\"${CONTAINER_ID:-}\"\n[ -z \"${container_name}\" ] && container_name=\"$(grep \"name=\" /run/.containerenv | cut -d'=' -f2- | tr -d '\"')\"\nexport_action=\"\"\nexported_app=\"\"\nexported_app_label=\"\"\nexported_bin=\"\"\nexported_delete=0\nextra_flags=\"\"\nenter_flags=\"\"\n# Use DBX_HOST_HOME if defined, else fallback to HOME\n#\tDBX_HOST_HOME is set in case container is created\n#\twith custom --home directory\nhost_home=\"${DISTROBOX_HOST_HOME:-\"${HOME}\"}\"\ndest_path=\"${DISTROBOX_EXPORT_PATH:-${host_home}/.local/bin}\"\nis_sudo=0\nrootful=\"\"\nsudo_prefix=\"\"\nverbose=0\nversion=\"1.8.2.4\"\n\nsudo_askpass_path=\"${dest_path}/distrobox_sudo_askpass\"\nsudo_askpass_script=\"#!/bin/sh\nif command -v zenity 2>&1 > /dev/null; then\n\tzenity --password\nelif command -v kdialog 2>&1 > /dev/null; then\n\tkdialog --password 'A password is required...'\nelse\n\texit 127\nfi\"\n\n# We depend on some commands, let's be sure we have them\nbase_dependencies=\"basename find grep sed\"\nfor dep in ${base_dependencies}; do\n\tif ! command -v \"${dep}\" > /dev/null; then\n\t\tprintf >&2 \"Missing dependency: %s\\n\" \"${dep}\"\n\t\texit 127\n\tfi\ndone\n\n# show_help will print usage to stdout.\n# Arguments:\n#   None\n# Expected global variables:\n#   version: distrobox version\n# Expected env variables:\n#   None\n# Outputs:\n#   print usage with examples.\nshow_help()\n{\n\tcat << EOF\ndistrobox version: ${version}\n\nUsage:\n\n\tdistrobox-export --app mpv [--extra-flags \"flags\"] [--enter-flags \"flags\"] [--delete] [--sudo]\n\tdistrobox-export --bin /path/to/bin [--export-path ~/.local/bin] [--extra-flags \"flags\"] [--enter-flags \"flags\"] [--delete] [--sudo]\n\nOptions:\n\n\t--app/-a:\t\tname of the application to export or absolute path to desktopfile to export\n\t--bin/-b:\t\tabsolute path of the binary to export\n\t--list-apps:\t\tlist applications exported from this container\n\t--list-binaries:\tlist binaries exported from this container, use -ep to specify custom paths to search\n\t--delete/-d:\t\tdelete exported application or binary\n\t--export-label/-el:\tlabel to add to exported application name.\n\t\t\t\tUse \"none\" to disable.\n\t\t\t\tDefaults to (on \\$container_name)\n\t--export-path/-ep:\tpath where to export the binary\n\t--extra-flags/-ef:\textra flags to add to the command\n\t--enter-flags/-nf:\tflags to add to distrobox-enter\n\t--sudo/-S:\t\tspecify if the exported item should be run as sudo\n\t--help/-h:\t\tshow this message\n\t--verbose/-v:\t\tshow more verbosity\n\t--version/-V:\t\tshow version\nEOF\n}\n\n# Parse arguments\nwhile :; do\n\tcase $1 in\n\t\t-h | --help)\n\t\t\t# Call a \"show_help\" function to display a synopsis, then exit.\n\t\t\tshow_help\n\t\t\texit 0\n\t\t\t;;\n\t\t-v | --verbose)\n\t\t\tshift\n\t\t\tverbose=1\n\t\t\t;;\n\t\t-V | --version)\n\t\t\tprintf \"distrobox: %s\\n\" \"${version}\"\n\t\t\texit 0\n\t\t\t;;\n\t\t-a | --app)\n\t\t\tif [ -n \"$2\" ]; then\n\t\t\t\texport_action=\"app\"\n\t\t\t\texported_app=\"$2\"\n\t\t\t\tshift\n\t\t\t\tshift\n\t\t\tfi\n\t\t\t;;\n\t\t-b | --bin)\n\t\t\tif [ -n \"$2\" ]; then\n\t\t\t\texport_action=\"bin\"\n\t\t\t\texported_bin=\"$2\"\n\t\t\t\tshift\n\t\t\t\tshift\n\t\t\tfi\n\t\t\t;;\n\t\t--list-apps)\n\t\t\texport_action=\"list-apps\"\n\t\t\texported_bin=\"null\"\n\t\t\tshift\n\t\t\t;;\n\t\t--list-binaries)\n\t\t\texport_action=\"list-binaries\"\n\t\t\texported_bin=\"null\"\n\t\t\tshift\n\t\t\t;;\n\t\t-S | --sudo)\n\t\t\tis_sudo=1\n\t\t\tshift\n\t\t\t;;\n\t\t-el | --export-label)\n\t\t\tif [ -n \"$2\" ]; then\n\t\t\t\texported_app_label=\"$2\"\n\t\t\t\tshift\n\t\t\t\tshift\n\t\t\tfi\n\t\t\t;;\n\t\t-ep | --export-path)\n\t\t\tif [ -n \"$2\" ]; then\n\t\t\t\tdest_path=\"$2\"\n\t\t\t\tshift\n\t\t\t\tshift\n\t\t\tfi\n\t\t\t;;\n\t\t-ef | --extra-flags)\n\t\t\tif [ -n \"$2\" ]; then\n\t\t\t\textra_flags=\"$2\"\n\t\t\t\tshift\n\t\t\t\tshift\n\t\t\tfi\n\t\t\t;;\n\t\t-nf | --enter-flags)\n\t\t\tif [ -n \"$2\" ]; then\n\t\t\t\tenter_flags=\"$2\"\n\t\t\t\tshift\n\t\t\t\tshift\n\t\t\tfi\n\t\t\t;;\n\t\t-d | --delete)\n\t\t\texported_delete=1\n\t\t\tshift\n\t\t\t;;\n\t\t-*) # Invalid options.\n\t\t\tprintf >&2 \"ERROR: Invalid flag '%s'\\n\\n\" \"$1\"\n\t\t\tshow_help\n\t\t\texit 1\n\t\t\t;;\n\t\t*) # Default case: If no more options then break out of the loop.\n\t\t\tbreak ;;\n\tesac\ndone\n\nset -o errexit\nset -o nounset\n# set verbosity\nif [ \"${verbose}\" -ne 0 ]; then\n\tset -o xtrace\nfi\n\n# Ensure we can write stuff there\nif [ ! -e \"${dest_path}\" ]; then\n\tmkdir -p \"${dest_path}\"\nfi\n\n# Check we're running inside a container and not on the host.\nif [ ! -f /run/.containerenv ] && [ ! -f /.dockerenv ] && [ -z \"${container:-}\" ]; then\n\tprintf >&2 \"You must run %s inside a container!\\n\" \" $(basename \"$0\")\"\n\texit 126\nfi\n\n# Check if we're in a rootful or rootless container.\nif grep -q \"rootless=0\" /run/.containerenv 2> /dev/null; then\n\trootful=\"--root\"\n\n\t# We need an askpass script for SUDO_ASKPASS, to launch graphical apps\n\t# from the drawer\n\tif [ ! -e \"${sudo_askpass_path}\" ]; then\n\t\techo \"${sudo_askpass_script}\" > \"${sudo_askpass_path}\"\n\t\tchmod +x \"${sudo_askpass_path}\"\n\tfi\nfi\n\n# We're working with HOME, so we must run as USER, not as root.\nif [ \"$(id -u)\" -eq 0 ]; then\n\tprintf >&2 \"You must not run %s as root!\\n\" \" $(basename \"$0\")\"\n\texit 1\nfi\n\n# Ensure we're not receiving more than one action at time.\nif [ -n \"${exported_app}\" ] && [ -n \"${exported_bin}\" ]; then\n\tprintf >&2 \"Error: Invalid arguments, choose only one action below.\\n\"\n\tprintf >&2 \"Error: You can only export one thing at time.\\n\"\n\texit 2\nfi\n\n# Filter enter_flags and remove redundant options\nif [ -n \"${enter_flags}\" ]; then\n\t# shellcheck disable=SC2086\n\tset -- ${enter_flags}\n\tfiltered_flags=\"\"\n\t# Inform user that certain flags are redundant\n\twhile [ $# -gt 0 ]; do\n\t\tcase \"$1\" in\n\t\t\t--root | -r)\n\t\t\t\tprintf >&2 \"Warning: %s argument will be set automatically and should be removed.\\n\" \"${1}\"\n\t\t\t\t;;\n\t\t\t--name | -n)\n\t\t\t\tprintf >&2 \"Warning: %s argument will be set automatically and should be removed.\\n\" \"${1}\"\n\t\t\t\tshift\n\t\t\t\t;;\n\t\t\t*)\n\t\t\t\tfiltered_flags=\"${filtered_flags} $1\"\n\t\t\t\t;;\n\t\tesac\n\t\tshift\n\tdone\n\tenter_flags=\"${filtered_flags}\"\nfi\n\n# Command to execute\ncontainer_command_suffix=\"'${exported_bin}' ${extra_flags} \\\"\\$@\\\"\"\n\n# Check if exported application/binary should be run with sudo privileges\nif [ \"${is_sudo}\" -ne 0 ]; then\n\tsudo_prefix=\"sudo -S\"\n\tif ! ${sudo_prefix} test > /dev/null 2>&1; then\n\t\tsudo_prefix=\"sudo\"\n\tfi\n\n\t# Edge case for systems with doas\n\tif command -v doas > /dev/null >&1; then\n\t\tsudo_prefix=\"doas\"\n\t\tcontainer_command_suffix=\"sh -l -c \\\"'${exported_bin}' ${extra_flags} \\$@\\\"\"\n\tfi\n\n\t# Edge case for systems without sudo\n\tif command -v su-exec > /dev/null >&1; then\n\t\tsudo_prefix=\"su-exec root\"\n\t\tcontainer_command_suffix=\"sh -l -c \\\"'${exported_bin}' ${extra_flags} \\$@\\\"\"\n\tfi\nfi\n\n# Prefix to add to an existing command to work through the container\ncontainer_command_prefix=\"${DISTROBOX_ENTER_PATH:-\"distrobox-enter\"} ${rootful} -n ${container_name} ${enter_flags} -- ${sudo_prefix} \"\n\nif [ -n \"${rootful}\" ]; then\n\tcontainer_command_prefix=\"env SUDO_ASKPASS=\\\"${sudo_askpass_path}\\\" DBX_SUDO_PROGRAM=\\\"sudo --askpass\\\" ${container_command_prefix}\"\nfi\n\nif [ -z \"${exported_app_label}\" ]; then\n\texported_app_label=\" (on ${container_name})\"\nelif [ \"${exported_app_label}\" = \"none\" ]; then\n\texported_app_label=\"\"\nelse\n\t# Add a leading space so that we can have \"NAME LABEL\" in the entry\n\texported_app_label=\" ${exported_app_label}\"\nfi\n\n# generate_script will generate a script from template. This script will wrap the\n# exported binary in order to ensure it will be executed in the right container.\n# Arguments:\n#\tNone\n# Expected global variables:\n#   CONTAINER_ID: id of the current container\n#   container_command_suffix: string to postpone to the command to launch\n#   container_name:  string name of this container\n#   dest_path: string path where to export the binary\n#   enter_flags:  string extra flags to append to the distrobox enter command\n#   exported_bin: string path to the binary to export\n#   exported_delete: bool delete the binary exported\n#   extra_flags:  string extra flags to append to the exported app command\n#   rootful: bool if this is a rootful container\n#   sudo_prefix: string sudo command to prepend to the exported command\n# Expected env variables:\n#   None\n# Outputs:\n#\tprint generated script.\ngenerate_script()\n{\n\tcat << EOF\n#!/bin/sh\n# distrobox_binary\n# name: ${container_name}\nif [ -z \"\\${CONTAINER_ID}\" ]; then\n\texec \"${DISTROBOX_ENTER_PATH:-\"distrobox-enter\"}\" ${rootful} -n ${container_name} ${enter_flags} -- ${sudo_prefix} ${container_command_suffix}\nelif [ -n \"\\${CONTAINER_ID}\" ] && [ \"\\${CONTAINER_ID}\" != \"${container_name}\" ]; then\n\texec distrobox-host-exec '${dest_path}/$(basename \"${exported_bin}\")' \"\\$@\"\nelse\n\texec ${sudo_prefix} '${exported_bin}' \"\\$@\"\nfi\nEOF\n\treturn $?\n}\n\n# export_binary will export selected binary to destination directory.\n# the following function will use generate_script to create a shell script in\n# dest_path that will execute the exported binary in the selected distrobox.\n#\n# Arguments:\n#\tNone\n# Expected global variables:\n#   CONTAINER_ID: id of the current container\n#   container_name: string name of this container\n#   dest_path: string path where to export the binary\n#   exported_bin: string path to the binary to export\n#   exported_delete: bool delete the binary exported\n# Expected env variables:\n#   None\n# Outputs:\n#\ta generated_script in dest_path\n#\tor error code.\nexport_binary()\n{\n\t# Ensure the binary we're exporting is installed\n\tif [ ! -f \"${exported_bin}\" ]; then\n\t\tprintf >&2 \"Error: cannot find %s.\\n\" \"${exported_bin}\"\n\t\treturn 127\n\tfi\n\t# generate dest_file path\n\tdest_file=\"${dest_path}/$(basename \"${exported_bin}\")\"\n\n\t# create the binary destination path if it doesn't exist\n\tmkdir -p \"${dest_path}\"\n\n\t# If we're deleting it, just do it and exit\n\tif [ \"${exported_delete}\" -ne 0 ]; then\n\t\t# ensure it's a distrobox exported binary\n\t\tif ! grep -q \"distrobox_binary\" \"${dest_file}\"; then\n\t\t\tprintf >&2 \"Error: %s is not exported.\\n\" \"${exported_bin}\"\n\t\t\treturn 1\n\t\tfi\n\n\t\tif rm -f \"${dest_file}\"; then\n\t\t\tprintf \"%s from %s removed successfully from %s.\\nOK!\\n\" \\\n\t\t\t\t\"${exported_bin}\" \"${container_name}\" \"${dest_path}\"\n\t\t\treturn 0\n\t\tfi\n\t\treturn 1\n\tfi\n\n\t# test if we have writing rights on the file\n\tif ! touch \"${dest_file}\"; then\n\t\tprintf >&2 \"Error: cannot create destination file %s.\\n\" \"${dest_file}\"\n\t\treturn 1\n\tfi\n\n\t# create the script from template and write to file\n\tif generate_script > \"${dest_file}\"; then\n\t\tchmod +x \"${dest_file}\"\n\t\tprintf \"%s from %s exported successfully in %s.\\nOK!\\n\" \\\n\t\t\t\"${exported_bin}\" \"${container_name}\" \"${dest_path}\"\n\t\treturn 0\n\tfi\n\t# Unknown error.\n\treturn 3\n}\n\n# export_application will export input graphical application to the host.\n# the following function will scan the distrobox for desktop and icon files for\n# the selected application. It will then put the needed icons in the host's icons\n# directory and create a new .desktop file that will execute the selected application\n# in the distrobox.\n#\n# Arguments:\n#\tNone\n# Expected global variables:\n#   CONTAINER_ID: id of the current container\n#   container_command_prefix: string to prepend to the command to launch\n#   container_name:  string name of this container\n#   exported_app:   string name of the app to export\n#   exported_app_label: string label to use to mark the exported app\n#   exported_delete:  bool if we want to delete or not\n#   extra_flags:  string extra flags to append to the exported app command\n#   host_home: home path ofr the host, where to search desktop files\n# Expected env variables:\n#   None\n# Outputs:\n#\tneeded icons in /run/host/$host_home/.local/share/icons\n#\tneeded desktop files in /run/host/$host_home/.local/share/applications\n#\tor error code.\nexport_application()\n{\n\tcanon_dirs=\"\"\n\n\t# In case we're explicitly going for a full desktopfile path\n\tif [ -e \"${exported_app}\" ]; then\n\t\tdesktop_files=\"${exported_app}\"\n\telse\n\t\tIFS=\":\"\n\t\tif [ -n \"${XDG_DATA_DIRS}\" ]; then\n\t\t\tfor xdg_data_dir in ${XDG_DATA_DIRS}; do\n\t\t\t\t[ -d \"${xdg_data_dir}/applications\" ] && canon_dirs=\"${canon_dirs} ${xdg_data_dir}/applications\"\n\t\t\tdone\n\t\telse\n\t\t\t[ -d /usr/share/applications ] && canon_dirs=\"/usr/share/applications\"\n\t\t\t[ -d /usr/local/share/applications ] && canon_dirs=\"${canon_dirs} /usr/local/share/applications\"\n\t\t\t[ -d /var/lib/flatpak/exports/share/applications ] && canon_dirs=\"${canon_dirs} /var/lib/flatpak/exports/share/applications\"\n\t\tfi\n\t\tif [ -n \"${XDG_DATA_HOME}\" ]; then\n\t\t\t[ -d \"${XDG_DATA_HOME}/applications\" ] && canon_dirs=\"${canon_dirs} ${XDG_DATA_HOME}/applications\"\n\t\telse\n\t\t\t[ -d \"${HOME}/.local/share/applications\" ] && canon_dirs=\"${canon_dirs} ${HOME}/.local/share/applications\"\n\t\tfi\n\t\tunset IFS\n\n\t\t# In this phase we search for applications to export.\n\t\t# First find command will grep through all files in the canonical directories\n\t\t# and only list files that contain the $exported_app, excluding those that\n\t\t# already contains a distrobox-enter command. So skipping already exported apps.\n\t\t# Second find will list all files that contain the name specified, so that\n\t\t# it is possible to export an app not only by its executable name but also\n\t\t# by its launcher name.\n\t\tdesktop_files=$(\n\t\t\t# shellcheck disable=SC2086\n\t\t\tfind ${canon_dirs} -type f -print -o -type l -print | sed 's/./\\\\&/g' |\n\t\t\t\txargs -I{} grep -l -e \"Exec=.*${exported_app}.*\" -e \"Name=.*${exported_app}.*\" \"{}\" | sed 's/./\\\\&/g' |\n\t\t\t\txargs -I{} grep -L -e \"Exec=.*${DISTROBOX_ENTER_PATH:-\"distrobox.*enter\"}.*\" \"{}\" | sed 's/./\\\\&/g' |\n\t\t\t\txargs -I{} printf \"%s¤\" \"{}\"\n\t\t)\n\tfi\n\n\t# Ensure the app we're exporting is installed\n\t# Check that we found some desktop files first.\n\tif [ -z \"${desktop_files}\" ]; then\n\t\tprintf >&2 \"Error: cannot find any desktop files.\\n\"\n\t\tprintf >&2 \"Error: trying to export a non-installed application.\\n\"\n\t\treturn 127\n\tfi\n\n\t# Find icons by using the Icon= specification. If it's only a name, we'll\n\t# search for the file, if it's already a path, just grab it.\n\ticon_files=\"\"\n\tIFS=\"¤\"\n\tfor desktop_file in ${desktop_files}; do\n\t\tif [ -z \"${desktop_file}\" ]; then\n\t\t\tcontinue\n\t\tfi\n\n\t\ticon_name=\"$(grep Icon= \"${desktop_file}\" | cut -d'=' -f2- | paste -sd \"¤\" -)\"\n\n\t\tfor icon in ${icon_name}; do\n\t\t\tif case \"${icon_name}\" in \"/\"*) true ;; *) false ;; esac &&\n\t\t\t\t[ -e \"${icon_name}\" ]; then\n\t\t\t\t# In case it's an hard path, conserve it and continue\n\t\t\t\ticon_files=\"${icon_files}¤${icon_name}\"\n\t\t\telse\n\t\t\t\t# If it's not an hard path, find all files in the canonical paths.\n\t\t\t\ticon_files=\"${icon_files}¤$(find \\\n\t\t\t\t\t/usr/share/icons \\\n\t\t\t\t\t/usr/share/pixmaps \\\n\t\t\t\t\t/var/lib/flatpak/exports/share/icons -iname \"*${icon}*\" \\\n\t\t\t\t\t-printf \"%p¤\" 2> /dev/null || :)\"\n\t\t\tfi\n\t\tdone\n\n\t\t# remove leading delimiter\n\t\ticon_files=${icon_files#¤}\n\tdone\n\n\t# create applications dir if not existing\n\tmkdir -p \"/run/host${host_home}/.local/share/applications\"\n\n\t# copy icons in home directory\n\ticon_file_absolute_path=\"\"\n\tIFS=\"¤\"\n\tfor icon_file in ${icon_files}; do\n\t\tif [ -z \"${icon_file}\" ]; then\n\t\t\tcontinue\n\t\tfi\n\n\t\t# replace canonical paths with equivalent paths in HOME\n\t\ticon_home_directory=\"$(dirname \"${icon_file}\" |\n\t\t\tsed \"s|/usr/share/|\\/run\\/host\\/${host_home}/.local/share/|g\" |\n\t\t\tsed \"s|/var/lib/flatpak/exports/share|\\/run\\/host\\/${host_home}/.local/share/|g\" |\n\t\t\tsed \"s|pixmaps|icons|g\")\"\n\n\t\t# check if we're exporting an icon which is not in a canonical path\n\t\tif [ \"${icon_home_directory}\" = \"$(dirname \"${icon_file}\")\" ]; then\n\t\t\ticon_home_directory=\"${host_home}/.local/share/icons/\"\n\t\t\ticon_file_absolute_path=\"${icon_home_directory}$(basename \"${icon_file}\")\"\n\t\tfi\n\n\t\t# check if we're exporting or deleting\n\t\tif [ \"${exported_delete}\" -ne 0 ]; then\n\t\t\t# we need to remove, not export\n\t\t\trm -rf \"${icon_home_directory:?}\"/\"$(basename \"${icon_file:?}\")\"\n\t\t\tcontinue\n\t\tfi\n\n\t\t# we wanto to export the application's icons\n\t\tmkdir -p \"${icon_home_directory}\"\n\t\tif [ ! -e \"${icon_home_directory}/$(basename \"${icon_file}\")\" ] && [ -e \"$(realpath \"${icon_file}\")\" ]; then\n\t\t\tcp -rf \"$(realpath \"${icon_file}\")\" \"${icon_home_directory}\"\n\t\tfi\n\tdone\n\n\t# create desktop files for the distrobox\n\tIFS=\"¤\"\n\tfor desktop_file in ${desktop_files}; do\n\t\tif [ -z \"${desktop_file}\" ]; then\n\t\t\tcontinue\n\t\tfi\n\n\t\tdesktop_original_file=\"$(basename \"${desktop_file}\")\"\n\t\tdesktop_home_file=\"${container_name}-$(basename \"${desktop_file}\")\"\n\n\t\t# check if we're exporting or deleting\n\t\tif [ \"${exported_delete}\" -ne 0 ]; then\n\t\t\trm -f \"/run/host${host_home}/.local/share/applications/${desktop_original_file}\"\n\t\t\trm -f \"/run/host${host_home}/.local/share/applications/${desktop_home_file}\"\n\t\t\t# we're done, go to next\n\t\t\tcontinue\n\t\tfi\n\n\t\t# Add command_prefix\n\t\t# Add extra flags\n\t\t# Add closing quote\n\t\t# If a TryExec is present, we have to fake it as it will not work\n\t\t# through the container separation\n\t\tsed \"s|^Exec=\\(.*\\)|Exec=${container_command_prefix} \\1 |g\" \"${desktop_file}\" |\n\t\t\tsed \"s|\\(%.*\\)|${extra_flags} \\1|g\" |\n\t\t\tsed \"/^TryExec=.*/d\" |\n\t\t\tsed \"/^DBusActivatable=true/d\" |\n\t\t\tsed \"s|Name.*|&${exported_app_label}|g\" \\\n\t\t\t\t> \"/run/host${host_home}/.local/share/applications/${desktop_home_file}\"\n\t\t# in the end we add the final quote we've opened in the \"container_command_prefix\"\n\n\t\tif ! grep -q \"StartupWMClass\" \"/run/host${host_home}/.local/share/applications/${desktop_home_file}\"; then\n\t\t\tprintf \"StartupWMClass=%s\\n\" \"${exported_app}\" >> \"\\\n/run/host${host_home}/.local/share/applications/${desktop_home_file}\"\n\t\tfi\n\t\t# In case of an icon in a non canonical path, we need to replace the path\n\t\t# in the desktop file.\n\t\tif [ -n \"${icon_file_absolute_path}\" ]; then\n\t\t\tsed -i \"s|Icon=.*|Icon=${icon_file_absolute_path}|g\" \\\n\t\t\t\t\"/run/host${host_home}/.local/share/applications/${desktop_home_file}\"\n\t\t\t# we're done, go to next\n\t\t\tcontinue\n\t\tfi\n\n\t\t# In case of an icon in a canonical path, but specified as an absolute\n\t\t# we need to replace the path in the desktop file.\n\t\tsed -i \"s|Icon=/usr/share/|Icon=/run/host${host_home}/.local/share/|g\" \\\n\t\t\t\"/run/host${host_home}/.local/share/applications/${desktop_home_file}\"\n\t\tsed -i \"s|pixmaps|icons|g\" \\\n\t\t\t\"/run/host${host_home}/.local/share/applications/${desktop_home_file}\"\n\tdone\n\n\t# Update the desktop files database to ensure exported applications will\n\t# show up in the taskbar/desktop menu/whatnot right after running this\n\t# script.\n\t/usr/bin/distrobox-host-exec --yes update-desktop-database \"${host_home}/.local/share/applications\" > /dev/null 2>&1 || :\n\n\tif [ \"${exported_delete}\" -ne 0 ]; then\n\t\tprintf \"Application %s successfully un-exported.\\nOK!\\n\" \"${exported_app}\"\n\t\tprintf \"%s will disappear from your applications list in a few seconds.\\n\" \"${exported_app}\"\n\telse\n\t\tprintf \"Application %s successfully exported.\\nOK!\\n\" \"${exported_app}\"\n\t\tprintf \"%s will appear in your applications list in a few seconds.\\n\" \"${exported_app}\"\n\tfi\n}\n\n# list_exported_applications will print all exported applications in canonical directories.\n# the following function will list exported desktop files from this container.\n#\n# Arguments:\n#\tNone\n# Expected global variables:\n#   host_home: home path ofr the host, where to search desktop files\n#   CONTAINER_ID: id of the current container\n# Expected env variables:\n#   None\n# Outputs:\n#\ta list of exported apps\n#\tor error code.\nlist_exported_applications()\n{\n\t# In this phase we search for applications exported.\n\t# First find command will grep through all files in the canonical directories\n\t# and only list files that contain the $DISTROBOX_ENTER_PATH.\n\tdesktop_files=$(\n\t\t# shellcheck disable=SC2086\n\t\tfind \"/run/host${host_home}/.local/share/applications\" -type f -print -o -type l -print 2> /dev/null | sed 's/./\\\\&/g' |\n\t\t\txargs -I{} grep -l -e \"Exec=.*${DISTROBOX_ENTER_PATH:-\"distrobox.*enter\"}.*\" \"{}\" | sed 's/./\\\\&/g' |\n\t\t\txargs -I{} printf \"%s¤\" \"{}\"\n\t)\n\n\t# Then we try to pretty print them.\n\tIFS=\"¤\"\n\tfor i in ${desktop_files}; do\n\t\tif [ -z \"${i}\" ]; then\n\t\t\tcontinue\n\t\tfi\n\t\t# Get app name, and remove label\n\t\tname=\"$(grep -Eo 'Name=.*' \"${i}\" | head -n 1 | cut -d'=' -f2- | sed 's|(.*)||g')\"\n\t\t# Print only stuff we exported from this box!\n\t\tif echo \"${i}\" | grep -q \"${CONTAINER_ID}\"; then\n\t\t\tprintf \"%-20s | %-30s\\n\" \"${name}\" \"${i}\"\n\t\tfi\n\tdone\n\tunset IFS\n}\n\n# list_exported_binaries will print all exported binaries.\n# the following function will list exported desktop files from this container.\n# If no export-path is specified, it searches in the default path.\n#\n# Arguments:\n#\tNone\n# Expected global variables:\n#   dest_path: destination path where to search binaries\n#   CONTAINER_ID: id of the current container\n# Expected env variables:\n#\tNone\n# Outputs:\n#\ta list of exported apps\n#\tor error code.\nlist_exported_binaries()\n{\n\t# In this phase we search for binaries exported.\n\t# First find command will grep through all files in the canonical directories\n\t# and only list files that contain the comment \"# distrobox_binary\".\n\tbinary_files=$(\n\t\tfind \"${dest_path}\" -type f -print 2> /dev/null | sed 's/./\\\\&/g' |\n\t\t\txargs -I{} grep -l -e \"^# distrobox_binary\" \"{}\" | sed 's/./\\\\&/g' |\n\t\t\txargs -I{} printf \"%s¤\" \"{}\"\n\t)\n\n\t# Then we try to pretty print them.\n\tIFS=\"¤\"\n\tfor i in ${binary_files}; do\n\t\tif [ -z \"${i}\" ]; then\n\t\t\tcontinue\n\t\tfi\n\t\t# Get original binary name\n\t\tname=\"$(grep -B1 \"fi\" \"${i}\" | grep exec | cut -d' ' -f2)\"\n\t\t# Print only stuff we exported from this box!\n\t\tif grep \"^# name:.*\" \"${i}\" | grep -q \"${CONTAINER_ID}\"; then\n\t\t\tprintf \"%-20s | %-30s\\n\" \"${name}\" \"${i}\"\n\t\tfi\n\tdone\n\tunset IFS\n}\n\n# Main routine\ncase \"${export_action}\" in\n\tapp)\n\t\texport_application\n\t\t;;\n\tbin)\n\t\texport_binary\n\t\t;;\n\tlist-apps)\n\t\tlist_exported_applications\n\t\t;;\n\tlist-binaries)\n\t\tlist_exported_binaries\n\t\t;;\n\t*)\n\t\tprintf >&2 \"Invalid arguments, choose an action below.\\n\"\n\t\tshow_help\n\t\texit 2\n\t\t;;\nesac\n"
  },
  {
    "path": "distrobox-generate-entry",
    "content": "#!/bin/sh\n# SPDX-License-Identifier: GPL-3.0-only\n#\n# This file is part of the distrobox project:\n#    https://github.com/89luca89/distrobox\n#\n# Copyright (C) 2021 distrobox contributors\n#\n# distrobox is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 3\n# as published by the Free Software Foundation.\n#\n# distrobox is distributed in the hope that it will be useful, but\n# WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n# General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with distrobox; if not, see <http://www.gnu.org/licenses/>.\n\n# POSIX\n# Optional env variables:\n#\tDBX_CONTAINER_MANAGER\n#\tDBX_VERBOSE\n\n# Despite of running this script via SUDO/DOAS being not supported (the\n# script itself will call the appropriate tool when necessary), we still want\n# to allow people to run it as root, logged in in a shell, and create rootful\n# containers.\n#\n# SUDO_USER is a variable set by SUDO and can be used to check whether the script was called by it. Same thing for DOAS_USER, set by DOAS.\nif {\n\t[ -n \"${SUDO_USER}\" ] || [ -n \"${DOAS_USER}\" ]\n} && [ \"$(id -ru)\" -eq 0 ]; then\n\tprintf >&2 \"Running %s via SUDO/DOAS is not supported. Instead, please try running:\\n\" \"$(basename \"${0}\")\"\n\tprintf >&2 \"  %s --root %s\\n\" \"$(basename \"${0}\")\" \"$*\"\n\texit 1\nfi\n\n# Ensure we have our env variables correctly set\n[ -z \"${USER}\" ] && USER=\"$(id -run)\"\n[ -z \"${HOME}\" ] && HOME=\"$(getent passwd \"${USER}\" | cut -d':' -f6)\"\n[ -z \"${SHELL}\" ] && SHELL=\"$(getent passwd \"${USER}\" | cut -d':' -f7)\"\n\n# If the user runs this script as root in a login shell, set rootful=1.\n# There's no need for them to pass the --root flag option in such cases.\n[ \"$(id -ru)\" -eq 0 ] && rootful=1 || rootful=0\nextra_flags=\"\"\nall=0\ncontainer_manager=\"autodetect\"\ncontainer_name_default=\"my-distrobox\"\ndelete=0\nicon=\"auto\"\nicon_default=\"${XDG_DATA_HOME:-${HOME}/.local/share}/icons/terminal-distrobox-icon.svg\"\nverbose=0\nonline=0\nversion=\"1.8.2.4\"\n\n# Source configuration files, this is done in an hierarchy so local files have\n# priority over system defaults\n# leave priority to environment variables.\n#\n# On NixOS, for the distrobox derivation to pick up a static config file shipped\n# by the package maintainer the path must be relative to the script itself.\nself_dir=\"$(dirname \"$(realpath \"$0\")\")\"\nnix_config_file=\"${self_dir}/../share/distrobox/distrobox.conf\"\n\nconfig_files=\"\n\t${nix_config_file}\n\t/usr/share/distrobox/distrobox.conf\n\t/usr/share/defaults/distrobox/distrobox.conf\n\t/usr/etc/distrobox/distrobox.conf\n\t/usr/local/share/distrobox/distrobox.conf\n\t/etc/distrobox/distrobox.conf\n\t${XDG_CONFIG_HOME:-\"${HOME}/.config\"}/distrobox/distrobox.conf\n\t${HOME}/.distroboxrc\n\"\nfor config_file in ${config_files}; do\n\t# Shellcheck will give error for sourcing a variable file as it cannot follow\n\t# it. We don't care so let's disable this linting for now.\n\t# shellcheck disable=SC1090\n\t[ -e \"${config_file}\" ] && . \"$(realpath \"${config_file}\")\"\ndone\n\n[ -n \"${DBX_CONTAINER_MANAGER}\" ] && container_manager=\"${DBX_CONTAINER_MANAGER}\"\n[ -n \"${DBX_VERBOSE}\" ] && verbose=\"${DBX_VERBOSE}\"\n\n# Fixup variable=[true|false], in case we find it in the config file(s)\n[ \"${verbose}\" = \"true\" ] && verbose=1\n[ \"${verbose}\" = \"false\" ] && verbose=0\n\n# show_help will print usage to stdout.\n# Arguments:\n#   None\n# Expected global variables:\n#   version: distrobox version\n# Expected env variables:\n#   None\n# Outputs:\n#   print usage with examples.\nshow_help()\n{\n\tcat << EOF\ndistrobox version: ${version}\n\nUsage:\n\n\tdistrobox-generate-entry container-name [--delete] [--icon [auto,/path/to/icon]]\n\nOptions:\n\n\t--help/-h:\t\tshow this message\n\t--all/-a:\t\tperform for all distroboxes\n\t--delete/-d:\t\tdelete the entry\n\t--icon/-i:\t\tspecify a custom icon [/path/to/icon] (default auto)\n\t--root/-r:\t\tperform on rootful distroboxes\n\t--verbose/-v:\t\tshow more verbosity\n\t--version/-V:\t\tshow version\nEOF\n}\n\n# Parse arguments\nwhile :; do\n\tcase $1 in\n\t\t-h | --help)\n\t\t\t# Call a \"show_help\" function to display a synopsis, then exit.\n\t\t\tshow_help\n\t\t\texit 0\n\t\t\t;;\n\t\t-v | --verbose)\n\t\t\tverbose=1\n\t\t\tshift\n\t\t\t;;\n\t\t-V | --version)\n\t\t\tprintf \"distrobox: %s\\n\" \"${version}\"\n\t\t\texit 0\n\t\t\t;;\n\t\t-d | --delete)\n\t\t\tdelete=1\n\t\t\tshift\n\t\t\t;;\n\t\t-a | --all)\n\t\t\tall=1\n\t\t\tshift\n\t\t\t;;\n\t\t-i | --icon)\n\t\t\tif [ -n \"$2\" ]; then\n\t\t\t\ticon=\"$2\"\n\t\t\t\tshift\n\t\t\t\tshift\n\t\t\tfi\n\t\t\t;;\n\t\t-r | --root)\n\t\t\tshift\n\t\t\trootful=1\n\t\t\t;;\n\t\t--) # End of all options.\n\t\t\tshift\n\t\t\tbreak\n\t\t\t;;\n\t\t-*) # Invalid options.\n\t\t\tprintf >&2 \"ERROR: Invalid flag '%s'\\n\\n\" \"$1\"\n\t\t\tshow_help\n\t\t\texit 1\n\t\t\t;;\n\t\t*) # Default case: If no more options then break out of the loop.\n\t\t\t# If we have a flagless option and container_name is not specified\n\t\t\t# then let's accept argument as container_name\n\t\t\tif [ -n \"$1\" ]; then\n\t\t\t\tcontainer_name=\"$1\"\n\t\t\t\tshift\n\t\t\telse\n\t\t\t\tbreak\n\t\t\tfi\n\t\t\t;;\n\tesac\ndone\n\nset -o errexit\nset -o nounset\n# set verbosity\nif [ \"${verbose}\" -ne 0 ]; then\n\tset -o xtrace\nfi\n\nif [ -z \"${container_name:-}\" ]; then\n\tcontainer_name=\"${container_name_default}\"\nfi\n\nif [ \"${all}\" -ne 0 ]; then\n\tcontainer_names=\"$(distrobox list --no-color | tail -n +2 | cut -d'|' -f2 | tr -d ' ')\"\n\tfor container_name in ${container_names}; do\n\t\tif [ \"${delete}\" -ne 0 ]; then\n\t\t\t\"${0}\" \"${container_name}\" --delete\n\t\t\tcontinue\n\t\tfi\n\t\t\"${0}\" \"${container_name}\"\n\tdone\n\texit\nfi\n\n# If we delete, just ask confirmation and exit.\nif [ \"${delete}\" -ne 0 ]; then\n\trm -f \"${XDG_DATA_HOME:-${HOME}/.local/share}/applications/${container_name}.desktop\"\n\texit\nfi\n\nif ! command -v curl > /dev/null && ! command -v wget > /dev/null; then\n\tprintf >&2 \"Icon generation depends on either curl or wget\\n\"\n\tprintf >&2 \"Fallbacking to default icon.\\n\"\n\tdownload=\"null\"\nfi\n\nif command -v curl > /dev/null 2>&1; then\n\tdownload=\"curl --connect-timeout 3 --retry 1 -sLo\"\nelif command -v wget > /dev/null 2>&1; then\n\tdownload=\"wget --timeout=3 --tries=1 -qO\"\nfi\n\n# We depend on a container manager let's be sure we have it\n# First we use podman, else docker, else lilipod\ncase \"${container_manager}\" in\n\tautodetect)\n\t\tif command -v podman > /dev/null; then\n\t\t\tcontainer_manager=\"podman\"\n\t\t\tcontainer_manager_cp_command=\"podman cp\"\n\t\telif command -v podman-launcher > /dev/null; then\n\t\t\tcontainer_manager=\"podman-launcher\"\n\t\t\tcontainer_manager_cp_command=\"podman-launcher cp\"\n\t\telif command -v docker > /dev/null; then\n\t\t\tcontainer_manager=\"docker\"\n\t\t\tcontainer_manager_cp_command=\"docker cp -L\"\n\t\telif command -v lilipod > /dev/null; then\n\t\t\tcontainer_manager=\"lilipod\"\n\t\t\tcontainer_manager_cp_command=\"lilipod cp\"\n\t\tfi\n\t\t;;\n\tpodman)\n\t\tcontainer_manager=\"podman\"\n\t\tcontainer_manager_cp_command=\"podman cp\"\n\t\t;;\n\tpodman-launcher)\n\t\tcontainer_manager=\"podman-launcher\"\n\t\tcontainer_manager_cp_command=\"podman-launcher cp\"\n\t\t;;\n\tlilipod)\n\t\tcontainer_manager=\"lilipod\"\n\t\tcontainer_manager_cp_command=\"lilipod cp\"\n\t\t;;\n\tdocker)\n\t\tcontainer_manager=\"docker\"\n\t\tcontainer_manager_cp_command=\"docker cp -L\"\n\t\t;;\n\t*)\n\t\tprintf >&2 \"Invalid input %s.\\n\" \"${container_manager}\"\n\t\tprintf >&2 \"The available choices are: 'autodetect', 'podman', 'docker', 'lilipod'\\n\"\n\t\t;;\nesac\n\n# Be sure we have a container manager to work with.\nif ! command -v \"${container_manager}\" > /dev/null; then\n\t# Error: we need at least one between docker, podman or lilipod.\n\tprintf >&2 \"Missing dependency: we need a container manager.\\n\"\n\tprintf >&2 \"Please install one of podman,  docker or lilipod.\\n\"\n\tprintf >&2 \"You can follow the documentation on:\\n\"\n\tprintf >&2 \"\\tman distrobox-compatibility\\n\"\n\tprintf >&2 \"or:\\n\"\n\tprintf >&2 \"\\thttps://github.com/89luca89/distrobox/blob/main/docs/compatibility.md\\n\"\n\texit 127\nfi\n\n# add verbose if -v is specified\nif [ \"${verbose}\" -ne 0 ]; then\n\tcontainer_manager=\"${container_manager} --log-level debug\"\n\tcontainer_manager_cp_command=\"${container_manager_cp_command} --log-level debug\"\nfi\n\n# prepend sudo (or the specified sudo program) if we want our container manager to be rootful\nif [ \"${rootful}\" -ne 0 ]; then\n\textra_flags=\"${extra_flags} --root\"\n\tcontainer_manager=\"${distrobox_sudo_program:-\"sudo\"} ${container_manager}\"\n\tcontainer_manager_cp_command=\"${distrobox_sudo_program:-\"sudo\"} ${container_manager_cp_command}\"\nfi\n\nif ! ${container_manager} inspect --type container \"${container_name}\" > /dev/null; then\n\tprintf >&2 \"Cannot find container %s. Please create it first.\\n\" \"${container_name}\"\n\texit 1\nfi\n\n# Ensure the destination dir exists.\nmkdir -p \"${XDG_DATA_HOME:-${HOME}/.local/share}/applications\"\nmkdir -p \"${XDG_DATA_HOME:-${HOME}/.local/share}/icons/distrobox\"\n\ndistrobox_path=\"$(dirname \"$(realpath \"${0}\")\")\"\nentry_name=\"$(echo \"${container_name}\" | cut -c1 | tr \"[:lower:]\" \"[:upper:]\")$(echo \"${container_name}\" | cut -c2-)\"\n\nif [ \"${icon}\" = \"auto\" ]; then\n\t# Set icon to the generic terminal as a fallback.\n\ticon=\"${icon_default}\"\n\t# This is a NON comprehensive list of logos of the most popular distributions. If you find logos for\n\t# other supported distros, add it here.\n\tDISTRO_ICON_MAP=\"\n\t\talma:https://raw.githubusercontent.com/89luca89/distrobox/main/docs/assets/png/distros/alma-distrobox.png\n\t\talpine:https://raw.githubusercontent.com/89luca89/distrobox/main/docs/assets/png/distros/alpine-distrobox.png\n\t\talt:https://raw.githubusercontent.com/89luca89/distrobox/main/docs/assets/png/distros/alt-distrobox.png\n\t\tarch:https://raw.githubusercontent.com/89luca89/distrobox/main/docs/assets/png/distros/arch-distrobox.png\n\t\tcentos:https://raw.githubusercontent.com/89luca89/distrobox/main/docs/assets/png/distros/centos-distrobox.png\n\t\tclear--os:https://raw.githubusercontent.com/89luca89/distrobox/main/docs/assets/png/distros/clear-distrobox.png\n\t\tdebian:https://raw.githubusercontent.com/89luca89/distrobox/main/docs/assets/png/distros/debian-distrobox.png\n\t\tdeepin:https://raw.githubusercontent.com/89luca89/distrobox/main/docs/assets/png/distros/deepin-distrobox.png\n\t\tfedora:https://raw.githubusercontent.com/89luca89/distrobox/main/docs/assets/png/distros/fedora-distrobox.png\n\t\tgentoo:https://raw.githubusercontent.com/89luca89/distrobox/main/docs/assets/png/distros/gentoo-distrobox.png\n\t\tkali:https://raw.githubusercontent.com/89luca89/distrobox/main/docs/assets/png/distros/kali-distrobox.png\n\t\tkdeneon:https://raw.githubusercontent.com/89luca89/distrobox/main/docs/assets/png/distros/kdeneon-distrobox.png\n\t\topensuse-leap:https://raw.githubusercontent.com/89luca89/distrobox/main/docs/assets/png/distros/opensuse-distrobox.png\n\t\topensuse-tumbleweed:https://raw.githubusercontent.com/89luca89/distrobox/main/docs/assets/png/distros/opensuse-distrobox.png\n\t\trhel:https://raw.githubusercontent.com/89luca89/distrobox/main/docs/assets/png/distros/redhat-distrobox.png\n\t\trocky:https://raw.githubusercontent.com/89luca89/distrobox/main/docs/assets/png/distros/rocky-distrobox.png\n\t\tubuntu:https://raw.githubusercontent.com/89luca89/distrobox/main/docs/assets/png/distros/ubuntu-distrobox.png\n\t\tvanilla:https://raw.githubusercontent.com/89luca89/distrobox/main/docs/assets/png/distros/vanilla-distrobox.png\n\t\tvoid:https://raw.githubusercontent.com/89luca89/distrobox/main/docs/assets/png/distros/void-distrobox.png\n\t\"\n\t# Try to detect container's distribution by using /etc/os-release\n\t${container_manager_cp_command} \"${container_name}\":/etc/os-release /tmp/\"${container_name}\".os-release\n\tcontainer_distro=\"$(grep \"^ID=\" /tmp/\"${container_name}\".os-release |\n\t\tcut -d'=' -f2- |\n\t\tsed \"s|linux||g\" |\n\t\ttr -d ' ' |\n\t\ttr -d '\"')\"\n\n\tif [ \"${rootful}\" -ne 0 ]; then\n\t\t${distrobox_sudo_program:-\"sudo\"} rm -f /tmp/\"${container_name}\".os-release\n\telse\n\t\trm -f /tmp/\"${container_name}\".os-release\n\tfi\n\n\ticon_url=\"$(echo \"${DISTRO_ICON_MAP}\" | grep \"${container_distro}:\" | cut -d':' -f2-)\"\n\n\t# Distro not found in our map, fallback to generic icon\n\tif [ -z \"${icon_url}\" ]; then\n\t\ticon_url=\"https://raw.githubusercontent.com/89luca89/distrobox/main/icons/terminal-distrobox-icon.svg\"\n\t\tcontainer_distro=\"terminal-distrobox-icon\"\n\tfi\n\n\tif [ -n \"${icon_url}\" ] && [ \"${download}\" != \"null\" ]; then\n\t\ticon_extension=\"${icon_url##*.}\"\n\n\t\tif [ \"${online}\" -lt 1 ] && ${download} - \"${icon_url}\" > \"${XDG_DATA_HOME:-${HOME}/.local/share}/icons/distrobox/${container_distro}.${icon_extension}\"; then\n\t\t\ticon=\"${XDG_DATA_HOME:-${HOME}/.local/share}/icons/distrobox/${container_distro}.${icon_extension}\"\n\t\telse\n\t\t\t# Wget failed for some reasons. Default to generic terminal icon as declared at the beginning.\n\t\t\tprintf >&2 \"Warning: Failed to download icon. Defaulting to generic one.\\n\"\n\t\tfi\n\telse\n\t\t# Distribution not found in the list. Default to generic terminal icon as declared at the beginning.\n\t\tprintf >&2 \"Warning: Distribution not found in default icon set. Defaulting to generic one.\\n\"\n\tfi\nfi\n\ncat << EOF > \"${XDG_DATA_HOME:-${HOME}/.local/share}/applications/${container_name}.desktop\"\n[Desktop Entry]\nName=${entry_name}\nGenericName=Terminal entering ${entry_name}\nComment=Terminal entering ${entry_name}\nCategories=Distrobox;System;Utility\nExec=${distrobox_path}/distrobox enter ${extra_flags} ${container_name}\nIcon=${icon}\nKeywords=distrobox;\nNoDisplay=false\nTerminal=true\nTryExec=${distrobox_path}/distrobox\nType=Application\nActions=Remove;\n\n[Desktop Action Remove]\nName=Remove ${entry_name} from system\nExec=${distrobox_path}/distrobox rm ${extra_flags} ${container_name}\nEOF\n"
  },
  {
    "path": "distrobox-host-exec",
    "content": "#!/bin/sh\n# SPDX-License-Identifier: GPL-3.0-only\n#\n# This file is part of the distrobox project:\n#    https://github.com/89luca89/distrobox\n#\n# Copyright (C) 2022 distrobox contributors\n#\n# distrobox is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 3\n# as published by the Free Software Foundation.\n#\n# distrobox is distributed in the hope that it will be useful, but\n# WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n# General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with distrobox; if not, see <http://www.gnu.org/licenses/>.\n\n# Ensure we have our env variables correctly set\n[ -z \"${USER}\" ] && USER=\"$(id -run)\"\n[ -z \"${HOME}\" ] && HOME=\"$(getent passwd \"${USER}\" | cut -d':' -f6)\"\n[ -z \"${SHELL}\" ] && SHELL=\"$(getent passwd \"${USER}\" | cut -d':' -f7)\"\n\n# Defaults\nhost_command=\"\"\nnon_interactive=0\n# If we're in a non-interactive shell, let's act accordingly\nif [ ! -t 1 ] ||\n\t! tty > /dev/null 2>&1; then\n\tnon_interactive=1\nfi\ndistrobox_host_exec_default_command=\"${SHELL:-/bin/sh}\"\nhost_spawn_version=\"v1.6.0\"\ndownload_command=\"\"\nsudo_command=\"\"\nverbose=0\nversion=\"1.8.2.4\"\n\n# show_help will print usage to stdout.\n# Arguments:\n#   None\n# Expected global variables:\n#   version: distrobox version\n# Expected env variables:\n#   None\n# Outputs:\n#   print usage with examples.\nshow_help()\n{\n\tcat << EOF\ndistrobox version: ${version}\n\nUsage:\n\n\tdistrobox-host-exec [command [arguments]]\n\tdistrobox-host-exec ls\n\tdistrobox-host-exec bash -l\n\tdistrobox-host-exec flatpak run org.mozilla.firefox\n\tdistrobox-host-exec podman ps -a\n\n\nOptions:\n\n\t--help/-h:\t\tshow this message\n\t--verbose/-v:\t\tshow more verbosity\n\t--version/-V:\t\tshow version\n\t--yes/-Y:\t\tAutomatically answer yes to prompt:\n                                host-spawn will be installed on the guest system\n                                if host-spawn is not detected.\n                                This behaviour is default when running in a non-interactive shell.\nEOF\n}\n\n# If we're a symlink to a command, use that as command to exec, and skip arg parsing.\nif [ \"$(basename \"${0}\")\" != \"distrobox-host-exec\" ]; then\n\thost_command=\"$(basename \"${0}\")\"\nfi\n# Parse arguments\nif [ -z \"${host_command}\" ]; then\n\t# Skip argument parsing if we're a symlink\n\twhile :; do\n\t\tcase $1 in\n\t\t\t-h | --help)\n\t\t\t\t# Call a \"show_help\" function to display a synopsis, then exit.\n\t\t\t\tshow_help\n\t\t\t\texit 0\n\t\t\t\t;;\n\t\t\t-v | --verbose)\n\t\t\t\tverbose=1\n\t\t\t\tshift\n\t\t\t\t;;\n\t\t\t-V | --version)\n\t\t\t\tprintf \"distrobox: %s\\n\" \"${version}\"\n\t\t\t\tprintf \"host-spawn: %s\\n\" \"${host_spawn_version}\"\n\t\t\t\texit 0\n\t\t\t\t;;\n\t\t\t-Y | --yes)\n\t\t\t\tnon_interactive=1\n\t\t\t\tshift\n\t\t\t\t;;\n\t\t\t--) # End of all options.\n\t\t\t\tshift\n\t\t\t\t;;\n\t\t\t-*) # Invalid options.\n\t\t\t\tprintf >&2 \"ERROR: Invalid flag '%s'\\n\\n\" \"$1\"\n\t\t\t\tshow_help\n\t\t\t\texit 1\n\t\t\t\t;;\n\t\t\t*)\n\t\t\t\tif [ -n \"$1\" ]; then\n\t\t\t\t\thost_command=$1\n\t\t\t\t\tshift\n\t\t\t\tfi\n\t\t\t\tbreak\n\t\t\t\t;;\n\t\tesac\n\tdone\nfi\n\nset -o errexit\nset -o nounset\n# set verbosity\nif [ \"${verbose}\" -ne 0 ]; then\n\tset -o xtrace\nfi\n\n# Check we're running inside a container and not on the host\nif [ ! -f /run/.containerenv ] && [ ! -f /.dockerenv ] && [ -z \"${container:-}\" ]; then\n\tprintf >&2 \"You must run %s inside a container!\\n\" \" $(basename \"$0\")\"\n\texit 126\nfi\n\nif [ -z \"${host_command}\" ]; then\n\thost_command=\"${distrobox_host_exec_default_command}\"\nfi\n\nif [ \"$(id -ru)\" -ne 0 ]; then\n\tif command -v sudo 2> /dev/null > /dev/null; then\n\t\tsudo_command=\"sudo\"\n\telse\n\t\tsudo_command=\"su -l -c\"\n\tfi\nfi\n\nif  command -v curl > /dev/null 2>&1; then\n\tdownload_command=\"curl -sLfo\"\nelif  command -v wget > /dev/null 2>&1; then\n\tdownload_command=\"wget -qO\"\nfi\n\n# Normalize architecture name to comply to golang/release naming\narchitecture=\"$(uname -m)\"\nif echo \"${architecture}\" | grep -q armv; then\n\tarchitecture=\"$(echo \"${architecture}\" | grep -Eo \"armv[0-9]+\")\"\nfi\n\n# Setup host-spawn as a way to execute commands back on the host\nif ! command -v host-spawn > /dev/null ||\n\t[ \"$(printf \"%s\\n%s\\n\" \"${host_spawn_version}\" \"$(host-spawn --version)\" |\n\t\tsort -V | head -n 1)\" != \"${host_spawn_version}\" ]; then\n\n\t# if non-interactive flag flag hasn't been set\n\tif [ \"${non_interactive}\" -eq 0 ]; then\n\t\t# Prompt to download it.\n\t\tprintf \"Warning: host-spawn not found or version is too old!\\n\"\n\t\tprintf \"Do you want to install host-spawn utility? [Y/n] \"\n\t\tread -r response\n\t\tresponse=${response:-\"Y\"}\n\telse\n\t\tresponse=\"yes\"\n\tfi\n\t# Accept only y,Y,Yes,yes,n,N,No,no.\n\tcase \"${response}\" in\n\t\ty | Y | Yes | yes | YES)\n\t\t\t# Download matching version with current distrobox\n\t\t\tif ! ${download_command} /tmp/host-spawn \\\n\t\t\t\t\"https://github.com/1player/host-spawn/releases/download/${host_spawn_version}/host-spawn-${architecture}\"; then\n\n\t\t\t\tprintf \"Error: Cannot download host-spawn\\n\"\n\t\t\t\texit 1\n\t\t\tfi\n\t\t\tif [ -e /tmp/host-spawn ]; then\n\t\t\t\t${sudo_command} sh -c \"mv /tmp/host-spawn /usr/bin/\"\n\t\t\t\t${sudo_command} sh -c \"chmod +x /usr/bin/host-spawn\"\n\t\t\tfi\n\t\t\t;;\n\t\tn | N | No | no | NO)\n\t\t\tprintf \"Installation aborted, please install host-spawn.\\n\"\n\t\t\texit 0\n\t\t\t;;\n\t\t*) # Default case: If no more options then break out of the loop.\n\t\t\tprintf >&2 \"Invalid input.\\n\"\n\t\t\tprintf >&2 \"The available choices are: y,Y,Yes,yes,YES or n,N,No,no,NO.\\nExiting.\\n\"\n\t\t\texit 1\n\t\t\t;;\n\tesac\n\nfi\n\n# This makes host-spawn work on initful containers, where the dbus session is\n# separate from the host, we point the dbus session straight to the host's socket\n# in order to talk with the org.freedesktop.Flatpak.Development.HostCommand on the host\n[ -z \"${XDG_RUNTIME_DIR:-}\" ] && XDG_RUNTIME_DIR=\"/run/user/$(id -ru)\"\n[ -z \"${DBUS_SESSION_BUS_ADDRESS:-}\" ] && DBUS_SESSION_BUS_ADDRESS=\"unix:path=/run/user/$(id -ru)/bus\"\nXDG_RUNTIME_DIR=\"/run/host/${XDG_RUNTIME_DIR}\"\nDBUS_SESSION_BUS_ADDRESS=\"unix:path=/run/host/$(echo \"${DBUS_SESSION_BUS_ADDRESS}\" | cut -d '=' -f2-)\"\n\n###\n# This workaround is needed because of a bug in gio (used by xdg-open) where\n# a race condition happens when allocating a pty, leading to the command\n# being killed before having time to be executed.\n#\n# https://gitlab.gnome.org/GNOME/glib/-/issues/2695\n# https://github.com/1player/host-spawn/issues/7\n#\n# As an (ugly) workaround, we will not allocate a pty for those commands.\n###\n# Also, we don't initialize a pty, if we're not in a tty.\nif [ \"$(basename \"${host_command}\")\" = \"xdg-open\" ] ||\n\t[ \"$(basename \"${host_command}\")\" = \"gio\" ] ||\n\t[ \"$(basename \"${host_command}\")\" = \"flatpak\" ] ||\n\t[ ! -t 1 ] ||\n\t! tty > /dev/null 2>&1; then\n\n\thost-spawn --no-pty \"${host_command}\" \"$@\"\n\t# Exit here, we don't continue execution\n\texit $?\nfi\n\nhost-spawn \"${host_command}\" \"$@\"\n# Exit here, we don't continue execution\nexit $?\n"
  },
  {
    "path": "distrobox-init",
    "content": "#!/bin/sh\n# SPDX-License-Identifier: GPL-3.0-only\n#\n# This file is part of the distrobox project:\n#    https://github.com/89luca89/distrobox\n#\n# Copyright (C) 2021 distrobox contributors\n#\n# distrobox is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 3\n# as published by the Free Software Foundation.\n#\n# distrobox is distributed in the hope that it will be useful, but\n# WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n# General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with distrobox; if not, see <http://www.gnu.org/licenses/>.\n\n# POSIX\n# Expected env variables:\n#\tHOME\n#\tUSER\n#\tSHELL\n\ntrap '[ \"$?\" -ne 0 ] && printf \"Error: An error occurred\\n\"' EXIT\n\n# Redirect stderr to stdout as podman by default logs stderr as priority 3 journald errors.\n# Github issue: https://github.com/containers/podman/issues/20728\nexec 2>&1\n\n# We'll also bind mount READ-WRITE useful mountpoints to pass external drives and libvirt from\n# the host to the container\nHOST_MOUNTS=\"\n\t/etc/host.conf\n\t/etc/machine-id\n\t/media\n\t/mnt\n\t/run/libvirt\n\t/run/media\n\t/run/netconfig/\n\t/run/systemd/journal\n\t/run/systemd/resolve/\n\t/run/systemd/seats\n\t/run/systemd/sessions\n\t/run/systemd/users\n\t/run/udev\n\t/var/lib/libvirt\n\t/var/mnt\"\n\n# We'll also bind mount in READ-ONLY useful directories from the host\nHOST_MOUNTS_RO=\"\n\t/etc/localtime\n\t/var/lib/systemd/coredump\n\t/var/log/journal\"\n\nHOST_MOUNTS_RO_INIT=\"\n\t/etc/localtime\n\t/run/systemd/journal\n\t/run/systemd/resolve\n\t/run/systemd/seats\n\t/run/systemd/sessions\n\t/run/systemd/users\n\t/var/lib/systemd/coredump\n\t/var/log/journal\"\n\n# Defaults\ncontainer_additional_packages=\"\"\ninit=0\ninit_hook=\"\"\nnvidia=0\npre_init_hook=\"\"\nrootful=0\nupgrade=0\nverbose=0\nversion=\"1.8.2.4\"\n\n# show_help will print usage to stdout.\n# Arguments:\n#   None\n# Expected global variables:\n#   version: distrobox version\n# Expected env variables:\n#   USER\n#   HOME\n# Outputs:\n#   print usage with examples.\nshow_help()\n{\n\tcat << EOF\ndistrobox version: ${version}\n\nUsage:\n\n\tdistrobox-init --name ${USER} --user $(id -ru) --group $(id -rg) --home ${HOME}\n\nOptions:\n\n\t--name/-n:\t\tuser name\n\t--user/-u:\t\tuid of the user\n\t--group/-g:\t\tgid of the user\n\t--home/-d:\t\tpath/to/home of the user\n\t--help/-h:\t\tshow this message\n\t--additional-packages:\tpackages to install in addition\n\t--init/-I:\t\twhether to use or not init\n\t--pre-init-hooks:\tcommands to execute prior to init\n\t--nvidia:\t\ttry to integrate host's nVidia drivers in the guest\n\t--upgrade/-U:\t\trun init in upgrade mode\n\t--verbose/-v:\t\tshow more verbosity\n\t--version/-V:\t\tshow version\n\t--:\t\t\tend arguments execute the rest as command to execute during init\nEOF\n}\n\n# Parse arguments\nwhile :; do\n\tcase $1 in\n\t\t-h | --help)\n\t\t\t# Call a \"show_help\" function to display a synopsis, then exit.\n\t\t\tshow_help\n\t\t\texit 0\n\t\t\t;;\n\t\t-v | --verbose)\n\t\t\tshift\n\t\t\tverbose=1\n\t\t\t;;\n\t\t-V | --version)\n\t\t\tprintf \"distrobox: %s\\n\" \"${version}\"\n\t\t\texit 0\n\t\t\t;;\n\t\t-U | --upgrade)\n\t\t\tshift\n\t\t\tupgrade=1\n\t\t\t;;\n\t\t-n | --name)\n\t\t\tif [ -n \"$2\" ]; then\n\t\t\t\tcontainer_user_name=\"$2\"\n\t\t\t\tshift\n\t\t\t\tshift\n\t\t\tfi\n\t\t\t;;\n\t\t-i | --init)\n\t\t\tif [ -n \"$2\" ]; then\n\t\t\t\tinit=\"$2\"\n\t\t\t\tshift\n\t\t\t\tshift\n\t\t\tfi\n\t\t\t;;\n\t\t-d | --home)\n\t\t\tif [ -n \"$2\" ]; then\n\t\t\t\tcontainer_user_home=\"$2\"\n\t\t\t\tshift\n\t\t\t\tshift\n\t\t\tfi\n\t\t\t;;\n\t\t-u | --user)\n\t\t\tif [ -n \"$2\" ]; then\n\t\t\t\tcontainer_user_uid=\"$2\"\n\t\t\t\tshift\n\t\t\t\tshift\n\t\t\tfi\n\t\t\t;;\n\t\t-g | --group)\n\t\t\tif [ -n \"$2\" ]; then\n\t\t\t\tcontainer_user_gid=\"$2\"\n\t\t\t\tshift\n\t\t\t\tshift\n\t\t\tfi\n\t\t\t;;\n\t\t--pre-init-hooks)\n\t\t\tif [ -n \"$2\" ]; then\n\t\t\t\tpre_init_hook=\"$2\"\n\t\t\tfi\n\t\t\tshift\n\t\t\tshift\n\t\t\t;;\n\t\t--additional-packages)\n\t\t\tif [ -n \"$2\" ]; then\n\t\t\t\tcontainer_additional_packages=\"$2\"\n\t\t\tfi\n\t\t\tshift\n\t\t\tshift\n\t\t\t;;\n\t\t--nvidia)\n\t\t\tif [ -n \"$2\" ]; then\n\t\t\t\tnvidia=\"$2\"\n\t\t\t\tshift\n\t\t\t\tshift\n\t\t\tfi\n\t\t\t;;\n\t\t--)\n\t\t\tshift\n\t\t\tinit_hook=$*\n\t\t\tbreak\n\t\t\t;;\n\t\t-*) # Invalid options.\n\t\t\tprintf >&2 \"Error: Invalid flag '%s'\\n\\n\" \"$1\"\n\t\t\tshow_help\n\t\t\texit 1\n\t\t\t;;\n\t\t*) # Default case: If no more options then break out of the loop.\n\t\t\tbreak ;;\n\tesac\ndone\n\n# Check we're running inside a container and not on the host\nif [ ! -f /run/.containerenv ] && [ ! -f /.dockerenv ] && [ -z \"${container:-}\" ]; then\n\tprintf >&2 \"You must run %s inside a container!\\n\" \" $(basename \"$0\")\"\n\tprintf >&2 \"distrobox-init should only be used as an entrypoint for a distrobox!\\n\\n\"\n\tprintf >&2 \"This is not intended to be used manually, but instead used by distrobox-enter\\n\"\n\tprintf >&2 \"to set up the container's entrypoint.\\n\"\n\texit 126\nfi\n\n# Ensure the foundamental variables are set and not empty, we will not proceed if\n# they are not all set.\nif [ \"${upgrade}\" -eq 0 ]; then\n\t[ -z \"${container_user_gid}\" ] && printf \"Error: Invalid arguments, missing user gid\\n\" && exit 2\n\t[ -z \"${container_user_home}\" ] && printf \"Error: Invalid argument, missing user home\\n\" && exit 2\n\t[ -z \"${container_user_name}\" ] && printf \"Error: Invalid arguments, missing username\\n\" && exit 2\n\t[ -z \"${container_user_uid}\" ] && printf \"Error: Invalid arguments, missing user uid\\n\" && exit 2\nfi\nset -o errexit\nset -o nounset\n# set verbosity\nif [ \"${verbose}\" -ne 0 ]; then\n\tset -o xtrace\nfi\n\n# Determine if we're in a rootful container, generally if we're able to read\n# host's /etc/shadow, it means we're really root!\n#\n# if /run/.nopasswd is present, let's treat the init as rootless, this is not\n# a good thing, users behold!\n#\n# if /run/.distrobox.rootless is present, the container was explicitly created\n# without --root (distrobox-create mounts this marker for rootless containers).\n# Trust it over the shadow heuristic, which gives false positives on Docker\n# Desktop (macOS) where the container always has root access to the VM's fs.\nif [ ! -e /run/.distrobox.rootless ] &&\n\tstat /run/host/etc/shadow > /dev/null &&\n\t{\n\t\t[ \"$(stat -c \"%u\" /run/host/etc/shadow)\" = \"0\" ] || [ \"$(stat -f \"%u\" /run/host/etc/shadow 2> /dev/null)\" = \"0\" ]\n\t} &&\n\t[ ! -e /run/.nopasswd ]; then\n\trootful=1\nfi\n\n# Get host $LANG\nif [ -f \"/run/host/etc/locale.conf\" ]; then\n\tHOST_LOCALE=$(grep -e '^LANG=' /run/host/etc/locale.conf | sed 's/LANG=//' | sed 's/\"//g' | sed \"s/'//g\")\n\tHOST_LOCALE_ENCODING=$(echo \"${HOST_LOCALE}\" | sed -n 's/^[^.]*\\.\\(.*\\)$/\\1/p')\n\tHOST_LOCALE_LANG=$(echo \"${HOST_LOCALE}\" | sed -n 's/^\\([^.]*\\)\\..*$/\\1/p')\nelif [ -f \"/run/host/etc/default/locale\" ]; then\n\tHOST_LOCALE=$(grep -e '^LANG=' /run/host/etc/default/locale | sed 's/LANG=//' | sed 's/\"//g')\n\tHOST_LOCALE_ENCODING=$(echo \"${HOST_LOCALE}\" | sed -n 's/^[^.]*\\.\\(.*\\)$/\\1/p')\n\tHOST_LOCALE_LANG=$(echo \"${HOST_LOCALE}\" | sed -n 's/^\\([^.]*\\)\\..*$/\\1/p')\nfi\n# Add fallback values in case host's locale is not set correctly\nif [ -z \"${HOST_LOCALE:-}\" ] || [ \"${HOST_LOCALE:-}\" = \"C.UTF-8\" ]; then\n\tHOST_LOCALE=\"en_US.UTF-8\"\n\tHOST_LOCALE_ENCODING=\"UTF-8\"\n\tHOST_LOCALE_LANG=\"en_US\"\nfi\n\n# get_locked_mount_flags will print mount flags considered \"locked\".\n# Arguments:\n# \tsrc: path to the file/directory\n# Expected env variables:\n#\tNone\n# Expected global variables:\n#\tNone\n# Outputs:\n# \tComma-separated list of locked mount flags\nget_locked_mount_flags()\n{\n\tsrc=\"$1\"\n\tprev=\"\"\n\tlocked_flags=\"\"\n\n\t# If findmnt does not exist, exit\n\tif ! command -v findmnt 2> /dev/null > /dev/null; then\n\t\treturn 0\n\tfi\n\n\t# If we can't read the file/directory, exit\n\tif ! ls \"${src}\" 2> /dev/null > /dev/null; then\n\t\treturn 0\n\tfi\n\n\t# Get mount flags of given file/directory, using nearest mountpoint.\n\t# Earlier versions of findmnt did not check parents until it found a mountpoint,\n\t# so we use a workaround with dirname.\n\twhile true; do\n\t\tflags=\"$(findmnt --noheadings --output OPTIONS --target \"${src}\" || :)\"\n\t\t# shellcheck disable=SC2181\n\t\tif [ -n \"${flags}\" ]; then\n\t\t\tbreak\n\t\tfi\n\t\tprev=\"${src}\"\n\t\tsrc=\"$(dirname \"${src}\")\"\n\t\t[ \"${src}\" = \"${prev}\" ] && return 1\n\tdone\n\n\tfor flag in nodev noexec nosuid; do\n\t\tif printf \"%s\" \"${flags}\" | grep -q \"${flag}\"; then\n\t\t\t# Locked flag found, append to list while avoiding leading/trailing commas\n\t\t\tlocked_flags=\"${locked_flags:+${locked_flags},}${flag}\"\n\t\tfi\n\tdone\n\n\tprintf \"%s\" \"${locked_flags}\"\n}\n\n# init_readlink is a simplistic implementation for\n# readlink -fm\n# we use this as readlink -fm does not work on\n# busybox systems, and we need the path even for broken links.\n# Arguments:\n#\tsource file\n# Expected env variables:\n#\tNone\n# Expected global variables:\n#\tNone\n# Outputs:\n#\toriginal path the link is pointing\ninit_readlink()\n{\n\t# shellcheck disable=SC2010\n\tls -l \"${1}\" | grep -Eo '\\->.*' | cut -d' ' -f2- | sed 's|\\.\\./|/|g'\n}\n\n# mount_bind will perform a bind mount for inputs or error\n# Arguments:\n#   source_dir: string what to mount\n#\ttarget_dir: string where to mount\n#\tmount_flags: list of mount flags -> optional\n# Expected env variables:\n#\tNone\n# Expected global variables:\n#\tNone\n# Outputs:\n#   No output if all ok\n#\tError if not\nmount_bind()\n{\n\tsource_dir=\"$1\"\n\ttarget_dir=\"$2\"\n\tmount_flags=\"\"\n\tif [ \"$#\" -gt 2 ]; then\n\t\tmount_flags=\"$3\"\n\tfi\n\n\t# Adjust source_dir in order to point to /run/host if it's a symlink\n\tif [ -L \"${source_dir}\" ]; then\n\t\tsource_dir=\"$(init_readlink \"${source_dir}\")\"\n\t\tif ! printf \"%s\" \"${source_dir}\" | grep -q \"/run/host\"; then\n\t\t\tsource_dir=\"/run/host${source_dir}\"\n\t\tfi\n\tfi\n\n\t# if source dir doesn't exist, just exit\n\tif [ ! -d \"${source_dir}\" ] && [ ! -f \"${source_dir}\" ]; then\n\t\treturn 0\n\tfi\n\n\t# if target_dir exists, check if it is a mountpoint and umount it.\n\tif [ -e \"${target_dir}\" ] && findmnt \"${target_dir}\" > /dev/null; then\n\t\tumount \"${target_dir}\"\n\tfi\n\n\t# if target_dir exists, and is a symlink, remove it\n\tif [ -L \"${target_dir}\" ]; then\n\t\trm -f \"${target_dir}\"\n\tfi\n\n\t# if the source_dir exists, then create the target_dir\n\tif [ -d \"${source_dir}\" ]; then\n\t\tif ! mkdir -p \"${target_dir}\"; then\n\t\t\tprintf \"Warning: cannot create mount target directory: %s\\n\" \"${target_dir}\"\n\t\t\treturn 1\n\t\tfi\n\t# if instead it's a file, create it with touch\n\telif [ -f \"${source_dir}\" ]; then\n\t\tif [ ! -d \"$(dirname \"${target_dir}\")\" ]; then\n\t\t\tmkdir -p \"$(dirname \"${target_dir}\")\"\n\t\tfi\n\t\t# if we encounter a broken link, and we touch it\n\t\t# then remove the broken link, the next touch\n\t\t# will cover it.\n\t\tif ! touch \"${target_dir}\"; then\n\t\t\tprintf \"Warning: cannot create mount target file: %s\\n\" \"${target_dir}\"\n\t\t\treturn 1\n\t\tfi\n\tfi\n\n\t# Add mountflags if needed, if no are specified, use rslave as default.\n\t# bind mount source_dir to target_dir, return error if not successful\n\tif [ \"${mount_flags}\" = \"\" ]; then\n\t\tif ! mount --rbind \"${source_dir}\" \"${target_dir}\"; then\n\t\t\tprintf \"Warning: failed to bind mount %s to %s\\n\" \"${source_dir}\" \"${target_dir}\"\n\t\t\treturn 1\n\t\tfi\n\t\tif ! mount --make-rslave \"${target_dir}\"; then\n\t\t\tprintf \"Warning: failed to make rslave to %s\\n\" \"${target_dir}\"\n\t\t\treturn 1\n\t\tfi\n\telif ! mount --rbind -o \"${mount_flags}\" \"${source_dir}\" \"${target_dir}\"; then\n\t\tprintf \"Warning: failed to bind mount %s to %s using option %s\\n\" \"${source_dir}\" \"${target_dir}\" \"${mount_flags}\"\n\t\treturn 1\n\tfi\n\n\treturn 0\n}\n\nif [ -n \"${pre_init_hook}\" ]; then\n\tprintf \"distrobox: Executing pre-init hooks...\\n\"\n\t# execute pre-init hooks if specified\n\t# shellcheck disable=SC2086\n\teval ${pre_init_hook}\nfi\n\n###############################################################################\nprintf \"distrobox: Installing basic packages...\\n\"\n# Extract shell name from the $SHELL environment variable\n# If not present as package in the container, we want to install it.\nshell_pkg=\"$(basename \"${SHELL:-\"bash\"}\")\"\n# Ash shell is an exception, it is not a standalone package, but part of busybox.\n# for this reason, use this quirk to adjust the package name to standard bash.\nif [ \"${shell_pkg}\" = \"ash\" ]; then\n\tshell_pkg=\"bash\"\nfi\n\n# setup_pkg_manager_hooks will create umount/remount hooks script for a package\n# manager. Mainly used by apt and pacman.\n# Arguments:\n#   None\n# Expected global variables:\n#   init: if this is an initful container\n#   HOST_MOUNTS_RO_INIT: list of mountpoints of an initful system, to avoid\n# Expected env variables:\n#   None\n# Outputs:\n#   None\nsetup_pkg_manager_hooks()\n{\n\tif {\n\t\t[ -d \"/etc/dpkg/dpkg.cfg.d/\" ] || [ -d \"/usr/share/libalpm/scripts\" ]\n\t} && [ \"${init}\" -eq 0 ]; then\n\t\tcat << EOF > /etc/distrobox-pre-hook.sh\n#!/bin/sh\nmounts=\"${HOST_MOUNTS_RO_INIT}\"\nfor mount in \\$mounts; do\n\tif findmnt \\$mount >/dev/null; then\n\t\tumount -l \\$mount\n\tfi\ndone\nEOF\n\t\tcat << EOF > /etc/distrobox-post-hook.sh\n#!/bin/sh\nmounts=\"${HOST_MOUNTS_RO_INIT}\"\nfor mount in \\$mounts; do\n\tif [ -e /run/host/\\$mount ] || [ -e /run/host/\\$(readlink -fm /run/host/\\$mount) ]; then\n\t\tif [ ! -d /run/host/\\$mount ]; then\n\t\t\trm -f \\$mount && touch \\$mount\n\t\tfi\n\t\tif ! mount --rbind \\$(readlink -fm /run/host/\\$mount) \\$mount; then\n\t\t\tmount --rbind /run/host/\\$(readlink -fm /run/host/\\$mount) \\$mount\n\t\tfi\n\tfi\ndone\nEOF\n\t\tchmod +x /etc/distrobox-pre-hook.sh /etc/distrobox-post-hook.sh\n\tfi\n}\n\n# setup_deb_exceptions will create path-excludes for host mounts, dpkg/apt only.\n# Arguments:\n#   None\n# Expected global variables:\n#   init: if this is an initful container\n#   HOST_MOUNTS_RO: list of readonly mountpoints, to avoid\n#   HOST_MOUNTS: list of readwrite mountpoints, to avoid\n# Expected env variables:\n#   None\n# Outputs:\n#   None\nsetup_deb_exceptions()\n{\n\tsetup_pkg_manager_hooks\n\n\t# In case of an DEB distro, we can specify that our bind_mount directories\n\t# have to be ignored. This prevents conflicts during package installations.\n\tif [ \"${init}\" -eq 0 ]; then\n\t\t# Loop through all the environment vars\n\t\t# and export them to the container.\n\t\tmkdir -p /etc/dpkg/dpkg.cfg.d/\n\t\tprintf \"\" > /etc/dpkg/dpkg.cfg.d/00_distrobox\n\t\tfor net_mount in ${HOST_MOUNTS_RO} ${HOST_MOUNTS}; do\n\t\t\tprintf \"path-exclude %s/*\\n\" \"${net_mount}\" >> /etc/dpkg/dpkg.cfg.d/00_distrobox\n\t\tdone\n\n\t\t# Also we put a hook to clear some critical paths that do not play well\n\t\t# with read only filesystems, like Systemd.\n\t\tif [ -d \"/etc/apt/apt.conf.d/\" ]; then\n\t\t\tprintf 'DPkg::Pre-Invoke {/etc/distrobox-pre-hook.sh};\\n' > /etc/apt/apt.conf.d/00_distrobox\n\t\t\tprintf 'DPkg::Post-Invoke {/etc/distrobox-post-hook.sh};\\n' >> /etc/apt/apt.conf.d/00_distrobox\n\t\tfi\n\tfi\n}\n\n# setup_pacman_exceptions will set pre/post transaction hooks to avoid host's mounts, pacman only.\n# Arguments:\n#   None\n# Expected global variables:\n#   init: if this is an initful container\n# Expected env variables:\n#   None\n# Outputs:\n#   None\nsetup_pacman_exceptions()\n{\n\tsetup_pkg_manager_hooks\n\n\t# Workarounds for pacman. We need to exclude the paths by using a pre-hook to umount them and a\n\t# post-hook to remount them. Additionally we neutralize the systemd-post-hooks as they do not\n\t# work on a rootless container system.\n\tif [ -d \"/usr/share/libalpm/scripts\" ] && [ \"${init}\" -eq 0 ]; then\n\t\t# in case we're not using an init image, neutralize systemd post installation hooks\n\t\t# so that we do not encounter problems along the way.\n\t\t# This will be removed if we're using --init.\n\t\tcat << EOF > /usr/share/libalpm/scripts/distrobox_post_hook.sh\n#!/bin/sh\necho -e '#!/bin/sh\\nexit 0' > /usr/share/libalpm/scripts/systemd-hook;\nEOF\n\t\tchmod +x /usr/share/libalpm/scripts/distrobox_post_hook.sh\n\n\t\t# create hooks files for them\n\t\tfind /usr/share/libalpm/hooks/*distrobox* -delete || :\n\t\tfor hook in /etc/distrobox-pre-hook.sh /etc/distrobox-post-hook.sh /usr/share/libalpm/scripts/distrobox_post_hook.sh; do\n\t\t\twhen=\"PostTransaction\"\n\t\t\t[ -z \"${hook##*pre*}\" ] && when=\"PreTransaction\"\n\t\t\tcat << EOF > \"/usr/share/libalpm/hooks/$(basename \"${hook}\").hook\"\n[Trigger]\nOperation = Install\nOperation = Upgrade\nType = Package\nTarget = *\n[Action]\nDescription = Distrobox hook ${hook}...\nWhen = ${when}\nExec = ${hook}\nEOF\n\t\tdone\n\tfi\n\n}\n\n# setup_rpm_exceptions will create path-excludes for host mounts, rpm only (dnf, yum, zypper, microdnf).\n# Arguments:\n#   None\n# Expected global variables:\n#   init: if this is an initful container\n#   HOST_MOUNTS_RO: list of readonly mountpoints, to avoid\n#   HOST_MOUNTS: list of readwrite mountpoints, to avoid\n# Expected env variables:\n#   None\n# Outputs:\n#   None\nsetup_rpm_exceptions()\n{\n\t# In case of an RPM distro, we can specify that our bind_mount directories\n\t# are in fact net shares. This prevents conflicts during package installations.\n\tif [ \"${init}\" -eq 0 ]; then\n\t\tmkdir -p /usr/lib/rpm/macros.d/\n\t\t# Loop through all the environment vars\n\t\t# and export them to the container.\n\t\tnet_mounts=\"\"\n\t\tfor net_mount in \\\n\t\t\t${HOST_MOUNTS_RO} ${HOST_MOUNTS} \\\n\t\t\t'/dev' '/proc' '/sys' '/tmp' \\\n\t\t\t'/etc/hosts' '/etc/resolv.conf' '/etc/passwd' '/etc/shadow'; do\n\n\t\t\tnet_mounts=\"${net_mount}:${net_mounts}\"\n\t\tdone\n\t\tnet_mounts=${net_mounts%?}\n\t\tcat << EOF > /usr/lib/rpm/macros.d/macros.distrobox\n%_netsharedpath ${net_mounts}\nEOF\n\tfi\n}\n\n# setup_xbps_exceptions will create path-excludes for host mounts, xbps only.\n# Arguments:\n#   None\n# Expected global variables:\n#   None\n# Expected env variables:\n#   None\n# Outputs:\n#   None\nsetup_xbps_exceptions()\n{\n\t# We have to lock this paths from xbps extraction, as it's incompatible with distrobox's\n\t# mount process.\n\tcat << EOF > /etc/xbps.d/distrobox-ignore.conf\nnoextract=/etc/passwd\nnoextract=/etc/hosts\nnoextract=/etc/host.conf\nnoextract=/etc/hostname\nnoextract=/etc/localtime\nnoextract=/etc/machine-id\nnoextract=/etc/resolv.conf\nEOF\n}\n\n# setup_apk will upgrade or setup all packages for apk based systems.\n# Arguments:\n#   None\n# Expected global variables:\n#   upgrade: if we need to upgrade or not\n#   container_additional_packages: additional packages to install during this phase\n# Expected env variables:\n#   None\n# Outputs:\n#   None\nsetup_apk()\n{\n\t# If we need to upgrade, do it and exit, no further action required.\n\tif [ \"${upgrade}\" -ne 0 ]; then\n\t\tapk update\n\t\tapk upgrade\n\t\texit\n\tfi\n\t# Check if shell_pkg is available in distro's repo. If not we\n\t# fall back to bash, and we set the SHELL variable to bash so\n\t# that it is set up correctly for the user.\n\tif ! apk add \"${shell_pkg}\"; then\n\t\tshell_pkg=\"bash\"\n\tfi\n\tif apk add wolfi-base; then\n\t\tdeps=\"\n\t\t\tbusybox\n\t\t\tgnutar\n\t\t\tman-db\n\t\t\tmesa\n\t\t\topenssh-client\n\t\t\tpinentry\n\t\t\tposix-libc-utils\n\t\t\tscript\n\t\t\"\n\telif apk add alpine-base; then\n\t\tdeps=\"\n\t\t\tbash-completion\n\t\t\tdocs\n\t\t\tgcompat\n\t\t\tlibc-utils\n\t\t\tlsof\n\t\t\tman-pages\n\t\t\tmandoc\n\t\t\tmusl-utils\n\t\t\topenssh-client-default\n\t\t\tpinentry\n\t\t\ttar\n\t\t\tvte3\n\t\t\twhich\n\t\t\t$(apk search -q mesa-dri)\n\t\t\t$(apk search -q mesa-vulkan)\n\t\t\"\n\telif apk add base-bootstrap; then\n\t\t# Prevent \"ADB schema error\" while installing tzdb in rootful container on currently old image\n\t\tapk upgrade -Ua\n\t\t# Prevent \"fchownat() of /tmp failed: Operation not permitted\" from sd-tools trigger script\n\t\tsed -i '' '/^q \\/tmp/ s/^/#/' /usr/lib/tmpfiles.d/tmp.conf\n\t\t# Setup rest of packages while also allowing install of extras from user repo\n\t\tapk add chimera-repo-user\n\t\tapk update\n\t\tdeps=\"\n\t\t\tbase-full-man\n\t\t\tbash-completion\n\t\t\tbc-gh\n\t\t\tgtar\n\t\t\tlibarchive-progs\n\t\t\tlibcap-progs\n\t\t\tlsof\n\t\t\tmesa-dri\n\t\t\tncurses-term\n\t\t\topendoas\n\t\t\topenssh\n\t\t\tutil-linux-mount\n\t\t\tvte\n\t\t\twget2\n\t\t\"\n\tfi\n\tdeps=\"${deps:-}\n\t\t${shell_pkg}\n\t\tbash\n\t\tbc\n\t\tbzip2\n\t\tcoreutils\n\t\tcurl\n\t\tdiffutils\n\t\tfindmnt\n\t\tfindutils\n\t\tgnupg\n\t\tgpg\n\t\tiproute2\n\t\tiputils\n\t\tkeyutils\n\t\tless\n\t\tlibcap\n\t\tmount\n\t\tncurses\n\t\tncurses-terminfo\n\t\tnet-tools\n\t\tpigz\n\t\trsync\n\t\tshadow\n\t\tsudo\n\t\ttcpdump\n\t\ttree\n\t\ttzdata\n\t\tumount\n\t\tunzip\n\t\tutil-linux\n\t\tutil-linux-login\n\t\tutil-linux-misc\n\t\tvulkan-loader\n\t\twget\n\t\txauth\n\t\txz\n\t\tzip\n\t\t$(apk search -qe procps)\n\t\"\n\t# shellcheck disable=SC2086\n\tfound_deps=\"$(apk search -qe ${deps} | tr '\\n' ' ')\"\n\tinstall_pkg=\"\"\n\tfor dep in ${deps}; do\n\t\t# shellcheck disable=SC2249\n\t\tcase \" ${found_deps} \" in\n\t\t\t*\" ${dep} \"*)\n\t\t\t\tinstall_pkg=\"${install_pkg} ${dep}\"\n\t\t\t\t;;\n\t\tesac\n\tdone\n\t# shellcheck disable=SC2086\n\tapk add --force-overwrite ${install_pkg}\n\n\t# Ensure we have tzdata installed and populated, sometimes container\n\t# images blank the zoneinfo directory, so we reinstall the package to\n\t# ensure population\n\tif [ ! -e /usr/share/zoneinfo/UTC ]; then\n\t\tapk del tzdata\n\t\tapk add tzdata\n\tfi\n\n\t# Install additional packages passed at distrbox-create time\n\tif [ -n \"${container_additional_packages}\" ]; then\n\t\t# shellcheck disable=SC2086\n\t\tapk add --force-overwrite ${container_additional_packages}\n\tfi\n}\n\n# setup_apt will upgrade or setup all packages for apt based systems.\n# Arguments:\n#   None\n# Expected global variables:\n#   upgrade: if we need to upgrade or not\n#   container_additional_packages: additional packages to install during this phase\n# Expected env variables:\n#   None\n# Outputs:\n#   None\nsetup_apt()\n{\n\texport DEBIAN_FRONTEND=noninteractive\n\n\t# If we need to upgrade, do it and exit, no further action required.\n\tif [ \"${upgrade}\" -ne 0 ]; then\n\t\tapt-get update\n\t\tapt-get upgrade -o Dpkg::Options::=\"--force-confold\" -y\n\t\texit\n\tfi\n\t# In Ubuntu official images, dpkg is configured to ignore locale and docs\n\t# This however, results in a rather poor out-of-the-box experience\n\t# So, let's enable them.\n\trm -f /etc/dpkg/dpkg.cfg.d/excludes\n\n\tapt-get update\n\t# Check if shell_pkg is available in distro's repo. If not we\n\t# fall back to bash, and we set the SHELL variable to bash so\n\t# that it is set up correctly for the user.\n\tif ! apt-get install -y \"${shell_pkg}\"; then\n\t\tshell_pkg=\"bash\"\n\tfi\n\tdeps=\"\n\t\t${shell_pkg}\n\t\tapt-utils\n\t\tbash-completion\n\t\tbc\n\t\tbzip2\n\t\tcurl\n\t\tdialog\n\t\tdiffutils\n\t\tfindutils\n\t\tgnupg\n\t\tgnupg2\n\t\tgpgsm\n\t\thostname\n\t\tiproute2\n\t\tiputils-ping\n\t\tkeyutils\n\t\tlanguage-pack-en\n\t\tless\n\t\tlibcap2-bin\n\t\tlibkrb5-3\n\t\tlibnss-mdns\n\t\tlibnss-myhostname\n\t\tlibvte-2.9*-common\n\t\tlibvte-common\n\t\tlocales\n\t\tlsof\n\t\tman-db\n\t\tmanpages\n\t\tmtr\n\t\tncurses-base\n\t\topenssh-client\n\t\tpasswd\n\t\tpigz\n\t\tpinentry-curses\n\t\tprocps\n\t\trsync\n\t\tsudo\n\t\ttcpdump\n\t\ttime\n\t\ttraceroute\n\t\ttree\n\t\ttzdata\n\t\tunzip\n\t\tutil-linux\n\t\twget\n\t\txauth\n\t\txz-utils\n\t\tzip\n\t\tlibgl1\n\t\tlibegl-mesa0\n\t\tlibegl1-mesa\n\t\tlibgl1-mesa-glx\n\t\tlibegl1\n\t\tlibglx-mesa0\n\t\tlibvulkan1\n\t\tmesa-vulkan-drivers\n\t\"\n\t# shellcheck disable=SC2086,2046\n\tapt-get install -y $(apt-cache show ${deps} 2> /dev/null | grep \"Package:\" | sort -u | cut -d' ' -f2-)\n\n\t# In case the locale is not available, install it\n\t# will ensure we don't fallback to C.UTF-8\n\tif [ -e /etc/locale.gen ] && {\n\t\t! locale -a | grep -qi en_us.utf8 || ! locale -a | grep -qi \"$(echo \"${HOST_LOCALE}\" | tr -d '-')\"\n\t}; then\n\t\tsed -i \"s|#.*en_US.UTF-8|en_US.UTF-8|g\" /etc/locale.gen\n\t\tsed -i \"s|#.*${HOST_LOCALE}|${HOST_LOCALE}|g\" /etc/locale.gen\n\t\tlocale-gen\n\t\tupdate-locale LC_ALL=\"${HOST_LOCALE}\" LANG=\"${HOST_LOCALE}\"\n\t\tdpkg-reconfigure locales\n\tfi\n\n\t# Ensure we have tzdata installed and populated, sometimes container\n\t# images blank the zoneinfo directory, so we reinstall the package to\n\t# ensure population\n\tif [ ! -e /usr/share/zoneinfo/UTC ]; then\n\t\tapt-get --reinstall install tzdata\n\tfi\n\n\t# Install additional packages passed at distrbox-create time\n\tif [ -n \"${container_additional_packages}\" ]; then\n\t\t# shellcheck disable=SC2086\n\t\tapt-get install -y ${container_additional_packages}\n\tfi\n}\n\n# setup_aptrpm will upgrade or setup all packages for apt-get and rpm based systems.\n# Arguments:\n#   None\n# Expected global variables:\n#   upgrade: if we need to upgrade or not\n#   container_additional_packages: additional packages to install during this phase\n# Expected env variables:\n#   None\n# Outputs:\n#   None\nsetup_aptrpm()\n{\n\t# If we need to upgrade, do it and exit, no further action required.\n\tif [ \"${upgrade}\" -ne 0 ]; then\n\t\tapt-get update\n\t\tapt-get dist-upgrade -y\n\t\texit\n\tfi\n\n\tapt-get update\n\t# Check if shell_pkg is available in distro's repo. If not we\n\t# fall back to bash, and we set the SHELL variable to bash so\n\t# that it is set up correctly for the user.\n\tif ! apt-get install -y \"${shell_pkg}\"; then\n\t\tshell_pkg=\"bash\"\n\tfi\n\tdeps=\"\n\t\t${shell_pkg}\n\t\tapt-repo-tools\n\t\tapt-rsync\n\t\tbash-completion\n\t\tbc\n\t\tbzip2\n\t\tcurl\n\t\tcracklib\n\t\tdialog\n\t\tdiffutils\n\t\tfindutils\n\t\tfontconfig\n\t\tgettext\n\t\tglibc\n\t\tglibc-i18ndata\n\t\tgnupg\n\t\tgnupg2\n\t\ticonv\n\t\tiproute2\n\t\tiputils\n\t\tkeyutils\n\t\tless\n\t\tlibcap\n\t\tlibEGL\n\t\tlibGL\n\t\tlibkrb5\n\t\tlibnss-mdns\n\t\tlibnss-myhostname\n\t\tvte3\n\t\tlibvulkan1\n\t\tlsof\n\t\tman-db\n\t\tmount\n\t\tmtr\n\t\tncurses\n\t\topenssh-clients\n\t\tpam\n\t\tpasswd\n\t\tpigz\n\t\tpinentry-common\n\t\tprocps\n\t\tsu\n\t\tsudo\n\t\ttcpdump\n\t\ttime\n\t\ttraceroute\n\t\ttree\n\t\ttzdata\n\t\tunzip\n\t\tutil-linux\n\t\twget\n\t\txauth\n\t\txorg-dri-intel\n\t\txorg-dri-radeon\n\t\txorg-utils\n\t\txz\n\t\tzip\n\t\"\n\t# shellcheck disable=SC2086,2046\n\tapt-get install -y ${deps}\n\n\t# Altlinux hooks. Without them the commands su, sudo, sudoreplay and passwd do not work\n\tif command -v control; then\n\t\tcontrol passwd traditional\n\t\tcontrol sudo public\n\t\tcontrol sudoreplay public\n\t\tcontrol su wheel\n\t\tcontrol pam_mktemp disabled\n\t\tmkdir -p /etc/tcb/\"${container_user_name}\"\n\t\techo \"${container_user_name}::::::::\" > /etc/tcb/\"${container_user_name}\"/shadow\n\t\tsed -i 's/*//g' /etc/passwd\n\n\t\t# ALT Linux ships its own su incompatible with util-linux su flags.\n\t\t# distrobox-enter passes flags like -m, --pty, -s, -c which ALT su rejects.\n\t\t# runuser (from util-linux, always present) accepts the same flags.\n\t\t# Place the wrapper in /usr/local/bin so it is found before /bin/su.\n\t\tmkdir -p /usr/local/bin\n\t\tcat << 'EOF' > /usr/local/bin/su\n#!/bin/sh\nexec /usr/sbin/runuser \"$@\"\nEOF\n\t\tchmod +x /usr/local/bin/su\n\tfi\n\n\t# In case the locale is not available, install it\n\t# will ensure we don't fallback to C.UTF-8\n\tif [ ! -e /usr/share/i18n/charmaps ]; then\n\t\tapt-get --reinstall install -y glibc-i18ndata iconv\n\tfi\n\tif ! locale -a | grep -qi en_us.utf8 || ! locale -a | grep -qi \"${HOST_LOCALE}\"; then\n\t\tLANG=\"${HOST_LOCALE}\" localedef -i \"${HOST_LOCALE_LANG}\" -f \"${HOST_LOCALE_ENCODING}\" \"${HOST_LOCALE}\"\n\tfi\n\n\t# Ensure we have tzdata installed and populated, sometimes container\n\t# images blank the zoneinfo directory, so we reinstall the package to\n\t# ensure population\n\tif [ ! -e /usr/share/zoneinfo/UTC ]; then\n\t\tapt-get --reinstall install -y tzdata\n\tfi\n\n\t# Install additional packages passed at distrbox-create time\n\tif [ -n \"${container_additional_packages}\" ]; then\n\t\t# shellcheck disable=SC2086\n\t\tapt-get install -y ${container_additional_packages}\n\tfi\n}\n\n# setup_dnf will upgrade or setup all packages for dnf/yum based systems.\n# Arguments:\n#   manager: yum or dnf\n# Expected global variables:\n#   upgrade: if we need to upgrade or not\n#   container_additional_packages: additional packages to install during this phase\n# Expected env variables:\n#   None\n# Outputs:\n#   None\nsetup_dnf()\n{\n\tmanager=$1\n\n\t# If we need to upgrade, do it and exit, no further action required.\n\tif [ \"${upgrade}\" -ne 0 ]; then\n\t\t${manager} upgrade -y\n\t\texit\n\tfi\n\t# In dnf family official images, dnf is configured to ignore locale and docs\n\t# This however, results in a rather poor out-of-the-box experience\n\t# So, let's enable them.\n\t[ -e /etc/dnf/dnf.conf ] && sed -i '/tsflags=nodocs/d' /etc/dnf/dnf.conf\n\t[ -e /etc/yum.conf ] && sed -i '/tsflags=nodocs/d' /etc/yum.conf\n\n\t# Check if shell_pkg is available in distro's repo. If not we\n\t# fall back to bash, and we set the SHELL variable to bash so\n\t# that it is set up correctly for the user.\n\tif ! ${manager} install -y \"${shell_pkg}\" 2> /dev/null; then\n\t\tshell_pkg=\"bash\"\n\tfi\n\tflags=\"\"\n\tif [ \"${manager}\" = \"dnf\" ]; then\n\t\tflags=\"--allowerasing\"\n\tfi\n\tdeps=\"\n\t\t${shell_pkg}\n\t\tbash-completion\n\t\tbc\n\t\tbzip2\n\t\tcracklib-dicts\n\t\tcurl\n\t\tdiffutils\n\t\tdnf-plugins-core\n\t\tfindutils\n\t\tglibc-all-langpacks\n\t\tglibc-common\n\t\tglibc-locale-source\n\t\tgnupg2\n\t\tgnupg2-smime\n\t\thostname\n\t\tiproute\n\t\tiputils\n\t\tkeyutils\n\t\tkrb5-libs\n\t\tless\n\t\tlsof\n\t\tman-db\n\t\tman-pages\n\t\tmtr\n\t\tncurses\n\t\tnss-mdns\n\t\topenssh-clients\n\t\tpam\n\t\tpasswd\n\t\tpigz\n\t\tpinentry\n\t\tprocps-ng\n\t\trsync\n\t\tshadow-utils\n\t\tsudo\n\t\ttcpdump\n\t\ttime\n\t\ttraceroute\n\t\ttree\n\t\ttzdata\n\t\tunzip\n\t\tutil-linux\n\t\tutil-linux-script\n\t\tvte-profile\n\t\twget\n\t\twget2-wget\n\t\twhich\n\t\twhois\n\t\twords\n\t\txorg-x11-xauth\n\t\txz\n\t\tzip\n\t\tmesa-dri-drivers\n\t\tmesa-vulkan-drivers\n\t\tvulkan\n\t\"\n\t# shellcheck disable=SC2086,2046,2248\n\t${manager} install ${flags} -y $(${manager} list -q ${deps} |\n\t\tgrep -v \"Packages\" |\n\t\tgrep \"$(uname -m)\" |\n\t\tcut -d' ' -f1)\n\n\t# In case the locale is not available, install it\n\t# will ensure we don't fallback to C.UTF-8\n\tif [ ! -e /usr/share/i18n/charmaps ]; then\n\t\t${manager} reinstall -y glibc-common\n\tfi\n\tif ! locale -a | grep -qi en_us.utf8 || ! locale -a | grep -qi \"$(echo \"${HOST_LOCALE}\" | tr -d '-')\"; then\n\t\tLANG=\"${HOST_LOCALE}\" localedef -i \"${HOST_LOCALE_LANG}\" -f \"${HOST_LOCALE_ENCODING}\" \"${HOST_LOCALE}\"\n\tfi\n\n\t# Ensure we have tzdata installed and populated, sometimes container\n\t# images blank the zoneinfo directory, so we reinstall the package to\n\t# ensure population\n\tif [ ! -e /usr/share/zoneinfo/UTC ]; then\n\t\t${manager} reinstall -y tzdata\n\tfi\n\n\t# Install additional packages passed at distrbox-create time\n\tif [ -n \"${container_additional_packages}\" ]; then\n\t\t# shellcheck disable=SC2086\n\t\t${manager} install -y ${container_additional_packages}\n\tfi\n}\n\n# setup_emerge will upgrade or setup all packages for gentoo based systems.\n# Arguments:\n#   None\n# Expected global variables:\n#   upgrade: if we need to upgrade or not\n#   container_additional_packages: additional packages to install during this phase\n# Expected env variables:\n#   None\n# Outputs:\n#   None\nsetup_emerge()\n{\n\t# Check if the container we are using has a ::gentoo repo defined,\n\t# if it is defined and it is empty, then synchroznize it.\n\tgentoo_repo=\"$(portageq get_repo_path / gentoo)\"\n\tif [ -n \"${gentoo_repo}\" ] && [ ! -e \"${gentoo_repo}\" ]; then\n\t\temerge-webrsync\n\tfi\n\t# If we need to upgrade, do it and exit, no further action required.\n\tif [ \"${upgrade}\" -ne 0 ]; then\n\t\temerge --sync\n\t\texit\n\tfi\n\t# Check if shell_pkg is available in distro's repo. If not we\n\t# fall back to bash, and we set the SHELL variable to bash so\n\t# that it is set up correctly for the user.\n\tif ! emerge --ask=n --autounmask-continue --noreplace --quiet-build \"${shell_pkg}\"; then\n\t\tshell_pkg=\"bash\"\n\tfi\n\tdeps=\"\n\t\tapp-shells/${shell_pkg}\n\t\tapp-crypt/gnupg\n\t\tapp-shells/bash-completion\n\t\tsys-apps/diffutils\n\t\tsys-apps/findutils\n\t\tsys-apps/less\n\t\tsys-libs/ncurses\n\t\tnet-misc/curl\n\t\tapp-crypt/pinentry\n\t\tsys-process/procps\n\t\tsys-apps/shadow\n\t\tapp-admin/sudo\n\t\tsys-devel/bc\n\t\tsys-process/lsof\n\t\tsys-apps/util-linux\n\t\tnet-misc/wget\n\t\"\n\tinstall_pkg=\"\"\n\tfor dep in ${deps}; do\n\t\tif [ \"$(emerge --ask=n --search \"${dep}\" | grep \"Applications found\" | grep -Eo \"[0-9]\")\" -gt 0 ]; then\n\t\t\t# shellcheck disable=SC2086\n\t\t\tinstall_pkg=\"${install_pkg} ${dep}\"\n\t\tfi\n\tdone\n\t# shellcheck disable=SC2086\n\temerge --ask=n --autounmask-continue --noreplace --quiet-build ${install_pkg}\n\n\t# In case the locale is not available, install it\n\t# will ensure we don't fallback to C.UTF-8\n\tif ! locale -a | grep -qi en_us.utf8 || ! locale -a | grep -qi \"$(echo \"${HOST_LOCALE}\" | tr -d '-')\"; then\n\t\tsed -i \"s|#.*en_US.UTF-8|en_US.UTF-8|g\" /etc/locale.gen\n\t\tsed -i \"s|#.*${HOST_LOCALE}|${HOST_LOCALE}|g\" /etc/locale.gen\n\t\tlocale-gen\n\t\tcat << EOF > /etc/env.d/02locale\nLANG=${HOST_LOCALE}\nLC_CTYPE=${HOST_LOCALE}\nEOF\n\tfi\n\n\t# Install additional packages passed at distrbox-create time\n\tif [ -n \"${container_additional_packages}\" ]; then\n\t\t# shellcheck disable=SC2086\n\t\temerge --ask=n --autounmask-continue --noreplace --quiet-build \\\n\t\t\t${container_additional_packages}\n\tfi\n}\n\n# setup_microdnf will upgrade or setup all packages for microdnf based systems.\n# Arguments:\n#   None\n# Expected global variables:\n#   upgrade: if we need to upgrade or not\n#   container_additional_packages: additional packages to install during this phase\n# Expected env variables:\n#   None\n# Outputs:\n#   None\nsetup_microdnf()\n{\n\t# If we need to upgrade, do it and exit, no further action required.\n\tif [ \"${upgrade}\" -ne 0 ]; then\n\t\tmicrodnf upgrade -y\n\t\texit\n\tfi\n\t# Check if shell_pkg is available in distro's repo. If not we\n\t# fall back to bash, and we set the SHELL variable to bash so\n\t# that it is set up correctly for the user.\n\tif ! microdnf install -y \"${shell_pkg}\"; then\n\t\tshell_pkg=\"bash\"\n\tfi\n\tdeps=\"\n\t\t${shell_pkg}\n\t\tbash-completion\n\t\tbc\n\t\tbzip2\n\t\tcracklib-dicts\n\t\tdiffutils\n\t\tdnf-plugins-core\n\t\tfindutils\n\t\tglibc-all-langpacks\n\t\tglibc-common\n\t\tglibc-locale-source\n\t\tgnupg2\n\t\tgnupg2-smime\n\t\thostname\n\t\tiproute\n\t\tiputils\n\t\tkeyutils\n\t\tkrb5-libs\n\t\tless\n\t\tlsof\n\t\tman-db\n\t\tman-pages\n\t\tmtr\n\t\tncurses\n\t\tnss-mdns\n\t\topenssh-clients\n\t\tpam\n\t\tpasswd\n\t\tpigz\n\t\tpinentry\n\t\tprocps-ng\n\t\trsync\n\t\tshadow-utils\n\t\tsudo\n\t\ttcpdump\n\t\ttime\n\t\ttraceroute\n\t\ttree\n\t\ttzdata\n\t\tunzip\n\t\tutil-linux\n\t\tvte-profile\n\t\twget\n\t\twhich\n\t\twhois\n\t\twords\n\t\txorg-x11-xauth\n\t\txz\n\t\tzip\n\t\tmesa-dri-drivers\n\t\tmesa-vulkan-drivers\n\t\tvulkan\n\t\"\n\tinstall_pkg=\"\"\n\tfor dep in ${deps}; do\n\t\tif [ \"$(microdnf repoquery \"${dep}\" | wc -l)\" -gt 0 ]; then\n\t\t\tinstall_pkg=\"${install_pkg} ${dep}\"\n\t\tfi\n\tdone\n\t# shellcheck disable=SC2086,SC2046\n\tmicrodnf install -y ${install_pkg}\n\n\t# In case the locale is not available, install it\n\t# will ensure we don't fallback to C.UTF-8\n\tif [ ! -e /usr/share/zoneinfo/UTC ]; then\n\t\tmicrodnf reinstall -y tzdata || microdnf install -y glibc-common\n\tfi\n\tif ! locale -a | grep -qi en_us.utf8 || ! locale -a | grep -qi \"$(echo \"${HOST_LOCALE}\" | tr -d '-')\"; then\n\t\tLANG=\"${HOST_LOCALE}\" localedef -i \"${HOST_LOCALE_LANG}\" -f \"${HOST_LOCALE_ENCODING}\" \"${HOST_LOCALE}\"\n\tfi\n\n\t# Ensure we have tzdata installed and populated, sometimes container\n\t# images blank the zoneinfo directory, so we reinstall the package to\n\t# ensure population\n\tif [ ! -e /usr/share/zoneinfo/UTC ]; then\n\t\tmicrodnf reinstall -y tzdata || microdnf install -y tzdata\n\tfi\n\n\t# Install additional packages passed at distrbox-create time\n\tif [ -n \"${container_additional_packages}\" ]; then\n\t\t# shellcheck disable=SC2086\n\t\tmicrodnf install -y ${container_additional_packages}\n\tfi\n}\n\n# setup_pacman will upgrade or setup all packages for pacman based systems.\n# Arguments:\n#   None\n# Expected global variables:\n#   upgrade: if we need to upgrade or not\n#   container_additional_packages: additional packages to install during this phase\n# Expected env variables:\n#   None\n# Outputs:\n#   None\nsetup_pacman()\n{\n\t# Update the package repository cache exactly once before installing packages.\n\tpacman -S -y -y\n\n\t# If we need to upgrade, do it and exit, no further action required.\n\tif [ \"${upgrade}\" -ne 0 ]; then\n\t\tpacman -S -u --noconfirm\n\t\texit\n\tfi\n\t# In archlinux official images, pacman is configured to ignore locale and docs\n\t# This however, results in a rather poor out-of-the-box experience\n\t# So, let's enable them.\n\tsed -i \"s|NoExtract.*||g\" /etc/pacman.conf\n\tsed -i \"s|NoProgressBar.*||g\" /etc/pacman.conf\n\n\tpacman -S -u --noconfirm\n\t# Check if shell_pkg is available in distro's repo. If not we\n\t# fall back to bash, and we set the SHELL variable to bash so\n\t# that it is set up correctly for the user.\n\tif ! pacman -S --needed --noconfirm \"${shell_pkg}\"; then\n\t\tshell_pkg=\"bash\"\n\tfi\n\tdeps=\"\n\t\t${shell_pkg}\n\t\tbash-completion\n\t\tbc\n\t\tcurl\n\t\tdiffutils\n\t\tfindutils\n\t\tglibc\n\t\tgnupg\n\t\tiputils\n\t\tinetutils\n\t\tkeyutils\n\t\tless\n\t\tlsof\n\t\tman-db\n\t\tman-pages\n\t\tmlocate\n\t\tmtr\n\t\tncurses\n\t\tnss-mdns\n\t\topenssh\n\t\tpigz\n\t\tpinentry\n\t\tprocps-ng\n\t\trsync\n\t\tshadow\n\t\tsudo\n\t\ttcpdump\n\t\ttime\n\t\ttraceroute\n\t\ttree\n\t\ttzdata\n\t\tunzip\n\t\tutil-linux\n\t\tutil-linux-libs\n\t\tvte-common\n\t\twget\n\t\twords\n\t\txorg-xauth\n\t\tzip\n\t\tmesa\n\t\tvulkan-intel\n\t\tvulkan-radeon\n\t\"\n\t# shellcheck disable=SC2086,2046\n\tpacman -S --needed --noconfirm $(pacman -Ssq | grep -E \"^($(echo ${deps} | tr ' ' '|'))$\")\n\n\tif [ ! -e \"/usr/share/i18n/locales${HOST_LOCALE}\" ]; then\n\t\tpacman -S --noconfirm glibc glibc-locales\n\tfi\n\n\t# Ensure we have tzdata installed and populated, sometimes container\n\t# images blank the zoneinfo directory, so we reinstall the package to\n\t# ensure population\n\tif [ ! -e /usr/share/zoneinfo/UTC ]; then\n\t\tpacman -S --noconfirm tzdata\n\tfi\n\n\t# In case the locale is not available, install it\n\t# will ensure we don't fallback to C.UTF-8\n\tif ! locale -a | grep -qi en_us.utf8 || ! locale -a | grep -qi \"$(echo \"${HOST_LOCALE}\" | tr -d '-')\"; then\n\t\tsed -i \"s|#.*en_US.UTF-8|en_US.UTF-8|g\" /etc/locale.gen\n\t\tsed -i \"s|#.*${HOST_LOCALE}|${HOST_LOCALE}|g\" /etc/locale.gen\n\t\tlocale-gen -a\n\tfi\n\n\t# Install additional packages passed at distrbox-create time\n\tif [ -n \"${container_additional_packages}\" ]; then\n\t\t# shellcheck disable=SC2086\n\t\tpacman -S --needed --noconfirm ${container_additional_packages}\n\tfi\n}\n\n# setup_slackpkg will upgrade or setup all packages for slackware based systems.\n# Arguments:\n#   None\n# Expected global variables:\n#   upgrade: if we need to upgrade or not\n#   container_additional_packages: additional packages to install during this phase\n# Expected env variables:\n#   None\n# Outputs:\n#   None\nsetup_slackpkg()\n{\n\t# If we need to upgrade, do it and exit, no further action required.\n\tif [ \"${upgrade}\" -ne 0 ]; then\n\t\tyes | slackpkg upgrade-all -default_answer=yes -batch=yes\n\t\texit\n\tfi\n\tslackpkg update\n\t# Check if shell_pkg is available in distro's repo. If not we\n\t# fall back to bash, and we set the SHELL variable to bash so\n\t# that it is set up correctly for the user.\n\tif ! yes | slackpkg install -default_answer=yes -batch=yes \"${shell_pkg}\"; then\n\t\tshell_pkg=\"bash\"\n\tfi\n\tdeps=\"\n\t\t${shell_pkg}\n\t\tbash-completion\n\t\tbc\n\t\tcurl\n\t\tdiffutils\n\t\tfindutils\n\t\tglew\n\t\tglibc\n\t\tglu\n\t\tgnupg2\n\t\tiputils\n\t\tless\n\t\tlibX11\n\t\tlibXau\n\t\tlibXdamage\n\t\tlibXdmcp\n\t\tlibXext\n\t\tlibXfixes\n\t\tlibXxf86vm\n\t\tlibdrm\n\t\tlibvte-2\n\t\tlibxcb\n\t\tlibxcb-dri2\n\t\tlibxcb-dri3\n\t\tlibxcb-glx\n\t\tlibxcb-present\n\t\tlibxcb-randr\n\t\tlibxcb-render\n\t\tlibxcb-shape\n\t\tlibxcb-sync\n\t\tlibxcb-xfixes\n\t\tlibxshmfence\n\t\tlsof\n\t\tman\n\t\tmesa\n\t\tncurses\n\t\topenssh\n\t\tpinentry\n\t\tprocps\n\t\trsync\n\t\tshadow\n\t\tssh\n\t\tsudo\n\t\ttime\n\t\twget\n\t\txauth\n\t\"\n\tinstall_pkg=\"\"\n\tdep=\"\"\n\tfor dep in ${deps}; do\n\t\tif ! slackpkg search \"${dep}\" | grep -q \"No package name matches the pattern\"; then\n\t\t\tinstall_pkg=\"${install_pkg} ${dep}\"\n\t\tfi\n\tdone\n\n\trm -f /var/lock/slackpkg.*\n\n\t# shellcheck disable=SC2086\n\tyes | slackpkg install -default_answer=yes -batch=yes ${install_pkg}\n\n\t# Install additional packages passed at distrbox-create time\n\tif [ -n \"${container_additional_packages}\" ]; then\n\t\t# shellcheck disable=SC2086\n\t\tyes | slackpkg install -default_answer=yes -batch=yes \\\n\t\t\t${container_additional_packages}\n\tfi\n}\n\n# setup_xbps will upgrade or setup all packages for xbps based systems.\n# Arguments:\n#   None\n# Expected global variables:\n#   upgrade: if we need to upgrade or not\n#   container_additional_packages: additional packages to install during this phase\n# Expected env variables:\n#   None\n# Outputs:\n#   None\nsetup_xbps()\n{\n\t# If we need to upgrade, do it and exit, no further action required.\n\tif [ \"${upgrade}\" -ne 0 ]; then\n\t\txbps-install -Syu\n\t\texit\n\tfi\n\t# Ensure we avoid errors by keeping xbps updated\n\txbps-install -Syu xbps\n\n\t# Check if shell_pkg is available in distro's repo. If not we\n\t# fall back to bash, and we set the SHELL variable to bash so\n\t# that it is set up correctly for the user.\n\tif ! xbps-install -Sy \"${shell_pkg}\"; then\n\t\tshell_pkg=\"bash\"\n\tfi\n\tdeps=\"\n\t\t${shell_pkg}\n\t\tbash-completion\n\t\tbc\n\t\tbzip2\n\t\tcurl\n\t\tdiffutils\n\t\tfindutils\n\t\tgnupg2\n\t\tinetutils-ping\n\t\tiproute2\n\t\tless\n\t\tlsof\n\t\tman-db\n\t\tmit-krb5-client\n\t\tmit-krb5-libs\n\t\tmtr\n\t\tncurses-base\n\t\tnss\n\t\topenssh\n\t\tpigz\n\t\tpinentry-tty\n\t\tprocps-ng\n\t\trsync\n\t\tshadow\n\t\tsudo\n\t\ttime\n\t\ttraceroute\n\t\ttree\n\t\ttzdata\n\t\tunzip\n\t\tutil-linux\n\t\txauth\n\t\txz\n\t\tzip\n\t\twget\n\t\tvte3\n\t\tmesa-dri\n\t\tvulkan-loader\n\t\tmesa-vulkan-intel\n\t\tmesa-vulkan-radeon\n\t\"\n\t# shellcheck disable=SC2086,2046\n\txbps-install -Sy $(xbps-query -Rs '*' | awk '{print $2}' | sed 's/-[^-]*$//' | grep -E \"^($(echo ${deps} | tr ' ' '|'))$\")\n\n\t# In case the locale is not available, install it\n\t# will ensure we don't fallback to C.UTF-8\n\tif command -v locale && {\n\t\t! locale -a | grep -qi en_us.utf8 || ! locale -a | grep -qi \"$(echo \"${HOST_LOCALE}\" | tr -d '-')\"\n\t}; then\n\t\tsed -i \"s|#.*en_US.UTF-8|en_US.UTF-8|g\" /etc/default/libc-locales\n\t\tsed -i \"s|#.*${HOST_LOCALE}|${HOST_LOCALE}|g\" /etc/default/libc-locales\n\t\txbps-reconfigure --force glibc-locales\n\tfi\n\n\t# Ensure we have tzdata installed and populated, sometimes container\n\t# images blank the zoneinfo directory, so we reinstall the package to\n\t# ensure population\n\tif [ ! -e /usr/share/zoneinfo/UTC ]; then\n\t\txbps-install --force -y tzdata\n\tfi\n\n\t# Install additional packages passed at distrbox-create time\n\tif [ -n \"${container_additional_packages}\" ]; then\n\t\t# shellcheck disable=SC2086\n\t\txbps-install -Sy ${container_additional_packages}\n\tfi\n}\n\n# setup_zypper will upgrade or setup all packages for zypper based systems.\n# Arguments:\n#   None\n# Expected global variables:\n#   upgrade: if we need to upgrade or not\n#   container_additional_packages: additional packages to install during this phase\n# Expected env variables:\n#   None\n# Outputs:\n#   None\nsetup_zypper()\n{\n\t# If we need to upgrade, do it and exit, no further action required.\n\tif [ \"${upgrade}\" -ne 0 ]; then\n\t\tzypper dup -y\n\t\texit\n\tfi\n\tif ! zypper install -y \"${shell_pkg}\"; then\n\t\tshell_pkg=\"bash\"\n\tfi\n\n\t# In openSUSE official images, zypper is configured to ignore recommended\n\t# packages (i.e., weak dependencies). This however, results in a rather\n\t# poor out-of-the-box experience (e.g., when trying to run GUI apps).\n\t# So, let's enable them. For the same reason, we make sure we install\n\t# docs.\n\tif [ -d /etc/zypp/zypp.conf.d ]; then\n\t\tcat << EOF > /etc/zypp/zypp.conf.d/99-distrobox.conf\n[main]\nsolver.onlyRequires = false\nrpm.install.excludedocs = no\nEOF\n\telse\n\t\tsed -i 's/.*solver.onlyRequires.*/solver.onlyRequires = false/g' /etc/zypp/zypp.conf\n\t\tsed -i 's/.*rpm.install.excludedocs.*/rpm.install.excludedocs = no/g' /etc/zypp/zypp.conf\n\tfi\n\n\t# With recommended packages, something might try to pull in\n\t# parallel-printer-support which can't be installed in rootless containers.\n\t# Since we very much likely never need it, just lock it\n\tzypper al parallel-printer-support\n\t# Check if shell_pkg is available in distro's repo. If not we\n\t# fall back to bash, and we set the SHELL variable to bash so\n\t# that it is set up correctly for the user.\n\tdeps=\"\n\t\t${shell_pkg}\n\t\tbash-completion\n\t\tbc\n\t\tbzip2\n\t\tcurl\n\t\tdiffutils\n\t\tfindutils\n\t\tglibc-locale\n\t\tglibc-locale-base\n\t\tgnupg\n\t\thostname\n\t\tiputils\n\t\tkeyutils\n\t\tless\n\t\tlibvte-2*\n\t\tlsof\n\t\tman\n\t\tman-pages\n\t\tmtr\n\t\tncurses\n\t\tnss-mdns\n\t\topenssh-clients\n\t\tpam\n\t\tpam-extra\n\t\tpigz\n\t\tpinentry\n\t\tprocps\n\t\trsync\n\t\tshadow\n\t\tsudo\n\t\tsystem-group-wheel\n\t\tsystemd\n\t\ttime\n\t\ttimezone\n\t\ttree\n\t\tunzip\n\t\tutil-linux\n\t\tutil-linux-systemd\n\t\twget\n\t\twords\n\t\txauth\n\t\tzip\n\t\tMesa-dri\n\t\tlibvulkan1\n\t\tlibvulkan_intel\n\t\tlibvulkan_radeon\n\t\"\n\t# Mark gpg errors (exit code 106) as non-fatal, but don't pull anything from unverified repos\n\t# shellcheck disable=SC2086,SC2046\n\tzypper -n install -y $(zypper -n -q se --match-exact ${deps} | grep -e 'package$' | cut -d'|' -f2) || [ ${?} = 106 ]\n\n\t# In case the locale is not available, install it\n\t# will ensure we don't fallback to C.UTF-8\n\tif ! locale -a | grep -qi en_us.utf8 || ! locale -a | grep -qi \"$(echo \"${HOST_LOCALE}\" | tr -d '-')\"; then\n\t\tLANG=\"${HOST_LOCALE}\" localedef -i \"${HOST_LOCALE_LANG}\" -f \"${HOST_LOCALE_ENCODING}\" \"${HOST_LOCALE}\" || true\n\tfi\n\n\t# Ensure we have tzdata installed and populated, sometimes container\n\t# images blank the zoneinfo directory, so we reinstall the package to\n\t# ensure population\n\tif [ ! -e /usr/share/zoneinfo/UTC ]; then\n\t\tzypper install -f -y timezone\n\tfi\n\n\t# Install additional packages passed at distrbox-create time\n\tif [ -n \"${container_additional_packages}\" ]; then\n\t\t# shellcheck disable=SC2086\n\t\tzypper install -y ${container_additional_packages}\n\tfi\n}\n\n# Check if all commands are installed.\n# Arguments:\n#   None\n# Expected global variables:\n#   shell_pkg: shell package of the container shell\n# Expected env variables:\n#   None\n# Outputs:\n#   None\ncheck_missing_packages()\n{\n\tdependencies=\"\n\t\tbc\n\t\tbzip2\n\t\tchpasswd\n\t\tcurl\n\t\tdiff\n\t\tfind\n\t\tfindmnt\n\t\tgpg\n\t\thostname\n\t\tless\n\t\tlsof\n\t\tman\n\t\tmount\n\t\tpasswd\n\t\tpigz\n\t\tpinentry\n\t\tping\n\t\tps\n\t\trsync\n\t\tscript\n\t\tssh\n\t\tsudo\n\t\ttime\n\t\ttree\n\t\tumount\n\t\tunzip\n\t\tuseradd\n\t\twc\n\t\twget\n\t\txauth\n\t\tzip\n\t\t${shell_pkg}\n\t\"\n\tfor dep in ${dependencies}; do\n\t\t! command -v \"${dep}\" && return 1\n\tdone\n\treturn 0\n}\n\n# Ensure we have the least minimal path of standard Linux File System set\nPATH=\"${PATH}:/bin:/sbin:/usr/bin:/usr/sbin\"\n\n# Setup pkg manager exceptions and excludes\nif command -v apt-get; then\n\tif command -v rpm; then\n\t\tsetup_rpm_exceptions\n\telse\n\t\tsetup_deb_exceptions\n\tfi\nelif command -v pacman; then\n\tsetup_pacman_exceptions\nelif command -v xbps-install; then\n\tsetup_xbps_exceptions\nelif command -v zypper; then\n\tsetup_rpm_exceptions\nelif command -v dnf; then\n\tsetup_rpm_exceptions\nelif command -v microdnf; then\n\tsetup_rpm_exceptions\nelif command -v yum; then\n\tsetup_rpm_exceptions\nfi\n\n# Check if dependencies are met for the script to run.\nif [ \"${upgrade}\" -ne 0 ] || [ ! -e /.containersetupdone ]; then\n\n\t# Detect the available package manager\n\t# install minimal dependencies needed to bootstrap the container:\n\t#\tthe same shell that's on the host + ${dependencies}\n\tif command -v apk; then\n\t\tsetup_apk\n\telif command -v apt-get; then\n\t\tif command -v rpm; then\n\t\t\tsetup_aptrpm\n\t\telse\n\t\t\tsetup_apt\n\t\tfi\n\telif command -v emerge; then\n\t\tsetup_emerge\n\telif command -v pacman; then\n\t\tsetup_pacman\n\telif command -v slackpkg; then\n\t\tsetup_slackpkg\n\telif command -v xbps-install; then\n\t\tsetup_xbps\n\telif command -v zypper; then\n\t\tsetup_zypper\n\telif command -v dnf; then\n\t\tsetup_dnf dnf\n\telif command -v microdnf; then\n\t\tsetup_microdnf\n\telif command -v yum; then\n\t\tsetup_dnf yum\n\telse\n\t\tprintf \"Error: could not find a supported package manager.\\n\"\n\t\tprintf \"Error: could not set up base dependencies.\\n\"\n\t\t# Exit as command not found\n\t\texit 127\n\tfi\n\tif [ ! -e /.containersetupdone ]; then\n\t\tif ! check_missing_packages; then\n\t\t\tprintf \"Warning: some dependencies are missing.\\n\"\n\t\tfi\n\t\ttouch /.containersetupdone\n\tfi\nfi\n\n# Set SHELL to the install path inside the container\nSHELL=\"$(command -v \"${shell_pkg}\")\"\n\n# Attempt to download host-spawn during init, we don't care if it fails, so let's\n# continue in that case\n/usr/bin/distrobox-host-exec -Y test 2> /dev/null > /dev/null || :\n\n# If xdg-open is not present and we don't have an init system, do a link of it.\n# This is handy to handle opening of links, files and apps from inside the container\n# into the host.\nif [ \"${init}\" -eq 0 ] && ! command -v xdg-open; then\n\tmkdir -p /usr/local/bin/\n\tln -sf /usr/bin/distrobox-host-exec /usr/local/bin/xdg-open\nfi\n\n# If flatpak is not present, do a link of it. This is handy to handle opening of\n# links, files and apps from inside the container into the host.\n# Note: we're using /usr/bin instead of /usr/local/bin because xdg-open will read\n# the desktopfile, which will contain an absolute path of /usr/bin/flatpak\nif ! command -v flatpak; then\n\tln -sf /usr/bin/distrobox-host-exec /usr/bin/flatpak\nfi\n\n###############################################################################\n\n# Ensure compatibility with older versions of su, this will allow to specify\n# the --pty flag\n#\n# This won't work well on very old distros with su version from util-linux\n# before version 2.34 or other su implementations but will give an usable\n# shell nonetheless\nif [ ! -e /usr/local/bin/su ] && {\n\t! su --version | grep -q util-linux ||\n\t\tsu --version | awk '{printf  \"%s\\n%s\", $4, 2.34}' | sort --check=quiet --version-sort\n}; then\n\tcat << EOF > /usr/local/bin/su\n#!/bin/sh\n\nfor i do\n  [ \"\\$i\" = --pty ] || set -- \"\\$@\" \"\\$i\"\n  shift\ndone\n\n/bin/su \"\\$@\"\nEOF\n\tchmod +x /usr/local/bin/su\nfi\n\n###############################################################################\nprintf \"distrobox: Setting up devpts mounts...\\n\"\n\n# First we need to ensure we have a tty group to assign /dev/pts to\nif ! grep -q tty /etc/group; then\n\tprintf \"%s\" 'tty:x:5:' >> /etc/group\nfi\n\n# Instantiate a new /dev/pts mount, this will ensure pseudoterminals are container-scoped\n# and make easier in case of initful containers to have a separate /dev/console\n#\n# Podman supports a mount option to do this at creation time, but we're doing it\n# here to support also other container rmanagers which does not support that flag\nmount -t devpts devpts -o noexec,nosuid,newinstance,ptmxmode=0666,mode=0620,gid=tty /dev/pts/\nmount --bind /dev/pts/ptmx /dev/ptmx\n\n# Change mount propagation to shared to make the environment more similar to a\n# modern Linux system, e.g. with Systemd as PID 1.\nmount --make-rshared /\n###############################################################################\n\n###############################################################################\nprintf \"distrobox: Setting up read-only mounts...\\n\"\n\nfor host_mount_ro in ${HOST_MOUNTS_RO}; do\n\t# Mounting read-only in a user namespace will trigger a check to see if certain\n\t# \"locked\" flags (line noexec,nodev,nosuid) are changed. This ensures we explicitly reuse those flags.\n\tlocked_flags=\"$(get_locked_mount_flags /run/host\"${host_mount_ro}\")\"\n\tif ! mount_bind /run/host\"${host_mount_ro}\" \"${host_mount_ro}\" ro\"${locked_flags:+,${locked_flags}}\"; then\n\t\tprintf \"Warning: %s integration with the host failed, runtime sync for %s disabled.\\n\" \"${host_mount_ro}\" \"${host_mount_ro}\"\n\t\t# Fallback options for files, we do a hard copy of it\n\t\tif [ -f /run/host\"${host_mount_ro}\" ]; then\n\t\t\tif ! (rm -f \"${host_mount_ro}\" && cp -f /run/host\"${host_mount_ro}\" \"${host_mount_ro}\"); then\n\t\t\t\tprintf \"Warning: Hard copy failed. Error: %s\\n\" \"$(cp -f /run/host\"${host_mount_ro}\" \"${host_mount_ro}\" 2>&1)\"\n\t\t\tfi\n\t\tfi\n\tfi\ndone\n###############################################################################\n\n###############################################################################\nprintf \"distrobox: Setting up read-write mounts...\\n\"\n\n# On some ostree systems, home is in /var/home, but most of the software expects\n# it to be in /home. In the hosts systems this is fixed by using a symlink.\n# Do something similar here with a bind mount.\nif [ -e \"/var/home/${container_user_name}\" ]; then\n\tif ! mount_bind \"/run/host/var/home/${container_user_name}\" \"/home/${container_user_name}\"; then\n\t\tprintf \"Warning: Cannot bind mount %s to /run/host%s\\n\" \"/var/home\" \"/home\"\n\tfi\nfi\n\nfor host_mount in ${HOST_MOUNTS}; do\n\tif ! mount_bind /run/host\"${host_mount}\" \"${host_mount}\"; then\n\t\tprintf \"Warning: Cannot bind mount %s to /run/host%s\\n\" \"${host_mount}\" \"${host_mount}\"\n\tfi\ndone\n###############################################################################\n\n###############################################################################\nprintf \"distrobox: Setting up host's sockets integration...\\n\"\n# Find all the user's socket and mount them inside the container\n# this will allow for continuity of functionality between host and container\n#\n# for example using `podman --remote` to control the host's podman from inside\n# the container or accessing docker and libvirt sockets.\nhost_sockets=\"$(find /run/host/run \\\n\t-xdev \\\n\t-path /run/host/run/media -prune -o \\\n\t-path /run/host/run/timeshift -prune -o \\\n\t-name 'user' -prune -o \\\n\t-name 'bees' -prune -o \\\n\t-name 'nscd' -prune -o \\\n\t-name 'schroot' -prune -o \\\n\t-name 'system_bus_socket' -prune -o \\\n\t-name 'io.systemd.Multiplexer' -prune -o \\\n\t-name 'io.systemd.DropIn' -prune -o \\\n\t-name 'io.systemd.NameServiceSwitch' -prune -o \\\n\t-type s -print \\\n\t2> /dev/null || :)\"\n\n# we're excluding system dbus socket, nscd socket and systemd-userdbd sockets here. Including them will\n# create many problems with package managers thinking they have access to\n# system dbus, user auth cache misused or query wrong user information.\nfor host_socket in ${host_sockets}; do\n\tcontainer_socket=\"${host_socket#/run/host}\"\n\t# Check if the socket already exists or the symlink already exists\n\tif [ ! -S \"${container_socket}\" ] && [ ! -L \"${container_socket}\" ]; then\n\t\t# link it.\n\t\trm -f \"${container_socket}\"\n\t\tmkdir -p \"$(dirname \"${container_socket}\")\"\n\t\tif ! ln -s \"${host_socket}\" \"${container_socket}\"; then\n\t\t\tprintf \"Warning: Cannot link socket %s to %s\\n\" \"${host_socket}\" \"${container_socket}\"\n\t\tfi\n\tfi\ndone\n###############################################################################\n\n# If --nvidia, we try to integrate host's nvidia drivers in to the guest\nif [ \"${nvidia}\" -eq 1 ]; then\n\tprintf \"distrobox: Setting up host's nvidia integration...\\n\"\n\n\t# Refresh ldconfig cache, also detect if there are empty files remaining\n\t# and clean them.\n\t# This could happen when upgrading drivers and changing versions.\n\tfind /usr/lib* -empty -iname \"*.so.*\" -exec sh -c 'rm -rf \"$1\" || umount \"$1\" && rm -rf \"$1\"' sh {} ';' || :\n\tfind /usr/ /etc/ -empty -iname \"*nvidia*\" -exec sh -c 'rm -rf \"$1\" || umount \"$1\" && rm -rf \"$1\"' sh {} ';' || :\n\n\t# First we find all generic config files we might need\n\tNVIDIA_FILES=\"$(find /run/host/etc/ -not -type d \\\n\t\t-wholename \"*nvidia*\" || :)\"\n\tfor nvidia_file in ${NVIDIA_FILES}; do\n\t\tdest_file=\"$(printf \"%s\" \"${nvidia_file}\" | sed 's|/run/host||g')\"\n\n\t\tif [ ! -e \"$(dirname \"${dest_file}\")\" ]; then\n\t\t\tif ! mkdir -p \"$(dirname \"${dest_file}\")\"; then\n\t\t\t\tprintf \"Warning: skpping file %s, %s mounted as read-only\\n\" \"${dest_file}\" \"$(dirname \"${dest_file}\")\"\n\t\t\t\tcontinue\n\t\t\tfi\n\t\tfi\n\t\tif [ ! -w \"$(dirname \"${dest_file}\")\" ]; then\n\t\t\tprintf \"Warning: skpping file %s, %s mounted as read-only\\n\" \"${dest_file}\" \"$(dirname \"${dest_file}\")\"\n\t\t\tcontinue\n\t\tfi\n\n\t\ttype=\"file\"\n\t\tif [ -L \"${nvidia_file}\" ]; then\n\t\t\ttype=\"link\"\n\t\tfi\n\n\t\tif [ \"${type}\" = \"link\" ]; then\n\t\t\tnvidia_file=\"$(readlink -fm \"${nvidia_file}\")\"\n\t\tfi\n\t\t# Mounting read-only in a user namespace will trigger a check to see if certain\n\t\t# \"locked\" flags (line noexec,nodev,nosuid) are changed. This ensures we explicitly reuse those flags.\n\t\tlocked_flags=\"$(get_locked_mount_flags \"${nvidia_file}\")\"\n\t\tmount_bind \"${nvidia_file}\" \"${dest_file}\" ro\"${locked_flags:+,${locked_flags}}\"\n\tdone\n\n\t# Then we find all non-lib files we need, this includes\n\t#       - egl files\n\t#       - icd files\n\t#       - doc files\n\t#       - src files\n\tNVIDIA_CONFS=\"$(find /run/host/usr/ -not -type d \\\n\t\t-wholename \"*glvnd/egl_vendor.d/10_nvidia.json\" \\\n\t\t-o -wholename \"*X11/xorg.conf.d/10-nvidia.conf\" \\\n\t\t-o -wholename \"*X11/xorg.conf.d/nvidia-drm-outputclass.conf\" \\\n\t\t-o -wholename \"*egl/egl_external_platform.d/10_nvidia_wayland.json\" \\\n\t\t-o -wholename \"*egl/egl_external_platform.d/15_nvidia_gbm.json\" \\\n\t\t-o -wholename \"*nvidia/nvoptix.bin\" \\\n\t\t-o -wholename \"*vulkan/icd.d/nvidia_icd*.json\" \\\n\t\t-o -wholename \"*vulkan/icd.d/nvidia_layers.json\" \\\n\t\t-o -wholename \"*vulkan/implicit_layer.d/nvidia_layers.json\" \\\n\t\t-o -wholename \"*nvidia.icd\" \\\n\t\t-o -wholename \"*nvidia.yaml\" \\\n\t\t-o -wholename \"*nvidia.json\" || :)\"\n\tfor nvidia_file in ${NVIDIA_CONFS}; do\n\t\tdest_file=\"$(printf \"%s\" \"${nvidia_file}\" | sed 's|/run/host||g')\"\n\n\t\tif [ ! -e \"$(dirname \"${dest_file}\")\" ]; then\n\t\t\tif ! mkdir -p \"$(dirname \"${dest_file}\")\"; then\n\t\t\t\tprintf \"Warning: skpping file %s, %s mounted as read-only\\n\" \"${dest_file}\" \"$(dirname \"${dest_file}\")\"\n\t\t\t\tcontinue\n\t\t\tfi\n\t\tfi\n\t\tif [ ! -w \"$(dirname \"${dest_file}\")\" ]; then\n\t\t\tprintf \"Warning: skpping file %s, %s mounted as read-only\\n\" \"${dest_file}\" \"$(dirname \"${dest_file}\")\"\n\t\t\tcontinue\n\t\tfi\n\t\t# Mounting read-only in a user namespace will trigger a check to see if certain\n\t\t# \"locked\" flags (line noexec,nodev,nosuid) are changed. This ensures we explicitly reuse those flags.\n\t\tlocked_flags=\"$(get_locked_mount_flags \"${nvidia_file}\")\"\n\t\tmount_bind \"${nvidia_file}\" \"${dest_file}\" ro\"${locked_flags:+,${locked_flags}}\"\n\tdone\n\n\t# Then we find all the CLI utilities\n\tNVIDIA_BINARIES=\"$(find /run/host/bin/ /run/host/sbin/ /run/host/usr/bin/ /run/host/usr/sbin/ -not -type d \\\n\t\t-iname \"*nvidia*\" || :)\"\n\tfor nvidia_file in ${NVIDIA_BINARIES}; do\n\t\tdest_file=\"$(printf \"%s\" \"${nvidia_file}\" | sed 's|/run/host||g')\"\n\n\t\tif [ ! -e \"$(dirname \"${dest_file}\")\" ]; then\n\t\t\tif ! mkdir -p \"$(dirname \"${dest_file}\")\"; then\n\t\t\t\tprintf \"Warning: skpping file %s, %s mounted as read-only\\n\" \"${dest_file}\" \"$(dirname \"${dest_file}\")\"\n\t\t\t\tcontinue\n\t\t\tfi\n\t\tfi\n\t\tif [ ! -w \"$(dirname \"${dest_file}\")\" ]; then\n\t\t\tprintf \"Warning: skpping file %s, %s mounted as read-only\\n\" \"${dest_file}\" \"$(dirname \"${dest_file}\")\"\n\t\t\tcontinue\n\t\tfi\n\n\t\ttype=\"file\"\n\t\tif [ -L \"${nvidia_file}\" ]; then\n\t\t\ttype=\"link\"\n\t\tfi\n\n\t\tif [ \"${type}\" = \"link\" ]; then\n\t\t\tnvidia_file=\"$(readlink -fm \"${nvidia_file}\")\"\n\t\tfi\n\t\t# Mounting read-only in a user namespace will trigger a check to see if certain\n\t\t# \"locked\" flags (line noexec,nodev,nosuid) are changed. This ensures we explicitly reuse those flags.\n\t\tlocked_flags=\"$(get_locked_mount_flags \"${nvidia_file}\")\"\n\t\tmount_bind \"${nvidia_file}\" \"${dest_file}\" ro\"${locked_flags:+,${locked_flags}}\"\n\tdone\n\n\t# Find where the system expects libraries to be put\n\tlib32_dir=\"/usr/lib/\"\n\tlib64_dir=\"/usr/lib/\"\n\tif [ -e \"/usr/lib/x86_64-linux-gnu\" ]; then\n\t\tlib64_dir=\"/usr/lib/x86_64-linux-gnu/\"\n\t\tlib32_dir=\"/usr/lib/i386-linux-gnu/\"\n\telif [ -e \"/usr/lib64\" ]; then\n\t\tlib64_dir=\"/usr/lib64/\"\n\tfi\n\tif [ -e \"/usr/lib32\" ]; then\n\t\tlib32_dir=\"/usr/lib32/\"\n\tfi\n\n\t# Then we find all the \".so\" libraries, these are searched separately\n\t# because we need to extract the relative path to mount them in the\n\t# correct path based on the guest's setup\n\t#\n\t# /usr/lib64 is common in Arch or RPM based distros, while /usr/lib/x86_64-linux-gnu is\n\t# common on Debian derivatives, so we need to adapt between the two nomenclatures.\n\tNVIDIA_LIBS=\"$(find /run/host/usr/lib*/ -not -type d \\\n\t\t-iname \"*lib*nvidia*.so*\" \\\n\t\t-o -iname \"*nvidia*.so*\" \\\n\t\t-o -iname \"libcuda*.so*\" \\\n\t\t-o -iname \"libnvcuvid*\" \\\n\t\t-o -iname \"libnvoptix*\" || :)\"\n\tfor nvidia_lib in ${NVIDIA_LIBS}; do\n\t\tdest_file=\"$(printf \"%s\" \"${nvidia_lib}\" |\n\t\t\tsed \"s|/run/host/usr/lib/x86_64-linux-gnu/|${lib64_dir}|g\" |\n\t\t\tsed \"s|/run/host/usr/lib/i386-linux-gnu/|${lib32_dir}|g\" |\n\t\t\tsed \"s|/run/host/usr/lib64/|${lib64_dir}|g\" |\n\t\t\tsed \"s|/run/host/usr/lib32/|${lib32_dir}|g\" |\n\t\t\tsed \"s|/run/host/usr/lib/|${lib32_dir}|g\")\"\n\n\t\t# If file exists, just continue\n\t\t# this may happen for directories like /usr/lib/nvidia/xorg/foo.so\n\t\t# where the directory is already bind mounted (ro) and we don't need\n\t\t# to mount further files in it.\n\t\tif [ -e \"${dest_file}\" ]; then\n\t\t\tcontinue\n\t\tfi\n\n\t\tif [ ! -e \"$(dirname \"${dest_file}\")\" ]; then\n\t\t\tif ! mkdir -p \"$(dirname \"${dest_file}\")\"; then\n\t\t\t\tprintf \"Warning: skpping file %s, %s mounted as read-only\\n\" \"${dest_file}\" \"$(dirname \"${dest_file}\")\"\n\t\t\t\tcontinue\n\t\t\tfi\n\t\tfi\n\t\tif [ ! -w \"$(dirname \"${dest_file}\")\" ]; then\n\t\t\tprintf \"Warning: skpping file %s, %s mounted as read-only\\n\" \"${dest_file}\" \"$(dirname \"${dest_file}\")\"\n\t\t\tcontinue\n\t\tfi\n\n\t\ttype=\"file\"\n\t\tif [ -L \"${nvidia_lib}\" ]; then\n\t\t\ttype=\"link\"\n\t\tfi\n\n\t\tif [ \"${type}\" = \"link\" ]; then\n\t\t\tnvidia_lib=\"$(readlink -fm \"${nvidia_lib}\")\"\n\t\tfi\n\n\t\t# Mounting read-only in a user namespace will trigger a check to see if certain\n\t\t# \"locked\" flags (line noexec,nodev,nosuid) are changed. This ensures we explicitly reuse those flags.\n\t\tlocked_flags=\"$(get_locked_mount_flags \"${nvidia_lib}\")\"\n\t\tmount_bind \"${nvidia_lib}\" \"${dest_file}\" ro\"${locked_flags:+,${locked_flags}}\"\n\tdone\n\n\t# Refresh ldconfig cache\n\tldconfig 2>&1 /dev/null\n\nfi\n\n###############################################################################\nprintf \"distrobox: Integrating host's themes, icons, fonts...\\n\"\n# Themes and icons integration works using a bind mount inside the container\n# of the host's themes and icons directory. This ensures that the host's home will\n# not be littered with files and directories and broken symlinks.\nif ! mount_bind \"/run/host/usr/share/themes\" \"/usr/local/share/themes\"; then\n\tprintf \"Warning: Cannot bind mount /run/host/usr/share/themes to /usr/local/share/themes\\n\"\n\tprintf \"Warning: Themes integration with the host is disabled.\\n\"\nfi\nif ! mount_bind \"/run/host/usr/share/icons\" \"/usr/local/share/icons\"; then\n\tprintf \"Warning: Cannot bind mount /run/host/usr/share/icons to /usr/local/share/icons\\n\"\n\tprintf \"Warning: Icons integration with the host is disabled.\\n\"\nfi\nif ! mount_bind \"/run/host/usr/share/fonts\" \"/usr/local/share/fonts\"; then\n\tprintf \"Warning: Cannot bind mount /run/host/usr/share/fonts to /usr/local/share/fonts\\n\"\n\tprintf \"Warning: Fonts integration with the host is disabled.\\n\"\nfi\n###############################################################################\n\nprintf \"distrobox: Setting up distrobox profile...\\n\"\n\n# This ensures compatibility with prompts and tools between toolbx and distrobox\ntouch /run/.toolboxenv\n\n# Ensure we have some basic env variables and prompt as base if /etc/profile.d is missing\nif [ ! -d /etc/profile.d ]; then\n\trcfiles=\"\n\t\t/etc/profile\n\t\t/etc/bash.bashrc\n\t\t/etc/bashrc\n\t\t/etc/zshrc\n\t\"\n\tfor rcfile in ${rcfiles}; do\n\t\tif [ -e \"${rcfile}\" ] && ! grep -q 'distrobox_profile.sh' \"${rcfile}\"; then\n\t\t\techo \"[ -e /etc/profile.d/distrobox_profile.sh ] && . /etc/profile.d/distrobox_profile.sh\" >> \"${rcfile}\"\n\t\tfi\n\tdone\n\tmkdir -p /etc/profile.d\nfi\ncat << EOF > /etc/profile.d/distrobox_profile.sh\ntest -z \"\\$USER\" && export USER=\"\\$(id -un 2> /dev/null)\"\ntest -z \"\\$UID\"  && readonly UID=\"\\$(id -ur 2> /dev/null)\"\ntest -z \"\\$EUID\" && readonly EUID=\"\\$(id -u  2> /dev/null)\"\nexport SHELL=\"\\$(getent passwd \"\\${USER}\" | cut -f 7 -d :)\"\n\ntest -z \"\\${XDG_RUNTIME_DIR:-}\" && export XDG_RUNTIME_DIR=\"/run/user/\\$(id -ru)\"\ntest -z \"\\${DBUS_SESSION_BUS_ADDRESS:-}\" && export DBUS_SESSION_BUS_ADDRESS=\"unix:path=/run/user/\\$(id -ru)/bus\"\n\n# Ensure we have these two variables from the host, so that graphical apps\n# also work in case we use a login session\nif [ -z \"\\$XAUTHORITY\" ]; then\n    export XAUTHORITY=\"\\$(host-spawn sh -c \"printf \"%s\" \\\\\\$XAUTHORITY\")\"\n    # if the variable is still empty, unset it, because empty it could be harmful\n    [ -z \"\\$XAUTHORITY\" ] && unset XAUTHORITY\nfi\nif [ -z \"\\$XAUTHLOCALHOSTNAME\" ]; then\n    export XAUTHLOCALHOSTNAME=\"\\$(host-spawn sh -c \"printf \"%s\" \\\\\\$XAUTHLOCALHOSTNAME\")\"\n    [ -z \"\\$XAUTHLOCALHOSTNAME\" ] && unset XAUTHLOCALHOSTNAME\nfi\nif [ -z \"\\$WAYLAND_DISPLAY\" ]; then\n    export WAYLAND_DISPLAY=\"\\$(host-spawn sh -c \"printf \"%s\" \\\\\\$WAYLAND_DISPLAY\")\"\n    [ -z \"\\$WAYLAND_DISPLAY\" ] && unset WAYLAND_DISPLAY\nfi\nif [ -z \"\\$DISPLAY\" ]; then\n    export DISPLAY=\"\\$(host-spawn sh -c \"printf \"%s\" \\\\\\$DISPLAY\")\"\n    [ -z \"\\$DISPLAY\" ] && unset DISPLAY\nfi\n\n# This will ensure a default prompt for a container, this will be remineshent of\n# toolbx prompt: https://github.com/containers/toolbox/blob/main/profile.d/toolbox.sh#L47\n# this will ensure greater compatibility between the two implementations\nif [ -f /run/.toolboxenv ]; then\n    [ \"\\${BASH_VERSION:-}\" != \"\" ] && export PS1=\"📦[\\u@\\$CONTAINER_ID \\W]\\$ \"\n    [ \"\\${ZSH_VERSION:-}\" != \"\" ] && export PS1=\"📦[%n@\\$CONTAINER_ID]%~%# \"\nfi\n\n# This will ensure we have a first-shell password setup for an user if needed.\n# We're going to use this later in case of rootful containers\nif [ -e /var/tmp/.\\$USER.passwd.initialize ]; then\n\techo \"⚠️  First time user password setup ⚠️ \"\n\ttrap \"echo; exit\" INT\n\tpasswd && rm -f /var/tmp/.\\$USER.passwd.initialize\n\ttrap - INT\nfi\nEOF\n\n# It's also importanto to keep this working on fish shells\nif [ -e \"/etc/fish/config.fish\" ]; then\n\tmkdir -p /etc/fish/conf.d\n\tcat << EOF > /etc/fish/conf.d/distrobox_config.fish\nif status --is-interactive\n\ttest -z \"\\$USER\" && set -gx USER (id -un 2> /dev/null)\n\ttest -z \"\\$UID\"  && set -gx UID (id -ur 2> /dev/null)\n\ttest -z \"\\$EUID\" && set -gx EUID (id -u  2> /dev/null)\n\tset -gx SHELL (getent passwd \"\\$USER\" | cut -f 7 -d :)\n\n\ttest -z \"\\$XDG_RUNTIME_DIR && set -gx XDG_RUNTIME_DIR /run/user/(id -ru)\n\ttest -z \"\\$DBUS_SESSION_BUS_ADDRESS && set -gx DBUS_SESSION_BUS_ADDRESS unix:path=/run/user/(id -ru)/bus\n\n\t# Ensure we have these two variables from the host, so that graphical apps\n\t# also work in case we use a login session\n\tif test -z \\$XAUTHORITY\n\t\tset -gx XAUTHORITY (host-spawn sh -c \"printf \"%s\" \\\\\\$XAUTHORITY\")\n\t\t# if the variable is still empty, unset it, because empty it could be harmful\n\t\ttest -z \\$XAUTHORITY ; and set -e XAUTHORITY\n\tend\n\tif test -z \\$XAUTHLOCALHOSTNAME\n\t\tset -gx XAUTHLOCALHOSTNAME (host-spawn sh -c \"printf \"%s\" \\\\\\$XAUTHLOCALHOSTNAME\")\n\t\ttest -z \\$XAUTHLOCALHOSTNAME ; and set -e XAUTHLOCALHOSTNAME\n\tend\n\tif test -z \\$WAYLAND_DISPLAY\n\t\tset -gx WAYLAND_DISPLAY (host-spawn sh -c \"printf \"%s\" \\\\\\$WAYLAND_DISPLAY\")\n\t\ttest -z \\$WAYLAND_DISPLAY ; and set -e WAYLAND_DISPLAY\n\tend\n\tif test -z \\$DISPLAY\n\t\tset -gx DISPLAY (host-spawn sh -c \"printf \"%s\" \\\\\\$DISPLAY\")\n\t\ttest -z \\$DISPLAY ; and set -e DISPLAY\n\tend\n\n\t# This will ensure we have a first-shell password setup for an user if needed.\n\t# We're going to use this later in case of rootful containers\n\tif test -e /var/tmp/.\\$USER.passwd.initialize\n\t\techo \"⚠️  First time user password setup ⚠️ \"\n\t\ttrap \"echo; exit\" INT\n\t\tpasswd && rm -f /var/tmp/.\\$USER.passwd.initialize\n\t\ttrap - INT\n\tend\nend\nEOF\n\tmkdir -p /etc/fish/functions\n\tcat << EOF > /etc/fish/functions/fish_prompt.fish\nfunction fish_prompt\n\tset current_dir (basename (pwd))\n\techo \"📦[\\$USER@\\$CONTAINER_ID \\$current_dir]> \"\nend\nEOF\nfi\n###############################################################################\n\n###############################################################################\nprintf \"distrobox: Setting up sudo...\\n\"\nmkdir -p /etc/sudoers.d\n# Ensure we're using the user's password for sudo, not root\nif [ -e /etc/sudoers ]; then\n\tsed -i \"s|^Defaults targetpw.*||g\" /etc/sudoers\nfi\n\n# Do not check fqdn when doing sudo, it will not work anyways\n# Also allow canonical groups to use sudo\ncat << EOF > /etc/sudoers.d/sudoers\nDefaults !targetpw\nDefaults !fqdn\n%wheel ALL=(ALL:ALL) ALL\n%sudo ALL=(ALL:ALL) ALL\n%root ALL=(ALL:ALL) ALL\nEOF\n# ditto for doas\nif [ -e /etc/doas.conf ]; then\n\tcat << EOF > /etc/doas.conf\npermit persist :root\npermit persist :wheel\npermit nopass root\npermit nopass keepenv setenv { PATH } root as root\nEOF\nfi\n# if no sudo but doas is present, we want to have it as an alias\n# of sudo, so other part of the program will find it as expected\nif command -v doas && ! command -v sudo; then\n\tln -sf \"$(command -v doas)\" /usr/bin/sudo\nfi\n\n# PAM config for \"su\" command\nif [ ! -e /etc/pam.d/su ]; then\n\tmkdir -p /etc/pam.d\n\tcat << EOF > /etc/pam.d/su\nauth            sufficient      pam_rootok.so\nauth            required        pam_unix.so\naccount\t        required        pam_unix.so\nsession         required        pam_unix.so\n-session        optional        pam_systemd.so\nEOF\nfi\n\nif ! grep -q \"pam_systemd.so\" /etc/pam.d/su; then\n\tprintf \"%s\" '-session   optional   pam_systemd.so' >> /etc/pam.d/su\nfi\n\n# If we're running this script as root in a login shell (sudoless), we don't\n# have to bother setting up sudo.\n#\n# Also if we're in a rootful container, we will setup user's password,\n# so let's skip passwordless sudo too\nif [ \"${container_user_uid}\" -ne 0 ] && [ \"${rootful}\" -eq 0 ]; then\n\t# Ensure passwordless sudo is set up for user\n\tprintf \"\\\"%s\\\" ALL = (root) NOPASSWD:ALL\\n\" \"${container_user_name}\" >> /etc/sudoers.d/sudoers\n\t# ditto for doas\n\tif [ -e /etc/doas.conf ]; then\n\t\tprintf \"permit nopass %s\\n\" \"${container_user_name}\" >> /etc/doas.conf\n\tfi\nfi\n###############################################################################\n\n###############################################################################\n# If not existing, ensure we have a group for our user.\nif ! grep -q \"^${container_user_name}:\" /etc/group; then\n\tprintf \"distrobox: Setting up user groups...\\n\"\n\n\tif ! groupadd --force --gid \"${container_user_gid}\" \"${container_user_name}\"; then\n\t\t# It may occur that we have users with unsupported user name (eg. on LDAP or AD)\n\t\t# So let's try and force the group creation this way.\n\t\tprintf \"%s:x:%s:\\n\" \"${container_user_name}\" \"${container_user_gid}\" >> /etc/group\n\tfi\nfi\n###############################################################################\n\n###############################################################################\n\n# Setup kerberos integration with the host\nif [ -d \"/run/host/var/kerberos\" ] &&\n\t[ -d \"/etc/krb5.conf.d\" ] &&\n\t[ ! -e \"/etc/krb5.conf.d/kcm_default_ccache\" ]; then\n\n\tprintf \"distrobox: Setting up kerberos integration...\\n\"\n\n\tcat << EOF > /etc/krb5.conf.d/kcm_default_ccache\n# # To disable the KCM credential cache, comment out the following lines.\n[libdefaults]\n    default_ccache_name = KCM:\nEOF\nfi\n\nprintf \"distrobox: Setting up user's group list...\\n\"\n# If we have sudo/wheel groups, let's add the user to them.\n# and ensure that user's in those groups can effectively sudo\nadditional_groups=\"\"\nif grep -q \"^sudo\" /etc/group; then\n\tadditional_groups=\"sudo\"\nelif grep -q \"^wheel\" /etc/group; then\n\tadditional_groups=\"wheel\"\nelif grep -q \"^root\" /etc/group; then\n\tadditional_groups=\"root\"\nfi\n\n# If we're rootful, search for host's groups, if we're not in anyone, let's not\n# add the current user to any sudoers group, so that host's sudo settings are\n# respected\nif [ \"${rootful}\" -eq 1 ] &&\n\t! grep -q \"^wheel.*${container_user_name}\" /run/host/etc/group &&\n\t! grep -q \"^wheel.*${container_user_name}\" /run/host/etc/group &&\n\t! grep -q \"^sudo.*${container_user_name}\" /run/host/etc/group; then\n\tadditional_groups=\"\"\nfi\n\n# Let's add our user to the container. if the user already exists, enforce properties.\n#\n# In case of AD or LDAP usernames, it is possible we will have a backslach in the name.\n# In that case grep would fail, so we replace the backslash with a point to make the regex work.\n# shellcheck disable=SC1003\nif ! grep -q \"^$(printf '%s' \"${container_user_name}\" | tr '\\\\' '.'):\" /etc/passwd &&\n\t! getent passwd \"${container_user_uid}\"; then\n\tprintf \"distrobox: Adding user...\\n\"\n\tif ! useradd \\\n\t\t--home-dir \"${container_user_home}\" \\\n\t\t--no-create-home \\\n\t\t--groups \"${additional_groups}\" \\\n\t\t--shell \"${SHELL:-\"/bin/bash\"}\" \\\n\t\t--uid \"${container_user_uid}\" \\\n\t\t--gid \"${container_user_gid}\" \\\n\t\t\"${container_user_name}\"; then\n\n\t\tprintf \"Warning: There was a problem setting up the user with usermod, trying manual addition\\n\"\n\n\t\tprintf \"%s:x:%s:%s:%s:%s:%s\\n\" \\\n\t\t\t\"${container_user_name}\" \"${container_user_uid}\" \\\n\t\t\t\"${container_user_gid}\" \"${container_user_name}\" \\\n\t\t\t\"${container_user_home}\" \"${SHELL:-\"/bin/bash\"}\" >> /etc/passwd\n\t\tprintf \"%s::1::::::\" \"${container_user_name}\" >> /etc/shadow\n\tfi\n# Ensure we're not using the specified SHELL. Run it only once, so that future\n# user's preferences are not overwritten at each start.\nelif [ ! -e /etc/passwd.done ]; then\n\t# This situation is presented when podman or docker already creates the user\n\t# for us inside container. We should modify the user's prepopulated shadowfile\n\t# entry though as per user's active preferences.\n\n\t# Get current user attributes using container_user_uid as the reference\n\t# (script runs as root, so we must look up the target user by UID)\n\tcurrent_user_entry=$(getent passwd \"${container_user_uid}\")\n\tcurrent_user_name=$(printf '%s' \"${current_user_entry}\" | cut -d: -f1)\n\tcurrent_shell=$(printf '%s' \"${current_user_entry}\" | cut -d: -f7)\n\tcurrent_gid=$(printf '%s' \"${current_user_entry}\" | cut -d: -f4)\n\tcurrent_groups=$(id -nG \"${current_user_name}\" 2> /dev/null)\n\n\t# Modify username if needed\n\tif [ \"${current_user_name}\" != \"${container_user_name}\" ]; then\n\t\tprintf \"distrobox: Setting up existing user - username...\\n\"\n\t\tif ! usermod --login \"${container_user_name}\" \"${current_user_name}\"; then\n\t\t\tprintf \"Warning: usermod --login failed, trying manual modification\\n\"\n\t\t\tsed -i \"s|^${current_user_name}:|${container_user_name}:|g\" /etc/passwd\n\t\t\tif ! getent passwd \"${container_user_name}\" > /dev/null 2>&1; then\n\t\t\t\tprintf \"Error: Failed to modify user login name\\n\" >&2\n\t\t\t\texit 1\n\t\t\tfi\n\t\tfi\n\t\t# Update current_user_name for subsequent commands\n\t\tcurrent_user_name=\"${container_user_name}\"\n\tfi\n\n\t# Modify shell if needed\n\tif [ \"${current_shell}\" != \"${SHELL:-\"/bin/bash\"}\" ]; then\n\t\tprintf \"distrobox: Setting up existing user - shell...\\n\"\n\t\tif ! usermod --shell \"${SHELL:-\"/bin/bash\"}\" \"${current_user_name}\"; then\n\t\t\tprintf \"Warning: usermod --shell failed, trying manual modification\\n\"\n\t\t\t# sed to update shell field (7th field) in /etc/passwd\n\t\t\tsed -i \"s|^\\(${current_user_name}:[^:]*:[^:]*:[^:]*:[^:]*:[^:]*:\\).*|\\1${SHELL:-\"/bin/bash\"}|g\" /etc/passwd\n\t\tfi\n\tfi\n\n\t# Modify GID if needed\n\tif [ \"${current_gid}\" != \"${container_user_gid}\" ]; then\n\t\tprintf \"distrobox: Setting up existing user - GID...\\n\"\n\t\tif ! usermod --gid \"${container_user_gid}\" \"${current_user_name}\"; then\n\t\t\tprintf \"Warning: usermod --gid failed, trying manual modification\\n\"\n\t\t\t# sed to update gid field (4th field) in /etc/passwd\n\t\t\tsed -i \"s|^\\(${current_user_name}:[^:]*:[^:]*:\\)[^:]*|\\1${container_user_gid}|g\" /etc/passwd\n\t\tfi\n\tfi\n\n\t# Modify groups if needed (check if user is missing from any additional group)\n\tgroups_need_modification=0\n\tfor group in ${additional_groups}; do\n\t\tif ! printf '%s' \" ${current_groups} \" | grep -q \" ${group} \"; then\n\t\t\tgroups_need_modification=1\n\t\t\tbreak\n\t\tfi\n\tdone\n\tif [ \"${groups_need_modification}\" -eq 1 ]; then\n\t\tprintf \"distrobox: Setting up existing user - groups...\\n\"\n\t\t# Workaround: usermod --groups fails if an /etc/group file does not end with\n\t\t# a newline, so we preemptively add one just in case.\n\t\tprintf '\\n' >> /etc/group\n\t\tif ! usermod --append --groups \"${additional_groups}\" \"${current_user_name}\"; then\n\t\t\tprintf \"Warning: usermod --groups failed, trying manual modification\\n\"\n\t\t\tfor group in ${additional_groups}; do\n\t\t\t\tif ! grep -q \"^${group}.*${current_user_name}.*\" /etc/group; then\n\t\t\t\t\tgroup_line=\"$(grep \"^${group}.*\" /etc/group)\"\n\t\t\t\t\tif grep -q \"^${group}.*:$\" /etc/group; then\n\t\t\t\t\t\tsed -i \"s|${group_line}|${group_line}${current_user_name}|g\" /etc/group\n\t\t\t\t\telse\n\t\t\t\t\t\tsed -i \"s|${group_line}|${group_line},${current_user_name}|g\" /etc/group\n\t\t\t\t\tfi\n\t\t\t\tfi\n\t\t\tdone\n\t\tfi\n\tfi\n\n\t# Modify UID if needed\n\tcurrent_uid=$(getent passwd \"${current_user_name}\" | cut -d: -f3)\n\tif [ \"${current_uid}\" != \"${container_user_uid}\" ]; then\n\t\tprintf \"distrobox: UID...\\n\"\n\t\tif ! usermod --uid \"${container_user_uid}\" \"${current_user_name}\"; then\n\t\t\tprintf \"Warning: usermod --uid failed, trying manual modification\\n\"\n\t\t\tsed -i \"s|^\\(${current_user_name}:[^:]*:\\)[^:]*|\\1${container_user_uid}|g\" /etc/passwd\n\t\tfi\n\tfi\nfi\n\n# Ensure we have our home correctly set, in case of cloned containers or whatnot\nif [ \"$(getent passwd \"${container_user_name}\" | cut -d: -f6)\" != \"${container_user_home}\" ]; then\n\tprintf \"distrobox: Setting up user home...\\n\"\n\n\tif ! usermod -d \"${container_user_home}\" \"${container_user_name}\"; then\n\t\tsed -i \"s|^${container_user_name}.*|${container_user_name}:x:${container_user_uid}:${container_user_gid}::${container_user_home}:${SHELL:-\"/bin/bash\"}|g\" /etc/passwd\n\tfi\nfi\n\n# If we're rootless, delete password for root and user\nif [ ! -e /etc/passwd.done ]; then\n\tprintf \"distrobox: Ensuring user's access...\\n\"\n\n\ttemporary_password=\"$(md5sum < /proc/sys/kernel/random/uuid | cut -d' ' -f1)\"\n\t# We generate a random password to initialize the entry for the user.\n\tchpasswd_failed=0\n\tprintf \"%s:%s\" \"${container_user_name}\" \"${temporary_password}\" | chpasswd || chpasswd_failed=1\n\t# Then we remove the password for current user\n\tif ! passwd -d \"${container_user_name}\"; then\n\t\t# Fallback to chpasswd for older systems without passwd -d\n\t\tprintf \"%s:\" \"${container_user_name}\" | chpasswd || chpasswd_failed=1\n\tfi\n\n\tif [ \"${chpasswd_failed}\" -eq 1 ]; then\n\t\tprintf \"Warning: There was a problem setting up the user, trying manual addition\\n\"\n\t\tif grep -q \"${container_user_name}\" /etc/shadow; then\n\t\t\tsed -i \"s|^${container_user_name}.*|${container_user_name}::::::::|g\" /etc/shadow\n\t\telse\n\t\t\techo \"${container_user_name}::::::::\" >> /etc/shadow\n\t\tfi\n\tfi\n\n\tif [ \"${rootful}\" -eq 0 ]; then\n\t\t# We're rootless so we don't care about account password, so we remove it\n\t\tpasswd_cmd=passwd\n\t\tif passwd --help 2>&1 | grep -q -- --stdin; then\n\t\t\tpasswd_cmd=\"passwd --stdin\"\n\t\tfi\n\t\tprintf \"%s\\n%s\\n\" \"${temporary_password}\" \"${temporary_password}\" | ${passwd_cmd} root\n\t\tif ! passwd -d \"root\"; then\n\t\t\t# Fallback to chpasswd for older systems without passwd -d\n\t\t\tprintf \"%s:\" \"root\" | chpasswd\n\t\tfi\n\telse\n\t\t# We're rootful, so we don't want passwordless accounts, so we lock them\n\t\t# down by default.\n\n\t\t# lock out root user\n\t\tif ! usermod -L root; then\n\t\t\tsed -i 's|^root.*|root:!:1::::::|g' /etc/shadow\n\t\tfi\n\tfi\nfi\n\n# If we are in a rootful container, let's setup a first-shell password setup\n# so that sudo, and su has a password\n#\n# else we fallback to the usual setup with passwordless sudo/su user. This is\n# likely because we're in a rootless setup, so privilege escalation is not a concern.\nif [ \"${rootful}\" -eq 1 ] &&\n\t{\n\t\t[ \"$(grep \"${container_user_name}\" /etc/shadow | cut -d':' -f2)\" = '!!' ] ||\n\t\t\t[ \"$(grep \"${container_user_name}\" /etc/shadow | cut -d':' -f2)\" = \"\" ]\n\t}; then\n\n\t# force setup of user's password on first shell\n\tif [ ! -e /var/tmp ]; then\n\t\tmkdir -p /var/tmp\n\t\tchmod 0777 /var/tmp\n\tfi\n\ttouch /var/tmp/.\"${container_user_name}\".passwd.initialize\n\tchown \"${container_user_name}:${container_user_gid}\" /var/tmp/.\"${container_user_name}\".passwd.initialize\nfi\n\n# Now we're done\ntouch /etc/passwd.done\n\n# Ensure shadow files are readable by root without relying on CAP_DAC_OVERRIDE,\n# which may not be effective on all container storage drivers (e.g. fuse-overlayfs\n# in rootless mode, or VMs like Docker Desktop / Colima on macOS).\n# Fedora/Arch ship these as mode 000, expecting the capability to bypass DAC.\nchmod 0400 /etc/shadow 2> /dev/null || :\nchmod 0400 /etc/gshadow 2> /dev/null || :\n###############################################################################\n\n###############################################################################\nif [ -n \"${DISTROBOX_HOST_HOME-}\" ] && [ -d \"/etc/skel\" ]; then\n\tprintf \"distrobox: Setting up skel...\\n\"\n\n\t# If we do not have profile files in the home, we should copy the\n\t# skeleton files, if present.\n\t# Ensure we copy only if the dotfile is not already present.\n\tskel_files=\"$(find /etc/skel/ -type f || :)\"\n\tfor skel_file in ${skel_files}; do\n\t\tbase_file_name=$(basename \"${skel_file}\")\n\t\tskel_file_path=$(dirname \"${skel_file}\")\n\t\tfile_path_for_home=${skel_file_path#/etc/skel}\n\n\t\tif [ -n \"${file_path_for_home}\" ] &&\n\t\t\t[ ! -d \"${container_user_home}/${file_path_for_home:+\"${file_path_for_home}\"}\" ]; then\n\t\t\tmkdir -p \"${container_user_home}/${file_path_for_home:+\"${file_path_for_home}\"/}\"\n\t\t\tchown \"${container_user_uid}\":\"${container_user_gid}\" \"${container_user_home}/${file_path_for_home:+\"${file_path_for_home}\"/}\"\n\t\tfi\n\n\t\tif [ ! -f \"${container_user_home}/${file_path_for_home:+\"${file_path_for_home}\"/}${base_file_name}\" ] &&\n\t\t\t[ ! -L \"${container_user_home}/${file_path_for_home:+\"${file_path_for_home}\"/}${base_file_name}\" ]; then\n\t\t\tcp \"${skel_file}\" \"${container_user_home}/${file_path_for_home:+\"${file_path_for_home}\"/}${base_file_name}\"\n\t\t\tchown \"${container_user_uid}\":\"${container_user_gid}\" \"${container_user_home}/${file_path_for_home:+\"${file_path_for_home}\"/}${base_file_name}\"\n\t\tfi\n\n\tdone\nfi\n###############################################################################\n\n###############################################################################\nif [ -n \"${init_hook}\" ]; then\n\tprintf \"distrobox: Executing init hooks...\\n\"\n\t# execute eventual init hooks if specified\n\t# shellcheck disable=SC2086\n\teval ${init_hook}\nfi\n###############################################################################\n\nHOST_WATCH=\"\n\t/etc/hostname\n\t/etc/hosts\n\t/etc/localtime\n\t/etc/resolv.conf\n\"\nid=\"${CONTAINER_ID:-}\"\nif [ -e /run/.containerenv ]; then\n\t# shellcheck disable=SC1091,SC2034\n\t. /run/.containerenv\nelif [ -e /.dockerenv ]; then\n\tid=\"$(curl -s --unix-socket /run/docker.sock http://docker/containers/\"${CONTAINER_ID:-$(hostname | cut -d'.' -f1)}\"/json |\n\t\tgrep -Eo '\"Id\":\"[a-zA-Z0-9]{64}\",' | cut -d '\"' -f4)\"\nfi\n\n###############################################################################\n# If init support is disabled, let's do our routine to keep the container\n# up, running and in sync with host.\n#\n# For non-init containers, the init will stop here\nif [ \"${init}\" -eq 0 ]; then\n\tprintf \"container_setup_done\\n\"\n\t# Keepalive loop\n\t# disable verbose logging for this phase.\n\tset +x\n\twhile true; do\n\t\t# Let's check for changes every 15 seconds.\n\t\t# This way we can dynamically keep hosts, dns and timezone setups\n\t\t# in sync with host, without having permissions problems:\n\t\t#\t- symlink will fail with \"Device or Resource busy\"\n\t\t#\t- bindmount will need a container restart on changes\n\t\tfor file_watch in ${HOST_WATCH}; do\n\t\t\t# do stuff, only if the file is a mountpoint, and if the mountpoint is NOT containing the\n\t\t\t# container id, because if it does, it is because it's part of the podman/docker setup\n\t\t\t# The mount point might not exist, either because it's umounted or it doesn't exist on\n\t\t\t# host in some cases like /etc/localtime, so ignore findmnt errors\n\t\t\tmount_source=\"$(findmnt -no SOURCE \"${file_watch}\")\" || :\n\t\t\tif [ -n \"${mount_source}\" ] && ! echo \"${mount_source}\" | grep -q \"${id}\"; then\n\t\t\t\tfile_watch_src=\"/run/host${file_watch}\"\n\t\t\t\t# check if the target file exists\n\t\t\t\tif ls -l \"${file_watch_src}\" 2> /dev/null > /dev/null; then\n\t\t\t\t\t# if it's a symlink and take the source\n\t\t\t\t\tif [ -L \"${file_watch_src}\" ]; then\n\t\t\t\t\t\tfile_watch_src=\"$(init_readlink \"/run/host${file_watch}\")\"\n\t\t\t\t\t\t# if it's an absolute link, we need to append /run/host ourselves.\n\t\t\t\t\t\tif ! printf \"%s\" \"${file_watch_src}\" | grep -q \"/run/host\"; then\n\t\t\t\t\t\t\tfile_watch_src=\"/run/host${file_watch_src}\"\n\t\t\t\t\t\tfi\n\t\t\t\t\tfi\n\t\t\t\t\tif ! diff \"${file_watch}\" \"${file_watch_src}\" > /dev/null; then\n\t\t\t\t\t\t# We only do this, if the file is actually different\n\t\t\t\t\t\tumount \"${file_watch}\" &&\n\t\t\t\t\t\t\tmount_bind \"${file_watch_src}\" \"${file_watch}\"\n\n\t\t\t\t\t\t# Let's keep in sync host's hostname and container's hostname\n\t\t\t\t\t\tif [ \"${file_watch}\" = \"/etc/hostname\" ]; then\n\t\t\t\t\t\t\thostname \"$(cat /etc/hostname)\"\n\t\t\t\t\t\tfi\n\t\t\t\t\tfi\n\t\t\t\tfi\n\t\t\tfi\n\t\tdone\n\t\tsleep 15\n\tdone\nfi\n###############################################################################\n\n###############################################################################\n# If we're here, the init support has been enabled.\nprintf \"distrobox: Setting up init system...\\n\"\n\n# some of this directories are needed by\n# the init system. If they're mounts, there might\n# be problems. Let's unmount them.\nfor host_mount in ${HOST_MOUNTS_RO_INIT}; do\n\tif findmnt \"${host_mount}\" > /dev/null; then umount \"${host_mount}\"; fi\ndone\n\n# Remove symlinks\nrm -f /run/systemd/coredump\nrm -f /run/systemd/io.system.ManagedOOM\nrm -f /run/systemd/notify\nrm -f /run/systemd/private\n\n# Restore the symlink if it's an empty file\nif [ -f /etc/localtime ]; then\n\trm -f /etc/localtime\n\tln -sf /usr/share/zoneinfo/UCT /etc/localtime\nfi\n\n# Remove /dev/console when using init systems, this will confuse host system if\n# we use rootful containers\n# Instantiate a new pty to mount over /dev/console\n# this way we will have init output right of the logs\n[ -e /dev/console ] || touch /dev/console\nrm -f /var/console\nmkfifo /var/console\nscript -c \"cat /var/console\" /dev/null &\n\n# Ensure the pty is created\nsleep 0.5\n\n# Mount the created pty over /dev/console in order to have systemd logs\n# right into container logs\nif ! mount --bind /dev/pts/0 /dev/console; then\n\t# Fallback to older behaviour or fake plaintext file in case it fails\n\t# this ensures rootful + initful boxes do not interfere with host's /dev/console\n\trm -f /var/console\n\ttouch /var/console\n\tmount --bind /var/console /dev/console\nfi\n\nif [ -e /etc/inittab ]; then\n\t# Cleanup openrc to not interfere with the host\n\tsed -i 's/^\\(tty\\d\\:\\:\\)/#\\1/g' /etc/inittab\nfi\n\nif [ -e /etc/rc.conf ]; then\n\tsed -i \\\n\t\t-e 's/#rc_env_allow=\".*\"/rc_env_allow=\"\\*\"/g' \\\n\t\t-e 's/#rc_crashed_stop=.*/rc_crashed_stop=NO/g' \\\n\t\t-e 's/#rc_crashed_start=.*/rc_crashed_start=YES/g' \\\n\t\t-e 's/#rc_provide=\".*\"/rc_provide=\"loopback net\"/g' \\\n\t\t/etc/rc.conf\nfi\n\nif [ -e /etc/init.d ]; then\n\trm -f /etc/init.d/hwdrivers \\\n\t\t/etc/init.d/hwclock \\\n\t\t/etc/init.d/hwdrivers \\\n\t\t/etc/init.d/modules \\\n\t\t/etc/init.d/modules-load \\\n\t\t/etc/init.d/modloop\nfi\n\nif command -v systemctl 2> /dev/null; then\n\t# Cleanup Systemd to not interfere with the host\n\tUNIT_TARGETS=\"\n\t\t/usr/lib/systemd/system/*.mount\n\t\t/usr/lib/systemd/system/console-getty.service\n\t\t/usr/lib/systemd/system/getty@.service\n\t\t/usr/lib/systemd/system/systemd-machine-id-commit.service\n\t\t/usr/lib/systemd/system/systemd-binfmt.service\n\t\t/usr/lib/systemd/system/systemd-tmpfiles*\n\t\t/usr/lib/systemd/system/systemd-udevd.service\n\t\t/usr/lib/systemd/system/systemd-udev-trigger.service\n\t\t/usr/lib/systemd/system/systemd-update-utmp*\n\t\t/usr/lib/systemd/user/pipewire*\n\t\t/usr/lib/systemd/user/wireplumber*\n\t\t/usr/lib/systemd/system/suspend.target\n\t\t/usr/lib/systemd/system/hibernate.target\n\t\t/usr/lib/systemd/system/hybrid-sleep.target\n\t\t/usr/lib/systemd/system/systemd-remount-fs.service\n\t\"\n\n\t# in case /etc/resolv.conf is a mount, we need to mask resolved\n\t# in this case we're using network=host and systemd-resolved won't\n\t# be able to bind to localhost:53\n\tmount_source=\"$(findmnt -no SOURCE /etc/resolv.conf)\" || :\n\tif [ -n \"${mount_source}\" ] && ! echo \"${mount_source}\" | grep -q \"${id}\"; then\n\t\tUNIT_TARGETS=\"${UNIT_TARGETS}\n\t\t\t/usr/lib/systemd/system/systemd-resolved.service\n\t\t\"\n\tfi\n\n\t# shellcheck disable=SC2086,SC2044\n\tfor unit in $(find ${UNIT_TARGETS} 2> /dev/null); do\n\t\tsystemctl mask \"$(basename \"${unit}\")\" || :\n\tdone\nfi\n\n# Let's do a minimal user-integration for the user when using system\n# as the user@.service will trigger the user-runtime-dir@.service which will\n# undo all the integration we did at the start of the script\n#\n# This will ensure the basic integration for x11/wayland/pipewire/keyring\nif [ -e /usr/lib/systemd/system/user@.service ]; then\n\tcat << EOF > /usr/local/bin/user-integration\n#!/bin/sh\nsleep 1\nln -sf /run/host/run/user/\\$(id -ru)/wayland-* /run/user/\\$(id -ru)/\nln -sf /run/host/run/user/\\$(id -ru)/pipewire-* /run/user/\\$(id -ru)/\nfind /run/host/run/user/\\$(id -ru)/ -maxdepth 1 -type f -exec sh -c 'grep -qlE COOKIE \\$0 && ln -sf \\$0 /run/user/\\$(id -ru)/\\$(basename \\$0)' {} \\;\nmkdir -p /run/user/\\$(id -ru)/app && ln -sf /run/host/run/user/\\$(id -ru)/app/* /run/user/\\$(id -ru)/app/\nmkdir -p /run/user/\\$(id -ru)/at-spi && ln -sf /run/host/run/user/\\$(id -ru)/at-spi/* /run/user/\\$(id -ru)/at-spi/\nmkdir -p /run/user/\\$(id -ru)/dbus-1 && ln -sf /run/host/run/user/\\$(id -ru)/dbus-1/* /run/user/\\$(id -ru)/dbus-1/\nmkdir -p /run/user/\\$(id -ru)/dconf && ln -sf /run/host/run/user/\\$(id -ru)/dconf/* /run/user/\\$(id -ru)/dconf/\nmkdir -p /run/user/\\$(id -ru)/gnupg && ln -sf /run/host/run/user/\\$(id -ru)/gnupg/* /run/user/\\$(id -ru)/gnupg/\nmkdir -p /run/user/\\$(id -ru)/keyring && ln -sf /run/host/run/user/\\$(id -ru)/keyring/* /run/user/\\$(id -ru)/keyring/\nmkdir -p /run/user/\\$(id -ru)/p11-kit && ln -sf /run/host/run/user/\\$(id -ru)/p11-kit/* /run/user/\\$(id -ru)/p11-kit/\nmkdir -p /run/user/\\$(id -ru)/pulse && ln -sf /run/host/run/user/\\$(id -ru)/pulse/* /run/user/\\$(id -ru)/pulse/\nfind /run/user/\\$(id -ru) -maxdepth 2 -xtype l -delete\nEOF\n\n\tchmod +x /usr/local/bin/user-integration\n\n\tcat << EOF > /usr/lib/systemd/system/user-integration@.service\n[Unit]\nDescription=User runtime integration for UID %i\nAfter=user@%i.service\nRequires=user-runtime-dir@%i.service\n\n[Service]\nUser=%i\nType=oneshot\nExecStart=/usr/local/bin/user-integration\n\nSlice=user-%i.slice\nEOF\nfi\n\n# Now we can launch init\nprintf \"distrobox: Firing up init system...\\n\"\n\nif [ -e /usr/lib/systemd/systemd ] || [ -e /lib/systemd/systemd ]; then\n\t# Start user Systemd unit, this will attempt until Systemd is ready\n\tsh -c \"timeout=120 && sleep 1 && while [ \\\"\\${timeout}\\\" -gt 0 ]; do \\\n\t    systemctl is-system-running | grep -E 'running|degraded' && break; \\\n\t\techo 'waiting for systemd to come up...\\n' && sleep 1 && timeout=\\$(( timeout -1 )); \\\n\tdone && \\\n\tsystemctl start user@${container_user_name}.service && \\\n\tsystemctl start user-integration@${container_user_name}.service && \\\n\tloginctl enable-linger ${container_user_name} || : && \\\n\techo container_setup_done\" &\n\n\t[ -e /usr/lib/systemd/systemd ] && exec /usr/lib/systemd/systemd --system --log-target=console --unit=multi-user.target\n\t[ -e /lib/systemd/systemd ] && exec /lib/systemd/systemd --system --log-target=console --unit=multi-user.target\n\nelif [ -e /sbin/init ]; then\n\tprintf \"container_setup_done\\n\"\n\n\t# Fallback to standard init path, this is useful in case of non-Systemd containers\n\t# like an openrc alpine\n\texec /sbin/init\nelse\n\tprintf \"Error: could not set up init system, no init found! Consider using an image that ships with an init system, or add it with \\\"--additional-packages\\\" during creation.!\\n\"\n\texit 1\nfi\n"
  },
  {
    "path": "distrobox-list",
    "content": "#!/bin/sh\n# SPDX-License-Identifier: GPL-3.0-only\n#\n# This file is part of the distrobox project:\n#    https://github.com/89luca89/distrobox\n#\n# Copyright (C) 2021 distrobox contributors\n#\n# distrobox is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 3\n# as published by the Free Software Foundation.\n#\n# distrobox is distributed in the hope that it will be useful, but\n# WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n# General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with distrobox; if not, see <http://www.gnu.org/licenses/>.\n\n# POSIX\n# Optional env variables:\n#\tDBX_CONTAINER_MANAGER\n#\tDBX_VERBOSE\n#\tDBX_SUDO_PROGRAM\n\n# Despite of running this script via SUDO/DOAS being not supported (the\n# script itself will call the appropriate tool when necessary), we still want\n# to allow people to run it as root, logged in in a shell, and create rootful\n# containers.\n#\n# SUDO_USER is a variable set by SUDO and can be used to check whether the script was called by it. Same thing for DOAS_USER, set by DOAS.\nif {\n\t[ -n \"${SUDO_USER}\" ] || [ -n \"${DOAS_USER}\" ]\n} && [ \"$(id -ru)\" -eq 0 ]; then\n\tprintf >&2 \"Running %s via SUDO/DOAS is not supported. Instead, please try running:\\n\" \"$(basename \"${0}\")\"\n\tprintf >&2 \"  %s --root %s\\n\" \"$(basename \"${0}\")\" \"$*\"\n\texit 1\nfi\n\n# Ensure we have our env variables correctly set\n[ -z \"${USER}\" ] && USER=\"$(id -run)\"\n[ -z \"${HOME}\" ] && HOME=\"$(getent passwd \"${USER}\" | cut -d':' -f6)\"\n[ -z \"${SHELL}\" ] && SHELL=\"$(getent passwd \"${USER}\" | cut -d':' -f7)\"\n\n# Defaults\nno_color=0\n# If the user runs this script as root in a login shell, set rootful=1.\n# There's no need for them to pass the --root flag option in such cases.\n[ \"$(id -ru)\" -eq 0 ] && rootful=1 || rootful=0\nverbose=0\nversion=\"1.8.2.4\"\ncontainer_manager=\"autodetect\"\n\n# Source configuration files, this is done in an hierarchy so local files have\n# priority over system defaults\n# leave priority to environment variables.\n#\n# On NixOS, for the distrobox derivation to pick up a static config file shipped\n# by the package maintainer the path must be relative to the script itself.\nself_dir=\"$(dirname \"$(realpath \"$0\")\")\"\nnix_config_file=\"${self_dir}/../share/distrobox/distrobox.conf\"\n\nconfig_files=\"\n\t${nix_config_file}\n\t/usr/share/distrobox/distrobox.conf\n\t/usr/share/defaults/distrobox/distrobox.conf\n\t/usr/etc/distrobox/distrobox.conf\n\t/usr/local/share/distrobox/distrobox.conf\n\t/etc/distrobox/distrobox.conf\n\t${XDG_CONFIG_HOME:-\"${HOME}/.config\"}/distrobox/distrobox.conf\n\t${HOME}/.distroboxrc\n\"\nfor config_file in ${config_files}; do\n\t# Shellcheck will give error for sourcing a variable file as it cannot follow\n\t# it. We don't care so let's disable this linting for now.\n\t# shellcheck disable=SC1090\n\t[ -e \"${config_file}\" ] && . \"$(realpath \"${config_file}\")\"\ndone\n\n[ -n \"${DBX_VERBOSE}\" ] && verbose=\"${DBX_VERBOSE}\"\n\n# Fixup variable=[true|false], in case we find it in the config file(s)\n[ \"${verbose}\" = \"true\" ] && verbose=1\n[ \"${verbose}\" = \"false\" ] && verbose=0\n\n# If we're running this script as root -- as in logged in in the shell as root\n# user, and not via SUDO/DOAS --, we don't need to set distrobox_sudo_program\n# as it's meaningless for this use case.\nif [ \"$(id -ru)\" -ne 0 ]; then\n\t# If the DBX_SUDO_PROGRAM/distrobox_sudo_program variable was set by the\n\t# user, use its value instead of \"sudo\". But only if not running the script\n\t# as root (UID 0).\n\tdistrobox_sudo_program=${DBX_SUDO_PROGRAM:-${distrobox_sudo_program:-\"sudo\"}}\nfi\n[ -n \"${DBX_CONTAINER_MANAGER}\" ] && container_manager=\"${DBX_CONTAINER_MANAGER}\"\n\n# show_help will print usage to stdout.\n# Arguments:\n#   None\n# Expected global variables:\n#   version: distrobox version\n# Expected env variables:\n#   None\n# Outputs:\n#   print usage with examples.\nshow_help()\n{\n\tcat << EOF\ndistrobox version: ${version}\n\nUsage:\n\n\tdistrobox-list\n\nOptions:\n\n\t--help/-h:\t\tshow this message\n\t--no-color:\t\tdisable color formatting\n\t--root/-r:\t\tlaunch podman/docker/lilipod with root privileges. Note that if you need root this is the preferred\n\t\t\t\tway over \"sudo distrobox\" (note: if using a program other than 'sudo' for root privileges is necessary,\n\t\t\t\tspecify it through the DBX_SUDO_PROGRAM env variable, or 'distrobox_sudo_program' config variable)\n\t--verbose/-v:\t\tshow more verbosity\n\t--version/-V:\t\tshow version\nEOF\n}\n\n# Parse arguments\nwhile :; do\n\tcase $1 in\n\t\t-h | --help)\n\t\t\t# Call a \"show_help\" function to display a synopsis, then exit.\n\t\t\tshow_help\n\t\t\texit 0\n\t\t\t;;\n\t\t--no-color)\n\t\t\tshift\n\t\t\tno_color=1\n\t\t\t;;\n\t\t-r | --root)\n\t\t\tshift\n\t\t\trootful=1\n\t\t\t;;\n\t\t-v | --verbose)\n\t\t\tverbose=1\n\t\t\tshift\n\t\t\t;;\n\t\t-V | --version)\n\t\t\tprintf \"distrobox: %s\\n\" \"${version}\"\n\t\t\texit 0\n\t\t\t;;\n\t\t--) # End of all options.\n\t\t\tshift\n\t\t\tbreak\n\t\t\t;;\n\t\t-*) # Invalid options.\n\t\t\tprintf >&2 \"ERROR: Invalid flag '%s'\\n\\n\" \"$1\"\n\t\t\tshow_help\n\t\t\texit 1\n\t\t\t;;\n\t\t*) # Default case: If no more options then break out of the loop.\n\t\t\tbreak ;;\n\tesac\ndone\n\nset -o errexit\nset -o nounset\n# set verbosity\nif [ \"${verbose}\" -ne 0 ]; then\n\tset -o xtrace\nfi\n\n# We depend on a container manager let's be sure we have it\n# First we use podman, else docker, else lilipod\ncase \"${container_manager}\" in\n\tautodetect)\n\t\tif command -v podman > /dev/null; then\n\t\t\tcontainer_manager=\"podman\"\n\t\telif command -v podman-launcher > /dev/null; then\n\t\t\tcontainer_manager=\"podman-launcher\"\n\t\telif command -v docker > /dev/null; then\n\t\t\tcontainer_manager=\"docker\"\n\t\telif command -v lilipod > /dev/null; then\n\t\t\tcontainer_manager=\"lilipod\"\n\t\tfi\n\t\t;;\n\tpodman)\n\t\tcontainer_manager=\"podman\"\n\t\t;;\n\tpodman-launcher)\n\t\tcontainer_manager=\"podman-launcher\"\n\t\t;;\n\tlilipod)\n\t\tcontainer_manager=\"lilipod\"\n\t\t;;\n\tdocker)\n\t\tcontainer_manager=\"docker\"\n\t\t;;\n\t*)\n\t\tprintf >&2 \"Invalid input %s.\\n\" \"${container_manager}\"\n\t\tprintf >&2 \"The available choices are: 'autodetect', 'podman', 'docker', 'lilipod'\\n\"\n\t\t;;\nesac\n\n# Be sure we have a container manager to work with.\nif ! command -v \"${container_manager}\" > /dev/null; then\n\t# Error: we need at least one between docker, podman or lilipod.\n\tprintf >&2 \"Missing dependency: we need a container manager.\\n\"\n\tprintf >&2 \"Please install one of podman,  docker or lilipod.\\n\"\n\tprintf >&2 \"You can follow the documentation on:\\n\"\n\tprintf >&2 \"\\tman distrobox-compatibility\\n\"\n\tprintf >&2 \"or:\\n\"\n\tprintf >&2 \"\\thttps://github.com/89luca89/distrobox/blob/main/docs/compatibility.md\\n\"\n\texit 127\nfi\n# add verbose if -v is specified\nif [ \"${verbose}\" -ne 0 ]; then\n\tcontainer_manager=\"${container_manager} --log-level debug\"\nfi\n\n# prepend sudo (or the specified sudo program) if we want our container manager to be rootful\nif [ \"${rootful}\" -ne 0 ]; then\n\tcontainer_manager=\"${distrobox_sudo_program-} ${container_manager}\"\nfi\n\n# List containers using custom format that included MOUNTS\n# we do this as we can detect the custom mounts done by distrobox to distringuish\n# between a normal container and a distrobox one.\ncontainer_list=$(${container_manager} ps -a --no-trunc --format \\\n\t\"{{.ID}}|{{.Image}}|{{.Names}}|{{.Status}}|{{.Labels}}{{.Mounts}}\")\nprintf \"%-12s | %-20s | %-18s | %-30s\\n\" \\\n\t\"ID\" \"NAME\" \"STATUS\" \"IMAGE\"\nIFS='\n'\n\n# if we're in not a tty, don't use colors\nGREEN=\"\"\nYELLOW=\"\"\nCLEAR=\"\"\nif [ -t 0 ] && [ -t 1 ] && [ \"${no_color}\" -ne 1 ]; then\n\t# we're in a tty, use colors\n\tGREEN='\\033[32m'\n\tYELLOW='\\033[33m'\n\tCLEAR='\\033[0m'\nfi\n# Header of the output\nfor container in ${container_list}; do\n\t# Check if the current container has a custom mount point for distrobox.\n\tif [ -z \"${container##*distrobox*}\" ]; then\n\n\t\t# Extract the information for the single container to pretty print it\n\t\tcontainer_id=\"$(printf \"%s\" \"${container}\" | cut -d'|' -f1 | cut -c1-12)\"\n\t\tcontainer_image=\"$(printf \"%s\" \"${container}\" | cut -d'|' -f2)\"\n\t\tcontainer_name=\"$(printf \"%s\" \"${container}\" | cut -d'|' -f3)\"\n\t\tcontainer_status=\"$(printf \"%s\" \"${container}\" | cut -d'|' -f4)\"\n\n\t\tIFS=' '\n\n\t\t# If the container is Up and Running, print it in green and go next.\n\t\tif [ -z \"${container_status##*Up*}\" ] || [ -z \"${container_status##*running*}\" ]; then\n\t\t\t# echo -e is not defined in posix, and printing with %s will not work\n\t\t\t# for colors, so we're disabling this lint for color prints.\n\t\t\t# shellcheck disable=SC2059\n\t\t\tprintf \"${GREEN}\"\n\t\telse\n\t\t\t# shellcheck disable=SC2059\n\t\t\tprintf \"${YELLOW}\"\n\t\tfi\n\t\t# print it in yellow if not Running\n\t\tprintf \"%-12s | %-20s | %-18s | %-30s\" \\\n\t\t\t\"${container_id}\" \"${container_name}\" \"${container_status}\" \"${container_image}\"\n\n\t\t# shellcheck disable=SC2059\n\t\tprintf \"${CLEAR}\\n\"\n\tfi\ndone\n"
  },
  {
    "path": "distrobox-rm",
    "content": "#!/bin/sh\n# SPDX-License-Identifier: GPL-3.0-only\n#\n# This file is part of the distrobox project:\n#    https://github.com/89luca89/distrobox\n#\n# Copyright (C) 2021 distrobox contributors\n#\n# distrobox is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 3\n# as published by the Free Software Foundation.\n#\n# distrobox is distributed in the hope that it will be useful, but\n# WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n# General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with distrobox; if not, see <http://www.gnu.org/licenses/>.\n\n# POSIX\n# Optional env variables:\n#\tDBX_CONTAINER_MANAGER\n#\tDBX_CONTAINER_NAME\n#\tDBX_CONTAINER_RM_CUSTOM_HOME\n#\tDBX_NON_INTERACTIVE\n#\tDBX_VERBOSE\n#\tDBX_SUDO_PROGRAM\n\n# Despite of running this script via SUDO/DOAS being not supported (the\n# script itself will call the appropriate tool when necessary), we still want\n# to allow people to run it as root, logged in in a shell, and create rootful\n# containers.\n#\n# SUDO_USER is a variable set by SUDO and can be used to check whether the script was called by it. Same thing for DOAS_USER, set by DOAS.\nif {\n\t[ -n \"${SUDO_USER}\" ] || [ -n \"${DOAS_USER}\" ]\n} && [ \"$(id -ru)\" -eq 0 ]; then\n\tprintf >&2 \"Running %s via SUDO/DOAS is not supported. Instead, please try running:\\n\" \"$(basename \"${0}\")\"\n\tprintf >&2 \"  %s --root %s\\n\" \"$(basename \"${0}\")\" \"$*\"\n\texit 1\nfi\n\n# Ensure we have our env variables correctly set\n[ -z \"${USER}\" ] && USER=\"$(id -run)\"\n[ -z \"${HOME}\" ] && HOME=\"$(getent passwd \"${USER}\" | cut -d':' -f6)\"\n[ -z \"${SHELL}\" ] && SHELL=\"$(getent passwd \"${USER}\" | cut -d':' -f7)\"\n\n# Defaults\nall=0\ncontainer_manager=\"autodetect\"\ndistrobox_flags=\"\"\ndistrobox_path=\"$(dirname \"$(realpath \"${0}\")\")\"\nforce=0\nforce_flag=\"\"\nnon_interactive=0\n# If the user runs this script as root in a login shell, set rootful=1.\n# There's no need for them to pass the --root flag option in such cases.\n[ \"$(id -ru)\" -eq 0 ] && rootful=1 || rootful=0\nverbose=0\nrm_home=0\nresponse_rm_home=\"N\"\nversion=\"1.8.2.4\"\n\n# Source configuration files, this is done in an hierarchy so local files have\n# priority over system defaults\n# leave priority to environment variables.\n#\n# On NixOS, for the distrobox derivation to pick up a static config file shipped\n# by the package maintainer the path must be relative to the script itself.\nself_dir=\"$(dirname \"$(realpath \"$0\")\")\"\nnix_config_file=\"${self_dir}/../share/distrobox/distrobox.conf\"\n\nconfig_files=\"\n\t${nix_config_file}\n\t/usr/share/distrobox/distrobox.conf\n\t/usr/share/defaults/distrobox/distrobox.conf\n\t/usr/etc/distrobox/distrobox.conf\n\t/usr/local/share/distrobox/distrobox.conf\n\t/etc/distrobox/distrobox.conf\n\t${XDG_CONFIG_HOME:-\"${HOME}/.config\"}/distrobox/distrobox.conf\n\t${HOME}/.distroboxrc\n\"\nfor config_file in ${config_files}; do\n\t# Shellcheck will give error for sourcing a variable file as it cannot follow\n\t# it. We don't care so let's disable this linting for now.\n\t# shellcheck disable=SC1090\n\t[ -e \"${config_file}\" ] && . \"$(realpath \"${config_file}\")\"\ndone\n\n[ -n \"${DBX_CONTAINER_MANAGER}\" ] && container_manager=\"${DBX_CONTAINER_MANAGER}\"\n[ -n \"${DBX_CONTAINER_RM_CUSTOM_HOME}\" ] && rm_home=\"${DBX_CONTAINER_RM_CUSTOM_HOME}\"\n[ -n \"${DBX_NON_INTERACTIVE}\" ] && non_interactive=\"${DBX_NON_INTERACTIVE}\"\n[ -n \"${DBX_VERBOSE}\" ] && verbose=\"${DBX_VERBOSE}\"\n\n# Fixup variable=[true|false], in case we find it in the config file(s)\n[ \"${non_interactive}\" = \"true\" ] && non_interactive=1\n[ \"${non_interactive}\" = \"false\" ] && non_interactive=0\n[ \"${verbose}\" = \"true\" ] && verbose=1\n[ \"${verbose}\" = \"false\" ] && verbose=0\n\n# If we're running this script as root - as in logged in in the shell as root\n# user, and not via SUDO/DOAS -, we don't need to set distrobox_sudo_program\n# as it's meaningless for this use case.\nif [ \"$(id -ru)\" -ne 0 ]; then\n\t# If the DBX_SUDO_PROGRAM/distrobox_sudo_program variable was set by the\n\t# user, use its value instead of \"sudo\". But only if not running the script\n\t# as root (UID 0).\n\tdistrobox_sudo_program=${DBX_SUDO_PROGRAM:-${distrobox_sudo_program:-\"sudo\"}}\nfi\n\n# Declare it AFTER config sourcing because we do not want a default name set for rm.\ncontainer_name_default=\"my-distrobox\"\ncontainer_name_list=\"\"\n\n# show_help will print usage to stdout.\n# Arguments:\n#   None\n# Expected global variables:\n#   version: distrobox version\n# Expected env variables:\n#   None\n# Outputs:\n#   print usage with examples.\nshow_help()\n{\n\tcat << EOF\ndistrobox version: ${version}\n\nUsage:\n\n\tdistrobox-rm [-f/--force] container-name [container-name1 container-name2 ...]\n\nOptions:\n\n\t--all/-a:\t\tdelete all distroboxes\n\t--force/-f:\t\tforce deletion\n\t--rm-home:\t\tremove the mounted home if it differs from the host user's one\n\t--root/-r:\t\tlaunch podman/docker/lilipod with root privileges. Note that if you need root this is the preferred\n\t\t\t\tway over \"sudo distrobox\" (note: if using a program other than 'sudo' for root privileges is necessary,\n\t\t\t\tspecify it through the DBX_SUDO_PROGRAM env variable, or 'distrobox_sudo_program' config variable)\n\t--help/-h:\t\tshow this message\n\t--verbose/-v:\t\tshow more verbosity\n\t--version/-V:\t\tshow version\nEOF\n}\n\n# Parse arguments\nwhile :; do\n\tcase $1 in\n\t\t-h | --help)\n\t\t\t# Call a \"show_help\" function to display a synopsis, then exit.\n\t\t\tshow_help\n\t\t\texit 0\n\t\t\t;;\n\t\t-a | --all)\n\t\t\tshift\n\t\t\tall=1\n\t\t\t;;\n\t\t-r | --root)\n\t\t\tshift\n\t\t\trootful=1\n\t\t\t;;\n\t\t--rm-home)\n\t\t\tshift\n\t\t\trm_home=1\n\t\t\t;;\n\t\t-v | --verbose)\n\t\t\tverbose=1\n\t\t\tshift\n\t\t\t;;\n\t\t-V | --version)\n\t\t\tprintf \"distrobox: %s\\n\" \"${version}\"\n\t\t\texit 0\n\t\t\t;;\n\t\t-f | --force)\n\t\t\tforce=1\n\t\t\tnon_interactive=1\n\t\t\tshift\n\t\t\t;;\n\t\t-Y | --yes)\n\t\t\tnon_interactive=1\n\t\t\tshift\n\t\t\t;;\n\t\t--) # End of all options.\n\t\t\tshift\n\t\t\tbreak\n\t\t\t;;\n\t\t-*) # Invalid options.\n\t\t\tprintf >&2 \"ERROR: Invalid flag '%s'\\n\\n\" \"$1\"\n\t\t\tshow_help\n\t\t\texit 1\n\t\t\t;;\n\t\t*) # Default case: If no more options then break out of the loop.\n\t\t\t# If we have a flagless option and container_name is not specified\n\t\t\t# then let's accept argument as container_name\n\t\t\tif [ -n \"$1\" ]; then\n\t\t\t\tcontainer_name_list=\"${container_name_list} $1\"\n\t\t\t\tshift\n\t\t\telse\n\t\t\t\tbreak\n\t\t\tfi\n\t\t\t;;\n\tesac\ndone\n\nset -o errexit\nset -o nounset\n# set verbosity\nif [ \"${verbose}\" -ne 0 ]; then\n\tset -o xtrace\nfi\n\n# We depend on a container manager let's be sure we have it\n# First we use podman, else docker, else lilipod\ncase \"${container_manager}\" in\n\tautodetect)\n\t\tif command -v podman > /dev/null; then\n\t\t\tcontainer_manager=\"podman\"\n\t\telif command -v podman-launcher > /dev/null; then\n\t\t\tcontainer_manager=\"podman-launcher\"\n\t\telif command -v docker > /dev/null; then\n\t\t\tcontainer_manager=\"docker\"\n\t\telif command -v lilipod > /dev/null; then\n\t\t\tcontainer_manager=\"lilipod\"\n\t\tfi\n\t\t;;\n\tpodman)\n\t\tcontainer_manager=\"podman\"\n\t\t;;\n\tpodman-launcher)\n\t\tcontainer_manager=\"podman-launcher\"\n\t\t;;\n\tlilipod)\n\t\tcontainer_manager=\"lilipod\"\n\t\t;;\n\tdocker)\n\t\tcontainer_manager=\"docker\"\n\t\t;;\n\t*)\n\t\tprintf >&2 \"Invalid input %s.\\n\" \"${container_manager}\"\n\t\tprintf >&2 \"The available choices are: 'autodetect', 'podman', 'docker', 'lilipod'\\n\"\n\t\t;;\nesac\n\n# Be sure we have a container manager to work with.\nif ! command -v \"${container_manager}\" > /dev/null; then\n\t# Error: we need at least one between docker, podman or lilipod.\n\tprintf >&2 \"Missing dependency: we need a container manager.\\n\"\n\tprintf >&2 \"Please install one of podman,  docker or lilipod.\\n\"\n\tprintf >&2 \"You can follow the documentation on:\\n\"\n\tprintf >&2 \"\\tman distrobox-compatibility\\n\"\n\tprintf >&2 \"or:\\n\"\n\tprintf >&2 \"\\thttps://github.com/89luca89/distrobox/blob/main/docs/compatibility.md\\n\"\n\texit 127\nfi\n\n# add verbose if -v is specified\nif [ \"${verbose}\" -ne 0 ]; then\n\tcontainer_manager=\"${container_manager} --log-level debug\"\nfi\n\n# add -f if force is specified\nif [ \"${force}\" -ne 0 ]; then\n\tforce_flag=\"--force\"\nfi\n\n# prepend sudo (or the specified sudo program) if we want our container manager to be rootful\nif [ \"${rootful}\" -ne 0 ]; then\n\tcontainer_manager=\"${distrobox_sudo_program-} ${container_manager}\"\n\tdistrobox_flags=\"--root\"\nfi\n\n# If all, just set container_name to the list of names in distrobox-list\nif [ \"${all}\" -ne 0 ]; then\n\t# prepend sudo (or the specified sudo program) if we want our container manager to be rootful\n\t# shellcheck disable=SC2086,2248\n\tcontainer_name_list=\"$(\"${distrobox_path}\"/distrobox-list ${distrobox_flags} --no-color |\n\t\ttail -n +2 | cut -d'|' -f2 | tr -d ' ' | tr '\\n' ' ')\"\nfi\n\nif [ -z \"${container_name_list}\" ] && [ \"${all}\" -ne 0 ]; then\n\tprintf >&2 \"No containers found.\\n\"\n\texit 0\nfi\n\n# check if we have containers to delete\nif [ -z \"${container_name_list}\" ]; then\n\tcontainer_name_list=\"${container_name_default}\"\nfi\n\n# cleanup_exports will remove exported apps and bins for container to delete.\n# Arguments:\n#   container_name: string container name\n# Expected global variables:\n#   distrobox_flags: string additional distrobox flags to use\n# Expected env variables:\n#   None\n# Outputs:\n#   None\ncleanup_exports()\n{\n\tcontainer_name=\"$1\"\n\tIFS='¤'\n\tprintf \"Removing exported binaries...\\n\"\n\tbinary_files=\"$(grep -rl \"# distrobox_binary\" \"${HOME}/.local/bin\" 2> /dev/null | sed 's/./\\\\&/g' |\n\t\txargs -I{} grep -le \"# name: ${container_name}$\" \"{}\" | sed 's/./\\\\&/g' |\n\t\txargs -I{} printf \"%s¤\" \"{}\" 2> /dev/null || :)\"\n\tfor file in ${binary_files}; do\n\t\tprintf \"Removing exported binary %s...\\n\" \"${file}\"\n\t\trm -f \"${file}\"\n\tdone\n\n\t# Remove exported gui apps from this container in default path\n\t# shellcheck disable=SC2086,SC2038\n\tdesktop_files=\"$(find \"${HOME}/.local/share/applications/${container_name}\"* -type f -o -type l 2> /dev/null | sed 's/./\\\\&/g' |\n\t\txargs -I{} grep -le \"Exec=.*${container_name} \" \"{}\" | sed 's/./\\\\&/g' |\n\t\txargs -I{} printf \"%s¤\" \"{}\" 2> /dev/null || :)\"\n\tfor file in ${desktop_files}; do\n\t\tif [ -e \"${file}\" ]; then\n\t\t\tapp=\"$(grep -Eo \"Name=.*\" \"${file}\" | head -n 1 | cut -d'=' -f2)\"\n\t\t\ticon=\"$(grep -Eo \"Icon=.*\" \"${file}\" | head -n 1 | cut -d'=' -f2)\"\n\n\t\t\tprintf \"Removing exported app %s...\\n\" \"${app}\"\n\t\t\trm -f \"${file}\"\n\t\t\tfind \"${HOME}/.local/share/icons\" -name \"${icon}.*\" -delete\n\t\tfi\n\tdone\n\tunset IFS\n}\n\n# delete_container will remove input container\n# Arguments:\n#   container_name: string container name\n# Expected global variables:\n#   container_manager: string container manager to use\n#   distrobox_flags: string distrobox additional flags\n#   non_interactive: bool non interactive mode\n#   force_flag: bool force mode\n#   rm_home: bool remove home\n#   verbose: bool verbose\n# Expected env variables:\n#   None\n# Outputs:\n#   None\ndelete_container()\n{\n\tcontainer_name=\"$1\"\n\t# Inspect the container we're working with.\n\tcontainer_status=\"$(${container_manager} inspect --type container \\\n\t\t--format '{{.State.Status}}' \"${container_name}\" || :)\"\n\t# Does the container exist? check if inspect reported errors\n\tif [ -z \"${container_status}\" ]; then\n\t\t# If not, prompt to create it first\n\t\tprintf >&2 \"Cannot find container %s.\\n\" \"${container_name}\"\n\t\treturn\n\tfi\n\n\t# Retrieve container's HOME, and check if it's different from host's one. In\n\t# this case we prompt for deletion of the custom home.\n\tcontainer_home=$(${container_manager} inspect --type container --format \\\n\t\t'{{range .Config.Env}}{{if and (ge (len .) 5) (eq (slice . 0 5) \"HOME=\")}}{{slice . 5}}{{end}}{{end}}' \"${container_name}\")\n\t# Prompt for confirmation\n\tif [ \"${container_home}\" != \"${HOME}\" ]; then\n\t\tif [ \"${non_interactive}\" -eq 0 ] &&\n\t\t\t[ \"${rm_home}\" -eq 1 ]; then\n\n\t\t\tprintf \"Do you want to remove custom home of container %s (%s)? [y/N]: \" \"${container_name}\" \"${container_home}\"\n\t\t\tread -r response_rm_home\n\t\t\tresponse_rm_home=\"${response_rm_home:-\"N\"}\"\n\t\tfi\n\tfi\n\n\t# Validate home response\n\t# Accept only y,Y,Yes,yes,n,N,No,no.\n\tcase \"${response_rm_home}\" in\n\t\ty | Y | Yes | yes | YES)\n\t\t\trm_home_local=1\n\t\t\t;;\n\t\tn | N | No | no | NO)\n\t\t\trm_home_local=0\n\t\t\t;;\n\t\t*) # Default case: If no more options then break out of the loop.\n\t\t\tprintf >&2 \"Invalid input.\\n\"\n\t\t\tprintf >&2 \"The available choices are: y,Y,Yes,yes,YES or n,N,No,no,NO.\\nExiting.\\n\"\n\t\t\texit 1\n\t\t\t;;\n\tesac\n\n\t# Remove the container\n\tprintf \"Removing container...\\n\"\n\t# shellcheck disable=SC2086,SC2248\n\t${container_manager} rm ${force_flag} --volumes \"${container_name}\"\n\n\t# Remove exported apps and bins\n\tcleanup_exports \"${container_name}\"\n\n\t# We're going to delete the box, let's also delete the entry\n\tverbose_arg=\"\"\n\tif [ \"${verbose}\" -ne 0 ]; then\n\t\tverbose_arg=\"--verbose\"\n\tfi\n\t\"$(dirname \"$(realpath \"${0}\")\")/distrobox-generate-entry\" \"${container_name}\" --delete \"${verbose_arg}\"\n\n\t# Remove custom home\n\tif [ \"${rm_home_local}\" -eq 1 ]; then\n\t\trm -r \"${container_home}\"\n\t\tprintf \"Successfully removed %s\\n\" \"${container_home}\"\n\tfi\n}\n\n# Prompt for confirmation\nif [ \"${non_interactive}\" -eq 0 ] && [ \"${force}\" -eq 0 ]; then\n\tprintf \"Do you really want to delete containers:%s? [Y/n]: \" \"${container_name_list}\"\n\tread -r response\n\tresponse=\"${response:-\"Y\"}\"\nelse\n\tresponse=\"yes\"\nfi\n\nfor container in ${container_name_list}; do\n\tif [ \"$(${container_manager} inspect --type container --format '{{.State.Status}}' \"${container}\")\" = \"running\" ]; then\n\t\tif [ \"${non_interactive}\" -eq 0 ] && [ \"${force}\" -eq 0 ]; then\n\t\t\tprintf \"Container %s running, do you want to force delete them? [Y/n]: \" \"${container_name_list}\"\n\t\t\tread -r response_force\n\t\t\tresponse_force=\"${response_force:-\"Y\"}\"\n\t\telse\n\t\t\tresponse_force=\"yes\"\n\t\tfi\n\tfi\n\n\t# Accept only y,Y,Yes,yes,n,N,No,no.\n\tcase \"${response_force:-\"N\"}\" in\n\t\ty | Y | Yes | yes | YES)\n\t\t\tforce=1\n\t\t\tforce_flag=\"--force\"\n\t\t\tbreak\n\t\t\t;;\n\t\tn | N | No | no | NO) ;;\n\n\t\t*) # Default case: If no more options then break out of the loop.\n\t\t\tprintf >&2 \"Invalid input.\\n\"\n\t\t\tprintf >&2 \"The available choices are: y,Y,Yes,yes,YES or n,N,No,no,NO.\\nExiting.\\n\"\n\t\t\t;;\n\tesac\ndone\n\n# Accept only y,Y,Yes,yes,n,N,No,no.\ncase \"${response}\" in\n\ty | Y | Yes | yes | YES)\n\t\tfor container in ${container_name_list}; do\n\t\t\tdelete_container \"${container}\"\n\t\tdone\n\t\t;;\n\tn | N | No | no | NO)\n\t\tprintf \"Aborted.\\n\"\n\t\texit 0\n\t\t;;\n\t*) # Default case: If no more options then break out of the loop.\n\t\tprintf >&2 \"Invalid input.\\n\"\n\t\tprintf >&2 \"The available choices are: y,Y,Yes,yes,YES or n,N,No,no,NO.\\nExiting.\\n\"\n\t\texit 1\n\t\t;;\nesac\n"
  },
  {
    "path": "distrobox-stop",
    "content": "#!/bin/sh\n# SPDX-License-Identifier: GPL-3.0-only\n#\n# This file is part of the distrobox project:\n#    https://github.com/89luca89/distrobox\n#\n# Copyright (C) 2021 distrobox contributors\n#\n# distrobox is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 3\n# as published by the Free Software Foundation.\n#\n# distrobox is distributed in the hope that it will be useful, but\n# WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n# General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with distrobox; if not, see <http://www.gnu.org/licenses/>.\n\n# POSIX\n# Optional env variables:\n#\tDBX_CONTAINER_MANAGER\n#\tDBX_CONTAINER_NAME\n#\tDBX_NON_INTERACTIVE\n#\tDBX_VERBOSE\n#\tDBX_SUDO_PROGRAM\n\n# Despite of running this script via SUDO/DOAS being not supported (the\n# script itself will call the appropriate tool when necessary), we still want\n# to allow people to run it as root, logged in in a shell, and create rootful\n# containers.\n#\n# SUDO_USER is a variable set by SUDO and can be used to check whether the script was called by it. Same thing for DOAS_USER, set by DOAS.\nif {\n\t[ -n \"${SUDO_USER}\" ] || [ -n \"${DOAS_USER}\" ]\n} && [ \"$(id -ru)\" -eq 0 ]; then\n\tprintf >&2 \"Running %s via SUDO/DOAS is not supported. Instead, please try running:\\n\" \"$(basename \"${0}\")\"\n\tprintf >&2 \"  %s --root %s\\n\" \"$(basename \"${0}\")\" \"$*\"\n\texit 1\nfi\n\n# Ensure we have our env variables correctly set\n[ -z \"${USER}\" ] && USER=\"$(id -run)\"\n[ -z \"${HOME}\" ] && HOME=\"$(getent passwd \"${USER}\" | cut -d':' -f6)\"\n[ -z \"${SHELL}\" ] && SHELL=\"$(getent passwd \"${USER}\" | cut -d':' -f7)\"\n\n# Defaults\nall=0\ncontainer_manager=\"autodetect\"\ndistrobox_flags=\"\"\ndistrobox_path=\"$(dirname \"$(realpath \"${0}\")\")\"\ncontainer_name=\"\"\ncontainer_name_default=\"my-distrobox\"\ncontainer_name_list=\"\"\nnon_interactive=0\n# If the user runs this script as root in a login shell, set rootful=1.\n# There's no need for them to pass the --root flag option in such cases.\n[ \"$(id -ru)\" -eq 0 ] && rootful=1 || rootful=0\nverbose=0\nversion=\"1.8.2.4\"\n\n# Source configuration files, this is done in an hierarchy so local files have\n# priority over system defaults\n# leave priority to environment variables.\n#\n# On NixOS, for the distrobox derivation to pick up a static config file shipped\n# by the package maintainer the path must be relative to the script itself.\nself_dir=\"$(dirname \"$(realpath \"$0\")\")\"\nnix_config_file=\"${self_dir}/../share/distrobox/distrobox.conf\"\n\nconfig_files=\"\n\t${nix_config_file}\n\t/usr/share/distrobox/distrobox.conf\n\t/usr/share/defaults/distrobox/distrobox.conf\n\t/usr/etc/distrobox/distrobox.conf\n\t/usr/local/share/distrobox/distrobox.conf\n\t/etc/distrobox/distrobox.conf\n\t${XDG_CONFIG_HOME:-\"${HOME}/.config\"}/distrobox/distrobox.conf\n\t${HOME}/.distroboxrc\n\"\nfor config_file in ${config_files}; do\n\t# Shellcheck will give error for sourcing a variable file as it cannot follow\n\t# it. We don't care so let's disable this linting for now.\n\t# shellcheck disable=SC1090\n\t[ -e \"${config_file}\" ] && . \"$(realpath \"${config_file}\")\"\ndone\n\n[ -n \"${DBX_CONTAINER_MANAGER}\" ] && container_manager=\"${DBX_CONTAINER_MANAGER}\"\n[ -n \"${DBX_CONTAINER_NAME}\" ] && container_name=\"${DBX_CONTAINER_NAME}\"\n[ -n \"${DBX_NON_INTERACTIVE}\" ] && non_interactive=\"${DBX_NON_INTERACTIVE}\"\n[ -n \"${DBX_VERBOSE}\" ] && verbose=\"${DBX_VERBOSE}\"\n\n# Fixup variable=[true|false], in case we find it in the config file(s)\n[ \"${verbose}\" = \"true\" ] && verbose=1\n[ \"${verbose}\" = \"false\" ] && verbose=0\n[ \"${non_interactive}\" = \"true\" ] && non_interactive=1\n[ \"${non_interactive}\" = \"false\" ] && non_interactive=0\n\n# If we're running this script as root - as in logged in in the shell as root\n# user, and not via SUDO/DOAS -, we don't need to set distrobox_sudo_program\n# as it's meaningless for this use case.\nif [ \"$(id -ru)\" -ne 0 ]; then\n\t# If the DBX_SUDO_PROGRAM/distrobox_sudo_program variable was set by the\n\t# user, use its value instead of \"sudo\". But only if not running the script\n\t# as root (UID 0).\n\tdistrobox_sudo_program=${DBX_SUDO_PROGRAM:-${distrobox_sudo_program:-\"sudo\"}}\nfi\n\n[ -n \"${DBX_SUDO_PROGRAM}\" ] && distrobox_sudo_program=\"${DBX_SUDO_PROGRAM}\"\n\n# show_help will print usage to stdout.\n# Arguments:\n#   None\n# Expected global variables:\n#   version: distrobox version\n# Expected env variables:\n#   None\n# Outputs:\n#   print usage with examples.\nshow_help()\n{\n\tcat << EOF\ndistrobox version: ${version}\n\nUsage:\n\n\tdistrobox-stop container-name\n\nOptions:\n\n\t--all/-a:\t\tstop all distroboxes\n\t--yes/-Y:\t\tnon-interactive, stop without asking\n\t--help/-h:\t\tshow this message\n\t--root/-r:\t\tlaunch podman/docker/lilipod with root privileges. Note that if you need root this is the preferred\n\t\t\t\tway over \"sudo distrobox\" (note: if using a program other than 'sudo' for root privileges is necessary,\n\t\t\t\tspecify it through the DBX_SUDO_PROGRAM env variable, or 'distrobox_sudo_program' config variable)\n\t--verbose/-v:\t\tshow more verbosity\n\t--version/-V:\t\tshow version\nEOF\n}\n\n# Parse arguments\nwhile :; do\n\tcase $1 in\n\t\t-h | --help)\n\t\t\t# Call a \"show_help\" function to display a synopsis, then exit.\n\t\t\tshow_help\n\t\t\texit 0\n\t\t\t;;\n\t\t-a | --all)\n\t\t\tshift\n\t\t\tall=1\n\t\t\t;;\n\t\t-r | --root)\n\t\t\tshift\n\t\t\trootful=1\n\t\t\t;;\n\t\t-v | --verbose)\n\t\t\tverbose=1\n\t\t\tshift\n\t\t\t;;\n\t\t-V | --version)\n\t\t\tprintf \"distrobox: %s\\n\" \"${version}\"\n\t\t\texit 0\n\t\t\t;;\n\t\t-Y | --yes)\n\t\t\tnon_interactive=1\n\t\t\tshift\n\t\t\t;;\n\t\t--) # End of all options.\n\t\t\tshift\n\t\t\tbreak\n\t\t\t;;\n\t\t-*) # Invalid options.\n\t\t\tprintf >&2 \"ERROR: Invalid flag '%s'\\n\\n\" \"$1\"\n\t\t\tshow_help\n\t\t\texit 1\n\t\t\t;;\n\t\t*) # Default case: If no more options then break out of the loop.\n\t\t\t# If we have a flagless option and container_name is not specified\n\t\t\t# then let's accept argument as container_name\n\t\t\tif [ -n \"$1\" ]; then\n\t\t\t\tcontainer_name_list=\"${container_name_list} $1\"\n\t\t\t\tshift\n\t\t\telse\n\t\t\t\tbreak\n\t\t\tfi\n\t\t\t;;\n\tesac\ndone\n\nset -o errexit\nset -o nounset\n# set verbosity\nif [ \"${verbose}\" -ne 0 ]; then\n\tset -o xtrace\nfi\n\nif [ -z \"${container_name}\" ]; then\n\tcontainer_name=\"${container_name_default}\"\nfi\n\n# We depend on a container manager let's be sure we have it\n# First we use podman, else docker, else lilipod\ncase \"${container_manager}\" in\n\tautodetect)\n\t\tif command -v podman > /dev/null; then\n\t\t\tcontainer_manager=\"podman\"\n\t\telif command -v podman-launcher > /dev/null; then\n\t\t\tcontainer_manager=\"podman-launcher\"\n\t\telif command -v docker > /dev/null; then\n\t\t\tcontainer_manager=\"docker\"\n\t\telif command -v lilipod > /dev/null; then\n\t\t\tcontainer_manager=\"lilipod\"\n\t\tfi\n\t\t;;\n\tpodman)\n\t\tcontainer_manager=\"podman\"\n\t\t;;\n\tpodman-launcher)\n\t\tcontainer_manager=\"podman-launcher\"\n\t\t;;\n\tlilipod)\n\t\tcontainer_manager=\"lilipod\"\n\t\t;;\n\tdocker)\n\t\tcontainer_manager=\"docker\"\n\t\t;;\n\t*)\n\t\tprintf >&2 \"Invalid input %s.\\n\" \"${container_manager}\"\n\t\tprintf >&2 \"The available choices are: 'autodetect', 'podman', 'docker', 'lilipod'\\n\"\n\t\t;;\nesac\n\n# Be sure we have a container manager to work with.\nif ! command -v \"${container_manager}\" > /dev/null; then\n\t# Error: we need at least one between docker, podman or lilipod.\n\tprintf >&2 \"Missing dependency: we need a container manager.\\n\"\n\tprintf >&2 \"Please install one of podman,  docker or lilipod.\\n\"\n\tprintf >&2 \"You can follow the documentation on:\\n\"\n\tprintf >&2 \"\\tman distrobox-compatibility\\n\"\n\tprintf >&2 \"or:\\n\"\n\tprintf >&2 \"\\thttps://github.com/89luca89/distrobox/blob/main/docs/compatibility.md\\n\"\n\texit 127\nfi\n# add  verbose if -v is specified\nif [ \"${verbose}\" -ne 0 ]; then\n\tcontainer_manager=\"${container_manager} --log-level debug\"\nfi\n\n# prepend sudo (or the specified sudo program) if we want our container manager to be rootful\nif [ \"${rootful}\" -ne 0 ]; then\n\tcontainer_manager=\"${distrobox_sudo_program-} ${container_manager}\"\n\tdistrobox_flags=\"--root\"\nfi\n\n# If all, just set container_name to the list of names in distrobox-list\nif [ \"${all}\" -ne 0 ]; then\n\t# prepend sudo (or the specified sudo program) if we want our container manager to be rootful\n\t# shellcheck disable=SC2086,2248\n\tcontainer_name_list=\"$(\"${distrobox_path}\"/distrobox-list ${distrobox_flags} --no-color |\n\t\ttail -n +2 | cut -d'|' -f2 | tr -d ' ' | tr '\\n' ' ')\"\nfi\n\nif [ -z \"${container_name_list}\" ] && [ \"${all}\" -ne 0 ]; then\n\tprintf >&2 \"No containers found.\\n\"\n\texit 0\nfi\n\n# check if we have containers to delete\nif [ -z \"${container_name_list}\" ]; then\n\tcontainer_name_list=\"${container_name_default}\"\nelse\n\t# strip leading whitespace from container name\n\tcontainer_name_list=\"$(echo \"${container_name_list}\" | sed -E 's/^[[:space:]]+//')\"\nfi\n\nif [ \"${non_interactive}\" -eq 0 ]; then\n\t# Prompt to stop the container.\n\tprintf \"Do you really want to stop %s? [Y/n]: \" \"${container_name_list}\"\n\tread -r response\n\tresponse=\"${response:-\"Y\"}\"\nelse\n\tresponse=\"yes\"\nfi\n\n# Accept only y,Y,Yes,yes,n,N,No,no.\ncase \"${response}\" in\n\ty | Y | Yes | yes | YES)\n\t\t# Stop the container\n\t\tfor container_name in ${container_name_list}; do\n\t\t\t${container_manager} stop \"${container_name}\"\n\t\tdone\n\t\t;;\n\tn | N | No | no | NO)\n\t\tprintf \"Aborted.\\n\"\n\t\texit 0\n\t\t;;\n\t*) # Default case: If no more options then break out of the loop.\n\t\tprintf >&2 \"Invalid input.\\n\"\n\t\tprintf >&2 \"The available choices are: y,Y,Yes,yes,YES or n,N,No,no,NO.\\nExiting.\\n\"\n\t\texit 1\n\t\t;;\nesac\n"
  },
  {
    "path": "distrobox-upgrade",
    "content": "#!/bin/sh\n# SPDX-License-Identifier: GPL-3.0-only\n#\n# This file is part of the distrobox project:\n#    https://github.com/89luca89/distrobox\n#\n# Copyright (C) 2021 distrobox contributors\n#\n# distrobox is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 3\n# as published by the Free Software Foundation.\n#\n# distrobox is distributed in the hope that it will be useful, but\n# WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n# General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with distrobox; if not, see <http://www.gnu.org/licenses/>.\n\n# Despite of running this script via SUDO/DOAS being not supported (the\n# script itself will call the appropriate tool when necessary), we still want\n# to allow people to run it as root, logged in in a shell, and create rootful\n# containers.\n#\n# SUDO_USER is a variable set by SUDO and can be used to check whether the script was called by it. Same thing for DOAS_USER, set by DOAS.\nif {\n\t[ -n \"${SUDO_USER}\" ] || [ -n \"${DOAS_USER}\" ]\n} && [ \"$(id -ru)\" -eq 0 ]; then\n\tprintf >&2 \"Running %s via SUDO/DOAS is not supported. Instead, please try running:\\n\" \"$(basename \"${0}\")\"\n\tprintf >&2 \"  %s --root %s\\n\" \"$(basename \"${0}\")\" \"$*\"\n\texit 1\nfi\n\n# Ensure we have our env variables correctly set\n[ -z \"${USER}\" ] && USER=\"$(id -run)\"\n[ -z \"${HOME}\" ] && HOME=\"$(getent passwd \"${USER}\" | cut -d':' -f6)\"\n[ -z \"${SHELL}\" ] && SHELL=\"$(getent passwd \"${USER}\" | cut -d':' -f7)\"\n\nall=0\nrunning=0\ncontainer_manager=\"autodetect\"\ndistrobox_flags=\"\"\ndistrobox_path=\"$(dirname \"$(realpath \"${0}\")\")\"\nrootful=0\nverbose=0\nversion=\"1.8.2.4\"\n\n# Source configuration files, this is done in an hierarchy so local files have\n# priority over system defaults\n# leave priority to environment variables.\n#\n# On NixOS, for the distrobox derivation to pick up a static config file shipped\n# by the package maintainer the path must be relative to the script itself.\nself_dir=\"$(dirname \"$(realpath \"$0\")\")\"\nnix_config_file=\"${self_dir}/../share/distrobox/distrobox.conf\"\n\nconfig_files=\"\n\t${nix_config_file}\n\t/usr/share/distrobox/distrobox.conf\n\t/usr/share/defaults/distrobox/distrobox.conf\n\t/usr/etc/distrobox/distrobox.conf\n\t/usr/local/share/distrobox/distrobox.conf\n\t/etc/distrobox/distrobox.conf\n\t${XDG_CONFIG_HOME:-\"${HOME}/.config\"}/distrobox/distrobox.conf\n\t${HOME}/.distroboxrc\n\"\nfor config_file in ${config_files}; do\n\t# Shellcheck will give error for sourcing a variable file as it cannot follow\n\t# it. We don't care so let's disable this linting for now.\n\t# shellcheck disable=SC1090\n\t[ -e \"${config_file}\" ] && . \"$(realpath \"${config_file}\")\"\ndone\n\n[ -n \"${DBX_CONTAINER_MANAGER}\" ] && container_manager=\"${DBX_CONTAINER_MANAGER}\"\n[ -n \"${DBX_VERBOSE}\" ] && verbose=\"${DBX_VERBOSE}\"\n\n# Fixup variable=[true|false], in case we find it in the config file(s)\n[ \"${verbose}\" = \"true\" ] && verbose=1\n[ \"${verbose}\" = \"false\" ] && verbose=0\n\n# If we're running this script as root - as in logged in in the shell as root\n# user, and not via SUDO/DOAS -, we don't need to set distrobox_sudo_program\n# as it's meaningless for this use case.\nif [ \"$(id -ru)\" -ne 0 ]; then\n\t# If the DBX_SUDO_PROGRAM/distrobox_sudo_program variable was set by the\n\t# user, use its value instead of \"sudo\". But only if not running the script\n\t# as root (UID 0).\n\tdistrobox_sudo_program=${DBX_SUDO_PROGRAM:-${distrobox_sudo_program:-\"sudo\"}}\nfi\n\n# Declare it AFTER config sourcing because we do not want a default name set.\ncontainer_name=\"\"\n\n# show_help will print usage to stdout.\n# Arguments:\n#   None\n# Expected global variables:\n#   version: distrobox version\n# Expected env variables:\n#   None\n# Outputs:\n#   print usage with examples.\nshow_help()\n{\n\tcat << EOF\ndistrobox version: ${version}\n\nUsage:\n\n\tdistrobox-upgrade container-name\n\tdistrobox-upgrade --all\n\nOptions:\n\n\t--help/-h:\t\tshow this message\n\t--all/-a:\t\tperform for all distroboxes\n\t--running:\t\tperform only for running distroboxes\n\t--root/-r:\t\tlaunch podman/docker/lilipod with root privileges. Note that if you need root this is the preferred\n\t\t\t\tway over \"sudo distrobox\" (note: if using a program other than 'sudo' for root privileges is necessary,\n\t\t\t\tspecify it through the DBX_SUDO_PROGRAM env variable, or 'distrobox_sudo_program' config variable)\n\t--verbose/-v:\t\tshow more verbosity\n\t--version/-V:\t\tshow version\nEOF\n}\n\nif [ $# -eq 0 ]; then\n\tshow_help\n\texit\nfi\n\n# Parse arguments\nwhile :; do\n\tcase $1 in\n\t\t-h | --help)\n\t\t\t# Call a \"show_help\" function to display a synopsis, then exit.\n\t\t\tshow_help\n\t\t\texit 0\n\t\t\t;;\n\t\t-v | --verbose)\n\t\t\tverbose=1\n\t\t\tshift\n\t\t\t;;\n\t\t-V | --version)\n\t\t\tprintf \"distrobox: %s\\n\" \"${version}\"\n\t\t\texit 0\n\t\t\t;;\n\t\t-a | --all)\n\t\t\tall=1\n\t\t\tshift\n\t\t\t;;\n\t\t--running)\n\t\t\trunning=1\n\t\t\tshift\n\t\t\t;;\n\t\t-r | --root)\n\t\t\tshift\n\t\t\trootful=1\n\t\t\t;;\n\t\t--) # End of all options.\n\t\t\tshift\n\t\t\tbreak\n\t\t\t;;\n\t\t-*) # Invalid options.\n\t\t\tprintf >&2 \"ERROR: Invalid flag '%s'\\n\\n\" \"$1\"\n\t\t\tshow_help\n\t\t\texit 1\n\t\t\t;;\n\t\t*) # Default case: If no more options then break out of the loop.\n\t\t\t# If we have a flagless option and container_name is not specified\n\t\t\t# then let's accept argument as container_name\n\t\t\tif [ -n \"$1\" ]; then\n\t\t\t\tcontainer_name=\"${container_name} $1\"\n\t\t\t\tshift\n\t\t\telse\n\t\t\t\tbreak\n\t\t\tfi\n\t\t\t;;\n\tesac\ndone\n\nset -o errexit\nset -o nounset\n# set verbosity\nif [ \"${verbose}\" -ne 0 ]; then\n\tset -o xtrace\nfi\n\nif [ -z \"${container_name}\" ] && [ \"${all}\" -eq 0 ] && [ \"${running}\" -eq 0 ]; then\n\tprintf >&2 \"Please specify the name of the container.\\n\"\n\texit 1\nfi\n\n# We depend on a container manager let's be sure we have it\n# First we use podman, else docker, else lilipod\ncase \"${container_manager}\" in\n\tautodetect)\n\t\tif command -v podman > /dev/null; then\n\t\t\tcontainer_manager=\"podman\"\n\t\telif command -v podman-launcher > /dev/null; then\n\t\t\tcontainer_manager=\"podman-launcher\"\n\t\telif command -v docker > /dev/null; then\n\t\t\tcontainer_manager=\"docker\"\n\t\telif command -v lilipod > /dev/null; then\n\t\t\tcontainer_manager=\"lilipod\"\n\t\tfi\n\t\t;;\n\tpodman)\n\t\tcontainer_manager=\"podman\"\n\t\t;;\n\tpodman-launcher)\n\t\tcontainer_manager=\"podman-launcher\"\n\t\t;;\n\tlilipod)\n\t\tcontainer_manager=\"lilipod\"\n\t\t;;\n\tdocker)\n\t\tcontainer_manager=\"docker\"\n\t\t;;\n\t*)\n\t\tprintf >&2 \"Invalid input %s.\\n\" \"${container_manager}\"\n\t\tprintf >&2 \"The available choices are: 'autodetect', 'podman', 'docker', 'lilipod'\\n\"\n\t\t;;\nesac\n\n# Be sure we have a container manager to work with.\nif ! command -v \"${container_manager}\" > /dev/null; then\n\t# Error: we need at least one between docker, podman or lilipod.\n\tprintf >&2 \"Missing dependency: we need a container manager.\\n\"\n\tprintf >&2 \"Please install one of podman,  docker or lilipod.\\n\"\n\tprintf >&2 \"You can follow the documentation on:\\n\"\n\tprintf >&2 \"\\tman distrobox-compatibility\\n\"\n\tprintf >&2 \"or:\\n\"\n\tprintf >&2 \"\\thttps://github.com/89luca89/distrobox/blob/main/docs/compatibility.md\\n\"\n\texit 127\nfi\n\n# add  verbose if -v is specified\nif [ \"${verbose}\" -ne 0 ]; then\n\tcontainer_manager=\"${container_manager} --log-level debug\"\nfi\n\n# prepend sudo (or the specified sudo program) if we want our container manager to be rootful\nif [ \"${rootful}\" -ne 0 ]; then\n\tcontainer_manager=\"${distrobox_sudo_program} ${container_manager}\"\n\tdistrobox_flags=\"--root\"\nfi\n\n# If all, just set container_name to the list of names in distrobox-list\nif [ \"${all}\" -ne 0 ]; then\n\n\t# prepend sudo (or the specified sudo program) if we want our container manager to be rootful\n\t# shellcheck disable=SC2086,2248\n\tcontainer_name=\"$(\"${distrobox_path}\"/distrobox-list ${distrobox_flags} --no-color |\n\t\ttail -n +2 | cut -d'|' -f2 | tr -d ' ')\"\n\n\t# If running, set container_name to the list of names of running instances\n\tif [ \"${running}\" -ne 0 ]; then\n\t\t# shellcheck disable=SC2086,2248\n\t\tcontainer_name=\"$(\"${distrobox_path}\"/distrobox-list ${distrobox_flags} --no-color |\n\t\t\ttail -n +2 | grep -iE '\\| running|up' | cut -d'|' -f2 | tr -d ' ')\"\n\tfi\nfi\n\n# Launch the entrypoint in upgrade mode\nfor container in ${container_name}; do\n\tprintf >&2 \"\\033[1;31m Upgrading %s...\\n\\033[0m\" \"${container}\"\n\t# shellcheck disable=SC2086,SC2248\n\t\"${distrobox_path}\"/distrobox-enter \\\n\t\t${distrobox_flags} ${container} -- sh -c \\\n\t\t\"command -v su-exec 2>/dev/null && su-exec root /usr/bin/entrypoint --upgrade || command -v doas 2>/dev/null && doas /usr/bin/entrypoint --upgrade || sudo -S /usr/bin/entrypoint --upgrade\"\ndone\n"
  },
  {
    "path": "docs/404.md",
    "content": "---\nlayout: default\npermalink: /404.html\n---\n\n![404]({{site.baseurl}}/assets/404.png){:.full.pixels}\n\n# Document Not Found\n\nThe requested page could not be found. If you feel this is not normal, then you create an issue on the Gitlab.\n\n[Go Back](<javascript:window.history.go(-1);>){: .inline-button} [File an issue]({{site.issuesurl}})\n{: .dialog-buttons}\n"
  },
  {
    "path": "docs/CNAME",
    "content": "distrobox.it\n"
  },
  {
    "path": "docs/Gemfile",
    "content": "source \"https://rubygems.org\"\n\n# Hello! This is where you manage which Jekyll version is used to run.\n# When you want to use a different version, change it below, save the\n# file and run `bundle install`. Run Jekyll with `bundle exec`, like so:\n#\n#     bundle exec jekyll serve\n#\n# This will help ensure the proper Jekyll version is running.\n# Happy Jekylling!\ngem \"jekyll\", \"~> 4.1.0\"\n\n# This is the default theme for new Jekyll sites. You may change this to anything you like.\n\n# If you want to use GitHub Pages, remove the \"gem \"jekyll\"\" above and\n# uncomment the line below. To upgrade, run `bundle update github-pages`.\n# gem \"github-pages\", group: :jekyll_plugins\n\n# If you have any plugins, put them here!\ngroup :jekyll_plugins do\n#  gem 'jekyll-feed', '~> 0.13'\n#  gem 'jekyll-sitemap', '~> 1.4'\n#  gem 'jekyll-compose', '~> 0.12.0'\n#  gem 'jekyll-postfiles', '~> 3.1'\nend\n\n# Windows does not include zoneinfo files, so bundle the tzinfo-data gem\n# gem \"tzinfo-data\", platforms: [:mingw, :mswin, :x64_mingw, :jruby]\n\n# Performance-booster for watching directories on Windows\n# gem \"wdm\", \"~> 0.1.0\" if Gem.win_platform?\n"
  },
  {
    "path": "docs/README.md",
    "content": "<img src=\"assets/splash.svg\" style=\"border-radius:12px\">\n\n# Distrobox\n\n<sub>previous logo credits [j4ckr3d](https://github.com/j4ckr3d)  \ncurrent logo credits [David Lapshin](https://github.com/daudix)<sub>\n\n[![Lint](https://github.com/89luca89/distrobox/actions/workflows/main.yml/badge.svg)](https://github.com/89luca89/distrobox/actions/workflows/main.yml)\n[![CI](https://github.com/89luca89/distrobox/actions/workflows/compatibility.yml/badge.svg)](https://github.com/89luca89/distrobox/actions/workflows/compatibility.yml)\n[![GitHub](https://img.shields.io/github/license/89luca89/distrobox?color=blue)](../COPYING.md)\n[![GitHub release (latest by date)](https://img.shields.io/github/v/release/89luca89/distrobox)](https://github.com/89luca89/distrobox/releases/latest)\n[![Packaging status](https://repology.org/badge/tiny-repos/distrobox.svg)](https://repology.org/project/distrobox/versions)\n[![GitHub issues by-label](https://img.shields.io/github/issues-search/89luca89/distrobox?query=is%3Aissue%20is%3Aopen%20label%3Abug%20-label%3Await-on-user%20&label=Open%20Bug%20Reports&color=red)](https://github.com/89luca89/distrobox/issues?q=is%3Aissue+is%3Aopen+label%3Abug+-label%3Await-on-user)\n\nUse any Linux distribution inside your terminal. Enable both backward and forward\ncompatibility with software and freedom to use whatever distribution you’re more\ncomfortable with.\nDistrobox uses `podman`, `docker` or\n[`lilipod`](https://github.com/89luca89/lilipod) to create containers using the Linux distribution\nof your choice.\nThe created container will be tightly integrated with the host, allowing sharing\nof the HOME directory of the user, external storage, external USB devices and\ngraphical apps (X11/Wayland), and audio.\n\n---\n\n[Documentation](https://distrobox.it/#distrobox) -\n[Matrix Room](https://matrix.to/#/%23distrobox:matrix.org) -\n[Telegram Group](https://t.me/distrobox_chat_new)\n\n---\n\n![overview](https://user-images.githubusercontent.com/598882/144294862-f6684334-ccf4-4e5e-85f8-1d66210a0fff.png)\n\n---\n\n> [!WARNING]  \n> Documentation on GitHub strictly refers to the code in the main branch. For the official documentation\n> Head over [https://distrobox.it](https://distrobox.it)\n\n- [Distrobox](#distrobox)\n  - [What it does](#what-it-does)\n    - [See it in action](#see-it-in-action)\n  - [Why?](#why)\n    - [Aims](#aims)\n      - [Security implications](#security-implications)\n- [Quick Start](#quick-start)\n- [Assemble Distrobox](#assemble-distrobox)\n- [Configure Distrobox](#configure-distrobox)\n- [Installation](#installation)\n  - [Alternative methods](#alternative-methods)\n    - [Curl or Wget](#curl-or-wget)\n    - [Git](#git)\n  - [Dependencies](#dependencies)\n    - [Install Podman without root](compatibility.md#install-podman-in-a-static-manner)\n  - [Uninstallation](#uninstallation)\n- [Compatibility](compatibility.md)\n  - [Supported container managers](compatibility.md#supported-container-managers)\n  - [Host Distros](compatibility.md#host-distros)\n    - [Install on the Steamdeck](posts/steamdeck_guide.md)\n  - [Containers Distros](compatibility.md#containers-distros)\n- [Usage](usage/usage.md)\n  - [Outside the distrobox](usage/usage.md#outside-the-distrobox)\n    - [distrobox-assemble](usage/distrobox-assemble.md)\n    - [distrobox-create](usage/distrobox-create.md)\n    - [distrobox-enter](usage/distrobox-enter.md)\n    - [distrobox-ephemeral](usage/distrobox-ephemeral.md)\n    - [distrobox-generate-entry](usage/distrobox-generate-entry.md)\n    - [distrobox-list](usage/distrobox-list.md)\n    - [distrobox-rm](usage/distrobox-rm.md)\n    - [distrobox-stop](usage/distrobox-stop.md)\n    - [distrobox-upgrade](usage/distrobox-upgrade.md)\n  - [Inside the distrobox](usage/usage.md#inside-the-distrobox)\n    - [distrobox-export](usage/distrobox-export.md)\n    - [distrobox-host-exec](usage/distrobox-host-exec.md)\n    - [distrobox-init](usage/distrobox-init.md)\n  - [Configure distrobox](#configure-distrobox)\n- [Useful tips](useful_tips.md)\n  - [Launch a distrobox from your applications list](useful_tips.md#launch-a-distrobox-from-your-applications-list)\n  - [Create a distrobox with a custom HOME directory](useful_tips.md#create-a-distrobox-with-a-custom-home-directory)\n  - [Mount additional volumes in a distrobox](useful_tips.md#mount-additional-volumes-in-a-distrobox)\n  - [Use a different shell than the host](useful_tips.md#use-a-different-shell-than-the-host)\n  - [Run the container with real root](useful_tips.md#run-the-container-with-real-root)\n  - [Run Debian/Ubuntu container behind proxy](useful_tips.md#run-debianubuntu-container-behind-proxy)\n  - [Using a command other than sudo to run a rootful container](useful_tips.md#using-a-command-other-than-sudo-to-run-a-rootful-container)\n  - [Duplicate an existing distrobox](useful_tips.md#duplicate-an-existing-distrobox)\n  - [Export to the host](useful_tips.md#export-to-the-host)\n  - [Execute commands on the host](useful_tips.md#execute-commands-on-the-host)\n  - [Resolve \"Error cannot open display: :0\"](useful_tips.md#resolve-error-cannot-open-display-0)\n  - [Enable SSH X-Forwarding when SSH-ing in a distrobox](useful_tips.md#enable-ssh-x-forwarding-when-ssh-ing-in-a-distrobox)\n  - [Using init system inside a distrobox](useful_tips.md#using-init-system-inside-a-distrobox)\n  - [Using Docker inside a Distrobox](useful_tips.md#using-docker-inside-a-distrobox)\n  - [Using Podman inside a Distrobox](useful_tips.md#using-podman-inside-a-distrobox)\n  - [Using LXC inside a Distrobox](useful_tips.md#using-lxc-inside-a-distrobox)\n  - [Using Waydroid inside a Distrobox](useful_tips.md#using-waydroid-inside-a-distrobox)\n    - [Manual Installation](useful_tips.md#manual-installation)\n    - [Automated Installation](useful_tips.md#automated-installation)\n  - [Using host's Podman or Docker inside a Distrobox](useful_tips.md#using-hosts-podman-or-docker-inside-a-distrobox)\n  - [Using distrobox as main cli](useful_tips.md#using-distrobox-as-main-cli)\n  - [Using a different architecture](useful_tips.md#using-a-different-architecture)\n  - [Using the GPU inside the container](useful_tips.md#using-the-gpu-inside-the-container)\n    - [Using nvidia-container-toolkit](useful_tips.md#using-nvidia-container-toolkit)\n  - [Slow creation on podman and image size getting bigger with distrobox create](useful_tips.md#slow-creation-on-podman-and-image-size-getting-bigger-with-distrobox-create)\n  - [Container save and restore](useful_tips.md#container-save-and-restore)\n  - [Check used resources](useful_tips.md#check-used-resources)\n  - [Pre-installing additional package repositories](useful_tips.md#pre-installing-additional-package-repositories)\n  - [Apply resource limitation on the fly](useful_tips.md#apply-resource-limitation-on-the-fly)\n- [Posts](posts/posts.md)\n  - [Create a dedicated distrobox container](posts/distrobox_custom.md)\n  - [Execute a command on the Host](posts/execute_commands_on_host.md)\n  - [Install Podman in HOME](posts/install_podman_static.md)\n  - [Install Lilipod in HOME](posts/install_lilipod_static.md)\n  - [Install on Steamdeck](posts/steamdeck_guide.md)\n  - [Integrate VSCode and Distrobox](posts/integrate_vscode_distrobox.md)\n  - [Run Libvirt using distrobox](posts/run_libvirt_in_distrobox.md)\n  - [Run latest GNOME and KDE Plasma using distrobox](posts/run_latest_gnome_kde_on_distrobox.md)\n- [Featured Articles](featured_articles.md)\n  - [Articles](featured_articles.md#articles)\n    - [Run Distrobox on Fedora Linux - Fedora Magazine](https://fedoramagazine.org/run-distrobox-on-fedora-linux/)\n    - [DistroBox – Run Any Linux Distribution Inside Linux Terminal - TecMint](https://www.tecmint.com/distrobox-run-any-linux-distribution/)\n    - [Distrobox: Try Multiple Linux Distributions via the Terminal - It's FOSS](https://itsfoss.com/distrobox/)\n    - [Distrobox - How to quickly deploy a Linux distribution with GUI applications via a container](https://www.techrepublic.com/article/how-to-quickly-deploy-a-linux-distribution-with-gui-applications-via-a-container/)\n    - [Using Distrobox To Augment The Package Selection On Clear Linux - Phoronix](https://www.phoronix.com/scan.php?page=news_item&px=Distrobox-Clear-Linux)\n    - [Benchmark: benefits of Clear Linux containers (distrobox) - Phoronix](https://www.phoronix.com/forums/forum/phoronix/latest-phoronix-articles/1305326-clear-linux-container-performance-continues-showing-sizable-gains)\n    - [Distrobox - A great item in the Linux toolbelt - phmurphy's blog](https://phmurphy.com/posts/distrobox-toolbelt/)\n    - [Distrobox: Run (pretty much) any Linux distro under almost any other - TheRegister](https://www.theregister.com/2022/05/31/distrobox_130_released/)\n    - [Day-to-day differences between Fedora Silverblue and Ubuntu - castrojo's blog](https://www.ypsidanger.com/day-to-day-advantages-of-fedora-silverblue/)\n    - [Distrobox is Awesome - Running Window Manager and Desktop environments using Distrobox](https://cloudyday.tech.blog/2022/05/14/distrobox-is-awesome/)\n    - [Japanese input on Clear Linux with Mozc via Ubuntu container with Distrobox](https://impsbl.hatenablog.jp/entry/JapaneseInputOnClearLinuxWithMozc_en)\n    - [MID (MaXX Interactive Desktop) on Clear Linux via Ubuntu container with Distrobox](https://impsbl.hatenablog.jp/entry/MIDonClearLinuxWithDistrobox_en)\n    - [Running Other Linux Distros with Distrobox on Fedora Linux - bandithijo's blog](featured_articles.md)\n  - [Talks and Videos](featured_articles.md#talks)\n    - [Linux App Summit 2022 - Distrobox: Run Any App On Any Distro - BoF](https://github.com/89luca89/distrobox/files/8598433/distrobox-las-talk.pdf)\n    - [Opensource Summit 2022 - Distrobox: Run Any App On Any Distro](https://www.youtube.com/watch?v=eM1p47tow4o)\n    - [A \"Box\" Full of Tools and Distros - Dario Faggioli @ OpenSUSE Conference 2022](https://www.youtube.com/watch?v=_RzARte80SQ)\n    - [Podman Community Meeting October 4, 2022](https://www.youtube.com/watch?v=JNijOHL4_Ko)\n    - [Distrobox opens the Steam Deck to a whole new world (GUIDE) - GamingOnLinux](https://www.youtube.com/watch?v=kkkyNA31KOA)\n    - [CERN - Containerization as a means of extending the lifetime of HDL development tools](https://cdsweb.cern.ch/record/2859962?ln=ja)\n    - [How to Code with Distrobox on the Steam Deck](https://www.youtube.com/watch?v=qic7lmACqPo)\n    - [Why you should be running the MicroOS Desktop](https://www.youtube.com/watch?v=lKYLF1tA4Ik)\n  - [Podcasts](featured_articles.md#podcasts)\n\n---\n\n## What it does\n\nSimply put it's a fancy wrapper around `podman`, `docker`, or `lilipod` to create and start\ncontainers which are highly integrated with the hosts.\n\nThe distrobox environment is based on an [OCI image](https://github.com/opencontainers/image-spec).\nThis image is used to create a container that seamlessly integrates with the\nrest of the operating system by providing access to the user's home directory,\nthe Wayland and X11 sockets, networking, removable devices (like USB sticks),\nsystemd journal, SSH agent, D-Bus,\nulimits, /dev and the udev database, etc...\n\nIt implements the same concepts introduced by <https://github.com/containers/toolbox>\nbut in a simplified way, using POSIX sh and aiming at broader compatibility.\n\nAll the props go to them as they had the great idea to implement this stuff.\n\nIt is divided into 12 commands:\n\n- `distrobox-assemble` – create and destroy containers based on a config file\n- `distrobox-create` – create a container\n- `distrobox-enter`  – enter a container\n- `distrobox-ephemeral`  – create a temporal container, destroy it when exiting the shell\n- `distrobox-list` – list containers created with distrobox\n- `distrobox-rm` – delete a container created with distrobox\n- `distrobox-stop` – stop a running container created with distrobox\n- `distrobox-upgrade` – upgrade one or more running containers created with distrobox at once\n- `distrobox-generate-entry` – create an entry of a created container in the applications list\n- `distrobox-init`   – entry point of the container (not meant to be used manually)\n- `distrobox-export` – use inside the container,\n  export apps and services from the container to the host\n- `distrobox-host-exec` – run commands/programs from the host, while inside\n of the container\n\nIt also includes a little wrapper to launch commands with `distrobox COMMAND`\ninstead of calling the single files.\n\nPlease check [the usage docs](usage/usage.md) and [see some handy tips on how to use it](useful_tips.md).\n\n### See it in action\n\nThanks to [castrojo](https://github.com/castrojo), you can see Distrobox in\naction in this explanatory video on his setup with Distrobox, Toolbx,\nFedora Silverblue for the [uBlue](https://github.com/ublue-os) project\n(check it out!)\n\n[![Video](https://user-images.githubusercontent.com/598882/153680522-f5903607-2854-4cfb-a186-cba7403745bd.png)](https://www.youtube.com/watch?v=Q2PrISAOtbY)\n\n## Why\n\n- Provide a mutable environment on an immutable OS, like [ChromeOS, Endless OS,\n  Fedora Atomic Desktops (e.g. Silverblue), OpenSUSE Aeon/Kalpa, Vanilla OS](compatibility.md#host-distros), or [SteamOS3](posts/steamdeck_guide.md)\n- Provide a locally privileged environment for sudoless setups\n  (e.g. company-provided laptops, security reasons, etc...)\n- To mix and match a stable base system (e.g. Debian Stable, Ubuntu LTS, Red Hat)\n  with a bleeding-edge environment for development or gaming\n  (e.g. Arch, OpenSUSE Tumbleweed, or Fedora with the latest Mesa)\n- Leverage a high abundance of curated distro images for `docker`/`podman` to\n  manage multiple environments.\n\nRefer to the compatibility list for an overview of the supported host distros\n[HERE](compatibility.md#host-distros) and container's distro [HERE](compatibility.md#containers-distros).\n\n### Aims\n\nThis project aims to bring **any distro userland to any other distro**\nsupporting `podman`, `docker`, or `lilipod`.\nIt has been written in POSIX shell to be as portable as possible and it does not have\nproblems with dependencies and `glibc` version's compatibility.\n\nRefer [HERE](compatibility.md#supported-container-managers) for a list of\nsupported container managers and minimum supported versions.\n\nIt also aims to enter the container **as fast as possible**, every millisecond\nadds up if you use the container as your default environment for your terminal:\n\nThese are some sample results of `distrobox-enter` on the same container on my\nweak laptop:\n\n```console\n~$ hyperfine --warmup 3 --runs 100 \"distrobox enter bench -- whoami\"\nBenchmark 1: distrobox enter bench -- whoami\n  Time (mean ± σ):     395.6 ms ±  10.5 ms    [User: 167.4 ms, System: 62.4 ms]\n  Range (min … max):   297.3 ms … 408.9 ms    100 runs\n```\n\n#### Security implications\n\nIsolation and sandboxing are **not** the main aims of the project, on the contrary\nit aims to tightly integrate the container with the host.\nThe container will have complete access to your home, pen drive, and so on,\nso do not expect it to be highly sandboxed like a plain\n`docker`/`podman` container or a Flatpak.\n\n⚠️ **BE CAREFUL**:⚠️  if you use `docker`, or you use `podman`/`lilipod` with the `--root/-r` flag,\nthe containers will run as root, so **root inside the rootful container can modify\nsystem stuff outside the container**,\nBe also aware that **In rootful mode, you'll be asked to set up the user's password**, this will\nensure at least that the container is not a passwordless gate to root,\nbut if you have security concerns for this, **use `podman` or `lilipod` that runs in rootless mode**.\nRootless `docker` is still not working as intended and will be included in the future\nwhen it will be complete.\n\nThat said, it is useful to read the discussion about decoupling with the host,\navailable here: [#28 Sandboxed mode](https://github.com/89luca89/distrobox/issues/28).\n\nIf you are looking for something similar to Distrobox but with sandboxing capabilities,\nthere are other options to consider which do prioritise isolation such as [Litterbox](https://github.com/Gerharddc/litterbox).\n\n---\n\n# Quick Start\n\n**Create a new distrobox:**\n\n`distrobox create -n test`\n\n**Create a new distrobox with Systemd (acts similar to an LXC):**\n\n`distrobox create --name test --init --image debian:latest --additional-packages \"systemd libpam-systemd pipewire-audio-client-libraries\"`\n\n**Enter created distrobox:**\n\n`distrobox enter test`\n\n**Add one with a [different distribution](https://github.com/89luca89/distrobox/blob/main/docs/compatibility.md#host-distros),\ne.g. Ubuntu 20.04:**\n\n`distrobox create -i ubuntu:20.04`\n\n**Execute a command in a distrobox:**\n\n`distrobox enter test -- command-to-execute`\n\n**List running distroboxes:**\n\n`distrobox list`\n\n**Stop a running distrobox:**\n\n`distrobox stop test`\n\n**Remove a distrobox:**\n\n`distrobox rm test`\n\nYou can check [HERE for more advanced usage](usage/usage.md)\nand check a [comprehensive list of useful tips HERE](useful_tips.md).\n\n# Assemble Distrobox\n\nManifest files can be used to declare a set of distroboxes and use\n`distrobox-assemble` to create/destroy them in batch.\n\nHead over the [usage docs of distrobox-assemble](usage/distrobox-assemble.md)\nfor a more detailed guide.\n\n# Configure Distrobox\n\nConfiguration files can be placed in the following paths, from the least important\nto the most important:\n\n- /usr/share/distrobox/distrobox.conf\n- /usr/etc/distrobox/distrobox.conf\n- /etc/distrobox/distrobox.conf\n- ${HOME}/.config/distrobox/distrobox.conf\n- ${HOME}/.distroboxrc\n\nYou can specify inside distrobox configurations and distrobox-specific Environment\nvariables.\n\nExample configuration file:\n\n```conf\ncontainer_always_pull=\"1\"\ncontainer_generate_entry=0\ncontainer_manager=\"docker\"\ncontainer_image_default=\"registry.opensuse.org/opensuse/toolbox:latest\"\ncontainer_name_default=\"test-name-1\"\ncontainer_user_custom_home=\"$HOME/.local/share/container-home-test\"\ncontainer_init_hook=\"~/.local/distrobox/a_custom_default_init_hook.sh\"\ncontainer_pre_init_hook=\"~/a_custom_default_pre_init_hook.sh\"\ncontainer_manager_additional_flags=\"--env-file /path/to/file --custom-flag\"\ncontainer_additional_volumes=\"/example:/example1 /example2:/example3:ro\"\nnon_interactive=\"1\"\nskip_workdir=\"0\"\nPATH=\"$PATH:/path/to/custom/podman\"\n```\n\nAlternatively, it is possible to specify preferences using ENV variables:\n\n- DBX_CONTAINER_ALWAYS_PULL\n- DBX_CONTAINER_CUSTOM_HOME\n- DBX_CONTAINER_IMAGE\n- DBX_CONTAINER_MANAGER\n- DBX_CONTAINER_NAME\n- DBX_CONTAINER_ENTRY\n- DBX_NON_INTERACTIVE\n- DBX_SKIP_WORKDIR\n\n---\n\n# Installation\n\nDistrobox is packaged in the following distributions, if your distribution is\non this list, you can refer to your repos for installation:\n\n[![Packaging status](https://repology.org/badge/vertical-allrepos/distrobox.svg)](https://repology.org/project/distrobox/versions)\n\nThanks to the maintainers for their work: [M0Rf30](https://github.com/M0Rf30),\n[alcir](https://github.com/alcir), [dfaggioli](https://github.com/dfaggioli),\n[AtilaSaraiva](https://github.com/AtilaSaraiva), [michel-slm](https://github.com/michel-slm)\n\n## Alternative methods\n\nHere is a list of alternative ways to install `distrobox`.\n\n### Curl or Wget\n\nIf you like to live your life dangerously, or you want the latest release,\nyou can trust me and simply run this in your terminal:\n\n```sh\ncurl -s https://raw.githubusercontent.com/89luca89/distrobox/main/install | sudo sh\n```\n\nor using wget\n\n```sh\nwget -qO- https://raw.githubusercontent.com/89luca89/distrobox/main/install | sudo sh\n```\n\nor if you want to select a custom directory to install without sudo:\n\n```sh\ncurl -s https://raw.githubusercontent.com/89luca89/distrobox/main/install | sh -s -- --prefix ~/.local\n```\n\nor using wget\n\n```sh\nwget -qO- https://raw.githubusercontent.com/89luca89/distrobox/main/install | sh -s -- --prefix ~/.local\n```\n\nIf you want to install the last development version, directly from the last commit on Git, you can use:\n\n```sh\ncurl -s https://raw.githubusercontent.com/89luca89/distrobox/main/install | sudo sh -s -- --next\n```\n\nor using wget\n\n```sh\nwget -qO- https://raw.githubusercontent.com/89luca89/distrobox/main/install | sudo sh -s -- --next\n```\n\nor:\n\n```sh\ncurl -s https://raw.githubusercontent.com/89luca89/distrobox/main/install | sh -s -- --next --prefix ~/.local\n```\n\nor using wget\n\n```sh\nwget -qO- https://raw.githubusercontent.com/89luca89/distrobox/main/install | sh -s -- --next --prefix ~/.local\n```\n\n### Upgrading\n\nJust run the `curl` or `wget` command again.\n\n> [!WARNING]\n> Remember to add prefix-path-you-choose/bin to your PATH, to make it work.\n\n### Git\n\nAlternatively, you can clone the project using `git clone` or using the latest\nrelease [HERE](https://github.com/89luca89/distrobox/releases/latest).\n\nEnter the directory and run `./install`, by default it will attempt to install\nin `~/.local` but if you run the script as root, it will default to `/usr/local`.\nYou can specify a custom directory with the `--prefix` flag\nsuch as `./install --prefix ~/.distrobox`.\n\nPrefix explained: main distrobox files get installed to `${prefix}/bin` whereas\nthe man pages get installed to `${prefix}/share/man`.\n\n---\n\nCheck the [Host Distros](compatibility.md#host-distros) compatibility list for\ndistro-specific instructions.\n\n## Dependencies\n\nDistrobox depends on a container manager to work, you can choose to install\neither `podman`, `docker` or [`lilipod`](https://github.com/89luca89/lilipod).\n\nPlease look in the [Compatibility Table](compatibility.md#host-distros) for your\ndistribution notes.\n\nThere are ways to install\n[Podman without root privileges and in home](compatibility.md#install-podman-in-a-static-manner). Or\n[Lilipod without root privileges and in home](compatibility.md#install-lilipod-in-a-static-manner).\nThis should play well with completely sudoless setups and with devices like the Steam Deck (SteamOS).\n\n---\n\n## Uninstallation\n\nIf you installed `distrobox` using the `install` script in the default install\ndirectory use this:\n\n```sh\ncurl -s https://raw.githubusercontent.com/89luca89/distrobox/main/uninstall | sudo sh\n```\n\nor if you specified a custom path:\n\n```sh\ncurl -s https://raw.githubusercontent.com/89luca89/distrobox/main/uninstall | sh -s -- --prefix ~/.local\n```\n\nElse, if you cloned the project using `git clone` or using the latest archive release\nfrom [HERE](https://github.com/89luca89/distrobox/releases/latest),\n\nenter the directory and run `./uninstall`, by default it will assume the installation\ndirectory was `/usr/local` if ran as root or `~/.local`,\nyou can specify another directory if needed with `./uninstall --prefix ~/.local`\n\n---\n\n![distro-box](./assets/distro-box.webp)\n\n<sub>This artwork uses [Cardboard Box](https://skfb.ly/6Wq6q) model by [J0Y](https://sketchfab.com/lloydrostek)\nlicensed under [Creative Commons Attribution 4.0](http://creativecommons.org/licenses/by/4.0)  \nThis artwork uses [GTK Loop Animation](https://github.com/gnome-design-team/gnome-mockups/blob/master/gtk/loop6.blend)\nby [GNOME Project](https://www.gnome.org)\nlicensed under [Creative Commons Attribution-ShareAlike 3.0](https://creativecommons.org/licenses/by-sa/3.0)\nas a pre-configured scene<sub>\n"
  },
  {
    "path": "docs/_config.yml",
    "content": "# Site settings\ntitle: Distrobox\nbaseurl: \"/\" # the subpath of your site, e.g. /blog/\n                                 # usually empty. necessary for building absolute URIs\n                                 # for metadata header\nurl: \"https://distrobox.it\"   # the base hostname & protocol for your site\nsourceurl: \"https://github.com/89luca89/distrobox/tree/main/docs\" # \"edit this website\" link in the footer\ndescription: \"Use any linux distribution inside your terminal.\"\nissuesurl: \"https://github.com/89luca89/distrobox/issues\" # issue tracker for website\npermalink: /:title/\nprimary-color: \"#70594d\" #used in ios theme. further color customization in style.css\n\n# Build settings\nmarkdown: kramdown\n"
  },
  {
    "path": "docs/_includes/footer.html",
    "content": "<footer class=\"site-footer\">\n  <p>&copy; {{ site.title }}, 2021 &ndash; 2024</p>\n\n  <p><a href=\"{{ site.sourceurl }}\">Website source</a></p>\n</footer>\n"
  },
  {
    "path": "docs/_includes/head.html",
    "content": "<head>\n  <meta charset=\"utf-8\">\n  <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">\n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n  <meta name=\"theme-color\" content=\"{{ site.primary-color }}\"><!-- primary color -->\n\n  <title>{% if page.title %}{{ page.title }}{% else %}{{ site.title }}{% endif %}</title>\n\n  <link rel=\"canonical\" href=\"{{ page.url | replace:'index.html','' | prepend: site.baseurl | prepend: site.url }}\" />\n  <link rel=\"alternate\" type=\"application/rss+xml\" title=\"{{ site.title }}\" href=\"{{ \"/feed.xml\" | prepend: site.baseurl | prepend: site.url }}\" />\n\n  <link rel=\"stylesheet\" href=\"{{ \"/style.css\" | prepend: site.baseurl }}\" />\n  \n  <link rel=\"icon\" type=\"image/png\" href=\"{{ \"/favicon.png\" | prepend: site.baseurl }}\" />\n  <link rel=\"icon\" sizes=\"144x144\" href=\"{{ \"/apple-touch-icon.png\" | prepend: site.baseurl }}\" />\n  \n  <!-- Twitter -->\n  <meta property=\"twitter:title\" content=\"{{site.title}}\" />\n  <meta property=\"twitter:image\" content=\"{{ \"/assets/card.web\" | prepend: site.baseurl | prepend: site.url }}\" />\n  <meta property=\"twitter:card\" content=\"summary_large_image\" />\n  <meta property=\"twitter:description\" content=\"{{site.description}}\" />\n\n  <!-- Open Graph -->\n  <meta property=\"og:title\" content=\"{{ site.title }}\" />\n  <meta property=\"og:url\" content=\"{{ site.url }}\" />\n  <meta property=\"og:description\" content=\"{{ site.description }}\" />\n  <meta property=\"og:image\" content=\"{{ \"/assets/card.webp\" | prepend: site.baseurl | prepend: site.url }}\" />\n</head>\n"
  },
  {
    "path": "docs/_includes/header.html",
    "content": "<header class=\"site-header\">\n  <h1 id=\"logo\"><a href=\"{{ \"/\" | prepend: site.baseurl }}\">{{ site.title }}</a></h1>\n</header>\n"
  },
  {
    "path": "docs/_layouts/default.html",
    "content": "<!DOCTYPE html>\n<html>\n\n  {% include head.html %}\n\n  <body>\n\n    {% include header.html %}\n\n    <div class=\"container\">\n      {{ content }}\n    </div>\n\n    {% include footer.html %}\n\n  </body>\n\n</html>\n"
  },
  {
    "path": "docs/assets/credits.md",
    "content": "# Assets credits\n\n## Logo\n\nPrevious logo was created by [j4ckr3d](https://github.com/j4ckr3d)\n\nCurrent logo was created by [daudix-UFO](https://github.com/daudix-UFO)\n\n## Images\n\nAssets used in `distro-box.webp`\n\n- [Cardboard Box](https://skfb.ly/6Wq6q) model by\n  [J0Y](https://sketchfab.com/lloydrostek) licensed under\n  [Creative Commons Attribution 4.0](http://creativecommons.org/licenses/by/4.0)\n- [GTK Loop Animation](https://github.com/gnome-design-team/gnome-mockups/blob/master/gtk/loop6.blend) by\n  [GNOME Project](https://www.gnome.org) licensed under\n  [Creative Commons Attribution-ShareAlike 3.0](https://creativecommons.org/licenses/by-sa/3.0) as a pre-configured scene\n- Distro icons by\n  [u/walrusz](https://www.reddit.com/r/linux/comments/nt1tm9/i_made_a_uniform_icon_set_of_linux_distribution)\n\nAssets used in `distro-box-alt.webp`\n\n- ['90 Light Commercial Truck](https://skfb.ly/ootyy) model by\n  [Daniel Zhabotinsky](https://sketchfab.com/DanielZhabotinsky) licensed under\n  [Creative Commons Attribution 4.0](http://creativecommons.org/licenses/by/4.0)\n- [Cardboard Box](https://skfb.ly/6Wq6q) model by\n  [J0Y](https://sketchfab.com/lloydrostek) licensed under\n  [Creative Commons Attribution 4.0](http://creativecommons.org/licenses/by/4.0)\n- [GTK Loop Animation](https://github.com/gnome-design-team/gnome-mockups/blob/master/gtk/loop6.blend) by\n  [GNOME Project](https://www.gnome.org) licensed under\n  [Creative Commons Attribution-ShareAlike 3.0](https://creativecommons.org/licenses/by-sa/3.0) as a pre-configured scene\n- Distro icons by\n  [u/walrusz](https://www.reddit.com/r/linux/comments/nt1tm9/i_made_a_uniform_icon_set_of_linux_distribution)\n"
  },
  {
    "path": "docs/compatibility.md",
    "content": "- [Distrobox](README.md)\n  - [Compatibility](#compatibility)\n    - [Supported container managers](#supported-container-managers)\n    - [Host Distros](#host-distros)\n      - [Compatibility notes](#compatibility-notes)\n      - [Non shared mounts](#non-shared-mounts)\n      - [List of distributions including distrobox in their repositories](#list-of-distributions-including-distrobox-in-their-repositories)\n      - [New Host Distro support](#new-host-distro-support)\n    - [Containers Distros](#containers-distros)\n      - [New Distro support](#new-distro-support)\n      - [Older distributions](#older-distributions)\n\n---\n\n# Compatibility\n\nThis project **does not need a dedicated image**. It can use any OCI images from\ndocker-hub, quay.io, or any registry of your choice.\n\nMany cloud images are stripped down on purpose to save size and may not include\ncommands such as `which`, `mount`, `less` or `vi`). Additional packages can be\ninstalled once inside the container. We recommend using your preferred automation\ntool inside the container if you find yourself having to repeatedly create new containers.\nMaintaining your own custom image is also an option.\n\nThe main concern is having basic Linux utilities (`mount`), basic user management\nutilities (`usermod, passwd`), and `sudo` correctly set.\n\n## Supported container managers\n\n`distrobox` can run on either `podman`, `docker` or [`lilipod`](https://github.com/89luca89/lilipod)\n\nIt depends either on `podman` configured in `rootless mode`\nor on `docker` configured without sudo (follow [THESE instructions](https://docs.docker.com/engine/install/linux-postinstall/))\n\n- Minimum podman version: **2.1.0**\n- Minimum docker client version: **19.03.15**\n- Minimum lilipod version: **v0.0.1**\n\nFollow the official installation guide here:\n\n- <https://podman.io/getting-started/installation>\n- <https://docs.docker.com/engine/install>\n- <https://docs.docker.com/engine/install/linux-postinstall/>\n\n## Host Distros\n\nDistrobox has been successfully tested on:\n\n| Distro | Version | Notes |\n| --- | --- | --- |\n| Alpine Linux | | To setup rootless podman, look [HERE](https://wiki.alpinelinux.org/wiki/Podman) |\n| Arch Linux | | `distrobox` is available in the `extra` repository and `distrobox-git` is available in the AUR (thanks [M0Rf30](https://github.com/M0Rf30)!). <br> To setup rootless podman, look [HERE](https://wiki.archlinux.org/title/Podman) |\n| Bazzite | 38 | `distrobox-git` is preinstalled. |\n| CentOS | 8 <br> 8 Stream <br> 9 Stream | `distrobox` is available in epel repos. (thanks [alcir](https://github.com/alcir)!) |\n| Chimera Linux | | `distrobox` is available in `chimera-repo-user`. |\n| ChromeOS | Debian 11 (docker with make-shared workaround #non-shared-mounts) <br> Debian 12 (podman) | using built-in Linux on ChromeOS mode which is debian-based, which can be [upgraded](https://wiki.debian.org/DebianUpgrade) from 11 bullseye to 12 bookworm (in fact 12 is recommended) |\n| Debian | 11 <br> 12 <br> Testing <br> Unstable | `distrobox` is available in default repos starting from version 12 (thanks [michel-slm!](https://github.com/michel-slm!)!) |\n| deepin | 23 <br> Testing <br> Unstable | `distrobox` is available in default repos in `testing` and `unstable` |\n| EndlessOS | 4.0.0 | |\n| Fedora Silverblue/Kinoite | 35 <br> 36 <br> 37 <br> Rawhide | `distrobox` is available in default repos.(thanks [alcir](https://github.com/alcir)!) |\n| Fedora | 35 <br> 36 <br> 37 <br> 38 <br> Rawhide | `distrobox` is available in default repos.(thanks [alcir](https://github.com/alcir)!) |\n| Gentoo | | To setup rootless podman, look [HERE](https://wiki.gentoo.org/wiki/Podman) |\n| KDE neon | | `distrobox` is available in default repo |\n| macOS | | Requires [Docker Desktop](https://docs.docker.com/desktop/install/mac-install/). Support is limited to CLI use only; GUI, sound, and graphics are not supported. Please do not open issues for GUI/sound/graphics-related bugs on macOS. |\n| Manjaro | | To setup rootless podman, look [HERE](https://wiki.archlinux.org/title/Podman) |\n| NixOS | 21.11 | Make sure to mind your executable paths. Sometimes a container will not have nix paths, and sometimes it will not have its own paths.  <br>  Distrobox is available in Nixpkg collection (thanks [AtilaSaraiva](https://github.com/AtilaSaraiva)!)< <br> To setup Docker, look [HERE](https://wiki.nixos.org/wiki/Docker)  <br> To setup Podman, look [HERE](https://wiki.nixos.org/wiki/Podman) and [HERE](https://gist.github.com/adisbladis/187204cb772800489ee3dac4acdd9947) |\n| openSUSE | Leap | `distrobox` is available in default repos (thanks [dfaggioli](https://github.com/dfaggioli)!). <br> Prior to Leap 15.6 ``podman`` logging needs to be configured properly, more details in [this openSUSE bug](https://bugzilla.opensuse.org/show_bug.cgi?id=1199871). |\n| openSUSE | Tumbleweed <br> Slowroll <br> Aeon/Kalpa | `distrobox` is available in default repos (thanks [dfaggioli](https://github.com/dfaggioli)!) <br> For Tumbleweed/Slowroll, do: `zypper install distrobox`. <br> For Aeon/Kalpa, **distrobox is installed by default**. |\n| SUSE Linux Enterprise Server | 15 SP5 <br> or later | `distrobox` is available in `SUSE Package Hub` repo. <br> Enable this repo and then: <br> `zypper install distrobox`. <br>Prior to SLES 15 SP6 ``podman`` logging needs to be configured properly, more details in [this openSUSE bug](https://bugzilla.opensuse.org/show_bug.cgi?id=1199871). |\n| SteamOS | | SteamOS officially included Podman and Distrobox as pre-installed tools starting with the release of **SteamOS 3.5**. However, the versions are a little bit behind. You can follow the [Install Podman in a static manner](posts/install_podman_static.md) or [Install Lilipod in a static manner](posts/install_lilipod_static.md) guide, this will install it in your $HOME and it will survive updates. |\n| RedHat | 8 <br> 9 | `distrobox` is available in epel repos. (thanks [alcir](https://github.com/alcir)!) |\n| Ubuntu | 18.04 <br> 20.04 <br> 22.04 <br> 23.04 <br> 24.04 <br> | Older versions based on 20.04 or earlier may need external repos to install newer Podman and Docker releases. <br> Derivatives like Pop_OS!, Mint and Elementary OS should work the same. <br> [Now PPA available!](https://launchpad.net/~michel-slm/+archive/ubuntu/distrobox), also `distrobox` is available in default repos from `22.10` onward (thanks [michel-slm](https://github.com/michel-slm)!) |\n| Vanilla OS | 22.10 <br> Orchid | `distrobox` should be installed in the home directory using the official script |\n| Void Linux | glibc <br> musl | |\n| Windows | Oracle Linux 9 | using built-in Windows Subsystem for Linux |\n\n### Compatibility notes\n\n### Non shared mounts\n\nNote also that in some distributions, root filesystem is **not** mounted as a shared mount,\nthis will give an error like:\n\n```sh\n$ distrobox-enter\nError response from daemon: path /sys is mounted on /sys but it is not a shared or slave mount\nError: failed to start containers: ...\n```\n\nTo resolve this, use this command:\n\n```sh\nmount --make-rshared /\n```\n\nTo make it permanent, you can place it in `/etc/rc.local`.\n\n#### systemd Service unit\n\n`/etc/rc.local` may be missing in your system.\n\nIf your system uses `systemd`, here is how you can create and activate a systemd Service unit with the same\nfunctionality.\n\n##### Create the Service unit file\n\nCreate `/etc/systemd/system/mount-root-shared.service` file using your favorite text editor (e.g. `sudo nano\n/etc/systemd/system/mount-root-shared.service`), with the following contents:\n\n```systemd\n[Unit]\nDescription=Mount root filesystem as a shared mount\n# Ensure the service runs after the root fs is mounted\nAfter=local-fs.target\n\n[Service]\nType=oneshot\nExecStart=/usr/bin/mount --make-rshared /\n# Ensure the service is considered \"active\" after running\nRemainAfterExit=yes\n\n[Install]\n# Ensure the service runs before user login\nWantedBy=multi-user.target\n```\n\n##### Enable and start the Service\n\nThe following command registers the service so it runs on every boot, and starts it immediately so you don't have to\nreboot for it to take effect:\n\n```sh\nsudo systemctl enable --now mount-root-shared.service\n```\n\n## List of distributions including distrobox in their repositories\n\n[![Packaging status](https://repology.org/badge/vertical-allrepos/distrobox.svg)](https://repology.org/project/distrobox/versions)\n\n### New Host Distro support\n\nIf your distro of choice is not on the list, open an issue requesting support\nfor it, we can work together to check if it is possible to add support for it.\n\nOr just try using it anyway, if it works, open an issue\nand it will be added to the list!\n\n---\n\n## Containers Distros\n\nDistrobox guests tested successfully with the following container images:\n\n| Distro | Version | Images |\n| --- | --- | --- |\n| AlmaLinux (Toolbox) | 8 <br> 9 | quay.io/toolbx-images/almalinux-toolbox:8 <br> quay.io/toolbx-images/almalinux-toolbox:9 <br> quay.io/toolbx-images/almalinux-toolbox:latest |\n| Alpine (Toolbox) | 3.20 <br> 3.21 <br> 3.22 <br> edge | quay.io/toolbx-images/alpine-toolbox:3.20 <br> quay.io/toolbx-images/alpine-toolbox:3.21 <br> quay.io/toolbx-images/alpine-toolbox:3.22 <br> quay.io/toolbx-images/alpine-toolbox:edge <br> quay.io/toolbx-images/alpine-toolbox:latest |\n| AmazonLinux (Toolbox) | 2 <br> 2022 | quay.io/toolbx-images/amazonlinux-toolbox:2 <br> quay.io/toolbx-images/amazonlinux-toolbox:2023 <br> quay.io/toolbx-images/amazonlinux-toolbox:latest |\n| Archlinux (Toolbox) | | quay.io/toolbx/arch-toolbox:latest |\n| ALT Linux | p10 <br> p11 <br> sisyphus | docker.io/library/alt:p10 <br> docker.io/library/alt:p11 <br> docker.io/library/alt:sisyphus |\n| Bazzite Arch | | ghcr.io/ublue-os/bazzite-arch:latest <br> ghcr.io/ublue-os/bazzite-arch-gnome:latest |\n| Centos (Toolbox) | stream9 <br> stream10 | quay.io/toolbx-images/centos-toolbox:stream9 <br> quay.io/toolbx-images/centos-toolbox:stream10 <br> quay.io/toolbx-images/centos-toolbox:latest |\n| Debian (Toolbox) | 11 <br> 12 <br> 13 <br> testing <br> unstable <br> | quay.io/toolbx-images/debian-toolbox:11 <br> quay.io/toolbx-images/debian-toolbox:12 <br> quay.io/toolbx-images/debian-toolbox:13 <br> quay.io/toolbx-images/debian-toolbox:testing <br> quay.io/toolbx-images/debian-toolbox:unstable <br> quay.io/toolbx-images/debian-toolbox:latest |\n| Fedora (Toolbox) | 38 <br> 39 <br> 40 <br> 41 <br> 42 <br> 43 <br> Rawhide | registry.fedoraproject.org/fedora-toolbox:38 <br> registry.fedoraproject.org/fedora-toolbox:39 <br> registry.fedoraproject.org/fedora-toolbox:40 <br> quay.io/fedora/fedora-toolbox:41 <br> quay.io/fedora/fedora-toolbox:42 <br> quay.io/fedora/fedora-toolbox:43 <br> quay.io/fedora/fedora-toolbox:rawhide |\n| openSUSE (Toolbox) | | registry.opensuse.org/opensuse/distrobox:latest |\n| RedHat (Toolbox) | 8 <br> 9 | registry.access.redhat.com/ubi8/toolbox <br> registry.access.redhat.com/ubi9/toolbox |\n| Rocky Linux (Toolbox) | 8 <br> 9 | quay.io/toolbx-images/rockylinux-toolbox:8 <br> quay.io/toolbx-images/rockylinux-toolbox:9 <br> quay.io/toolbx-images/rockylinux-toolbox:latest |\n| Ubuntu (Toolbox) | 16.04 <br> 18.04 <br> 20.04 <br> 22.04 <br> 24.04 | quay.io/toolbx/ubuntu-toolbox:16.04 <br> quay.io/toolbx/ubuntu-toolbox:18.04 <br> quay.io/toolbx/ubuntu-toolbox:20.04 <br> quay.io/toolbx/ubuntu-toolbox:22.04 <br> quay.io/toolbx/ubuntu-toolbox:24.04 <br> quay.io/toolbx/ubuntu-toolbox:latest |\n| Chainguard Wolfi (Toolbox) | | quay.io/toolbx-images/wolfi-toolbox:latest |\n| Ublue | ubuntu-toolbox <br> fedora-toolbox <br> wolfi-toolbox <br> archlinux-distrobox | ghcr.io/ublue-os/ubuntu-toolbox <br> ghcr.io/ublue-os/fedora-toolbox <br> ghcr.io/ublue-os/wolfi-toolbox <br> ghcr.io/ublue-os/arch-toolbox |\n| | | |\n| AlmaLinux | 8 <br> 8-minimal <br> 9 <br> 9-minimal | docker.io/library/almalinux:8 <br> docker.io/library/almalinux:9 |\n| Alpine Linux | 3.20 <br> 3.21 <br> 3.22 <br> edge | docker.io/library/alpine:3.20 <br> docker.io/library/alpine:3.21 <br> docker.io/library/alpine:3.22 <br> docker.io/library/alpine:edge <br> docker.io/library/alpine:latest |\n| AmazonLinux | 1 <br> 2 <br> 2023 | public.ecr.aws/amazonlinux/amazonlinux:1 <br> public.ecr.aws/amazonlinux/amazonlinux:2 <br>  public.ecr.aws/amazonlinux/amazonlinux:2023 |\n| Archlinux | | docker.io/library/archlinux:latest |\n| Blackarch | | docker.io/blackarchlinux/blackarch:latest |\n| CentOS Stream | 8 <br> 9 <br> 10 | quay.io/centos/centos:stream8 <br> quay.io/centos/centos:stream9 <br> quay.io/centos/centos:stream10 |\n| Chainguard Wolfi | | cgr.dev/chainguard/wolfi-base:latest |\n| Chimera Linux | | docker.io/chimeralinux/chimera:latest |\n| Crystal Linux | | registry.gitlab.com/crystal-linux/misc/docker:latest |\n| Debian | 7 <br> 8 <br> 9 <br> 10 <br> 11 <br> 12 <br> 13 | docker.io/debian/eol:wheezy <br> docker.io/debian/eol:buster <br> docker.io/debian/eol:bullseye <br> docker.io/library/debian:bookworm-backports <br> docker.io/library/debian:stable-backports |\n| Debian | Testing | docker.io/library/debian:testing  <br>  docker.io/library/debian:testing-backports |\n| Debian | Unstable | docker.io/library/debian:unstable |\n| deepin | 20 (apricot) <br> 23 (beige) | docker.io/linuxdeepin/apricot <br> docker.io/linuxdeepin/deepin:beige |\n| Fedora | 38 <br> 39 <br> 40 <br> 41 <br> 42 <br> 43 <br> Rawhide | quay.io/fedora/fedora:38 <br> quay.io/fedora/fedora:39 <br> quay.io/fedora/fedora:40 <br> quay.io/fedora/fedora:41 <br> quay.io/fedora/fedora:42 <br> <br> quay.io/fedora/fedora:43 <br> quay.io/fedora/fedora:rawhide |\n| Gentoo Linux | rolling | docker.io/gentoo/stage3:latest |\n| KDE neon | Latest | invent-registry.kde.org/neon/docker-images/plasma:latest |\n| Kali Linux | rolling | docker.io/kalilinux/kali-rolling:latest |\n| Mint | 22.3 | docker.io/linuxmintd/mint22.3-amd64 |\n| Neurodebian | nd120 | docker.io/library/neurodebian:nd120 |\n| openSUSE | Leap | registry.opensuse.org/opensuse/leap:latest |\n| openSUSE | Tumbleweed | registry.opensuse.org/opensuse/distrobox:latest <br> registry.opensuse.org/opensuse/tumbleweed:latest <br>  registry.opensuse.org/opensuse/toolbox:latest <br> registry.opensuse.org/opensuse/distrobox-bpftrace:latest |\n| Oracle Linux | 8 <br> 8-slim <br> 9 <br> 9-slim <br> 10 <br> 10-slim | container-registry.oracle.com/os/oraclelinux:8 <br> container-registry.oracle.com/os/oraclelinux:8-slim <br> container-registry.oracle.com/os/oraclelinux:9 <br> container-registry.oracle.com/os/oraclelinux:9-slim <br> container-registry.oracle.com/os/oraclelinux:10 <br> container-registry.oracle.com/os/oraclelinux:10-slim |\n| RedHat (UBI) | 7 <br> 8 <br> 9 | registry.access.redhat.com/ubi7/ubi <br> registry.access.redhat.com/ubi8/ubi <br> registry.access.redhat.com/ubi8/ubi-init <br> registry.access.redhat.com/ubi8/ubi-minimal <br> registry.access.redhat.com/ubi9/ubi <br> registry.access.redhat.com/ubi9/ubi-init <br> registry.access.redhat.com/ubi9/ubi-minimal |\n| Rocky Linux | 8 <br> 8-minimal <br> 9 | quay.io/rockylinux/rockylinux:8 <br> quay.io/rockylinux/rockylinux:8-minimal <br> quay.io/rockylinux/rockylinux:9 <br> quay.io/rockylinux/rockylinux:latest |\n| Slackware | | docker.io/vbatts/slackware:current |\n| SteamOS | | ghcr.io/linuxserver/steamos:latest |\n| Ubuntu | 14.04 <br> 16.04 <br> 18.04 <br> 20.04 <br> 22.04 <br> 24.04 | docker.io/library/ubuntu:14.04 <br> docker.io/library/ubuntu:16.04 <br> docker.io/library/ubuntu:18.04 <br> docker.io/library/ubuntu:20.04 <br> docker.io/library/ubuntu:22.04 <br> docker.io/library/ubuntu:24.04 |\n| Vanilla OS | VSO | ghcr.io/vanilla-os/vso:main |\n| Void Linux | glibc <br> musl | ghcr.io/void-linux/void-glibc-full:latest <br> ghcr.io/void-linux/void-musl-full:latest |\n\nImages marked with **Toolbox** are tailored images made by the community efforts in [toolbx-images/images](https://github.com/toolbx-images/images),\nso they are more indicated for desktop use, and first setup will take less time.\nNote however that if you use a non-toolbox preconfigured image,\nthe **first** `distrobox-enter` you'll perform\ncan take a while as it will download and install the missing dependencies.\n\nA small time tax to pay for the ability to use any type of image.\nThis will **not** occur after the first time, **subsequent enters will be much faster.**\n\nNixOS is not a supported container distro, and there are currently no plans to\nbring support to it. If you are looking for unprivileged NixOS environments,\nwe suggest you look into [nix-shell](https://nixos.org/manual/nix/unstable/command-ref/nix-shell.html)\nor [nix portable](https://github.com/DavHau/nix-portable)\n\n### New Distro support\n\nIf your distro of choice is not on the list, open an issue requesting support\nfor it, we can work together to check if it is possible to add support for it.\n\nOr just try using it anyway, if it works, open an issue\nand it will be added to the list!\n\n### Older distributions\n\nFor older distributions like CentOS 5, CentOS 6, Debian 6, Ubuntu 12.04,\ncompatibility is not assured.\n\nTheir `libc` version is incompatible with kernel releases after `>=4.11`.\nA work around this is to use the `vsyscall=emulate` flag in the bootloader of the\nhost.\n\nKeep also in mind that mirrors could be down for such old releases, so you will\nneed to build a [custom distrobox image to ensure basic dependencies are met](./posts/distrobox_custom.md).\n\n### GPU Acceleration support\n\nFor Intel and AMD Gpus, the support is baked in, as the containers will install\ntheir latest available mesa/dri drivers.\n\nFor NVidia, you can use the `--nvidia` flag during create, see [distrobox-create](./usage/distrobox-create.md)\ndocumentation to discover how to use it.\n\nAlternatively, you can use the [nvidia-container-toolkit](./useful_tips.md#using-nvidia-container-toolkit)\nutility to set up the integration independently from the distrobox's own flag.\n"
  },
  {
    "path": "docs/featured_articles.md",
    "content": "- [Distrobox](README.md)\n  - [Featured articles](#articles)\n  - [Talks](#talks)\n  - [Podcasts](#podcasts)\n\n---\n\n## Articles\n\n- [Run Distrobox on Fedora Linux - Fedora Magazine](https://fedoramagazine.org/run-distrobox-on-fedora-linux/)\n- [DistroBox – Run Any Linux Distribution Inside Linux Terminal - TecMint](https://www.tecmint.com/distrobox-run-any-linux-distribution/)\n- [Distrobox: Try Multiple Linux Distributions via the Terminal - It's FOSS](https://itsfoss.com/distrobox/)\n- [Distrobox - How to quickly deploy a Linux distribution with GUI applications via a container](https://www.techrepublic.com/article/how-to-quickly-deploy-a-linux-distribution-with-gui-applications-via-a-container/)\n- [Using Distrobox To Augment The Package Selection On Clear Linux - Phoronix](https://www.phoronix.com/scan.php?page=news_item&px=Distrobox-Clear-Linux)\n- [Benchmark: benefits of Clear Linux containers (distrobox) - Phoronix](https://www.phoronix.com/forums/forum/phoronix/latest-phoronix-articles/1305326-clear-linux-container-performance-continues-showing-sizable-gains)\n- [Distrobox - A great item in the Linux toolbelt - phmurphy's blog](https://phmurphy.com/posts/distrobox-toolbelt/)\n- Running Other Linux Distros with Distrobox on Fedora Linux - bandithijo's blog:\n  [ORIGINAL](https://bandithijo.github.io/blog/menjalankan-distro-linux-lain-dengan-distrobox-di-fedora-linux)\n  or [TRANSLATED](https://bandithijo-github-io.translate.goog/blog/menjalankan-distro-linux-lain-dengan-distrobox-di-fedora-linux?_x_tr_sl=id&_x_tr_tl=en&_x_tr_hl=it&_x_tr_pto=wapp)\n- [Distrobox: Run (pretty much) any Linux distro under almost any other - TheRegister](https://www.theregister.com/2022/05/31/distrobox_130_released/)\n- [Day-to-day differences between Fedora Silverblue and Ubuntu - castrojo's blog](https://www.ypsidanger.com/day-to-day-advantages-of-fedora-silverblue/)\n- [Distrobox is Awesome - Running Window Manager and Desktop environments using Distrobox](https://cloudyday.tech.blog/2022/05/14/distrobox-is-awesome/)\n- [Japanese input on Clear Linux with Mozc via Ubuntu container with Distrobox](https://impsbl.hatenablog.jp/entry/JapaneseInputOnClearLinuxWithMozc_en)\n- [MID (MaXX Interactive Desktop) on Clear Linux via Ubuntu container with Distrobox](https://impsbl.hatenablog.jp/entry/MIDonClearLinuxWithDistrobox_en)\n\n## Talks\n\n- [Linux App Summit 2022 - Distrobox: Run Any App On Any Distro - BoF](https://github.com/89luca89/distrobox/files/8598433/distrobox-las-talk.pdf)\n- [A \"Box\" Full of Tools and Distros - Dario Faggioli @ OpenSUSE Conference 2022](https://www.youtube.com/watch?v=_RzARte80SQ)\n\n## Podcasts\n\n- [Linux After Dark – Episode 07](https://linuxafterdark.net/linux-after-dark-episode-07/)\n- [Linux Lads - Season 7 - Episode 1](https://linuxlads.com/episodes/season-7-episode-1)\n- [Late Night Linux - Episode 39](https://latenightlinux.com/linux-downtime-episode-39/)\n- [Late After Dark - Episode 16](https://linuxafterdark.net/linux-after-dark-episode-16/)\n"
  },
  {
    "path": "docs/posts/distrobox_custom.md",
    "content": "- [Distrobox](README.md)\n\n---\n\n# Create a dedicated distrobox container\n\nDistrobox wants to be as generic as possible in supporting OCI images,\nbut sometimes there could be some problems:\n\n- The image you want to use is too old and the package manager mirrors are down\n- The image you want to use has not a supported package manager or no package\n  manager at all\n\n## Requirements\n\nThe only required programs that must be available in the container so that\n`distrobox-init` won't start the installation are:\n\n- the $SHELL you use (bash, zsh, fish etc etc)\n- bash-completion\n- bc\n- bzip2\n- curl\n- diffutils\n- findutils\n- gnupg2\n- hostname\n- iproute\n- iputils\n- keyutils\n- krb5-libs\n- less\n- lsof\n- man-db\n- man-pages\n- ncurses\n- nss-mdns\n- openssh-clients\n- pam\n- passwd\n- pigz\n- pinentry\n- ping\n- procps-ng\n- rsync\n- shadow-utils\n- sudo\n- tcpdump\n- time\n- traceroute\n- tree\n- tzdata\n- unzip\n- util-linux\n- vte-profile\n- wget\n- which\n- whois\n- words\n- xorg-x11-xauth\n- xz\n- zip\n\nAnd optionally:\n\n- mesa-dri-drivers\n- mesa-vulkan-drivers\n- vulkan\n\nIf all those dependencies are met, then the `distrobox-init`\nwill simply skip the installation process and work as expected.\n\nTo test if all packages requirements are met just run this in the container:\n\n```shell\ndependencies=\"\n    bc\n    bzip2\n    chpasswd\n    curl\n    diff\n    find\n    findmnt\n    gpg\n    hostname\n    less\n    lsof\n    man\n    mount\n    passwd\n    pigz\n    pinentry\n    ping\n    ps\n    rsync\n    script\n    ssh\n    sudo\n    time\n    tree\n    umount\n    unzip\n    useradd\n    wc\n    wget\n    xauth\n    zip\n\"\nfor dep in ${dependencies}; do\n    ! command -v \"${dep}\" && echo \"missing $dep\"\ndone\n```\n"
  },
  {
    "path": "docs/posts/execute_commands_on_host.md",
    "content": "- [Distrobox](../README.md)\n  - [Execute a command on the host](#execute-a-command-on-the-host)\n    - [With distrobox-host-exec](#with-distrobox-host-exec)\n    - [Using symlinks](#using-symlinks)\n  - [Integrate host with container seamlessly](#integrate-host-with-container-seamlessly)\n    - [bash or zsh](#bash-or-zsh)\n    - [fish](#fish)\n\n---\n\n# Execute a command on the host\n\nIt may be needed to execute commands back on the host. Be it the filemanager, an\narchive manager, a container manager and so on.\n\nHere are a couple of solutions.\n\n## With distrobox-host-exec\n\ndistrobox offers the `distrobox-host-exec` helper, that can be used exactly for this.\n\nSee [distrobox-host-exec](../usage/distrobox-host-exec.md).\n\n```console\nuser@fedora-distrobox:~$ which podman\n/usr/bin/which: no podman in [...]\nuser@fedora-distrobox:~$ distrobox-host-exec podman version # <-- this is executed on host.\nClient:\nVersion:      3.4.2\nAPI Version:  3.4.2\nGo Version:   go1.16.6\nBuilt:        Thu Jan  1 01:00:00 1970\nOS/Arch:      linux/amd64\n\nServer:\nVersion:      3.4.2\nAPI Version:  3.4.2\nGo Version:   go1.16.6\nBuilt:        Thu Jan  1 01:00:00 1970\nOS/Arch:      linux/amd64\n```\n\n## Using symlinks\n\nAnother way to execute commands on the host, is to create executables symlinking `distrobox-host-exec`:\n\n```console\nuser@fedora-distrobox:~$ ln -s /usr/bin/distrobox-host-exec /usr/local/bin/podman\nuser@fedora-distrobox:~$ ls -l /usr/local/bin/podman\nlrwxrwxrwx. 1 root root 51 Jul 11 19:26 /usr/local/bin/podman -> /usr/bin/distrobox-host-exec\nuser@fedora-distrobox:~$ podman version # <-- this is executed on host. Equivalent to \"distrobox-host-exec podman version\"\nClient:\nVersion:      3.4.2\nAPI Version:  3.4.2\nGo Version:   go1.16.6\nBuilt:        Thu Jan  1 01:00:00 1970\nOS/Arch:      linux/amd64\n\nServer:\nVersion:      3.4.2\nAPI Version:  3.4.2\nGo Version:   go1.16.6\nBuilt:        Thu Jan  1 01:00:00 1970\nOS/Arch:      linux/amd64\n```\n\n# Integrate host with container seamlessly\n\nAnother cool trick we can pull, is to use the handy `command_not_found_handle` function\nto try and execute missing commands in the container on the host.\n\n## bash or zsh\n\nPlace this in your `~/.profile`:\n\n```shell\ncommand_not_found_handle() {\n# don't run if not in a container\n  if [ ! -e /run/.containerenv ] && [ ! -e /.dockerenv ]; then\n    exit 127\n  fi\n  \n  distrobox-host-exec \"${@}\"\n}\nif [ -n \"${ZSH_VERSION-}\" ]; then\n  command_not_found_handler() {\n    command_not_found_handle \"$@\"\n }\nfi\n```\n\nAnd then, run `source ~/.profile` to reload `.profile` in the current session.\n\n## fish\n\nPlace this snippet in a new fish function file (`~/.config/fish/functions/fish_command_not_found.fish`):\n\n```fish\nfunction fish_command_not_found\n    # \"In a container\" check\n    if test -e /run/.containerenv -o -e /.dockerenv\n        distrobox-host-exec $argv\n    else\n        __fish_default_command_not_found_handler $argv\n    end\nend\n```\n\nAnd restart your terminal. Now when a command does not exist on your container,\nit will be automatically executed back on the host:\n\n```shell\nuser@fedora-distrobox:~$ which podman\n/usr/bin/which: no podman in [...]\nuser@fedora-distrobox:~$ podman version # <-- this is automatically executed on host.\nClient:\nVersion:      3.4.2\nAPI Version:  3.4.2\nGo Version:   go1.16.6\nBuilt:        Thu Jan  1 01:00:00 1970\nOS/Arch:      linux/amd64\n\nServer:\nVersion:      3.4.2\nAPI Version:  3.4.2\nGo Version:   go1.16.6\nBuilt:        Thu Jan  1 01:00:00 1970\nOS/Arch:      linux/amd64\n```\n\nThis is also useful to open `code`, `xdg-open`, or `flatpak` from within the container\nseamlessly.\n"
  },
  {
    "path": "docs/posts/install_lilipod_static.md",
    "content": "# Install Lilipod in a static manner\n\nIf on your distribution (eg. SteamOS) can be difficult to install something and keep it\nbetween updates, then you could use this guide to install [lilipod](https://github.com/89luca89/lilipod) in your `$HOME`.\n\n[Lilipod](https://github.com/89luca89/lilipod) is a very simple container manager with minimal features to:\n\n- Download and manager images\n- Create and run containers\n\nTo install `lilipod`:\n\n1. Add the Path you've chosen to install to your PATH (by default it's `$HOME/.local/bin`.\n   - [See here how to do it](https://www.howtogeek.com/658904/how-to-add-a-directory-to-your-path-in-linux/)\n2. Ensure you have /etc/subuid and /etc/subgid, if you don't do:\n   - `sudo touch /etc/subuid /etc/subgid`\n   - `sudo usermod --add-subuid 100000-165535 --add-subgid 100000-165535 $USER`\n\nThis is particularly indicated also for completely *sudoless* setups, where you don't\nhave any superuser access to the system, like for example company provided computers.\n\nDownload the latest release of [lilipod](https://github.com/89luca89/lilipod/releases)\nand put it somewhere in your $PATH\n\nProvided the only dependency on the host (`newuidmap/newgidmap`, of the package `uidmap` or `shadow`),\nyou should be good to go.\n\nTo uninstall, just delete the binary.\n"
  },
  {
    "path": "docs/posts/install_podman_static.md",
    "content": "# Install Podman in a static manner\n\nIf on your distribution (eg. SteamOS) can be difficult to install something and keep it\nbetween updates, then you could use this guide to install `podman` in your `$HOME`.\n\n1. Add the Path you've chosen to install to your PATH (by default it's `$HOME/.local/bin`.\n   - [See here how to do it](https://www.howtogeek.com/658904/how-to-add-a-directory-to-your-path-in-linux/)\n2. Ensure you have /etc/subuid and /etc/subgid, if you don't do:\n   - `sudo touch /etc/subuid /etc/subgid`\n   - `sudo usermod --add-subuid 100000-165535 --add-subgid 100000-165535 $USER`\n\nThis is particularly indicated also for completely *sudoless* setups, where you don't\nhave any superuser access to the system, like for example company provided computers.\n\nDownload the latest release of [podman-launcher](https://github.com/89luca89/podman-launcher/releases),\nmake it executable and put it somewhere in your $PATH\n\nProvided the only dependency on the host (`newuidmap/newgidmap`, of the package `uidmap` or `shadow`),\nyou should be good to go.\n\nTo uninstall, just delete the binary.\n"
  },
  {
    "path": "docs/posts/integrate_vscode_distrobox.md",
    "content": "- [Distrobox](../README.md)\n  - [Integrate VSCode and Distrobox](#integrate-vscode-and-distrobox)\n    - [From distrobox](#from-distrobox)\n    - [From flatpak](#from-flatpak)\n      - [First step, install it](#first-step-install-it)\n      - [Second step, extensions](#second-step-extensions)\n      - [Third step, podman wrapper](#third-step-podman-wrapper)\n    - [Final Result](#final-result)\n\n---\n\n# Integrate VSCode and Distrobox\n\nVScode doesn't need presentations, and it's a powerful tool for development.\nYou may want to use it, but how to handle the dualism between host and container?\n\nIn this experiment we will use [VSCodium](https://vscodium.com/) as an opensource\nalternative to VSCode. Dev Containers extension works only\nfor non-opensource version of VS code. There are community made extensions like\n[DevPod Containers](https://open-vsx.org/extension/3timeslazy/vscodium-devpodcontainers) that work in VSCodium\n\nThis guide has become outdated and you will need to expect that some things broke since then.\n\n## From distrobox\n\nWell, you could just install VSCodium in your Distrobox of choice, and export it!\n\nFor example using an Arch Linux container (We use --home so to not clutter our home directory.\nYou can change it if you have VSCode configuration in your home directory that you like):\n\n```shell\n~$ distrobox create --image archlinux:latest --name arch-distrobox --home ./devcontainer\n~$ distrobox enter --name arch-distrobox\nuser@arch-distrobox:~$\n```\n\nDownload the deb file\n[HERE](https://github.com/VSCodium/vscodium/releases), or in Arch case just install\n\n```shell\nuser@arch-distrobox:~$ sudo pacman -S code\n```\n\nNow that we have installed it, we can export it:\n\n```shell\nuser@ubuntu-distrobox:~$ distrobox-export --app code\n```\n\nFor proprietary version you need to use the binary hosted on [AUR](https://aur.archlinux.org/packages/visual-studio-code-bin).\n\nTo enable and install from AUR do:\n\n```bash\nsudo pacman -Syu git base-devel &&\\\ngit clone https://aur.archlinux.org/yay.git &&\\\ncd yay &&\\\nmakepkg -si &&\\\nyay -S visual-studio-code-bin &&\\\ndistrobox-export --app code\n```\n\nAnd that's really it, you'll have VSCode in your app list, and it will run from\nthe Distrobox itself, so it will have access to all the software and tools inside\nit without problems.\n\n![image](https://user-images.githubusercontent.com/598882/149206335-1a2d0edd-8b2f-437d-aae0-44b9723d2c30.png)\n![image](https://user-images.githubusercontent.com/598882/149206414-56bdbc5a-3728-45ef-8dd4-2e168a0d7ccc.png)\n\n### Manage podman from Distrobox\n\nWe will use the\n[podman-remote](https://docs.redhat.com/en/documentation/red_hat_enterprise_linux/8/html/building_running_and_managing_containers/using-the-container-tools-api)\nto manage our containers running on host\n\n1. Install\n[Dev Containers extension](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers)\nin VSCode\n2. Make sure that podman sockets is enabled on the host system\n  `\nls -l /run/user/$(id -u)/podman/podman.sock\n  `\n  if it isn't, enable it with:\n  `\nsystemctl --user enable --now podman.socket\n  `\n3. Inside the Distrobox install podman to provide `podman-remote`\n  `\nsudo pacman -Syu podman\n  `\n4. Check if it's working by running:\n  `\npodman-remote info\n  `\n5. Configure Dev Containers Extension by putting `podman-remote` in\n[vscode://settings/dev.containers.dockerPath](vscode://settings/dev.containers.dockerPath)\n6. If you click refresh in Dev Containers extension you should see your host's containers\n\n![image](https://raw.githubusercontent.com/89luca89/distrobox/450e2bd06294558fb5ed70fdda1004716c5bd3b6/docs/assets/png/integrate_vscode_distrobox.png)\n\n## From flatpak\n\nAlternatively you may want to install VSCode on your host. We will explore how\nto integrate VSCode installed via **Flatpak** with Distrobox.\n\nFor this one you'll need to use VSCode from Microsoft, and not VSCodium, in order\nto have access to the remote containers extension.\n\n### First step install it\n\n```shell\n~$ flatpak install --user app/com.visualstudio.code \n```\n\n### Second step, extensions\n\nNow we want to install VSCode [Dev Containers extension](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers)\n\n![image](https://user-images.githubusercontent.com/598882/149207447-76a82e91-dd3f-43fa-8c52-9c2e85ae8fee.png)\n\n### Third step podman wrapper\n\nBeing in a Flatpak, we will need access to host's `podman` to be\nable to use the containers. Place this in your `~/.local/bin/podman-host`\nIn case of access to host's `docker` to be\nable to use the containers, use `~/.local/bin/docker-host`\n\nFor podman:\n\n```shell\ncurl -s https://raw.githubusercontent.com/89luca89/distrobox/main/extras/podman-host -o ~/.local/bin/podman-host\nchmod +x ~/.local/bin/podman-host\n```\n\nFor docker:\n\n```shell\ncurl -s https://raw.githubusercontent.com/89luca89/distrobox/main/extras/docker-host -o ~/.local/bin/docker-host\nchmod +x ~/.local/bin/docker-host\n```\n\nOpen VSCode settings (Ctrl+,) and head to `Remote>Containers>Docker Path` and\nset it to the path of `/home/<your-user>/.local/bin/podman-host` (or docker-host in case of docker), like in the example\n\n![image](https://user-images.githubusercontent.com/598882/149208525-5ad630c9-fcbc-4ee6-9d77-e50d2c782a56.png)\n\nThis will give a way to execute host's container manager from within the\nflatpak app.\n\n## Final Result\n\nAfter that, we're good to go! Open VSCode and Attach to Remote Container:\n\n![image](https://user-images.githubusercontent.com/598882/149210561-2f1839ae-9a57-42fc-a122-21652588e327.png)\n\nAnd let's choose our Distrobox\n\n![image](https://user-images.githubusercontent.com/598882/149210690-8bcb9a0d-1dc5-4937-9494-8c6aa6b26fd5.png)\n\nAnd we're good to go! We have our VSCode remote session inside our Distrobox container!\n\n![image](https://user-images.githubusercontent.com/598882/149210881-749a8146-c69d-4382-bbef-91e4b477b7ba.png)\n\n# Open VSCode directly attached to our Distrobox\n\nYou may want to instead have a more direct way to launch your VSCode when you're already in your project directory,\nin this case you can use `vscode-distrobox` script:\n\n```shell\ncurl -s https://raw.githubusercontent.com/89luca89/distrobox/main/extras/vscode-distrobox -o ~/.local/bin/vscode-distrobox\nchmod +x ~/.local/bin/vscode-distrobox\n```\n\nThis will make it easy to launch VSCode attached to target distrobox, on a target path:\n\n`vscode-distrobox my-distrobox /path/to/project`\n"
  },
  {
    "path": "docs/posts/posts.md",
    "content": "- [Distrobox](../README.md)\n\n---\n\n## Latest posts\n\n- [Execute a command on the Host](execute_commands_on_host.md)\n- [Install Podman in HOME](install_podman_static.md)\n- [Install Lilipod in HOME](install_lilipod_static.md)\n- [Install on Steamdeck](steamdeck_guide.md)\n- [Integrate VSCode and Distrobox](integrate_vscode_distrobox.md)\n- [Run Libvirt using distrobox](run_libvirt_in_distrobox.md)\n- [Run latest GNOME and KDE Plasma using distrobox](run_latest_gnome_kde_on_distrobox.md)\n"
  },
  {
    "path": "docs/posts/run_latest_gnome_kde_hyprland_on_distrobox.md",
    "content": "- [Distrobox](../README.md)\n  - [Run latest GNOME, KDE Plasma, and Hyprland using distrobox](run_latest_gnome_kde_on_distrobox.md)\n    - [Using a stable-release distribution](#using-a-stable-release-distribution)\n      - [Initializing the distrobox](#initializing-the-distrobox)\n      - [Running Latest GNOME](#running-latest-gnome)\n        - [Generate session file - GNOME](#generate-session-file---gnome)\n      - [Running Latest Plasma](#running-latest-plasma)\n        - [Generate session file - Plasma](#generate-session-file---plasma)\n        - [Add a couple of fixes](#add-a-couple-of-fixes)\n      - [Running Latest Hyprland](#running-latest-hyprland)\n    - [Using other GUIs](#using-other-guis)\n    - [Using apps from host](#using-apps-from-host)\n\n---\n\n⚠️ **BE CAREFUL**:⚠️  THIS IS EXPERIMENTAL, JUST FOOD FOR THOUGHTS\n\n⚠️ **BE CAREFUL**:⚠️  BUG REPORTS FOR THIS TYPE OF EXPERIMENTS WILL BE TREATED WITH VERY LOW PRIORITY\n\n# Using a stable-release distribution\n\nLots of people prefer to run a distribution following a stable-LTS release cycle\nlike Debian, UbuntuLTS or CentOS family (Almalinux, Rocky Linux).\nThis ensures great stability on one hand, but package staling on the other.\n\nOne way to counter this effect is to use a pet-container managed by Distrobox\nto run packages from much newer distributions without giving up on core base os stability.\n\n## Initializing the distrobox\n\nFor this experiment we'll use Fedora Rawhide as our distrobox, and Centos 8 Stream\nas our host, so:\n\n```shell\ndistrobox create --name fedora-rawhide --init --additional-packages \"systemd\" --image registry.fedoraproject.org/fedora:rawhide\n```\n\nand\n\n```shell\ndistrobox enter fedora-rawhide\n```\n\n## Running Latest GNOME\n\nFirst we need to install GNOME in the container:\n\n```shell\nuser@fedora-rawhide:~$ sudo dnf group install gnome-desktop\n```\n\nAnd let's grab a coffee while it finishes :-)\n\nAfter the `dnf` process finishes, we have GNOME installed in our container,\nnow how do we use it?\n\n### Generate session file - GNOME\n\nFirst in the host we need a reliable way to fix the permissions problem of the\n`/tmp/.X11-unix` directory. This directory should either belong to `root` or\n`$USER`. But in a rootless container, host's `root` is not mapped inside the\ncontainer so we need to change the ownership from `root` to `$USER` each time.\n\nLet's add:\n\n```shell\nchown -f -R $USER:$USER /tmp/.X11-unix\n```\n\nto `/etc/profile.d/fix_tmp.sh` file.\n\nThis is needed for the XWayland session to work properly which right now is\nnecessary to run gnome-shell even on wayland.\n\nThen we need to add a desktop file for the session on the **host's** file system,\nso that it appears on your login manager (Be it SDDM or GDM)\n\n```shell\n[Desktop Entry]\nName=GNOME on Wayland (fedora-rawhide distrobox)\nComment=This session logs you into GNOME\nExec=/usr/local/bin/distrobox-enter -n fedora-rawhide -- /usr/bin/gnome-session\nType=Application\nDesktopNames=GNOME\nX-GDM-SessionRegisters=true\n```\n\nThis file should be placed under `/usr/local/share/wayland-sessions/distrobox-gnome.desktop`\n(If it doesn't show up, you can place it under `/usr/share/xsessions/distrobox-gnome.desktop`)\n\nLet's log out and voilá!\n\n![image](https://user-images.githubusercontent.com/598882/148703229-82905d23-f3d0-41bc-a048-d12cdf8066d0.png)\n![Screenshot from 2024-02-21 23-32-13](https://github.com/89luca89/distrobox/assets/598882/9b981f40-fdbe-4ed4-82cc-1e96b6e945e5)\n![Screenshot from 2024-02-21 23-32-03](https://github.com/89luca89/distrobox/assets/598882/d2200195-74c6-4a1c-8ddb-a9fabe775999)\n\nWe now are in a GNOME 42 session inside Fedora Rawhide while our main OS remains\nCentos.\n\n## Running Latest Plasma\n\nWe first need to install Plasma in the container:\n\n```shell\nuser@fedora-rawhide:~$ sudo dnf groupinstall KDE\n```\n\n### Generate session file - Plasma\n\nWe need to add a desktop file for the session on the **host's** file system,\nso that it appears on your login manager (Be it SSDM or GDM)\n\n```shell\n[Desktop Entry]\nExec=/usr/local/bin/distrobox-enter -- /usr/libexec/plasma-dbus-run-session-if-needed /usr/bin/startplasma-wayland\nDesktopNames=KDE\nName=Plasma on Wayland (fedora-rawhide distrobox)\nX-KDE-PluginInfo-Version=5.23.3\n```\n\nThis file should be placed under `/usr/local/share/wayland-sessions/distrobox-plasma.desktop`\n(If it doesn't show up, you can place it under `/usr/share/xsessions/distrobox-plasma.desktop`)\n\n### Add a couple of fixes\n\nTo make Plasma work we need a couple more fixes to run both on the host and in the container.\n\nFirst in the host we need a reliable way to fix the permissions problem of the\n`/tmp/.X11-unix` directory. This directory should either belong to `root` or\n`$USER`. But in a rootless container, host's `root` is not mapped inside the\ncontainer so we need to change the ownership from `root` to `$USER` each time.\n\nLet's add:\n\n```shell\nchown -f -R $USER:$USER /tmp/.X11-unix\n```\n\nto `/etc/profile.d/fix_tmp.sh` file.\n\nWe also need to add a process in autostart on which Plasma shell relies on a\nprocess called `kactivitymanagerd`. Not having host's systemd at disposal we\ncan start it simply adding it to the ~/.profile file, add:\n\n```shell\nif [ -f /usr/libexec/kactivitymanagerd ]; then\n  /usr/libexec/kactivitymanagerd & disown\nfi\n```\n\nto `~/.profile` file.\n\nLet's log out and voilá!\n\n![image](https://user-images.githubusercontent.com/598882/148704789-3d799a85-51cc-4de7-9ee3-f54add4949bc.png)\n![image](https://user-images.githubusercontent.com/598882/148705044-7271af0c-0675-42f8-9f45-ad20ec53deca.png)\n\nWe now are in latest KDE Plasma session inside Fedora Rawhide while our main OS remains\nCentos.\n\n## Running Latest Hyprland\n\nHyprland is a bit tricky because of how it is implemented. We will need to\ncreate a container with access to `dri` and `input` devices, along with the dbus\nsocket that Wayland will use. Simply use this as a template:\n\n```shell\ndistrobox-create -n hyprbox -i archlinux:latest \\\n   --additional-flags \"--device /dev/dri --device /dev/input -v /run/dbus/system_bus_socket:/run/dbus/system_bus_socket\"\n```\n\nInstall Hyprland inside the container and then use the following line to start Hyprland:\n\n```shell\ndistrobox-enter hyprbox -- bash -c '\n  #export XDG_RUNTIME_DIR=$XDG_RUNTIME_DIR\n  #export WAYLAND_DISPLAY=$WAYLAND_DISPLAY\n\n  exec Hyprland\n'\n```\n\nThis will require you to not have any other Wayland sessions running.\n\nIf you want to run Hyprland on a second tty, set the `XDG_RUNTIME_DIR` and the\n`WAYLAND_DISPLAY` variables to something unique. Otherwise, applications\nlaunched from the container will display on the first Wayland Display they see.\n\n# Using other GUIs\n\nThanks to [J.S. Evans](https://twitter.com/usenetnerd) he experimented and wrote a beautiful blog post\non how to use Distrobox for much more than simply running apps.\n\nYou'll read on how to set up a working Ubuntu container with IceWM running on Xorg using Distrobox:\n\n[Read the Article HERE](https://cloudyday.tech.blog/2022/05/14/distrobox-is-awesome/)\n\n# Using apps from host\n\nNow that we're in a container session, we may want to still use some of the host's\napps. Refer to [THIS](execute_commands_on_host.md) to create handlers and wrappers\nto use the complete selection of host's apps and binaries inside the container.\n"
  },
  {
    "path": "docs/posts/run_libvirt_in_distrobox.md",
    "content": "- [Distrobox](../README.md)\n  - [Run Libvirt using distrobox](run_libvirt_in_distrobox.md)\n    - [Prepare the container](#prepare-the-container)\n    - [Launch from the container](#launch-from-the-container)\n    - [Connect via SSH](#connect-via-ssh)\n\n# Using an immutable distribution\n\nIf you are on an immutable distribution (Silverblue/Kionite, Aeon/Kalpa) chances are that\ninstalling lots and lots of packages on the base system is not advisable.\n\nOne way is to use a distrobox for them.\n\n## Prepare the container\n\nTo run libvirt/qemu/kvm we need a systemd container and we need a **rootful** container\nto be able to use it, see [this tip](../useful_tips.md#using-init-system-inside-a-distrobox)\nto have a list of compatible images.\nWe will use in this example OpenSUSE's dedicated distrobox image:\n\nAssembly file:\n\n```ini\n[libvirt]\nimage=registry.opensuse.org/opensuse/distrobox:latest\npull=true\ninit=true\nroot=true\nentry=true\nstart_now=false\nunshare_all=true\nadditional_packages=\"systemd\"\n# Basic utilities for terminal use\ninit_hooks=\"zypper in -y --no-recommends openssh-server patterns-server-kvm_server patterns-server-kvm_tools qemu-arm qemu-ppc qemu-s390x qemu-extra qemu-linux-user qemu-hw-display-virtio-gpu-pci qemu-hw-display-virtio-gpu\"\ninit_hooks=\"systemctl enable sshd.service\"\ninit_hooks=\"systemctl enable virtqemud.socket virtnetworkd.socket virtstoraged.socket virtnodedevd.socket\"\n# Add the default user to the libvirt group\ninit_hooks=\"usermod -aG libvirt ${USER}\"\n# Expose container ssh on host\nadditional_flags=\"-p 2222:22\"\n# Export virt-manager\nexported_apps=\"virt-manager\"\n```\n\nAlternatively, command line:\n\n```console\ndistrobox create --pull --root --init --unshare-all --image registry.opensuse.org/opensuse/distrobox:latest --name libvirtd --additional-flags \"-p 2222:22\" \\\n  --init-hooks \"zypper in -y --no-recommends openssh-server patterns-server-kvm_server patterns-server-kvm_tools qemu-arm qemu-ppc qemu-s390x qemu-extra qemu-linux-user qemu-hw-display-virtio-gpu-pci qemu-hw-display-virtio-gpu && systemctl enable sshd.service && systemctl enable virtqemud.socket virtnetworkd.socket virtstoraged.socket virtnodedevd.socket && usermod -aG libvirt $USER\"\n\ndistrobox-enter --root libvirtd -- distrobox-export --app virt-manager\n```\n\n## Launch from the container\n\nSimply select the `Virt Manager (on libvirt)` entry in your menu, entry your root password and you're done!\n\n![image](https://github.com/89luca89/distrobox/assets/598882/ca4f8fed-c8bd-4a01-b845-48be1aafd523)\n![image](https://github.com/89luca89/distrobox/assets/598882/2f709b1b-f0e6-451a-8b59-3ed3177b9fcf)\n![image](https://github.com/89luca89/distrobox/assets/598882/3f5f36cf-749d-4832-93f0-8eb9574dea9a)\n\n## Connect via SSH\n\nYou can alternatively connect from an existing VirtManager\n\nNow you will need to **Add a connection**:\n\n![image](https://user-images.githubusercontent.com/598882/208441337-4dbade85-4c72-4342-b9ee-acd76b9b1675.png)\n\nThen set it like this:\n\n![Screenshot from 2024-02-19 19-50-04](https://github.com/89luca89/distrobox/assets/598882/bff78725-63c9-4da6-9d25-318c58162673)\n\n- Tick the \"Use ssh\" option\n- username: `<your-user-name>`\n- hostname: 127.0.0.1:2222\n\nOptionally you can set it to autoconnect.\n\nNow you can simply double click the connection to activate it, you'll be prompted\nwith your password, insert the same password as the host:\n\n![image](https://github.com/89luca89/distrobox/assets/598882/27bba705-223f-4876-a2fc-b6d102b7130a)\n\nAnd you should be good to go!\n\n![image](https://user-images.githubusercontent.com/598882/208442009-fe9df606-e6a8-44f9-94c2-1c2bfba4ca15.png)\n"
  },
  {
    "path": "docs/posts/steamdeck_guide.md",
    "content": "### Install Distrobox and Podman PERMANENT on Steam Deck >= 3.5\n\n**1 - Modify $PATH for binaries**\nFirst, verify if ~/.bashrc contains the necessary $PATH modification. Open the file with:\n`nano ~/.bashrc`\nAdd the following line if it’s not already there:\n`export PATH=/home/deck/.local/bin:$PATH`\n\n**2 - Install and configure Distrobox**\nTo install Distrobox in the defined $PATH, use one of the following commands\ndepending on whether you need the latest version (`--next`) or not:\n\n`curl -s https://raw.githubusercontent.com/89luca89/distrobox/main/install | sh -s -- --prefix $HOME/.local`\n\nAfter installing, create the file `~/.distroboxrc` if it doesn't already exist.\nOpen it with:\n\n`nano ~/.distroboxrc`\n\nAdd the following lines to configure Distrobox:\n\n```sh\n# Ensure the graphical apps can talk to the Xwayland session\nxhost +si:localuser:$USER >/dev/null\n# Force the use of pulseaudio inside the container\nexport PIPEWIRE_RUNTIME_DIR=/dev/null\n# Needed to ensure distrobox can find the podman binary we previously downloaded\nexport PATH=/home/deck/.local/bin:$PATH\nexport PATH=$PATH:/home/deck/.local/bin\n```\n\n**3 - Install and configure Podman**\nTo install Podman, download the latest version from the GitHub releases page:\n[](https://github.com/89luca89/podman-launcher/releases)\n\n`curl -L -o /home/deck/Downloads/podman-launcher-amd64 https://github.com/89luca89/podman-launcher/releases/download/v0.0.5/podman-launcher-amd64`\n\nNext, move and rename the Podman binary with ROOT permissions to the $PATH:\n\n`mv /home/deck/Downloads/podman-launcher-amd64 /home/deck/.local/bin/podman`\n\nThen, make Podman executable:\n\n`chmod +x /home/deck/.local/bin/podman`\n\nConfigure the deck user’s UID and GID mapping with the following commands:\n\n`sudo touch /etc/subuid /etc/subgid`\n\n`sudo usermod --add-subuid 100000-165535 --add-subgid 100000-165535 deck`\n\n**4 - Configure Distrobox Icon folder** - (if you install distrobox with sudo)\nTo ensure Distrobox can store its icons correctly, set the proper permissions\non the `/home/deck/.local/share/icons` folder with:\n\n`chown deck:deck /home/deck/.local/share/icons`\n\n**5 - Verify installations**\nAfter the installation steps, verify that both Distrobox and Podman are properly\ninstalled and configured. Use the following commands:\n\n`which distrobox`\n`which podman`\n`distrobox --version`\n`podman --version`\n`podman info`\n\n**6 - Create and test distros** - install pulseaudio within the distros\nYou can now create and test containers with Distrobox. To create and test a\nROOTLESS container, run:\n\n`distrobox create --image docker.io/library/archlinux:latest --name arch`\n\nFor a ROOT container, use:\n\n`distrobox create --image docker.io/library/archlinux:latest --name rarch --root`\n\nYou can either remove the created distros later or keep them for regular use.\n"
  },
  {
    "path": "docs/style.css",
    "content": "/* \n\n    OS Component Website\n    ====================\n    \n    shamelessly stolen CSS from systemd\n    https://github.com/systemd/systemd/tree/main/docs\n    \n*/\n\n/* GNOME Color Palette */\n:root {\n  --rounded-corner: 12px;\n  --blue1: rgb(153,193,241);\n  --blue2: rgb(98,160,234);\n  --blue3: rgb(53,132,228);\n  --blue4: rgb(28,113,216);\n  --blue5: rgb(26,95,180);\n  --green1: rgb(143,240,164);\n  --green2: rgb(87,227,137);\n  --green3: rgb(51,209,122);\n  --green4: rgb(46,194,126);\n  --green5: rgb(38,162,105);\n  --yellow1: rgb(249,240,107);\n  --yellow2: rgb(248,228,92);\n  --yellow3: rgb(246,211,45);\n  --yellow4: rgb(245,194,17);\n  --yellow5: rgb(229,165,10);\n  --orange1: rgb(255,190,111);\n  --orange2: rgb(255,163,72);\n  --orange3: rgb(255,120,0);\n  --orange4: rgb(230,97,0);\n  --orange5: rgb(198,70,0);\n  --red1: rgb(246,97,81);\n  --red2: rgb(237,51,59);\n  --red3: rgb(224,27,36);\n  --red4: rgb(192,28,40);\n  --red5: rgb(165,29,45);\n  --purple1: rgb(220,138,221);\n  --purple2: rgb(192,97,203);\n  --purple3: rgb(145,65,172);\n  --purple4: rgb(129,61,156);\n  --purple5: rgb(97,53,131);\n  --brown1: rgb(205,171,143);\n  --brown2: rgb(181,131,90);\n  --brown3: rgb(152,106,68);\n  --brown4: rgb(134,94,60);\n  --brown5: rgb(99,69,44);\n  --light1: rgb(255,255,255);\n  --light2: rgb(246,245,244);\n  --light3: rgb(222,221,218);\n  --light4: rgb(192,191,188);\n  --light5: rgb(154,153,150);\n  --dark1: rgb(119,118,123);\n  --dark2: rgb(94,92,100);\n  --dark3: rgb(61,56,70);\n  --dark4: rgb(36,31,49);\n  --dark5: rgb(0,0,0);\n  --primary-color: var(--medium-armadillo); /* Set your project color */\n  --borders: var(--light3);\n  \n  --dark-armadillo: #4f433c;\n  --medium-armadillo: #70594d;\n  --light-armadillo: #f0e2d1;\n}\n\n/* Typography */\n\n@font-face {\n  font-family: 'Inter Var';\n  font-weight: 100 900;\n  font-display: swap;\n  font-style: oblique 0deg 10deg;\n  src: url(\"fonts/Inter.var.woff2?v=3.19\") format(\"woff2\");\n}\n\n* {\n  -moz-box-sizing: border-box;\n  -webkit-box-sizing: border-box;\n  box-sizing: border-box;\n}\nhtml, body {\n  margin: 0;\n  padding: 0;\n  font-size: 16px;\n  font-family: \"Inter Var\", sans-serif;\n  font-weight: 400;\n  line-height: 1.6;\n  scroll-behavior: smooth;\n}\nbody {\n  color: #241f31;\n  background-color: #f6f5f4;\n  /* ⇩⇩ put footer at the bottom for short pages, such as the 404 ⇩⇩ */\n  display: grid;\n  min-height: 100vh;\n  grid-template-rows: auto minmax(auto,1fr) auto; /* header, stuff, footer */\n}\nh1, h2, h3, h4, h5, h6 {\n  margin: 3rem 0 1rem;\n  font-weight: 600;\n  line-height: 1.25;\n  font-variation-settings: \"wght\" 600; /* needed for webkit */\n}\n\nh1 {\n  font-size: 1.5rem;\n  font-weight: 100;\n  font-style: normal;\n  margin: 3rem 0 1rem;\n}\n\n@media screen and (min-width: 650px) {\n  h1 {\n    font-size: 1.6rem;\n  }\n}\nh2 {\n  font-size: 1.2rem;\n}\n\n@media (prefers-color-scheme: dark) {\n  body {\n    filter: invert(100%) hue-rotate(180deg);\n  }\n\n  html {\n    background-color: var(--dark5);\n  }\n\n  img, video, iframe {\n    filter: invert(100%) hue-rotate(180deg);\n  }\n}\n\na {\n  font-weight: 600;\n  text-decoration: none;\n  color: var(--primary-color);\n  cursor: pointer;\n  font-variation-settings: \"wght\" 600; /* needed for webkit */\n}\na:hover {\n  text-decoration: underline;\n}\nb {\n  font-weight: 600;\n}\nsmall {\n  color: #777;\n}\nhr {\n  margin: 3rem auto 4rem;\n  width: 40%;\n  opacity: 40%;\n}\n\nimg {\n  display: block;\n  margin: 2rem auto;\n  max-width: 100%;\n  }\n  img.full { width: 100%; }\n  img.pixels { \n    image-rendering: crisp-edges; /* older firefox browsers */ \n    image-rendering: pixelated; \n  }\n\n\n/* Layout */\n.container {\n  width: 80%;\n  margin-left: auto;\n  margin-right: auto;\n  max-width: 720px;\n}\n\n/* Singletons */\n#logo {\n  display: block;\n  width: 251px; height: 26px;\n  background: url('assets/page-logo.svg') no-repeat center;\n  padding: 5rem 0 3rem;\n  margin: 0 auto;\n  position: relative;\n}\n  #logo a {\n    display: block;\n    position: absolute;\n    top: 0; left: 0; right: 0; bottom: 0;\n    color: rgba(0,0,0,0); /* make text transparent */\n    cursor: pointer;\n  }\n.page-logo > img {\n  margin: 0 auto;\n}\n\n  @media (prefers-color-scheme: dark) {\n    #logo {\n      filter: invert(100%) hue-rotate(180deg); /* uninvert */\n      background-image: url('assets/page-logo-i.svg');\n    }\n  }\n\n.brand-white {\n  background-color: #fff;\n}\n\n.brand-green {\n  background-color: #30D475;\n}\n\n.brand-black {\n  background-color: #201A26;\n  color: white;\n}\n\n.page-link::after {\n  content: \" ➜\";\n}\n\n\n/* Footer */\nfooter {\n  text-align: center;\n  padding: 3em 0 3em;\n  font-size: 1em;\n  margin-top: 4rem;\n}\n\n/* Make tables vertically aligned to the top */\ntbody td {\n  vertical-align: top;\n}\n\n/* Github Code Highlighting */\n.highlight table td { padding: 5px; }\n.highlight table pre { margin: 0; }\n.highlight .cm {\n  color: #999988;\n  font-style: italic;\n}\n.highlight .cp {\n  color: #999999;\n  font-weight: bold;\n}\n.highlight .c1 {\n  color: #999988;\n  font-style: italic;\n}\n.highlight .cs {\n  color: #999999;\n  font-weight: bold;\n  font-style: italic;\n}\n.highlight .c, .highlight .ch, .highlight .cd, .highlight .cpf {\n  color: #999988;\n  font-style: italic;\n}\n.highlight .err {\n  color: #a61717;\n  background-color: #e3d2d2;\n}\n.highlight .gd {\n  color: #000000;\n  background-color: #ffdddd;\n}\n.highlight .ge {\n  color: #000000;\n  font-style: italic;\n}\n.highlight .gr {\n  color: #aa0000;\n}\n.highlight .gh {\n  color: #999999;\n}\n.highlight .gi {\n  color: #000000;\n  background-color: #ddffdd;\n}\n.highlight .go {\n  color: #888888;\n}\n.highlight .gp {\n  color: #555555;\n}\n.highlight .gs {\n  font-weight: bold;\n}\n.highlight .gu {\n  color: #aaaaaa;\n}\n.highlight .gt {\n  color: #aa0000;\n}\n.highlight .kc {\n  color: #000000;\n  font-weight: bold;\n}\n.highlight .kd {\n  color: #000000;\n  font-weight: bold;\n}\n.highlight .kn {\n  color: #000000;\n  font-weight: bold;\n}\n.highlight .kp {\n  color: #000000;\n  font-weight: bold;\n}\n.highlight .kr {\n  color: #000000;\n  font-weight: bold;\n}\n.highlight .kt {\n  color: #445588;\n  font-weight: bold;\n}\n.highlight .k, .highlight .kv {\n  color: #000000;\n  font-weight: bold;\n}\n.highlight .mf {\n  color: #009999;\n}\n.highlight .mh {\n  color: #009999;\n}\n.highlight .il {\n  color: #009999;\n}\n.highlight .mi {\n  color: #009999;\n}\n.highlight .mo {\n  color: #009999;\n}\n.highlight .m, .highlight .mb, .highlight .mx {\n  color: #009999;\n}\n.highlight .sb {\n  color: #d14;\n}\n.highlight .sc {\n  color: #d14;\n}\n.highlight .sd {\n  color: #d14;\n}\n.highlight .s2 {\n  color: #d14;\n}\n.highlight .se {\n  color: #d14;\n}\n.highlight .sh {\n  color: #d14;\n}\n.highlight .si {\n  color: #d14;\n}\n.highlight .sx {\n  color: #d14;\n}\n.highlight .sr {\n  color: #009926;\n}\n.highlight .s1 {\n  color: #d14;\n}\n.highlight .ss {\n  color: #990073;\n}\n.highlight .s, .highlight .sa, .highlight .dl {\n  color: #d14;\n}\n.highlight .na {\n  color: #008080;\n}\n.highlight .bp {\n  color: #999999;\n}\n.highlight .nb {\n  color: #0086B3;\n}\n.highlight .nc {\n  color: #445588;\n  font-weight: bold;\n}\n.highlight .no {\n  color: #008080;\n}\n.highlight .nd {\n  color: #3c5d5d;\n  font-weight: bold;\n}\n.highlight .ni {\n  color: #800080;\n}\n.highlight .ne {\n  color: #990000;\n  font-weight: bold;\n}\n.highlight .nf, .highlight .fm {\n  color: #990000;\n  font-weight: bold;\n}\n.highlight .nl {\n  color: #990000;\n  font-weight: bold;\n}\n.highlight .nn {\n  color: #555555;\n}\n.highlight .nt {\n  color: #000080;\n}\n.highlight .vc {\n  color: #008080;\n}\n.highlight .vg {\n  color: #008080;\n}\n.highlight .vi {\n  color: #008080;\n}\n.highlight .nv, .highlight .vm {\n  color: #008080;\n}\n.highlight .ow {\n  color: #000000;\n  font-weight: bold;\n}\n.highlight .o {\n  color: #000000;\n  font-weight: bold;\n}\n.highlight .w {\n  color: #bbbbbb;\n}\n.highlight {\n  background-color: #f8f8f8;\n}\n\n\n/* Code Blocks */\n.highlighter-rouge {\n  padding: 2px 1rem;\n  border-radius: 5px;\n  background-color: var(--light1);\n  max-width: 100%;\n  overflow-x: auto;\n}\n  @media only screen and (max-device-width : 480px) {\n  /*mobile*/\n  .highlighter-rouge { max-width: 80vw; }\n  }\n  \n.highlighter-rouge * {\n  background-color: var(--light1);\n}\n\n/* Inline Code */\ncode.highlighter-rouge {\n  padding: 2px 6px;\n  background-color: rgba(0,0,0, 0.07);\n}\n\n/* Buttons */\n\n.dialog-buttons {\n  display: flex;\n  flex-direction: row;\n  align-items: baseline;\n  justify-content: space-between;\n  margin-top: 6rem;\n}\n\n.inline-button {\n  display: inline-block;\n  font-weight: 900;\n  font-size: 90%;\n  padding: .4rem 1rem;\n  border-radius: var(--rounded-corner);\n  background-color: rgba(0,0,0,0.05);\n  color: var(--dark5);\n}\n"
  },
  {
    "path": "docs/usage/distrobox-assemble.md",
    "content": "<!-- markdownlint-disable MD010 MD036 MD046 -->\n# NAME\n\n\tdistrobox assemble\n\tdistrobox-assemble\n\n# DESCRIPTION\n\ndistrobox-assemble takes care of creating or destroying containers in batches,\nbased on a manifest file.\nThe manifest file by default is `./distrobox.ini`, but can be specified using the\n`--file` flag.\n\n# SYNOPSIS\n\n**distrobox assemble**\n\n\t--file:\t\t\tpath or URL to the distrobox manifest/ini file\n\t--name/-n:\t\trun against a single entry in the manifest/ini file\n\t--replace/-R:\t\treplace already existing distroboxes with matching names\n\t--dry-run/-d:\t\tonly print the container manager command generated\n\t--verbose/-v:\t\tshow more verbosity\n\t--version/-V:\t\tshow version\n\n# EXAMPLES\n\nThis is an example manifest file to create two containers:\n\n\t[ubuntu]\n\tadditional_packages=\"git vim tmux nodejs\"\n\timage=ubuntu:latest\n\tinit=false\n\tnvidia=false\n\tpull=true\n\troot=false\n\treplace=true\n\tstart_now=false\n\n\t# You can add comments using this #\n\t[arch] # also inline comments are supported\n\tadditional_packages=\"git vim tmux nodejs\"\n\thome=/tmp/home\n\timage=archlinux:latest\n\tinit=false\n\tstart_now=true\n\tinit_hooks=\"touch /init-normal\"\n\tnvidia=true\n\tpre_init_hooks=\"touch /pre-init\"\n\tpull=true\n\troot=false\n\treplace=false\n\tvolume=\"/tmp/test:/run/a /tmp/test:/run/b\"\n\n**Create**\n\nWe can bring them up simply using\n\n\tdistrobox assemble create\n\nIf the file is called `distrobox.ini` and is in the same directory you're launching\nthe command, no further arguments are needed.\nYou can specify a custom path for the file using\n\n\tdistrobox assemble create --file /my/custom/path.ini\n\nOr even specify a remote file, by using an URL:\n\n\tdistrobox-assemble create --file https://raw.githubusercontent.com/89luca89/dotfiles/master/distrobox.ini\n\n**Replace**\n\nBy default, `distrobox assemble` will replace a container only if `replace=true`\nis specified in the manifest file.\n\nIn the example of the manifest above, the ubuntu container will always be replaced\nwhen running `distrobox assemble create`, while the arch container will not.\n\nTo force a replace for all containers in a manifest use the `--replace` flag\n\n\tdistrobox assemble create --replace [--file my/custom/path.ini]\n\n**Remove**\n\nWe can bring down all the containers in a manifest file by simply doing\n\n\tdistrobox assemble rm\n\nOr using a custom path for the ini file\n\n\tdistrobox assemble rm --file my/custom/path.ini\n\n**Test**\n\nYou can always test what distrobox **would do** by using the `--dry-run` flag.\nThis command will only print what commands distrobox would do without actually\nrunning them.\n\n**Clone**\n\n**Disclaimer**: You need to start the container once to ensure it is fully initialized and created\nbefore cloning it. The container being copied must also be stopped before the cloning process can proceed.\n\n**Available options**\n\nThis is a list of available options with the corresponding type:\n\nTypes legend:\n\n- bool: true or false\n- string: a single string, for example `home=\"/home/luca-linux/dbox\"`\n- string_list: multiple strings, for example `additional_packages=\"htop vim git\"`. Note that `string_list` can be\ndeclared multiple times to be compounded:\n\n\t```ini\n\t[ubuntu]\n\timage=ubuntu:latest\n\tadditional_packages=\"git vim tmux nodejs\"\n\tadditional_packages=\"htop iftop iotop\"\n\tadditional_packages=\"zsh fish\"\n\t```\n\n| Flag Name | Type | |\n| - | - | - |\n| additional_flags | string_list | Additional flags to pass to the container manager |\n| additional_packages | string_list | Additional packages to install inside the container |\n| home | string | Which home directory should the container use |\n| hostname | string | Set hostname of the container |\n| image | string | Which image should the container use, look [here](../compatibility.md) for a list |\n| clone | string | Name of the Distrobox container to use as the base for a new container (the container must be stopped). |\n| include | string | Name of the entry in the manifest to include in the current definition. |\n| init_hooks | string_list | Commands to run inside the container, after the packages setup |\n| pre_init_hooks | string_list | Commands to run inside the container, before the packages setup |\n| volume | string_list | Additional volumes to mount inside the containers |\n| exported_apps | string_list | App names or desktopfile paths to export |\n| exported_bins | string_list | Binaries to export |\n| exported_bins_path | string | Optional path where to export binaries (default: $HOME/.local/bin) |\n| entry | bool | Generate an entry for the container in the app list (default: false) |\n| start_now | bool | Start the container immediately (default: false) |\n| init | bool | Specify if this is an initful container (default: false) |\n| nvidia | bool | Specify if you want to enable NVidia drivers integration (default: false) |\n| pull | bool | Specify if you want to pull the image every time (default: false) |\n| root | bool | Specify if the container is rootful (default: false) |\n| unshare_groups | bool | Specify if the container should unshare users additional groups (default: false) |\n| unshare_ipc | bool | Specify if the container should unshare the ipc namespace (default: false) |\n| unshare_netns | bool | Specify if the container should unshare the network namespace (default: false) |\n| unshare_process | bool | Specify if the container should unshare the process (pid) namespace (default: false) |\n| unshare_devsys | bool | Specify if the container should unshare /dev (default: false) |\n| unshare_all | bool | Specify if the container should unshare all the previous options (default: false) |\n\nThe `include` option copies the attributes of a definition into another one. Recursive inclusions are allowed.\nIt operates on the manifest file and the consequent `distrobox` containers have no relation of any kind.\nPlease be aware that attributes in the including definition will not override nor shadow the ones in the included definition,\nthey will simply duplicate.\n\nFor further explanation of each of the other options in the list, take a look at the [distrobox create usage](distrobox-create.md#synopsis),\neach option corresponds to one of the `create` flags.\n\n**Advanced example**\n\n\t[tumbleweed_distrobox]\n\timage=registry.opensuse.org/opensuse/distrobox\n\tpull=true\n\tadditional_packages=\"acpi bash-completion findutils iproute iputils sensors inotify-tools unzip\"\n\tadditional_packages=\"net-tools nmap openssl procps psmisc rsync man tig tmux tree vim htop xclip yt-dlp\"\n\tadditional_packages=\"git git-credential-libsecret\"\n\tadditional_packages=\"patterns-devel-base-devel_basis\"\n\tadditional_packages=\"ShellCheck ansible-lint clang clang-tools codespell ctags desktop-file-utils gcc golang jq python3\"\n\tadditional_packages=\"python3-bashate python3-flake8 python3-mypy python3-pipx python3-pycodestyle python3-pyflakes python3-pylint python3-python-lsp-server python3-rstcheck python3-yapf python3-yamllint rustup shfmt\"\n\tadditional_packages=\"kubernetes-client helm\"\n\tinit_hooks=GOPATH=\"${HOME}/.local/share/system-go\" GOBIN=/usr/local/bin go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest;\n\tinit_hooks=GOPATH=\"${HOME}/.local/share/system-go\" GOBIN=/usr/local/bin go install github.com/onsi/ginkgo/v2/ginkgo@latest;\n\tinit_hooks=GOPATH=\"${HOME}/.local/share/system-go\" GOBIN=/usr/local/bin go install golang.org/x/tools/cmd/goimports@latest;\n\tinit_hooks=GOPATH=\"${HOME}/.local/share/system-go\" GOBIN=/usr/local/bin go install golang.org/x/tools/gopls@latest;\n\tinit_hooks=GOPATH=\"${HOME}/.local/share/system-go\" GOBIN=/usr/local/bin go install sigs.k8s.io/kind@latest;\n\tinit_hooks=ln -sf /usr/bin/distrobox-host-exec /usr/local/bin/conmon;\n\tinit_hooks=ln -sf /usr/bin/distrobox-host-exec /usr/local/bin/crun;\n\tinit_hooks=ln -sf /usr/bin/distrobox-host-exec /usr/local/bin/docker;\n\tinit_hooks=ln -sf /usr/bin/distrobox-host-exec /usr/local/bin/docker-compose;\n\tinit_hooks=ln -sf /usr/bin/distrobox-host-exec /usr/local/bin/flatpak;\n\tinit_hooks=ln -sf /usr/bin/distrobox-host-exec /usr/local/bin/podman;\n\tinit_hooks=ln -sf /usr/bin/distrobox-host-exec /usr/local/bin/xdg-open;\n\texported_apps=\"htop\"\n\texported_bins=\"/usr/bin/htop /usr/bin/git\"\n\texported_bins_path=\"~/.local/bin\"\n\n**Clone example**\n\n\t[ubuntu]\n\tadditional_packages=\"git vim tmux\"\n\timage=ubuntu:latest\n\tinit=false\n\tnvidia=false\n\tpull=true\n\troot=false\n\treplace=true\n\tstart_now=true\n\t\n\t[deno_ubuntu]\n\tclone=ubuntu\n\tinit=false\n\tnvidia=false\n\tpull=true\n\troot=false\n\treplace=true\n\tstart_now=true\n\tpre_init_hooks=curl -fsSL https://deno.land/install.sh | sh;\n\t\n\t[bun_ubuntu]\n\tclone=ubuntu\n\tinit=false\n\tnvidia=false\n\tpull=true\n\troot=false\n\treplace=true\n\tstart_now=true\n\tpre_init_hooks=curl -fsSL https://bun.sh/install | bash;\n\n**Custom login shell example**\n\n\t[ubuntu]\n\timage=ubuntu:latest\n\tpre_init_hooks=\"export SHELL=/bin/bash;\"\n\n**Include example (inherit fields from another distrobox)**\n\n\t[ubuntu]\n\timage=ubuntu:latest\n\tadditional_packages=\"git vim tmux nodejs\"\n\tadditional_packages=\"htop iftop iotop\"\n\tadditional_packages=\"zsh fish\"\n\n\t[ubuntu-nvidia]\n\tinclude=ubuntu\n\tnvidia=true\n"
  },
  {
    "path": "docs/usage/distrobox-create.md",
    "content": "<!-- markdownlint-disable MD010 MD036 -->\n# NAME\n\n\tdistrobox create\n\tdistrobox-create\n\n# DESCRIPTION\n\ndistrobox-create takes care of creating the container with input name and image.\nThe created container will be tightly integrated with the host, allowing sharing of\nthe HOME directory of the user, external storage, external usb devices and\ngraphical apps (X11/Wayland), and audio.\n\n# SYNOPSIS\n\n**distrobox create**\n\n\t--image/-i:\t\timage to use for the container\tdefault: ${container_image_default}\n\t--name/-n:\t\tname for the distrobox          default: ${container_name_default}\n\t--hostname:\t\thostname for the distrobox      default: <container-name>.$(uname -n)\n\t--pull/-p:\t\tpull the image even if it exists locally (implies --yes)\n\t--yes/-Y:\t\tnon-interactive, pull images without asking\n\t--root/-r:\t\tlaunch podman/docker/lilipod with root privileges. Note that if you need root this is the preferred\n\t\t\t\tway over \"sudo distrobox\" (note: if using a program other than 'sudo' for root privileges is necessary,\n\t\t\t\tspecify it through the DBX_SUDO_PROGRAM env variable, or 'distrobox_sudo_program' config variable)\n\t--clone/-c:\t\tname of the distrobox container to use as base for a new container\n\t\t\t\tthis will be useful to either rename an existing distrobox or have multiple copies\n\t\t\t\tof the same environment.\n\t--home/-H:\t\tselect a custom HOME directory for the container. Useful to avoid host's home littering with temp files.\n\t--volume:\t\tadditional volumes to add to the container\n\t--additional-flags/-a:\tadditional flags to pass to the container manager command\n\t--additional-packages/-ap:\tadditional packages to install during initial container setup\n\t--init-hooks:\t\tadditional commands to execute at the end of container initialization\n\t--pre-init-hooks:\tadditional commands to execute at the start of container initialization\n\t--init/-I:\t\tuse init system (like systemd) inside the container.\n\t\t\t\tthis will make host's processes not visible from within the container. (assumes --unshare-process)\n\t\t\t\tmay require additional packages depending on the container image: https://github.com/89luca89/distrobox/blob/main/docs/useful_tips.md#using-init-system-inside-a-distrobox\n\t--nvidia:\t\ttry to integrate host's nVidia drivers in the guest\n\t--platform:\t\tspecify which platform to use, eg: linux/arm64\n\t--unshare-devsys:          do not share host devices and sysfs dirs from host\n\t--unshare-groups:          do not forward user's additional groups into the container\n\t--unshare-ipc:          do not share ipc namespace with host\n\t--unshare-netns:        do not share the net namespace with host\n\t--unshare-process:          do not share process namespace with host\n\t--unshare-all:          activate all the unshare flags below\n\t--compatibility/-C:\tshow list of compatible images\n\t--help/-h:\t\tshow this message\n\t--no-entry:\t\tdo not generate a container entry in the application list\n\t--dry-run/-d:\t\tonly print the container manager command generated\n\t--verbose/-v:\t\tshow more verbosity\n\t--version/-V:\t\tshow version\n\n\t--absolutely-disable-root-password-i-am-really-positively-sure: ⚠️ ⚠️  when setting up a rootful distrobox, this will skip user password setup, leaving it blank. ⚠️ ⚠️\n\n# COMPATIBILITY\n\n\tfor a list of compatible images and container managers, please consult the man page:\n\t\tman distrobox\n\t\tman distrobox-compatibility\n\tor consult the documentation page on: https://github.com/89luca89/distrobox/blob/main/docs/compatibility.md#containers-distros\n\n# EXAMPLES\n\nCreate a distrobox with image alpine, called my-alpine container\n\n\tdistrobox create --image alpine my-alpine-container\n\nCreate a distrobox from fedora-toolbox:35 image\n\n\tdistrobox create --image registry.fedoraproject.org/fedora-toolbox:35 --name fedora-toolbox-35\n\nClone an existing distrobox container\n\n\tdistrobox create --clone fedora-35 --name fedora-35-copy\n\nAlways pull for the new image when creating a distrobox\n\n\tdistrobox create --pull --image centos:stream9 --home ~/distrobox/centos9\n\nAdd additional environment variables to the container\n\n\tdistrobox create --image fedora:35 --name test --additional-flags \"--env MY_VAR=value\"\n\nAdd additional volumes to the container\n\n\tdistrobox create --image fedora:35 --name test --volume /opt/my-dir:/usr/local/my-dir:rw --additional-flags \"--pids-limit -1\"\n\nAdd additional packages to the container\n\n\tdistrobox create --image alpine:latest --name test2 --additional-packages \"git tmux vim\"\n\nUse init-hooks to perform an action during container startup\n\n\tdistrobox create --image alpine:latest --name test --init-hooks \"touch /var/tmp/test1 && touch /var/tmp/test2\"\n\nUse pre-init-hooks to perform an action at the beginning of the container startup (before any package manager starts)\n\n\tdistrobox create -i docker.io/almalinux/8-init --init --name test --pre-init-hooks \"dnf config-manager --enable powertools && dnf -y install epel-release\"\n\nUse init to create a Systemd container (acts similar to an LXC):\n\n\tdistrobox create -i ubuntu:latest --name test --additional-packages \"systemd libpam-systemd pipewire-audio-client-libraries\" --init\n\nUse init to create a OpenRC container (acts similar to an LXC):\n\n\tdistrobox create -i alpine:latest --name test --additional-packages \"openrc\" --init\n\nUse host's NVidia drivers integration\n\n\tdistrobox create --image ubuntu:22.04 --name ubuntu-nvidia --nvidia\n\nDo not use host's IP inside the container:\n\n\tdistrobox create --image ubuntu:latest --name test --unshare-netns\n\nCreate a more isolated container, where only the $HOME, basic sockets and host's FS (in /run/host) is shared:\n\n\tdistrobox create --name unshared-test --unshare-all\n\nCreate a more isolated container, with it's own init system, this will act very similar to a full LXC container:\n\n\tdistrobox create --name unshared-init-test --unshare-all --init --image fedora:latest\n\nUse environment variables to specify container name, image and container manager:\n\n\tDBX_CONTAINER_MANAGER=\"docker\" DBX_NON_INTERACTIVE=1 DBX_CONTAINER_NAME=test-alpine DBX_CONTAINER_IMAGE=alpine distrobox-create\n\n# ENVIRONMENT VARIABLES\n\n\tDBX_CONTAINER_ALWAYS_PULL\n\tDBX_CONTAINER_CUSTOM_HOME\n\tDBX_CONTAINER_HOME_PREFIX\n\tDBX_CONTAINER_IMAGE\n\tDBX_CONTAINER_MANAGER\n\tDBX_CONTAINER_NAME\n\tDBX_CONTAINER_HOSTNAME\n\tDBX_NON_INTERACTIVE\n\tDBX_SUDO_PROGRAM\n\nDBX_CONTAINER_HOME_PREFIX defines where containers' home directories will be located.\nIf you define it as ~/dbx then all future containers' home directories will be ~/dbx/$container_name\n\n# EXTRA\n\nThe `--additional-flags` or `-a` is useful to modify defaults in the container creations.\nFor example:\n\n\tdistrobox create -i docker.io/library/archlinux -n dev-arch\n\n\tpodman container inspect dev-arch | jq '.[0].HostConfig.PidsLimit'\n\t2048\n\n\tdistrobox rm -f dev-arch\n\tdistrobox create -i docker.io/library/archlinux -n dev-arch --volume $CBL_TC:/tc --additional-flags \"--pids-limit -1\"\n\n\tpodman container inspect dev-arch | jq '.[0].HostConfig,.PidsLimit'\n\t0\n\nAdditional volumes can be specified using the `--volume` flag. This flag follows the\nsame standard as `docker` and `podman` to specify the mount point so `--volume SOURCE_PATH:DEST_PATH:MODE`.\n\n\tdistrobox create --image docker.io/library/archlinux --name dev-arch --volume /usr/share/:/var/test:ro\n\nDuring container creation, it is possible to specify (using the additional-flags) some\nenvironment variables that will persist in the container and be independent from your environment:\n\n\tdistrobox create --image fedora:35 --name test --additional-flags \"--env MY_VAR=value\"\n\nThe `--init-hooks` is useful to add commands to the entrypoint (init) of the container.\nThis could be useful to create containers with a set of programs already installed, add users, groups.\n\n\tdistrobox create  --image fedora:35 --name test --init-hooks \"dnf groupinstall -y \\\"C Development Tools and Libraries\\\"\"\n\nThe `--init` is useful to create a container that will use its own separate init system within.\nFor example using:\n\n\tdistrobox create -i docker.io/almalinux/8-init --init --name test\n\tdistrobox create -i docker.io/library/debian --additional-packages \"systemd\" --init --name test-debian\n\nInside the container we will be able to use normal systemd units:\n\n\t~$ distrobox enter test\n\tuser@test:~$ sudo systemctl enable --now sshd\n\tuser@test:~$ sudo systemctl status sshd\n\t\t● sshd.service - OpenSSH server daemon\n\t\t   Loaded: loaded (/usr/lib/systemd/system/sshd.service; enabled; vendor preset: enabled)\n\t\t   Active: active (running) since Fri 2022-01-28 22:54:50 CET; 17s ago\n\t\t\t Docs: man:sshd(8)\n\t\t\t\t   man:sshd_config(5)\n\t\t Main PID: 291 (sshd)\n\nNote that enabling `--init` **will disable host's process integration**.\nFrom within the container you will not be able to see and manage host's processes.\nThis is needed because `/sbin/init` must be pid 1.\n\nIf you want to use a non-pre-create image, you'll need to add the additional package:\n\n\tdistrobox create -i alpine:latest --init --additional-packages \"openrc\" -n test\n\tdistrobox create -i debian:stable --init --additional-packages \"systemd libpam-systemd pipewire-audio-client-libraries\" -n test\n\tdistrobox create -i ubuntu:22.04 --init --additional-packages \"systemd libpam-systemd pipewire-audio-client-libraries\" -n test\n\tdistrobox create -i archlinux:latest --init --additional-packages \"systemd\" -n test\n\tdistrobox create -i registry.opensuse.org/opensuse/tumbleweed:latest --init --additional-packages \"systemd\" -n test\n\tdistrobox create -i registry.fedoraproject.org/fedora:39 --init --additional-packages \"systemd\" -n test\n\nThe `--init` flag is useful to create system containers, where the container acts\nmore similar to a full VM than an application-container.\nInside you'll have a separate init, user-session, daemons and so on.\n\nThe `--home` flag let's you specify a custom HOME for the container.\nNote that this will NOT prevent the mount of the host's home directory,\nbut will ensure that configs and dotfiles will not litter it.\n\nThe `--root` flag will let you create a container with real root privileges. At\nfirst `enter` the user will be required to setup a password. This is done in order\nto not enable passwordless sudo/su, in a **rootful** container, this is needed\nbecause **in this mode, root inside the container is also root outside the container!**\n\nThe `--absolutely-disable-root-password-i-am-really-positively-sure`  will skip user password setup,\nleaving it blank.\n**This is genuinely dangerous and you really, positively should NOT enable this**.\n\nFrom version 1.4.0 of distrobox, when you create a new container, it will also generate\nan entry in the applications list.\n\n## NVidia integration\n\nIf your host has an NVidia gpu, with installed proprietary drivers, you can integrate\nthem with the guests by using the `--nvidia` flag:\n\n`distrobox create --nvidia --image ubuntu:latest --name ubuntu-nvidia`\n\nBe aware that **this is not compatible with non-glibc systems** and **needs somewhat newer\ndistributions to work**.\n\nThis feature was tested working on:\n\n- Almalinux\n- Archlinux\n- Centos 7 and newer\n- Clearlinux\n- Debian 10 and newer\n- OpenSUSE Leap\n- OpenSUSE Tumbleweed\n- Rockylinux\n- Ubuntu 18.04 and newer\n- Void Linux (glibc)\n"
  },
  {
    "path": "docs/usage/distrobox-enter.md",
    "content": "<!-- markdownlint-disable MD010 MD036 -->\n# NAME\n\n\tdistrobox enter\n\tdistrobox-enter\n\n# DESCRIPTION\n\ndistrobox-enter takes care of entering the container with the name specified.\nDefault command executed is your SHELL, but you can specify different shells or\nentire commands to execute.\nIf using it inside a script, an application, or a service, you can specify the\n--headless mode to disable tty and interactivity.\n\n# SYNOPSIS\n\n**distrobox enter**\n\n\t--name/-n:\t\tname for the distrobox\t\t\t\t\t\tdefault: my-distrobox\n\t--/-e:\t\t\tend arguments execute the rest as command to execute at login\tdefault: default ${USER}'s shell\n\t--no-tty/-T:\t\tdo not instantiate a tty\n\t--no-workdir/-nw:\talways start the container from container's home directory\n\t--additional-flags/-a:\tadditional flags to pass to the container manager command\n\t--help/-h:\t\tshow this message\n\t--root/-r:\t\tlaunch podman/docker/lilipod with root privileges. Note that if you need root this is the preferred\n\t\t\t\tway over \"sudo distrobox\" (note: if using a program other than 'sudo' for root privileges is necessary,\n\t\t\t\tspecify it through the DBX_SUDO_PROGRAM env variable, or 'distrobox_sudo_program' config variable)\n\t--dry-run/-d:\t\tonly print the container manager command generated\n\t--verbose/-v:\t\tshow more verbosity\n\t--version/-V:\t\tshow version\n\n# EXAMPLES\n\nEnter a distrobox named \"example\"\n\n\tdistrobox-enter example\n\nEnter a distrobox specifying a command\n\n\tdistrobox-enter --name fedora-toolbox-35 -- bash -l\n\tdistrobox-enter my-alpine-container -- sh -l\n\nUse additional podman/docker/lilipod flags while entering a distrobox\n\n\tdistrobox-enter --additional-flags \"--preserve-fds\" --name test -- bash -l\n\nSpecify additional environment variables while entering a distrobox\n\n\tdistrobox-enter --additional-flags \"--env MY_VAR=value\" --name test -- bash -l\n\tMY_VAR=value distrobox-enter --additional-flags \"--preserve-fds\" --name test -- bash -l\n\nYou can also use environment variables to specify container manager and container name:\n\n\tDBX_CONTAINER_MANAGER=\"docker\" DBX_CONTAINER_NAME=test-alpine distrobox-enter\n\n# ENVIRONMENT VARIABLES\n\n\tDBX_CONTAINER_NAME\n\tDBX_CONTAINER_MANAGER\n\tDBX_SKIP_WORKDIR\n\tDBX_SUDO_PROGRAM\n\n# EXTRA\n\nThis command is used to enter the distrobox itself. Personally, I just create multiple profiles in\nmy `gnome-terminal` to have multiple distros accessible.\n\nThe `--additional-flags` or `-a` is useful to modify default command when executing in the container.\nFor example:\n\n\tdistrobox enter -n dev-arch --additional-flags \"--env my_var=test\" -- printenv &| grep my_var\n\tmy_var=test\n\nThis is possible also using normal env variables:\n\n\tmy_var=test distrobox enter -n dev-arch --additional-flags -- printenv &| grep my_var\n\tmy_var=test\n\nIf you'd like to enter a rootful container having distrobox use a program other than 'sudo' to\nrun podman/docker/lilipod as root, such as 'pkexec' or 'doas', you may specify it with the\n`DBX_SUDO_PROGRAM` environment variable. For example, to use 'doas' to enter a rootful container:\n\n\tDBX_SUDO_PROGRAM=\"doas\" distrobox enter -n container --root\n\nAdditionally, in one of the config file paths that distrobox supports, such as `~/.distroboxrc`,\nyou can also append the line `distrobox_sudo_program=\"doas\"` (for example) to always run\ndistrobox commands involving rootful containers using 'doas'.\n"
  },
  {
    "path": "docs/usage/distrobox-ephemeral.md",
    "content": "<!-- markdownlint-disable MD010 MD036 -->\n# NAME\n\n\tdistrobox ephemeral\n\tdistrobox-ephemeral\n\n# DESCRIPTION\n\ndistrobox-ephemeral creates a temporary distrobox that is automatically destroyed\nwhen the command is terminated.\n\n# SYNOPSIS\n\n**distrobox ephemeral**\n\n\t--root/-r:\t\tlaunch podman/docker/lilipod with root privileges. Note that if you need root this is the preferred\n\t\t\t\tway over \"sudo distrobox\" (note: if using a program other than 'sudo' for root privileges is necessary,\n\t\t\t\tspecify it through the DBX_SUDO_PROGRAM env variable, or 'distrobox_sudo_program' config variable)\n\t--verbose/-v:\t\tshow more verbosity\n\t--help/-h:\t\tshow this message\n\t--/-e:\t\t\tend arguments execute the rest as command to execute at login\tdefault: default ${USER}'s shell\n\t--version/-V:\t\tshow version\n\n# EXAMPLES\n\n\tdistrobox-ephemeral --image alpine:latest -- cat /etc/os-release\n\tdistrobox-ephemeral --root --verbose --image alpine:latest --volume /opt:/opt\n\nYou can also use [flags from **distrobox-create**](distrobox-create.md) to customize the ephemeral container to run.\n\n# SEE ALSO\n\n\tdistrobox-create --help\n\tman distrobox-create\n\n# ENVIRONMENT VARIABLES\n\n\tdistrobox-ephemeral calls distrobox-create, SEE ALSO distrobox-create(1) for\n\ta list of supported environment variables to use.\n"
  },
  {
    "path": "docs/usage/distrobox-export.md",
    "content": "<!-- markdownlint-disable MD010 MD036 -->\n\n# NAME\n\n\tdistrobox-export\n\n# DESCRIPTION\n\n**Application and binary exporting**\n\ndistrobox-export takes care of exporting an app or a binary from the container\nto the host.\n\nThe exported app will be easily available in your normal launcher and it will\nautomatically be launched from the container it is exported from.\n\n# SYNOPSIS\n\n**distrobox-export**\n\n\t--app/-a:\t\tname of the application to export or absolute path to desktopfile to export\n\t--bin/-b:\t\tabsolute path of the binary to export\n\t--list-apps:\t\tlist applications exported from this container\n\t--list-binaries\t\tlist binaries exported from this container, use -ep to specify custom paths to search\n\t--delete/-d:\t\tdelete exported application or binary\n\t--export-label/-el:\tlabel to add to exported application name.\n\t\t\t\tUse \"none\" to disable.\n\t\t\t\tDefaults to (on \\$container_name)\n\t--export-path/-ep:\tpath where to export the binary\n\t--extra-flags/-ef:\textra flags to add to the command\n\t--enter-flags/-nf:\tflags to add to distrobox-enter\n\t--sudo/-S:\t\tspecify if the exported item should be run as sudo\n\t--help/-h:\t\tshow this message\n\t--verbose/-v:\t\tshow more verbosity\n\t--version/-V:\t\tshow version\n\nYou may want to install graphical applications or CLI tools in your distrobox.\nUsing `distrobox-export` from **inside** the container will let you use them from the host itself.\n\n# EXAMPLES\n\n\tdistrobox-export --app mpv [--extra-flags \"flags\"] [--delete] [--sudo]\n\tdistrobox-export --bin /path/to/bin [--export-path ~/.local/bin] [--extra-flags \"flags\"] [--delete] [--sudo]\n\n**App export example**\n\n\tdistrobox-export --app abiword\n\nThis tool will simply copy the original `.desktop` files along with needed icons,\nadd the prefix `/usr/local/bin/distrobox-enter -n distrobox_name -e ...` to the commands to run, and\nsave them in your home to be used directly from the host as a normal app.\n\n\tdistrobox-export --app /opt/application/my-app.desktop\n\nThis will skip searching for the desktopfile in canonical paths, and just use the provided file path.\n\n**Binary export example**\n\n\tdistrobox-export --bin /usr/bin/code --extra-flags \"--foreground\" --export-path $HOME/.local/bin\n\nIn the case of exporting binaries, you will have to specify **where** to export it\n(`--export-path`) and the tool will create a little wrapper script that will\n`distrobox-enter -e` from the host, the desired binary.\nThis can be handy with the use of `direnv` to have different versions of the same binary based on\nyour `env` or project.\n\nThe exported binaries will be exported in the \"--export-path\" of choice as a wrapper\nscript that acts naturally both on the host and in the container.\n\n**Additional flags**\n\nYou can specify additional flags to add to the command, for example if you want\nto export an electron app, you could add the \"--foreground\" flag to the command:\n\n\tdistrobox-export --app atom --extra-flags \"--foreground\"\n\tdistrobox-export --bin /usr/bin/vim --export-path ~/.local/bin --extra-flags \"-p\"\n\nThis works for binaries and apps.\nExtra flags are only used then the exported app or binary is used from\nthe host, using them inside the container will not include them.\n\n**Unexport**\n\nThe option \"--delete\" will un-export an app or binary\n\n\tdistrobox-export --app atom --delete\n\tdistrobox-export --bin /usr/bin/vim --export-path ~/.local/bin --delete\n\n**Run as root in the container**\n\nThe option \"--sudo\" will launch the exported item as root inside the distrobox.\n\n**Notes**\n\nNote you can use --app OR --bin but not together.\n\n![app-export](https://user-images.githubusercontent.com/598882/144294795-c7785620-bf68-4d1b-b251-1e1f0a32a08d.png)\n\nNOTE: some electron apps such as vscode and atom need additional flags to work from inside the\ncontainer, use the `--extra-flags` option to provide a series of flags, for example:\n\n`distrobox-export --app atom --extra-flags \"--foreground\"`\n"
  },
  {
    "path": "docs/usage/distrobox-generate-entry.md",
    "content": "<!-- markdownlint-disable MD010 MD036 -->\n# NAME\n\n\tdistrobox generate-entry\n\n# DESCRIPTION\n\ndistrobox-generate-entry will create a desktop icon for one of the available distroboxes.\nThis will be then deleted when you remove the matching distrobox.\n\n# SYNOPSIS\n\n**distrobox generate-entry**\n\n\t--help/-h:\t\tshow this message\n\t--all/-a:\t\tperform for all distroboxes\n\t--delete/-d:\t\tdelete the entry\n\t--icon/-i:\t\tspecify a custom icon [/path/to/icon] (default auto)\n\t--root/-r:\t\tperform on rootful distroboxes\n\t--verbose/-v:\t\tshow more verbosity\n\t--version/-V:\t\tshow version\n\n# EXAMPLES\n\nGenerate an entry for a container\n\n\tdistrobox generate-entry my-container-name\n\nSpecify a custom icon for the entry\n\n\tdistrobox generate-entry my-container-name --icon /path/to/icon.png\n\nGenerate an entry for all distroboxes\n\n\tdistrobox generate-entry --all\n\nDelete an entry\n\n\tdistrobox generate-entry container-name --delete\n"
  },
  {
    "path": "docs/usage/distrobox-host-exec.md",
    "content": "<!-- markdownlint-disable MD010 MD036 -->\n# NAME\n\n\tdistrobox-host-exec\n\n# DESCRIPTION\n\ndistrobox-host-exec lets one execute command on the host, while inside of a container.\n\nUnder the hood, distrobox-host-exec uses `host-spawn` a project that lets us\nexecute commands back on the host.\nIf the tool is not found the user will be prompted to install it.\n\n# SYNOPSIS\n\nJust pass to \"distrobox-host-exec\" any command and all its arguments, if any.\n\n\t--help/-h:\t\tshow this message\n\t--verbose/-v:\t\tshow more verbosity\n\t--version/-V:\t\tshow version\n\t--yes/-Y:\t\tAutomatically answer yes to prompt:\n                                host-spawn will be installed on the guest system\n                                if host-spawn is not detected.\n                                This behaviour is default when running in a non-interactive shell.\n\nIf no command is provided, it will execute \"$SHELL\".\n\nAlternatively, you can symlink a command name to `distrobox-host-exec`\nand then call that command by its name on the host, while inside of a container.\n\n# EXAMPLES\n\n## Run individual commands\n\n\tdistrobox-host-exec ls\n\tdistrobox-host-exec bash -l\n\tdistrobox-host-exec flatpak run org.mozilla.firefox\n\tdistrobox-host-exec podman ps -a\n\n## Drop into host shell\n\n\t~$: distrobox-host-exec # No command, executes \"$SHELL\" on the host\n\t~$: distrobox-host-exec # This command now runs on the host\n\tYou must run  distrobox-host-exec inside a container!\n\n## Symlinking host commands\n\nUse the host command name to create a symlink to `distrobox-host-exec`.\nYou can then call the host command from within the container.\n\n\t~$: git # We do not have git in the container\n\tbash: git: command not found\n\t~$: sudo ln -s /usr/bin/distrobox-host-exec /usr/local/bin/git\n\t~$: git version\n\tgit version 2.51.1\n\nYou can control podman on the host from within the container as follows:\n\n\t~$: ln -s /usr/bin/distrobox-host-exec /usr/local/bin/podman\n\t~$: ls -l /usr/local/bin/podman\n\tlrwxrwxrwx. 1 root root 51 Jul 11 19:26 /usr/local/bin/podman -> /usr/bin/distrobox-host-exec\n\t~$: podman version\n\t...this is executed on host...\n"
  },
  {
    "path": "docs/usage/distrobox-init.md",
    "content": "<!-- markdownlint-disable MD010 MD036 -->\n# NAME\n\n\tdistrobox-init\n\n# DESCRIPTION\n\n**Init the distrobox (not to be launched manually)**\n\ndistrobox-init is the entrypoint of a created distrobox.\nNote that this HAS to run from inside a distrobox, will not work if you run it\nfrom your host.\n\n**This is not intended to be used manually, but instead used by distrobox-create\nto set up the container's entrypoint.**\n\ndistrobox-init will take care of installing missing dependencies (eg. sudo), set\nup the user and groups, mount directories from the host to ensure the tight\nintegration.\n\n# SYNOPSIS\n\n**distrobox-init**\n\n\t--name/-n:\t\tuser name\n\t--user/-u:\t\tuid of the user\n\t--group/-g:\t\tgid of the user\n\t--home/-d:\t\tpath/to/home of the user\n\t--help/-h:\t\tshow this message\n\t--additional-packages:\tpackages to install in addition\n\t--init/-I:\t\twhether to use or not init\n\t--pre-init-hooks:\tcommands to execute prior to init\n\t--nvidia:\t\ttry to integrate host's nVidia drivers in the guest\n\t--upgrade/-U:\t\trun init in upgrade mode\n\t--verbose/-v:\t\tshow more verbosity\n\t--version/-V:\t\tshow version\n\t--:\t\t\tend arguments execute the rest as command to execute during init\n\n# EXAMPLES\n\n\tdistrobox-init --name test-user --user 1000 --group 1000 --home /home/test-user\n\tdistrobox-init --upgrade\n"
  },
  {
    "path": "docs/usage/distrobox-list.md",
    "content": "<!-- markdownlint-disable MD010 MD036 -->\n# NAME\n\n\tdistrobox list\n\tdistrobox-list\n\n# DESCRIPTION\n\ndistrobox-list lists available distroboxes. It detects them and lists them separately\nfrom the rest of normal containers.\n\n# SYNOPSIS\n\n**distrobox list**\n\n\t--help/-h:\t\tshow this message\n\t--no-color:\t\tdisable color formatting\n\t--root/-r:\t\tlaunch podman/docker/lilipod with root privileges. Note that if you need root this is the preferred\n\t\t\t\tway over \"sudo distrobox\" (note: if using a program other than 'sudo' for root privileges is necessary,\n\t\t\t\tspecify it through the DBX_SUDO_PROGRAM env variable, or 'distrobox_sudo_program' config variable)\n\t--verbose/-v:\t\tshow more verbosity\n\t--version/-V:\t\tshow version\n\n# EXAMPLES\n\n\tdistrobox-list\n\nYou can also use environment variables to specify container manager\n\n\tDBX_CONTAINER_MANAGER=\"docker\" distrobox-list\n\n# ENVIRONMENT VARIABLES\n\n\tDBX_CONTAINER_MANAGER\n\tDBX_SUDO_PROGRAM\n\n![image](https://user-images.githubusercontent.com/598882/147831082-24b5bc2e-b47e-49ac-9b1a-a209478c9705.png)\n"
  },
  {
    "path": "docs/usage/distrobox-rm.md",
    "content": "<!-- markdownlint-disable MD010 MD036 -->\n# NAME\n\n\tdistrobox rm\n\tdistrobox-rm\n\n# DESCRIPTION\n\ndistrobox-rm delete one of the available distroboxes.\n\n# SYNOPSIS\n\n**distrobox rm**\n\n\t--all/-a:\t\tdelete all distroboxes\n\t--force/-f:\t\tforce deletion\n\t--rm-home:\t\tremove the mounted home if it differs from the host user's one\n\t--root/-r:\t\tlaunch podman/docker/lilipod with root privileges. Note that if you need root this is the preferred\n\t\t\t\tway over \"sudo distrobox\" (note: if using a program other than 'sudo' for root privileges is necessary,\n\t\t\t\tspecify it through the DBX_SUDO_PROGRAM env variable, or 'distrobox_sudo_program' config variable)\n\t--help/-h:\t\tshow this message\n\t--verbose/-v:\t\tshow more verbosity\n\t--version/-V:\t\tshow version\n\n# EXAMPLES\n\n\tdistrobox-rm container-name [--force] [--all]\n\nYou can also use environment variables to specify container manager and name:\n\n\tDBX_CONTAINER_MANAGER=\"docker\" DBX_CONTAINER_NAME=test-alpine distrobox-rm\n\n# ENVIRONMENT VARIABLES\n\n\tDBX_CONTAINER_MANAGER\n\tDBX_CONTAINER_NAME\n\tDBX_NON_INTERACTIVE\n\tDBX_SUDO_PROGRAM\n"
  },
  {
    "path": "docs/usage/distrobox-stop.md",
    "content": "<!-- markdownlint-disable MD010 MD036 -->\n# NAME\n\n\tdistrobox stop\n\tdistrobox-stop\n\n# DESCRIPTION\n\ndistrobox-stop stop a running distrobox.\n\nDistroboxes are left running, even after exiting out of them, so that\nsubsequent enters are really quick. This is how they can be stopped.\n\n# SYNOPSIS\n\n**distrobox stop**\n\n\t--all/-a:\t\tstop all distroboxes\n\t--yes/-Y:\t\tnon-interactive, stop without asking\n\t--help/-h:\t\tshow this message\n\t--root/-r:\t\tlaunch podman/docker/lilipod with root privileges. Note that if you need root this is the preferred\n\t\t\t\tway over \"sudo distrobox\" (note: if using a program other than 'sudo' for root privileges is necessary,\n\t\t\t\tspecify it through the DBX_SUDO_PROGRAM env variable, or 'distrobox_sudo_program' config variable)\n\t--verbose/-v:\t\tshow more verbosity\n\t--version/-V:\t\tshow version\n\n# EXAMPLES\n\n\tdistrobox-stop container-name1 container-name2\n\tdistrobox-stop container-name\n\tdistrobox-stop --all\n\nYou can also use environment variables to specify container manager and name:\n\n\tDBX_CONTAINER_MANAGER=\"docker\" DBX_CONTAINER_NAME=test-alpine distrobox-stop\n\n# ENVIRONMENT VARIABLES\n\n\tDBX_CONTAINER_MANAGER\n\tDBX_CONTAINER_NAME\n\tDBX_NON_INTERACTIVE\n\tDBX_SUDO_PROGRAM\n"
  },
  {
    "path": "docs/usage/distrobox-upgrade.md",
    "content": "<!-- markdownlint-disable MD010 MD036 -->\n# NAME\n\n\tdistrobox-upgrade\n\n# DESCRIPTION\n\ndistrobox-upgrade will enter the specified list of containers and will perform\nan upgrade using the container's package manager.\n\n# SYNOPSIS\n\n**distrobox upgrade**\n\n\t--help/-h:\t\tshow this message\n\t--all/-a:\t\tperform for all distroboxes\n\t--running:\t\tperform only for running distroboxes\n\t--root/-r:\t\tlaunch podman/docker/lilipod with root privileges. Note that if you need root this is the preferred\n\t\t\t\tway over \"sudo distrobox\" (note: if using a program other than 'sudo' for root privileges is necessary,\n\t\t\t\tspecify it through the DBX_SUDO_PROGRAM env variable, or 'distrobox_sudo_program' config variable)\n\t--verbose/-v:\t\tshow more verbosity\n\t--version/-V:\t\tshow version\n\n# EXAMPLES\n\nUpgrade all distroboxes\n\n\tdistrobox-upgrade --all\n\nUpgrade all running distroboxes\n\n\tdistrobox-upgrade --all --running\n\nUpgrade a specific distrobox\n\n\tdistrobox-upgrade alpine-linux \n\nUpgrade a list of distroboxes\n\n\tdistrobox-upgrade alpine-linux ubuntu22 my-distrobox123\n\n**Automatically update all distro**\n\nYou can create a systemd service to perform distrobox-upgrade automatically,\nthis example shows how to run it daily:\n\n~/.config/systemd/user/distrobox-upgrade.service\n\n\t[Unit]\n\tDescription=distrobox-upgrade Automatic Update\n\n\t[Service]\n\tType=simple\n\tExecStart=distrobox-upgrade --all\n\tStandardOutput=null\n\n~/.config/systemd/user/distrobox-upgrade.timer\n\n\t[Unit]\n\tDescription=distrobox-upgrade Automatic Update Trigger\n\n\t[Timer]\n\tOnBootSec=1h\n\tOnUnitInactiveSec=1d\n\n\t[Install]\n\tWantedBy=timers.target\n\nThen simply do a `systemctl --user daemon-reload && systemctl --user enable --now distrobox-upgrade.timer`\n"
  },
  {
    "path": "docs/usage/usage.md",
    "content": "<!-- markdownlint-disable MD010 MD051 -->\n- [Distrobox](../README.md)\n  - [Outside the distrobox](#outside-the-distrobox)\n    - [distrobox-assemble](distrobox-assemble.md)\n    - [distrobox-create](distrobox-create.md)\n    - [distrobox-enter](distrobox-enter.md)\n    - [distrobox-ephemeral](distrobox-ephemeral.md)\n    - [distrobox-list](distrobox-list.md)\n    - [distrobox-rm](distrobox-rm.md)\n    - [distrobox-stop](distrobox-stop.md)\n    - [distrobox-upgrade](distrobox-upgrade.md)\n    - [distrobox-generate-entry](distrobox-generate-entry.md)\n  - [Inside the distrobox](#inside-the-distrobox)\n    - [distrobox-export](distrobox-export.md)\n    - [distrobox-host-exec](distrobox-host-exec.md)\n    - [distrobox-init](distrobox-init.md)\n"
  },
  {
    "path": "docs/useful_tips.md",
    "content": "- [Distrobox](README.md)\n  - [Launch a distrobox from your applications list](#launch-a-distrobox-from-your-applications-list)\n  - [Create a distrobox with a custom HOME directory](#create-a-distrobox-with-a-custom-home-directory)\n  - [Mount additional volumes in a distrobox](#mount-additional-volumes-in-a-distrobox)\n  - [Use a different shell than the host](#use-a-different-shell-than-the-host)\n  - [Run the container with real root](#run-the-container-with-real-root)\n  - [Run Debian/Ubuntu container behind proxy](#run-debianubuntu-container-behind-proxy)\n  - [Using a command other than sudo to run a rootful container](#using-a-command-other-than-sudo-to-run-a-rootful-container)\n  - [Duplicate an existing distrobox](#duplicate-an-existing-distrobox)\n  - [Export to the host](#export-to-the-host)\n  - [Execute commands on the host](#execute-commands-on-the-host)\n  <!-- markdownlint-disable-next-line MD051 -->\n  - [Resolve \"Error cannot open display: :0\"](#resolve-error-cannot-open-display-0)\n  - [Using init system inside a distrobox](#using-init-system-inside-a-distrobox)\n  - [Using Docker inside a Distrobox](#using-docker-inside-a-distrobox)\n  - [Using Podman inside a Distrobox](#using-podman-inside-a-distrobox)\n  - [Using LXC inside a Distrobox](#using-lxc-inside-a-distrobox)\n  - [Using Waydroid inside a Distrobox](#using-waydroid-inside-a-distrobox)\n    - [Manual Installation](#manual-installation)\n    - [Automated Installation](#automated-installation)\n  - [Using host's Podman or Docker inside a Distrobox](#using-hosts-podman-or-docker-inside-a-distrobox)\n  - [Using distrobox as main cli](#using-distrobox-as-main-cli)\n  - [Using a different architecture](#using-a-different-architecture)\n  - [Using the GPU inside the container](#using-the-gpu-inside-the-container)\n    - [Using nvidia-container-toolkit](#using-nvidia-container-toolkit)\n  - [Slow creation on podman and image size getting bigger with distrobox create](#slow-creation-on-podman-and-image-size-getting-bigger-with-distrobox-create)\n  - [Container save and restore](#container-save-and-restore)\n  - [Check used resources](#check-used-resources)\n  - [Pre-installing additional package repositories](#pre-installing-additional-package-repositories)\n  - [Apply resource limitation on the fly](#apply-resource-limitation-on-the-fly)\n  - [Copy/yank text to host clipboard](#copy-text-to-host-clipboard)\n\n---\n\n# Useful tips\n\n## Detect if you're in a distrobox\n\nBeing this tightly integrated, it may be useful to know when you're in a container or not.\n\nTo detect you can just check the environment variable `\"${CONTAINER_ID}\"`, if set, you're in a distrobox.\n\n## Launch a distrobox from your applications list\n\nStarting from distrobox 1.4.0, containers created will automatically generate a desktop entry.\nFor containers generated with older versions, you can use:\n\n`distrobox generate-entry your-container-name`\n\nTo delete it:\n\n`distrobox generate-entry your-container-name --delete`\n\n## Create a distrobox with a custom HOME directory\n\n`distrobox create` supports the use of the `--home` flag, as specified in the\nusage [HERE](./usage/distrobox-create.md)\n\nSimply use:\n\n`distrobox create --name test --image your-chosen-image:tag --home /your/custom/home`\n\n## Mount additional volumes in a distrobox\n\n`distrobox create` supports the use of the `--volume` flag, as specified in the\nusage [HERE](./usage/distrobox-create.md)\n\nSimply use:\n\n`distrobox create --name test --image your-chosen-image:tag --volume /your/custom/volume/path`\n\n## Use a different shell than the host\n\nFrom version 1.4.0, `distrobox enter` will execute the login shell of the container's user\nby default. So, just change the default shell in the container using:\n\n`chsh -s /bin/shell-to-use`\n\nexit and log back in the container.\n\nFor version older than 1.4.0, distrobox will pick up the shell from the host and use it inside the container.\nIf you want a different one you can use:\n\n```sh\nSHELL=/bin/zsh distrobox create -n test\nSHELL=/bin/zsh distrobox enter test\n```\n\nIf you want to declaratively set a custom shell for each container when using `distrobox assemble`,\nyou can achieve this by using the `pre_init_hooks` option. For example:\n\n```ini\npre_init_hooks=\"export SHELL=/bin/bash;\"\n```\n\n## Run the container with real root\n\nWhen using podman, distrobox will prefer to use rootless containers. In this mode the `root`\nuser inside the container is **not** the real `root` user of the host. But it still has\nthe same privileges as your normal `$USER`.\n\nBut what if you really really need those `root` privileges even inside the container?\n\nRunning `sudo distrobox` is not supported, instead, it is better to simply use normal\ncommand with the `--root` or `-r` flag, so that distrobox can still integrate better\nwith your `$USER`.\n\n```console\n:~$ distrobox create --name test --image your-chosen-image:tag --root\n```\n\nAnother use case, what if you want or need to run distrobox with the root user, in a login\nshell?\n\nBefore the 1.4.3 release, it wasn't possible. We couldn't make a distinction between someone\nrunning distrobox via `sudo` from someone logged in as the root user in a shell. Now things are\nas easy as it would be if you were creating a rootless container:\n\n```console\n:~# distrobox create --name your-container --pull --image your-chosen-image:tag`\n```\n\nAnd:\n\n```console\n:~# distrobox enter your-container`\n```\n\nWe trust you already know the implications of running distrobox, as well as anything else,\nwith the root user and that with great power comes great responsibilities.\n\n## Run Debian/Ubuntu container behind proxy\n\nIt might be that you're trying to set-up your distrobox, but you're stuck behind a proxy.\nA simple solution can be crafted using `pre-init-hooks`\n\n```console\nproxy=http://my_proxy.domain.example:3128\nt=\"echo 'Acquire::http::Proxy \\\\\\\"\"${proxy}\"\\\\\\\";' > /etc/apt/apt.conf.d/proxy.conf; echo 'Acquire::https::Proxy \\\\\\\"\"${proxy}\"\\\\\\\";' >> /etc/apt/apt.conf.d/proxy.conf;\"\nhttp_proxy=\"${proxy}\" distrobox create --image debian --name deb --pre-init-hooks \"${t}\"\n```\n\nThis way, we're configuring `apt` before using it.\n\n## Using a command other than sudo to run a rootful container\n\nWhen using the `--root` option with Distrobox, internally, it uses `sudo` to be able to\ninteract with the rootful container through podman/docker, which will prompt for a valid\nroot password on the terminal. However, some users might prefer to use a command other\nthan `sudo` in order to authenticate as root; for example, `pkexec` could be used to\ndisplay a graphical authentication prompt. If you need this, make sure to specify\nthe desired command through the `DBX_SUDO_PROGRAM` environment variable\n(supported by most `distrobox` subcommands), alongside `--root`. Sample usage:\n\n`DBX_SUDO_PROGRAM=\"pkexec\" distrobox create --name test --image your-chosen-image:tag --root`\n\nAdditionally, you may also have any further distrobox commands use `pkexec` (for example)\nfor rootful containers by appending the line `distrobox_sudo_program=\"pkexec\"`\n(replace `pkexec` with the desired program) to one of the config file paths that\ndistrobox supports; for example, to '~/.distroboxrc'.\n\nIt is also worth noting that, if your sudo program does not have persistence\n(i.e., cooldown before asking for the root password again after a successful authentication)\nconfigured, then you may have to enter the root password multiple times, as distrobox\ncalls multiple podman/docker commands under the hood. In order to avoid this, it is\nrecommended to either configure your sudo program to be persistent, or, if that's\nnot feasible, use `sudo` whenever possible (which has persistence enabled by default).\n\nHowever, if you'd like to have a graphical authentication prompt, but would also like\nto benefit from `sudo`'s persistence (to avoid prompting for a password multiple times in a row),\nyou may specify `sudo --askpass` as the sudo program.\nThe `--askpass` option makes sudo launch the program in the path (or name, if it is in `$PATH`)\nspecified by the `SUDO_ASKPASS` environment variable, and uses its output (to stdout)\nas the password input to authenticate as root. If unsuccessful, it launches the program again,\nuntil either it outputs the correct password, the user cancels the operation, or\na limit of amount of authentication attempts is reached.\n\nSo, for example, assume you'd like to use `zenity --password` to prompt for the sudo password.\nYou may save a script, e.g. `my-password-prompt`, to somewhere in your machine - say,\nto `~/.local/bin/my-password-prompt` - with the following contents:\n\n```sh\n#!/bin/sh\nzenity --password\n```\n\nMake it executable using, for example, `chmod` (in the example, by running `chmod +x ~/.local/bin/my-password-prompt` -\nreplace with the path to your script). Afterwards, make sure `SUDO_ASKPASS` is set to your newly-created script's path,\nand also ensure `DBX_SUDO_PROGRAM` is set to `sudo --askpass`, and you should be good to go. For example,\nrunning the below command should only prompt the root authentication GUI once throughout the whole process:\n\n`SUDO_ASKPASS=\"$HOME/.local/bin/my-password-prompt\" DBX_SUDO_PROGRAM=\"sudo --askpass\" distrobox-ephemeral -r`\n\nYou may make these options persist by specifying those environment variables in your shell's rc file (such as `~/.bashrc`).\nNote that this will also work if `distrobox_sudo_program=\"sudo --askpass\"` is specified in one of distrobox's config files\n(such as `~/.distroboxrc`), alongside `export SUDO_ASKPASS=\"/path/to/password/prompt/program\"` (for example - however, this\nlast line is usually better suited to your shell's rc file).\n\n## Duplicate an existing distrobox\n\nIt can be useful to just duplicate an already set up environment, to do this,\n`distrobox create` supports the use of the\n`--clone` flag, as specified in the usage [HERE](./usage/distrobox-create.md)\n\nSimply use:\n\n`distrobox create --name test --clone name-of-distrobox-to-clone`\n\n## Export to the host\n\nDistrobox supports exporting to the host either binaries or applications.\n[Head over the usage page to have an explanation and examples.](usage/distrobox-export.md)\n\n## Execute commands on the host\n\nYou can check this little post about [executing commands on the host.](posts/execute_commands_on_host.md)\n\n## Resolve \"Error cannot open display: :0\"\n\nIf your container is not able to connect to your host xserver, make sure to\ninstall `xhost` on the host machine and run `xhost +si:localuser:$USER`.\nIf you wish to enable this functionality on future reboots add the above command\nto your `~/.distroboxrc`\n\n```console\n-$ cat ~/.distroboxrc\nxhost +si:localuser:$USER >/dev/null\n```\n\n## Using init system inside a distrobox\n\nYou can use an init system inside the container. You can either use supported\npre-created images, or have to add additional packages.\n\nExample of such images are:\n\n- docker.io/almalinux/8-init\n- registry.access.redhat.com/ubi7/ubi-init\n- registry.access.redhat.com/ubi8/ubi-init\n- registry.access.redhat.com/ubi9/ubi-init\n- registry.opensuse.org/opensuse/leap:latest\n- registry.opensuse.org/opensuse/tumbleweed:latest\n\nYou can use such feature using:\n\n`distrobox create -i docker.io/almalinux/8-init --init --name test`\n\nIf you want to use a non-pre-create image, you'll need to add the additional package:\n\n```console\ndistrobox create -i alpine:latest --init --additional-packages \"openrc\" -n test\ndistrobox create -i debian:stable --init --additional-packages \"systemd libpam-systemd pipewire-audio-client-libraries\" -n test\ndistrobox create -i ubuntu:22.04 --init --additional-packages \"systemd libpam-systemd pipewire-audio-client-libraries\" -n test\ndistrobox create -i archlinux:latest --init --additional-packages \"systemd\" -n test\ndistrobox create -i registry.opensuse.org/opensuse/tumbleweed:latest --init --additional-packages \"systemd\" -n test\ndistrobox create -i registry.fedoraproject.org/fedora:39 --init --additional-packages \"systemd\" -n test\n```\n\nNote however that in this mode, you'll not be able to access host's processes\nfrom within the container.\n\nResult:\n\nSystemd running on openSUSE\n![image](https://github.com/89luca89/distrobox/assets/598882/aa70ce88-2ca6-4266-b530-f51956bd4a0a)\n\nOpenRC running on Alpine Linux\n![image](https://github.com/89luca89/distrobox/assets/598882/eb6226d5-6992-47d8-a42b-f3e90e5809d2)\n\nExample use:\n\n```shell\n~$ distrobox create -i docker.io/almalinux/8-init --init --name test\n\nuser@test:~$ sudo systemctl enable --now sshd\n\nuser@test:~$ sudo systemctl status sshd\n    ● sshd.service - OpenSSH server daemon\n       Loaded: loaded (sshd.service; enabled; vendor preset: enabled)\n       Active: active (running) since Fri 2022-01-28 22:54:50 CET; 17s ago\n         Docs: man:sshd(8)\n               man:sshd_config(5)\n     Main PID: 291 (sshd)\n```\n\n## Using Docker inside a Distrobox\n\nYou may want to run a separate instance of docker inside your container.\nIn order to do this, create a [container with an init system](#using-init-system-inside-a-distrobox)\nusing rootful Podman or Docker and using the **unshare-all** flag.\n\nExample:\n\n```sh\ndistrobox create --root \\\n  --image registry.opensuse.org/opensuse/distrobox:latest \\\n  --additional-packages \"systemd docker\" \\\n  --init \\\n  --unshare-all\n```\n\nInside the container:\n\n```console\nluca-linux@tumbleweed:~$ sudo systemctl enable --now docker\nluca-linux@tumbleweed:~$ sudo systemctl status docker\n● docker.service - Docker Application Container Engine\n     Loaded: loaded (/usr/lib/systemd/system/docker.service; enabled; preset: disabled)\n     Active: active (running) since Sat 2023-08-26 19:21:34 UTC; 3min 47s ago\n       Docs: http://docs.docker.com\n   Main PID: 1924 (dockerd)\n        CPU: 1.268s\n     CGroup: /system.slice/docker-b63c525a32a313837146cfb00ed09c151eabd3137ad62779f47d3924c92f7b16.scope/system.slice/docker.service\n             ├─1924 /usr/bin/dockerd --add-runtime oci=/usr/sbin/docker-runc\n             └─1942 containerd --config /var/run/docker/containerd/containerd.toml --log-level warn\n\nAug 26 19:21:31 tumbleweed.localhost dockerd[1924]: time=\"2023-08-26T19:21:31.188589166Z\" level=error msg=\"failed to mount overlay: invalid argument\" storage-driver=overlay2\nAug 26 19:21:31 tumbleweed.localhost dockerd[1924]: time=\"2023-08-26T19:21:31.391206840Z\" level=warning msg=\"WARNING: No swap limit support\"\nAug 26 19:22:54 tumbleweed.localhost dockerd[1942]: time=\"2023-08-26T19:22:54.385157019Z\" level=info msg=\"loading plugin \\\"io.containerd.event.v1.publisher\\\"...\" runtime=io.containerd.runc.v2 type=io.containerd.event.v1\nAug 26 19:22:54 tumbleweed.localhost dockerd[1942]: time=\"2023-08-26T19:22:54.385241039Z\" level=info msg=\"loading plugin \\\"io.containerd.internal.v1.shutdown\\\"...\" runtime=io.containerd.runc.v2 type=io.containerd.internal.v1\nAug 26 19:22:54 tumbleweed.localhost dockerd[1942]: time=\"2023-08-26T19:22:54.385250887Z\" level=info msg=\"loading plugin \\\"io.containerd.ttrpc.v1.task\\\"...\" runtime=io.containerd.runc.v2 type=io.containerd.ttrpc.v1\nAug 26 19:22:54 tumbleweed.localhost dockerd[1942]: time=\"2023-08-26T19:22:54.385411802Z\" level=info msg=\"starting signal loop\" namespace=moby path=/run/docker/containerd/daemon/io.containerd.runtime.v2.task/moby/bd4cb19537b4c39131b084e04>\nAug 26 19:23:16 tumbleweed.localhost dockerd[1942]: time=\"2023-08-26T19:23:16.575589748Z\" level=error msg=\"failed to enable controllers ([cpuset cpu io memory hugetlb pids rdma misc])\" error=\"failed to write subtree controllers [cpuset cp>\nAug 26 19:23:16 tumbleweed.localhost dockerd[1942]: time=\"2023-08-26T19:23:16.575764283Z\" level=warning msg=\"error from *cgroupsv2.Manager.EventChan\" error=\"failed to add inotify watch for \\\"/sys/fs/cgroup/system.slice/docker-b63c525a32a3>\nAug 26 19:23:44 tumbleweed.localhost dockerd[1942]: time=\"2023-08-26T19:23:44.744144975Z\" level=warning msg=\"cleaning up after shim disconnected\" id=bd4cb19537b4c39131b084e04c354712bac71c6d1ced33d6d1d6933ada0507cc namespace=moby\nAug 26 19:23:44 tumbleweed.localhost dockerd[1942]: time=\"2023-08-26T19:23:44.754027382Z\" level=warning msg=\"cleanup warnings time=\\\"2023-08-26T19:23:44Z\\\" level=info msg=\\\"starting signal loop\\\" namespace=moby pid=2221 runtime=io.contain>\nluca-linux@tumbleweed:~$ sudo docker run --rm -ti alpine\n/ # \n```\n\n## Using Podman inside a Distrobox\n\nYou may want to run a separate instance of podman inside your container.\nIn order to do this, create a container using rootful Podman or Docker\nand using the **unshare-all** flag.\n\nExample:\n\n```sh\ndistrobox create --root \\\n  --image registry.opensuse.org/opensuse/distrobox:latest \\\n  --additional-packages \"podman\" \\\n  --unshare-all\n```\n\nInside it install podman, and add subuids for the user:\n\n```sh\nsudo usermod --add-subuids 10000-65536 $USER\nsudo usermod --add-subgids 10000-65536 $USER\ncat << EOF | sudo tee /etc/containers/containers.conf\n[containers]\nnetns=\"host\"\nuserns=\"host\"\nipcns=\"host\"\nutsns=\"host\"\ncgroupns=\"host\"\nlog_driver = \"k8s-file\"\n[engine]\ncgroup_manager = \"cgroupfs\"\nevents_logger=\"file\"\nEOF\n```\n\nThen you'll be able to use both rootful and rootless podman inside the container:\n\n```console\nluca-linux@tumbleweed:~> podman run --rm -ti alpine\n/ #\nluca-linux@tumbleweed:~> sudo podman run --rm -ti alpine\n/ #\n```\n\n## Using LXC inside a Distrobox\n\nYou may want to run an LXC instance inside your container.\nIn order to do this, create a [container with an init system](#using-init-system-inside-a-distrobox)\nusing the **unshare-all** flag, this works with either docker, rootful podman, or rootless podman.\n\nExample:\n\n```sh\ndistrobox create --root \\\n  --image registry.opensuse.org/opensuse/distrobox:latest \\\n  --additional-packages \"systemd lxc\" \\\n  --init \\\n  --unshare-all\n```\n\nInside the container we will need to first setup the lxcbr0 network and enable the services:\n\n```console\nluca-linux@tumbleweed:~> sudo systemctl enable --now lxc-monitord.service lxc-net.service lxc.service lxcfs.service\nCreated symlink /etc/systemd/system/multi-user.target.wants/lxc-monitord.service → /usr/lib/systemd/system/lxc-monitord.service.\nCreated symlink /etc/systemd/system/multi-user.target.wants/lxc-net.service → /usr/lib/systemd/system/lxc-net.service.\nCreated symlink /etc/systemd/system/multi-user.target.wants/lxc.service → /usr/lib/systemd/system/lxc.service.\nCreated symlink /etc/systemd/system/multi-user.target.wants/lxcfs.service → /usr/lib/systemd/system/lxcfs.service.\nluca-linux@tumbleweed:~> ip a\n1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000\n    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00\n    inet 127.0.0.1/8 scope host lo\n       valid_lft forever preferred_lft forever\n    inet6 ::1/128 scope host proto kernel_lo \n       valid_lft forever preferred_lft forever\n2: tap0: <BROADCAST,UP,LOWER_UP> mtu 65520 qdisc fq_codel state UNKNOWN group default qlen 1000\n    link/ether 02:81:bf:43:1e:65 brd ff:ff:ff:ff:ff:ff\n    inet 10.0.2.100/24 brd 10.0.2.255 scope global tap0\n       valid_lft forever preferred_lft forever\n    inet6 fd00::81:bfff:fe43:1e65/64 scope global dynamic mngtmpaddr proto kernel_ra \n       valid_lft 86309sec preferred_lft 14309sec\n    inet6 fe80::81:bfff:fe43:1e65/64 scope link proto kernel_ll \n       valid_lft forever preferred_lft forever\nluca-linux@tumbleweed:~> sudo ip link add name lxcbr0 type bridge\nluca-linux@tumbleweed:~> sudo ip link set dev lxcbr0 up\nluca-linux@tumbleweed:~> sudo ip link set tap0 master lxcbr0\nluca-linux@tumbleweed:~> sudo ip address add 10.0.2.100/24 dev lxcbr0\n```\n\nThen we can proceed with the LXC container creation:\n\n```console\nluca-linux@tumbleweed:~> sudo lxc-create -n test-nested-lxc -t download\n[ ... ] # Here do the interactive rootfs choice, I'll use alpine:edge amd64\n\nDownloading the image index\nDownloading the rootfs\nDownloading the metadata\nThe image cache is now ready\nUnpacking the rootfs\n\n---\nYou just created an Alpinelinux edge x86_64 (20230826_13:00) container.\n\nluca-linux@tumbleweed:~> sudo lxc-start test-nested-lxc\nluca-linux@tumbleweed:~> sudo lxc-attach test-nested-lxc\n/ # ps aux\nPID   USER     TIME  COMMAND\n    1 root      0:00 /sbin/init\n  266 root      0:00 /sbin/syslogd -t -n\n  273 root      0:00 /sbin/openrc default\n  293 root      0:00 /usr/sbin/crond -c /etc/crontabs -f\n  300 root      0:00 {networking} /sbin/openrc-run /etc/init.d/networking --lockfd 4 start\n  301 root      0:00 {openrc-run.sh} /bin/sh /lib/rc/sh/openrc-run.sh /etc/init.d/networking start\n  347 root      0:00 ifup -i /etc/network/interfaces eth0\n  367 root      0:00 {dhcp} /bin/sh /usr/libexec/ifupdown-ng/dhcp\n  372 root      0:00 /sbin/udhcpc -b -R -p /var/run/udhcpc.eth0.pid -i eth0 -x hostname:test-nested-lxc\n  375 root      0:00 /bin/ash\n  376 root      0:00 ps aux\n/ #\n```\n\nAnd you have a working LXC inside your Distrobox container.\n\n## Using Waydroid inside a Distrobox\n\nWaydroid is a popular solution for running Android applications on Linux using an LXC container.\nSince these containers run inside a Distrobox, you can also run Waydroid.\n\n> **Note**: Wayland and the `binder_linux` module are required at the host level. You can install\n> the DKMS from the [choff/anbox-modules](https://github.com/choff/anbox-modules) repository.\n\n### Manual Installation\n\nTo do this, we need a rootful container [with Systemd](#using-init-system-inside-a-distrobox) plus\nsome additional dependencies (tested with Vanilla OS Pico and Debian Sid):\n\n- libpam-systemd\n- curl\n- kmod\n- dbus-x11\n- iptables\n- mutter\n\nLet's create a rootful and unshared container as follows:\n\n```sh\ndistrobox create --root \\\n  --image ghcr.io/vanilla-os/pico:main \\\n  --additional-packages \"systemd libpam-systemd curl kmod dbus-x11 iptables mutter\" \\\n  --init \\\n  --unshare-all \\\n  --name waydroid\n```\n\nOnce it's started with `distrobox enter --root waydroid`, we can proceed with the Waydroid\ninstallation from the official repository:\n\n```bash\ncurl --progress-bar --proto '=https' --tlsv1.2 -Sf https://repo.waydro.id/waydroid.gpg --output /usr/share/keyrings/waydroid.gpg\necho \"deb [signed-by=/usr/share/keyrings/waydroid.gpg] https://repo.waydro.id/ bookworm main\" | tee /etc/apt/sources.list.d/waydroid.list\nsudo apt update\nsudo apt install waydroid\n```\n\nThen proceed with its initialization using:\n\n```bash\nexport XDG_RUNTIME_DIR=\"/run/host/${XDG_RUNTIME_DIR}\"\nexport DBUS_SESSION_BUS_ADDRESS=\"unix:path=/run/host/$(echo \"${DBUS_SESSION_BUS_ADDRESS}\" | cut -d '=' -f2-)\"\n\nwaydroid init\n```\n\nThe above environment variables must be present each time the `waydroid` command is used.\n\n### Automated Installation\n\nThe [Waydroid image](https://github.com/Vanilla-OS/waydroid-image/blob/main/recipe.yml) from\nthe Vanilla OS Team is designed to streamline the entire setup process. To use it, proceed as follows:\n\n```bash\ndistrobox create --root \\\n  --image ghcr.io/vanilla-os/waydroid:main \\\n  --init \\\n  --unshare-all \\\n  --name waydroid\n\ndistrobox enter --root waydroid\n```\n\nOnce started, Waydroid is automatically executed via Systemd. Check for the process to finish using\nthe `systemctl status waydroid-init` command, then start using Waydroid with:\n\n```bash\newaydroid --help\n```\n\nMake sure to use the `ewaydroid` command each time you need to work with Waydroid. This command is a\nwrapper that sets the proper environment variables to make it work with the host D-Bus.\n\n## Using host's Podman or Docker inside a Distrobox\n\nYou can easily control host's instance of docker or podman, using `distrobox-host-exec`\nYou can use:\n\n```console\nsudo ln -s /usr/bin/distrobox-host-exec /usr/local/bin/podman\n```\n\nor\n\n```console\nsudo ln -s /usr/bin/distrobox-host-exec /usr/local/bin/docker\n```\n\nThis will create a `podman` or `docker` command inside the distrobox that will\ntransparently execute the command on the host.\n\n## Using distrobox as main cli\n\nIn case you want (like me) to use your container as the main CLI environment,\nit comes handy to use `gnome-terminal` profiles to create a dedicated setup for it:\n\n![Screenshot from 2021-12-19 22-29-08](https://user-images.githubusercontent.com/598882/146691460-b8a5bb0a-a83d-4e32-abd0-4a0ff9f50eb7.png)\n\nPersonally, I just bind `Ctrl-Alt-T` to the Distrobox profile and `Super+Enter`\nto the Host profile.\n\nFor other terminals, there are similar features (profiles) or  you can set up a\ndedicated shortcut to launch a terminal directly in the distrobox\n\n## Using a different architecture\n\nIn case you want to run a container with a different architecture from your host,\nyou can leverage the use of `qemu` and support from podman/docker.\n\nInstall on your host the following dependencies:\n\n- qemu\n- qemu-user-static\n- binfmt-support\n\nThen you can easily run the image you like:\n\n```console\n~$ uname -m\nx86_64\n~$ distrobox create --image debian --additional-flags  --platform=linux/aarch64 -n debian-arm64\n~$ distrobox enter debian-arm64\n...\nuser@debian-arm64:~$ uname -m\naarch64\n```\n\n![image](https://user-images.githubusercontent.com/598882/170837120-9170a9fa-6153-4684-a435-d60a0136b563.png)\n\n## Using the GPU inside the container\n\nFor Intel and AMD GPUs, the support is baked in, as the containers will install\ntheir latest available mesa/dri drivers.\n\nFor NVidia, you can use the `--nvidia` flag during create, see [distrobox-create](./usage/distrobox-create.md)\ndocumentation to discover how to use it.\n\n```console\n~$ distrobox create --nvidia --name ubuntu-nvidia --image ubuntu:latest\n```\n\n### Using nvidia-container-toolkit\n\nAlternatively from the `--nvidia` flag, you can use NVidia's own [nvidia-container-toolkit](https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/user-guide.html).\nAfter following the [official guide to set nvidia-ctk up](https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/user-guide.html)\nyou can use it from distrobox doing:\n\nIn case of podman container manager, run:\n\n```console\ndistrobox create --name example-nvidia-toolkit --additional-flags \"--gpus all\" --image  docker.io/nvidia/cuda\n```\n\nIn case of docker container manager, run:\n\n```console\ndistrobox create --name example-nvidia-toolkit --additional-flags \"--gpus all --device=nvidia.com/gpu=all\" --image  docker.io/nvidia/cuda\n```\n\n## Slow creation on podman and image size getting bigger with distrobox create\n\nFor rootless podman 3.4.0 and upward, adding this to your `~/.config/containers/storage.conf`\nfile will improve container creation speed and fix issues with images getting\nbigger when using rootless containers.\n\n```conf\n[storage]\ndriver = \"overlay\"\n\n[storage.options.overlay]\nmount_program = \"/usr/bin/fuse-overlayfs\"\n```\n\nNote that this is necessary only on Kernel version older than `5.11` .\nFrom version `5.11` onwards native `overlayfs` is supported and reports noticeable\ngains in performance as explained [HERE](https://www.redhat.com/sysadmin/podman-rootless-overlay)\n\n## Permission problems when using VirtualBox\n\nIf you have VirtualBox installed on your host, you may encounter some permission\nproblems using **rootless Podman**:\n\n```log\nError: unable to start container \"XYZ\": runc: runc create failed: unable to start container process: error during container init: error mounting \"/dev/vboxusb/002/005\" to rootfs at \"/dev/vboxusb/002/005\": lstat /..../dev/vboxusb/002: permission denied: OCI permission denied\n```\n\nThis is because a rootless container done with `runc` will not port the host's groups\ninto the container.\n\nThe solution is to install `crun` from your package manager, and recreate your container.\n\ncrun supports the flag\n\n```sh\nrun.oci.keep_original_groups=1\n```\n\nWhich will allow porting the host's group inside the container, thus making it possible\nfor the rootless container to read vbox files.\n\n## Container save and restore\n\nTo save, export and reuse an already configured container, you can leverage\n`podman save` or `docker save` and `podman import` or `docker import` to\ncreate snapshots of your environment.\n\n---\n\nTo save a container to an image:\n\nwith podman:\n\n```sh\npodman container commit -p distrobox_name image_name_you_choose\npodman save image_name_you_choose:latest | bzip2 > image_name_you_choose.tar.bz\n```\n\nwith docker:\n\n```sh\ndocker container commit -p distrobox_name image_name_you_choose\ndocker save image_name_you_choose:latest | gzip > image_name_you_choose.tar.gz\n```\n\nThis will create a tar.gz of the container of your choice at that exact moment.\n\n---\n\nNow you can backup that archive or transfer it to another host, and to restore it\njust run\n\n```sh\npodman load < image_name_you_choose.tar.bz2\n```\n\nor\n\n```sh\ndocker load < image_name_you_choose.tar.gz\n```\n\nAnd create a new container based on that image:\n\n```sh\ndistrobox create --image image_name_you_choose:latest --name distrobox_name\ndistrobox enter --name distrobox_name\n```\n\nAnd you're good to go, now you can reproduce your personal environment everywhere\nin simple (and scriptable) steps.\n\n## Check used resources\n\n- You can always check how much space a `distrobox` is taking by using `podman` command:\n\n`podman system df -v` or `docker system df -v`\n\n## Pre-installing additional package repositories\n\nOn Red Hat Enterprise Linux and its derivatives, the amount of packages in the\nbase repositories is limited, and additional packages need to be brought in by\nenabling additional repositories such as [EPEL](https://docs.fedoraproject.org/en-US/epel/).\n\nYou can use `--init-hooks` to automate this, but this does not solve the\nissue for package installations done during initialization itself, e.g. if\nthe shell you use on the host is not available in the default repos (e.g.\n`fish`).\n\nUse the pre-initialization hooks for this:\n\n```shell\ndistrobox create -i docker.io/almalinux/8-init --init --name test --pre-init-hooks \"dnf -y install dnf-plugins-core && dnf config-manager --enable powertools && dnf -y install epel-release\"\n```\n\n```shell\ndistrobox create -i docker.io/library/almalinux:9 -n alma9 --pre-init-hooks \"dnf -y install dnf-plugins-core && dnf config-manager --enable crb && dnf -y install epel-release\"\n```\n\n```shell\ndistrobox create -i quay.io/centos/centos:stream9 c9s --pre-init-hooks \"dnf -y install dnf-plugins-core && dnf config-manager --enable crb && dnf -y install epel-next-release\"\n```\n\n## Apply resource limitation on the fly\n\nPodman has `--cpuset-cpus` and `--memory` flags to apply limitation on how much resources a container can use. However,\nthese flags only work during container creation (`podman create` / `podman run`) and not after it's created\n(`podman exec`, which is used by Distrobox to execute commands inside of container), which means changing resource\nlimitation requires recreation of a container.\n\nNonetheless you can still apply resource limitation using systemd's resource control functionality. It's not recommended\nto pass resource limitation arguments (e.g. `--cpuset-cpus` and `--memory`) to `distrobox create --additional-flags`\nas systemd already provides much more flexible resource control functionality.\n\nTo list all distroboxes and their full IDs:\n\n```bash\npodman ps --all --no-trunc --format \"{{.Names}} {{.ID}} {{.Labels}}\" | grep \"manager:distrobox\" | cut -d \" \" -f1,2 | column -t\n```\n\n- Removing `--all` flag will cause the output to only contain currently running distroboxes\n\nTo check your container status with `systemctl`:\n\n```bash\nsystemctl --user status libpod-$UUID.scope\n```\n\n- Your distrobox needs to be running for its scope to present (e.g. `distrobox enter` before running this command)\n- Replace `$UUID` with your container's real full ID\n- To make things easier when tweaking properties, optionally set a environment variable for the current shell:\n\n  bash/zsh:\n\n  ```bash\n  UUID=XXXXXXXXX\n  ```\n  \n  fish:\n\n  ```fish\n  set UUID XXXXXXXXX\n  ```\n\nEverything provided by `systemd.resource-control` could be applied to your distrobox. For example:\n\nTo make your distrobox only run on CPU0 and CPU1:\n\n```bash\nsystemctl --user set-property libpod-$UUID.scope AllowedCPUs=0,1\n```\n\nTo hard throttle your distrobox to not use above 20% of CPU:\n\n```bash\nsystemctl --user set-property libpod-$UUID.scope CPUQuota=20%\n```\n\nTo limit your distrobox's maximum amount of memory:\n\n```bash\nsystemctl --user set-property libpod-$UUID.scope MemoryMax=2G\n```\n\nTo give your distrobox less IO bandwidth when IO is overloaded:\n\n```bash\nsystemctl --user set-property libpod-$UUID.scope IOWeight=1\n```\n\n- `IOWeight` accepts value from `1` to `10000`, higher means more bandwidth.\n\nTo see all applicable properties:\n\n```bash\nman systemd.resource-control\n```\n\nChanges are transient, meaning you lose the resource limitation properties when distrobox is stopped and restarted.\n\nTo make certain changes persistent, first check the currently active properties:\n\n```bash\nsystemctl --user status libpod-$UUID.scope\n```\n\nLook for the `Drop-In` lines. Something like this should be shown:\n\n```console\n    Drop-In: /run/user/1000/systemd/transient/libpod-45ae38d61c9a636230b2ba89ea07792d662e01cd9ee38d04feb0a994b039a271.scope.d\n             └─50-AllowedCPUs.conf\n```\n\nMove the transient overrides to persistent overrides:\n\n```bash\nmkdir -p ~/.config/systemd/user/libpod-$UUID.scope.d\nmv --target-directory=\"$HOME/.config/systemd/user/libpod-$UUID.scope.d\" \\\n  \"/run/user/$(id -u)/systemd/transient/libpod-$UUID.scope.d/50-AllowedCPUs.conf\"\n```\n\n- Replace `$(id -u)` with your real user id if it did not get expanded properly.\n- `50-AllowedCPUs.conf` is only an example. Replace it with something you want to keep persistently.\n\nThen reload systemd daemon to apply the changes:\n\n```bash\nsystemctl --user daemon-reload\n```\n\n## Copy text to host clipboard\n\nTo copy/yank text from the container to the host clipboard you need to install\n`xsel` in the container for Xorg hosts or `wlroots` for wayland hosts.\n"
  },
  {
    "path": "extras/distrobox-example-manifest.ini",
    "content": "# This is an example assemble file to show how options are laid out\n# You generally have a section header, followed by options so:\n#\n# [name-of-your-container]\n# additional_flags=\"\"\n# additional_packages=\"\"\n# entry=\"\"\n# home=\"\"\n# image=\"\"\n# start_now=\"\"\n# init=\"\"\n# init_hooks=\"\"\n# nvidia=\"\"\n# pre_init_hooks=\"\"\n# pull=\"\"\n# root=\"\"\n# unshare_ipc=\"\"\n# unshare_netns=\"\"\n# volume=\"\"\n#\n###############################################################################\n\n[ generic1]\nunshare_netns=true\nunshare_ipc=true\n\n# This is a comment!\n# you can put them how you like\n\n[generic2]\n# Comment\nadditional_packages=\"git vim tmux\"\n# this will enable nvidia driver integration\nnvidia=true\n\n[generic3] # Comment also here\nadditional_packages=\"git vim tmux\" # Comment\nhome=/tmp/home\n\n[arch]\nadditional_packages=\"git vim tmux nodejs\"\n# lines with spaces, wants quotes\nhome=/tmp/home\nimage=archlinux:latest\ninit=false\ninit_hooks=\"touch /init-normal\"\npre_init_hooks=\"touch /pre-init\"\npull=true\nroot=false\nvolume=/tmp/test:/run/a /tmp/test:/run/b\nunshare_netns=true\nunshare_ipc=true\n# We can choose to start the container immediately, it's off by default\nstart_now=true\n\n###############################################################################\n# A more complex example now\n##############################################################################\n[tumbleweed_distrobox]\nimage=registry.opensuse.org/opensuse/distrobox\npull=true\n# Basic utilities for terminal use\nadditional_packages=\"acpi bash-completion findutils iproute iputils sensors inotify-tools unzip\"\nadditional_packages=\"net-tools nmap openssl procps psmisc rsync man tig tmux tree vim htop xclip yt-dlp\"\n# Development packages\nadditional_packages=\"git git-credential-libsecret\"\nadditional_packages=\"patterns-devel-base-devel_basis\"\nadditional_packages=\"ShellCheck ansible-lint clang clang-tools codespell ctags desktop-file-utils gcc golang jq python3\"\nadditional_packages=\"python3-bashate python3-flake8 python3-mypy python3-pipx python3-pycodestyle python3-pyflakes python3-pylint python3-python-lsp-server python3-rstcheck python3-yapf python3-yamllint rustup shfmt\"\n# Gotta work\nadditional_packages=\"kubernetes-client helm\"\n# Setup golang stuff\ninit_hooks=GOPATH=\"${HOME}/.local/share/system-go\" GOBIN=/usr/local/bin go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest;\ninit_hooks=GOPATH=\"${HOME}/.local/share/system-go\" GOBIN=/usr/local/bin go install github.com/onsi/ginkgo/v2/ginkgo@latest;\ninit_hooks=GOPATH=\"${HOME}/.local/share/system-go\" GOBIN=/usr/local/bin go install golang.org/x/tools/cmd/goimports@latest;\ninit_hooks=GOPATH=\"${HOME}/.local/share/system-go\" GOBIN=/usr/local/bin go install golang.org/x/tools/gopls@latest;\ninit_hooks=GOPATH=\"${HOME}/.local/share/system-go\" GOBIN=/usr/local/bin go install sigs.k8s.io/kind@latest;\n# Add some useful commands from host, to the guest\ninit_hooks=ln -sf /usr/bin/distrobox-host-exec /usr/local/bin/conmon;\ninit_hooks=ln -sf /usr/bin/distrobox-host-exec /usr/local/bin/crun;\ninit_hooks=ln -sf /usr/bin/distrobox-host-exec /usr/local/bin/docker;\ninit_hooks=ln -sf /usr/bin/distrobox-host-exec /usr/local/bin/docker-compose;\ninit_hooks=ln -sf /usr/bin/distrobox-host-exec /usr/local/bin/flatpak;\ninit_hooks=ln -sf /usr/bin/distrobox-host-exec /usr/local/bin/podman;\ninit_hooks=ln -sf /usr/bin/distrobox-host-exec /usr/local/bin/xdg-open;\nexported_apps=\"htop\"\nexported_bins=\"/usr/bin/htop /usr/bin/git\"\nexported_bins_path=\"~/.local/bin\"\n"
  },
  {
    "path": "extras/docker-host",
    "content": "#!/bin/sh\n\nid=\"$(echo \"$@\" | grep -Eo ' [a-zA-Z0-9]{64} ' | tr -d ' ')\"\nDOCKER_COMMAND=\"$(command -v docker 2> /dev/null)\"\nENV_COMMAND=\"printenv\"\n\n# if we're in a flatpak, we fallback to host-spawn\nif [ -n \"${FLATPAK_ID}\" ]; then\n\tDOCKER_COMMAND=\"flatpak-spawn --host docker\"\n\tENV_COMMAND=\"flatpak-spawn --host printenv\"\nfi\n\n# This little workaround is used to ensure\n# we use our distrobox to properly enter the container\nif echo \"$@\" | grep -q 'exec'; then\n\t# we do this procedure only for distroboxes\n\t# we will leave regular containers alone.\n\tif [ \"$(${DOCKER_COMMAND} inspect --type container --format '{{ index .Config.Labels \"manager\" }}' \"${id}\")\" = \"distrobox\" ]; then\n\n\t\t# Ensure that our distrobox containers will use different vscode-servers\n\t\t# by symlinking to different paths\n\t\t# This is necessary because vscode-server will always use $HOME/.vscode-server\n\t\t# so we're forced to do this workaround\n\t\tif [ -n \"${id}\" ]; then\n\t\t\t# shellcheck disable=SC2016\n\t\t\t${DOCKER_COMMAND} exec -u \"${USER}\" \"${id}\" /bin/sh -c '\n\t\t\tif [ ! -L \"${HOME}/.vscode-server\" ]; then\n\t\t\t\t[ -e \"${HOME}/.vscode-server\" ] && mv \"${HOME}/.vscode-server\" /var/tmp\n\t\t\t\t[ -d /var/tmp/.vscode-server ] || mkdir /var/tmp/.vscode-server\n\t\t\t\tln -sf /var/tmp/.vscode-server \"$HOME\"\n\t\t\telif [ ! -e \"${HOME}/.vscode-server\" ]; then\n\t\t\t\tmkdir /var/tmp/.vscode-server\n\t\t\t\tln -sf /var/tmp/.vscode-server \"$HOME\"\n\t\t\tfi\n\t\t'\n\t\tfi\n\n\t\tfor i; do\n\t\t\t# interject root:root, we want to be our own user\n\t\t\tif echo \"${i}\" | grep -q \"root:root\"; then\n\t\t\t\tset -- \"$@\" \"${USER}:${USER}\"\n\t\t\t\tshift\n\t\t\t# inject host's environment\n\t\t\telif echo \"${i}\" | grep -q \"exec\"; then\n\t\t\t\tset -- \"$@\" \"exec\"\n\t\t\t\tshift\n\t\t\t\t# inject host's environment\n\t\t\t\tfor j in $(${ENV_COMMAND} | grep '=' | grep -Ev ' |\"|`|\\$' |\n\t\t\t\t\t# refer to distrobox-enter:L454\n\t\t\t\t\tgrep -Ev '^(CONTAINER_ID|HOST|HOSTNAME|HOME|PATH|PROFILEREAD|SHELL|XDG_SEAT|XDG_VTNR|XDG_.*_DIRS|^_)'); do\n\n\t\t\t\t\tset -- \"$@\" \"--env\"\n\t\t\t\t\tset -- \"$@\" \"${j}\"\n\t\t\t\tdone\n\t\t\telse\n\t\t\t\tset -- \"$@\" \"${i}\"\n\t\t\t\tshift\n\t\t\tfi\n\t\tdone\n\tfi\nfi\n\n${DOCKER_COMMAND} \"$@\"\n"
  },
  {
    "path": "extras/install-podman",
    "content": "#!/bin/sh\n# SPDX-License-Identifier: GPL-3.0-only\n#\n# This file is part of the distrobox project: https://github.com/89luca89/distrobox\n#\n# Copyright (C) 2021 distrobox contributors\n#\n# distrobox is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 3\n# as published by the Free Software Foundation.\n#\n# distrobox is distributed in the hope that it will be useful, but\n# WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n# General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with distrobox; if not, see <http://www.gnu.org/licenses/>.\n\n# POSIX\n\necho \"This script is deprecated and unsupported\"\necho \"head over to:\"\necho \"\"\necho \"https://github.com/89luca89/distrobox/blob/main/docs/posts/install_podman_static.md\"\necho \"or\"\necho \"https://github.com/89luca89/distrobox/blob/main/docs/posts/install_lilipod_static.md\"\necho \"\"\necho \"for updated instructions on how to install podman-launcher\"\n\nexit 1\n"
  },
  {
    "path": "extras/podman-host",
    "content": "#!/bin/sh\n\nid=\"$(echo \"$@\" | grep -Eo ' [a-zA-Z0-9]{64} ' | tr -d ' ')\"\nPODMAN_COMMAND=\"$(command -v podman 2> /dev/null)\"\nENV_COMMAND=\"printenv\"\n\n# if we're in a flatpak, we fallback to host-spawn\nif [ -n \"${FLATPAK_ID}\" ]; then\n\tPODMAN_COMMAND=\"flatpak-spawn --host podman\"\n\tENV_COMMAND=\"flatpak-spawn --host printenv\"\nfi\n\n# This little workaround is used to ensure\n# we use our distrobox to properly enter the container\nif echo \"$@\" | grep -q 'exec'; then\n\t# we do this procedure only for distroboxes\n\t# we will leave regular containers alone.\n\tif [ \"$(${PODMAN_COMMAND} inspect --type container --format '{{ index .Config.Labels \"manager\" }}' \"${id}\")\" = \"distrobox\" ]; then\n\n\t\t# Ensure that our distrobox containers will use different vscode-servers\n\t\t# by symlinking to different paths\n\t\t# This is necessary because vscode-server will always use $HOME/.vscode-server\n\t\t# so we're forced to do this workaround\n\t\tif [ -n \"${id}\" ]; then\n\t\t\t# shellcheck disable=SC2016\n\t\t\t${PODMAN_COMMAND} exec -u \"${USER}\" \"${id}\" /bin/sh -c '\n\t\t\tif [ ! -L \"${HOME}/.vscode-server\" ]; then\n\t\t\t\t[ -e \"${HOME}/.vscode-server\" ] && mv \"${HOME}/.vscode-server\" /var/tmp\n\t\t\t\t[ -d /var/tmp/.vscode-server ] || mkdir /var/tmp/.vscode-server\n\t\t\t\tln -sf /var/tmp/.vscode-server \"$HOME\"\n\t\t\telif [ ! -e \"${HOME}/.vscode-server\" ]; then\n\t\t\t\tmkdir /var/tmp/.vscode-server\n\t\t\t\tln -sf /var/tmp/.vscode-server \"$HOME\"\n\t\t\tfi\n\t\t'\n\t\tfi\n\n\t\tfor i; do\n\t\t\t# interject root:root, we want to be our own user\n\t\t\tif echo \"${i}\" | grep -q \"root:root\"; then\n\t\t\t\tset -- \"$@\" \"${USER}:${USER}\"\n\t\t\t\tshift\n\t\t\t# inject host's environment\n\t\t\telif echo \"${i}\" | grep -q \"exec\"; then\n\t\t\t\tset -- \"$@\" \"exec\"\n\t\t\t\tshift\n\t\t\t\t# inject host's environment\n\t\t\t\tfor j in $(${ENV_COMMAND} | grep '=' | grep -Ev ' |\"|`|\\$' |\n\t\t\t\t\t# refer to distrobox-enter:L454\n\t\t\t\t\tgrep -Ev '^(CONTAINER_ID|HOST|HOSTNAME|HOME|PATH|PROFILEREAD|SHELL|XDG_SEAT|XDG_VTNR|XDG_.*_DIRS|^_)'); do\n\n\t\t\t\t\tset -- \"$@\" \"--env\"\n\t\t\t\t\tset -- \"$@\" \"${j}\"\n\t\t\t\tdone\n\t\t\telse\n\t\t\t\tset -- \"$@\" \"${i}\"\n\t\t\t\tshift\n\t\t\tfi\n\t\tdone\n\tfi\nfi\n\n${PODMAN_COMMAND} \"$@\"\n"
  },
  {
    "path": "extras/vscode-distrobox",
    "content": "#!/bin/sh\n\ncontainer_name=\"$(printf '{\"containerName\":\"%s\"}' \"$1\" | od -A n -t x1 | tr -d \"\\n\\t \")\"\n\nif command -v code 2> /dev/null > /dev/null; then\n\tcode_command=\"code\"\nelif flatpak list | grep -q com.visualstudio.code; then\n\tcode_command=\"flatpak run com.visualstudio.code\"\nelse\n\techo \"vscode not installed\"\n\texit 127\nfi\n\n${code_command} --folder-uri=\"vscode-remote://attached-container+${container_name}/$(realpath \"${2}\")\"\n"
  },
  {
    "path": "install",
    "content": "#!/bin/sh\n# SPDX-License-Identifier: GPL-3.0-only\n#\n# This file is part of the distrobox project: https://github.com/89luca89/distrobox\n#\n# Copyright (C) 2021 distrobox contributors\n#\n# distrobox is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 3\n# as published by the Free Software Foundation.\n#\n# distrobox is distributed in the hope that it will be useful, but\n# WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n# General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with distrobox; if not, see <http://www.gnu.org/licenses/>.\n\n# POSIX\n\nnext=0\nno_color=0\nverbose=0\nversion=1.8.2.4\n\n# show_help will print usage to stdout.\n# Arguments:\n#   None\n# Outputs:\n#   print usage with examples.\nshow_help()\n{\n\tcat << EOF\ninstall --prefix /usr/local\n\nOptions:\n\t--prefix/-P:\t\tbase bath where all files will be deployed (default /usr/local if root, ~/.local if not)\n\t--next/-N:\t\tinstall latest development version from git, instead of the latest stable release.\n\t--no-color:\t\tdisable color formatting\n\t--help/-h:\t\tshow this message\n\t-v:\t\t\tshow more verbosity\nEOF\n}\n\n# Parse arguments\nwhile :; do\n\tcase $1 in\n\t\t-h | --help)\n\t\t\t# Call a \"show_help\" function to display a synopsis, then exit.\n\t\t\tshow_help\n\t\t\texit\n\t\t\t;;\n\t\t--no-color)\n\t\t\tshift\n\t\t\tno_color=1\n\t\t\t;;\n\t\t-v | --verbose)\n\t\t\tshift\n\t\t\tverbose=1\n\t\t\t;;\n\t\t-N | --next)\n\t\t\tshift\n\t\t\tnext=1\n\t\t\t;;\n\t\t-P | --prefix)\n\t\t\tif [ -n \"$2\" ]; then\n\t\t\t\tprefix=\"$2\"\n\t\t\t\tshift\n\t\t\t\tshift\n\t\t\tfi\n\t\t\t;;\n\t\t*) # Default case: If no more options then break out of the loop.\n\t\t\tbreak ;;\n\tesac\ndone\n\n# if we're in not a tty, don't use colors\nBOLD_GREEN=\"\"\nBOLD_RED=\"\"\nCLEAR=\"\"\nif [ -t 0 ] && [ -t 1 ] && [ \"${no_color}\" -ne 1 ]; then\n\t# we're in a tty, use colors\n\tBOLD_GREEN='\\033[1;32m'\n\tBOLD_RED='\\033[1;31m'\n\tCLEAR='\\033[0m'\nfi\n\nif  [ -z \"${prefix}\" ]; then\n\tprefix=\"/usr/local\"\n\t# in case we're not root, just default to the home directory\n\tif [ \"$(id -u)\" -ne 0 ]; then\n\t\tprefix=\"${HOME}/.local\"\n\tfi\nfi\ndest_path=\"${prefix}/bin\"\nman_dest_path=\"${prefix}/share/man/man1\"\nicon_dest_path=\"${prefix}/share/icons/hicolor\"\ncompletion_bash_dest_path=\"${prefix}/share/bash-completion/completions/\"\ncompletion_zsh_dest_path=\"${prefix}/share/zsh/site-functions/\"\n\nset -o errexit\nset -o nounset\n# set verbosity\nif [ \"${verbose}\" -ne 0 ]; then\n\tset -o xtrace\nfi\n\n# get current dir\ncurr_dir=$(dirname \"$0\")\ncd \"${curr_dir}\" || exit 1\n\n# if files are available, install files in dest directory\n# else download targz and uncompress it\nif [ -e \"${curr_dir}/distrobox-enter\" ]; then\n\tif ! install -d \"${dest_path}\" \"${man_dest_path}\" \"${completion_bash_dest_path}\" \\\n\t\t\"${completion_zsh_dest_path}\" \"${icon_dest_path}/scalable/apps\"; then\n\t\tprintf >&2 \"Do you have permission to write to %s?\\n\" \"${prefix}\"\n\t\texit 1\n\tfi\n\tfor file in distrobox*; do\n\t\tif ! install -m 0755 \"${file}\" \"${dest_path}\"; then\n\t\t\tprintf >&2 \"Do you have permission to write to %s?\\n\" \"${dest_path}\"\n\t\t\texit 1\n\t\tfi\n\tdone\n\tif [ -e \"man\" ]; then\n\t\tfor file in man/man1/*; do\n\t\t\tinstall -m 0644 \"${file}\" \"${man_dest_path}\"\n\t\tdone\n\tfi\n\tif [ -e \"completions\" ]; then\n\t\tfor file in completions/bash/*; do\n\t\t\tinstall -m 0644 \"${file}\" \"${completion_bash_dest_path}\"\n\t\tdone\n\tfi\n\tif [ -e \"completions\" ]; then\n\t\tfor file in completions/zsh/*; do\n\t\t\tinstall -m 0644 \"${file}\" \"${completion_zsh_dest_path}\"\n\t\tdone\n\tfi\n\tif [ -e icons/terminal-distrobox-icon.svg ]; then\n\t\tinstall -m 0644 icons/terminal-distrobox-icon.svg \"${icon_dest_path}/scalable/apps\"\n\t\tfor sz in 16 22 24 32 36 48 64 72 96 128 256; do\n\t\t\tinstall -d \"${icon_dest_path}/${sz}x${sz}/apps\"\n\t\t\tinstall -m 0644 icons/hicolor/\"${sz}x${sz}\"/apps/terminal-distrobox-icon.png \\\n\t\t\t\t\"${icon_dest_path}/${sz}x${sz}/apps\"\n\t\tdone\n\tfi\nelse\n\tprintf >&2 \"%b Checking dependencies...\\n%b\" \"${BOLD_GREEN}\" \"${CLEAR}\"\n\t# check that we have base dependencies\n\tif ! {\n\t\tcommand -v curl > /dev/null || command -v wget > /dev/null\n\t} || ! command -v tar > /dev/null; then\n\t\tprintf >&2 \"Online install depends on tar and either curl or wget\\n\"\n\t\tprintf >&2 \"Ensure you have all dependencies installed.\\n\"\n\t\texit 1\n\tfi\n\n\tif command -v curl > /dev/null 2>&1; then\n\t\tdownload=\"curl -sLo\"\n\telif command -v wget > /dev/null 2>&1; then\n\t\tdownload=\"wget -qO\"\n\tfi\n\n\tprintf >&2 \"%b Downloading...\\n%b\" \"${BOLD_RED}\" \"${CLEAR}\"\n\tif [ \"${next}\" -eq 0 ]; then\n\t\trelease_ver=\"89luca89/distrobox/archive/refs/tags/${version}.tar.gz\"\n\t\trelease_name=$(basename \"${release_ver}\")\n\telse\n\t\trelease_ver=\"89luca89/distrobox/archive/refs/heads/main.tar.gz\"\n\t\trelease_name=\"main\"\n\tfi\n\t# go in tmp\n\ttmp_dir=\"$(mktemp -d)\"\n\tcd \"${tmp_dir}\"\n\t# download our target\n\t${download} \"${release_name}\" \"https://github.com/${release_ver}\"\n\t# uncompress\n\tprintf >&2 \"%b Unpacking...\\n%b\" \"${BOLD_RED}\" \"${CLEAR}\"\n\tif [ \"${verbose}\" -ne 0 ]; then\n\t\ttar xvf \"${release_name}\"\n\telse\n\t\ttar xf \"${release_name}\"\n\tfi\n\t# deploy our files\n\tif ! install -d \"${dest_path}\" \"${man_dest_path}\" \"${completion_bash_dest_path}\" \\\n\t\t\"${completion_zsh_dest_path}\" \"${icon_dest_path}/scalable/apps\"; then\n\t\tprintf >&2 \"Do you have permission to write to %s?\\n\" \"${prefix}\"\n\t\texit 1\n\tfi\n\tfor file in \"distrobox-$(echo \"${release_name}\" | sed 's/.tar.gz//g')\"/distrobox*; do\n\t\tif ! install -m 0755 \"${file}\" \"${dest_path}\"; then\n\t\t\tprintf >&2 \"Do you have permission to write to %s?\\n\" \"${dest_path}\"\n\t\t\texit 1\n\t\tfi\n\tdone\n\tif [ -e \"distrobox-$(echo \"${release_name}\" | sed 's/.tar.gz//g')/man/\" ]; then\n\t\tfor file in \"distrobox-$(echo \"${release_name}\" | sed 's/.tar.gz//g')\"/man/man1/*; do\n\t\t\tinstall -m 0644 \"${file}\" \"${man_dest_path}\"\n\t\tdone\n\tfi\n\tif [ -e \"distrobox-$(echo \"${release_name}\" | sed 's/.tar.gz//g')/completions/bash/\" ]; then\n\t\tfor file in \"distrobox-$(echo \"${release_name}\" | sed 's/.tar.gz//g')\"/completions/bash/*; do\n\t\t\tinstall -m 0644 \"${file}\" \"${completion_bash_dest_path}\"\n\t\tdone\n\tfi\n\tif [ -e \"distrobox-$(echo \"${release_name}\" | sed 's/.tar.gz//g')/completions/zsh/\" ]; then\n\t\tfor file in \"distrobox-$(echo \"${release_name}\" | sed 's/.tar.gz//g')\"/completions/zsh/*; do\n\t\t\tinstall -m 0644 \"${file}\" \"${completion_zsh_dest_path}\"\n\t\tdone\n\tfi\n\tif [ -e \"distrobox-$(echo \"${release_name}\" | sed 's/.tar.gz//g')\"/icons/terminal-distrobox-icon.svg ]; then\n\t\tinstall -m 0644 \"distrobox-$(echo \"${release_name}\" | sed 's/.tar.gz//g')\"/icons/terminal-distrobox-icon.svg \\\n\t\t\t\"${icon_dest_path}/scalable/apps\"\n\t\tfor sz in 16 22 24 32 36 48 64 72 96 128 256; do\n\t\t\tinstall -d \"${icon_dest_path}/${sz}x${sz}/apps\"\n\t\t\tinstall -m 0644 \"distrobox-$(echo \"${release_name}\" | sed 's/.tar.gz//g')/icons/hicolor/${sz}x${sz}/apps/terminal-distrobox-icon.png\" \\\n\t\t\t\t\"${icon_dest_path}/${sz}x${sz}/apps\"\n\t\tdone\n\tfi\n\n\t# securely delete unneeded files\n\tcd\n\tif [ -n \"${tmp_dir}\" ] && [ -e \"${tmp_dir}\" ]; then\n\t\trm -rf \"${tmp_dir}\"\n\tfi\nfi\n\n[ ! -w \"${dest_path}\" ] && printf >&2 \"Cannot write into %s, permission denied.\\n\" \"${dest_path}\" && exit 1\n[ ! -w \"${man_dest_path}\" ] && printf >&2 \"Cannot write into %s, permission denied.\\n\" \"${man_dest_path}\" && exit 1\n\nprintf >&2 \"%b Installation successful!\\n%b\" \"${BOLD_GREEN}\" \"${CLEAR}\"\nprintf >&2 \"%b Shell scripts are located in %b%s\\n%b\" \"${CLEAR}\" \"${BOLD_RED}\" \"${dest_path}\" \"${CLEAR}\"\nprintf >&2 \"%b Manpages are located in %b%s\\n%b\" \"${CLEAR}\" \"${BOLD_RED}\" \"${man_dest_path}\" \"${CLEAR}\"\n\nif ! echo \"${PATH}\" | grep -q \"${dest_path}\"; then\n\tprintf >&2 \"%b Be sure that %b%s%b is in your %b\\$PATH%b environment variable to be able to use distrobox without specifying the full path.\\n%s\" \"${CLEAR}\" \"${BOLD_RED}\" \"${dest_path}\" \"${CLEAR}\" \"${BOLD_RED}\" \"${CLEAR}\" \"${CLEAR}\"\nfi\n"
  },
  {
    "path": "man/gen-man",
    "content": "#!/bin/sh\n\nif ! command -v pandoc; then\n\techo '\nPlease install \"pandoc\". This tool is needed to convert markdown to man pages.\nThis tool is needed to convert files under docs/usage into man pages for the\ninstallation.\n'\n\texit 1\nfi\n\nfor i in \"$(dirname \"${0}\")\"/../docs/usage/distrobox*; do\n\tpandoc --standalone \\\n\t\t--metadata title=\"$(basename \"${i}\" | cut -d'.' -f1 | tr '[:lower:]' '[:upper:]')\" \\\n\t\t--metadata section=1 \\\n\t\t--metadata header=\"User Manual\" \\\n\t\t--metadata footer=\"Distrobox\" \\\n\t\t--metadata date=\"$(date +\"%b %Y\")\" \\\n\t\t--to man \"${i}\" \\\n\t\t-o \"$(dirname \"${0}\")\"/man1/out\n\tsed -i 's|\\\" Automatically generated by Pandoc.*||g' \"$(dirname \"${0}\")\"/man1/out\n\tmv \"$(dirname \"${0}\")/man1/out\" \"$(dirname \"${0}\")/man1/$(basename \"${i}\" | sed 's|md|1|g')\"\ndone\n\ncompatibility_file=\"$(mktemp --suffix='.md')\"\nHEAD=\"$(grep -n -B1 \"^# Compatibility\" \"$(dirname \"${0}\")/../docs/compatibility.md\" | head -1 | tr -d '-')\"\nSTART=\"$(grep -n \"# Host Distros\" \"$(dirname \"${0}\")/../docs/compatibility.md\" | cut -d\":\" -f1)\"\nEND=\"$(grep -n -B1 \"# Containers Distros\" \"$(dirname \"${0}\")/../docs/compatibility.md\" | head -1 | tr -d '-')\"\n\nsed -e \"${START},${END}d\" \"$(dirname \"${0}\")/../docs/compatibility.md\" > \"${compatibility_file}\"\nsed -e \"1,${HEAD}d\" -i \"${compatibility_file}\"\nsed -i \"s/^#.*/\\U&/g\" \"${compatibility_file}\"\n\npandoc --standalone \\\n\t--metadata title=\"DISTROBOX\" \\\n\t--metadata section=1 \\\n\t--metadata header=\"User Manual\" \\\n\t--metadata footer=\"Distrobox\" \\\n\t--metadata date=\"$(date +\"%b %Y\")\" \\\n\t--to man \"${compatibility_file}\" \\\n\t-o \"$(dirname \"${0}\")\"/man1/out\nsed -i 's|\\\" Automatically generated by Pandoc.*||g' \"$(dirname \"${0}\")\"/man1/out\nmv \"$(dirname \"${0}\")\"/man1/out \"$(dirname \"${0}\")\"/man1/distrobox-compatibility.1\n\ncat \"$(dirname \"${0}\")/man1/distrobox-\"* > \"$(dirname \"${0}\")/man1/distrobox.1\"\n"
  },
  {
    "path": "man/man1/distrobox-assemble.1",
    "content": "'\\\" t\n.\\\n.\\\"\n.TH \"DISTROBOX\\-ASSEMBLE\" \"1\" \"Mar 2026\" \"Distrobox\" \"User Manual\"\n.SH NAME\n.IP\n.EX\ndistrobox assemble\ndistrobox\\-assemble\n.EE\n.SH DESCRIPTION\ndistrobox\\-assemble takes care of creating or destroying containers in\nbatches, based on a manifest file.\nThe manifest file by default is \\f[CR]./distrobox.ini\\f[R], but can be\nspecified using the \\f[CR]\\-\\-file\\f[R] flag.\n.SH SYNOPSIS\n\\f[B]distrobox assemble\\f[R]\n.IP\n.EX\n\\-\\-file:         path or URL to the distrobox manifest/ini file\n\\-\\-name/\\-n:      run against a single entry in the manifest/ini file\n\\-\\-replace/\\-R:       replace already existing distroboxes with matching names\n\\-\\-dry\\-run/\\-d:       only print the container manager command generated\n\\-\\-verbose/\\-v:       show more verbosity\n\\-\\-version/\\-V:       show version\n.EE\n.SH EXAMPLES\nThis is an example manifest file to create two containers:\n.IP\n.EX\n[ubuntu]\nadditional_packages=\\[dq]git vim tmux nodejs\\[dq]\nimage=ubuntu:latest\ninit=false\nnvidia=false\npull=true\nroot=false\nreplace=true\nstart_now=false\n\n# You can add comments using this #\n[arch] # also inline comments are supported\nadditional_packages=\\[dq]git vim tmux nodejs\\[dq]\nhome=/tmp/home\nimage=archlinux:latest\ninit=false\nstart_now=true\ninit_hooks=\\[dq]touch /init\\-normal\\[dq]\nnvidia=true\npre_init_hooks=\\[dq]touch /pre\\-init\\[dq]\npull=true\nroot=false\nreplace=false\nvolume=\\[dq]/tmp/test:/run/a /tmp/test:/run/b\\[dq]\n.EE\n.PP\n\\f[B]Create\\f[R]\n.PP\nWe can bring them up simply using\n.IP\n.EX\ndistrobox assemble create\n.EE\n.PP\nIf the file is called \\f[CR]distrobox.ini\\f[R] and is in the same\ndirectory you\\[cq]re launching the command, no further arguments are\nneeded.\nYou can specify a custom path for the file using\n.IP\n.EX\ndistrobox assemble create \\-\\-file /my/custom/path.ini\n.EE\n.PP\nOr even specify a remote file, by using an URL:\n.IP\n.EX\ndistrobox\\-assemble create \\-\\-file https://raw.githubusercontent.com/89luca89/dotfiles/master/distrobox.ini\n.EE\n.PP\n\\f[B]Replace\\f[R]\n.PP\nBy default, \\f[CR]distrobox assemble\\f[R] will replace a container only\nif \\f[CR]replace=true\\f[R] is specified in the manifest file.\n.PP\nIn the example of the manifest above, the ubuntu container will always\nbe replaced when running \\f[CR]distrobox assemble create\\f[R], while the\narch container will not.\n.PP\nTo force a replace for all containers in a manifest use the\n\\f[CR]\\-\\-replace\\f[R] flag\n.IP\n.EX\ndistrobox assemble create \\-\\-replace [\\-\\-file my/custom/path.ini]\n.EE\n.PP\n\\f[B]Remove\\f[R]\n.PP\nWe can bring down all the containers in a manifest file by simply doing\n.IP\n.EX\ndistrobox assemble rm\n.EE\n.PP\nOr using a custom path for the ini file\n.IP\n.EX\ndistrobox assemble rm \\-\\-file my/custom/path.ini\n.EE\n.PP\n\\f[B]Test\\f[R]\n.PP\nYou can always test what distrobox \\f[B]would do\\f[R] by using the\n\\f[CR]\\-\\-dry\\-run\\f[R] flag.\nThis command will only print what commands distrobox would do without\nactually running them.\n.PP\n\\f[B]Clone\\f[R]\n.PP\n\\f[B]Disclaimer\\f[R]: You need to start the container once to ensure it\nis fully initialized and created before cloning it.\nThe container being copied must also be stopped before the cloning\nprocess can proceed.\n.PP\n\\f[B]Available options\\f[R]\n.PP\nThis is a list of available options with the corresponding type:\n.PP\nTypes legend:\n.IP \\[bu] 2\nbool: true or false\n.IP \\[bu] 2\nstring: a single string, for example\n\\f[CR]home=\\[dq]/home/luca\\-linux/dbox\\[dq]\\f[R]\n.IP \\[bu] 2\nstring_list: multiple strings, for example\n\\f[CR]additional_packages=\\[dq]htop vim git\\[dq]\\f[R].\nNote that \\f[CR]string_list\\f[R] can be declared multiple times to be\ncompounded:\n.RS 2\n.IP\n.EX\n\\f[B][ubuntu]\\f[R]\nimage=ubuntu:latest\nadditional_packages=\\[dq]git vim tmux nodejs\\[dq]\nadditional_packages=\\[dq]htop iftop iotop\\[dq]\nadditional_packages=\\[dq]zsh fish\\[dq]\n.EE\n.RE\n.PP\n.TS\ntab(@);\nlw(23.3n) lw(23.3n) lw(23.3n).\nT{\nFlag Name\nT}@T{\nType\nT}@T{\nT}\n_\nT{\nadditional_flags\nT}@T{\nstring_list\nT}@T{\nAdditional flags to pass to the container manager\nT}\nT{\nadditional_packages\nT}@T{\nstring_list\nT}@T{\nAdditional packages to install inside the container\nT}\nT{\nhome\nT}@T{\nstring\nT}@T{\nWhich home directory should the container use\nT}\nT{\nhostname\nT}@T{\nstring\nT}@T{\nSet hostname of the container\nT}\nT{\nimage\nT}@T{\nstring\nT}@T{\nWhich image should the container use, look here for a list\nT}\nT{\nclone\nT}@T{\nstring\nT}@T{\nName of the Distrobox container to use as the base for a new container\n(the container must be stopped).\nT}\nT{\ninclude\nT}@T{\nstring\nT}@T{\nName of the entry in the manifest to include in the current definition.\nT}\nT{\ninit_hooks\nT}@T{\nstring_list\nT}@T{\nCommands to run inside the container, after the packages setup\nT}\nT{\npre_init_hooks\nT}@T{\nstring_list\nT}@T{\nCommands to run inside the container, before the packages setup\nT}\nT{\nvolume\nT}@T{\nstring_list\nT}@T{\nAdditional volumes to mount inside the containers\nT}\nT{\nexported_apps\nT}@T{\nstring_list\nT}@T{\nApp names or desktopfile paths to export\nT}\nT{\nexported_bins\nT}@T{\nstring_list\nT}@T{\nBinaries to export\nT}\nT{\nexported_bins_path\nT}@T{\nstring\nT}@T{\nOptional path where to export binaries (default: $HOME/.local/bin)\nT}\nT{\nentry\nT}@T{\nbool\nT}@T{\nGenerate an entry for the container in the app list (default: false)\nT}\nT{\nstart_now\nT}@T{\nbool\nT}@T{\nStart the container immediately (default: false)\nT}\nT{\ninit\nT}@T{\nbool\nT}@T{\nSpecify if this is an initful container (default: false)\nT}\nT{\nnvidia\nT}@T{\nbool\nT}@T{\nSpecify if you want to enable NVidia drivers integration (default:\nfalse)\nT}\nT{\npull\nT}@T{\nbool\nT}@T{\nSpecify if you want to pull the image every time (default: false)\nT}\nT{\nroot\nT}@T{\nbool\nT}@T{\nSpecify if the container is rootful (default: false)\nT}\nT{\nunshare_groups\nT}@T{\nbool\nT}@T{\nSpecify if the container should unshare users additional groups\n(default: false)\nT}\nT{\nunshare_ipc\nT}@T{\nbool\nT}@T{\nSpecify if the container should unshare the ipc namespace (default:\nfalse)\nT}\nT{\nunshare_netns\nT}@T{\nbool\nT}@T{\nSpecify if the container should unshare the network namespace (default:\nfalse)\nT}\nT{\nunshare_process\nT}@T{\nbool\nT}@T{\nSpecify if the container should unshare the process (pid) namespace\n(default: false)\nT}\nT{\nunshare_devsys\nT}@T{\nbool\nT}@T{\nSpecify if the container should unshare /dev (default: false)\nT}\nT{\nunshare_all\nT}@T{\nbool\nT}@T{\nSpecify if the container should unshare all the previous options\n(default: false)\nT}\n.TE\n.PP\nThe \\f[CR]include\\f[R] option copies the attributes of a definition into\nanother one.\nRecursive inclusions are allowed.\nIt operates on the manifest file and the consequent \\f[CR]distrobox\\f[R]\ncontainers have no relation of any kind.\nPlease be aware that attributes in the including definition will not\noverride nor shadow the ones in the included definition, they will\nsimply duplicate.\n.PP\nFor further explanation of each of the other options in the list, take a\nlook at the distrobox create usage, each option corresponds to one of\nthe \\f[CR]create\\f[R] flags.\n.PP\n\\f[B]Advanced example\\f[R]\n.IP\n.EX\n[tumbleweed_distrobox]\nimage=registry.opensuse.org/opensuse/distrobox\npull=true\nadditional_packages=\\[dq]acpi bash\\-completion findutils iproute iputils sensors inotify\\-tools unzip\\[dq]\nadditional_packages=\\[dq]net\\-tools nmap openssl procps psmisc rsync man tig tmux tree vim htop xclip yt\\-dlp\\[dq]\nadditional_packages=\\[dq]git git\\-credential\\-libsecret\\[dq]\nadditional_packages=\\[dq]patterns\\-devel\\-base\\-devel_basis\\[dq]\nadditional_packages=\\[dq]ShellCheck ansible\\-lint clang clang\\-tools codespell ctags desktop\\-file\\-utils gcc golang jq python3\\[dq]\nadditional_packages=\\[dq]python3\\-bashate python3\\-flake8 python3\\-mypy python3\\-pipx python3\\-pycodestyle python3\\-pyflakes python3\\-pylint python3\\-python\\-lsp\\-server python3\\-rstcheck python3\\-yapf python3\\-yamllint rustup shfmt\\[dq]\nadditional_packages=\\[dq]kubernetes\\-client helm\\[dq]\ninit_hooks=GOPATH=\\[dq]${HOME}/.local/share/system\\-go\\[dq] GOBIN=/usr/local/bin go install github.com/golangci/golangci\\-lint/cmd/golangci\\-lint\\[at]latest;\ninit_hooks=GOPATH=\\[dq]${HOME}/.local/share/system\\-go\\[dq] GOBIN=/usr/local/bin go install github.com/onsi/ginkgo/v2/ginkgo\\[at]latest;\ninit_hooks=GOPATH=\\[dq]${HOME}/.local/share/system\\-go\\[dq] GOBIN=/usr/local/bin go install golang.org/x/tools/cmd/goimports\\[at]latest;\ninit_hooks=GOPATH=\\[dq]${HOME}/.local/share/system\\-go\\[dq] GOBIN=/usr/local/bin go install golang.org/x/tools/gopls\\[at]latest;\ninit_hooks=GOPATH=\\[dq]${HOME}/.local/share/system\\-go\\[dq] GOBIN=/usr/local/bin go install sigs.k8s.io/kind\\[at]latest;\ninit_hooks=ln \\-sf /usr/bin/distrobox\\-host\\-exec /usr/local/bin/conmon;\ninit_hooks=ln \\-sf /usr/bin/distrobox\\-host\\-exec /usr/local/bin/crun;\ninit_hooks=ln \\-sf /usr/bin/distrobox\\-host\\-exec /usr/local/bin/docker;\ninit_hooks=ln \\-sf /usr/bin/distrobox\\-host\\-exec /usr/local/bin/docker\\-compose;\ninit_hooks=ln \\-sf /usr/bin/distrobox\\-host\\-exec /usr/local/bin/flatpak;\ninit_hooks=ln \\-sf /usr/bin/distrobox\\-host\\-exec /usr/local/bin/podman;\ninit_hooks=ln \\-sf /usr/bin/distrobox\\-host\\-exec /usr/local/bin/xdg\\-open;\nexported_apps=\\[dq]htop\\[dq]\nexported_bins=\\[dq]/usr/bin/htop /usr/bin/git\\[dq]\nexported_bins_path=\\[dq]\\[ti]/.local/bin\\[dq]\n.EE\n.PP\n\\f[B]Clone example\\f[R]\n.IP\n.EX\n[ubuntu]\nadditional_packages=\\[dq]git vim tmux\\[dq]\nimage=ubuntu:latest\ninit=false\nnvidia=false\npull=true\nroot=false\nreplace=true\nstart_now=true\n\n[deno_ubuntu]\nclone=ubuntu\ninit=false\nnvidia=false\npull=true\nroot=false\nreplace=true\nstart_now=true\npre_init_hooks=curl \\-fsSL https://deno.land/install.sh | sh;\n\n[bun_ubuntu]\nclone=ubuntu\ninit=false\nnvidia=false\npull=true\nroot=false\nreplace=true\nstart_now=true\npre_init_hooks=curl \\-fsSL https://bun.sh/install | bash;\n.EE\n.PP\n\\f[B]Custom login shell example\\f[R]\n.IP\n.EX\n[ubuntu]\nimage=ubuntu:latest\npre_init_hooks=\\[dq]export SHELL=/bin/bash;\\[dq]\n.EE\n.PP\n\\f[B]Include example (inherit fields from another distrobox)\\f[R]\n.IP\n.EX\n[ubuntu]\nimage=ubuntu:latest\nadditional_packages=\\[dq]git vim tmux nodejs\\[dq]\nadditional_packages=\\[dq]htop iftop iotop\\[dq]\nadditional_packages=\\[dq]zsh fish\\[dq]\n\n[ubuntu\\-nvidia]\ninclude=ubuntu\nnvidia=true\n.EE\n"
  },
  {
    "path": "man/man1/distrobox-compatibility.1",
    "content": "'\\\" t\n.\\\n.\\\"\n.TH \"DISTROBOX\" \"1\" \"Mar 2026\" \"Distrobox\" \"User Manual\"\n.SH COMPATIBILITY\nThis project \\f[B]does not need a dedicated image\\f[R].\nIt can use any OCI images from docker\\-hub, quay.io, or any registry of\nyour choice.\n.PP\nMany cloud images are stripped down on purpose to save size and may not\ninclude commands such as \\f[CR]which\\f[R], \\f[CR]mount\\f[R],\n\\f[CR]less\\f[R] or \\f[CR]vi\\f[R]).\nAdditional packages can be installed once inside the container.\nWe recommend using your preferred automation tool inside the container\nif you find yourself having to repeatedly create new containers.\nMaintaining your own custom image is also an option.\n.PP\nThe main concern is having basic Linux utilities (\\f[CR]mount\\f[R]),\nbasic user management utilities (\\f[CR]usermod, passwd\\f[R]), and\n\\f[CR]sudo\\f[R] correctly set.\n.SS SUPPORTED CONTAINER MANAGERS\n\\f[CR]distrobox\\f[R] can run on either \\f[CR]podman\\f[R],\n\\f[CR]docker\\f[R] or \\c\n.UR https://github.com/89luca89/lilipod\n\\f[CR]lilipod\\f[R]\n.UE \\c\n.PP\nIt depends either on \\f[CR]podman\\f[R] configured in\n\\f[CR]rootless mode\\f[R] or on \\f[CR]docker\\f[R] configured without sudo\n(follow \\c\n.UR https://docs.docker.com/engine/install/linux-postinstall/\nTHESE instructions\n.UE \\c\n)\n.IP \\[bu] 2\nMinimum podman version: \\f[B]2.1.0\\f[R]\n.IP \\[bu] 2\nMinimum docker client version: \\f[B]19.03.15\\f[R]\n.IP \\[bu] 2\nMinimum lilipod version: \\f[B]v0.0.1\\f[R]\n.PP\nFollow the official installation guide here:\n.IP \\[bu] 2\n\\c\n.UR https://podman.io/getting-started/installation\n.UE \\c\n.IP \\[bu] 2\n\\c\n.UR https://docs.docker.com/engine/install\n.UE \\c\n.IP \\[bu] 2\n\\c\n.UR https://docs.docker.com/engine/install/linux-postinstall/\n.UE \\c\n.SS CONTAINERS DISTROS\nDistrobox guests tested successfully with the following container\nimages:\n.PP\n.TS\ntab(@);\nlw(23.3n) lw(23.3n) lw(23.3n).\nT{\nDistro\nT}@T{\nVersion\nT}@T{\nImages\nT}\n_\nT{\nAlmaLinux (Toolbox)\nT}@T{\n8  9\nT}@T{\nquay.io/toolbx\\-images/almalinux\\-toolbox:8 \nquay.io/toolbx\\-images/almalinux\\-toolbox:9 \nquay.io/toolbx\\-images/almalinux\\-toolbox:latest\nT}\nT{\nAlpine (Toolbox)\nT}@T{\n3.20  3.21  3.22  edge\nT}@T{\nquay.io/toolbx\\-images/alpine\\-toolbox:3.20 \nquay.io/toolbx\\-images/alpine\\-toolbox:3.21 \nquay.io/toolbx\\-images/alpine\\-toolbox:3.22 \nquay.io/toolbx\\-images/alpine\\-toolbox:edge \nquay.io/toolbx\\-images/alpine\\-toolbox:latest\nT}\nT{\nAmazonLinux (Toolbox)\nT}@T{\n2  2022\nT}@T{\nquay.io/toolbx\\-images/amazonlinux\\-toolbox:2 \nquay.io/toolbx\\-images/amazonlinux\\-toolbox:2023 \nquay.io/toolbx\\-images/amazonlinux\\-toolbox:latest\nT}\nT{\nArchlinux (Toolbox)\nT}@T{\nT}@T{\nquay.io/toolbx/arch\\-toolbox:latest\nT}\nT{\nALT Linux\nT}@T{\np10  p11  sisyphus\nT}@T{\ndocker.io/library/alt:p10  docker.io/library/alt:p11 \ndocker.io/library/alt:sisyphus\nT}\nT{\nBazzite Arch\nT}@T{\nT}@T{\nghcr.io/ublue\\-os/bazzite\\-arch:latest \nghcr.io/ublue\\-os/bazzite\\-arch\\-gnome:latest\nT}\nT{\nCentos (Toolbox)\nT}@T{\nstream9  stream10\nT}@T{\nquay.io/toolbx\\-images/centos\\-toolbox:stream9 \nquay.io/toolbx\\-images/centos\\-toolbox:stream10 \nquay.io/toolbx\\-images/centos\\-toolbox:latest\nT}\nT{\nDebian (Toolbox)\nT}@T{\n11  12  13  testing  unstable\nT}@T{\nquay.io/toolbx\\-images/debian\\-toolbox:11 \nquay.io/toolbx\\-images/debian\\-toolbox:12 \nquay.io/toolbx\\-images/debian\\-toolbox:13 \nquay.io/toolbx\\-images/debian\\-toolbox:testing \nquay.io/toolbx\\-images/debian\\-toolbox:unstable \nquay.io/toolbx\\-images/debian\\-toolbox:latest\nT}\nT{\nFedora (Toolbox)\nT}@T{\n38  39  40  41  42  43  Rawhide\nT}@T{\nregistry.fedoraproject.org/fedora\\-toolbox:38 \nregistry.fedoraproject.org/fedora\\-toolbox:39 \nregistry.fedoraproject.org/fedora\\-toolbox:40 \nquay.io/fedora/fedora\\-toolbox:41  quay.io/fedora/fedora\\-toolbox:42 \nquay.io/fedora/fedora\\-toolbox:43 \nquay.io/fedora/fedora\\-toolbox:rawhide\nT}\nT{\nopenSUSE (Toolbox)\nT}@T{\nT}@T{\nregistry.opensuse.org/opensuse/distrobox:latest\nT}\nT{\nRedHat (Toolbox)\nT}@T{\n8  9\nT}@T{\nregistry.access.redhat.com/ubi8/toolbox \nregistry.access.redhat.com/ubi9/toolbox\nT}\nT{\nRocky Linux (Toolbox)\nT}@T{\n8  9\nT}@T{\nquay.io/toolbx\\-images/rockylinux\\-toolbox:8 \nquay.io/toolbx\\-images/rockylinux\\-toolbox:9 \nquay.io/toolbx\\-images/rockylinux\\-toolbox:latest\nT}\nT{\nUbuntu (Toolbox)\nT}@T{\n16.04  18.04  20.04  22.04  24.04\nT}@T{\nquay.io/toolbx/ubuntu\\-toolbox:16.04 \nquay.io/toolbx/ubuntu\\-toolbox:18.04 \nquay.io/toolbx/ubuntu\\-toolbox:20.04 \nquay.io/toolbx/ubuntu\\-toolbox:22.04 \nquay.io/toolbx/ubuntu\\-toolbox:24.04 \nquay.io/toolbx/ubuntu\\-toolbox:latest\nT}\nT{\nChainguard Wolfi (Toolbox)\nT}@T{\nT}@T{\nquay.io/toolbx\\-images/wolfi\\-toolbox:latest\nT}\nT{\nUblue\nT}@T{\nubuntu\\-toolbox  fedora\\-toolbox  wolfi\\-toolbox  archlinux\\-distrobox\nT}@T{\nghcr.io/ublue\\-os/ubuntu\\-toolbox  ghcr.io/ublue\\-os/fedora\\-toolbox \nghcr.io/ublue\\-os/wolfi\\-toolbox  ghcr.io/ublue\\-os/arch\\-toolbox\nT}\nT{\nT}@T{\nT}@T{\nT}\nT{\nAlmaLinux\nT}@T{\n8  8\\-minimal  9  9\\-minimal\nT}@T{\ndocker.io/library/almalinux:8  docker.io/library/almalinux:9\nT}\nT{\nAlpine Linux\nT}@T{\n3.20  3.21  3.22  edge\nT}@T{\ndocker.io/library/alpine:3.20  docker.io/library/alpine:3.21 \ndocker.io/library/alpine:3.22  docker.io/library/alpine:edge \ndocker.io/library/alpine:latest\nT}\nT{\nAmazonLinux\nT}@T{\n1  2  2023\nT}@T{\npublic.ecr.aws/amazonlinux/amazonlinux:1 \npublic.ecr.aws/amazonlinux/amazonlinux:2 \npublic.ecr.aws/amazonlinux/amazonlinux:2023\nT}\nT{\nArchlinux\nT}@T{\nT}@T{\ndocker.io/library/archlinux:latest\nT}\nT{\nBlackarch\nT}@T{\nT}@T{\ndocker.io/blackarchlinux/blackarch:latest\nT}\nT{\nCentOS Stream\nT}@T{\n8  9  10\nT}@T{\nquay.io/centos/centos:stream8  quay.io/centos/centos:stream9 \nquay.io/centos/centos:stream10\nT}\nT{\nChainguard Wolfi\nT}@T{\nT}@T{\ncgr.dev/chainguard/wolfi\\-base:latest\nT}\nT{\nChimera Linux\nT}@T{\nT}@T{\ndocker.io/chimeralinux/chimera:latest\nT}\nT{\nCrystal Linux\nT}@T{\nT}@T{\nregistry.gitlab.com/crystal\\-linux/misc/docker:latest\nT}\nT{\nDebian\nT}@T{\n7  8  9  10  11  12  13\nT}@T{\ndocker.io/debian/eol:wheezy  docker.io/debian/eol:buster \ndocker.io/debian/eol:bullseye \ndocker.io/library/debian:bookworm\\-backports \ndocker.io/library/debian:stable\\-backports\nT}\nT{\nDebian\nT}@T{\nTesting\nT}@T{\ndocker.io/library/debian:testing \ndocker.io/library/debian:testing\\-backports\nT}\nT{\nDebian\nT}@T{\nUnstable\nT}@T{\ndocker.io/library/debian:unstable\nT}\nT{\ndeepin\nT}@T{\n20 (apricot)  23 (beige)\nT}@T{\ndocker.io/linuxdeepin/apricot  docker.io/linuxdeepin/deepin:beige\nT}\nT{\nFedora\nT}@T{\n38  39  40  41  42  43  Rawhide\nT}@T{\nquay.io/fedora/fedora:38  quay.io/fedora/fedora:39 \nquay.io/fedora/fedora:40  quay.io/fedora/fedora:41 \nquay.io/fedora/fedora:42   quay.io/fedora/fedora:43 \nquay.io/fedora/fedora:rawhide\nT}\nT{\nGentoo Linux\nT}@T{\nrolling\nT}@T{\ndocker.io/gentoo/stage3:latest\nT}\nT{\nKDE neon\nT}@T{\nLatest\nT}@T{\ninvent\\-registry.kde.org/neon/docker\\-images/plasma:latest\nT}\nT{\nKali Linux\nT}@T{\nrolling\nT}@T{\ndocker.io/kalilinux/kali\\-rolling:latest\nT}\nT{\nMint\nT}@T{\n22.3\nT}@T{\ndocker.io/linuxmintd/mint22.3\\-amd64\nT}\nT{\nNeurodebian\nT}@T{\nnd120\nT}@T{\ndocker.io/library/neurodebian:nd120\nT}\nT{\nopenSUSE\nT}@T{\nLeap\nT}@T{\nregistry.opensuse.org/opensuse/leap:latest\nT}\nT{\nopenSUSE\nT}@T{\nTumbleweed\nT}@T{\nregistry.opensuse.org/opensuse/distrobox:latest \nregistry.opensuse.org/opensuse/tumbleweed:latest \nregistry.opensuse.org/opensuse/toolbox:latest \nregistry.opensuse.org/opensuse/distrobox\\-bpftrace:latest\nT}\nT{\nOracle Linux\nT}@T{\n8  8\\-slim  9  9\\-slim  10  10\\-slim\nT}@T{\ncontainer\\-registry.oracle.com/os/oraclelinux:8 \ncontainer\\-registry.oracle.com/os/oraclelinux:8\\-slim \ncontainer\\-registry.oracle.com/os/oraclelinux:9 \ncontainer\\-registry.oracle.com/os/oraclelinux:9\\-slim \ncontainer\\-registry.oracle.com/os/oraclelinux:10 \ncontainer\\-registry.oracle.com/os/oraclelinux:10\\-slim\nT}\nT{\nRedHat (UBI)\nT}@T{\n7  8  9\nT}@T{\nregistry.access.redhat.com/ubi7/ubi  registry.access.redhat.com/ubi8/ubi\n\\ registry.access.redhat.com/ubi8/ubi\\-init \nregistry.access.redhat.com/ubi8/ubi\\-minimal \nregistry.access.redhat.com/ubi9/ubi \nregistry.access.redhat.com/ubi9/ubi\\-init \nregistry.access.redhat.com/ubi9/ubi\\-minimal\nT}\nT{\nRocky Linux\nT}@T{\n8  8\\-minimal  9\nT}@T{\nquay.io/rockylinux/rockylinux:8 \nquay.io/rockylinux/rockylinux:8\\-minimal \nquay.io/rockylinux/rockylinux:9  quay.io/rockylinux/rockylinux:latest\nT}\nT{\nSlackware\nT}@T{\nT}@T{\ndocker.io/vbatts/slackware:current\nT}\nT{\nSteamOS\nT}@T{\nT}@T{\nghcr.io/linuxserver/steamos:latest\nT}\nT{\nUbuntu\nT}@T{\n14.04  16.04  18.04  20.04  22.04  24.04\nT}@T{\ndocker.io/library/ubuntu:14.04  docker.io/library/ubuntu:16.04 \ndocker.io/library/ubuntu:18.04  docker.io/library/ubuntu:20.04 \ndocker.io/library/ubuntu:22.04  docker.io/library/ubuntu:24.04\nT}\nT{\nVanilla OS\nT}@T{\nVSO\nT}@T{\nghcr.io/vanilla\\-os/vso:main\nT}\nT{\nVoid Linux\nT}@T{\nglibc  musl\nT}@T{\nghcr.io/void\\-linux/void\\-glibc\\-full:latest \nghcr.io/void\\-linux/void\\-musl\\-full:latest\nT}\n.TE\n.PP\nImages marked with \\f[B]Toolbox\\f[R] are tailored images made by the\ncommunity efforts in \\c\n.UR https://github.com/toolbx-images/images\ntoolbx\\-images/images\n.UE \\c\n, so they are more indicated for desktop use, and first setup will take\nless time.\nNote however that if you use a non\\-toolbox preconfigured image, the\n\\f[B]first\\f[R] \\f[CR]distrobox\\-enter\\f[R] you\\[cq]ll perform can take\na while as it will download and install the missing dependencies.\n.PP\nA small time tax to pay for the ability to use any type of image.\nThis will \\f[B]not\\f[R] occur after the first time, \\f[B]subsequent\nenters will be much faster.\\f[R]\n.PP\nNixOS is not a supported container distro, and there are currently no\nplans to bring support to it.\nIf you are looking for unprivileged NixOS environments, we suggest you\nlook into \\c\n.UR https://nixos.org/manual/nix/unstable/command-ref/nix-shell.html\nnix\\-shell\n.UE \\c\n\\ or \\c\n.UR https://github.com/DavHau/nix-portable\nnix portable\n.UE \\c\n.SS NEW DISTRO SUPPORT\nIf your distro of choice is not on the list, open an issue requesting\nsupport for it, we can work together to check if it is possible to add\nsupport for it.\n.PP\nOr just try using it anyway, if it works, open an issue and it will be\nadded to the list!\n.SS OLDER DISTRIBUTIONS\nFor older distributions like CentOS 5, CentOS 6, Debian 6, Ubuntu 12.04,\ncompatibility is not assured.\n.PP\nTheir \\f[CR]libc\\f[R] version is incompatible with kernel releases after\n\\f[CR]>=4.11\\f[R].\nA work around this is to use the \\f[CR]vsyscall=emulate\\f[R] flag in the\nbootloader of the host.\n.PP\nKeep also in mind that mirrors could be down for such old releases, so\nyou will need to build a custom distrobox image to ensure basic\ndependencies are met.\n.SS GPU ACCELERATION SUPPORT\nFor Intel and AMD Gpus, the support is baked in, as the containers will\ninstall their latest available mesa/dri drivers.\n.PP\nFor NVidia, you can use the \\f[CR]\\-\\-nvidia\\f[R] flag during create,\nsee distrobox\\-create documentation to discover how to use it.\n.PP\nAlternatively, you can use the nvidia\\-container\\-toolkit utility to set\nup the integration independently from the distrobox\\[cq]s own flag.\n"
  },
  {
    "path": "man/man1/distrobox-create.1",
    "content": ".\\\n.\\\"\n.TH \"DISTROBOX\\-CREATE\" \"1\" \"Mar 2026\" \"Distrobox\" \"User Manual\"\n.SH NAME\n.IP\n.EX\ndistrobox create\ndistrobox\\-create\n.EE\n.SH DESCRIPTION\ndistrobox\\-create takes care of creating the container with input name\nand image.\nThe created container will be tightly integrated with the host, allowing\nsharing of the HOME directory of the user, external storage, external\nusb devices and graphical apps (X11/Wayland), and audio.\n.SH SYNOPSIS\n\\f[B]distrobox create\\f[R]\n.IP\n.EX\n\\-\\-image/\\-i:     image to use for the container  default: ${container_image_default}\n\\-\\-name/\\-n:      name for the distrobox          default: ${container_name_default}\n\\-\\-hostname:     hostname for the distrobox      default: <container\\-name>.$(uname \\-n)\n\\-\\-pull/\\-p:      pull the image even if it exists locally (implies \\-\\-yes)\n\\-\\-yes/\\-Y:       non\\-interactive, pull images without asking\n\\-\\-root/\\-r:      launch podman/docker/lilipod with root privileges. Note that if you need root this is the preferred\n            way over \\[dq]sudo distrobox\\[dq] (note: if using a program other than \\[aq]sudo\\[aq] for root privileges is necessary,\n            specify it through the DBX_SUDO_PROGRAM env variable, or \\[aq]distrobox_sudo_program\\[aq] config variable)\n\\-\\-clone/\\-c:     name of the distrobox container to use as base for a new container\n            this will be useful to either rename an existing distrobox or have multiple copies\n            of the same environment.\n\\-\\-home/\\-H:      select a custom HOME directory for the container. Useful to avoid host\\[aq]s home littering with temp files.\n\\-\\-volume:       additional volumes to add to the container\n\\-\\-additional\\-flags/\\-a:  additional flags to pass to the container manager command\n\\-\\-additional\\-packages/\\-ap:  additional packages to install during initial container setup\n\\-\\-init\\-hooks:       additional commands to execute at the end of container initialization\n\\-\\-pre\\-init\\-hooks:   additional commands to execute at the start of container initialization\n\\-\\-init/\\-I:      use init system (like systemd) inside the container.\n            this will make host\\[aq]s processes not visible from within the container. (assumes \\-\\-unshare\\-process)\n            may require additional packages depending on the container image: https://github.com/89luca89/distrobox/blob/main/docs/useful_tips.md#using\\-init\\-system\\-inside\\-a\\-distrobox\n\\-\\-nvidia:       try to integrate host\\[aq]s nVidia drivers in the guest\n\\-\\-platform:     specify which platform to use, eg: linux/arm64\n\\-\\-unshare\\-devsys:          do not share host devices and sysfs dirs from host\n\\-\\-unshare\\-groups:          do not forward user\\[aq]s additional groups into the container\n\\-\\-unshare\\-ipc:          do not share ipc namespace with host\n\\-\\-unshare\\-netns:        do not share the net namespace with host\n\\-\\-unshare\\-process:          do not share process namespace with host\n\\-\\-unshare\\-all:          activate all the unshare flags below\n\\-\\-compatibility/\\-C: show list of compatible images\n\\-\\-help/\\-h:      show this message\n\\-\\-no\\-entry:     do not generate a container entry in the application list\n\\-\\-dry\\-run/\\-d:       only print the container manager command generated\n\\-\\-verbose/\\-v:       show more verbosity\n\\-\\-version/\\-V:       show version\n\n\\-\\-absolutely\\-disable\\-root\\-password\\-i\\-am\\-really\\-positively\\-sure: ⚠️ ⚠️  when setting up a rootful distrobox, this will skip user password setup, leaving it blank. ⚠️ ⚠️\n.EE\n.SH COMPATIBILITY\n.IP\n.EX\nfor a list of compatible images and container managers, please consult the man page:\n    man distrobox\n    man distrobox\\-compatibility\nor consult the documentation page on: https://github.com/89luca89/distrobox/blob/main/docs/compatibility.md#containers\\-distros\n.EE\n.SH EXAMPLES\nCreate a distrobox with image alpine, called my\\-alpine container\n.IP\n.EX\ndistrobox create \\-\\-image alpine my\\-alpine\\-container\n.EE\n.PP\nCreate a distrobox from fedora\\-toolbox:35 image\n.IP\n.EX\ndistrobox create \\-\\-image registry.fedoraproject.org/fedora\\-toolbox:35 \\-\\-name fedora\\-toolbox\\-35\n.EE\n.PP\nClone an existing distrobox container\n.IP\n.EX\ndistrobox create \\-\\-clone fedora\\-35 \\-\\-name fedora\\-35\\-copy\n.EE\n.PP\nAlways pull for the new image when creating a distrobox\n.IP\n.EX\ndistrobox create \\-\\-pull \\-\\-image centos:stream9 \\-\\-home \\[ti]/distrobox/centos9\n.EE\n.PP\nAdd additional environment variables to the container\n.IP\n.EX\ndistrobox create \\-\\-image fedora:35 \\-\\-name test \\-\\-additional\\-flags \\[dq]\\-\\-env MY_VAR=value\\[dq]\n.EE\n.PP\nAdd additional volumes to the container\n.IP\n.EX\ndistrobox create \\-\\-image fedora:35 \\-\\-name test \\-\\-volume /opt/my\\-dir:/usr/local/my\\-dir:rw \\-\\-additional\\-flags \\[dq]\\-\\-pids\\-limit \\-1\\[dq]\n.EE\n.PP\nAdd additional packages to the container\n.IP\n.EX\ndistrobox create \\-\\-image alpine:latest \\-\\-name test2 \\-\\-additional\\-packages \\[dq]git tmux vim\\[dq]\n.EE\n.PP\nUse init\\-hooks to perform an action during container startup\n.IP\n.EX\ndistrobox create \\-\\-image alpine:latest \\-\\-name test \\-\\-init\\-hooks \\[dq]touch /var/tmp/test1 && touch /var/tmp/test2\\[dq]\n.EE\n.PP\nUse pre\\-init\\-hooks to perform an action at the beginning of the\ncontainer startup (before any package manager starts)\n.IP\n.EX\ndistrobox create \\-i docker.io/almalinux/8\\-init \\-\\-init \\-\\-name test \\-\\-pre\\-init\\-hooks \\[dq]dnf config\\-manager \\-\\-enable powertools && dnf \\-y install epel\\-release\\[dq]\n.EE\n.PP\nUse init to create a Systemd container (acts similar to an LXC):\n.IP\n.EX\ndistrobox create \\-i ubuntu:latest \\-\\-name test \\-\\-additional\\-packages \\[dq]systemd libpam\\-systemd pipewire\\-audio\\-client\\-libraries\\[dq] \\-\\-init\n.EE\n.PP\nUse init to create a OpenRC container (acts similar to an LXC):\n.IP\n.EX\ndistrobox create \\-i alpine:latest \\-\\-name test \\-\\-additional\\-packages \\[dq]openrc\\[dq] \\-\\-init\n.EE\n.PP\nUse host\\[cq]s NVidia drivers integration\n.IP\n.EX\ndistrobox create \\-\\-image ubuntu:22.04 \\-\\-name ubuntu\\-nvidia \\-\\-nvidia\n.EE\n.PP\nDo not use host\\[cq]s IP inside the container:\n.IP\n.EX\ndistrobox create \\-\\-image ubuntu:latest \\-\\-name test \\-\\-unshare\\-netns\n.EE\n.PP\nCreate a more isolated container, where only the $HOME, basic sockets\nand host\\[cq]s FS (in /run/host) is shared:\n.IP\n.EX\ndistrobox create \\-\\-name unshared\\-test \\-\\-unshare\\-all\n.EE\n.PP\nCreate a more isolated container, with it\\[cq]s own init system, this\nwill act very similar to a full LXC container:\n.IP\n.EX\ndistrobox create \\-\\-name unshared\\-init\\-test \\-\\-unshare\\-all \\-\\-init \\-\\-image fedora:latest\n.EE\n.PP\nUse environment variables to specify container name, image and container\nmanager:\n.IP\n.EX\nDBX_CONTAINER_MANAGER=\\[dq]docker\\[dq] DBX_NON_INTERACTIVE=1 DBX_CONTAINER_NAME=test\\-alpine DBX_CONTAINER_IMAGE=alpine distrobox\\-create\n.EE\n.SH ENVIRONMENT VARIABLES\n.IP\n.EX\nDBX_CONTAINER_ALWAYS_PULL\nDBX_CONTAINER_CUSTOM_HOME\nDBX_CONTAINER_HOME_PREFIX\nDBX_CONTAINER_IMAGE\nDBX_CONTAINER_MANAGER\nDBX_CONTAINER_NAME\nDBX_CONTAINER_HOSTNAME\nDBX_NON_INTERACTIVE\nDBX_SUDO_PROGRAM\n.EE\n.PP\nDBX_CONTAINER_HOME_PREFIX defines where containers\\[cq] home directories\nwill be located.\nIf you define it as \\[ti]/dbx then all future containers\\[cq] home\ndirectories will be \\[ti]/dbx/$container_name\n.SH EXTRA\nThe \\f[CR]\\-\\-additional\\-flags\\f[R] or \\f[CR]\\-a\\f[R] is useful to\nmodify defaults in the container creations.\nFor example:\n.IP\n.EX\ndistrobox create \\-i docker.io/library/archlinux \\-n dev\\-arch\n\npodman container inspect dev\\-arch | jq \\[aq].[0].HostConfig.PidsLimit\\[aq]\n2048\n\ndistrobox rm \\-f dev\\-arch\ndistrobox create \\-i docker.io/library/archlinux \\-n dev\\-arch \\-\\-volume $CBL_TC:/tc \\-\\-additional\\-flags \\[dq]\\-\\-pids\\-limit \\-1\\[dq]\n\npodman container inspect dev\\-arch | jq \\[aq].[0].HostConfig,.PidsLimit\\[aq]\n0\n.EE\n.PP\nAdditional volumes can be specified using the \\f[CR]\\-\\-volume\\f[R]\nflag.\nThis flag follows the same standard as \\f[CR]docker\\f[R] and\n\\f[CR]podman\\f[R] to specify the mount point so\n\\f[CR]\\-\\-volume SOURCE_PATH:DEST_PATH:MODE\\f[R].\n.IP\n.EX\ndistrobox create \\-\\-image docker.io/library/archlinux \\-\\-name dev\\-arch \\-\\-volume /usr/share/:/var/test:ro\n.EE\n.PP\nDuring container creation, it is possible to specify (using the\nadditional\\-flags) some environment variables that will persist in the\ncontainer and be independent from your environment:\n.IP\n.EX\ndistrobox create \\-\\-image fedora:35 \\-\\-name test \\-\\-additional\\-flags \\[dq]\\-\\-env MY_VAR=value\\[dq]\n.EE\n.PP\nThe \\f[CR]\\-\\-init\\-hooks\\f[R] is useful to add commands to the\nentrypoint (init) of the container.\nThis could be useful to create containers with a set of programs already\ninstalled, add users, groups.\n.IP\n.EX\ndistrobox create  \\-\\-image fedora:35 \\-\\-name test \\-\\-init\\-hooks \\[dq]dnf groupinstall \\-y \\[rs]\\[dq]C Development Tools and Libraries\\[rs]\\[dq]\\[dq]\n.EE\n.PP\nThe \\f[CR]\\-\\-init\\f[R] is useful to create a container that will use\nits own separate init system within.\nFor example using:\n.IP\n.EX\ndistrobox create \\-i docker.io/almalinux/8\\-init \\-\\-init \\-\\-name test\ndistrobox create \\-i docker.io/library/debian \\-\\-additional\\-packages \\[dq]systemd\\[dq] \\-\\-init \\-\\-name test\\-debian\n.EE\n.PP\nInside the container we will be able to use normal systemd units:\n.IP\n.EX\n\\[ti]$ distrobox enter test\nuser\\[at]test:\\[ti]$ sudo systemctl enable \\-\\-now sshd\nuser\\[at]test:\\[ti]$ sudo systemctl status sshd\n    ● sshd.service \\- OpenSSH server daemon\n       Loaded: loaded (/usr/lib/systemd/system/sshd.service; enabled; vendor preset: enabled)\n       Active: active (running) since Fri 2022\\-01\\-28 22:54:50 CET; 17s ago\n         Docs: man:sshd(8)\n               man:sshd_config(5)\n     Main PID: 291 (sshd)\n.EE\n.PP\nNote that enabling \\f[CR]\\-\\-init\\f[R] \\f[B]will disable host\\[cq]s\nprocess integration\\f[R].\nFrom within the container you will not be able to see and manage\nhost\\[cq]s processes.\nThis is needed because \\f[CR]/sbin/init\\f[R] must be pid 1.\n.PP\nIf you want to use a non\\-pre\\-create image, you\\[cq]ll need to add the\nadditional package:\n.IP\n.EX\ndistrobox create \\-i alpine:latest \\-\\-init \\-\\-additional\\-packages \\[dq]openrc\\[dq] \\-n test\ndistrobox create \\-i debian:stable \\-\\-init \\-\\-additional\\-packages \\[dq]systemd libpam\\-systemd pipewire\\-audio\\-client\\-libraries\\[dq] \\-n test\ndistrobox create \\-i ubuntu:22.04 \\-\\-init \\-\\-additional\\-packages \\[dq]systemd libpam\\-systemd pipewire\\-audio\\-client\\-libraries\\[dq] \\-n test\ndistrobox create \\-i archlinux:latest \\-\\-init \\-\\-additional\\-packages \\[dq]systemd\\[dq] \\-n test\ndistrobox create \\-i registry.opensuse.org/opensuse/tumbleweed:latest \\-\\-init \\-\\-additional\\-packages \\[dq]systemd\\[dq] \\-n test\ndistrobox create \\-i registry.fedoraproject.org/fedora:39 \\-\\-init \\-\\-additional\\-packages \\[dq]systemd\\[dq] \\-n test\n.EE\n.PP\nThe \\f[CR]\\-\\-init\\f[R] flag is useful to create system containers,\nwhere the container acts more similar to a full VM than an\napplication\\-container.\nInside you\\[cq]ll have a separate init, user\\-session, daemons and so\non.\n.PP\nThe \\f[CR]\\-\\-home\\f[R] flag let\\[cq]s you specify a custom HOME for the\ncontainer.\nNote that this will NOT prevent the mount of the host\\[cq]s home\ndirectory, but will ensure that configs and dotfiles will not litter it.\n.PP\nThe \\f[CR]\\-\\-root\\f[R] flag will let you create a container with real\nroot privileges.\nAt first \\f[CR]enter\\f[R] the user will be required to setup a password.\nThis is done in order to not enable passwordless sudo/su, in a\n\\f[B]rootful\\f[R] container, this is needed because \\f[B]in this mode,\nroot inside the container is also root outside the container!\\f[R]\n.PP\nThe\n\\f[CR]\\-\\-absolutely\\-disable\\-root\\-password\\-i\\-am\\-really\\-positively\\-sure\\f[R]\nwill skip user password setup, leaving it blank.\n\\f[B]This is genuinely dangerous and you really, positively should NOT\nenable this\\f[R].\n.PP\nFrom version 1.4.0 of distrobox, when you create a new container, it\nwill also generate an entry in the applications list.\n.SS NVidia integration\nIf your host has an NVidia gpu, with installed proprietary drivers, you\ncan integrate them with the guests by using the \\f[CR]\\-\\-nvidia\\f[R]\nflag:\n.PP\n\\f[CR]distrobox create \\-\\-nvidia \\-\\-image ubuntu:latest \\-\\-name ubuntu\\-nvidia\\f[R]\n.PP\nBe aware that \\f[B]this is not compatible with non\\-glibc systems\\f[R]\nand \\f[B]needs somewhat newer distributions to work\\f[R].\n.PP\nThis feature was tested working on:\n.IP \\[bu] 2\nAlmalinux\n.IP \\[bu] 2\nArchlinux\n.IP \\[bu] 2\nCentos 7 and newer\n.IP \\[bu] 2\nClearlinux\n.IP \\[bu] 2\nDebian 10 and newer\n.IP \\[bu] 2\nOpenSUSE Leap\n.IP \\[bu] 2\nOpenSUSE Tumbleweed\n.IP \\[bu] 2\nRockylinux\n.IP \\[bu] 2\nUbuntu 18.04 and newer\n.IP \\[bu] 2\nVoid Linux (glibc)\n"
  },
  {
    "path": "man/man1/distrobox-enter.1",
    "content": ".\\\n.\\\"\n.TH \"DISTROBOX\\-ENTER\" \"1\" \"Mar 2026\" \"Distrobox\" \"User Manual\"\n.SH NAME\n.IP\n.EX\ndistrobox enter\ndistrobox\\-enter\n.EE\n.SH DESCRIPTION\ndistrobox\\-enter takes care of entering the container with the name\nspecified.\nDefault command executed is your SHELL, but you can specify different\nshells or entire commands to execute.\nIf using it inside a script, an application, or a service, you can\nspecify the \\[en]headless mode to disable tty and interactivity.\n.SH SYNOPSIS\n\\f[B]distrobox enter\\f[R]\n.IP\n.EX\n\\-\\-name/\\-n:      name for the distrobox                      default: my\\-distrobox\n\\-\\-/\\-e:          end arguments execute the rest as command to execute at login   default: default ${USER}\\[aq]s shell\n\\-\\-no\\-tty/\\-T:        do not instantiate a tty\n\\-\\-no\\-workdir/\\-nw:   always start the container from container\\[aq]s home directory\n\\-\\-additional\\-flags/\\-a:  additional flags to pass to the container manager command\n\\-\\-help/\\-h:      show this message\n\\-\\-root/\\-r:      launch podman/docker/lilipod with root privileges. Note that if you need root this is the preferred\n            way over \\[dq]sudo distrobox\\[dq] (note: if using a program other than \\[aq]sudo\\[aq] for root privileges is necessary,\n            specify it through the DBX_SUDO_PROGRAM env variable, or \\[aq]distrobox_sudo_program\\[aq] config variable)\n\\-\\-dry\\-run/\\-d:       only print the container manager command generated\n\\-\\-verbose/\\-v:       show more verbosity\n\\-\\-version/\\-V:       show version\n.EE\n.SH EXAMPLES\nEnter a distrobox named \\[lq]example\\[rq]\n.IP\n.EX\ndistrobox\\-enter example\n.EE\n.PP\nEnter a distrobox specifying a command\n.IP\n.EX\ndistrobox\\-enter \\-\\-name fedora\\-toolbox\\-35 \\-\\- bash \\-l\ndistrobox\\-enter my\\-alpine\\-container \\-\\- sh \\-l\n.EE\n.PP\nUse additional podman/docker/lilipod flags while entering a distrobox\n.IP\n.EX\ndistrobox\\-enter \\-\\-additional\\-flags \\[dq]\\-\\-preserve\\-fds\\[dq] \\-\\-name test \\-\\- bash \\-l\n.EE\n.PP\nSpecify additional environment variables while entering a distrobox\n.IP\n.EX\ndistrobox\\-enter \\-\\-additional\\-flags \\[dq]\\-\\-env MY_VAR=value\\[dq] \\-\\-name test \\-\\- bash \\-l\nMY_VAR=value distrobox\\-enter \\-\\-additional\\-flags \\[dq]\\-\\-preserve\\-fds\\[dq] \\-\\-name test \\-\\- bash \\-l\n.EE\n.PP\nYou can also use environment variables to specify container manager and\ncontainer name:\n.IP\n.EX\nDBX_CONTAINER_MANAGER=\\[dq]docker\\[dq] DBX_CONTAINER_NAME=test\\-alpine distrobox\\-enter\n.EE\n.SH ENVIRONMENT VARIABLES\n.IP\n.EX\nDBX_CONTAINER_NAME\nDBX_CONTAINER_MANAGER\nDBX_SKIP_WORKDIR\nDBX_SUDO_PROGRAM\n.EE\n.SH EXTRA\nThis command is used to enter the distrobox itself.\nPersonally, I just create multiple profiles in my\n\\f[CR]gnome\\-terminal\\f[R] to have multiple distros accessible.\n.PP\nThe \\f[CR]\\-\\-additional\\-flags\\f[R] or \\f[CR]\\-a\\f[R] is useful to\nmodify default command when executing in the container.\nFor example:\n.IP\n.EX\ndistrobox enter \\-n dev\\-arch \\-\\-additional\\-flags \\[dq]\\-\\-env my_var=test\\[dq] \\-\\- printenv &| grep my_var\nmy_var=test\n.EE\n.PP\nThis is possible also using normal env variables:\n.IP\n.EX\nmy_var=test distrobox enter \\-n dev\\-arch \\-\\-additional\\-flags \\-\\- printenv &| grep my_var\nmy_var=test\n.EE\n.PP\nIf you\\[cq]d like to enter a rootful container having distrobox use a\nprogram other than `sudo' to run podman/docker/lilipod as root, such as\n`pkexec' or `doas', you may specify it with the\n\\f[CR]DBX_SUDO_PROGRAM\\f[R] environment variable.\nFor example, to use `doas' to enter a rootful container:\n.IP\n.EX\nDBX_SUDO_PROGRAM=\\[dq]doas\\[dq] distrobox enter \\-n container \\-\\-root\n.EE\n.PP\nAdditionally, in one of the config file paths that distrobox supports,\nsuch as \\f[CR]\\[ti]/.distroboxrc\\f[R], you can also append the line\n\\f[CR]distrobox_sudo_program=\\[dq]doas\\[dq]\\f[R] (for example) to always\nrun distrobox commands involving rootful containers using `doas'.\n"
  },
  {
    "path": "man/man1/distrobox-ephemeral.1",
    "content": ".\\\n.\\\"\n.TH \"DISTROBOX\\-EPHEMERAL\" \"1\" \"Mar 2026\" \"Distrobox\" \"User Manual\"\n.SH NAME\n.IP\n.EX\ndistrobox ephemeral\ndistrobox\\-ephemeral\n.EE\n.SH DESCRIPTION\ndistrobox\\-ephemeral creates a temporary distrobox that is automatically\ndestroyed when the command is terminated.\n.SH SYNOPSIS\n\\f[B]distrobox ephemeral\\f[R]\n.IP\n.EX\n\\-\\-root/\\-r:      launch podman/docker/lilipod with root privileges. Note that if you need root this is the preferred\n            way over \\[dq]sudo distrobox\\[dq] (note: if using a program other than \\[aq]sudo\\[aq] for root privileges is necessary,\n            specify it through the DBX_SUDO_PROGRAM env variable, or \\[aq]distrobox_sudo_program\\[aq] config variable)\n\\-\\-verbose/\\-v:       show more verbosity\n\\-\\-help/\\-h:      show this message\n\\-\\-/\\-e:          end arguments execute the rest as command to execute at login   default: default ${USER}\\[aq]s shell\n\\-\\-version/\\-V:       show version\n.EE\n.SH EXAMPLES\n.IP\n.EX\ndistrobox\\-ephemeral \\-\\-image alpine:latest \\-\\- cat /etc/os\\-release\ndistrobox\\-ephemeral \\-\\-root \\-\\-verbose \\-\\-image alpine:latest \\-\\-volume /opt:/opt\n.EE\n.PP\nYou can also use flags from \\f[B]distrobox\\-create\\f[R] to customize the\nephemeral container to run.\n.SH SEE ALSO\n.IP\n.EX\ndistrobox\\-create \\-\\-help\nman distrobox\\-create\n.EE\n.SH ENVIRONMENT VARIABLES\n.IP\n.EX\ndistrobox\\-ephemeral calls distrobox\\-create, SEE ALSO distrobox\\-create(1) for\na list of supported environment variables to use.\n.EE\n"
  },
  {
    "path": "man/man1/distrobox-export.1",
    "content": ".\\\n.\\\"\n.TH \"DISTROBOX\\-EXPORT\" \"1\" \"Mar 2026\" \"Distrobox\" \"User Manual\"\n.SH NAME\n.IP\n.EX\ndistrobox\\-export\n.EE\n.SH DESCRIPTION\n\\f[B]Application and binary exporting\\f[R]\n.PP\ndistrobox\\-export takes care of exporting an app or a binary from the\ncontainer to the host.\n.PP\nThe exported app will be easily available in your normal launcher and it\nwill automatically be launched from the container it is exported from.\n.SH SYNOPSIS\n\\f[B]distrobox\\-export\\f[R]\n.IP\n.EX\n\\-\\-app/\\-a:       name of the application to export or absolute path to desktopfile to export\n\\-\\-bin/\\-b:       absolute path of the binary to export\n\\-\\-list\\-apps:        list applications exported from this container\n\\-\\-list\\-binaries     list binaries exported from this container, use \\-ep to specify custom paths to search\n\\-\\-delete/\\-d:        delete exported application or binary\n\\-\\-export\\-label/\\-el: label to add to exported application name.\n            Use \\[dq]none\\[dq] to disable.\n            Defaults to (on \\[rs]$container_name)\n\\-\\-export\\-path/\\-ep:  path where to export the binary\n\\-\\-extra\\-flags/\\-ef:  extra flags to add to the command\n\\-\\-enter\\-flags/\\-nf:  flags to add to distrobox\\-enter\n\\-\\-sudo/\\-S:      specify if the exported item should be run as sudo\n\\-\\-help/\\-h:      show this message\n\\-\\-verbose/\\-v:       show more verbosity\n\\-\\-version/\\-V:       show version\n.EE\n.PP\nYou may want to install graphical applications or CLI tools in your\ndistrobox.\nUsing \\f[CR]distrobox\\-export\\f[R] from \\f[B]inside\\f[R] the container\nwill let you use them from the host itself.\n.SH EXAMPLES\n.IP\n.EX\ndistrobox\\-export \\-\\-app mpv [\\-\\-extra\\-flags \\[dq]flags\\[dq]] [\\-\\-delete] [\\-\\-sudo]\ndistrobox\\-export \\-\\-bin /path/to/bin [\\-\\-export\\-path \\[ti]/.local/bin] [\\-\\-extra\\-flags \\[dq]flags\\[dq]] [\\-\\-delete] [\\-\\-sudo]\n.EE\n.PP\n\\f[B]App export example\\f[R]\n.IP\n.EX\ndistrobox\\-export \\-\\-app abiword\n.EE\n.PP\nThis tool will simply copy the original \\f[CR].desktop\\f[R] files along\nwith needed icons, add the prefix\n\\f[CR]/usr/local/bin/distrobox\\-enter \\-n distrobox_name \\-e ...\\f[R] to\nthe commands to run, and save them in your home to be used directly from\nthe host as a normal app.\n.IP\n.EX\ndistrobox\\-export \\-\\-app /opt/application/my\\-app.desktop\n.EE\n.PP\nThis will skip searching for the desktopfile in canonical paths, and\njust use the provided file path.\n.PP\n\\f[B]Binary export example\\f[R]\n.IP\n.EX\ndistrobox\\-export \\-\\-bin /usr/bin/code \\-\\-extra\\-flags \\[dq]\\-\\-foreground\\[dq] \\-\\-export\\-path $HOME/.local/bin\n.EE\n.PP\nIn the case of exporting binaries, you will have to specify\n\\f[B]where\\f[R] to export it (\\f[CR]\\-\\-export\\-path\\f[R]) and the tool\nwill create a little wrapper script that will\n\\f[CR]distrobox\\-enter \\-e\\f[R] from the host, the desired binary.\nThis can be handy with the use of \\f[CR]direnv\\f[R] to have different\nversions of the same binary based on your \\f[CR]env\\f[R] or project.\n.PP\nThe exported binaries will be exported in the\n\\[lq]\\[en]export\\-path\\[rq] of choice as a wrapper script that acts\nnaturally both on the host and in the container.\n.PP\n\\f[B]Additional flags\\f[R]\n.PP\nYou can specify additional flags to add to the command, for example if\nyou want to export an electron app, you could add the\n\\[lq]\\[en]foreground\\[rq] flag to the command:\n.IP\n.EX\ndistrobox\\-export \\-\\-app atom \\-\\-extra\\-flags \\[dq]\\-\\-foreground\\[dq]\ndistrobox\\-export \\-\\-bin /usr/bin/vim \\-\\-export\\-path \\[ti]/.local/bin \\-\\-extra\\-flags \\[dq]\\-p\\[dq]\n.EE\n.PP\nThis works for binaries and apps.\nExtra flags are only used then the exported app or binary is used from\nthe host, using them inside the container will not include them.\n.PP\n\\f[B]Unexport\\f[R]\n.PP\nThe option \\[lq]\\[en]delete\\[rq] will un\\-export an app or binary\n.IP\n.EX\ndistrobox\\-export \\-\\-app atom \\-\\-delete\ndistrobox\\-export \\-\\-bin /usr/bin/vim \\-\\-export\\-path \\[ti]/.local/bin \\-\\-delete\n.EE\n.PP\n\\f[B]Run as root in the container\\f[R]\n.PP\nThe option \\[lq]\\[en]sudo\\[rq] will launch the exported item as root\ninside the distrobox.\n.PP\n\\f[B]Notes\\f[R]\n.PP\nNote you can use \\[en]app OR \\[en]bin but not together.\n[IMAGE: \\c\n.UR https://user-images.githubusercontent.com/598882/144294795-c7785620-bf68-4d1b-b251-1e1f0a32a08d.png\napp\\-export\n.UE \\c\n]\napp\\-export\n.PP\nNOTE: some electron apps such as vscode and atom need additional flags\nto work from inside the container, use the \\f[CR]\\-\\-extra\\-flags\\f[R]\noption to provide a series of flags, for example:\n.PP\n\\f[CR]distrobox\\-export \\-\\-app atom \\-\\-extra\\-flags \\[dq]\\-\\-foreground\\[dq]\\f[R]\n"
  },
  {
    "path": "man/man1/distrobox-generate-entry.1",
    "content": ".\\\n.\\\"\n.TH \"DISTROBOX\\-GENERATE\\-ENTRY\" \"1\" \"Mar 2026\" \"Distrobox\" \"User Manual\"\n.SH NAME\n.IP\n.EX\ndistrobox generate\\-entry\n.EE\n.SH DESCRIPTION\ndistrobox\\-generate\\-entry will create a desktop icon for one of the\navailable distroboxes.\nThis will be then deleted when you remove the matching distrobox.\n.SH SYNOPSIS\n\\f[B]distrobox generate\\-entry\\f[R]\n.IP\n.EX\n\\-\\-help/\\-h:      show this message\n\\-\\-all/\\-a:       perform for all distroboxes\n\\-\\-delete/\\-d:        delete the entry\n\\-\\-icon/\\-i:      specify a custom icon [/path/to/icon] (default auto)\n\\-\\-root/\\-r:      perform on rootful distroboxes\n\\-\\-verbose/\\-v:       show more verbosity\n\\-\\-version/\\-V:       show version\n.EE\n.SH EXAMPLES\nGenerate an entry for a container\n.IP\n.EX\ndistrobox generate\\-entry my\\-container\\-name\n.EE\n.PP\nSpecify a custom icon for the entry\n.IP\n.EX\ndistrobox generate\\-entry my\\-container\\-name \\-\\-icon /path/to/icon.png\n.EE\n.PP\nGenerate an entry for all distroboxes\n.IP\n.EX\ndistrobox generate\\-entry \\-\\-all\n.EE\n.PP\nDelete an entry\n.IP\n.EX\ndistrobox generate\\-entry container\\-name \\-\\-delete\n.EE\n"
  },
  {
    "path": "man/man1/distrobox-host-exec.1",
    "content": ".\\\n.\\\"\n.TH \"DISTROBOX\\-HOST\\-EXEC\" \"1\" \"Mar 2026\" \"Distrobox\" \"User Manual\"\n.SH NAME\n.IP\n.EX\ndistrobox\\-host\\-exec\n.EE\n.SH DESCRIPTION\ndistrobox\\-host\\-exec lets one execute command on the host, while inside\nof a container.\n.PP\nUnder the hood, distrobox\\-host\\-exec uses \\f[CR]host\\-spawn\\f[R] a\nproject that lets us execute commands back on the host.\nIf the tool is not found the user will be prompted to install it.\n.SH SYNOPSIS\nJust pass to \\[lq]distrobox\\-host\\-exec\\[rq] any command and all its\narguments, if any.\n.IP\n.EX\n\\-\\-help/\\-h:      show this message\n\\-\\-verbose/\\-v:       show more verbosity\n\\-\\-version/\\-V:       show version\n\\-\\-yes/\\-Y:       Automatically answer yes to prompt:\n                            host\\-spawn will be installed on the guest system\n                            if host\\-spawn is not detected.\n                            This behaviour is default when running in a non\\-interactive shell.\n.EE\n.PP\nIf no command is provided, it will execute \\[lq]$SHELL\\[rq].\n.PP\nAlternatively, you can symlink a command name to\n\\f[CR]distrobox\\-host\\-exec\\f[R] and then call that command by its name\non the host, while inside of a container.\n.SH EXAMPLES\n.SS Run individual commands\n.IP\n.EX\ndistrobox\\-host\\-exec ls\ndistrobox\\-host\\-exec bash \\-l\ndistrobox\\-host\\-exec flatpak run org.mozilla.firefox\ndistrobox\\-host\\-exec podman ps \\-a\n.EE\n.SS Drop into host shell\n.IP\n.EX\n\\[ti]$: distrobox\\-host\\-exec # No command, executes \\[dq]$SHELL\\[dq] on the host\n\\[ti]$: distrobox\\-host\\-exec # This command now runs on the host\nYou must run  distrobox\\-host\\-exec inside a container!\n.EE\n.SS Symlinking host commands\nUse the host command name to create a symlink to\n\\f[CR]distrobox\\-host\\-exec\\f[R].\nYou can then call the host command from within the container.\n.IP\n.EX\n\\[ti]$: git # We do not have git in the container\nbash: git: command not found\n\\[ti]$: sudo ln \\-s /usr/bin/distrobox\\-host\\-exec /usr/local/bin/git\n\\[ti]$: git version\ngit version 2.51.1\n.EE\n.PP\nYou can control podman on the host from within the container as follows:\n.IP\n.EX\n\\[ti]$: ln \\-s /usr/bin/distrobox\\-host\\-exec /usr/local/bin/podman\n\\[ti]$: ls \\-l /usr/local/bin/podman\nlrwxrwxrwx. 1 root root 51 Jul 11 19:26 /usr/local/bin/podman \\-> /usr/bin/distrobox\\-host\\-exec\n\\[ti]$: podman version\n\\&...this is executed on host...\n.EE\n"
  },
  {
    "path": "man/man1/distrobox-init.1",
    "content": ".\\\n.\\\"\n.TH \"DISTROBOX\\-INIT\" \"1\" \"Mar 2026\" \"Distrobox\" \"User Manual\"\n.SH NAME\n.IP\n.EX\ndistrobox\\-init\n.EE\n.SH DESCRIPTION\n\\f[B]Init the distrobox (not to be launched manually)\\f[R]\n.PP\ndistrobox\\-init is the entrypoint of a created distrobox.\nNote that this HAS to run from inside a distrobox, will not work if you\nrun it from your host.\n.PP\n\\f[B]This is not intended to be used manually, but instead used by\ndistrobox\\-create to set up the container\\[cq]s entrypoint.\\f[R]\n.PP\ndistrobox\\-init will take care of installing missing dependencies (eg.\nsudo), set up the user and groups, mount directories from the host to\nensure the tight integration.\n.SH SYNOPSIS\n\\f[B]distrobox\\-init\\f[R]\n.IP\n.EX\n\\-\\-name/\\-n:      user name\n\\-\\-user/\\-u:      uid of the user\n\\-\\-group/\\-g:     gid of the user\n\\-\\-home/\\-d:      path/to/home of the user\n\\-\\-help/\\-h:      show this message\n\\-\\-additional\\-packages:  packages to install in addition\n\\-\\-init/\\-I:      whether to use or not init\n\\-\\-pre\\-init\\-hooks:   commands to execute prior to init\n\\-\\-nvidia:       try to integrate host\\[aq]s nVidia drivers in the guest\n\\-\\-upgrade/\\-U:       run init in upgrade mode\n\\-\\-verbose/\\-v:       show more verbosity\n\\-\\-version/\\-V:       show version\n\\-\\-:         end arguments execute the rest as command to execute during init\n.EE\n.SH EXAMPLES\n.IP\n.EX\ndistrobox\\-init \\-\\-name test\\-user \\-\\-user 1000 \\-\\-group 1000 \\-\\-home /home/test\\-user\ndistrobox\\-init \\-\\-upgrade\n.EE\n"
  },
  {
    "path": "man/man1/distrobox-list.1",
    "content": ".\\\n.\\\"\n.TH \"DISTROBOX\\-LIST\" \"1\" \"Mar 2026\" \"Distrobox\" \"User Manual\"\n.SH NAME\n.IP\n.EX\ndistrobox list\ndistrobox\\-list\n.EE\n.SH DESCRIPTION\ndistrobox\\-list lists available distroboxes.\nIt detects them and lists them separately from the rest of normal\ncontainers.\n.SH SYNOPSIS\n\\f[B]distrobox list\\f[R]\n.IP\n.EX\n\\-\\-help/\\-h:      show this message\n\\-\\-no\\-color:     disable color formatting\n\\-\\-root/\\-r:      launch podman/docker/lilipod with root privileges. Note that if you need root this is the preferred\n            way over \\[dq]sudo distrobox\\[dq] (note: if using a program other than \\[aq]sudo\\[aq] for root privileges is necessary,\n            specify it through the DBX_SUDO_PROGRAM env variable, or \\[aq]distrobox_sudo_program\\[aq] config variable)\n\\-\\-verbose/\\-v:       show more verbosity\n\\-\\-version/\\-V:       show version\n.EE\n.SH EXAMPLES\n.IP\n.EX\ndistrobox\\-list\n.EE\n.PP\nYou can also use environment variables to specify container manager\n.IP\n.EX\nDBX_CONTAINER_MANAGER=\\[dq]docker\\[dq] distrobox\\-list\n.EE\n.SH ENVIRONMENT VARIABLES\n.IP\n.EX\nDBX_CONTAINER_MANAGER\nDBX_SUDO_PROGRAM\n.EE\n[IMAGE: \\c\n.UR https://user-images.githubusercontent.com/598882/147831082-24b5bc2e-b47e-49ac-9b1a-a209478c9705.png\nimage\n.UE \\c\n]\nimage\n"
  },
  {
    "path": "man/man1/distrobox-rm.1",
    "content": ".\\\n.\\\"\n.TH \"DISTROBOX\\-RM\" \"1\" \"Mar 2026\" \"Distrobox\" \"User Manual\"\n.SH NAME\n.IP\n.EX\ndistrobox rm\ndistrobox\\-rm\n.EE\n.SH DESCRIPTION\ndistrobox\\-rm delete one of the available distroboxes.\n.SH SYNOPSIS\n\\f[B]distrobox rm\\f[R]\n.IP\n.EX\n\\-\\-all/\\-a:       delete all distroboxes\n\\-\\-force/\\-f:     force deletion\n\\-\\-rm\\-home:      remove the mounted home if it differs from the host user\\[aq]s one\n\\-\\-root/\\-r:      launch podman/docker/lilipod with root privileges. Note that if you need root this is the preferred\n            way over \\[dq]sudo distrobox\\[dq] (note: if using a program other than \\[aq]sudo\\[aq] for root privileges is necessary,\n            specify it through the DBX_SUDO_PROGRAM env variable, or \\[aq]distrobox_sudo_program\\[aq] config variable)\n\\-\\-help/\\-h:      show this message\n\\-\\-verbose/\\-v:       show more verbosity\n\\-\\-version/\\-V:       show version\n.EE\n.SH EXAMPLES\n.IP\n.EX\ndistrobox\\-rm container\\-name [\\-\\-force] [\\-\\-all]\n.EE\n.PP\nYou can also use environment variables to specify container manager and\nname:\n.IP\n.EX\nDBX_CONTAINER_MANAGER=\\[dq]docker\\[dq] DBX_CONTAINER_NAME=test\\-alpine distrobox\\-rm\n.EE\n.SH ENVIRONMENT VARIABLES\n.IP\n.EX\nDBX_CONTAINER_MANAGER\nDBX_CONTAINER_NAME\nDBX_NON_INTERACTIVE\nDBX_SUDO_PROGRAM\n.EE\n"
  },
  {
    "path": "man/man1/distrobox-stop.1",
    "content": ".\\\n.\\\"\n.TH \"DISTROBOX\\-STOP\" \"1\" \"Mar 2026\" \"Distrobox\" \"User Manual\"\n.SH NAME\n.IP\n.EX\ndistrobox stop\ndistrobox\\-stop\n.EE\n.SH DESCRIPTION\ndistrobox\\-stop stop a running distrobox.\n.PP\nDistroboxes are left running, even after exiting out of them, so that\nsubsequent enters are really quick.\nThis is how they can be stopped.\n.SH SYNOPSIS\n\\f[B]distrobox stop\\f[R]\n.IP\n.EX\n\\-\\-all/\\-a:       stop all distroboxes\n\\-\\-yes/\\-Y:       non\\-interactive, stop without asking\n\\-\\-help/\\-h:      show this message\n\\-\\-root/\\-r:      launch podman/docker/lilipod with root privileges. Note that if you need root this is the preferred\n            way over \\[dq]sudo distrobox\\[dq] (note: if using a program other than \\[aq]sudo\\[aq] for root privileges is necessary,\n            specify it through the DBX_SUDO_PROGRAM env variable, or \\[aq]distrobox_sudo_program\\[aq] config variable)\n\\-\\-verbose/\\-v:       show more verbosity\n\\-\\-version/\\-V:       show version\n.EE\n.SH EXAMPLES\n.IP\n.EX\ndistrobox\\-stop container\\-name1 container\\-name2\ndistrobox\\-stop container\\-name\ndistrobox\\-stop \\-\\-all\n.EE\n.PP\nYou can also use environment variables to specify container manager and\nname:\n.IP\n.EX\nDBX_CONTAINER_MANAGER=\\[dq]docker\\[dq] DBX_CONTAINER_NAME=test\\-alpine distrobox\\-stop\n.EE\n.SH ENVIRONMENT VARIABLES\n.IP\n.EX\nDBX_CONTAINER_MANAGER\nDBX_CONTAINER_NAME\nDBX_NON_INTERACTIVE\nDBX_SUDO_PROGRAM\n.EE\n"
  },
  {
    "path": "man/man1/distrobox-upgrade.1",
    "content": ".\\\n.\\\"\n.TH \"DISTROBOX\\-UPGRADE\" \"1\" \"Mar 2026\" \"Distrobox\" \"User Manual\"\n.SH NAME\n.IP\n.EX\ndistrobox\\-upgrade\n.EE\n.SH DESCRIPTION\ndistrobox\\-upgrade will enter the specified list of containers and will\nperform an upgrade using the container\\[cq]s package manager.\n.SH SYNOPSIS\n\\f[B]distrobox upgrade\\f[R]\n.IP\n.EX\n\\-\\-help/\\-h:      show this message\n\\-\\-all/\\-a:       perform for all distroboxes\n\\-\\-running:      perform only for running distroboxes\n\\-\\-root/\\-r:      launch podman/docker/lilipod with root privileges. Note that if you need root this is the preferred\n            way over \\[dq]sudo distrobox\\[dq] (note: if using a program other than \\[aq]sudo\\[aq] for root privileges is necessary,\n            specify it through the DBX_SUDO_PROGRAM env variable, or \\[aq]distrobox_sudo_program\\[aq] config variable)\n\\-\\-verbose/\\-v:       show more verbosity\n\\-\\-version/\\-V:       show version\n.EE\n.SH EXAMPLES\nUpgrade all distroboxes\n.IP\n.EX\ndistrobox\\-upgrade \\-\\-all\n.EE\n.PP\nUpgrade all running distroboxes\n.IP\n.EX\ndistrobox\\-upgrade \\-\\-all \\-\\-running\n.EE\n.PP\nUpgrade a specific distrobox\n.IP\n.EX\ndistrobox\\-upgrade alpine\\-linux \n.EE\n.PP\nUpgrade a list of distroboxes\n.IP\n.EX\ndistrobox\\-upgrade alpine\\-linux ubuntu22 my\\-distrobox123\n.EE\n.PP\n\\f[B]Automatically update all distro\\f[R]\n.PP\nYou can create a systemd service to perform distrobox\\-upgrade\nautomatically, this example shows how to run it daily:\n.PP\n\\[ti]/.config/systemd/user/distrobox\\-upgrade.service\n.IP\n.EX\n[Unit]\nDescription=distrobox\\-upgrade Automatic Update\n\n[Service]\nType=simple\nExecStart=distrobox\\-upgrade \\-\\-all\nStandardOutput=null\n.EE\n.PP\n\\[ti]/.config/systemd/user/distrobox\\-upgrade.timer\n.IP\n.EX\n[Unit]\nDescription=distrobox\\-upgrade Automatic Update Trigger\n\n[Timer]\nOnBootSec=1h\nOnUnitInactiveSec=1d\n\n[Install]\nWantedBy=timers.target\n.EE\n.PP\nThen simply do a\n\\f[CR]systemctl \\-\\-user daemon\\-reload && systemctl \\-\\-user enable \\-\\-now distrobox\\-upgrade.timer\\f[R]\n"
  },
  {
    "path": "man/man1/distrobox.1",
    "content": "'\\\" t\n.\\\n.\\\"\n.TH \"DISTROBOX\\-ASSEMBLE\" \"1\" \"Mar 2026\" \"Distrobox\" \"User Manual\"\n.SH NAME\n.IP\n.EX\ndistrobox assemble\ndistrobox\\-assemble\n.EE\n.SH DESCRIPTION\ndistrobox\\-assemble takes care of creating or destroying containers in\nbatches, based on a manifest file.\nThe manifest file by default is \\f[CR]./distrobox.ini\\f[R], but can be\nspecified using the \\f[CR]\\-\\-file\\f[R] flag.\n.SH SYNOPSIS\n\\f[B]distrobox assemble\\f[R]\n.IP\n.EX\n\\-\\-file:         path or URL to the distrobox manifest/ini file\n\\-\\-name/\\-n:      run against a single entry in the manifest/ini file\n\\-\\-replace/\\-R:       replace already existing distroboxes with matching names\n\\-\\-dry\\-run/\\-d:       only print the container manager command generated\n\\-\\-verbose/\\-v:       show more verbosity\n\\-\\-version/\\-V:       show version\n.EE\n.SH EXAMPLES\nThis is an example manifest file to create two containers:\n.IP\n.EX\n[ubuntu]\nadditional_packages=\\[dq]git vim tmux nodejs\\[dq]\nimage=ubuntu:latest\ninit=false\nnvidia=false\npull=true\nroot=false\nreplace=true\nstart_now=false\n\n# You can add comments using this #\n[arch] # also inline comments are supported\nadditional_packages=\\[dq]git vim tmux nodejs\\[dq]\nhome=/tmp/home\nimage=archlinux:latest\ninit=false\nstart_now=true\ninit_hooks=\\[dq]touch /init\\-normal\\[dq]\nnvidia=true\npre_init_hooks=\\[dq]touch /pre\\-init\\[dq]\npull=true\nroot=false\nreplace=false\nvolume=\\[dq]/tmp/test:/run/a /tmp/test:/run/b\\[dq]\n.EE\n.PP\n\\f[B]Create\\f[R]\n.PP\nWe can bring them up simply using\n.IP\n.EX\ndistrobox assemble create\n.EE\n.PP\nIf the file is called \\f[CR]distrobox.ini\\f[R] and is in the same\ndirectory you\\[cq]re launching the command, no further arguments are\nneeded.\nYou can specify a custom path for the file using\n.IP\n.EX\ndistrobox assemble create \\-\\-file /my/custom/path.ini\n.EE\n.PP\nOr even specify a remote file, by using an URL:\n.IP\n.EX\ndistrobox\\-assemble create \\-\\-file https://raw.githubusercontent.com/89luca89/dotfiles/master/distrobox.ini\n.EE\n.PP\n\\f[B]Replace\\f[R]\n.PP\nBy default, \\f[CR]distrobox assemble\\f[R] will replace a container only\nif \\f[CR]replace=true\\f[R] is specified in the manifest file.\n.PP\nIn the example of the manifest above, the ubuntu container will always\nbe replaced when running \\f[CR]distrobox assemble create\\f[R], while the\narch container will not.\n.PP\nTo force a replace for all containers in a manifest use the\n\\f[CR]\\-\\-replace\\f[R] flag\n.IP\n.EX\ndistrobox assemble create \\-\\-replace [\\-\\-file my/custom/path.ini]\n.EE\n.PP\n\\f[B]Remove\\f[R]\n.PP\nWe can bring down all the containers in a manifest file by simply doing\n.IP\n.EX\ndistrobox assemble rm\n.EE\n.PP\nOr using a custom path for the ini file\n.IP\n.EX\ndistrobox assemble rm \\-\\-file my/custom/path.ini\n.EE\n.PP\n\\f[B]Test\\f[R]\n.PP\nYou can always test what distrobox \\f[B]would do\\f[R] by using the\n\\f[CR]\\-\\-dry\\-run\\f[R] flag.\nThis command will only print what commands distrobox would do without\nactually running them.\n.PP\n\\f[B]Clone\\f[R]\n.PP\n\\f[B]Disclaimer\\f[R]: You need to start the container once to ensure it\nis fully initialized and created before cloning it.\nThe container being copied must also be stopped before the cloning\nprocess can proceed.\n.PP\n\\f[B]Available options\\f[R]\n.PP\nThis is a list of available options with the corresponding type:\n.PP\nTypes legend:\n.IP \\[bu] 2\nbool: true or false\n.IP \\[bu] 2\nstring: a single string, for example\n\\f[CR]home=\\[dq]/home/luca\\-linux/dbox\\[dq]\\f[R]\n.IP \\[bu] 2\nstring_list: multiple strings, for example\n\\f[CR]additional_packages=\\[dq]htop vim git\\[dq]\\f[R].\nNote that \\f[CR]string_list\\f[R] can be declared multiple times to be\ncompounded:\n.RS 2\n.IP\n.EX\n\\f[B][ubuntu]\\f[R]\nimage=ubuntu:latest\nadditional_packages=\\[dq]git vim tmux nodejs\\[dq]\nadditional_packages=\\[dq]htop iftop iotop\\[dq]\nadditional_packages=\\[dq]zsh fish\\[dq]\n.EE\n.RE\n.PP\n.TS\ntab(@);\nlw(23.3n) lw(23.3n) lw(23.3n).\nT{\nFlag Name\nT}@T{\nType\nT}@T{\nT}\n_\nT{\nadditional_flags\nT}@T{\nstring_list\nT}@T{\nAdditional flags to pass to the container manager\nT}\nT{\nadditional_packages\nT}@T{\nstring_list\nT}@T{\nAdditional packages to install inside the container\nT}\nT{\nhome\nT}@T{\nstring\nT}@T{\nWhich home directory should the container use\nT}\nT{\nhostname\nT}@T{\nstring\nT}@T{\nSet hostname of the container\nT}\nT{\nimage\nT}@T{\nstring\nT}@T{\nWhich image should the container use, look here for a list\nT}\nT{\nclone\nT}@T{\nstring\nT}@T{\nName of the Distrobox container to use as the base for a new container\n(the container must be stopped).\nT}\nT{\ninclude\nT}@T{\nstring\nT}@T{\nName of the entry in the manifest to include in the current definition.\nT}\nT{\ninit_hooks\nT}@T{\nstring_list\nT}@T{\nCommands to run inside the container, after the packages setup\nT}\nT{\npre_init_hooks\nT}@T{\nstring_list\nT}@T{\nCommands to run inside the container, before the packages setup\nT}\nT{\nvolume\nT}@T{\nstring_list\nT}@T{\nAdditional volumes to mount inside the containers\nT}\nT{\nexported_apps\nT}@T{\nstring_list\nT}@T{\nApp names or desktopfile paths to export\nT}\nT{\nexported_bins\nT}@T{\nstring_list\nT}@T{\nBinaries to export\nT}\nT{\nexported_bins_path\nT}@T{\nstring\nT}@T{\nOptional path where to export binaries (default: $HOME/.local/bin)\nT}\nT{\nentry\nT}@T{\nbool\nT}@T{\nGenerate an entry for the container in the app list (default: false)\nT}\nT{\nstart_now\nT}@T{\nbool\nT}@T{\nStart the container immediately (default: false)\nT}\nT{\ninit\nT}@T{\nbool\nT}@T{\nSpecify if this is an initful container (default: false)\nT}\nT{\nnvidia\nT}@T{\nbool\nT}@T{\nSpecify if you want to enable NVidia drivers integration (default:\nfalse)\nT}\nT{\npull\nT}@T{\nbool\nT}@T{\nSpecify if you want to pull the image every time (default: false)\nT}\nT{\nroot\nT}@T{\nbool\nT}@T{\nSpecify if the container is rootful (default: false)\nT}\nT{\nunshare_groups\nT}@T{\nbool\nT}@T{\nSpecify if the container should unshare users additional groups\n(default: false)\nT}\nT{\nunshare_ipc\nT}@T{\nbool\nT}@T{\nSpecify if the container should unshare the ipc namespace (default:\nfalse)\nT}\nT{\nunshare_netns\nT}@T{\nbool\nT}@T{\nSpecify if the container should unshare the network namespace (default:\nfalse)\nT}\nT{\nunshare_process\nT}@T{\nbool\nT}@T{\nSpecify if the container should unshare the process (pid) namespace\n(default: false)\nT}\nT{\nunshare_devsys\nT}@T{\nbool\nT}@T{\nSpecify if the container should unshare /dev (default: false)\nT}\nT{\nunshare_all\nT}@T{\nbool\nT}@T{\nSpecify if the container should unshare all the previous options\n(default: false)\nT}\n.TE\n.PP\nThe \\f[CR]include\\f[R] option copies the attributes of a definition into\nanother one.\nRecursive inclusions are allowed.\nIt operates on the manifest file and the consequent \\f[CR]distrobox\\f[R]\ncontainers have no relation of any kind.\nPlease be aware that attributes in the including definition will not\noverride nor shadow the ones in the included definition, they will\nsimply duplicate.\n.PP\nFor further explanation of each of the other options in the list, take a\nlook at the distrobox create usage, each option corresponds to one of\nthe \\f[CR]create\\f[R] flags.\n.PP\n\\f[B]Advanced example\\f[R]\n.IP\n.EX\n[tumbleweed_distrobox]\nimage=registry.opensuse.org/opensuse/distrobox\npull=true\nadditional_packages=\\[dq]acpi bash\\-completion findutils iproute iputils sensors inotify\\-tools unzip\\[dq]\nadditional_packages=\\[dq]net\\-tools nmap openssl procps psmisc rsync man tig tmux tree vim htop xclip yt\\-dlp\\[dq]\nadditional_packages=\\[dq]git git\\-credential\\-libsecret\\[dq]\nadditional_packages=\\[dq]patterns\\-devel\\-base\\-devel_basis\\[dq]\nadditional_packages=\\[dq]ShellCheck ansible\\-lint clang clang\\-tools codespell ctags desktop\\-file\\-utils gcc golang jq python3\\[dq]\nadditional_packages=\\[dq]python3\\-bashate python3\\-flake8 python3\\-mypy python3\\-pipx python3\\-pycodestyle python3\\-pyflakes python3\\-pylint python3\\-python\\-lsp\\-server python3\\-rstcheck python3\\-yapf python3\\-yamllint rustup shfmt\\[dq]\nadditional_packages=\\[dq]kubernetes\\-client helm\\[dq]\ninit_hooks=GOPATH=\\[dq]${HOME}/.local/share/system\\-go\\[dq] GOBIN=/usr/local/bin go install github.com/golangci/golangci\\-lint/cmd/golangci\\-lint\\[at]latest;\ninit_hooks=GOPATH=\\[dq]${HOME}/.local/share/system\\-go\\[dq] GOBIN=/usr/local/bin go install github.com/onsi/ginkgo/v2/ginkgo\\[at]latest;\ninit_hooks=GOPATH=\\[dq]${HOME}/.local/share/system\\-go\\[dq] GOBIN=/usr/local/bin go install golang.org/x/tools/cmd/goimports\\[at]latest;\ninit_hooks=GOPATH=\\[dq]${HOME}/.local/share/system\\-go\\[dq] GOBIN=/usr/local/bin go install golang.org/x/tools/gopls\\[at]latest;\ninit_hooks=GOPATH=\\[dq]${HOME}/.local/share/system\\-go\\[dq] GOBIN=/usr/local/bin go install sigs.k8s.io/kind\\[at]latest;\ninit_hooks=ln \\-sf /usr/bin/distrobox\\-host\\-exec /usr/local/bin/conmon;\ninit_hooks=ln \\-sf /usr/bin/distrobox\\-host\\-exec /usr/local/bin/crun;\ninit_hooks=ln \\-sf /usr/bin/distrobox\\-host\\-exec /usr/local/bin/docker;\ninit_hooks=ln \\-sf /usr/bin/distrobox\\-host\\-exec /usr/local/bin/docker\\-compose;\ninit_hooks=ln \\-sf /usr/bin/distrobox\\-host\\-exec /usr/local/bin/flatpak;\ninit_hooks=ln \\-sf /usr/bin/distrobox\\-host\\-exec /usr/local/bin/podman;\ninit_hooks=ln \\-sf /usr/bin/distrobox\\-host\\-exec /usr/local/bin/xdg\\-open;\nexported_apps=\\[dq]htop\\[dq]\nexported_bins=\\[dq]/usr/bin/htop /usr/bin/git\\[dq]\nexported_bins_path=\\[dq]\\[ti]/.local/bin\\[dq]\n.EE\n.PP\n\\f[B]Clone example\\f[R]\n.IP\n.EX\n[ubuntu]\nadditional_packages=\\[dq]git vim tmux\\[dq]\nimage=ubuntu:latest\ninit=false\nnvidia=false\npull=true\nroot=false\nreplace=true\nstart_now=true\n\n[deno_ubuntu]\nclone=ubuntu\ninit=false\nnvidia=false\npull=true\nroot=false\nreplace=true\nstart_now=true\npre_init_hooks=curl \\-fsSL https://deno.land/install.sh | sh;\n\n[bun_ubuntu]\nclone=ubuntu\ninit=false\nnvidia=false\npull=true\nroot=false\nreplace=true\nstart_now=true\npre_init_hooks=curl \\-fsSL https://bun.sh/install | bash;\n.EE\n.PP\n\\f[B]Custom login shell example\\f[R]\n.IP\n.EX\n[ubuntu]\nimage=ubuntu:latest\npre_init_hooks=\\[dq]export SHELL=/bin/bash;\\[dq]\n.EE\n.PP\n\\f[B]Include example (inherit fields from another distrobox)\\f[R]\n.IP\n.EX\n[ubuntu]\nimage=ubuntu:latest\nadditional_packages=\\[dq]git vim tmux nodejs\\[dq]\nadditional_packages=\\[dq]htop iftop iotop\\[dq]\nadditional_packages=\\[dq]zsh fish\\[dq]\n\n[ubuntu\\-nvidia]\ninclude=ubuntu\nnvidia=true\n.EE\n'\\\" t\n.\\\n.\\\"\n.TH \"DISTROBOX\" \"1\" \"Mar 2026\" \"Distrobox\" \"User Manual\"\n.SH COMPATIBILITY\nThis project \\f[B]does not need a dedicated image\\f[R].\nIt can use any OCI images from docker\\-hub, quay.io, or any registry of\nyour choice.\n.PP\nMany cloud images are stripped down on purpose to save size and may not\ninclude commands such as \\f[CR]which\\f[R], \\f[CR]mount\\f[R],\n\\f[CR]less\\f[R] or \\f[CR]vi\\f[R]).\nAdditional packages can be installed once inside the container.\nWe recommend using your preferred automation tool inside the container\nif you find yourself having to repeatedly create new containers.\nMaintaining your own custom image is also an option.\n.PP\nThe main concern is having basic Linux utilities (\\f[CR]mount\\f[R]),\nbasic user management utilities (\\f[CR]usermod, passwd\\f[R]), and\n\\f[CR]sudo\\f[R] correctly set.\n.SS SUPPORTED CONTAINER MANAGERS\n\\f[CR]distrobox\\f[R] can run on either \\f[CR]podman\\f[R],\n\\f[CR]docker\\f[R] or \\c\n.UR https://github.com/89luca89/lilipod\n\\f[CR]lilipod\\f[R]\n.UE \\c\n.PP\nIt depends either on \\f[CR]podman\\f[R] configured in\n\\f[CR]rootless mode\\f[R] or on \\f[CR]docker\\f[R] configured without sudo\n(follow \\c\n.UR https://docs.docker.com/engine/install/linux-postinstall/\nTHESE instructions\n.UE \\c\n)\n.IP \\[bu] 2\nMinimum podman version: \\f[B]2.1.0\\f[R]\n.IP \\[bu] 2\nMinimum docker client version: \\f[B]19.03.15\\f[R]\n.IP \\[bu] 2\nMinimum lilipod version: \\f[B]v0.0.1\\f[R]\n.PP\nFollow the official installation guide here:\n.IP \\[bu] 2\n\\c\n.UR https://podman.io/getting-started/installation\n.UE \\c\n.IP \\[bu] 2\n\\c\n.UR https://docs.docker.com/engine/install\n.UE \\c\n.IP \\[bu] 2\n\\c\n.UR https://docs.docker.com/engine/install/linux-postinstall/\n.UE \\c\n.SS CONTAINERS DISTROS\nDistrobox guests tested successfully with the following container\nimages:\n.PP\n.TS\ntab(@);\nlw(23.3n) lw(23.3n) lw(23.3n).\nT{\nDistro\nT}@T{\nVersion\nT}@T{\nImages\nT}\n_\nT{\nAlmaLinux (Toolbox)\nT}@T{\n8  9\nT}@T{\nquay.io/toolbx\\-images/almalinux\\-toolbox:8 \nquay.io/toolbx\\-images/almalinux\\-toolbox:9 \nquay.io/toolbx\\-images/almalinux\\-toolbox:latest\nT}\nT{\nAlpine (Toolbox)\nT}@T{\n3.20  3.21  3.22  edge\nT}@T{\nquay.io/toolbx\\-images/alpine\\-toolbox:3.20 \nquay.io/toolbx\\-images/alpine\\-toolbox:3.21 \nquay.io/toolbx\\-images/alpine\\-toolbox:3.22 \nquay.io/toolbx\\-images/alpine\\-toolbox:edge \nquay.io/toolbx\\-images/alpine\\-toolbox:latest\nT}\nT{\nAmazonLinux (Toolbox)\nT}@T{\n2  2022\nT}@T{\nquay.io/toolbx\\-images/amazonlinux\\-toolbox:2 \nquay.io/toolbx\\-images/amazonlinux\\-toolbox:2023 \nquay.io/toolbx\\-images/amazonlinux\\-toolbox:latest\nT}\nT{\nArchlinux (Toolbox)\nT}@T{\nT}@T{\nquay.io/toolbx/arch\\-toolbox:latest\nT}\nT{\nALT Linux\nT}@T{\np10  p11  sisyphus\nT}@T{\ndocker.io/library/alt:p10  docker.io/library/alt:p11 \ndocker.io/library/alt:sisyphus\nT}\nT{\nBazzite Arch\nT}@T{\nT}@T{\nghcr.io/ublue\\-os/bazzite\\-arch:latest \nghcr.io/ublue\\-os/bazzite\\-arch\\-gnome:latest\nT}\nT{\nCentos (Toolbox)\nT}@T{\nstream9  stream10\nT}@T{\nquay.io/toolbx\\-images/centos\\-toolbox:stream9 \nquay.io/toolbx\\-images/centos\\-toolbox:stream10 \nquay.io/toolbx\\-images/centos\\-toolbox:latest\nT}\nT{\nDebian (Toolbox)\nT}@T{\n11  12  13  testing  unstable\nT}@T{\nquay.io/toolbx\\-images/debian\\-toolbox:11 \nquay.io/toolbx\\-images/debian\\-toolbox:12 \nquay.io/toolbx\\-images/debian\\-toolbox:13 \nquay.io/toolbx\\-images/debian\\-toolbox:testing \nquay.io/toolbx\\-images/debian\\-toolbox:unstable \nquay.io/toolbx\\-images/debian\\-toolbox:latest\nT}\nT{\nFedora (Toolbox)\nT}@T{\n38  39  40  41  42  43  Rawhide\nT}@T{\nregistry.fedoraproject.org/fedora\\-toolbox:38 \nregistry.fedoraproject.org/fedora\\-toolbox:39 \nregistry.fedoraproject.org/fedora\\-toolbox:40 \nquay.io/fedora/fedora\\-toolbox:41  quay.io/fedora/fedora\\-toolbox:42 \nquay.io/fedora/fedora\\-toolbox:43 \nquay.io/fedora/fedora\\-toolbox:rawhide\nT}\nT{\nopenSUSE (Toolbox)\nT}@T{\nT}@T{\nregistry.opensuse.org/opensuse/distrobox:latest\nT}\nT{\nRedHat (Toolbox)\nT}@T{\n8  9\nT}@T{\nregistry.access.redhat.com/ubi8/toolbox \nregistry.access.redhat.com/ubi9/toolbox\nT}\nT{\nRocky Linux (Toolbox)\nT}@T{\n8  9\nT}@T{\nquay.io/toolbx\\-images/rockylinux\\-toolbox:8 \nquay.io/toolbx\\-images/rockylinux\\-toolbox:9 \nquay.io/toolbx\\-images/rockylinux\\-toolbox:latest\nT}\nT{\nUbuntu (Toolbox)\nT}@T{\n16.04  18.04  20.04  22.04  24.04\nT}@T{\nquay.io/toolbx/ubuntu\\-toolbox:16.04 \nquay.io/toolbx/ubuntu\\-toolbox:18.04 \nquay.io/toolbx/ubuntu\\-toolbox:20.04 \nquay.io/toolbx/ubuntu\\-toolbox:22.04 \nquay.io/toolbx/ubuntu\\-toolbox:24.04 \nquay.io/toolbx/ubuntu\\-toolbox:latest\nT}\nT{\nChainguard Wolfi (Toolbox)\nT}@T{\nT}@T{\nquay.io/toolbx\\-images/wolfi\\-toolbox:latest\nT}\nT{\nUblue\nT}@T{\nubuntu\\-toolbox  fedora\\-toolbox  wolfi\\-toolbox  archlinux\\-distrobox\nT}@T{\nghcr.io/ublue\\-os/ubuntu\\-toolbox  ghcr.io/ublue\\-os/fedora\\-toolbox \nghcr.io/ublue\\-os/wolfi\\-toolbox  ghcr.io/ublue\\-os/arch\\-toolbox\nT}\nT{\nT}@T{\nT}@T{\nT}\nT{\nAlmaLinux\nT}@T{\n8  8\\-minimal  9  9\\-minimal\nT}@T{\ndocker.io/library/almalinux:8  docker.io/library/almalinux:9\nT}\nT{\nAlpine Linux\nT}@T{\n3.20  3.21  3.22  edge\nT}@T{\ndocker.io/library/alpine:3.20  docker.io/library/alpine:3.21 \ndocker.io/library/alpine:3.22  docker.io/library/alpine:edge \ndocker.io/library/alpine:latest\nT}\nT{\nAmazonLinux\nT}@T{\n1  2  2023\nT}@T{\npublic.ecr.aws/amazonlinux/amazonlinux:1 \npublic.ecr.aws/amazonlinux/amazonlinux:2 \npublic.ecr.aws/amazonlinux/amazonlinux:2023\nT}\nT{\nArchlinux\nT}@T{\nT}@T{\ndocker.io/library/archlinux:latest\nT}\nT{\nBlackarch\nT}@T{\nT}@T{\ndocker.io/blackarchlinux/blackarch:latest\nT}\nT{\nCentOS Stream\nT}@T{\n8  9  10\nT}@T{\nquay.io/centos/centos:stream8  quay.io/centos/centos:stream9 \nquay.io/centos/centos:stream10\nT}\nT{\nChainguard Wolfi\nT}@T{\nT}@T{\ncgr.dev/chainguard/wolfi\\-base:latest\nT}\nT{\nChimera Linux\nT}@T{\nT}@T{\ndocker.io/chimeralinux/chimera:latest\nT}\nT{\nCrystal Linux\nT}@T{\nT}@T{\nregistry.gitlab.com/crystal\\-linux/misc/docker:latest\nT}\nT{\nDebian\nT}@T{\n7  8  9  10  11  12  13\nT}@T{\ndocker.io/debian/eol:wheezy  docker.io/debian/eol:buster \ndocker.io/debian/eol:bullseye \ndocker.io/library/debian:bookworm\\-backports \ndocker.io/library/debian:stable\\-backports\nT}\nT{\nDebian\nT}@T{\nTesting\nT}@T{\ndocker.io/library/debian:testing \ndocker.io/library/debian:testing\\-backports\nT}\nT{\nDebian\nT}@T{\nUnstable\nT}@T{\ndocker.io/library/debian:unstable\nT}\nT{\ndeepin\nT}@T{\n20 (apricot)  23 (beige)\nT}@T{\ndocker.io/linuxdeepin/apricot  docker.io/linuxdeepin/deepin:beige\nT}\nT{\nFedora\nT}@T{\n38  39  40  41  42  43  Rawhide\nT}@T{\nquay.io/fedora/fedora:38  quay.io/fedora/fedora:39 \nquay.io/fedora/fedora:40  quay.io/fedora/fedora:41 \nquay.io/fedora/fedora:42   quay.io/fedora/fedora:43 \nquay.io/fedora/fedora:rawhide\nT}\nT{\nGentoo Linux\nT}@T{\nrolling\nT}@T{\ndocker.io/gentoo/stage3:latest\nT}\nT{\nKDE neon\nT}@T{\nLatest\nT}@T{\ninvent\\-registry.kde.org/neon/docker\\-images/plasma:latest\nT}\nT{\nKali Linux\nT}@T{\nrolling\nT}@T{\ndocker.io/kalilinux/kali\\-rolling:latest\nT}\nT{\nMint\nT}@T{\n22.3\nT}@T{\ndocker.io/linuxmintd/mint22.3\\-amd64\nT}\nT{\nNeurodebian\nT}@T{\nnd120\nT}@T{\ndocker.io/library/neurodebian:nd120\nT}\nT{\nopenSUSE\nT}@T{\nLeap\nT}@T{\nregistry.opensuse.org/opensuse/leap:latest\nT}\nT{\nopenSUSE\nT}@T{\nTumbleweed\nT}@T{\nregistry.opensuse.org/opensuse/distrobox:latest \nregistry.opensuse.org/opensuse/tumbleweed:latest \nregistry.opensuse.org/opensuse/toolbox:latest \nregistry.opensuse.org/opensuse/distrobox\\-bpftrace:latest\nT}\nT{\nOracle Linux\nT}@T{\n8  8\\-slim  9  9\\-slim  10  10\\-slim\nT}@T{\ncontainer\\-registry.oracle.com/os/oraclelinux:8 \ncontainer\\-registry.oracle.com/os/oraclelinux:8\\-slim \ncontainer\\-registry.oracle.com/os/oraclelinux:9 \ncontainer\\-registry.oracle.com/os/oraclelinux:9\\-slim \ncontainer\\-registry.oracle.com/os/oraclelinux:10 \ncontainer\\-registry.oracle.com/os/oraclelinux:10\\-slim\nT}\nT{\nRedHat (UBI)\nT}@T{\n7  8  9\nT}@T{\nregistry.access.redhat.com/ubi7/ubi  registry.access.redhat.com/ubi8/ubi\n\\ registry.access.redhat.com/ubi8/ubi\\-init \nregistry.access.redhat.com/ubi8/ubi\\-minimal \nregistry.access.redhat.com/ubi9/ubi \nregistry.access.redhat.com/ubi9/ubi\\-init \nregistry.access.redhat.com/ubi9/ubi\\-minimal\nT}\nT{\nRocky Linux\nT}@T{\n8  8\\-minimal  9\nT}@T{\nquay.io/rockylinux/rockylinux:8 \nquay.io/rockylinux/rockylinux:8\\-minimal \nquay.io/rockylinux/rockylinux:9  quay.io/rockylinux/rockylinux:latest\nT}\nT{\nSlackware\nT}@T{\nT}@T{\ndocker.io/vbatts/slackware:current\nT}\nT{\nSteamOS\nT}@T{\nT}@T{\nghcr.io/linuxserver/steamos:latest\nT}\nT{\nUbuntu\nT}@T{\n14.04  16.04  18.04  20.04  22.04  24.04\nT}@T{\ndocker.io/library/ubuntu:14.04  docker.io/library/ubuntu:16.04 \ndocker.io/library/ubuntu:18.04  docker.io/library/ubuntu:20.04 \ndocker.io/library/ubuntu:22.04  docker.io/library/ubuntu:24.04\nT}\nT{\nVanilla OS\nT}@T{\nVSO\nT}@T{\nghcr.io/vanilla\\-os/vso:main\nT}\nT{\nVoid Linux\nT}@T{\nglibc  musl\nT}@T{\nghcr.io/void\\-linux/void\\-glibc\\-full:latest \nghcr.io/void\\-linux/void\\-musl\\-full:latest\nT}\n.TE\n.PP\nImages marked with \\f[B]Toolbox\\f[R] are tailored images made by the\ncommunity efforts in \\c\n.UR https://github.com/toolbx-images/images\ntoolbx\\-images/images\n.UE \\c\n, so they are more indicated for desktop use, and first setup will take\nless time.\nNote however that if you use a non\\-toolbox preconfigured image, the\n\\f[B]first\\f[R] \\f[CR]distrobox\\-enter\\f[R] you\\[cq]ll perform can take\na while as it will download and install the missing dependencies.\n.PP\nA small time tax to pay for the ability to use any type of image.\nThis will \\f[B]not\\f[R] occur after the first time, \\f[B]subsequent\nenters will be much faster.\\f[R]\n.PP\nNixOS is not a supported container distro, and there are currently no\nplans to bring support to it.\nIf you are looking for unprivileged NixOS environments, we suggest you\nlook into \\c\n.UR https://nixos.org/manual/nix/unstable/command-ref/nix-shell.html\nnix\\-shell\n.UE \\c\n\\ or \\c\n.UR https://github.com/DavHau/nix-portable\nnix portable\n.UE \\c\n.SS NEW DISTRO SUPPORT\nIf your distro of choice is not on the list, open an issue requesting\nsupport for it, we can work together to check if it is possible to add\nsupport for it.\n.PP\nOr just try using it anyway, if it works, open an issue and it will be\nadded to the list!\n.SS OLDER DISTRIBUTIONS\nFor older distributions like CentOS 5, CentOS 6, Debian 6, Ubuntu 12.04,\ncompatibility is not assured.\n.PP\nTheir \\f[CR]libc\\f[R] version is incompatible with kernel releases after\n\\f[CR]>=4.11\\f[R].\nA work around this is to use the \\f[CR]vsyscall=emulate\\f[R] flag in the\nbootloader of the host.\n.PP\nKeep also in mind that mirrors could be down for such old releases, so\nyou will need to build a custom distrobox image to ensure basic\ndependencies are met.\n.SS GPU ACCELERATION SUPPORT\nFor Intel and AMD Gpus, the support is baked in, as the containers will\ninstall their latest available mesa/dri drivers.\n.PP\nFor NVidia, you can use the \\f[CR]\\-\\-nvidia\\f[R] flag during create,\nsee distrobox\\-create documentation to discover how to use it.\n.PP\nAlternatively, you can use the nvidia\\-container\\-toolkit utility to set\nup the integration independently from the distrobox\\[cq]s own flag.\n.\\\n.\\\"\n.TH \"DISTROBOX\\-CREATE\" \"1\" \"Mar 2026\" \"Distrobox\" \"User Manual\"\n.SH NAME\n.IP\n.EX\ndistrobox create\ndistrobox\\-create\n.EE\n.SH DESCRIPTION\ndistrobox\\-create takes care of creating the container with input name\nand image.\nThe created container will be tightly integrated with the host, allowing\nsharing of the HOME directory of the user, external storage, external\nusb devices and graphical apps (X11/Wayland), and audio.\n.SH SYNOPSIS\n\\f[B]distrobox create\\f[R]\n.IP\n.EX\n\\-\\-image/\\-i:     image to use for the container  default: ${container_image_default}\n\\-\\-name/\\-n:      name for the distrobox          default: ${container_name_default}\n\\-\\-hostname:     hostname for the distrobox      default: <container\\-name>.$(uname \\-n)\n\\-\\-pull/\\-p:      pull the image even if it exists locally (implies \\-\\-yes)\n\\-\\-yes/\\-Y:       non\\-interactive, pull images without asking\n\\-\\-root/\\-r:      launch podman/docker/lilipod with root privileges. Note that if you need root this is the preferred\n            way over \\[dq]sudo distrobox\\[dq] (note: if using a program other than \\[aq]sudo\\[aq] for root privileges is necessary,\n            specify it through the DBX_SUDO_PROGRAM env variable, or \\[aq]distrobox_sudo_program\\[aq] config variable)\n\\-\\-clone/\\-c:     name of the distrobox container to use as base for a new container\n            this will be useful to either rename an existing distrobox or have multiple copies\n            of the same environment.\n\\-\\-home/\\-H:      select a custom HOME directory for the container. Useful to avoid host\\[aq]s home littering with temp files.\n\\-\\-volume:       additional volumes to add to the container\n\\-\\-additional\\-flags/\\-a:  additional flags to pass to the container manager command\n\\-\\-additional\\-packages/\\-ap:  additional packages to install during initial container setup\n\\-\\-init\\-hooks:       additional commands to execute at the end of container initialization\n\\-\\-pre\\-init\\-hooks:   additional commands to execute at the start of container initialization\n\\-\\-init/\\-I:      use init system (like systemd) inside the container.\n            this will make host\\[aq]s processes not visible from within the container. (assumes \\-\\-unshare\\-process)\n            may require additional packages depending on the container image: https://github.com/89luca89/distrobox/blob/main/docs/useful_tips.md#using\\-init\\-system\\-inside\\-a\\-distrobox\n\\-\\-nvidia:       try to integrate host\\[aq]s nVidia drivers in the guest\n\\-\\-platform:     specify which platform to use, eg: linux/arm64\n\\-\\-unshare\\-devsys:          do not share host devices and sysfs dirs from host\n\\-\\-unshare\\-groups:          do not forward user\\[aq]s additional groups into the container\n\\-\\-unshare\\-ipc:          do not share ipc namespace with host\n\\-\\-unshare\\-netns:        do not share the net namespace with host\n\\-\\-unshare\\-process:          do not share process namespace with host\n\\-\\-unshare\\-all:          activate all the unshare flags below\n\\-\\-compatibility/\\-C: show list of compatible images\n\\-\\-help/\\-h:      show this message\n\\-\\-no\\-entry:     do not generate a container entry in the application list\n\\-\\-dry\\-run/\\-d:       only print the container manager command generated\n\\-\\-verbose/\\-v:       show more verbosity\n\\-\\-version/\\-V:       show version\n\n\\-\\-absolutely\\-disable\\-root\\-password\\-i\\-am\\-really\\-positively\\-sure: ⚠️ ⚠️  when setting up a rootful distrobox, this will skip user password setup, leaving it blank. ⚠️ ⚠️\n.EE\n.SH COMPATIBILITY\n.IP\n.EX\nfor a list of compatible images and container managers, please consult the man page:\n    man distrobox\n    man distrobox\\-compatibility\nor consult the documentation page on: https://github.com/89luca89/distrobox/blob/main/docs/compatibility.md#containers\\-distros\n.EE\n.SH EXAMPLES\nCreate a distrobox with image alpine, called my\\-alpine container\n.IP\n.EX\ndistrobox create \\-\\-image alpine my\\-alpine\\-container\n.EE\n.PP\nCreate a distrobox from fedora\\-toolbox:35 image\n.IP\n.EX\ndistrobox create \\-\\-image registry.fedoraproject.org/fedora\\-toolbox:35 \\-\\-name fedora\\-toolbox\\-35\n.EE\n.PP\nClone an existing distrobox container\n.IP\n.EX\ndistrobox create \\-\\-clone fedora\\-35 \\-\\-name fedora\\-35\\-copy\n.EE\n.PP\nAlways pull for the new image when creating a distrobox\n.IP\n.EX\ndistrobox create \\-\\-pull \\-\\-image centos:stream9 \\-\\-home \\[ti]/distrobox/centos9\n.EE\n.PP\nAdd additional environment variables to the container\n.IP\n.EX\ndistrobox create \\-\\-image fedora:35 \\-\\-name test \\-\\-additional\\-flags \\[dq]\\-\\-env MY_VAR=value\\[dq]\n.EE\n.PP\nAdd additional volumes to the container\n.IP\n.EX\ndistrobox create \\-\\-image fedora:35 \\-\\-name test \\-\\-volume /opt/my\\-dir:/usr/local/my\\-dir:rw \\-\\-additional\\-flags \\[dq]\\-\\-pids\\-limit \\-1\\[dq]\n.EE\n.PP\nAdd additional packages to the container\n.IP\n.EX\ndistrobox create \\-\\-image alpine:latest \\-\\-name test2 \\-\\-additional\\-packages \\[dq]git tmux vim\\[dq]\n.EE\n.PP\nUse init\\-hooks to perform an action during container startup\n.IP\n.EX\ndistrobox create \\-\\-image alpine:latest \\-\\-name test \\-\\-init\\-hooks \\[dq]touch /var/tmp/test1 && touch /var/tmp/test2\\[dq]\n.EE\n.PP\nUse pre\\-init\\-hooks to perform an action at the beginning of the\ncontainer startup (before any package manager starts)\n.IP\n.EX\ndistrobox create \\-i docker.io/almalinux/8\\-init \\-\\-init \\-\\-name test \\-\\-pre\\-init\\-hooks \\[dq]dnf config\\-manager \\-\\-enable powertools && dnf \\-y install epel\\-release\\[dq]\n.EE\n.PP\nUse init to create a Systemd container (acts similar to an LXC):\n.IP\n.EX\ndistrobox create \\-i ubuntu:latest \\-\\-name test \\-\\-additional\\-packages \\[dq]systemd libpam\\-systemd pipewire\\-audio\\-client\\-libraries\\[dq] \\-\\-init\n.EE\n.PP\nUse init to create a OpenRC container (acts similar to an LXC):\n.IP\n.EX\ndistrobox create \\-i alpine:latest \\-\\-name test \\-\\-additional\\-packages \\[dq]openrc\\[dq] \\-\\-init\n.EE\n.PP\nUse host\\[cq]s NVidia drivers integration\n.IP\n.EX\ndistrobox create \\-\\-image ubuntu:22.04 \\-\\-name ubuntu\\-nvidia \\-\\-nvidia\n.EE\n.PP\nDo not use host\\[cq]s IP inside the container:\n.IP\n.EX\ndistrobox create \\-\\-image ubuntu:latest \\-\\-name test \\-\\-unshare\\-netns\n.EE\n.PP\nCreate a more isolated container, where only the $HOME, basic sockets\nand host\\[cq]s FS (in /run/host) is shared:\n.IP\n.EX\ndistrobox create \\-\\-name unshared\\-test \\-\\-unshare\\-all\n.EE\n.PP\nCreate a more isolated container, with it\\[cq]s own init system, this\nwill act very similar to a full LXC container:\n.IP\n.EX\ndistrobox create \\-\\-name unshared\\-init\\-test \\-\\-unshare\\-all \\-\\-init \\-\\-image fedora:latest\n.EE\n.PP\nUse environment variables to specify container name, image and container\nmanager:\n.IP\n.EX\nDBX_CONTAINER_MANAGER=\\[dq]docker\\[dq] DBX_NON_INTERACTIVE=1 DBX_CONTAINER_NAME=test\\-alpine DBX_CONTAINER_IMAGE=alpine distrobox\\-create\n.EE\n.SH ENVIRONMENT VARIABLES\n.IP\n.EX\nDBX_CONTAINER_ALWAYS_PULL\nDBX_CONTAINER_CUSTOM_HOME\nDBX_CONTAINER_HOME_PREFIX\nDBX_CONTAINER_IMAGE\nDBX_CONTAINER_MANAGER\nDBX_CONTAINER_NAME\nDBX_CONTAINER_HOSTNAME\nDBX_NON_INTERACTIVE\nDBX_SUDO_PROGRAM\n.EE\n.PP\nDBX_CONTAINER_HOME_PREFIX defines where containers\\[cq] home directories\nwill be located.\nIf you define it as \\[ti]/dbx then all future containers\\[cq] home\ndirectories will be \\[ti]/dbx/$container_name\n.SH EXTRA\nThe \\f[CR]\\-\\-additional\\-flags\\f[R] or \\f[CR]\\-a\\f[R] is useful to\nmodify defaults in the container creations.\nFor example:\n.IP\n.EX\ndistrobox create \\-i docker.io/library/archlinux \\-n dev\\-arch\n\npodman container inspect dev\\-arch | jq \\[aq].[0].HostConfig.PidsLimit\\[aq]\n2048\n\ndistrobox rm \\-f dev\\-arch\ndistrobox create \\-i docker.io/library/archlinux \\-n dev\\-arch \\-\\-volume $CBL_TC:/tc \\-\\-additional\\-flags \\[dq]\\-\\-pids\\-limit \\-1\\[dq]\n\npodman container inspect dev\\-arch | jq \\[aq].[0].HostConfig,.PidsLimit\\[aq]\n0\n.EE\n.PP\nAdditional volumes can be specified using the \\f[CR]\\-\\-volume\\f[R]\nflag.\nThis flag follows the same standard as \\f[CR]docker\\f[R] and\n\\f[CR]podman\\f[R] to specify the mount point so\n\\f[CR]\\-\\-volume SOURCE_PATH:DEST_PATH:MODE\\f[R].\n.IP\n.EX\ndistrobox create \\-\\-image docker.io/library/archlinux \\-\\-name dev\\-arch \\-\\-volume /usr/share/:/var/test:ro\n.EE\n.PP\nDuring container creation, it is possible to specify (using the\nadditional\\-flags) some environment variables that will persist in the\ncontainer and be independent from your environment:\n.IP\n.EX\ndistrobox create \\-\\-image fedora:35 \\-\\-name test \\-\\-additional\\-flags \\[dq]\\-\\-env MY_VAR=value\\[dq]\n.EE\n.PP\nThe \\f[CR]\\-\\-init\\-hooks\\f[R] is useful to add commands to the\nentrypoint (init) of the container.\nThis could be useful to create containers with a set of programs already\ninstalled, add users, groups.\n.IP\n.EX\ndistrobox create  \\-\\-image fedora:35 \\-\\-name test \\-\\-init\\-hooks \\[dq]dnf groupinstall \\-y \\[rs]\\[dq]C Development Tools and Libraries\\[rs]\\[dq]\\[dq]\n.EE\n.PP\nThe \\f[CR]\\-\\-init\\f[R] is useful to create a container that will use\nits own separate init system within.\nFor example using:\n.IP\n.EX\ndistrobox create \\-i docker.io/almalinux/8\\-init \\-\\-init \\-\\-name test\ndistrobox create \\-i docker.io/library/debian \\-\\-additional\\-packages \\[dq]systemd\\[dq] \\-\\-init \\-\\-name test\\-debian\n.EE\n.PP\nInside the container we will be able to use normal systemd units:\n.IP\n.EX\n\\[ti]$ distrobox enter test\nuser\\[at]test:\\[ti]$ sudo systemctl enable \\-\\-now sshd\nuser\\[at]test:\\[ti]$ sudo systemctl status sshd\n    ● sshd.service \\- OpenSSH server daemon\n       Loaded: loaded (/usr/lib/systemd/system/sshd.service; enabled; vendor preset: enabled)\n       Active: active (running) since Fri 2022\\-01\\-28 22:54:50 CET; 17s ago\n         Docs: man:sshd(8)\n               man:sshd_config(5)\n     Main PID: 291 (sshd)\n.EE\n.PP\nNote that enabling \\f[CR]\\-\\-init\\f[R] \\f[B]will disable host\\[cq]s\nprocess integration\\f[R].\nFrom within the container you will not be able to see and manage\nhost\\[cq]s processes.\nThis is needed because \\f[CR]/sbin/init\\f[R] must be pid 1.\n.PP\nIf you want to use a non\\-pre\\-create image, you\\[cq]ll need to add the\nadditional package:\n.IP\n.EX\ndistrobox create \\-i alpine:latest \\-\\-init \\-\\-additional\\-packages \\[dq]openrc\\[dq] \\-n test\ndistrobox create \\-i debian:stable \\-\\-init \\-\\-additional\\-packages \\[dq]systemd libpam\\-systemd pipewire\\-audio\\-client\\-libraries\\[dq] \\-n test\ndistrobox create \\-i ubuntu:22.04 \\-\\-init \\-\\-additional\\-packages \\[dq]systemd libpam\\-systemd pipewire\\-audio\\-client\\-libraries\\[dq] \\-n test\ndistrobox create \\-i archlinux:latest \\-\\-init \\-\\-additional\\-packages \\[dq]systemd\\[dq] \\-n test\ndistrobox create \\-i registry.opensuse.org/opensuse/tumbleweed:latest \\-\\-init \\-\\-additional\\-packages \\[dq]systemd\\[dq] \\-n test\ndistrobox create \\-i registry.fedoraproject.org/fedora:39 \\-\\-init \\-\\-additional\\-packages \\[dq]systemd\\[dq] \\-n test\n.EE\n.PP\nThe \\f[CR]\\-\\-init\\f[R] flag is useful to create system containers,\nwhere the container acts more similar to a full VM than an\napplication\\-container.\nInside you\\[cq]ll have a separate init, user\\-session, daemons and so\non.\n.PP\nThe \\f[CR]\\-\\-home\\f[R] flag let\\[cq]s you specify a custom HOME for the\ncontainer.\nNote that this will NOT prevent the mount of the host\\[cq]s home\ndirectory, but will ensure that configs and dotfiles will not litter it.\n.PP\nThe \\f[CR]\\-\\-root\\f[R] flag will let you create a container with real\nroot privileges.\nAt first \\f[CR]enter\\f[R] the user will be required to setup a password.\nThis is done in order to not enable passwordless sudo/su, in a\n\\f[B]rootful\\f[R] container, this is needed because \\f[B]in this mode,\nroot inside the container is also root outside the container!\\f[R]\n.PP\nThe\n\\f[CR]\\-\\-absolutely\\-disable\\-root\\-password\\-i\\-am\\-really\\-positively\\-sure\\f[R]\nwill skip user password setup, leaving it blank.\n\\f[B]This is genuinely dangerous and you really, positively should NOT\nenable this\\f[R].\n.PP\nFrom version 1.4.0 of distrobox, when you create a new container, it\nwill also generate an entry in the applications list.\n.SS NVidia integration\nIf your host has an NVidia gpu, with installed proprietary drivers, you\ncan integrate them with the guests by using the \\f[CR]\\-\\-nvidia\\f[R]\nflag:\n.PP\n\\f[CR]distrobox create \\-\\-nvidia \\-\\-image ubuntu:latest \\-\\-name ubuntu\\-nvidia\\f[R]\n.PP\nBe aware that \\f[B]this is not compatible with non\\-glibc systems\\f[R]\nand \\f[B]needs somewhat newer distributions to work\\f[R].\n.PP\nThis feature was tested working on:\n.IP \\[bu] 2\nAlmalinux\n.IP \\[bu] 2\nArchlinux\n.IP \\[bu] 2\nCentos 7 and newer\n.IP \\[bu] 2\nClearlinux\n.IP \\[bu] 2\nDebian 10 and newer\n.IP \\[bu] 2\nOpenSUSE Leap\n.IP \\[bu] 2\nOpenSUSE Tumbleweed\n.IP \\[bu] 2\nRockylinux\n.IP \\[bu] 2\nUbuntu 18.04 and newer\n.IP \\[bu] 2\nVoid Linux (glibc)\n.\\\n.\\\"\n.TH \"DISTROBOX\\-ENTER\" \"1\" \"Mar 2026\" \"Distrobox\" \"User Manual\"\n.SH NAME\n.IP\n.EX\ndistrobox enter\ndistrobox\\-enter\n.EE\n.SH DESCRIPTION\ndistrobox\\-enter takes care of entering the container with the name\nspecified.\nDefault command executed is your SHELL, but you can specify different\nshells or entire commands to execute.\nIf using it inside a script, an application, or a service, you can\nspecify the \\[en]headless mode to disable tty and interactivity.\n.SH SYNOPSIS\n\\f[B]distrobox enter\\f[R]\n.IP\n.EX\n\\-\\-name/\\-n:      name for the distrobox                      default: my\\-distrobox\n\\-\\-/\\-e:          end arguments execute the rest as command to execute at login   default: default ${USER}\\[aq]s shell\n\\-\\-no\\-tty/\\-T:        do not instantiate a tty\n\\-\\-no\\-workdir/\\-nw:   always start the container from container\\[aq]s home directory\n\\-\\-additional\\-flags/\\-a:  additional flags to pass to the container manager command\n\\-\\-help/\\-h:      show this message\n\\-\\-root/\\-r:      launch podman/docker/lilipod with root privileges. Note that if you need root this is the preferred\n            way over \\[dq]sudo distrobox\\[dq] (note: if using a program other than \\[aq]sudo\\[aq] for root privileges is necessary,\n            specify it through the DBX_SUDO_PROGRAM env variable, or \\[aq]distrobox_sudo_program\\[aq] config variable)\n\\-\\-dry\\-run/\\-d:       only print the container manager command generated\n\\-\\-verbose/\\-v:       show more verbosity\n\\-\\-version/\\-V:       show version\n.EE\n.SH EXAMPLES\nEnter a distrobox named \\[lq]example\\[rq]\n.IP\n.EX\ndistrobox\\-enter example\n.EE\n.PP\nEnter a distrobox specifying a command\n.IP\n.EX\ndistrobox\\-enter \\-\\-name fedora\\-toolbox\\-35 \\-\\- bash \\-l\ndistrobox\\-enter my\\-alpine\\-container \\-\\- sh \\-l\n.EE\n.PP\nUse additional podman/docker/lilipod flags while entering a distrobox\n.IP\n.EX\ndistrobox\\-enter \\-\\-additional\\-flags \\[dq]\\-\\-preserve\\-fds\\[dq] \\-\\-name test \\-\\- bash \\-l\n.EE\n.PP\nSpecify additional environment variables while entering a distrobox\n.IP\n.EX\ndistrobox\\-enter \\-\\-additional\\-flags \\[dq]\\-\\-env MY_VAR=value\\[dq] \\-\\-name test \\-\\- bash \\-l\nMY_VAR=value distrobox\\-enter \\-\\-additional\\-flags \\[dq]\\-\\-preserve\\-fds\\[dq] \\-\\-name test \\-\\- bash \\-l\n.EE\n.PP\nYou can also use environment variables to specify container manager and\ncontainer name:\n.IP\n.EX\nDBX_CONTAINER_MANAGER=\\[dq]docker\\[dq] DBX_CONTAINER_NAME=test\\-alpine distrobox\\-enter\n.EE\n.SH ENVIRONMENT VARIABLES\n.IP\n.EX\nDBX_CONTAINER_NAME\nDBX_CONTAINER_MANAGER\nDBX_SKIP_WORKDIR\nDBX_SUDO_PROGRAM\n.EE\n.SH EXTRA\nThis command is used to enter the distrobox itself.\nPersonally, I just create multiple profiles in my\n\\f[CR]gnome\\-terminal\\f[R] to have multiple distros accessible.\n.PP\nThe \\f[CR]\\-\\-additional\\-flags\\f[R] or \\f[CR]\\-a\\f[R] is useful to\nmodify default command when executing in the container.\nFor example:\n.IP\n.EX\ndistrobox enter \\-n dev\\-arch \\-\\-additional\\-flags \\[dq]\\-\\-env my_var=test\\[dq] \\-\\- printenv &| grep my_var\nmy_var=test\n.EE\n.PP\nThis is possible also using normal env variables:\n.IP\n.EX\nmy_var=test distrobox enter \\-n dev\\-arch \\-\\-additional\\-flags \\-\\- printenv &| grep my_var\nmy_var=test\n.EE\n.PP\nIf you\\[cq]d like to enter a rootful container having distrobox use a\nprogram other than `sudo' to run podman/docker/lilipod as root, such as\n`pkexec' or `doas', you may specify it with the\n\\f[CR]DBX_SUDO_PROGRAM\\f[R] environment variable.\nFor example, to use `doas' to enter a rootful container:\n.IP\n.EX\nDBX_SUDO_PROGRAM=\\[dq]doas\\[dq] distrobox enter \\-n container \\-\\-root\n.EE\n.PP\nAdditionally, in one of the config file paths that distrobox supports,\nsuch as \\f[CR]\\[ti]/.distroboxrc\\f[R], you can also append the line\n\\f[CR]distrobox_sudo_program=\\[dq]doas\\[dq]\\f[R] (for example) to always\nrun distrobox commands involving rootful containers using `doas'.\n.\\\n.\\\"\n.TH \"DISTROBOX\\-EPHEMERAL\" \"1\" \"Mar 2026\" \"Distrobox\" \"User Manual\"\n.SH NAME\n.IP\n.EX\ndistrobox ephemeral\ndistrobox\\-ephemeral\n.EE\n.SH DESCRIPTION\ndistrobox\\-ephemeral creates a temporary distrobox that is automatically\ndestroyed when the command is terminated.\n.SH SYNOPSIS\n\\f[B]distrobox ephemeral\\f[R]\n.IP\n.EX\n\\-\\-root/\\-r:      launch podman/docker/lilipod with root privileges. Note that if you need root this is the preferred\n            way over \\[dq]sudo distrobox\\[dq] (note: if using a program other than \\[aq]sudo\\[aq] for root privileges is necessary,\n            specify it through the DBX_SUDO_PROGRAM env variable, or \\[aq]distrobox_sudo_program\\[aq] config variable)\n\\-\\-verbose/\\-v:       show more verbosity\n\\-\\-help/\\-h:      show this message\n\\-\\-/\\-e:          end arguments execute the rest as command to execute at login   default: default ${USER}\\[aq]s shell\n\\-\\-version/\\-V:       show version\n.EE\n.SH EXAMPLES\n.IP\n.EX\ndistrobox\\-ephemeral \\-\\-image alpine:latest \\-\\- cat /etc/os\\-release\ndistrobox\\-ephemeral \\-\\-root \\-\\-verbose \\-\\-image alpine:latest \\-\\-volume /opt:/opt\n.EE\n.PP\nYou can also use flags from \\f[B]distrobox\\-create\\f[R] to customize the\nephemeral container to run.\n.SH SEE ALSO\n.IP\n.EX\ndistrobox\\-create \\-\\-help\nman distrobox\\-create\n.EE\n.SH ENVIRONMENT VARIABLES\n.IP\n.EX\ndistrobox\\-ephemeral calls distrobox\\-create, SEE ALSO distrobox\\-create(1) for\na list of supported environment variables to use.\n.EE\n.\\\n.\\\"\n.TH \"DISTROBOX\\-EXPORT\" \"1\" \"Mar 2026\" \"Distrobox\" \"User Manual\"\n.SH NAME\n.IP\n.EX\ndistrobox\\-export\n.EE\n.SH DESCRIPTION\n\\f[B]Application and binary exporting\\f[R]\n.PP\ndistrobox\\-export takes care of exporting an app or a binary from the\ncontainer to the host.\n.PP\nThe exported app will be easily available in your normal launcher and it\nwill automatically be launched from the container it is exported from.\n.SH SYNOPSIS\n\\f[B]distrobox\\-export\\f[R]\n.IP\n.EX\n\\-\\-app/\\-a:       name of the application to export or absolute path to desktopfile to export\n\\-\\-bin/\\-b:       absolute path of the binary to export\n\\-\\-list\\-apps:        list applications exported from this container\n\\-\\-list\\-binaries     list binaries exported from this container, use \\-ep to specify custom paths to search\n\\-\\-delete/\\-d:        delete exported application or binary\n\\-\\-export\\-label/\\-el: label to add to exported application name.\n            Use \\[dq]none\\[dq] to disable.\n            Defaults to (on \\[rs]$container_name)\n\\-\\-export\\-path/\\-ep:  path where to export the binary\n\\-\\-extra\\-flags/\\-ef:  extra flags to add to the command\n\\-\\-enter\\-flags/\\-nf:  flags to add to distrobox\\-enter\n\\-\\-sudo/\\-S:      specify if the exported item should be run as sudo\n\\-\\-help/\\-h:      show this message\n\\-\\-verbose/\\-v:       show more verbosity\n\\-\\-version/\\-V:       show version\n.EE\n.PP\nYou may want to install graphical applications or CLI tools in your\ndistrobox.\nUsing \\f[CR]distrobox\\-export\\f[R] from \\f[B]inside\\f[R] the container\nwill let you use them from the host itself.\n.SH EXAMPLES\n.IP\n.EX\ndistrobox\\-export \\-\\-app mpv [\\-\\-extra\\-flags \\[dq]flags\\[dq]] [\\-\\-delete] [\\-\\-sudo]\ndistrobox\\-export \\-\\-bin /path/to/bin [\\-\\-export\\-path \\[ti]/.local/bin] [\\-\\-extra\\-flags \\[dq]flags\\[dq]] [\\-\\-delete] [\\-\\-sudo]\n.EE\n.PP\n\\f[B]App export example\\f[R]\n.IP\n.EX\ndistrobox\\-export \\-\\-app abiword\n.EE\n.PP\nThis tool will simply copy the original \\f[CR].desktop\\f[R] files along\nwith needed icons, add the prefix\n\\f[CR]/usr/local/bin/distrobox\\-enter \\-n distrobox_name \\-e ...\\f[R] to\nthe commands to run, and save them in your home to be used directly from\nthe host as a normal app.\n.IP\n.EX\ndistrobox\\-export \\-\\-app /opt/application/my\\-app.desktop\n.EE\n.PP\nThis will skip searching for the desktopfile in canonical paths, and\njust use the provided file path.\n.PP\n\\f[B]Binary export example\\f[R]\n.IP\n.EX\ndistrobox\\-export \\-\\-bin /usr/bin/code \\-\\-extra\\-flags \\[dq]\\-\\-foreground\\[dq] \\-\\-export\\-path $HOME/.local/bin\n.EE\n.PP\nIn the case of exporting binaries, you will have to specify\n\\f[B]where\\f[R] to export it (\\f[CR]\\-\\-export\\-path\\f[R]) and the tool\nwill create a little wrapper script that will\n\\f[CR]distrobox\\-enter \\-e\\f[R] from the host, the desired binary.\nThis can be handy with the use of \\f[CR]direnv\\f[R] to have different\nversions of the same binary based on your \\f[CR]env\\f[R] or project.\n.PP\nThe exported binaries will be exported in the\n\\[lq]\\[en]export\\-path\\[rq] of choice as a wrapper script that acts\nnaturally both on the host and in the container.\n.PP\n\\f[B]Additional flags\\f[R]\n.PP\nYou can specify additional flags to add to the command, for example if\nyou want to export an electron app, you could add the\n\\[lq]\\[en]foreground\\[rq] flag to the command:\n.IP\n.EX\ndistrobox\\-export \\-\\-app atom \\-\\-extra\\-flags \\[dq]\\-\\-foreground\\[dq]\ndistrobox\\-export \\-\\-bin /usr/bin/vim \\-\\-export\\-path \\[ti]/.local/bin \\-\\-extra\\-flags \\[dq]\\-p\\[dq]\n.EE\n.PP\nThis works for binaries and apps.\nExtra flags are only used then the exported app or binary is used from\nthe host, using them inside the container will not include them.\n.PP\n\\f[B]Unexport\\f[R]\n.PP\nThe option \\[lq]\\[en]delete\\[rq] will un\\-export an app or binary\n.IP\n.EX\ndistrobox\\-export \\-\\-app atom \\-\\-delete\ndistrobox\\-export \\-\\-bin /usr/bin/vim \\-\\-export\\-path \\[ti]/.local/bin \\-\\-delete\n.EE\n.PP\n\\f[B]Run as root in the container\\f[R]\n.PP\nThe option \\[lq]\\[en]sudo\\[rq] will launch the exported item as root\ninside the distrobox.\n.PP\n\\f[B]Notes\\f[R]\n.PP\nNote you can use \\[en]app OR \\[en]bin but not together.\n[IMAGE: \\c\n.UR https://user-images.githubusercontent.com/598882/144294795-c7785620-bf68-4d1b-b251-1e1f0a32a08d.png\napp\\-export\n.UE \\c\n]\napp\\-export\n.PP\nNOTE: some electron apps such as vscode and atom need additional flags\nto work from inside the container, use the \\f[CR]\\-\\-extra\\-flags\\f[R]\noption to provide a series of flags, for example:\n.PP\n\\f[CR]distrobox\\-export \\-\\-app atom \\-\\-extra\\-flags \\[dq]\\-\\-foreground\\[dq]\\f[R]\n.\\\n.\\\"\n.TH \"DISTROBOX\\-GENERATE\\-ENTRY\" \"1\" \"Mar 2026\" \"Distrobox\" \"User Manual\"\n.SH NAME\n.IP\n.EX\ndistrobox generate\\-entry\n.EE\n.SH DESCRIPTION\ndistrobox\\-generate\\-entry will create a desktop icon for one of the\navailable distroboxes.\nThis will be then deleted when you remove the matching distrobox.\n.SH SYNOPSIS\n\\f[B]distrobox generate\\-entry\\f[R]\n.IP\n.EX\n\\-\\-help/\\-h:      show this message\n\\-\\-all/\\-a:       perform for all distroboxes\n\\-\\-delete/\\-d:        delete the entry\n\\-\\-icon/\\-i:      specify a custom icon [/path/to/icon] (default auto)\n\\-\\-root/\\-r:      perform on rootful distroboxes\n\\-\\-verbose/\\-v:       show more verbosity\n\\-\\-version/\\-V:       show version\n.EE\n.SH EXAMPLES\nGenerate an entry for a container\n.IP\n.EX\ndistrobox generate\\-entry my\\-container\\-name\n.EE\n.PP\nSpecify a custom icon for the entry\n.IP\n.EX\ndistrobox generate\\-entry my\\-container\\-name \\-\\-icon /path/to/icon.png\n.EE\n.PP\nGenerate an entry for all distroboxes\n.IP\n.EX\ndistrobox generate\\-entry \\-\\-all\n.EE\n.PP\nDelete an entry\n.IP\n.EX\ndistrobox generate\\-entry container\\-name \\-\\-delete\n.EE\n.\\\n.\\\"\n.TH \"DISTROBOX\\-HOST\\-EXEC\" \"1\" \"Mar 2026\" \"Distrobox\" \"User Manual\"\n.SH NAME\n.IP\n.EX\ndistrobox\\-host\\-exec\n.EE\n.SH DESCRIPTION\ndistrobox\\-host\\-exec lets one execute command on the host, while inside\nof a container.\n.PP\nUnder the hood, distrobox\\-host\\-exec uses \\f[CR]host\\-spawn\\f[R] a\nproject that lets us execute commands back on the host.\nIf the tool is not found the user will be prompted to install it.\n.SH SYNOPSIS\nJust pass to \\[lq]distrobox\\-host\\-exec\\[rq] any command and all its\narguments, if any.\n.IP\n.EX\n\\-\\-help/\\-h:      show this message\n\\-\\-verbose/\\-v:       show more verbosity\n\\-\\-version/\\-V:       show version\n\\-\\-yes/\\-Y:       Automatically answer yes to prompt:\n                            host\\-spawn will be installed on the guest system\n                            if host\\-spawn is not detected.\n                            This behaviour is default when running in a non\\-interactive shell.\n.EE\n.PP\nIf no command is provided, it will execute \\[lq]$SHELL\\[rq].\n.PP\nAlternatively, you can symlink a command name to\n\\f[CR]distrobox\\-host\\-exec\\f[R] and then call that command by its name\non the host, while inside of a container.\n.SH EXAMPLES\n.SS Run individual commands\n.IP\n.EX\ndistrobox\\-host\\-exec ls\ndistrobox\\-host\\-exec bash \\-l\ndistrobox\\-host\\-exec flatpak run org.mozilla.firefox\ndistrobox\\-host\\-exec podman ps \\-a\n.EE\n.SS Drop into host shell\n.IP\n.EX\n\\[ti]$: distrobox\\-host\\-exec # No command, executes \\[dq]$SHELL\\[dq] on the host\n\\[ti]$: distrobox\\-host\\-exec # This command now runs on the host\nYou must run  distrobox\\-host\\-exec inside a container!\n.EE\n.SS Symlinking host commands\nUse the host command name to create a symlink to\n\\f[CR]distrobox\\-host\\-exec\\f[R].\nYou can then call the host command from within the container.\n.IP\n.EX\n\\[ti]$: git # We do not have git in the container\nbash: git: command not found\n\\[ti]$: sudo ln \\-s /usr/bin/distrobox\\-host\\-exec /usr/local/bin/git\n\\[ti]$: git version\ngit version 2.51.1\n.EE\n.PP\nYou can control podman on the host from within the container as follows:\n.IP\n.EX\n\\[ti]$: ln \\-s /usr/bin/distrobox\\-host\\-exec /usr/local/bin/podman\n\\[ti]$: ls \\-l /usr/local/bin/podman\nlrwxrwxrwx. 1 root root 51 Jul 11 19:26 /usr/local/bin/podman \\-> /usr/bin/distrobox\\-host\\-exec\n\\[ti]$: podman version\n\\&...this is executed on host...\n.EE\n.\\\n.\\\"\n.TH \"DISTROBOX\\-INIT\" \"1\" \"Mar 2026\" \"Distrobox\" \"User Manual\"\n.SH NAME\n.IP\n.EX\ndistrobox\\-init\n.EE\n.SH DESCRIPTION\n\\f[B]Init the distrobox (not to be launched manually)\\f[R]\n.PP\ndistrobox\\-init is the entrypoint of a created distrobox.\nNote that this HAS to run from inside a distrobox, will not work if you\nrun it from your host.\n.PP\n\\f[B]This is not intended to be used manually, but instead used by\ndistrobox\\-create to set up the container\\[cq]s entrypoint.\\f[R]\n.PP\ndistrobox\\-init will take care of installing missing dependencies (eg.\nsudo), set up the user and groups, mount directories from the host to\nensure the tight integration.\n.SH SYNOPSIS\n\\f[B]distrobox\\-init\\f[R]\n.IP\n.EX\n\\-\\-name/\\-n:      user name\n\\-\\-user/\\-u:      uid of the user\n\\-\\-group/\\-g:     gid of the user\n\\-\\-home/\\-d:      path/to/home of the user\n\\-\\-help/\\-h:      show this message\n\\-\\-additional\\-packages:  packages to install in addition\n\\-\\-init/\\-I:      whether to use or not init\n\\-\\-pre\\-init\\-hooks:   commands to execute prior to init\n\\-\\-nvidia:       try to integrate host\\[aq]s nVidia drivers in the guest\n\\-\\-upgrade/\\-U:       run init in upgrade mode\n\\-\\-verbose/\\-v:       show more verbosity\n\\-\\-version/\\-V:       show version\n\\-\\-:         end arguments execute the rest as command to execute during init\n.EE\n.SH EXAMPLES\n.IP\n.EX\ndistrobox\\-init \\-\\-name test\\-user \\-\\-user 1000 \\-\\-group 1000 \\-\\-home /home/test\\-user\ndistrobox\\-init \\-\\-upgrade\n.EE\n.\\\n.\\\"\n.TH \"DISTROBOX\\-LIST\" \"1\" \"Mar 2026\" \"Distrobox\" \"User Manual\"\n.SH NAME\n.IP\n.EX\ndistrobox list\ndistrobox\\-list\n.EE\n.SH DESCRIPTION\ndistrobox\\-list lists available distroboxes.\nIt detects them and lists them separately from the rest of normal\ncontainers.\n.SH SYNOPSIS\n\\f[B]distrobox list\\f[R]\n.IP\n.EX\n\\-\\-help/\\-h:      show this message\n\\-\\-no\\-color:     disable color formatting\n\\-\\-root/\\-r:      launch podman/docker/lilipod with root privileges. Note that if you need root this is the preferred\n            way over \\[dq]sudo distrobox\\[dq] (note: if using a program other than \\[aq]sudo\\[aq] for root privileges is necessary,\n            specify it through the DBX_SUDO_PROGRAM env variable, or \\[aq]distrobox_sudo_program\\[aq] config variable)\n\\-\\-verbose/\\-v:       show more verbosity\n\\-\\-version/\\-V:       show version\n.EE\n.SH EXAMPLES\n.IP\n.EX\ndistrobox\\-list\n.EE\n.PP\nYou can also use environment variables to specify container manager\n.IP\n.EX\nDBX_CONTAINER_MANAGER=\\[dq]docker\\[dq] distrobox\\-list\n.EE\n.SH ENVIRONMENT VARIABLES\n.IP\n.EX\nDBX_CONTAINER_MANAGER\nDBX_SUDO_PROGRAM\n.EE\n[IMAGE: \\c\n.UR https://user-images.githubusercontent.com/598882/147831082-24b5bc2e-b47e-49ac-9b1a-a209478c9705.png\nimage\n.UE \\c\n]\nimage\n.\\\n.\\\"\n.TH \"DISTROBOX\\-RM\" \"1\" \"Mar 2026\" \"Distrobox\" \"User Manual\"\n.SH NAME\n.IP\n.EX\ndistrobox rm\ndistrobox\\-rm\n.EE\n.SH DESCRIPTION\ndistrobox\\-rm delete one of the available distroboxes.\n.SH SYNOPSIS\n\\f[B]distrobox rm\\f[R]\n.IP\n.EX\n\\-\\-all/\\-a:       delete all distroboxes\n\\-\\-force/\\-f:     force deletion\n\\-\\-rm\\-home:      remove the mounted home if it differs from the host user\\[aq]s one\n\\-\\-root/\\-r:      launch podman/docker/lilipod with root privileges. Note that if you need root this is the preferred\n            way over \\[dq]sudo distrobox\\[dq] (note: if using a program other than \\[aq]sudo\\[aq] for root privileges is necessary,\n            specify it through the DBX_SUDO_PROGRAM env variable, or \\[aq]distrobox_sudo_program\\[aq] config variable)\n\\-\\-help/\\-h:      show this message\n\\-\\-verbose/\\-v:       show more verbosity\n\\-\\-version/\\-V:       show version\n.EE\n.SH EXAMPLES\n.IP\n.EX\ndistrobox\\-rm container\\-name [\\-\\-force] [\\-\\-all]\n.EE\n.PP\nYou can also use environment variables to specify container manager and\nname:\n.IP\n.EX\nDBX_CONTAINER_MANAGER=\\[dq]docker\\[dq] DBX_CONTAINER_NAME=test\\-alpine distrobox\\-rm\n.EE\n.SH ENVIRONMENT VARIABLES\n.IP\n.EX\nDBX_CONTAINER_MANAGER\nDBX_CONTAINER_NAME\nDBX_NON_INTERACTIVE\nDBX_SUDO_PROGRAM\n.EE\n.\\\n.\\\"\n.TH \"DISTROBOX\\-STOP\" \"1\" \"Mar 2026\" \"Distrobox\" \"User Manual\"\n.SH NAME\n.IP\n.EX\ndistrobox stop\ndistrobox\\-stop\n.EE\n.SH DESCRIPTION\ndistrobox\\-stop stop a running distrobox.\n.PP\nDistroboxes are left running, even after exiting out of them, so that\nsubsequent enters are really quick.\nThis is how they can be stopped.\n.SH SYNOPSIS\n\\f[B]distrobox stop\\f[R]\n.IP\n.EX\n\\-\\-all/\\-a:       stop all distroboxes\n\\-\\-yes/\\-Y:       non\\-interactive, stop without asking\n\\-\\-help/\\-h:      show this message\n\\-\\-root/\\-r:      launch podman/docker/lilipod with root privileges. Note that if you need root this is the preferred\n            way over \\[dq]sudo distrobox\\[dq] (note: if using a program other than \\[aq]sudo\\[aq] for root privileges is necessary,\n            specify it through the DBX_SUDO_PROGRAM env variable, or \\[aq]distrobox_sudo_program\\[aq] config variable)\n\\-\\-verbose/\\-v:       show more verbosity\n\\-\\-version/\\-V:       show version\n.EE\n.SH EXAMPLES\n.IP\n.EX\ndistrobox\\-stop container\\-name1 container\\-name2\ndistrobox\\-stop container\\-name\ndistrobox\\-stop \\-\\-all\n.EE\n.PP\nYou can also use environment variables to specify container manager and\nname:\n.IP\n.EX\nDBX_CONTAINER_MANAGER=\\[dq]docker\\[dq] DBX_CONTAINER_NAME=test\\-alpine distrobox\\-stop\n.EE\n.SH ENVIRONMENT VARIABLES\n.IP\n.EX\nDBX_CONTAINER_MANAGER\nDBX_CONTAINER_NAME\nDBX_NON_INTERACTIVE\nDBX_SUDO_PROGRAM\n.EE\n.\\\n.\\\"\n.TH \"DISTROBOX\\-UPGRADE\" \"1\" \"Mar 2026\" \"Distrobox\" \"User Manual\"\n.SH NAME\n.IP\n.EX\ndistrobox\\-upgrade\n.EE\n.SH DESCRIPTION\ndistrobox\\-upgrade will enter the specified list of containers and will\nperform an upgrade using the container\\[cq]s package manager.\n.SH SYNOPSIS\n\\f[B]distrobox upgrade\\f[R]\n.IP\n.EX\n\\-\\-help/\\-h:      show this message\n\\-\\-all/\\-a:       perform for all distroboxes\n\\-\\-running:      perform only for running distroboxes\n\\-\\-root/\\-r:      launch podman/docker/lilipod with root privileges. Note that if you need root this is the preferred\n            way over \\[dq]sudo distrobox\\[dq] (note: if using a program other than \\[aq]sudo\\[aq] for root privileges is necessary,\n            specify it through the DBX_SUDO_PROGRAM env variable, or \\[aq]distrobox_sudo_program\\[aq] config variable)\n\\-\\-verbose/\\-v:       show more verbosity\n\\-\\-version/\\-V:       show version\n.EE\n.SH EXAMPLES\nUpgrade all distroboxes\n.IP\n.EX\ndistrobox\\-upgrade \\-\\-all\n.EE\n.PP\nUpgrade all running distroboxes\n.IP\n.EX\ndistrobox\\-upgrade \\-\\-all \\-\\-running\n.EE\n.PP\nUpgrade a specific distrobox\n.IP\n.EX\ndistrobox\\-upgrade alpine\\-linux \n.EE\n.PP\nUpgrade a list of distroboxes\n.IP\n.EX\ndistrobox\\-upgrade alpine\\-linux ubuntu22 my\\-distrobox123\n.EE\n.PP\n\\f[B]Automatically update all distro\\f[R]\n.PP\nYou can create a systemd service to perform distrobox\\-upgrade\nautomatically, this example shows how to run it daily:\n.PP\n\\[ti]/.config/systemd/user/distrobox\\-upgrade.service\n.IP\n.EX\n[Unit]\nDescription=distrobox\\-upgrade Automatic Update\n\n[Service]\nType=simple\nExecStart=distrobox\\-upgrade \\-\\-all\nStandardOutput=null\n.EE\n.PP\n\\[ti]/.config/systemd/user/distrobox\\-upgrade.timer\n.IP\n.EX\n[Unit]\nDescription=distrobox\\-upgrade Automatic Update Trigger\n\n[Timer]\nOnBootSec=1h\nOnUnitInactiveSec=1d\n\n[Install]\nWantedBy=timers.target\n.EE\n.PP\nThen simply do a\n\\f[CR]systemctl \\-\\-user daemon\\-reload && systemctl \\-\\-user enable \\-\\-now distrobox\\-upgrade.timer\\f[R]\n"
  },
  {
    "path": "uninstall",
    "content": "#!/bin/sh\n# SPDX-License-Identifier: GPL-3.0-only\n#\n# This file is part of the distrobox project: https://github.com/89luca89/distrobox\n#\n# Copyright (C) 2021 distrobox contributors\n#\n# distrobox is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 3\n# as published by the Free Software Foundation.\n#\n# distrobox is distributed in the hope that it will be useful, but\n# WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n# General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with distrobox; if not, see <http://www.gnu.org/licenses/>.\n\n# POSIX\n\nno_color=0\nverbose=0\n\n# Print usage to stdout.\n# Arguments:\n#   None\n# Outputs:\n#   print usage with examples.\nshow_help()\n{\n\tcat << EOF\nuninstall --prefix /usr/local\n\nOptions:\n\t--no-color:\t\tdisable color formatting\n\t--prefix/-P:\t\tbase bath where all files will be deployed (default /usr/local if root, ~/.local if not)\n\t--help/-h:\t\tshow this message\n\t-v:\t\t\tshow more verbosity\nEOF\n}\n\n# Parse arguments\nwhile :; do\n\tcase $1 in\n\t\t-h | --help)\n\t\t\t# Call a \"show_help\" function to display a synopsis, then exit.\n\t\t\tshow_help\n\t\t\texit\n\t\t\t;;\n\t\t--no-color)\n\t\t\tshift\n\t\t\tno_color=1\n\t\t\t;;\n\t\t-v | --verbose)\n\t\t\tshift\n\t\t\tverbose=1\n\t\t\t;;\n\t\t-p | --path)\n\t\t\tif [ -n \"$2\" ]; then\n\t\t\t\tdest_path=\"$2\"\n\t\t\t\tshift\n\t\t\t\tshift\n\t\t\tfi\n\t\t\t;;\n\t\t-P | --prefix)\n\t\t\tif [ -n \"$2\" ]; then\n\t\t\t\tprefix=\"$2\"\n\t\t\t\tshift\n\t\t\t\tshift\n\t\t\tfi\n\t\t\t;;\n\t\t*) # Default case: If no more options then break out of the loop.\n\t\t\tbreak ;;\n\tesac\ndone\n\n# if we're in not a tty, don't use colors\nBOLD_GREEN=\"\"\nBOLD_RED=\"\"\nCLEAR=\"\"\nif [ -t 0 ] && [ -t 1 ] && [ \"${no_color}\" -ne 1 ]; then\n\t# we're in a tty, use colors\n\tBOLD_GREEN='\\033[1;32m'\n\tBOLD_RED='\\033[1;31m'\n\tCLEAR='\\033[0m'\nfi\n\nif  [ -z \"${prefix}\" ]; then\n\tprefix=\"/usr/local\"\n\t# in case we're not root, just default to the home directory\n\tif [ \"$(id -u)\" -ne 0 ]; then\n\t\tprefix=\"${HOME}/.local\"\n\tfi\nfi\ndest_path=\"${prefix}/bin\"\nman_dest_path=\"${prefix}/share/man/man1\"\nicon_dest_path=\"${prefix}/share/icons\"\ncompletion_dest_path=\"${prefix}/share/bash-completion/completions/\"\n\nset -o errexit\nset -o nounset\n# set verbosity\nif [ \"${verbose}\" -ne 0 ]; then\n\tset -o xtrace\nfi\n\n[ ! -w \"${dest_path}\" ] && printf >&2 \"Cannot write into %s, permission denied.\\n\" \"${dest_path}\" && exit 1\n[ ! -w \"${man_dest_path}\" ] && printf >&2 \"Cannot write into %s, permission denied.\\n\" \"${man_dest_path}\" && exit 1\n\n# uninstall\nfor file in \"${dest_path}/distrobox\"*; do\n\t[ -e \"${file}\" ] && rm \"${file}\"\ndone\nfor file in \"${man_dest_path}/distrobox\"*; do\n\t[ -e \"${file}\" ] && rm \"${file}\"\ndone\nfor file in \"${completion_dest_path}/distrobox\"*; do\n\t[ -e \"${file}\" ] && rm \"${file}\"\ndone\n[  -e \"${icon_dest_path}\"/terminal-distrobox-icon.svg ] && rm \"${icon_dest_path}\"/terminal-distrobox-icon.svg\n[  -e \"${icon_dest_path}\"/distrobox ] && rm -rf \"${icon_dest_path}\"/distrobox\n\nprintf >&2 \"%b Thank you for using Distrobox. Uninstall complete.\\n%b\" \"${BOLD_GREEN}\" \"${CLEAR}\"\nprintf >&2 \"%b Removed shell scripts located in %b%s\\n%b\" \"${CLEAR}\" \"${BOLD_RED}\" \"${dest_path}\" \"${CLEAR}\"\nprintf >&2 \"%b Removed manpages located in %b%s\\n%b\" \"${CLEAR}\" \"${BOLD_RED}\" \"${man_dest_path}\" \"${CLEAR}\"\n"
  }
]