Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 14 additions & 2 deletions protocol/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -1059,10 +1059,22 @@ type ProviderUpstreamImagePolicy struct {
}

func (p ProviderUpstreamImagePolicy) Validate() error {
var errs []error
if !p.DigestPinnedImageRequired {
return errors.New("digest_pinned_image_required must be true")
errs = append(errs, errors.New("digest_pinned_image_required must be true"))
}
return nil
if !p.OperatorSuppliedImageRequired && strings.TrimSpace(p.RecommendedImageRef) == "" {
errs = append(errs, errors.New("recommended_image_ref is required unless operator_supplied_image_required is true"))
}
if p.RecommendedImageRef != "" && (strings.TrimSpace(p.RecommendedImageRef) == "" || strings.ContainsAny(p.RecommendedImageRef, "\t\r\n\x00")) {
errs = append(errs, errors.New("recommended_image_ref is invalid"))
}
for i, ref := range p.KnownImageRefs {
if strings.TrimSpace(ref) == "" || strings.ContainsAny(ref, "\t\r\n\x00") {
errs = append(errs, fmt.Errorf("known_image_refs[%d] is required", i))
}
}
return errors.Join(errs...)
}

func CanonicalHash(value any) string {
Expand Down
19 changes: 19 additions & 0 deletions protocol/types_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,25 @@ func TestProviderContractRejectsMalformedConfigSchemaDigest(t *testing.T) {
}
}

func TestProviderUpstreamImagePolicyRequiresRecommendedImageUnlessOperatorSupplied(t *testing.T) {
policy := protocol.ProviderUpstreamImagePolicy{
DigestPinnedImageRequired: true,
}

err := policy.Validate()
if err == nil {
t.Fatal("expected missing recommended image to fail")
}
if !strings.Contains(err.Error(), "recommended_image_ref") {
t.Fatalf("expected recommended_image_ref error, got %v", err)
}

policy.OperatorSuppliedImageRequired = true
if err := policy.Validate(); err != nil {
t.Fatalf("operator-supplied image should not require recommended image: %v", err)
}
}

func TestProviderRuntimeProfileRejectsReusableResidueWithoutWorkspace(t *testing.T) {
contract := validBatchProviderContract()
profile := &contract.RuntimeContract.Profiles[0]
Expand Down
Loading