diff options
| -rw-r--r-- | flake.nix | 154 | ||||
| -rw-r--r-- | src/db/mod.rs | 1 | ||||
| -rw-r--r-- | src/log_setup.rs | 42 | ||||
| -rw-r--r-- | src/main.rs | 2 |
4 files changed, 144 insertions, 55 deletions
@@ -26,7 +26,8 @@ flake-utils, ... } @ inputs: let - buildToolchain = pkgs: pkgs.rust-bin.nightly."2022-11-20".minimal; + mkBuildToolchain = pkgs: pkgs.rust-bin.nightly."2022-11-20".minimal; + deps = pkgs: with pkgs; [ openssl pkgconfig @@ -35,7 +36,7 @@ ]; mkPkg = pkgs: let - buildToolchain = buildToolchain pkgs; + buildToolchain = mkBuildToolchain pkgs; naersk = pkgs.callPackage inputs.naersk { cargo = buildToolchain; @@ -48,7 +49,24 @@ pname = "thulani"; version = self.rev or "dirty"; - src = lib.cleanSource ./.; + src = lib.cleanSourceWith { + src = lib.cleanSource ./.; + + filter = path: ty: with builtins; with lib; let + baseName = baseNameOf "${path}"; + extMatch = match "((.*\\.?)*\\.)?(.*)" baseName; + extension = elemAt extMatch 2; + parent = baseNameOf (dirOf "${path}"); + isCargoFile = baseName == "Cargo.toml" || baseName == "Cargo.lock"; + isCargoConfig = parent == ".cargo" && baseName == "config.toml"; + in + ty == "directory" || + isCargoFile || + isCargoConfig || + extension == "rs" || + extension == "sql" || + extension == "pest"; + }; nativeBuildInputs = deps pkgs; remapPathPrefix = true; @@ -64,7 +82,7 @@ ]; }; - devToolchain = (buildToolchain pkgs).override { + devToolchain = (mkBuildToolchain pkgs).override { extensions = [ "rust-src" "rust-analyzer" @@ -93,9 +111,58 @@ }) // { overlays.default = final: prev: let - withRust = (import inputs.rust-overlay) final prev; - in { - thulani = mkPkg withRust; + withRust = ((import inputs.rust-overlay) final prev); + in withRust // { + thulani = mkPkg (final // withRust); + }; + + nixosConfigurations.test = nixpkgs.lib.nixosSystem { + system = "x86_64-linux"; + + modules = [ + self.nixosModules.default + "${nixpkgs}/nixos/modules/virtualisation/qemu-vm.nix" + + ({ lib, ... }: { + nixpkgs.overlays = [ + self.overlays.default + ]; + + users = { + mutableUsers = false; + + users.root.hashedPassword = lib.mkForce ""; + + users.test = { + password = lib.mkForce "test"; + group = "test"; + isNormalUser = true; + extraGroups = [ + "wheel" + "sudo" + ]; + }; + + groups.test = {}; + }; + + virtualisation = { + cores = 8; + graphics = false; + diskSize = 32*1024; + memorySize = 12*1024; + writableStoreUseTmpfs = false; + }; + + services.thulani = { + enable = true; + + postgres = { + enable = true; + }; + }; + }) + ]; }; nixosModules.default = { pkgs, lib, config, ... }: let @@ -113,7 +180,18 @@ environment = mkOption { description = "literal environment to include"; type = attrsOf str; - default = {}; + + default = { + RUST_BACKTRACE = "1"; + MAX_HIST = "30"; + DEFAULT_HIST = "5"; + MAX_SHEET_COLUMN = "ZZZ"; + STEAM_API_KEY = ""; + SPREADSHEET_ID = ""; + SHEETS_API_KEY = ""; + } // (optionalAttrs cfg.postgres.enable { + DATABASE_URL = "postgres://${cfg.user}@/${cfg.postgres.db}"; + }); }; envFiles = mkOption { @@ -137,13 +215,15 @@ postgres = mkOption { description = "local postgres server with automatic setup"; - type = sumodule { - enable = mkEnableOption "postgres"; + type = submodule { + options = { + enable = mkEnableOption "postgres"; - db = mkOption { - description = "db name"; - type = str; - default = "memes"; + db = mkOption { + description = "db name"; + type = str; + default = "memes"; + }; }; }; }; @@ -159,30 +239,11 @@ bindsTo = [ "network-online.target" - ]; + ] ++ lib.optional cfg.postgres.enable "postgresql.service"; after = [ "network-online.target" - ]; - - preStart = lib.mkIf (cfg.postgres.enable) (let - invokePsql = "${pkgs.sudo}/bin/sudo -u ${config.services.postgresql.superUser} -- ${config.services.postgresql.package}/bin/psql"; - - in '' - ${invokePsql} <<EOF - DO $$ - BEGIN - CREATE ROLE ${cfg.user}; - EXCEPTION WHEN duplicate_object THEN RAISE NOTICE '%, skipping', SQLERRM USING ERRCODE = SQLSTATE; - END - $$; - - SELECT 'CREATE DATABASE ${cfg.postgres.db}' - WHERE NOT EXISTS (SELECT FROM pg_database WHERE datname = '${cfg.postgres.db}')\gexec - EOF - - echo 'CREATE EXTENSION IF NOT EXISTS pgcrypto' | ${invokePsql} ${cfg.postgres.db} - ''); + ] ++ lib.optional cfg.postgres.enable "postgresql.service"; inherit (cfg) environment; @@ -194,8 +255,29 @@ serviceConfig = { Type = "exec"; ExecStart = "${cfg.package}/bin/thulani"; + ExecStartPre = let + invokePsql = "${pkgs.sudo}/bin/sudo -u ${config.services.postgresql.superUser} -- ${config.services.postgresql.package}/bin/psql"; + preStart = pkgs.writeShellScript "" '' + set -euo pipefail + + ${invokePsql} <<'EOF' + DO $$ + BEGIN + CREATE ROLE ${cfg.user} WITH LOGIN; + EXCEPTION WHEN duplicate_object THEN RAISE NOTICE '%, skipping', SQLERRM USING ERRCODE = SQLSTATE; + END + $$; + + SELECT 'CREATE DATABASE ${cfg.postgres.db}' + WHERE NOT EXISTS (SELECT FROM pg_database WHERE datname = '${cfg.postgres.db}')\gexec + EOF + + echo 'CREATE EXTENSION IF NOT EXISTS pgcrypto' | ${invokePsql} ${cfg.postgres.db} + ''; + + in "+${preStart}"; - EnvironmentFile = cfg.environmentFiles; + EnvironmentFile = cfg.envFiles; DynamicUser = true; User = cfg.user; diff --git a/src/db/mod.rs b/src/db/mod.rs index 483665e..476d9d9 100644 --- a/src/db/mod.rs +++ b/src/db/mod.rs @@ -54,6 +54,7 @@ pub fn connection() -> Result<PgConnection> { MIGRATE.call_once(|| { log::info!("running migrations"); conn.run_pending_migrations(MIGRATIONS).expect("failed running migrations"); + log::info!("migrations complete"); }); conn diff --git a/src/log_setup.rs b/src/log_setup.rs index a51ebcc..c01f3f5 100644 --- a/src/log_setup.rs +++ b/src/log_setup.rs @@ -2,13 +2,13 @@ use crate::{Result, Error}; use fern::colors::{Color, ColoredLevelConfig}; -pub fn init() -> Result<()> { +pub fn init(file_output: bool) -> Result<()> { let colors = ColoredLevelConfig::new() .info(Color::Green) .debug(Color::BrightBlue) .trace(Color::BrightMagenta); - fern::Dispatch::new() + let mut logger = fern::Dispatch::new() .level_for("serenity::voice::connection", log::LevelFilter::Error) .chain(fern::Dispatch::new() .format(move |out, message, record| { @@ -23,21 +23,27 @@ pub fn init() -> Result<()> { .level(log::LevelFilter::Warn) .level_for("thulani", log::LevelFilter::Debug) .chain(std::io::stdout()) - ) - .chain(fern::Dispatch::new() - .format(|out, message, record| { - out.finish(format_args!( - "{} [{}] [{}] {}", - chrono::Local::now().format("%_m/%_d/%y %l:%M:%S%P"), - record.level(), - record.target(), - message - )) - }) - .level(log::LevelFilter::Info) - .level_for("thulani", log::LevelFilter::Trace) - .chain(fern::log_file("thulani.log").expect("problem creating log file")) - ) + ); + + if file_output { + logger = logger + .chain(fern::Dispatch::new() + .format(|out, message, record| { + out.finish(format_args!( + "{} [{}] [{}] {}", + chrono::Local::now().format("%_m/%_d/%y %l:%M:%S%P"), + record.level(), + record.target(), + message + )) + }) + .level(log::LevelFilter::Info) + .level_for("thulani", log::LevelFilter::Trace) + .chain(fern::log_file("thulani.log").expect("problem creating log file")) + ); + } + + logger .apply() .map_err(Error::from) -}
\ No newline at end of file +} diff --git a/src/main.rs b/src/main.rs index ffcd2f5..1bf3e98 100644 --- a/src/main.rs +++ b/src/main.rs @@ -59,7 +59,7 @@ const BACKOFF_INIT: f64 = 100.0; const MIN_RUN_DURATION: Duration = Duration::from_secs(120); fn main() { - log_setup::init().expect("initializing logging"); + log_setup::init(false).expect("initializing logging"); let mut backoff_count: usize = 0; |
