imagebuildah: Support custom image reference lookup for cache push/pull
This allows callers to provide custom SourceLookupReferenceFunc and DestinationLookupReferenceFunc for cache pull/push. These can be used to implement custom blob caches, and to wrap the reference being pushed/pulled to influence the copy behavior. Signed-off-by: Aaron Lehmann <alehmann@netflix.com>
This commit is contained in:
parent
bb4c8b0479
commit
e6c7949aa7
|
@ -4,6 +4,7 @@ import (
|
|||
"io"
|
||||
"time"
|
||||
|
||||
"github.com/containers/common/libimage"
|
||||
nettypes "github.com/containers/common/libnetwork/types"
|
||||
"github.com/containers/image/v5/docker/reference"
|
||||
"github.com/containers/image/v5/types"
|
||||
|
@ -342,4 +343,19 @@ type BuildOptions struct {
|
|||
// CDIConfigDir is the location of CDI configuration files, if the files in
|
||||
// the default configuration locations shouldn't be used.
|
||||
CDIConfigDir string
|
||||
// CachePullSourceLookupReferenceFunc is an optional LookupReferenceFunc
|
||||
// used to look up source references for cache pulls.
|
||||
CachePullSourceLookupReferenceFunc libimage.LookupReferenceFunc
|
||||
// CachePullDestinationLookupReferenceFunc is an optional generator
|
||||
// function which provides a LookupReferenceFunc used to look up
|
||||
// destination references for cache pulls.
|
||||
CachePullDestinationLookupReferenceFunc func(imageName string) libimage.LookupReferenceFunc
|
||||
// CachePushSourceLookupReferenceFunc is an optional generator function
|
||||
// which provides a LookupReferenceFunc used to look up source
|
||||
// references for cache pushes.
|
||||
CachePushSourceLookupReferenceFunc func(dest types.ImageReference) libimage.LookupReferenceFunc
|
||||
// CachePushDestinationLookupReferenceFunc is an optional
|
||||
// LookupReferenceFunc used to look up destination references for cache
|
||||
// pushes
|
||||
CachePushDestinationLookupReferenceFunc libimage.LookupReferenceFunc
|
||||
}
|
||||
|
|
|
@ -94,67 +94,71 @@ type Executor struct {
|
|||
cniPluginPath string
|
||||
cniConfigDir string
|
||||
// NetworkInterface is the libnetwork network interface used to setup CNI or netavark networks.
|
||||
networkInterface nettypes.ContainerNetwork
|
||||
idmappingOptions *define.IDMappingOptions
|
||||
commonBuildOptions *define.CommonBuildOptions
|
||||
defaultMountsFilePath string
|
||||
iidfile string
|
||||
squash bool
|
||||
labels []string
|
||||
layerLabels []string
|
||||
annotations []string
|
||||
layers bool
|
||||
noHostname bool
|
||||
noHosts bool
|
||||
useCache bool
|
||||
removeIntermediateCtrs bool
|
||||
forceRmIntermediateCtrs bool
|
||||
imageMap map[string]string // Used to map images that we create to handle the AS construct.
|
||||
containerMap map[string]*buildah.Builder // Used to map from image names to only-created-for-the-rootfs containers.
|
||||
baseMap map[string]struct{} // Holds the names of every base image, as given.
|
||||
rootfsMap map[string]struct{} // Holds the names of every stage whose rootfs is referenced in a COPY or ADD instruction.
|
||||
blobDirectory string
|
||||
excludes []string
|
||||
groupAdd []string
|
||||
ignoreFile string
|
||||
args map[string]string
|
||||
globalArgs map[string]string
|
||||
unusedArgs map[string]struct{}
|
||||
capabilities []string
|
||||
devices define.ContainerDevices
|
||||
deviceSpecs []string
|
||||
signBy string
|
||||
architecture string
|
||||
timestamp *time.Time
|
||||
os string
|
||||
maxPullPushRetries int
|
||||
retryPullPushDelay time.Duration
|
||||
ociDecryptConfig *encconfig.DecryptConfig
|
||||
lastError error
|
||||
terminatedStage map[string]error
|
||||
stagesLock sync.Mutex
|
||||
stagesSemaphore *semaphore.Weighted
|
||||
logRusage bool
|
||||
rusageLogFile io.Writer
|
||||
imageInfoLock sync.Mutex
|
||||
imageInfoCache map[string]imageTypeAndHistoryAndDiffIDs
|
||||
fromOverride string
|
||||
additionalBuildContexts map[string]*define.AdditionalBuildContext
|
||||
manifest string
|
||||
secrets map[string]define.Secret
|
||||
sshsources map[string]*sshagent.Source
|
||||
logPrefix string
|
||||
unsetEnvs []string
|
||||
unsetLabels []string
|
||||
processLabel string // Shares processLabel of first stage container with containers of other stages in same build
|
||||
mountLabel string // Shares mountLabel of first stage container with containers of other stages in same build
|
||||
buildOutput string // Specifies instructions for any custom build output
|
||||
osVersion string
|
||||
osFeatures []string
|
||||
envs []string
|
||||
confidentialWorkload define.ConfidentialWorkloadOptions
|
||||
sbomScanOptions []define.SBOMScanOptions
|
||||
cdiConfigDir string
|
||||
networkInterface nettypes.ContainerNetwork
|
||||
idmappingOptions *define.IDMappingOptions
|
||||
commonBuildOptions *define.CommonBuildOptions
|
||||
defaultMountsFilePath string
|
||||
iidfile string
|
||||
squash bool
|
||||
labels []string
|
||||
layerLabels []string
|
||||
annotations []string
|
||||
layers bool
|
||||
noHostname bool
|
||||
noHosts bool
|
||||
useCache bool
|
||||
removeIntermediateCtrs bool
|
||||
forceRmIntermediateCtrs bool
|
||||
imageMap map[string]string // Used to map images that we create to handle the AS construct.
|
||||
containerMap map[string]*buildah.Builder // Used to map from image names to only-created-for-the-rootfs containers.
|
||||
baseMap map[string]struct{} // Holds the names of every base image, as given.
|
||||
rootfsMap map[string]struct{} // Holds the names of every stage whose rootfs is referenced in a COPY or ADD instruction.
|
||||
blobDirectory string
|
||||
excludes []string
|
||||
groupAdd []string
|
||||
ignoreFile string
|
||||
args map[string]string
|
||||
globalArgs map[string]string
|
||||
unusedArgs map[string]struct{}
|
||||
capabilities []string
|
||||
devices define.ContainerDevices
|
||||
deviceSpecs []string
|
||||
signBy string
|
||||
architecture string
|
||||
timestamp *time.Time
|
||||
os string
|
||||
maxPullPushRetries int
|
||||
retryPullPushDelay time.Duration
|
||||
cachePullSourceLookupReferenceFunc libimage.LookupReferenceFunc
|
||||
cachePullDestinationLookupReferenceFunc func(imageName string) libimage.LookupReferenceFunc
|
||||
cachePushSourceLookupReferenceFunc func(dest types.ImageReference) libimage.LookupReferenceFunc
|
||||
cachePushDestinationLookupReferenceFunc libimage.LookupReferenceFunc
|
||||
ociDecryptConfig *encconfig.DecryptConfig
|
||||
lastError error
|
||||
terminatedStage map[string]error
|
||||
stagesLock sync.Mutex
|
||||
stagesSemaphore *semaphore.Weighted
|
||||
logRusage bool
|
||||
rusageLogFile io.Writer
|
||||
imageInfoLock sync.Mutex
|
||||
imageInfoCache map[string]imageTypeAndHistoryAndDiffIDs
|
||||
fromOverride string
|
||||
additionalBuildContexts map[string]*define.AdditionalBuildContext
|
||||
manifest string
|
||||
secrets map[string]define.Secret
|
||||
sshsources map[string]*sshagent.Source
|
||||
logPrefix string
|
||||
unsetEnvs []string
|
||||
unsetLabels []string
|
||||
processLabel string // Shares processLabel of first stage container with containers of other stages in same build
|
||||
mountLabel string // Shares mountLabel of first stage container with containers of other stages in same build
|
||||
buildOutput string // Specifies instructions for any custom build output
|
||||
osVersion string
|
||||
osFeatures []string
|
||||
envs []string
|
||||
confidentialWorkload define.ConfidentialWorkloadOptions
|
||||
sbomScanOptions []define.SBOMScanOptions
|
||||
cdiConfigDir string
|
||||
}
|
||||
|
||||
type imageTypeAndHistoryAndDiffIDs struct {
|
||||
|
@ -221,92 +225,96 @@ func newExecutor(logger *logrus.Logger, logPrefix string, store storage.Store, o
|
|||
}
|
||||
|
||||
exec := Executor{
|
||||
args: options.Args,
|
||||
cacheFrom: options.CacheFrom,
|
||||
cacheTo: options.CacheTo,
|
||||
cacheTTL: options.CacheTTL,
|
||||
containerSuffix: options.ContainerSuffix,
|
||||
logger: logger,
|
||||
stages: make(map[string]*StageExecutor),
|
||||
store: store,
|
||||
contextDir: options.ContextDirectory,
|
||||
excludes: excludes,
|
||||
groupAdd: options.GroupAdd,
|
||||
ignoreFile: options.IgnoreFile,
|
||||
pullPolicy: options.PullPolicy,
|
||||
registry: options.Registry,
|
||||
ignoreUnrecognizedInstructions: options.IgnoreUnrecognizedInstructions,
|
||||
quiet: options.Quiet,
|
||||
runtime: options.Runtime,
|
||||
runtimeArgs: options.RuntimeArgs,
|
||||
transientMounts: transientMounts,
|
||||
compression: options.Compression,
|
||||
output: options.Output,
|
||||
outputFormat: options.OutputFormat,
|
||||
additionalTags: options.AdditionalTags,
|
||||
signaturePolicyPath: options.SignaturePolicyPath,
|
||||
skipUnusedStages: options.SkipUnusedStages,
|
||||
systemContext: options.SystemContext,
|
||||
log: options.Log,
|
||||
in: options.In,
|
||||
out: options.Out,
|
||||
err: options.Err,
|
||||
reportWriter: writer,
|
||||
isolation: options.Isolation,
|
||||
namespaceOptions: options.NamespaceOptions,
|
||||
configureNetwork: options.ConfigureNetwork,
|
||||
cniPluginPath: options.CNIPluginPath,
|
||||
cniConfigDir: options.CNIConfigDir,
|
||||
networkInterface: options.NetworkInterface,
|
||||
idmappingOptions: options.IDMappingOptions,
|
||||
commonBuildOptions: options.CommonBuildOpts,
|
||||
defaultMountsFilePath: options.DefaultMountsFilePath,
|
||||
iidfile: options.IIDFile,
|
||||
squash: options.Squash,
|
||||
labels: append([]string{}, options.Labels...),
|
||||
layerLabels: append([]string{}, options.LayerLabels...),
|
||||
annotations: append([]string{}, options.Annotations...),
|
||||
layers: options.Layers,
|
||||
noHostname: options.CommonBuildOpts.NoHostname,
|
||||
noHosts: options.CommonBuildOpts.NoHosts,
|
||||
useCache: !options.NoCache,
|
||||
removeIntermediateCtrs: options.RemoveIntermediateCtrs,
|
||||
forceRmIntermediateCtrs: options.ForceRmIntermediateCtrs,
|
||||
imageMap: make(map[string]string),
|
||||
containerMap: make(map[string]*buildah.Builder),
|
||||
baseMap: make(map[string]struct{}),
|
||||
rootfsMap: make(map[string]struct{}),
|
||||
blobDirectory: options.BlobDirectory,
|
||||
unusedArgs: make(map[string]struct{}),
|
||||
capabilities: capabilities,
|
||||
deviceSpecs: options.Devices,
|
||||
signBy: options.SignBy,
|
||||
architecture: options.Architecture,
|
||||
timestamp: options.Timestamp,
|
||||
os: options.OS,
|
||||
maxPullPushRetries: options.MaxPullPushRetries,
|
||||
retryPullPushDelay: options.PullPushRetryDelay,
|
||||
ociDecryptConfig: options.OciDecryptConfig,
|
||||
terminatedStage: make(map[string]error),
|
||||
stagesSemaphore: options.JobSemaphore,
|
||||
logRusage: options.LogRusage,
|
||||
rusageLogFile: rusageLogFile,
|
||||
imageInfoCache: make(map[string]imageTypeAndHistoryAndDiffIDs),
|
||||
fromOverride: options.From,
|
||||
additionalBuildContexts: options.AdditionalBuildContexts,
|
||||
manifest: options.Manifest,
|
||||
secrets: secrets,
|
||||
sshsources: sshsources,
|
||||
logPrefix: logPrefix,
|
||||
unsetEnvs: append([]string{}, options.UnsetEnvs...),
|
||||
unsetLabels: append([]string{}, options.UnsetLabels...),
|
||||
buildOutput: options.BuildOutput,
|
||||
osVersion: options.OSVersion,
|
||||
osFeatures: append([]string{}, options.OSFeatures...),
|
||||
envs: append([]string{}, options.Envs...),
|
||||
confidentialWorkload: options.ConfidentialWorkload,
|
||||
sbomScanOptions: options.SBOMScanOptions,
|
||||
cdiConfigDir: options.CDIConfigDir,
|
||||
args: options.Args,
|
||||
cacheFrom: options.CacheFrom,
|
||||
cacheTo: options.CacheTo,
|
||||
cacheTTL: options.CacheTTL,
|
||||
containerSuffix: options.ContainerSuffix,
|
||||
logger: logger,
|
||||
stages: make(map[string]*StageExecutor),
|
||||
store: store,
|
||||
contextDir: options.ContextDirectory,
|
||||
excludes: excludes,
|
||||
groupAdd: options.GroupAdd,
|
||||
ignoreFile: options.IgnoreFile,
|
||||
pullPolicy: options.PullPolicy,
|
||||
registry: options.Registry,
|
||||
ignoreUnrecognizedInstructions: options.IgnoreUnrecognizedInstructions,
|
||||
quiet: options.Quiet,
|
||||
runtime: options.Runtime,
|
||||
runtimeArgs: options.RuntimeArgs,
|
||||
transientMounts: transientMounts,
|
||||
compression: options.Compression,
|
||||
output: options.Output,
|
||||
outputFormat: options.OutputFormat,
|
||||
additionalTags: options.AdditionalTags,
|
||||
signaturePolicyPath: options.SignaturePolicyPath,
|
||||
skipUnusedStages: options.SkipUnusedStages,
|
||||
systemContext: options.SystemContext,
|
||||
log: options.Log,
|
||||
in: options.In,
|
||||
out: options.Out,
|
||||
err: options.Err,
|
||||
reportWriter: writer,
|
||||
isolation: options.Isolation,
|
||||
namespaceOptions: options.NamespaceOptions,
|
||||
configureNetwork: options.ConfigureNetwork,
|
||||
cniPluginPath: options.CNIPluginPath,
|
||||
cniConfigDir: options.CNIConfigDir,
|
||||
networkInterface: options.NetworkInterface,
|
||||
idmappingOptions: options.IDMappingOptions,
|
||||
commonBuildOptions: options.CommonBuildOpts,
|
||||
defaultMountsFilePath: options.DefaultMountsFilePath,
|
||||
iidfile: options.IIDFile,
|
||||
squash: options.Squash,
|
||||
labels: append([]string{}, options.Labels...),
|
||||
layerLabels: append([]string{}, options.LayerLabels...),
|
||||
annotations: append([]string{}, options.Annotations...),
|
||||
layers: options.Layers,
|
||||
noHostname: options.CommonBuildOpts.NoHostname,
|
||||
noHosts: options.CommonBuildOpts.NoHosts,
|
||||
useCache: !options.NoCache,
|
||||
removeIntermediateCtrs: options.RemoveIntermediateCtrs,
|
||||
forceRmIntermediateCtrs: options.ForceRmIntermediateCtrs,
|
||||
imageMap: make(map[string]string),
|
||||
containerMap: make(map[string]*buildah.Builder),
|
||||
baseMap: make(map[string]struct{}),
|
||||
rootfsMap: make(map[string]struct{}),
|
||||
blobDirectory: options.BlobDirectory,
|
||||
unusedArgs: make(map[string]struct{}),
|
||||
capabilities: capabilities,
|
||||
deviceSpecs: options.Devices,
|
||||
signBy: options.SignBy,
|
||||
architecture: options.Architecture,
|
||||
timestamp: options.Timestamp,
|
||||
os: options.OS,
|
||||
maxPullPushRetries: options.MaxPullPushRetries,
|
||||
retryPullPushDelay: options.PullPushRetryDelay,
|
||||
cachePullSourceLookupReferenceFunc: options.CachePullSourceLookupReferenceFunc,
|
||||
cachePullDestinationLookupReferenceFunc: options.CachePullDestinationLookupReferenceFunc,
|
||||
cachePushSourceLookupReferenceFunc: options.CachePushSourceLookupReferenceFunc,
|
||||
cachePushDestinationLookupReferenceFunc: options.CachePushDestinationLookupReferenceFunc,
|
||||
ociDecryptConfig: options.OciDecryptConfig,
|
||||
terminatedStage: make(map[string]error),
|
||||
stagesSemaphore: options.JobSemaphore,
|
||||
logRusage: options.LogRusage,
|
||||
rusageLogFile: rusageLogFile,
|
||||
imageInfoCache: make(map[string]imageTypeAndHistoryAndDiffIDs),
|
||||
fromOverride: options.From,
|
||||
additionalBuildContexts: options.AdditionalBuildContexts,
|
||||
manifest: options.Manifest,
|
||||
secrets: secrets,
|
||||
sshsources: sshsources,
|
||||
logPrefix: logPrefix,
|
||||
unsetEnvs: append([]string{}, options.UnsetEnvs...),
|
||||
unsetLabels: append([]string{}, options.UnsetLabels...),
|
||||
buildOutput: options.BuildOutput,
|
||||
osVersion: options.OSVersion,
|
||||
osFeatures: append([]string{}, options.OSFeatures...),
|
||||
envs: append([]string{}, options.Envs...),
|
||||
confidentialWorkload: options.ConfidentialWorkload,
|
||||
sbomScanOptions: options.SBOMScanOptions,
|
||||
cdiConfigDir: options.CDIConfigDir,
|
||||
}
|
||||
if exec.err == nil {
|
||||
exec.err = os.Stderr
|
||||
|
|
|
@ -1992,6 +1992,12 @@ func (s *StageExecutor) pushCache(ctx context.Context, src, cacheKey string) err
|
|||
MaxRetries: s.executor.maxPullPushRetries,
|
||||
RetryDelay: s.executor.retryPullPushDelay,
|
||||
}
|
||||
if s.executor.cachePushSourceLookupReferenceFunc != nil {
|
||||
options.SourceLookupReferenceFunc = s.executor.cachePushSourceLookupReferenceFunc(dest)
|
||||
}
|
||||
if s.executor.cachePushDestinationLookupReferenceFunc != nil {
|
||||
options.DestinationLookupReferenceFunc = s.executor.cachePushDestinationLookupReferenceFunc
|
||||
}
|
||||
ref, digest, err := buildah.Push(ctx, src, dest, options)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed pushing cache to %q: %w", dest, err)
|
||||
|
@ -2013,7 +2019,9 @@ func (s *StageExecutor) pullCache(ctx context.Context, cacheKey string) (referen
|
|||
return nil, "", err
|
||||
}
|
||||
for _, src := range srcList {
|
||||
logrus.Debugf("trying to pull cache from remote repo: %+v", src.DockerReference())
|
||||
srcDockerRef := src.DockerReference()
|
||||
logrus.Debugf("trying to pull cache from remote repo: %+v", srcDockerRef)
|
||||
imageName := srcDockerRef.String()
|
||||
options := buildah.PullOptions{
|
||||
SignaturePolicyPath: s.executor.signaturePolicyPath,
|
||||
Store: s.executor.store,
|
||||
|
@ -2025,7 +2033,14 @@ func (s *StageExecutor) pullCache(ctx context.Context, cacheKey string) (referen
|
|||
ReportWriter: nil,
|
||||
PullPolicy: define.PullIfNewer,
|
||||
}
|
||||
id, err := buildah.Pull(ctx, src.DockerReference().String(), options)
|
||||
if s.executor.cachePullSourceLookupReferenceFunc != nil {
|
||||
options.SourceLookupReferenceFunc = s.executor.cachePullSourceLookupReferenceFunc
|
||||
}
|
||||
if s.executor.cachePullDestinationLookupReferenceFunc != nil {
|
||||
options.DestinationLookupReferenceFunc = s.executor.cachePullDestinationLookupReferenceFunc(imageName)
|
||||
}
|
||||
|
||||
id, err := buildah.Pull(ctx, imageName, options)
|
||||
if err != nil {
|
||||
logrus.Debugf("failed pulling cache from source %s: %v", src, err)
|
||||
continue // failed pulling this one try next
|
||||
|
|
13
pull.go
13
pull.go
|
@ -50,6 +50,12 @@ type PullOptions struct {
|
|||
OciDecryptConfig *encconfig.DecryptConfig
|
||||
// PullPolicy takes the value PullIfMissing, PullAlways, PullIfNewer, or PullNever.
|
||||
PullPolicy define.PullPolicy
|
||||
// SourceLookupReference provides a function to look up source
|
||||
// references.
|
||||
SourceLookupReferenceFunc libimage.LookupReferenceFunc
|
||||
// DestinationLookupReference provides a function to look up destination
|
||||
// references.
|
||||
DestinationLookupReferenceFunc libimage.LookupReferenceFunc
|
||||
}
|
||||
|
||||
// Pull copies the contents of the image from somewhere else to local storage. Returns the
|
||||
|
@ -62,7 +68,12 @@ func Pull(ctx context.Context, imageName string, options PullOptions) (imageID s
|
|||
libimageOptions.OciDecryptConfig = options.OciDecryptConfig
|
||||
libimageOptions.AllTags = options.AllTags
|
||||
libimageOptions.RetryDelay = &options.RetryDelay
|
||||
libimageOptions.DestinationLookupReferenceFunc = cacheLookupReferenceFunc(options.BlobDirectory, types.PreserveOriginal)
|
||||
libimageOptions.SourceLookupReferenceFunc = options.SourceLookupReferenceFunc
|
||||
if options.DestinationLookupReferenceFunc != nil {
|
||||
libimageOptions.DestinationLookupReferenceFunc = options.DestinationLookupReferenceFunc
|
||||
} else {
|
||||
libimageOptions.DestinationLookupReferenceFunc = cacheLookupReferenceFunc(options.BlobDirectory, types.PreserveOriginal)
|
||||
}
|
||||
|
||||
if options.MaxRetries > 0 {
|
||||
retries := uint(options.MaxRetries)
|
||||
|
|
13
push.go
13
push.go
|
@ -90,6 +90,12 @@ type PushOptions struct {
|
|||
// integers in the slice represent 0-indexed layer indices, with support for negative
|
||||
// indexing. i.e. 0 is the first layer, -1 is the last (top-most) layer.
|
||||
OciEncryptLayers *[]int
|
||||
// SourceLookupReference provides a function to look up source
|
||||
// references.
|
||||
SourceLookupReferenceFunc libimage.LookupReferenceFunc
|
||||
// DestinationLookupReference provides a function to look up destination
|
||||
// references.
|
||||
DestinationLookupReferenceFunc libimage.LookupReferenceFunc
|
||||
|
||||
// CompressionFormat is the format to use for the compression of the blobs
|
||||
CompressionFormat *compression.Algorithm
|
||||
|
@ -125,7 +131,12 @@ func Push(ctx context.Context, image string, dest types.ImageReference, options
|
|||
if options.Compression == archive.Gzip {
|
||||
compress = types.Compress
|
||||
}
|
||||
libimageOptions.SourceLookupReferenceFunc = cacheLookupReferenceFunc(options.BlobDirectory, 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 {
|
||||
|
|
Loading…
Reference in New Issue