diff --git a/nix/configuration/configuration.nix b/nix/configuration/configuration.nix index bf55f68..383b40d 100644 --- a/nix/configuration/configuration.nix +++ b/nix/configuration/configuration.nix @@ -2,7 +2,6 @@ config, lib, pkgs, - home-manager, ... }: @@ -74,6 +73,7 @@ ./roles/zfs ./roles/zrepl ./roles/zsh + ./util/install_files ./util/unfree_polyfill ]; @@ -122,21 +122,6 @@ ]; }; users.groups.talexander.gid = 11235; - home-manager.users.talexander = - { pkgs, ... }: - { - # The state version is required and should stay at the version you - # originally installed. - home.stateVersion = "24.11"; - }; - - home-manager.users.root = - { pkgs, ... }: - { - # The state version is required and should stay at the version you - # originally installed. - home.stateVersion = "24.11"; - }; # Automatic garbage collection nix.gc = lib.mkIf (!config.me.buildingIso) { diff --git a/nix/configuration/flake.lock b/nix/configuration/flake.lock index a5eaabe..455a82b 100644 --- a/nix/configuration/flake.lock +++ b/nix/configuration/flake.lock @@ -147,26 +147,6 @@ "type": "github" } }, - "home-manager": { - "inputs": { - "nixpkgs": [ - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1751549056, - "narHash": "sha256-miKaJ4SFNxhZ/WVDADae2jNd9zka5bV9hKmXspAzvxo=", - "owner": "nix-community", - "repo": "home-manager", - "rev": "1fa73bb2cc39e250eb01e511ae6ac83bfbf9f38c", - "type": "github" - }, - "original": { - "owner": "nix-community", - "repo": "home-manager", - "type": "github" - } - }, "impermanence": { "locked": { "lastModified": 1737831083, @@ -303,7 +283,6 @@ "inputs": { "ansible-sshjail": "ansible-sshjail", "disko": "disko", - "home-manager": "home-manager", "impermanence": "impermanence", "lanzaboote": "lanzaboote", "nixpkgs": "nixpkgs", diff --git a/nix/configuration/flake.nix b/nix/configuration/flake.nix index dec37cf..54b2c84 100644 --- a/nix/configuration/flake.nix +++ b/nix/configuration/flake.nix @@ -45,8 +45,6 @@ nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; nixpkgs-dda3dcd3f.url = "github:NixOS/nixpkgs/dda3dcd3fe03e991015e9a74b22d35950f264a54"; nixpkgs-unoptimized.url = "github:NixOS/nixpkgs/nixos-unstable"; - home-manager.url = "github:nix-community/home-manager"; - home-manager.inputs.nixpkgs.follows = "nixpkgs"; lanzaboote = { url = "github:nix-community/lanzaboote/v0.4.2"; @@ -78,7 +76,6 @@ nixpkgs-unoptimized, nixpkgs-dda3dcd3f, impermanence, - home-manager, lanzaboote, zsh-histdb, ansible-sshjail, @@ -99,13 +96,8 @@ }; modules = [ impermanence.nixosModules.impermanence - home-manager.nixosModules.home-manager lanzaboote.nixosModules.lanzaboote inputs.disko.nixosModules.disko - { - home-manager.useGlobalPkgs = true; - home-manager.useUserPackages = true; - } { nixpkgs.overlays = [ zsh-histdb.overlays.default diff --git a/nix/configuration/roles/alacritty/default.nix b/nix/configuration/roles/alacritty/default.nix index e691ad8..e6e85f7 100644 --- a/nix/configuration/roles/alacritty/default.nix +++ b/nix/configuration/roles/alacritty/default.nix @@ -24,13 +24,11 @@ xdg-utils # for xdg-open ]; - home-manager.users.talexander = - { pkgs, ... }: - { - home.file.".config/alacritty/alacritty.toml" = { - source = ./files/alacritty.toml; - }; + me.install.user.talexander.file = { + ".config/alacritty/alacritty.toml" = { + source = ./files/alacritty.toml; }; + }; }) ] ); diff --git a/nix/configuration/roles/emacs/default.nix b/nix/configuration/roles/emacs/default.nix index 4fd70ee..8689db6 100644 --- a/nix/configuration/roles/emacs/default.nix +++ b/nix/configuration/roles/emacs/default.nix @@ -141,14 +141,12 @@ in }) ]; - home-manager.users.talexander = - { pkgs, ... }: - { - home.file.".config/emacs" = { - source = ./files/emacs; - recursive = true; - }; + me.install.user.talexander.file = { + ".config/emacs" = { + source = ./files/emacs; + recursive = true; }; + }; }) (lib.mkIf (config.me.emacs_flavor == "plainmacs") { nixpkgs.overlays = [ diff --git a/nix/configuration/roles/git/default.nix b/nix/configuration/roles/git/default.nix index 5f0e57d..db65e52 100644 --- a/nix/configuration/roles/git/default.nix +++ b/nix/configuration/roles/git/default.nix @@ -36,13 +36,11 @@ in ]; } (lib.mkIf (config.me.git.config != null) { - home-manager.users.talexander = - { pkgs, ... }: - { - home.file.".gitconfig" = { - source = config.me.git.config; - }; + me.install.user.talexander.file = { + ".gitconfig" = { + source = config.me.git.config; }; + }; }) (lib.mkIf (config.me.graphical) { nixpkgs.overlays = [ diff --git a/nix/configuration/roles/gpg/default.nix b/nix/configuration/roles/gpg/default.nix index cb8b4b2..eeab4d3 100644 --- a/nix/configuration/roles/gpg/default.nix +++ b/nix/configuration/roles/gpg/default.nix @@ -57,14 +57,11 @@ in # disable-ccid = true; # }; - # .gnupg/scdaemon.conf - home-manager.users.talexander = - { pkgs, ... }: - { - home.file.".gnupg/scdaemon.conf" = { - source = ./files/scdaemon.conf; - }; + me.install.user.talexander.file = { + ".gnupg/scdaemon.conf" = { + source = ./files/scdaemon.conf; }; + }; # programs.gnupg.dirmngr.enable = true; programs.gnupg.agent = { diff --git a/nix/configuration/roles/kanshi/default.nix b/nix/configuration/roles/kanshi/default.nix index b1fdbb9..be886c4 100644 --- a/nix/configuration/roles/kanshi/default.nix +++ b/nix/configuration/roles/kanshi/default.nix @@ -41,15 +41,11 @@ in exec_kanshi ]; - home-manager.users.talexander = - { pkgs, ... }: - { - home.file = { - ".config/kanshi/config" = { - source = ./files/config_kanshi; - }; - }; + me.install.user.talexander.file = { + ".config/kanshi/config" = { + source = ./files/config_kanshi; }; + }; }) ] ); diff --git a/nix/configuration/roles/kodi/default.nix b/nix/configuration/roles/kodi/default.nix index b37bf06..d67e3fd 100644 --- a/nix/configuration/roles/kodi/default.nix +++ b/nix/configuration/roles/kodi/default.nix @@ -78,21 +78,13 @@ }; }; - home-manager.users.kodi = - { pkgs, ... }: - { - # home.file.".kodi/userdata/mediasources.xml".source = ./files/mediasources.xml; + # home.file.".kodi/userdata/mediasources.xml".source = ./files/mediasources.xml; - # home.file.".kodi/userdata/addon_data/peripheral.joystick/resources/buttonmaps/xml/linux/DualSense_Wireless_Controller_13b_8a.xml".source = - # ./files/DualSense_Wireless_Controller_13b_8a.xml; + # home.file.".kodi/userdata/addon_data/peripheral.joystick/resources/buttonmaps/xml/linux/DualSense_Wireless_Controller_13b_8a.xml".source = + # ./files/DualSense_Wireless_Controller_13b_8a.xml; - # TODO: Maybe .kodi/userdata/sources.xml - # TODO: ./userdata/guisettings.xml:303: 128 - - # The state version is required and should stay at the version you - # originally installed. - home.stateVersion = "24.11"; - }; + # TODO: Maybe .kodi/userdata/sources.xml + # TODO: ./userdata/guisettings.xml:303: 128 }) ] ); diff --git a/nix/configuration/roles/media/default.nix b/nix/configuration/roles/media/default.nix index 7fd4e67..e121fc0 100644 --- a/nix/configuration/roles/media/default.nix +++ b/nix/configuration/roles/media/default.nix @@ -52,13 +52,11 @@ in imv ]; - home-manager.users.talexander = - { pkgs, ... }: - { - home.file.".config/mpv/mpv.conf" = { - source = ./files/mpv.conf; - }; + me.install.user.talexander.file = { + ".config/mpv/mpv.conf" = { + source = ./files/mpv.conf; }; + }; }) (lib.mkIf (config.me.graphics_card_type == "amd" || config.me.graphics_card_type == "intel") { environment.systemPackages = with pkgs; [ diff --git a/nix/configuration/roles/pcsx2/default.nix b/nix/configuration/roles/pcsx2/default.nix index 2af42ea..a5866da 100644 --- a/nix/configuration/roles/pcsx2/default.nix +++ b/nix/configuration/roles/pcsx2/default.nix @@ -82,13 +82,11 @@ }; }; - home-manager.users.talexander = - { pkgs, ... }: - { - home.file.".config/PCSX2/inis/PCSX2.ini" = { - source = ./files/PCSX2.ini; - }; + me.install.user.talexander.file = { + ".config/PCSX2/inis/PCSX2.ini" = { + source = ./files/PCSX2.ini; }; + }; }) ] ); diff --git a/nix/configuration/roles/rpcs3/default.nix b/nix/configuration/roles/rpcs3/default.nix index 2182cd3..7d2d074 100644 --- a/nix/configuration/roles/rpcs3/default.nix +++ b/nix/configuration/roles/rpcs3/default.nix @@ -70,28 +70,26 @@ in } ]; - home-manager.users.talexander = - { pkgs, ... }: - { - home.file.".config/rpcs3/config.yml" = lib.mkIf (config.me.rpcs3.config != null) { - source = rpcs3_config_yaml; - }; - home.file.".config/rpcs3/GuiConfigs/CurrentSettings.ini" = { - source = ./files/CurrentSettings.ini; - }; - home.file.".config/rpcs3/custom_configs/config_BLUS30443.yml" = { - # Demon's Souls per-game config. - source = ./files/config_BLUS30443.yml; - }; - home.file.".config/rpcs3/patches/patch.yml" = { - # All of the available patches. - source = ./files/patch.yml; - }; - home.file.".config/rpcs3/patch_config.yml" = { - # Patches that I have enabled. - source = ./files/patch_config.yml; - }; + me.install.user.talexander.file = { + ".config/rpcs3/config.yml" = lib.mkIf (config.me.rpcs3.config != null) { + source = rpcs3_config_yaml; }; + ".config/rpcs3/GuiConfigs/CurrentSettings.ini" = { + source = ./files/CurrentSettings.ini; + }; + ".config/rpcs3/custom_configs/config_BLUS30443.yml" = { + # Demon's Souls per-game config. + source = ./files/config_BLUS30443.yml; + }; + ".config/rpcs3/patches/patch.yml" = { + # All of the available patches. + source = ./files/patch.yml; + }; + ".config/rpcs3/patch_config.yml" = { + # Patches that I have enabled. + source = ./files/patch_config.yml; + }; + }; environment.persistence."/persist" = lib.mkIf (!config.me.buildingIso) { hideMounts = true; diff --git a/nix/configuration/roles/rust/default.nix b/nix/configuration/roles/rust/default.nix index 8482484..4ac6cb2 100644 --- a/nix/configuration/roles/rust/default.nix +++ b/nix/configuration/roles/rust/default.nix @@ -48,18 +48,14 @@ in # ? cargo-public-api ]; - home-manager.users.talexander = - { pkgs, ... }: - { - home.file = { - ".cargo/config.toml" = { - source = ./files/cargo_config.toml; - }; - ".rustup/settings.toml" = { - source = ./files/rustup_settings.toml; - }; - }; + me.install.user.talexander.file = { + ".cargo/config.toml" = { + source = ./files/cargo_config.toml; }; + ".rustup/settings.toml" = { + source = ./files/rustup_settings.toml; + }; + }; environment.persistence."/state" = lib.mkIf (!config.me.buildingIso) { hideMounts = true; diff --git a/nix/configuration/roles/shadps4/default.nix b/nix/configuration/roles/shadps4/default.nix index 8615466..08bc049 100644 --- a/nix/configuration/roles/shadps4/default.nix +++ b/nix/configuration/roles/shadps4/default.nix @@ -24,13 +24,11 @@ shadps4 ]; - home-manager.users.talexander = - { pkgs, ... }: - { - home.file.".local/share/shadPS4/config.toml" = { - source = ./files/config.toml; - }; + me.install.user.talexander.file = { + ".local/share/shadPS4/config.toml" = { + source = ./files/config.toml; }; + }; environment.persistence."/persist" = lib.mkIf (!config.me.buildingIso) { hideMounts = true; diff --git a/nix/configuration/roles/shikane/default.nix b/nix/configuration/roles/shikane/default.nix index 728bb4f..1d79348 100644 --- a/nix/configuration/roles/shikane/default.nix +++ b/nix/configuration/roles/shikane/default.nix @@ -36,15 +36,11 @@ in exec_shikane ]; - home-manager.users.talexander = - { pkgs, ... }: - { - home.file = { - ".config/shikane/config.toml" = { - source = ./files/config.toml; - }; - }; + me.install.user.talexander.file = { + ".config/shikane/config.toml" = { + source = ./files/config.toml; }; + }; }) ] ); diff --git a/nix/configuration/roles/ssh/default.nix b/nix/configuration/roles/ssh/default.nix index f4c1d8b..3c7dc68 100644 --- a/nix/configuration/roles/ssh/default.nix +++ b/nix/configuration/roles/ssh/default.nix @@ -27,19 +27,14 @@ }; }; - home-manager.users.talexander = - { pkgs, ... }: - { - home.file.".ssh/config" = { - source = ./files/ssh_config; - }; + me.install.user.root.file = { + ".ssh/config" = { + source = ./files/ssh_config_root; }; - - home-manager.users.root = - { pkgs, ... }: - { - home.file.".ssh/config" = { - source = ./files/ssh_config_root; - }; + }; + me.install.user.talexander.file = { + ".ssh/config" = { + source = ./files/ssh_config; }; + }; } diff --git a/nix/configuration/roles/sway/default.nix b/nix/configuration/roles/sway/default.nix index 6100cab..04a636a 100644 --- a/nix/configuration/roles/sway/default.nix +++ b/nix/configuration/roles/sway/default.nix @@ -376,26 +376,18 @@ in }; }; - home-manager.users.talexander = - { pkgs, ... }: - { - home.file = { - # Configure default programs (for example, default browser) - ".config/mimeapps.list" = { - source = ./files/mimeapps.list; - }; - }; - home.file = { - ".config/gtk-3.0/settings.ini" = { - source = ./files/settings.ini; - }; - }; - home.file = { - ".icons/default" = { - source = "${pkgs.adwaita-icon-theme}/share/icons/Adwaita"; - }; - }; + me.install.user.talexander.file = { + ".config/mimeapps.list" = { + # Configure default programs (for example, default browser) + source = ./files/mimeapps.list; }; + ".config/gtk-3.0/settings.ini" = { + source = ./files/settings.ini; + }; + ".icons/default" = { + source = "${pkgs.adwaita-icon-theme}/share/icons/Adwaita"; + }; + }; # For mounting drives in pcmanfm services.gvfs.enable = true; diff --git a/nix/configuration/roles/vscode/default.nix b/nix/configuration/roles/vscode/default.nix index af50003..b37b0e0 100644 --- a/nix/configuration/roles/vscode/default.nix +++ b/nix/configuration/roles/vscode/default.nix @@ -48,16 +48,14 @@ }) ]; - home-manager.users.talexander = - { pkgs, ... }: - { - home.file.".config/Code/User/settings.json" = { - source = ./files/settings.json; - }; - home.file.".config/Code/User/keybindings.json" = { - source = ./files/keybindings.json; - }; + me.install.user.talexander.file = { + ".config/Code/User/settings.json" = { + source = ./files/settings.json; }; + ".config/Code/User/keybindings.json" = { + source = ./files/keybindings.json; + }; + }; }) ] ); diff --git a/nix/configuration/roles/waybar/default.nix b/nix/configuration/roles/waybar/default.nix index ea03b4f..b2ef5d3 100644 --- a/nix/configuration/roles/waybar/default.nix +++ b/nix/configuration/roles/waybar/default.nix @@ -113,18 +113,14 @@ in services.upower.enable = true; # for battery - home-manager.users.talexander = - { pkgs, ... }: - { - home.file = { - ".config/waybar/config" = { - source = ./files/waybar_config.json; - }; - ".config/waybar/style.css" = { - source = ./files/style.css; - }; - }; + me.install.user.talexander.file = { + ".config/waybar/config" = { + source = ./files/waybar_config.json; }; + ".config/waybar/style.css" = { + source = ./files/style.css; + }; + }; }) ] ); diff --git a/nix/configuration/roles/zsh/default.nix b/nix/configuration/roles/zsh/default.nix index 518fdda..2a4fdfe 100644 --- a/nix/configuration/roles/zsh/default.nix +++ b/nix/configuration/roles/zsh/default.nix @@ -90,13 +90,11 @@ in enable = true; }; - home-manager.users.talexander = - { pkgs, ... }: - { - home.file.".zshrc" = { - source = "${zshrc}"; - }; + me.install.user.talexander.file = { + ".zshrc" = { + source = "${zshrc}"; }; + }; environment.persistence."/persist" = lib.mkIf (!config.me.buildingIso) { hideMounts = true; diff --git a/nix/configuration/util/install_files/default.nix b/nix/configuration/util/install_files/default.nix new file mode 100644 index 0000000..7be496d --- /dev/null +++ b/nix/configuration/util/install_files/default.nix @@ -0,0 +1,333 @@ +{ + config, + lib, + pkgs, + ... +}: + +let + cfg = config.me.install; + inherit (lib) + filter + attrNames + ; + + get_shell_values = + target: + let + homedir = config.users.users."${target.username}".home; + group = config.users.users."${target.username}".group; + in + { + source = lib.strings.escapeShellArg "${target.source}"; + destination = lib.strings.escapeShellArg "${homedir}/${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 = { + "overwrite" = install_user_file_overwrite; + "symlink" = install_user_file_symlink; + }; + in + stage: target: (constructors."${target.method}"."${stage}" target); + install_user_file_overwrite = { + "check" = (target: ""); + "install" = ( + target: + let + inherit (get_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_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_user_file_symlink = { + "check" = (target: ""); + "install" = ( + target: + let + inherit (get_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_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} + '' + ] + ); + }; +in +{ + imports = [ ]; + + options.me.install = { + user = lib.mkOption { + type = lib.types.attrsOf ( + lib.types.submodule ( + { name, config, ... }: + let + username = name; + in + { + options = { + 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."; + }; + + 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; + }; + } + ) + ); + }; + }; + } + ) + ); + }; + }; + + config = + let + all_users = builtins.map (username: cfg.user."${username}") (attrNames cfg.user); + enabled_users = filter (user: user.enable) all_users; + all_file_targets = lib.flatten ( + 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 + ); + in + { + systemd.services.me-install-file = { + enable = true; + description = "me-install-file"; + wantedBy = [ "multi-user.target" ]; + wants = [ "multi-user.target" ]; + before = [ "multi-user.target" ]; + # path = with pkgs; [ + # zfs + # ]; + unitConfig.DefaultDependencies = "no"; + serviceConfig = { + Type = "oneshot"; + RemainAfterExit = "yes"; + }; + script = + '' + set -o pipefail + IFS=$'\n\t' + source ${./files/lib.bash} + '' + + (lib.strings.concatStringsSep "\n" ( + [ + ] + ++ check_commands + ++ install_commands + )); + preStop = + '' + set -o pipefail + IFS=$'\n\t' + source ${./files/lib.bash} + '' + + (lib.strings.concatStringsSep "\n" uninstall_commands); + }; + }; +} diff --git a/nix/configuration/util/install_files/files/lib.bash b/nix/configuration/util/install_files/files/lib.bash new file mode 100644 index 0000000..1a5c178 --- /dev/null +++ b/nix/configuration/util/install_files/files/lib.bash @@ -0,0 +1,38 @@ +#!/usr/bin/env bash +# + +############## Setup ######################### + +function die { + local status_code="$1" + shift + (>&2 echo "${@}") + exit "$status_code" +} + +function log { + (>&2 echo "${@}") +} + +############## Program ######################### + +function create_containing_directories { + local full_dest="$1" + shift 1 + local dirs_to_create=() + local containing_directory="$full_dest" + while true; do + containing_directory=$(dirname "$containing_directory") + if [ -e "$containing_directory" ] || [ "$containing_directory" = "/" ]; then + break + fi + dirs_to_create+=($containing_directory) + done + + for (( idx=${#dirs_to_create[@]}-1 ; idx>=0 ; idx-- )) ; do + local containing_directory="${dirs_to_create[idx]}" + log "Creating $containing_directory" + $DRY_RUN_CMD install $VERBOSE_ARG -d "${@}" "$containing_directory" + done + +}