github.com/MOXA-ISD/edge-library-libcompose@v0.4.1-0.20200417083957-c90441e63650/docker/image/image.go (about) 1 package image 2 3 import ( 4 "encoding/base64" 5 "encoding/json" 6 "fmt" 7 "io" 8 "os" 9 10 "github.com/docker/distribution/reference" 11 "github.com/docker/docker/api/types" 12 "github.com/docker/docker/client" 13 "github.com/docker/docker/pkg/jsonmessage" 14 "github.com/docker/docker/pkg/term" 15 "github.com/docker/docker/registry" 16 "github.com/docker/libcompose/docker/auth" 17 "golang.org/x/net/context" 18 ) 19 20 // Exists return whether or not the service image already exists 21 func Exists(ctx context.Context, clt client.ImageAPIClient, image string) (bool, error) { 22 _, err := InspectImage(ctx, clt, image) 23 if err != nil { 24 if client.IsErrNotFound(err) { 25 return false, nil 26 } 27 return false, err 28 } 29 return true, nil 30 } 31 32 // InspectImage inspect the specified image (can be a name, an id or a digest) 33 // with the specified client. 34 func InspectImage(ctx context.Context, client client.ImageAPIClient, image string) (types.ImageInspect, error) { 35 imageInspect, _, err := client.ImageInspectWithRaw(ctx, image) 36 return imageInspect, err 37 } 38 39 // RemoveImage removes the specified image (can be a name, an id or a digest) 40 // from the daemon store with the specified client. 41 func RemoveImage(ctx context.Context, client client.ImageAPIClient, image string) error { 42 _, err := client.ImageRemove(ctx, image, types.ImageRemoveOptions{}) 43 return err 44 } 45 46 // PullImage pulls the specified image (can be a name, an id or a digest) 47 // to the daemon store with the specified client. 48 func PullImage(ctx context.Context, client client.ImageAPIClient, serviceName string, authLookup auth.Lookup, image string) error { 49 fmt.Fprintf(os.Stderr, "Pulling %s (%s)...\n", serviceName, image) 50 distributionRef, err := reference.ParseNormalizedNamed(image) 51 if err != nil { 52 return err 53 } 54 55 repoInfo, err := registry.ParseRepositoryInfo(distributionRef) 56 if err != nil { 57 return err 58 } 59 60 authConfig := authLookup.Lookup(repoInfo) 61 62 // Use ConfigFile.SaveToWriter to not re-define encodeAuthToBase64 63 encodedAuth, err := encodeAuthToBase64(authConfig) 64 if err != nil { 65 return err 66 } 67 68 options := types.ImagePullOptions{ 69 RegistryAuth: encodedAuth, 70 } 71 responseBody, err := client.ImagePull(ctx, distributionRef.String(), options) 72 if err != nil { 73 logrus.Errorf("Failed to pull image %s: %v", image, err) 74 return err 75 } 76 defer responseBody.Close() 77 78 var writeBuff io.Writer = os.Stderr 79 80 outFd, isTerminalOut := term.GetFdInfo(os.Stderr) 81 82 err = jsonmessage.DisplayJSONMessagesStream(responseBody, writeBuff, outFd, isTerminalOut, nil) 83 if err != nil { 84 if jerr, ok := err.(*jsonmessage.JSONError); ok { 85 // If no error code is set, default to 1 86 if jerr.Code == 0 { 87 jerr.Code = 1 88 } 89 fmt.Fprintf(os.Stderr, "%s", writeBuff) 90 return fmt.Errorf("Status: %s, Code: %d", jerr.Message, jerr.Code) 91 } 92 } 93 return err 94 } 95 96 // encodeAuthToBase64 serializes the auth configuration as JSON base64 payload 97 func encodeAuthToBase64(authConfig types.AuthConfig) (string, error) { 98 buf, err := json.Marshal(authConfig) 99 if err != nil { 100 return "", err 101 } 102 return base64.URLEncoding.EncodeToString(buf), nil 103 }