From a8ca3653b4f17b46b6f23958fda1086c5dc4b451 Mon Sep 17 00:00:00 2001 From: Nikolaos Karaolidis Date: Wed, 29 Jan 2025 16:16:17 +0000 Subject: [PATCH] Add custom kubernetes module base Signed-off-by: Nikolaos Karaolidis --- flake.lock | 6 +- .../system/kubernetes/addons/default.nix | 7 - .../configs/system/kubernetes/default.nix | 201 +---- .../options/addons/addon-manager/default.nix | 70 ++ .../addons/bootstrap/default.nix | 40 +- .../addons/kubelet-api-admin/default.nix | 21 + .../addons/metrics-server/default.nix | 48 +- .../system/kubernetes/options/default.nix | 757 ++++++++++++++++++ .../system/kubernetes/secrets/default.nix | 191 +++-- .../kubernetes/secrets/generate-secrets.sh | 107 ++- .../user/console/kubernetes/default.nix | 20 +- .../configs/user/gui/obsidian/options.nix | 360 +++++---- submodules/nixpkgs | 2 +- 13 files changed, 1286 insertions(+), 544 deletions(-) delete mode 100644 hosts/common/configs/system/kubernetes/addons/default.nix create mode 100644 hosts/common/configs/system/kubernetes/options/addons/addon-manager/default.nix rename hosts/common/configs/system/kubernetes/{ => options}/addons/bootstrap/default.nix (93%) create mode 100644 hosts/common/configs/system/kubernetes/options/addons/kubelet-api-admin/default.nix rename hosts/common/configs/system/kubernetes/{ => options}/addons/metrics-server/default.nix (95%) create mode 100644 hosts/common/configs/system/kubernetes/options/default.nix diff --git a/flake.lock b/flake.lock index 5d983bb..434abfc 100644 --- a/flake.lock +++ b/flake.lock @@ -143,11 +143,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1738059769, - "narHash": "sha256-SBOwc5HSi0zThWoj3EfYh673X1d1dc78N2qCtcJmIvo=", + "lastModified": 1738150270, + "narHash": "sha256-GkH7I9LW0aFklGc3YxjaBW7TtJy5aWHE0rPBUuz35Hk=", "owner": "karaolidis", "repo": "nixpkgs", - "rev": "befe9d27e7e7be485aae35d541f135c8471bd508", + "rev": "e8e18ef6309d021fa600f5aa2665963d8cf76ab7", "type": "github" }, "original": { diff --git a/hosts/common/configs/system/kubernetes/addons/default.nix b/hosts/common/configs/system/kubernetes/addons/default.nix deleted file mode 100644 index 4124090..0000000 --- a/hosts/common/configs/system/kubernetes/addons/default.nix +++ /dev/null @@ -1,7 +0,0 @@ -{ config, lib, ... }: -{ - services.kubernetes.addonManager.bootstrapAddons = lib.mkMerge [ - (import ./bootstrap { inherit config; }) - (import ./metrics-server { }) - ]; -} diff --git a/hosts/common/configs/system/kubernetes/default.nix b/hosts/common/configs/system/kubernetes/default.nix index 02c4122..7b2e0bc 100644 --- a/hosts/common/configs/system/kubernetes/default.nix +++ b/hosts/common/configs/system/kubernetes/default.nix @@ -1,20 +1,11 @@ { config, - lib, pkgs, ... }: -let - adminKubeconfig = config.services.kubernetes.lib.mkKubeConfig "admin" { - caFile = config.sops.secrets."kubernetes/ca/crt".path; - keyFile = config.sops.secrets."kubernetes/accounts/admin/key".path; - certFile = config.sops.secrets."kubernetes/accounts/admin/crt".path; - server = config.services.kubernetes.apiserverAddress; - }; -in { imports = [ - ./addons + ./options ./secrets ]; @@ -26,208 +17,36 @@ in "/var/lib/etcd" = { }; }; - etc."kubeconfig".source = adminKubeconfig; + etc."kubeconfig".source = config.services.kubernetes.kubeconfigs.admin; systemPackages = with pkgs; [ kubectl ]; }; services = { kubernetes = { + enable = true; + roles = [ "master" "node" ]; - - masterAddress = "localhost"; - easyCerts = false; - caFile = config.sops.secrets."kubernetes/ca/crt".path; - addonManager.enable = true; - - apiserver = { - allowPrivileged = true; - - clientCaFile = config.sops.secrets."kubernetes/ca/crt".path; - kubeletClientCaFile = config.sops.secrets."kubernetes/ca/crt".path; - tlsKeyFile = config.sops.secrets."kubernetes/apiserver/cert/key".path; - tlsCertFile = config.sops.secrets."kubernetes/apiserver/cert/crt".path; - kubeletClientKeyFile = config.sops.secrets."kubernetes/apiserver/kubelet-client/key".path; - kubeletClientCertFile = config.sops.secrets."kubernetes/apiserver/kubelet-client/crt".path; - proxyClientKeyFile = config.sops.secrets."kubernetes/front-proxy/client/key".path; - proxyClientCertFile = config.sops.secrets."kubernetes/front-proxy/client/crt".path; - serviceAccountSigningKeyFile = config.sops.secrets."kubernetes/sa/key".path; - serviceAccountKeyFile = config.sops.secrets."kubernetes/sa/pub".path; - - extraOpts = lib.strings.concatStringsSep " " [ - "--enable-bootstrap-token-auth=true" - "--token-auth-file=${config.sops.secrets."kubernetes/accounts/kubelet-bootstrap/csv".path}" - "--requestheader-client-ca-file=${config.sops.secrets."kubernetes/front-proxy/ca/crt".path}" - "--requestheader-allowed-names=front-proxy-client" - "--requestheader-extra-headers-prefix=X-Remote-Extra-" - "--requestheader-group-headers=X-Remote-Group" - "--requestheader-username-headers=X-Remote-User" - ]; - - etcd = { - servers = [ "https://etcd.local:2379" ]; - caFile = config.sops.secrets."kubernetes/etcd/ca/crt".path; - keyFile = config.sops.secrets."kubernetes/apiserver/etcd-client/key".path; - certFile = config.sops.secrets."kubernetes/apiserver/etcd-client/crt".path; - }; - }; - - controllerManager = { - rootCaFile = config.sops.secrets."kubernetes/ca/crt".path; - serviceAccountKeyFile = config.sops.secrets."kubernetes/sa/key".path; - - extraOpts = lib.strings.concatStringsSep " " [ - "--client-ca-file=${config.sops.secrets."kubernetes/ca/crt".path}" - "--cluster-signing-cert-file=${config.sops.secrets."kubernetes/ca/crt".path}" - "--cluster-signing-key-file=${config.sops.secrets."kubernetes/ca/key".path}" - "--requestheader-client-ca-file=${config.sops.secrets."kubernetes/front-proxy/ca/crt".path}" - ]; - - kubeconfig = { - caFile = config.sops.secrets."kubernetes/ca/crt".path; - keyFile = config.sops.secrets."kubernetes/accounts/controller-manager/key".path; - certFile = config.sops.secrets."kubernetes/accounts/controller-manager/crt".path; - }; - }; - - kubelet = { - clientCaFile = config.sops.secrets."kubernetes/ca/crt".path; - - extraOpts = lib.strings.concatStringsSep " " [ - "--bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubeconfig" - "--kubeconfig=/var/lib/kubelet/kubeconfig" - "--cert-dir=/var/lib/kubelet" - ]; - - extraConfig = { - failSwapOn = false; - rotateCertificates = true; - serverTLSBootstrap = true; - memorySwap.swapBehavior = "LimitedSwap"; - }; - - featureGates = { - RotateKubeletServerCertificate = true; - NodeSwap = true; - }; - }; - - proxy.kubeconfig = { - caFile = config.sops.secrets."kubernetes/ca/crt".path; - keyFile = config.sops.secrets."kubernetes/accounts/proxy/key".path; - certFile = config.sops.secrets."kubernetes/accounts/proxy/crt".path; - }; - - scheduler.kubeconfig = { - caFile = config.sops.secrets."kubernetes/ca/crt".path; - keyFile = config.sops.secrets."kubernetes/accounts/scheduler/key".path; - certFile = config.sops.secrets."kubernetes/accounts/scheduler/crt".path; - }; }; - - etcd = { - keyFile = config.sops.secrets."kubernetes/etcd/server/key".path; - certFile = config.sops.secrets."kubernetes/etcd/server/crt".path; - peerKeyFile = config.sops.secrets."kubernetes/etcd/peer/key".path; - peerCertFile = config.sops.secrets."kubernetes/etcd/peer/crt".path; - trustedCaFile = config.sops.secrets."kubernetes/etcd/ca/crt".path; - peerTrustedCaFile = config.sops.secrets."kubernetes/etcd/ca/crt".path; - listenClientUrls = [ "https://127.0.0.1:2379" ]; - listenPeerUrls = [ "https://127.0.0.1:2380" ]; - advertiseClientUrls = [ "https://etcd.local:2379" ]; - initialCluster = [ "${config.services.kubernetes.masterAddress}=https://etcd.local:2380" ]; - initialAdvertisePeerUrls = [ "https://etcd.local:2380" ]; - }; - - flannel.kubeconfig = config.services.kubernetes.lib.mkKubeConfig "flannel" { - caFile = config.sops.secrets."kubernetes/ca/crt".path; - keyFile = config.sops.secrets."kubernetes/accounts/flannel/key".path; - certFile = config.sops.secrets."kubernetes/accounts/flannel/crt".path; - server = config.services.kubernetes.apiserverAddress; - }; - }; - - networking = { - firewall.enable = false; - extraHosts = lib.strings.optionalString (config.services.etcd.enable) '' - 127.0.0.1 etcd.${config.services.kubernetes.addons.dns.clusterDomain} etcd.local - ''; }; systemd.services = { - kube-addon-manager = { - after = [ - "sops-nix.service" - config.environment.persistence."/persist"."/var/lib/kubernetes".mount - ]; + kube-addon-manager.after = [ + config.environment.persistence."/persist"."/var/lib/kubernetes".mount + ]; - environment.KUBECONFIG = config.services.kubernetes.lib.mkKubeConfig "addon-manager" { - caFile = config.sops.secrets."kubernetes/ca/crt".path; - keyFile = config.sops.secrets."kubernetes/accounts/addon-manager/key".path; - certFile = config.sops.secrets."kubernetes/accounts/addon-manager/crt".path; - server = config.services.kubernetes.apiserverAddress; - }; - - serviceConfig.PermissionsStartOnly = true; - - preStart = '' - export KUBECONFIG=${adminKubeconfig} - ${config.services.kubernetes.package}/bin/kubectl apply -f ${ - lib.strings.concatStringsSep " \\\n -f " ( - lib.attrsets.mapAttrsToList ( - n: v: pkgs.writeText "${n}.json" (builtins.toJSON v) - ) config.services.kubernetes.addonManager.bootstrapAddons - ) - } - ''; - }; - - kubelet = { - preStart = '' - mkdir -p /etc/kubernetes - cat > /etc/kubernetes/bootstrap-kubeconfig < /etc/kubernetes/bootstrap-kubeconfig < "${decrypted_secrets_file}" yq -i ' del(.kubernetes) | - .kubernetes.ca.crt = load_str("out/ca.crt") | - .kubernetes.ca.key = load_str("out/ca.key") | - .kubernetes.front-proxy.ca.crt = load_str("out/front-proxy/ca.crt") | - .kubernetes.front-proxy.ca.key = load_str("out/front-proxy/ca.key") | - .kubernetes.etcd.ca.crt = load_str("out/etcd/ca.crt") | - .kubernetes.etcd.ca.key = load_str("out/etcd/ca.key") | - .kubernetes.apiserver.cert.crt = load_str("out/apiserver/cert.crt") | - .kubernetes.apiserver.cert.key = load_str("out/apiserver/cert.key") | - .kubernetes.apiserver.kubelet-client.crt = load_str("out/apiserver/kubelet-client.crt") | - .kubernetes.apiserver.kubelet-client.key = load_str("out/apiserver/kubelet-client.key") | - .kubernetes.apiserver.etcd-client.crt = load_str("out/apiserver/etcd-client.crt") | - .kubernetes.apiserver.etcd-client.key = load_str("out/apiserver/etcd-client.key") | - .kubernetes.front-proxy.client.crt = load_str("out/front-proxy/client.crt") | - .kubernetes.front-proxy.client.key = load_str("out/front-proxy/client.key") | - .kubernetes.etcd.server.crt = load_str("out/etcd/server.crt") | - .kubernetes.etcd.server.key = load_str("out/etcd/server.key") | - .kubernetes.etcd.peer.crt = load_str("out/etcd/peer.crt") | - .kubernetes.etcd.peer.key = load_str("out/etcd/peer.key") | - .kubernetes.sa.key = load_str("out/sa.key") | - .kubernetes.sa.pub = load_str("out/sa.pub") | - .kubernetes.accounts.admin.crt = load_str("out/accounts/admin.crt") | - .kubernetes.accounts.admin.key = load_str("out/accounts/admin.key") | - .kubernetes.accounts.users.crt = load_str("out/accounts/users.crt") | - .kubernetes.accounts.users.key = load_str("out/accounts/users.key") | - .kubernetes.accounts.controller-manager.crt = load_str("out/accounts/controller-manager.crt") | - .kubernetes.accounts.controller-manager.key = load_str("out/accounts/controller-manager.key") | - .kubernetes.accounts.addon-manager.crt = load_str("out/accounts/addon-manager.crt") | - .kubernetes.accounts.addon-manager.key = load_str("out/accounts/addon-manager.key") | - .kubernetes.accounts.scheduler.crt = load_str("out/accounts/scheduler.crt") | - .kubernetes.accounts.scheduler.key = load_str("out/accounts/scheduler.key") | - .kubernetes.accounts.proxy.crt = load_str("out/accounts/proxy.crt") | - .kubernetes.accounts.proxy.key = load_str("out/accounts/proxy.key") | - .kubernetes.accounts.flannel.crt = load_str("out/accounts/flannel.crt") | - .kubernetes.accounts.flannel.key = load_str("out/accounts/flannel.key") | - .kubernetes.accounts.kubelet-bootstrap.token = load_str("out/accounts/kubelet-bootstrap.token") | - .kubernetes.accounts.kubelet-bootstrap.csv = load_str("out/accounts/kubelet-bootstrap.csv") + .kubernetes.ca.kubernetes.crt = load_str("out/ca/kubernetes.crt") | + .kubernetes.ca.kubernetes.key = load_str("out/ca/kubernetes.key") | + .kubernetes.ca.front-proxy.crt = load_str("out/ca/front-proxy.crt") | + .kubernetes.ca.front-proxy.key = load_str("out/ca/front-proxy.key") | + .kubernetes.ca.etcd.crt = load_str("out/ca/etcd.crt") | + .kubernetes.ca.etcd.key = load_str("out/ca/etcd.key") | + .kubernetes.cert.apiserver.server.crt = load_str("out/cert/apiserver/server.crt") | + .kubernetes.cert.apiserver.server.key = load_str("out/cert/apiserver/server.key") | + .kubernetes.cert.apiserver.etcd-client.crt = load_str("out/cert/apiserver/etcd-client.crt") | + .kubernetes.cert.apiserver.etcd-client.key = load_str("out/cert/apiserver/etcd-client.key") | + .kubernetes.cert.apiserver.kubelet-client.crt = load_str("out/cert/apiserver/kubelet-client.crt") | + .kubernetes.cert.apiserver.kubelet-client.key = load_str("out/cert/apiserver/kubelet-client.key") | + .kubernetes.cert.etcd.server.crt = load_str("out/cert/etcd/server.crt") | + .kubernetes.cert.etcd.server.key = load_str("out/cert/etcd/server.key") | + .kubernetes.cert.etcd.peer.crt = load_str("out/cert/etcd/peer.crt") | + .kubernetes.cert.etcd.peer.key = load_str("out/cert/etcd/peer.key") | + .kubernetes.cert.front-proxy.crt = load_str("out/cert/front-proxy.crt") | + .kubernetes.cert.front-proxy.key = load_str("out/cert/front-proxy.key") | + .kubernetes.cert.sa.key = load_str("out/cert/sa.key") | + .kubernetes.cert.sa.pub = load_str("out/cert/sa.pub") | + .kubernetes.cert.accounts.scheduler.crt = load_str("out/cert/accounts/scheduler.crt") | + .kubernetes.cert.accounts.scheduler.key = load_str("out/cert/accounts/scheduler.key") | + .kubernetes.cert.accounts.controller-manager.crt = load_str("out/cert/accounts/controller-manager.crt") | + .kubernetes.cert.accounts.controller-manager.key = load_str("out/cert/accounts/controller-manager.key") | + .kubernetes.cert.accounts.addon-manager.crt = load_str("out/cert/accounts/addon-manager.crt") | + .kubernetes.cert.accounts.addon-manager.key = load_str("out/cert/accounts/addon-manager.key") | + .kubernetes.cert.accounts.proxy.crt = load_str("out/cert/accounts/proxy.crt") | + .kubernetes.cert.accounts.proxy.key = load_str("out/cert/accounts/proxy.key") | + .kubernetes.cert.accounts.admin.crt = load_str("out/cert/accounts/admin.crt") | + .kubernetes.cert.accounts.admin.key = load_str("out/cert/accounts/admin.key") | + .kubernetes.cert.accounts.users.crt = load_str("out/cert/accounts/users.crt") | + .kubernetes.cert.accounts.users.key = load_str("out/cert/accounts/users.key") | + .kubernetes.token.kubelet-bootstrap.token = load_str("out/token/kubelet-bootstrap.token") | + .kubernetes.token.kubelet-bootstrap.csv = load_str("out/token/kubelet-bootstrap.csv") ' "${decrypted_secrets_file}" sops --config "${sops_config}" -e "${decrypted_secrets_file}" > "${secrets_file}" -rm -rf out +rm -rf ${decrypted_secrets_file} out diff --git a/hosts/common/configs/user/console/kubernetes/default.nix b/hosts/common/configs/user/console/kubernetes/default.nix index dbaa6e9..8d5545f 100644 --- a/hosts/common/configs/user/console/kubernetes/default.nix +++ b/hosts/common/configs/user/console/kubernetes/default.nix @@ -25,19 +25,24 @@ users.users.${user}.extraGroups = [ "kubernetes" ]; sops.secrets = { - "kubernetes/accounts/${user}/crt" = { - key = "kubernetes/accounts/users/crt"; + "kubernetes/cert/accounts/${user}/crt" = { + key = "kubernetes/cert/accounts/users/crt"; group = "users"; mode = "0440"; }; - "kubernetes/accounts/${user}/key" = { - key = "kubernetes/accounts/users/key"; + "kubernetes/cert/accounts/${user}/key" = { + key = "kubernetes/cert/accounts/users/key"; group = "users"; mode = "0440"; }; }; + services.kubernetes.kubeconfigs.${user} = + config.services.kubernetes.lib.mkKubeConfig user config.sops.secrets."kubernetes/ca/kubernetes/crt".path + config.sops.secrets."kubernetes/cert/accounts/${user}/crt".path + config.sops.secrets."kubernetes/cert/accounts/${user}/key".path; + home-manager.users.${user} = { home = { packages = with pkgs; [ @@ -47,12 +52,7 @@ kompose ]; - file.".kube/local".source = config.services.kubernetes.lib.mkKubeConfig user { - caFile = config.sops.secrets."kubernetes/ca/crt".path; - certFile = config.sops.secrets."kubernetes/accounts/${user}/crt".path; - keyFile = config.sops.secrets."kubernetes/accounts/${user}/key".path; - server = config.services.kubernetes.apiserverAddress; - }; + file.".kube/local".source = config.services.kubernetes.kubeconfigs.${user}; }; programs = { diff --git a/hosts/common/configs/user/gui/obsidian/options.nix b/hosts/common/configs/user/gui/obsidian/options.nix index db89dea..7c3889b 100644 --- a/hosts/common/configs/user/gui/obsidian/options.nix +++ b/hosts/common/configs/user/gui/obsidian/options.nix @@ -37,154 +37,11 @@ let "workspaces" "zk-prefixer" ]; - - toCssName = path: lib.strings.removeSuffix ".css" (builtins.baseNameOf path); in { options.programs.obsidian = with lib; with types; - let - corePluginsOptions = - { config, ... }: - { - options = { - enable = mkOption { - type = bool; - default = true; - description = "Whether to enable the plugin."; - }; - - name = mkOption { - type = enum corePlugins; - description = "The plugin."; - }; - - options = mkOption { - type = attrsOf anything; - description = "Plugin options to include."; - default = { }; - }; - }; - }; - - communityPluginsOptions = - { config, ... }: - { - options = { - enable = mkOption { - type = bool; - default = true; - description = "Whether to enable the plugin."; - }; - - pkg = mkOption { - type = package; - description = "The plugin package."; - }; - - options = mkOption { - type = attrsOf anything; - description = "Options to include in the plugin's `data.json`."; - default = { }; - }; - }; - }; - - checkCssPath = path: lib.filesystem.pathIsRegularFile path && lib.strings.hasSuffix ".css" path; - - cssSnippetsOptions = - { config, ... }: - { - options = { - enable = mkOption { - type = bool; - default = true; - description = "Whether to enable the snippet."; - }; - - name = mkOption { - type = str; - defaultText = literalExpression "lib.strings.removeSuffix \".css\" (builtins.baseNameOf source)"; - description = "Name of the snippet."; - }; - - source = mkOption { - type = nullOr (addCheck path checkCssPath); - description = "Path of the source file."; - default = null; - }; - - text = mkOption { - type = nullOr str; - description = "Text of the file."; - default = null; - }; - }; - - config.name = mkDefault (toCssName config.source); - }; - - themesOptions = - { config, ... }: - { - options = { - enable = mkOption { - type = bool; - default = true; - description = "Whether to set the theme as active."; - }; - - pkg = mkOption { - type = package; - description = "The theme package."; - }; - }; - }; - - hotkeysOptions = - { config, ... }: - { - options = { - modifiers = mkOption { - type = listOf str; - description = "The hotkey modifiers."; - default = [ ]; - }; - - key = mkOption { - type = str; - description = "The hotkey."; - }; - }; - }; - - extraFilesOptions = - { name, config, ... }: - { - options = { - source = mkOption { - type = nullOr path; - description = "Path of the source file or directory."; - default = null; - }; - - text = mkOption { - type = nullOr str; - description = "Text of the file."; - default = null; - }; - - target = mkOption { - type = str; - defaultText = literalExpression "name"; - description = "Path to target relative to the vault's directory."; - }; - }; - - config.target = mkDefault name; - }; - in { enable = mkEnableOption "obsidian"; package = mkPackageOption pkgs "obsidian" { }; @@ -290,43 +147,196 @@ in default = cfg.sharedSettings.appearance; }; - corePlugins = mkOption { - description = "Core plugins to activate."; - type = listOf (coercedTo (enum corePlugins) (p: { name = p; }) (submodule corePluginsOptions)); - default = cfg.sharedSettings.corePlugins; - }; + corePlugins = + let + corePluginsOptions = + { config, ... }: + { + options = { + enable = mkOption { + type = bool; + default = true; + description = "Whether to enable the plugin."; + }; - communityPlugins = mkOption { - description = "Community plugins to install and activate."; - type = listOf (coercedTo package (p: { pkg = p; }) (submodule communityPluginsOptions)); - default = cfg.sharedSettings.communityPlugins; - }; + name = mkOption { + type = enum corePlugins; + description = "The plugin."; + }; - cssSnippets = mkOption { - description = "CSS snippets to install."; - type = listOf ( - coercedTo (addCheck path checkCssPath) (p: { source = p; }) (submodule cssSnippetsOptions) - ); - default = cfg.sharedSettings.cssSnippets; - }; + options = mkOption { + type = attrsOf anything; + description = "Plugin options to include."; + default = { }; + }; + }; + }; + in + mkOption { + description = "Core plugins to activate."; + type = listOf (coercedTo (enum corePlugins) (p: { name = p; }) (submodule corePluginsOptions)); + default = cfg.sharedSettings.corePlugins; + }; - themes = mkOption { - description = "Themes to install."; - type = listOf (coercedTo package (p: { pkg = p; }) (submodule themesOptions)); - default = cfg.sharedSettings.themes; - }; + communityPlugins = + let + communityPluginsOptions = + { config, ... }: + { + options = { + enable = mkOption { + type = bool; + default = true; + description = "Whether to enable the plugin."; + }; - hotkeys = mkOption { - description = "Hotkeys to configure."; - type = attrsOf (listOf (submodule hotkeysOptions)); - default = cfg.sharedSettings.hotkeys; - }; + pkg = mkOption { + type = package; + description = "The plugin package."; + }; - extraFiles = mkOption { - description = "Extra files to link to the vault directory."; - type = attrsOf (submodule extraFilesOptions); - default = cfg.sharedSettings.extraFiles; - }; + options = mkOption { + type = attrsOf anything; + description = "Options to include in the plugin's `data.json`."; + default = { }; + }; + }; + }; + in + mkOption { + description = "Community plugins to install and activate."; + type = listOf (coercedTo package (p: { pkg = p; }) (submodule communityPluginsOptions)); + default = cfg.sharedSettings.communityPlugins; + }; + + cssSnippets = + let + checkCssPath = path: lib.filesystem.pathIsRegularFile path && lib.strings.hasSuffix ".css" path; + toCssName = path: lib.strings.removeSuffix ".css" (builtins.baseNameOf path); + cssSnippetsOptions = + { config, ... }: + { + options = { + enable = mkOption { + type = bool; + default = true; + description = "Whether to enable the snippet."; + }; + + name = mkOption { + type = str; + defaultText = literalExpression "lib.strings.removeSuffix \".css\" (builtins.baseNameOf source)"; + description = "Name of the snippet."; + }; + + source = mkOption { + type = nullOr (addCheck path checkCssPath); + description = "Path of the source file."; + default = null; + }; + + text = mkOption { + type = nullOr str; + description = "Text of the file."; + default = null; + }; + }; + + config.name = mkDefault (toCssName config.source); + }; + in + mkOption { + description = "CSS snippets to install."; + type = listOf ( + coercedTo (addCheck path checkCssPath) (p: { source = p; }) (submodule cssSnippetsOptions) + ); + default = cfg.sharedSettings.cssSnippets; + }; + + themes = + let + + themesOptions = + { config, ... }: + { + options = { + enable = mkOption { + type = bool; + default = true; + description = "Whether to set the theme as active."; + }; + + pkg = mkOption { + type = package; + description = "The theme package."; + }; + }; + }; + in + mkOption { + description = "Themes to install."; + type = listOf (coercedTo package (p: { pkg = p; }) (submodule themesOptions)); + default = cfg.sharedSettings.themes; + }; + + hotkeys = + let + hotkeysOptions = + { config, ... }: + { + options = { + modifiers = mkOption { + type = listOf str; + description = "The hotkey modifiers."; + default = [ ]; + }; + + key = mkOption { + type = str; + description = "The hotkey."; + }; + }; + }; + in + mkOption { + description = "Hotkeys to configure."; + type = attrsOf (listOf (submodule hotkeysOptions)); + default = cfg.sharedSettings.hotkeys; + }; + + extraFiles = + let + extraFilesOptions = + { name, config, ... }: + { + options = { + source = mkOption { + type = nullOr path; + description = "Path of the source file or directory."; + default = null; + }; + + text = mkOption { + type = nullOr str; + description = "Text of the file."; + default = null; + }; + + target = mkOption { + type = str; + defaultText = literalExpression "name"; + description = "Path to target relative to the vault's directory."; + }; + }; + + config.target = mkDefault name; + }; + in + mkOption { + description = "Extra files to link to the vault directory."; + type = attrsOf (submodule extraFilesOptions); + default = cfg.sharedSettings.extraFiles; + }; }; }; diff --git a/submodules/nixpkgs b/submodules/nixpkgs index befe9d2..e8e18ef 160000 --- a/submodules/nixpkgs +++ b/submodules/nixpkgs @@ -1 +1 @@ -Subproject commit befe9d27e7e7be485aae35d541f135c8471bd508 +Subproject commit e8e18ef6309d021fa600f5aa2665963d8cf76ab7