diff --git a/commands.go b/commands.go index 1f2c3650d7..e7def9afec 100644 --- a/commands.go +++ b/commands.go @@ -826,10 +826,22 @@ func (srv *Server) CmdRun(stdin io.ReadCloser, stdout io.Writer, args ...string) fmt.Fprintln(stdout, "Error: Command not specified") return fmt.Errorf("Command not specified") } + // Create new container container, err := srv.runtime.Create(config) if err != nil { - return errors.New("Error creating container: " + err.Error()) + // If container not found, try to pull it + if srv.runtime.graph.IsNotExist(err) { + fmt.Fprintf(stdout, "Image %s not found, trying to pull it from registry.\n", config.Image) + if err = srv.CmdPull(stdin, stdout, config.Image); err != nil { + return err + } + if container, err = srv.runtime.Create(config); err != nil { + return err + } + } else { + return err + } } if config.OpenStdin { cmd_stdin, err := container.StdinPipe() diff --git a/graph.go b/graph.go index 35f092703f..29d8b2bb6f 100644 --- a/graph.go +++ b/graph.go @@ -6,6 +6,7 @@ import ( "os" "path" "path/filepath" + "strings" "time" ) @@ -27,6 +28,12 @@ func NewGraph(root string) (*Graph, error) { }, nil } +// FIXME: Implement error subclass instead of looking at the error text +// Note: This is the way golang implements os.IsNotExists on Plan9 +func (graph *Graph) IsNotExist(err error) bool { + return err != nil && strings.Contains(err.Error(), "does not exist") +} + func (graph *Graph) Exists(id string) bool { if _, err := graph.Get(id); err != nil { return false diff --git a/tags.go b/tags.go index 1df7c6e463..e259c2e7ea 100644 --- a/tags.go +++ b/tags.go @@ -75,7 +75,7 @@ func (store *TagStore) LookupImage(name string) (*Image, error) { if i, err := store.GetImage(repoAndTag[0], repoAndTag[1]); err != nil { return nil, err } else if i == nil { - return nil, fmt.Errorf("No such image: %s", name) + return nil, fmt.Errorf("Image does not exist: %s", name) } else { img = i }