github.com/flavio/docker@v0.1.3-0.20170117145210-f63d1a6eec47/image/image.go (about)

     1  package image
     2  
     3  import (
     4  	"encoding/json"
     5  	"errors"
     6  	"io"
     7  	"time"
     8  
     9  	"github.com/docker/docker/api/types/container"
    10  	"github.com/opencontainers/go-digest"
    11  )
    12  
    13  // ID is the content-addressable ID of an image.
    14  type ID digest.Digest
    15  
    16  func (id ID) String() string {
    17  	return id.Digest().String()
    18  }
    19  
    20  // Digest converts ID into a digest
    21  func (id ID) Digest() digest.Digest {
    22  	return digest.Digest(id)
    23  }
    24  
    25  // IDFromDigest creates an ID from a digest
    26  func IDFromDigest(digest digest.Digest) ID {
    27  	return ID(digest)
    28  }
    29  
    30  // V1Image stores the V1 image configuration.
    31  type V1Image struct {
    32  	// ID is a unique 64 character identifier of the image
    33  	ID string `json:"id,omitempty"`
    34  	// Parent is the ID of the parent image
    35  	Parent string `json:"parent,omitempty"`
    36  	// Comment is the commit message that was set when committing the image
    37  	Comment string `json:"comment,omitempty"`
    38  	// Created is the timestamp at which the image was created
    39  	Created time.Time `json:"created"`
    40  	// Container is the id of the container used to commit
    41  	Container string `json:"container,omitempty"`
    42  	// ContainerConfig is the configuration of the container that is committed into the image
    43  	ContainerConfig container.Config `json:"container_config,omitempty"`
    44  	// DockerVersion specifies the version of Docker that was used to build the image
    45  	DockerVersion string `json:"docker_version,omitempty"`
    46  	// Author is the name of the author that was specified when committing the image
    47  	Author string `json:"author,omitempty"`
    48  	// Config is the configuration of the container received from the client
    49  	Config *container.Config `json:"config,omitempty"`
    50  	// Architecture is the hardware that the image is build and runs on
    51  	Architecture string `json:"architecture,omitempty"`
    52  	// OS is the operating system used to build and run the image
    53  	OS string `json:"os,omitempty"`
    54  	// Size is the total size of the image including all layers it is composed of
    55  	Size int64 `json:",omitempty"`
    56  }
    57  
    58  // Image stores the image configuration
    59  type Image struct {
    60  	V1Image
    61  	Parent     ID        `json:"parent,omitempty"`
    62  	RootFS     *RootFS   `json:"rootfs,omitempty"`
    63  	History    []History `json:"history,omitempty"`
    64  	OSVersion  string    `json:"os.version,omitempty"`
    65  	OSFeatures []string  `json:"os.features,omitempty"`
    66  
    67  	// rawJSON caches the immutable JSON associated with this image.
    68  	rawJSON []byte
    69  
    70  	// computedID is the ID computed from the hash of the image config.
    71  	// Not to be confused with the legacy V1 ID in V1Image.
    72  	computedID ID
    73  }
    74  
    75  // RawJSON returns the immutable JSON associated with the image.
    76  func (img *Image) RawJSON() []byte {
    77  	return img.rawJSON
    78  }
    79  
    80  // ID returns the image's content-addressable ID.
    81  func (img *Image) ID() ID {
    82  	return img.computedID
    83  }
    84  
    85  // ImageID stringifies ID.
    86  func (img *Image) ImageID() string {
    87  	return img.ID().String()
    88  }
    89  
    90  // RunConfig returns the image's container config.
    91  func (img *Image) RunConfig() *container.Config {
    92  	return img.Config
    93  }
    94  
    95  // MarshalJSON serializes the image to JSON. It sorts the top-level keys so
    96  // that JSON that's been manipulated by a push/pull cycle with a legacy
    97  // registry won't end up with a different key order.
    98  func (img *Image) MarshalJSON() ([]byte, error) {
    99  	type MarshalImage Image
   100  
   101  	pass1, err := json.Marshal(MarshalImage(*img))
   102  	if err != nil {
   103  		return nil, err
   104  	}
   105  
   106  	var c map[string]*json.RawMessage
   107  	if err := json.Unmarshal(pass1, &c); err != nil {
   108  		return nil, err
   109  	}
   110  	return json.Marshal(c)
   111  }
   112  
   113  // History stores build commands that were used to create an image
   114  type History struct {
   115  	// Created is the timestamp at which the image was created
   116  	Created time.Time `json:"created"`
   117  	// Author is the name of the author that was specified when committing the image
   118  	Author string `json:"author,omitempty"`
   119  	// CreatedBy keeps the Dockerfile command used while building the image
   120  	CreatedBy string `json:"created_by,omitempty"`
   121  	// Comment is the commit message that was set when committing the image
   122  	Comment string `json:"comment,omitempty"`
   123  	// EmptyLayer is set to true if this history item did not generate a
   124  	// layer. Otherwise, the history item is associated with the next
   125  	// layer in the RootFS section.
   126  	EmptyLayer bool `json:"empty_layer,omitempty"`
   127  }
   128  
   129  // Exporter provides interface for loading and saving images
   130  type Exporter interface {
   131  	Load(io.ReadCloser, io.Writer, bool) error
   132  	// TODO: Load(net.Context, io.ReadCloser, <- chan StatusMessage) error
   133  	Save([]string, io.Writer) error
   134  }
   135  
   136  // NewFromJSON creates an Image configuration from json.
   137  func NewFromJSON(src []byte) (*Image, error) {
   138  	img := &Image{}
   139  
   140  	if err := json.Unmarshal(src, img); err != nil {
   141  		return nil, err
   142  	}
   143  	if img.RootFS == nil {
   144  		return nil, errors.New("invalid image JSON, no RootFS key")
   145  	}
   146  
   147  	img.rawJSON = src
   148  
   149  	return img, nil
   150  }