Image Update Automations
The ImageUpdateAutomation
API defines an automation process that will update a
Git repository, based on ImagePolicy
objects in the same namespace.
The updates are governed by marking fields to be updated in each YAML file. For each field marked, the automation process checks the image policy named, and updates the field value if there is a new image selected by the policy. The marker format is shown in the image automation guide.
Example
The following is an example of keeping the images in a Git repository up-to-date:
---
apiVersion: source.toolkit.fluxcd.io/v1
kind: GitRepository
metadata:
name: podinfo
namespace: default
spec:
interval: 5m0s
url: https://github.com/fluxcd/example
ref:
branch: main
---
apiVersion: image.toolkit.fluxcd.io/v1beta2
kind: ImageRepository
metadata:
name: podinfo
namespace: default
spec:
image: ghcr.io/stefanprodan/podinfo
interval: 5h
---
apiVersion: image.toolkit.fluxcd.io/v1beta2
kind: ImagePolicy
metadata:
name: podinfo-policy
namespace: default
spec:
imageRepositoryRef:
name: podinfo
policy:
semver:
range: 5.0.x
---
apiVersion: image.toolkit.fluxcd.io/v1beta2
kind: ImageUpdateAutomation
metadata:
name: podinfo-update
namespace: default
spec:
interval: 30m
sourceRef:
kind: GitRepository
name: podinfo
git:
commit:
author:
email: fluxcdbot@users.noreply.github.com
name: fluxcdbot
push:
branch: main
update:
path: ./
In the above example:
- A GitRepository named
podinfo
is created, indicated by theGitRepository.metadata.name
field. The Git repository athttps://github.com/fluxcd/example
is assumed to contain YAML files with image policy markers, as described in image automation guide, to update them. - An ImageRepository named
podinfo
is created, indicated by theImageRepository.metadata.name
field. This scans all the tags for an image repository. - An ImagePolicy named
podinfo-policy
is created, indicated by theImagePolicy.metadata.name
field. - An ImageUpdateAutomation named
podinfo-update
is created, indicated by theImageUpdateAutomation.metadata.name
field. - The ImagePolicy refers to the
podinfo
ImageRepository to query for all the tags related to an image, indicated byImagePolicy.spec.imageRepositoryRef
. These tags are then evaluated to select the latest image with tag based on the policy rules, indicated byImagePolicy.spec.policy
. - The ImageUpdateAutomation refers to
podinfo
GitRepository as the source that should be kept up-to-date, indicated byImageUpdateAutomation.spec.sourceRef
. - The image-automation-controller lists all the ImagePolicies in the
ImageUpdateAutomation’s namespace. It then checks out the Git repository
main
branch, as configured inGitRepository.spec.ref.branch
. It then goes through the YAML manifests from the root of the Git repository, as configured inImageUpdateAutomation.spec.update.path
and applies updates based on the latest images from the image policies. The source changes are saved as a Git commit with the commit author defined inImageUpdateAutomation.spec.git.commit.author
. The commit is then push to the remote Git repository’smain
branch, indicated byImageUpdateAutomation.spec.git.push.branch
. - The push commit hash is reported in the
ImageUpdateAutomation.status.lastPushCommit
field and the push time is reported in.status.lastPushTime
field.
This example can be run by saving the manifest into
imageupdateautomation.yaml
.
- Apply the resource on the cluster:
kubectl apply -f imageupdateautomation.yaml
- Run
kubectl get imageupdateautomation
to see the ImageUpdateAutomation:
NAME LAST RUN
podinfo-update 2024-03-17T22:22:34Z
- Run
kubectl describe imageupdateautomation podinfo-update
to see the Last Push Commit and Conditions in the ImageUpdateAutomation’s Status:
Status:
Conditions:
Last Transition Time: 2024-03-17T22:22:33Z
Message: repository up-to-date
Observed Generation: 1
Reason: Succeeded
Status: True
Type: Ready
Last Automation Run Time: 2024-03-17T22:22:34Z
Last Push Commit: 3ebb95cc56d2db59bc6ffbe0d9dd0ea445edeb77
Last Push Time: 2024-03-17T22:22:34Z
Observed Generation: 1
Observed Policies:
Podinfo - Policy:
Name: ghcr.io/stefanprodan/podinfo
Tag: 5.0.3
Observed Source Revision: main@sha1:3ebb95cc56d2db59bc6ffbe0d9dd0ea445edeb77
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Succeeded 5s (x2 over 6s) image-automation-controller repository up-to-date
Normal Succeeded 5s image-automation-controller pushed commit '3ebb95c' to branch 'main'
Update from image update automation
Writing an ImageUpdateAutomation spec
As with all other Kubernetes config, an ImageUpdateAutomation needs
apiVersion
, kind
, and metadata
fields. The name of an
ImageUpdateAutomation object must be a valid
DNS subdomain
name.
An ImageUpdateAutomation also needs a
.spec
section.
Source reference
.spec.sourceRef
is a required field to specify a reference to a source object
in the same namespace as the ImageUpdateAutomation or in another namespace. The
only supported source kind at the moment is GitRepository
, which is used by
default if the .spec.sourceRef.kind
is not specified. The source reference
name is a required field, .spec.sourceRef.name
. The source reference namespace
is optional, .spec.sourceRef.namespace
. If not specified, the source is
assumed to be in the same namespace as the ImageUpdateAutomation. The
GitRepository must contain the authentication configuration required to check
out the source, if any.
---
apiVersion: image.toolkit.fluxcd.io/v1beta2
kind: ImageUpdateAutomation
metadata:
name: <automation-name>
spec:
sourceRef:
name: <gitrepository-name>
namespace: <gitrepository-namespace>
By default, GitRepository in a different namespace can be referenced. This can
be disabled by setting the controller flag --no-cross-namespace-refs
.
The timeouts used in the Git operations for an ImageUpdateAutomation is derived
from the referenced GitRepository source. GitRepository.spec.timeout
can be
tuned to adjust the Git operation timeout.
The proxy configurations are also derived from the referenced GitRepository
source. GitRepository.spec.proxySecretRef
can be used to configure proxy use.
Git specification
.spec.git
is a required field to specify Git configurations related to source
checkout
, commit
and push
operations.
Checkout
.spec.git.checkout
is an optional field to specify the Git reference to check
out. The .spec.git.checkout.ref
field is the same as the
GitRepository.spec.ref
field. It can be used to override the checkout
configuration in the referenced GitRepository. Not specifying this reference
defaults to the checkout reference of the associated GitRepository.
---
apiVersion: image.toolkit.fluxcd.io/v1beta2
kind: ImageUpdateAutomation
metadata:
name: <automation-name>
spec:
git:
checkout:
ref:
branch: <branch-name>
If .spec.git.push
is unspecified, .spec.git.checkout
will be used as the
push branch for any updates.
By default the controller will only do shallow clones, but this can be disabled
by starting the controller with flag --feature-gates=GitShallowClone=false
.
Commit
.spec.git.commit
is a required field to specify the details about the commit
made by the automation.
Author
.spec.git.commit.author
is a required field to specify the commit author. The
author .email
is required. The author .name
is optional. The name and email
are used as the author of the commits made by the automation.
---
apiVersion: image.toolkit.fluxcd.io/v1beta2
kind: ImageUpdateAutomation
metadata:
name: <automation-name>
spec:
git:
commit:
author:
email: <author-email>
name: <author-name>
Signing Key
.spec.git.commit.signingKey
is an optional field to specify the signing PGP
key to sign the commits with. .secretRef.name
refers to a Secret in the same
namespace as the ImageUpdateAutomation, containing an ASCII-armored PGP key, in
a field named git.asc
. If the private key is protected by a passphrase, the
passphrase can be specified in the same Secret in a field named passphrase
.
---
apiVersion: image.toolkit.fluxcd.io/v1beta2
kind: ImageUpdateAutomation
metadata:
name: <automation-name>
spec:
git:
commit:
signingKey:
secretRef:
name: signing-key
...
---
apiVersion: v1
kind: Secret
metadata:
name: signing-key
stringData:
git.asc: |
<ARMOR ENCODED PGP KEY>
passphrase: <private-key-passphrase>
Message Template
.spec.git.commit.messageTemplate
is an optional field to specify the commit
message template. If unspecified, a default commit message is used.
---
apiVersion: image.toolkit.fluxcd.io/v1beta2
kind: ImageUpdateAutomation
metadata:
name: <automation-name>
spec:
git:
commit:
messageTemplate: |-
Automated image update by Flux
Deprecation Note: The Updated
template data available in v1beta1 API is
deprecated. Changed
template data is recommended for template data, as it
accommodates for all the updates, including partial updates to just the image
name or the tag, not just full image with name and tag update. The old templates
will continue to work in v1beta2 API as Updated
has not been removed yet. In
the next API version, Updated
may be removed.
The message template also has access to the data related to the changes made by the automation. The template is a Go text template. The data available to the template have the following structure (not reproduced verbatim):
// TemplateData is the type of the value given to the commit message
// template.
type TemplateData struct {
AutomationObject struct {
Name, Namespace string
}
Changed update.ResultV2
}
// ResultV2 contains the file changes made during the update. It contains
// details about the exact changes made to the files and the objects in them. It
// has a nested structure file->objects->changes.
type ResultV2 struct {
FileChanges map[string]ObjectChanges
}
// ObjectChanges contains all the changes made to objects.
type ObjectChanges map[ObjectIdentifier][]Change
// ObjectIdentifier holds the identifying data for a particular
// object. This won't always have a name (e.g., a kustomization.yaml).
type ObjectIdentifier struct {
Name, Namespace, APIVersion, Kind string
}
// Change contains the setter that resulted in a Change, the old and the new
// value after the Change.
type Change struct {
OldValue string
NewValue string
Setter string
}
The Changed
template data field also has a few helper methods to easily range
over the changed objects and changes:
// Changes returns all the changes that were made in at least one update.
func (r ResultV2) Changes() []Change
// Objects returns ObjectChanges, regardless of which file they appear in.
func (r ResultV2) Objects() ObjectChanges
Example of using the methods in a template:
spec:
commit:
messageTemplate: |
Automated image update
Automation name: {{ .AutomationObject }}
Files:
{{ range $filename, $_ := .Changed.FileChanges -}}
- {{ $filename }}
{{ end -}}
Objects:
{{ range $resource, $changes := .Changed.Objects -}}
- {{ $resource.Kind }} {{ $resource.Name }}
Changes:
{{- range $_, $change := $changes }}
- {{ $change.OldValue }} -> {{ $change.NewValue }}
{{ end -}}
{{ end -}}
With template functions, it is possible to manipulate and transform the supplied data in order to generate more complex commit messages.
spec:
commit:
messageTemplate: |
Automated image update
Automation name: {{ .AutomationObject }}
Files:
{{ range $filename, $_ := .Changed.FileChanges -}}
- {{ $filename }}
{{ end -}}
Objects:
{{ range $resource, $changes := .Changed.Objects -}}
- {{ $resource.Kind | lower }} {{ $resource.Name | lower }}
Changes:
{{- range $_, $change := $changes }}
{{ if contains "5.0.3" $change.NewValue -}}
- {{ $change.OldValue }} -> {{ $change.NewValue }}
{{ else -}}
[skip ci] wrong image
{{ end -}}
{{ end -}}
{{ end -}}
There are over 70 available functions. Some of them are defined by the Go template language itself. Most of the others are part of the Sprig template library.
Push
.spec.git.push
is an optional field that specifies how the commits are pushed
to the remote source repository.
Branch
.spec.git.push.branch
field specifies the remote branch to push to. If
unspecified, the commits are pushed to the branch specified in
.spec.git.checkout.branch
. If .spec.git.checkout
is also unspecified, it
will fall back to the branch specified in the associated GitRepository’s
.spec.sourceRef
. If none of these yield a push branch name, the automation
will fail.
The push branch will be created locally if it does not already exist, starting
from the checkout branch. If the push branch already exists, it will be
overwritten with the cloned version plus the changes made by the controller.
Alternatively, force push can be disabled by starting the controller with flag
--feature-gates=GitForcePushBranch=false
, in which case the updates will be
calculated on top of any commits already on the push branch. Note that without
force push in push branches, if the target branch is stale, the controller may
not be able to conclude the operation and will consistently fail until the
branch is either deleted or refreshed.
In the following snippet, updates will be pushed as commits to the branch
auto
, and when that branch does not exist at the origin, it will be created
locally starting from the branch main
, and pushed:
spec:
git:
checkout:
ref:
branch: main
push:
branch: auto
Refspec
.spec.git.push.refspec
field specifies the refspec to push to any arbitrary
destination reference. An example of a valid refspec is
refs/heads/branch:refs/heads/branch
.
If both .push.refspec
and .push.branch
are specified, then the reconciler
will push to both the destinations. This is particularly useful for working with
Gerrit servers. For more information about this, please refer to the
Gerrit section.
Note: If both .push.refspec
and .push.branch
are essentially equal to
each other (for e.g.: .push.refspec: refs/heads/main:refs/heads/main
and
.push.branch: main
), then the reconciler might fail with an already up-to-date
error.
In the following snippet, updates and commits will be made on the main
branch locally.
The commits will be then pushed using the refs/heads/main:refs/heads/auto
refspec:
spec:
git:
checkout:
ref:
branch: main
push:
refspec: refs/heads/main:refs/heads/auto
Push options
To specify the
push options
to be sent to the upstream Git server, use .push.options
. These options can be
used to perform operations as a result of the push. For example, using the below
push options will open a GitLab Merge Request to the release
branch
automatically with the commit the controller pushed to the dev
branch:
spec:
git:
push:
branch: dev
options:
merge_request.create: ""
merge_request.target: release
Interval
.spec.interval
is a required field that specifies the interval at which the
Image update is attempted.
After successfully reconciling the object, the image-automation-controller
requeues it for inspection after the specified interval. The value must be in a
Go recognized duration string format,
e.g. 10m0s
to reconcile the object every 10 minutes.
If the .metadata.generation
of a resource changes (due to e.g. a change to
the spec), this is handled instantly outside the interval window.
Update
.spec.update
is an optional field that specifies how to carry out the updates
on a source. The only supported update strategy at the moment is Setters
,
which is used by default for .spec.update.strategy
field. The
.spec.update.path
is an optional field to specify the directory containing the
manifests to be updated. If not specified, it defaults to the root of the source
repository.
---
apiVersion: image.toolkit.fluxcd.io/v1beta2
kind: ImageUpdateAutomation
metadata:
name: <automation-name>
spec:
update:
path: </path/to/manifest>
Suspend
.spec.suspend
is an optional field to suspend the reconciliation of an
ImageUpdateAutomation. When set to true
, the controller will stop reconciling
the ImageUpdateAutomation, and changes to the resource or image policies or Git
repository will not result in any update. When the field is set to false
or
removed, it will resume.
PolicySelector
.spec.policySelector
is an optional field to limit policies that an
ImageUpdateAutomation takes into account. It supports the same selectors as
Deployment.spec.selector
(matchLabels
and matchExpressions
fields). If
not specified, it defaults to matchLabels: {}
which means all policies in
namespace.
---
apiVersion: image.toolkit.fluxcd.io/v1beta2
kind: ImageUpdateAutomation
metadata:
name: <automation-name>
spec:
policySelector:
matchLabels:
app.kubernetes.io/instance: my-app
---
apiVersion: image.toolkit.fluxcd.io/v1beta2
kind: ImageUpdateAutomation
metadata:
name: <automation-name>
spec:
policySelector:
matchExpressions:
- key: app.kubernetes.io/component
operator: In
values:
- my-component
- my-other-component
Working with ImageUpdateAutomation
Triggering a reconciliation
To manually tell the image-automation-controller to reconcile an
ImageUpdateAutomation outside of the
specified interval window, an
ImageUpdateAutomation can be annotated with
reconcile.fluxcd.io/requestedAt: <arbitrary value>
. Annotating the resource
queues the ImageUpdateAutomation for reconciliation if the <arbitrary-value>
differs from the last value the controller acted on, as reported in
.status.lastHandledReconcileAt
.
Using kubectl
:
kubectl annotate --field-manager=flux-client-side-apply --overwrite imageupdateautomation/<automation-name> reconcile.fluxcd.io/requestedAt="$(date +%s)"
Using flux
:
flux reconcile image update <automation-name>
Waiting for Ready
When a change is applied, it is possible to wait for the ImageUpdateAutomation
to reach a
ready state using kubectl
:
kubectl wait imageupdateautomation/<automation-name> --for=condition=ready --timeout=1m
Suspending and resuming
When you find yourself in a situation where you temporarily want to pause the
reconciliation of a ImageUpdateAutomation, you can suspend it using the
.spec.suspend
field.
Suspend an ImageUpdateAutomation
In your YAML declaration:
---
apiVersion: image.toolkit.fluxcd.io/v1beta2
kind: ImageUpdateAutomation
metadata:
name: <automation-name>
spec:
suspend: true
Using kubectl
:
kubectl patch imageupdateautomation <automation-name> --field-manager=flux-client-side-apply -p '{\"spec\": {\"suspend\" : true }}'
Using flux
:
flux suspend image update <automation-name>
Resume an ImageUpdateAutomation
In your YAML declaration, comment out (or remove) the .spec.suspend
field:
---
apiVersion: image.toolkit.fluxcd.io/v1beta2
kind: ImageUpdateAutomation
metadata:
name: <automation-name>
spec:
# suspend: true
Note: Setting the field value to false
has the same effect as removing
it, but does not allow for “hot patching” using e.g. kubectl
while practicing
GitOps; as the manually applied patch would be overwritten by the declared
state in Git.
Using kubectl
:
kubectl patch imageupdateautomation <automation-name> --field-manager=flux-client-side-apply -p '{\"spec\" : {\"suspend\" : false }}'
Using flux
:
flux resume image update <automation-name>
Debugging an ImageUpdateAutomation
There are several ways to gather information about an ImageUpdateAutomation for debugging purposes.
Describe the ImageUpdateAutomation
Describing an ImageUpdateAutomation using
kubectl describe imageupdateautomation <automation-name>
displays the latest
recorded information for the resource in the Status
and
Events
sections:
...
Status:
Conditions:
Last Transition Time: 2024-03-18T20:00:56Z
Message: processing object: new generation 6 -> 7
Observed Generation: 7
Reason: ProgressingWithRetry
Status: True
Type: Reconciling
Last Transition Time: 2024-03-18T20:00:54Z
Message: failed to checkout source: unable to clone 'https://github.com/fluxcd/example': couldn't find remote ref "refs/heads/non-existing-branch"
Observed Generation: 7
Reason: GitOperationFailed
Status: False
Type: Ready
Last Automation Run Time: 2024-03-18T20:00:56Z
Last Handled Reconcile At: 1710791381
Last Push Commit: 8084f1bb180ac259c6698cd027064b7dce86a72a
Last Push Time: 2024-03-18T18:53:04Z
Observed Generation: 6
Observed Policies:
Podinfo - Policy:
Name: ghcr.io/stefanprodan/podinfo
Tag: 4.0.6
Observed Source Revision: main@sha1:8084f1bb180ac259c6698cd027064b7dce86a72a
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Succeeded 11m (x11 over 170m) image-automation-controller no change since last reconciliation
Warning GitOperationFailed 2s (x3 over 4s) image-automation-controller failed to checkout source: unable to clone 'https://github.com/fluxcd/example': couldn't find remote ref "refs/heads/non-existing-branch"
Trace emitted Events
To view events for specific ImageUpdateAutomation(s), kubectl events
can be
used in combination with --for
to list the Events for specific objects. For
example, running
kubectl events --for ImageUpdateAutomation/<automation-name>
lists
LAST SEEN TYPE REASON OBJECT MESSAGE
3m29s (x7 over 4m17s) Warning GitOperationFailed ImageUpdateAutomation/<automation-name> failed to checkout source: unable to clone 'https://github.com/fluxcd/example': couldn't find remote ref "refs/heads/non-existing-branch"
3m14s (x4 over 3h24m) Normal Succeeded ImageUpdateAutomation/<automation-name> repository up-to-date
2m41s (x12 over 174m) Normal Succeeded ImageUpdateAutomation/<automation-name> no change since last reconciliation
Besides being reported in Events, the reconciliation errors are also logged by
the controller. The Flux CLI offer commands for filtering the logs for a
specific ImageUpdateAutomation, e.g.
flux logs --level=error --kind=ImageUpdateAutomation --name=<automation-name>
.
Gerrit
Gerrit operates differently from a
standard Git server. Rather than sending individual commits to a branch,
all changes are bundled into a single commit. This commit requires a distinct
identifier separate from the commit SHA. Additionally, instead of initiating
a Pull Request between branches, the commit is pushed using a refspec:
HEAD:refs/for/main
.
As the image-automation-controller is primarily designed to work with standard Git servers, these special characteristics necessitate a few workarounds. The following is an example configuration that works well with Gerrit:
spec:
git:
checkout:
ref:
branch: main
commit:
author:
email: flux@localdomain
name: flux
messageTemplate: |
Perform automatic image update
Automation name: {{ .AutomationObject }}
{{- $ChangeId := .AutomationObject -}}
{{- $ChangeId = printf "%s%s" $ChangeId ( .Changed.FileChanges | toString ) -}}
{{- $ChangeId = printf "%s%s" $ChangeId ( .Changed.Objects | toString ) -}}
{{- $ChangeId = printf "%s%s" $ChangeId ( .Changed.Changes | toString ) }}
Change-Id: {{ printf "I%s" ( sha256sum $ChangeId | trunc 40 ) }}
push:
branch: auto
refspec: refs/heads/auto:refs/heads/main
This instructs the image-automation-controller to clone the repository using the
main
branch but execute its update logic and commit with the provided message
template on the auto
branch. Commits are then pushed to the auto
branch,
followed by pushing the HEAD
of the auto
branch to the HEAD
of the remote
main
branch. The message template ensures the inclusion of a
Change-Id
at the bottom of the commit message.
The initial branch push aims to prevent multiple
Patch Sets.
If we exclude .push.branch
and only specify
.push.refspec: refs/heads/main:refs/heads/main
, the desired
Change
can be created as intended. However, when the controller freshly clones the
main
branch while a Change is open, it executes its update logic on main
,
leading to new commits being pushed with the same changes to the existing open
Change. Specifying .push.branch
circumvents this by instructing the controller
to apply the update logic to the auto
branch, already containing the desired
commit. This approach is also recommended in the
Gerrit documentation.
Another thing to note is the syntax of .push.refspec
. Instead of it being
HEAD:refs/for/main
, commonly used by Gerrit users, we specify the full
refname refs/heads/auto
in the source part of the refpsec.
Note: A known limitation of using the image-automation-controller with Gerrit involves handling multiple concurrent Changes. This is due to the calculation of the Change-Id, relying on factors like file names and image tags. If the controller introduces a new file or modifies a previously updated image tag to a different one, it leads to a distinct Change-Id for the commit. Consequently, this action will trigger the creation of an additional Change, even when an existing Change containing outdated modifications remains open.
ImageUpdateAutomation Status
Observed Policies
The ImageUpdateAutomation reports the observed image policies that were
considered during the image update in the .status.observedPolicies
field. It
is a map of the policy name and its latest image name and tag.
Example:
status:
...
observedPolicies:
podinfo-policy:
name: ghcr.io/stefanprodan/podinfo
tag: 4.0.6
myapp1:
name: ghcr.io/fluxcd/myapp1
tag: 4.0.0
myapp2:
name: ghcr.io/fluxcd/myapp2
tag: 2.0.0
...
The observed policies keep track of the policies considered in the last reconciliation and is used to determine if the reconciliation can skip full execution due to no change in image policies or remote source.
Observed Source Revision
The ImageUpdateAutomation reports the observed source revision that was checked
out during the image update in the .status.observedSourceRevision
field. For a
GitRepository, the observed source revision would contain the branch name and
the commit hash; e.g., main@sha1:8084f1bb180ac259c6698cd027064b7dce86a72a
.
If the checkout and push branchs are the same, the commit hash of the observed
source revision is equal to the
last push commit.
The observed source revision keeps track of the source revision seen in the last reconciliation and is used to determine if the reconciliation can skip full execution due to no change in image policies or remote source.
Last Automation Run Time
The ImageUpdateAutomation reports the last automation run time in the
.status.lastAutomationRunTime
field. It is a timestamp of when the
reconciliation ran the last time, regardless of any effective resulting update.
Last Push Commit
The ImageUpdateAutomation reports the last pushed commit for image update in the
.status.lastPushCommit
field. It is the commit hash of the last pushed commit.
The commit has may not be the same that’s present in the observed source
revision if the puch branch is different from the checkout branch or the remote
repository has new commits which didn’t result in an image update.
Last Push Time
The ImageUpdateAutomation reports the last pushed commit time for image update
in the .status.lastPushTime
field. It is a timestamp of when the last image
update resulted in a pushing of new commit to the source.
Conditions
An ImageUpdateAutomation enters various states during its lifecycle, reflected as Kubernetes Conditions. It can be reconciling while checking out and updating images in source, it can be ready, or it can fail during reconciliation.
The ImageUpdateAutomation API is compatible with the
kstatus specification,
and reports Reconciling
and Stalled
conditions where applicable to provide
better (timeout) support to solutions polling the ImageUpdateAutomation to
become Ready
.
Reconciling ImageUpdateAutomation
The image-automation-controller marks an ImageUpdateAutomation as reconciling when one of the following is true:
- The generation of the ImageUpdateAutomation is newer than the Observed Generation.
- The ImageUpdateAutomation has observed new ImagePolicies or changes in the ImagePolicies’ latest images, or change in the remote source.
When the ImageUpdateAutomation is “reconciling”, the Ready
Condition status
becomes Unknown
, and the controller adds a Condition with the following
attributes to the ImageUpdateAutomation’s .status.conditions
:
type: Reconciling
status: "True"
reason: Progressing
It has a
“negative polarity”, and is only present
on the ImageUpdateAutomation while its status value is "True"
.
Ready ImageUpdateAutomation
The image-automation-controller marks an ImageUpdateAutomation as ready when it has the following characteristics:
- The controller was able to check out the remote source repository using the specified GitRepository configurations.
- The ImageUpdateAutomation could not find any update to the source, already up-to-date.
- The ImageUpdateAutomation pushes image updates to the source, making it up-to-date.
When the ImageUpdateAutomation is “ready”, the controller sets a Condition with the
following attributes in the ImageUpdateAutomation’s .status.conditions
:
type: Ready
status: "True"
reason: Succeeded
This Ready
Condition will retain a status value of "True"
until a
failure occurs due to any reason.
Failed ImageUpdateAutomation
The image-automation-controller may get stuck trying to update a source without completing. This can occur due to some of the following factors:
- The remote source is temporarily unavailable.
- The referenced source is in a different namespace and cross-namespace reference is disabled.
- The referenced source does not exist.
- The credentials associated with the source are invalid.
- The source configuration is invalid for the current state of the source, for example, the specified branch does not exists in the remote source repository.
- The remote source repository prevents push or creation of new push branch.
- The policy selector is invalid, for example, label is too long.
When this happens, the controller sets the Ready
Condition status to False
with the following reasons:
reason: AccessDenied
|reason: InvalidSourceConfiguration
|reason: GitOperationFailed
|reason: UpdateFailed
|reason: InvalidPolicySelector
While the ImageUpdateAutomation is in failing state, the controller will continue to attempt to update the source with an exponential backoff, until it succeeds and the ImageUpdateAutomation is marked as ready.
Note that an ImageUpdateAutomation can be reconciling while failing at the same time, for example due to a newly introduced configuration issue in the ImageUpdateAutomation spec.
Observed Generation
The image-automation-controller reports an
observed generation in the ImageUpdateAutomation’s
.status.observedGeneration
. The observed generation is the latest
.metadata.generation
which resulted in either a
ready state, or stalled due to error it can not
recover from without human intervention.
Last Handled Reconcile At
The image-automation-controller reports the last
reconcile.fluxcd.io/requestedAt
annotation value it acted on in the
.status.lastHandledReconcileAt
field.
For practical information about this field, see triggering a reconcile.