add hive-forge module: private forgejo for agents
new `services.hive-forge.enable` (off by default) wraps `services.forgejo` with hyperhive-friendly defaults: sqlite (no extra db service), built-in ssh on 2222 so it doesn't fight the host's openssh, http on 3000 (outside hyperhive's 7000/8000/8100-8999 ranges), registration off (operator seeds agent users), private repos by default. exported as `nixosModules.hive-forge` — operator imports it on the host alongside hive-c0re. container-side wiring (MCP tools or a bind-mounted token) is deferred; containers already share the host netns so they can reach http://localhost:3000 today.
This commit is contained in:
parent
824acee134
commit
c2d176ed13
2 changed files with 117 additions and 0 deletions
|
|
@ -98,6 +98,7 @@
|
||||||
hyperhivePackage = system: self.packages.${system}.default;
|
hyperhivePackage = system: self.packages.${system}.default;
|
||||||
hyperhiveFlake = "${self}";
|
hyperhiveFlake = "${self}";
|
||||||
};
|
};
|
||||||
|
hive-forge = ./nix/modules/hive-forge.nix;
|
||||||
};
|
};
|
||||||
|
|
||||||
nixosConfigurations =
|
nixosConfigurations =
|
||||||
|
|
|
||||||
116
nix/modules/hive-forge.nix
Normal file
116
nix/modules/hive-forge.nix
Normal file
|
|
@ -0,0 +1,116 @@
|
||||||
|
{
|
||||||
|
pkgs,
|
||||||
|
lib,
|
||||||
|
config,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
let
|
||||||
|
cfg = config.services.hive-forge;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
# Thin wrapper around `services.forgejo` with hyperhive-friendly
|
||||||
|
# defaults: sqlite (no extra service to manage), built-in SSH on a
|
||||||
|
# non-22 port so it doesn't fight the host's sshd, registration off
|
||||||
|
# (agents get accounts seeded out of band), and ports opened in the
|
||||||
|
# firewall.
|
||||||
|
#
|
||||||
|
# Forge wiring into the agent containers is intentionally out of
|
||||||
|
# scope here — containers already share the host network namespace,
|
||||||
|
# so once this module is enabled an agent can reach the forge at
|
||||||
|
# http://localhost:<httpPort> without any extra bind mount. The MCP
|
||||||
|
# tool surface (open PR, list repos, etc.) lives in a separate
|
||||||
|
# follow-up that the operator opts into per agent.
|
||||||
|
|
||||||
|
options.services.hive-forge = {
|
||||||
|
enable = lib.mkEnableOption "hive-forge — private Forgejo instance for hyperhive agents";
|
||||||
|
|
||||||
|
httpPort = lib.mkOption {
|
||||||
|
type = lib.types.port;
|
||||||
|
default = 3000;
|
||||||
|
description = ''
|
||||||
|
TCP port the forge serves HTTP on. Default 3000 sits outside
|
||||||
|
hyperhive's claimed ranges (dashboard 7000, manager 8000,
|
||||||
|
sub-agents 8100..8999) so they don't collide.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
sshPort = lib.mkOption {
|
||||||
|
type = lib.types.port;
|
||||||
|
default = 2222;
|
||||||
|
description = ''
|
||||||
|
TCP port the forge's built-in SSH server listens on. Kept off
|
||||||
|
22 so it doesn't clash with the host's openssh. Agents push
|
||||||
|
with `ssh -p <sshPort> git@<domain>:<owner>/<repo>.git`.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
domain = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
default = "localhost";
|
||||||
|
example = "forge.internal";
|
||||||
|
description = ''
|
||||||
|
Hostname agents and operator dial the forge by. `localhost` is
|
||||||
|
fine for a single-host setup since containers share the host
|
||||||
|
netns; set a real hostname when you want clones from outside
|
||||||
|
the host to look canonical.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
openFirewall = lib.mkOption {
|
||||||
|
type = lib.types.bool;
|
||||||
|
default = true;
|
||||||
|
description = ''
|
||||||
|
Open `httpPort` + `sshPort` in the host firewall. Off when the
|
||||||
|
forge should only be reachable from inside the host (the
|
||||||
|
forge listens on all interfaces either way; this just gates
|
||||||
|
external access).
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = lib.mkIf cfg.enable {
|
||||||
|
services.forgejo = {
|
||||||
|
enable = true;
|
||||||
|
database.type = "sqlite3";
|
||||||
|
lfs.enable = true;
|
||||||
|
settings = {
|
||||||
|
server = {
|
||||||
|
DOMAIN = cfg.domain;
|
||||||
|
ROOT_URL = "http://${cfg.domain}:${toString cfg.httpPort}/";
|
||||||
|
HTTP_PORT = cfg.httpPort;
|
||||||
|
START_SSH_SERVER = true;
|
||||||
|
SSH_PORT = cfg.sshPort;
|
||||||
|
SSH_LISTEN_PORT = cfg.sshPort;
|
||||||
|
BUILTIN_SSH_SERVER_USER = "git";
|
||||||
|
DISABLE_SSH = false;
|
||||||
|
};
|
||||||
|
# Registration off — operator creates agent users via
|
||||||
|
# `forgejo admin user create` (or the API once seeded).
|
||||||
|
# Agents that need access get a dedicated account + token.
|
||||||
|
service = {
|
||||||
|
DISABLE_REGISTRATION = true;
|
||||||
|
REQUIRE_SIGNIN_VIEW = false;
|
||||||
|
};
|
||||||
|
repository = {
|
||||||
|
DEFAULT_BRANCH = "main";
|
||||||
|
DEFAULT_PRIVATE = "private";
|
||||||
|
};
|
||||||
|
# Quiet logs at idle; bump when debugging.
|
||||||
|
log.LEVEL = "Warn";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
networking.firewall = lib.mkIf cfg.openFirewall {
|
||||||
|
allowedTCPPorts = [
|
||||||
|
cfg.httpPort
|
||||||
|
cfg.sshPort
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
# Convenience: drop the forgejo CLI on the host PATH so the
|
||||||
|
# operator can `forgejo admin user create …` without hunting for
|
||||||
|
# the wrapped binary. The forgejo service runs as its own user;
|
||||||
|
# admin commands need `sudo -u forgejo`.
|
||||||
|
environment.systemPackages = [ pkgs.forgejo ];
|
||||||
|
};
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue