ublue-os / fleek

[deprecated] Own your $HOME
https://getfleek.dev
Apache License 2.0
835 stars 24 forks source link

Fleek default config removes `nix` from path #238

Open mtalexan opened 1 year ago

mtalexan commented 1 year ago

Describe the bug The default fleek init && fleek apply results in a shell that is unable to find or use the nix command.

To Reproduce Steps to reproduce the behavior:

  1. Install Fedora 38 workstation fresh with all defaults
  2. Install Nix with the Determinate Nix installer, taking all defaults
  3. Install fleek with the curl command
  4. Config your git user.name and user.email
  5. Add and register a GitHub SSH key
  6. Run fleek init
  7. Immediately run fleek apply
  8. Open a new terminal window

Expected behavior which nix should still find nix (which still works in the old terminal window).

Environment

Additional context echo $PATH in the old window versus the new window shows that the only thing missing are the nix paths. The $HOME/.nix-profile/bin and the /nix/var/nix/profiles/default/bin are both missing from the PATH in the new terminal window, but present in the old one. Running which nix in the old window reveals that the nix command is in /nix/var/nix/profiles/default/bin/nix.

Explicitly adding the two missing paths to the paths section of the .fleek.yaml and then running fleek apply seems to succeed, but opening a new terminal window afterward shows that those two paths got ignored/removed and are not present in the new terminal's $PATH.

bketelsen commented 1 year ago

on my Fedora workstation the Nix installer has modified both /etc/bashrc and /etc/bash.bashrc which load the correct environment. my install is a multi-user install. Did you install single-user or multi-user? What are the contents of /etc/bashrc? At the end is there a part sourcing Nix?

mtalexan commented 1 year ago

I have a multi-user install, so it's getting the nix path by the /etc/bash.bashrc file calling the nix_daemon.sh script and not from the ~/.bashrc or ~/.bash_profile.

To verify I confirmed Nix was working before I started installing fleek by running nix profile list (it was empty because I didn't install anything yet, but it completed). After installing fleek, my still-open terminal could still find nix, but my newly opened one could not. I moved the ~/.bash_profile and ~/.bashrc that had been populated by fleek to *.bak files, leaving me with no ~/.bash_profile or ~/.bashrc, and opened a new terminal. In that terminal I had the crappy default prompt bash-5.2>, but I could successfully run which nix. Putting the *.bak files for back and opening a new temrinal, I was back to being unable to succesfully run which nix.

I literally just installed nix and then fleek on a fresh Fedora 38 Workstation install, with no modifications to the default generated fleek.yaml, and that's the effect I'm seeing.

mtalexan commented 1 year ago

I'm spinning up a completely clean Fedora 38 Workstation VM right now to run thru it again to confirm. This doesn't seem like something that would easily get by basic testing, so it seems unusual.

mtalexan commented 1 year ago

Ok, I just confirmed it in a completely stock brand new Fedora 38 VM.

  1. Install from ISO into VM
  2. Reboot and go thru inital VM setup
  3. Run dnf upgrade
  4. Reboot VM
  5. Run Determinate Nix installer, accepting defaults: curl --proto '=https' --tlsv1.2 -sSf -L https://install.determinate.systems/nix | sh -s -- install
  6. Open a new terminal window
  7. Verify which nix (success)
  8. Install fleek in the new terminal window: curl -fsSL https://getfleek.dev/installer | bash
  9. Initialize fleek fleek init
  10. Apply the default config: fleek apply
  11. Open a new terminal window
  12. Verify which nix (fail)
mtalexan commented 1 year ago

Ah ha!

After playing with it, I narrowed it down to it happening only if the stock fedora ~/.bashrc and ~/.bash_profile are replaced with the fleek one, and it goes away if I swap the originals back in. I looked and looked and couldn't see why that would happen until I realized that the stock Fedora ~/.bashrc is manually sourcing the global /etc/bashrc, which is where the multi-user nix install puts the pathing (it adds sourcing of nix-daemon.sh to both /etc/bashrc/ and/etc/bash.bashrc` apparently).

So these lines:

# Source global definitions
if [ -f /etc/bashrc ]; then
    . /etc/bashrc
fi

Need to be preserved from the stock Fedora ~/.bashrc into the fleek-replaced ~/.bashrc

mtalexan commented 1 year ago

Once I dumped the old ~/.bashrc.bak into my ~/.local/share/fleek/fedora/custom.nix as:

  programs.bash.initExtra = ''
        ######################################################################
        # Preserve stock Fedora .bashrc so we get global settings properly

        # Source global definitions
        if [ -f /etc/bashrc ]; then
                . /etc/bashrc
        fi

        # User specific environment
        if ! [[ "$PATH" =~ "$HOME/.local/bin:$HOME/bin:" ]]
        then
            PATH="$HOME/.local/bin:$HOME/bin:$PATH"
        fi
        export PATH

        # Uncomment the following line if you don't like systemctl's auto-paging feature:
        # export SYSTEMD_PAGER=

        # User specific aliases and functions
        if [ -d ~/.bashrc.d ]; then
                for rc in ~/.bashrc.d/*; do
                        if [ -f "$rc" ]; then
                                . "$rc"
                        fi
                done
        fi

        unset rc
        ######################################################################
      '';

And re-ran fleek apply, opening a new terminal got it all working again.

mtalexan commented 1 year ago

It seems like it would be useful to just automatically dump the old pre-existing ~/.bashrc contents into the machine-specific custom.nix if a new machine is being generated, and document that the user should go remove what they don't need. Otherwise most systems will need to go thru this process to replicate the old file into the custom.nix.

bketelsen commented 1 year ago

great detective work @mtalexan. I'll explore options on resolving this and leave this open to document fixes or possible changes.

mtalexan commented 1 year ago

Heads up, in Fedora the default ~/.bashrc contains a line to source /etc/bashrc.bashrc if it exists, and this file is what includes a bunch of the files to setup the default aliases. I've found that if I add the line sourcing /etc/bashrc.bashrc in my ${hostname}/custom.nix file as part of the appropriate home-manager config, the default aliases end up overriding the custom aliases home-manager sets up.

Hopefully your PR is inserting the sourcing of that file somewhere that gets added to the ~/.bashrc before all the default home-manager generated content, otherwise many systems will no longer be able to set any aliases that conflict with the distro default ones.

mtalexan commented 1 year ago

Really it might just be better to add instructions for installation that recommend copying the ~/.bashrc.old contents into the ${hostname}/custom.nix as a programs.bash.initExtra value, and pruning it of things you've changed in the home-manager settings.

bketelsen commented 1 year ago

did it create ~/.bashrc.old or was it .bak?

bketelsen commented 1 year ago

add /etc/bashrc.bashrc to source

mtalexan commented 1 year ago

did it create ~/.bashrc.old or was it .bak?

Sorry, you're right, it was .bak.

mtalexan commented 1 year ago

add /etc/bashrc.bashrc to source

The "standard" files are: /etc/bashrc and /etc/bashrc.bashrc. Ubuntu uses the former and Fedora the latter for example.

As I mentioned though, if you're adding the sourcing of these to the programs.bash.initExtra it will break any aliases that collide with the system defaults. That means things like less, ll, etc won't be usable as aliases. Home Manager constructs the ~/.bashrc by putting the bash.initExtra content after the sessionAliases and bash.Aliases and the last alias definition when there are conflicts wins.

zsh actually has a whole separate variable for defining things that should be first to avoid this in fact.

mtalexan commented 10 months ago

So the overall problem is this: Home-manager's programs.bash.initExtra places its contents after all other session.* and programs.bash.*. There is no home-manager programs.bash option for specifying free text that should be populated before the other definitions. Home-manager's programs.zsh includes a programs.zsh.initExtraFirst specifically for including things that need to go before everything else.

The default sourcing of /etc/bashrc or /etc/bashrc.bashrc that Ubuntu and Fedora include in the default .bashrc respectively has to be specified before anything else, otherwise it will override what the user has explicitly specified. In particular this is noticeable for if the user has eza and aliases ll to eza -l (for example). Both Ubuntu and Fedora include in their default settings alias ll='ls -l ', so if the default file is sourced at the end, the default alias for ll will override the customized one using eza.