1
1
package main
2
2
3
3
import (
4
+ "archive/tar"
5
+ "bytes"
4
6
"flag"
5
7
"fmt"
8
+ "github.com/google/go-containerregistry/pkg/v1/empty"
9
+ "github.com/google/go-containerregistry/pkg/v1/tarball"
10
+ "io"
6
11
"io/fs"
7
12
"log"
8
13
"os"
14
+ "path/filepath"
15
+ "sort"
9
16
"strings"
10
17
11
18
"github.com/google/go-containerregistry/pkg/crane"
12
- v1 "github.com/google/go-containerregistry/pkg/v1"
19
+ "github.com/google/go-containerregistry/pkg/v1"
13
20
"github.com/google/go-containerregistry/pkg/v1/mutate"
14
21
"github.com/spf13/pflag"
15
22
"gopkg.in/yaml.v2"
16
23
)
17
24
18
25
const (
19
- bundlesSubPath string = "bundles"
20
- catalogsSubPath string = "catalogs"
26
+ controllersSubPath string = "controllers"
27
+ bundlesSubPath string = "bundles"
28
+ catalogsSubPath string = "catalogs"
21
29
)
22
30
23
31
func main () {
@@ -34,6 +42,7 @@ func main() {
34
42
35
43
bundlesFullPath := fmt .Sprintf ("%s/%s" , imagesPath , bundlesSubPath )
36
44
catalogsFullPath := fmt .Sprintf ("%s/%s" , imagesPath , catalogsSubPath )
45
+ controllersFullPath := fmt .Sprintf ("%s/%s" , imagesPath , controllersSubPath )
37
46
38
47
bundles , err := buildBundles (bundlesFullPath )
39
48
if err != nil {
@@ -43,6 +52,10 @@ func main() {
43
52
if err != nil {
44
53
log .Fatalf ("failed to build catalogs: %s" , err .Error ())
45
54
}
55
+ controllers , err := buildControllers (controllersFullPath )
56
+ if err != nil {
57
+ log .Fatalf ("failed to build controllers: %s" , err .Error ())
58
+ }
46
59
// Push the images
47
60
for name , image := range bundles {
48
61
dest := fmt .Sprintf ("%s/%s" , registryAddr , name )
@@ -58,6 +71,13 @@ func main() {
58
71
log .Fatalf ("failed to push catalog images: %s" , err .Error ())
59
72
}
60
73
}
74
+ for name , image := range controllers {
75
+ dest := fmt .Sprintf ("%s/%s" , registryAddr , name )
76
+ log .Printf ("pushing controller %s to %s" , name , dest )
77
+ if err := crane .Push (image , dest ); err != nil {
78
+ log .Fatalf ("failed to push controller images: %s" , err .Error ())
79
+ }
80
+ }
61
81
log .Printf ("finished" )
62
82
os .Exit (0 )
63
83
}
@@ -122,6 +142,27 @@ func buildCatalogs(path string) (map[string]v1.Image, error) {
122
142
return mutatedMap , nil
123
143
}
124
144
145
+ func buildControllers (path string ) (map [string ]v1.Image , error ) {
146
+ controllers , err := processImageDirTree (path )
147
+ if err != nil {
148
+ return nil , err
149
+ }
150
+ mutatedMap := make (map [string ]v1.Image , 0 )
151
+ // Apply required catalog label
152
+ for key , img := range controllers {
153
+ cfg := v1.Config {
154
+ WorkingDir : "/" ,
155
+ Entrypoint : []string {"/manager" },
156
+ User : "65532:65532" ,
157
+ }
158
+ mutatedMap [fmt .Sprintf ("controllers/%s" , key )], err = mutate .Config (img , cfg )
159
+ if err != nil {
160
+ return nil , fmt .Errorf ("failed to apply image labels: %w" , err )
161
+ }
162
+ }
163
+ return mutatedMap , nil
164
+ }
165
+
125
166
func processImageDirTree (path string ) (map [string ]v1.Image , error ) {
126
167
imageMap := make (map [string ]v1.Image , 0 )
127
168
images , err := os .ReadDir (path )
@@ -145,38 +186,66 @@ func processImageDirTree(path string) (map[string]v1.Image, error) {
145
186
continue
146
187
}
147
188
tagFullPath := fmt .Sprintf ("%s/%s" , entryFullPath , tag .Name ())
189
+ b := & bytes.Buffer {}
190
+ w := tar .NewWriter (b )
148
191
149
- var fileMap map [string ][]byte
150
- fileMap , err = createFileMap (tagFullPath )
192
+ files , err := collectFiles (tagFullPath )
151
193
if err != nil {
152
194
return nil , fmt .Errorf ("failed to read files for image: %w" , err )
153
195
}
196
+ sort .Strings (files )
197
+
198
+ for _ , f := range files {
199
+ filePath := filepath .Join (tagFullPath , f )
200
+ fileBytes , err := os .ReadFile (filePath )
201
+ if err != nil {
202
+ return nil , fmt .Errorf ("failed to read file %q for image: %w" , filePath , err )
203
+ }
204
+ if err := w .WriteHeader (& tar.Header {
205
+ Name : f ,
206
+ Mode : 0755 ,
207
+ Size : int64 (len (fileBytes )),
208
+ }); err != nil {
209
+ return nil , err
210
+ }
211
+ if _ , err := w .Write (fileBytes ); err != nil {
212
+ return nil , err
213
+ }
214
+ }
215
+ if err := w .Close (); err != nil {
216
+ return nil , err
217
+ }
218
+
219
+ // Return a new copy of the buffer each time it's opened.
220
+ layer , err := tarball .LayerFromOpener (func () (io.ReadCloser , error ) {
221
+ return io .NopCloser (bytes .NewBuffer (b .Bytes ())), nil
222
+ })
223
+ if err != nil {
224
+ return nil , fmt .Errorf ("failed to create image layer: %w" , err )
225
+ }
154
226
155
- image , err := crane . Image ( fileMap )
227
+ image , err := mutate . AppendLayers ( empty . Image , layer )
156
228
if err != nil {
157
- return nil , fmt .Errorf ("failed to generate image: %w" , err )
229
+ return nil , fmt .Errorf ("failed to append layer to image: %w" , err )
158
230
}
159
231
imageMap [fmt .Sprintf ("%s:%s" , entry .Name (), tag .Name ())] = image
160
232
}
161
233
}
162
234
return imageMap , nil
163
235
}
164
236
165
- func createFileMap (originPath string ) (map [ string ][] byte , error ) {
166
- fileMap := make ( map [ string ][] byte )
237
+ func collectFiles (originPath string ) ([] string , error ) {
238
+ var files [] string
167
239
if err := fs .WalkDir (os .DirFS (originPath ), "." , func (path string , d fs.DirEntry , err error ) error {
168
240
if err != nil {
169
241
return err
170
242
}
171
243
if d != nil && ! d .IsDir () {
172
- fileMap [path ], err = os .ReadFile (fmt .Sprintf ("%s/%s" , originPath , path ))
173
- if err != nil {
174
- return err
175
- }
244
+ files = append (files , path )
176
245
}
177
246
return nil
178
247
}); err != nil {
179
248
return nil , err
180
249
}
181
- return fileMap , nil
250
+ return files , nil
182
251
}
0 commit comments