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  }