@@ -16,7 +16,9 @@ package puller
16
16
17
17
import (
18
18
"context"
19
+ "encoding/json"
19
20
"fmt"
21
+ "io"
20
22
21
23
v1 "github.com/opencontainers/image-spec/specs-go/v1"
22
24
"oras.land/oras-go/v2"
@@ -47,7 +49,7 @@ func NewPuller(client *auth.Client, tracker ProgressTracker) *Puller {
47
49
48
50
// Pull an artifact from a remote registry.
49
51
// Ref format follows: REGISTRY/REPO[:TAG|@DIGEST]. Ex. localhost:5000/hello:latest.
50
- func (p * Puller ) Pull (ctx context.Context , artifactType oci. ArtifactType , ref , destDir , os , arch string ) (* oci.RegistryResult , error ) {
52
+ func (p * Puller ) Pull (ctx context.Context , ref , destDir , os , arch string ) (* oci.RegistryResult , error ) {
51
53
fileStore := file .New (destDir )
52
54
53
55
repo , err := remote .NewRepository (ref )
@@ -56,14 +58,20 @@ func (p *Puller) Pull(ctx context.Context, artifactType oci.ArtifactType, ref, d
56
58
}
57
59
repo .Client = p .Client
58
60
61
+ // if no tag was specified, "latest" is used
62
+ if repo .Reference .Reference == "" {
63
+ ref += ":" + oci .DefaultTag
64
+ repo .Reference .Reference = oci .DefaultTag
65
+ }
66
+
59
67
refDesc , _ , err := repo .FetchReference (ctx , ref )
60
68
if err != nil {
61
69
return nil , err
62
70
}
63
71
64
72
copyOpts := oras.CopyOptions {}
65
73
copyOpts .Concurrency = 1
66
- if artifactType == oci . Plugin && refDesc .MediaType == v1 .MediaTypeImageIndex {
74
+ if refDesc .MediaType == v1 .MediaTypeImageIndex {
67
75
plt := & v1.Platform {
68
76
OS : os ,
69
77
Architecture : arch ,
@@ -83,7 +91,37 @@ func (p *Puller) Pull(ctx context.Context, artifactType oci.ArtifactType, ref, d
83
91
repo .Reference .Repository , repo .Reference .Reference , repo .Reference .Repository , err )
84
92
}
85
93
94
+ descReader , err := repo .Fetch (ctx , desc )
95
+ if err != nil {
96
+ return nil , fmt .Errorf ("unable to fetch descriptor with digest %q: %w" , desc .Digest , err )
97
+ }
98
+
99
+ var manifest v1.Manifest
100
+ descBytes , err := io .ReadAll (descReader )
101
+ if err != nil {
102
+ return nil , fmt .Errorf ("unable to read bytes from descriptor: %w" , err )
103
+ }
104
+
105
+ if err = json .Unmarshal (descBytes , & manifest ); err != nil {
106
+ return nil , fmt .Errorf ("unable to unmarshal manifest: %w" , err )
107
+ }
108
+
109
+ if len (manifest .Layers ) < 1 {
110
+ return nil , fmt .Errorf ("no layers in manifest" )
111
+ }
112
+
113
+ var artifactType oci.ArtifactType
114
+ switch manifest .Layers [0 ].MediaType {
115
+ case oci .FalcoPluginLayerMediaType :
116
+ artifactType = oci .Plugin
117
+ case oci .FalcoRulesfileLayerMediaType :
118
+ artifactType = oci .Rulesfile
119
+ default :
120
+ return nil , fmt .Errorf ("unknown media type: %q" , manifest .Layers [0 ].MediaType )
121
+ }
122
+
86
123
return & oci.RegistryResult {
87
124
Digest : string (desc .Digest ),
125
+ Type : artifactType ,
88
126
}, nil
89
127
}
0 commit comments