Skip to content

fix(update): recognise a distribution package on hosts without apt - #401

Open
cbyrd01 wants to merge 1 commit into
google:mainfrom
cbyrd01:fix/update-non-apt-linux
Open

cbyrd01 wants to merge 1 commit into
google:mainfrom
cbyrd01:fix/update-non-apt-linux

Conversation

@cbyrd01

@cbyrd01 cbyrd01 commented Nov 10, 2026 •

Copy link
Copy Markdown

The install layout is inferred from the executable path, and anything under /usr/bin is treated as a .deb install. A distribution's own package installs there too. On such a host:

  • capsem update downloaded the .deb, asked for a sudo password, and only then failed inside the privileged script because /usr/bin/apt-get does not exist.
  • Automatic updates repeated that on every poll once a newer release existed. Because the binary step fails first, the VM assets were never refreshed either.

This adds InstallLayout::SystemPackage for /usr/bin without apt-get. It gets the treatment the user-dir and development layouts already have: no installer is selected, so the update goes straight on to the VM assets. The user is told:

This Capsem was installed by your system's package manager, which also updates it. VM assets are still updated here.

.deb installs are unchanged: with apt-get present the layout is still LinuxDeb. install_bin_dir_for returns None for the new layout, so capsem uninstall leaves the package manager's files in /usr/bin alone.

Tests. Four new unit tests in platform/tests.rs (layout selection with and without apt, no other layout affected, no install bin dir, the message) and one added assertion in the existing deb installer test. They fail to compile before the change; cargo test -p capsem --bin capsem passes (394) and clippy is clean.

The message lives on InstallLayout rather than in update.rs, and the installer check is an assertion rather than a new test, so update.rs and update/tests.rs stay at their line ratchet in config/gate.toml.

Not verified. I have not run this against a release channel that is ahead of the installed version, so the "newer release exists" path is covered by the unit tests only.

🤖 Generated with Claude Code

The install layout is inferred from the executable path, and anything
under /usr/bin was a .deb install. A distribution's own package installs
there too. On such a host `capsem update` downloaded the .deb, asked for
sudo and failed in the privileged script because apt-get does not exist.
Automatic updates repeated that on every poll, and because the binary
step fails first the VM assets were never refreshed either.

Add InstallLayout::SystemPackage for /usr/bin without apt-get. It is
offered no installer, like the user-dir and development layouts, so the
update goes straight on to the VM assets, and the user is told that the
package manager updates the programs.

@mangeshraut712 mangeshraut712 left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Skipping the binary step and still refreshing VM assets is the right outcome for a distro-packaged install.

Comment on lines +52 to 57
fn layout_for_package_manager(layout: InstallLayout, apt_get_present: bool) -> InstallLayout {
match layout {
InstallLayout::LinuxDeb if !apt_get_present => InstallLayout::SystemPackage,
other => other,
}
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"apt-get exists" answers can a .deb be installed here, but the question that matters is was this binary installed from our .deb. Those differ on Debian/Ubuntu hosts: if Capsem comes from the distro's own archive or a PPA, or someone copied the binary into /usr/bin by hand, apt-get is present, the layout stays LinuxDeb, and the updater will swap in the release .deb over a package another source owns. The next apt upgrade would then fight it.

Asking dpkg about the actual file would cover both cases with one check: dpkg-query -S <exe path> (or reading /var/lib/dpkg/info/<pkg>.list) says whether the file belongs to the package name the release .deb uses. If it doesn't, or dpkg isn't there, return SystemPackage. The pure layout_for_package_manager(layout, owned_by_release_deb: bool) shape would stay just as testable.

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.

2 participants