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,16 +191,53 @@ 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 )
202+
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+ //mode, err := getFileMode(filePath)
210+ //if err != nil {
211+ // return nil, fmt.Errorf("failed to determine mode for file %q for image: %w", filePath, err)
212+ //}
213+ if err := w .WriteHeader (& tar.Header {
214+ Name : f ,
215+ Mode : 0777 ,
216+ Size : int64 (len (fileBytes )),
217+ }); err != nil {
218+ return nil , err
219+ }
220+ log .Printf ("added file %s with mode %d" , filePath , 0777 )
221+
222+ if _ , err := w .Write (fileBytes ); err != nil {
223+ return nil , err
224+ }
225+ }
226+ if err := w .Close (); err != nil {
227+ return nil , err
228+ }
229+
230+ // Return a new copy of the buffer each time it's opened.
231+ layer , err := tarball .LayerFromOpener (func () (io.ReadCloser , error ) {
232+ return io .NopCloser (bytes .NewBuffer (b .Bytes ())), nil
233+ })
234+ if err != nil {
235+ return nil , fmt .Errorf ("failed to create image layer: %w" , err )
236+ }
154237
155- image , err := crane . Image ( fileMap )
238+ image , err := mutate . AppendLayers ( empty . Image , layer )
156239 if err != nil {
157- return nil , fmt .Errorf ("failed to generate image: %w" , err )
240+ return nil , fmt .Errorf ("failed to append layer to image: %w" , err )
158241 }
159242 imageMap [fmt .Sprintf ("%s:%s" , entry .Name (), tag .Name ())] = image
160243 }
@@ -180,3 +263,35 @@ func createFileMap(originPath string) (map[string][]byte, error) {
180263 }
181264 return fileMap , nil
182265}
266+
267+ func collectFiles (originPath string ) ([]string , error ) {
268+ var files []string
269+ if err := fs .WalkDir (os .DirFS (originPath ), "." , func (path string , d fs.DirEntry , err error ) error {
270+ if err != nil {
271+ return err
272+ }
273+ if d != nil && ! d .IsDir () {
274+ files = append (files , path )
275+ }
276+ return nil
277+ }); err != nil {
278+ return nil , err
279+ }
280+ return files , nil
281+ }
282+
283+ func getFileMode (path string ) (int64 , error ) {
284+ info , err := os .Stat (path )
285+ if err != nil {
286+ return 0 , err
287+ }
288+
289+ // return owner read/write by default
290+ var fileMode int64 = 0655
291+
292+ // or owner read/write/execute if the executable bit is set
293+ if info .Mode ()& 0111 != 0 {
294+ fileMode = 0755
295+ }
296+ return fileMode , nil
297+ }
0 commit comments