about summary refs log tree commit diff
path: root/modules
diff options
context:
space:
mode:
authorAzat Bahawi <azat@bahawi.net>2023-11-13 10:40:41 +0300
committerAzat Bahawi <azat@bahawi.net>2023-11-13 10:40:41 +0300
commita3f9fde2a2d43dd477f402bd4b8df2a1cd29ca43 (patch)
treecbd0c2457daa6865eb33b5389ec40309e60868a9 /modules
parent2023-11-12 (diff)
2023-11-13
Diffstat (limited to '')
-rw-r--r--modules/common/common/default.nix2
-rw-r--r--modules/common/common/nix.nix (renamed from modules/common/common/nix/default.nix)82
-rw-r--r--modules/common/common/nix/patches/alejandra-no-ads.patch33
-rw-r--r--modules/common/profiles/dev/editorconfig.ini85
-rw-r--r--modules/nixos/lidarr.nix24
-rw-r--r--modules/nixos/monitoring/default.nix402
-rw-r--r--modules/nixos/plausible.nix1
-rw-r--r--patches/prismlauncher-allow-offline-accounts.patch (renamed from modules/common/common/nix/patches/prismlauncher-allow-offline-accounts.patch)0
-rw-r--r--patches/telegram-desktop-no-ads.patch (renamed from modules/common/common/nix/patches/telegram-desktop-no-ads.patch)0
-rw-r--r--patches/vesktop-no-anime.patch (renamed from modules/common/common/nix/patches/vesktop-no-anime.patch)0
10 files changed, 276 insertions, 353 deletions
diff --git a/modules/common/common/default.nix b/modules/common/common/default.nix
index a516ef3..0087754 100644
--- a/modules/common/common/default.nix
+++ b/modules/common/common/default.nix
@@ -4,7 +4,7 @@ _: {
     ./home-manager.nix
     ./locale.nix
     ./networking.nix
-    ./nix
+    ./nix.nix
     ./secrets.nix
     ./shell
     ./users.nix
diff --git a/modules/common/common/nix/default.nix b/modules/common/common/nix.nix
index 370667c..ec3a4a3 100644
--- a/modules/common/common/nix/default.nix
+++ b/modules/common/common/nix.nix
@@ -4,7 +4,6 @@
   lib,
   localUsername ? lib.my.username,
   pkgs,
-  pkgsMaster,
   this,
   ...
 }:
@@ -84,84 +83,8 @@ with lib; {
   nixpkgs.overlays = with inputs; [
     self.overlays.default
     nur.overlay
-    (
-      _: super: {
-        grc = super.grc.overrideAttrs (_: final: {
-          version = "unstable-2021-08-12";
-          src = super.fetchFromGitHub {
-            owner = "garabik";
-            repo = "grc";
-            rev = "4d6a51fd78ad7e19af8dd12b2a828d1807267079";
-            hash = "sha256-SmOZrgV0lgLryFoxADU15IKJ7jhxXar0MgbsV/z1GaE=";
-          };
-          patches = [
-            (super.fetchpatch {
-              url = "https://patch-diff.githubusercontent.com/raw/garabik/grc/pull/214.patch";
-              hash = "sha256-VNr9jl5oFbFNJbGsjflwFV3oTbCzJ0lBIZA4eyeoXLY=";
-            })
-          ];
-          postPatch =
-            final.postPatch
-            + ''
-              substituteInPlace grc.conf \
-                --replace "^([/\w\.]+\/)" "^([/\w\.\-]+\/)"
-            '';
-        });
-
-        alejandra = super.alejandra.overrideAttrs (_: final: {
-          patches =
-            final.patches
-            ++ [
-              ./patches/alejandra-no-ads.patch
-            ];
-        });
-
-        prismlauncher-unwrapped =
-          (super.prismlauncher-unwrapped.override (finalAttrs: {
-            stdenv = pkgs.useMoldLinker finalAttrs.stdenv;
-          }))
-          .overrideAttrs (_: final: {
-            patches =
-              final.patches
-              ++ [
-                ./patches/prismlauncher-allow-offline-accounts.patch
-              ];
-          });
-
-        telegram-desktop =
-          (pkgsMaster.telegram-desktop.override (finalAttrs: {
-            stdenv = pkgs.useMoldLinker finalAttrs.stdenv;
-          }))
-          .overrideAttrs (_: final: {
-            patches =
-              final.patches
-              ++ [
-                ./patches/telegram-desktop-no-ads.patch
-              ];
-          });
-
-        vesktop = pkgsMaster.vesktop.overrideAttrs (_: final: {
-          nativeBuildInputs = final.nativeBuildInputs ++ [super.imagemagick];
-          patches =
-            final.patches
-            ++ [
-              ./patches/vesktop-no-anime.patch
-            ];
-          postInstall = ''
-            # Replace gay icons with the default one. Apparently, these were
-            # designed specifically for MacOS[1]. You can't make this shit up
-            # LMAO.
-            #
-            # [1]: https://github.com/Vencord/Vesktop/pull/48
-            rm -rf $out/share/icons/hicolor/*
-            for size in 16 24 32 48 64 96; do
-              convert -scale $size icon.png $size.png
-              install -Dm644 $size.png $out/share/icons/hicolor/''${size}x''${size}/apps/vencorddesktop.png
-            done
-          '';
-        });
-      }
-    )
+    (_: _: {
+    })
   ];
 
   environment = {
@@ -175,6 +98,7 @@ with lib; {
   };
 
   hm = {
+    # Used primarily in conjunction with the "nixfiles" script.
     home.file.".nix-defexpr/default.nix".text = let
       hostname = strings.escapeNixIdentifier this.hostname;
     in
diff --git a/modules/common/common/nix/patches/alejandra-no-ads.patch b/modules/common/common/nix/patches/alejandra-no-ads.patch
deleted file mode 100644
index 6eaac66..0000000
--- a/modules/common/common/nix/patches/alejandra-no-ads.patch
+++ /dev/null
@@ -1,33 +0,0 @@
-diff --git i/src/alejandra_cli/src/cli.rs w/src/alejandra_cli/src/cli.rs
-index bab102c..b90bf1d 100644
---- i/src/alejandra_cli/src/cli.rs
-+++ w/src/alejandra_cli/src/cli.rs
-@@ -7,7 +7,6 @@ use futures::future::RemoteHandle;
- use futures::stream::FuturesUnordered;
- use futures::task::SpawnExt;
- 
--use crate::ads::random_ad;
- use crate::verbosity::Verbosity;
- 
- /// The Uncompromising Nix Code Formatter.
-@@ -203,11 +202,6 @@ pub fn main() -> std::io::Result<()> {
-                     (true, false) => "requires formatting",
-                 }
-             );
--
--            if in_place {
--                eprintln!();
--                eprint!("{}", random_ad());
--            }
-         }
- 
-         std::process::exit(if in_place { 0 } else { 2 });
-@@ -218,8 +212,6 @@ pub fn main() -> std::io::Result<()> {
-         eprintln!(
-             "Congratulations! Your code complies with the Alejandra style."
-         );
--        eprintln!();
--        eprint!("{}", random_ad());
-     }
- 
-     std::process::exit(0);
diff --git a/modules/common/profiles/dev/editorconfig.ini b/modules/common/profiles/dev/editorconfig.ini
index 098229f..87f47eb 100644
--- a/modules/common/profiles/dev/editorconfig.ini
+++ b/modules/common/profiles/dev/editorconfig.ini
@@ -9,79 +9,88 @@ insert_final_newline = true
 max_line_length = 80
 trim_trailing_whitespace = true
 
-[*.nix]
-indent_size = 2
-indent_style = space
-
-[*.{S,s,asm}]
-indent_size = 4
-indent_style = tab
-
-[*.{C,H,c,c++,cc,cpp,cxx,h,h++,hh,hpp,hxx}]
+# C/C++
+[*.{c,cc,cpp,cxx,h,hh,hpp,hxx,ixx}]
 indent_size = 4
 indent_style = tab
 
-[*.{cl,clj,el,l,lisp,lsp,rkt,scm,ss}]
-indent_size = 2
-indent_style = space
-
+# Go
 [*.go]
 indent_size = 4
 indent_style = tab
 
-[*.{py,pyx}]
+# Python
+[*.py]
 indent_size = 4
 indent_style = space
+max_line_length = 72
 
-[*.{hs,lhs}]
-indent_size = 2
-indent_style = space
-
-[*.{html,xhtml,xml}]
-indent_size = 4
-indent_style = tab
-
-[*.json]
+# Haskell
+[*.hs]
 indent_size = 2
 indent_style = space
 
-[*.{yaml,yml}]
+# Lisp(s)
+[*.{lisp,cl,rkt,scm,el}]
 indent_size = 2
 indent_style = space
 
-[*.{toml,tml}]
-indent_size = 4
-indent_style = space
-
-[*.{py,pyx}]
-indent_size = 4
-indent_style = space
-max_line_length = 72
-
+# Zig
 [*.zig]
 indent_size = 4
 indent_style = tab
 
-[*.{tf,hcl}]
-indent_size = 2
-indent_style = space
+# Assembly
+[*.{asm,s}]
+indent_size = 4
+indent_style = tab
 
+# GNU Cringetools
 [configure.ac]
 indent_size = 4
 indent_style = tab
 
+# Make
 [{Makefile*,*.mk}]
 indent_size = 4
 indent_style = tab
 
+# CMake
 [{CMakeLists.txt,*.cmake}]
 indent_size = 8
 indent_style = tab
 
-[*.tex]
+# Nix
+[*.nix]
+indent_size = 2
+indent_style = space
+
+# HCL
+[*.{tf,hcl}]
+indent_size = 2
+indent_style = space
+
+# JSON
+[*.json]
+indent_size = 2
+indent_style = space
+
+# YAML
+[*.{yaml,yml}]
+indent_size = 2
+indent_style = space
+
+# TOML
+[*.{toml,tml}]
+indent_size = 4
+indent_style = space
+
+# Markup
+[*.{html,xml}]
 indent_size = 4
 indent_style = tab
 
-[*.{md,adoc,rtf,txt}]
+# (La)TeX
+[*.{tex,cls}]
 indent_size = 4
 indent_style = tab
diff --git a/modules/nixos/lidarr.nix b/modules/nixos/lidarr.nix
index b0c833c..9b166cf 100644
--- a/modules/nixos/lidarr.nix
+++ b/modules/nixos/lidarr.nix
@@ -1,5 +1,6 @@
 {
   config,
+  inputs,
   lib,
   libNginx,
   ...
@@ -18,6 +19,8 @@ in {
   };
 
   config = mkIf cfg.enable {
+    secrets.lidarr-api-key.file = "${inputs.self}/secrets/lidarr-api-key";
+
     ark.directories = ["/var/lib/lidarr"];
 
     nixfiles.modules.nginx = {
@@ -29,10 +32,23 @@ in {
       };
     };
 
-    services.lidarr = {
-      enable = true;
-      user = "rtorrent";
-      group = "rtorrent";
+    services = {
+      lidarr = {
+        enable = true;
+        user = "rtorrent";
+        group = "rtorrent";
+      };
+
+      prometheus.exporters.exportarr-lidarr = {
+        enable = true;
+        url = "http://127.0.0.1";
+        apiKeyFile = config.secrets.lidarr-api-key.path;
+        port = mkDefault 9708;
+        inherit (config.services.lidarr) user;
+        inherit (config.services.lidarr) group;
+        listenAddress = this.wireguard.ipv4.address;
+        environment.CONFIG = "/var/lib/lidarr/.config/Lidarr/config.xml";
+      };
     };
 
     systemd.tmpfiles.rules = with config.services.lidarr; [
diff --git a/modules/nixos/monitoring/default.nix b/modules/nixos/monitoring/default.nix
index 57adf1c..a09b7e7 100644
--- a/modules/nixos/monitoring/default.nix
+++ b/modules/nixos/monitoring/default.nix
@@ -6,217 +6,223 @@
 }:
 with lib; let
   cfg = config.nixfiles.modules.monitoring;
-in {
-  options.nixfiles.modules.monitoring.enable = mkEnableOption ''
-    a glue to provision a monitoring stack
-  '';
+in
+  {
+    options.nixfiles.modules.monitoring.enable = mkEnableOption ''
+      a glue to provision a monitoring stack
+    '';
 
-  config = mkIf cfg.enable {
-    nixfiles.modules = {
-      alertmanager.enable = true;
-      grafana.enable = true;
-      loki.enable = true;
-      prometheus.enable = true;
-    };
+    config = mkIf cfg.enable {
+      nixfiles.modules = {
+        alertmanager.enable = true;
+        grafana.enable = true;
+        loki.enable = true;
+        prometheus.enable = true;
+      };
 
-    services = {
-      grafana = {
-        declarativePlugins = with pkgs.grafanaPlugins; [
-          redis-app
-          redis-datasource
-          redis-explorer-app
-        ];
+      services = {
+        grafana = {
+          declarativePlugins = with pkgs.grafanaPlugins; [
+            redis-app
+            redis-datasource
+            redis-explorer-app
+          ];
 
-        provision = {
-          enable = true;
+          provision = {
+            enable = true;
 
-          # https://grafana.com/docs/grafana/latest/administration/provisioning/#data-sources
-          datasources.settings.datasources = with config.nixfiles.modules; [
-            {
-              name = "Alertmanager";
-              type = "alertmanager";
-              access = "proxy";
-              jsonData.implementation = "prometheus";
-              url = "https://${alertmanager.domain}";
-            }
-            {
-              name = "Loki";
-              type = "loki";
-              access = "proxy";
-              url = "https://${loki.domain}";
-              isDefault = true;
-            }
-            {
-              name = "Prometheus";
-              type = "prometheus";
-              access = "proxy";
-              url = "https://${prometheus.domain}";
-            }
-            (mkIf config.nixfiles.modules.redis.enable {
-              name = "Redis";
-              type = "redis-datasource";
-              access = "proxy";
-              url = with config.services.redis.servers.default; "redis://${bind}:${toString port}";
-              jsonData.client = "standalone";
-            })
-          ];
-          datasources.settings.deleteDatasources = [
-            {
-              name = "PostgreSQL";
-              orgId = 1;
-            }
-          ];
+            # https://grafana.com/docs/grafana/latest/administration/provisioning/#data-sources
+            datasources.settings.datasources = with config.nixfiles.modules; [
+              {
+                name = "Alertmanager";
+                type = "alertmanager";
+                access = "proxy";
+                jsonData.implementation = "prometheus";
+                url = "https://${alertmanager.domain}";
+              }
+              {
+                name = "Loki";
+                type = "loki";
+                access = "proxy";
+                url = "https://${loki.domain}";
+                isDefault = true;
+              }
+              {
+                name = "Prometheus";
+                type = "prometheus";
+                access = "proxy";
+                url = "https://${prometheus.domain}";
+              }
+              (mkIf config.nixfiles.modules.redis.enable {
+                name = "Redis";
+                type = "redis-datasource";
+                access = "proxy";
+                url = with config.services.redis.servers.default; "redis://${bind}:${toString port}";
+                jsonData.client = "standalone";
+              })
+            ];
+            datasources.settings.deleteDatasources = [
+              {
+                name = "PostgreSQL";
+                orgId = 1;
+              }
+            ];
 
-          # https://grafana.com/docs/grafana/latest/administration/provisioning/#dashboards
-          dashboards.settings.providers = [
-            {
-              name = "node";
-              options.path = ./dashboards/node.json;
-            }
-            {
-              name = "ntfy";
-              options.path = ./dashboards/ntfy.json;
-            }
-            {
-              name = "endlessh";
-              options.path = ./dashboards/endlessh.json;
-            }
-            {
-              name = "unbound";
-              options.path = ./dashboards/unbound.json;
-            }
-            {
-              name = "nginx";
-              options.path = ./dashboards/nginx.json;
-            }
-            {
-              name = "postgersql";
-              options.path = ./dashboards/postgresql.json;
-            }
-            {
-              name = "redis";
-              options.path = ./dashboards/redis.json;
-            }
-            {
-              name = "redis-streaming";
-              options.path = ./dashboards/redis-streaming.json;
-            }
-          ];
+            # https://grafana.com/docs/grafana/latest/administration/provisioning/#dashboards
+            dashboards.settings.providers = [
+              {
+                name = "node";
+                options.path = ./dashboards/node.json;
+              }
+              {
+                name = "ntfy";
+                options.path = ./dashboards/ntfy.json;
+              }
+              {
+                name = "endlessh";
+                options.path = ./dashboards/endlessh.json;
+              }
+              {
+                name = "unbound";
+                options.path = ./dashboards/unbound.json;
+              }
+              {
+                name = "nginx";
+                options.path = ./dashboards/nginx.json;
+              }
+              {
+                name = "postgersql";
+                options.path = ./dashboards/postgresql.json;
+              }
+              {
+                name = "redis";
+                options.path = ./dashboards/redis.json;
+              }
+              {
+                name = "redis-streaming";
+                options.path = ./dashboards/redis-streaming.json;
+              }
+            ];
 
-          # https://grafana.com/docs/grafana/latest/administration/provisioning/#alerting
-          alerting.contactPoints.settings.contactPoints = [
-            {
-              name = "Alertmanager";
-              receivers = [
-                {
-                  uid = 1;
-                  type = "prometheus-alertmanager";
-                  settings.url = "https://${config.nixfiles.modules.alertmanager.domain}";
-                }
-              ];
-            }
-          ];
+            # https://grafana.com/docs/grafana/latest/administration/provisioning/#alerting
+            alerting.contactPoints.settings.contactPoints = [
+              {
+                name = "Alertmanager";
+                receivers = [
+                  {
+                    uid = 1;
+                    type = "prometheus-alertmanager";
+                    settings.url = "https://${config.nixfiles.modules.alertmanager.domain}";
+                  }
+                ];
+              }
+            ];
+          };
         };
-      };
 
-      loki.configuration.ruler.alertmanager_url = "https://${config.nixfiles.modules.alertmanager.domain}";
+        loki.configuration.ruler.alertmanager_url = "https://${config.nixfiles.modules.alertmanager.domain}";
 
-      prometheus = {
-        scrapeConfigs = with my.configurations;
-          mapAttrsToList
-          (
-            name: value: {
-              job_name = name;
-              static_configs = [
-                {
-                  targets = with value;
-                    map (host:
-                      concatStringsSep ":" [
-                        (
-                          if isAttrs host
-                          then host.hostname
-                          else host
-                        )
-                        (toString port)
-                      ])
-                    hosts;
-                }
-              ];
-              relabel_configs =
-                [
+        prometheus = {
+          scrapeConfigs = with my.configurations;
+            mapAttrsToList
+            (
+              name: value: {
+                job_name = name;
+                static_configs = [
                   {
-                    source_labels = ["__address__"];
-                    regex = "([^:]+):\\d+";
-                    target_label = "instance";
+                    targets = with value;
+                      map (host:
+                        concatStringsSep ":" [
+                          (
+                            if isAttrs host
+                            then host.hostname
+                            else host
+                          )
+                          (toString port)
+                        ])
+                      hosts;
                   }
-                ]
-                ++ optionals (hasAttr "relabel" value) value.relabel;
-            }
-          )
-          {
-            promtail = {
-              hosts = [manwe varda yavanna];
-              inherit (config.nixfiles.modules.promtail) port;
-            };
-            ntfy = {
-              hosts = [manwe];
-              inherit (config.nixfiles.modules.ntfy.prometheus) port;
-            };
-            soju = {
-              hosts = ["127.0.0.1"];
-              inherit (config.nixfiles.modules.soju.prometheus) port;
-            };
-            endlessh-go = {
-              hosts = [manwe varda yavanna];
-              inherit (config.services.endlessh-go.prometheus) port;
-            };
-            nginx = {
-              hosts = [manwe yavanna];
-              inherit (config.services.prometheus.exporters.nginx) port;
-            };
-            node = {
-              hosts = [manwe varda yavanna];
-              inherit (config.services.prometheus.exporters.node) port;
-            };
-            postgres = {
-              hosts = [manwe];
-              inherit (config.services.prometheus.exporters.postgres) port;
-            };
-            redis = {
-              hosts = [manwe];
-              inherit (config.services.prometheus.exporters.redis) port;
-            };
-            unbound = {
-              hosts = [manwe];
-              inherit (config.services.prometheus.exporters.unbound) port;
-            };
-            wireguard = {
-              hosts = [manwe];
-              inherit (config.services.prometheus.exporters.wireguard) port;
-            };
-            # TODO Wait for https://github.com/NixOS/nixpkgs/pull/265696
-            exportarr-lidarr = {
-              hosts = [yavanna];
-              port = 9708;
+                ];
+                relabel_configs =
+                  [
+                    {
+                      source_labels = ["__address__"];
+                      regex = "([^:]+):\\d+";
+                      target_label = "instance";
+                    }
+                  ]
+                  ++ optionals (hasAttr "relabel" value) value.relabel;
+              }
+            )
+            {
+              promtail = {
+                hosts = [manwe varda yavanna];
+                inherit (config.nixfiles.modules.promtail) port;
+              };
+              ntfy = {
+                hosts = [manwe];
+                inherit (config.nixfiles.modules.ntfy.prometheus) port;
+              };
+              soju = {
+                hosts = ["127.0.0.1"];
+                inherit (config.nixfiles.modules.soju.prometheus) port;
+              };
+              endlessh-go = {
+                hosts = [manwe varda yavanna];
+                inherit (config.services.endlessh-go.prometheus) port;
+              };
+              nginx = {
+                hosts = [manwe yavanna];
+                inherit (config.services.prometheus.exporters.nginx) port;
+              };
+              node = {
+                hosts = [manwe varda yavanna];
+                inherit (config.services.prometheus.exporters.node) port;
+              };
+              postgres = {
+                hosts = [manwe];
+                inherit (config.services.prometheus.exporters.postgres) port;
+              };
+              redis = {
+                hosts = [manwe];
+                inherit (config.services.prometheus.exporters.redis) port;
+              };
+              unbound = {
+                hosts = [manwe];
+                inherit (config.services.prometheus.exporters.unbound) port;
+              };
+              wireguard = {
+                hosts = [manwe];
+                inherit (config.services.prometheus.exporters.wireguard) port;
+              };
+              # TODO Wait for https://github.com/NixOS/nixpkgs/pull/265696
+              exportarr-lidarr = {
+                hosts = [yavanna];
+                port = 9708;
+              };
             };
-          };
 
-        ruleFiles = [
-          ./rules/nginx.yaml
-          ./rules/node.yaml
-          ./rules/postgres.yaml
-          ./rules/redis.yaml
-        ];
+          ruleFiles = [
+            ./rules/nginx.yaml
+            ./rules/node.yaml
+            ./rules/postgres.yaml
+            ./rules/redis.yaml
+          ];
 
-        alertmanagers = [
-          {
-            scheme = "https";
-            static_configs = [
-              {targets = [config.nixfiles.modules.alertmanager.domain];}
-            ];
-          }
-        ];
+          alertmanagers = [
+            {
+              scheme = "https";
+              static_configs = [
+                {targets = [config.nixfiles.modules.alertmanager.domain];}
+              ];
+            }
+          ];
+        };
       };
     };
-  };
-}
+  }
+  # FIXME https://nixpk.gs/pr-tracker.html?pr=265696
+  // lib.moduleFromRef
+  "services/monitoring/prometheus/exporters.nix"
+  "Stunkymonkey:nixos-exportarr"
+  "0c9n3dc8l64bshynpbzaplvxhi2f0ihh6wcslh42y9kilwjp2zjv"
diff --git a/modules/nixos/plausible.nix b/modules/nixos/plausible.nix
index 91bdff9..172da3f 100644
--- a/modules/nixos/plausible.nix
+++ b/modules/nixos/plausible.nix
@@ -123,6 +123,7 @@ in
         };
       };
   }
+  # FIXME https://nixpk.gs/pr-tracker.html?pr=266702
   // lib.moduleFromRef
   "services/web-apps/plausible.nix"
   "nh2:plausible-listen-address-no-distributed-erlang"
diff --git a/modules/common/common/nix/patches/prismlauncher-allow-offline-accounts.patch b/patches/prismlauncher-allow-offline-accounts.patch
index c245066..c245066 100644
--- a/modules/common/common/nix/patches/prismlauncher-allow-offline-accounts.patch
+++ b/patches/prismlauncher-allow-offline-accounts.patch
diff --git a/modules/common/common/nix/patches/telegram-desktop-no-ads.patch b/patches/telegram-desktop-no-ads.patch
index d066066..d066066 100644
--- a/modules/common/common/nix/patches/telegram-desktop-no-ads.patch
+++ b/patches/telegram-desktop-no-ads.patch
diff --git a/modules/common/common/nix/patches/vesktop-no-anime.patch b/patches/vesktop-no-anime.patch
index 5fd97ef..5fd97ef 100644
--- a/modules/common/common/nix/patches/vesktop-no-anime.patch
+++ b/patches/vesktop-no-anime.patch

Consider giving Nix/NixOS a try! <3