├── .codespellexcludefile ├── .github ├── CODEOWNERS ├── ISSUE_TEMPLATE │ ├── bug-report.md │ └── feature-request.md └── workflows │ ├── arch-images.yaml │ ├── ubuntu-images.yaml │ └── ubuntu-tests.yaml ├── .gitignore ├── .gitmodules ├── .mailmap ├── .zuul.yaml ├── CODE-OF-CONDUCT.md ├── CONTRIBUTING.md ├── COPYING ├── GOALS.md ├── NEWS ├── NEWS.old ├── README.md ├── SECURITY.md ├── data ├── config │ ├── meson.build │ └── toolbox.conf ├── gfx │ ├── CONTRIBUTING.gif │ ├── README.gif │ └── powerup.gif ├── meson.build └── tmpfiles.d │ ├── meson.build │ └── toolbox.conf ├── doc ├── meson.build ├── toolbox-create.1.md ├── toolbox-enter.1.md ├── toolbox-help.1.md ├── toolbox-init-container.1.md ├── toolbox-list.1.md ├── toolbox-rm.1.md ├── toolbox-rmi.1.md ├── toolbox-run.1.md ├── toolbox.1.md └── toolbox.conf.5.md ├── gen-docs-list ├── images ├── arch │ ├── Containerfile │ └── extra-packages ├── fedora │ ├── f28 │ │ ├── Containerfile │ │ ├── README.md │ │ ├── extra-packages │ │ └── missing-docs │ ├── f29 │ │ ├── Containerfile │ │ ├── README.md │ │ ├── extra-packages │ │ └── missing-docs │ ├── f30 │ │ ├── Containerfile │ │ ├── README.md │ │ ├── extra-packages │ │ └── missing-docs │ ├── f31 │ │ ├── Containerfile │ │ ├── README.md │ │ ├── extra-packages │ │ └── missing-docs │ ├── f32 │ │ ├── Containerfile │ │ ├── README.md │ │ ├── extra-packages │ │ └── missing-docs │ ├── f33 │ │ ├── Containerfile │ │ ├── README.md │ │ ├── extra-packages │ │ └── missing-docs │ ├── f34 │ │ ├── Containerfile │ │ ├── README.md │ │ ├── extra-packages │ │ └── missing-docs │ ├── f35 │ │ ├── Containerfile │ │ ├── README.md │ │ ├── extra-packages │ │ └── missing-docs │ ├── f36 │ │ ├── Containerfile │ │ ├── README.md │ │ ├── ensure-files │ │ ├── extra-packages │ │ └── missing-docs │ ├── f37 │ │ ├── Containerfile │ │ ├── README.md │ │ ├── ensure-files │ │ ├── extra-packages │ │ └── missing-docs │ ├── f38 │ │ ├── Containerfile │ │ ├── README.md │ │ ├── ensure-files │ │ ├── extra-packages │ │ └── missing-docs │ └── f39 │ │ ├── Containerfile │ │ ├── README.md │ │ ├── ensure-files │ │ ├── extra-packages │ │ └── missing-docs ├── rhel │ ├── 8.5 │ │ ├── Containerfile │ │ ├── README.md │ │ ├── extra-packages │ │ └── missing-docs │ ├── 8.6 │ │ ├── Containerfile │ │ ├── README.md │ │ ├── extra-packages │ │ └── missing-docs │ ├── 8.7 │ │ ├── Containerfile │ │ ├── README.md │ │ ├── extra-packages │ │ └── missing-docs │ ├── 8.8 │ │ ├── Containerfile │ │ ├── README.md │ │ ├── extra-packages │ │ └── missing-docs │ ├── 8.9 │ │ ├── Containerfile │ │ ├── README.md │ │ ├── ensure-files │ │ ├── extra-packages │ │ └── missing-docs │ ├── 9.1 │ │ ├── Containerfile │ │ ├── README.md │ │ ├── extra-packages │ │ └── missing-docs │ ├── 9.2 │ │ ├── Containerfile │ │ ├── README.md │ │ ├── extra-packages │ │ └── missing-docs │ └── 9.3 │ │ ├── Containerfile │ │ ├── README.md │ │ ├── ensure-files │ │ ├── extra-packages │ │ └── missing-docs ├── test │ └── busybox │ │ ├── Containerfile │ │ └── README.md └── ubuntu │ ├── 16.04 │ ├── Containerfile │ └── extra-packages │ ├── 18.04 │ ├── Containerfile │ └── extra-packages │ ├── 20.04 │ ├── Containerfile │ └── extra-packages │ ├── 22.04 │ ├── Containerfile │ └── extra-packages │ ├── 24.04 │ ├── Containerfile │ └── extra-packages │ ├── 24.10 │ ├── Containerfile │ └── extra-packages │ └── 25.04 │ ├── Containerfile │ └── extra-packages ├── meson.build ├── meson_options.txt ├── meson_post_install.py ├── playbooks ├── build.yaml ├── dependencies-centos-9-stream.yaml ├── dependencies-fedora-restricted.yaml ├── dependencies-fedora.yaml ├── setup-env-migration-path-for-coreos-toolbox.yaml ├── setup-env-restricted.yaml ├── setup-env.yaml ├── system-test-commands-options.yaml ├── system-test-runtime-environment-arch-fedora.yaml ├── system-test-runtime-environment-ubuntu.yaml └── unit-test.yaml ├── profile.d ├── meson.build └── toolbox.sh ├── src ├── cmd │ ├── completion.go │ ├── create.go │ ├── enter.go │ ├── help.go │ ├── initContainer.go │ ├── list.go │ ├── rm.go │ ├── rmi.go │ ├── root.go │ ├── rootDefault.go │ ├── rootMigrationPath.go │ ├── root_test.go │ ├── run.go │ └── utils.go ├── go-build-wrapper ├── go.mod ├── go.sum ├── meson.build ├── meson_generate_completions.py ├── meson_go_fmt.py ├── pkg │ ├── nvidia │ │ └── nvidia.go │ ├── podman │ │ ├── container.go │ │ ├── containerInspect_test.go │ │ ├── errors.go │ │ └── podman.go │ ├── shell │ │ ├── shell.go │ │ └── shell_test.go │ ├── skopeo │ │ └── skopeo.go │ ├── term │ │ ├── term.go │ │ └── term_test.go │ ├── utils │ │ ├── arch.go │ │ ├── errors.go │ │ ├── fedora.go │ │ ├── libsubid-wrappers.c │ │ ├── libsubid-wrappers.h │ │ ├── rhel.go │ │ ├── ubuntu.go │ │ ├── utils.go │ │ ├── utils_cgo.go │ │ └── utils_test.go │ └── version │ │ └── version.go └── toolbox.go ├── test ├── meson.build └── system │ ├── 001-version.bats │ ├── 002-help.bats │ ├── 101-create.bats │ ├── 102-list.bats │ ├── 103-container.bats │ ├── 104-run.bats │ ├── 105-enter.bats │ ├── 106-rm.bats │ ├── 107-rmi.bats │ ├── 108-completion.bats │ ├── 201-ipc.bats │ ├── 203-network.bats │ ├── 206-user.bats │ ├── 210-ulimit.bats │ ├── 211-dbus.bats │ ├── 220-environment-variables.bats │ ├── 230-cdi.bats │ ├── 250-kerberos.bats │ ├── 270-rpm.bats │ ├── 501-create.bats │ ├── 504-run.bats │ ├── 505-enter.bats │ ├── README.md │ ├── data │ ├── cdi-empty.json │ ├── cdi-hooks-00.json │ ├── cdi-hooks-01.json │ ├── cdi-hooks-02.json │ ├── cdi-hooks-10.json │ ├── cdi-hooks-11.json │ ├── cdi-hooks-12.json │ ├── cdi-hooks-14.json │ ├── cdi-hooks-15.json │ ├── cdi-hooks-create-symlinks-00.json │ ├── cdi-hooks-create-symlinks-01.json │ ├── cdi-hooks-create-symlinks-02.json │ ├── cdi-hooks-create-symlinks-03.json │ ├── cdi-hooks-create-symlinks-04.json │ ├── cdi-hooks-create-symlinks-05.json │ ├── cdi-hooks-create-symlinks-06.json │ ├── cdi-hooks-create-symlinks-07.json │ ├── cdi-hooks-create-symlinks-08.json │ ├── cdi-hooks-create-symlinks-30.json │ ├── cdi-hooks-create-symlinks-31.json │ ├── cdi-hooks-create-symlinks-32.json │ ├── cdi-hooks-create-symlinks-33.json │ ├── cdi-hooks-create-symlinks-34.json │ ├── cdi-hooks-create-symlinks-35.json │ ├── cdi-hooks-create-symlinks-36.json │ ├── cdi-hooks-create-symlinks-37.json │ ├── cdi-mounts-10.json │ ├── cdi-mounts-11.json │ └── cdi-mounts-12.json │ ├── libs │ └── helpers.bash │ ├── meson.build │ └── setup_suite.bash └── toolbox /.codespellexcludefile: -------------------------------------------------------------------------------- 1 | usr_mount_destination_flags="ro" 2 | toolbox_profile_bind="--volume /etc/profile.d/toolbox.sh:/etc/profile.d/toolbox.sh:ro" 3 | toolbox_profile_bind="--volume /usr/share/profile.d/toolbox.sh:/etc/profile.d/toolbox.sh:ro" 4 | if echo "$usr_mount_source_flags" | grep --invert-match "ro" >/dev/null 2>&3; then 5 | --volume "$TOOLBOX_PATH":/usr/bin/toolbox:ro \ 6 | if ! mount_bind /run/host/etc/machine-id /etc/machine-id ro; then 7 | if ! mount_bind /run/host/var/lib/flatpak /var/lib/flatpak ro; then 8 | if ! mount_bind /run/host/var/log/journal /var/log/journal ro; then 9 | if strings.Contains(command.Name(), "complet") { 10 | toolboxPathMountArg := toolboxPath + ":/usr/bin/toolbox:ro" 11 | toolboxShMountArg := mount.source + ":" + mount.containerPath + ":ro" 12 | {"/etc/machine-id", "/run/host/etc/machine-id", "ro"}, 13 | {"/var/lib/flatpak", "/run/host/var/lib/flatpak", "ro"}, 14 | {"/var/lib/systemd/coredump", "/run/host/var/lib/systemd/coredump", "ro"}, 15 | {"/var/log/journal", "/run/host/var/log/journal", "ro"}, 16 | " \"ro\"," + 17 | -------------------------------------------------------------------------------- /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | * @HarryMichal @debarshiray 2 | /.github/workflows/arch-images.yaml @Foxboron 3 | /.github/workflows/arch-images-pr.yaml @Foxboron 4 | /.github/workflows/ubuntu-images.yaml @Jmennius 5 | /.github/workflows/ubuntu-tests.yaml @Jmennius 6 | /data/gfx/*.gif @jimmac 7 | /images/arch @Foxboron 8 | /images/rhel @debarshiray @olivergs 9 | /images/ubuntu @Jmennius 10 | /src/pkg/utils/arch.go @Foxboron 11 | /src/pkg/utils/ubuntu.go @Jmennius 12 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug-report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Toolbx's bug report template 4 | title: '' 5 | labels: 1. Bug 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of *what the bug is*. If possible, re-run the command(s) with `--log-level debug` and put the output here. 12 | 13 | **Steps how to reproduce the behaviour** 14 | 1. Go to '...' 15 | 2. Click on '....' 16 | 3. Scroll down to '....' 17 | 4. See error 18 | 19 | **Expected behaviour** 20 | A clear and concise description of what you *expected to happen*. 21 | 22 | **Actual behaviour** 23 | A clear and concise description of what *actually happened*. 24 | 25 | **Screenshots** 26 | If applicable, add screenshots to help explain your problem. 27 | 28 | **Output of `toolbox --version` (v0.0.90+)** 29 | e.g., `toolbox version 0.0.90` 30 | 31 | **Toolbx package info (`rpm -q toolbox`)** 32 | e.g., `toolbox-0.0.18-2.fc32.noarch` 33 | 34 | **Output of `podman version`** 35 | e.g., 36 | ``` 37 | Version: 1.9.2 38 | RemoteAPI Version: 1 39 | Go Version: go1.14.2 40 | OS/Arch: linux/amd64 41 | ``` 42 | 43 | **Podman package info (`rpm -q podman`)** 44 | e.g., `podman-1.9.2-1.fc32.x86_64` 45 | 46 | **Info about your OS** 47 | e.g., Fedora Silverblue 32 48 | 49 | **Additional context** 50 | Add any other context about the problem here. 51 | When did the issue start occurring? After an update (what packages were updated)? 52 | If the issue is about operating with containers/images (creating, using, deleting,..), share here what image you used. If you're unsure, share here the output of `toolbox list -i` (shows all Toolbx images on your system). 53 | 54 | If you see an error message saying: `Error: invalid entry point PID of container `, add to the ticket output of command `podman start --attach `. 55 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature-request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Toolbx's feature request template 4 | title: '' 5 | labels: 1. Feature request 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. If a different tool has the functionality you're requesting, share it here. 21 | -------------------------------------------------------------------------------- /.github/workflows/arch-images.yaml: -------------------------------------------------------------------------------- 1 | name: "Arch Linux: Build and push arch-toolbox image" 2 | 3 | permissions: read-all 4 | 5 | on: 6 | pull_request: 7 | branches: 8 | - main 9 | paths: 10 | - images/arch/** 11 | - .github/workflows/arch-images.yaml 12 | push: 13 | branches: 14 | - main 15 | paths: 16 | - images/arch/** 17 | - .github/workflows/arch-images.yaml 18 | schedule: 19 | - cron: '0 0 * * MON' 20 | 21 | env: 22 | distro: 'arch' 23 | platforms: 'linux/amd64' 24 | registry: 'quay.io/toolbx' 25 | username: 'toolbx+github' 26 | 27 | # Prevent multiple workflow runs from racing to ensure that pushes are made 28 | # sequentially for the main branch. Also cancel in progress workflow runs for 29 | # pull requests only. 30 | concurrency: 31 | group: ${{ github.workflow }}-${{ github.ref }} 32 | cancel-in-progress: ${{ github.event_name == 'pull_request' }} 33 | 34 | jobs: 35 | build-push-images: 36 | name: Build and push the arch-toolbox image 37 | 38 | runs-on: ubuntu-latest 39 | steps: 40 | - name: Checkout 41 | uses: actions/checkout@v4 42 | 43 | - name: Build container image (latest tag) 44 | uses: redhat-actions/buildah-build@v2 45 | if: env.latest_release == matrix.release 46 | with: 47 | platforms: ${{ env.platforms }} 48 | context: images/${{ env.distro }} 49 | image: ${{ env.distro }}-toolbox 50 | tags: latest 51 | containerfiles: images/${{ env.distro }}/Containerfile 52 | layers: false 53 | oci: true 54 | 55 | - name: Push to Container Registry (latest tag) 56 | uses: redhat-actions/push-to-registry@v2 57 | id: push-latest 58 | if: (github.event_name == 'push' || github.event_name == 'schedule') && github.ref == 'refs/heads/main' 59 | with: 60 | username: ${{ env.username }} 61 | password: ${{ secrets.QUAY_ROBOT_TOKEN }} 62 | image: ${{ env.distro }}-toolbox 63 | registry: ${{ env.registry }} 64 | tags: latest 65 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | src/toolbox 2 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "test/system/libs/bats-support"] 2 | path = test/system/libs/bats-support 3 | url = https://github.com/bats-core/bats-support.git 4 | [submodule "test/system/libs/bats-assert"] 5 | path = test/system/libs/bats-assert 6 | url = https://github.com/bats-core/bats-assert.git 7 | -------------------------------------------------------------------------------- /.mailmap: -------------------------------------------------------------------------------- 1 | 2 | Ondřej Míchal 3 | -------------------------------------------------------------------------------- /CODE-OF-CONDUCT.md: -------------------------------------------------------------------------------- 1 | ## The Toolbx Project Community Code of Conduct 2 | 3 | The Toolbx project follows the [Containers Community Code of Conduct](https://github.com/containers/common/blob/main/CODE-OF-CONDUCT.md). 4 | -------------------------------------------------------------------------------- /GOALS.md: -------------------------------------------------------------------------------- 1 | Toolbox logo landscape 2 | 3 | ## Goals 4 | 5 | ### High Level Goals 6 | 7 | - Provide a convenient command line interface to run containers using 8 | [Podman](https://podman.io/) 9 | - Support for development, debugging and system management use cases 10 | - Support for multiple distros 11 | - `toolbox` package in multiple distros 12 | - `toolbox` containers for multiple distros 13 | 14 | ### Non-goals 15 | 16 | - Supporting multiple container runtimes. Toolbx will use Podman exclusively 17 | - Adding significant features on top of Podman 18 | - Significant feature requests should be driven into Podman upstream 19 | - To run containers that aren't tightly integrated with the host 20 | - Extremely sandboxed containers quickly become specific to the user 21 | 22 | ### Developer Use Cases 23 | 24 | - I’m a developer hacking on source code and building/testing code 25 | - Most cases: user doesn't need root, rootless containers work fine 26 | - Some cases: user needs root for testing 27 | - Desktop Development: 28 | - Developers need things like D-Bus, display, etc. to be forwarded into the 29 | Toolbx container 30 | - Headless Development: 31 | - Toolbx works properly in headless environments (no display, etc) 32 | - Need development tools like GDB, strace, etc. to work 33 | 34 | ### Debugging and System Management Use Cases 35 | 36 | - Inspecting host processes and the kernel 37 | - Typically need root access 38 | - Need bpftrace, strace on host processes to work 39 | - Ideally even do things like helping get kernel-debuginfo data for the 40 | host kernel 41 | - Managing system services 42 | - `systemctl restart foo.service` 43 | - journalctl 44 | - Managing updates to the host 45 | - rpm-ostree 46 | - dnf/yum (classic systems) 47 | 48 | ### Specific environments 49 | 50 | - Fedora Silverblue 51 | - Silverblue comes with a subset of packages and discourages host software 52 | changes 53 | - Users need a Toolbx container as a working environment 54 | - Future: use Toolbx container by default when a user opens a shell 55 | - Fedora CoreOS 56 | - Similar to Silverblue, but non-graphical and smaller package set 57 | - RHEL CoreOS 58 | - Similar to Fedora CoreOS. Based on RHEL content and the underlying 59 | operating system for OpenShift 60 | - Need to [use default authfile on pull](https://github.com/coreos/toolbox/pull/58/commits/413f83f7240d3c31121b557bfd55e489fad24489) 61 | - Need to ensure compatibility with the rhel7/support-tools container 62 | - Currently not a Toolbx image, opportunity for collaboration 63 | - Alignment with `oc debug node/` (OpenShift) 64 | - `oc debug node` opens a shell on a kubernetes node 65 | - Value in having a consistent environment for both Toolbx's debugging 66 | mode and `oc debug node` 67 | -------------------------------------------------------------------------------- /NEWS: -------------------------------------------------------------------------------- 1 | 0.1.1 2 | ===== 3 | 4 | ### Security fixes 5 | 6 | * Bumped the minimum github.com/NVIDIA/nvidia-container-toolkit version to 7 | 1.16.2 for CVE-2024-0132 or GHSA-mjjw-553x-87pq, and CVE-2024-0133 or 8 | GHSA-f748-7hpg-88ch 9 | 10 | ### Bug fixes 11 | 12 | * Unbroke 'enter' if the NVIDIA Persistence Daemon is used (regression in 13 | 0.0.99.6) 14 | * Unbroke 'enter' if the proprietary NVIDIA driver is installed, but not used 15 | (regression in 0.0.99.6) 16 | 17 | 18 | ---- 19 | 20 | Copyright © 2024 Red Hat, Inc. 21 | All rights reserved. 22 | 23 | Copying and distribution of this file, with or without modification, 24 | are permitted in any medium without royalty provided the copyright 25 | notice and this notice are preserved. 26 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | ## Security and Disclosure Information Policy for the Toolbx Project 2 | 3 | The Toolbx Project follows the 4 | [Security and Disclosure Information Policy](https://github.com/containers/common/blob/main/SECURITY.md) 5 | for the Containers Projects. 6 | -------------------------------------------------------------------------------- /data/config/meson.build: -------------------------------------------------------------------------------- 1 | install_data( 2 | 'toolbox.conf', 3 | install_dir: get_option('sysconfdir') / 'containers', 4 | ) 5 | -------------------------------------------------------------------------------- /data/config/toolbox.conf: -------------------------------------------------------------------------------- 1 | [general] 2 | # Create a toolbox container for a different operating system distro than the 3 | # host. Cannot be used with 'image'. 4 | ## distro = "fedora" 5 | 6 | # Create a toolbox container for a different operating system release than the 7 | # host. Cannot be used with 'image'. 8 | ## release = "33" 9 | 10 | # Change the name of the image used to create the toolbox container. This is 11 | # useful for creating containers from custom-built images. Cannot be used with 12 | # 'distro' or 'release'. 13 | # 14 | # If the name does not contain a registry, the local image storage will be 15 | # consulted, and if it's not present there then it will be pulled from a 16 | # suitable remote registry. 17 | ## image = "registry.fedoraproject.org/fedora-toolbox:34" 18 | -------------------------------------------------------------------------------- /data/gfx/CONTRIBUTING.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/containers/toolbox/5ed2442214f0eb8d58d1bfc7df50f62328815cb2/data/gfx/CONTRIBUTING.gif -------------------------------------------------------------------------------- /data/gfx/README.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/containers/toolbox/5ed2442214f0eb8d58d1bfc7df50f62328815cb2/data/gfx/README.gif -------------------------------------------------------------------------------- /data/gfx/powerup.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/containers/toolbox/5ed2442214f0eb8d58d1bfc7df50f62328815cb2/data/gfx/powerup.gif -------------------------------------------------------------------------------- /data/meson.build: -------------------------------------------------------------------------------- 1 | subdir('config') 2 | subdir('tmpfiles.d') 3 | -------------------------------------------------------------------------------- /data/tmpfiles.d/meson.build: -------------------------------------------------------------------------------- 1 | install_data( 2 | 'toolbox.conf', 3 | install_dir: tmpfilesdir, 4 | ) 5 | -------------------------------------------------------------------------------- /data/tmpfiles.d/toolbox.conf: -------------------------------------------------------------------------------- 1 | d /run/media 0755 root root - - 2 | L /run/host - - - - ../ 3 | -------------------------------------------------------------------------------- /doc/meson.build: -------------------------------------------------------------------------------- 1 | go_md2man_command = [ 2 | go_md2man, 3 | '-in', '@INPUT@', 4 | '-out', '@OUTPUT@', 5 | ] 6 | 7 | manuals = { 8 | '1': [ 9 | 'toolbox', 10 | 'toolbox-create', 11 | 'toolbox-enter', 12 | 'toolbox-init-container', 13 | 'toolbox-help', 14 | 'toolbox-list', 15 | 'toolbox-rm', 16 | 'toolbox-rmi', 17 | 'toolbox-run', 18 | ], 19 | '5': [ 20 | 'toolbox.conf', 21 | ] 22 | } 23 | 24 | foreach section, pages: manuals 25 | foreach page: pages 26 | output = page + '.' + section 27 | input = output + '.md' 28 | sectiondir = 'man' + section 29 | 30 | custom_target( 31 | output, 32 | command: go_md2man_command, 33 | input: input, 34 | install: true, 35 | install_dir: get_option('mandir') / sectiondir, 36 | output: output, 37 | ) 38 | endforeach 39 | endforeach 40 | -------------------------------------------------------------------------------- /doc/toolbox-enter.1.md: -------------------------------------------------------------------------------- 1 | % toolbox-enter 1 2 | 3 | ## NAME 4 | toolbox\-enter - Enter a Toolbx container for interactive use 5 | 6 | ## SYNOPSIS 7 | **toolbox enter** [*--distro DISTRO* | *-d DISTRO*] 8 | [*--release RELEASE* | *-r RELEASE*] 9 | [*CONTAINER*] 10 | 11 | ## DESCRIPTION 12 | 13 | Spawns an interactive shell inside a Toolbx container that was created using 14 | the `toolbox create` command. It tries to spawn the user's default shell, but 15 | if it's not available inside the container then it falls back to `/bin/bash`. 16 | 17 | When invoked without any options, `toolbox enter` will try to enter the default 18 | Toolbx container for the host, or if there's only one container available then 19 | it will use it. On Fedora, the default container is known as 20 | `fedora-toolbox-N`, where N is the release of the host. If there aren't any 21 | containers, `toolbox enter` will offer to create the default one for you. 22 | 23 | A specific container can be selected using the CONTAINER argument. 24 | 25 | A Toolbx container is an OCI container. Therefore, `toolbox enter` is 26 | analogous to a `podman start` followed by a `podman exec`. 27 | 28 | ## OPTIONS ## 29 | 30 | The following options are understood: 31 | 32 | **--distro** DISTRO, **-d** DISTRO 33 | 34 | Enter a Toolbx container for a different operating system DISTRO than the 35 | host. Has to be coupled with `--release` unless the selected DISTRO matches the 36 | host. 37 | 38 | **--release** RELEASE, **-r** RELEASE 39 | 40 | Enter a Toolbx container for a different operating system RELEASE than the 41 | host. 42 | 43 | ## EXAMPLES 44 | 45 | ### Enter the default Toolbx container matching the host OS 46 | 47 | ``` 48 | $ toolbox enter 49 | ``` 50 | 51 | ### Enter the default Toolbx container for Fedora 36 52 | 53 | ``` 54 | $ toolbox enter --distro fedora --release f36 55 | ``` 56 | 57 | ### Enter a Toolbx container with a custom name 58 | 59 | ``` 60 | $ toolbox enter foo 61 | ``` 62 | 63 | ## SEE ALSO 64 | 65 | `toolbox(1)`, `toolbox-run(1)`, `podman(1)`, `podman-exec(1)`, 66 | `podman-start(1)` 67 | -------------------------------------------------------------------------------- /doc/toolbox-help.1.md: -------------------------------------------------------------------------------- 1 | % toolbox-help 1 2 | 3 | ## NAME 4 | toolbox\-help - Display help information about Toolbx 5 | 6 | ## SYNOPSIS 7 | **toolbox help** [*COMMAND*] 8 | 9 | ## DESCRIPTION 10 | 11 | When no COMMAND is specified, the `toolbox(1)` manual is shown. If a COMMAND 12 | is specified, a manual page for that command is brought up. 13 | 14 | Note that `toolbox --help ...` is identical to `toolbox help ...` because the 15 | former is internally converted to the latter. 16 | 17 | This page can be displayed with `toolbox help help` or `toolbox help --help`. 18 | 19 | ## EXAMPLES 20 | 21 | ### Show the toolbox manual 22 | 23 | ``` 24 | $ toolbox help 25 | ``` 26 | 27 | ### Show the manual for the create command 28 | 29 | ``` 30 | $ toolbox help create 31 | ``` 32 | 33 | ## SEE ALSO 34 | 35 | `toolbox(1)` 36 | -------------------------------------------------------------------------------- /doc/toolbox-list.1.md: -------------------------------------------------------------------------------- 1 | % toolbox-list 1 2 | 3 | ## NAME 4 | toolbox\-list - List existing Toolbx containers and images 5 | 6 | ## SYNOPSIS 7 | **toolbox list** [*--containers* | *-c*] [*--images* | *-i*] 8 | 9 | ## DESCRIPTION 10 | 11 | Lists existing Toolbx containers and images. These are OCI containers and 12 | images, which can be managed directly with a tool like `podman`. 13 | 14 | ## OPTIONS ## 15 | 16 | The following options are understood: 17 | 18 | **--containers, -c** 19 | 20 | List only Toolbx containers, not images. 21 | 22 | **--images, -i** 23 | 24 | List only Toolbx images, not containers. 25 | 26 | ## EXAMPLES 27 | 28 | ### List all existing Toolbx containers and images 29 | 30 | ``` 31 | $ toolbox list 32 | ``` 33 | 34 | ### List existing Toolbx containers only 35 | 36 | ``` 37 | $ toolbox list --containers 38 | ``` 39 | 40 | ### List existing Toolbx images only 41 | 42 | ``` 43 | $ toolbox list --images 44 | ``` 45 | 46 | ## SEE ALSO 47 | 48 | `toolbox(1)`, `podman(1)`, `podman-ps(1)`, `podman-images(1)` 49 | -------------------------------------------------------------------------------- /doc/toolbox-rm.1.md: -------------------------------------------------------------------------------- 1 | % toolbox-rm 1 2 | 3 | ## NAME 4 | toolbox\-rm - Remove one or more Toolbx containers 5 | 6 | ## SYNOPSIS 7 | **toolbox rm** [*--all* | *-a*] [*--force* | *-f*] [*CONTAINER*...] 8 | 9 | ## DESCRIPTION 10 | 11 | Removes one or more Toolbx containers from the host. The container should 12 | have been created using the `toolbox create` command. 13 | 14 | A Toolbx container is an OCI container. Therefore, `toolbox rm` can be used 15 | interchangeably with `podman rm`. 16 | 17 | ## OPTIONS ## 18 | 19 | The following options are understood: 20 | 21 | **--all, -a** 22 | 23 | Remove all Toolbx containers. It can be used in conjunction with `--force` as 24 | well. 25 | 26 | **--force, -f** 27 | 28 | Force the removal of running and paused Toolbx containers. 29 | 30 | ## EXAMPLES 31 | 32 | ### Remove a Toolbx container named `fedora-toolbox-gegl:36` 33 | 34 | ``` 35 | $ toolbox rm fedora-toolbox-gegl:36 36 | ``` 37 | 38 | ### Remove all Toolbx containers, but not those that are running or paused 39 | 40 | ``` 41 | $ toolbox rm --all 42 | ``` 43 | 44 | ### Remove all Toolbx containers, including ones that are running or paused 45 | 46 | ``` 47 | $ toolbox rm --all --force 48 | ``` 49 | 50 | ## SEE ALSO 51 | 52 | `toolbox(1)`, `podman(1)`, `podman-rm(1)` 53 | -------------------------------------------------------------------------------- /doc/toolbox-rmi.1.md: -------------------------------------------------------------------------------- 1 | % toolbox-rmi 1 2 | 3 | ## NAME 4 | toolbox\-rmi - Remove one or more Toolbx images 5 | 6 | ## SYNOPSIS 7 | **toolbox rmi** [*--all* | *-a*] [*--force* | *-f*] [*IMAGE*...] 8 | 9 | ## DESCRIPTION 10 | 11 | Removes one or more Toolbx images from the host. The image should have been 12 | created using the `toolbox create` command. 13 | 14 | A Toolbx image is an OCI image. Therefore, `toolbox rmi` can be used 15 | interchangeably with `podman rmi`. 16 | 17 | ## OPTIONS ## 18 | 19 | The following options are understood: 20 | 21 | **--all, -a** 22 | 23 | Remove all Toolbx images. It can be used in conjunction with `--force` as well. 24 | 25 | **--force, -f** 26 | 27 | Force the removal of Toolbx images that are used by Toolbx containers. The 28 | dependent containers will be removed as well. 29 | 30 | ## EXAMPLES 31 | 32 | ### Remove a Toolbx image named `localhost/fedora-toolbox-gegl:36` 33 | 34 | ``` 35 | $ toolbox rmi localhost/fedora-toolbox-gegl:36 36 | ``` 37 | 38 | ### Remove all Toolbx images, but not those that are used by containers 39 | 40 | ``` 41 | $ toolbox rmi --all 42 | ``` 43 | 44 | ### Remove all Toolbx images and their dependent containers 45 | 46 | ``` 47 | $ toolbox rmi --all --force 48 | ``` 49 | 50 | ## SEE ALSO 51 | 52 | `toolbox(1)`, `podman(1)`, `podman-rmi(1)` 53 | -------------------------------------------------------------------------------- /doc/toolbox-run.1.md: -------------------------------------------------------------------------------- 1 | % toolbox-run 1 2 | 3 | ## NAME 4 | toolbox\-run - Run a command in an existing Toolbx container 5 | 6 | ## SYNOPSIS 7 | **toolbox run** [*--container NAME* | *-c NAME*] 8 | [*--distro DISTRO* | *-d DISTRO*] 9 | [*--preserve-fds N*] 10 | [*--release RELEASE* | *-r RELEASE*] 11 | [*COMMAND*] 12 | 13 | ## DESCRIPTION 14 | 15 | Runs a command inside an existing Toolbx container. The container should have 16 | been created using the `toolbox create` command. 17 | 18 | On Fedora, the default container is known as `fedora-toolbox-N`, where N is 19 | the release of the host. A specific container can be selected using the 20 | `--container` option. 21 | 22 | A Toolbx container is an OCI container. Therefore, `toolbox run` is analogous 23 | to a `podman start` followed by a `podman exec`. 24 | 25 | ## OPTIONS ## 26 | 27 | The following options are understood: 28 | 29 | **--container** NAME, **-c** NAME 30 | 31 | Run command inside a Toolbx container with the given NAME. This is useful 32 | when there are multiple Toolbx containers created from the same image, or 33 | entirely customized containers created from custom-built images. 34 | 35 | **--distro** DISTRO, **-d** DISTRO 36 | 37 | Run command inside a Toolbx container for a different operating system DISTRO 38 | than the host. Has to be coupled with `--release` unless the selected DISTRO 39 | matches the host system. 40 | 41 | **--preserve-fds** N 42 | 43 | Pass down to command N additional file descriptors (in addition to 0, 1, 44 | 2). The total number of file descriptors will be 3+N. 45 | 46 | **--release** RELEASE, **-r** RELEASE 47 | 48 | Run command inside a Toolbx container for a different operating system 49 | RELEASE than the host. 50 | 51 | ## EXIT STATUS 52 | 53 | The exit code gives information about why the command within the container 54 | failed to run or why it exited. 55 | 56 | **1** There was an internal error in Toolbx 57 | 58 | **125** There was an internal error in Podman 59 | 60 | **126** The run command could not be invoked 61 | 62 | ``` 63 | $ toolbox run /etc; echo $? 64 | /bin/sh: line 1: /etc: Is a directory 65 | /bin/sh: line 1: exec: /etc: cannot execute: Is a directory 66 | Error: failed to invoke command /etc in container fedora-toolbox-36 67 | 126 68 | ``` 69 | 70 | **127** The run command cannot be found or the working directory does not exist 71 | 72 | ``` 73 | $ toolbox run foo; echo $? 74 | /bin/sh: line 1: exec: foo: not found 75 | Error: command foo not found in container fedora-toolbox-36 76 | 127 77 | ``` 78 | 79 | **Exit code** The run command exit code 80 | 81 | ``` 82 | $ toolbox run false; echo $? 83 | 1 84 | ``` 85 | 86 | ## EXAMPLES 87 | 88 | ### Run ls inside the default Toolbx container matching the host OS 89 | 90 | ``` 91 | $ toolbox run ls -la 92 | ``` 93 | 94 | ### Run emacs inside the default Toolbx container for Fedora 36 95 | 96 | ``` 97 | $ toolbox run --distro fedora --release f36 emacs 98 | ``` 99 | 100 | ### Run uptime inside a Toolbx container with a custom name 101 | 102 | ``` 103 | $ toolbox run --container foo uptime 104 | ``` 105 | 106 | ## SEE ALSO 107 | 108 | `toolbox(1)`, `podman(1)`, `podman-exec(1)`, `podman-start(1)` 109 | -------------------------------------------------------------------------------- /doc/toolbox.conf.5.md: -------------------------------------------------------------------------------- 1 | % toolbox.conf 5 2 | 3 | ## NAME 4 | toolbox.conf - Toolbx configuration file 5 | 6 | ## DESCRIPTION 7 | 8 | Persistently overrides the default behaviour of `toolbox(1)`. The syntax is 9 | TOML and the names of the options match their command line counterparts. 10 | Currently, the only supported section is *general*. 11 | 12 | ## OPTIONS 13 | 14 | **distro** = "DISTRO" 15 | 16 | Create a Toolbx container for a different operating system DISTRO than the 17 | host. Cannot be used with `image`. 18 | 19 | **image** = "NAME" 20 | 21 | Change the NAME of the image used to create the Toolbx container. This is 22 | useful for creating containers from custom-built images. Cannot be used with 23 | `distro` and `release`. 24 | 25 | If NAME does not contain a registry, the local image storage will be 26 | consulted, and if it's not present there then it will be pulled from a suitable 27 | remote registry. 28 | 29 | **release** = "RELEASE" 30 | 31 | Create a Toolbx container for a different operating system RELEASE than the 32 | host. Cannot be used with `image`. 33 | 34 | ## FILES 35 | 36 | The following locations are looked up in increasing order of priority: 37 | 38 | **/etc/containers/toolbox.conf** 39 | 40 | This is meant to be provided by the operating system distributor or the system 41 | administrator, and affects all users on the host. 42 | 43 | Fields specified here can be overridden by any of the files below. 44 | 45 | **$XDG_CONFIG_HOME/containers/toolbox.conf** 46 | 47 | This is meant for user-specific changes. Fields specified here override any of 48 | the files above. 49 | 50 | ## EXAMPLES 51 | 52 | ### Override the default operating system distro: 53 | ``` 54 | [general] 55 | distro = "fedora" 56 | release = "36" 57 | ``` 58 | 59 | ### Override the default image: 60 | ``` 61 | [general] 62 | image = "registry.fedoraproject.org/fedora-toolbox:36" 63 | ``` 64 | 65 | ## SEE ALSO 66 | 67 | `toolbox(1)`, `toolbox-create(1)` 68 | -------------------------------------------------------------------------------- /gen-docs-list: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # Copyright © 2019 – 2024 Red Hat, Inc. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | 18 | 19 | collect() 20 | ( 21 | if $1; then 22 | postfix="_toolbox" 23 | else 24 | postfix="" 25 | fi 26 | 27 | manpages_list="" 28 | for dir in /usr/share/man/man*/ ; do 29 | for docs in $dir*; do 30 | package=$(rpm -qf $docs --qf "%{NAME}\n") 31 | if ! [[ $package = *"is not owned by any"* ]]; then 32 | manpages_list="$manpages_list$package\n" 33 | fi 34 | done 35 | done 36 | 37 | mkdir -p tmp 38 | echo -e "$manpages_list" | sort | uniq > tmp/docs_list$postfix 39 | rpm -qa --qf "%{NAME}\n" | sort | uniq > tmp/rpm_list$postfix 40 | ) 41 | 42 | 43 | generate() 44 | ( 45 | diff -c tmp/rpm_list_toolbox tmp/rpm_list | grep -E "^\+" | tr -d '+ ' > tmp/missing_packages 46 | diff -c tmp/docs_list_toolbox tmp/docs_list | grep -E "^\+" | tr -d '+ ' > tmp/missing_manpages 47 | manpages_list=$(comm -1 -3 tmp/missing_packages tmp/missing_manpages) 48 | manpages_final="" 49 | while read -r line; do 50 | if [ "$(man $line)" != "" ]; then 51 | manpages_final="$manpages_final$line\n" 52 | fi 53 | done <<< "$manpages_list" 54 | echo -e "$manpages_final" >> missing-docs 55 | ) 56 | 57 | 58 | case $1 in 59 | collect ) 60 | shift 61 | toolbox=false 62 | case $1 in 63 | -t | --toolbox ) 64 | toolbox=true 65 | ;; 66 | esac 67 | collect "$toolbox" 68 | exit 69 | ;; 70 | generate ) 71 | generate 72 | exit 73 | ;; 74 | clean ) 75 | rm -rf tmp 76 | exit 77 | ;; 78 | * ) 79 | exit 1 80 | esac 81 | -------------------------------------------------------------------------------- /images/arch/Containerfile: -------------------------------------------------------------------------------- 1 | FROM docker.io/library/archlinux:base-devel 2 | 3 | LABEL com.github.containers.toolbox="true" \ 4 | name="arch-toolbox" \ 5 | version="base-devel" \ 6 | usage="This image is meant to be used with the toolbox command" \ 7 | summary="Base image for creating Arch Linux Toolbx containers" \ 8 | maintainer="Morten Linderud " 9 | 10 | # Install extra packages 11 | COPY extra-packages / 12 | RUN pacman -Syu --needed --noconfirm - < extra-packages 13 | RUN rm /extra-packages 14 | 15 | # Enable man pages, enable progress bars 16 | RUN sed -i -e 's/NoProgressBar/#NoProgressBar/' -e 's/NoExtract/#NoExtract/' /etc/pacman.conf 17 | 18 | # Force reinstall of packages which have man pages (shouldn't redownload any that were just upgraded) 19 | RUN mkdir -p /usr/share/man && pacman -Qo /usr/share/man | awk '{print $5}' | xargs pacman -S --noconfirm man-db 20 | 21 | # Clean up cache 22 | RUN yes | pacman -Scc 23 | 24 | # Enable sudo permission for wheel users 25 | RUN echo "%wheel ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/toolbox 26 | 27 | # Enable the use of p11-kit-client.so to access CA certificates from the host 28 | RUN mkdir --parents /etc/pkcs11/modules 29 | -------------------------------------------------------------------------------- /images/arch/extra-packages: -------------------------------------------------------------------------------- 1 | bash-completion 2 | diffutils 3 | flatpak-xdg-utils 4 | git 5 | gnupg 6 | keyutils 7 | libp11-kit 8 | lsof 9 | man-db 10 | man-pages 11 | mlocate 12 | mtr 13 | nss-mdns 14 | openssh 15 | pigz 16 | procps-ng 17 | rsync 18 | tcpdump 19 | time 20 | traceroute 21 | tree 22 | unzip 23 | vte-common 24 | wget 25 | words 26 | xorg-xauth 27 | zip 28 | -------------------------------------------------------------------------------- /images/fedora/f28/Containerfile: -------------------------------------------------------------------------------- 1 | FROM registry.fedoraproject.org/fedora:28 2 | 3 | ENV NAME=fedora-toolbox VERSION=28 4 | LABEL com.github.containers.toolbox="true" \ 5 | com.redhat.component="$NAME" \ 6 | name="$FGC/$NAME" \ 7 | version="$VERSION" \ 8 | usage="This image is meant to be used with the toolbox command" \ 9 | summary="Base image for creating Fedora toolbox containers" \ 10 | maintainer="Debarshi Ray " 11 | 12 | COPY README.md / 13 | 14 | RUN sed -i '/tsflags=nodocs/d' /etc/dnf/dnf.conf 15 | RUN dnf -y swap coreutils-single coreutils-full 16 | 17 | COPY missing-docs / 18 | RUN dnf -y reinstall $(/dev/null; then \ 34 | echo "$file: No such file or directory" >&2; \ 35 | ret_val=1; \ 36 | break; \ 37 | fi; \ 38 | done /dev/null; then \ 34 | echo "$file: No such file or directory" >&2; \ 35 | ret_val=1; \ 36 | break; \ 37 | fi; \ 38 | done &2; \ 50 | echo "$broken_packages" >&2; \ 51 | false; \ 52 | fi 53 | 54 | RUN dnf clean all 55 | -------------------------------------------------------------------------------- /images/fedora/f37/README.md: -------------------------------------------------------------------------------- 1 | [Toolbox](https://containertoolbx.org/) is a tool for Linux, which allows the 2 | use of interactive command line environments for development and 3 | troubleshooting the host operating system, without having to install software 4 | on the host. It is built on top of [Podman](https://podman.io/) and other 5 | standard container technologies from [OCI](https://opencontainers.org/). 6 | 7 | Toolbox environments have seamless access to the user's home directory, 8 | the Wayland and X11 sockets, networking (including Avahi), removable devices 9 | (like USB sticks), systemd journal, SSH agent, D-Bus, ulimits, /dev and the 10 | udev database, etc.. 11 | 12 | This is particularly useful on 13 | [OSTree](https://ostree.readthedocs.io/en/latest/) based operating systems like 14 | [Fedora CoreOS](https://coreos.fedoraproject.org/) and 15 | [Silverblue](https://silverblue.fedoraproject.org/). The intention of these 16 | systems is to discourage installation of software on the host, and instead 17 | install software as (or in) containers — they mostly don't even have package 18 | managers like DNF or YUM. This makes it difficult to set up a development 19 | environment or troubleshoot the operating system in the usual way. 20 | 21 | Toolbox solves this problem by providing a fully mutable container within 22 | which one can install their favourite development and troubleshooting tools, 23 | editors and SDKs. For example, it's possible to do `yum install ansible` 24 | without affecting the base operating system. 25 | 26 | However, this tool doesn't *require* using an OSTree based system. It works 27 | equally well on Fedora Workstation and Server, and that's a useful way to 28 | incrementally adopt containerization. 29 | 30 | The toolbox environment is based on an [OCI](https://www.opencontainers.org/) 31 | image. On Fedora this is the `fedora-toolbox` image. This image is used to 32 | create a toolbox container that offers the interactive command line 33 | environment. 34 | 35 | Note that Toolbox makes no promise about security beyond what's already 36 | available in the usual command line environment on the host that everybody is 37 | familiar with. 38 | 39 | 40 | ## Installation & Use 41 | 42 | See our guides on 43 | [installing & getting started](https://containertoolbx.org/install/) with 44 | Toolbox and [Linux distro support](https://containertoolbx.org/distros/). 45 | -------------------------------------------------------------------------------- /images/fedora/f37/ensure-files: -------------------------------------------------------------------------------- 1 | /usr/share/man/man1/bash.1* 2 | /usr/share/man/man1/cd.1* 3 | /usr/share/man/man1/export.1* 4 | 5 | /usr/share/man/man1/cat.1* 6 | /usr/share/man/man1/cp.1* 7 | /usr/share/man/man1/ls.1* 8 | 9 | /usr/share/man/man8/dnf.8* 10 | /usr/share/man/man5/dnf.conf.5* 11 | 12 | /usr/share/locale/de/LC_MESSAGES/elfutils.mo 13 | /usr/share/locale/ja/LC_MESSAGES/elfutils.mo 14 | 15 | /usr/share/man/man1/gpg2.1* 16 | /usr/share/man/man7/gnupg2.7* 17 | 18 | /usr/share/info/nettle.info* 19 | 20 | /usr/share/locale/fr/LC_MESSAGES/popt.mo 21 | /usr/share/locale/ja/LC_MESSAGES/popt.mo 22 | 23 | /usr/share/man/fr/man1/pstree.1* 24 | /usr/share/man/ru/man1/pstree.1* 25 | /usr/share/man/man1/pstree.1* 26 | 27 | /usr/share/info/history.info* 28 | 29 | /usr/share/man/fr/man8/rpm.8* 30 | /usr/share/man/ja/man8/rpm.8* 31 | /usr/share/man/man8/rpm.8* 32 | 33 | /usr/share/man/fr/man8/useradd.8* 34 | /usr/share/man/ja/man8/useradd.8* 35 | /usr/share/man/man8/useradd.8* 36 | 37 | /usr/share/man/man1/cal.1.* 38 | /usr/share/man/man1/getopt.1* 39 | /usr/share/man/man1/hexdump.1* 40 | 41 | /usr/share/man/man1/kill.1* 42 | /usr/share/man/man8/mount.8* 43 | 44 | /usr/share/man/fr/man1/xz.1* 45 | /usr/share/man/ko/man1/xz.1* 46 | /usr/share/man/man1/xz.1* 47 | -------------------------------------------------------------------------------- /images/fedora/f37/extra-packages: -------------------------------------------------------------------------------- 1 | bash-completion 2 | bc 3 | bzip2 4 | diffutils 5 | dnf-plugins-core 6 | findutils 7 | flatpak-spawn 8 | fpaste 9 | git 10 | gnupg2 11 | gnupg2-smime 12 | gvfs-client 13 | hostname 14 | iproute 15 | iputils 16 | keyutils 17 | krb5-libs 18 | less 19 | lsof 20 | man-db 21 | man-pages 22 | mesa-dri-drivers 23 | mesa-vulkan-drivers 24 | mtr 25 | nano-default-editor 26 | nss-mdns 27 | openssh-clients 28 | passwd 29 | pigz 30 | procps-ng 31 | psmisc 32 | rsync 33 | shadow-utils 34 | sudo 35 | tcpdump 36 | time 37 | traceroute 38 | tree 39 | unzip 40 | util-linux 41 | vte-profile 42 | vulkan-loader 43 | wget 44 | which 45 | whois 46 | words 47 | xorg-x11-xauth 48 | xz 49 | zip 50 | -------------------------------------------------------------------------------- /images/fedora/f37/missing-docs: -------------------------------------------------------------------------------- 1 | acl 2 | alternatives 3 | audit-libs 4 | authselect 5 | authselect-libs 6 | bash 7 | ca-certificates 8 | coreutils-common 9 | cracklib 10 | crypto-policies 11 | curl 12 | cyrus-sasl-lib 13 | dnf 14 | dnf-data 15 | elfutils-libelf 16 | expat 17 | file-libs 18 | filesystem 19 | findutils 20 | gawk 21 | glib2 22 | gmp 23 | gnupg2 24 | gnutls 25 | gpgme 26 | grep 27 | gzip 28 | ima-evm-utils 29 | keyutils-libs 30 | krb5-libs 31 | libarchive 32 | libassuan 33 | libblkid 34 | libcap 35 | libcap-ng 36 | libdb 37 | libdnf 38 | libeconf 39 | libevent 40 | libffi 41 | libgcrypt 42 | libgomp 43 | libgpg-error 44 | libidn2 45 | libksba 46 | libmodulemd 47 | libpwquality 48 | librepo 49 | libsemanage 50 | libsigsegv 51 | libsolv 52 | libssh 53 | libtasn1 54 | libtirpc 55 | libunistring 56 | libverto 57 | libxcrypt 58 | libxml2 59 | libyaml 60 | lz4-libs 61 | mpfr 62 | ncurses-base 63 | nettle 64 | openldap 65 | openssl 66 | p11-kit 67 | pam 68 | pcre 69 | pcre2-syntax 70 | popt 71 | python3 72 | python3-gpg 73 | python3-libs 74 | python3-rpm 75 | readline 76 | rpm 77 | sed 78 | setup 79 | shadow-utils 80 | sqlite-libs 81 | sudo 82 | systemd 83 | systemd-libs 84 | tar 85 | tpm2-tss 86 | tzdata 87 | util-linux-core 88 | vim-minimal 89 | yum 90 | zchunk-libs 91 | zlib 92 | -------------------------------------------------------------------------------- /images/fedora/f38/Containerfile: -------------------------------------------------------------------------------- 1 | FROM registry.fedoraproject.org/fedora:38 2 | 3 | ARG NAME=fedora-toolbox 4 | ARG VERSION=38 5 | LABEL com.github.containers.toolbox="true" \ 6 | com.redhat.component="$NAME" \ 7 | name="$NAME" \ 8 | version="$VERSION" \ 9 | usage="This image is meant to be used with the toolbox(1) command" \ 10 | summary="Image for creating Fedora Toolbx containers" \ 11 | maintainer="Debarshi Ray " 12 | 13 | COPY README.md / 14 | 15 | RUN rm /etc/rpm/macros.image-language-conf 16 | RUN sed -i '/tsflags=nodocs/d' /etc/dnf/dnf.conf 17 | 18 | RUN dnf -y upgrade 19 | RUN dnf -y swap coreutils-single coreutils-full 20 | RUN dnf -y swap glibc-minimal-langpack glibc-all-langpacks 21 | 22 | COPY missing-docs / 23 | RUN dnf -y reinstall $(/dev/null; then \ 34 | echo "$file: No such file or directory" >&2; \ 35 | ret_val=1; \ 36 | break; \ 37 | fi; \ 38 | done &2; \ 50 | echo "$broken_packages" >&2; \ 51 | false; \ 52 | fi 53 | 54 | RUN dnf clean all 55 | -------------------------------------------------------------------------------- /images/fedora/f38/README.md: -------------------------------------------------------------------------------- 1 | [Toolbx](https://containertoolbx.org/) is a tool for Linux, which allows the 2 | use of interactive command line environments for development and 3 | troubleshooting the host operating system, without having to install software 4 | on the host. It is built on top of [Podman](https://podman.io/) and other 5 | standard container technologies from [OCI](https://opencontainers.org/). 6 | 7 | Toolbx environments have seamless access to the user's home directory, 8 | the Wayland and X11 sockets, networking (including Avahi), removable devices 9 | (like USB sticks), systemd journal, SSH agent, D-Bus, ulimits, /dev and the 10 | udev database, etc.. 11 | 12 | This is particularly useful on 13 | [OSTree](https://ostreedev.github.io/ostree/) based operating systems like 14 | [Fedora CoreOS](https://coreos.fedoraproject.org/) and 15 | [Silverblue](https://silverblue.fedoraproject.org/). The intention of these 16 | systems is to discourage installation of software on the host, and instead 17 | install software as (or in) containers — they mostly don't even have package 18 | managers like DNF or YUM. This makes it difficult to set up a development 19 | environment or troubleshoot the operating system in the usual way. 20 | 21 | Toolbx solves this problem by providing a fully mutable container within 22 | which one can install their favourite development and troubleshooting tools, 23 | editors and SDKs. For example, it's possible to do `yum install ansible` 24 | without affecting the base operating system. 25 | 26 | However, this tool doesn't *require* using an OSTree based system. It works 27 | equally well on Fedora Workstation and Server, and that's a useful way to 28 | incrementally adopt containerization. 29 | 30 | The Toolbx environment is based on an [OCI](https://www.opencontainers.org/) 31 | image. On Fedora this is the `fedora-toolbox` image. This image is used to 32 | create a Toolbx container that offers the interactive command line 33 | environment. 34 | 35 | Note that Toolbx makes no promise about security beyond what's already 36 | available in the usual command line environment on the host that everybody is 37 | familiar with. 38 | 39 | 40 | ## Installation & Use 41 | 42 | See our guides on 43 | [installing & getting started](https://containertoolbx.org/install/) with 44 | Toolbx and [Linux distro support](https://containertoolbx.org/distros/). 45 | -------------------------------------------------------------------------------- /images/fedora/f38/ensure-files: -------------------------------------------------------------------------------- 1 | /usr/share/man/man1/bash.1* 2 | /usr/share/man/man1/cd.1* 3 | /usr/share/man/man1/export.1* 4 | 5 | /usr/share/man/man1/cat.1* 6 | /usr/share/man/man1/cp.1* 7 | /usr/share/man/man1/ls.1* 8 | 9 | /usr/share/cracklib/cracklib-small.pwd* 10 | /usr/share/cracklib/pw_dict.pwd* 11 | 12 | /usr/share/man/man8/dnf.8* 13 | /usr/share/man/man5/dnf.conf.5* 14 | 15 | /usr/share/locale/de/LC_MESSAGES/elfutils.mo 16 | /usr/share/locale/ja/LC_MESSAGES/elfutils.mo 17 | 18 | /usr/share/locale/fr/LC_MESSAGES/gawk.mo 19 | /usr/share/locale/ko/LC_MESSAGES/gawk.mo 20 | 21 | /usr/share/man/man1/gpg2.1* 22 | /usr/share/man/man7/gnupg2.7* 23 | 24 | /usr/share/info/nettle.info* 25 | 26 | /usr/share/locale/fr/LC_MESSAGES/popt.mo 27 | /usr/share/locale/ja/LC_MESSAGES/popt.mo 28 | 29 | /usr/share/man/fr/man1/pstree.1* 30 | /usr/share/man/ko/man1/pstree.1* 31 | /usr/share/man/man1/pstree.1* 32 | 33 | /usr/share/info/history.info* 34 | 35 | /usr/share/man/fr/man8/rpm.8* 36 | /usr/share/man/ja/man8/rpm.8* 37 | /usr/share/man/man8/rpm.8* 38 | 39 | /usr/share/man/fr/man8/useradd.8* 40 | /usr/share/man/ja/man8/useradd.8* 41 | /usr/share/man/man8/useradd.8* 42 | 43 | /usr/share/man/man1/cal.1.* 44 | /usr/share/man/man1/getopt.1* 45 | /usr/share/man/man1/hexdump.1* 46 | 47 | /usr/share/man/man1/kill.1* 48 | /usr/share/man/man8/mount.8* 49 | 50 | /usr/share/man/fr/man1/xz.1* 51 | /usr/share/man/ko/man1/xz.1* 52 | /usr/share/man/man1/xz.1* 53 | -------------------------------------------------------------------------------- /images/fedora/f38/extra-packages: -------------------------------------------------------------------------------- 1 | bash-completion 2 | bc 3 | bzip2 4 | cracklib-dicts 5 | diffutils 6 | dnf-plugins-core 7 | findutils 8 | flatpak-spawn 9 | fpaste 10 | gawk-all-langpacks 11 | git 12 | glibc-gconv-extra 13 | gnupg2 14 | gnupg2-smime 15 | gvfs-client 16 | hostname 17 | iproute 18 | iputils 19 | keyutils 20 | krb5-libs 21 | less 22 | lsof 23 | man-db 24 | man-pages 25 | mesa-dri-drivers 26 | mesa-vulkan-drivers 27 | mtr 28 | nano-default-editor 29 | nss-mdns 30 | openssh-clients 31 | passwd 32 | pigz 33 | procps-ng 34 | psmisc 35 | rsync 36 | shadow-utils 37 | sudo 38 | tcpdump 39 | time 40 | traceroute 41 | tree 42 | unzip 43 | util-linux 44 | vte-profile 45 | vulkan-loader 46 | wget 47 | which 48 | whois 49 | words 50 | xorg-x11-xauth 51 | xz 52 | zip 53 | -------------------------------------------------------------------------------- /images/fedora/f38/missing-docs: -------------------------------------------------------------------------------- 1 | acl 2 | alternatives 3 | audit-libs 4 | authselect 5 | authselect-libs 6 | bash 7 | ca-certificates 8 | coreutils-common 9 | cracklib 10 | crypto-policies 11 | curl 12 | cyrus-sasl-lib 13 | dnf 14 | dnf-data 15 | elfutils-libelf 16 | expat 17 | file-libs 18 | filesystem 19 | findutils 20 | gawk 21 | glib2 22 | gmp 23 | gnupg2 24 | gnutls 25 | gpgme 26 | grep 27 | gzip 28 | ima-evm-utils 29 | keyutils-libs 30 | krb5-libs 31 | libarchive 32 | libassuan 33 | libblkid 34 | libcap 35 | libcap-ng 36 | libcomps 37 | libdb 38 | libdnf 39 | libeconf 40 | libevent 41 | libffi 42 | libgcrypt 43 | libgomp 44 | libgpg-error 45 | libidn2 46 | libksba 47 | libmodulemd 48 | libpwquality 49 | librepo 50 | libsemanage 51 | libsigsegv 52 | libsolv 53 | libssh 54 | libtasn1 55 | libtirpc 56 | libunistring 57 | libunistring1.0 58 | libverto 59 | libxcrypt 60 | libxml2 61 | libyaml 62 | lz4-libs 63 | mpfr 64 | ncurses-base 65 | nettle 66 | openldap 67 | openssl 68 | p11-kit 69 | pam 70 | pcre2-syntax 71 | popt 72 | python3 73 | python3-libs 74 | python3-rpm 75 | readline 76 | rpm 77 | rpm-sequoia 78 | sed 79 | setup 80 | shadow-utils 81 | sqlite-libs 82 | sudo 83 | systemd 84 | systemd-libs 85 | tar 86 | tpm2-tss 87 | tzdata 88 | util-linux-core 89 | vim-minimal 90 | yum 91 | zchunk-libs 92 | zlib 93 | -------------------------------------------------------------------------------- /images/fedora/f39/Containerfile: -------------------------------------------------------------------------------- 1 | FROM registry.fedoraproject.org/fedora:39 2 | 3 | ARG NAME=fedora-toolbox 4 | ARG VERSION=39 5 | LABEL com.github.containers.toolbox="true" \ 6 | com.redhat.component="$NAME" \ 7 | name="$NAME" \ 8 | version="$VERSION" \ 9 | usage="This image is meant to be used with the toolbox(1) command" \ 10 | summary="Image for creating Fedora Toolbx containers" \ 11 | maintainer="Debarshi Ray " 12 | 13 | COPY README.md / 14 | 15 | RUN rm /etc/rpm/macros.image-language-conf 16 | RUN sed -i '/tsflags=nodocs/d' /etc/dnf/dnf.conf 17 | 18 | RUN dnf -y upgrade 19 | RUN dnf -y swap coreutils-single coreutils-full 20 | RUN dnf -y swap glibc-minimal-langpack glibc-all-langpacks 21 | 22 | COPY missing-docs / 23 | RUN dnf -y reinstall $(/dev/null; then \ 34 | echo "$file: No such file or directory" >&2; \ 35 | ret_val=1; \ 36 | break; \ 37 | fi; \ 38 | done &2; \ 50 | echo "$broken_packages" >&2; \ 51 | false; \ 52 | fi 53 | 54 | RUN dnf clean all 55 | -------------------------------------------------------------------------------- /images/fedora/f39/README.md: -------------------------------------------------------------------------------- 1 | [Toolbx](https://containertoolbx.org/) is a tool for Linux, which allows the 2 | use of interactive command line environments for software development and 3 | troubleshooting the host operating system, without having to install software 4 | on the host. It is built on top of [Podman](https://podman.io/) and other 5 | standard container technologies from [OCI](https://opencontainers.org/). 6 | 7 | Toolbx environments have seamless access to the user's home directory, 8 | the Wayland and X11 sockets, networking (including Avahi), removable devices 9 | (like USB sticks), systemd journal, SSH agent, D-Bus, ulimits, /dev and the 10 | udev database, etc.. 11 | 12 | This is particularly useful on 13 | [OSTree](https://ostreedev.github.io/ostree/) based operating systems like 14 | [Fedora CoreOS](https://fedoraproject.org/coreos/) and 15 | [Silverblue](https://fedoraproject.org/silverblue/). The intention of these 16 | systems is to discourage installation of software on the host, and instead 17 | install software as (or in) containers — they mostly don't even have package 18 | managers like DNF or YUM. This makes it difficult to set up a development 19 | environment or troubleshoot the operating system in the usual way. 20 | 21 | Toolbx solves this problem by providing a fully mutable container within 22 | which one can install their favourite development and troubleshooting tools, 23 | editors and SDKs. For example, it's possible to do `yum install ansible` 24 | without affecting the base operating system. 25 | 26 | However, this tool doesn't *require* using an OSTree based system. It works 27 | equally well on Fedora Workstation and Server, and that's a useful way to 28 | incrementally adopt containerization. 29 | 30 | The Toolbx environment is based on an [OCI](https://www.opencontainers.org/) 31 | image. On Fedora this is the `fedora-toolbox` image. This image is used to 32 | create a Toolbx container that offers the interactive command line 33 | environment. 34 | 35 | Note that Toolbx makes no promise about security beyond what's already 36 | available in the usual command line environment on the host that everybody is 37 | familiar with. 38 | 39 | 40 | ## Installation & Use 41 | 42 | See our guides on 43 | [installing & getting started](https://containertoolbx.org/install/) with 44 | Toolbx and [Linux distro support](https://containertoolbx.org/distros/). 45 | -------------------------------------------------------------------------------- /images/fedora/f39/ensure-files: -------------------------------------------------------------------------------- 1 | /usr/share/man/man1/bash.1* 2 | /usr/share/man/man1/cd.1* 3 | /usr/share/man/man1/export.1* 4 | 5 | /usr/share/man/man1/cat.1* 6 | /usr/share/man/man1/cp.1* 7 | /usr/share/man/man1/ls.1* 8 | 9 | /usr/share/cracklib/cracklib-small.pwd* 10 | /usr/share/cracklib/pw_dict.pwd* 11 | 12 | /usr/share/man/man8/dnf.8* 13 | /usr/share/man/man5/dnf.conf.5* 14 | 15 | /usr/share/locale/de/LC_MESSAGES/elfutils.mo 16 | /usr/share/locale/ja/LC_MESSAGES/elfutils.mo 17 | 18 | /usr/share/locale/fr/LC_MESSAGES/gawk.mo 19 | /usr/share/locale/ko/LC_MESSAGES/gawk.mo 20 | 21 | /usr/share/man/man1/gpg2.1* 22 | /usr/share/man/man7/gnupg2.7* 23 | 24 | /usr/share/info/nettle.info* 25 | 26 | /usr/share/locale/fr/LC_MESSAGES/popt.mo 27 | /usr/share/locale/ja/LC_MESSAGES/popt.mo 28 | 29 | /usr/share/man/fr/man1/pstree.1* 30 | /usr/share/man/ko/man1/pstree.1* 31 | /usr/share/man/man1/pstree.1* 32 | 33 | /usr/share/info/history.info* 34 | 35 | /usr/share/man/man8/rpm.8* 36 | /usr/share/man/man8/rpm2cpio.8* 37 | 38 | /usr/share/man/fr/man8/useradd.8* 39 | /usr/share/man/ja/man8/useradd.8* 40 | /usr/share/man/man8/useradd.8* 41 | 42 | /usr/share/man/man1/cal.1.* 43 | /usr/share/man/man1/getopt.1* 44 | /usr/share/man/man1/hexdump.1* 45 | 46 | /usr/share/man/man1/kill.1* 47 | /usr/share/man/man8/mount.8* 48 | 49 | /usr/share/man/fr/man1/xz.1* 50 | /usr/share/man/ko/man1/xz.1* 51 | /usr/share/man/man1/xz.1* 52 | -------------------------------------------------------------------------------- /images/fedora/f39/extra-packages: -------------------------------------------------------------------------------- 1 | bash-completion 2 | bc 3 | bzip2 4 | cracklib-dicts 5 | diffutils 6 | dnf-plugins-core 7 | findutils 8 | flatpak-spawn 9 | fpaste 10 | gawk-all-langpacks 11 | git 12 | glibc-gconv-extra 13 | gnupg2 14 | gnupg2-smime 15 | gvfs-client 16 | hostname 17 | iproute 18 | iputils 19 | keyutils 20 | krb5-libs 21 | less 22 | lsof 23 | man-db 24 | man-pages 25 | mesa-dri-drivers 26 | mesa-vulkan-drivers 27 | mtr 28 | nano-default-editor 29 | nss-mdns 30 | openssh-clients 31 | passwd 32 | pigz 33 | procps-ng 34 | psmisc 35 | rsync 36 | shadow-utils 37 | sudo 38 | tcpdump 39 | time 40 | traceroute 41 | tree 42 | unzip 43 | util-linux 44 | vte-profile 45 | vulkan-loader 46 | wget 47 | which 48 | whois 49 | words 50 | xorg-x11-xauth 51 | xz 52 | zip 53 | -------------------------------------------------------------------------------- /images/fedora/f39/missing-docs: -------------------------------------------------------------------------------- 1 | acl 2 | alternatives 3 | audit-libs 4 | authselect 5 | authselect-libs 6 | bash 7 | ca-certificates 8 | coreutils-common 9 | cracklib 10 | crypto-policies 11 | curl 12 | cyrus-sasl-lib 13 | dnf 14 | dnf-data 15 | elfutils-libelf 16 | expat 17 | file-libs 18 | filesystem 19 | findutils 20 | gawk 21 | glib2 22 | gmp 23 | gnupg2 24 | gnutls 25 | grep 26 | gzip 27 | ima-evm-utils 28 | keyutils-libs 29 | krb5-libs 30 | libarchive 31 | libassuan 32 | libblkid 33 | libcap 34 | libcap-ng 35 | libcomps 36 | libdb 37 | libdnf 38 | libeconf 39 | libevent 40 | libffi 41 | libgcrypt 42 | libgomp 43 | libgpg-error 44 | libidn2 45 | libksba 46 | libmodulemd 47 | libpwquality 48 | librepo 49 | libsemanage 50 | libsigsegv 51 | libsolv 52 | libssh 53 | libtasn1 54 | libtirpc 55 | libunistring 56 | libverto 57 | libxcrypt 58 | libxml2 59 | libyaml 60 | lz4-libs 61 | mpfr 62 | ncurses-base 63 | nettle 64 | openldap 65 | openssl 66 | p11-kit 67 | pam 68 | pcre2-syntax 69 | popt 70 | python3 71 | python3-libs 72 | python3-rpm 73 | readline 74 | rpm 75 | rpm-sequoia 76 | sed 77 | setup 78 | shadow-utils 79 | sqlite-libs 80 | sudo 81 | systemd 82 | systemd-libs 83 | tar 84 | tpm2-tss 85 | tzdata 86 | util-linux-core 87 | vim-minimal 88 | yum 89 | zchunk-libs 90 | zlib 91 | -------------------------------------------------------------------------------- /images/rhel/8.5/Containerfile: -------------------------------------------------------------------------------- 1 | FROM registry.access.redhat.com/ubi8:8.5 2 | 3 | ENV NAME=toolbox-container VERSION=8.5 4 | LABEL com.github.containers.toolbox="true" \ 5 | com.redhat.component="$NAME" \ 6 | com.redhat.license_terms="https://www.redhat.com/en/about/red-hat-end-user-license-agreements#UBI" \ 7 | name="$NAME" \ 8 | version="$VERSION" \ 9 | usage="This image is meant to be used with the toolbox command" \ 10 | summary="Base image for creating UBI toolbox containers" \ 11 | maintainer="Oliver Gutiérrez " 12 | 13 | COPY README.md / 14 | 15 | RUN sed -i '/tsflags=nodocs/d' /etc/dnf/dnf.conf 16 | RUN dnf -y swap coreutils-single coreutils-full 17 | 18 | COPY missing-docs / 19 | RUN dnf -y reinstall $(/dev/null; then \ 35 | echo "$file: No such file or directory" >&2; \ 36 | ret_val=1; \ 37 | break; \ 38 | fi; \ 39 | done /dev/null; then \ 35 | echo "$file: No such file or directory" >&2; \ 36 | ret_val=1; \ 37 | break; \ 38 | fi; \ 39 | done )\s*(.*)/\1\2 myhostname \3/' /etc/nsswitch.conf 19 | 20 | # Install ubuntu-minimal & ubuntu-standard 21 | # Ask resolvconf maintainer script not to touch resolve.conf file 22 | # Install extra packages as well as libnss-myhostname 23 | COPY extra-packages / 24 | RUN apt-get update && \ 25 | echo "resolvconf resolvconf/linkify-resolvconf boolean false" | debconf-set-selections && \ 26 | DEBIAN_FRONTEND=noninteractive apt-get install -y \ 27 | ubuntu-minimal ubuntu-standard \ 28 | libnss-myhostname \ 29 | $(cat extra-packages | xargs) && \ 30 | rm -rd /var/lib/apt/lists/* 31 | RUN rm /extra-packages 32 | 33 | # Allow authentication with empty password, promptless 34 | RUN sed -i '/^auth.*pam_unix.so/s/nullok_secure/try_first_pass nullok/' /etc/pam.d/common-auth 35 | 36 | # Fix empty bind-mount to clear selinuxfs (see #337) 37 | RUN mkdir /usr/share/empty 38 | 39 | # Disable APT ESM hook which tries to enable some systemd services on each apt invocation 40 | RUN rm /etc/apt/apt.conf.d/20apt-esm-hook.conf 41 | -------------------------------------------------------------------------------- /images/ubuntu/16.04/extra-packages: -------------------------------------------------------------------------------- 1 | curl 2 | git 3 | gnupg2 4 | keyutils 5 | tree 6 | unzip 7 | zip 8 | zsh 9 | -------------------------------------------------------------------------------- /images/ubuntu/18.04/Containerfile: -------------------------------------------------------------------------------- 1 | FROM docker.io/library/ubuntu:18.04 2 | 3 | LABEL com.github.containers.toolbox="true" \ 4 | name="ubuntu-toolbox" \ 5 | version="18.04" \ 6 | usage="This image is meant to be used with the toolbox command" \ 7 | summary="Base image for creating Ubuntu Toolbx containers" \ 8 | maintainer="Ievgen Popovych " 9 | 10 | # Remove apt configuration optimized for containers 11 | # Remove docker-gzip-indexes to help with "command-not-found" 12 | RUN rm /etc/apt/apt.conf.d/docker-gzip-indexes /etc/apt/apt.conf.d/docker-no-languages 13 | 14 | # Enable myhostname nss plugin for clean hostname resolution without patching 15 | # hosts (at least for sudo), add it right after 'files' entry. We expect that 16 | # this entry is not present yet. Do this early so that package postinst (which 17 | # adds it too late in the order) skips this step 18 | RUN sed -Ei 's/^(hosts:.*)(\)\s*(.*)/\1\2 myhostname \3/' /etc/nsswitch.conf 19 | 20 | # Restore documentation but do not upgrade all packages 21 | # Install extra packages as well as libnss-myhostname 22 | COPY extra-packages / 23 | RUN sed -Ei '/apt-get (update|upgrade)/s/^/#/' /usr/local/sbin/unminimize && \ 24 | apt-get update && \ 25 | yes | /usr/local/sbin/unminimize && \ 26 | DEBIAN_FRONTEND=noninteractive apt-get -y install \ 27 | ubuntu-minimal ubuntu-standard \ 28 | libnss-myhostname \ 29 | $(cat extra-packages | xargs) && \ 30 | rm -rd /var/lib/apt/lists/* 31 | RUN rm /extra-packages 32 | 33 | # Allow authentication with empty password, promptless 34 | RUN sed -i '/^auth.*pam_unix.so/s/nullok_secure/try_first_pass nullok/' /etc/pam.d/common-auth 35 | 36 | # Enable the use of p11-kit-client.so to access CA certificates from the host 37 | RUN mkdir --parents /etc/pkcs11/modules 38 | 39 | # Fix empty bind-mount to clear selinuxfs (see #337) 40 | RUN mkdir /usr/share/empty 41 | 42 | # Disable APT ESM hook which tries to enable some systemd services on each apt invocation 43 | RUN rm /etc/apt/apt.conf.d/20apt-esm-hook.conf 44 | -------------------------------------------------------------------------------- /images/ubuntu/18.04/extra-packages: -------------------------------------------------------------------------------- 1 | curl 2 | git 3 | gnupg2 4 | keyutils 5 | p11-kit-modules 6 | tree 7 | unzip 8 | zip 9 | zsh 10 | -------------------------------------------------------------------------------- /images/ubuntu/20.04/Containerfile: -------------------------------------------------------------------------------- 1 | FROM docker.io/library/ubuntu:20.04 2 | 3 | LABEL com.github.containers.toolbox="true" \ 4 | name="ubuntu-toolbox" \ 5 | version="20.04" \ 6 | usage="This image is meant to be used with the toolbox command" \ 7 | summary="Base image for creating Ubuntu Toolbx containers" \ 8 | maintainer="Ievgen Popovych " 9 | 10 | # Remove apt configuration optimized for containers 11 | # Remove docker-gzip-indexes to help with "command-not-found" 12 | RUN rm /etc/apt/apt.conf.d/docker-gzip-indexes /etc/apt/apt.conf.d/docker-no-languages 13 | 14 | # Enable myhostname nss plugin for clean hostname resolution without patching 15 | # hosts (at least for sudo), add it right after 'files' entry. We expect that 16 | # this entry is not present yet. Do this early so that package postinst (which 17 | # adds it too late in the order) skips this step 18 | RUN sed -Ei 's/^(hosts:.*)(\)\s*(.*)/\1\2 myhostname \3/' /etc/nsswitch.conf 19 | 20 | # Restore documentation but do not upgrade all packages 21 | # Install ubuntu-minimal & ubuntu-standard 22 | # Install extra packages as well as libnss-myhostname 23 | COPY extra-packages / 24 | RUN sed -Ei '/apt-get (update|upgrade)/s/^/#/' /usr/local/sbin/unminimize && \ 25 | apt-get update && \ 26 | yes | /usr/local/sbin/unminimize && \ 27 | DEBIAN_FRONTEND=noninteractive apt-get -y install \ 28 | ubuntu-minimal ubuntu-standard \ 29 | libnss-myhostname \ 30 | flatpak-xdg-utils \ 31 | $(cat extra-packages | xargs) && \ 32 | rm -rd /var/lib/apt/lists/* 33 | RUN rm /extra-packages 34 | 35 | # Allow authentication with empty password, promptless 36 | RUN sed -i '/^auth.*pam_unix.so/s/nullok_secure/try_first_pass nullok/' /etc/pam.d/common-auth 37 | 38 | # Enable the use of p11-kit-client.so to access CA certificates from the host 39 | RUN mkdir --parents /etc/pkcs11/modules 40 | 41 | # Fix empty bind-mount to clear selinuxfs (see #337) 42 | RUN mkdir /usr/share/empty 43 | 44 | # Add flatpak-spawn to /usr/bin 45 | RUN ln -s /usr/libexec/flatpak-xdg-utils/flatpak-spawn /usr/bin/ 46 | 47 | # Disable APT ESM hook which tries to enable some systemd services on each apt invocation 48 | RUN rm /etc/apt/apt.conf.d/20apt-esm-hook.conf 49 | -------------------------------------------------------------------------------- /images/ubuntu/20.04/extra-packages: -------------------------------------------------------------------------------- 1 | curl 2 | git 3 | gnupg2 4 | keyutils 5 | p11-kit-modules 6 | tree 7 | unzip 8 | zip 9 | zsh 10 | -------------------------------------------------------------------------------- /images/ubuntu/22.04/Containerfile: -------------------------------------------------------------------------------- 1 | FROM docker.io/library/ubuntu:22.04 2 | 3 | LABEL com.github.containers.toolbox="true" \ 4 | name="ubuntu-toolbox" \ 5 | version="22.04" \ 6 | usage="This image is meant to be used with the toolbox command" \ 7 | summary="Base image for creating Ubuntu Toolbx containers" \ 8 | maintainer="Ievgen Popovych " 9 | 10 | # Remove apt configuration optimized for containers 11 | # Remove docker-gzip-indexes to help with "command-not-found" 12 | RUN rm /etc/apt/apt.conf.d/docker-gzip-indexes /etc/apt/apt.conf.d/docker-no-languages 13 | 14 | # Enable myhostname nss plugin for clean hostname resolution without patching 15 | # hosts (at least for sudo), add it right after 'files' entry. We expect that 16 | # this entry is not present yet. Do this early so that package postinst (which 17 | # adds it too late in the order) skips this step 18 | RUN sed -Ei 's/^(hosts:.*)(\)\s*(.*)/\1\2 myhostname \3/' /etc/nsswitch.conf 19 | 20 | # Restore documentation but do not upgrade all packages 21 | # Install ubuntu-minimal & ubuntu-standard 22 | # Install extra packages as well as libnss-myhostname 23 | COPY extra-packages / 24 | RUN sed -Ei '/apt-get (update|upgrade)/s/^/#/' /usr/local/sbin/unminimize && \ 25 | apt-get update && \ 26 | yes | /usr/local/sbin/unminimize && \ 27 | DEBIAN_FRONTEND=noninteractive apt-get -y install \ 28 | ubuntu-minimal ubuntu-standard \ 29 | libnss-myhostname \ 30 | flatpak-xdg-utils \ 31 | $(cat extra-packages | xargs) && \ 32 | rm -rd /var/lib/apt/lists/* 33 | RUN rm /extra-packages 34 | 35 | # Enable the use of p11-kit-client.so to access CA certificates from the host 36 | RUN mkdir --parents /etc/pkcs11/modules 37 | 38 | # Fix empty bind-mount to clear selinuxfs (see #337) 39 | RUN mkdir /usr/share/empty 40 | 41 | # Add flatpak-spawn to /usr/bin 42 | RUN ln -s /usr/libexec/flatpak-xdg-utils/flatpak-spawn /usr/bin/ 43 | 44 | # Disable APT ESM hook which tries to enable some systemd services on each apt invocation 45 | RUN rm /etc/apt/apt.conf.d/20apt-esm-hook.conf 46 | -------------------------------------------------------------------------------- /images/ubuntu/22.04/extra-packages: -------------------------------------------------------------------------------- 1 | curl 2 | git 3 | gnupg2 4 | keyutils 5 | p11-kit-modules 6 | tree 7 | unzip 8 | zip 9 | zsh 10 | -------------------------------------------------------------------------------- /images/ubuntu/24.04/Containerfile: -------------------------------------------------------------------------------- 1 | FROM docker.io/library/ubuntu:24.04 2 | 3 | LABEL com.github.containers.toolbox="true" \ 4 | name="ubuntu-toolbox" \ 5 | version="24.04" \ 6 | usage="This image is meant to be used with the toolbox command" \ 7 | summary="Base image for creating Ubuntu Toolbx containers" \ 8 | maintainer="Ievgen Popovych " 9 | 10 | # Remove apt configuration optimized for containers 11 | # Remove docker-gzip-indexes to help with "command-not-found" 12 | RUN rm /etc/apt/apt.conf.d/docker-gzip-indexes /etc/apt/apt.conf.d/docker-no-languages 13 | 14 | # Enable myhostname nss plugin for clean hostname resolution without patching 15 | # hosts (at least for sudo), add it right after 'files' entry. We expect that 16 | # this entry is not present yet. Do this early so that package postinst (which 17 | # adds it too late in the order) skips this step 18 | RUN sed -Ei 's/^(hosts:.*)(\)\s*(.*)/\1\2 myhostname \3/' /etc/nsswitch.conf 19 | 20 | # Restore documentation but do not upgrade all packages 21 | # Install ubuntu-minimal & ubuntu-standard 22 | # Install extra packages as well as libnss-myhostname 23 | COPY extra-packages / 24 | RUN apt-get update && \ 25 | DEBIAN_FRONTEND=noninteractive apt-get -y install unminimize && \ 26 | sed -Ei '/apt-get (update|upgrade)/s/^/#/' /usr/bin/unminimize && \ 27 | yes | /usr/bin/unminimize && \ 28 | DEBIAN_FRONTEND=noninteractive apt-get -y install \ 29 | ubuntu-minimal ubuntu-standard \ 30 | libnss-myhostname \ 31 | flatpak-xdg-utils \ 32 | $(cat extra-packages | xargs) && \ 33 | rm -rd /var/lib/apt/lists/* 34 | RUN rm /extra-packages 35 | 36 | # Enable the use of p11-kit-client.so to access CA certificates from the host 37 | RUN mkdir --parents /etc/pkcs11/modules 38 | 39 | # Fix empty bind-mount to clear selinuxfs (see #337) 40 | RUN mkdir /usr/share/empty 41 | 42 | # Add flatpak-spawn to /usr/bin 43 | RUN ln -s /usr/libexec/flatpak-xdg-utils/flatpak-spawn /usr/bin/ 44 | 45 | # Having anything in /home prevents toolbox from symlinking /var/home there, 46 | # and 'ubuntu' user with UID 1000 will most likely conflict with host user as well 47 | RUN userdel --remove ubuntu 48 | 49 | # Disable APT ESM hook which tries to enable some systemd services on each apt invocation 50 | RUN rm /etc/apt/apt.conf.d/20apt-esm-hook.conf 51 | -------------------------------------------------------------------------------- /images/ubuntu/24.04/extra-packages: -------------------------------------------------------------------------------- 1 | curl 2 | git 3 | gnupg2 4 | keyutils 5 | p11-kit-modules 6 | tree 7 | unzip 8 | zip 9 | zsh 10 | -------------------------------------------------------------------------------- /images/ubuntu/24.10/Containerfile: -------------------------------------------------------------------------------- 1 | FROM docker.io/library/ubuntu:24.10 2 | 3 | LABEL com.github.containers.toolbox="true" \ 4 | name="ubuntu-toolbox" \ 5 | version="24.10" \ 6 | usage="This image is meant to be used with the toolbox command" \ 7 | summary="Base image for creating Ubuntu Toolbx containers" \ 8 | maintainer="Ievgen Popovych " 9 | 10 | # Remove apt configuration optimized for containers 11 | # Remove docker-gzip-indexes to help with "command-not-found" 12 | RUN rm /etc/apt/apt.conf.d/docker-gzip-indexes /etc/apt/apt.conf.d/docker-no-languages 13 | 14 | # Restore documentation but do not upgrade all packages 15 | # Install ubuntu-minimal & ubuntu-standard 16 | # Install extra packages as well as libnss-myhostname 17 | COPY extra-packages / 18 | RUN apt-get update && \ 19 | DEBIAN_FRONTEND=noninteractive apt-get -y install unminimize && \ 20 | sed -Ei '/apt-get (update|upgrade)/s/^/#/' /usr/bin/unminimize && \ 21 | yes | /usr/bin/unminimize && \ 22 | DEBIAN_FRONTEND=noninteractive apt-get -y install \ 23 | ubuntu-minimal ubuntu-standard \ 24 | libnss-myhostname \ 25 | flatpak-xdg-utils \ 26 | $(cat extra-packages | xargs) && \ 27 | rm -rd /var/lib/apt/lists/* 28 | RUN rm /extra-packages 29 | 30 | # Enable the use of p11-kit-client.so to access CA certificates from the host 31 | RUN mkdir --parents /etc/pkcs11/modules 32 | 33 | # Fix empty bind-mount to clear selinuxfs (see #337) 34 | RUN mkdir /usr/share/empty 35 | 36 | # Add flatpak-spawn to /usr/bin 37 | RUN ln -s /usr/libexec/flatpak-xdg-utils/flatpak-spawn /usr/bin/ 38 | 39 | # Having anything in /home prevents toolbox from symlinking /var/home there, 40 | # and 'ubuntu' user with UID 1000 will most likely conflict with host user as well 41 | RUN userdel --remove ubuntu 42 | 43 | # Disable APT ESM hook which tries to enable some systemd services on each apt invocation 44 | RUN rm /etc/apt/apt.conf.d/20apt-esm-hook.conf 45 | -------------------------------------------------------------------------------- /images/ubuntu/24.10/extra-packages: -------------------------------------------------------------------------------- 1 | curl 2 | git 3 | gnupg2 4 | keyutils 5 | p11-kit-modules 6 | tree 7 | unzip 8 | zip 9 | zsh 10 | -------------------------------------------------------------------------------- /images/ubuntu/25.04/Containerfile: -------------------------------------------------------------------------------- 1 | FROM docker.io/library/ubuntu:25.04 2 | 3 | LABEL com.github.containers.toolbox="true" \ 4 | name="ubuntu-toolbox" \ 5 | version="25.04" \ 6 | usage="This image is meant to be used with the toolbox command" \ 7 | summary="Base image for creating Ubuntu Toolbx containers" \ 8 | maintainer="Ievgen Popovych " 9 | 10 | # Remove apt configuration optimized for containers 11 | # Remove docker-gzip-indexes to help with "command-not-found" 12 | RUN rm /etc/apt/apt.conf.d/docker-gzip-indexes /etc/apt/apt.conf.d/docker-no-languages 13 | 14 | # Restore documentation but do not upgrade all packages 15 | # Install ubuntu-minimal & ubuntu-standard 16 | # Install extra packages as well as libnss-myhostname 17 | COPY extra-packages / 18 | RUN apt-get update && \ 19 | DEBIAN_FRONTEND=noninteractive apt-get -y install unminimize && \ 20 | sed -Ei '/apt-get (update|upgrade)/s/^/#/' /usr/bin/unminimize && \ 21 | yes | /usr/bin/unminimize && \ 22 | DEBIAN_FRONTEND=noninteractive apt-get -y install \ 23 | ubuntu-minimal ubuntu-standard \ 24 | libnss-myhostname \ 25 | flatpak-xdg-utils \ 26 | $(cat extra-packages | xargs) && \ 27 | rm -rd /var/lib/apt/lists/* 28 | RUN rm /extra-packages 29 | 30 | # Enable the use of p11-kit-client.so to access CA certificates from the host 31 | RUN mkdir --parents /etc/pkcs11/modules 32 | 33 | # Fix empty bind-mount to clear selinuxfs (see #337) 34 | RUN mkdir /usr/share/empty 35 | 36 | # Add flatpak-spawn to /usr/bin 37 | RUN ln -s /usr/libexec/flatpak-xdg-utils/flatpak-spawn /usr/bin/ 38 | 39 | # Having anything in /home prevents toolbox from symlinking /var/home there, 40 | # and 'ubuntu' user with UID 1000 will most likely conflict with host user as well 41 | RUN userdel --remove ubuntu 42 | 43 | # Disable APT ESM hook which tries to enable some systemd services on each apt invocation 44 | RUN rm /etc/apt/apt.conf.d/20apt-esm-hook.conf 45 | -------------------------------------------------------------------------------- /images/ubuntu/25.04/extra-packages: -------------------------------------------------------------------------------- 1 | curl 2 | git 3 | gnupg2 4 | keyutils 5 | p11-kit-modules 6 | tree 7 | unzip 8 | zip 9 | zsh 10 | -------------------------------------------------------------------------------- /meson_options.txt: -------------------------------------------------------------------------------- 1 | option( 2 | 'bash_completions', 3 | description: 'Install Bash completion scripts', 4 | type: 'feature', 5 | ) 6 | 7 | option( 8 | 'bash_completions_dir', 9 | description: 'Directory for Bash completion scripts', 10 | type: 'string', 11 | ) 12 | 13 | option( 14 | 'fish_completions', 15 | description: 'Install fish completion scripts', 16 | type: 'feature', 17 | ) 18 | 19 | option( 20 | 'fish_completions_dir', 21 | description: 'Directory for fish completion scripts', 22 | type: 'string', 23 | ) 24 | 25 | option( 26 | 'zsh_completions_dir', 27 | description: 'Directory for Z shell completion scripts (default=$datadir/zsh/site-functions)', 28 | type: 'string', 29 | ) 30 | 31 | option( 32 | 'migration_path_for_coreos_toolbox', 33 | description: 'Offer a migration path to users of github.com/coreos/toolbox', 34 | type: 'boolean', 35 | value: false 36 | ) 37 | 38 | option( 39 | 'profile_dir', 40 | description: 'Directory for profile.d files to be read by the shell on start-up', 41 | type: 'string', 42 | value: '/usr/share/profile.d' 43 | ) 44 | 45 | option( 46 | 'tmpfiles_dir', 47 | description: 'Directory for system-wide tmpfiles.d(5) files', 48 | type: 'string', 49 | ) 50 | -------------------------------------------------------------------------------- /meson_post_install.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # 3 | # Copyright © 2021 – 2024 Red Hat Inc. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | 18 | import os 19 | import subprocess 20 | import sys 21 | 22 | destdir = os.environ.get('DESTDIR', '') 23 | euid = os.geteuid() 24 | 25 | if not destdir and not os.path.exists('/run/.containerenv') and euid == 0: 26 | subprocess.run(['systemd-tmpfiles', '--create'], check=True) 27 | 28 | sys.exit(0) 29 | -------------------------------------------------------------------------------- /playbooks/build.yaml: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright © 2022 – 2024 Red Hat, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | - name: Build Toolbx 18 | command: meson compile -C builddir 19 | args: 20 | chdir: '{{ zuul.project.src_dir }}' 21 | creates: builddir/src/toolbox 22 | 23 | - name: Install Toolbx 24 | become: yes 25 | command: meson install -C builddir 26 | args: 27 | chdir: '{{ zuul.project.src_dir }}' 28 | creates: /usr/local/bin/toolbox 29 | -------------------------------------------------------------------------------- /playbooks/dependencies-centos-9-stream.yaml: -------------------------------------------------------------------------------- 1 | - name: Install RPM packages from CentOS Stream 2 | become: yes 3 | package: 4 | name: 5 | - flatpak-session-helper 6 | - gcc 7 | - golang 8 | - httpd-tools 9 | - meson 10 | - ninja-build 11 | - openssl 12 | - pkgconfig(bash-completion) 13 | - podman 14 | - shadow-utils-subid-devel 15 | - skopeo 16 | - systemd 17 | - udisks2 18 | 19 | - name: Install RPM packages from CentOS Stream CodeReady Linux Builder 20 | become: yes 21 | package: 22 | enablerepo: crb 23 | name: 24 | - golang-github-cpuguy83-md2man 25 | 26 | - name: Enable EPEL 27 | become: yes 28 | package: 29 | name: 30 | - epel-release 31 | 32 | - name: Install RPM packages from EPEL 33 | become: yes 34 | package: 35 | name: 36 | - ShellCheck 37 | - bats 38 | - codespell 39 | - fish 40 | 41 | - name: Ensure that 'p11-kit server' is absent 42 | become: yes 43 | package: 44 | name: 45 | - p11-kit-server 46 | state: absent 47 | 48 | - name: Download Go modules 49 | command: go mod download -x 50 | environment: 51 | GOINSECURE: go.opencensus.io 52 | args: 53 | chdir: '{{ zuul.project.src_dir }}/src' 54 | 55 | - name: Initialize Git submodules 56 | command: git submodule init 57 | args: 58 | chdir: '{{ zuul.project.src_dir }}' 59 | 60 | - name: Update Git submodules 61 | command: git submodule update 62 | args: 63 | chdir: '{{ zuul.project.src_dir }}' 64 | 65 | - name: Check versions of crucial packages 66 | command: rpm -qa ShellCheck bash bash-completion bats codespell *kernel* gcc *glibc* golang golang-github-cpuguy83-md2man shadow-utils-subid-devel podman conmon containernetworking-plugins containers-common container-selinux crun fuse-overlayfs flatpak-session-helper skopeo 67 | 68 | - name: Show podman versions 69 | command: podman version 70 | 71 | - name: Show podman debug information 72 | command: podman info --debug 73 | -------------------------------------------------------------------------------- /playbooks/dependencies-fedora-restricted.yaml: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright © 2023 – 2025 Red Hat, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | - name: Ensure that subordinate group ID ranges are absent 18 | become: yes 19 | file: 20 | path: /etc/subgid 21 | state: absent 22 | 23 | - name: Ensure that subordinate user ID ranges are absent 24 | become: yes 25 | file: 26 | path: /etc/subuid 27 | state: absent 28 | 29 | - name: Install RPM packages 30 | become: yes 31 | package: 32 | name: 33 | - ShellCheck 34 | - codespell 35 | - fish 36 | - flatpak-session-helper 37 | - gcc 38 | - golang 39 | - golang-github-cpuguy83-md2man 40 | - meson 41 | - ninja-build 42 | - pkgconfig(bash-completion) 43 | - shadow-utils-subid-devel 44 | - systemd 45 | - udisks2 46 | state: present 47 | update_cache: "{{ true if zuul.attempts > 1 else false }}" 48 | use: "{{ 'dnf' if zuul.attempts > 1 else 'auto' }}" 49 | 50 | - name: Ensure that 'p11-kit server' is absent 51 | become: yes 52 | package: 53 | name: 54 | - p11-kit-server 55 | state: absent 56 | update_cache: "{{ true if zuul.attempts > 1 else false }}" 57 | use: "{{ 'dnf' if zuul.attempts > 1 else 'auto' }}" 58 | 59 | - name: Ensure that podman(1) is absent 60 | become: yes 61 | package: 62 | name: 63 | - podman 64 | state: absent 65 | update_cache: "{{ true if zuul.attempts > 1 else false }}" 66 | use: "{{ 'dnf' if zuul.attempts > 1 else 'auto' }}" 67 | 68 | - name: Ensure that skopeo(1) is absent 69 | become: yes 70 | package: 71 | name: 72 | - skopeo 73 | state: absent 74 | update_cache: "{{ true if zuul.attempts > 1 else false }}" 75 | use: "{{ 'dnf' if zuul.attempts > 1 else 'auto' }}" 76 | 77 | - name: Download Go modules 78 | command: go mod download -x 79 | environment: 80 | GOINSECURE: go.opencensus.io 81 | args: 82 | chdir: '{{ zuul.project.src_dir }}/src' 83 | 84 | - name: Initialize Git submodules 85 | command: git submodule init 86 | args: 87 | chdir: '{{ zuul.project.src_dir }}' 88 | 89 | - name: Update Git submodules 90 | command: git submodule update 91 | args: 92 | chdir: '{{ zuul.project.src_dir }}' 93 | 94 | - name: Check versions of crucial packages 95 | command: rpm -qa ShellCheck bash-completion codespell *kernel* gcc *glibc* shadow-utils-subid-devel golang golang-github-cpuguy83-md2man flatpak-session-helper 96 | -------------------------------------------------------------------------------- /playbooks/dependencies-fedora.yaml: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright © 2022 – 2025 Red Hat, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | - name: Install RPM packages 18 | become: yes 19 | package: 20 | update_cache: "{{ true if zuul.attempts > 1 else false }}" 21 | name: 22 | - ShellCheck 23 | - bats 24 | - codespell 25 | - fish 26 | - flatpak-session-helper 27 | - gcc 28 | - golang 29 | - golang-github-cpuguy83-md2man 30 | - httpd-tools 31 | - meson 32 | - ninja-build 33 | - openssl 34 | - pkgconfig(bash-completion) 35 | - podman 36 | - shadow-utils-subid-devel 37 | - skopeo 38 | - systemd 39 | - udisks2 40 | use: "{{ 'dnf' if zuul.attempts > 1 else 'auto' }}" 41 | 42 | - name: Ensure that 'p11-kit server' is absent 43 | become: yes 44 | package: 45 | name: 46 | - p11-kit-server 47 | state: absent 48 | update_cache: "{{ true if zuul.attempts > 1 else false }}" 49 | use: "{{ 'dnf' if zuul.attempts > 1 else 'auto' }}" 50 | 51 | - name: Download Go modules 52 | command: go mod download -x 53 | environment: 54 | GOINSECURE: go.opencensus.io 55 | args: 56 | chdir: '{{ zuul.project.src_dir }}/src' 57 | 58 | - name: Initialize Git submodules 59 | command: git submodule init 60 | args: 61 | chdir: '{{ zuul.project.src_dir }}' 62 | 63 | - name: Update Git submodules 64 | command: git submodule update 65 | args: 66 | chdir: '{{ zuul.project.src_dir }}' 67 | 68 | - name: Check versions of crucial packages 69 | command: rpm -qa ShellCheck bash bash-completion bats codespell *kernel* gcc *glibc* shadow-utils-subid-devel golang golang-github-cpuguy83-md2man podman conmon containernetworking-plugins containers-common container-selinux crun fuse-overlayfs flatpak-session-helper skopeo 70 | 71 | - name: Show podman versions 72 | command: podman version 73 | 74 | - name: Show podman debug information 75 | command: podman info --debug 76 | -------------------------------------------------------------------------------- /playbooks/setup-env-migration-path-for-coreos-toolbox.yaml: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright © 2022 – 2024 Red Hat, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | --- 18 | - hosts: all 19 | tasks: 20 | - include_tasks: dependencies-centos-9-stream.yaml 21 | 22 | - name: Set up build directory 23 | command: meson -Dmigration_path_for_coreos_toolbox=true builddir 24 | args: 25 | chdir: '{{ zuul.project.src_dir }}' 26 | -------------------------------------------------------------------------------- /playbooks/setup-env-restricted.yaml: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright © 2023 – 2024 Red Hat, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | --- 18 | - hosts: all 19 | tasks: 20 | - include_tasks: dependencies-fedora-restricted.yaml 21 | 22 | - name: Set up build directory 23 | command: meson setup builddir 24 | args: 25 | chdir: '{{ zuul.project.src_dir }}' 26 | -------------------------------------------------------------------------------- /playbooks/setup-env.yaml: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright © 2021 – 2024 Red Hat, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | --- 18 | - hosts: all 19 | tasks: 20 | - include_tasks: dependencies-fedora.yaml 21 | 22 | - name: Set up build directory 23 | command: meson setup builddir 24 | args: 25 | chdir: '{{ zuul.project.src_dir }}' 26 | -------------------------------------------------------------------------------- /playbooks/system-test-commands-options.yaml: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright © 2021 – 2024 Red Hat, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | --- 18 | - hosts: all 19 | tasks: 20 | - include_tasks: build.yaml 21 | 22 | - name: Run the commands-options system tests 23 | command: bats --filter-tags commands-options ./test/system 24 | environment: 25 | TMPDIR: '/var/tmp' 26 | TOOLBX: '/usr/local/bin/toolbox' 27 | TOOLBX_TEST_SYSTEM_TAGS: 'arch-fedora,commands-options,custom-image,ubuntu' 28 | args: 29 | chdir: '{{ zuul.project.src_dir }}' 30 | -------------------------------------------------------------------------------- /playbooks/system-test-runtime-environment-arch-fedora.yaml: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright © 2021 – 2024 Red Hat, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | --- 18 | - hosts: all 19 | tasks: 20 | - include_tasks: build.yaml 21 | 22 | - name: Run the (arch-fedora,runtime-environment) system tests 23 | command: bats --filter-tags arch-fedora,runtime-environment ./test/system 24 | environment: 25 | TMPDIR: '/var/tmp' 26 | TOOLBX: '/usr/local/bin/toolbox' 27 | TOOLBX_TEST_SYSTEM_TAGS: 'arch-fedora,runtime-environment' 28 | args: 29 | chdir: '{{ zuul.project.src_dir }}' 30 | -------------------------------------------------------------------------------- /playbooks/system-test-runtime-environment-ubuntu.yaml: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright © 2021 – 2024 Red Hat, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | --- 18 | - hosts: all 19 | tasks: 20 | - include_tasks: build.yaml 21 | 22 | - name: Run the (runtime-environment,ubuntu) system tests 23 | command: bats --filter-tags runtime-environment,ubuntu ./test/system 24 | environment: 25 | TMPDIR: '/var/tmp' 26 | TOOLBX: '/usr/local/bin/toolbox' 27 | TOOLBX_TEST_SYSTEM_TAGS: 'runtime-environment,ubuntu' 28 | args: 29 | chdir: '{{ zuul.project.src_dir }}' 30 | -------------------------------------------------------------------------------- /playbooks/unit-test.yaml: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright © 2021 – 2024 Red Hat, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | --- 18 | - hosts: all 19 | tasks: 20 | - include_tasks: build.yaml 21 | 22 | - name: Test 23 | command: meson test -C builddir --verbose 24 | args: 25 | chdir: '{{ zuul.project.src_dir }}' 26 | -------------------------------------------------------------------------------- /profile.d/meson.build: -------------------------------------------------------------------------------- 1 | profile_toolbox_sh = files('toolbox.sh') 2 | 3 | if shellcheck.found() 4 | test('shellcheck profile.d/toolbox.sh', shellcheck, args: ['--shell=sh', profile_toolbox_sh]) 5 | endif 6 | 7 | install_data( 8 | profile_toolbox_sh, 9 | install_dir: profiledir, 10 | ) 11 | -------------------------------------------------------------------------------- /src/cmd/help.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2019 – 2024 Red Hat Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package cmd 18 | 19 | import ( 20 | "errors" 21 | "fmt" 22 | "os" 23 | 24 | "github.com/containers/toolbox/pkg/utils" 25 | "github.com/spf13/cobra" 26 | ) 27 | 28 | var helpCmd = &cobra.Command{ 29 | Use: "help", 30 | Short: "Display help information about Toolbx", 31 | RunE: help, 32 | ValidArgsFunction: completionCommands, 33 | } 34 | 35 | func init() { 36 | helpCmd.SetHelpFunc(helpHelp) 37 | rootCmd.AddCommand(helpCmd) 38 | } 39 | 40 | func help(cmd *cobra.Command, args []string) error { 41 | if utils.IsInsideContainer() { 42 | if !utils.IsInsideToolboxContainer() { 43 | return errors.New("this is not a Toolbx container") 44 | } 45 | 46 | exitCode, err := utils.ForwardToHost() 47 | return &exitError{exitCode, err} 48 | } 49 | 50 | if err := helpShowManual(args); err != nil { 51 | return err 52 | } 53 | 54 | return nil 55 | } 56 | 57 | func helpHelp(cmd *cobra.Command, args []string) { 58 | if utils.IsInsideContainer() { 59 | if !utils.IsInsideToolboxContainer() { 60 | fmt.Fprintf(os.Stderr, "Error: this is not a Toolbx container\n") 61 | return 62 | } 63 | 64 | if _, err := utils.ForwardToHost(); err != nil { 65 | fmt.Fprintf(os.Stderr, "Error: %s\n", err) 66 | return 67 | } 68 | 69 | return 70 | } 71 | 72 | if err := helpShowManual(args); err != nil { 73 | fmt.Fprintf(os.Stderr, "Error: %s\n", err) 74 | return 75 | } 76 | } 77 | 78 | func helpShowManual(args []string) error { 79 | var manual string 80 | 81 | if len(args) == 0 { 82 | manual = "toolbox" 83 | } else if args[0] == executableBase { 84 | manual = "toolbox" 85 | } else { 86 | manual = "toolbox-" + args[0] 87 | } 88 | 89 | if err := showManual(manual); err != nil { 90 | return err 91 | } 92 | 93 | return nil 94 | } 95 | -------------------------------------------------------------------------------- /src/cmd/rootDefault.go: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright © 2021 – 2024 Red Hat Inc. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | 17 | //go:build !migration_path_for_coreos_toolbox 18 | // +build !migration_path_for_coreos_toolbox 19 | 20 | package cmd 21 | 22 | import ( 23 | "errors" 24 | "fmt" 25 | "strings" 26 | 27 | "github.com/spf13/cobra" 28 | ) 29 | 30 | func preRunIsCoreOSBug() error { 31 | return nil 32 | } 33 | 34 | func rootRunImpl(cmd *cobra.Command, args []string) error { 35 | var builder strings.Builder 36 | fmt.Fprintf(&builder, "missing command\n") 37 | fmt.Fprintf(&builder, "\n") 38 | 39 | usage := getUsageForCommonCommands() 40 | fmt.Fprintf(&builder, "%s", usage) 41 | 42 | fmt.Fprintf(&builder, "\n") 43 | fmt.Fprintf(&builder, "Run '%s --help' for usage.", executableBase) 44 | 45 | errMsg := builder.String() 46 | return errors.New(errMsg) 47 | } 48 | -------------------------------------------------------------------------------- /src/cmd/rootMigrationPath.go: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright © 2021 – 2025 Red Hat Inc. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | 17 | //go:build migration_path_for_coreos_toolbox 18 | // +build migration_path_for_coreos_toolbox 19 | 20 | package cmd 21 | 22 | import ( 23 | "errors" 24 | "os" 25 | "strings" 26 | 27 | "github.com/containers/toolbox/pkg/utils" 28 | "github.com/spf13/cobra" 29 | ) 30 | 31 | func preRunIsCoreOSBug() error { 32 | if containerType := os.Getenv("container"); containerType == "" { 33 | var builder strings.Builder 34 | builder.WriteString("/run/.containerenv found on what looks like the host\n") 35 | builder.WriteString("If this is the host, then remove /run/.containerenv and try again.\n") 36 | builder.WriteString("Otherwise, contact your system administrator or file a bug.") 37 | 38 | errMsg := builder.String() 39 | return errors.New(errMsg) 40 | } 41 | 42 | return nil 43 | } 44 | 45 | func rootRunImpl(cmd *cobra.Command, args []string) error { 46 | if len(args) != 0 { 47 | panic("unexpected argument: commands known or unknown shouldn't reach here") 48 | } 49 | 50 | if utils.IsInsideContainer() { 51 | if !utils.IsInsideToolboxContainer() { 52 | return errors.New("this is not a Toolbx container") 53 | } 54 | 55 | exitCode, err := utils.ForwardToHost() 56 | return &exitError{exitCode, err} 57 | } 58 | 59 | container, image, release, err := resolveContainerAndImageNames("", "", "", "", "") 60 | if err != nil { 61 | return err 62 | } 63 | 64 | userShell := os.Getenv("SHELL") 65 | if userShell == "" { 66 | return errors.New("failed to get the current user's default shell") 67 | } 68 | 69 | command := []string{userShell, "-l"} 70 | 71 | if err := runCommand(container, true, image, release, 0, command, true, true, false); err != nil { 72 | return err 73 | } 74 | 75 | return nil 76 | } 77 | -------------------------------------------------------------------------------- /src/cmd/root_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2022 Ondřej Míchal 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package cmd 18 | 19 | import ( 20 | "errors" 21 | "testing" 22 | 23 | "github.com/stretchr/testify/assert" 24 | ) 25 | 26 | func getExitError(err error, rc int) error { 27 | return &exitError{rc, err} 28 | } 29 | 30 | func TestExitError(t *testing.T) { 31 | t.Run("correct error interface implementation", func(t *testing.T) { 32 | var err error = &exitError{0, nil} 33 | assert.Implements(t, (*error)(nil), err) 34 | }) 35 | 36 | testCases := []struct { 37 | name string 38 | err error 39 | rc int 40 | }{ 41 | { 42 | "errmsg empty; return code 0; casting from Error", 43 | nil, 44 | 0, 45 | }, 46 | { 47 | "errmsg empty; return code > 0; casting from Error", 48 | nil, 49 | 42, 50 | }, 51 | { 52 | "errmsg full; return code 0; casting from Error", 53 | errors.New("this is an error message"), 54 | 0, 55 | }, 56 | { 57 | "errmsg full; return code > 0; casting from Error", 58 | errors.New("this is an error message"), 59 | 42, 60 | }, 61 | } 62 | 63 | for _, tc := range testCases { 64 | t.Run(tc.name, func(t *testing.T) { 65 | err := getExitError(tc.err, tc.rc) 66 | var errExit *exitError 67 | 68 | assert.ErrorAs(t, err, &errExit) 69 | assert.Equal(t, tc.rc, errExit.code) 70 | if tc.err != nil { 71 | assert.Equal(t, tc.err.Error(), errExit.Error()) 72 | } 73 | }) 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /src/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/containers/toolbox 2 | 3 | go 1.21 4 | 5 | require ( 6 | github.com/HarryMichal/go-version v1.0.1 7 | github.com/NVIDIA/go-nvlib v0.7.1 8 | github.com/NVIDIA/go-nvml v0.12.4-1 9 | github.com/NVIDIA/nvidia-container-toolkit v1.17.4 10 | github.com/acobaugh/osrelease v0.1.0 11 | github.com/briandowns/spinner v1.23.2 12 | github.com/docker/go-units v0.5.0 13 | github.com/fsnotify/fsnotify v1.7.0 14 | github.com/go-logfmt/logfmt v0.5.0 15 | github.com/godbus/dbus/v5 v5.0.6 16 | github.com/google/renameio/v2 v2.0.0 17 | github.com/sirupsen/logrus v1.9.3 18 | github.com/spf13/cobra v1.3.0 19 | github.com/spf13/viper v1.19.0 20 | github.com/stretchr/testify v1.10.0 21 | golang.org/x/sys v0.26.0 22 | tags.cncf.io/container-device-interface v0.8.0 23 | tags.cncf.io/container-device-interface/specs-go v0.8.0 24 | ) 25 | 26 | require ( 27 | github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect 28 | github.com/fatih/color v1.14.1 // indirect 29 | github.com/google/uuid v1.6.0 // indirect 30 | github.com/hashicorp/hcl v1.0.0 // indirect 31 | github.com/inconshreveable/mousetrap v1.0.0 // indirect 32 | github.com/magiconair/properties v1.8.7 // indirect 33 | github.com/mattn/go-colorable v0.1.13 // indirect 34 | github.com/mattn/go-isatty v0.0.17 // indirect 35 | github.com/mitchellh/mapstructure v1.5.0 // indirect 36 | github.com/opencontainers/runtime-spec v1.2.0 // indirect 37 | github.com/opencontainers/runtime-tools v0.9.1-0.20221107090550-2e043c6bd626 // indirect 38 | github.com/pelletier/go-toml/v2 v2.2.2 // indirect 39 | github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect 40 | github.com/rogpeppe/go-internal v1.12.0 // indirect 41 | github.com/sagikazarmark/locafero v0.4.0 // indirect 42 | github.com/sagikazarmark/slog-shim v0.1.0 // indirect 43 | github.com/sourcegraph/conc v0.3.0 // indirect 44 | github.com/spf13/afero v1.11.0 // indirect 45 | github.com/spf13/cast v1.6.0 // indirect 46 | github.com/spf13/pflag v1.0.5 // indirect 47 | github.com/subosito/gotenv v1.6.0 // indirect 48 | github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635 // indirect 49 | go.uber.org/atomic v1.9.0 // indirect 50 | go.uber.org/multierr v1.9.0 // indirect 51 | golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect 52 | golang.org/x/mod v0.20.0 // indirect 53 | golang.org/x/term v0.1.0 // indirect 54 | golang.org/x/text v0.14.0 // indirect 55 | gopkg.in/ini.v1 v1.67.0 // indirect 56 | gopkg.in/yaml.v2 v2.4.0 // indirect 57 | gopkg.in/yaml.v3 v3.0.1 // indirect 58 | sigs.k8s.io/yaml v1.3.0 // indirect 59 | ) 60 | -------------------------------------------------------------------------------- /src/meson_generate_completions.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # 3 | # Copyright © 2022 Ondřej Míchal 4 | # Copyright © 2022 – 2024 Red Hat Inc. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | 19 | import os 20 | import subprocess 21 | import sys 22 | 23 | if len(sys.argv) != 3: 24 | print('{}: wrong arguments'.format(sys.argv[0]), file=sys.stderr) 25 | print('Usage: {} [SOURCE DIR] [COMPLETION TYPE]'.format(sys.argv[0]), file=sys.stderr) 26 | sys.exit(1) 27 | 28 | source_dir = sys.argv[1] 29 | completion_type = sys.argv[2] 30 | 31 | os.chdir(source_dir) 32 | output = subprocess.run(['go', 'run', '.', 'completion', completion_type], check=True) 33 | 34 | sys.exit(0) 35 | -------------------------------------------------------------------------------- /src/meson_go_fmt.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # 3 | # Copyright © 2022 – 2024 Red Hat Inc. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | 18 | import subprocess 19 | import sys 20 | 21 | if len(sys.argv) != 2: 22 | print('{}: wrong arguments'.format(sys.argv[0]), file=sys.stderr) 23 | print('Usage: {} [SOURCE DIR]'.format(sys.argv[0]), file=sys.stderr) 24 | sys.exit(1) 25 | 26 | source_dir = sys.argv[1] 27 | 28 | gofmt = subprocess.run(['gofmt', '-d', source_dir], capture_output=True, check=True) 29 | if gofmt.stdout: 30 | diff = gofmt.stdout.decode() 31 | print(diff) 32 | sys.exit(1) 33 | 34 | sys.exit(0) 35 | -------------------------------------------------------------------------------- /src/pkg/podman/errors.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2024 Red Hat Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package podman 18 | 19 | import ( 20 | "fmt" 21 | ) 22 | 23 | type ImageError struct { 24 | Image string 25 | Err error 26 | } 27 | 28 | func (err *ImageError) Error() string { 29 | errMsg := fmt.Sprintf("%s: %s", err.Image, err.Err) 30 | return errMsg 31 | } 32 | 33 | func (err *ImageError) Unwrap() error { 34 | return err.Err 35 | } 36 | -------------------------------------------------------------------------------- /src/pkg/shell/shell.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2019 – 2024 Red Hat Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package shell 18 | 19 | import ( 20 | "context" 21 | "errors" 22 | "fmt" 23 | "io" 24 | "os" 25 | "os/exec" 26 | 27 | "github.com/sirupsen/logrus" 28 | ) 29 | 30 | func Run(name string, stdin io.Reader, stdout, stderr io.Writer, arg ...string) error { 31 | ctx := context.Background() 32 | err := RunContext(ctx, name, stdin, stdout, stderr, arg...) 33 | return err 34 | } 35 | 36 | func RunContext(ctx context.Context, name string, stdin io.Reader, stdout, stderr io.Writer, arg ...string) error { 37 | exitCode, err := RunContextWithExitCode(ctx, name, stdin, stdout, stderr, arg...) 38 | if err != nil { 39 | return err 40 | } 41 | if exitCode != 0 { 42 | return fmt.Errorf("failed to invoke %s(1)", name) 43 | } 44 | return nil 45 | } 46 | 47 | func RunContextWithExitCode(ctx context.Context, 48 | name string, 49 | stdin io.Reader, 50 | stdout, stderr io.Writer, 51 | arg ...string) (int, error) { 52 | 53 | logLevel := logrus.GetLevel() 54 | if stderr == nil && logLevel >= logrus.DebugLevel { 55 | stderr = os.Stderr 56 | } 57 | 58 | cmd := exec.CommandContext(ctx, name, arg...) 59 | cmd.Stdin = stdin 60 | cmd.Stdout = stdout 61 | cmd.Stderr = stderr 62 | 63 | if err := cmd.Run(); err != nil { 64 | if errors.Is(err, exec.ErrNotFound) { 65 | return 1, fmt.Errorf("%s(1) not found", name) 66 | } 67 | 68 | if ctxErr := ctx.Err(); ctxErr != nil { 69 | return 1, ctxErr 70 | } 71 | 72 | var exitErr *exec.ExitError 73 | if errors.As(err, &exitErr) { 74 | exitCode := exitErr.ExitCode() 75 | return exitCode, nil 76 | } 77 | 78 | return 1, fmt.Errorf("failed to invoke %s(1)", name) 79 | } 80 | 81 | return 0, nil 82 | } 83 | 84 | func RunWithExitCode(name string, stdin io.Reader, stdout, stderr io.Writer, arg ...string) (int, error) { 85 | ctx := context.Background() 86 | exitCode, err := RunContextWithExitCode(ctx, name, stdin, stdout, stderr, arg...) 87 | return exitCode, err 88 | } 89 | -------------------------------------------------------------------------------- /src/pkg/skopeo/skopeo.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2023 – 2024 Red Hat Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package skopeo 18 | 19 | import ( 20 | "bytes" 21 | "context" 22 | "encoding/json" 23 | 24 | "github.com/containers/toolbox/pkg/shell" 25 | ) 26 | 27 | type Layer struct { 28 | Size json.Number 29 | } 30 | type Image struct { 31 | LayersData []Layer 32 | } 33 | 34 | func Inspect(ctx context.Context, target string) (*Image, error) { 35 | var stdout bytes.Buffer 36 | 37 | targetWithTransport := "docker://" + target 38 | args := []string{"inspect", "--format", "json", targetWithTransport} 39 | 40 | if err := shell.RunContext(ctx, "skopeo", nil, &stdout, nil, args...); err != nil { 41 | return nil, err 42 | } 43 | 44 | output := stdout.Bytes() 45 | var image Image 46 | if err := json.Unmarshal(output, &image); err != nil { 47 | return nil, err 48 | } 49 | 50 | return &image, nil 51 | } 52 | -------------------------------------------------------------------------------- /src/pkg/term/term.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2023 – 2024 Red Hat Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package term 18 | 19 | import ( 20 | "os" 21 | 22 | "golang.org/x/sys/unix" 23 | ) 24 | 25 | type Option func(*unix.Termios) 26 | 27 | func GetState(file *os.File) (*unix.Termios, error) { 28 | fileFD := file.Fd() 29 | fileFDInt := int(fileFD) 30 | state, err := unix.IoctlGetTermios(fileFDInt, unix.TCGETS) 31 | return state, err 32 | } 33 | 34 | func IsTerminal(file *os.File) bool { 35 | if _, err := GetState(file); err != nil { 36 | return false 37 | } 38 | 39 | return true 40 | } 41 | 42 | func NewStateFrom(oldState *unix.Termios, options ...Option) *unix.Termios { 43 | newState := *oldState 44 | for _, option := range options { 45 | option(&newState) 46 | } 47 | 48 | return &newState 49 | } 50 | 51 | func SetState(file *os.File, state *unix.Termios) error { 52 | fileFD := file.Fd() 53 | fileFDInt := int(fileFD) 54 | err := unix.IoctlSetTermios(fileFDInt, unix.TCSETS, state) 55 | return err 56 | } 57 | 58 | func WithVMIN(vmin uint8) Option { 59 | return func(state *unix.Termios) { 60 | state.Cc[unix.VMIN] = vmin 61 | } 62 | } 63 | 64 | func WithVTIME(vtime uint8) Option { 65 | return func(state *unix.Termios) { 66 | state.Cc[unix.VTIME] = vtime 67 | } 68 | } 69 | 70 | func WithoutECHO() Option { 71 | return func(state *unix.Termios) { 72 | state.Lflag &^= unix.ECHO 73 | } 74 | } 75 | 76 | func WithoutICANON() Option { 77 | return func(state *unix.Termios) { 78 | state.Lflag &^= unix.ICANON 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /src/pkg/utils/arch.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2023 – 2025 Red Hat Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package utils 18 | 19 | func getDefaultReleaseArch() (string, error) { 20 | return "latest", nil 21 | } 22 | 23 | func getFullyQualifiedImageArch(image, release string) string { 24 | imageFull := "quay.io/toolbx/" + image 25 | return imageFull 26 | } 27 | 28 | func getP11KitClientPathsArch() []string { 29 | paths := []string{"/usr/lib/pkcs11/p11-kit-client.so"} 30 | return paths 31 | } 32 | 33 | func parseReleaseArch(release string) (string, error) { 34 | if release != "latest" && release != "rolling" && release != "" { 35 | return "", &ParseReleaseError{"The release must be 'latest'."} 36 | } 37 | 38 | return "latest", nil 39 | } 40 | -------------------------------------------------------------------------------- /src/pkg/utils/errors.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2022 – 2025 Red Hat Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package utils 18 | 19 | import ( 20 | "fmt" 21 | ) 22 | 23 | type ContainerError struct { 24 | Container string 25 | Image string 26 | Err error 27 | } 28 | 29 | type DistroError struct { 30 | Distro string 31 | Err error 32 | } 33 | 34 | type FlockError struct { 35 | Path string 36 | Errs []error 37 | errSuffix string 38 | } 39 | 40 | type ImageError struct { 41 | Image string 42 | Err error 43 | } 44 | 45 | type ParseReleaseError struct { 46 | Hint string 47 | } 48 | 49 | func (err *ContainerError) Error() string { 50 | errMsg := fmt.Sprintf("%s: %s", err.Container, err.Err) 51 | return errMsg 52 | } 53 | 54 | func (err *ContainerError) Unwrap() error { 55 | return err.Err 56 | } 57 | 58 | func (err *DistroError) Error() string { 59 | errMsg := fmt.Sprintf("%s: %s", err.Distro, err.Err) 60 | return errMsg 61 | } 62 | 63 | func (err *DistroError) Unwrap() error { 64 | return err.Err 65 | } 66 | 67 | func (err *FlockError) Error() string { 68 | if err.Errs == nil || len(err.Errs) != 2 { 69 | panicMsg := fmt.Sprintf("invalid %T", err) 70 | panic(panicMsg) 71 | } 72 | 73 | errSuffix := " " 74 | if err.errSuffix != "" { 75 | errSuffix = fmt.Sprintf(" %s ", err.errSuffix) 76 | } 77 | 78 | errMsg := fmt.Sprintf("%s%s%s: %s", err.Errs[0], errSuffix, err.Path, err.Errs[1]) 79 | return errMsg 80 | } 81 | 82 | func (err *FlockError) Unwrap() []error { 83 | return err.Errs 84 | } 85 | 86 | func (err *ImageError) Error() string { 87 | errMsg := fmt.Sprintf("%s: %s", err.Image, err.Err) 88 | return errMsg 89 | } 90 | 91 | func (err *ImageError) Unwrap() error { 92 | return err.Err 93 | } 94 | 95 | func (err *ParseReleaseError) Error() string { 96 | return err.Hint 97 | } 98 | -------------------------------------------------------------------------------- /src/pkg/utils/fedora.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2021 – 2025 Red Hat Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package utils 18 | 19 | import ( 20 | "strconv" 21 | "strings" 22 | 23 | "github.com/sirupsen/logrus" 24 | ) 25 | 26 | func getDefaultReleaseFedora() (string, error) { 27 | release, err := getHostVersionID() 28 | if err != nil { 29 | return "", err 30 | } 31 | 32 | return release, nil 33 | } 34 | 35 | func getFullyQualifiedImageFedora(image, release string) string { 36 | imageFull := "registry.fedoraproject.org/" + image 37 | return imageFull 38 | } 39 | 40 | func getP11KitClientPathsFedora() []string { 41 | paths := []string{"/usr/lib64/pkcs11/p11-kit-client.so"} 42 | return paths 43 | } 44 | 45 | func parseReleaseFedora(release string) (string, error) { 46 | if strings.HasPrefix(release, "F") || strings.HasPrefix(release, "f") { 47 | release = release[1:] 48 | } 49 | 50 | releaseN, err := strconv.Atoi(release) 51 | if err != nil { 52 | logrus.Debugf("Parsing release %s as an integer failed: %s", release, err) 53 | return "", &ParseReleaseError{"The release must be a positive integer."} 54 | } 55 | 56 | if releaseN <= 0 { 57 | return "", &ParseReleaseError{"The release must be a positive integer."} 58 | } 59 | 60 | return release, nil 61 | } 62 | -------------------------------------------------------------------------------- /src/pkg/utils/libsubid-wrappers.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2022 – 2024 Red Hat Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | 18 | #include 19 | #include 20 | 21 | #include "libsubid-wrappers.h" 22 | 23 | #ifndef SUBID_ABI_VERSION 24 | #define SUBID_ABI_VERSION 3.0.0 25 | #endif 26 | 27 | #if SUBID_ABI_MAJOR < 4 28 | #define subid_init libsubid_init 29 | #define subid_get_gid_ranges get_subgid_ranges 30 | #define subid_get_uid_ranges get_subuid_ranges 31 | #endif 32 | 33 | #define TOOLBOX_STRINGIZE_HELPER(s) #s 34 | #define TOOLBOX_STRINGIZE(s) TOOLBOX_STRINGIZE_HELPER (s) 35 | 36 | 37 | typedef bool (*ToolboxSubidInitFunc) (const char *progname, FILE *logfd); 38 | typedef int (*ToolboxSubidGetRangesFunc) (const char *owner, struct subid_range **ranges); 39 | 40 | const char *TOOLBOX_LIBSUBID = "libsubid.so." TOOLBOX_STRINGIZE (SUBID_ABI_VERSION); 41 | 42 | const char *TOOLBOX_SUBID_INIT = TOOLBOX_STRINGIZE (subid_init); 43 | 44 | const char *TOOLBOX_SUBID_GET_GID_RANGES_SYMBOL = TOOLBOX_STRINGIZE (subid_get_gid_ranges); 45 | const char *TOOLBOX_SUBID_GET_UID_RANGES_SYMBOL = TOOLBOX_STRINGIZE (subid_get_uid_ranges); 46 | 47 | 48 | void 49 | toolbox_subid_init (void *subid_init_func) 50 | { 51 | (* (ToolboxSubidInitFunc) subid_init_func) (NULL, stderr); 52 | } 53 | 54 | 55 | int 56 | toolbox_subid_get_id_ranges (void *subid_get_id_ranges_func, const char *owner, struct subid_range **ranges) 57 | { 58 | int ret_val = 0; 59 | 60 | ret_val = (* (ToolboxSubidGetRangesFunc) subid_get_id_ranges_func) (owner, ranges); 61 | return ret_val; 62 | } 63 | -------------------------------------------------------------------------------- /src/pkg/utils/libsubid-wrappers.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2023 – 2024 Red Hat Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #pragma once 18 | 19 | #include 20 | 21 | extern const char *TOOLBOX_LIBSUBID; 22 | 23 | extern const char *TOOLBOX_LIBSUBID_INIT; 24 | extern const char *TOOLBOX_SUBID_INIT; 25 | 26 | extern const char *TOOLBOX_SUBID_GET_GID_RANGES_SYMBOL; 27 | extern const char *TOOLBOX_SUBID_GET_UID_RANGES_SYMBOL; 28 | 29 | void toolbox_subid_init (void *subid_init_func); 30 | 31 | int toolbox_subid_get_id_ranges (void *subid_get_id_ranges_func, const char *owner, struct subid_range **ranges); 32 | -------------------------------------------------------------------------------- /src/pkg/utils/rhel.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2021 – 2025 Red Hat Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package utils 18 | 19 | import ( 20 | "fmt" 21 | "strconv" 22 | "strings" 23 | 24 | "github.com/sirupsen/logrus" 25 | ) 26 | 27 | func getDefaultReleaseRHEL() (string, error) { 28 | release, err := getHostVersionID() 29 | if err != nil { 30 | return "", err 31 | } 32 | 33 | return release, nil 34 | } 35 | 36 | func getFullyQualifiedImageRHEL(image, release string) string { 37 | i := strings.IndexRune(release, '.') 38 | if i == -1 { 39 | panicMsg := fmt.Sprintf("release %s not in '.' format", release) 40 | panic(panicMsg) 41 | } 42 | 43 | releaseMajor := release[:i] 44 | imageFull := "registry.access.redhat.com/ubi" + releaseMajor + "/" + image 45 | return imageFull 46 | } 47 | 48 | func getP11KitClientPathsRHEL() []string { 49 | paths := []string{"/usr/lib64/pkcs11/p11-kit-client.so"} 50 | return paths 51 | } 52 | 53 | func parseReleaseRHEL(release string) (string, error) { 54 | if i := strings.IndexRune(release, '.'); i == -1 { 55 | return "", &ParseReleaseError{"The release must be in the '.' format."} 56 | } 57 | 58 | releaseN, err := strconv.ParseFloat(release, 32) 59 | if err != nil { 60 | logrus.Debugf("Parsing release %s as a float failed: %s", release, err) 61 | return "", &ParseReleaseError{"The release must be in the '.' format."} 62 | } 63 | 64 | if releaseN <= 0 { 65 | return "", &ParseReleaseError{"The release must be a positive number."} 66 | } 67 | 68 | return release, nil 69 | } 70 | -------------------------------------------------------------------------------- /src/pkg/utils/ubuntu.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2023 – 2025 Red Hat Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package utils 18 | 19 | import ( 20 | "strconv" 21 | "strings" 22 | "unicode/utf8" 23 | 24 | "github.com/sirupsen/logrus" 25 | ) 26 | 27 | func getDefaultReleaseUbuntu() (string, error) { 28 | release, err := getHostVersionID() 29 | if err != nil { 30 | return "", err 31 | } 32 | 33 | return release, nil 34 | } 35 | 36 | func getFullyQualifiedImageUbuntu(image, release string) string { 37 | imageFull := "quay.io/toolbx/" + image 38 | return imageFull 39 | } 40 | 41 | func getP11KitClientPathsUbuntu() []string { 42 | paths := []string{ 43 | "/usr/lib/aarch64-linux-gnu/pkcs11/p11-kit-client.so", 44 | "/usr/lib/x86_64-linux-gnu/pkcs11/p11-kit-client.so", 45 | } 46 | 47 | return paths 48 | } 49 | 50 | func parseReleaseUbuntu(release string) (string, error) { 51 | releaseParts := strings.Split(release, ".") 52 | if len(releaseParts) != 2 { 53 | return "", &ParseReleaseError{"The release must be in the 'YY.MM' format."} 54 | } 55 | 56 | releaseYear, err := strconv.Atoi(releaseParts[0]) 57 | if err != nil { 58 | logrus.Debugf("Parsing release year %s as an integer failed: %s", releaseParts[0], err) 59 | return "", &ParseReleaseError{"The release must be in the 'YY.MM' format."} 60 | } 61 | 62 | if releaseYear < 4 { 63 | return "", &ParseReleaseError{"The release year must be 4 or more."} 64 | } 65 | 66 | releaseYearLen := utf8.RuneCountInString(releaseParts[0]) 67 | if releaseYearLen > 2 { 68 | return "", &ParseReleaseError{"The release year cannot have more than two digits."} 69 | } else if releaseYear < 10 && releaseYearLen == 2 { 70 | return "", &ParseReleaseError{"The release year cannot have a leading zero."} 71 | } 72 | 73 | releaseMonth, err := strconv.Atoi(releaseParts[1]) 74 | if err != nil { 75 | logrus.Debugf("Parsing release month %s as an integer failed: %s", releaseParts[1], err) 76 | return "", &ParseReleaseError{"The release must be in the 'YY.MM' format."} 77 | } 78 | 79 | if releaseMonth < 1 { 80 | return "", &ParseReleaseError{"The release month must be between 01 and 12."} 81 | } else if releaseMonth > 12 { 82 | return "", &ParseReleaseError{"The release month must be between 01 and 12."} 83 | } 84 | 85 | releaseMonthLen := utf8.RuneCountInString(releaseParts[1]) 86 | if releaseMonthLen != 2 { 87 | return "", &ParseReleaseError{"The release month must have two digits."} 88 | } 89 | 90 | return release, nil 91 | } 92 | -------------------------------------------------------------------------------- /src/pkg/utils/utils_cgo.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2022 – 2024 Red Hat Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package utils 18 | 19 | import ( 20 | "errors" 21 | "fmt" 22 | "os/user" 23 | "unsafe" 24 | ) 25 | 26 | /* 27 | #cgo LDFLAGS: -ldl 28 | 29 | #include 30 | 31 | #include 32 | #include 33 | 34 | #include "libsubid-wrappers.h" 35 | */ 36 | import "C" 37 | 38 | func validateSubIDRange(user *user.User, libsubid unsafe.Pointer, cSubidGetIDRangesSymbol *C.char) (bool, error) { 39 | subid_get_id_ranges := C.dlsym(libsubid, cSubidGetIDRangesSymbol) 40 | if subid_get_id_ranges == nil { 41 | subidGetIDRangesSymbol := C.GoString(cSubidGetIDRangesSymbol) 42 | return false, fmt.Errorf("cannot dlsym(3) %s", subidGetIDRangesSymbol) 43 | } 44 | 45 | cUsername := C.CString(user.Username) 46 | defer C.free(unsafe.Pointer(cUsername)) 47 | 48 | var cRanges *C.struct_subid_range 49 | defer C.free(unsafe.Pointer(cRanges)) 50 | 51 | nRanges := C.toolbox_subid_get_id_ranges(subid_get_id_ranges, cUsername, &cRanges) 52 | if nRanges <= 0 { 53 | cUid := C.CString(user.Uid) 54 | defer C.free(unsafe.Pointer(cUid)) 55 | 56 | nRanges = C.toolbox_subid_get_id_ranges(subid_get_id_ranges, cUid, &cRanges) 57 | } 58 | 59 | if nRanges <= 0 { 60 | return false, errors.New("cannot read subids") 61 | } 62 | 63 | return true, nil 64 | } 65 | 66 | func ValidateSubIDRanges(user *user.User) (bool, error) { 67 | if IsInsideContainer() { 68 | panic("cannot validate subordinate IDs inside container") 69 | } 70 | 71 | if user == nil { 72 | panic("cannot validate subordinate IDs when user is nil") 73 | } 74 | 75 | if user.Username == "ALL" { 76 | return false, errors.New("username ALL not supported") 77 | } 78 | 79 | libsubid := C.dlopen(C.TOOLBOX_LIBSUBID, C.RTLD_LAZY) 80 | if libsubid == nil { 81 | filename := C.GoString(C.TOOLBOX_LIBSUBID) 82 | return false, fmt.Errorf("cannot dlopen(3) %s", filename) 83 | } 84 | 85 | defer C.dlclose(libsubid) 86 | 87 | subid_init := C.dlsym(libsubid, C.TOOLBOX_SUBID_INIT) 88 | if subid_init == nil { 89 | subidInitSymbol := C.GoString(C.TOOLBOX_SUBID_INIT) 90 | return false, fmt.Errorf("cannot dlsym(3) %s", subidInitSymbol) 91 | } 92 | 93 | C.toolbox_subid_init(subid_init) 94 | 95 | if _, err := validateSubIDRange(user, libsubid, C.TOOLBOX_SUBID_GET_GID_RANGES_SYMBOL); err != nil { 96 | return false, err 97 | } 98 | 99 | if _, err := validateSubIDRange(user, libsubid, C.TOOLBOX_SUBID_GET_UID_RANGES_SYMBOL); err != nil { 100 | return false, err 101 | } 102 | 103 | return true, nil 104 | } 105 | -------------------------------------------------------------------------------- /src/pkg/version/version.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2019 – 2024 Red Hat Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package version 18 | 19 | // currentVersion holds the information about current build version 20 | var ( 21 | currentVersion string 22 | ) 23 | 24 | // GetVersion returns string with the version of Toolbx 25 | func GetVersion() string { 26 | return currentVersion 27 | } 28 | -------------------------------------------------------------------------------- /src/toolbox.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2019 – 2024 Red Hat Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package main 18 | 19 | import "github.com/containers/toolbox/cmd" 20 | 21 | func main() { 22 | cmd.Execute() 23 | } 24 | -------------------------------------------------------------------------------- /test/meson.build: -------------------------------------------------------------------------------- 1 | subdir('system') 2 | -------------------------------------------------------------------------------- /test/system/001-version.bats: -------------------------------------------------------------------------------- 1 | # shellcheck shell=bats 2 | # 3 | # Copyright © 2019 – 2024 Red Hat, Inc. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | 18 | # bats file_tags=commands-options 19 | 20 | load 'libs/bats-support/load' 21 | load 'libs/bats-assert/load' 22 | load 'libs/helpers.bash' 23 | 24 | setup() { 25 | bats_require_minimum_version 1.8.0 26 | _setup_environment 27 | } 28 | 29 | @test "version: Check version using option --version" { 30 | run --separate-stderr "$TOOLBX" --version 31 | 32 | assert_success 33 | assert_output --regexp '^toolbox version [0-9]+\.[0-9]+\.[0-9]+(\.[0-9]+)?$' 34 | assert [ ${#lines[@]} -eq 1 ] 35 | 36 | # shellcheck disable=SC2154 37 | assert [ ${#stderr_lines[@]} -eq 0 ] 38 | } 39 | -------------------------------------------------------------------------------- /test/system/103-container.bats: -------------------------------------------------------------------------------- 1 | # shellcheck shell=bats 2 | # 3 | # Copyright © 2021 – 2024 Red Hat, Inc. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | 18 | # bats file_tags=commands-options 19 | 20 | load 'libs/bats-support/load' 21 | load 'libs/bats-assert/load' 22 | load 'libs/helpers' 23 | 24 | setup() { 25 | bats_require_minimum_version 1.8.0 26 | _setup_environment 27 | cleanup_all 28 | } 29 | 30 | teardown() { 31 | cleanup_all 32 | } 33 | 34 | 35 | @test "container: Check container starts without issues" { 36 | CONTAINER_NAME="$(get_system_id)-toolbox-$(get_system_version)" 37 | readonly CONTAINER_NAME 38 | 39 | create_default_container 40 | 41 | run container_started "$CONTAINER_NAME" 42 | assert_success 43 | } 44 | 45 | @test "container: Start with an old forward incompatible runtime" { 46 | create_distro_container fedora 34 fedora-toolbox-34 47 | 48 | run container_started fedora-toolbox-34 49 | assert_success 50 | } 51 | 52 | @test "container(Fedora Rawhide): Containers with supported versions start without issues" { 53 | if ! is_fedora_rawhide; then 54 | skip "This test is only for Fedora Rawhide" 55 | fi 56 | 57 | local system_id 58 | system_id="$(get_system_id)" 59 | 60 | local system_version 61 | system_version="$(get_system_version)" 62 | 63 | create_distro_container "$system_id" "$system_version" latest 64 | run container_started latest 65 | assert_success 66 | 67 | create_distro_container "$system_id" "$((system_version-1))" second 68 | run container_started second 69 | assert_success 70 | 71 | create_distro_container "$system_id" "$((system_version-2))" third 72 | run container_started third 73 | assert_success 74 | } 75 | -------------------------------------------------------------------------------- /test/system/106-rm.bats: -------------------------------------------------------------------------------- 1 | # shellcheck shell=bats 2 | # 3 | # Copyright © 2021 – 2024 Red Hat, Inc. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | 18 | # bats file_tags=commands-options 19 | 20 | load 'libs/bats-support/load' 21 | load 'libs/bats-assert/load' 22 | load 'libs/helpers' 23 | 24 | setup() { 25 | bats_require_minimum_version 1.8.0 26 | _setup_environment 27 | cleanup_all 28 | } 29 | 30 | teardown() { 31 | cleanup_all 32 | } 33 | 34 | 35 | @test "rm: Try to remove a non-existent container" { 36 | container_name="nonexistentcontainer" 37 | run "$TOOLBX" rm "$container_name" 38 | 39 | #assert_failure #BUG: it should return 1 40 | assert_output "Error: failed to inspect container $container_name" 41 | } 42 | 43 | @test "rm: Try to remove a running container" { 44 | skip "Bug: Fail in 'toolbox rm' does not return non-zero value" 45 | create_container running 46 | start_container running 47 | 48 | run "$TOOLBX" rm running 49 | 50 | #assert_failure #BUG: it should return 1 51 | assert_output "Error: container running is running" 52 | } 53 | 54 | @test "rm: Remove a not running container" { 55 | create_container not-running 56 | 57 | run "$TOOLBX" rm not-running 58 | 59 | assert_success 60 | assert_output "" 61 | } 62 | 63 | @test "rm: Force remove a running container" { 64 | create_container running 65 | start_container running 66 | 67 | run "$TOOLBX" rm --force running 68 | 69 | assert_success 70 | assert_output "" 71 | } 72 | 73 | @test "rm: Force remove all containers (with 2 containers created and 1 running)" { 74 | num_of_containers="$(list_containers)" 75 | assert_equal "$num_of_containers" 0 76 | 77 | create_container running 78 | create_container not-running 79 | start_container running 80 | 81 | run "$TOOLBX" rm --force --all 82 | 83 | assert_success 84 | assert_output "" 85 | 86 | new_num_of_containers="$(list_containers)" 87 | 88 | assert_equal "$new_num_of_containers" "$num_of_containers" 89 | } 90 | -------------------------------------------------------------------------------- /test/system/108-completion.bats: -------------------------------------------------------------------------------- 1 | # shellcheck shell=bats 2 | # 3 | # Copyright © 2023 – 2024 Red Hat, Inc. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | 18 | # bats file_tags=commands-options 19 | 20 | load 'libs/bats-support/load' 21 | load 'libs/bats-assert/load' 22 | load 'libs/helpers' 23 | 24 | setup() { 25 | bats_require_minimum_version 1.8.0 26 | _setup_environment 27 | } 28 | 29 | @test "completion: Smoke test with 'bash'" { 30 | run "$TOOLBX" completion bash 31 | 32 | assert_success 33 | assert [ ${#lines[@]} -gt 0 ] 34 | 35 | # shellcheck disable=SC2154 36 | assert [ ${#stderr_lines[@]} -eq 0 ] 37 | } 38 | 39 | @test "completion: Smoke test with 'fish'" { 40 | run "$TOOLBX" completion fish 41 | 42 | assert_success 43 | assert [ ${#lines[@]} -gt 0 ] 44 | assert [ ${#stderr_lines[@]} -eq 0 ] 45 | } 46 | 47 | @test "completion: Smoke test with 'zsh'" { 48 | run "$TOOLBX" completion zsh 49 | 50 | assert_success 51 | assert [ ${#lines[@]} -gt 0 ] 52 | assert [ ${#stderr_lines[@]} -eq 0 ] 53 | } 54 | 55 | @test "completion: Try without any arguments" { 56 | run --separate-stderr "$TOOLBX" completion 57 | 58 | assert_failure 59 | assert [ ${#lines[@]} -eq 0 ] 60 | lines=("${stderr_lines[@]}") 61 | assert_line --index 0 "Error: accepts 1 arg(s), received 0" 62 | assert_line --index 1 "Run 'toolbox --help' for usage." 63 | assert [ ${#stderr_lines[@]} -eq 2 ] 64 | } 65 | 66 | @test "completion: Try with invalid arguments" { 67 | run --separate-stderr "$TOOLBX" completion foo 68 | 69 | assert_failure 70 | assert [ ${#lines[@]} -eq 0 ] 71 | lines=("${stderr_lines[@]}") 72 | assert_line --index 0 "Error: invalid argument \"foo\" for \"toolbox completion\"" 73 | assert_line --index 1 "Run 'toolbox --help' for usage." 74 | assert [ ${#stderr_lines[@]} -eq 2 ] 75 | } 76 | 77 | @test "completion: Try with unknown flag" { 78 | run --separate-stderr "$TOOLBX" completion --foo 79 | 80 | assert_failure 81 | assert [ ${#lines[@]} -eq 0 ] 82 | lines=("${stderr_lines[@]}") 83 | assert_line --index 0 "Error: unknown flag: --foo" 84 | assert_line --index 1 "Run 'toolbox --help' for usage." 85 | assert [ ${#stderr_lines[@]} -eq 2 ] 86 | } 87 | 88 | @test "completion: Try with unsupported shell" { 89 | run --separate-stderr "$TOOLBX" completion powershell 90 | 91 | assert_failure 92 | assert [ ${#lines[@]} -eq 0 ] 93 | lines=("${stderr_lines[@]}") 94 | assert_line --index 0 "Error: invalid argument \"powershell\" for \"toolbox completion\"" 95 | assert_line --index 1 "Run 'toolbox --help' for usage." 96 | assert [ ${#stderr_lines[@]} -eq 2 ] 97 | } 98 | -------------------------------------------------------------------------------- /test/system/201-ipc.bats: -------------------------------------------------------------------------------- 1 | # shellcheck shell=bats 2 | # 3 | # Copyright © 2023 – 2024 Red Hat, Inc. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | 18 | # bats file_tags=runtime-environment 19 | 20 | load 'libs/bats-support/load' 21 | load 'libs/bats-assert/load' 22 | load 'libs/helpers' 23 | 24 | setup() { 25 | bats_require_minimum_version 1.10.0 26 | _setup_environment 27 | cleanup_all 28 | pushd "$HOME" || return 1 29 | } 30 | 31 | teardown() { 32 | popd || return 1 33 | cleanup_all 34 | } 35 | 36 | # bats test_tags=arch-fedora 37 | @test "ipc: No namespace" { 38 | local ns_host 39 | ns_host=$(readlink /proc/$$/ns/ipc) 40 | 41 | create_default_container 42 | 43 | run --keep-empty-lines --separate-stderr "$TOOLBX" run sh -c 'readlink /proc/$$/ns/ipc' 44 | 45 | assert_success 46 | assert_line --index 0 "$ns_host" 47 | assert [ ${#lines[@]} -eq 1 ] 48 | 49 | # shellcheck disable=SC2154 50 | assert [ ${#stderr_lines[@]} -eq 0 ] 51 | } 52 | -------------------------------------------------------------------------------- /test/system/505-enter.bats: -------------------------------------------------------------------------------- 1 | # shellcheck shell=bats 2 | # 3 | # Copyright © 2024 Red Hat, Inc. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | 18 | # bats file_tags=commands-options 19 | 20 | load 'libs/bats-support/load' 21 | load 'libs/bats-assert/load' 22 | load 'libs/helpers' 23 | 24 | setup() { 25 | bats_require_minimum_version 1.8.0 26 | _setup_environment 27 | cleanup_all 28 | pushd "$HOME" || return 1 29 | } 30 | 31 | teardown() { 32 | popd || return 1 33 | cleanup_all 34 | } 35 | 36 | @test "enter: Try a non-existent container (forwarded to host)" { 37 | create_default_container 38 | 39 | run -1 --keep-empty-lines --separate-stderr "$TOOLBX" run toolbox enter wrong-container 40 | 41 | assert_failure 42 | assert [ ${#lines[@]} -eq 0 ] 43 | lines=("${stderr_lines[@]}") 44 | assert_line --index 0 "Error: container wrong-container not found" 45 | assert_line --index 1 "Use the '--container' option to select a Toolbx." 46 | assert_line --index 2 "Run 'toolbox --help' for usage." 47 | assert [ ${#stderr_lines[@]} -eq 3 ] 48 | } 49 | 50 | @test "enter: Try an unsupported distribution (forwarded to host)" { 51 | create_default_container 52 | 53 | local distro="foo" 54 | 55 | run -1 --keep-empty-lines --separate-stderr "$TOOLBX" run toolbox enter --distro "$distro" 56 | 57 | assert_failure 58 | assert [ ${#lines[@]} -eq 0 ] 59 | lines=("${stderr_lines[@]}") 60 | assert_line --index 0 "Error: invalid argument for '--distro'" 61 | assert_line --index 1 "Distribution $distro is unsupported." 62 | assert_line --index 2 "Run 'toolbox --help' for usage." 63 | assert [ ${#stderr_lines[@]} -eq 3 ] 64 | } 65 | -------------------------------------------------------------------------------- /test/system/data/cdi-empty.json: -------------------------------------------------------------------------------- 1 | { 2 | } 3 | -------------------------------------------------------------------------------- /test/system/data/cdi-hooks-00.json: -------------------------------------------------------------------------------- 1 | { 2 | "containerEdits": { 3 | "hooks": [ 4 | { 5 | "args": [ 6 | "nvidia-cdi-hook", 7 | "update-ldcache" 8 | ], 9 | "hookName": "createContainer", 10 | "path": "/usr/bin/nvidia-cdi-hook" 11 | } 12 | ] 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /test/system/data/cdi-hooks-01.json: -------------------------------------------------------------------------------- 1 | { 2 | "containerEdits": { 3 | "hooks": [ 4 | { 5 | "args": [ 6 | "nvidia-cdi-hook", 7 | "update-ldcache", 8 | "--folder", 9 | "/usr/lib64" 10 | ], 11 | "hookName": "createContainer", 12 | "path": "/usr/bin/nvidia-cdi-hook" 13 | } 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /test/system/data/cdi-hooks-02.json: -------------------------------------------------------------------------------- 1 | { 2 | "containerEdits": { 3 | "hooks": [ 4 | { 5 | "args": [ 6 | "nvidia-cdi-hook", 7 | "update-ldcache", 8 | "--folder", 9 | "/usr/lib", 10 | "--folder", 11 | "/usr/lib64" 12 | ], 13 | "hookName": "createContainer", 14 | "path": "/usr/bin/nvidia-cdi-hook" 15 | } 16 | ] 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /test/system/data/cdi-hooks-10.json: -------------------------------------------------------------------------------- 1 | { 2 | "containerEdits": { 3 | "hooks": [ 4 | { 5 | "args": [ 6 | "nvidia-cdi-hook", 7 | "update-ldcache" 8 | ], 9 | "hookName": "createContainer", 10 | "path": "" 11 | } 12 | ] 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /test/system/data/cdi-hooks-11.json: -------------------------------------------------------------------------------- 1 | { 2 | "containerEdits": { 3 | "hooks": [ 4 | { 5 | "args": [ 6 | "unknown", 7 | "update-ldcache" 8 | ], 9 | "hookName": "createContainer", 10 | "path": "/usr/bin/unknown" 11 | } 12 | ] 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /test/system/data/cdi-hooks-12.json: -------------------------------------------------------------------------------- 1 | { 2 | "containerEdits": { 3 | "hooks": [ 4 | { 5 | "args": [ 6 | "nvidia-cdi-hook", 7 | "unknown" 8 | ], 9 | "hookName": "createContainer", 10 | "path": "/usr/bin/nvidia-cdi-hook" 11 | } 12 | ] 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /test/system/data/cdi-hooks-14.json: -------------------------------------------------------------------------------- 1 | { 2 | "containerEdits": { 3 | "hooks": [ 4 | { 5 | "args": [ 6 | "nvidia-cdi-hook", 7 | "update-ldcache" 8 | ], 9 | "hookName": "invalid", 10 | "path": "/usr/bin/nvidia-cdi-hook" 11 | } 12 | ] 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /test/system/data/cdi-hooks-15.json: -------------------------------------------------------------------------------- 1 | { 2 | "containerEdits": { 3 | "hooks": [ 4 | { 5 | "args": [ 6 | "nvidia-cdi-hook", 7 | "update-ldcache" 8 | ], 9 | "hookName": "createRuntime", 10 | "path": "/usr/bin/nvidia-cdi-hook" 11 | } 12 | ] 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /test/system/data/cdi-hooks-create-symlinks-00.json: -------------------------------------------------------------------------------- 1 | { 2 | "containerEdits": { 3 | "hooks": [ 4 | { 5 | "args": [ 6 | "nvidia-cdi-hook", 7 | "create-symlinks" 8 | ], 9 | "hookName": "createContainer", 10 | "path": "/usr/bin/nvidia-cdi-hook" 11 | } 12 | ] 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /test/system/data/cdi-hooks-create-symlinks-01.json: -------------------------------------------------------------------------------- 1 | { 2 | "containerEdits": { 3 | "hooks": [ 4 | { 5 | "args": [ 6 | "nvidia-cdi-hook", 7 | "create-symlinks", 8 | "--link", 9 | "/usr/bin/toolbox::/run/toolbox.1" 10 | ], 11 | "hookName": "createContainer", 12 | "path": "/usr/bin/nvidia-cdi-hook" 13 | } 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /test/system/data/cdi-hooks-create-symlinks-02.json: -------------------------------------------------------------------------------- 1 | { 2 | "containerEdits": { 3 | "hooks": [ 4 | { 5 | "args": [ 6 | "nvidia-cdi-hook", 7 | "create-symlinks", 8 | "--link", 9 | "/usr/bin/toolbox::/opt/bin/toolbox" 10 | ], 11 | "hookName": "createContainer", 12 | "path": "/usr/bin/nvidia-cdi-hook" 13 | } 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /test/system/data/cdi-hooks-create-symlinks-03.json: -------------------------------------------------------------------------------- 1 | { 2 | "containerEdits": { 3 | "hooks": [ 4 | { 5 | "args": [ 6 | "nvidia-cdi-hook", 7 | "create-symlinks", 8 | "--link", 9 | "/usr/bin/toolbox::/usr/bin/toolbox.1" 10 | ], 11 | "hookName": "createContainer", 12 | "path": "/usr/bin/nvidia-cdi-hook" 13 | } 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /test/system/data/cdi-hooks-create-symlinks-04.json: -------------------------------------------------------------------------------- 1 | { 2 | "containerEdits": { 3 | "hooks": [ 4 | { 5 | "args": [ 6 | "nvidia-cdi-hook", 7 | "create-symlinks", 8 | "--link", 9 | "/usr/bin/toolbox::/run/toolbox.1", 10 | "--link", 11 | "/usr/bin/toolbox::/opt/bin/toolbox", 12 | "--link", 13 | "/usr/bin/toolbox::/usr/bin/toolbox.1" 14 | ], 15 | "hookName": "createContainer", 16 | "path": "/usr/bin/nvidia-cdi-hook" 17 | } 18 | ] 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /test/system/data/cdi-hooks-create-symlinks-05.json: -------------------------------------------------------------------------------- 1 | { 2 | "containerEdits": { 3 | "hooks": [ 4 | { 5 | "args": [ 6 | "nvidia-cdi-hook", 7 | "create-symlinks", 8 | "--link", 9 | "../usr/bin/toolbox::/run/toolbox.1" 10 | ], 11 | "hookName": "createContainer", 12 | "path": "/usr/bin/nvidia-cdi-hook" 13 | } 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /test/system/data/cdi-hooks-create-symlinks-06.json: -------------------------------------------------------------------------------- 1 | { 2 | "containerEdits": { 3 | "hooks": [ 4 | { 5 | "args": [ 6 | "nvidia-cdi-hook", 7 | "create-symlinks", 8 | "--link", 9 | "../../usr/bin/toolbox::/opt/bin/toolbox" 10 | ], 11 | "hookName": "createContainer", 12 | "path": "/usr/bin/nvidia-cdi-hook" 13 | } 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /test/system/data/cdi-hooks-create-symlinks-07.json: -------------------------------------------------------------------------------- 1 | { 2 | "containerEdits": { 3 | "hooks": [ 4 | { 5 | "args": [ 6 | "nvidia-cdi-hook", 7 | "create-symlinks", 8 | "--link", 9 | "toolbox::/usr/bin/toolbox.1" 10 | ], 11 | "hookName": "createContainer", 12 | "path": "/usr/bin/nvidia-cdi-hook" 13 | } 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /test/system/data/cdi-hooks-create-symlinks-08.json: -------------------------------------------------------------------------------- 1 | { 2 | "containerEdits": { 3 | "hooks": [ 4 | { 5 | "args": [ 6 | "nvidia-cdi-hook", 7 | "create-symlinks", 8 | "--link", 9 | "../usr/bin/toolbox::/run/toolbox.1", 10 | "--link", 11 | "../../usr/bin/toolbox::/opt/bin/toolbox", 12 | "--link", 13 | "toolbox::/usr/bin/toolbox.1" 14 | ], 15 | "hookName": "createContainer", 16 | "path": "/usr/bin/nvidia-cdi-hook" 17 | } 18 | ] 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /test/system/data/cdi-hooks-create-symlinks-30.json: -------------------------------------------------------------------------------- 1 | { 2 | "containerEdits": { 3 | "hooks": [ 4 | { 5 | "args": [ 6 | "nvidia-cdi-hook", 7 | "create-symlinks" 8 | ], 9 | "hookName": "createContainer", 10 | "path": "" 11 | } 12 | ] 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /test/system/data/cdi-hooks-create-symlinks-31.json: -------------------------------------------------------------------------------- 1 | { 2 | "containerEdits": { 3 | "hooks": [ 4 | { 5 | "args": [ 6 | "unknown", 7 | "create-symlinks", 8 | "--link", 9 | "toolbox::/usr/bin/toolbox.1" 10 | ], 11 | "hookName": "createContainer", 12 | "path": "/usr/bin/unknown" 13 | } 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /test/system/data/cdi-hooks-create-symlinks-32.json: -------------------------------------------------------------------------------- 1 | { 2 | "containerEdits": { 3 | "hooks": [ 4 | { 5 | "args": [ 6 | "nvidia-cdi-hook", 7 | "create-symlinks", 8 | "--link" 9 | ], 10 | "hookName": "createContainer", 11 | "path": "/usr/bin/nvidia-cdi-hook" 12 | } 13 | ] 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /test/system/data/cdi-hooks-create-symlinks-33.json: -------------------------------------------------------------------------------- 1 | { 2 | "containerEdits": { 3 | "hooks": [ 4 | { 5 | "args": [ 6 | "nvidia-cdi-hook", 7 | "create-symlinks", 8 | "--link", 9 | "toolbox::toolbox.1" 10 | ], 11 | "hookName": "createContainer", 12 | "path": "/usr/bin/nvidia-cdi-hook" 13 | } 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /test/system/data/cdi-hooks-create-symlinks-34.json: -------------------------------------------------------------------------------- 1 | { 2 | "containerEdits": { 3 | "hooks": [ 4 | { 5 | "args": [ 6 | "nvidia-cdi-hook", 7 | "create-symlinks", 8 | "--link", 9 | "foo" 10 | ], 11 | "hookName": "createContainer", 12 | "path": "/usr/bin/nvidia-cdi-hook" 13 | } 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /test/system/data/cdi-hooks-create-symlinks-35.json: -------------------------------------------------------------------------------- 1 | { 2 | "containerEdits": { 3 | "hooks": [ 4 | { 5 | "args": [ 6 | "nvidia-cdi-hook", 7 | "create-symlinks", 8 | "--link", 9 | "foo::bar::baz" 10 | ], 11 | "hookName": "createContainer", 12 | "path": "/usr/bin/nvidia-cdi-hook" 13 | } 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /test/system/data/cdi-hooks-create-symlinks-36.json: -------------------------------------------------------------------------------- 1 | { 2 | "containerEdits": { 3 | "hooks": [ 4 | { 5 | "args": [ 6 | "nvidia-cdi-hook", 7 | "create-symlinks" 8 | ], 9 | "hookName": "invalid", 10 | "path": "/usr/bin/nvidia-cdi-hook" 11 | } 12 | ] 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /test/system/data/cdi-hooks-create-symlinks-37.json: -------------------------------------------------------------------------------- 1 | { 2 | "containerEdits": { 3 | "hooks": [ 4 | { 5 | "args": [ 6 | "nvidia-cdi-hook", 7 | "create-symlinks", 8 | "--link", 9 | "toolbox::/usr/bin/toolbox.1" 10 | ], 11 | "hookName": "createRuntime", 12 | "path": "/usr/bin/nvidia-cdi-hook" 13 | } 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /test/system/data/cdi-mounts-10.json: -------------------------------------------------------------------------------- 1 | { 2 | "containerEdits": { 3 | "mounts": [ 4 | { 5 | "containerPath": "", 6 | "hostPath": "/tmp" 7 | } 8 | ] 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /test/system/data/cdi-mounts-11.json: -------------------------------------------------------------------------------- 1 | { 2 | "containerEdits": { 3 | "mounts": [ 4 | { 5 | "containerPath": "/tmp", 6 | "hostPath": "" 7 | } 8 | ] 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /test/system/data/cdi-mounts-12.json: -------------------------------------------------------------------------------- 1 | { 2 | "containerEdits": { 3 | "mounts": [ 4 | { 5 | "containerPath": "/non/existent/path", 6 | "hostPath": "/non/existent/path" 7 | } 8 | ] 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /test/system/meson.build: -------------------------------------------------------------------------------- 1 | test_system = files( 2 | '001-version.bats', 3 | '002-help.bats', 4 | '101-create.bats', 5 | '102-list.bats', 6 | '103-container.bats', 7 | '104-run.bats', 8 | '105-enter.bats', 9 | '106-rm.bats', 10 | '107-rmi.bats', 11 | '108-completion.bats', 12 | '201-ipc.bats', 13 | '203-network.bats', 14 | '206-user.bats', 15 | '210-ulimit.bats', 16 | '211-dbus.bats', 17 | '220-environment-variables.bats', 18 | '230-cdi.bats', 19 | '250-kerberos.bats', 20 | '270-rpm.bats', 21 | '501-create.bats', 22 | '504-run.bats', 23 | '505-enter.bats', 24 | 'setup_suite.bash', 25 | 'libs/helpers.bash', 26 | ) 27 | 28 | if shellcheck.found() 29 | test('shellcheck test/system', shellcheck, args: [test_system]) 30 | endif 31 | -------------------------------------------------------------------------------- /test/system/setup_suite.bash: -------------------------------------------------------------------------------- 1 | # shellcheck shell=bash 2 | # 3 | # Copyright © 2021 – 2025 Red Hat, Inc. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | 18 | missing_dependencies=false 19 | 20 | if [ -f "$BATS_TEST_DIRNAME/libs/bats-assert/load.bash" ] && [ -f "$BATS_TEST_DIRNAME/libs/bats-support/load.bash" ]; then 21 | load 'libs/helpers' 22 | else 23 | missing_dependencies=true 24 | fi 25 | 26 | setup_suite() { 27 | bats_require_minimum_version 1.7.0 28 | echo "# test suite: Set up" >&3 29 | 30 | if $missing_dependencies; then 31 | echo "# Missing dependencies" >&3 32 | echo "# Forgot to run 'git submodule init' and 'git submodule update' ?" >&3 33 | return 1 34 | fi 35 | 36 | local system_id 37 | system_id="$(get_system_id)" 38 | 39 | local system_version 40 | system_version="$(get_system_version)" 41 | 42 | _setup_environment 43 | 44 | if echo "$TOOLBX_TEST_SYSTEM_TAGS" | grep "arch" >/dev/null 2>/dev/null; then 45 | _pull_and_cache_distro_image arch latest || false 46 | fi 47 | 48 | if echo "$TOOLBX_TEST_SYSTEM_TAGS" | grep "fedora" >/dev/null 2>/dev/null; then 49 | # Cache the default image for the system 50 | _pull_and_cache_distro_image "$system_id" "$system_version" || false 51 | # Cache all images that will be needed during the tests 52 | _pull_and_cache_distro_image fedora 34 || false 53 | _pull_and_cache_distro_image rhel 8.10 || false 54 | fi 55 | 56 | if echo "$TOOLBX_TEST_SYSTEM_TAGS" | grep "ubuntu" >/dev/null 2>/dev/null; then 57 | _pull_and_cache_distro_image ubuntu 16.04 || false 58 | _pull_and_cache_distro_image ubuntu 18.04 || false 59 | _pull_and_cache_distro_image ubuntu 20.04 || false 60 | fi 61 | 62 | if echo "$TOOLBX_TEST_SYSTEM_TAGS" | grep "commands-options" >/dev/null 2>/dev/null; then 63 | _pull_and_cache_distro_image busybox || false 64 | # If run on Fedora Rawhide, cache 2 extra images (previous Fedora versions) 65 | if is_fedora_rawhide && (echo "$TOOLBX_TEST_SYSTEM_TAGS" | grep "fedora" >/dev/null 2>/dev/null); then 66 | _pull_and_cache_distro_image fedora "$((system_version-1))" || false 67 | _pull_and_cache_distro_image fedora "$((system_version-2))" || false 68 | fi 69 | 70 | _setup_docker_registry 71 | fi 72 | } 73 | 74 | teardown_suite() { 75 | bats_require_minimum_version 1.7.0 76 | echo "# test suite: Tear down" >&3 77 | 78 | if $missing_dependencies; then 79 | return 0 80 | fi 81 | 82 | _setup_environment 83 | 84 | if echo "$TOOLBX_TEST_SYSTEM_TAGS" | grep "commands-options" >/dev/null 2>/dev/null; then 85 | _clean_docker_registry 86 | fi 87 | 88 | podman system reset --force >/dev/null 89 | } 90 | --------------------------------------------------------------------------------