github.com/toplink-cn/moby@v0.0.0-20240305205811-460b4aebdf81/image/v1/imagev1.go (about) 1 package v1 // import "github.com/docker/docker/image/v1" 2 3 import ( 4 "context" 5 "encoding/json" 6 "strings" 7 8 "github.com/containerd/log" 9 "github.com/docker/docker/api/types/versions" 10 "github.com/docker/docker/image" 11 "github.com/docker/docker/layer" 12 "github.com/docker/docker/pkg/stringid" 13 "github.com/opencontainers/go-digest" 14 ) 15 16 // noFallbackMinVersion is the minimum version for which v1compatibility 17 // information will not be marshaled through the Image struct to remove 18 // blank fields. 19 const noFallbackMinVersion = "1.8.3" 20 21 // HistoryFromConfig creates a History struct from v1 configuration JSON 22 func HistoryFromConfig(imageJSON []byte, emptyLayer bool) (image.History, error) { 23 h := image.History{} 24 var v1Image image.V1Image 25 if err := json.Unmarshal(imageJSON, &v1Image); err != nil { 26 return h, err 27 } 28 29 return image.History{ 30 Author: v1Image.Author, 31 Created: v1Image.Created, 32 CreatedBy: strings.Join(v1Image.ContainerConfig.Cmd, " "), 33 Comment: v1Image.Comment, 34 EmptyLayer: emptyLayer, 35 }, nil 36 } 37 38 // CreateID creates an ID from v1 image, layerID and parent ID. 39 // Used for backwards compatibility with old clients. 40 func CreateID(v1Image image.V1Image, layerID layer.ChainID, parent digest.Digest) (digest.Digest, error) { 41 v1Image.ID = "" 42 v1JSON, err := json.Marshal(v1Image) 43 if err != nil { 44 return "", err 45 } 46 47 var config map[string]*json.RawMessage 48 if err := json.Unmarshal(v1JSON, &config); err != nil { 49 return "", err 50 } 51 52 // FIXME: note that this is slightly incompatible with RootFS logic 53 config["layer_id"] = rawJSON(layerID) 54 if parent != "" { 55 config["parent"] = rawJSON(parent) 56 } 57 58 configJSON, err := json.Marshal(config) 59 if err != nil { 60 return "", err 61 } 62 log.G(context.TODO()).Debugf("CreateV1ID %s", configJSON) 63 64 return digest.FromBytes(configJSON), nil 65 } 66 67 // MakeConfigFromV1Config creates an image config from the legacy V1 config format. 68 func MakeConfigFromV1Config(imageJSON []byte, rootfs *image.RootFS, history []image.History) ([]byte, error) { 69 var dver struct { 70 DockerVersion string `json:"docker_version"` 71 } 72 73 if err := json.Unmarshal(imageJSON, &dver); err != nil { 74 return nil, err 75 } 76 77 useFallback := versions.LessThan(dver.DockerVersion, noFallbackMinVersion) 78 79 if useFallback { 80 var v1Image image.V1Image 81 err := json.Unmarshal(imageJSON, &v1Image) 82 if err != nil { 83 return nil, err 84 } 85 imageJSON, err = json.Marshal(v1Image) 86 if err != nil { 87 return nil, err 88 } 89 } 90 91 var c map[string]*json.RawMessage 92 if err := json.Unmarshal(imageJSON, &c); err != nil { 93 return nil, err 94 } 95 96 delete(c, "id") 97 delete(c, "parent") 98 delete(c, "Size") // Size is calculated from data on disk and is inconsistent 99 delete(c, "parent_id") 100 delete(c, "layer_id") 101 delete(c, "throwaway") 102 103 c["rootfs"] = rawJSON(rootfs) 104 c["history"] = rawJSON(history) 105 106 return json.Marshal(c) 107 } 108 109 func rawJSON(value interface{}) *json.RawMessage { 110 jsonval, err := json.Marshal(value) 111 if err != nil { 112 return nil 113 } 114 return (*json.RawMessage)(&jsonval) 115 } 116 117 // ValidateID checks whether an ID string is a valid image ID. 118 func ValidateID(id string) error { 119 return stringid.ValidateID(id) 120 }