mirror of https://github.com/containers/podman.git
pkg/specgen: cache image in generator
To prevent expensive redundant lookups and inspects on the same image, cache the image in the generator. Note that once a given image has been inspected, subsequent calls will use the libimage-internal cache. [NO TESTS NEEDED] since it is no functional change. Signed-off-by: Valentin Rothberg <rothberg@redhat.com>
This commit is contained in:
parent
1da364783d
commit
686b7ef7bf
|
@ -18,19 +18,43 @@ import (
|
||||||
"golang.org/x/sys/unix"
|
"golang.org/x/sys/unix"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func getImageFromSpec(ctx context.Context, r *libpod.Runtime, s *specgen.SpecGenerator) (*libimage.Image, string, *libimage.ImageData, error) {
|
||||||
|
if s.Image == "" || s.Rootfs != "" {
|
||||||
|
return nil, "", nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Image may already have been set in the generator.
|
||||||
|
image, resolvedName := s.GetImage()
|
||||||
|
if image != nil {
|
||||||
|
inspectData, err := image.Inspect(ctx, false)
|
||||||
|
if err != nil {
|
||||||
|
return nil, "", nil, err
|
||||||
|
}
|
||||||
|
return image, resolvedName, inspectData, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Need to look up image.
|
||||||
|
image, resolvedName, err := r.LibimageRuntime().LookupImage(s.Image, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, "", nil, err
|
||||||
|
}
|
||||||
|
s.SetImage(image, resolvedName)
|
||||||
|
inspectData, err := image.Inspect(ctx, false)
|
||||||
|
if err != nil {
|
||||||
|
return nil, "", nil, err
|
||||||
|
}
|
||||||
|
return image, resolvedName, inspectData, err
|
||||||
|
}
|
||||||
|
|
||||||
// Fill any missing parts of the spec generator (e.g. from the image).
|
// Fill any missing parts of the spec generator (e.g. from the image).
|
||||||
// Returns a set of warnings or any fatal error that occurred.
|
// Returns a set of warnings or any fatal error that occurred.
|
||||||
func CompleteSpec(ctx context.Context, r *libpod.Runtime, s *specgen.SpecGenerator) ([]string, error) {
|
func CompleteSpec(ctx context.Context, r *libpod.Runtime, s *specgen.SpecGenerator) ([]string, error) {
|
||||||
// Only add image configuration if we have an image
|
// Only add image configuration if we have an image
|
||||||
var newImage *libimage.Image
|
newImage, _, inspectData, err := getImageFromSpec(ctx, r, s)
|
||||||
var inspectData *libimage.ImageData
|
if err != nil {
|
||||||
var err error
|
return nil, err
|
||||||
if s.Image != "" {
|
}
|
||||||
newImage, _, err = r.LibimageRuntime().LookupImage(s.Image, nil)
|
if inspectData != nil {
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
inspectData, err = newImage.Inspect(ctx, false)
|
inspectData, err = newImage.Inspect(ctx, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
|
@ -102,20 +102,15 @@ func MakeContainer(ctx context.Context, rt *libpod.Runtime, s *specgen.SpecGener
|
||||||
options = append(options, libpod.WithCreateCommand(s.ContainerCreateCommand))
|
options = append(options, libpod.WithCreateCommand(s.ContainerCreateCommand))
|
||||||
}
|
}
|
||||||
|
|
||||||
var newImage *libimage.Image
|
|
||||||
var imageData *libimage.ImageData
|
|
||||||
if s.Rootfs != "" {
|
if s.Rootfs != "" {
|
||||||
options = append(options, libpod.WithRootFS(s.Rootfs, s.RootfsOverlay))
|
options = append(options, libpod.WithRootFS(s.Rootfs, s.RootfsOverlay))
|
||||||
} else {
|
}
|
||||||
var resolvedImageName string
|
|
||||||
newImage, resolvedImageName, err = rt.LibimageRuntime().LookupImage(s.Image, nil)
|
newImage, resolvedImageName, imageData, err := getImageFromSpec(ctx, rt, s)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, nil, err
|
return nil, nil, nil, err
|
||||||
}
|
}
|
||||||
imageData, err = newImage.Inspect(ctx, false)
|
if newImage != nil {
|
||||||
if err != nil {
|
|
||||||
return nil, nil, nil, err
|
|
||||||
}
|
|
||||||
// If the input name changed, we could properly resolve the
|
// If the input name changed, we could properly resolve the
|
||||||
// image. Otherwise, it must have been an ID where we're
|
// image. Otherwise, it must have been an ID where we're
|
||||||
// defaulting to the first name or an empty one if no names are
|
// defaulting to the first name or an empty one if no names are
|
||||||
|
|
|
@ -5,6 +5,7 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
|
"github.com/containers/common/libimage"
|
||||||
"github.com/containers/image/v5/manifest"
|
"github.com/containers/image/v5/manifest"
|
||||||
nettypes "github.com/containers/podman/v3/libpod/network/types"
|
nettypes "github.com/containers/podman/v3/libpod/network/types"
|
||||||
"github.com/containers/storage/types"
|
"github.com/containers/storage/types"
|
||||||
|
@ -512,6 +513,21 @@ type SpecGenerator struct {
|
||||||
ContainerNetworkConfig
|
ContainerNetworkConfig
|
||||||
ContainerResourceConfig
|
ContainerResourceConfig
|
||||||
ContainerHealthCheckConfig
|
ContainerHealthCheckConfig
|
||||||
|
|
||||||
|
image *libimage.Image `json:"-"`
|
||||||
|
resolvedImageName string `json:"-"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetImage sets the associated for the generator.
|
||||||
|
func (s *SpecGenerator) SetImage(image *libimage.Image, resolvedImageName string) {
|
||||||
|
s.image = image
|
||||||
|
s.resolvedImageName = resolvedImageName
|
||||||
|
}
|
||||||
|
|
||||||
|
// Image returns the associated image for the generator.
|
||||||
|
// May be nil if no image has been set yet.
|
||||||
|
func (s *SpecGenerator) GetImage() (*libimage.Image, string) {
|
||||||
|
return s.image, s.resolvedImageName
|
||||||
}
|
}
|
||||||
|
|
||||||
type Secret struct {
|
type Secret struct {
|
||||||
|
|
Loading…
Reference in New Issue