aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbaude <bbaude@redhat.com>2017-11-13 12:40:21 -0600
committerAtomic Bot <atomic-devel@projectatomic.io>2017-11-14 21:14:13 +0000
commit5cfd7a313fcae7c748b5bae84de779b28d4ea01b (patch)
tree310b7b4d63f989415d5dcf1696a127c2f3d0ce0a
parent7df322123290ee600812312421b98cfb97031e9f (diff)
downloadpodman-5cfd7a313fcae7c748b5bae84de779b28d4ea01b.tar.gz
podman-5cfd7a313fcae7c748b5bae84de779b28d4ea01b.tar.bz2
podman-5cfd7a313fcae7c748b5bae84de779b28d4ea01b.zip
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
-rw-r--r--cmd/kpod/create.go10
-rw-r--r--cmd/kpod/run.go11
-rw-r--r--libpod/runtime_img.go80
-rw-r--r--libpod/util.go10
4 files changed, 96 insertions, 15 deletions
diff --git a/cmd/kpod/create.go b/cmd/kpod/create.go
index 55f02e8e6..bbfeaebae 100644
--- a/cmd/kpod/create.go
+++ b/cmd/kpod/create.go
@@ -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
}
diff --git a/cmd/kpod/run.go b/cmd/kpod/run.go
index 6b67b55cd..84da12e6a 100644
--- a/cmd/kpod/run.go
+++ b/cmd/kpod/run.go
@@ -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
}
diff --git a/libpod/runtime_img.go b/libpod/runtime_img.go
index 8a5258e75..0fa003799 100644
--- a/libpod/runtime_img.go
+++ b/libpod/runtime_img.go
@@ -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")
}
- fqname, _ := k.GetFQName()
+ 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
+ }
- _, err = k.runtime.GetImage(fqname)
- if err == nil {
- return true
+ if imageName == k.Name {
+ return name, nil
+ }
+ imageSplit := strings.Split(imageName, "/")
+ baseName := imageSplit[len(imageSplit)-1]
+ if baseName == k.Name {
+ return name, nil
+ }
+ }
}
- return false
+ fqname, _ := k.GetFQName()
+ 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
diff --git a/libpod/util.go b/libpod/util.go
index 0270af07c..61546f23e 100644
--- a/libpod/util.go
+++ b/libpod/util.go
@@ -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)
+}