Stichprobenbasierter Scrub-Job: nimmt BAK-05s existing_in_storage, priorisiert nach eigenem scrub_state.last_scrubbed_at (nicht file_revisions.created_at, sonst kein echtes Rotationsverhalten), prueft Inhalt per SHA-256 gegen file_revisions.checksum_sha256. Meldung ueber echten dauerhaften /metrics-Endpunkt (Pull-Modell, OPS-03 scrapt, kein Push), Counter monoton steigend. Real registriert in Core metrics_sources, End-zu-Ende ueber OPS-03-Aggregator bestaetigt, realer Befund-Durchlauf mit absichtlich falscher Pruefsumme durchgefuehrt.
58 lines
1.7 KiB
Go
58 lines
1.7 KiB
Go
package scrub
|
|
|
|
import (
|
|
"context"
|
|
"crypto/sha256"
|
|
"encoding/hex"
|
|
"fmt"
|
|
"io"
|
|
"os"
|
|
"path/filepath"
|
|
|
|
"github.com/jackc/pgx/v5/pgxpool"
|
|
)
|
|
|
|
// ExpectedChecksums liest file_revisions.checksum_sha256 fuer genau die
|
|
// uebergebenen storage_keys — bewusst eine eigene, minimale Abfrage statt
|
|
// Erweiterung von reconcile.DBEntry (BAK-05 bleibt existenz-only, keine
|
|
// Kopplung an Inhaltspruefungs-Bedarf von BAK-08).
|
|
func ExpectedChecksums(ctx context.Context, pool *pgxpool.Pool, storageKeys []string) (map[string]string, error) {
|
|
if len(storageKeys) == 0 {
|
|
return map[string]string{}, nil
|
|
}
|
|
rows, err := pool.Query(ctx, `
|
|
SELECT storage_key, checksum_sha256 FROM file_revisions WHERE storage_key = ANY($1)
|
|
`, storageKeys)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("scrub: erwartete pruefsummen lesen: %w", err)
|
|
}
|
|
defer rows.Close()
|
|
|
|
out := make(map[string]string, len(storageKeys))
|
|
for rows.Next() {
|
|
var key, checksum string
|
|
if err := rows.Scan(&key, &checksum); err != nil {
|
|
return nil, fmt.Errorf("scrub: pruefsummen-zeile lesen: %w", err)
|
|
}
|
|
out[key] = checksum
|
|
}
|
|
return out, rows.Err()
|
|
}
|
|
|
|
// ActualChecksum liest die Datei unter baseDir/storageKey vollstaendig
|
|
// und berechnet ihren SHA-256 — echte Inhaltspruefung, kein
|
|
// Header-/Groessenvergleich (dieselbe Disziplin wie BAK-01s Verify).
|
|
func ActualChecksum(baseDir, storageKey string) (string, error) {
|
|
f, err := os.Open(filepath.Join(baseDir, filepath.FromSlash(storageKey)))
|
|
if err != nil {
|
|
return "", fmt.Errorf("scrub: objekt lesen: %w", err)
|
|
}
|
|
defer func() { _ = f.Close() }()
|
|
|
|
h := sha256.New()
|
|
if _, err := io.Copy(h, f); err != nil {
|
|
return "", fmt.Errorf("scrub: objekt hashen: %w", err)
|
|
}
|
|
return hex.EncodeToString(h.Sum(nil)), nil
|
|
}
|