penguin/monok8s

k8s image for Mono Gateway Dev Kit

clitools/pkg/controller/osimage/verify.go

raw ยท 2158 bytes

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))
}