Workaround for Nix(OS)
codenyte opened this issue ยท 23 comments
Please consider creating a package for the Nix package manager/NixOS. Although NixOS is a Linux distribution, it handles many things very differently and unfortunately it's not possible to install fx-autoconfig the traditional way on Nix. This guide explains how to create a Nix package: https://nixos.wiki/wiki/Packaging/Tutorial
Note that this is not a installable package and I purposefully don't provide any kind of "install-script" for it.
The way you you would set up fx-autoconfig is to just copy the files in program
directory to wherever your firefox binary is, and the files in profile
to wherever your Firefox profile directory is located. Follow the steps in readme for more detailed information, or if there is particular bit that you can't get past of then tell me what it is and maybe we can figure it out.
All packages installed through Nix are located in a read-only directory. When using the Nix package manager on a "normal" distro, you might be able to bypass this with root, but on NixOS there is no real way around it. Packages (like Firefox) can't be modified. I thought packaging fx-autoconfig for Nix would solve that, but then I reallized that a package can't overwrite another package's files either. I'll figure out a solution and let you know. But it would be great if there was some workaround for installing fx-autoconfig on Nix or other immutable distributions.
Right, I doubt I can do anything about that. Firefox' autoconfig feature requires that you can write default pref files to program folder because that's the only place it knows to look for them.
So, I suppose you have to compile Firefox in a way where it looks somewhere else for them. This is probably a long shot, but maybe the package manager already compiles Firefox to make it look for default pref/autoconfiguration files in some different folder?
There actually is a way in Nix to modify system/package files: https://discourse.nixos.org/t/how-to-edit-file-in-nix-store/19261
It's complicated (at least for me) and I'm not very familiar with the Nix language. (I only know how to set up basic stuff). But I will try to figure it out.
If this works and I manage to create a Nix config snippet that installs fx-autoconfig, you could maybe put that in the README.
Sure. It seems quite a task though, that sounds like you would have to compile or at least re-package the whole Firefox with your added patch.
I was wondering the same thing and came up with this workaround for now by using an overlay to symlink the files from my home dir into the nix store:
final: prev: {
firefox = (prev.firefox).overrideAttrs (oldAttrs: {
buildCommand = (oldAttrs.buildCommand or "") + ''
ln -sf /home/${username}/.dotfiles/${path_to_userChromeJS}/config.js $out/lib/firefox/config.js
ln -sf /home/${username}/.dotfiles/${path_to_userChromeJS}/config-prefs.js $out/lib/firefox/browser/defaults/preferences/config-prefs.js
'';
});
}
If using this, replace the config paths with yours
(postInstall
isn't called in firefox's case, so I had to append to buildCommand
instead)
chrome
can be managed manually just fine, I personally symlink it too to my dotfiles:
# Symlink chrome dir
home.file."/home/${username}/.mozilla/firefox/${profile}/chrome".source = config.lib.file.mkOutOfStoreSymlink "/home/${username}/.dotfiles/user/apps/browser/firefox_profile/chrome";
# Symlink user.js
xdg.configFile."/home/${username}/.mozilla/firefox/${profile}/user.js".source = config.lib.file.mkOutOfStoreSymlink "/home/${username}/.dotfiles/user/apps/browser/firefox_profile/user.js";
I don't know if there's a better solution, but for now this seems to work
Okay, so essentially what you are saying is that if you don't have write access to the program directory then you can instead create symlink for <firefox-bin>/defaults/preferences/config-prefs.js
and <firefox-bin>/config.js
- or did I misunderstand something? (The actual path names and structure can vary between systems).
Sidenote, honestly that feels kinda nonsensical since then you kinda do have write access to that directory after all.
Yes, you understood correctly. I instruct nix to create a symlink during the firefox's package build phase.
There's probably a way to write the files instead, but I'm very new to NixOS and haven't found a way yet.
From what I understand, you have write access only during the package build phase and only within the isolated build environment. You lose write access once the package is built and moved into the nix store. The package's isolated build environment has no access to the system (hence symlink instead of a copy) or Internet (so no fetch from github & move files).
My workaround works as a temporary solution, but I'm positive there should be a proper way to resolve this.
I was wondering the same thing and came up with this workaround for now by using an overlay to symlink the files from my home dir into the nix store:
final: prev: { firefox = (prev.firefox).overrideAttrs (oldAttrs: { buildCommand = (oldAttrs.buildCommand or "") + '' ln -sf /home/${username}/.dotfiles/${path_to_userChromeJS}/config.js $out/lib/firefox/config.js ln -sf /home/${username}/.dotfiles/${path_to_userChromeJS}/config-prefs.js $out/lib/firefox/browser/defaults/preferences/config-prefs.js ''; }); }If using this, replace the config paths with yours (
postInstall
isn't called in firefox's case, so I had to append tobuildCommand
instead)
chrome
can be managed manually just fine, I personally symlink it too to my dotfiles:# Symlink chrome dir home.file."/home/${username}/.mozilla/firefox/${profile}/chrome".source = config.lib.file.mkOutOfStoreSymlink "/home/${username}/.dotfiles/user/apps/browser/firefox_profile/chrome"; # Symlink user.js xdg.configFile."/home/${username}/.mozilla/firefox/${profile}/user.js".source = config.lib.file.mkOutOfStoreSymlink "/home/${username}/.dotfiles/user/apps/browser/firefox_profile/user.js";I don't know if there's a better solution, but for now this seems to work
where do I put this stuff?
where do I put this stuff?
I was later told in NixOS Discord that it's better to use it as package directly instead of overlay. You can put this in your configuration.nix/home.nix, or as a separate module if you use flakes:
Minimal flake example
{ pkgs, config, ... }:
let
userChromeJSPath = "/path/to/user_chrome_js_files"; # (!) Replace with your path
firefox = (pkgs.firefox).overrideAttrs (oldAttrs: {
# Add support for https://github.com/MrOtherGuy/fx-autoconfig
buildCommand = (oldAttrs.buildCommand or "") + ''
ln -sf ${userChromeJSPath}/config.js $out/lib/firefox/config.js
ln -sf ${userChromeJSPath}/defaults/pref/config-prefs.js $out/lib/firefox/browser/defaults/preferences/config-prefs.js
'';
});
in
{
programs.firefox = {
enable = true;
package = firefox;
};
}
Note: $out
path to config-prefs.js
might be different if you are not on Firefox stable.
Sadly, I'm unable to find a way to do this with Firefox Nightly.
{ pkgs, config, ... }: let userChromeJSPath = "/path/to/user_chrome_js_files"; # (!) Replace with your path firefox = (pkgs.firefox).overrideAttrs (oldAttrs: { # Add support for https://github.com/MrOtherGuy/fx-autoconfig buildCommand = (oldAttrs.buildCommand or "") + '' ln -sf ${userChromeJSPath}/config.js $out/lib/firefox/config.js ln -sf ${userChromeJSPath}/defaults/pref/config-prefs.js $out/lib/firefox/browser/defaults/preferences/config-prefs.js ''; }); in { programs.firefox = { enable = true; package = firefox; }; }
I tried adding this to configuration.nix, but I get unexpected LET error
I tried adding this to configuration.nix, but I get unexpected LET error
Are you sure you added it in the right places? It builds for me, so I believe the syntax is correct
Can you show your configuration.nix
?
All I had to do to get this working was
programs.firefox = {
enable = true;
autoConfig = builtins.readFile(builtins.fetchurl {
url = "https://raw.githubusercontent.com/MrOtherGuy/fx-autoconfig/master/program/config.js";
sha256 = "1mx679fbc4d9x4bnqajqx5a95y1lfasvf90pbqkh9sm3ch945p40";
});
};
@rohanssrao Your solution is probably the best one, thanks for sharing it
@MrOtherGuy Consider putting this in the README as the official way of installing on Nix(OS)
@rohanssrao
Oh, that's neat!
I can confirm it works with the base firefox package. Sadly, it doesn't with firefox-nightly-bin
from nix-community, but I guess that's package's fault.
Might also be worth noting that the programs.firefox.autoConfig
option does not exist in home-manager.
One other thing I'm curious about, is it okay to completely ignore defaults/pref/config-prefs.js
?
One other thing I'm curious about, is it okay to completely ignore
defaults/pref/config-prefs.js
?
Yes, this is configured by default in the firefox
package definition.
Might also be worth noting that the
programs.firefox.autoConfig
option does not exist in home-manager.
Nix on non-NixOS systems doesn't support modules (i.e. programs.<name>.<option>
) so that is expected.
Looking at the definition, there is an extraPrefsFiles
attribute that defines files which get appended to mozilla.cfg
so I believe you can put the following in your home.nix
to achieve the equivalent:
home.packages = with pkgs; [
# hello
# cowsay
# ...
(firefox.overrideAttrs {
extraPrefsFiles = [(builtins.fetchurl {
url = "https://raw.githubusercontent.com/MrOtherGuy/fx-autoconfig/master/program/config.js";
sha256 = "1mx679fbc4d9x4bnqajqx5a95y1lfasvf90pbqkh9sm3ch945p40";
})];
})
];
I don't use home-manager anymore though so I can't test it. Let me know if it works. If it does, I'll add it to my PR.
Sadly, it doesn't with
firefox-nightly-bin
from nix-community, but I guess that's package's fault.
You could possibly try something like this to make a new derivation, inheriting the original, that manually puts the files in the correct spot afterward:
environment.systemPackages = with pkgs; [
# hello
# cowsay
# ...
(stdenv.mkDerivation {
name = "firefoxWithAutoconfig";
src = inputs.firefox.packages.${system}.firefox-nightly-bin; # if you specified the package a different way, replace it here
buildPhase = ''
mkdir $out
cp -r * $out/
echo 'pref("general.config.filename", "mozilla.cfg");' > "$out/lib/firefox/defaults/pref/autoconfig.js"
echo 'pref("general.config.obscure_value", 0);' >> "$out/lib/firefox/defaults/pref/autoconfig.js"
cp ${builtins.fetchurl {
url = "https://raw.githubusercontent.com/MrOtherGuy/fx-autoconfig/master/program/config.js";
sha256 = "1mx679fbc4d9x4bnqajqx5a95y1lfasvf90pbqkh9sm3ch945p40";
}} $out/lib/firefox/mozilla.cfg;
'';
})
];
This probably won't work as written since I just wrote it in the text editor and haven't tested it, but feel free to mess around with it.
home-manager has some programs.firefox options, but autoConfig
is not implemented (yet?).
I've tried using extraPrefsFiles
as suggested (only had to wrap builtins.fetchurl
in (parentheses)), but while it compiles without errors, there's no fx-autoconfig support.
The issue with firefox-nightly-bin
is that it fully consists of symlinks to firefox-nightly-bin-unwrapped
, including the launching binary, so any changes to firefox-nightly-bin
's nix store are ignored.
I've tried using
extraPrefsFiles
as suggested (only had to wrapbuiltins.fetchurl
in (parentheses)), but while it compiles without errors, there's no fx-autoconfig support.
Thanks, updated to include parentheses.
This is weird because all that programs.firefox.autoConfig
does in the background is override extraPrefsFiles
.
If you go to the build output in the /nix/store, does it have the correct file layout and contents needed for fx-autoconfig?
Have you also tried adding pref("general.config.sandbox_enabled", false);
, both through Nix and manually through about:config
?
If you go to the build output in the /nix/store, does it have the correct file layout and contents needed for fx-autoconfig?
From what I can see, building with nixos (autoConfig) appends fx-autoconfig's config.js
contents into mozilla.cfg
.
For some reason, it doesn't when built with home-manager (extraPrefsFiles).
This is weird because all that
programs.firefox.autoConfig
does in the background is overrideextraPrefsFiles
.
I've tried using extraPrefsFiles
with nixos:
environment.systemPackages = with pkgs; [
(firefox.overrideAttrs {
extraPrefsFiles = [
(builtins.fetchurl {
url = "https://raw.githubusercontent.com/MrOtherGuy/fx-autoconfig/master/program/config.js";
sha256 = "1mx679fbc4d9x4bnqajqx5a95y1lfasvf90pbqkh9sm3ch945p40";
})
];
})
];
But it also doesn't append to mozilla.cfg
for some reason?
Try changing overrideAttrs
to override
.
Using override
did the trick, works with home-manager now!
Great, I added it to the PR.
Not sure why I haven't thought of this earlier, but I was finally able to add fx-autoconfig to nightly. I just replaced symlinks to binaries with actual binaries upon building it.
If anyone's interested, I've used nix-community/flake-firefox-nightly with this home-manager flake:
firefox.nix
{ pkgs, config, inputs, ... }:
let
# Firefox Nightly with https://github.com/MrOtherGuy/fx-autoconfig
firefox-nightly = (
(inputs.firefox-nightly.packages.${pkgs.system}.firefox-nightly-bin).override {
extraPrefsFiles = [
(builtins.fetchurl {
url = "https://raw.githubusercontent.com/MrOtherGuy/fx-autoconfig/master/program/config.js";
sha256 = "1mx679fbc4d9x4bnqajqx5a95y1lfasvf90pbqkh9sm3ch945p40";
})
];
}
).overrideAttrs (oldAttrs: {
buildCommand = (oldAttrs.buildCommand or "") + ''
# Find firefox dir
firefoxDir=$(find "$out/lib/" -type d -name 'firefox*' -print -quit)
# Function to replace symlink with destination file
replaceSymlink() {
local symlink_path="$firefoxDir/$1"
local target_path=$(readlink -f "$symlink_path")
rm "$symlink_path"
cp "$target_path" "$symlink_path"
}
# Copy firefox binaries
replaceSymlink "firefox"
replaceSymlink "firefox-bin"
'';
});
in
{
programs.firefox = {
enable = true;
package = firefox-nightly;
};
}
For NixOS, just replace that override
block with programs.firefox.autoConfig
option.