From c8023afcebe20bc1e7aebf9c08c04e77beaa3dbf Mon Sep 17 00:00:00 2001 From: Pim Kunis Date: Sat, 13 Apr 2024 16:37:18 +0200 Subject: [PATCH] reorganize --- flake-parts/kubenix.nix | 14 ++ flake-parts/kubenix/base.nix | 34 ---- flake-parts/kubenix/default.nix | 169 ------------------ flake.nix | 2 +- kubenix-modules/all.nix | 24 +++ kubenix-modules/base.nix | 41 +++++ .../kubenix => kubenix-modules}/bind9.nix | 0 .../cert-manager-manifests}/certificate.yaml | 0 .../certificaterequest.yaml | 0 .../cert-manager-manifests}/challenge.yaml | 0 .../clusterissuer.yaml | 0 .../cert-manager-manifests}/issuer.yaml | 0 .../cert-manager-manifests}/order.yaml | 0 kubenix-modules/cert-manager.nix | 15 ++ kubenix-modules/custom-types.nix | 35 ++++ .../kubenix => kubenix-modules}/cyberchef.nix | 0 .../kubenix => kubenix-modules}/dnsmasq.nix | 0 kubenix-modules/esrom.nix | 39 ++++ .../kubenix => kubenix-modules}/forgejo.nix | 0 .../kubenix => kubenix-modules}/freshrss.nix | 0 .../kubenix => kubenix-modules}/hedgedoc.nix | 0 .../kubenix => kubenix-modules}/inbucket.nix | 0 .../kitchenowl.nix | 0 .../kubenix => kubenix-modules}/kms.nix | 0 .../kubenix => kubenix-modules}/media.nix | 0 kubenix-modules/metallb.nix | 7 + .../kubenix => kubenix-modules}/nextcloud.nix | 0 .../paperless-ngx.nix | 0 .../kubenix => kubenix-modules}/pihole.nix | 0 .../kubenix => kubenix-modules}/radicale.nix | 0 .../kubenix => kubenix-modules}/syncthing.nix | 0 kubenix-modules/traefik.nix | 31 ++++ {modules => nixos-modules}/backups.nix | 0 {modules => nixos-modules}/data-sharing.nix | 0 {modules => nixos-modules}/default.nix | 0 {modules => nixos-modules}/globals.nix | 0 {modules => nixos-modules}/k3s/bootstrap.nix | 0 {modules => nixos-modules}/k3s/default.nix | 0 .../monitoring/default.nix | 0 .../monitoring/gatus-endpoints.nix | 0 .../networking/default.nix | 0 {modules => nixos-modules}/storage.nix | 0 42 files changed, 207 insertions(+), 204 deletions(-) create mode 100644 flake-parts/kubenix.nix delete mode 100644 flake-parts/kubenix/base.nix delete mode 100644 flake-parts/kubenix/default.nix create mode 100644 kubenix-modules/all.nix create mode 100644 kubenix-modules/base.nix rename {flake-parts/kubenix => kubenix-modules}/bind9.nix (100%) rename {flake-parts/kubenix => kubenix-modules/cert-manager-manifests}/certificate.yaml (100%) rename {flake-parts/kubenix => kubenix-modules/cert-manager-manifests}/certificaterequest.yaml (100%) rename {flake-parts/kubenix => kubenix-modules/cert-manager-manifests}/challenge.yaml (100%) rename {flake-parts/kubenix => kubenix-modules/cert-manager-manifests}/clusterissuer.yaml (100%) rename {flake-parts/kubenix => kubenix-modules/cert-manager-manifests}/issuer.yaml (100%) rename {flake-parts/kubenix => kubenix-modules/cert-manager-manifests}/order.yaml (100%) create mode 100644 kubenix-modules/cert-manager.nix create mode 100644 kubenix-modules/custom-types.nix rename {flake-parts/kubenix => kubenix-modules}/cyberchef.nix (100%) rename {flake-parts/kubenix => kubenix-modules}/dnsmasq.nix (100%) create mode 100644 kubenix-modules/esrom.nix rename {flake-parts/kubenix => kubenix-modules}/forgejo.nix (100%) rename {flake-parts/kubenix => kubenix-modules}/freshrss.nix (100%) rename {flake-parts/kubenix => kubenix-modules}/hedgedoc.nix (100%) rename {flake-parts/kubenix => kubenix-modules}/inbucket.nix (100%) rename {flake-parts/kubenix => kubenix-modules}/kitchenowl.nix (100%) rename {flake-parts/kubenix => kubenix-modules}/kms.nix (100%) rename {flake-parts/kubenix => kubenix-modules}/media.nix (100%) create mode 100644 kubenix-modules/metallb.nix rename {flake-parts/kubenix => kubenix-modules}/nextcloud.nix (100%) rename {flake-parts/kubenix => kubenix-modules}/paperless-ngx.nix (100%) rename {flake-parts/kubenix => kubenix-modules}/pihole.nix (100%) rename {flake-parts/kubenix => kubenix-modules}/radicale.nix (100%) rename {flake-parts/kubenix => kubenix-modules}/syncthing.nix (100%) create mode 100644 kubenix-modules/traefik.nix rename {modules => nixos-modules}/backups.nix (100%) rename {modules => nixos-modules}/data-sharing.nix (100%) rename {modules => nixos-modules}/default.nix (100%) rename {modules => nixos-modules}/globals.nix (100%) rename {modules => nixos-modules}/k3s/bootstrap.nix (100%) rename {modules => nixos-modules}/k3s/default.nix (100%) rename {modules => nixos-modules}/monitoring/default.nix (100%) rename {modules => nixos-modules}/monitoring/gatus-endpoints.nix (100%) rename {modules => nixos-modules}/networking/default.nix (100%) rename {modules => nixos-modules}/storage.nix (100%) diff --git a/flake-parts/kubenix.nix b/flake-parts/kubenix.nix new file mode 100644 index 0000000..38501ad --- /dev/null +++ b/flake-parts/kubenix.nix @@ -0,0 +1,14 @@ +{ flake-utils, kubenix, nixhelm, ... }: flake-utils.lib.eachDefaultSystem + (system: { + kubenix = kubenix.packages.${system}.default.override + { + specialArgs = { inherit kubenix nixhelm system; }; + module = { imports = [ ../kubenix-modules/all.nix ]; }; + }; + + kubenix-bootstrap = kubenix.packages.${system}.default.override + { + specialArgs = { inherit kubenix nixhelm system; }; + module = { imports = [ ../kubenix-modules/base.nix ]; }; + }; + }) diff --git a/flake-parts/kubenix/base.nix b/flake-parts/kubenix/base.nix deleted file mode 100644 index 76ba1af..0000000 --- a/flake-parts/kubenix/base.nix +++ /dev/null @@ -1,34 +0,0 @@ -# We deploy several resources that rely on "custom resource definitions". -# We must first import these resources definitions, before deploying resources that depend on them. -{ nixhelm, system, ... }: { - kubenix.project = "home"; - - kubernetes = { - kubeconfig = "~/.kube/config"; - - # TODO: These were copied from https://github.com/cert-manager/cert-manager/releases/download/v1.14.4/cert-manager.crds.yaml - # See https://cert-manager.io/docs/installation/helm/ - # Seems kubenix cannot import a list of resources, but only individual resources. - # Might be good to create a PR for this. - imports = [ - ./certificaterequest.yaml - ./certificate.yaml - ./challenge.yaml - ./clusterissuer.yaml - ./issuer.yaml - ./order.yaml - ]; - - helm.releases = { - metallb = { - chart = nixhelm.chartsDerivations.${system}.metallb.metallb; - includeCRDs = true; - }; - - cert-manager = { - chart = nixhelm.chartsDerivations.${system}.jetstack.cert-manager; - includeCRDs = false; - }; - }; - }; -} diff --git a/flake-parts/kubenix/default.nix b/flake-parts/kubenix/default.nix deleted file mode 100644 index 47599df..0000000 --- a/flake-parts/kubenix/default.nix +++ /dev/null @@ -1,169 +0,0 @@ -{ self, flake-utils, kubenix, nixhelm, ... }: flake-utils.lib.eachDefaultSystem - (system: { - kubenix = kubenix.packages.${system}.default.override - { - specialArgs = { - flake = self; - inherit nixhelm system; - }; - - module = { kubenix, ... }: { - imports = [ - kubenix.modules.k8s - kubenix.modules.helm - ./base.nix - ./freshrss.nix - ./cyberchef.nix - ./kms.nix - ./inbucket.nix - ./radicale.nix - ./syncthing.nix - ./nextcloud.nix - ./pihole.nix - ./hedgedoc.nix - ./paperless-ngx.nix - ./kitchenowl.nix - ./forgejo.nix - ./media.nix - ./bind9.nix - ./dnsmasq.nix - ]; - - kubernetes = { - customTypes = { - # HACK: These are dummy custom types. - # This is needed, because the CRDs imported as a chart are not available as Nix modules. - # There is no nix-based validation on resources defined using these types! - # See: https://github.com/hall/kubenix/issues/34 - ipAddressPool = { - attrName = "ipAddressPools"; - group = "metallb.io"; - version = "v1beta1"; - kind = "IPAddressPool"; - }; - - l2Advertisement = { - attrName = "l2Advertisements"; - group = "metallb.io"; - version = "v1beta1"; - kind = "L2Advertisement"; - }; - - helmChartConfig = { - attrName = "helmChartConfigs"; - group = "helm.cattle.io"; - version = "v1"; - kind = "HelmChartConfig"; - }; - - clusterIssuer = { - attrName = "clusterIssuers"; - group = "cert-manager.io"; - version = "v1"; - kind = "ClusterIssuer"; - }; - }; - - # TODO: These resources should probably exist within the kube-system namespace. - resources = { - ipAddressPools.main.spec.addresses = [ "192.168.30.128-192.168.30.200" ]; - l2Advertisements.main.metadata = { }; - - # NOTE: The name of each helmChartConfig must match the relevant chart name! - # Override Traefik's service with a static load balancer IP. - helmChartConfigs = { - traefik = { - metadata.namespace = "kube-system"; - - spec.valuesContent = '' - service: - spec: - loadBalancerIP: "192.168.30.128" - ports: - localsecure: - port: 8444 - expose: true - exposedPort: 444 - protocol: TCP - tls: - enabled: true - options: "" - certResolver: "" - domains: [] - providers: - kubernetesIngress: - allowExternalNameServices: true - ''; - }; - }; - - clusterIssuers.letsencrypt = { - metadata.namespace = "kube-system"; - - spec.acme = { - server = "https://acme-v02.api.letsencrypt.org/directory"; - email = "pim@kunis.nl"; - privateKeySecretRef.name = "letsencrypt-private-key"; - solvers = [{ - selector = { }; - http01.ingress.class = "traefik"; - }]; - }; - }; - - services.esrom.spec = { - type = "ExternalName"; - externalName = "esrom.dmz"; - ports = [{ - port = 80; - targetPort = 80; - }]; - }; - - ingresses.esrom = { - metadata.annotations."cert-manager.io/cluster-issuer" = "letsencrypt"; - - spec = { - ingressClassName = "traefik"; - - rules = [{ - host = "esrom.kun.is"; - - http.paths = [{ - path = "/"; - pathType = "Prefix"; - - backend.service = { - name = "esrom"; - port.number = 80; - }; - }]; - }]; - - tls = [{ - secretName = "esrom-tls"; - hosts = [ "esrom.kun.is" ]; - }]; - }; - }; - }; - }; - }; - }; - - kubenix-bootstrap = kubenix.packages.${system}.default.override - { - specialArgs = { - flake = self; - inherit nixhelm system; - }; - - module = { kubenix, ... }: { - imports = [ - kubenix.modules.k8s - kubenix.modules.helm - ./base.nix - ]; - }; - }; - }) diff --git a/flake.nix b/flake.nix index 7d90175..f47fc2d 100644 --- a/flake.nix +++ b/flake.nix @@ -46,7 +46,7 @@ ./flake-parts/checks.nix ./flake-parts/deploy.nix ./flake-parts/nixos.nix - ./flake-parts/kubenix + ./flake-parts/kubenix.nix ] // (flake-utils.lib.eachDefaultSystem (system: { formatter = nixpkgs.legacyPackages.${system}.nixfmt; })); diff --git a/kubenix-modules/all.nix b/kubenix-modules/all.nix new file mode 100644 index 0000000..b4c1075 --- /dev/null +++ b/kubenix-modules/all.nix @@ -0,0 +1,24 @@ +{ + imports = [ + ./base.nix + ./custom-types.nix + ./freshrss.nix + ./cyberchef.nix + ./kms.nix + ./inbucket.nix + ./radicale.nix + ./syncthing.nix + ./nextcloud.nix + ./pihole.nix + ./hedgedoc.nix + ./paperless-ngx.nix + ./kitchenowl.nix + ./forgejo.nix + ./media.nix + ./bind9.nix + ./dnsmasq.nix + ./esrom.nix + ./metallb.nix + ./cert-manager.nix + ]; +} diff --git a/kubenix-modules/base.nix b/kubenix-modules/base.nix new file mode 100644 index 0000000..d7e8522 --- /dev/null +++ b/kubenix-modules/base.nix @@ -0,0 +1,41 @@ +# We deploy several resources that rely on "custom resource definitions". +# We must first import these resources definitions, before deploying resources that depend on them. +{ kubenix, nixhelm, system, ... }: { + imports = [ + kubenix.modules.k8s + kubenix.modules.helm + ]; + + config = { + kubenix.project = "home"; + + kubernetes = { + kubeconfig = "~/.kube/config"; + + # TODO: These were copied from https://github.com/cert-manager/cert-manager/releases/download/v1.14.4/cert-manager.crds.yaml + # See https://cert-manager.io/docs/installation/helm/ + # Seems kubenix cannot import a list of resources, but only individual resources. + # Might be good to create a PR for this. + imports = [ + ./cert-manager-manifests/certificaterequest.yaml + ./cert-manager-manifests/certificate.yaml + ./cert-manager-manifests/challenge.yaml + ./cert-manager-manifests/clusterissuer.yaml + ./cert-manager-manifests/issuer.yaml + ./cert-manager-manifests/order.yaml + ]; + + helm.releases = { + metallb = { + chart = nixhelm.chartsDerivations.${system}.metallb.metallb; + includeCRDs = true; + }; + + cert-manager = { + chart = nixhelm.chartsDerivations.${system}.jetstack.cert-manager; + includeCRDs = false; + }; + }; + }; + }; +} diff --git a/flake-parts/kubenix/bind9.nix b/kubenix-modules/bind9.nix similarity index 100% rename from flake-parts/kubenix/bind9.nix rename to kubenix-modules/bind9.nix diff --git a/flake-parts/kubenix/certificate.yaml b/kubenix-modules/cert-manager-manifests/certificate.yaml similarity index 100% rename from flake-parts/kubenix/certificate.yaml rename to kubenix-modules/cert-manager-manifests/certificate.yaml diff --git a/flake-parts/kubenix/certificaterequest.yaml b/kubenix-modules/cert-manager-manifests/certificaterequest.yaml similarity index 100% rename from flake-parts/kubenix/certificaterequest.yaml rename to kubenix-modules/cert-manager-manifests/certificaterequest.yaml diff --git a/flake-parts/kubenix/challenge.yaml b/kubenix-modules/cert-manager-manifests/challenge.yaml similarity index 100% rename from flake-parts/kubenix/challenge.yaml rename to kubenix-modules/cert-manager-manifests/challenge.yaml diff --git a/flake-parts/kubenix/clusterissuer.yaml b/kubenix-modules/cert-manager-manifests/clusterissuer.yaml similarity index 100% rename from flake-parts/kubenix/clusterissuer.yaml rename to kubenix-modules/cert-manager-manifests/clusterissuer.yaml diff --git a/flake-parts/kubenix/issuer.yaml b/kubenix-modules/cert-manager-manifests/issuer.yaml similarity index 100% rename from flake-parts/kubenix/issuer.yaml rename to kubenix-modules/cert-manager-manifests/issuer.yaml diff --git a/flake-parts/kubenix/order.yaml b/kubenix-modules/cert-manager-manifests/order.yaml similarity index 100% rename from flake-parts/kubenix/order.yaml rename to kubenix-modules/cert-manager-manifests/order.yaml diff --git a/kubenix-modules/cert-manager.nix b/kubenix-modules/cert-manager.nix new file mode 100644 index 0000000..ff3dbd1 --- /dev/null +++ b/kubenix-modules/cert-manager.nix @@ -0,0 +1,15 @@ +{ + kubernetes.resources.clusterIssuers.letsencrypt = { + metadata.namespace = "kube-system"; + + spec.acme = { + server = "https://acme-v02.api.letsencrypt.org/directory"; + email = "pim@kunis.nl"; + privateKeySecretRef.name = "letsencrypt-private-key"; + solvers = [{ + selector = { }; + http01.ingress.class = "traefik"; + }]; + }; + }; +} diff --git a/kubenix-modules/custom-types.nix b/kubenix-modules/custom-types.nix new file mode 100644 index 0000000..5941a95 --- /dev/null +++ b/kubenix-modules/custom-types.nix @@ -0,0 +1,35 @@ +{ + kubernetes.customTypes = { + # HACK: These are dummy custom types. + # This is needed, because the CRDs imported as a chart are not available as Nix modules. + # There is no nix-based validation on resources defined using these types! + # See: https://github.com/hall/kubenix/issues/34 + ipAddressPool = { + attrName = "ipAddressPools"; + group = "metallb.io"; + version = "v1beta1"; + kind = "IPAddressPool"; + }; + + l2Advertisement = { + attrName = "l2Advertisements"; + group = "metallb.io"; + version = "v1beta1"; + kind = "L2Advertisement"; + }; + + helmChartConfig = { + attrName = "helmChartConfigs"; + group = "helm.cattle.io"; + version = "v1"; + kind = "HelmChartConfig"; + }; + + clusterIssuer = { + attrName = "clusterIssuers"; + group = "cert-manager.io"; + version = "v1"; + kind = "ClusterIssuer"; + }; + }; +} diff --git a/flake-parts/kubenix/cyberchef.nix b/kubenix-modules/cyberchef.nix similarity index 100% rename from flake-parts/kubenix/cyberchef.nix rename to kubenix-modules/cyberchef.nix diff --git a/flake-parts/kubenix/dnsmasq.nix b/kubenix-modules/dnsmasq.nix similarity index 100% rename from flake-parts/kubenix/dnsmasq.nix rename to kubenix-modules/dnsmasq.nix diff --git a/kubenix-modules/esrom.nix b/kubenix-modules/esrom.nix new file mode 100644 index 0000000..79cf4e3 --- /dev/null +++ b/kubenix-modules/esrom.nix @@ -0,0 +1,39 @@ +{ + kubernetes.resources = { + services.esrom.spec = { + type = "ExternalName"; + externalName = "esrom.dmz"; + ports = [{ + port = 80; + targetPort = 80; + }]; + }; + + ingresses.esrom = { + metadata.annotations."cert-manager.io/cluster-issuer" = "letsencrypt"; + + spec = { + ingressClassName = "traefik"; + + rules = [{ + host = "esrom.kun.is"; + + http.paths = [{ + path = "/"; + pathType = "Prefix"; + + backend.service = { + name = "esrom"; + port.number = 80; + }; + }]; + }]; + + tls = [{ + secretName = "esrom-tls"; + hosts = [ "esrom.kun.is" ]; + }]; + }; + }; + }; +} diff --git a/flake-parts/kubenix/forgejo.nix b/kubenix-modules/forgejo.nix similarity index 100% rename from flake-parts/kubenix/forgejo.nix rename to kubenix-modules/forgejo.nix diff --git a/flake-parts/kubenix/freshrss.nix b/kubenix-modules/freshrss.nix similarity index 100% rename from flake-parts/kubenix/freshrss.nix rename to kubenix-modules/freshrss.nix diff --git a/flake-parts/kubenix/hedgedoc.nix b/kubenix-modules/hedgedoc.nix similarity index 100% rename from flake-parts/kubenix/hedgedoc.nix rename to kubenix-modules/hedgedoc.nix diff --git a/flake-parts/kubenix/inbucket.nix b/kubenix-modules/inbucket.nix similarity index 100% rename from flake-parts/kubenix/inbucket.nix rename to kubenix-modules/inbucket.nix diff --git a/flake-parts/kubenix/kitchenowl.nix b/kubenix-modules/kitchenowl.nix similarity index 100% rename from flake-parts/kubenix/kitchenowl.nix rename to kubenix-modules/kitchenowl.nix diff --git a/flake-parts/kubenix/kms.nix b/kubenix-modules/kms.nix similarity index 100% rename from flake-parts/kubenix/kms.nix rename to kubenix-modules/kms.nix diff --git a/flake-parts/kubenix/media.nix b/kubenix-modules/media.nix similarity index 100% rename from flake-parts/kubenix/media.nix rename to kubenix-modules/media.nix diff --git a/kubenix-modules/metallb.nix b/kubenix-modules/metallb.nix new file mode 100644 index 0000000..5988636 --- /dev/null +++ b/kubenix-modules/metallb.nix @@ -0,0 +1,7 @@ +# TODO: These resources should probably exist within the kube-system namespace. +{ + kubernetes.resources = { + ipAddressPools.main.spec.addresses = [ "192.168.30.128-192.168.30.200" ]; + l2Advertisements.main.metadata = { }; + }; +} diff --git a/flake-parts/kubenix/nextcloud.nix b/kubenix-modules/nextcloud.nix similarity index 100% rename from flake-parts/kubenix/nextcloud.nix rename to kubenix-modules/nextcloud.nix diff --git a/flake-parts/kubenix/paperless-ngx.nix b/kubenix-modules/paperless-ngx.nix similarity index 100% rename from flake-parts/kubenix/paperless-ngx.nix rename to kubenix-modules/paperless-ngx.nix diff --git a/flake-parts/kubenix/pihole.nix b/kubenix-modules/pihole.nix similarity index 100% rename from flake-parts/kubenix/pihole.nix rename to kubenix-modules/pihole.nix diff --git a/flake-parts/kubenix/radicale.nix b/kubenix-modules/radicale.nix similarity index 100% rename from flake-parts/kubenix/radicale.nix rename to kubenix-modules/radicale.nix diff --git a/flake-parts/kubenix/syncthing.nix b/kubenix-modules/syncthing.nix similarity index 100% rename from flake-parts/kubenix/syncthing.nix rename to kubenix-modules/syncthing.nix diff --git a/kubenix-modules/traefik.nix b/kubenix-modules/traefik.nix new file mode 100644 index 0000000..73133d3 --- /dev/null +++ b/kubenix-modules/traefik.nix @@ -0,0 +1,31 @@ +{ + kubernetes.resources.helmChartConfigs = { + traefik = { + metadata.namespace = "kube-system"; + + # Override Traefik's service with a static load balancer IP. + # Create endpoint for HTTPS on port444. + # Allow external name services for esrom. + spec.valuesContent = '' + service: + spec: + loadBalancerIP: "192.168.30.128" + ports: + localsecure: + port: 8444 + expose: true + exposedPort: 444 + protocol: TCP + tls: + enabled: true + options: "" + certResolver: "" + domains: [] + providers: + kubernetesIngress: + allowExternalNameServices: true + ''; + }; + }; + +} diff --git a/modules/backups.nix b/nixos-modules/backups.nix similarity index 100% rename from modules/backups.nix rename to nixos-modules/backups.nix diff --git a/modules/data-sharing.nix b/nixos-modules/data-sharing.nix similarity index 100% rename from modules/data-sharing.nix rename to nixos-modules/data-sharing.nix diff --git a/modules/default.nix b/nixos-modules/default.nix similarity index 100% rename from modules/default.nix rename to nixos-modules/default.nix diff --git a/modules/globals.nix b/nixos-modules/globals.nix similarity index 100% rename from modules/globals.nix rename to nixos-modules/globals.nix diff --git a/modules/k3s/bootstrap.nix b/nixos-modules/k3s/bootstrap.nix similarity index 100% rename from modules/k3s/bootstrap.nix rename to nixos-modules/k3s/bootstrap.nix diff --git a/modules/k3s/default.nix b/nixos-modules/k3s/default.nix similarity index 100% rename from modules/k3s/default.nix rename to nixos-modules/k3s/default.nix diff --git a/modules/monitoring/default.nix b/nixos-modules/monitoring/default.nix similarity index 100% rename from modules/monitoring/default.nix rename to nixos-modules/monitoring/default.nix diff --git a/modules/monitoring/gatus-endpoints.nix b/nixos-modules/monitoring/gatus-endpoints.nix similarity index 100% rename from modules/monitoring/gatus-endpoints.nix rename to nixos-modules/monitoring/gatus-endpoints.nix diff --git a/modules/networking/default.nix b/nixos-modules/networking/default.nix similarity index 100% rename from modules/networking/default.nix rename to nixos-modules/networking/default.nix diff --git a/modules/storage.nix b/nixos-modules/storage.nix similarity index 100% rename from modules/storage.nix rename to nixos-modules/storage.nix