Skip to content
Closed
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
359 changes: 359 additions & 0 deletions dag/gunbc/bmc_converge.dag
Original file line number Diff line number Diff line change
@@ -0,0 +1,359 @@
module gunbc.bmc_converge

import extdeps.bmc.capability {
BmcFirmwareIntent,
BmcFirmwareObservation,
BmcFirmwareTrackRequired,
BmcFirmwareUnpinned,
BmcFirmwareVersion,
bmc_firmware_observation_matches_intent,
bmc_firmware_version_matches_track,
}
import extdeps.bmc.types {
BmcConfigPersistenceObservation,
BmcConfigPersistenceUnsupported,
BmcFanCurve,
BmcFanPolicyObservation,
BmcOverlayConfigObserved,
BmcUpdateServiceObservation,
}
import extdeps.boards.types { BaseboardModel }
import extdeps.crypto.hash { Digest }
import extdeps.filesystem.linux {
linux_overlay_observation_is_flash_backed,
}
import extdeps.uri { Uri }
import gunbc.bmc_intent {
BmcControlPlaneIntent,
}
import gunbc.bmc_fan_projection {
BmcFanDurabilityEvidence,
BmcFanPolicyProjectionCapability,
bmc_fan_policy_projection_durability_admission,
bmc_fan_policy_projection_durability_capability,
bmc_fan_policy_projection_supports_apply,
bmc_fan_policy_projection_topology_matches,
}
import product.placement_supply { HostIdentity }
import std.state_durability {
StatePerturbationGeneration,
state_durability_satisfied,
state_durability_verdict,
state_durability_verdict_reason,
}
import std.types { Bool, List, NonEmptyStr }
import std.upsert_decision {
Apply,
Conflict,
Converged,
Drifted,
Noop,
Refuse,
UnknownRefused,
UpsertClassification,
}

type ApprovedBmcFirmwareArtifact {
firmware: BmcFirmwareVersion
board: BaseboardModel
image_uri: Uri
digest: Digest
}

type BmcFirmwareUpdatePlan {
host: HostIdentity
observed: BmcFirmwareObservation
artifact: ApprovedBmcFirmwareArtifact
update_service: BmcUpdateServiceObservation
}

type BmcFanPolicyApplyPlan {
host: HostIdentity
observed: BmcFanPolicyObservation
desired_curve: BmcFanCurve
config_path: NonEmptyStr
controller_service: NonEmptyStr
projection: BmcFanPolicyProjectionCapability
}

data bmc_converge_shared_workflow_note: String = "BMC and Ubuntu convergence share std.upsert_decision for observe/classify/plan and std.realization_reconcile for apply/read-back. This module supplies only BMC policy comparison and a BMC-specific apply plan; it does not fork the reconciliation workflow or reuse HostOs shell effects against the BmcController control plane."

fn bmc_firmware_classification(
host: HostIdentity,
board: BaseboardModel,
intent: BmcFirmwareIntent,
observation: BmcFirmwareObservation?,
artifact: ApprovedBmcFirmwareArtifact?,
update_service: BmcUpdateServiceObservation?,
) -> UpsertClassification<BmcFirmwareUpdatePlan> {
match observation {
Absent =>
UpsertClassification {
verdict: UnknownRefused,
decision: Refuse {
reason: "bmc firmware observation absent; refuse both noop and update",
},
}
Present { value: observed } =>
if bmc_firmware_observation_matches_intent(
intent: intent,
observation: observed,
) {
UpsertClassification {
verdict: Converged,
decision: Noop,
}
} else {
match artifact {
Absent =>
UpsertClassification {
verdict: Drifted,
decision: Refuse {
reason: "bmc firmware drift observed, but no exact approved board-compatible image artifact is available",
},
}
Present { value: approved } =>
if approved.board == board
&& bmc_firmware_version_matches_intent(
firmware: approved.firmware,
intent: intent,
) {
match update_service {
Absent =>
UpsertClassification {
verdict: Drifted,
decision: Refuse {
reason: "bmc firmware drift and approved artifact are known, but the current UpdateService surface has not been observed",
},
}
Present { value: update_surface } =>
if update_surface.firmware.endpoint == observed.endpoint
&& update_surface.firmware.firmware == observed.firmware
&& update_surface.active_bmc_image_updateable {
UpsertClassification {
verdict: Drifted,
decision: Apply {
plan: BmcFirmwareUpdatePlan {
host: host,
observed: observed,
artifact: approved,
update_service: update_surface,
},
},
}
} else {
UpsertClassification {
verdict: Conflict,
decision: Refuse {
reason: "observed UpdateService does not identify an updateable active image for the exact target controller and firmware",
},
}
}
}
} else {
UpsertClassification {
verdict: Conflict,
decision: Refuse {
reason: "approved bmc firmware artifact does not match the target board and declared firmware track",
},
}
}
}
}
}
}

fn bmc_firmware_version_matches_intent(
firmware: BmcFirmwareVersion,
intent: BmcFirmwareIntent,
) -> Bool {
match intent {
BmcFirmwareUnpinned => false
BmcFirmwareTrackRequired { track: required } =>
bmc_firmware_version_matches_track(
firmware: firmware,
track: required,
)
}
}

fn bmc_fan_policy_firmware_supported(
desired_firmware: BmcFirmwareIntent,
observed_firmware: BmcFirmwareVersion,
) -> Bool {
match desired_firmware {
BmcFirmwareUnpinned => false
BmcFirmwareTrackRequired { track: required } =>
bmc_firmware_version_matches_track(
firmware: observed_firmware,
track: required,
)
}
}

fn bmc_config_persistence_supports_apply(
observation: BmcConfigPersistenceObservation,
expected_firmware: BmcFirmwareVersion,
config_path: NonEmptyStr,
) -> Bool {
match observation {
BmcOverlayConfigObserved {
firmware: firmware,
config_path: observed_path,
overlay: overlay,
writable: writable,
upper_override_present: _,
available_bytes: _,
observed_at: _,
} =>
firmware == expected_firmware
&& writable
&& observed_path == config_path
&& linux_overlay_observation_is_flash_backed(
observation: overlay,
)
BmcConfigPersistenceUnsupported {
firmware: _,
config_path: _,
reason: _,
observed_at: _,
} => false
}
}

fn bmc_fan_policy_classification(
host: HostIdentity,
board: BaseboardModel,
intent: BmcControlPlaneIntent,
observation: BmcFanPolicyObservation?,
persistence: BmcConfigPersistenceObservation?,
projection: BmcFanPolicyProjectionCapability?,
durability_generation: StatePerturbationGeneration,
durability_evidence: List<BmcFanDurabilityEvidence>,
) -> UpsertClassification<BmcFanPolicyApplyPlan> {
let desired = intent.fan_policy.curve
match observation {
Absent =>
UpsertClassification {
verdict: UnknownRefused,
decision: Refuse {
reason: "bmc fan-policy observation absent; Redfish InitialDuty is not curve evidence",
},
}
Present { value: observed } =>
if !bmc_fan_policy_firmware_supported(
desired_firmware: intent.firmware,
observed_firmware: observed.firmware,
) {
UpsertClassification {
verdict: Conflict,
decision: Refuse {
reason: "bmc firmware must converge and be re-observed before selecting a version-specific fan-policy realizer",
},
}
} else {
match projection {
Absent =>
UpsertClassification {
verdict: UnknownRefused,
decision: Refuse {
reason: "bmc fan state cannot converge without an exact board-and-firmware projection for both curve and installed-tach topology",
},
}
Present { value: projector } =>
if projector.required_tach_inputs != intent.fan_policy.required_tach_inputs {
UpsertClassification {
verdict: Conflict,
decision: Refuse {
reason: "bmc fan projection installed-tach topology differs from fleet intent",
},
}
} else if !bmc_fan_policy_projection_supports_apply(
capability: projector,
board: board,
desired_curve: desired,
observation: observed,
) {
UpsertClassification {
verdict: Conflict,
decision: Refuse {
reason: "bmc fan projection capability does not match the observed board, exact firmware, config path, and controller service",
},
}
} else {
match persistence {
Absent =>
UpsertClassification {
verdict: UnknownRefused,
decision: Refuse {
reason: "bmc fan realizer lifetime cannot be evaluated because its current filesystem substrate has not been observed",
},
}
Present { value: storage } =>
if !bmc_config_persistence_supports_apply(
observation: storage,
expected_firmware: observed.firmware,
config_path: observed.board_config_path,
) {
UpsertClassification {
verdict: Conflict,
decision: Refuse {
reason: "bmc fan realizer is not grounded by the observed overlay, SquashFS lower, writable JFFS2 upper, exact firmware, and config path",
},
}
} else {
let durability = state_durability_verdict(
intent: intent.fan_policy.durability,
admission: bmc_fan_policy_projection_durability_admission(
host: host,
capability: projector,
perturbation_generation: durability_generation,
),
capability: Present {
value: bmc_fan_policy_projection_durability_capability(
capability: projector,
),
},
evidence: durability_evidence,
)
if !state_durability_satisfied(verdict: durability) {
UpsertClassification {
verdict: UnknownRefused,
decision: Refuse {
reason: concat(
"bmc fan realizer does not satisfy the declared state lifetime: ",
state_durability_verdict_reason(verdict: durability),
),
},
}
} else if observed.curve == desired
&& bmc_fan_policy_projection_topology_matches(
capability: projector,
observation: observed,
) {
UpsertClassification {
verdict: Converged,
decision: Noop,
}
} else {
UpsertClassification {
verdict: Drifted,
decision: Apply {
plan: BmcFanPolicyApplyPlan {
host: host,
observed: observed,
desired_curve: desired,
config_path: observed.board_config_path,
controller_service: observed.controller_service,
projection: projector,
},
},
}
}
}
}
}
}
}
}
}
Loading