summaryrefslogtreecommitdiff
path: root/pkg/options
diff options
context:
space:
mode:
authorjannfis <jann@mistrust.net>2022-01-11 16:35:51 +0100
committerGitHub <noreply@github.com>2022-01-11 16:35:51 +0100
commite1f65012575eac6cd46fc6fdfc2d1ef03ad9b930 (patch)
tree7e4bd77d6e96ee77d8cd3f383165448c9ad01501 /pkg/options
parent77a6e8f1f8afa1d5b5b5f440dd9341830e14f7ef (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.go87
-rw-r--r--pkg/options/options_test.go74
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"))
+ })
+}