9.9 KiB
Image Update Automations
The ImageUpdateAutomation
type defines an automation process that will update a git repository,
based on image policiy 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.
Specification
// ImageUpdateAutomationSpec defines the desired state of ImageUpdateAutomation
type ImageUpdateAutomationSpec struct {
// Checkout gives the parameters for cloning the git repository,
// ready to make changes.
// +required
Checkout GitCheckoutSpec `json:"checkout"`
// Interval gives an lower bound for how often the automation
// run should be attempted.
// +required
Interval metav1.Duration `json:"interval"`
// Update gives the specification for how to update the files in
// the repository. This can be left empty, to use the default
// value.
// +kubebuilder:default={"strategy":"Setters"}
Update *UpdateStrategy `json:"update,omitempty"`
// Commit specifies how to commit to the git repo
// +required
Commit CommitSpec `json:"commit"`
// Suspend tells the controller to not run this automation, until
// it is unset (or set to false). Defaults to false.
// +optional
Suspend bool `json:"suspend,omitempty"`
}
See the sections below, regarding checkout
, update
, and commit
.
The required interval
field gives a period for automation runs, in duration notation;
e.g., "5m"
.
While suspend
has a value of true
, the automation will not run.
Checkout
The checkout value specifies the git repository and branch in which to commit changes:
type GitCheckoutSpec struct {
// GitRepositoryRef refers to the resource giving access details
// to a git repository to update files in.
// +required
GitRepositoryRef corev1.LocalObjectReference `json:"gitRepositoryRef"`
// Branch gives the branch to clone from the git repository.
// +required
Branch string `json:"branch"`
}
The gitRepositoryRef
field names a GitRepository
object in the same
namespace. To be able to commit changes back, the GitRepository
object must refer to credentials
with write access; e.g., if using a GitHub deploy key, "Allow write access" should be checked when
creating it. Only the url
, secretRef
and gitImplementation
(see just below) fields of the
GitRepository
are used.
The branch
field names the branch in the git repository to check out; this will also be the branch
the controller pushes commits to.
Git implementation
The gitImplementation
field controls which git library is used. This will matter if you run on
Azure, and possibly otherwise -- see the source controller documentation for more
details.
Update strategy
The update
field specifies how to carry out updates on the git repository. There is one strategy
possible at present -- {strategy: Setters}
. This field may be left empty, to default to that
value.
// UpdateStrategyName is the type for names that go in
// .update.strategy. NB the value in the const immediately below.
// +kubebuilder:validation:Enum=Setters
type UpdateStrategyName string
const (
// UpdateStrategySetters is the name of the update strategy that
// uses kyaml setters. NB the value in the enum annotation for the
// type, above.
UpdateStrategySetters UpdateStrategyName = "Setters"
)
// UpdateStrategy is a union of the various strategies for updating
// the Git repository. Parameters for each strategy (if any) can be
// inlined here.
type UpdateStrategy struct {
// Strategy names the strategy to be used.
// +required
Strategy UpdateStrategyName `json:"strategy"`
}
Setters strategy
At present, there is one strategy: "Setters". This uses field markers referring to image policies, as described in the image automation guide.
Commit
The commit field specifies how to construct a commit, once changes have been made to the files according to the update strategy.
// CommitSpec specifies how to commit changes to the git repository
type CommitSpec struct {
// AuthorName gives the name to provide when making a commit
// +required
AuthorName string `json:"authorName"`
// AuthorEmail gives the email to provide when making a commit
// +required
AuthorEmail string `json:"authorEmail"`
// MessageTemplate provides a template for the commit message,
// into which will be interpolated the details of the change made.
// +optional
MessageTemplate string `json:"messageTemplate,omitempty"`
}
The authorName
and authorEmail
are used together to give the author of the commit. For example,
spec:
# checkout, update, etc.
commit:
authorName: Fluxbot
authorEmail: flux@example.com
will result in commits with the author Fluxbot <flux@example.com>
.
The messageTemplate
field is a string which will be used as a template for the commit message. If
empty, there is a default message; but you will likely want to provide your own, especially if you
want to put tokens in to control how CI reacts to commits made by automation. For example,
spec:
commit:
messsageTemplate: |
Automated image update by Flux
[ci skip]
Commit template data
The message template is a Go text template. The data available to the template have this structure (not reproduced verbatim):
// controllers/imageupdateautomation_controller.go
// TemplateData is the type of the value given to the commit message
// template.
type TemplateData struct {
AutomationObject struct {
Name, Namespace string
}
Updated update.Result
}
// pkg/update/result.go
// ImageRef represents the image reference used to replace a field
// value in an update.
type ImageRef interface {
// String returns a string representation of the image ref as it
// is used in the update; e.g., "helloworld:v1.0.1"
String() string
// Identifier returns the tag or digest; e.g., "v1.0.1"
Identifier() string
// Repository returns the repository component of the ImageRef,
// with an implied defaults, e.g., "library/helloworld"
Repository() string
// Registry returns the registry component of the ImageRef, e.g.,
// "index.docker.io"
Registry() string
// Name gives the fully-qualified reference name, e.g.,
// "index.docker.io/library/helloworld:v1.0.1"
Name() string
}
// 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
}
// Result reports the outcome of an automated update. It has a nested
// structure file->objects->images. Different projections (e.g., all
// the images, regardless of object) are available via methods.
type Result struct {
Files map[string]FileResult
}
// FileResult gives the updates in a particular file.
type FileResult struct {
Objects map[ObjectIdentifier][]ImageRef
}
These methods are defined on update.Result
:
// Images returns all the images that were involved in at least one
// update.
func (r Result) Images() []ImageRef {
// ...
}
// Objects returns a map of all the objects against the images updated
// within, regardless of which file they appear in.
func (r Result) Objects() map[ObjectIdentifier][]ImageRef {
// ...
}
The methods let you range over the objects and images without descending the data structure. Here's an example of using the fields and methods in a template:
spec:
commit:
messsageTemplate: |
Automated image update
Automation name: {{ .AutomationObject }}
Files:
{{ range $filename, $_ := .Updated.Files -}}
- {{ $filename }}
{{ end -}}
Objects:
{{ range $resource, $_ := .Updated.Objects -}}
- {{ $resource.Kind }} {{ $resource.Name }}
{{ end -}}
Images:
{{ range .Updated.Images -}}
- {{.}}
{{ end -}}
Status
The status of an ImageUpdateAutomation
object records the result of the last automation run.
// ImageUpdateAutomationStatus defines the observed state of ImageUpdateAutomation
type ImageUpdateAutomationStatus struct {
// LastAutomationRunTime records the last time the controller ran
// this automation through to completion (even if no updates were
// made).
// +optional
LastAutomationRunTime *metav1.Time `json:"lastAutomationRunTime,omitempty"`
// LastPushCommit records the SHA1 of the last commit made by the
// controller, for this automation object
// +optional
LastPushCommit string `json:"lastPushCommit,omitempty"`
// LastPushTime records the time of the last pushed change.
// +optional
LastPushTime *metav1.Time `json:"lastPushTime,omitempty"`
// +optional
ObservedGeneration int64 `json:"observedGeneration,omitempty"`
// +optional
Conditions []metav1.Condition `json:"conditions,omitempty"`
meta.ReconcileRequestStatus `json:",inline"`
}
The lastAutomationRunTime
gives the time of the last automation run, whether or not it made a
commit. The lastPushCommit
field records the SHA1 hash of the last commit pushed to the origin git
repository, and the lastPushTime
gives the time that push occurred.
Conditions
There is one condition maintained by the controller, which is the usual ReadyCondition
condition. This will be recorded as True
when automation has run without errors, whether or not it
resulted in a commit.