diff --git a/nix/configuration/roles/ssh/default.nix b/nix/configuration/roles/ssh/default.nix index e5ad8ae6..92e01df1 100644 --- a/nix/configuration/roles/ssh/default.nix +++ b/nix/configuration/roles/ssh/default.nix @@ -47,5 +47,9 @@ source = ./files/ssh_config; }; }; + + programs.ssh.extraConfig = '' + Include ${./files/ssh_config_global} + ''; }; } diff --git a/nix/configuration/roles/ssh/files/ssh_config b/nix/configuration/roles/ssh/files/ssh_config index 6b6fa9ff..02178649 100644 --- a/nix/configuration/roles/ssh/files/ssh_config +++ b/nix/configuration/roles/ssh/files/ssh_config @@ -37,6 +37,3 @@ Host hydra Host i_only_boot_zfs HostName 127.0.0.1 Port 60022 - -Host * - Compression yes diff --git a/nix/configuration/roles/ssh/files/ssh_config_global b/nix/configuration/roles/ssh/files/ssh_config_global new file mode 100644 index 00000000..8e582f59 --- /dev/null +++ b/nix/configuration/roles/ssh/files/ssh_config_global @@ -0,0 +1,4 @@ +Host * + Compression yes + ServerAliveInterval 240 + # TCPKeepAlive yes # Default is yes diff --git a/nix/configuration/roles/ssh/files/ssh_config_root b/nix/configuration/roles/ssh/files/ssh_config_root index 0d340b3a..3001f41a 100644 --- a/nix/configuration/roles/ssh/files/ssh_config_root +++ b/nix/configuration/roles/ssh/files/ssh_config_root @@ -4,6 +4,3 @@ Host hydra User nixworker IdentitiesOnly yes IdentityFile /persist/manual/ssh/root/keys/id_ed25519 - -Host * - Compression yes diff --git a/nix/configuration/roles/sshd/default.nix b/nix/configuration/roles/sshd/default.nix index 928a0593..eb3f1bf4 100644 --- a/nix/configuration/roles/sshd/default.nix +++ b/nix/configuration/roles/sshd/default.nix @@ -22,6 +22,9 @@ settings = { PasswordAuthentication = false; KbdInteractiveAuthentication = false; + # ClientAliveInterval = 120; + # ClientAliveCountMax = 3; + # TCPKeepAlive = "yes"; # Default is yes }; hostKeys = [ { diff --git a/nix/configuration/util/install_files/default.nix b/nix/configuration/util/install_files/default.nix index 171e0384..3b5ed856 100644 --- a/nix/configuration/util/install_files/default.nix +++ b/nix/configuration/util/install_files/default.nix @@ -11,7 +11,7 @@ let attrNames ; - get_shell_values = + get_user_shell_values = target: let homedir = config.users.users."${target.username}".home; @@ -25,6 +25,19 @@ let username = lib.strings.escapeShellArg "${target.username}"; group = lib.strings.escapeShellArg "${group}"; }; + get_global_shell_values = + target: + let + group = config.users.users."${target.username}".group; + in + { + source = lib.strings.escapeShellArg "${target.source}"; + destination = lib.strings.escapeShellArg "${target.target}"; + mode = lib.strings.escapeShellArg "${target.mode}"; + dir_mode = lib.strings.escapeShellArg "${target.dir_mode}"; + username = lib.strings.escapeShellArg "${target.username}"; + group = lib.strings.escapeShellArg "${group}"; + }; install_user_file = let constructors = { @@ -33,12 +46,20 @@ let }; in stage: target: (constructors."${target.method}"."${stage}" target); + install_global_file = + let + constructors = { + "overwrite" = install_global_file_overwrite; + "symlink" = install_global_file_symlink; + }; + in + stage: target: (constructors."${target.method}"."${stage}" target); install_user_file_overwrite = { "check" = (target: ""); "install" = ( target: let - inherit (get_shell_values target) + inherit (get_user_shell_values target) source destination mode @@ -79,7 +100,7 @@ let "uninstall" = ( target: let - inherit (get_shell_values target) + inherit (get_user_shell_values target) source destination ; @@ -107,7 +128,7 @@ let "install" = ( target: let - inherit (get_shell_values target) + inherit (get_user_shell_values target) source destination mode @@ -151,7 +172,7 @@ let "uninstall" = ( target: let - inherit (get_shell_values target) + inherit (get_user_shell_values target) source destination ; @@ -174,18 +195,163 @@ let ] ); }; -in -{ - imports = [ ]; + install_global_file_overwrite = { + "check" = (target: ""); + "install" = ( + target: + let + inherit (get_global_shell_values target) + source + destination + mode + dir_mode + username + group + ; + flags = lib.strings.concatStringsSep " " [ + (if mode != "" then "-m ${mode}" else "") + (if username != "" then "-o ${username}" else "") + (if group != "" then "-g ${group}" else "") + ]; + dir_flags = lib.strings.concatStringsSep " " [ + (if dir_mode != "" then "-m ${dir_mode}" else "") + (if username != "" then "-o ${username}" else "") + (if group != "" then "-g ${group}" else "") + ]; + in + if target.recursive then + [ + '' + find ${source} -type f -print0 | while read -r -d "" file; do + relative_path=$(realpath -s --relative-to ${source} "$file") + full_dest=${destination}/"$relative_path" + create_containing_directories "$full_dest" ${dir_flags} + $DRY_RUN_CMD install $VERBOSE_ARG --compare ${flags} "$file" "$full_dest" + done + '' + ] + else + [ + '' + create_containing_directories ${destination} ${dir_flags} + $DRY_RUN_CMD install $VERBOSE_ARG --compare ${flags} ${source} ${destination} + '' + ] + ); + "uninstall" = ( + target: + let + inherit (get_global_shell_values target) + source + destination + ; + in + if target.recursive then + [ + '' + find ${source} -type f -print0 | while read -r -d "" file; do + relative_path=$(realpath -s --relative-to ${source} "$file") + full_dest=${destination}/"$relative_path" + $DRY_RUN_CMD echo rm -f "$full_dest" + done + '' + ] + else + [ + '' + $DRY_RUN_CMD echo rm -f ${destination} + '' + ] + ); + }; + install_global_file_symlink = { + "check" = (target: ""); + "install" = ( + target: + let + inherit (get_global_shell_values target) + source + destination + mode + dir_mode + username + group + ; + owner = lib.strings.concatStringsSep ":" ( + filter (val: val != "") [ + username + group + ] + ); + dir_flags = lib.strings.concatStringsSep " " [ + (if dir_mode != "" then "-m ${dir_mode}" else "") + (if username != "" then "-o ${username}" else "") + (if group != "" then "-g ${group}" else "") + ]; + in + if target.recursive then + [ + '' + find ${source} -type f -print0 | while read -r -d "" file; do + relative_path=$(realpath -s --relative-to ${source} "$file") + full_dest=${destination}/"$relative_path" + create_containing_directories "$full_dest" ${dir_flags} + $DRY_RUN_CMD ln $VERBOSE_ARG -s "$file" "$full_dest" + $DRY_RUN_CMD chown $VERBOSE_ARG -h ${owner} "$full_dest" + done + '' + ] + else + [ + '' + create_containing_directories ${destination} ${dir_flags} + $DRY_RUN_CMD ln $VERBOSE_ARG -s ${source} ${destination} + $DRY_RUN_CMD chown $VERBOSE_ARG -h ${owner} ${destination} + '' + ] + ); + "uninstall" = ( + target: + let + inherit (get_global_shell_values target) + source + destination + ; + in + if target.recursive then + [ + '' + find ${source} -type f -print0 | while read -r -d "" file; do + relative_path=$(realpath -s --relative-to ${source} "$file") + full_dest=${destination}/"$relative_path" + $DRY_RUN_CMD echo rm -f "$full_dest" + done + '' + ] + else + [ + '' + $DRY_RUN_CMD echo rm -f ${destination} + '' + ] + ); + }; + install_target_options = username: { + enable = lib.mkOption { + type = lib.types.bool; + default = true; + defaultText = "enable"; + example = lib.literalExpression false; + description = "Whether we want to install files in this user's home directory."; + }; - options.me.install = { - user = lib.mkOption { + file = lib.mkOption { default = { }; type = lib.types.attrsOf ( lib.types.submodule ( { name, config, ... }: let - username = name; + path = name; in { options = { @@ -194,91 +360,92 @@ in default = true; defaultText = "enable"; example = lib.literalExpression false; - description = "Whether we want to install files in this user's home directory."; + description = "Whether we want to install this file in this user's home directory."; }; - - file = lib.mkOption { - type = lib.types.attrsOf ( - lib.types.submodule ( - { name, config, ... }: - let - path = name; - in - { - options = { - enable = lib.mkOption { - type = lib.types.bool; - default = true; - defaultText = "enable"; - example = lib.literalExpression false; - description = "Whether we want to install this file in this user's home directory."; - }; - username = lib.mkOption { - type = lib.types.str; - defaultText = "username"; - example = "root"; - description = "The username for the user whose home directory will contain the file."; - }; - target = lib.mkOption { - type = lib.types.str; - defaultText = "target"; - example = ".local/share/foo/bar.txt"; - description = "The path where the file should be written."; - }; - method = lib.mkOption { - type = lib.types.enum [ - "symlink" - "overwrite" - # "bind_mount" TODO: for directories? - ]; - default = "symlink"; - defaultText = "me.install.file.‹path›.method"; - example = "overwrite"; - description = "The way in which the file should be installed."; - }; - mode = lib.mkOption { - type = lib.types.str; - default = "0444"; - defaultText = "me.install.file.‹path›.mode"; - example = "0750"; - description = "The read, write, execute permission flags."; - }; - dir_mode = lib.mkOption { - type = lib.types.str; - default = "0755"; - defaultText = "dir_mode"; - example = "0755"; - description = "The read, write, execute permission flags for any parent directories that need to be created."; - }; - source = lib.mkOption { - type = lib.types.path; - defaultText = "me.install.file.‹path›.source"; - example = ./files/foo.txt; - description = "The source file to install into the destination."; - }; - recursive = lib.mkOption { - type = lib.types.bool; - default = false; - defaultText = "recursive"; - example = lib.literalExpression false; - description = "Whether we want to recurse through the directory doing individual installs for each file."; - }; - }; - - config = { - username = lib.mkDefault username; - target = lib.mkDefault path; - }; - } - ) - ); + username = lib.mkOption { + type = lib.types.str; + defaultText = "username"; + example = "root"; + description = "The username for the user whose home directory will contain the file."; }; + target = lib.mkOption { + type = lib.types.str; + defaultText = "target"; + example = ".local/share/foo/bar.txt"; + description = "The path where the file should be written."; + }; + method = lib.mkOption { + type = lib.types.enum [ + "symlink" + "overwrite" + # "bind_mount" TODO: for directories? + ]; + default = "symlink"; + defaultText = "me.install.file.‹path›.method"; + example = "overwrite"; + description = "The way in which the file should be installed."; + }; + mode = lib.mkOption { + type = lib.types.str; + default = "0444"; + defaultText = "me.install.file.‹path›.mode"; + example = "0750"; + description = "The read, write, execute permission flags."; + }; + dir_mode = lib.mkOption { + type = lib.types.str; + default = "0755"; + defaultText = "dir_mode"; + example = "0755"; + description = "The read, write, execute permission flags for any parent directories that need to be created."; + }; + source = lib.mkOption { + type = lib.types.path; + defaultText = "me.install.file.‹path›.source"; + example = ./files/foo.txt; + description = "The source file to install into the destination."; + }; + recursive = lib.mkOption { + type = lib.types.bool; + default = false; + defaultText = "recursive"; + example = lib.literalExpression false; + description = "Whether we want to recurse through the directory doing individual installs for each file."; + }; + }; + + config = { + username = lib.mkDefault username; + target = lib.mkDefault path; }; } ) ); }; }; +in +{ + imports = [ ]; + + options.me.install = ( + { + user = lib.mkOption { + default = { }; + type = lib.types.attrsOf ( + lib.types.submodule ( + { name, config, ... }: + let + username = name; + in + { + options = (install_target_options username); + } + ) + ); + }; + } + // (install_target_options "root") + ); config = let @@ -288,11 +455,17 @@ in builtins.map (user: (builtins.map (path: user.file."${path}") (attrNames user.file))) enabled_users ); enabled_file_targets = filter (target: target.enable) all_file_targets; - check_commands = lib.flatten (builtins.map (install_user_file "check") enabled_file_targets); - install_commands = lib.flatten (builtins.map (install_user_file "install") enabled_file_targets); - uninstall_commands = lib.flatten ( - builtins.map (install_user_file "uninstall") enabled_file_targets - ); + all_global_file_targets = (builtins.map (path: cfg.file."${path}") (attrNames cfg.file)); + enabled_global_file_targets = filter (target: target.enable) all_global_file_targets; + check_commands = + (lib.flatten (builtins.map (install_global_file "check") enabled_global_file_targets)) + ++ (lib.flatten (builtins.map (install_user_file "check") enabled_file_targets)); + install_commands = + (lib.flatten (builtins.map (install_global_file "install") enabled_global_file_targets)) + ++ (lib.flatten (builtins.map (install_user_file "install") enabled_file_targets)); + uninstall_commands = + (lib.flatten (builtins.map (install_global_file "uninstall") enabled_global_file_targets)) + ++ (lib.flatten (builtins.map (install_user_file "uninstall") enabled_file_targets)); in { systemd.services.me-install-file = {