GitRepo: Add observed content config in status
Replace content config checksum with explicit artifact content config observations. It makes the observations of the controller more transparent and easier to debug. Introduces `observedIgnore`, `observedRecurseSubmodules` and `observedInclude` status fields. Signed-off-by: Sunny <darkowlzz@protonmail.com>
This commit is contained in:
parent
278a223bc6
commit
e996848555
|
@ -224,9 +224,27 @@ type GitRepositoryStatus struct {
|
||||||
// be used to determine if the content of the included repository has
|
// be used to determine if the content of the included repository has
|
||||||
// changed.
|
// changed.
|
||||||
// It has the format of `<algo>:<checksum>`, for example: `sha256:<checksum>`.
|
// It has the format of `<algo>:<checksum>`, for example: `sha256:<checksum>`.
|
||||||
|
//
|
||||||
|
// Deprecated: Replaced with explicit fields for observed artifact content
|
||||||
|
// config in the status.
|
||||||
// +optional
|
// +optional
|
||||||
ContentConfigChecksum string `json:"contentConfigChecksum,omitempty"`
|
ContentConfigChecksum string `json:"contentConfigChecksum,omitempty"`
|
||||||
|
|
||||||
|
// ObservedIgnore is the observed exclusion patterns used for constructing
|
||||||
|
// the source artifact.
|
||||||
|
// +optional
|
||||||
|
ObservedIgnore *string `json:"observedIgnore,omitempty"`
|
||||||
|
|
||||||
|
// ObservedRecurseSubmodules is the observed resource submodules
|
||||||
|
// configuration used to produce the current Artifact.
|
||||||
|
// +optional
|
||||||
|
ObservedRecurseSubmodules bool `json:"observedRecurseSubmodules,omitempty"`
|
||||||
|
|
||||||
|
// ObservedInclude is the observed list of GitRepository resources used to
|
||||||
|
// to produce the current Artifact.
|
||||||
|
// +optional
|
||||||
|
ObservedInclude []GitRepositoryInclude `json:"observedInclude,omitempty"`
|
||||||
|
|
||||||
meta.ReconcileRequestStatus `json:",inline"`
|
meta.ReconcileRequestStatus `json:",inline"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -346,6 +346,16 @@ func (in *GitRepositoryStatus) DeepCopyInto(out *GitRepositoryStatus) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if in.ObservedIgnore != nil {
|
||||||
|
in, out := &in.ObservedIgnore, &out.ObservedIgnore
|
||||||
|
*out = new(string)
|
||||||
|
**out = **in
|
||||||
|
}
|
||||||
|
if in.ObservedInclude != nil {
|
||||||
|
in, out := &in.ObservedInclude, &out.ObservedInclude
|
||||||
|
*out = make([]GitRepositoryInclude, len(*in))
|
||||||
|
copy(*out, *in)
|
||||||
|
}
|
||||||
out.ReconcileRequestStatus = in.ReconcileRequestStatus
|
out.ReconcileRequestStatus = in.ReconcileRequestStatus
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -658,13 +658,14 @@ spec:
|
||||||
type: object
|
type: object
|
||||||
type: array
|
type: array
|
||||||
contentConfigChecksum:
|
contentConfigChecksum:
|
||||||
description: 'ContentConfigChecksum is a checksum of all the configurations
|
description: "ContentConfigChecksum is a checksum of all the configurations
|
||||||
related to the content of the source artifact: - .spec.ignore -
|
related to the content of the source artifact: - .spec.ignore -
|
||||||
.spec.recurseSubmodules - .spec.included and the checksum of the
|
.spec.recurseSubmodules - .spec.included and the checksum of the
|
||||||
included artifacts observed in .status.observedGeneration version
|
included artifacts observed in .status.observedGeneration version
|
||||||
of the object. This can be used to determine if the content of the
|
of the object. This can be used to determine if the content of the
|
||||||
included repository has changed. It has the format of `<algo>:<checksum>`,
|
included repository has changed. It has the format of `<algo>:<checksum>`,
|
||||||
for example: `sha256:<checksum>`.'
|
for example: `sha256:<checksum>`. \n Deprecated: Replaced with explicit
|
||||||
|
fields for observed artifact content config in the status."
|
||||||
type: string
|
type: string
|
||||||
includedArtifacts:
|
includedArtifacts:
|
||||||
description: IncludedArtifacts contains a list of the last successfully
|
description: IncludedArtifacts contains a list of the last successfully
|
||||||
|
@ -723,6 +724,44 @@ spec:
|
||||||
the GitRepository object.
|
the GitRepository object.
|
||||||
format: int64
|
format: int64
|
||||||
type: integer
|
type: integer
|
||||||
|
observedIgnore:
|
||||||
|
description: ObservedIgnore is the observed exclusion patterns used
|
||||||
|
for constructing the source artifact.
|
||||||
|
type: string
|
||||||
|
observedInclude:
|
||||||
|
description: ObservedInclude is the observed list of GitRepository
|
||||||
|
resources used to to produce the current Artifact.
|
||||||
|
items:
|
||||||
|
description: GitRepositoryInclude specifies a local reference to
|
||||||
|
a GitRepository which Artifact (sub-)contents must be included,
|
||||||
|
and where they should be placed.
|
||||||
|
properties:
|
||||||
|
fromPath:
|
||||||
|
description: FromPath specifies the path to copy contents from,
|
||||||
|
defaults to the root of the Artifact.
|
||||||
|
type: string
|
||||||
|
repository:
|
||||||
|
description: GitRepositoryRef specifies the GitRepository which
|
||||||
|
Artifact contents must be included.
|
||||||
|
properties:
|
||||||
|
name:
|
||||||
|
description: Name of the referent.
|
||||||
|
type: string
|
||||||
|
required:
|
||||||
|
- name
|
||||||
|
type: object
|
||||||
|
toPath:
|
||||||
|
description: ToPath specifies the path to copy contents to,
|
||||||
|
defaults to the name of the GitRepositoryRef.
|
||||||
|
type: string
|
||||||
|
required:
|
||||||
|
- repository
|
||||||
|
type: object
|
||||||
|
type: array
|
||||||
|
observedRecurseSubmodules:
|
||||||
|
description: ObservedRecurseSubmodules is the observed resource submodules
|
||||||
|
configuration used to produce the current Artifact.
|
||||||
|
type: boolean
|
||||||
url:
|
url:
|
||||||
description: URL is the dynamic fetch link for the latest Artifact.
|
description: URL is the dynamic fetch link for the latest Artifact.
|
||||||
It is provided on a "best effort" basis, and using the precise GitRepositoryStatus.Artifact
|
It is provided on a "best effort" basis, and using the precise GitRepositoryStatus.Artifact
|
||||||
|
|
|
@ -18,12 +18,10 @@ package controllers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"crypto/sha256"
|
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strconv"
|
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
@ -33,6 +31,7 @@ import (
|
||||||
"k8s.io/apimachinery/pkg/runtime"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
"k8s.io/apimachinery/pkg/types"
|
"k8s.io/apimachinery/pkg/types"
|
||||||
kuberecorder "k8s.io/client-go/tools/record"
|
kuberecorder "k8s.io/client-go/tools/record"
|
||||||
|
"k8s.io/utils/pointer"
|
||||||
ctrl "sigs.k8s.io/controller-runtime"
|
ctrl "sigs.k8s.io/controller-runtime"
|
||||||
"sigs.k8s.io/controller-runtime/pkg/builder"
|
"sigs.k8s.io/controller-runtime/pkg/builder"
|
||||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||||
|
@ -507,8 +506,8 @@ func (r *GitRepositoryReconciler) reconcileSource(ctx context.Context,
|
||||||
// If it's a partial commit obtained from an existing artifact, check if the
|
// If it's a partial commit obtained from an existing artifact, check if the
|
||||||
// reconciliation can be skipped if other configurations have not changed.
|
// reconciliation can be skipped if other configurations have not changed.
|
||||||
if !git.IsConcreteCommit(*commit) {
|
if !git.IsConcreteCommit(*commit) {
|
||||||
// Calculate content configuration checksum.
|
// Check if the content config contributing to the artifact has changed.
|
||||||
if r.calculateContentConfigChecksum(obj, includes) == obj.Status.ContentConfigChecksum {
|
if !gitContentConfigChanged(obj, includes) {
|
||||||
ge := serror.NewGeneric(
|
ge := serror.NewGeneric(
|
||||||
fmt.Errorf("no changes since last reconcilation: observed revision '%s'",
|
fmt.Errorf("no changes since last reconcilation: observed revision '%s'",
|
||||||
commit.String()), sourcev1.GitOperationSucceedReason,
|
commit.String()), sourcev1.GitOperationSucceedReason,
|
||||||
|
@ -559,27 +558,24 @@ func (r *GitRepositoryReconciler) reconcileSource(ctx context.Context,
|
||||||
//
|
//
|
||||||
// The inspection of the given data to the object is differed, ensuring any
|
// The inspection of the given data to the object is differed, ensuring any
|
||||||
// stale observations like v1beta2.ArtifactOutdatedCondition are removed.
|
// stale observations like v1beta2.ArtifactOutdatedCondition are removed.
|
||||||
// If the given Artifact and/or artifactSet (includes) and the content config
|
// If the given Artifact and/or artifactSet (includes) and observed artifact
|
||||||
// checksum do not differ from the object's current, it returns early.
|
// content config do not differ from the object's current, it returns early.
|
||||||
// Source ignore patterns are loaded, and the given directory is archived while
|
// Source ignore patterns are loaded, and the given directory is archived while
|
||||||
// taking these patterns into account.
|
// taking these patterns into account.
|
||||||
// On a successful archive, the Artifact, Includes and new content config
|
// On a successful archive, the Artifact, Includes, observed ignore, recurse
|
||||||
// checksum in the Status of the object are set, and the symlink in the Storage
|
// submodules and observed include in the Status of the object are set, and the
|
||||||
// is updated to its path.
|
// symlink in the Storage is updated to its path.
|
||||||
func (r *GitRepositoryReconciler) reconcileArtifact(ctx context.Context,
|
func (r *GitRepositoryReconciler) reconcileArtifact(ctx context.Context,
|
||||||
obj *sourcev1.GitRepository, commit *git.Commit, includes *artifactSet, dir string) (sreconcile.Result, error) {
|
obj *sourcev1.GitRepository, commit *git.Commit, includes *artifactSet, dir string) (sreconcile.Result, error) {
|
||||||
|
|
||||||
// Create potential new artifact with current available metadata
|
// Create potential new artifact with current available metadata
|
||||||
artifact := r.Storage.NewArtifactFor(obj.Kind, obj.GetObjectMeta(), commit.String(), fmt.Sprintf("%s.tar.gz", commit.Hash.String()))
|
artifact := r.Storage.NewArtifactFor(obj.Kind, obj.GetObjectMeta(), commit.String(), fmt.Sprintf("%s.tar.gz", commit.Hash.String()))
|
||||||
|
|
||||||
// Calculate the content config checksum.
|
|
||||||
ccc := r.calculateContentConfigChecksum(obj, includes)
|
|
||||||
|
|
||||||
// Set the ArtifactInStorageCondition if there's no drift.
|
// Set the ArtifactInStorageCondition if there's no drift.
|
||||||
defer func() {
|
defer func() {
|
||||||
if obj.GetArtifact().HasRevision(artifact.Revision) &&
|
if obj.GetArtifact().HasRevision(artifact.Revision) &&
|
||||||
!includes.Diff(obj.Status.IncludedArtifacts) &&
|
!includes.Diff(obj.Status.IncludedArtifacts) &&
|
||||||
obj.Status.ContentConfigChecksum == ccc {
|
!gitContentConfigChanged(obj, includes) {
|
||||||
conditions.Delete(obj, sourcev1.ArtifactOutdatedCondition)
|
conditions.Delete(obj, sourcev1.ArtifactOutdatedCondition)
|
||||||
conditions.MarkTrue(obj, sourcev1.ArtifactInStorageCondition, meta.SucceededReason,
|
conditions.MarkTrue(obj, sourcev1.ArtifactInStorageCondition, meta.SucceededReason,
|
||||||
"stored artifact for revision '%s'", artifact.Revision)
|
"stored artifact for revision '%s'", artifact.Revision)
|
||||||
|
@ -589,7 +585,7 @@ func (r *GitRepositoryReconciler) reconcileArtifact(ctx context.Context,
|
||||||
// The artifact is up-to-date
|
// The artifact is up-to-date
|
||||||
if obj.GetArtifact().HasRevision(artifact.Revision) &&
|
if obj.GetArtifact().HasRevision(artifact.Revision) &&
|
||||||
!includes.Diff(obj.Status.IncludedArtifacts) &&
|
!includes.Diff(obj.Status.IncludedArtifacts) &&
|
||||||
obj.Status.ContentConfigChecksum == ccc {
|
!gitContentConfigChanged(obj, includes) {
|
||||||
r.eventLogf(ctx, obj, events.EventTypeTrace, sourcev1.ArtifactUpToDateReason, "artifact up-to-date with remote revision: '%s'", artifact.Revision)
|
r.eventLogf(ctx, obj, events.EventTypeTrace, sourcev1.ArtifactUpToDateReason, "artifact up-to-date with remote revision: '%s'", artifact.Revision)
|
||||||
return sreconcile.ResultSuccess, nil
|
return sreconcile.ResultSuccess, nil
|
||||||
}
|
}
|
||||||
|
@ -652,10 +648,13 @@ func (r *GitRepositoryReconciler) reconcileArtifact(ctx context.Context,
|
||||||
return sreconcile.ResultEmpty, e
|
return sreconcile.ResultEmpty, e
|
||||||
}
|
}
|
||||||
|
|
||||||
// Record it on the object
|
// Record the observations on the object.
|
||||||
obj.Status.Artifact = artifact.DeepCopy()
|
obj.Status.Artifact = artifact.DeepCopy()
|
||||||
obj.Status.IncludedArtifacts = *includes
|
obj.Status.IncludedArtifacts = *includes
|
||||||
obj.Status.ContentConfigChecksum = ccc
|
obj.Status.ContentConfigChecksum = "" // To be removed in the next API version.
|
||||||
|
obj.Status.ObservedIgnore = obj.Spec.Ignore
|
||||||
|
obj.Status.ObservedRecurseSubmodules = obj.Spec.RecurseSubmodules
|
||||||
|
obj.Status.ObservedInclude = obj.Spec.Include
|
||||||
|
|
||||||
// Update symlink on a "best effort" basis
|
// Update symlink on a "best effort" basis
|
||||||
url, err := r.Storage.Symlink(artifact, "latest.tar.gz")
|
url, err := r.Storage.Symlink(artifact, "latest.tar.gz")
|
||||||
|
@ -825,39 +824,6 @@ func (r *GitRepositoryReconciler) fetchIncludes(ctx context.Context, obj *source
|
||||||
return &artifacts, nil
|
return &artifacts, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// calculateContentConfigChecksum calculates a checksum of all the
|
|
||||||
// configurations that result in a change in the source artifact. It can be used
|
|
||||||
// to decide if further reconciliation is needed when an artifact already exists
|
|
||||||
// for a set of configurations.
|
|
||||||
func (r *GitRepositoryReconciler) calculateContentConfigChecksum(obj *sourcev1.GitRepository, includes *artifactSet) string {
|
|
||||||
c := []byte{}
|
|
||||||
// Consider the ignore rules and recurse submodules.
|
|
||||||
if obj.Spec.Ignore != nil {
|
|
||||||
c = append(c, []byte(*obj.Spec.Ignore)...)
|
|
||||||
}
|
|
||||||
c = append(c, []byte(strconv.FormatBool(obj.Spec.RecurseSubmodules))...)
|
|
||||||
|
|
||||||
// Consider the included repository attributes.
|
|
||||||
for _, incl := range obj.Spec.Include {
|
|
||||||
c = append(c, []byte(incl.GitRepositoryRef.Name+incl.FromPath+incl.ToPath)...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Consider the checksum and revision of all the included remote artifact.
|
|
||||||
// This ensures that if the included repos get updated, this checksum changes.
|
|
||||||
// NOTE: The content of an artifact may change at the same revision if the
|
|
||||||
// ignore rules change. Hence, consider both checksum and revision to
|
|
||||||
// capture changes in artifact checksum as well.
|
|
||||||
// TODO: Fix artifactSet.Diff() to consider checksum as well.
|
|
||||||
if includes != nil {
|
|
||||||
for _, incl := range *includes {
|
|
||||||
c = append(c, []byte(incl.Checksum)...)
|
|
||||||
c = append(c, []byte(incl.Revision)...)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return fmt.Sprintf("sha256:%x", sha256.Sum256(c))
|
|
||||||
}
|
|
||||||
|
|
||||||
// verifyCommitSignature verifies the signature of the given Git commit, if a
|
// verifyCommitSignature verifies the signature of the given Git commit, if a
|
||||||
// verification mode is specified on the object.
|
// verification mode is specified on the object.
|
||||||
// If the signature can not be verified or the verification fails, it records
|
// If the signature can not be verified or the verification fails, it records
|
||||||
|
@ -978,3 +944,64 @@ func (r *GitRepositoryReconciler) eventLogf(ctx context.Context, obj runtime.Obj
|
||||||
}
|
}
|
||||||
r.Eventf(obj, eventType, reason, msg)
|
r.Eventf(obj, eventType, reason, msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// gitContentConfigChanged evaluates the current spec with the observations of
|
||||||
|
// the artifact in the status to determine if artifact content configuration has
|
||||||
|
// changed and requires rebuilding the artifact.
|
||||||
|
func gitContentConfigChanged(obj *sourcev1.GitRepository, includes *artifactSet) bool {
|
||||||
|
if !pointer.StringEqual(obj.Spec.Ignore, obj.Status.ObservedIgnore) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if obj.Spec.RecurseSubmodules != obj.Status.ObservedRecurseSubmodules {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if len(obj.Spec.Include) != len(obj.Status.ObservedInclude) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert artifactSet to index addressable artifacts and ensure that it and
|
||||||
|
// the included artifacts include all the include from the spec.
|
||||||
|
artifacts := []*sourcev1.Artifact(*includes)
|
||||||
|
if len(obj.Spec.Include) != len(artifacts) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if len(obj.Spec.Include) != len(obj.Status.IncludedArtifacts) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// The order of spec.include, status.IncludeArtifacts and
|
||||||
|
// status.observedInclude are the same. Compare the values by index.
|
||||||
|
for index, incl := range obj.Spec.Include {
|
||||||
|
observedIncl := obj.Status.ObservedInclude[index]
|
||||||
|
observedInclArtifact := obj.Status.IncludedArtifacts[index]
|
||||||
|
currentIncl := artifacts[index]
|
||||||
|
|
||||||
|
// Check if the include are the same in spec and status.
|
||||||
|
if !gitRepositoryIncludeEqual(incl, observedIncl) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if the included repositories are still the same.
|
||||||
|
if observedInclArtifact.Revision != currentIncl.Revision {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if observedInclArtifact.Checksum != currentIncl.Checksum {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns true if both GitRepositoryIncludes are equal.
|
||||||
|
func gitRepositoryIncludeEqual(a, b sourcev1.GitRepositoryInclude) bool {
|
||||||
|
if a.GitRepositoryRef != b.GitRepositoryRef {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if a.FromPath != b.FromPath {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if a.ToPath != b.ToPath {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
|
@ -143,7 +143,6 @@ Oomb3gD/TRf/nAdVED+k81GdLzciYdUGtI71/qI47G0nMBluLRE=
|
||||||
=/4e+
|
=/4e+
|
||||||
-----END PGP PUBLIC KEY BLOCK-----
|
-----END PGP PUBLIC KEY BLOCK-----
|
||||||
`
|
`
|
||||||
emptyContentConfigChecksum = "sha256:fcbcf165908dd18a9e49f7ff27810176db8e9f63b4352213741664245224f8aa"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -685,8 +684,6 @@ func TestGitRepositoryReconciler_reconcileSource_checkoutStrategy(t *testing.T)
|
||||||
Revision: "staging/" + latestRev,
|
Revision: "staging/" + latestRev,
|
||||||
Path: randStringRunes(10),
|
Path: randStringRunes(10),
|
||||||
},
|
},
|
||||||
// Checksum with all the relevant fields unset.
|
|
||||||
ContentConfigChecksum: emptyContentConfigChecksum,
|
|
||||||
}
|
}
|
||||||
conditions.MarkTrue(obj, sourcev1.ArtifactInStorageCondition, meta.SucceededReason, "foo")
|
conditions.MarkTrue(obj, sourcev1.ArtifactInStorageCondition, meta.SucceededReason, "foo")
|
||||||
},
|
},
|
||||||
|
@ -709,8 +706,6 @@ func TestGitRepositoryReconciler_reconcileSource_checkoutStrategy(t *testing.T)
|
||||||
Revision: "staging/" + latestRev,
|
Revision: "staging/" + latestRev,
|
||||||
Path: randStringRunes(10),
|
Path: randStringRunes(10),
|
||||||
},
|
},
|
||||||
// Checksum with all the relevant fields unset.
|
|
||||||
ContentConfigChecksum: emptyContentConfigChecksum,
|
|
||||||
}
|
}
|
||||||
conditions.MarkTrue(obj, sourcev1.ArtifactInStorageCondition, meta.SucceededReason, "foo")
|
conditions.MarkTrue(obj, sourcev1.ArtifactInStorageCondition, meta.SucceededReason, "foo")
|
||||||
},
|
},
|
||||||
|
@ -835,6 +830,9 @@ func TestGitRepositoryReconciler_reconcileArtifact(t *testing.T) {
|
||||||
includes: artifactSet{&sourcev1.Artifact{Revision: "main/revision"}},
|
includes: artifactSet{&sourcev1.Artifact{Revision: "main/revision"}},
|
||||||
beforeFunc: func(obj *sourcev1.GitRepository) {
|
beforeFunc: func(obj *sourcev1.GitRepository) {
|
||||||
obj.Spec.Interval = metav1.Duration{Duration: interval}
|
obj.Spec.Interval = metav1.Duration{Duration: interval}
|
||||||
|
obj.Spec.Include = []sourcev1.GitRepositoryInclude{
|
||||||
|
{GitRepositoryRef: meta.LocalObjectReference{Name: "foo"}},
|
||||||
|
}
|
||||||
},
|
},
|
||||||
afterFunc: func(t *WithT, obj *sourcev1.GitRepository) {
|
afterFunc: func(t *WithT, obj *sourcev1.GitRepository) {
|
||||||
t.Expect(obj.GetArtifact()).ToNot(BeNil())
|
t.Expect(obj.GetArtifact()).ToNot(BeNil())
|
||||||
|
@ -850,12 +848,15 @@ func TestGitRepositoryReconciler_reconcileArtifact(t *testing.T) {
|
||||||
{
|
{
|
||||||
name: "Up-to-date artifact should not update status",
|
name: "Up-to-date artifact should not update status",
|
||||||
dir: "testdata/git/repository",
|
dir: "testdata/git/repository",
|
||||||
includes: artifactSet{&sourcev1.Artifact{Revision: "main/revision"}},
|
includes: artifactSet{&sourcev1.Artifact{Revision: "main/revision", Checksum: "some-checksum"}},
|
||||||
beforeFunc: func(obj *sourcev1.GitRepository) {
|
beforeFunc: func(obj *sourcev1.GitRepository) {
|
||||||
obj.Spec.Interval = metav1.Duration{Duration: interval}
|
obj.Spec.Interval = metav1.Duration{Duration: interval}
|
||||||
|
obj.Spec.Include = []sourcev1.GitRepositoryInclude{
|
||||||
|
{GitRepositoryRef: meta.LocalObjectReference{Name: "foo"}},
|
||||||
|
}
|
||||||
obj.Status.Artifact = &sourcev1.Artifact{Revision: "main/revision"}
|
obj.Status.Artifact = &sourcev1.Artifact{Revision: "main/revision"}
|
||||||
obj.Status.IncludedArtifacts = []*sourcev1.Artifact{{Revision: "main/revision", Checksum: "some-checksum"}}
|
obj.Status.IncludedArtifacts = []*sourcev1.Artifact{{Revision: "main/revision", Checksum: "some-checksum"}}
|
||||||
obj.Status.ContentConfigChecksum = "sha256:f825d11a1c5987e033d2cb36449a3b0435a6abc9b2bfdbcdcc7c49bf40e9285d"
|
obj.Status.ObservedInclude = obj.Spec.Include
|
||||||
},
|
},
|
||||||
afterFunc: func(t *WithT, obj *sourcev1.GitRepository) {
|
afterFunc: func(t *WithT, obj *sourcev1.GitRepository) {
|
||||||
t.Expect(obj.Status.URL).To(BeEmpty())
|
t.Expect(obj.Status.URL).To(BeEmpty())
|
||||||
|
@ -2145,53 +2146,6 @@ func TestGitRepositoryReconciler_fetchIncludes(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGitRepositoryReconciler_calculateContentConfigChecksum(t *testing.T) {
|
|
||||||
g := NewWithT(t)
|
|
||||||
obj := &sourcev1.GitRepository{}
|
|
||||||
r := &GitRepositoryReconciler{}
|
|
||||||
|
|
||||||
emptyChecksum := r.calculateContentConfigChecksum(obj, nil)
|
|
||||||
g.Expect(emptyChecksum).To(Equal(emptyContentConfigChecksum))
|
|
||||||
|
|
||||||
// Ignore modified.
|
|
||||||
obj.Spec.Ignore = pointer.String("some-rule")
|
|
||||||
ignoreModChecksum := r.calculateContentConfigChecksum(obj, nil)
|
|
||||||
g.Expect(emptyChecksum).ToNot(Equal(ignoreModChecksum))
|
|
||||||
|
|
||||||
// Recurse submodules modified.
|
|
||||||
obj.Spec.RecurseSubmodules = true
|
|
||||||
submodModChecksum := r.calculateContentConfigChecksum(obj, nil)
|
|
||||||
g.Expect(ignoreModChecksum).ToNot(Equal(submodModChecksum))
|
|
||||||
|
|
||||||
// Include modified.
|
|
||||||
obj.Spec.Include = []sourcev1.GitRepositoryInclude{
|
|
||||||
{
|
|
||||||
GitRepositoryRef: meta.LocalObjectReference{Name: "foo"},
|
|
||||||
FromPath: "aaa",
|
|
||||||
ToPath: "bbb",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
artifacts := &artifactSet{
|
|
||||||
&sourcev1.Artifact{Revision: "some-revision-1", Checksum: "some-checksum-1"},
|
|
||||||
}
|
|
||||||
includeModChecksum := r.calculateContentConfigChecksum(obj, artifacts)
|
|
||||||
g.Expect(submodModChecksum).ToNot(Equal(includeModChecksum))
|
|
||||||
|
|
||||||
// Artifact modified revision.
|
|
||||||
artifacts = &artifactSet{
|
|
||||||
&sourcev1.Artifact{Revision: "some-revision-2", Checksum: "some-checksum-1"},
|
|
||||||
}
|
|
||||||
artifactModChecksum := r.calculateContentConfigChecksum(obj, artifacts)
|
|
||||||
g.Expect(includeModChecksum).ToNot(Equal(artifactModChecksum))
|
|
||||||
|
|
||||||
// Artifact modified checksum.
|
|
||||||
artifacts = &artifactSet{
|
|
||||||
&sourcev1.Artifact{Revision: "some-revision-2", Checksum: "some-checksum-2"},
|
|
||||||
}
|
|
||||||
artifactCsumModChecksum := r.calculateContentConfigChecksum(obj, artifacts)
|
|
||||||
g.Expect(artifactModChecksum).ToNot(Equal(artifactCsumModChecksum))
|
|
||||||
}
|
|
||||||
|
|
||||||
func resetChmod(path string, dirMode os.FileMode, fileMode os.FileMode) error {
|
func resetChmod(path string, dirMode os.FileMode, fileMode os.FileMode) error {
|
||||||
err := filepath.Walk(path,
|
err := filepath.Walk(path,
|
||||||
func(path string, info os.FileInfo, err error) error {
|
func(path string, info os.FileInfo, err error) error {
|
||||||
|
@ -2212,3 +2166,371 @@ func resetChmod(path string, dirMode os.FileMode, fileMode os.FileMode) error {
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestGitRepositoryIncludeEqual(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
a sourcev1.GitRepositoryInclude
|
||||||
|
b sourcev1.GitRepositoryInclude
|
||||||
|
want bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "empty",
|
||||||
|
want: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "different refs",
|
||||||
|
a: sourcev1.GitRepositoryInclude{
|
||||||
|
GitRepositoryRef: meta.LocalObjectReference{Name: "foo"},
|
||||||
|
},
|
||||||
|
b: sourcev1.GitRepositoryInclude{
|
||||||
|
GitRepositoryRef: meta.LocalObjectReference{Name: "bar"},
|
||||||
|
},
|
||||||
|
want: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "same refs",
|
||||||
|
a: sourcev1.GitRepositoryInclude{
|
||||||
|
GitRepositoryRef: meta.LocalObjectReference{Name: "foo"},
|
||||||
|
},
|
||||||
|
b: sourcev1.GitRepositoryInclude{
|
||||||
|
GitRepositoryRef: meta.LocalObjectReference{Name: "foo"},
|
||||||
|
},
|
||||||
|
want: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "different from paths",
|
||||||
|
a: sourcev1.GitRepositoryInclude{FromPath: "foo"},
|
||||||
|
b: sourcev1.GitRepositoryInclude{FromPath: "bar"},
|
||||||
|
want: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "same from paths",
|
||||||
|
a: sourcev1.GitRepositoryInclude{FromPath: "foo"},
|
||||||
|
b: sourcev1.GitRepositoryInclude{FromPath: "foo"},
|
||||||
|
want: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "different to paths",
|
||||||
|
a: sourcev1.GitRepositoryInclude{ToPath: "foo"},
|
||||||
|
b: sourcev1.GitRepositoryInclude{ToPath: "bar"},
|
||||||
|
want: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "same to paths",
|
||||||
|
a: sourcev1.GitRepositoryInclude{ToPath: "foo"},
|
||||||
|
b: sourcev1.GitRepositoryInclude{ToPath: "foo"},
|
||||||
|
want: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "same all",
|
||||||
|
a: sourcev1.GitRepositoryInclude{
|
||||||
|
GitRepositoryRef: meta.LocalObjectReference{Name: "foo-ref"},
|
||||||
|
FromPath: "foo-path",
|
||||||
|
ToPath: "bar-path",
|
||||||
|
},
|
||||||
|
b: sourcev1.GitRepositoryInclude{
|
||||||
|
GitRepositoryRef: meta.LocalObjectReference{Name: "foo-ref"},
|
||||||
|
FromPath: "foo-path",
|
||||||
|
ToPath: "bar-path",
|
||||||
|
},
|
||||||
|
want: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
g := NewWithT(t)
|
||||||
|
|
||||||
|
g.Expect(gitRepositoryIncludeEqual(tt.a, tt.b)).To(Equal(tt.want))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGitContentConfigChanged(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
obj sourcev1.GitRepository
|
||||||
|
artifacts []*sourcev1.Artifact
|
||||||
|
want bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "no content config",
|
||||||
|
want: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "unobserved ignore",
|
||||||
|
obj: sourcev1.GitRepository{
|
||||||
|
Spec: sourcev1.GitRepositorySpec{Ignore: pointer.String("foo")},
|
||||||
|
},
|
||||||
|
want: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "observed ignore",
|
||||||
|
obj: sourcev1.GitRepository{
|
||||||
|
Spec: sourcev1.GitRepositorySpec{Ignore: pointer.String("foo")},
|
||||||
|
Status: sourcev1.GitRepositoryStatus{ObservedIgnore: pointer.String("foo")},
|
||||||
|
},
|
||||||
|
want: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "unobserved recurse submodules",
|
||||||
|
obj: sourcev1.GitRepository{
|
||||||
|
Spec: sourcev1.GitRepositorySpec{RecurseSubmodules: true},
|
||||||
|
},
|
||||||
|
want: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "observed recurse submodules",
|
||||||
|
obj: sourcev1.GitRepository{
|
||||||
|
Spec: sourcev1.GitRepositorySpec{RecurseSubmodules: true},
|
||||||
|
Status: sourcev1.GitRepositoryStatus{ObservedRecurseSubmodules: true},
|
||||||
|
},
|
||||||
|
want: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "unobserved include",
|
||||||
|
obj: sourcev1.GitRepository{
|
||||||
|
Spec: sourcev1.GitRepositorySpec{
|
||||||
|
Include: []sourcev1.GitRepositoryInclude{
|
||||||
|
{GitRepositoryRef: meta.LocalObjectReference{Name: "foo"}, FromPath: "bar", ToPath: "baz"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
want: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "observed include",
|
||||||
|
obj: sourcev1.GitRepository{
|
||||||
|
Spec: sourcev1.GitRepositorySpec{
|
||||||
|
Include: []sourcev1.GitRepositoryInclude{
|
||||||
|
{
|
||||||
|
GitRepositoryRef: meta.LocalObjectReference{Name: "foo"},
|
||||||
|
FromPath: "bar",
|
||||||
|
ToPath: "baz",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Status: sourcev1.GitRepositoryStatus{
|
||||||
|
ObservedInclude: []sourcev1.GitRepositoryInclude{
|
||||||
|
{
|
||||||
|
GitRepositoryRef: meta.LocalObjectReference{Name: "foo"},
|
||||||
|
FromPath: "bar",
|
||||||
|
ToPath: "baz",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
IncludedArtifacts: []*sourcev1.Artifact{{Revision: "aaa", Checksum: "bbb"}},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
artifacts: []*sourcev1.Artifact{
|
||||||
|
{Revision: "aaa", Checksum: "bbb"},
|
||||||
|
},
|
||||||
|
want: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "observed include but different artifact revision",
|
||||||
|
obj: sourcev1.GitRepository{
|
||||||
|
Spec: sourcev1.GitRepositorySpec{
|
||||||
|
Include: []sourcev1.GitRepositoryInclude{
|
||||||
|
{
|
||||||
|
GitRepositoryRef: meta.LocalObjectReference{Name: "foo"},
|
||||||
|
FromPath: "bar",
|
||||||
|
ToPath: "baz",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Status: sourcev1.GitRepositoryStatus{
|
||||||
|
ObservedInclude: []sourcev1.GitRepositoryInclude{
|
||||||
|
{
|
||||||
|
GitRepositoryRef: meta.LocalObjectReference{Name: "foo"},
|
||||||
|
FromPath: "bar",
|
||||||
|
ToPath: "baz",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
IncludedArtifacts: []*sourcev1.Artifact{{Revision: "aaa", Checksum: "bbb"}},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
artifacts: []*sourcev1.Artifact{
|
||||||
|
{Revision: "ccc", Checksum: "bbb"},
|
||||||
|
},
|
||||||
|
want: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "observed include but different artifact checksum",
|
||||||
|
obj: sourcev1.GitRepository{
|
||||||
|
Spec: sourcev1.GitRepositorySpec{
|
||||||
|
Include: []sourcev1.GitRepositoryInclude{
|
||||||
|
{
|
||||||
|
GitRepositoryRef: meta.LocalObjectReference{Name: "foo"},
|
||||||
|
FromPath: "bar",
|
||||||
|
ToPath: "baz",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Status: sourcev1.GitRepositoryStatus{
|
||||||
|
ObservedInclude: []sourcev1.GitRepositoryInclude{
|
||||||
|
{
|
||||||
|
GitRepositoryRef: meta.LocalObjectReference{Name: "foo"},
|
||||||
|
FromPath: "bar",
|
||||||
|
ToPath: "baz",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
IncludedArtifacts: []*sourcev1.Artifact{{Revision: "aaa", Checksum: "bbb"}},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
artifacts: []*sourcev1.Artifact{
|
||||||
|
{Revision: "aaa", Checksum: "ddd"},
|
||||||
|
},
|
||||||
|
want: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "observed include but updated spec",
|
||||||
|
obj: sourcev1.GitRepository{
|
||||||
|
Spec: sourcev1.GitRepositorySpec{
|
||||||
|
Include: []sourcev1.GitRepositoryInclude{
|
||||||
|
{
|
||||||
|
GitRepositoryRef: meta.LocalObjectReference{Name: "foo2"},
|
||||||
|
FromPath: "bar",
|
||||||
|
ToPath: "baz",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Status: sourcev1.GitRepositoryStatus{
|
||||||
|
ObservedInclude: []sourcev1.GitRepositoryInclude{
|
||||||
|
{
|
||||||
|
GitRepositoryRef: meta.LocalObjectReference{Name: "foo"},
|
||||||
|
FromPath: "bar",
|
||||||
|
ToPath: "baz",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
IncludedArtifacts: []*sourcev1.Artifact{{Revision: "aaa", Checksum: "bbb"}},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
artifacts: []*sourcev1.Artifact{
|
||||||
|
{Revision: "aaa", Checksum: "bbb"},
|
||||||
|
},
|
||||||
|
want: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "different number of include and observed include",
|
||||||
|
obj: sourcev1.GitRepository{
|
||||||
|
Spec: sourcev1.GitRepositorySpec{
|
||||||
|
Include: []sourcev1.GitRepositoryInclude{
|
||||||
|
{
|
||||||
|
GitRepositoryRef: meta.LocalObjectReference{Name: "foo"},
|
||||||
|
FromPath: "bar",
|
||||||
|
ToPath: "baz",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
GitRepositoryRef: meta.LocalObjectReference{Name: "foo2"},
|
||||||
|
FromPath: "bar",
|
||||||
|
ToPath: "baz",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Status: sourcev1.GitRepositoryStatus{
|
||||||
|
IncludedArtifacts: []*sourcev1.Artifact{
|
||||||
|
{Revision: "aaa", Checksum: "bbb"},
|
||||||
|
{Revision: "ccc", Checksum: "ccc"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
artifacts: []*sourcev1.Artifact{
|
||||||
|
{Revision: "aaa", Checksum: "bbb"},
|
||||||
|
{Revision: "ccc", Checksum: "ddd"},
|
||||||
|
},
|
||||||
|
want: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "different number of include and artifactset",
|
||||||
|
obj: sourcev1.GitRepository{
|
||||||
|
Spec: sourcev1.GitRepositorySpec{
|
||||||
|
Include: []sourcev1.GitRepositoryInclude{
|
||||||
|
{
|
||||||
|
GitRepositoryRef: meta.LocalObjectReference{Name: "foo"},
|
||||||
|
FromPath: "bar",
|
||||||
|
ToPath: "baz",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
GitRepositoryRef: meta.LocalObjectReference{Name: "foo2"},
|
||||||
|
FromPath: "bar",
|
||||||
|
ToPath: "baz",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Status: sourcev1.GitRepositoryStatus{
|
||||||
|
ObservedInclude: []sourcev1.GitRepositoryInclude{
|
||||||
|
{
|
||||||
|
GitRepositoryRef: meta.LocalObjectReference{Name: "foo"},
|
||||||
|
FromPath: "bar",
|
||||||
|
ToPath: "baz",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
GitRepositoryRef: meta.LocalObjectReference{Name: "foo2"},
|
||||||
|
FromPath: "bar",
|
||||||
|
ToPath: "baz",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
IncludedArtifacts: []*sourcev1.Artifact{
|
||||||
|
{Revision: "aaa", Checksum: "bbb"},
|
||||||
|
{Revision: "ccc", Checksum: "ccc"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
artifacts: []*sourcev1.Artifact{
|
||||||
|
{Revision: "aaa", Checksum: "bbb"},
|
||||||
|
},
|
||||||
|
want: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "different number of include and included artifacts",
|
||||||
|
obj: sourcev1.GitRepository{
|
||||||
|
Spec: sourcev1.GitRepositorySpec{
|
||||||
|
Include: []sourcev1.GitRepositoryInclude{
|
||||||
|
{
|
||||||
|
GitRepositoryRef: meta.LocalObjectReference{Name: "foo"},
|
||||||
|
FromPath: "bar",
|
||||||
|
ToPath: "baz",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
GitRepositoryRef: meta.LocalObjectReference{Name: "foo2"},
|
||||||
|
FromPath: "bar",
|
||||||
|
ToPath: "baz",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Status: sourcev1.GitRepositoryStatus{
|
||||||
|
ObservedInclude: []sourcev1.GitRepositoryInclude{
|
||||||
|
{
|
||||||
|
GitRepositoryRef: meta.LocalObjectReference{Name: "foo"},
|
||||||
|
FromPath: "bar",
|
||||||
|
ToPath: "baz",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
GitRepositoryRef: meta.LocalObjectReference{Name: "foo2"},
|
||||||
|
FromPath: "bar",
|
||||||
|
ToPath: "baz",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
IncludedArtifacts: []*sourcev1.Artifact{
|
||||||
|
{Revision: "aaa", Checksum: "bbb"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
artifacts: []*sourcev1.Artifact{
|
||||||
|
{Revision: "aaa", Checksum: "bbb"},
|
||||||
|
{Revision: "ccc", Checksum: "ccc"},
|
||||||
|
},
|
||||||
|
want: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
g := NewWithT(t)
|
||||||
|
|
||||||
|
includes := artifactSet(tt.artifacts)
|
||||||
|
g.Expect(gitContentConfigChanged(&tt.obj, &includes)).To(Equal(tt.want))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1539,7 +1539,8 @@ github.com/fluxcd/pkg/apis/meta.ReconcileRequestStatus
|
||||||
</h3>
|
</h3>
|
||||||
<p>
|
<p>
|
||||||
(<em>Appears on:</em>
|
(<em>Appears on:</em>
|
||||||
<a href="#source.toolkit.fluxcd.io/v1beta2.GitRepositorySpec">GitRepositorySpec</a>)
|
<a href="#source.toolkit.fluxcd.io/v1beta2.GitRepositorySpec">GitRepositorySpec</a>,
|
||||||
|
<a href="#source.toolkit.fluxcd.io/v1beta2.GitRepositoryStatus">GitRepositoryStatus</a>)
|
||||||
</p>
|
</p>
|
||||||
<p>GitRepositoryInclude specifies a local reference to a GitRepository which
|
<p>GitRepositoryInclude specifies a local reference to a GitRepository which
|
||||||
Artifact (sub-)contents must be included, and where they should be placed.</p>
|
Artifact (sub-)contents must be included, and where they should be placed.</p>
|
||||||
|
@ -1969,6 +1970,49 @@ observed in .status.observedGeneration version of the object. This can
|
||||||
be used to determine if the content of the included repository has
|
be used to determine if the content of the included repository has
|
||||||
changed.
|
changed.
|
||||||
It has the format of <code><algo>:<checksum></code>, for example: <code>sha256:<checksum></code>.</p>
|
It has the format of <code><algo>:<checksum></code>, for example: <code>sha256:<checksum></code>.</p>
|
||||||
|
<p>Deprecated: Replaced with explicit fields for observed artifact content
|
||||||
|
config in the status.</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<code>observedIgnore</code><br>
|
||||||
|
<em>
|
||||||
|
string
|
||||||
|
</em>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<em>(Optional)</em>
|
||||||
|
<p>ObservedIgnore is the observed exclusion patterns used for constructing
|
||||||
|
the source artifact.</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<code>observedRecurseSubmodules</code><br>
|
||||||
|
<em>
|
||||||
|
bool
|
||||||
|
</em>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<em>(Optional)</em>
|
||||||
|
<p>ObservedRecurseSubmodules is the observed resource submodules
|
||||||
|
configuration used to produce the current Artifact.</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<code>observedInclude</code><br>
|
||||||
|
<em>
|
||||||
|
<a href="#source.toolkit.fluxcd.io/v1beta2.GitRepositoryInclude">
|
||||||
|
[]GitRepositoryInclude
|
||||||
|
</a>
|
||||||
|
</em>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<em>(Optional)</em>
|
||||||
|
<p>ObservedInclude is the observed list of GitRepository resources used to
|
||||||
|
to produce the current Artifact.</p>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
|
|
|
@ -854,6 +854,79 @@ configurations of the GitRepository that indicate a change in source and
|
||||||
records it in `.status.contentConfigChecksum`. This field is used to determine
|
records it in `.status.contentConfigChecksum`. This field is used to determine
|
||||||
if the source artifact needs to be rebuilt.
|
if the source artifact needs to be rebuilt.
|
||||||
|
|
||||||
|
**Deprecation Note:** `contentConfigChecksum` is no longer used and will be
|
||||||
|
removed in the next API version. The individual components used for generating
|
||||||
|
content configuration checksum now have explicit fields in the status. This
|
||||||
|
makes the observations used by the controller for making artifact rebuild
|
||||||
|
decisions more transparent and easier to debug.
|
||||||
|
|
||||||
|
### Observed Ignore
|
||||||
|
|
||||||
|
The source-controller reports an observed ignore in the GitRepository's
|
||||||
|
`.status.observedIgnore`. The observed ignore is the latest `.spec.ignore` value
|
||||||
|
which resulted in a [ready state](#ready-gitrepository), or stalled due to error
|
||||||
|
it can not recover from without human intervention.
|
||||||
|
The value is the same as the [ignore in spec](#ignore).
|
||||||
|
It indicates the ignore rules used in building the current artifact in storage.
|
||||||
|
It is also used by the controller to determine if an artifact needs to be
|
||||||
|
rebuilt.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
```yaml
|
||||||
|
status:
|
||||||
|
...
|
||||||
|
observedIgnore: |
|
||||||
|
cue
|
||||||
|
pkg
|
||||||
|
...
|
||||||
|
```
|
||||||
|
|
||||||
|
### Observed Recurse Submodules
|
||||||
|
|
||||||
|
The source-controller reports an observed recurse submodule in the
|
||||||
|
GitRepository's `.status.observedRecurseSubmodules`. The observed recurse
|
||||||
|
submodules is the latest `.spec.recurseSubmodules` value which resulted in a
|
||||||
|
[ready state](#ready-gitrepository), or stalled due to error it can not recover
|
||||||
|
from without human intervention. The value is the same as the
|
||||||
|
[recurse submodules in spec](#recurse-submodules). It indicates the recurse
|
||||||
|
submodules configuration used in building the current artifact in storage. It is
|
||||||
|
also used by the controller to determine if an artifact needs to be rebuilt.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
```yaml
|
||||||
|
status:
|
||||||
|
...
|
||||||
|
observedRecurseSubmodules: true
|
||||||
|
...
|
||||||
|
```
|
||||||
|
|
||||||
|
### Observed Include
|
||||||
|
|
||||||
|
The source-controller reports observed include in the GitRepository's
|
||||||
|
`.status.observedInclude`. The observed include is the latest
|
||||||
|
`.spec.recurseSubmodules` value which resulted in a
|
||||||
|
[ready state](#ready-gitrepository), or stalled due to error it can not recover
|
||||||
|
from without human intervention. The value is the same as the
|
||||||
|
[include in spec](#include). It indicates the include configuration used in
|
||||||
|
building the current artifact in storage. It is also used by the controller to
|
||||||
|
determine if an artifact needs to be rebuilt.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
```yaml
|
||||||
|
status:
|
||||||
|
...
|
||||||
|
observedInclude:
|
||||||
|
- fromPath: deploy/webapp
|
||||||
|
repository:
|
||||||
|
name: repo1
|
||||||
|
toPath: foo
|
||||||
|
- fromPath: deploy/secure
|
||||||
|
repository:
|
||||||
|
name: repo2
|
||||||
|
toPath: bar
|
||||||
|
...
|
||||||
|
```
|
||||||
|
|
||||||
### Observed Generation
|
### Observed Generation
|
||||||
|
|
||||||
The source-controller reports an [observed generation][typical-status-properties]
|
The source-controller reports an [observed generation][typical-status-properties]
|
||||||
|
|
Loading…
Reference in New Issue