Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 19 additions & 2 deletions dag/extdeps/os/systemctl.dag
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
module extdeps.os.systemctl

import std.types { NonEmptyStr, String, List, Bool, Int }
import extdeps.os.systemd { SystemdUnitProperty, systemd_unit_property_wire }

import extdeps.external_authority { ExternalAuthority }
import extdeps.uri { Uri, Https }
Expand Down Expand Up @@ -28,6 +29,16 @@ fn systemctl_disable_now_argv(unit: NonEmptyStr) -> List<String> {
["systemctl", "disable", "--now", unit as String]
}

fn systemctl_show_property_argv(unit: NonEmptyStr, property: SystemdUnitProperty) -> List<String> {
[
"systemctl",
"show",
unit as String,
concat("--property=", systemd_unit_property_wire(property: property) as String),
"--value",
]
}

type UnitFileState
= UnitEnabled
| UnitEnabledRuntime
Expand Down Expand Up @@ -139,13 +150,19 @@ service systemd.Systemctl {
}

operation ShowProperty {
input { unit: NonEmptyStr, property: NonEmptyStr }
output { value: String from "stdout" }
input { unit: NonEmptyStr, property: SystemdUnitProperty }
output {
value: String from "stdout"
success: Bool from "exit_success"
}
readonly
transport shell { argv: ["systemctl", "show", "{unit}", "--property={property}", "--value"] }
exit {
0 => Unit
nonzero => String "systemctl show failed"
}
mock_response {
0 => { value: "8589934592", success: true } "hermetic systemd.Systemctl.ShowProperty"
}
}
}
26 changes: 21 additions & 5 deletions dag/extdeps/os/systemd.dag
Original file line number Diff line number Diff line change
Expand Up @@ -26,16 +26,32 @@ data systemd_parse_label_derivation_debt: List<NonEmptyStr> = [
"dissolve-on: when contract-driven derivation is available (§3 single authority), derive parse/label from wire contract instead of hand-rolling",
]

type SystemdUnitProperty
= MemoryMax
| MemorySwapMax
| MemoryHigh
| CPUWeight
| MemoryCurrent

fn systemd_unit_property_wire(property: SystemdUnitProperty) -> NonEmptyStr {
match property {
MemoryMax => "MemoryMax" as NonEmptyStr
MemorySwapMax => "MemorySwapMax" as NonEmptyStr
MemoryHigh => "MemoryHigh" as NonEmptyStr
CPUWeight => "CPUWeight" as NonEmptyStr
MemoryCurrent => "MemoryCurrent" as NonEmptyStr
}
}

data systemd_memory_max_property: NonEmptyStr = "MemoryMax"
data systemd_memory_max_property: NonEmptyStr = systemd_unit_property_wire(property: MemoryMax)

data systemd_memory_swap_max_property: NonEmptyStr = "MemorySwapMax"
data systemd_memory_swap_max_property: NonEmptyStr = systemd_unit_property_wire(property: MemorySwapMax)

data systemd_memory_high_property: NonEmptyStr = "MemoryHigh"
data systemd_memory_high_property: NonEmptyStr = systemd_unit_property_wire(property: MemoryHigh)

data systemd_cpu_weight_property: NonEmptyStr = "CPUWeight"
data systemd_cpu_weight_property: NonEmptyStr = systemd_unit_property_wire(property: CPUWeight)

data systemd_memory_current_property: NonEmptyStr = "MemoryCurrent"
data systemd_memory_current_property: NonEmptyStr = systemd_unit_property_wire(property: MemoryCurrent)

type SystemdCgroupMemoryLimit
= MemoryLimitUnbounded
Expand Down
2 changes: 0 additions & 2 deletions dag/gunbc/ci_deploy_access_observe.dag
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,6 @@ fn deploy_access_effect_is_typed_probe(effect: HostEffect) -> Bool {
Srv3BootOnceReadBackSleep => false
Srv3ReceiptEmit { lines: _ } => false
HostIdentityShortHostnameRead => false
SystemdUnitMemoryMaxRead { unit: _ } => false
SystemdUnitMemoryPropertiesRead { unit: _ } => false
LiveDeployApply { spec: _ } => false
LiveDeployRetract { spec: _ } => false
LiveDeployEnsureDependency { dep: _ } => false
Expand Down
2 changes: 0 additions & 2 deletions dag/gunbc/fleet_converge_cli.dag
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,6 @@ fn converge_cli_applied_knob_count(intent: HostEffectIntent, fallback: Int) -> I
Srv3BootOnceReadBackSleep => fallback
Srv3ReceiptEmit { lines: _ } => fallback
HostIdentityShortHostnameRead => fallback
SystemdUnitMemoryMaxRead { unit: _ } => fallback
SystemdUnitMemoryPropertiesRead { unit: _ } => fallback
LiveDeployApply { spec: _ } => fallback
LiveDeployRetract { spec: _ } => fallback
LiveDeployEnsureDependency { dep: _ } => fallback
Expand Down
111 changes: 45 additions & 66 deletions dag/gunbc/fleet_show_effective_read.dag
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ type FleetHostEffectiveReadGroundedReceipt {
}

data gunbc_fleet_show_effective_read_scope_disposition: Disposition = std.disposition.Terminal {
reason: "Typed READ-ONLY live host-read seam for runner-allocation-v0 (three blocking knobs): (1) runner-slice MemoryMax on system-actions-runner.slice, (2) per-slot MemoryMax+MemorySwapMax on actions-runner@<host>-*.service, (3) runner_width active-unit count. Transport intent lives here; shell realization is scaffold-marked medium-as-string (fleet_show_effective_read_transport_script_scaffold) until host_effect orchestration emit binds grammar rows. Committed ShowEffectiveRead rows stay ReadAbsent until live or fixture-grounded read supplies ReadObserved. ManagedOOMMemoryPressureLimit percent-wire grounding lives in extdeps.os.oomd."
reason: "Typed READ-ONLY live host-read seam for runner-allocation-v0 (three blocking knobs): (1) runner-slice MemoryMax on system-actions-runner.slice, (2) per-slot MemoryMax+MemorySwapMax on actions-runner@<host>-*.service, (3) runner_width active-unit count. systemctl show reads dissolve through extdeps.os.systemctl.ShowProperty typed argv (gunbc.systemctl_show_read) — no per-command HostEffect nicknames, no concat shell strings. Committed ShowEffectiveRead rows stay ReadAbsent until live or fixture-grounded read supplies ReadObserved. ManagedOOMMemoryPressureLimit percent-wire grounding lives in extdeps.os.oomd."
}

data fleet_show_effective_read_transport_script_scaffold: Disposition = Scaffold {
Expand All @@ -71,11 +71,50 @@ data fleet_show_effective_read_transport_script_scaffold: Disposition = Scaffold
}
}

fn fleet_runner_unit_property_read_script(unit: NonEmptyStr, property: NonEmptyStr) -> String {
concat(
concat(concat("systemctl show \"", unit, "\" --property="), property),
" --value 2>/dev/null || true"
)
fn fleet_runner_unit_memory_live_read(
host: HostIdentity,
unit: NonEmptyStr,
probed_at: NonEmptyStr,
) -> RunnerUnitMemoryLiveRead? {
match fleet_host_ssh_transport(host: host) {
Present { value: transport } =>
match systemctl_show_property_read(transport: transport, unit: unit, property: MemoryMax) {
Present { value: memory_max_raw } =>
match systemctl_show_property_read(transport: transport, unit: unit, property: MemorySwapMax) {
Present { value: memory_swap_max_raw } =>
match systemctl_show_property_read(transport: transport, unit: unit, property: MemoryHigh) {
Present { value: memory_high_raw } =>
Present {
value: runner_unit_live_read_typed(
row: RunnerUnitLiveReadRow {
unit: unit,
memory_max_raw: memory_max_raw,
memory_swap_max_raw: memory_swap_max_raw,
memory_high_raw: memory_high_raw,
memory_current_raw: "",
probed_at: probed_at,
}
)
}
Absent => none
}
Absent => none
}
Absent => none
}
Absent => none
}
}

fn fleet_runner_slice_cap_memory_max_raw(
host: HostIdentity,
slice_unit: NonEmptyStr,
) -> String? {
match fleet_host_ssh_transport(host: host) {
Present { value: transport } =>
systemctl_show_property_read(transport: transport, unit: slice_unit, property: MemoryMax)
Absent => none
}
}

fn runner_unit_live_read_row_from_stdout(
Expand Down Expand Up @@ -111,44 +150,6 @@ fn runner_unit_memory_live_read_from_stdout(
}
}

fn fleet_runner_unit_memory_read_apply(
host: HostIdentity,
unit: NonEmptyStr,
) -> Reconciliation<HostEffectIntent, HostEffectEvidence>? {
match fleet_host_control_plane(host: host) {
Present { value: cp } =>
match fleet_host_ssh_transport(host: host) {
Present { value: transport } =>
Present {
value: host_effect_apply(
target: cp,
effect: SystemdUnitMemoryPropertiesRead { unit: unit },
evidence: host_effect_read_evidence,
transport: transport,
)
}
Absent => none
}
Absent => none
}
}

fn runner_unit_memory_live_read_from_apply(
r: Reconciliation<HostEffectIntent, HostEffectEvidence>,
unit: NonEmptyStr,
probed_at: NonEmptyStr,
) -> RunnerUnitMemoryLiveRead? {
match r {
Converged { evidence: e, applied: _ } =>
match e {
ShellEffectApplied { stdout: out, exit_code: _ } =>
runner_unit_memory_live_read_from_stdout(unit: unit, stdout: out, probed_at: probed_at)
ConvergePlanApplied { stdout: _, exit_code: _ } => none
}
NotConverged { reason: _, applied: _ } => none
}
}

fn show_effective_read_from_unit_row(
host: HostIdentity,
row: RunnerUnitLiveReadRow,
Expand Down Expand Up @@ -259,28 +260,6 @@ fn fleet_host_ssh_transport(host: HostIdentity) -> HostEffectTransport? {
} else { none } }
}

fn fleet_runner_slice_cap_read_apply(
host: HostIdentity,
slice_unit: NonEmptyStr,
) -> Reconciliation<HostEffectIntent, HostEffectEvidence>? {
match fleet_host_control_plane(host: host) {
Present { value: cp } =>
match fleet_host_ssh_transport(host: host) {
Present { value: transport } =>
Present {
value: host_effect_apply(
target: cp,
effect: SystemdUnitMemoryMaxRead { unit: slice_unit },
evidence: host_effect_read_evidence,
transport: transport,
)
}
Absent => none
}
Absent => none
}
}

fn runner_slice_cap_live_read_typed(row: RunnerSliceCapLiveReadRow) -> RunnerSliceCapLiveRead {
RunnerSliceCapLiveRead {
slice_unit: row.slice_unit,
Expand Down
36 changes: 0 additions & 36 deletions dag/gunbc/fleet_show_effective_read_script.dag

This file was deleted.

51 changes: 27 additions & 24 deletions dag/gunbc/host_converge_slice1.dag
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,16 @@ import std.decl_ref { DeclarationRef, WholeDeclaration }
import extdeps.shell
import extdeps.shell.exec { transport_script_from_body }
import product.placement_supply { HostIdentity }
import extdeps.os.systemd { systemd_memory_max_property, systemd_memory_current_property, parse_systemd_memory_limit_show, MemoryLimitBytes, MemoryLimitUnbounded, MemoryLimitAbsent }
import extdeps.os.systemd {
systemd_memory_max_property,
MemoryMax,
MemoryCurrent,
parse_systemd_memory_limit_show,
MemoryLimitBytes,
MemoryLimitUnbounded,
MemoryLimitAbsent,
}
import gunbc.systemctl_show_read { systemctl_show_property_read_local }
import std.measure { ByteSize, byte_size, byte_size_count }
import gunbc.fleet_intent_network { operator_host_srv1, operator_host_srv3 }
import gunbc.fleet_host_budget { declared_runner_count }
Expand All @@ -32,7 +41,6 @@ import gunbc.runner_unit_live_read {
runner_unit_usage_exceeds_bytes,
}
import gunbc.fleet_show_effective_read {
fleet_runner_unit_property_read_script,
per_slot_memory_cap_verdict_from_unit_read,
}

Expand Down Expand Up @@ -135,8 +143,8 @@ fn host_converge_slice1_probed_at() -> NonEmptyStr? {
}
}

fn host_converge_slice1_memory_max_read_script(unit: NonEmptyStr) -> String {
fleet_runner_unit_property_read_script(unit: unit, property: systemd_memory_max_property)
fn host_converge_slice1_read_memory_max_raw(unit: NonEmptyStr) -> String? {
systemctl_show_property_read_local(unit: unit, property: MemoryMax)
}

fn host_converge_slice1_memory_max_set_script(unit: NonEmptyStr, bytes_value: String) -> String {
Expand All @@ -146,16 +154,6 @@ fn host_converge_slice1_memory_max_set_script(unit: NonEmptyStr, bytes_value: St
)
}

fn host_converge_slice1_read_memory_max_raw(unit: NonEmptyStr) -> String? {
let result = shell.Exec.Run(script: transport_script_from_body(body: host_converge_slice1_memory_max_read_script(unit: unit)))
if result.success {
let raw = trim(result.stdout)
if raw == "" { none } else { Present { value: raw } }
} else {
none
}
}

fn host_converge_slice1_live_read(unit: NonEmptyStr, probed_at: NonEmptyStr) -> RunnerUnitMemoryLiveRead? {
match host_converge_slice1_read_memory_max_raw(unit: unit) {
Present { value: memory_max_raw } =>
Expand Down Expand Up @@ -237,14 +235,7 @@ type HostConvergeSlice1UsageGuardOutcome
data host_converge_slice1_usage_guard_placeholder_probed_at: NonEmptyStr = "host_converge_slice1_usage_guard"

fn host_converge_slice1_read_memory_current_raw(unit: NonEmptyStr) -> String? {
let script = fleet_runner_unit_property_read_script(unit: unit, property: systemd_memory_current_property)
let result = shell.Exec.Run(script: transport_script_from_body(body: script))
if result.success {
let raw = trim(result.stdout)
if raw == "" { none } else { Present { value: raw } }
} else {
none
}
systemctl_show_property_read_local(unit: unit, property: MemoryCurrent)
}

fn host_converge_slice1_usage_guard(unit: NonEmptyStr, target_bytes_value: String) -> HostConvergeSlice1UsageGuardOutcome {
Expand Down Expand Up @@ -312,15 +303,27 @@ fn host_converge_slice1_enumerate_units_script(instance_glob: String) -> String
)
}

fn host_converge_slice1_enumerate_unit_line_trimmed(line: String) -> String {
trim(line)
}

fn host_converge_slice1_enumerate_unit_line_nonempty(line: String) -> Bool {
host_converge_slice1_enumerate_unit_line_trimmed(line: line) != ""
}

fn host_converge_slice1_enumerate_unit_line_as_unit(line: String) -> NonEmptyStr {
host_converge_slice1_enumerate_unit_line_trimmed(line: line) as NonEmptyStr
}

fn host_converge_slice1_enumerate_units(instance_glob: String) -> List<NonEmptyStr>? {
let result = shell.Exec.Run(script: transport_script_from_body(body: host_converge_slice1_enumerate_units_script(instance_glob: instance_glob)))
if result.success {
let trimmed = trim(result.stdout)
if trimmed == "" {
Present { value: [] }
} else {
let lines = filter(split(s: trimmed, delimiter: "\n"), l => trim(l) != "")
Present { value: map(lines, l => trim(l) as NonEmptyStr) }
let lines = filter(split(s: trimmed, delimiter: "\n"), host_converge_slice1_enumerate_unit_line_nonempty)
Present { value: map(lines, host_converge_slice1_enumerate_unit_line_as_unit) }
}
} else {
none
Expand Down
2 changes: 0 additions & 2 deletions dag/gunbc/host_effect.dag
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,6 @@ type HostEffect =
| Srv3BootOnceReadBackSleep
| Srv3ReceiptEmit { lines: List<String> }
| HostIdentityShortHostnameRead
| SystemdUnitMemoryMaxRead { unit: NonEmptyStr }
| SystemdUnitMemoryPropertiesRead { unit: NonEmptyStr }
| LiveDeployApply { spec: DeploymentSpec }
| LiveDeployRetract { spec: DeploymentSpec }
| LiveDeployEnsureDependency { dep: DeploymentDependencyStep }
Expand Down
Loading
Loading