// PrepareForUpdate clears fields that are not allowed to be set by end users on update. // It extracts the latest info from the manifest and sets that on the object. It allows a user // to update the manifest so that it matches the digest (in case an older server stored a manifest // that was malformed, it can always be corrected). func (imageStrategy) PrepareForUpdate(obj, old runtime.Object) { newImage := obj.(*api.Image) oldImage := old.(*api.Image) // image metadata cannot be altered newImage.DockerImageReference = oldImage.DockerImageReference newImage.DockerImageMetadata = oldImage.DockerImageMetadata newImage.DockerImageMetadataVersion = oldImage.DockerImageMetadataVersion newImage.DockerImageLayers = oldImage.DockerImageLayers // allow an image update that results in the manifest matching the digest (the name) newManifest := newImage.DockerImageManifest newImage.DockerImageManifest = oldImage.DockerImageManifest if newManifest != oldImage.DockerImageManifest && len(newManifest) > 0 { ok, err := api.ManifestMatchesImage(oldImage, []byte(newManifest)) if err != nil { utilruntime.HandleError(fmt.Errorf("attempted to validate that a manifest change to %q matched the signature, but failed: %v", oldImage.Name, err)) } else if ok { newImage.DockerImageManifest = newManifest } } if err := api.ImageWithMetadata(newImage); err != nil { utilruntime.HandleError(fmt.Errorf("Unable to update image metadata for %q: %v", newImage.Name, err)) } }
// PrepareForUpdate clears fields that are not allowed to be set by end users on update. // It extracts the latest info from the manifest and sets that on the object. It allows a user // to update the manifest so that it matches the digest (in case an older server stored a manifest // that was malformed, it can always be corrected). func (s imageStrategy) PrepareForUpdate(ctx kapi.Context, obj, old runtime.Object) { newImage := obj.(*api.Image) oldImage := old.(*api.Image) // image metadata cannot be altered newImage.DockerImageMetadata = oldImage.DockerImageMetadata newImage.DockerImageMetadataVersion = oldImage.DockerImageMetadataVersion newImage.DockerImageLayers = oldImage.DockerImageLayers if oldImage.DockerImageSignatures != nil { newImage.DockerImageSignatures = nil for _, v := range oldImage.DockerImageSignatures { newImage.DockerImageSignatures = append(newImage.DockerImageSignatures, v) } } var err error // allow an image update that results in the manifest matching the digest (the name) if newImage.DockerImageManifest != oldImage.DockerImageManifest { ok := true if len(newImage.DockerImageManifest) > 0 { ok, err = api.ManifestMatchesImage(oldImage, []byte(newImage.DockerImageManifest)) if err != nil { utilruntime.HandleError(fmt.Errorf("attempted to validate that a manifest change to %q matched the signature, but failed: %v", oldImage.Name, err)) } } if !ok { newImage.DockerImageManifest = oldImage.DockerImageManifest } } if newImage.DockerImageConfig != oldImage.DockerImageConfig { ok := true if len(newImage.DockerImageConfig) > 0 { ok, err = api.ImageConfigMatchesImage(newImage, []byte(newImage.DockerImageConfig)) if err != nil { utilruntime.HandleError(fmt.Errorf("attempted to validate that a new config for %q mentioned in the manifest, but failed: %v", oldImage.Name, err)) } } if !ok { newImage.DockerImageConfig = oldImage.DockerImageConfig } } if err = api.ImageWithMetadata(newImage); err != nil { utilruntime.HandleError(fmt.Errorf("Unable to update image metadata for %q: %v", newImage.Name, err)) } // clear signature fields that will be later set by server once it's able to parse the content s.clearSignatureDetails(newImage) }