Compare creates a diff between the given mounts and uploads the result to the content store.
(ctx context.Context, lower, upper []mount.Mount, opts ...diff.Opt)
| 57 | // Compare creates a diff between the given mounts and uploads the result |
| 58 | // to the content store. |
| 59 | func (s erofsDiff) Compare(ctx context.Context, lower, upper []mount.Mount, opts ...diff.Opt) (d ocispec.Descriptor, err error) { |
| 60 | layer, err := erofsutils.MountsToLayer(upper) |
| 61 | if err != nil { |
| 62 | return emptyDesc, fmt.Errorf("unsupported layer for erofsDiff Compare method: %w", err) |
| 63 | } |
| 64 | |
| 65 | var config diff.Config |
| 66 | for _, opt := range opts { |
| 67 | if err := opt(&config); err != nil { |
| 68 | return emptyDesc, err |
| 69 | } |
| 70 | } |
| 71 | if tm := epoch.FromContext(ctx); tm != nil && config.SourceDateEpoch == nil { |
| 72 | config.SourceDateEpoch = tm |
| 73 | } |
| 74 | |
| 75 | if config.MediaType == "" { |
| 76 | config.MediaType = ocispec.MediaTypeImageLayerGzip |
| 77 | } |
| 78 | |
| 79 | var compressionType compression.Compression |
| 80 | switch config.MediaType { |
| 81 | case ocispec.MediaTypeImageLayer: |
| 82 | compressionType = compression.Uncompressed |
| 83 | case ocispec.MediaTypeImageLayerGzip: |
| 84 | compressionType = compression.Gzip |
| 85 | case ocispec.MediaTypeImageLayerZstd: |
| 86 | compressionType = compression.Zstd |
| 87 | default: |
| 88 | return emptyDesc, fmt.Errorf("unsupported diff media type: %v: %w", config.MediaType, errdefs.ErrNotImplemented) |
| 89 | } |
| 90 | |
| 91 | var newReference bool |
| 92 | if config.Reference == "" { |
| 93 | newReference = true |
| 94 | config.Reference = uniqueRef() |
| 95 | } |
| 96 | |
| 97 | cw, err := s.store.Writer(ctx, |
| 98 | content.WithRef(config.Reference), |
| 99 | content.WithDescriptor(ocispec.Descriptor{ |
| 100 | MediaType: config.MediaType, // most contentstore implementations just ignore this |
| 101 | })) |
| 102 | if err != nil { |
| 103 | return emptyDesc, fmt.Errorf("failed to open writer: %w", err) |
| 104 | } |
| 105 | |
| 106 | // errOpen is set when an error occurs while the content writer has not been |
| 107 | // committed or closed yet to force a cleanup |
| 108 | var errOpen error |
| 109 | defer func() { |
| 110 | if errOpen != nil { |
| 111 | cw.Close() |
| 112 | if newReference { |
| 113 | if abortErr := s.store.Abort(ctx, config.Reference); abortErr != nil { |
| 114 | log.G(ctx).WithError(abortErr).WithField("ref", config.Reference).Warnf("failed to delete diff upload") |
| 115 | } |
| 116 | } |
nothing calls this directly
no test coverage detected