From 94cd725a825705ad58fa406c2aad6fa37c6e2630 Mon Sep 17 00:00:00 2001 From: technofab Date: Sat, 9 Mar 2024 14:26:09 +0000 Subject: [PATCH] feat: add some nixlets --- flake.nix | 3 + nixlets/attic/configMap.nix | 9 + nixlets/attic/default.nix | 7 + nixlets/attic/deployment.nix | 42 +++++ nixlets/attic/service.nix | 16 ++ nixlets/attic/values.nix | 177 ++++++++++++++++++++ nixlets/mosquitto/configMap.nix | 9 + nixlets/mosquitto/default.nix | 8 + nixlets/mosquitto/persistentVolumeClaim.nix | 8 + nixlets/mosquitto/service.nix | 17 ++ nixlets/mosquitto/statefulSet.nix | 40 +++++ nixlets/mosquitto/values.nix | 64 +++++++ nixlets/postgres/default.nix | 7 + nixlets/postgres/persistentVolumeClaim.nix | 8 + nixlets/postgres/service.nix | 17 ++ nixlets/postgres/statefulSet.nix | 26 +++ nixlets/postgres/values.nix | 50 ++++++ 17 files changed, 508 insertions(+) create mode 100644 nixlets/attic/configMap.nix create mode 100644 nixlets/attic/default.nix create mode 100644 nixlets/attic/deployment.nix create mode 100644 nixlets/attic/service.nix create mode 100644 nixlets/attic/values.nix create mode 100644 nixlets/mosquitto/configMap.nix create mode 100644 nixlets/mosquitto/default.nix create mode 100644 nixlets/mosquitto/persistentVolumeClaim.nix create mode 100644 nixlets/mosquitto/service.nix create mode 100644 nixlets/mosquitto/statefulSet.nix create mode 100644 nixlets/mosquitto/values.nix create mode 100644 nixlets/postgres/default.nix create mode 100644 nixlets/postgres/persistentVolumeClaim.nix create mode 100644 nixlets/postgres/service.nix create mode 100644 nixlets/postgres/statefulSet.nix create mode 100644 nixlets/postgres/values.nix diff --git a/flake.nix b/flake.nix index 2019f6b..db239fd 100644 --- a/flake.nix +++ b/flake.nix @@ -20,6 +20,9 @@ # █░▀█ █ █░█ █▄▄ ██▄ ░█░ ▄█ nixlets = { # = utils.mkNixlet ./nixlets/; + mosquitto = utils.mkNixlet ./nixlets/mosquitto; + attic = utils.mkNixlet ./nixlets/attic; + postgres = utils.mkNixlet ./nixlets/postgres; }; }; perSystem = { diff --git a/nixlets/attic/configMap.nix b/nixlets/attic/configMap.nix new file mode 100644 index 0000000..d8c5c6d --- /dev/null +++ b/nixlets/attic/configMap.nix @@ -0,0 +1,9 @@ +{values, ...}: { + kubernetes.resources = { + configMaps."${values.uniqueName}-config" = { + data = { + "config.toml" = values.configToml; + }; + }; + }; +} diff --git a/nixlets/attic/default.nix b/nixlets/attic/default.nix new file mode 100644 index 0000000..0a00ffe --- /dev/null +++ b/nixlets/attic/default.nix @@ -0,0 +1,7 @@ +{...}: { + imports = [ + ./deployment.nix + ./configMap.nix + ./service.nix + ]; +} diff --git a/nixlets/attic/deployment.nix b/nixlets/attic/deployment.nix new file mode 100644 index 0000000..5ed270d --- /dev/null +++ b/nixlets/attic/deployment.nix @@ -0,0 +1,42 @@ +{values, ...}: { + kubernetes.resources = { + deployments."${values.uniqueName}" = { + spec = { + replicas = values.replicaCount; + selector.matchLabels.app = "${values.uniqueName}"; + template = { + metadata.labels.app = "${values.uniqueName}"; + spec = { + securityContext.fsGroup = 1000; + containers."api-server" = { + image = "${values.image.repository}:${values.image.tag}"; + imagePullPolicy = values.image.pullPolicy; + command = ["atticd" "-f" "/etc/attic/config.toml" "--mode" "monolithic"]; # TODO: only api-server can be replicated + envFrom = [ + {secretRef.name = "${values.uniqueName}-env";} + ]; + volumeMounts = { + "config" = { + name = "config"; + mountPath = "/etc/attic"; + readOnly = true; + }; + }; + }; + volumes = { + "config".configMap = { + name = "${values.uniqueName}-config"; + items = [ + { + key = "config.toml"; + path = "config.toml"; + } + ]; + }; + }; + }; + }; + }; + }; + }; +} diff --git a/nixlets/attic/service.nix b/nixlets/attic/service.nix new file mode 100644 index 0000000..8bd5366 --- /dev/null +++ b/nixlets/attic/service.nix @@ -0,0 +1,16 @@ +{values, ...}: { + kubernetes.resources = { + services."${values.uniqueName}" = { + spec = { + selector.app = "${values.uniqueName}"; + ports = [ + { + name = "http"; + port = 8080; + } + ]; + type = values.service.type; + }; + }; + }; +} diff --git a/nixlets/attic/values.nix b/nixlets/attic/values.nix new file mode 100644 index 0000000..c425878 --- /dev/null +++ b/nixlets/attic/values.nix @@ -0,0 +1,177 @@ +{ + lib, + utils, + project, + ... +}: +with lib; { + # for some basic values see https://github.com/helm/examples/blob/4888ba8fb8180dd0c36d1e84c1fcafc6efd81532/charts/hello-world/values.yaml + options = { + replicaCount = mkOption { + type = types.int; + default = 1; + }; + image = utils.mkNestedOption { + repository = mkOption { + type = types.str; + default = "ghcr.io/zhaofengli/attic"; + }; + pullPolicy = mkOption { + type = types.str; + default = "IfNotPresent"; + }; + tag = mkOption { + type = types.str; + default = "latest"; + }; + }; + configToml = mkOption { + type = types.str; + default = '' + # Socket address to listen on + listen = "[::]:8080" + + # Allowed `Host` headers + # + # This _must_ be configured for production use. If unconfigured or the + # list is empty, all `Host` headers are allowed. + allowed-hosts = [] + + # The canonical API endpoint of this server + # + # This is the endpoint exposed to clients in `cache-config` responses. + # + # This _must_ be configured for production use. If not configured, the + # API endpoint is synthesized from the client's `Host` header which may + # be insecure. + # + # The API endpoint _must_ end with a slash (e.g., `https://domain.tld/attic/` + # not `https://domain.tld/attic`). + #api-endpoint = "https://your.domain.tld/" + + # Whether to soft-delete caches + # + # If this is enabled, caches are soft-deleted instead of actually + # removed from the database. Note that soft-deleted caches cannot + # have their names reused as long as the original database records + # are there. + #soft-delete-caches = false + + # Whether to require fully uploading a NAR if it exists in the global cache. + # + # If set to false, simply knowing the NAR hash is enough for + # an uploader to gain access to an existing NAR in the global + # cache. + #require-proof-of-possession = true + + # JWT signing token + # + # Set this to the Base64 encoding of some random data. + # You can also set it via the `ATTIC_SERVER_TOKEN_HS256_SECRET_BASE64` environment + # variable. + token-hs256-secret-base64 = "" + + # Database connection + [database] + # Connection URL + # + # For production use it's recommended to use PostgreSQL. + url = "sqlite:///data/attic.db" + + # Whether to enable sending on periodic heartbeat queries + # + # If enabled, a heartbeat query will be sent every minute + #heartbeat = false + + # File storage configuration + [storage] + # Storage type + # + # Can be "local" or "s3". + type = "local" + + # ## Local storage + + # The directory to store all files under + path = "/data/storage" + + # ## S3 Storage (set type to "s3" and uncomment below) + + # The AWS region + #region = "us-east-1" + + # The name of the bucket + #bucket = "some-bucket" + + # Custom S3 endpoint + # + # Set this if you are using an S3-compatible object storage (e.g., Minio). + #endpoint = "https://xxx.r2.cloudflarestorage.com" + + # Credentials + # + # If unset, the credentials are read from the `AWS_ACCESS_KEY_ID` and + # `AWS_SECRET_ACCESS_KEY` environment variables. + #[storage.credentials] + # access_key_id = "" + # secret_access_key = "" + + # Data chunking + # + # Warning: If you change any of the values here, it will be + # difficult to reuse existing chunks for newly-uploaded NARs + # since the cutpoints will be different. As a result, the + # deduplication ratio will suffer for a while after the change. + [chunking] + # The minimum NAR size to trigger chunking + # + # If 0, chunking is disabled entirely for newly-uploaded NARs. + # If 1, all NARs are chunked. + nar-size-threshold = 65536 # chunk files that are 64 KiB or larger + + # The preferred minimum size of a chunk, in bytes + min-size = 16384 # 16 KiB + + # The preferred average size of a chunk, in bytes + avg-size = 65536 # 64 KiB + + # The preferred maximum size of a chunk, in bytes + max-size = 262144 # 256 KiB + + # Compression + [compression] + # Compression type + # + # Can be "none", "brotli", "zstd", or "xz" + type = "zstd" + + # Compression level + #level = 8 + + # Garbage collection + [garbage-collection] + # The frequency to run garbage collection at + # + # By default it's 12 hours. You can use natural language + # to specify the interval, like "1 day". + # + # If zero, automatic garbage collection is disabled, but + # it can still be run manually with `atticd --mode garbage-collector-once`. + interval = "12 hours" + + # Default retention period + # + # Zero (default) means time-based garbage-collection is + # disabled by default. You can enable it on a per-cache basis. + #default-retention-period = "6 months" + ''; + }; + + # internal + uniqueName = mkOption { + internal = true; + type = types.str; + default = "${project}-atticd"; + }; + }; +} diff --git a/nixlets/mosquitto/configMap.nix b/nixlets/mosquitto/configMap.nix new file mode 100644 index 0000000..2e8f3a0 --- /dev/null +++ b/nixlets/mosquitto/configMap.nix @@ -0,0 +1,9 @@ +{values, ...}: { + kubernetes.resources = { + configMaps."${values.uniqueName}-config" = { + data = { + "mosquitto.conf" = values.configContent; + }; + }; + }; +} diff --git a/nixlets/mosquitto/default.nix b/nixlets/mosquitto/default.nix new file mode 100644 index 0000000..60ed286 --- /dev/null +++ b/nixlets/mosquitto/default.nix @@ -0,0 +1,8 @@ +{...}: { + imports = [ + ./statefulSet.nix + ./service.nix + ./configMap.nix + ./persistentVolumeClaim.nix + ]; +} diff --git a/nixlets/mosquitto/persistentVolumeClaim.nix b/nixlets/mosquitto/persistentVolumeClaim.nix new file mode 100644 index 0000000..7c323c1 --- /dev/null +++ b/nixlets/mosquitto/persistentVolumeClaim.nix @@ -0,0 +1,8 @@ +{values, ...}: { + kubernetes.resources = { + persistentVolumeClaims."${values.uniqueName}-data".spec = { + accessModes = ["ReadWriteOnce"]; + resources.requests.storage = values.storage; + }; + }; +} diff --git a/nixlets/mosquitto/service.nix b/nixlets/mosquitto/service.nix new file mode 100644 index 0000000..611c048 --- /dev/null +++ b/nixlets/mosquitto/service.nix @@ -0,0 +1,17 @@ +{values, ...}: { + kubernetes.resources = { + services."${values.uniqueName}" = { + spec = { + selector.app = "${values.uniqueName}"; + ports = [ + { + name = "mqtt"; + port = values.service.port; + targetPort = 1883; + } + ]; + type = values.service.type; + }; + }; + }; +} diff --git a/nixlets/mosquitto/statefulSet.nix b/nixlets/mosquitto/statefulSet.nix new file mode 100644 index 0000000..defa832 --- /dev/null +++ b/nixlets/mosquitto/statefulSet.nix @@ -0,0 +1,40 @@ +{values, ...}: { + kubernetes.resources = { + statefulSets."${values.uniqueName}".spec = { + replicas = values.replicaCount; + selector.matchLabels.name = "${values.uniqueName}"; + serviceName = "${values.uniqueName}"; + template = { + metadata.labels.name = "${values.uniqueName}"; + spec = { + containers."mosquitto" = { + image = "${values.image.repository}:${values.image.tag}"; + imagePullPolicy = values.image.pullPolicy; + ports."mqtt".containerPort = 1883; + volumeMounts = { + "password-file" = { + name = "password-file"; + mountPath = "/mosquitto/config/password_file"; + subPath = "password_file"; + }; + "config" = { + name = "config"; + mountPath = "/mosquitto/config/mosquitto.conf"; + subPath = "mosquitto.conf"; + }; + "data" = { + name = "data"; + mountPath = "/mosquitto/data"; + }; + }; + }; + volumes = { + "password-file".secret.secretName = "${values.uniqueName}"; + "config".configMap.name = "${values.uniqueName}-config"; + "data".persistentVolumeClaim.claimName = "${values.uniqueName}-data"; + }; + }; + }; + }; + }; +} diff --git a/nixlets/mosquitto/values.nix b/nixlets/mosquitto/values.nix new file mode 100644 index 0000000..3b9c2e3 --- /dev/null +++ b/nixlets/mosquitto/values.nix @@ -0,0 +1,64 @@ +{ + lib, + utils, + project, + ... +}: +with lib; { + # for some basic values see https://github.com/helm/examples/blob/4888ba8fb8180dd0c36d1e84c1fcafc6efd81532/charts/hello-world/values.yaml + options = { + replicaCount = mkOption { + type = types.int; + default = 1; + }; + image = utils.mkNestedOption { + repository = mkOption { + type = types.str; + default = "eclipse-mosquitto"; + }; + tag = mkOption { + type = types.str; + default = "latest"; + }; + pullPolicy = mkOption { + type = types.str; + default = "IfNotPresent"; + }; + }; + service = utils.mkNestedOption { + port = mkOption { + type = types.int; + default = 1883; + }; + type = mkOption { + type = types.str; + default = "ClusterIP"; + }; + }; + storage = mkOption { + type = types.str; + default = "5G"; + }; + passwordAuthEnabled = mkOption { + type = types.bool; + default = true; + }; + configContent = mkOption { + type = types.str; + default = '' + listener 1883 + persistence true + persistence_location /mosquitto/data + autosave_interval 1800 + password_file /mosquitto/config/password_file + ''; + }; + + # internal + uniqueName = mkOption { + internal = true; + type = types.str; + default = "${project}-mosquitto"; + }; + }; +} diff --git a/nixlets/postgres/default.nix b/nixlets/postgres/default.nix new file mode 100644 index 0000000..bf3991f --- /dev/null +++ b/nixlets/postgres/default.nix @@ -0,0 +1,7 @@ +{...}: { + imports = [ + ./statefulSet.nix + ./service.nix + ./persistentVolumeClaim.nix + ]; +} diff --git a/nixlets/postgres/persistentVolumeClaim.nix b/nixlets/postgres/persistentVolumeClaim.nix new file mode 100644 index 0000000..7c323c1 --- /dev/null +++ b/nixlets/postgres/persistentVolumeClaim.nix @@ -0,0 +1,8 @@ +{values, ...}: { + kubernetes.resources = { + persistentVolumeClaims."${values.uniqueName}-data".spec = { + accessModes = ["ReadWriteOnce"]; + resources.requests.storage = values.storage; + }; + }; +} diff --git a/nixlets/postgres/service.nix b/nixlets/postgres/service.nix new file mode 100644 index 0000000..11c011a --- /dev/null +++ b/nixlets/postgres/service.nix @@ -0,0 +1,17 @@ +{values, ...}: { + kubernetes.resources = { + services."${values.uniqueName}" = { + spec = { + selector.app = "${values.uniqueName}"; + ports = [ + { + name = "tcp"; + port = values.service.port; + targetPort = 5432; + } + ]; + type = values.service.type; + }; + }; + }; +} diff --git a/nixlets/postgres/statefulSet.nix b/nixlets/postgres/statefulSet.nix new file mode 100644 index 0000000..76f5d71 --- /dev/null +++ b/nixlets/postgres/statefulSet.nix @@ -0,0 +1,26 @@ +{values, ...}: { + kubernetes.resources = { + statefulSets."${values.uniqueName}".spec = { + replicas = values.replicaCount; + selector.matchLabels.name = "${values.uniqueName}"; + serviceName = "${values.uniqueName}"; + template = { + metadata.labels.name = "${values.uniqueName}"; + spec = { + containers."postgres" = { + image = "${values.image.repository}:${values.image.tag}"; + imagePullPolicy = values.image.pullPolicy; + ports."tcp".containerPort = 5432; + volumeMounts."data" = { + name = "data"; + mountPath = "/var/lib/postgresql/data"; + }; + }; + volumes = { + "data".persistentVolumeClaim.claimName = "${values.uniqueName}-data"; + }; + }; + }; + }; + }; +} diff --git a/nixlets/postgres/values.nix b/nixlets/postgres/values.nix new file mode 100644 index 0000000..7b3bc0f --- /dev/null +++ b/nixlets/postgres/values.nix @@ -0,0 +1,50 @@ +{ + lib, + utils, + project, + ... +}: +with lib; { + # for some basic values see https://github.com/helm/examples/blob/4888ba8fb8180dd0c36d1e84c1fcafc6efd81532/charts/hello-world/values.yaml + options = { + replicaCount = mkOption { + type = types.int; + default = 1; + }; + image = utils.mkNestedOption { + repository = mkOption { + type = types.str; + default = "postgres"; + }; + tag = mkOption { + type = types.str; + default = "latest"; + }; + pullPolicy = mkOption { + type = types.str; + default = "IfNotPresent"; + }; + }; + service = utils.mkNestedOption { + port = mkOption { + type = types.int; + default = 5432; + }; + type = mkOption { + type = types.str; + default = "ClusterIP"; + }; + }; + storage = mkOption { + type = types.str; + default = "5G"; + }; + + # internal + uniqueName = mkOption { + internal = true; + type = types.str; + default = "${project}-postgres"; + }; + }; +}