Files
monok8s/clitools/pkg/controller/osimage/verify.go
2026-04-04 02:45:46 +08:00

105 lines
2.1 KiB
Go

package osimage
import (
"context"
"crypto/sha256"
"encoding/hex"
"fmt"
"io"
"os"
"strings"
)
func VerifyTargetSHA256(ctx context.Context, targetPath string, expectedSize int64,
bufferSize int, progress ProgressFunc) (string, error) {
if targetPath == "" {
return "", fmt.Errorf("target path is required")
}
if expectedSize <= 0 {
return "", fmt.Errorf("expected raw size is required for verification")
}
if bufferSize <= 0 {
bufferSize = 4 * 1024 * 1024
}
f, err := os.Open(targetPath)
if err != nil {
return "", fmt.Errorf("open target for verify: %w", err)
}
defer f.Close()
h := sha256.New()
buf := make([]byte, bufferSize)
var readTotal int64
limited := io.LimitReader(f, expectedSize)
for {
select {
case <-ctx.Done():
return "", ctx.Err()
default:
}
n, err := limited.Read(buf)
if n > 0 {
if _, werr := h.Write(buf[:n]); werr != nil {
return "", fmt.Errorf("hash target: %w", werr)
}
readTotal += int64(n)
if progress != nil {
progress(Progress{
Stage: "verify",
BytesComplete: readTotal,
BytesTotal: expectedSize,
})
}
}
if err == io.EOF {
break
}
if err != nil {
return "", fmt.Errorf("read target: %w", err)
}
}
if readTotal != expectedSize {
return "", fmt.Errorf("verify size mismatch: got %d want %d", readTotal, expectedSize)
}
return hex.EncodeToString(h.Sum(nil)), nil
}
func ValidateApplyOptions(opts ApplyOptions) error {
if opts.URL == "" {
return fmt.Errorf("url is required")
}
if opts.TargetPath == "" {
return fmt.Errorf("target path is required")
}
if opts.ExpectedRawSHA256 == "" {
return fmt.Errorf("expected raw sha256 is required")
}
if opts.ExpectedRawSize <= 0 {
return fmt.Errorf("expected raw size must be > 0")
}
return nil
}
func VerifySHA256(got, expected string) error {
expected = NormalizeSHA256(expected)
if expected == "" {
return nil
}
got = NormalizeSHA256(got)
if got != expected {
return fmt.Errorf("sha256 mismatch: got %s want %s", got, expected)
}
return nil
}
func NormalizeSHA256(s string) string {
return strings.ToLower(strings.TrimSpace(s))
}