...

Source file src/github.com/sigstore/cosign/v2/pkg/oci/layout/write.go

Documentation: github.com/sigstore/cosign/v2/pkg/oci/layout

     1  //
     2  // Copyright 2021 The Sigstore Authors.
     3  //
     4  // Licensed under the Apache License, Version 2.0 (the "License");
     5  // you may not use this file except in compliance with the License.
     6  // You may obtain a copy of the License at
     7  //
     8  //     http://www.apache.org/licenses/LICENSE-2.0
     9  //
    10  // Unless required by applicable law or agreed to in writing, software
    11  // distributed under the License is distributed on an "AS IS" BASIS,
    12  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  // See the License for the specific language governing permissions and
    14  // limitations under the License.
    15  
    16  package layout
    17  
    18  import (
    19  	"fmt"
    20  
    21  	v1 "github.com/google/go-containerregistry/pkg/v1"
    22  	"github.com/google/go-containerregistry/pkg/v1/empty"
    23  	"github.com/google/go-containerregistry/pkg/v1/layout"
    24  	"github.com/sigstore/cosign/v2/pkg/oci"
    25  )
    26  
    27  // WriteSignedImage writes the image and all related signatures, attestations and attachments
    28  func WriteSignedImage(path string, si oci.SignedImage) error {
    29  	// First, write an empty index
    30  	layoutPath, err := layout.Write(path, empty.Index)
    31  	if err != nil {
    32  		return err
    33  	}
    34  	// write the image
    35  	if err := appendImage(layoutPath, si, imageAnnotation); err != nil {
    36  		return fmt.Errorf("appending signed image: %w", err)
    37  	}
    38  	return writeSignedEntity(layoutPath, si)
    39  }
    40  
    41  // WriteSignedImageIndex writes the image index and all related signatures, attestations and attachments
    42  func WriteSignedImageIndex(path string, si oci.SignedImageIndex) error {
    43  	// First, write an empty index
    44  	layoutPath, err := layout.Write(path, empty.Index)
    45  	if err != nil {
    46  		return err
    47  	}
    48  	// write the image index
    49  	if err := layoutPath.AppendIndex(si, layout.WithAnnotations(
    50  		map[string]string{kindAnnotation: imageIndexAnnotation},
    51  	)); err != nil {
    52  		return fmt.Errorf("appending signed image index: %w", err)
    53  	}
    54  	return writeSignedEntity(layoutPath, si)
    55  }
    56  
    57  func writeSignedEntity(path layout.Path, se oci.SignedEntity) error {
    58  	// write the signatures
    59  	sigs, err := se.Signatures()
    60  	if err != nil {
    61  		return fmt.Errorf("getting signatures: %w", err)
    62  	}
    63  	if !isEmpty(sigs) {
    64  		if err := appendImage(path, sigs, sigsAnnotation); err != nil {
    65  			return fmt.Errorf("appending signatures: %w", err)
    66  		}
    67  	}
    68  
    69  	// write attestations
    70  	atts, err := se.Attestations()
    71  	if err != nil {
    72  		return fmt.Errorf("getting atts")
    73  	}
    74  	if !isEmpty(atts) {
    75  		if err := appendImage(path, atts, attsAnnotation); err != nil {
    76  			return fmt.Errorf("appending atts: %w", err)
    77  		}
    78  	}
    79  	// TODO (priyawadhwa@) and attachments
    80  	return nil
    81  }
    82  
    83  // isEmpty returns true if the signatures or attestations are empty
    84  func isEmpty(s oci.Signatures) bool {
    85  	ss, _ := s.Get()
    86  	return ss == nil
    87  }
    88  
    89  func appendImage(path layout.Path, img v1.Image, annotation string) error {
    90  	return path.AppendImage(img, layout.WithAnnotations(
    91  		map[string]string{kindAnnotation: annotation},
    92  	))
    93  }
    94  

View as plain text