2016-07-14 09:37:11 +08:00
package directory
import (
2018-02-23 17:45:56 +08:00
"context"
2022-07-01 04:04:10 +08:00
"errors"
2016-07-19 01:16:06 +08:00
"fmt"
2016-07-09 11:24:41 +08:00
"path/filepath"
2016-07-12 23:10:03 +08:00
"strings"
2019-10-26 04:27:45 +08:00
"github.com/containers/image/v5/directory/explicitfilepath"
"github.com/containers/image/v5/docker/reference"
2022-06-11 03:49:31 +08:00
"github.com/containers/image/v5/internal/image"
2019-10-26 04:27:45 +08:00
"github.com/containers/image/v5/transports"
"github.com/containers/image/v5/types"
2017-01-09 18:10:30 +08:00
"github.com/opencontainers/go-digest"
2016-07-14 09:37:11 +08:00
)
2017-01-18 21:46:30 +08:00
func init ( ) {
transports . Register ( Transport )
}
2016-07-14 09:37:11 +08:00
// Transport is an ImageTransport for directory paths.
var Transport = dirTransport { }
type dirTransport struct { }
func ( t dirTransport ) Name ( ) string {
return "dir"
}
// ParseReference converts a string, which should not start with the ImageTransport.Name prefix, into an ImageReference.
func ( t dirTransport ) ParseReference ( reference string ) ( types . ImageReference , error ) {
2016-07-12 23:10:03 +08:00
return NewReference ( reference )
2016-07-14 09:37:11 +08:00
}
2016-07-19 01:16:06 +08:00
// ValidatePolicyConfigurationScope checks that scope is a valid name for a signature.PolicyTransportScopes keys
// (i.e. a valid PolicyConfigurationIdentity() or PolicyConfigurationNamespaces() return value).
// It is acceptable to allow an invalid value which will never be matched, it can "only" cause user confusion.
// scope passed to this function will not be "", that value is always allowed.
func ( t dirTransport ) ValidatePolicyConfigurationScope ( scope string ) error {
if ! strings . HasPrefix ( scope , "/" ) {
2022-07-01 03:05:20 +08:00
return fmt . Errorf ( "Invalid scope %s: Must be an absolute path" , scope )
2016-07-19 01:16:06 +08:00
}
// Refuse also "/", otherwise "/" and "" would have the same semantics,
// and "" could be unexpectedly shadowed by the "/" entry.
if scope == "/" {
return errors . New ( ` Invalid scope "/": Use the generic default scope "" ` )
}
2016-08-02 23:03:24 +08:00
cleaned := filepath . Clean ( scope )
if cleaned != scope {
2022-07-01 03:05:20 +08:00
return fmt . Errorf ( ` Invalid scope %s: Uses non-canonical format, perhaps try %s ` , scope , cleaned )
2016-08-02 23:03:24 +08:00
}
2016-07-19 01:16:06 +08:00
return nil
}
2016-07-14 09:37:11 +08:00
// dirReference is an ImageReference for directory paths.
type dirReference struct {
// Note that the interpretation of paths below depends on the underlying filesystem state, which may change under us at any time!
2016-07-12 23:10:03 +08:00
// Either of the paths may point to a different, or no, inode over time. resolvedPath may contain symbolic links, and so on.
// Generally we follow the intent of the user, and use the "path" member for filesystem operations (e.g. the user can use a relative path to avoid
// being exposed to symlinks and renames in the parent directories to the working directory).
// (But in general, we make no attempt to be completely safe against concurrent hostile filesystem modifications.)
path string // As specified by the user. May be relative, contain symlinks, etc.
resolvedPath string // Absolute path with no symlinks, at least at the time of its creation. Primarily used for policy namespaces.
2016-07-14 09:37:11 +08:00
}
// There is no directory.ParseReference because it is rather pointless.
// Callers who need a transport-independent interface will go through
// dirTransport.ParseReference; callers who intentionally deal with directories
// can use directory.NewReference.
// NewReference returns a directory reference for a specified path.
2016-07-12 23:10:03 +08:00
//
// We do not expose an API supplying the resolvedPath; we could, but recomputing it
// is generally cheap enough that we prefer being confident about the properties of resolvedPath.
func NewReference ( path string ) ( types . ImageReference , error ) {
resolved , err := explicitfilepath . ResolvePathToFullyExplicit ( path )
if err != nil {
return nil , err
}
return dirReference { path : path , resolvedPath : resolved } , nil
2016-07-14 09:37:11 +08:00
}
func ( ref dirReference ) Transport ( ) types . ImageTransport {
return Transport
}
// StringWithinTransport returns a string representation of the reference, which MUST be such that
// reference.Transport().ParseReference(reference.StringWithinTransport()) returns an equivalent reference.
// NOTE: The returned string is not promised to be equal to the original input to ParseReference;
2023-02-03 03:17:01 +08:00
// e.g. default attribute values omitted by the user may be filled in the return value, or vice versa.
2016-07-14 09:37:11 +08:00
// WARNING: Do not use the return value in the UI to describe an image, it does not contain the Transport().Name() prefix.
func ( ref dirReference ) StringWithinTransport ( ) string {
return ref . path
}
2016-07-14 09:38:27 +08:00
// DockerReference returns a Docker reference associated with this reference
// (fully explicit, i.e. !reference.IsNameOnly, but reflecting user intent,
// not e.g. after redirect or alias processing), or nil if unknown/not applicable.
func ( ref dirReference ) DockerReference ( ) reference . Named {
return nil
}
2016-07-15 01:55:37 +08:00
// PolicyConfigurationIdentity returns a string representation of the reference, suitable for policy lookup.
// This MUST reflect user intent, not e.g. after processing of third-party redirects or aliases;
// The value SHOULD be fully explicit about its semantics, with no hidden defaults, AND canonical
// (i.e. various references with exactly the same semantics should return the same configuration identity)
// It is fine for the return value to be equal to StringWithinTransport(), and it is desirable but
// not required/guaranteed that it will be a valid input to Transport().ParseReference().
// Returns "" if configuration identities for these references are not supported.
func ( ref dirReference ) PolicyConfigurationIdentity ( ) string {
2016-07-12 23:10:03 +08:00
return ref . resolvedPath
2016-07-15 01:55:37 +08:00
}
// PolicyConfigurationNamespaces returns a list of other policy configuration namespaces to search
// for if explicit configuration for PolicyConfigurationIdentity() is not set. The list will be processed
// in order, terminating on first match, and an implicit "" is always checked at the end.
// It is STRONGLY recommended for the first element, if any, to be a prefix of PolicyConfigurationIdentity(),
// and each following element to be a prefix of the element preceding it.
func ( ref dirReference ) PolicyConfigurationNamespaces ( ) [ ] string {
2016-07-12 23:10:03 +08:00
res := [ ] string { }
path := ref . resolvedPath
for {
lastSlash := strings . LastIndex ( path , "/" )
if lastSlash == - 1 || lastSlash == 0 {
break
}
path = path [ : lastSlash ]
res = append ( res , path )
}
2016-07-19 01:16:06 +08:00
// Note that we do not include "/"; it is redundant with the default "" global default,
// and rejected by dirTransport.ValidatePolicyConfigurationScope above.
2016-07-12 23:10:03 +08:00
return res
2016-07-15 01:55:37 +08:00
}
Do not Close the ImageSource in UnparsedImage/Image
Remove the .Close() methods from UnparsedImage/Image, which closed the
underlying ImageSource. Instead, just require the caller to ensure
that the ImageSource is not closed as long as the UnparsedImage/Image
are used.
This allows using several independent UnparsedImage/Image instances
for a shared ImageSource; notably independent Image objects for the
individual image instances in a manifest list. (copy.Image is already
simpler although it is only using a single instance.)
To keep ImageReference.NewImage simple and not to break all the external
callers of this, also add a simple ImageCloser wrapper which retains
the ImageSource closing functionality, and return it from image.FromSource
and ImageReference.NewImage implementations.
(It's very likely many of the NewImage callers would be surprised by how this
handles manifest lists, and it is very tempting to break this API, at least
by renaming, to force the callers to consider this; however, this would be
better done after eliminating the need of ImageReference.NewImage entirely,
by replacing the specialized types.Image extensions with something else, first.)
Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2017-09-16 08:11:14 +08:00
// NewImage returns a types.ImageCloser for this reference, possibly specialized for this ImageTransport.
// The caller must call .Close() on the returned ImageCloser.
2016-10-07 04:06:03 +08:00
// NOTE: If any kind of signature verification should happen, build an UnparsedImage from the value returned by NewImageSource,
// verify that UnparsedImage, and convert it into a real Image via image.FromUnparsedImage.
Do not Close the ImageSource in UnparsedImage/Image
Remove the .Close() methods from UnparsedImage/Image, which closed the
underlying ImageSource. Instead, just require the caller to ensure
that the ImageSource is not closed as long as the UnparsedImage/Image
are used.
This allows using several independent UnparsedImage/Image instances
for a shared ImageSource; notably independent Image objects for the
individual image instances in a manifest list. (copy.Image is already
simpler although it is only using a single instance.)
To keep ImageReference.NewImage simple and not to break all the external
callers of this, also add a simple ImageCloser wrapper which retains
the ImageSource closing functionality, and return it from image.FromSource
and ImageReference.NewImage implementations.
(It's very likely many of the NewImage callers would be surprised by how this
handles manifest lists, and it is very tempting to break this API, at least
by renaming, to force the callers to consider this; however, this would be
better done after eliminating the need of ImageReference.NewImage entirely,
by replacing the specialized types.Image extensions with something else, first.)
Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2017-09-16 08:11:14 +08:00
// WARNING: This may not do the right thing for a manifest list, see image.FromSource for details.
2018-02-23 17:45:56 +08:00
func ( ref dirReference ) NewImage ( ctx context . Context , sys * types . SystemContext ) ( types . ImageCloser , error ) {
2022-06-11 04:10:33 +08:00
return image . FromReference ( ctx , sys , ref )
2016-07-14 09:37:11 +08:00
}
2017-08-31 19:42:35 +08:00
// NewImageSource returns a types.ImageSource for this reference.
2016-08-27 05:24:39 +08:00
// The caller must call .Close() on the returned ImageSource.
2018-02-23 17:45:56 +08:00
func ( ref dirReference ) NewImageSource ( ctx context . Context , sys * types . SystemContext ) ( types . ImageSource , error ) {
2016-07-14 09:37:11 +08:00
return newImageSource ( ref ) , nil
}
// NewImageDestination returns a types.ImageDestination for this reference.
2016-09-06 04:10:47 +08:00
// The caller must call .Close() on the returned ImageDestination.
2018-02-23 17:45:56 +08:00
func ( ref dirReference ) NewImageDestination ( ctx context . Context , sys * types . SystemContext ) ( types . ImageDestination , error ) {
2021-07-27 19:57:31 +08:00
return newImageDestination ( sys , ref )
2016-07-14 09:37:11 +08:00
}
2016-07-09 11:24:41 +08:00
2016-08-25 06:07:47 +08:00
// DeleteImage deletes the named image from the registry, if supported.
2018-02-23 17:45:56 +08:00
func ( ref dirReference ) DeleteImage ( ctx context . Context , sys * types . SystemContext ) error {
2022-07-01 03:05:20 +08:00
return errors . New ( "Deleting images not implemented for dir: images" )
2016-08-25 06:07:47 +08:00
}
2016-07-09 11:24:41 +08:00
// manifestPath returns a path for the manifest within a directory using our conventions.
2024-04-18 04:26:46 +08:00
func ( ref dirReference ) manifestPath ( instanceDigest * digest . Digest ) ( string , error ) {
Add manifest list support
Add the manifest.List interface, and implementations for OCIv1 Index and
Docker Schema2List documents.
Add an instanceDigest parameter to PutManifest(), PutSignatures(), and
LayerInfosForCopy, for symmetry with GetManifest() and GetSignatures().
Return an error if the instanceDigest is supplied to destinations which
don't support them, and add stubs that do so even to the transports
which would support it, so that we don't break compilation here.
Add a MultipleImages flag to copy.Options, and if the source for a copy
operation contains multiple images, copy all of the images if we can.
If we can't copy them all, but we were told to, return an error.
Use the generic manifest list API to select a single image to copy from
a list, so that we aren't just limited to the Docker manifest list
format for those cases.
When guessing at the type of a manifest, if the manifest contains a list
of manifests, use its declared MIME type if it included one, else assume
it's an OCI index, because an OCI index doesn't include its MIME type.
When copying, switch from using an encode-then-compare of the original
and updated versions of the list to checking if the instance list was
changed (one of the things we might have changed) or if its type has
changed due to conversion (the other change we might have made). If
neither has changed, then we don't need to change the encoded value of
the manifest.
When copying, when checking for a digest mismatch in a target image
reference, ignore a mismatch between the digest in the reference and the
digest of the main manifest if we're copying one element from a list,
and the digest in the reference matches the digest of the manifest list.
When copying, if conversion of manifests for single images is being
forced, convert manifest lists to the corresponding list types.
When copying, supply the unparsed top level to Commit() by attaching the
value to the context.Context.
Support manifest lists in the directory transport by using the instance
digest as a prefix of the filename used to store a manifest or a piece
of signature data.
Support manifest lists in the oci-layout transport by accepting indexes
as we do images, and stop guessing about Platform values to add to the
top-level index.
Support storing manifest lists to registries in the docker: transport by
using the manifest digest when we're writing one image as part of
pushing a list of them, and by using the instance digest when reading or
writing signature data, when one is specified, or the cached digest of
the non-instanced digest when one is not specified.
Add partial support for manifest lists to the storage transport: when
committing one image from a list into storage, also add a copy of the
manifest list by extracting it from the context.Context. The logic is
already in place to enable locating an image using any of multiple
manifest digests.
When writing an image that has an instanceDigest value (meaning it's a
secondary image), don't try to generate a canonical reference to add to
the image's list of names if the reference for the primary image doesn't
contain a name. That should only happen if we're writing using just an
image ID, which is unlikely, but we still need to handle it.
Avoid computing the digest of the manifest, or retrieving the
either-a-tag-or-a-digest value from the target reference, if we're given
an instanceDigest, which would override them anyway.
Move the check for non-nil instanceDigest values up into the main
PutSignatures() method instead of duplicating it in the per-strategy
helpers.
Add mention of the instanceDigest parameter and its use to various
PutManifest, PutSignatures, and LayerInfosForCopy implementations and
their declarations in interfaces.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
2018-01-09 14:03:18 +08:00
if instanceDigest != nil {
2024-04-18 04:26:46 +08:00
if err := instanceDigest . Validate ( ) ; err != nil { // digest.Digest.Encoded() panics on failure, and could possibly result in a path with ../, so validate explicitly.
return "" , err
}
return filepath . Join ( ref . path , instanceDigest . Encoded ( ) + ".manifest.json" ) , nil
Add manifest list support
Add the manifest.List interface, and implementations for OCIv1 Index and
Docker Schema2List documents.
Add an instanceDigest parameter to PutManifest(), PutSignatures(), and
LayerInfosForCopy, for symmetry with GetManifest() and GetSignatures().
Return an error if the instanceDigest is supplied to destinations which
don't support them, and add stubs that do so even to the transports
which would support it, so that we don't break compilation here.
Add a MultipleImages flag to copy.Options, and if the source for a copy
operation contains multiple images, copy all of the images if we can.
If we can't copy them all, but we were told to, return an error.
Use the generic manifest list API to select a single image to copy from
a list, so that we aren't just limited to the Docker manifest list
format for those cases.
When guessing at the type of a manifest, if the manifest contains a list
of manifests, use its declared MIME type if it included one, else assume
it's an OCI index, because an OCI index doesn't include its MIME type.
When copying, switch from using an encode-then-compare of the original
and updated versions of the list to checking if the instance list was
changed (one of the things we might have changed) or if its type has
changed due to conversion (the other change we might have made). If
neither has changed, then we don't need to change the encoded value of
the manifest.
When copying, when checking for a digest mismatch in a target image
reference, ignore a mismatch between the digest in the reference and the
digest of the main manifest if we're copying one element from a list,
and the digest in the reference matches the digest of the manifest list.
When copying, if conversion of manifests for single images is being
forced, convert manifest lists to the corresponding list types.
When copying, supply the unparsed top level to Commit() by attaching the
value to the context.Context.
Support manifest lists in the directory transport by using the instance
digest as a prefix of the filename used to store a manifest or a piece
of signature data.
Support manifest lists in the oci-layout transport by accepting indexes
as we do images, and stop guessing about Platform values to add to the
top-level index.
Support storing manifest lists to registries in the docker: transport by
using the manifest digest when we're writing one image as part of
pushing a list of them, and by using the instance digest when reading or
writing signature data, when one is specified, or the cached digest of
the non-instanced digest when one is not specified.
Add partial support for manifest lists to the storage transport: when
committing one image from a list into storage, also add a copy of the
manifest list by extracting it from the context.Context. The logic is
already in place to enable locating an image using any of multiple
manifest digests.
When writing an image that has an instanceDigest value (meaning it's a
secondary image), don't try to generate a canonical reference to add to
the image's list of names if the reference for the primary image doesn't
contain a name. That should only happen if we're writing using just an
image ID, which is unlikely, but we still need to handle it.
Avoid computing the digest of the manifest, or retrieving the
either-a-tag-or-a-digest value from the target reference, if we're given
an instanceDigest, which would override them anyway.
Move the check for non-nil instanceDigest values up into the main
PutSignatures() method instead of duplicating it in the per-strategy
helpers.
Add mention of the instanceDigest parameter and its use to various
PutManifest, PutSignatures, and LayerInfosForCopy implementations and
their declarations in interfaces.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
2018-01-09 14:03:18 +08:00
}
2024-04-18 04:26:46 +08:00
return filepath . Join ( ref . path , "manifest.json" ) , nil
2016-07-09 11:24:41 +08:00
}
// layerPath returns a path for a layer tarball within a directory using our conventions.
2024-04-18 04:26:46 +08:00
func ( ref dirReference ) layerPath ( digest digest . Digest ) ( string , error ) {
if err := digest . Validate ( ) ; err != nil { // digest.Digest.Encoded() panics on failure, and could possibly result in a path with ../, so validate explicitly.
return "" , err
}
2016-07-09 11:24:41 +08:00
// FIXME: Should we keep the digest identification?
2024-04-18 04:26:46 +08:00
return filepath . Join ( ref . path , digest . Encoded ( ) ) , nil
2016-07-09 11:24:41 +08:00
}
// signaturePath returns a path for a signature within a directory using our conventions.
2024-04-18 04:26:46 +08:00
func ( ref dirReference ) signaturePath ( index int , instanceDigest * digest . Digest ) ( string , error ) {
Add manifest list support
Add the manifest.List interface, and implementations for OCIv1 Index and
Docker Schema2List documents.
Add an instanceDigest parameter to PutManifest(), PutSignatures(), and
LayerInfosForCopy, for symmetry with GetManifest() and GetSignatures().
Return an error if the instanceDigest is supplied to destinations which
don't support them, and add stubs that do so even to the transports
which would support it, so that we don't break compilation here.
Add a MultipleImages flag to copy.Options, and if the source for a copy
operation contains multiple images, copy all of the images if we can.
If we can't copy them all, but we were told to, return an error.
Use the generic manifest list API to select a single image to copy from
a list, so that we aren't just limited to the Docker manifest list
format for those cases.
When guessing at the type of a manifest, if the manifest contains a list
of manifests, use its declared MIME type if it included one, else assume
it's an OCI index, because an OCI index doesn't include its MIME type.
When copying, switch from using an encode-then-compare of the original
and updated versions of the list to checking if the instance list was
changed (one of the things we might have changed) or if its type has
changed due to conversion (the other change we might have made). If
neither has changed, then we don't need to change the encoded value of
the manifest.
When copying, when checking for a digest mismatch in a target image
reference, ignore a mismatch between the digest in the reference and the
digest of the main manifest if we're copying one element from a list,
and the digest in the reference matches the digest of the manifest list.
When copying, if conversion of manifests for single images is being
forced, convert manifest lists to the corresponding list types.
When copying, supply the unparsed top level to Commit() by attaching the
value to the context.Context.
Support manifest lists in the directory transport by using the instance
digest as a prefix of the filename used to store a manifest or a piece
of signature data.
Support manifest lists in the oci-layout transport by accepting indexes
as we do images, and stop guessing about Platform values to add to the
top-level index.
Support storing manifest lists to registries in the docker: transport by
using the manifest digest when we're writing one image as part of
pushing a list of them, and by using the instance digest when reading or
writing signature data, when one is specified, or the cached digest of
the non-instanced digest when one is not specified.
Add partial support for manifest lists to the storage transport: when
committing one image from a list into storage, also add a copy of the
manifest list by extracting it from the context.Context. The logic is
already in place to enable locating an image using any of multiple
manifest digests.
When writing an image that has an instanceDigest value (meaning it's a
secondary image), don't try to generate a canonical reference to add to
the image's list of names if the reference for the primary image doesn't
contain a name. That should only happen if we're writing using just an
image ID, which is unlikely, but we still need to handle it.
Avoid computing the digest of the manifest, or retrieving the
either-a-tag-or-a-digest value from the target reference, if we're given
an instanceDigest, which would override them anyway.
Move the check for non-nil instanceDigest values up into the main
PutSignatures() method instead of duplicating it in the per-strategy
helpers.
Add mention of the instanceDigest parameter and its use to various
PutManifest, PutSignatures, and LayerInfosForCopy implementations and
their declarations in interfaces.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
2018-01-09 14:03:18 +08:00
if instanceDigest != nil {
2024-04-18 04:26:46 +08:00
if err := instanceDigest . Validate ( ) ; err != nil { // digest.Digest.Encoded() panics on failure, and could possibly result in a path with ../, so validate explicitly.
return "" , err
}
return filepath . Join ( ref . path , fmt . Sprintf ( instanceDigest . Encoded ( ) + ".signature-%d" , index + 1 ) ) , nil
Add manifest list support
Add the manifest.List interface, and implementations for OCIv1 Index and
Docker Schema2List documents.
Add an instanceDigest parameter to PutManifest(), PutSignatures(), and
LayerInfosForCopy, for symmetry with GetManifest() and GetSignatures().
Return an error if the instanceDigest is supplied to destinations which
don't support them, and add stubs that do so even to the transports
which would support it, so that we don't break compilation here.
Add a MultipleImages flag to copy.Options, and if the source for a copy
operation contains multiple images, copy all of the images if we can.
If we can't copy them all, but we were told to, return an error.
Use the generic manifest list API to select a single image to copy from
a list, so that we aren't just limited to the Docker manifest list
format for those cases.
When guessing at the type of a manifest, if the manifest contains a list
of manifests, use its declared MIME type if it included one, else assume
it's an OCI index, because an OCI index doesn't include its MIME type.
When copying, switch from using an encode-then-compare of the original
and updated versions of the list to checking if the instance list was
changed (one of the things we might have changed) or if its type has
changed due to conversion (the other change we might have made). If
neither has changed, then we don't need to change the encoded value of
the manifest.
When copying, when checking for a digest mismatch in a target image
reference, ignore a mismatch between the digest in the reference and the
digest of the main manifest if we're copying one element from a list,
and the digest in the reference matches the digest of the manifest list.
When copying, if conversion of manifests for single images is being
forced, convert manifest lists to the corresponding list types.
When copying, supply the unparsed top level to Commit() by attaching the
value to the context.Context.
Support manifest lists in the directory transport by using the instance
digest as a prefix of the filename used to store a manifest or a piece
of signature data.
Support manifest lists in the oci-layout transport by accepting indexes
as we do images, and stop guessing about Platform values to add to the
top-level index.
Support storing manifest lists to registries in the docker: transport by
using the manifest digest when we're writing one image as part of
pushing a list of them, and by using the instance digest when reading or
writing signature data, when one is specified, or the cached digest of
the non-instanced digest when one is not specified.
Add partial support for manifest lists to the storage transport: when
committing one image from a list into storage, also add a copy of the
manifest list by extracting it from the context.Context. The logic is
already in place to enable locating an image using any of multiple
manifest digests.
When writing an image that has an instanceDigest value (meaning it's a
secondary image), don't try to generate a canonical reference to add to
the image's list of names if the reference for the primary image doesn't
contain a name. That should only happen if we're writing using just an
image ID, which is unlikely, but we still need to handle it.
Avoid computing the digest of the manifest, or retrieving the
either-a-tag-or-a-digest value from the target reference, if we're given
an instanceDigest, which would override them anyway.
Move the check for non-nil instanceDigest values up into the main
PutSignatures() method instead of duplicating it in the per-strategy
helpers.
Add mention of the instanceDigest parameter and its use to various
PutManifest, PutSignatures, and LayerInfosForCopy implementations and
their declarations in interfaces.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
2018-01-09 14:03:18 +08:00
}
2024-04-18 04:26:46 +08:00
return filepath . Join ( ref . path , fmt . Sprintf ( "signature-%d" , index + 1 ) ) , nil
2016-07-09 11:24:41 +08:00
}
2017-11-07 04:58:55 +08:00
// versionPath returns a path for the version file within a directory using our conventions.
func ( ref dirReference ) versionPath ( ) string {
return filepath . Join ( ref . path , "version" )
}