# Bosun library - Nix-based Nomad job definitions { # Nomad-specific helpers nomad = import ./nomad.nix; # Discover all jobs in a directory # Each subdirectory with a default.nix is treated as a job # Jobs can be: # - { lib, nomadLib }: { job.name = {...}; } # simple job # - { lib, nomadLib, vars }: { job.name = {...}; } # parameterized job discoverJobs = { path, lib, nomadLib ? (import ./nomad.nix {inherit lib;}), extraArgs ? {}, }: let # List all entries in the directory entries = builtins.readDir path; # Filter to directories that have a default.nix jobDirs = lib.filterAttrs (name: type: type == "directory" && builtins.pathExists (path + "/${name}/default.nix") ) entries; # Import each job importJob = name: let jobPath = path + "/${name}"; jobModule = import jobPath; in # Return the raw module - evaluation happens later with vars jobModule; in lib.mapAttrs (name: _: importJob name) jobDirs; # Evaluate a discovered job with given arguments evalJob = { job, # The imported job module (function) lib, nomadLib ? (import ./nomad.nix {inherit lib;}), vars ? {}, # Variables to pass to parameterized jobs extraArgs ? {}, }: let # Check function arity to see if it accepts vars funcArgs = builtins.functionArgs job; hasVars = funcArgs ? vars; baseArgs = {inherit lib nomadLib;} // extraArgs; fullArgs = if hasVars then baseArgs // {inherit vars;} else baseArgs; in job fullArgs; # Discover and evaluate all jobs (convenience wrapper) loadJobs = { path, lib, nomadLib ? (import ./nomad.nix {inherit lib;}), vars ? {}, # Global vars passed to all jobs extraArgs ? {}, }: let discovered = import ./default.nix; jobs = discovered.discoverJobs {inherit path lib nomadLib extraArgs;}; in lib.mapAttrs (name: job: discovered.evalJob {inherit job lib nomadLib vars extraArgs;} ) jobs; # Compile a set of jobs to JSON files # jobs: attrset of job definitions { name = { job.name = {...}; }; } # pkgs: nixpkgs compileJobs = { pkgs, jobs, lib ? pkgs.lib, }: lib.mapAttrs ( name: job: pkgs.writeText "${name}.nomad.json" (builtins.toJSON job) ) jobs; # Build a derivation containing all compiled jobs compileJobsDir = { pkgs, jobs, lib ? pkgs.lib, }: let jobFiles = lib.mapAttrs ( name: job: pkgs.writeText "${name}.nomad.json" (builtins.toJSON job) ) jobs; in pkgs.runCommand "nomad-jobs" {} '' mkdir -p $out ${lib.concatStrings (lib.mapAttrsToList (name: file: '' cp ${file} $out/${name}.nomad.json '') jobFiles)} ''; # Create a script to generate all job files to a directory mkGenerateScript = { pkgs, jobs, lib ? pkgs.lib, }: let jobFiles = lib.mapAttrs ( name: job: pkgs.writeText "${name}.nomad.json" (builtins.toJSON job) ) jobs; in pkgs.writeShellScriptBin "bosun-generate" '' set -euo pipefail OUTDIR="''${1:-$(pwd)/generated}" mkdir -p "$OUTDIR" ${lib.concatStrings (lib.mapAttrsToList (name: file: '' cp ${file} "$OUTDIR/${name}.nomad.json" chmod 644 "$OUTDIR/${name}.nomad.json" echo "✓ ${name}.nomad.json" '') jobFiles)} echo "" echo "Generated ${toString (lib.length (lib.attrNames jobs))} jobs in $OUTDIR" ''; }