Skip to content

Commit f6fa43f

Browse files
committedNov 22, 2019
fix(appr): use given cache dir for image builds
1 parent 768dcf1 commit f6fa43f

File tree

6 files changed

+409
-16
lines changed

6 files changed

+409
-16
lines changed
 

‎pkg/apprclient/apprclientfakes/fake_client.go

+273
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎pkg/apprclient/client.go

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
//go:generate go run github.com/maxbrunsfeld/counterfeiter/v6 . Client
12
package apprclient
23

34
import (

‎pkg/appregistry/builder.go

+4-10
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
//go:generate go run github.com/maxbrunsfeld/counterfeiter/v6 builder.go ImageAppender
12
package appregistry
23

34
import (
@@ -46,6 +47,7 @@ type AppregistryImageBuilder struct {
4647
CleanOutput bool
4748
ManifestDir string
4849
DatabaseDir string
50+
client apprclient.Client
4951
}
5052

5153
func NewAppregistryImageBuilder(options ...AppregistryBuildOption) (*AppregistryImageBuilder, error) {
@@ -69,14 +71,11 @@ func NewAppregistryImageBuilder(options ...AppregistryBuildOption) (*Appregistry
6971
CleanOutput: config.CleanOutput,
7072
ManifestDir: config.ManifestDir,
7173
DatabaseDir: config.DatabaseDir,
74+
client: config.Client,
7275
}, nil
7376
}
7477

7578
func (b *AppregistryImageBuilder) Build() error {
76-
opts := apprclient.Options{Source: b.AppRegistryEndpoint}
77-
if b.AuthToken != "" {
78-
opts.AuthToken = b.AuthToken
79-
}
8079

8180
defer func() {
8281
if !b.CleanOutput {
@@ -87,12 +86,7 @@ func (b *AppregistryImageBuilder) Build() error {
8786
}
8887
}()
8988

90-
client, err := apprclient.New(opts)
91-
if err != nil {
92-
return err
93-
}
94-
95-
downloader := NewManifestDownloader(client)
89+
downloader := NewManifestDownloader(b.client)
9690
if err := downloader.DownloadManifests(b.ManifestDir, b.AppRegistryOrg); err != nil {
9791
return err
9892
}

‎pkg/appregistry/builder_options.go

+49-6
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,10 @@ package appregistry
33
import (
44
"fmt"
55
"io/ioutil"
6+
"os"
67
"path"
8+
9+
"github.com/operator-framework/operator-registry/pkg/apprclient"
710
)
811

912
type AppregistryBuildOptions struct {
@@ -20,6 +23,8 @@ type AppregistryBuildOptions struct {
2023
CleanOutput bool
2124
ManifestDir string
2225
DatabaseDir string
26+
27+
Client apprclient.Client
2328
}
2429

2530
func (o *AppregistryBuildOptions) Validate() error {
@@ -46,18 +51,31 @@ func (o *AppregistryBuildOptions) Validate() error {
4651
if o.DatabaseDir == "" {
4752
return fmt.Errorf("local database directory required")
4853
}
54+
if o.Client == nil {
55+
return fmt.Errorf("app-registry client must not be nil")
56+
}
4957

5058
return nil
5159
}
5260

5361
func (o *AppregistryBuildOptions) Complete() error {
54-
// if a user has specified a specific cache dir, don't clean it after run
55-
o.CleanOutput = o.CacheDir == ""
62+
// if a user hasn't specified a specific cache directory, generate a temporary one
63+
if o.CacheDir == "" {
64+
tmp, err := ioutil.TempDir("", "cache-")
65+
if err != nil {
66+
return err
67+
}
68+
o.CacheDir = tmp
5669

57-
// build a separate path for manifests and the built database, so that
58-
// building is idempotent
70+
// clean up temporary directories
71+
o.CleanOutput = true
72+
} else if err := os.MkdirAll(o.CacheDir, os.ModePerm); err != nil && !os.IsExist(err) {
73+
return err
74+
}
75+
76+
// build a separate path for manifests and the built database, so that building is idempotent
5977
if o.ManifestDir == "" {
60-
manifestDir, err := ioutil.TempDir("", "manifests-")
78+
manifestDir, err := ioutil.TempDir(o.CacheDir, "manifests-")
6179
if err != nil {
6280
return err
6381
}
@@ -75,6 +93,22 @@ func (o *AppregistryBuildOptions) Complete() error {
7593
if o.DatabasePath == "" {
7694
o.DatabasePath = path.Join(o.DatabaseDir, "bundles.db")
7795
}
96+
97+
// create the client
98+
if o.Client == nil {
99+
opts := apprclient.Options{Source: o.AppRegistryEndpoint}
100+
if o.AuthToken != "" {
101+
opts.AuthToken = o.AuthToken
102+
}
103+
104+
client, err := apprclient.New(opts)
105+
if err != nil {
106+
return err
107+
}
108+
109+
o.Client = client
110+
}
111+
78112
return nil
79113
}
80114

@@ -88,7 +122,7 @@ func (c *AppregistryBuildOptions) Apply(options []AppregistryBuildOption) {
88122
// ToOption converts an AppregistryBuildOptions object into a function that applies
89123
// its current configuration to another AppregistryBuildOptions instance
90124
func (c *AppregistryBuildOptions) ToOption() AppregistryBuildOption {
91-
return func(o *AppregistryBuildOptions) {
125+
return func(o *AppregistryBuildOptions) {
92126
if c.Appender != nil {
93127
o.Appender = c.Appender
94128
}
@@ -116,6 +150,9 @@ func (c *AppregistryBuildOptions) ToOption() AppregistryBuildOption {
116150
if c.DatabaseDir != "" {
117151
o.DatabaseDir = c.DatabaseDir
118152
}
153+
if c.Client != nil {
154+
o.Client = c.Client
155+
}
119156
}
120157
}
121158

@@ -174,3 +211,9 @@ func WithCacheDir(s string) AppregistryBuildOption {
174211
o.CacheDir = s
175212
}
176213
}
214+
215+
func WithClient(c apprclient.Client) AppregistryBuildOption {
216+
return func(o *AppregistryBuildOptions) {
217+
o.Client = c
218+
}
219+
}

‎pkg/appregistry/builder_test.go

+82
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
package appregistry
2+
3+
import (
4+
"io/ioutil"
5+
"os"
6+
"path/filepath"
7+
8+
. "github.com/onsi/ginkgo"
9+
. "github.com/onsi/gomega"
10+
11+
"github.com/operator-framework/operator-registry/pkg/apprclient"
12+
"github.com/operator-framework/operator-registry/pkg/apprclient/apprclientfakes"
13+
)
14+
15+
var _ = Describe("Image building", func() {
16+
var (
17+
options []AppregistryBuildOption
18+
builder *AppregistryImageBuilder
19+
pkg *apprclient.RegistryMetadata
20+
operator *apprclient.OperatorMetadata
21+
)
22+
23+
JustBeforeEach(func() {
24+
var err error
25+
builder, err = NewAppregistryImageBuilder(options...)
26+
Expect(err).ToNot(HaveOccurred())
27+
Expect(builder).ToNot(BeNil())
28+
Expect(builder.Build()).To(Succeed())
29+
})
30+
31+
BeforeEach(func() {
32+
var noopAppender ImageAppendFunc = func(from, to, layer string) error {
33+
return nil
34+
}
35+
36+
client := &apprclientfakes.FakeClient{}
37+
pkg = &apprclient.RegistryMetadata{
38+
Namespace: "marsupials",
39+
Name: "koala",
40+
}
41+
client.ListPackagesReturns([]*apprclient.RegistryMetadata{pkg}, nil)
42+
43+
pkgBlob, err := ioutil.ReadFile("testdata/golden/marsupials_pkg.tar")
44+
Expect(err).ToNot(HaveOccurred())
45+
46+
operator = &apprclient.OperatorMetadata{
47+
RegistryMetadata: *pkg,
48+
Blob: pkgBlob,
49+
}
50+
client.RetrieveOneReturns(operator, nil)
51+
52+
options = append(options,
53+
WithAppender(noopAppender),
54+
WithAppRegistryOrg("metatheria"),
55+
WithClient(client),
56+
)
57+
})
58+
59+
Context("with a custom cache dir", func() {
60+
var (
61+
cacheDir string
62+
manifestsGlob string
63+
)
64+
65+
BeforeEach(func() {
66+
cacheDir = filepath.Join("testdata", "custom-cache")
67+
options = append(options, WithCacheDir(cacheDir))
68+
manifestsGlob = filepath.Join(cacheDir, "manifests-*/koala/marsupials")
69+
})
70+
71+
AfterEach(func() {
72+
Expect(os.RemoveAll(cacheDir)).To(Succeed())
73+
})
74+
75+
It("should retain unpacked operator manifests", func() {
76+
Expect(cacheDir).To(BeADirectory())
77+
Expect(filepath.Glob(filepath.Join(manifestsGlob, "package.yaml"))).To(HaveLen(1))
78+
Expect(filepath.Glob(filepath.Join(manifestsGlob, "v1.0.0", "koala.v1.0.0.clusterserviceversion.yaml"))).To(HaveLen(1))
79+
})
80+
81+
})
82+
})
Binary file not shown.

0 commit comments

Comments
 (0)
Please sign in to comment.