chore: establish local platform baseline
This commit is contained in:
@@ -0,0 +1,105 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"data-terminal-cloud/internal/firmwareconformance"
|
||||
)
|
||||
|
||||
func recordSimulatedFirmwareEvidence(command simulatedDeviceCommand, manifest simulatedFirmwareManifest, phase string, state simulatedFirmwareBootState, resultCode string) error {
|
||||
path := strings.TrimSpace(os.Getenv("SIM_FIRMWARE_EVIDENCE_FILE"))
|
||||
if path == "" {
|
||||
return nil
|
||||
}
|
||||
now := time.Now().UTC()
|
||||
var evidence firmwareconformance.DeviceEvidence
|
||||
content, err := os.ReadFile(path)
|
||||
if errors.Is(err, os.ErrNotExist) {
|
||||
partitionDigest := strings.ToLower(env("SIM_PARTITION_TABLE_SHA256", firmwareconformance.SHA256([]byte(env("SIM_DEVICE_MODEL", "simulated-terminal")+":"+env("SIM_DEVICE_HARDWARE_REVISION", "sim-rev-a")+":A/B"))))
|
||||
secureBoot, parseErr := simulatedEvidenceBoolean("SIM_SECURE_BOOT_ENABLED", false)
|
||||
if parseErr != nil {
|
||||
return parseErr
|
||||
}
|
||||
evidence = firmwareconformance.DeviceEvidence{
|
||||
SchemaVersion: firmwareconformance.DeviceEvidenceSchema, EvidenceSource: "SIMULATOR",
|
||||
CandidateVersion: env("SIM_CANDIDATE_VERSION", "local-development"), BuildDigest: strings.ToLower(strings.TrimSpace(os.Getenv("SIM_BUILD_DIGEST"))),
|
||||
DeviceID: env("SIM_DEVICE_ID", "10000000-0000-0000-0000-000000000511"), DeviceModel: env("SIM_DEVICE_MODEL", "simulated-terminal"), HardwareRevision: env("SIM_DEVICE_HARDWARE_REVISION", "sim-rev-a"),
|
||||
ReleaseID: manifest.ReleaseID, CommandID: command.ID, Scenario: strings.ToUpper(strings.TrimSpace(os.Getenv("SIM_FIRMWARE_EVIDENCE_SCENARIO"))),
|
||||
BootloaderVersion: env("SIM_BOOTLOADER_VERSION", "sim-bootloader-1"), PartitionTableSHA256: partitionDigest, SecureBootEnabled: secureBoot,
|
||||
ArtifactSHA256: manifest.Digest, SigningKeyID: manifest.SigningKeyID,
|
||||
InitialSlot: state.PreviousSlot, TargetSlot: state.TargetSlot, FinalSlot: state.PreviousSlot,
|
||||
InitialVersion: state.PreviousVersion, TargetVersion: state.TargetVersion, FinalVersion: state.PreviousVersion,
|
||||
BootAttemptID: state.BootAttemptID, CollectedAt: now, Events: []firmwareconformance.DeviceEvent{},
|
||||
}
|
||||
if evidence.BuildDigest == "" || evidence.Scenario == "" {
|
||||
return errors.New("SIM_BUILD_DIGEST and SIM_FIRMWARE_EVIDENCE_SCENARIO are required when evidence capture is enabled")
|
||||
}
|
||||
} else if err != nil {
|
||||
return fmt.Errorf("read simulated firmware evidence: %w", err)
|
||||
} else {
|
||||
evidence, err = firmwareconformance.ParseDeviceEvidence(content)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if evidence.CommandID != command.ID || evidence.ReleaseID != manifest.ReleaseID {
|
||||
return errors.New("simulated firmware evidence belongs to a different command or release")
|
||||
}
|
||||
}
|
||||
if manifest.SigningKeyID != "" && evidence.SigningKeyID == "" {
|
||||
evidence.SigningKeyID = manifest.SigningKeyID
|
||||
}
|
||||
if state.BootAttemptID != "" {
|
||||
evidence.BootAttemptID = state.BootAttemptID
|
||||
}
|
||||
event := firmwareconformance.DeviceEvent{
|
||||
Phase: phase, OccurredAt: now, ActiveSlot: state.ActiveSlot, TargetSlot: state.TargetSlot, ResultCode: resultCode, BootAttemptID: state.BootAttemptID,
|
||||
}
|
||||
evidence.Events = append(evidence.Events, event)
|
||||
evidence.CollectedAt = now
|
||||
switch phase {
|
||||
case "confirmed":
|
||||
evidence.FinalSlot = state.ActiveSlot
|
||||
evidence.FinalVersion = manifest.Version
|
||||
case "rolled_back":
|
||||
evidence.FinalSlot = state.ActiveSlot
|
||||
evidence.FinalVersion = state.TargetVersion
|
||||
}
|
||||
encoded, err := json.MarshalIndent(evidence, "", " ")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
file, err := os.OpenFile(path, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0o600)
|
||||
if err != nil {
|
||||
return fmt.Errorf("open simulated firmware evidence: %w", err)
|
||||
}
|
||||
if _, err = file.Write(encoded); err == nil {
|
||||
err = file.Sync()
|
||||
}
|
||||
closeErr := file.Close()
|
||||
if err != nil {
|
||||
return fmt.Errorf("write simulated firmware evidence: %w", err)
|
||||
}
|
||||
if closeErr != nil {
|
||||
return fmt.Errorf("close simulated firmware evidence: %w", closeErr)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func simulatedEvidenceBoolean(key string, fallback bool) (bool, error) {
|
||||
value := strings.ToLower(strings.TrimSpace(os.Getenv(key)))
|
||||
if value == "" {
|
||||
return fallback, nil
|
||||
}
|
||||
if value == "true" {
|
||||
return true, nil
|
||||
}
|
||||
if value == "false" {
|
||||
return false, nil
|
||||
}
|
||||
return false, fmt.Errorf("%s must be true or false", key)
|
||||
}
|
||||
Reference in New Issue
Block a user