838 lines
27 KiB
Markdown
838 lines
27 KiB
Markdown
<!-- -*- fill-column: 100 -*- -->
|
|
# Image Update Automations
|
|
|
|
<!-- menuweight:50 -->
|
|
|
|
The `ImageUpdateAutomation` type defines an automation process that will update a git repository,
|
|
based on image policy 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][image-auto-guide].
|
|
|
|
The v1beta1 version of the API has the same schema and semantics as the v1alpha2 version. To migrate
|
|
from v1alpha2, all that is required is to change the `apiVersion` field in manifests to the new
|
|
version:
|
|
|
|
```yaml
|
|
apiVersion: image.toolkit.fluxcd.io/v1beta1
|
|
```
|
|
|
|
Note that v1alpha2 resources will be implicitly and losslessly converted to v1beta1 resources. Until
|
|
v1alpha2 is deprecated, it is possible to keep using v1alpha2.
|
|
|
|
To see what has changed between the API version **`v1alpha1`** and this version `v1beta1`, read [the
|
|
section on migration](#migrating-from-v1alpha1) at the bottom. (If you have already migrated from
|
|
v1alpha1 to v1alpha2, all you need to do is change the version, as above.)
|
|
|
|
## Specification
|
|
|
|
```go
|
|
// ImageUpdateAutomationSpec defines the desired state of ImageUpdateAutomation
|
|
type ImageUpdateAutomationSpec struct {
|
|
// SourceRef refers to the resource giving access details
|
|
// to a git repository.
|
|
// +required
|
|
SourceRef CrossNamespaceSourceReference `json:"sourceRef"`
|
|
// GitSpec contains all the git-specific definitions. This is
|
|
// technically optional, but in practice mandatory until there are
|
|
// other kinds of source allowed.
|
|
// +optional
|
|
GitSpec *GitSpec `json:"git,omitempty"`
|
|
|
|
// 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"`
|
|
|
|
// 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"`
|
|
}
|
|
```
|
|
|
|
The `sourceRef` field refers to the `GitRepository` object that has details on how to access the Git
|
|
repository to be updated. The `kind` field in the reference currently only supports the value
|
|
`GitRepository`, which is the default.
|
|
|
|
```go
|
|
// CrossNamespaceSourceReference contains enough information to let you locate the
|
|
// typed Kubernetes resource object at cluster level.
|
|
type CrossNamespaceSourceReference struct {
|
|
// API version of the referent.
|
|
// +optional
|
|
APIVersion string `json:"apiVersion,omitempty"`
|
|
|
|
// Kind of the referent.
|
|
// +kubebuilder:validation:Enum=GitRepository
|
|
// +kubebuilder:default=GitRepository
|
|
// +required
|
|
Kind string `json:"kind"`
|
|
|
|
// Name of the referent.
|
|
// +required
|
|
Name string `json:"name"`
|
|
|
|
// Namespace of the referent, defaults to the namespace of the Kubernetes resource object that contains the reference.
|
|
// +optional
|
|
Namespace string `json:"namespace,omitempty"`
|
|
}
|
|
```
|
|
|
|
### Cross-namespace references
|
|
|
|
A ImageUpdateAutomation can refer to a GitRepository from a different namespace with
|
|
`spec.sourceRef.namespace` e.g.:
|
|
|
|
```yaml
|
|
apiVersion: image.toolkit.fluxcd.io/v1beta1
|
|
kind: ImageUpdateAutomation
|
|
metadata:
|
|
name: webapp
|
|
namespace: apps
|
|
spec:
|
|
interval: 5m
|
|
sourceRef:
|
|
kind: GitRepository # the only valid value, but good practice to be explicit here
|
|
name: apps
|
|
namespace: flux-system
|
|
```
|
|
|
|
On multi-tenant clusters, platform admins can disable cross-namespace references with the
|
|
`--no-cross-namespace-refs=true` flag.
|
|
|
|
To be able to commit changes back, the referenced `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`, `ref`, and `secretRef` fields of the `GitRepository` are used.
|
|
|
|
The [`gitImplementation` field][source-docs] in the referenced `GitRepository` is ignored. All
|
|
reconciliations are executed using the `go-git` implementation.
|
|
|
|
Other fields particular to how the Git repository is used are in the `git` field, [described
|
|
below](#git-specific-specification).
|
|
|
|
The `update` field is described in [its own section below](update-strategy).
|
|
|
|
The required field `interval` gives a period for automation runs, in [duration notation][durations];
|
|
e.g., `"5m"`.
|
|
|
|
While `suspend` has a value of `true`, the automation will not run.
|
|
|
|
## Git-specific specification
|
|
|
|
The `git` field has this definition:
|
|
|
|
```go
|
|
type GitSpec struct {
|
|
// Checkout gives the parameters for cloning the git repository,
|
|
// ready to make changes. If not present, the `spec.ref` field from the
|
|
// referenced `GitRepository` or its default will be used.
|
|
// +optional
|
|
Checkout *GitCheckoutSpec `json:"checkout,omitempty"`
|
|
|
|
// Commit specifies how to commit to the git repository.
|
|
// +required
|
|
Commit CommitSpec `json:"commit"`
|
|
|
|
// Push specifies how and where to push commits made by the
|
|
// automation. If missing, commits are pushed (back) to
|
|
// `.spec.checkout.branch` or its default.
|
|
// +optional
|
|
Push *PushSpec `json:"push,omitempty"`
|
|
}
|
|
```
|
|
|
|
The fields `checkout`, `commit` and `push` are explained in the following sections.
|
|
|
|
### Checkout
|
|
|
|
The optional `.spec.git.checkout` gives the Git reference to check out. The `.ref` value is the same
|
|
format as the `.ref` field in a [`GitRepository`][git-repo-ref].
|
|
|
|
```go
|
|
type GitCheckoutSpec struct {
|
|
// Reference gives a branch, tag or commit to clone from the Git
|
|
// repository.
|
|
// +required
|
|
Reference sourcev1.GitRepositoryRef `json:"ref"`
|
|
}
|
|
```
|
|
|
|
When `checkout` is given, it overrides the analogous field in the `GitRepository` object referenced
|
|
in `.spec.sourceRef`. You would use this to put automation commits on a different branch than that
|
|
you are syncing, for example.
|
|
|
|
By default the controller will only do shallow clones, but this can be disabled by starting the controller
|
|
with `--feature-gates=GitShallowClone=false`.
|
|
|
|
### Commit
|
|
|
|
The `.spec.git.commit` field gives details to use when making a commit to push to the Git repository:
|
|
|
|
```go
|
|
// CommitSpec specifies how to commit changes to the git repository
|
|
type CommitSpec struct {
|
|
// Author gives the email and optionally the name to use as the
|
|
// author of commits.
|
|
// +required
|
|
Author CommitUser `json:"author"`
|
|
// SigningKey provides the option to sign commits with a GPG key
|
|
// +optional
|
|
SigningKey *SigningKey `json:"signingKey,omitempty"`
|
|
// 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"`
|
|
}
|
|
|
|
type CommitUser struct {
|
|
// Name gives the name to provide when making a commit.
|
|
// +optional
|
|
Name string `json:"name,omitempty"`
|
|
// Email gives the email to provide when making a commit.
|
|
// +required
|
|
Email string `json:"email"`
|
|
}
|
|
|
|
// SigningKey references a Kubernetes secret that contains a GPG keypair
|
|
type SigningKey struct {
|
|
// SecretRef holds the name to a secret that contains a 'git.asc' key
|
|
// corresponding to the ASCII Armored file containing the GPG signing
|
|
// keypair as the value. It must be in the same namespace as the
|
|
// ImageUpdateAutomation.
|
|
// +required
|
|
SecretRef meta.LocalObjectReference `json:"secretRef,omitempty"`
|
|
}
|
|
```
|
|
|
|
The `author` field gives the author for commits. For example,
|
|
|
|
```yaml
|
|
spec:
|
|
git:
|
|
commit:
|
|
author:
|
|
name: Fluxbot
|
|
email: flux@example.com
|
|
```
|
|
|
|
will result in commits with the author `Fluxbot <flux@example.com>`.
|
|
|
|
The optional `signingKey` field can be used to provide a key to sign commits with. It holds a
|
|
reference to a secret, which is expected to have a file called `git.asc` containing an
|
|
ASCII-armoured PGP key. If the private key is protected by a password, you can specify the same
|
|
in the secret using the `passphrase` key.
|
|
|
|
```yaml
|
|
---
|
|
apiVersion: v1
|
|
kind: Secret
|
|
metadata:
|
|
name: signing-key
|
|
namespace: default
|
|
stringData:
|
|
git.asc: |
|
|
<ARMOR ENCODED PGP KEY>
|
|
passphrase: <private-key-passphrase>
|
|
```
|
|
|
|
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,
|
|
|
|
```yaml
|
|
spec:
|
|
git:
|
|
commit:
|
|
messageTemplate: |
|
|
Automated image update by Flux
|
|
|
|
[ci skip]
|
|
```
|
|
|
|
The following section describes what data is available to use in the template.
|
|
|
|
#### Commit message template data
|
|
|
|
The message template is a [Go text template][go-text-template]. The data available to the template
|
|
have this structure (not reproduced verbatim):
|
|
|
|
```go
|
|
// internal/controller/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`:
|
|
|
|
```go
|
|
// 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:
|
|
|
|
```yaml
|
|
spec:
|
|
commit:
|
|
messageTemplate: |
|
|
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 -}}
|
|
```
|
|
#### Commit Message with Template functions
|
|
|
|
With template functions, it is possible to manipulate and transform the supplied data in order to generate more complex commit messages.
|
|
|
|
```yaml
|
|
kind: ImageUpdateAutomation
|
|
metadata:
|
|
name: flux-system
|
|
spec:
|
|
git:
|
|
commit:
|
|
messageTemplate: |
|
|
Automated image update
|
|
|
|
Automation name: {{ .AutomationObject }}
|
|
|
|
Files:
|
|
{{ range $filename, $_ := .Updated.Files -}}
|
|
- {{ $filename }}
|
|
{{ end -}}
|
|
|
|
Objects:
|
|
{{ range $resource, $_ := .Updated.Objects -}}
|
|
- {{ $resource.Kind | lower }} {{ $resource.Name | lower }}
|
|
{{ end -}}
|
|
|
|
Images:
|
|
{{ range $image, $_ := .Updated.Images -}}
|
|
{{ if contains "1.0.0" $image -}}
|
|
- {{ $image }}
|
|
{{ else -}}
|
|
[skip ci] wrong image
|
|
{{ end -}}
|
|
{{ end -}}
|
|
author:
|
|
email: fluxcdbot@users.noreply.github.com
|
|
name: fluxcdbot
|
|
```
|
|
There are over 70 available functions. Some of them are defined by the [Go template language](https://pkg.go.dev/text/template) itself. Most of the others are part of the [Sprig template library](http://masterminds.github.io/sprig/).
|
|
|
|
### Push
|
|
|
|
The optional `push` field defines how commits are pushed to the origin.
|
|
|
|
```go
|
|
// PushSpec specifies how and where to push commits.
|
|
type PushSpec struct {
|
|
// Branch specifies that commits should be pushed to the branch
|
|
// named. The branch is created using `.spec.checkout.branch` as the
|
|
// starting point, if it doesn't already exist.
|
|
// +optional
|
|
Branch string `json:"branch,omitempty"`
|
|
|
|
// Refspec specifies the Git Refspec to use for a push operation.
|
|
// If both Branch and Refspec are provided, then the commit is pushed
|
|
// to the branch and also using the specified refspec.
|
|
// For more details about Git Refspecs, see:
|
|
// https://git-scm.com/book/en/v2/Git-Internals-The-Refspec
|
|
// +optional
|
|
Refspec string `json:"refspec,omitempty"`
|
|
|
|
// Options specifies the push options that are sent to the Git
|
|
// server when performing a push operation. For details, see:
|
|
// https://git-scm.com/docs/git-push#Documentation/git-push.txt---push-optionltoptiongt
|
|
Options map[string]string `json:"options,omitempty"`
|
|
}
|
|
```
|
|
|
|
If `.push` is not present, commits are made on the branch given in `.spec.git.checkout.branch` and
|
|
pushed to the same branch at the origin. If `.spec.git.checkout` is not present, it will fall back
|
|
to the branch given in the `GitRepository` referenced by `.spec.sourceRef`. If none of these yield a
|
|
branch name, the automation will fail.
|
|
|
|
If `.push.refspec` is present, the refspec specified is used to perform the push operation.
|
|
An example of a valid refspec is `refs/heads/branch:refs/heads/branch`. This allows users to
|
|
push to an arbitary destination reference.
|
|
|
|
If `.push.branch` is present, the specified branch is pushed to at the origin. The branch
|
|
will be created locally if it does not already exist, starting from the checkout branch. If it does
|
|
already exist, 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 `--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.
|
|
|
|
If both `.push.refspec` and `.push.branch` are specified, then the reconciler will perform
|
|
two push operations, one to the specified branch and another using the specified refspec.
|
|
This is particularly useful for working with Gerrit servers. For more information about this,
|
|
please refer to the [Gerrit](#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 to perform the second push
|
|
operation and error out with an `already up-to-date` error.
|
|
|
|
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:
|
|
|
|
```yaml
|
|
spec:
|
|
git:
|
|
checkout:
|
|
ref:
|
|
branch: main
|
|
push:
|
|
branch: auto
|
|
```
|
|
|
|
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:
|
|
|
|
```yaml
|
|
spec:
|
|
git:
|
|
checkout:
|
|
ref:
|
|
branch: main
|
|
push:
|
|
refspec: refs/heads/main:refs/heads/auto
|
|
```
|
|
|
|
To specify the [push options](https://git-scm.com/docs/git-push#Documentation/git-push.txt---push-optionltoptiongt)
|
|
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:
|
|
|
|
```yaml
|
|
spec:
|
|
git:
|
|
push:
|
|
branch: dev
|
|
options:
|
|
merge_request.create: ""
|
|
merge_request.target: release
|
|
```
|
|
|
|
#### Gerrit
|
|
|
|
[Gerrit](https://www.gerritcodereview.com/) 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:
|
|
|
|
```yaml
|
|
spec:
|
|
git:
|
|
checkout:
|
|
ref:
|
|
branch: main
|
|
commit:
|
|
author:
|
|
email: flux@localdomain
|
|
name: flux
|
|
messageTemplate: |
|
|
Perform automatic 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 }}
|
|
{{- $ChangeId := .AutomationObject -}}
|
|
{{- $ChangeId = printf "%s%s" $ChangeId ( .Updated.Files | toString ) -}}
|
|
{{- $ChangeId = printf "%s%s" $ChangeId ( .Updated.Objects | toString ) -}}
|
|
{{- $ChangeId = printf "%s%s" $ChangeId ( .Updated.Images | 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](https://gerrit-review.googlesource.com/Documentation/concept-changes.html#change-id)
|
|
at the bottom of the commit message.
|
|
|
|
The initial branch push aims to prevent multiple
|
|
[Patch Sets](https://gerrit-review.googlesource.com/Documentation/concept-patch-sets.html).
|
|
If we exclude `.push.branch` and only specify
|
|
`.push.refspec: refs/heads/main:refs/heads/main`, the desired [Change](https://gerrit-review.googlesource.com/Documentation/concept-changes.html)
|
|
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](https://gerrit-review.googlesource.com/Documentation/intro-gerrit-walkthrough-github.html#create-change).
|
|
|
|
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.
|
|
|
|
## Update strategy
|
|
|
|
The `.spec.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.
|
|
|
|
```go
|
|
// 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
|
|
// +kubebuilder:default=Setters
|
|
Strategy UpdateStrategyName `json:"strategy"`
|
|
|
|
// Path to the directory containing the manifests to be updated.
|
|
// Defaults to 'None', which translates to the root path
|
|
// of the GitRepositoryRef.
|
|
// +optional
|
|
Path string `json:"path,omitempty"`
|
|
}
|
|
```
|
|
|
|
**Setters strategy**
|
|
|
|
At present, there is one strategy: "Setters". This uses field markers referring to image policies,
|
|
as described in the [image automation guide][image-auto-guide].
|
|
|
|
## Status
|
|
|
|
The status of an `ImageUpdateAutomation` object records the result of the last automation run.
|
|
|
|
```go
|
|
// 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.
|
|
|
|
## Migrating from `v1alpha1`
|
|
|
|
For the most part, `v1alpha2` rearranges the API types to provide for future extension. Here are the
|
|
differences, and where each `v1alpha1` field goes. A full example appears after the table.
|
|
|
|
### Moves and changes
|
|
|
|
| `v1alpha1` field | change in `v1alpha2` |
|
|
|------------------|----------------------|
|
|
| .spec.checkout | moved to `.spec.git.checkout`, and optional |
|
|
| | `gitRepositoryRef` is now `.spec.sourceRef` |
|
|
| | `branch` is now `ref`, and optional |
|
|
| .spec.commit | moved to `.spec.git.commit` |
|
|
| | `authorName` and `authorEmail` now `author.name` and `author.email` |
|
|
| .spec.push | moved to `.spec.git.push` |
|
|
|
|
### Example of rewriting a v1alpha1 object to v1alpha2
|
|
|
|
This example shows the steps to rewrite a v1alpha1 ImageUpdateAutomation YAML to be a v1alpha2 YAML.
|
|
|
|
This is the v1alpha1 original:
|
|
|
|
```yaml
|
|
apiVersion: image.toolkit.fluxcd.io/v1alpha1
|
|
kind: ImageUpdateAutomation
|
|
spec:
|
|
checkout:
|
|
gitRepositoryRef:
|
|
name: auto-repo
|
|
branch: main
|
|
interval: 5m
|
|
# omit suspend, which has not changed
|
|
update:
|
|
strategy: Setters
|
|
path: ./app
|
|
commit:
|
|
authorName: fluxbot
|
|
authorEmail: fluxbot@example.com
|
|
messageTemplate: |
|
|
An automated update from FluxBot
|
|
[ci skip]
|
|
signingKey:
|
|
secretRef:
|
|
name: git-pgp
|
|
push:
|
|
branch: auto
|
|
```
|
|
|
|
**Change the API version**
|
|
|
|
The API version is now `image.toolkit.fluxcd.io/v1beta1`:
|
|
|
|
```yaml
|
|
apiVersion: image.toolkit.fluxcd.io/v1alpha1
|
|
|
|
# becomes
|
|
|
|
apiVersion: image.toolkit.fluxcd.io/v1beta1
|
|
```
|
|
|
|
**Move and adapt `.spec.checkout.gitRepositoryRef` to `.spec.sourceRef` and `.spec.git.checkout`**
|
|
|
|
The reference to a `GitRepository` object has moved to the field `sourceRef`. The `checkout` field
|
|
moves under the `git` key, with the branch to checkout in a structure under `ref`.
|
|
|
|
```yaml
|
|
spec:
|
|
checkout:
|
|
gitRepositoryRef:
|
|
name: auto-repo
|
|
branch:
|
|
main
|
|
|
|
# becomes
|
|
|
|
spec:
|
|
sourceRef:
|
|
kind: GitRepository # the default, but good practice to be explicit here
|
|
name: auto-repo
|
|
git:
|
|
checkout:
|
|
ref:
|
|
branch: main
|
|
```
|
|
|
|
Note that `.spec.git.checkout` is now optional. If not supplied, the `.spec.ref` field from the
|
|
`GitRepository` object is used as the checkout for updates.
|
|
|
|
**Move and adapt `.spec.commit` to `spec.git.commit`**
|
|
|
|
The `commit` field also moves under the `git` key, and the author is a structure rather than two
|
|
fields.
|
|
|
|
```yaml
|
|
spec:
|
|
commit:
|
|
authorName: fluxbot
|
|
authorEmail: fluxbot@example.com
|
|
messageTemplate: |
|
|
An automated update from FluxBot
|
|
[ci skip]
|
|
signingKey:
|
|
secretRef:
|
|
name: git-pgp
|
|
|
|
# becomes
|
|
|
|
spec:
|
|
git:
|
|
commit:
|
|
author:
|
|
name: fluxbot
|
|
email: fluxbot@example.com
|
|
messageTemplate: |
|
|
An automated update from FluxBot
|
|
[ci skip]
|
|
signingKey:
|
|
secretRef:
|
|
name: git-pgp
|
|
```
|
|
|
|
**Move `.spec.push` to `.spec.git.push`**
|
|
|
|
The field `push` moves under the `git` key.
|
|
|
|
```yaml
|
|
spec:
|
|
push:
|
|
branch: auto
|
|
|
|
# becomes
|
|
|
|
spec:
|
|
git:
|
|
push:
|
|
branch: auto
|
|
```
|
|
|
|
**Overall result**
|
|
|
|
The final YAML looks like this:
|
|
|
|
```yaml
|
|
apiVersion: image.toolkit.fluxcd.io/v1beta1
|
|
kind: ImageUpdateAutomation
|
|
spec:
|
|
sourceRef: # moved from `.spec.checkout`
|
|
kind: GitRepository
|
|
name: auto-repo
|
|
interval: 5m
|
|
# omit suspend, which has not changed
|
|
update:
|
|
strategy: Setters
|
|
path: ./app
|
|
git:
|
|
checkout: # moved under `git`, loses `gitRepositoryRef`
|
|
ref:
|
|
branch: main # moved into `ref` struct
|
|
commit: # moved under `git`
|
|
author:
|
|
name: fluxbot # moved from `authorName`
|
|
email: fluxbot@example.com # moved from `authorEmail`
|
|
messageTemplate: |
|
|
An automated update from FluxBot
|
|
[ci skip]
|
|
signingKey:
|
|
secretRef:
|
|
name: git-pgp
|
|
push: # moved under `git`
|
|
branch: auto
|
|
```
|
|
|
|
[image-auto-guide]: https://fluxcd.io/flux/guides/image-update/#configure-image-update-for-custom-resources
|
|
[git-repo-ref]: https://fluxcd.io/flux/components/source/gitrepositories/#writing-a-gitrepository-spec
|
|
[durations]: https://godoc.org/time#ParseDuration
|
|
[source-docs]: https://fluxcd.io/flux/components/source/api/v1beta2/#source.toolkit.fluxcd.io/v1beta2.GitRepositorySpec
|
|
[go-text-template]: https://golang.org/pkg/text/template/
|