image.go 4.6 KB

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