-
Notifications
You must be signed in to change notification settings - Fork 2
/
ocidist.go
76 lines (60 loc) · 2.03 KB
/
ocidist.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
package main
import (
"context"
"encoding/json"
"fmt"
"os"
"path/filepath"
"strings"
"github.com/opencontainers/umoci/oci/casext"
ispec "github.com/opencontainers/image-spec/specs-go/v1"
)
// some code borrowed from raharper/ocidist:
func getBlob(layer *ispec.Descriptor, layoutpath string) ([]byte, error) {
algo, digest, ok := strings.Cut(layer.Digest.String(), ":")
if !ok {
return []byte{}, fmt.Errorf("Failed to split layer digest '%s' into algo and hash", layer.Digest.Encoded())
}
blobPath := filepath.Join(layoutpath, "blobs", algo, digest)
blobBytes, err := os.ReadFile(blobPath)
if err != nil {
return []byte{}, fmt.Errorf("Failed to read OCI layer blob @ %q: %s", blobPath, err)
}
return blobBytes, nil
}
func getReferrersForImage(oci casext.Engine, layoutpath string, image *ispec.Descriptor) (*ispec.Index, error) {
ociIndex, err := oci.GetIndex(context.Background())
if err != nil {
return nil, fmt.Errorf("Failed to get index from OCI Layout: %s", err)
}
refs := ispec.Index{
MediaType: ispec.MediaTypeImageIndex,
}
for _, indexManifest := range ociIndex.Manifests {
if indexManifest.MediaType == ispec.MediaTypeImageManifest && indexManifest.Digest != image.Digest {
// get the blob @ manifest.Digest
// we can't use oci since it doesn't yet support "subject" descriptors
blob, err := getBlob(&indexManifest, layoutpath)
if err != nil {
return nil, fmt.Errorf("Failed to read index manifest blob: %s", err)
}
var refManifest ispec.Manifest
if err := json.Unmarshal(blob, &refManifest); err != nil {
return nil, fmt.Errorf("Failed to unmarshal index manifest blob into manifest: %s", err)
}
if refManifest.Subject == nil {
continue
}
if refManifest.Subject.Digest == image.Digest {
match := ispec.Descriptor{
ArtifactType: refManifest.ArtifactType,
MediaType: indexManifest.MediaType,
Digest: indexManifest.Digest,
Size: indexManifest.Size,
}
refs.Manifests = append(refs.Manifests, match)
}
}
}
return &refs, nil
}