Skip to content

Uninstall an application from a box - #211

Open
kacperpaczos wants to merge 4 commits into
Dvlv:masterfrom
kacperpaczos:feat/uninstall-app
Open

Uninstall an application from a box#211
kacperpaczos wants to merge 4 commits into
Dvlv:masterfrom
kacperpaczos:feat/uninstall-app

Conversation

@kacperpaczos

@kacperpaczos kacperpaczos commented Aug 19, 2026

Copy link
Copy Markdown
Contributor

Closes #207

Adds an Uninstall button to the applications list — the bookend to Add To Menu, and one of the Needs External Help roadmap items.

Uninstall button

The interesting part is picking what to remove. A desktop file's Exec= is the binary, which usually isn't the package name (gimp → gimp-2.10), so the handler asks the box who owns the binary — dpkg -S, rpm -qf or pacman -Qqo, after resolving the name through command -v with the games directories added since desktop files can point there (Debian's cowsay lives in /usr/games, which a non-login shell's PATH lacks) — and only falls back to the bare name if that fails. Removal is spelled per manager (pacman -R, apk del, slackware removepkg).

It reuses what master already has: the box's package manager comes from utils::detect_pkg_manager (the same table the .deb/.rpm install paths use), and the terminal is opened through the install path's helper, now taking the manager's arguments as a slice — so install and remove share one argv-based spawn. Everything from the desktop file reaches the commands as separate arguments or positional parameters, never spliced into shell text.

Testing

  • End-to-end on a real Ubuntu box with the current code: installed cowsay, ran the exact resolve queries the button issues (command -v found /usr/games/cowsay, dpkg -S named the package), removed it with the same sudo apt remove <pkg> argv, and confirmed the binary was gone afterwards. An earlier revision of the same pipeline was also exercised on a Fedora box.
  • Unit tests cover the pure pieces: argument splitting, the dpkg/rpm/pacman ownership parsing, and the per-manager removal table.
  • The button itself is screenshotted above; the wiring just calls the tested handler.

BoxBuddy Contributor and others added 2 commits August 22, 2026 20:19
Adds a pill 'Uninstall' button next to 'Run' on every row in the View
Applications popup. The handler shells to a terminal running
'distrobox enter NAME -- sudo <pkg-manager> remove EXEC', so the user
sees the sudo prompt and can confirm before the package is removed.

The package manager is picked from the box's image (apt/dnf/zypper/
pacman/apk/xbps-install/emerge/installpkg) by pick_pkg_manager_for_
uninstall - a small heuristic that mirrors what Kontainer's
packageinstallcommand.cpp does for install flows. The default is apt
because apt fails loudly on non-apt distros instead of partially
succeeding.

Resolves 'Uninstall application from box' from the Roadmap.

The .desktop export on the host is deliberately left alone - that is a
separate, reversible 'Remove From Menu' action already available on the
same row.
Uninstall passed the desktop file's Exec= value straight to the package
manager as if it were a package name. The two rarely agree - gimp lives
in gimp-2.10 - so the happy path mostly failed. Worse, the value was
interpolated unquoted into a bash -c line, and a desktop file comes from
the container image, not from the user: an Exec= with a semicolon in it
would have run whatever it liked with the host's home mounted.

The manager now gets asked who owns the binary (dpkg -S, rpm -qf or
pacman -Qqo, after resolving the name through command -v with /usr/games
widening the search, since desktop files may point outside the login
PATH), with the bare executable name kept as the fallback guess.
Everything that reaches the terminal command is shell-quoted, and the
untrusted values travel to the resolution queries as positional
parameters rather than shell text. Removal is also spelled per manager
now - pacman takes -R, apk takes del, and slackware removes with
removepkg despite installing with installpkg.

The pure pieces - token splitting, quoting, ownership-output parsing and
the removal table - come with unit tests.
master already knows how to tell a box's package manager from its image
(utils::detect_pkg_manager), so the uninstall path now asks that instead
of carrying its own copy of the table. The terminal spawn is shared with
the .deb/.rpm install path too: run_install_in_terminal takes the
manager's arguments as a slice, so install and remove go through the
same argv-based call - which also means there is no shell line to quote
any more, and the quoting helper and its test go away with it.
A non-login shell inside the box does not have /usr/games on its PATH,
so command -v could not find a desktop file's binary there and the
resolver fell back to the bare name. The lookup now adds the games
directories for that one query.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Uninstall an application from a box (Roadmap: Needs External Help)

1 participant