github.com/Heebron/moby@v0.0.0-20221111184709-6eab4f55faf7/image/v1/imagev1.go (about)

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