diff options
| author | jannfis <jann@mistrust.net> | 2022-01-11 16:35:51 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-01-11 16:35:51 +0100 |
| commit | e1f65012575eac6cd46fc6fdfc2d1ef03ad9b930 (patch) | |
| tree | 7e4bd77d6e96ee77d8cd3f383165448c9ad01501 /pkg/options | |
| parent | 77a6e8f1f8afa1d5b5b5f440dd9341830e14f7ef (diff) | |
feat: Support manifestlist and multi-arch images (#341)
* feat: Support manifestlist and multi-arch images
Signed-off-by: jannfis <jann@mistrust.net>
* Add unit test
Signed-off-by: jannfis <jann@mistrust.net>
* Fix linter issue
Signed-off-by: jannfis <jann@mistrust.net>
Diffstat (limited to 'pkg/options')
| -rw-r--r-- | pkg/options/options.go | 87 | ||||
| -rw-r--r-- | pkg/options/options_test.go | 74 |
2 files changed, 161 insertions, 0 deletions
diff --git a/pkg/options/options.go b/pkg/options/options.go new file mode 100644 index 0000000..c1a6462 --- /dev/null +++ b/pkg/options/options.go @@ -0,0 +1,87 @@ +package options + +import ( + "sort" + "sync" + + "github.com/argoproj-labs/argocd-image-updater/pkg/log" +) + +// ManifestOptions define some options when retrieving image manifests +type ManifestOptions struct { + platforms map[string]bool + mutex sync.RWMutex + metadata bool +} + +// NewManifestOptions returns an initialized ManifestOptions struct +func NewManifestOptions() *ManifestOptions { + return &ManifestOptions{ + platforms: make(map[string]bool), + metadata: false, + } +} + +// PlatformKey returns a string usable as platform key +func PlatformKey(os string, arch string, variant string) string { + key := os + "/" + arch + if variant != "" { + key += "/" + variant + } + return key +} + +// MatchesPlatform returns true if given OS name matches the OS set in options +func (o *ManifestOptions) WantsPlatform(os string, arch string, variant string) bool { + o.mutex.RLock() + defer o.mutex.RUnlock() + if len(o.platforms) == 0 { + return true + } + _, ok := o.platforms[PlatformKey(os, arch, variant)] + return ok +} + +// WithPlatform sets a platform filter for options o +func (o *ManifestOptions) WithPlatform(os string, arch string, variant string) *ManifestOptions { + o.mutex.Lock() + defer o.mutex.Unlock() + if o.platforms == nil { + o.platforms = map[string]bool{} + } + log.Debugf("Adding platform " + PlatformKey(os, arch, variant)) + o.platforms[PlatformKey(os, arch, variant)] = true + return o +} + +func (o *ManifestOptions) Platforms() []string { + o.mutex.RLock() + defer o.mutex.RUnlock() + if len(o.platforms) == 0 { + return []string{} + } + keys := make([]string, 0, len(o.platforms)) + for k := range o.platforms { + keys = append(keys, k) + } + // We sort the slice before returning it, to guarantee stable order + sort.Strings(keys) + return keys +} + +// WantsMetdata returns true if metadata should be requested +func (o *ManifestOptions) WantsMetdata() bool { + return o.metadata +} + +// WithMetadata sets metadata to be requested +func (o *ManifestOptions) WithMetadata() *ManifestOptions { + o.metadata = true + return o +} + +// WithoutMetadata sets metadata not not be requested +func (o *ManifestOptions) WithoutMetadata() *ManifestOptions { + o.metadata = false + return o +} diff --git a/pkg/options/options_test.go b/pkg/options/options_test.go new file mode 100644 index 0000000..d0a7fdc --- /dev/null +++ b/pkg/options/options_test.go @@ -0,0 +1,74 @@ +package options + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func Test_PlatformKey(t *testing.T) { + t.Run("Without variant", func(t *testing.T) { + assert.Equal(t, PlatformKey("linux", "amd64", ""), "linux/amd64") + }) + t.Run("With variant", func(t *testing.T) { + assert.Equal(t, PlatformKey("linux", "arm", "v6"), "linux/arm/v6") + }) +} + +func Test_WantsPlatform(t *testing.T) { + opts := NewManifestOptions() + t.Run("Empty options", func(t *testing.T) { + assert.True(t, opts.WantsPlatform("linux", "arm", "v7")) + assert.True(t, opts.WantsPlatform("linux", "amd64", "")) + }) + t.Run("Single platform", func(t *testing.T) { + opts = opts.WithPlatform("linux", "arm", "v7") + assert.True(t, opts.WantsPlatform("linux", "arm", "v7")) + }) + t.Run("Platform appended", func(t *testing.T) { + opts = opts.WithPlatform("linux", "arm", "v8") + assert.True(t, opts.WantsPlatform("linux", "arm", "v7")) + assert.True(t, opts.WantsPlatform("linux", "arm", "v8")) + }) + t.Run("Uninitialized options", func(t *testing.T) { + opts := &ManifestOptions{} + assert.True(t, opts.WantsPlatform("linux", "amd64", "")) + opts = (&ManifestOptions{}).WithPlatform("linux", "amd64", "") + assert.True(t, opts.WantsPlatform("linux", "amd64", "")) + }) +} + +func Test_WantsMetadata(t *testing.T) { + opts := NewManifestOptions() + t.Run("Empty options", func(t *testing.T) { + assert.False(t, opts.WantsMetdata()) + }) + t.Run("Wants metadata", func(t *testing.T) { + opts = opts.WithMetadata() + assert.True(t, opts.WantsMetdata()) + }) + t.Run("Does not want metadata", func(t *testing.T) { + opts = opts.WithoutMetadata() + assert.False(t, opts.WantsMetdata()) + }) +} + +func Test_Platforms(t *testing.T) { + opts := NewManifestOptions() + t.Run("Empty platforms returns empty array", func(t *testing.T) { + ps := opts.Platforms() + assert.Len(t, ps, 0) + }) + t.Run("Single platform without variant", func(t *testing.T) { + ps := opts.WithPlatform("linux", "amd64", "").Platforms() + require.Len(t, ps, 1) + assert.Equal(t, ps[0], PlatformKey("linux", "amd64", "")) + }) + t.Run("Single platform with variant", func(t *testing.T) { + ps := opts.WithPlatform("linux", "arm", "v8").Platforms() + require.Len(t, ps, 2) + assert.Equal(t, ps[0], PlatformKey("linux", "amd64", "")) + assert.Equal(t, ps[1], PlatformKey("linux", "arm", "v8")) + }) +} |
