Writes and verify image
This commit is contained in:
104
clitools/pkg/controller/osimage/verify.go
Normal file
104
clitools/pkg/controller/osimage/verify.go
Normal file
@@ -0,0 +1,104 @@
|
||||
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))
|
||||
}
|
||||
Reference in New Issue
Block a user