diff --git a/.gitignore b/.gitignore index 9c6653d9..8f484c97 100644 --- a/.gitignore +++ b/.gitignore @@ -17,7 +17,7 @@ *.yaml !sample_config.yaml -watgbridge +/watgbridge *.db *.db-journal watgbridge-build/ diff --git a/flake.nix b/flake.nix index 050ea950..51ee4b69 100644 --- a/flake.nix +++ b/flake.nix @@ -38,6 +38,13 @@ default = watgbridge; }; + overlay = final: prev: { + watgbridge = (pkgs.callPackage ./nix/pkgs/watgbridge-dev.nix { inherit nix-filter; }); + }; + + nixosModules.default = import ./nix/modules/nixos self; + homeManagerModules.default = import ./nix/modules/home-manager self; + } ); diff --git a/nix/modules/commonOptions.nix b/nix/modules/commonOptions.nix new file mode 100644 index 00000000..13946f2c --- /dev/null +++ b/nix/modules/commonOptions.nix @@ -0,0 +1,92 @@ +{ + lib, + package, +}: let + inherit (lib) mkEnableOption mkOption types; +in { + enable = mkEnableOption "WaTgBridge services"; + + commonSettings.package = mkOption { + type = types.package; + default = package; + }; + + commonSettings.maxRuntime = mkOption { + type = types.nullOr types.str; + default = "1d"; + }; + + commonSettings.after = mkOption { + type = types.nullOr (types.listOf types.str); + default = null; + }; + + instances = mkOption { + type = types.attrsOf(types.submodule { + options = { + + enable = mkEnableOption "Enable the instance"; + + name = mkOption { + type = types.nullOr types.str; + default = null; + description = '' + The name of the instance. The corresponding systemd service will be called `watgbridge-.service`. + + By default, the key of the instance in the attrset will be used. + ''; + }; + + package = mkOption { + type = types.nullOr types.package; + default = null; + description = '' + The WaTgBridge package to use for the instance. + + By default the common package defined will be used. + ''; + }; + + configPath = mkOption { + type = types.nullOr (types.either (types.str types.path)); + default = null; + description = '' + The path to the config file that will be loaded by WaTgBridge. + + By default, WaTgBridge loads config from config.yaml in the current working directory. + ''; + }; + + workingDirectory = mkOption { + type = types.nullOr types.str; + default = null; + description = '' + The directory from which the WaTgBridge binary will be executed. + + If not provided, it will use systemd's default working directory. + ''; + }; + + maxRuntime = mkOption { + type = types.nullOr types.str; + default = null; + description = '' + Max time in seconds (according to systemd's units) after which the service will be automatically restarted. + + If not provided, it will use the common setting (which is 1d, i.e. 1 day). + ''; + }; + + after = mkOption { + type = types.nullOf (types.listOf types.str); + default = null; + description = '' + The systemd services to wait for before starting watbridge. "network.target" is added to the module itself. This option is meant to be used for stuff like Telegram Bot API service. + + If not provided, it will use the common setting + ''; + }; + }; + }); + }; +} diff --git a/nix/modules/home-manager/default.nix b/nix/modules/home-manager/default.nix new file mode 100644 index 00000000..36912d57 --- /dev/null +++ b/nix/modules/home-manager/default.nix @@ -0,0 +1,72 @@ +self: { + lib, + config, + pkgs, + ... +}: let + inherit (pkgs.stdenv.hostPlatform) system; + inherit (lib) mapAttrs' mkIf; + cfg = config.services.watgbridge; + + package = self.packages."${system}".watgbridge; +in { + options = { + services.watgbridge = import ../commonOptions.nix { inherit lib package; }; + }; + + config = mkIf cfg.enable { + home.packages = [ cfg.package ]; + + systemd.user.services = mapAttrs' (key: settings: let + + instanceName = ( + if settings.name != null then + "watgbridge-${settings.name}" + else + "watgbridge-${key}" + ); + watgbridgePackage = ( + if settings.package != null then + settings.package + else + cfg.commonSettings.package + ); + + maxRuntime = ( + if settings.maxRuntime != null then + settings.maxRuntime + else + cfg.commonSettings.maxRuntime + ); + + after = ( + if settings.after != null then + settings.after + else + cfg.commonSettings.after + ); + + in { + + name = instanceName; + + value = mkIf settings.enable { + Unit = { + Description = "WaTgBridge service for '${instanceName}'"; + Documentation = "https://github.com/akshettrj/watbridge"; + After = [ "network.target" ] ++ lib.optionals (after != null) after; + }; + + Service = { + ExecStart = ''${watgbridgePackage}/bin/watbridge'' lib.optionalString (settings.configPath != null) '' "${settings.configPath}"''; + Restart = "on-failure"; + } // lib.optionalAttrs maxRuntime != null { + RuntimeMaxSec = maxRuntime; + }; + + Install = { WantedBy = ["default.target"]; }; + }; + + }) cfg.instances; + }; +} diff --git a/nix/modules/nixos/default.nix b/nix/modules/nixos/default.nix new file mode 100644 index 00000000..55bc167e --- /dev/null +++ b/nix/modules/nixos/default.nix @@ -0,0 +1,25 @@ +self: { + lib, + config, + pkgs, + ... +}: let + inherit (pkgs.stdenv.hostPlatform) system; + inherit (lib) mkIf; + cfg = config.services.watgbridge; + + package = self.packages."${system}".watgbridge; +in { + options = { + services.watgbridge = import ../commonOptions.nix { inherit lib package; }; + }; + + config = mkIf cfg.enable { + assertions = [{ + assertion = false; + message = "The NixOS module is not complete yet. Use home-manager module for now if possible."; + }]; + + environment.systemPackages = [ cfg.package ]; + }; +}