discord-bot/flake.nix
Brendan Golden 905aaa9620
All checks were successful
On_Push / lint_fmt (push) Successful in 6s
On_Push / lint_clippy (push) Successful in 10s
On_Push / build (push) Successful in 1m50s
On_Push / deploy (push) Successful in 12s
flake: update to use the right default package
2024-08-10 20:56:29 +01:00

236 lines
7.5 KiB
Nix

{
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 = {
LDAP_API = cfg.ldap;
SKYNET_SERVER = cfg.discord.server;
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.ldap}"
"${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 = {
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, DISCORD_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, WOLVES_KEY";
};
};
discord = {
server = mkOption rec {
type = types.str;
description = "ID of the server the bot runs on";
};
};
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}"
"${cfg.env.wolves}"
];
};
restartTriggers = [
"${cfg.env.ldap}"
"${cfg.env.discord}"
"${cfg.env.mail}"
"${cfg.env.wolves}"
];
};
}
// serviceGenerator scripts;
# timers to run the above services
systemd.timers = timerGenerator scripts;
};
};
}
);
}