{ description = "Skynet Discord Bot"; inputs = { nixpkgs.url = "nixpkgs/nixos-unstable"; naersk.url = "github:nix-community/naersk"; utils.url = "github:numtide/flake-utils"; }; nixConfig = { extra-substituters = "https://nix-cache.skynet.ie/skynet-cache"; extra-trusted-public-keys = "skynet-cache:zMFLzcRZPhUpjXUy8SF8Cf7KGAZwo98SKrzeXvdWABo="; }; outputs = { self, nixpkgs, utils, naersk, }: utils.lib.eachDefaultSystem ( system: let pkgs = (import nixpkgs) {inherit system;}; naersk' = pkgs.callPackage naersk {}; package_name = "skynet_discord_bot"; desc = "Skynet Discord Bot"; buildInputs = with pkgs; [ openssl pkg-config rustfmt ]; in rec { packages = { # For `nix build` & `nix run`: default = naersk'.buildPackage { pname = "${package_name}"; src = ./.; buildInputs = buildInputs; }; # Run `nix build .#fmt` to run tests fmt = naersk'.buildPackage { src = ./.; mode = "fmt"; buildInputs = buildInputs; }; # Run `nix build .#clippy` to lint code clippy = naersk'.buildPackage { src = ./.; mode = "clippy"; buildInputs = buildInputs; }; }; defaultPackage = packages.default; # `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 rustfmt]; }; nixosModule = { lib, pkgs, config, ... }: with lib; let cfg = config.services."${package_name}"; # secret options are in the env file(s) loaded separately environment_config = { HOME = cfg.home; DATABASE = "database.db"; }; service_name = script: lib.strings.sanitizeDerivationName "${cfg.user}@${script}"; # oneshot scripts to run serviceGenerator = mapAttrs' (script: time: nameValuePair (service_name script) { description = "Service for ${desc} ${script}"; wantedBy = []; after = ["network-online.target"]; environment = environment_config; serviceConfig = { Type = "oneshot"; User = "${cfg.user}"; Group = "${cfg.user}"; ExecStart = "${self.defaultPackage."${system}"}/bin/${script}"; EnvironmentFile = [ "${cfg.env.discord}" "${cfg.env.mail}" "${cfg.env.wolves}" ]; }; }); # each timer will run the above service timerGenerator = mapAttrs' (script: time: nameValuePair (service_name script) { description = "Timer for ${desc} ${script}"; wantedBy = ["timers.target"]; partOf = ["${service_name script}.service"]; timerConfig = { OnCalendar = time; Unit = "${service_name script}.service"; Persistent = true; }; }); # modify these scripts = { # every 20 min "update_data" = "*:0,20,40"; # groups are updated every hour, offset from teh ldap "update_users" = "*:05:00"; # minecraft stuff is updated at 5am "update_minecraft" = "5:10:00"; }; in { options.services."${package_name}" = { enable = mkEnableOption "enable ${package_name}"; env = { discord = mkOption rec { type = types.str; description = "ENV file with DISCORD_TOKEN, DISCORD_TOKEN_MINECRAFT"; }; mail = mkOption rec { type = types.str; description = "ENV file with EMAIL_SMTP, EMAIL_USER, EMAIL_PASS"; }; wolves = mkOption rec { type = types.str; description = "Mail details, has WOLVES_URL"; }; }; 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.discord}" "${cfg.env.mail}" "${cfg.env.wolves}" ]; }; restartTriggers = [ "${cfg.env.discord}" "${cfg.env.mail}" "${cfg.env.wolves}" ]; }; } // serviceGenerator scripts; # timers to run the above services systemd.timers = timerGenerator scripts; }; }; } ); }