mirror of https://github.com/docker/docs.git
Fix image pull bug (wait until download finishes)
Signed-off-by: Nishant Totla <nishanttotla@gmail.com>
This commit is contained in:
parent
2363ea8077
commit
ff0c79e08d
|
@ -2,6 +2,7 @@ package cluster
|
|||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
|
@ -952,40 +953,54 @@ func (e *Engine) CreateVolume(request *types.VolumeCreateRequest) (*Volume, erro
|
|||
}
|
||||
|
||||
// FIXME: This will become unnecessary after docker/engine-api#162 is merged
|
||||
func getTagFromNamedRef(dref reference.Named) string {
|
||||
var tag string
|
||||
switch x := dref.(type) {
|
||||
case reference.Digested:
|
||||
func buildImagePullOptions(image string) (types.ImagePullOptions, error) {
|
||||
distributionRef, err := reference.ParseNamed(image)
|
||||
if err != nil {
|
||||
return types.ImagePullOptions{}, err
|
||||
}
|
||||
|
||||
name := distributionRef.Name()
|
||||
tag := "latest"
|
||||
|
||||
switch x := distributionRef.(type) {
|
||||
case reference.Canonical:
|
||||
tag = x.Digest().String()
|
||||
case reference.NamedTagged:
|
||||
tag = x.Tag()
|
||||
}
|
||||
return tag
|
||||
|
||||
return types.ImagePullOptions{
|
||||
ImageID: name,
|
||||
Tag: tag,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Pull an image on the engine
|
||||
func (e *Engine) Pull(image string, authConfig *types.AuthConfig) error {
|
||||
distributionRef, err := reference.ParseNamed(image)
|
||||
pullOpts, err := buildImagePullOptions(image)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
repository := distributionRef.Name()
|
||||
tag := getTagFromNamedRef(distributionRef)
|
||||
|
||||
pullOpts := types.ImagePullOptions{
|
||||
ImageID: repository,
|
||||
Tag: tag,
|
||||
}
|
||||
_, err = e.apiClient.ImagePull(context.TODO(), pullOpts, nil)
|
||||
pullResponse, err := e.apiClient.ImagePull(context.TODO(), pullOpts, nil)
|
||||
e.CheckConnectionErr(err)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// wait until the image download is finished
|
||||
dec := json.NewDecoder(pullResponse)
|
||||
for {
|
||||
m := map[string]interface{}{}
|
||||
if err := dec.Decode(&m); err != nil {
|
||||
if err == io.EOF {
|
||||
break
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// force refresh images
|
||||
e.RefreshImages()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
@ -293,7 +293,7 @@ func TestCreateContainer(t *testing.T) {
|
|||
engine = NewEngine("test", 0, engOpts)
|
||||
client = mockclient.NewMockClient()
|
||||
apiClient = engineapimock.NewMockClient()
|
||||
readCloser = nopCloser{bytes.NewBufferString("ok")}
|
||||
readCloser = nopCloser{bytes.NewBufferString("")}
|
||||
)
|
||||
|
||||
engine.setState(stateUnhealthy)
|
||||
|
@ -346,7 +346,7 @@ func TestCreateContainer(t *testing.T) {
|
|||
id = "id3"
|
||||
apiClient.On("ImageList", mock.Anything, mock.AnythingOfType("ImageListOptions")).Return([]types.Image{}, nil).Once()
|
||||
mockConfig.CPUShares = int64(math.Ceil(float64(config.CPUShares*1024) / float64(mockInfo.NCPU)))
|
||||
apiClient.On("ImagePull", mock.Anything, types.ImagePullOptions{ImageID: config.Image}, mock.Anything).Return(readCloser, nil).Once()
|
||||
apiClient.On("ImagePull", mock.Anything, types.ImagePullOptions{ImageID: config.Image, Tag: "latest"}, mock.Anything).Return(readCloser, nil).Once()
|
||||
// FIXMEENGINEAPI : below should return an engine-api error, or something custom
|
||||
apiClient.On("ContainerCreate", mock.Anything, &mockConfig.Config, &mockConfig.HostConfig, &mockConfig.NetworkingConfig, name).Return(types.ContainerCreateResponse{}, dockerclient.ErrImageNotFound).Once()
|
||||
// FIXMEENGINEAPI : below should return an engine-api error, or something custom
|
||||
|
|
|
@ -14,6 +14,7 @@ import (
|
|||
log "github.com/Sirupsen/logrus"
|
||||
"github.com/docker/docker/pkg/discovery"
|
||||
"github.com/docker/docker/pkg/stringid"
|
||||
"github.com/docker/engine-api/client"
|
||||
"github.com/docker/engine-api/types"
|
||||
containertypes "github.com/docker/engine-api/types/container"
|
||||
networktypes "github.com/docker/engine-api/types/network"
|
||||
|
@ -148,8 +149,9 @@ func (c *Cluster) CreateContainer(config *cluster.ContainerConfig, name string,
|
|||
if err != nil {
|
||||
var retries int64
|
||||
// fails with image not found, then try to reschedule with image affinity
|
||||
// ENGINEAPIFIXME: The first error can be removed once dockerclient is removed
|
||||
bImageNotFoundError, _ := regexp.MatchString(`image \S* not found`, err.Error())
|
||||
if bImageNotFoundError && !config.HaveNodeConstraint() {
|
||||
if (bImageNotFoundError || client.IsErrImageNotFound(err)) && !config.HaveNodeConstraint() {
|
||||
// Check if the image exists in the cluster
|
||||
// If exists, retry with a image affinity
|
||||
if c.Image(config.Image) != nil {
|
||||
|
|
Loading…
Reference in New Issue