248 lines
6.7 KiB
Nix
248 lines
6.7 KiB
Nix
|
{ config, lib, pkgs, ... }:
|
||
|
|
||
|
# todo : this needs to be cleaned up
|
||
|
|
||
|
with lib;
|
||
|
|
||
|
let
|
||
|
|
||
|
cfg = config.programs.custom.browser;
|
||
|
library = import <library> { inherit pkgs lib; };
|
||
|
|
||
|
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
|
||
|
desktopFile = bin: let
|
||
|
browserName = bin.name;
|
||
|
in pkgs.writeTextFile {
|
||
|
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}
|
||
|
'';
|
||
|
};
|
||
|
|
||
|
cleanBrowser = name: browser: home: homeBackup:
|
||
|
let
|
||
|
backupFile = "${homeBackup}.tar.lzma";
|
||
|
rolloutFile = "${home}.tar.lzma";
|
||
|
lockFile = "${home}-lock";
|
||
|
in
|
||
|
pkgs.writeShellScriptBin "${name}-clean" /* sh */ ''
|
||
|
sudo killall -9 -u ${name}
|
||
|
sudo rm ${lockFile}
|
||
|
sudo rm -rf ${home}
|
||
|
'';
|
||
|
|
||
|
createBrowser = name: user: browser: home: homeBackup:
|
||
|
let
|
||
|
backupFile = "${homeBackup}.tar.lzma";
|
||
|
rolloutFile = "${home}.tar.lzma";
|
||
|
lockFile = "${home}-lock";
|
||
|
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
|
||
|
allBrowser = flip mapAttrsToList cfg.configList (
|
||
|
name: config:
|
||
|
let
|
||
|
browser = if config.browserType == "chrome"
|
||
|
then "${chromiumBin} \"$@\""
|
||
|
else if config.browserType == "google"
|
||
|
then "${chromeBin} \"$@\""
|
||
|
else "${firefoxBin} \"$@\"";
|
||
|
in
|
||
|
createBrowser name config.user browser config.home config.homeBackup
|
||
|
);
|
||
|
xclipBrowser = [
|
||
|
(pkgs.writeShellScriptBin "copy-to-xclip" /* sh */''
|
||
|
echo "$*" | ${pkgs.xclip}/bin/xclip
|
||
|
'')
|
||
|
];
|
||
|
in
|
||
|
allBrowser ++ xclipBrowser;
|
||
|
|
||
|
createBackupScript = name: home: backupHome:
|
||
|
pkgs.writeShellScriptBin "${name}-backup" /* sh */ ''
|
||
|
sudo -u ${name} \
|
||
|
${tarBin} \
|
||
|
--exclude=.cache \
|
||
|
--exclude=Downloads \
|
||
|
--create \
|
||
|
--verbos \
|
||
|
--lzma \
|
||
|
--file ${home}.tar.lzma \
|
||
|
--directory ${home} \
|
||
|
.
|
||
|
|
||
|
cp ${home}.tar.lzma ${backupHome}.tar.lzma
|
||
|
'';
|
||
|
|
||
|
allBackupScripts =
|
||
|
let
|
||
|
filteredConfigs =
|
||
|
filterAttrs
|
||
|
(name: browserConfig: browserConfig.homeBackup != null)
|
||
|
cfg.configList;
|
||
|
in
|
||
|
mapAttrsToList
|
||
|
(name: browserConfig: createBackupScript name browserConfig.home browserConfig.homeBackup)
|
||
|
filteredConfigs;
|
||
|
|
||
|
allCleanScripts =
|
||
|
let
|
||
|
filteredConfigs =
|
||
|
filterAttrs
|
||
|
(name: browserConfig: browserConfig.homeBackup != null)
|
||
|
cfg.configList;
|
||
|
in
|
||
|
mapAttrsToList
|
||
|
(name: browserConfig: cleanBrowser name name browserConfig.home browserConfig.homeBackup)
|
||
|
filteredConfigs;
|
||
|
|
||
|
|
||
|
# browser chooser
|
||
|
# ---------------
|
||
|
browserSelect = pkgs.writeScriptBin "browser-select" ''
|
||
|
# select a browser using dmenu
|
||
|
# ----------------------------
|
||
|
BROWSER=$( echo -e "${lib.concatMapStringsSep "\\n" (bin: bin.name) browserExecutableList}" \
|
||
|
| ${pkgs.rofi}/bin/rofi -dmenu )
|
||
|
|
||
|
# start selected browser
|
||
|
# ----------------------
|
||
|
case $BROWSER in
|
||
|
${lib.concatStringsSep "\n"
|
||
|
(flip map browserExecutableList (bin: "${bin.name}) export BIN=${bin}/bin/${bin.name} ;;"))
|
||
|
}
|
||
|
esac
|
||
|
$BIN "$@"
|
||
|
'';
|
||
|
|
||
|
|
||
|
in {
|
||
|
|
||
|
options.programs.custom.browser = {
|
||
|
enable = mkEnableOption "enable browsers";
|
||
|
configList = mkOption {
|
||
|
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.
|
||
|
'';
|
||
|
};
|
||
|
user = mkOption {
|
||
|
default = name;
|
||
|
type = with types; str;
|
||
|
description = ''
|
||
|
user to run the browser as
|
||
|
'';
|
||
|
};
|
||
|
sudoUsers = mkOption {
|
||
|
default = [ config.users.users.mainUser.name ];
|
||
|
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!
|
||
|
'';
|
||
|
};
|
||
|
};
|
||
|
}));
|
||
|
};
|
||
|
};
|
||
|
|
||
|
config = mkIf cfg.enable {
|
||
|
|
||
|
# add sudo rights
|
||
|
security.sudo.extraConfig =
|
||
|
let
|
||
|
extraRules = flip mapAttrsToList cfg.configList (name: values:
|
||
|
concatStringsSep "\n" (map (sudoUser: "${sudoUser} ALL=(${values.user}) NOPASSWD: ALL") values.sudoUsers)) ;
|
||
|
in
|
||
|
lib.concatStringsSep "\n" extraRules;
|
||
|
|
||
|
# create users
|
||
|
users.users = flip mapAttrs cfg.configList (name: config:
|
||
|
{
|
||
|
home = config.home;
|
||
|
createHome = true;
|
||
|
initialPassword = "${name}-browser";
|
||
|
shell = pkgs.bashInteractive;
|
||
|
isNormalUser = true;
|
||
|
group = "users";
|
||
|
# enable video usage
|
||
|
extraGroups = [ "video" "audio" ];
|
||
|
}
|
||
|
);
|
||
|
|
||
|
# add groups to mainUser
|
||
|
system.custom.mainUser.extraGroups = builtins.attrNames cfg.configList;
|
||
|
|
||
|
environment.systemPackages = [
|
||
|
browserSelect
|
||
|
( desktopFile browserSelect )
|
||
|
]
|
||
|
++ browserExecutableList
|
||
|
++ (map (bin: desktopFile bin) browserExecutableList)
|
||
|
++ allBackupScripts
|
||
|
++ allCleanScripts;
|
||
|
|
||
|
};
|
||
|
}
|