11package main
22
33import (
4+ "archive/tar"
5+ "bytes"
46 "flag"
57 "fmt"
8+ "github.com/google/go-containerregistry/pkg/v1/empty"
9+ "github.com/google/go-containerregistry/pkg/v1/tarball"
10+ "io"
611 "io/fs"
712 "log"
813 "os"
14+ "path/filepath"
15+ "sort"
916 "strings"
1017
1118 "github.com/google/go-containerregistry/pkg/crane"
12- v1 "github.com/google/go-containerregistry/pkg/v1"
19+ "github.com/google/go-containerregistry/pkg/v1"
1320 "github.com/google/go-containerregistry/pkg/v1/mutate"
1421 "github.com/spf13/pflag"
1522 "gopkg.in/yaml.v2"
1623)
1724
1825const (
19- bundlesSubPath string = "bundles"
20- catalogsSubPath string = "catalogs"
26+ controllersSubPath string = "controllers"
27+ bundlesSubPath string = "bundles"
28+ catalogsSubPath string = "catalogs"
2129)
2230
31+ type headerWithData struct {
32+ tar.Header
33+ Data []byte
34+ }
35+
2336func main () {
2437 var (
2538 registryAddr string
@@ -34,6 +47,7 @@ func main() {
3447
3548 bundlesFullPath := fmt .Sprintf ("%s/%s" , imagesPath , bundlesSubPath )
3649 catalogsFullPath := fmt .Sprintf ("%s/%s" , imagesPath , catalogsSubPath )
50+ controllersFullPath := fmt .Sprintf ("%s/%s" , imagesPath , controllersSubPath )
3751
3852 bundles , err := buildBundles (bundlesFullPath )
3953 if err != nil {
@@ -43,6 +57,10 @@ func main() {
4357 if err != nil {
4458 log .Fatalf ("failed to build catalogs: %s" , err .Error ())
4559 }
60+ controllers , err := buildControllers (controllersFullPath )
61+ if err != nil {
62+ log .Fatalf ("failed to build controllers: %s" , err .Error ())
63+ }
4664 // Push the images
4765 for name , image := range bundles {
4866 dest := fmt .Sprintf ("%s/%s" , registryAddr , name )
@@ -58,6 +76,13 @@ func main() {
5876 log .Fatalf ("failed to push catalog images: %s" , err .Error ())
5977 }
6078 }
79+ for name , image := range controllers {
80+ dest := fmt .Sprintf ("%s/%s" , registryAddr , name )
81+ log .Printf ("pushing controller %s to %s" , name , dest )
82+ if err := crane .Push (image , dest ); err != nil {
83+ log .Fatalf ("failed to push controller images: %s" , err .Error ())
84+ }
85+ }
6186 log .Printf ("finished" )
6287 os .Exit (0 )
6388}
@@ -122,6 +147,27 @@ func buildCatalogs(path string) (map[string]v1.Image, error) {
122147 return mutatedMap , nil
123148}
124149
150+ func buildControllers (path string ) (map [string ]v1.Image , error ) {
151+ controllers , err := processImageDirTree (path )
152+ if err != nil {
153+ return nil , err
154+ }
155+ mutatedMap := make (map [string ]v1.Image , 0 )
156+ // Apply required catalog label
157+ for key , img := range controllers {
158+ cfg := v1.Config {
159+ WorkingDir : "/" ,
160+ Entrypoint : []string {"/manager" },
161+ User : "65532:65532" ,
162+ }
163+ mutatedMap [fmt .Sprintf ("controllers/%s" , key )], err = mutate .Config (img , cfg )
164+ if err != nil {
165+ return nil , fmt .Errorf ("failed to apply image labels: %w" , err )
166+ }
167+ }
168+ return mutatedMap , nil
169+ }
170+
125171func processImageDirTree (path string ) (map [string ]v1.Image , error ) {
126172 imageMap := make (map [string ]v1.Image , 0 )
127173 images , err := os .ReadDir (path )
@@ -145,38 +191,66 @@ func processImageDirTree(path string) (map[string]v1.Image, error) {
145191 continue
146192 }
147193 tagFullPath := fmt .Sprintf ("%s/%s" , entryFullPath , tag .Name ())
194+ b := & bytes.Buffer {}
195+ w := tar .NewWriter (b )
148196
149- var fileMap map [string ][]byte
150- fileMap , err = createFileMap (tagFullPath )
197+ files , err := collectFiles (tagFullPath )
151198 if err != nil {
152199 return nil , fmt .Errorf ("failed to read files for image: %w" , err )
153200 }
201+ sort .Strings (files )
154202
155- image , err := crane .Image (fileMap )
203+ for _ , f := range files {
204+ filePath := filepath .Join (tagFullPath , f )
205+ fileBytes , err := os .ReadFile (filePath )
206+ if err != nil {
207+ return nil , fmt .Errorf ("failed to read file %q for image: %w" , filePath , err )
208+ }
209+ if err := w .WriteHeader (& tar.Header {
210+ Name : f ,
211+ Mode : 0755 ,
212+ Size : int64 (len (fileBytes )),
213+ }); err != nil {
214+ return nil , err
215+ }
216+ if _ , err := w .Write (fileBytes ); err != nil {
217+ return nil , err
218+ }
219+ }
220+ if err := w .Close (); err != nil {
221+ return nil , err
222+ }
223+
224+ // Return a new copy of the buffer each time it's opened.
225+ layer , err := tarball .LayerFromOpener (func () (io.ReadCloser , error ) {
226+ return io .NopCloser (bytes .NewBuffer (b .Bytes ())), nil
227+ })
156228 if err != nil {
157- return nil , fmt .Errorf ("failed to generate image: %w" , err )
229+ return nil , fmt .Errorf ("failed to create image layer: %w" , err )
230+ }
231+
232+ image , err := mutate .AppendLayers (empty .Image , layer )
233+ if err != nil {
234+ return nil , fmt .Errorf ("failed to append layer to image: %w" , err )
158235 }
159236 imageMap [fmt .Sprintf ("%s:%s" , entry .Name (), tag .Name ())] = image
160237 }
161238 }
162239 return imageMap , nil
163240}
164241
165- func createFileMap (originPath string ) (map [ string ][] byte , error ) {
166- fileMap := make ( map [ string ][] byte )
242+ func collectFiles (originPath string ) ([] string , error ) {
243+ var files [] string
167244 if err := fs .WalkDir (os .DirFS (originPath ), "." , func (path string , d fs.DirEntry , err error ) error {
168245 if err != nil {
169246 return err
170247 }
171248 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- }
249+ files = append (files , path )
176250 }
177251 return nil
178252 }); err != nil {
179253 return nil , err
180254 }
181- return fileMap , nil
255+ return files , nil
182256}
0 commit comments