MCPcopy Create free account
hub / github.com/containers/image / createNewLayer

Method createNewLayer

storage/storage_dest.go:1080–1284  ·  view source on GitHub ↗

createNewLayer creates a new layer newLayerID for (index, trusted) on top of parentLayer (which may be ""). If the layer cannot be committed yet, the function returns (nil, nil).

(index int, trusted trustedLayerIdentityData, parentLayer, newLayerID string)

Source from the content-addressed store, hash-verified

1078// createNewLayer creates a new layer newLayerID for (index, trusted) on top of parentLayer (which may be "").
1079// If the layer cannot be committed yet, the function returns (nil, nil).
1080func (s *storageImageDestination) createNewLayer(index int, trusted trustedLayerIdentityData, parentLayer, newLayerID string) (*storage.Layer, error) {
1081 s.lock.Lock()
1082 diffOutput, ok := s.lockProtected.diffOutputs[index]
1083 s.lock.Unlock()
1084 if ok {
1085 // Typically, we compute a trusted DiffID value to authenticate the layer contents, see the detailed explanation
1086 // in PutBlobPartial. If the user has opted out of that, but we know a trusted DiffID value
1087 // (e.g. from a BlobInfoCache), set it in diffOutput.
1088 // That way it will be persisted in storage even if the cache is deleted; also
1089 // we can use the value below to avoid the untrustedUncompressedDigest logic.
1090 if diffOutput.UncompressedDigest == "" && trusted.diffID != "" {
1091 diffOutput.UncompressedDigest = trusted.diffID
1092 }
1093
1094 var untrustedUncompressedDigest digest.Digest
1095 if diffOutput.UncompressedDigest == "" {
1096 d, err := s.untrustedLayerDiffID(index)
1097 if err != nil {
1098 var diffIDUnknownErr untrustedLayerDiffIDUnknownError
1099 switch {
1100 case errors.Is(err, errUntrustedLayerDiffIDNotYetAvailable):
1101 logrus.Debugf("Skipping commit for layer %q, manifest not yet available", newLayerID)
1102 return nil, nil
1103 case errors.As(err, &diffIDUnknownErr):
1104 // If untrustedLayerDiffIDUnknownError, the input image is schema1, has no TOC annotations,
1105 // so we should have !trusted.layerIdentifiedByTOC, i.e. we should have set
1106 // diffOutput.UncompressedDigest above in this function, at the very latest.
1107 //
1108 // Or, maybe, the input image is OCI, and has invalid/missing DiffID values in config. In that case
1109 // commitLayer should have already refused this image when dealing with the “view” ambiguity.
1110 return nil, fmt.Errorf("internal error: layer %d for blob %s was partially-pulled with unknown UncompressedDigest, but we don't have a DiffID in config",
1111 index, trusted.logString())
1112 default:
1113 return nil, err
1114 }
1115 }
1116
1117 untrustedUncompressedDigest = d
1118 // While the contents of the digest are untrusted, make sure at least the _format_ is valid,
1119 // because we are going to write it to durable storage in expectedLayerDiffIDFlag .
1120 if err := untrustedUncompressedDigest.Validate(); err != nil {
1121 return nil, err
1122 }
1123 }
1124
1125 flags := make(map[string]interface{})
1126 if untrustedUncompressedDigest != "" {
1127 flags[expectedLayerDiffIDFlag] = untrustedUncompressedDigest.String()
1128 logrus.Debugf("Setting uncompressed digest to %q for layer %q", untrustedUncompressedDigest, newLayerID)
1129 }
1130
1131 args := storage.ApplyStagedLayerOptions{
1132 ID: newLayerID,
1133 ParentLayer: parentLayer,
1134
1135 DiffOutput: diffOutput,
1136 DiffOptions: &graphdriver.ApplyDiffWithDifferOpts{
1137 Flags: flags,

Callers 1

commitLayerMethod · 0.95

Calls 6

untrustedLayerDiffIDMethod · 0.95
logStringMethod · 0.80
StringMethod · 0.65
CloseMethod · 0.65
OpenMethod · 0.65

Tested by

no test coverage detected