mirror of
https://github.com/containers/podman.git
synced 2025-08-06 03:19:52 +08:00
Address run/create performance issues
Fixed the logic where we observed different performance results when running an image by its fqname vs a shortname. In the case of the latter, we resolve the name without using the network. Signed-off-by: baude <bbaude@redhat.com> Closes: #37 Approved by: rhatdan
This commit is contained in:
@ -135,6 +135,7 @@ var createCommand = cli.Command{
|
||||
func createCmd(c *cli.Context) error {
|
||||
// TODO should allow user to create based off a directory on the host not just image
|
||||
// Need CLI support for this
|
||||
var imageName string
|
||||
if err := validateFlags(c, createFlags); err != nil {
|
||||
return err
|
||||
}
|
||||
@ -151,7 +152,8 @@ func createCmd(c *cli.Context) error {
|
||||
|
||||
// Deal with the image after all the args have been checked
|
||||
createImage := runtime.NewImage(createConfig.image)
|
||||
if !createImage.HasImageLocal() {
|
||||
createImage.LocalName, _ = createImage.GetLocalImageName()
|
||||
if createImage.LocalName == "" {
|
||||
// The image wasnt found by the user input'd name or its fqname
|
||||
// Pull the image
|
||||
fmt.Printf("Trying to pull %s...", createImage.PullName)
|
||||
@ -163,7 +165,11 @@ func createCmd(c *cli.Context) error {
|
||||
return err
|
||||
}
|
||||
defer runtime.Shutdown(false)
|
||||
imageName, err := createImage.GetFQName()
|
||||
if createImage.LocalName != "" {
|
||||
imageName = createImage.LocalName
|
||||
} else {
|
||||
imageName, err = createImage.GetFQName()
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -22,6 +22,7 @@ var runCommand = cli.Command{
|
||||
}
|
||||
|
||||
func runCmd(c *cli.Context) error {
|
||||
var imageName string
|
||||
if err := validateFlags(c, createFlags); err != nil {
|
||||
return err
|
||||
}
|
||||
@ -37,8 +38,8 @@ func runCmd(c *cli.Context) error {
|
||||
}
|
||||
|
||||
createImage := runtime.NewImage(createConfig.image)
|
||||
|
||||
if !createImage.HasImageLocal() {
|
||||
createImage.LocalName, _ = createImage.GetLocalImageName()
|
||||
if createImage.LocalName == "" {
|
||||
// The image wasnt found by the user input'd name or its fqname
|
||||
// Pull the image
|
||||
fmt.Printf("Trying to pull %s...", createImage.PullName)
|
||||
@ -52,7 +53,11 @@ func runCmd(c *cli.Context) error {
|
||||
defer runtime.Shutdown(false)
|
||||
logrus.Debug("spec is ", runtimeSpec)
|
||||
|
||||
imageName, err := createImage.GetFQName()
|
||||
if createImage.LocalName != "" {
|
||||
imageName = createImage.LocalName
|
||||
} else {
|
||||
imageName, err = createImage.GetFQName()
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -127,6 +127,7 @@ type Image struct {
|
||||
Transport string
|
||||
beenDecomposed bool
|
||||
PullName string
|
||||
LocalName string
|
||||
}
|
||||
|
||||
// NewImage creates a new image object based on its name
|
||||
@ -139,9 +140,21 @@ func (r *Runtime) NewImage(name string) Image {
|
||||
|
||||
// GetImageID returns the image ID of the image
|
||||
func (k *Image) GetImageID() (string, error) {
|
||||
// If the ID field is already populated, then
|
||||
// return it.
|
||||
if k.ID != "" {
|
||||
return k.ID, nil
|
||||
}
|
||||
// If we have the name of the image locally, then
|
||||
// get the image and returns its ID
|
||||
if k.LocalName != "" {
|
||||
img, err := k.runtime.GetImage(k.LocalName)
|
||||
if err == nil {
|
||||
return img.ID, nil
|
||||
}
|
||||
}
|
||||
// If neither the ID is known and no local name
|
||||
// is know, we search it out.
|
||||
image, _ := k.GetFQName()
|
||||
img, err := k.runtime.GetImage(image)
|
||||
if err != nil {
|
||||
@ -270,26 +283,73 @@ func (k *Image) Decompose() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// HasImageLocal returns a bool true if the image is already pulled
|
||||
func (k *Image) HasImageLocal() bool {
|
||||
func getTags(nameInput string) (reference.NamedTagged, bool, error) {
|
||||
inputRef, err := reference.Parse(nameInput)
|
||||
if err != nil {
|
||||
return nil, false, errors.Wrapf(err, "unable to obtain tag from input name")
|
||||
}
|
||||
tagged, isTagged := inputRef.(reference.NamedTagged)
|
||||
|
||||
return tagged, isTagged, nil
|
||||
}
|
||||
|
||||
// GetLocalImageName returns the name of the image if it is local.
|
||||
// It will return an empty string and error if not found.
|
||||
func (k *Image) GetLocalImageName() (string, error) {
|
||||
_, err := k.runtime.GetImage(k.Name)
|
||||
if err == nil {
|
||||
return true
|
||||
if err != nil {
|
||||
return "", errors.Wrapf(err, "unable to obtain local image")
|
||||
}
|
||||
localImages, err := k.runtime.GetImages(&ImageFilterParams{})
|
||||
if err != nil {
|
||||
return "", errors.Wrapf(err, "unable to obtain local image")
|
||||
}
|
||||
_, isTagged, err := getTags(k.Name)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
for _, image := range localImages {
|
||||
for _, name := range image.Names {
|
||||
imgRef, err := reference.Parse(name)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
var imageName string
|
||||
imageNameOnly := reference.Path(imgRef.(reference.Named))
|
||||
if isTagged {
|
||||
imageNameTag, _, err := getTags(name)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
imageName = fmt.Sprintf("%s:%s", imageNameOnly, imageNameTag.Tag())
|
||||
} else {
|
||||
imageName = imageNameOnly
|
||||
}
|
||||
|
||||
if imageName == k.Name {
|
||||
return name, nil
|
||||
}
|
||||
imageSplit := strings.Split(imageName, "/")
|
||||
baseName := imageSplit[len(imageSplit)-1]
|
||||
if baseName == k.Name {
|
||||
return name, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
fqname, _ := k.GetFQName()
|
||||
|
||||
_, err = k.runtime.GetImage(fqname)
|
||||
if err == nil {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
return fqname, nil
|
||||
}
|
||||
|
||||
// HasLatest determines if we have the latest image local
|
||||
func (k *Image) HasLatest() (bool, error) {
|
||||
if !k.HasImageLocal() {
|
||||
localName, err := k.GetLocalImageName()
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
if localName == "" {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
fqname, err := k.GetFQName()
|
||||
if err != nil {
|
||||
return false, err
|
||||
|
@ -1,8 +1,10 @@
|
||||
package libpod
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"time"
|
||||
)
|
||||
|
||||
// WriteFile writes a provided string to a provided path
|
||||
@ -32,3 +34,11 @@ func StringInSlice(s string, sl []string) bool {
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// FuncTimer helps measure the execution time of a function
|
||||
// For debug purposes, do not leave in code
|
||||
// used like defer FuncTimer("foo")
|
||||
func FuncTimer(funcName string) {
|
||||
elapsed := time.Since(time.Now())
|
||||
fmt.Printf("%s executed in %d ms\n", funcName, elapsed)
|
||||
}
|
||||
|
Reference in New Issue
Block a user