1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168
|
package buildah
import (
"context"
"fmt"
"io"
"time"
"github.com/containers/buildah/pkg/blobcache"
"github.com/containers/common/libimage"
"github.com/containers/image/v5/docker/reference"
"github.com/containers/image/v5/manifest"
"github.com/containers/image/v5/pkg/compression"
"github.com/containers/image/v5/transports"
"github.com/containers/image/v5/types"
encconfig "github.com/containers/ocicrypt/config"
"github.com/containers/storage"
"github.com/containers/storage/pkg/archive"
digest "github.com/opencontainers/go-digest"
"github.com/sirupsen/logrus"
)
func cacheLookupReferenceFunc(directory string, compress types.LayerCompression) libimage.LookupReferenceFunc {
return func(ref types.ImageReference) (types.ImageReference, error) {
if directory == "" {
return ref, nil
}
ref, err := blobcache.NewBlobCache(ref, directory, compress)
if err != nil {
return nil, fmt.Errorf("using blobcache %q: %w", directory, err)
}
return ref, nil
}
}
type PushOptions struct {
Compression archive.Compression
SignaturePolicyPath string
ReportWriter io.Writer
Store storage.Store
SystemContext *types.SystemContext
ManifestType string
BlobDirectory string
Quiet bool
SignBy string
RemoveSignatures bool
MaxRetries int
RetryDelay time.Duration
OciEncryptConfig *encconfig.EncryptConfig
OciEncryptLayers *[]int
SourceLookupReferenceFunc libimage.LookupReferenceFunc
DestinationLookupReferenceFunc libimage.LookupReferenceFunc
CompressionFormat *compression.Algorithm
CompressionLevel *int
ForceCompressionFormat bool
}
func Push(ctx context.Context, image string, dest types.ImageReference, options PushOptions) (reference.Canonical, digest.Digest, error) {
libimageOptions := &libimage.PushOptions{}
libimageOptions.SignaturePolicyPath = options.SignaturePolicyPath
libimageOptions.Writer = options.ReportWriter
libimageOptions.ManifestMIMEType = options.ManifestType
libimageOptions.SignBy = options.SignBy
libimageOptions.RemoveSignatures = options.RemoveSignatures
libimageOptions.RetryDelay = &options.RetryDelay
libimageOptions.OciEncryptConfig = options.OciEncryptConfig
libimageOptions.OciEncryptLayers = options.OciEncryptLayers
libimageOptions.CompressionFormat = options.CompressionFormat
libimageOptions.CompressionLevel = options.CompressionLevel
libimageOptions.ForceCompressionFormat = options.ForceCompressionFormat
libimageOptions.PolicyAllowStorage = true
if options.Quiet {
libimageOptions.Writer = nil
}
compress := types.PreserveOriginal
if options.Compression == archive.Gzip {
compress = types.Compress
}
if options.SourceLookupReferenceFunc != nil {
libimageOptions.SourceLookupReferenceFunc = options.SourceLookupReferenceFunc
} else {
libimageOptions.SourceLookupReferenceFunc = cacheLookupReferenceFunc(options.BlobDirectory, compress)
}
libimageOptions.DestinationLookupReferenceFunc = options.DestinationLookupReferenceFunc
runtime, err := libimage.RuntimeFromStore(options.Store, &libimage.RuntimeOptions{SystemContext: options.SystemContext})
if err != nil {
return nil, "", err
}
destString := fmt.Sprintf("%s:%s", dest.Transport().Name(), dest.StringWithinTransport())
manifestBytes, err := runtime.Push(ctx, image, destString, libimageOptions)
if err != nil {
return nil, "", err
}
manifestDigest, err := manifest.Digest(manifestBytes)
if err != nil {
return nil, "", fmt.Errorf("computing digest of manifest of new image %q: %w", transports.ImageName(dest), err)
}
var ref reference.Canonical
if name := dest.DockerReference(); name != nil {
ref, err = reference.WithDigest(name, manifestDigest)
if err != nil {
logrus.Warnf("error generating canonical reference with name %q and digest %s: %v", name, manifestDigest.String(), err)
}
}
return ref, manifestDigest, nil
}
|