Apply applies the content associated with the provided digests onto the provided mounts. Archive content will be extracted and decompressed if necessary.
(ctx context.Context, desc ocispec.Descriptor, mounts []mount.Mount, opts ...diff.ApplyOpt)
| 92 | // provided mounts. Archive content will be extracted and decompressed if |
| 93 | // necessary. |
| 94 | func (s windowsDiff) Apply(ctx context.Context, desc ocispec.Descriptor, mounts []mount.Mount, opts ...diff.ApplyOpt) (d ocispec.Descriptor, err error) { |
| 95 | layerPath, parentLayerPaths, err := mountsToLayerAndParents(mounts) |
| 96 | if err != nil { |
| 97 | return emptyDesc, err |
| 98 | } |
| 99 | |
| 100 | // TODO darrenstahlmsft: When this is done isolated, we should disable these. |
| 101 | // it currently cannot be disabled, unless we add ref counting. Since this is |
| 102 | // temporary, leaving it enabled is OK for now. |
| 103 | // https://github.com/containerd/containerd/issues/1681 |
| 104 | if err := winio.EnableProcessPrivileges([]string{winio.SeBackupPrivilege, winio.SeRestorePrivilege}); err != nil { |
| 105 | return emptyDesc, err |
| 106 | } |
| 107 | |
| 108 | t1 := time.Now() |
| 109 | defer func() { |
| 110 | if err == nil { |
| 111 | log.G(ctx).WithFields(log.Fields{ |
| 112 | "d": time.Since(t1), |
| 113 | "digest": desc.Digest, |
| 114 | "size": desc.Size, |
| 115 | "media": desc.MediaType, |
| 116 | }).Debug("diff applied") |
| 117 | } |
| 118 | }() |
| 119 | |
| 120 | var config diff.ApplyConfig |
| 121 | for _, o := range opts { |
| 122 | if err := o(ctx, desc, &config); err != nil { |
| 123 | return emptyDesc, fmt.Errorf("failed to apply config opt: %w", err) |
| 124 | } |
| 125 | } |
| 126 | |
| 127 | ra, err := s.store.ReaderAt(ctx, desc) |
| 128 | if err != nil { |
| 129 | return emptyDesc, fmt.Errorf("failed to get reader from content store: %w", err) |
| 130 | } |
| 131 | defer ra.Close() |
| 132 | |
| 133 | processor := diff.NewProcessorChain(desc.MediaType, content.NewReader(ra)) |
| 134 | for { |
| 135 | if processor, err = diff.GetProcessor(ctx, processor, config.ProcessorPayloads); err != nil { |
| 136 | return emptyDesc, fmt.Errorf("failed to get stream processor for %s: %w", desc.MediaType, err) |
| 137 | } |
| 138 | if processor.MediaType() == ocispec.MediaTypeImageLayer { |
| 139 | break |
| 140 | } |
| 141 | } |
| 142 | defer processor.Close() |
| 143 | |
| 144 | digester := digest.Canonical.Digester() |
| 145 | rc := &readCounter{ |
| 146 | r: io.TeeReader(processor, digester.Hash()), |
| 147 | } |
| 148 | |
| 149 | archiveOpts := []archive.ApplyOpt{ |
| 150 | archive.WithParents(parentLayerPaths), |
| 151 | archive.WithNoSameOwner(), // Lchown is not supported on Windows |
nothing calls this directly
no test coverage detected