From 8eebaf8cee812bd07d8d890040e403bacb1777fb Mon Sep 17 00:00:00 2001 From: Franck Cuny Date: Mon, 3 Nov 2025 07:23:57 -0800 Subject: consolidate all modules under modules/ --- modules/backups.nix | 210 +++++++++++++++++++++++++++++++++++++++++ modules/common/default.nix | 8 -- modules/common/home.nix | 38 -------- modules/common/host-config.nix | 15 --- modules/common/ssh.nix | 7 -- modules/default-darwin.nix | 8 ++ modules/default.nix | 12 +++ modules/home-manager.nix | 12 +++ modules/home.nix | 38 ++++++++ modules/host-config.nix | 15 +++ modules/nas-client.nix | 84 +++++++++++++++++ modules/nixos/backups.nix | 210 ----------------------------------------- modules/nixos/default.nix | 9 -- modules/nixos/home-manager.nix | 12 --- modules/nixos/nas-client.nix | 84 ----------------- modules/nixos/user.nix | 24 ----- modules/ssh.nix | 7 ++ modules/user.nix | 24 +++++ 18 files changed, 410 insertions(+), 407 deletions(-) create mode 100644 modules/backups.nix delete mode 100644 modules/common/default.nix delete mode 100644 modules/common/home.nix delete mode 100644 modules/common/host-config.nix delete mode 100644 modules/common/ssh.nix create mode 100644 modules/default-darwin.nix create mode 100644 modules/default.nix create mode 100644 modules/home-manager.nix create mode 100644 modules/home.nix create mode 100644 modules/host-config.nix create mode 100644 modules/nas-client.nix delete mode 100644 modules/nixos/backups.nix delete mode 100644 modules/nixos/default.nix delete mode 100644 modules/nixos/home-manager.nix delete mode 100644 modules/nixos/nas-client.nix delete mode 100644 modules/nixos/user.nix create mode 100644 modules/ssh.nix create mode 100644 modules/user.nix (limited to 'modules') diff --git a/modules/backups.nix b/modules/backups.nix new file mode 100644 index 0000000..78b3144 --- /dev/null +++ b/modules/backups.nix @@ -0,0 +1,210 @@ +# Some examples for how to use this module +# +# Host with media files - backup /media only locally +# my.modules.backups = { +# enable = true; +# passwordFile = config.age.secrets.restic_password.path +# local.paths = [ "/media" "/home" "/var/lib/important" ]; +# remote.paths = [ "/home" "/var/lib/important" ]; # Excludes /media +# }; +# +# Another example - different exclusions for local vs remote +# my.modules.backups = { +# enable = true; +# passwordFile = config.age.secrets.restic_password.path +# local.paths = [ "/home" "/var/cache/downloads" ]; +# local.exclude = [ "*.tmp" ]; +# remote.paths = [ "/home" ]; # Skip cache directory for remote +# remote.exclude = [ "*.tmp" "*.log" ]; # More aggressive exclusions for remote +# }; +{ + pkgs, + config, + lib, + ... +}: +let + cfg = config.my.modules.backups; + + # Helper scripts for easy backup access + restic-local = pkgs.writeShellScriptBin "restic-local" '' + export RESTIC_REPOSITORY="${cfg.localBasePath}/${config.networking.hostName}" + export RESTIC_PASSWORD_FILE="${cfg.passwordFile}" + exec ${pkgs.restic}/bin/restic "$@" + ''; + + restic-remote = pkgs.writeShellScriptBin "restic-remote" '' + export RESTIC_REPOSITORY="${cfg.remoteBaseRepository}:/${config.networking.hostName}/" + export RESTIC_PASSWORD_FILE="${cfg.passwordFile}" + ${lib.optionalString (cfg.remote.environmentFile != null) '' + source ${cfg.remote.environmentFile} + ''} + exec ${pkgs.restic}/bin/restic "$@" + ''; + + # Common backup options shared between local and remote + backupOptions = { + paths = lib.mkOption { + type = lib.types.listOf lib.types.str; + default = [ ]; + description = "Paths to backup"; + example = [ + "/home" + "/var/lib/important-data" + ]; + }; + + exclude = lib.mkOption { + type = lib.types.listOf lib.types.str; + default = [ ]; + description = "Paths to exclude from backup"; + example = [ + "*.tmp" + "/var/cache" + ]; + }; + + extraBackupArgs = lib.mkOption { + type = lib.types.listOf lib.types.str; + default = [ + "--exclude-caches" + "--compression=max" + ]; + description = "Additional arguments to pass to restic backup"; + }; + + pruneOpts = lib.mkOption { + type = lib.types.listOf lib.types.str; + default = [ + "--keep-daily 7" + "--keep-weekly 4" + "--keep-monthly 3" + ]; + description = "Pruning options for old backups"; + }; + + timerConfig = lib.mkOption { + type = lib.types.attrs; + default = { + OnCalendar = "daily"; + RandomizedDelaySec = "5m"; + }; + description = "Systemd timer configuration"; + }; + }; +in +{ + options.my.modules.backups = { + enable = lib.mkEnableOption "backups"; + + passwordFile = lib.mkOption { + type = lib.types.str; + default = config.age.secrets.restic_password.path; + description = "Path to file containing restic repository password"; + example = "/run/secrets/restic-password"; + }; + + localBasePath = lib.mkOption { + type = lib.types.str; + default = "/data/backups"; + description = "Base path for local backup repositories"; + example = "/mnt/backup-drive/backups"; + }; + + remoteBaseRepository = lib.mkOption { + type = lib.types.str; + default = "gs:fcuny-infra-backups"; + description = "Base repository URL for remote backups"; + example = "s3:my-backup-bucket"; + }; + + local = backupOptions; + + remote = backupOptions // { + timerConfig = lib.mkOption { + type = lib.types.attrs; + default = { + OnCalendar = "daily"; + # No randomized delay for remote to avoid overlap with local + }; + description = "Systemd timer configuration for remote backups"; + }; + + googleProjectId = lib.mkOption { + type = lib.types.nullOr lib.types.str; + default = "fcuny-infra"; + description = "Google Cloud project ID for GCS backups"; + example = "my-backup-project"; + }; + + googleCredentialsFile = lib.mkOption { + type = lib.types.nullOr lib.types.str; + default = config.age.secrets.restic_gcs_credentials.path; + description = "Path to Google Cloud service account credentials file"; + example = "/run/secrets/gcs-credentials"; + }; + + environmentFile = lib.mkOption { + type = lib.types.nullOr lib.types.path; + default = + if cfg.remote.googleProjectId != null && cfg.remote.googleCredentialsFile != null then + pkgs.writeText "restic-gcs-env" '' + GOOGLE_PROJECT_ID=${cfg.remote.googleProjectId} + GOOGLE_APPLICATION_CREDENTIALS=${cfg.remote.googleCredentialsFile} + '' + else + null; + description = "Environment file for remote backup authentication"; + }; + }; + + helpers = lib.mkOption { + type = lib.types.bool; + default = true; + description = "Install helper scripts (restic-local, restic-remote)"; + }; + }; + + config = lib.mkIf cfg.enable { + environment.systemPackages = [ + pkgs.restic + ] + ++ lib.optionals cfg.helpers [ + restic-local + restic-remote + ]; + + services.restic.backups = lib.mkMerge [ + # Local backup configuration - only if paths are specified + (lib.mkIf (cfg.local.paths != [ ]) { + local = { + initialize = true; + repository = "${cfg.localBasePath}/${config.networking.hostName}"; + passwordFile = cfg.passwordFile; + paths = cfg.local.paths; + exclude = cfg.local.exclude; + extraBackupArgs = cfg.local.extraBackupArgs; + timerConfig = cfg.local.timerConfig; + pruneOpts = cfg.local.pruneOpts; + }; + }) + + # Remote backup configuration - only if paths are specified + (lib.mkIf (cfg.remote.paths != [ ]) { + remote = { + initialize = true; + repository = "${cfg.remoteBaseRepository}:/${config.networking.hostName}/"; + passwordFile = cfg.passwordFile; + paths = cfg.remote.paths; + exclude = cfg.remote.exclude; + extraBackupArgs = cfg.remote.extraBackupArgs; + timerConfig = cfg.remote.timerConfig; + pruneOpts = cfg.remote.pruneOpts; + } + // lib.optionalAttrs (cfg.remote.environmentFile != null) { + environmentFile = toString cfg.remote.environmentFile; + }; + }) + ]; + }; +} diff --git a/modules/common/default.nix b/modules/common/default.nix deleted file mode 100644 index 5984f10..0000000 --- a/modules/common/default.nix +++ /dev/null @@ -1,8 +0,0 @@ -{ ... }: -{ - imports = [ - ./home.nix - ./host-config.nix - ./ssh.nix - ]; -} diff --git a/modules/common/home.nix b/modules/common/home.nix deleted file mode 100644 index 6b6b518..0000000 --- a/modules/common/home.nix +++ /dev/null @@ -1,38 +0,0 @@ -{ - userProfiles, - lib, - ... -}: -let - inherit (lib) mkOption; - inherit (lib.types) - submodule - listOf - attrsOf - str - ; -in -{ - options = { - home = mkOption { - type = attrsOf ( - submodule ( - { name, ... }: - { - options = { - name = mkOption { - type = str; - default = name; - }; - profiles = mkOption { - type = listOf str; - apply = map (v: userProfiles.${v}); - }; - }; - } - ) - ); - default = { }; - }; - }; -} diff --git a/modules/common/host-config.nix b/modules/common/host-config.nix deleted file mode 100644 index b10d85f..0000000 --- a/modules/common/host-config.nix +++ /dev/null @@ -1,15 +0,0 @@ -{ lib, ... }: -let - inherit (lib) mkOption; - inherit (lib.types) - attrs - ; -in -{ - options = { - adminUser = mkOption { - type = attrs; - default = { }; - }; - }; -} diff --git a/modules/common/ssh.nix b/modules/common/ssh.nix deleted file mode 100644 index 3e975ee..0000000 --- a/modules/common/ssh.nix +++ /dev/null @@ -1,7 +0,0 @@ -{ ... }: -{ - programs.ssh.knownHosts = { - "github.com".publicKey = - "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOMqqnkVzrm0SdG6UOoqKLsabgH5C9okWi0dh2l9GKJl"; - }; -} diff --git a/modules/default-darwin.nix b/modules/default-darwin.nix new file mode 100644 index 0000000..5984f10 --- /dev/null +++ b/modules/default-darwin.nix @@ -0,0 +1,8 @@ +{ ... }: +{ + imports = [ + ./home.nix + ./host-config.nix + ./ssh.nix + ]; +} diff --git a/modules/default.nix b/modules/default.nix new file mode 100644 index 0000000..0671724 --- /dev/null +++ b/modules/default.nix @@ -0,0 +1,12 @@ +{ ... }: +{ + imports = [ + ./backups.nix + ./home-manager.nix + ./home.nix + ./host-config.nix + ./nas-client.nix + ./ssh.nix + ./user.nix + ]; +} diff --git a/modules/home-manager.nix b/modules/home-manager.nix new file mode 100644 index 0000000..7a9ae43 --- /dev/null +++ b/modules/home-manager.nix @@ -0,0 +1,12 @@ +{ + adminUser, + ... +}: +{ + home-manager = { + users.${adminUser.name} = { + home.username = "${adminUser.name}"; + inherit (adminUser) userinfo; + }; + }; +} diff --git a/modules/home.nix b/modules/home.nix new file mode 100644 index 0000000..6b6b518 --- /dev/null +++ b/modules/home.nix @@ -0,0 +1,38 @@ +{ + userProfiles, + lib, + ... +}: +let + inherit (lib) mkOption; + inherit (lib.types) + submodule + listOf + attrsOf + str + ; +in +{ + options = { + home = mkOption { + type = attrsOf ( + submodule ( + { name, ... }: + { + options = { + name = mkOption { + type = str; + default = name; + }; + profiles = mkOption { + type = listOf str; + apply = map (v: userProfiles.${v}); + }; + }; + } + ) + ); + default = { }; + }; + }; +} diff --git a/modules/host-config.nix b/modules/host-config.nix new file mode 100644 index 0000000..b10d85f --- /dev/null +++ b/modules/host-config.nix @@ -0,0 +1,15 @@ +{ lib, ... }: +let + inherit (lib) mkOption; + inherit (lib.types) + attrs + ; +in +{ + options = { + adminUser = mkOption { + type = attrs; + default = { }; + }; + }; +} diff --git a/modules/nas-client.nix b/modules/nas-client.nix new file mode 100644 index 0000000..fe0952e --- /dev/null +++ b/modules/nas-client.nix @@ -0,0 +1,84 @@ +{ + config, + lib, + pkgs, + ... +}: + +let + cfg = config.my.modules.nas-client; +in +{ + options.my.modules.nas-client = with lib; { + enable = mkEnableOption "NAS client"; + + volumes = mkOption { + type = types.attrsOf ( + types.submodule { + options = { + server = mkOption { + type = types.str; + example = "nas"; + description = "Hostname of the server to connect to."; + }; + remotePath = mkOption { + type = types.str; + example = "data"; + description = "Remote path on the NAS to mount."; + }; + mountPoint = mkOption { + type = types.str; + description = "Local directory where the volume will be mounted."; + }; + uid = mkOption { + type = types.int; + default = 1000; + description = "User ID for mounted files."; + }; + gid = mkOption { + type = types.int; + default = 1000; + description = "Group ID for mounted files."; + }; + options = mkOption { + type = types.str; + default = "rw"; + description = "Additional mount options."; + }; + }; + } + ); + default = { }; + description = "NAS volumes to mount."; + }; + }; + + config = lib.mkIf cfg.enable { + boot.kernelModules = [ + "cifs" + "cmac" + "sha256" + ]; + + # this is required to get the credentials options to work + environment.systemPackages = [ pkgs.cifs-utils ]; + + systemd.mounts = lib.mapAttrsToList (name: volume: { + description = "Mount for NAS volume ${name}"; + what = "//${volume.server}/${volume.remotePath}"; + where = volume.mountPoint; + unitConfig = { + # This ensures it uses mount.cifs + Type = "cifs"; + }; + type = "cifs"; # Explicitly specify CIFS type otherwise we ran into issues when using the credentials file option + options = "credentials=${config.age.secrets.nas_client_credentials.path},uid=${toString volume.uid},gid=${toString volume.gid},${volume.options}"; + }) cfg.volumes; + + systemd.automounts = lib.mapAttrsToList (name: volume: { + description = "Automount for NAS volume ${name}"; + where = volume.mountPoint; + wantedBy = [ "multi-user.target" ]; + }) cfg.volumes; + }; +} diff --git a/modules/nixos/backups.nix b/modules/nixos/backups.nix deleted file mode 100644 index 78b3144..0000000 --- a/modules/nixos/backups.nix +++ /dev/null @@ -1,210 +0,0 @@ -# Some examples for how to use this module -# -# Host with media files - backup /media only locally -# my.modules.backups = { -# enable = true; -# passwordFile = config.age.secrets.restic_password.path -# local.paths = [ "/media" "/home" "/var/lib/important" ]; -# remote.paths = [ "/home" "/var/lib/important" ]; # Excludes /media -# }; -# -# Another example - different exclusions for local vs remote -# my.modules.backups = { -# enable = true; -# passwordFile = config.age.secrets.restic_password.path -# local.paths = [ "/home" "/var/cache/downloads" ]; -# local.exclude = [ "*.tmp" ]; -# remote.paths = [ "/home" ]; # Skip cache directory for remote -# remote.exclude = [ "*.tmp" "*.log" ]; # More aggressive exclusions for remote -# }; -{ - pkgs, - config, - lib, - ... -}: -let - cfg = config.my.modules.backups; - - # Helper scripts for easy backup access - restic-local = pkgs.writeShellScriptBin "restic-local" '' - export RESTIC_REPOSITORY="${cfg.localBasePath}/${config.networking.hostName}" - export RESTIC_PASSWORD_FILE="${cfg.passwordFile}" - exec ${pkgs.restic}/bin/restic "$@" - ''; - - restic-remote = pkgs.writeShellScriptBin "restic-remote" '' - export RESTIC_REPOSITORY="${cfg.remoteBaseRepository}:/${config.networking.hostName}/" - export RESTIC_PASSWORD_FILE="${cfg.passwordFile}" - ${lib.optionalString (cfg.remote.environmentFile != null) '' - source ${cfg.remote.environmentFile} - ''} - exec ${pkgs.restic}/bin/restic "$@" - ''; - - # Common backup options shared between local and remote - backupOptions = { - paths = lib.mkOption { - type = lib.types.listOf lib.types.str; - default = [ ]; - description = "Paths to backup"; - example = [ - "/home" - "/var/lib/important-data" - ]; - }; - - exclude = lib.mkOption { - type = lib.types.listOf lib.types.str; - default = [ ]; - description = "Paths to exclude from backup"; - example = [ - "*.tmp" - "/var/cache" - ]; - }; - - extraBackupArgs = lib.mkOption { - type = lib.types.listOf lib.types.str; - default = [ - "--exclude-caches" - "--compression=max" - ]; - description = "Additional arguments to pass to restic backup"; - }; - - pruneOpts = lib.mkOption { - type = lib.types.listOf lib.types.str; - default = [ - "--keep-daily 7" - "--keep-weekly 4" - "--keep-monthly 3" - ]; - description = "Pruning options for old backups"; - }; - - timerConfig = lib.mkOption { - type = lib.types.attrs; - default = { - OnCalendar = "daily"; - RandomizedDelaySec = "5m"; - }; - description = "Systemd timer configuration"; - }; - }; -in -{ - options.my.modules.backups = { - enable = lib.mkEnableOption "backups"; - - passwordFile = lib.mkOption { - type = lib.types.str; - default = config.age.secrets.restic_password.path; - description = "Path to file containing restic repository password"; - example = "/run/secrets/restic-password"; - }; - - localBasePath = lib.mkOption { - type = lib.types.str; - default = "/data/backups"; - description = "Base path for local backup repositories"; - example = "/mnt/backup-drive/backups"; - }; - - remoteBaseRepository = lib.mkOption { - type = lib.types.str; - default = "gs:fcuny-infra-backups"; - description = "Base repository URL for remote backups"; - example = "s3:my-backup-bucket"; - }; - - local = backupOptions; - - remote = backupOptions // { - timerConfig = lib.mkOption { - type = lib.types.attrs; - default = { - OnCalendar = "daily"; - # No randomized delay for remote to avoid overlap with local - }; - description = "Systemd timer configuration for remote backups"; - }; - - googleProjectId = lib.mkOption { - type = lib.types.nullOr lib.types.str; - default = "fcuny-infra"; - description = "Google Cloud project ID for GCS backups"; - example = "my-backup-project"; - }; - - googleCredentialsFile = lib.mkOption { - type = lib.types.nullOr lib.types.str; - default = config.age.secrets.restic_gcs_credentials.path; - description = "Path to Google Cloud service account credentials file"; - example = "/run/secrets/gcs-credentials"; - }; - - environmentFile = lib.mkOption { - type = lib.types.nullOr lib.types.path; - default = - if cfg.remote.googleProjectId != null && cfg.remote.googleCredentialsFile != null then - pkgs.writeText "restic-gcs-env" '' - GOOGLE_PROJECT_ID=${cfg.remote.googleProjectId} - GOOGLE_APPLICATION_CREDENTIALS=${cfg.remote.googleCredentialsFile} - '' - else - null; - description = "Environment file for remote backup authentication"; - }; - }; - - helpers = lib.mkOption { - type = lib.types.bool; - default = true; - description = "Install helper scripts (restic-local, restic-remote)"; - }; - }; - - config = lib.mkIf cfg.enable { - environment.systemPackages = [ - pkgs.restic - ] - ++ lib.optionals cfg.helpers [ - restic-local - restic-remote - ]; - - services.restic.backups = lib.mkMerge [ - # Local backup configuration - only if paths are specified - (lib.mkIf (cfg.local.paths != [ ]) { - local = { - initialize = true; - repository = "${cfg.localBasePath}/${config.networking.hostName}"; - passwordFile = cfg.passwordFile; - paths = cfg.local.paths; - exclude = cfg.local.exclude; - extraBackupArgs = cfg.local.extraBackupArgs; - timerConfig = cfg.local.timerConfig; - pruneOpts = cfg.local.pruneOpts; - }; - }) - - # Remote backup configuration - only if paths are specified - (lib.mkIf (cfg.remote.paths != [ ]) { - remote = { - initialize = true; - repository = "${cfg.remoteBaseRepository}:/${config.networking.hostName}/"; - passwordFile = cfg.passwordFile; - paths = cfg.remote.paths; - exclude = cfg.remote.exclude; - extraBackupArgs = cfg.remote.extraBackupArgs; - timerConfig = cfg.remote.timerConfig; - pruneOpts = cfg.remote.pruneOpts; - } - // lib.optionalAttrs (cfg.remote.environmentFile != null) { - environmentFile = toString cfg.remote.environmentFile; - }; - }) - ]; - }; -} diff --git a/modules/nixos/default.nix b/modules/nixos/default.nix deleted file mode 100644 index 21f6d26..0000000 --- a/modules/nixos/default.nix +++ /dev/null @@ -1,9 +0,0 @@ -{ ... }: -{ - imports = [ - ./backups.nix - ./home-manager.nix - ./nas-client.nix - ./user.nix - ]; -} diff --git a/modules/nixos/home-manager.nix b/modules/nixos/home-manager.nix deleted file mode 100644 index 7a9ae43..0000000 --- a/modules/nixos/home-manager.nix +++ /dev/null @@ -1,12 +0,0 @@ -{ - adminUser, - ... -}: -{ - home-manager = { - users.${adminUser.name} = { - home.username = "${adminUser.name}"; - inherit (adminUser) userinfo; - }; - }; -} diff --git a/modules/nixos/nas-client.nix b/modules/nixos/nas-client.nix deleted file mode 100644 index fe0952e..0000000 --- a/modules/nixos/nas-client.nix +++ /dev/null @@ -1,84 +0,0 @@ -{ - config, - lib, - pkgs, - ... -}: - -let - cfg = config.my.modules.nas-client; -in -{ - options.my.modules.nas-client = with lib; { - enable = mkEnableOption "NAS client"; - - volumes = mkOption { - type = types.attrsOf ( - types.submodule { - options = { - server = mkOption { - type = types.str; - example = "nas"; - description = "Hostname of the server to connect to."; - }; - remotePath = mkOption { - type = types.str; - example = "data"; - description = "Remote path on the NAS to mount."; - }; - mountPoint = mkOption { - type = types.str; - description = "Local directory where the volume will be mounted."; - }; - uid = mkOption { - type = types.int; - default = 1000; - description = "User ID for mounted files."; - }; - gid = mkOption { - type = types.int; - default = 1000; - description = "Group ID for mounted files."; - }; - options = mkOption { - type = types.str; - default = "rw"; - description = "Additional mount options."; - }; - }; - } - ); - default = { }; - description = "NAS volumes to mount."; - }; - }; - - config = lib.mkIf cfg.enable { - boot.kernelModules = [ - "cifs" - "cmac" - "sha256" - ]; - - # this is required to get the credentials options to work - environment.systemPackages = [ pkgs.cifs-utils ]; - - systemd.mounts = lib.mapAttrsToList (name: volume: { - description = "Mount for NAS volume ${name}"; - what = "//${volume.server}/${volume.remotePath}"; - where = volume.mountPoint; - unitConfig = { - # This ensures it uses mount.cifs - Type = "cifs"; - }; - type = "cifs"; # Explicitly specify CIFS type otherwise we ran into issues when using the credentials file option - options = "credentials=${config.age.secrets.nas_client_credentials.path},uid=${toString volume.uid},gid=${toString volume.gid},${volume.options}"; - }) cfg.volumes; - - systemd.automounts = lib.mapAttrsToList (name: volume: { - description = "Automount for NAS volume ${name}"; - where = volume.mountPoint; - wantedBy = [ "multi-user.target" ]; - }) cfg.volumes; - }; -} diff --git a/modules/nixos/user.nix b/modules/nixos/user.nix deleted file mode 100644 index 8a9dafb..0000000 --- a/modules/nixos/user.nix +++ /dev/null @@ -1,24 +0,0 @@ -{ - adminUser, - pkgs, - ... -}: -{ - nix.settings.trusted-users = [ adminUser.name ]; - users = { - users.${adminUser.name} = { - inherit (adminUser) uid; - shell = pkgs.fish; - isNormalUser = true; - hashedPassword = "$6$Llw8m62nKMLLN9mm$3.a4CKUFlqwkG8vjBryLlBNwTwgH63vpg2nhYwRoQzG76Q91vTXnlYDujS4G5yGrWoatkKZx5epCx4/NAvRh2/"; - openssh.authorizedKeys.keys = [ - "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINBkozy+X96u5ciX766bJ/AyQ3xm1tXZTIr5+4PVFZFi" - ]; - extraGroups = [ - "wheel" - ]; - }; - }; - - programs.fish.enable = true; -} diff --git a/modules/ssh.nix b/modules/ssh.nix new file mode 100644 index 0000000..3e975ee --- /dev/null +++ b/modules/ssh.nix @@ -0,0 +1,7 @@ +{ ... }: +{ + programs.ssh.knownHosts = { + "github.com".publicKey = + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOMqqnkVzrm0SdG6UOoqKLsabgH5C9okWi0dh2l9GKJl"; + }; +} diff --git a/modules/user.nix b/modules/user.nix new file mode 100644 index 0000000..8a9dafb --- /dev/null +++ b/modules/user.nix @@ -0,0 +1,24 @@ +{ + adminUser, + pkgs, + ... +}: +{ + nix.settings.trusted-users = [ adminUser.name ]; + users = { + users.${adminUser.name} = { + inherit (adminUser) uid; + shell = pkgs.fish; + isNormalUser = true; + hashedPassword = "$6$Llw8m62nKMLLN9mm$3.a4CKUFlqwkG8vjBryLlBNwTwgH63vpg2nhYwRoQzG76Q91vTXnlYDujS4G5yGrWoatkKZx5epCx4/NAvRh2/"; + openssh.authorizedKeys.keys = [ + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINBkozy+X96u5ciX766bJ/AyQ3xm1tXZTIr5+4PVFZFi" + ]; + extraGroups = [ + "wheel" + ]; + }; + }; + + programs.fish.enable = true; +} -- cgit v1.2.3