nixos-config/modules/browser.nix

342 lines
9.8 KiB
Nix
Raw Normal View History

2024-08-29 03:26:04 +02:00
{
config,
lib,
pkgs,
...
}:
2019-10-24 02:20:38 +02:00
# todo : this needs to be cleaned up
with lib;
let
2024-03-03 09:59:17 +01:00
cfg = config.services.browser;
2019-10-24 02:20:38 +02:00
chromiumBin = "${pkgs.chromium}/bin/chromium";
chromeBin = "${pkgs.google-chrome}/bin/google-chrome-stable";
firefoxBin = "${pkgs.firefox}/bin/firefox";
tarBin = "${pkgs.gnutar}/bin/tar";
# desktop file
# ------------
# makes it possible to be used by other programs
2024-08-29 03:26:04 +02:00
desktopFile =
bin:
let
browserName = bin.name;
in
pkgs.writeTextFile {
2019-12-20 05:54:26 +01:00
name = "${browserName}.desktop";
destination = "/share/applications/${browserName}.desktop";
text = ''
[Desktop Entry]
Type=Application
Exec=${bin}/bin/${browserName} %U
Icon=chromium
Comment=An open source web browser from Google
Terminal=false
Name=${browserName}
GenericName=Web browser
MimeType=text/html;text/xml;application/xhtml+xml;x-scheme-handler/http;x-scheme-handler/https;x-scheme-handler/ftp;x-scheme-handler/webcal;x-scheme-handler/about
Categories=Network;WebBrowser
StartupWMClass=${browserName}
'';
};
2019-10-24 02:20:38 +02:00
2024-08-29 03:26:04 +02:00
killBrowser =
name: pkgs.writeShellScriptBin "${name}-kill" "sudo ${pkgs.killall}/bin/killall -9 -u ${name}";
2020-10-12 23:05:15 +02:00
2024-08-29 03:26:04 +02:00
cleanBrowser =
name: browser: home: homeBackup:
2019-12-20 05:54:26 +01:00
let
backupFile = "${homeBackup}.tar.lzma";
rolloutFile = "${home}.tar.lzma";
lockFile = "${home}-lock";
2021-11-01 09:20:42 +01:00
in
pkgs.writeShellScriptBin "${name}-clean" # sh
''
sudo ${pkgs.killall}/bin/killall -9 -u ${name}
2021-11-01 09:20:42 +01:00
sudo rm -f ${lockFile}
sudo rm -rf ${home}
'';
2019-10-24 02:20:38 +02:00
2024-08-29 03:26:04 +02:00
createBrowser =
name: user: browser: home: homeBackup:
2019-12-20 05:54:26 +01:00
let
backupFile = "${homeBackup}.tar.lzma";
rolloutFile = "${home}.tar.lzma";
lockFile = "${home}-lock";
2021-11-01 09:20:42 +01:00
in
pkgs.writeShellScriptBin "${name}" # sh
''
# set -x
if [[ ! -e ${lockFile} ]]
then
# rollout backup
if [[ -e ${backupFile} ]]
then
if [[ ! -d ${home} ]]
then
# todo : use make user
sudo mkdir -p ${home}
sudo chown -R ${user}:users ${home}
fi
cp ${backupFile} ${rolloutFile}
sudo -u ${user} ${tarBin} xf ${rolloutFile} --directory ${home}
rm ${rolloutFile}
touch ${lockFile}
fi
fi
sudo -u ${user} ${browser}
'';
browserExecutableList =
let
2024-08-29 03:26:04 +02:00
allBrowser = flip mapAttrsToList cfg.configList (
name: config:
2021-11-01 09:20:42 +01:00
let
browser =
if config.browserType == "chrome" then
''${chromiumBin} "$@"''
else if config.browserType == "google" then
''${chromeBin} "$@"''
else
''${firefoxBin} "$@"'';
in
2024-08-29 03:26:04 +02:00
createBrowser name config.user browser config.home config.homeBackup
);
2021-11-01 09:20:42 +01:00
xclipBrowser = [
(pkgs.writeShellScriptBin "copy-to-xclip" # sh
''
echo "$*" | ${pkgs.xclip}/bin/xclip
2024-08-29 03:26:04 +02:00
''
)
2021-11-01 09:20:42 +01:00
];
in
allBrowser ++ xclipBrowser;
2019-10-24 02:20:38 +02:00
2024-08-29 03:26:04 +02:00
createBackupScript =
name: home: backupHome:
2023-11-06 10:50:00 +01:00
createBackupScriptTemplate {
sudo = name;
name = name;
source = home;
target = backupHome;
2023-11-06 11:46:59 +01:00
excludes = [
"Downloads"
".cache"
".config/*chrom*/*cache"
".config/*chrom*/Crash Reports"
".config/*chrom*/Default/DawnCache"
".config/*chrom*/Default/IndexedDB"
".config/*chrom*/Default/Local Storage"
".config/*chrom*/Default/Service Worker/CacheStorage"
".config/*chrom*/Default/Storage"
".config/*chrom*/Default/optimization_guide_prediction_model_downloads"
".mozilla/firefox/*.default/*cache*"
".mozilla/firefox/*.default/crashes"
".mozilla/firefox/*.default/datareporting"
".mozilla/firefox/*.default/sessionstore-backups"
".mozilla/firefox/*.default/storage-sync-v2.sqlite"
".mozilla/firefox/*.default/storage/temporary"
".mozilla/firefox/*.default/storage/to-be-removed"
".mozilla/firefox/Crash Reports"
2023-11-06 10:50:00 +01:00
];
};
2024-08-29 03:26:04 +02:00
createBackupScriptTemplate =
{
sudo,
name,
source,
target,
excludes ? [ ],
}:
pkgs.writers.writeBashBin "${name}-backup" ''
sudo -u ${sudo} \
${tarBin} \
${concatStringsSep " " (map (pattern: "--exclude=\"${pattern}\"") excludes)} \
--create \
--verbos \
--lzma \
--file ${source}.tar.lzma \
--directory ${source} \
.
2023-11-06 10:50:00 +01:00
2024-08-29 03:26:04 +02:00
cp ${source}.tar.lzma ${target}.tar.lzma
'';
2021-11-01 09:20:42 +01:00
allBackupScripts =
let
2024-08-29 03:26:04 +02:00
filteredConfigs = filterAttrs (
name: browserConfig: browserConfig.homeBackup != null
) cfg.configList;
2021-11-01 09:20:42 +01:00
in
2024-08-29 03:26:04 +02:00
mapAttrsToList (
name: browserConfig: createBackupScript name browserConfig.home browserConfig.homeBackup
) filteredConfigs;
2021-11-01 09:20:42 +01:00
allCleanScripts =
let
2024-08-29 03:26:04 +02:00
filteredConfigs = filterAttrs (
name: browserConfig: browserConfig.homeBackup != null
) cfg.configList;
2021-11-01 09:20:42 +01:00
in
2024-08-29 03:26:04 +02:00
mapAttrsToList (
name: browserConfig: cleanBrowser name name browserConfig.home browserConfig.homeBackup
) filteredConfigs;
2019-10-24 02:20:38 +02:00
2020-10-12 23:05:15 +02:00
allKillScripts = mapAttrsToList (name: _: killBrowser name) cfg.configList;
2019-10-24 02:20:38 +02:00
# browser chooser
# ---------------
2019-12-20 05:54:26 +01:00
browserSelect = pkgs.writeScriptBin "browser-select" ''
2019-10-24 02:20:38 +02:00
# select a browser using dmenu
# ----------------------------
2024-08-29 03:26:04 +02:00
BROWSER=$( echo -e "${lib.concatMapStringsSep "\\n" (bin: bin.name) browserExecutableList}" \
2019-10-24 02:20:38 +02:00
| ${pkgs.rofi}/bin/rofi -dmenu )
# start selected browser
# ----------------------
case $BROWSER in
2024-08-29 03:26:04 +02:00
${lib.concatStringsSep "\n" (
flip map browserExecutableList (bin: "${bin.name}) export BIN=${bin}/bin/${bin.name} ;;")
)}
*) exit 0 ;;
2019-10-24 02:20:38 +02:00
esac
$BIN "$@"
'';
2021-11-01 09:20:42 +01:00
in
{
2019-10-24 02:20:38 +02:00
2024-03-03 09:59:17 +01:00
options.services.browser = {
2019-10-24 02:20:38 +02:00
enable = mkEnableOption "enable browsers";
2023-07-01 00:20:03 +02:00
# todo : it's not a list
2019-10-24 02:20:38 +02:00
configList = mkOption {
2023-07-01 00:20:03 +02:00
default = { };
2024-08-29 03:26:04 +02:00
type =
with types;
attrsOf (
submodule (
{ name, ... }:
{
options = {
browserType = mkOption {
type =
with types;
enum [
"firefox"
"chrome"
"google"
];
default = "chrome";
description = ''
the type of browser which is simulated
'';
};
home = mkOption {
type = with types; str;
description = ''
Home of the browser.
'';
};
gpu = mkOption {
type = with types; bool;
default = true;
description = ''
add browser user to video group so give browser rights to use gpu.
see : chrome://gpu/
'';
};
user = mkOption {
default = name;
type = with types; str;
description = ''
user to run the browser as
'';
};
sudoUsers = mkOption {
type = with types; listOf str;
description = ''
user allowed to run sudo without password to start the browser
'';
};
homeBackup = mkOption {
type = with types; nullOr str;
default = null;
example = "~/.my-browser-backup";
description = ''
backup of the home, which gets rolled out if the
home does not exists. usefull for homes in tmpfs.
dont use file endings!
'';
};
};
}
)
);
2019-10-24 02:20:38 +02:00
};
};
config = mkIf cfg.enable {
# add sudo rights
2021-11-01 09:20:42 +01:00
security.sudo.extraConfig =
let
2024-08-29 03:26:04 +02:00
extraRules = flip mapAttrsToList cfg.configList (
name: values:
concatStringsSep "" (
map (sudoUser: ''
2021-11-01 09:20:42 +01:00
# sudo configuration to control browser
${sudoUser} ALL=(${values.user}) NOPASSWD: ALL
${sudoUser} ALL=(root) NOPASSWD: /run/current-system/sw/bin/mkdir -p ${values.home}
${sudoUser} ALL=(root) NOPASSWD: /run/current-system/sw/bin/chown -R ${values.user}\:users ${values.home}
${sudoUser} ALL=(root) NOPASSWD: ${pkgs.killall}/bin/killall -9 -u ${name}
2021-11-01 09:20:42 +01:00
${sudoUser} ALL=(root) NOPASSWD: /run/current-system/sw/bin/rm -rf ${values.home}
${sudoUser} ALL=(root) NOPASSWD: /run/current-system/sw/bin/rm -f ${values.home}-lock
2024-08-29 03:26:04 +02:00
'') values.sudoUsers
)
);
2021-11-01 09:20:42 +01:00
in
lib.concatStringsSep "\n" extraRules;
2019-10-24 02:20:38 +02:00
# create users
2024-08-29 03:26:04 +02:00
users.users =
flip mapAttrs cfg.configList (
name: config: {
home = config.home;
createHome = false;
initialPassword = "${name} -browser";
shell = pkgs.bashInteractive;
isNormalUser = false;
isSystemUser = true;
group = "users";
# enable video usage
extraGroups = [
"audio"
"pipewire"
] ++ (if config.gpu then [ "video" ] else [ ]);
}
)
// {
# add groups to mainUser
mainUser.extraGroups = builtins.attrNames cfg.configList;
};
2019-10-24 02:20:38 +02:00
2024-08-29 03:26:04 +02:00
environment.systemPackages =
[
browserSelect
(desktopFile browserSelect)
]
++ browserExecutableList
++ (map (bin: desktopFile bin) browserExecutableList)
++ allBackupScripts
++ allCleanScripts
++ allKillScripts;
2019-10-24 02:20:38 +02:00
};
}