Skip to content

Commit

Permalink
pkg/specgen: cache image in generator
Browse files Browse the repository at this point in the history
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 <[email protected]>
  • Loading branch information
vrothberg committed Oct 1, 2021
1 parent 1da3647 commit 686b7ef
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 21 deletions.
42 changes: 33 additions & 9 deletions pkg/specgen/generate/container.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,43 @@ import (
"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).
// Returns a set of warnings or any fatal error that occurred.
func CompleteSpec(ctx context.Context, r *libpod.Runtime, s *specgen.SpecGenerator) ([]string, error) {
// Only add image configuration if we have an image
var newImage *libimage.Image
var inspectData *libimage.ImageData
var err error
if s.Image != "" {
newImage, _, err = r.LibimageRuntime().LookupImage(s.Image, nil)
if err != nil {
return nil, err
}

newImage, _, inspectData, err := getImageFromSpec(ctx, r, s)
if err != nil {
return nil, err
}
if inspectData != nil {
inspectData, err = newImage.Inspect(ctx, false)
if err != nil {
return nil, err
Expand Down
19 changes: 7 additions & 12 deletions pkg/specgen/generate/container_create.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,20 +102,15 @@ func MakeContainer(ctx context.Context, rt *libpod.Runtime, s *specgen.SpecGener
options = append(options, libpod.WithCreateCommand(s.ContainerCreateCommand))
}

var newImage *libimage.Image
var imageData *libimage.ImageData
if s.Rootfs != "" {
options = append(options, libpod.WithRootFS(s.Rootfs, s.RootfsOverlay))
} else {
var resolvedImageName string
newImage, resolvedImageName, err = rt.LibimageRuntime().LookupImage(s.Image, nil)
if err != nil {
return nil, nil, nil, err
}
imageData, err = newImage.Inspect(ctx, false)
if err != nil {
return nil, nil, nil, err
}
}

newImage, resolvedImageName, imageData, err := getImageFromSpec(ctx, rt, s)
if err != nil {
return nil, nil, nil, err
}
if newImage != nil {
// If the input name changed, we could properly resolve the
// image. Otherwise, it must have been an ID where we're
// defaulting to the first name or an empty one if no names are
Expand Down
16 changes: 16 additions & 0 deletions pkg/specgen/specgen.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"strings"
"syscall"

"github.com/containers/common/libimage"
"github.com/containers/image/v5/manifest"
nettypes "github.com/containers/podman/v3/libpod/network/types"
"github.com/containers/storage/types"
Expand Down Expand Up @@ -512,6 +513,21 @@ type SpecGenerator struct {
ContainerNetworkConfig
ContainerResourceConfig
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 {
Expand Down

0 comments on commit 686b7ef

Please sign in to comment.