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
2 changes: 2 additions & 0 deletions dag/gunbc/host_effect.dag
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import std.access { AccessDecision }
import std.disposition { Disposition, RealizationDispatch, Scaffold, Terminal }
import std.decl_ref { DeclarationRef, WholeDeclaration }
import extdeps.bmc.types { RedfishSystemAction }
import extdeps.dns.domain_name { DnsLabel }
import gunbc.fleet_intent { ComputeHost }
import gunbc.host_converge { HostConverge }
import std.effects {
Expand All @@ -21,6 +22,7 @@ type HostEffect =
ShellCommand { script: String }
| RedfishAction { action: RedfishSystemAction }
| ConvergePlan { policy: HostConverge }
| SetHostnameCas { hostnamectl_path: NonEmptyStr, base: DnsLabel, desired: DnsLabel }
| Srv3InstallReconcileObserve { include_git_meta: Bool }
| DurableApprovalGrantRecord
| DurableApprovalGrantRead
Expand Down
24 changes: 24 additions & 0 deletions dag/gunbc/host_effect_hostname_script.dag
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
module gunbc.host_effect_hostname_script

import std.types { String, NonEmptyStr }
import extdeps.dns.domain_name { DnsLabel }
import std.disposition { Disposition, Scaffold, SingleAuthority }
import std.decl_ref { DeclarationRef, WholeDeclaration }

data host_effect_hostname_script_dissolution_trigger: String = "🟡 dissolve-on: host_effect_hostname_script — concat-built bash CAS hostnamectl body for SetHostnameCas realize-layer transport (P6 Part 1; relocated from host_identity_converge scaffold); DISSOLVES WHEN bash-emit (#5828 / shell-emission slice0) realizes SetHostnameCas through typed argv invocations / grammar-emitted nodes and host_effect_set_hostname_cas_script retires without concat-built transport strings; retire medium_structure_exception_roster entry for dag/gunbc/host_effect_hostname_script.dag. Wave 4 residue (shell→dag census §1C category C)."

data host_effect_hostname_script_scaffold: Disposition = Scaffold {
dissolves_to: SingleAuthority,
bind: DeclarationRef {
module_path: "gunbc.host_effect_hostname_script",
decl_name: "host_effect_hostname_script_dissolution_trigger",
field: WholeDeclaration,
}
}

fn host_effect_set_hostname_cas_script(hostnamectl_path: NonEmptyStr, base: DnsLabel, desired: DnsLabel) -> String {
concat(
concat("[ \"$(hostname -s)\" = \"", concat(base as String, "\" ] && sudo -n ")),
concat(hostnamectl_path as String, concat(" set-hostname ", desired as String))
)
}
28 changes: 27 additions & 1 deletion dag/gunbc/host_effect_realize.dag
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
module gunbc.host_effect_realize

import gunbc.host_effect {
HostEffect, ShellCommand, RedfishAction, ConvergePlan,
HostEffect, ShellCommand, RedfishAction, ConvergePlan, SetHostnameCas,
Srv3InstallReconcileObserve,
DurableApprovalGrantRecord,
DurableApprovalGrantRead,
Expand All @@ -21,6 +21,7 @@ import gunbc.host_effect {
EmitArtifactThenThinRun, BootstrapFragment,
host_effect_drive,
}
import extdeps.dns.domain_name { DnsLabel }
import std.effects { IdempotencyEvidence }
import std.realization_reconcile {
Reconciliation, Converged, NotConverged,
Expand All @@ -45,12 +46,14 @@ import gunbc.ci_deploy_access {
deploy_access_decision_reason,
}
import gunbc.srv3_host_effect_script { srv3_host_effect_script_for }
import gunbc.host_effect_hostname_script { host_effect_set_hostname_cas_script }
import std.types { String, NonEmptyStr, List }

type ResolvedHostEffectCell =
ShellOnHost { node: ComputeHost, script: String }
| RedfishOnBmc { node: ComputeHost, action: RedfishSystemAction }
| ConvergeOnHost { node: ComputeHost, host_converge: HostConverge }
| HostnameOnHost { node: ComputeHost, hostnamectl_path: NonEmptyStr, base: DnsLabel, desired: DnsLabel }
| IncompatibleCell { reason: String }

fn converge_plan_identity_mismatch_reason(node: ComputeHost, policy: HostConverge) -> String {
Expand Down Expand Up @@ -95,6 +98,8 @@ fn resolve_host_effect_cell(target: NodeControlPlane, effect: HostEffect) -> Res
Srv3NbdProxyServe => srv3_host_effect_script_resolution_failed_cell()
Srv3BootOnceReadBackSleep => srv3_host_effect_script_resolution_failed_cell()
Srv3ReceiptEmit { lines: _ } => srv3_host_effect_script_resolution_failed_cell()
SetHostnameCas { hostnamectl_path: p, base: b, desired: d } =>
HostnameOnHost { node: n, hostnamectl_path: p, base: b, desired: d }
}
}
BmcController { node: n } =>
Expand All @@ -120,6 +125,8 @@ fn resolve_host_effect_cell(target: NodeControlPlane, effect: HostEffect) -> Res
Srv3NbdProxyServe => srv3_host_effect_script_resolution_failed_cell()
Srv3BootOnceReadBackSleep => srv3_host_effect_script_resolution_failed_cell()
Srv3ReceiptEmit { lines: _ } => srv3_host_effect_script_resolution_failed_cell()
SetHostnameCas { hostnamectl_path: _, base: _, desired: _ } =>
IncompatibleCell { reason: "host_effect: SetHostnameCas is in-band (shell hostnamectl) and cannot target BmcController (out-of-band Redfish only); target HostOs instead. Typed mismatch via total fold, DESIGN section 5." }
}
}
}
Expand Down Expand Up @@ -236,6 +243,20 @@ fn realize_shell_on_host(script: String, transport: HostEffectTransport, intent:
)
}

fn realize_set_hostname_cas_on_host(
hostnamectl_path: NonEmptyStr,
base: DnsLabel,
desired: DnsLabel,
transport: HostEffectTransport,
intent: HostEffectIntent,
) -> Reconciliation<HostEffectIntent, HostEffectEvidence> {
realize_shell_on_host(
script: host_effect_set_hostname_cas_script(hostnamectl_path: hostnamectl_path, base: base, desired: desired),
transport: transport,
intent: intent,
)
}

fn host_effect_apply(target: NodeControlPlane, effect: HostEffect, evidence: IdempotencyEvidence, transport: HostEffectTransport) -> Reconciliation<HostEffectIntent, HostEffectEvidence> {
let intent = HostEffectIntent {
target: target,
Expand All @@ -248,6 +269,8 @@ fn host_effect_apply(target: NodeControlPlane, effect: HostEffect, evidence: Ide
ShellOnHost { node: _, script: s } => realize_shell_on_host(script: s, transport: transport, intent: intent)
ConvergeOnHost { node: _, host_converge: hc } =>
realize_converge_on_host(host_converge: hc, transport: transport, intent: intent)
HostnameOnHost { node: _, hostnamectl_path: p, base: b, desired: d } =>
realize_set_hostname_cas_on_host(hostnamectl_path: p, base: b, desired: d, transport: transport, intent: intent)
RedfishOnBmc { node: _, action: _ } =>
NotConverged { reason: "host_effect_apply: RedfishAction realization is a fail-closed Unimplemented stub in Phase A; neat-boar-71 realizes it over RedfishRest in Phase C. No plausible no-op for a power/boot action (DESIGN section 5).", applied: intent }
IncompatibleCell { reason: why } => NotConverged { reason: why, applied: intent }
Expand Down Expand Up @@ -286,6 +309,8 @@ fn host_effect_apply_gated(
ShellOnHost { node: _, script: s } => realize_shell_on_host(script: s, transport: transport, intent: intent)
ConvergeOnHost { node: _, host_converge: hc } =>
realize_converge_on_host(host_converge: hc, transport: transport, intent: intent)
HostnameOnHost { node: _, hostnamectl_path: p, base: b, desired: d } =>
realize_set_hostname_cas_on_host(hostnamectl_path: p, base: b, desired: d, transport: transport, intent: intent)
RedfishOnBmc { node: _, action: _ } =>
NotConverged { reason: "host_effect_apply: RedfishAction realization is a fail-closed Unimplemented stub in Phase A; neat-boar-71 realizes it over RedfishRest in Phase C. No plausible no-op for a power/boot action (DESIGN section 5).", applied: intent }
IncompatibleCell { reason: why } => NotConverged { reason: why, applied: intent }
Expand Down Expand Up @@ -325,6 +350,7 @@ fn host_effect_drive_directive(r: Reconciliation<HostEffectIntent, HostEffectEvi
IncompatibleCell { reason: inner_why } => Refused { reason: inner_why }
ShellOnHost { node: _, script: _ } => not_converged_directive(drive: host_effect_drive(intent: intent))
ConvergeOnHost { node: _, host_converge: _ } => not_converged_directive(drive: host_effect_drive(intent: intent))
HostnameOnHost { node: _, hostnamectl_path: _, base: _, desired: _ } => not_converged_directive(drive: host_effect_drive(intent: intent))
RedfishOnBmc { node: _, action: _ } => not_converged_directive(drive: host_effect_drive(intent: intent))
}
}
Expand Down
46 changes: 16 additions & 30 deletions dag/gunbc/host_identity_converge.dag
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
module gunbc.host_identity_converge

import std.types { String, NonEmptyStr, Bool }
import std.disposition { Disposition, Scaffold, SingleAuthority }
import std.decl_ref { DeclarationRef, WholeDeclaration }
import std.access { AccessDecision, Deny }
import extdeps.dns.domain_name { DnsLabel }
import std.effects {
Expand All @@ -14,7 +12,8 @@ import std.effects {
LatticeEffect,
}
import gunbc.host_effect {
ShellCommand,
HostEffect,
SetHostnameCas,
NodeControlPlane,
HostEffectTransport,
HostEffectIntent,
Expand Down Expand Up @@ -54,26 +53,6 @@ import std.realization_reconcile {
reconciliation_converged,
}

data host_identity_set_hostname_script_scaffold: Disposition = Scaffold {
dissolves_to: SingleAuthority,
bind: DeclarationRef {
module_path: "gunbc.live_deploy.emit",
decl_name: "live_deploy_emit_shell_dissolution_trigger",
field: WholeDeclaration,
}
}

fn host_identity_set_hostname_script(desired_hostname: DnsLabel) -> String {
concat(concat("sudo -n ", host_identity_hostnamectl_path), concat(" set-hostname ", desired_hostname as String))
}

fn host_identity_set_hostname_script_cas(base_hostname: DnsLabel, desired_hostname: DnsLabel) -> String {
concat(
concat("[ \"$(hostname -s)\" = \"", base_hostname as String, "\" ] && sudo -n "),
concat(host_identity_hostnamectl_path, " set-hostname ", desired_hostname as String)
)
}

fn host_identity_precondition_verdict(
base: DeployedIntentV0,
observed: HostIdentityObservation,
Expand Down Expand Up @@ -148,9 +127,16 @@ fn host_identity_plan_from_verdict(
}
}

fn host_identity_plan_effect_script(plan: HostIdentityPlan) -> String? {
fn host_identity_plan_effect(plan: HostIdentityPlan) -> HostEffect? {
match plan {
ApplyPlan { base: b, desired: d } => Present { value: host_identity_set_hostname_script_cas(base_hostname: b, desired_hostname: d) }
ApplyPlan { base: b, desired: d } =>
Present {
value: SetHostnameCas {
hostnamectl_path: host_identity_hostnamectl_path,
base: b,
desired: d,
}
}
NoopPlan => none
ConflictPlan { verdict: _ } => none
}
Expand All @@ -168,15 +154,15 @@ fn host_identity_apply_evidence() -> IdempotencyEvidence {

fn host_identity_apply_denied(
target: NodeControlPlane,
script: String,
effect: HostEffect,
transport: HostEffectTransport,
reason: String,
) -> Reconciliation<HostEffectIntent, HostEffectEvidence> {
NotConverged {
reason: reason,
applied: HostEffectIntent {
target: target,
effect: ShellCommand { script: script },
effect: effect,
evidence: host_identity_apply_evidence(),
transport: transport,
privilege_denial: none,
Expand All @@ -191,13 +177,13 @@ fn host_identity_apply_gated(
transport: HostEffectTransport,
fixture_actor: DeployAccessActor?,
) -> Reconciliation<HostEffectIntent, HostEffectEvidence>? {
match host_identity_plan_effect_script(plan: plan) {
Present { value: script } =>
match host_identity_plan_effect(plan: plan) {
Present { value: effect } =>
Present {
value: host_effect_apply_gated(
access: access,
target: target,
effect: ShellCommand { script: script },
effect: effect,
evidence: host_identity_apply_evidence(),
transport: transport,
fixture_actor: fixture_actor,
Expand Down
1 change: 1 addition & 0 deletions dag/gunbc/srv3_host_effect_script.dag
Original file line number Diff line number Diff line change
Expand Up @@ -222,5 +222,6 @@ fn srv3_host_effect_script_for(effect: HostEffect) -> String? {
ShellCommand { script: _ } => Absent
RedfishAction { action: _ } => Absent
ConvergePlan { policy: _ } => Absent
SetHostnameCas { hostnamectl_path: _, base: _, desired: _ } => Absent
}
}
2 changes: 1 addition & 1 deletion src/v2/lens/medium_structure_containment.dag
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ data medium_structure_exception_roster: List<String> = [
"dag/gunbc/ci_deploy_target_host.dag",
"dag/gunbc/host_identity_observation.dag",
"dag/gunbc/fleet_show_effective_read.dag",
"dag/gunbc/host_identity_converge.dag",
"dag/gunbc/host_effect_hostname_script.dag",
"dag/gunbc/host_identity_adopt.dag",
"dag/gunbc/host_identity_assimilation.dag",
"dag/gunbc/githooks_pre_push_emit.dag",
Expand Down
Loading