Skip to content

Commit 40d65ed

Browse files
author
Per Goncalves da Silva
committed
Add controller image build and publish support to test registry
Signed-off-by: Per Goncalves da Silva <pegoncal@redhat.com>
1 parent f94c7b0 commit 40d65ed

2 files changed

Lines changed: 89 additions & 14 deletions

File tree

testdata/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
push/bin
2+
images/controllers

testdata/push/push.go

Lines changed: 88 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,38 @@
11
package main
22

33
import (
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

1825
const (
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+
2336
func 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+
125171
func 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

Comments
 (0)