feat: distrobox v2.0#2122
Open
dottorblaster wants to merge 137 commits into
Open
Conversation
Signed-off-by: Fabrizio Sestito <fabrizio.sestito@suse.com>
* build(deps): add urfave/cli Signed-off-by: Fabrizio Sestito <fabrizio.sestito@suse.com> * chore: add gitignore Signed-off-by: Fabrizio Sestito <fabrizio.sestito@suse.com> * ci: add golangci configuration Signed-off-by: Fabrizio Sestito <fabrizio.sestito@suse.com> * build(Makefile): add Makefile Signed-off-by: Fabrizio Sestito <fabrizio.sestito@suse.com> * feat: add main package and distrobox cmd Signed-off-by: Fabrizio Sestito <fabrizio.sestito@suse.com> --------- Signed-off-by: Fabrizio Sestito <fabrizio.sestito@suse.com>
* feat: add containermanager package and docker provider Signed-off-by: Fabrizio Sestito <fabrizio.sestito@suse.com> * feat: add list command Signed-off-by: Fabrizio Sestito <fabrizio.sestito@suse.com> * feat: add root command Signed-off-by: Fabrizio Sestito <fabrizio.sestito@suse.com> * feat: add list command Signed-off-by: Fabrizio Sestito <fabrizio.sestito@suse.com> * feat: wire-up root command in main Signed-off-by: Fabrizio Sestito <fabrizio.sestito@suse.com> * refactor(docker): use format json Signed-off-by: Fabrizio Sestito <fabrizio.sestito@suse.com> --------- Signed-off-by: Fabrizio Sestito <fabrizio.sestito@suse.com>
balanza
requested changes
Jun 11, 2026
balanza
approved these changes
Jun 14, 2026
56c15d2 to
21e6b9a
Compare
* chore: disable mdlint (#6) * resolve lint issues Some issues where detected by the CI once run: * use of `fmt.Printf` forbidden by pattern `^(fmt\.Print(|f|ln)|print|println)$` (forbidigo) * File is not properly formatted (goimports) * Magic number: 12, in <condition> detected (mnd) * error-format: fmt.Errorf can be replaced with errors.New (perfsprint) --------- Co-authored-by: Alessio Biancalana <alessio@dottorblaster.it>
Bumps [actions/checkout](https://github.com/actions/checkout) from 5 to 6. - [Release notes](https://github.com/actions/checkout/releases) - [Commits](actions/checkout@v5...v6) --- updated-dependencies: - dependency-name: actions/checkout dependency-version: '6' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com>
* feat(cli): validate sudo (sudo -v) in beforeCommand if --root is set Signed-off-by: Fabrizio Sestito <fabrizio.sestito@suse.com> * feat(docker): add root and sudoCommand and execute commands with sudo if root is set Signed-off-by: Fabrizio Sestito <fabrizio.sestito@suse.com> * feat(cli): add --root description and -r alias Signed-off-by: Fabrizio Sestito <fabrizio.sestito@suse.com> --------- Signed-off-by: Fabrizio Sestito <fabrizio.sestito@suse.com>
* add GenerateEntryCommand package The package mimics the actual distrobox-generate-entry shell command that installs a desktop entry file so that the host's desktop environment can render the appropriate application icon. This first implementantion scaffolds the command package and implements the simplest scenario for a single container. * delete entry If the `delete` flag is provided, the command remove the desktop entry if present. Deleting a non-existing item does not raise an error. * generate entries for all containers With `opts.All` we implement an abstraction over the `GenerateEntryCommand` that iterates across all the containers to generate or delete the relative desktop entries. `ListCommand` is used to fetch the list of containers. * mount the generate-entry cli command Mount the command so that is reachable from the CLI. Define parameters with type and basic validation. Depending on the flag `--all`, the appropriate set of options is provided to the `GenerateEntryCommand.Execute()` method. If `--all` is set, `container-name` and `icon` arguments will be ignored.
* embed shell scripts to execute inside the distrobox The command init, export and host-exec must be accessible from inside the distrobox container. When needed, the embedded scripts will be written to a host directory and then mounted as volume on the created container. The host directory is determined by configuration and environment variables. The script will be not converted to GO to keep then architecture-agnostic. * add Create to the Docker container manager The function will compose argument string to append to the `docker` command. If `DryRun=true`, the command is just printed on screen and not executed. * add Create command package * mount cli command
* feat: add config Signed-off-by: Fabrizio Sestito <fabrizio.sestito@suse.com> * build(deps): add testify Signed-off-by: Fabrizio Sestito <fabrizio.sestito@suse.com> * test(config): add config loading test Signed-off-by: Fabrizio Sestito <fabrizio.sestito@suse.com> --------- Signed-off-by: Fabrizio Sestito <fabrizio.sestito@suse.com>
* feat(enter): rewrite in go * chore: make InspectContainer public * chore: use userenv package for user's environment * chore: export InspectResult type for convenience * fix: rename containerInspect to inpectOutput * fix: use userenv inside generateEnterCommand * fix(enter): more userenv * chore: add some unit tests for buildContainerPath and buildCommandArgs
915611a to
2db8252
Compare
* read desktop entry directory and distrobox path from the global config * implement entry generation requested from user
* remove unused ID field * add a test for include order
Signed-off-by: Luca Di Maio <luca.dimaio1@gmail.com>
Some flags are shared to many commands but not to all (example: `--root`). By composing decorators, each command can be configured so that is assigned only to the flags that matters.
`assemble` command cannot be executed as root. Instead, each item can either be processed by a rootful or rootless container manager.
Previously, the CLI hardcoded "1.0.0" as the version string in two places (the root command and the generate-entry subcommand). Introduce pkg/version, a minimal package that exposes a single variable Version, defaulting to "dev". The root command now references such a value; generate-entry does not need it al all The Makefile computes the version at build time by running: git describe --tags --always This produces the exact tag name when HEAD is tagged, or --g when it is not, giving a precise description of the build relative to the nearest ancestor tag. If git is unavailable, the value falls back to "dev". The resulting string is injected into the binary via: -ldflags "-X github.com/89luca89/distrobox/pkg/version.Version=<value>" so that distrobox --version and distrobox generate-entry --version both report the exact version of the build.
`Interactive: !NoTTY` routed stdio to discarded buffers whenever --no-tty was set, breaking ptyxis. --no-tty only governs whether `--tty` is appended to the exec args, not stdio plumbing. Signed-off-by: Luca Di Maio <luca.dimaio1@gmail.com>
Wire signal.NotifyContext in main so SIGINT/SIGTERM cancel the context instead of killing the process. ephemeral and assemble now defer rm on a detached cleanup ctx, so the in-flight container is removed even when the user hits Ctrl+C. Signed-off-by: Luca Di Maio <luca.dimaio1@gmail.com>
PullImage ignored opts.DryRun and pulled anyway. Thread DryRun through PullImage and gate the usesRunc / supportsKeepIDSize probes. Signed-off-by: Luca Di Maio <luca.dimaio1@gmail.com>
`makeContainerName` replaced user-provided names with DefaultContainerName whenever `image=` was empty, and `sectionToItem` kept whitespace from headers like `[ generic1]`. Both made `assemble create` emit `--name my-distrobox` (or a leading-space name) for sections without an explicit image. Signed-off-by: Luca Di Maio <luca.dimaio1@gmail.com>
- enter: fall back to cfg.DefaultContainerName (was passing "" to the manager) - rm: fall back to cfg.DefaultContainerName (was a silent no-op) - upgrade: error with "Please specify the name of the container." (was silently using my-distrobox) Signed-off-by: Luca Di Maio <luca.dimaio1@gmail.com>
* chore(ci): update actions and pin them to commit sha * chore(dependabot): add gomod package ecosystem * chore(dependabot): add cooldown for package updates
Forward the command/arguments collected after `--` on the ephemeral CLI
through `EphemeralOptions.CustomCommand` to the underlying enter
command, matching the bash reference (`distrobox-enter ... ${name}
${container_command}`). Without this, examples like `distrobox
ephemeral --image alpine -- cat /etc/os-release` would silently drop
the trailing command and just open an interactive shell.
…r name (#2108) Generate the random ephemeral container name in a loop that re-rolls if the name already exists according to the container manager, and fail loudly after a small number of attempts. Dry-run mode bypasses the existence check to match the rest of the dry-run pipeline. Also extends MockContainerManager with an optional ExistsFn override so tests can simulate collisions without changing behavior for existing tests (the default still returns false).
`distrobox assemble create /path/to/file.ini` and `distrobox assemble rm /path/to/file.ini` now work the same way as the original Bash `distrobox-assemble` script, in addition to the existing `--file` flag. When both are supplied, `--file` takes precedence (explicit over implicit). When neither is given, the default `./distrobox.ini` is still used. The resolution logic is extracted into a `resolveManifestPath` helper with unit tests covering flag precedence, positional fallback and the default path.
When `--icon auto` is used (the implicit default for `--all`), match the container's image name (or container name as fallback) against the upstream DISTRO_ICON_MAP and select the matching distro logo. Falls back to the generic terminal icon when no distro can be detected, preserving previous behaviour.
When `--additional-flags --label=manager=...` overrides the manager label at creation time, `distrobox list` would hide the container and `distrobox rm` would silently no-op (it filters through the same list). Match the distrobox.* label set alongside `manager` so containers remain detectable when the manager label is overridden, restoring v1's loose `*distrobox*` substring behavior.
The DE (at least Gnome and KDE) tries to match the app_id of
the running application with the corresponding .desktop file in this order:
- find ${app_id}.desktop
- if not found, tries to find a .desktop with StartupWMClass=${app_id}
Because when exporting a application we change the name of the .desktop
file, the DE can't match the running app, displaying a generic icon.
To solve this, change StartupWMClass key of the exported .desktop file
to the name of the .desktop inside distrobox (minus the .desktop extension).
Ports show_compatibility from bash distrobox-create. Downloads docs/compatibility.md from upstream and caches the parsed list in the user cache dir.
fabriziosestito
approved these changes
Jun 14, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No squash-merge for this! We are just merging all the v2.0 efforts in main.
More about that at: https://distrobox.it/posts/announcing_distrobox_next/