Skip to content

Commit 772ffb2

Browse files
Merge pull request #995 from carolynvs/force-all-tags
Add --force flag to commands that pull tags
2 parents 48d5f0c + b2ef6b5 commit 772ffb2

17 files changed

+172
-11
lines changed

cmd/porter/bundle.go

+3
Original file line numberDiff line numberDiff line change
@@ -347,5 +347,8 @@ func buildBundleArchiveCommand(p *porter.Porter) *cobra.Command {
347347
f.StringVar(&opts.CNABFile, "cnab-file", "", "Path to the CNAB bundle.json file.")
348348
f.StringVarP(&opts.Tag, "tag", "t", "",
349349
"Use a bundle in an OCI registry specified by the given tag")
350+
f.BoolVar(&opts.Force, "force", false,
351+
"Force a fresh pull of the bundle")
352+
350353
return &cmd
351354
}

cmd/porter/credentials.go

+3
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,9 @@ will then provide it to the bundle in the correct location. `,
8383
"Generate credential but do not save it.")
8484
f.StringVar(&opts.Tag, "tag", "",
8585
"Use a bundle in an OCI registry specified by the given tag.")
86+
f.BoolVar(&opts.Force, "force", false,
87+
"Force a fresh pull of the bundle")
88+
8689
return cmd
8790
}
8891

cmd/porter/explain.go

+2
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ func buildBundleExplainCommand(p *porter.Porter) *cobra.Command {
3030
f.StringVar(&opts.CNABFile, "cnab-file", "", "Path to the CNAB bundle.json file.")
3131
f.StringVarP(&opts.Tag, "tag", "t", "",
3232
"Use a bundle in an OCI registry specified by the given tag")
33+
f.BoolVar(&opts.Force, "force", false,
34+
"Force a fresh pull of the bundle")
3335
f.StringVarP(&opts.RawFormat, "output", "o", "table",
3436
"Specify an output format. Allowed values: table, json, yaml")
3537
return &cmd

cmd/porter/inspect.go

+2
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ like parameters, credentials, outputs and custom actions available.
3333
f.StringVar(&opts.CNABFile, "cnab-file", "", "Path to the CNAB bundle.json file.")
3434
f.StringVarP(&opts.Tag, "tag", "t", "",
3535
"Use a bundle in an OCI registry specified by the given tag")
36+
f.BoolVar(&opts.Force, "force", false,
37+
"Force a fresh pull of the bundle")
3638
f.StringVarP(&opts.RawFormat, "output", "o", "table",
3739
"Specify an output format. Allowed values: table, json, yaml")
3840
return &cmd

docs/content/cli/archive.md

+1
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ porter archive [flags]
3030
```
3131
--cnab-file string Path to the CNAB bundle.json file.
3232
-f, --file porter.yaml Path to the Porter manifest. Defaults to porter.yaml in the current directory.
33+
--force Force a fresh pull of the bundle
3334
-h, --help help for archive
3435
-t, --tag string Use a bundle in an OCI registry specified by the given tag
3536
```

docs/content/cli/bundles_archive.md

+1
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ porter bundles archive [flags]
3030
```
3131
--cnab-file string Path to the CNAB bundle.json file.
3232
-f, --file porter.yaml Path to the Porter manifest. Defaults to porter.yaml in the current directory.
33+
--force Force a fresh pull of the bundle
3334
-h, --help help for archive
3435
-t, --tag string Use a bundle in an OCI registry specified by the given tag
3536
```

docs/content/cli/bundles_explain.md

+1
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ porter bundles explain [flags]
3030
```
3131
--cnab-file string Path to the CNAB bundle.json file.
3232
-f, --file porter.yaml Path to the Porter manifest. Defaults to porter.yaml in the current directory.
33+
--force Force a fresh pull of the bundle
3334
-h, --help help for explain
3435
-o, --output string Specify an output format. Allowed values: table, json, yaml (default "table")
3536
-t, --tag string Use a bundle in an OCI registry specified by the given tag

docs/content/cli/bundles_inspect.md

+1
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ porter bundles inspect [flags]
3434
```
3535
--cnab-file string Path to the CNAB bundle.json file.
3636
-f, --file porter.yaml Path to the Porter manifest. Defaults to porter.yaml in the current directory.
37+
--force Force a fresh pull of the bundle
3738
-h, --help help for inspect
3839
-o, --output string Specify an output format. Allowed values: table, json, yaml (default "table")
3940
-t, --tag string Use a bundle in an OCI registry specified by the given tag

docs/content/cli/credentials_generate.md

+1
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ porter credentials generate [NAME] [flags]
4747
--cnab-file string Path to the CNAB bundle.json file.
4848
--dry-run Generate credential but do not save it.
4949
-f, --file string Path to the porter manifest file. Defaults to the bundle in the current directory.
50+
--force Force a fresh pull of the bundle
5051
-h, --help help for generate
5152
--tag string Use a bundle in an OCI registry specified by the given tag.
5253
```

docs/content/cli/explain.md

+1
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ porter explain [flags]
3030
```
3131
--cnab-file string Path to the CNAB bundle.json file.
3232
-f, --file porter.yaml Path to the Porter manifest. Defaults to porter.yaml in the current directory.
33+
--force Force a fresh pull of the bundle
3334
-h, --help help for explain
3435
-o, --output string Specify an output format. Allowed values: table, json, yaml (default "table")
3536
-t, --tag string Use a bundle in an OCI registry specified by the given tag

docs/content/cli/inspect.md

+1
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ porter inspect [flags]
3434
```
3535
--cnab-file string Path to the CNAB bundle.json file.
3636
-f, --file porter.yaml Path to the Porter manifest. Defaults to porter.yaml in the current directory.
37+
--force Force a fresh pull of the bundle
3738
-h, --help help for inspect
3839
-o, --output string Specify an output format. Allowed values: table, json, yaml (default "table")
3940
-t, --tag string Use a bundle in an OCI registry specified by the given tag

pkg/cnab/cnab-to-oci/helpers.go

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package cnabtooci
2+
3+
import (
4+
"github.com/cnabio/cnab-go/bundle"
5+
"github.com/cnabio/cnab-to-oci/relocation"
6+
)
7+
8+
var _ RegistryProvider = &TestRegistry{}
9+
10+
type TestRegistry struct {
11+
MockPullBundle func(tag string, insecureRegistry bool) (bun bundle.Bundle, reloMap *relocation.ImageRelocationMap, err error)
12+
MockPushBundle func(bun bundle.Bundle, tag string, insecureRegistry bool) (reloMap *relocation.ImageRelocationMap, err error)
13+
MockPushInvocationImage func(invocationImage string) (imageDigest string, err error)
14+
}
15+
16+
func NewTestRegistry() *TestRegistry {
17+
return &TestRegistry{}
18+
}
19+
20+
func (t TestRegistry) PullBundle(tag string, insecureRegistry bool) (bundle.Bundle, *relocation.ImageRelocationMap, error) {
21+
if t.MockPullBundle != nil {
22+
return t.MockPullBundle(tag, insecureRegistry)
23+
}
24+
25+
return bundle.Bundle{}, nil, nil
26+
}
27+
28+
func (t TestRegistry) PushBundle(bun bundle.Bundle, tag string, insecureRegistry bool) (*relocation.ImageRelocationMap, error) {
29+
if t.MockPushBundle != nil {
30+
return t.MockPushBundle(bun, tag, insecureRegistry)
31+
}
32+
33+
return nil, nil
34+
}
35+
36+
func (t TestRegistry) PushInvocationImage(invocationImage string) (string, error) {
37+
if t.MockPushInvocationImage != nil {
38+
return t.MockPushInvocationImage(invocationImage)
39+
}
40+
return "", nil
41+
}

pkg/porter/registry.go pkg/cnab/cnab-to-oci/provider.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
package porter
1+
package cnabtooci
22

33
import (
44
"github.com/cnabio/cnab-go/bundle"
55
"github.com/cnabio/cnab-to-oci/relocation"
66
)
77

88
// Registry handles talking with an OCI registry.
9-
type Registry interface {
9+
type RegistryProvider interface {
1010
// PullBundle pulls a bundle from an OCI registry.
1111
PullBundle(tag string, insecureRegistry bool) (bundle.Bundle, *relocation.ImageRelocationMap, error)
1212

pkg/cnab/cnab-to-oci/registry.go

+2
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ import (
2323
portercontext "get.porter.sh/porter/pkg/context"
2424
)
2525

26+
var _ RegistryProvider = &Registry{}
27+
2628
type Registry struct {
2729
*portercontext.Context
2830
}

pkg/porter/porter.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ type Porter struct {
2424
Cache cache.BundleCache
2525
Credentials credentials.CredentialProvider
2626
Claims claims.ClaimProvider
27-
Registry Registry
27+
Registry cnabtooci.RegistryProvider
2828
Templates *templates.Templates
2929
Builder BuildProvider
3030
Manifest *manifest.Manifest

pkg/porter/resolver.go

+11-8
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,27 @@ package porter
22

33
import (
44
"get.porter.sh/porter/pkg/cache"
5+
cnabtooci "get.porter.sh/porter/pkg/cnab/cnab-to-oci"
56
"github.com/pkg/errors"
67
)
78

89
type BundleResolver struct {
910
Cache cache.BundleCache
10-
Registry Registry
11+
Registry cnabtooci.RegistryProvider
1112
}
1213

1314
// Resolves a bundle from the cache, or pulls it and caches it
1415
// Returns the location of the bundle or an error
1516
func (r *BundleResolver) Resolve(opts BundlePullOptions) (cache.CachedBundle, error) {
16-
cachedBundle, ok, err := r.Cache.FindBundle(opts.Tag)
17-
if err != nil {
18-
return cache.CachedBundle{}, errors.Wrapf(err, "unable to load bundle %s from cache", opts.Tag)
19-
}
20-
// If we found the bundle, return the path to the bundle.json
21-
if ok && !opts.Force {
22-
return cachedBundle, nil
17+
if !opts.Force {
18+
cachedBundle, ok, err := r.Cache.FindBundle(opts.Tag)
19+
if err != nil {
20+
return cache.CachedBundle{}, errors.Wrapf(err, "unable to load bundle %s from cache", opts.Tag)
21+
}
22+
// If we found the bundle, return the path to the bundle.json
23+
if ok {
24+
return cachedBundle, nil
25+
}
2326
}
2427

2528
b, rMap, err := r.Registry.PullBundle(opts.Tag, opts.InsecureRegistry)

pkg/porter/resolver_test.go

+98
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
package porter
2+
3+
import (
4+
"testing"
5+
6+
"get.porter.sh/porter/pkg/cache"
7+
cnabtooci "get.porter.sh/porter/pkg/cnab/cnab-to-oci"
8+
"get.porter.sh/porter/pkg/config"
9+
"github.com/cnabio/cnab-go/bundle"
10+
"github.com/cnabio/cnab-to-oci/relocation"
11+
"github.com/stretchr/testify/assert"
12+
)
13+
14+
func TestBundleResolver_Resolve_ForcePull(t *testing.T) {
15+
tc := config.NewTestConfig(t)
16+
testReg := cnabtooci.NewTestRegistry()
17+
testCache := cache.NewTestCache(cache.New(tc.Config))
18+
resolver := BundleResolver{
19+
Cache: testCache,
20+
Registry: testReg,
21+
}
22+
23+
cacheSearched := false
24+
testCache.FindBundleMock = func(tag string) (cache.CachedBundle, bool, error) {
25+
cacheSearched = true
26+
return cache.CachedBundle{}, true, nil
27+
}
28+
29+
pulled := false
30+
testReg.MockPullBundle = func(tag string, insecureRegistry bool) (bundle.Bundle, *relocation.ImageRelocationMap, error) {
31+
pulled = true
32+
return bundle.Bundle{}, nil, nil
33+
}
34+
35+
opts := BundlePullOptions{
36+
Force: true,
37+
}
38+
resolver.Resolve(opts)
39+
40+
assert.False(t, cacheSearched, "Force should have skipped the cache")
41+
assert.True(t, pulled, "The bundle should have been re-pulled")
42+
}
43+
44+
func TestBundleResolver_Resolve_CacheHit(t *testing.T) {
45+
tc := config.NewTestConfig(t)
46+
testReg := cnabtooci.NewTestRegistry()
47+
testCache := cache.NewTestCache(cache.New(tc.Config))
48+
resolver := BundleResolver{
49+
Cache: testCache,
50+
Registry: testReg,
51+
}
52+
53+
cacheSearched := false
54+
testCache.FindBundleMock = func(tag string) (cache.CachedBundle, bool, error) {
55+
cacheSearched = true
56+
return cache.CachedBundle{}, true, nil
57+
}
58+
59+
pulled := false
60+
testReg.MockPullBundle = func(tag string, insecureRegistry bool) (bundle.Bundle, *relocation.ImageRelocationMap, error) {
61+
pulled = true
62+
return bundle.Bundle{}, nil, nil
63+
}
64+
65+
opts := BundlePullOptions{}
66+
resolver.Resolve(opts)
67+
68+
assert.True(t, cacheSearched, "The cache should be searched when force is not specified")
69+
assert.False(t, pulled, "The bundle should NOT be pulled because it was found in the cache")
70+
}
71+
72+
func TestBundleResolver_Resolve_CacheMiss(t *testing.T) {
73+
tc := config.NewTestConfig(t)
74+
testReg := cnabtooci.NewTestRegistry()
75+
testCache := cache.NewTestCache(cache.New(tc.Config))
76+
resolver := BundleResolver{
77+
Cache: testCache,
78+
Registry: testReg,
79+
}
80+
81+
cacheSearched := false
82+
testCache.FindBundleMock = func(tag string) (cache.CachedBundle, bool, error) {
83+
cacheSearched = true
84+
return cache.CachedBundle{}, false, nil
85+
}
86+
87+
pulled := false
88+
testReg.MockPullBundle = func(tag string, insecureRegistry bool) (bundle.Bundle, *relocation.ImageRelocationMap, error) {
89+
pulled = true
90+
return bundle.Bundle{}, nil, nil
91+
}
92+
93+
opts := BundlePullOptions{}
94+
resolver.Resolve(opts)
95+
96+
assert.True(t, cacheSearched, "The cache should be searched when force is not specified")
97+
assert.True(t, pulled, "The bundle should have been pulled because the bundle was not in the cache")
98+
}

0 commit comments

Comments
 (0)