{ description = "Skynet Discord Bot"; inputs = { nixpkgs.url = "nixpkgs/nixos-23.05"; naersk.url = "github:nix-community/naersk"; utils.url = "github:numtide/flake-utils"; }; outputs = { self, nixpkgs, utils, naersk }: utils.lib.eachDefaultSystem (system: let pkgs = nixpkgs.legacyPackages."${system}"; naersk-lib = naersk.lib."${system}"; package_name = "skynet_discord_bot"; desc = "Skynet Discord Bot"; in rec { # `nix build` packages."${package_name}" = naersk-lib.buildPackage { pname = "${package_name}"; root = ./.; buildInputs = [ pkgs.openssl pkgs.pkg-config ]; }; defaultPackage = packages."${package_name}"; # `nix run` apps."${package_name}" = utils.lib.mkApp { drv = packages."${package_name}"; }; defaultApp = apps."${package_name}"; # `nix develop` devShell = pkgs.mkShell { nativeBuildInputs = with pkgs; [ rustc cargo pkg-config openssl]; }; nixosModule = { lib, pkgs, config, ... }: with lib; let cfg = config.services."${package_name}"; # secret options are in the env file(s) loaded separately environment_config = { DISCORD_SERVER = cfg.discord.server; DISCORD_ROLE_CURRENT = cfg.discord.role.current; DISCORD_ROLE_PAST = cfg.discord.role.past; LDAP_API = cfg.ldap; DISCORD_TIMING_UPDATE = cfg.discord.timing.update; DISCORD_TIMING_FETCH = cfg.discord.timing.fetch; # local details HOME = cfg.home; DATABASE = "database.db"; }; in { options.services."${package_name}" = { enable = mkEnableOption "enable ${package_name}"; env = { ldap = mkOption rec { type = types.str; description = "ENV file with LDAP_DISCORD_AUTH"; }; discord = mkOption rec { type = types.str; description = "ENV file with DISCORD_TOKEN"; }; mail = mkOption rec { type = types.str; description = "ENV file with EMAIL_SMTP, EMAIL_USER, EMAIL_PASS"; }; }; discord = { server = mkOption rec { type = types.str; description = "ID of the server the bot runs on"; }; role = { past = mkOption rec { type = types.str; description = "ID of the role to apply to all members"; }; current = mkOption rec { type = types.str; description = "ID of the role to applt to only current members"; }; }; timing = { update = mkOption rec { type = types.str; default = "600"; description = "Time in seconds to update member roles"; }; fetch = mkOption rec { type = types.str; default = "300"; description = "Time in seconds to get current users"; }; }; }; ldap = mkOption rec { type = types.str; default = "https://api.account.skynet.ie"; description = "Location of the ldap api"; }; user = mkOption rec { type = types.str; default = "${package_name}"; description = "The user to run the service"; }; home = mkOption rec { type = types.str; default = "/etc/${cfg.prefix}${package_name}"; description = "The home for the user"; }; prefix = mkOption rec { type = types.str; default = "skynet_"; example = default; description = "The prefix used to name service/folders"; }; }; config = mkIf cfg.enable { users.groups."${cfg.user}" = { }; users.users."${cfg.user}" = { createHome = true; isSystemUser = true; home = "${cfg.home}"; group = "${cfg.user}"; }; systemd.services = { # main service "${package_name}" = { description = desc; wantedBy = [ "multi-user.target" ]; after = [ "network-online.target" ]; wants = [ ]; environment = environment_config; serviceConfig = { User = "${cfg.user}"; Group = "${cfg.user}"; Restart = "always"; ExecStart = "${self.defaultPackage."${system}"}/bin/${package_name}"; # can have multiple env files EnvironmentFile = [ "${cfg.env.ldap}" "${cfg.env.discord}" "${cfg.env.mail}" ]; }; }; }; }; }; } ); }