Unpack wraps an image handler to filter out blob handling and scheduling them during the unpack process. When an image config is encountered, the unpack process will be started in a goroutine.
(h images.Handler)
| 194 | // during the unpack process. When an image config is encountered, the unpack |
| 195 | // process will be started in a goroutine. |
| 196 | func (u *Unpacker) Unpack(h images.Handler) images.Handler { |
| 197 | var ( |
| 198 | lock sync.Mutex |
| 199 | layers = map[digest.Digest][]ocispec.Descriptor{} |
| 200 | ) |
| 201 | |
| 202 | var layerTypes map[string]bool |
| 203 | var configTypes map[string]bool |
| 204 | for _, p := range u.platforms { |
| 205 | if p.ConfigType != "" { |
| 206 | if configTypes == nil { |
| 207 | configTypes = make(map[string]bool) |
| 208 | } |
| 209 | configTypes[p.ConfigType] = true |
| 210 | } |
| 211 | if len(p.LayerTypes) > 0 { |
| 212 | if layerTypes == nil { |
| 213 | layerTypes = make(map[string]bool) |
| 214 | } |
| 215 | for _, t := range p.LayerTypes { |
| 216 | layerTypes[t] = true |
| 217 | } |
| 218 | } |
| 219 | } |
| 220 | |
| 221 | return images.HandlerFunc(func(ctx context.Context, desc ocispec.Descriptor) ([]ocispec.Descriptor, error) { |
| 222 | ctx, span := tracing.StartSpan(ctx, tracing.Name(unpackSpanPrefix, "UnpackHandler")) |
| 223 | defer span.End() |
| 224 | span.SetAttributes( |
| 225 | tracing.Attribute("descriptor.media.type", desc.MediaType), |
| 226 | tracing.Attribute("descriptor.digest", desc.Digest.String())) |
| 227 | unlock, err := u.lockBlobDescriptor(ctx, desc) |
| 228 | if err != nil { |
| 229 | return nil, err |
| 230 | } |
| 231 | children, err := h.Handle(ctx, desc) |
| 232 | unlock() |
| 233 | if err != nil { |
| 234 | return children, err |
| 235 | } |
| 236 | |
| 237 | if images.IsManifestType(desc.MediaType) { |
| 238 | var nonLayers []ocispec.Descriptor |
| 239 | var manifestLayers []ocispec.Descriptor |
| 240 | // Split layers from non-layers, layers will be handled after |
| 241 | // the config |
| 242 | for i, child := range children { |
| 243 | span.SetAttributes( |
| 244 | tracing.Attribute("descriptor.child."+strconv.Itoa(i), []string{child.MediaType, child.Digest.String()}), |
| 245 | ) |
| 246 | if images.IsLayerType(child.MediaType) || layerTypes[child.MediaType] { |
| 247 | manifestLayers = append(manifestLayers, child) |
| 248 | } else { |
| 249 | nonLayers = append(nonLayers, child) |
| 250 | } |
| 251 | } |
| 252 | |
| 253 | lock.Lock() |
no test coverage detected