feat(#1184): make agent CPU quota and memory limit configurable
This commit is contained in:
parent
4f80253101
commit
d1fbb4aef8
7 changed files with 80 additions and 12 deletions
|
|
@ -50,10 +50,6 @@ const GIT_EMAIL: &str = "c0re@hyperhive.local";
|
|||
const WEB_PORT_BASE: u16 = 8100;
|
||||
const WEB_PORT_RANGE: u16 = 900;
|
||||
|
||||
/// Default resource caps applied to every managed container via a systemd
|
||||
/// drop-in under `/run/systemd/system/container@<NAME>.service.d/`.
|
||||
const DEFAULT_MEMORY_MAX: &str = "2G";
|
||||
const DEFAULT_CPU_QUOTA: &str = "50%";
|
||||
|
||||
/// FNV-1a hash of a string — shared by `agent_web_port` and
|
||||
/// `agent_network_ip` so the derivation rule is identical.
|
||||
|
|
@ -240,6 +236,8 @@ pub async fn spawn(
|
|||
dashboard_port: u16,
|
||||
operator_pronouns: &str,
|
||||
context_window_tokens: &std::collections::HashMap<String, u64>,
|
||||
cpu_quota: &str,
|
||||
memory_max: &str,
|
||||
) -> Result<()> {
|
||||
validate(name)?;
|
||||
if let Some(other) = port_collision(name).await {
|
||||
|
|
@ -269,7 +267,7 @@ pub async fn spawn(
|
|||
let container = container_name(name);
|
||||
priv_run("create", name).await?;
|
||||
set_nspawn_flags(&container, agent_dir, claude_dir, notes_dir).await?;
|
||||
set_resource_limits(&container).await?;
|
||||
set_resource_limits(&container, memory_max, cpu_quota).await?;
|
||||
systemd_daemon_reload().await?;
|
||||
priv_run("start", name).await
|
||||
}
|
||||
|
|
@ -398,6 +396,8 @@ pub async fn rebuild(
|
|||
dashboard_port: u16,
|
||||
operator_pronouns: &str,
|
||||
context_window_tokens: &std::collections::HashMap<String, u64>,
|
||||
cpu_quota: &str,
|
||||
memory_max: &str,
|
||||
on_step: &(dyn Fn(&str) + Send + Sync),
|
||||
) -> Result<()> {
|
||||
// Sync the meta flake (idempotent — no-op when the rendered
|
||||
|
|
@ -420,7 +420,7 @@ pub async fn rebuild(
|
|||
// `applied/<n>/main` currently points at (deployed/<latest>).
|
||||
// Commits the lock if it changed.
|
||||
crate::meta::lock_update_for_rebuild(name).await?;
|
||||
rebuild_no_meta(name, agent_dir, applied_dir, claude_dir, notes_dir, on_step).await
|
||||
rebuild_no_meta(name, agent_dir, applied_dir, claude_dir, notes_dir, cpu_quota, memory_max, on_step).await
|
||||
}
|
||||
|
||||
/// Container-level rebuild without touching the meta repo. Callers
|
||||
|
|
@ -439,6 +439,8 @@ pub async fn rebuild_no_meta(
|
|||
applied_dir: &Path,
|
||||
claude_dir: &Path,
|
||||
notes_dir: &Path,
|
||||
cpu_quota: &str,
|
||||
memory_max: &str,
|
||||
on_step: &(dyn Fn(&str) + Send + Sync),
|
||||
) -> Result<()> {
|
||||
validate(name)?;
|
||||
|
|
@ -458,7 +460,7 @@ pub async fn rebuild_no_meta(
|
|||
// See `docs/coordinator.md::Container lifecycle`.
|
||||
let was_running = is_running(name).await;
|
||||
set_nspawn_flags(&container, agent_dir, claude_dir, notes_dir).await?;
|
||||
set_resource_limits(&container).await?;
|
||||
set_resource_limits(&container, memory_max, cpu_quota).await?;
|
||||
systemd_daemon_reload().await?;
|
||||
if was_running {
|
||||
on_step("nix build");
|
||||
|
|
@ -530,7 +532,7 @@ pub async fn rebuild_no_meta(
|
|||
on_step("nixos-container create");
|
||||
priv_run("create", name).await?;
|
||||
set_nspawn_flags(&container, agent_dir, claude_dir, notes_dir).await?;
|
||||
set_resource_limits(&container).await?;
|
||||
set_resource_limits(&container, memory_max, cpu_quota).await?;
|
||||
systemd_daemon_reload().await?;
|
||||
on_step("nixos-container start");
|
||||
priv_run("start", name).await
|
||||
|
|
@ -1049,9 +1051,8 @@ pub async fn git_update_ref(dir: &Path, refname: &str, target: &str) -> Result<(
|
|||
/// Write a systemd drop-in for `container@<container>.service` that applies
|
||||
/// our default resource caps. Goes under `/run/systemd/system/...` so it's
|
||||
/// ephemeral (regenerated on every spawn / rebuild).
|
||||
async fn set_resource_limits(container: &str) -> Result<()> {
|
||||
crate::priv_client::write_resource_limits(container, DEFAULT_MEMORY_MAX, DEFAULT_CPU_QUOTA)
|
||||
.await
|
||||
async fn set_resource_limits(container: &str, memory_max: &str, cpu_quota: &str) -> Result<()> {
|
||||
crate::priv_client::write_resource_limits(container, memory_max, cpu_quota).await
|
||||
}
|
||||
|
||||
async fn systemd_daemon_reload() -> Result<()> {
|
||||
|
|
|
|||
Loading…
Reference in a new issue