exo: add module

This commit is contained in:
0xdsqr
2026-04-28 12:10:06 -05:00
committed by Austin Horstman
parent 7a45713b5d
commit 2e54a938cd
4 changed files with 127 additions and 0 deletions

View File

@@ -0,0 +1,10 @@
{
time = "2026-04-28T03:00:36+00:00";
condition = true;
message = ''
A new module is available: 'services.exo'.
exo connects devices into a local AI cluster and provides a dashboard
and API server for interacting with local models.
'';
}

75
modules/services/exo.nix Normal file
View File

@@ -0,0 +1,75 @@
{
config,
lib,
pkgs,
...
}:
let
cfg = config.services.exo;
in
{
meta.maintainers = [ lib.maintainers.dsqr ];
options.services.exo = {
enable = lib.mkEnableOption "exo local AI cluster node";
package = lib.mkPackageOption pkgs "exo" { };
environmentVariables = lib.mkOption {
type = lib.types.attrsOf lib.types.str;
default = { };
example = {
EXO_LIBP2P_NAMESPACE = "home-cluster";
EXO_OFFLINE = "true";
};
description = ''
Environment variables for the exo service.
See <https://github.com/exo-explore/exo#environment-variables>
for supported environment variables.
'';
};
extraArgs = lib.mkOption {
type = lib.types.listOf lib.types.str;
default = [ ];
example = [ "--no-worker" ];
description = ''
Extra command-line arguments passed to {command}`exo`.
'';
};
};
config = lib.mkIf cfg.enable {
home.packages = [ cfg.package ];
systemd.user.services.exo = {
Unit = {
Description = "exo local AI cluster node";
After = [ "network.target" ];
};
Service = {
ExecStart = lib.escapeShellArgs ([ (lib.getExe cfg.package) ] ++ cfg.extraArgs);
Environment = lib.mapAttrsToList (name: value: "${name}=${value}") cfg.environmentVariables;
Restart = "on-failure";
};
Install.WantedBy = [ "default.target" ];
};
launchd.agents.exo = {
enable = true;
config = {
ProgramArguments = [ (lib.getExe cfg.package) ] ++ cfg.extraArgs;
EnvironmentVariables = cfg.environmentVariables;
KeepAlive = {
Crashed = true;
SuccessfulExit = false;
};
ProcessType = "Background";
RunAtLoad = true;
};
};
};
}

View File

@@ -0,0 +1,3 @@
{
exo-service = ./service.nix;
}

View File

@@ -0,0 +1,39 @@
{ config, pkgs, ... }:
{
services.exo = {
enable = true;
package = config.lib.test.mkStubPackage {
name = "exo";
outPath = "@exo@";
};
environmentVariables = {
EXO_LIBP2P_NAMESPACE = "hm-test";
EXO_OFFLINE = "true";
};
extraArgs = [ "--no-worker" ];
};
nmt.script =
if pkgs.stdenv.hostPlatform.isDarwin then
''
plistFile=LaunchAgents/org.nix-community.home.exo.plist
assertFileExists "$plistFile"
assertFileRegex "$plistFile" '<key>EXO_LIBP2P_NAMESPACE</key>'
assertFileRegex "$plistFile" '<string>hm-test</string>'
assertFileRegex "$plistFile" '<key>EXO_OFFLINE</key>'
assertFileRegex "$plistFile" '<string>true</string>'
assertFileRegex "$plistFile" '<string>/bin/wait4path /nix/store &amp;&amp; exec @exo@/bin/exo --no-worker</string>'
''
else
''
serviceFile=home-files/.config/systemd/user/exo.service
assertFileExists "$serviceFile"
assertFileRegex "$serviceFile" 'After=network\.target'
assertFileRegex "$serviceFile" 'Environment=EXO_LIBP2P_NAMESPACE=hm-test'
assertFileRegex "$serviceFile" 'Environment=EXO_OFFLINE=true'
assertFileRegex "$serviceFile" 'ExecStart=@exo@/bin/exo --no-worker'
assertFileRegex "$serviceFile" 'Restart=on-failure'
'';
}