8
8
"io"
9
9
"os"
10
10
"os/signal"
11
+ "sync"
11
12
12
13
"github.com/docker-library/meta-scripts/registry"
13
14
)
@@ -22,6 +23,16 @@ func main() {
22
23
)
23
24
24
25
args := os .Args [1 :]
26
+
27
+ var (
28
+ parallel = false
29
+ wg sync.WaitGroup
30
+ )
31
+ if len (args ) > 0 && args [0 ] == "--parallel" {
32
+ args = args [1 :]
33
+ parallel = true
34
+ }
35
+
25
36
for len (args ) > 0 {
26
37
img := args [0 ]
27
38
args = args [1 :]
@@ -35,53 +46,66 @@ func main() {
35
46
continue
36
47
}
37
48
38
- ref , err := registry .ParseRef (img )
39
- if err != nil {
40
- panic (err )
41
- }
42
-
43
- var obj any
44
- if opts == zeroOpts {
45
- // if we have no explicit type and didn't request a HEAD, invoke SynthesizeIndex instead of Lookup
46
- obj , err = registry .SynthesizeIndex (ctx , ref )
47
- if err != nil {
48
- panic (err )
49
- }
50
- } else {
51
- r , err := registry .Lookup (ctx , ref , & opts )
49
+ do := func (opts registry.LookupOptions ) {
50
+ ref , err := registry .ParseRef (img )
52
51
if err != nil {
53
52
panic (err )
54
53
}
55
- if r != nil {
56
- desc := r .Descriptor ()
57
- if opts .Head {
58
- obj = desc
59
- } else {
60
- b , err := io .ReadAll (r )
61
- if err != nil {
62
- r .Close ()
63
- panic (err )
64
- }
65
- if opts .Type == registry .LookupTypeManifest {
66
- // if it was a manifest lookup, cast the byte slice to json.RawMessage so we get the actual JSON (not base64)
67
- obj = json .RawMessage (b )
68
- } else {
69
- obj = b
70
- }
71
- }
72
- err = r .Close ()
54
+
55
+ var obj any
56
+ if opts == zeroOpts {
57
+ // if we have no explicit type and didn't request a HEAD, invoke SynthesizeIndex instead of Lookup
58
+ obj , err = registry .SynthesizeIndex (ctx , ref )
73
59
if err != nil {
74
60
panic (err )
75
61
}
76
62
} else {
77
- obj = nil
63
+ r , err := registry .Lookup (ctx , ref , & opts )
64
+ if err != nil {
65
+ panic (err )
66
+ }
67
+ if r != nil {
68
+ desc := r .Descriptor ()
69
+ if opts .Head {
70
+ obj = desc
71
+ } else {
72
+ b , err := io .ReadAll (r )
73
+ if err != nil {
74
+ r .Close ()
75
+ panic (err )
76
+ }
77
+ if opts .Type == registry .LookupTypeManifest {
78
+ // if it was a manifest lookup, cast the byte slice to json.RawMessage so we get the actual JSON (not base64)
79
+ obj = json .RawMessage (b )
80
+ } else {
81
+ obj = b
82
+ }
83
+ }
84
+ err = r .Close ()
85
+ if err != nil {
86
+ panic (err )
87
+ }
88
+ } else {
89
+ obj = nil
90
+ }
91
+ }
92
+
93
+ e := json .NewEncoder (os .Stdout )
94
+ e .SetIndent ("" , "\t " )
95
+ if err := e .Encode (obj ); err != nil {
96
+ panic (err )
78
97
}
79
98
}
80
99
81
- e := json .NewEncoder (os .Stdout )
82
- e .SetIndent ("" , "\t " )
83
- if err := e .Encode (obj ); err != nil {
84
- panic (err )
100
+ if parallel {
101
+ wg .Add (1 )
102
+ go func (opts registry.LookupOptions ) {
103
+ defer wg .Done ()
104
+ // TODO synchronize output so that it still arrives in-order? maybe the randomness is part of the charm?
105
+ do (opts )
106
+ }(opts )
107
+ } else {
108
+ do (opts )
85
109
}
86
110
87
111
// reset state
@@ -91,4 +115,8 @@ func main() {
91
115
if opts != zeroOpts {
92
116
panic ("dangling --type, --head, etc (without a following reference for it to apply to)" )
93
117
}
118
+
119
+ if parallel {
120
+ wg .Wait ()
121
+ }
94
122
}
0 commit comments