diff --git a/argocd-image-updater b/argocd-image-updater
new file mode 100755
index 00000000..9ac368df
Binary files /dev/null and b/argocd-image-updater differ
diff --git a/docs/basics/update-strategies.md b/docs/basics/update-strategies.md
index 453cbf1c..0963a534 100644
--- a/docs/basics/update-strategies.md
+++ b/docs/basics/update-strategies.md
@@ -15,9 +15,13 @@ The following update strategies are currently supported:
* [semver](#strategy-semver) - Update to the latest version of an image
considering semantic versioning constraints
-* [latest](#strategy-latest) - Update to the most recently built image found in a registry
+* [latest/newest-build](#strategy-latest) - Update to the most recently built image found in a registry
* [digest](#strategy-digest) - Update to the latest version of a given version (tag), using the tag's SHA digest
-* [name](#strategy-name) - Sorts tags alphabetically and update to the one with the highest cardinality
+* [name/alphabetical](#strategy-name) - Sorts tags alphabetically and update to the one with the highest cardinality
+
+!!!warning "Renamed image update strategies
+ The `latest` strategy has been renamed to `newest-build`, and `name` strategy has been renamed to `alphabetical`.
+ Please switch to the new convention as support for the old naming convention will be removed in future releases.
Some of the strategies will require additional configuration, or can be tweaked
with additional parameters. Please have a look at the
@@ -97,23 +101,29 @@ Image Updater will pick the highest version number found in the registry.
Argo CD Image Updater will omit any tags from your registry that do not match
a semantic version when using the `semver` update strategy.
-### latest - Update to the most recently built image
+### latest/newest-build - Update to the most recently built image
+
+
+!!!warning "Renamed image update strategies"
+ The `latest` strategy has been renamed to `newest-build`.
+ Please switch to the new convention as support for the old naming convention will be removed in future releases.
+ Detected usage of `latest` will result in a warning message within the image-updater controller logs.
!!!warning
As of November 2020, Docker Hub has introduced pull limits for accounts on
- the free plan and unauthenticated requests. The `latest` update strategy
+ the free plan and unauthenticated requests. The `latest` or `newest-build` update strategy
will perform manifest pulls for determining the most recently pushed tags,
and these will count into your pull limits. So unless you are not affected
- by these pull limits, it is **not recommended** to use the `latest` update
+ by these pull limits, it is **not recommended** to use the `latest` or `newest-build` update
strategy with images hosted on Docker Hub.
!!!note
If you are using *reproducible builds* for your container images (e.g. if
your build pipeline always sets the creation date of the image to the same
- value), the `latest` strategy will not be able to determine which tag to
+ value), the `latest` or `newest-build` strategy will not be able to determine which tag to
update to.
-Strategy name: `latest`
+Strategy name: `latest` or `newest-build`
Basic configuration:
@@ -121,6 +131,12 @@ Basic configuration:
argocd-image-updater.argoproj.io/image-list: =some/image
argocd-image-updater.argoproj.io/.update-strategy: latest
```
+or
+
+```yaml
+argocd-image-updater.argoproj.io/image-list: =some/image
+argocd-image-updater.argoproj.io/.update-strategy: newest-build
+```
Argo CD Image Updater can update to the image that has the most recent build
date, and is tagged with an arbitrary name (e.g. a Git commit SHA, or even a
@@ -147,6 +163,14 @@ argocd-image-updater.argoproj.io/myimage.update-strategy: latest
argocd-image-updater.argoproj.io/myimage.allow-tags: regexp:^[0-9a-f]{7}$
```
+or
+
+```yaml
+argocd-image-updater.argoproj.io/image-list: myimage=some/image
+argocd-image-updater.argoproj.io/myimage.update-strategy: newest-build
+argocd-image-updater.argoproj.io/myimage.allow-tags: regexp:^[0-9a-f]{7}$
+```
+
would only consider tags that match a given regular expression for update. In
this case, the regular expression matches a 7-digit hexadecimal string that
could represent the short version of a Git commit SHA, so it would match tags
@@ -160,6 +184,14 @@ argocd-image-updater.argoproj.io/myimage.update-strategy: latest
argocd-image-updater.argoproj.io/myimage.ignore-tags: latest, master
```
+or
+
+```yaml
+argocd-image-updater.argoproj.io/image-list: myimage=some/image
+argocd-image-updater.argoproj.io/myimage.update-strategy: newest-build
+argocd-image-updater.argoproj.io/myimage.ignore-tags: latest, master
+```
+
This would allow for considering all tags found but `latest` and `master`. You
can read more about filtering tags
[here](../../configuration/images/#filtering-tags).
@@ -206,7 +238,13 @@ argocd-image-updater.argoproj.io/myimage.update-strategy: digest
### Update according to lexical sort
-Strategy name: `name`
+!!!warning "Renamed image update strategies"
+ The `name` strategy has been renamed to `alphabetical`.
+ Please switch to the new convention as support for the old naming convention will be removed in future releases.
+ Detected usage of `name` will result in a warning message within the image-updater controller logs.
+
+
+Strategy name: `name` or `alphabetical`
Basic configuration:
@@ -214,6 +252,12 @@ Basic configuration:
argocd-image-updater.argoproj.io/image-list: =some/image
argocd-image-updater.argoproj.io/.update-strategy: name
```
+or
+
+```yaml
+argocd-image-updater.argoproj.io/image-list: =some/image
+argocd-image-updater.argoproj.io/.update-strategy: alphabetical
+```
This update strategy sorts the tags returned by the registry in a lexical way
(by name, in descending order) and picks the last tag in the list for update.
@@ -231,6 +275,14 @@ argocd-image-updater.argoproj.io/myimage.update-strategy: name
argocd-image-updater.argoproj.io/myimage.allow-tags: regexp:^[0-9]{4}-[0-9]{2}[0-9]{2}$
```
+or
+
+```yaml
+argocd-image-updater.argoproj.io/image-list: myimage=some/image
+argocd-image-updater.argoproj.io/myimage.update-strategy: alphabetical
+argocd-image-updater.argoproj.io/myimage.allow-tags: regexp:^[0-9]{4}-[0-9]{2}[0-9]{2}$
+```
+
would only consider tags that match a given regular expression for update. In
this case, only tags matching a date specification of `YYYY-MM-DD` would be
considered for update.
diff --git a/docs/index.md b/docs/index.md
index 511c77fc..32eb091e 100644
--- a/docs/index.md
+++ b/docs/index.md
@@ -42,14 +42,18 @@ RBAC authorization on Application resources etc. are fully supported.
## Features
+!!!warning "Renamed image update strategies"
+ The `latest` strategy has been renamed to `newest-build`, and `name` strategy has been renamed to `alphabetical`.
+ Please switch to the new convention as support for the old naming convention will be removed in future releases.
+
* Updates images of apps that are managed by Argo CD and are either generated
from *Helm* or *Kustomize* tooling
* Update app images according to different
[update strategies](./basics/update-strategies.md)
* `semver`: update to highest allowed version according to given image
constraint,
- * `latest`: update to the most recently created image tag,
- * `name`: update to the last tag in an alphabetically sorted list
+ * `latest/newest-build`: update to the most recently created image tag,
+ * `name/alphabetical`: update to the last tag in an alphabetically sorted list
* `digest`: update to the most recent pushed version of a mutable tag
* Support for
[widely used container registries](./configuration/registries.md#supported-registries)
diff --git a/pkg/image/options.go b/pkg/image/options.go
index df357c38..af6d12a0 100644
--- a/pkg/image/options.go
+++ b/pkg/image/options.go
@@ -101,9 +101,15 @@ func (img *ContainerImage) ParseUpdateStrategy(val string) UpdateStrategy {
case "semver":
return StrategySemVer
case "latest":
- return StrategyLatest
+ logCtx.Warnf("\"latest\" strategy has been renamed to \"newest-build\". Please switch to the new convention as support for the old naming convention will be removed in future versions.")
+ fallthrough
+ case "newest-build":
+ return StrategyNewestBuild
case "name":
- return StrategyName
+ logCtx.Warnf("\"name\" strategy has been renamed to \"alphabetical\". Please switch to the new convention as support for the old naming convention will be removed in future versions.")
+ fallthrough
+ case "alphabetical":
+ return StrategyAlphabetical
case "digest":
return StrategyDigest
default:
diff --git a/pkg/image/options_test.go b/pkg/image/options_test.go
index a563eec3..1d346de1 100644
--- a/pkg/image/options_test.go
+++ b/pkg/image/options_test.go
@@ -85,13 +85,22 @@ func Test_GetSortOption(t *testing.T) {
assert.Equal(t, StrategySemVer, sortMode)
})
+ t.Run("Use update strategy newest-build for configured application", func(t *testing.T) {
+ annotations := map[string]string{
+ fmt.Sprintf(common.UpdateStrategyAnnotation, "dummy"): "newest-build",
+ }
+ img := NewFromIdentifier("dummy=foo/bar:1.12")
+ sortMode := img.GetParameterUpdateStrategy(annotations)
+ assert.Equal(t, StrategyNewestBuild, sortMode)
+ })
+
t.Run("Get update strategy date for configured application", func(t *testing.T) {
annotations := map[string]string{
fmt.Sprintf(common.UpdateStrategyAnnotation, "dummy"): "latest",
}
img := NewFromIdentifier("dummy=foo/bar:1.12")
sortMode := img.GetParameterUpdateStrategy(annotations)
- assert.Equal(t, StrategyLatest, sortMode)
+ assert.Equal(t, StrategyNewestBuild, sortMode)
})
t.Run("Get update strategy name for configured application", func(t *testing.T) {
@@ -100,7 +109,16 @@ func Test_GetSortOption(t *testing.T) {
}
img := NewFromIdentifier("dummy=foo/bar:1.12")
sortMode := img.GetParameterUpdateStrategy(annotations)
- assert.Equal(t, StrategyName, sortMode)
+ assert.Equal(t, StrategyAlphabetical, sortMode)
+ })
+
+ t.Run("Use update strategy alphabetical for configured application", func(t *testing.T) {
+ annotations := map[string]string{
+ fmt.Sprintf(common.UpdateStrategyAnnotation, "dummy"): "alphabetical",
+ }
+ img := NewFromIdentifier("dummy=foo/bar:1.12")
+ sortMode := img.GetParameterUpdateStrategy(annotations)
+ assert.Equal(t, StrategyAlphabetical, sortMode)
})
t.Run("Get update strategy option configured application because of invalid option", func(t *testing.T) {
@@ -121,21 +139,21 @@ func Test_GetSortOption(t *testing.T) {
t.Run("Prefer update strategy option from image-specific annotation", func(t *testing.T) {
annotations := map[string]string{
- fmt.Sprintf(common.UpdateStrategyAnnotation, "dummy"): "name",
- common.ApplicationWideUpdateStrategyAnnotation: "latest",
+ fmt.Sprintf(common.UpdateStrategyAnnotation, "dummy"): "alphabetical",
+ common.ApplicationWideUpdateStrategyAnnotation: "newest-build",
}
img := NewFromIdentifier("dummy=foo/bar:1.12")
sortMode := img.GetParameterUpdateStrategy(annotations)
- assert.Equal(t, StrategyName, sortMode)
+ assert.Equal(t, StrategyAlphabetical, sortMode)
})
t.Run("Get update strategy option from application-wide annotation", func(t *testing.T) {
annotations := map[string]string{
- common.ApplicationWideUpdateStrategyAnnotation: "latest",
+ common.ApplicationWideUpdateStrategyAnnotation: "newest-build",
}
img := NewFromIdentifier("dummy=foo/bar:1.12")
sortMode := img.GetParameterUpdateStrategy(annotations)
- assert.Equal(t, StrategyLatest, sortMode)
+ assert.Equal(t, StrategyNewestBuild, sortMode)
})
}
diff --git a/pkg/image/version.go b/pkg/image/version.go
index 6312d23f..43b3f5c2 100644
--- a/pkg/image/version.go
+++ b/pkg/image/version.go
@@ -17,9 +17,9 @@ const (
// VersionSortSemVer sorts tags using semver sorting (the default)
StrategySemVer UpdateStrategy = 0
// VersionSortLatest sorts tags after their creation date
- StrategyLatest UpdateStrategy = 1
+ StrategyNewestBuild UpdateStrategy = 1
// VersionSortName sorts tags alphabetically by name
- StrategyName UpdateStrategy = 2
+ StrategyAlphabetical UpdateStrategy = 2
// VersionSortDigest uses latest digest of an image
StrategyDigest UpdateStrategy = 3
)
@@ -28,10 +28,10 @@ func (us UpdateStrategy) String() string {
switch us {
case StrategySemVer:
return "semver"
- case StrategyLatest:
- return "latest"
- case StrategyName:
- return "name"
+ case StrategyNewestBuild:
+ return "newest-build"
+ case StrategyAlphabetical:
+ return "alphabetical"
case StrategyDigest:
return "digest"
}
@@ -87,12 +87,12 @@ func (img *ContainerImage) GetNewestVersionFromTags(vc *VersionConstraint, tagLi
switch vc.Strategy {
case StrategySemVer:
availableTags = tagList.SortBySemVer()
- case StrategyName:
- availableTags = tagList.SortByName()
- case StrategyLatest:
+ case StrategyAlphabetical:
+ availableTags = tagList.SortAlphabetically()
+ case StrategyNewestBuild:
availableTags = tagList.SortByDate()
case StrategyDigest:
- availableTags = tagList.SortByName()
+ availableTags = tagList.SortAlphabetically()
}
considerTags := tag.SortableImageTagList{}
@@ -192,7 +192,7 @@ func (s UpdateStrategy) IsCacheable() bool {
// NeedsMetadata returns true if strategy s requires image metadata to work correctly
func (s UpdateStrategy) NeedsMetadata() bool {
switch s {
- case StrategyLatest:
+ case StrategyNewestBuild:
return true
default:
return false
diff --git a/pkg/image/version_test.go b/pkg/image/version_test.go
index 8cdc1f54..a54808fe 100644
--- a/pkg/image/version_test.go
+++ b/pkg/image/version_test.go
@@ -88,7 +88,7 @@ func Test_LatestVersion(t *testing.T) {
t.Run("Find the latest version using latest sortmode", func(t *testing.T) {
tagList := newImageTagListWithDate([]string{"zz", "bb", "yy", "cc", "yy", "aa", "ll"})
img := NewFromIdentifier("jannfis/test:bb")
- vc := VersionConstraint{Strategy: StrategyLatest}
+ vc := VersionConstraint{Strategy: StrategyNewestBuild}
newTag, err := img.GetNewestVersionFromTags(&vc, tagList)
require.NoError(t, err)
require.NotNil(t, newTag)
diff --git a/pkg/registry/registry.go b/pkg/registry/registry.go
index 11c061be..3feb8a38 100644
--- a/pkg/registry/registry.go
+++ b/pkg/registry/registry.go
@@ -80,7 +80,7 @@ func (endpoint *RegistryEndpoint) GetTags(img *image.ContainerImage, regClient R
//
// We just create a dummy time stamp according to the registry's sort mode, if
// set.
- if (vc.Strategy != image.StrategyLatest && vc.Strategy != image.StrategyDigest) || endpoint.TagListSort.IsTimeSorted() {
+ if (vc.Strategy != image.StrategyNewestBuild && vc.Strategy != image.StrategyDigest) || endpoint.TagListSort.IsTimeSorted() {
for i, tagStr := range tags {
var ts int
if endpoint.TagListSort == TagListSortLatestFirst {
diff --git a/pkg/registry/registry_test.go b/pkg/registry/registry_test.go
index 31164f7a..d558944b 100644
--- a/pkg/registry/registry_test.go
+++ b/pkg/registry/registry_test.go
@@ -70,7 +70,7 @@ func Test_GetTags(t *testing.T) {
img := image.NewFromIdentifier("foo/bar:1.2.0")
- tl, err := ep.GetTags(img, ®Client, &image.VersionConstraint{Strategy: image.StrategyName, Options: options.NewManifestOptions()})
+ tl, err := ep.GetTags(img, ®Client, &image.VersionConstraint{Strategy: image.StrategyAlphabetical, Options: options.NewManifestOptions()})
require.NoError(t, err)
assert.NotEmpty(t, tl)
@@ -102,7 +102,7 @@ func Test_GetTags(t *testing.T) {
ep.Cache.ClearCache()
img := image.NewFromIdentifier("foo/bar:1.2.0")
- tl, err := ep.GetTags(img, ®Client, &image.VersionConstraint{Strategy: image.StrategyLatest, Options: options.NewManifestOptions()})
+ tl, err := ep.GetTags(img, ®Client, &image.VersionConstraint{Strategy: image.StrategyNewestBuild, Options: options.NewManifestOptions()})
require.NoError(t, err)
assert.NotEmpty(t, tl)
diff --git a/pkg/tag/tag.go b/pkg/tag/tag.go
index 2a89aecd..5d16024e 100644
--- a/pkg/tag/tag.go
+++ b/pkg/tag/tag.go
@@ -123,7 +123,7 @@ func (il ImageTagList) Add(tag *ImageTag) {
}
// SortByName returns an array of ImageTag objects, sorted by the tag's name
-func (il ImageTagList) SortByName() SortableImageTagList {
+func (il ImageTagList) SortAlphabetically() SortableImageTagList {
sil := SortableImageTagList{}
for _, v := range il.items {
sil = append(sil, v)
diff --git a/pkg/tag/tag_test.go b/pkg/tag/tag_test.go
index f5985878..fb5bc02c 100644
--- a/pkg/tag/tag_test.go
+++ b/pkg/tag/tag_test.go
@@ -96,7 +96,7 @@ func Test_SortableImageTagList(t *testing.T) {
tag := NewImageTag(name, time.Now(), "")
il.Add(tag)
}
- sil := il.SortByName()
+ sil := il.SortAlphabetically()
require.Len(t, sil, len(names))
assert.Equal(t, "alpha", sil[0].TagName)
assert.Equal(t, "bazar", sil[1].TagName)