diff --git a/flake.nix b/flake.nix index 6e6b75b..7d82834 100644 --- a/flake.nix +++ b/flake.nix @@ -60,6 +60,7 @@ imports = [ (import path') ]; }) { common = "common.nix"; + tmproot = "tmproot.nix"; server = "server.nix"; }; diff --git a/modules/common.nix b/modules/common.nix index 08b6de7..73468db 100644 --- a/modules/common.nix +++ b/modules/common.nix @@ -12,19 +12,22 @@ defaultUsername = "dev"; uname = config.my.user.name; in { - my.user = rec { - name = mkDefault defaultUsername; - isNormalUser = true; - uid = mkDefault 1000; - extraGroups = mkDefault [ "wheel" ]; - password = mkDefault "hunter2"; # TODO: secrets... + my = { + user = { + name = mkDefault defaultUsername; + isNormalUser = true; + uid = mkDefault 1000; + extraGroups = mkDefault [ "wheel" ]; + password = mkDefault "hunter2"; # TODO: secrets... + }; }; time.timeZone = mkDefault "Europe/Dublin"; - users.mutableUsers = false; - users.users.${uname} = mkAliasDefinitions options.my.user; - users.groups.${uname}.gid = mkDefault config.users.users.${uname}.uid; + users = { + mutableUsers = false; + users.${uname} = mkAliasDefinitions options.my.user; + }; security = { sudo.enable = mkDefault false; @@ -43,11 +46,15 @@ }; environment.systemPackages = with pkgs; [ + bash-completion vim + htop iperf3 ]; - system.stateVersion = "21.11"; - system.configurationRevision = with inputs; mkIf (self ? rev) self.rev; + system = { + stateVersion = "21.11"; + configurationRevision = with inputs; mkIf (self ? rev) self.rev; + }; }; } diff --git a/modules/tmproot.nix b/modules/tmproot.nix new file mode 100644 index 0000000..9574208 --- /dev/null +++ b/modules/tmproot.nix @@ -0,0 +1,61 @@ +{ lib, pkgs, inputs, config, ... }: + let + inherit (lib) concatStringsSep mkIf mkDefault mkAliasDefinitions; + inherit (lib.my) mkOpt mkBoolOpt; + + cfg = config.my.tmproot; + + showUnsaved = + '' + #!${pkgs.python310}/bin/python + import stat + import sys + import os + + ignored = [ + ${concatStringsSep ",\n " (map (p: "'${p}'") cfg.ignoreUnsaved)} + ] + + base = '/' + base_dev = os.stat(base).st_dev + + def recurse(p, link=None): + try: + for ignore in ignored: + if p.startswith(ignore): + return + + st = os.lstat(p) + if st.st_dev != base_dev: + return + + if stat.S_ISLNK(st.st_mode): + target = os.path.realpath(p, strict=False) + if os.access(target, os.F_OK): + recurse(target, link=p) + return + elif stat.S_ISDIR(st.st_mode): + for e in os.listdir(p): + recurse(os.path.join(p, e)) + return + + print(link or p) + except PermissionError as ex: + print(f'{p}: {ex.strerror}', file=sys.stderr) + + recurse(base) + ''; + in { + options.my.tmproot = with lib.types; { + enable = mkBoolOpt true; + ignoreUnsaved = mkOpt (listOf str) [ + "/tmp" + ]; + }; + + config = mkIf cfg.enable { + environment.systemPackages = [ + (pkgs.writeScriptBin "tmproot-unsaved" showUnsaved) + ]; + }; + }