ublue-os / bazzite

Bazzite is a custom image built upon Fedora Atomic Desktops that brings the best of Linux gaming to all of your devices - including your favorite handheld.
https://bazzite.gg
Apache License 2.0
3.53k stars 201 forks source link

Brew packages installed on host are not available in container, even with host-exec #1294

Open C-Higgins opened 1 month ago

C-Higgins commented 1 month ago

Describe the bug

When you install something via brew in the host, you cannot access it inside a container, even by using distrobox-host-exec. It is simply not available in the PATH. Other host commands work as expected.

What did you expect to happen?

distrobox-host-exec should be able to run brew commands that the host can run

Output of rpm-ostree status

State: idle
Deployments:
● ostree-image-signed:docker://ghcr.io/ublue-os/bazzite:stable
                   Digest: sha256:03f4b166f57323b6228982bb8b78297d88f6483faf5dfe45982498cd15722c80
                  Version: 40.20240625.0 (2024-06-27T01:59:48Z)
            LocalPackages: mullvad-vpn-2024.3-1.x86_64
                   Pinned: yes

  ostree-image-signed:docker://ghcr.io/ublue-os/bazzite:stable
                   Digest: sha256:03f4b166f57323b6228982bb8b78297d88f6483faf5dfe45982498cd15722c80
                  Version: 40.20240625.0 (2024-06-27T01:59:48Z)

Hardware

No response

Extra information or context

> distrobox-host-exec which brew
which: no brew in (/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin)
Zeglius commented 1 month ago

brew by default is only added to PATH when the bash session is interactive, as default in /etc/profile.d/brew.sh:

#!/usr/bin/env bash
[[ -d /home/linuxbrew/.linuxbrew && $- == *i* ]] && eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)"

Using bash with the --interactive flag solves the issue: ^ Don't do this, see my comment below


πŸ“¦[zeglius@fedora ~]$ distrobox-host-exec bash -i -c 'which brew'

   Welcome to Bazzite 󰊴                                                       

  󱋩  bazzite-nvidia:stable                                                    

          ο’΅ COMMAND        β”‚         DESCRIPTION                              
  ─────────────────────────┼──────────────────────────────                    
    ujust                  β”‚ List all available commands                      
    ujust toggle-user-motd β”‚ Toggle this banner on/off                        
    ujust changelog        β”‚ View changelog                                   
    fastfetch              β”‚ View system information                          

  σ°‹Ό Want to customize and theme your desktop? Tweak your desktop by following 
  our guide https://universal-blue.discourse.group/docs?topic=574             

  β€’ ο‚› Report an issue https://github.com/ublue-os/bazzite/issues              
  β€’ σ°ˆ™ Documentation http://docs.bazzite.gg/                                   
  β€’ σ°™― Discord https://discord.bazzite.gg/                                     
  β€’ σ°«‘ Mastodon https://fosstodon.org/@UniversalBlue                           

/home/linuxbrew/.linuxbrew/bin/brew
Zeglius commented 1 month ago

Another option is using the absolute path to brew binary (which is way better), you don't want scripts to use interactive mode

distrobox-host-exec /home/linuxbrew/.linuxbrew/bin/brew
C-Higgins commented 1 month ago

This is still bugged; many packages in brew assume that they are available after being called. For example this will not work in a container, because the atuin init script calls atuin itself.

distrobox-host-exec /home/linuxbrew/.linuxbrew/bin/atuin init fish | source

- (line 1): 
atuin uuid
^~~~^
in command substitution
    called on line 1 of file -
from sourcing file -
- (line 1): Unknown command
set -gx ATUIN_SESSION (atuin uuid)
                      ^~~~~~~~~~~^
from sourcing file -

Nor does aliasing it work; these tools are setting necessary environment variables during init which seemingly don't propagate to the container's shell. I'm finding it very difficult to set up my shell this way. Something as simple as this, my usual config (with these packages via brew), is seemingly arcane when in a container:

        atuin init fish | source
        starship init fish | source
Zeglius commented 1 month ago

Well yeah, the point of containers is to prevent being affected by host dependencies. My best advice is simply installing brew inside the container.

Other than that, I don't think anything else can be done without breaking container isolation.

C-Higgins commented 1 month ago

Well yeah, the point of containers is to prevent being affected by host dependencies. My best advice is simply installing brew inside the container.

Other than that, I don't think anything else can be done without breaking container isolation.

The point of containers in this context is to prevent the container from affecting the host. The existence of distrobox-host-exec implies that the host ought to be able to affect the container, and it would be able to if these packages were installed at the image level or even the home level. It's just a quirk of the weird setup here that brew is a separate user instead of the binaries being located in ones own home. That decision is causing these downstream effects. With Bazzite pushing heavily for both Brew and Distrobox, it doesn't make sense for this incompatibility to be intended. At least, the base images provided by ujust distrobox-assemble should include a transparent Brew installation to facilitate this.

Zeglius commented 1 month ago

With Bazzite pushing heavily for both Brew and Distrobox

Not denying that, but I don't think it is intended to mix both. I would recommend installing these tools with the package manager the container image provides (apt if Ubuntu/debian, pacman for arch, etc).

Also there are some workarounds that might help, like symlinking host-spawn binary to ~/.local/bin/atuin or any other PATH directory, so it will call host atuin.

You can check https://distrobox.it/posts/execute_commands_on_host/ to see which option fits your needs