Document GitRepository API v1beta2 spec
Signed-off-by: Hidde Beydals <hello@hidde.co>
This commit is contained in:
parent
86d1d80bf2
commit
cbffd82d8f
|
@ -29,85 +29,117 @@ const (
|
||||||
// GitRepositoryKind is the string representation of a GitRepository.
|
// GitRepositoryKind is the string representation of a GitRepository.
|
||||||
GitRepositoryKind = "GitRepository"
|
GitRepositoryKind = "GitRepository"
|
||||||
|
|
||||||
// GoGitImplementation represents the go-git Git implementation kind.
|
// GoGitImplementation for performing Git operations using go-git.
|
||||||
GoGitImplementation = "go-git"
|
GoGitImplementation = "go-git"
|
||||||
// LibGit2Implementation represents the git2go Git implementation kind.
|
// LibGit2Implementation for performing Git operations using libgit2.
|
||||||
LibGit2Implementation = "libgit2"
|
LibGit2Implementation = "libgit2"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// IncludeUnavailableCondition indicates one of the includes is not available. For example, because it does not
|
// IncludeUnavailableCondition indicates one of the includes is not
|
||||||
// exist, or does not have an Artifact.
|
// available. For example, because it does not exist, or does not have an
|
||||||
// This is a "negative polarity" or "abnormal-true" type, and is only present on the resource if it is True.
|
// Artifact.
|
||||||
|
// This is a "negative polarity" or "abnormal-true" type, and is only
|
||||||
|
// present on the resource if it is True.
|
||||||
IncludeUnavailableCondition string = "IncludeUnavailable"
|
IncludeUnavailableCondition string = "IncludeUnavailable"
|
||||||
)
|
)
|
||||||
|
|
||||||
// GitRepositorySpec defines the desired state of a Git repository.
|
// GitRepositorySpec specifies the required configuration to produce an
|
||||||
|
// Artifact for a Git repository.
|
||||||
type GitRepositorySpec struct {
|
type GitRepositorySpec struct {
|
||||||
// The repository URL, can be a HTTP/S or SSH address.
|
// URL specifies the Git repository URL, it can be an HTTP/S or SSH address.
|
||||||
// +kubebuilder:validation:Pattern="^(http|https|ssh)://"
|
// +kubebuilder:validation:Pattern="^(http|https|ssh)://"
|
||||||
// +required
|
// +required
|
||||||
URL string `json:"url"`
|
URL string `json:"url"`
|
||||||
|
|
||||||
// The secret name containing the Git credentials.
|
// SecretRef specifies the Secret containing authentication credentials for
|
||||||
// For HTTPS repositories the secret must contain username and password fields.
|
// the GitRepository.
|
||||||
// For SSH repositories the secret must contain 'identity', 'identity.pub' and 'known_hosts' fields.
|
// For HTTPS repositories the Secret must contain 'username' and 'password'
|
||||||
|
// fields.
|
||||||
|
// For SSH repositories the Secret must contain 'identity', 'identity.pub'
|
||||||
|
// and 'known_hosts' fields.
|
||||||
// +optional
|
// +optional
|
||||||
SecretRef *meta.LocalObjectReference `json:"secretRef,omitempty"`
|
SecretRef *meta.LocalObjectReference `json:"secretRef,omitempty"`
|
||||||
|
|
||||||
// The interval at which to check for repository updates.
|
// Interval at which to check the GitRepository for updates.
|
||||||
// +required
|
// +required
|
||||||
Interval metav1.Duration `json:"interval"`
|
Interval metav1.Duration `json:"interval"`
|
||||||
|
|
||||||
// The timeout for remote Git operations like cloning, defaults to 60s.
|
// Timeout for Git operations like cloning, defaults to 60s.
|
||||||
// +kubebuilder:default="60s"
|
// +kubebuilder:default="60s"
|
||||||
// +optional
|
// +optional
|
||||||
Timeout *metav1.Duration `json:"timeout,omitempty"`
|
Timeout *metav1.Duration `json:"timeout,omitempty"`
|
||||||
|
|
||||||
// The Git reference to checkout and monitor for changes, defaults to
|
// Reference specifies the Git reference to resolve and monitor for
|
||||||
// master branch.
|
// changes, defaults to the 'master' branch.
|
||||||
// +optional
|
// +optional
|
||||||
Reference *GitRepositoryRef `json:"ref,omitempty"`
|
Reference *GitRepositoryRef `json:"ref,omitempty"`
|
||||||
|
|
||||||
// Verification defines the configuration to verify the OpenPGP signature for the Git commit HEAD points to.
|
// Verification specifies the configuration to verify the Git commit
|
||||||
|
// signature(s).
|
||||||
// +optional
|
// +optional
|
||||||
Verification *GitRepositoryVerification `json:"verify,omitempty"`
|
Verification *GitRepositoryVerification `json:"verify,omitempty"`
|
||||||
|
|
||||||
// Ignore overrides the set of excluded patterns in the .sourceignore format (which is the same as .gitignore).
|
// Ignore overrides the set of excluded patterns in the .sourceignore format
|
||||||
// If not provided, a default will be used, consult the documentation for your version to find out what those are.
|
// (which is the same as .gitignore). If not provided, a default will be used,
|
||||||
|
// consult the documentation for your version to find out what those are.
|
||||||
// +optional
|
// +optional
|
||||||
Ignore *string `json:"ignore,omitempty"`
|
Ignore *string `json:"ignore,omitempty"`
|
||||||
|
|
||||||
// Suspend tells the controller to suspend the reconciliation of this source.
|
// Suspend tells the controller to suspend the reconciliation of this
|
||||||
// This flag tells the controller to suspend the reconciliation of this source.
|
// GitRepository.
|
||||||
// +optional
|
// +optional
|
||||||
Suspend bool `json:"suspend,omitempty"`
|
Suspend bool `json:"suspend,omitempty"`
|
||||||
|
|
||||||
// Determines which git client library to use.
|
// GitImplementation specifies which Git client library implementation to
|
||||||
// Defaults to go-git, valid values are ('go-git', 'libgit2').
|
// use. Defaults to 'go-git', valid values are ('go-git', 'libgit2').
|
||||||
// +kubebuilder:validation:Enum=go-git;libgit2
|
// +kubebuilder:validation:Enum=go-git;libgit2
|
||||||
// +kubebuilder:default:=go-git
|
// +kubebuilder:default:=go-git
|
||||||
// +optional
|
// +optional
|
||||||
GitImplementation string `json:"gitImplementation,omitempty"`
|
GitImplementation string `json:"gitImplementation,omitempty"`
|
||||||
|
|
||||||
// When enabled, after the clone is created, initializes all submodules within, using their default settings.
|
// RecurseSubmodules enables the initialization of all submodules within
|
||||||
|
// the GitRepository as cloned from the URL, using their default settings.
|
||||||
// This option is available only when using the 'go-git' GitImplementation.
|
// This option is available only when using the 'go-git' GitImplementation.
|
||||||
// +optional
|
// +optional
|
||||||
RecurseSubmodules bool `json:"recurseSubmodules,omitempty"`
|
RecurseSubmodules bool `json:"recurseSubmodules,omitempty"`
|
||||||
|
|
||||||
// Include defines a list of GitRepository resources which artifacts should be included in the artifact produced for
|
// Include specifies a list of GitRepository resources which Artifacts
|
||||||
// this resource.
|
// should be included in the Artifact produced for this GitRepository.
|
||||||
Include []GitRepositoryInclude `json:"include,omitempty"`
|
Include []GitRepositoryInclude `json:"include,omitempty"`
|
||||||
|
|
||||||
// AccessFrom defines an Access Control List for allowing cross-namespace references to this object.
|
// AccessFrom specifies an Access Control List for allowing cross-namespace
|
||||||
|
// references to this object.
|
||||||
|
// NOTE: Not implemented, provisional as of https://github.com/fluxcd/flux2/pull/2092
|
||||||
// +optional
|
// +optional
|
||||||
AccessFrom *acl.AccessFrom `json:"accessFrom,omitempty"`
|
AccessFrom *acl.AccessFrom `json:"accessFrom,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GitRepositoryInclude specifies a local reference to a GitRepository which
|
||||||
|
// Artifact (sub-)contents must be included, and where they should be placed.
|
||||||
|
type GitRepositoryInclude struct {
|
||||||
|
// GitRepositoryRef specifies the GitRepository which Artifact contents
|
||||||
|
// must be included.
|
||||||
|
GitRepositoryRef meta.LocalObjectReference `json:"repository"`
|
||||||
|
|
||||||
|
// FromPath specifies the path to copy contents from, defaults to the root
|
||||||
|
// of the Artifact.
|
||||||
|
// +optional
|
||||||
|
FromPath string `json:"fromPath"`
|
||||||
|
|
||||||
|
// ToPath specifies the path to copy contents to, defaults to the name of
|
||||||
|
// the GitRepositoryRef.
|
||||||
|
// +optional
|
||||||
|
ToPath string `json:"toPath"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetFromPath returns the specified FromPath.
|
||||||
func (in *GitRepositoryInclude) GetFromPath() string {
|
func (in *GitRepositoryInclude) GetFromPath() string {
|
||||||
return in.FromPath
|
return in.FromPath
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetToPath returns the specified ToPath, falling back to the name of the
|
||||||
|
// GitRepositoryRef.
|
||||||
func (in *GitRepositoryInclude) GetToPath() string {
|
func (in *GitRepositoryInclude) GetToPath() string {
|
||||||
if in.ToPath == "" {
|
if in.ToPath == "" {
|
||||||
return in.GitRepositoryRef.Name
|
return in.GitRepositoryRef.Name
|
||||||
|
@ -115,52 +147,48 @@ func (in *GitRepositoryInclude) GetToPath() string {
|
||||||
return in.ToPath
|
return in.ToPath
|
||||||
}
|
}
|
||||||
|
|
||||||
// GitRepositoryInclude defines a source with a from and to path.
|
// GitRepositoryRef specifies the Git reference to resolve and checkout.
|
||||||
type GitRepositoryInclude struct {
|
|
||||||
// Reference to a GitRepository to include.
|
|
||||||
GitRepositoryRef meta.LocalObjectReference `json:"repository"`
|
|
||||||
|
|
||||||
// The path to copy contents from, defaults to the root directory.
|
|
||||||
// +optional
|
|
||||||
FromPath string `json:"fromPath"`
|
|
||||||
|
|
||||||
// The path to copy contents to, defaults to the name of the source ref.
|
|
||||||
// +optional
|
|
||||||
ToPath string `json:"toPath"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// GitRepositoryRef defines the Git ref used for pull and checkout operations.
|
|
||||||
type GitRepositoryRef struct {
|
type GitRepositoryRef struct {
|
||||||
// The Git branch to checkout, defaults to master.
|
// Branch to check out, defaults to 'master' if no other field is defined.
|
||||||
|
//
|
||||||
|
// When GitRepositorySpec.GitImplementation is set to 'go-git', a shallow
|
||||||
|
// clone of the specified branch is performed.
|
||||||
// +optional
|
// +optional
|
||||||
Branch string `json:"branch,omitempty"`
|
Branch string `json:"branch,omitempty"`
|
||||||
|
|
||||||
// The Git tag to checkout, takes precedence over Branch.
|
// Tag to check out, takes precedence over Branch.
|
||||||
// +optional
|
// +optional
|
||||||
Tag string `json:"tag,omitempty"`
|
Tag string `json:"tag,omitempty"`
|
||||||
|
|
||||||
// The Git tag semver expression, takes precedence over Tag.
|
// SemVer tag expression to check out, takes precedence over Tag.
|
||||||
// +optional
|
// +optional
|
||||||
SemVer string `json:"semver,omitempty"`
|
SemVer string `json:"semver,omitempty"`
|
||||||
|
|
||||||
// The Git commit SHA to checkout, if specified Tag filters will be ignored.
|
// Commit SHA to check out, takes precedence over all reference fields.
|
||||||
|
//
|
||||||
|
// When GitRepositorySpec.GitImplementation is set to 'go-git', this can be
|
||||||
|
// combined with Branch to shallow clone the branch, in which the commit is
|
||||||
|
// expected to exist.
|
||||||
// +optional
|
// +optional
|
||||||
Commit string `json:"commit,omitempty"`
|
Commit string `json:"commit,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// GitRepositoryVerification defines the OpenPGP signature verification process.
|
// GitRepositoryVerification specifies the Git commit signature verification
|
||||||
|
// strategy.
|
||||||
type GitRepositoryVerification struct {
|
type GitRepositoryVerification struct {
|
||||||
// Mode describes what Git object should be verified, currently ('head').
|
// Mode specifies what Git object should be verified, currently ('head').
|
||||||
// +kubebuilder:validation:Enum=head
|
// +kubebuilder:validation:Enum=head
|
||||||
Mode string `json:"mode"`
|
Mode string `json:"mode"`
|
||||||
|
|
||||||
// SecretRef containing the public keys of all trusted Git authors.
|
// SecretRef specifies the Secret containing the public keys of trusted Git
|
||||||
|
// authors.
|
||||||
SecretRef meta.LocalObjectReference `json:"secretRef,omitempty"`
|
SecretRef meta.LocalObjectReference `json:"secretRef,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// GitRepositoryStatus defines the observed state of a Git repository.
|
// GitRepositoryStatus records the observed state of a Git repository.
|
||||||
type GitRepositoryStatus struct {
|
type GitRepositoryStatus struct {
|
||||||
// ObservedGeneration is the last observed generation.
|
// ObservedGeneration is the last observed generation of the GitRepository
|
||||||
|
// object.
|
||||||
// +optional
|
// +optional
|
||||||
ObservedGeneration int64 `json:"observedGeneration,omitempty"`
|
ObservedGeneration int64 `json:"observedGeneration,omitempty"`
|
||||||
|
|
||||||
|
@ -168,15 +196,18 @@ type GitRepositoryStatus struct {
|
||||||
// +optional
|
// +optional
|
||||||
Conditions []metav1.Condition `json:"conditions,omitempty"`
|
Conditions []metav1.Condition `json:"conditions,omitempty"`
|
||||||
|
|
||||||
// URL is the fetch link for the artifact output of the last repository sync.
|
// URL is the dynamic fetch link for the latest Artifact.
|
||||||
|
// It is provided on a "best effort" basis, and using the precise
|
||||||
|
// GitRepositoryStatus.Artifact data is recommended.
|
||||||
// +optional
|
// +optional
|
||||||
URL string `json:"url,omitempty"`
|
URL string `json:"url,omitempty"`
|
||||||
|
|
||||||
// Artifact represents the output of the last successful repository sync.
|
// Artifact represents the last successful GitRepository reconciliation.
|
||||||
// +optional
|
// +optional
|
||||||
Artifact *Artifact `json:"artifact,omitempty"`
|
Artifact *Artifact `json:"artifact,omitempty"`
|
||||||
|
|
||||||
// IncludedArtifacts represents the included artifacts from the last successful repository sync.
|
// IncludedArtifacts contains a list of the last successfully included
|
||||||
|
// Artifacts as instructed by GitRepositorySpec.Include.
|
||||||
// +optional
|
// +optional
|
||||||
IncludedArtifacts []*Artifact `json:"includedArtifacts,omitempty"`
|
IncludedArtifacts []*Artifact `json:"includedArtifacts,omitempty"`
|
||||||
|
|
||||||
|
@ -184,10 +215,12 @@ type GitRepositoryStatus struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// GitOperationSucceedReason represents the fact that the git clone, pull and checkout operations succeeded.
|
// GitOperationSucceedReason signals that a Git operation (e.g. clone,
|
||||||
GitOperationSucceedReason string = "GitOperationSucceed"
|
// checkout, etc.) succeeded.
|
||||||
|
GitOperationSucceedReason string = "GitOperationSucceeded"
|
||||||
|
|
||||||
// GitOperationFailedReason represents the fact that the git clone, pull or checkout operations failed.
|
// GitOperationFailedReason signals that a Git operation (e.g. clone,
|
||||||
|
// checkout, etc.) failed.
|
||||||
GitOperationFailedReason string = "GitOperationFailed"
|
GitOperationFailedReason string = "GitOperationFailed"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -201,28 +234,18 @@ func (in *GitRepository) SetConditions(conditions []metav1.Condition) {
|
||||||
in.Status.Conditions = conditions
|
in.Status.Conditions = conditions
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetRequeueAfter returns the duration after which the source must be reconciled again.
|
// GetRequeueAfter returns the duration after which the GitRepository must be
|
||||||
|
// reconciled again.
|
||||||
func (in GitRepository) GetRequeueAfter() time.Duration {
|
func (in GitRepository) GetRequeueAfter() time.Duration {
|
||||||
return in.Spec.Interval.Duration
|
return in.Spec.Interval.Duration
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetInterval returns the interval at which the source is reconciled.
|
// GetArtifact returns the latest Artifact from the GitRepository if present in
|
||||||
// Deprecated: use GetRequeueAfter instead.
|
// the status sub-resource.
|
||||||
func (in GitRepository) GetInterval() metav1.Duration {
|
|
||||||
return in.Spec.Interval
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetArtifact returns the latest artifact from the source if present in the status sub-resource.
|
|
||||||
func (in *GitRepository) GetArtifact() *Artifact {
|
func (in *GitRepository) GetArtifact() *Artifact {
|
||||||
return in.Status.Artifact
|
return in.Status.Artifact
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetStatusConditions returns a pointer to the Status.Conditions slice.
|
|
||||||
// Deprecated: use GetConditions instead.
|
|
||||||
func (in *GitRepository) GetStatusConditions() *[]metav1.Condition {
|
|
||||||
return &in.Status.Conditions
|
|
||||||
}
|
|
||||||
|
|
||||||
// +genclient
|
// +genclient
|
||||||
// +genclient:Namespaced
|
// +genclient:Namespaced
|
||||||
// +kubebuilder:storageversion
|
// +kubebuilder:storageversion
|
||||||
|
@ -234,7 +257,7 @@ func (in *GitRepository) GetStatusConditions() *[]metav1.Condition {
|
||||||
// +kubebuilder:printcolumn:name="Ready",type="string",JSONPath=".status.conditions[?(@.type==\"Ready\")].status",description=""
|
// +kubebuilder:printcolumn:name="Ready",type="string",JSONPath=".status.conditions[?(@.type==\"Ready\")].status",description=""
|
||||||
// +kubebuilder:printcolumn:name="Status",type="string",JSONPath=".status.conditions[?(@.type==\"Ready\")].message",description=""
|
// +kubebuilder:printcolumn:name="Status",type="string",JSONPath=".status.conditions[?(@.type==\"Ready\")].message",description=""
|
||||||
|
|
||||||
// GitRepository is the Schema for the gitrepositories API
|
// GitRepository is the Schema for the gitrepositories API.
|
||||||
type GitRepository struct {
|
type GitRepository struct {
|
||||||
metav1.TypeMeta `json:",inline"`
|
metav1.TypeMeta `json:",inline"`
|
||||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||||
|
@ -244,7 +267,7 @@ type GitRepository struct {
|
||||||
Status GitRepositoryStatus `json:"status,omitempty"`
|
Status GitRepositoryStatus `json:"status,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// GitRepositoryList contains a list of GitRepository
|
// GitRepositoryList contains a list of GitRepository objects.
|
||||||
// +kubebuilder:object:root=true
|
// +kubebuilder:object:root=true
|
||||||
type GitRepositoryList struct {
|
type GitRepositoryList struct {
|
||||||
metav1.TypeMeta `json:",inline"`
|
metav1.TypeMeta `json:",inline"`
|
||||||
|
|
|
@ -365,7 +365,7 @@ spec:
|
||||||
name: v1beta2
|
name: v1beta2
|
||||||
schema:
|
schema:
|
||||||
openAPIV3Schema:
|
openAPIV3Schema:
|
||||||
description: GitRepository is the Schema for the gitrepositories API
|
description: GitRepository is the Schema for the gitrepositories API.
|
||||||
properties:
|
properties:
|
||||||
apiVersion:
|
apiVersion:
|
||||||
description: 'APIVersion defines the versioned schema of this representation
|
description: 'APIVersion defines the versioned schema of this representation
|
||||||
|
@ -380,11 +380,13 @@ spec:
|
||||||
metadata:
|
metadata:
|
||||||
type: object
|
type: object
|
||||||
spec:
|
spec:
|
||||||
description: GitRepositorySpec defines the desired state of a Git repository.
|
description: GitRepositorySpec specifies the required configuration to
|
||||||
|
produce an Artifact for a Git repository.
|
||||||
properties:
|
properties:
|
||||||
accessFrom:
|
accessFrom:
|
||||||
description: AccessFrom defines an Access Control List for allowing
|
description: 'AccessFrom specifies an Access Control List for allowing
|
||||||
cross-namespace references to this object.
|
cross-namespace references to this object. NOTE: Not implemented,
|
||||||
|
provisional as of https://github.com/fluxcd/flux2/pull/2092'
|
||||||
properties:
|
properties:
|
||||||
namespaceSelectors:
|
namespaceSelectors:
|
||||||
description: NamespaceSelectors is the list of namespace selectors
|
description: NamespaceSelectors is the list of namespace selectors
|
||||||
|
@ -411,8 +413,9 @@ spec:
|
||||||
type: object
|
type: object
|
||||||
gitImplementation:
|
gitImplementation:
|
||||||
default: go-git
|
default: go-git
|
||||||
description: Determines which git client library to use. Defaults
|
description: GitImplementation specifies which Git client library
|
||||||
to go-git, valid values are ('go-git', 'libgit2').
|
implementation to use. Defaults to 'go-git', valid values are ('go-git',
|
||||||
|
'libgit2').
|
||||||
enum:
|
enum:
|
||||||
- go-git
|
- go-git
|
||||||
- libgit2
|
- libgit2
|
||||||
|
@ -424,18 +427,20 @@ spec:
|
||||||
to find out what those are.
|
to find out what those are.
|
||||||
type: string
|
type: string
|
||||||
include:
|
include:
|
||||||
description: Include defines a list of GitRepository resources which
|
description: Include specifies a list of GitRepository resources which
|
||||||
artifacts should be included in the artifact produced for this resource.
|
Artifacts should be included in the Artifact produced for this GitRepository.
|
||||||
items:
|
items:
|
||||||
description: GitRepositoryInclude defines a source with a from and
|
description: GitRepositoryInclude specifies a local reference to
|
||||||
to path.
|
a GitRepository which Artifact (sub-)contents must be included,
|
||||||
|
and where they should be placed.
|
||||||
properties:
|
properties:
|
||||||
fromPath:
|
fromPath:
|
||||||
description: The path to copy contents from, defaults to the
|
description: FromPath specifies the path to copy contents from,
|
||||||
root directory.
|
defaults to the root of the Artifact.
|
||||||
type: string
|
type: string
|
||||||
repository:
|
repository:
|
||||||
description: Reference to a GitRepository to include.
|
description: GitRepositoryRef specifies the GitRepository which
|
||||||
|
Artifact contents must be included.
|
||||||
properties:
|
properties:
|
||||||
name:
|
name:
|
||||||
description: Name of the referent.
|
description: Name of the referent.
|
||||||
|
@ -444,45 +449,52 @@ spec:
|
||||||
- name
|
- name
|
||||||
type: object
|
type: object
|
||||||
toPath:
|
toPath:
|
||||||
description: The path to copy contents to, defaults to the name
|
description: ToPath specifies the path to copy contents to,
|
||||||
of the source ref.
|
defaults to the name of the GitRepositoryRef.
|
||||||
type: string
|
type: string
|
||||||
required:
|
required:
|
||||||
- repository
|
- repository
|
||||||
type: object
|
type: object
|
||||||
type: array
|
type: array
|
||||||
interval:
|
interval:
|
||||||
description: The interval at which to check for repository updates.
|
description: Interval at which to check the GitRepository for updates.
|
||||||
type: string
|
type: string
|
||||||
recurseSubmodules:
|
recurseSubmodules:
|
||||||
description: When enabled, after the clone is created, initializes
|
description: RecurseSubmodules enables the initialization of all submodules
|
||||||
all submodules within, using their default settings. This option
|
within the GitRepository as cloned from the URL, using their default
|
||||||
is available only when using the 'go-git' GitImplementation.
|
settings. This option is available only when using the 'go-git'
|
||||||
|
GitImplementation.
|
||||||
type: boolean
|
type: boolean
|
||||||
ref:
|
ref:
|
||||||
description: The Git reference to checkout and monitor for changes,
|
description: Reference specifies the Git reference to resolve and
|
||||||
defaults to master branch.
|
monitor for changes, defaults to the 'master' branch.
|
||||||
properties:
|
properties:
|
||||||
branch:
|
branch:
|
||||||
description: The Git branch to checkout, defaults to master.
|
description: "Branch to check out, defaults to 'master' if no
|
||||||
|
other field is defined. \n When GitRepositorySpec.GitImplementation
|
||||||
|
is set to 'go-git', a shallow clone of the specified branch
|
||||||
|
is performed."
|
||||||
type: string
|
type: string
|
||||||
commit:
|
commit:
|
||||||
description: The Git commit SHA to checkout, if specified Tag
|
description: "Commit SHA to check out, takes precedence over all
|
||||||
filters will be ignored.
|
reference fields. \n When GitRepositorySpec.GitImplementation
|
||||||
|
is set to 'go-git', this can be combined with Branch to shallow
|
||||||
|
clone the branch, in which the commit is expected to exist."
|
||||||
type: string
|
type: string
|
||||||
semver:
|
semver:
|
||||||
description: The Git tag semver expression, takes precedence over
|
description: SemVer tag expression to check out, takes precedence
|
||||||
Tag.
|
over Tag.
|
||||||
type: string
|
type: string
|
||||||
tag:
|
tag:
|
||||||
description: The Git tag to checkout, takes precedence over Branch.
|
description: Tag to check out, takes precedence over Branch.
|
||||||
type: string
|
type: string
|
||||||
type: object
|
type: object
|
||||||
secretRef:
|
secretRef:
|
||||||
description: The secret name containing the Git credentials. For HTTPS
|
description: SecretRef specifies the Secret containing authentication
|
||||||
repositories the secret must contain username and password fields.
|
credentials for the GitRepository. For HTTPS repositories the Secret
|
||||||
For SSH repositories the secret must contain 'identity', 'identity.pub'
|
must contain 'username' and 'password' fields. For SSH repositories
|
||||||
and 'known_hosts' fields.
|
the Secret must contain 'identity', 'identity.pub' and 'known_hosts'
|
||||||
|
fields.
|
||||||
properties:
|
properties:
|
||||||
name:
|
name:
|
||||||
description: Name of the referent.
|
description: Name of the referent.
|
||||||
|
@ -492,31 +504,31 @@ spec:
|
||||||
type: object
|
type: object
|
||||||
suspend:
|
suspend:
|
||||||
description: Suspend tells the controller to suspend the reconciliation
|
description: Suspend tells the controller to suspend the reconciliation
|
||||||
of this source. This flag tells the controller to suspend the reconciliation
|
of this GitRepository.
|
||||||
of this source.
|
|
||||||
type: boolean
|
type: boolean
|
||||||
timeout:
|
timeout:
|
||||||
default: 60s
|
default: 60s
|
||||||
description: The timeout for remote Git operations like cloning, defaults
|
description: Timeout for Git operations like cloning, defaults to
|
||||||
to 60s.
|
60s.
|
||||||
type: string
|
type: string
|
||||||
url:
|
url:
|
||||||
description: The repository URL, can be a HTTP/S or SSH address.
|
description: URL specifies the Git repository URL, it can be an HTTP/S
|
||||||
|
or SSH address.
|
||||||
pattern: ^(http|https|ssh)://
|
pattern: ^(http|https|ssh)://
|
||||||
type: string
|
type: string
|
||||||
verify:
|
verify:
|
||||||
description: Verification defines the configuration to verify the
|
description: Verification specifies the configuration to verify the
|
||||||
OpenPGP signature for the Git commit HEAD points to.
|
Git commit signature(s).
|
||||||
properties:
|
properties:
|
||||||
mode:
|
mode:
|
||||||
description: Mode describes what Git object should be verified,
|
description: Mode specifies what Git object should be verified,
|
||||||
currently ('head').
|
currently ('head').
|
||||||
enum:
|
enum:
|
||||||
- head
|
- head
|
||||||
type: string
|
type: string
|
||||||
secretRef:
|
secretRef:
|
||||||
description: SecretRef containing the public keys of all trusted
|
description: SecretRef specifies the Secret containing the public
|
||||||
Git authors.
|
keys of trusted Git authors.
|
||||||
properties:
|
properties:
|
||||||
name:
|
name:
|
||||||
description: Name of the referent.
|
description: Name of the referent.
|
||||||
|
@ -534,11 +546,11 @@ spec:
|
||||||
status:
|
status:
|
||||||
default:
|
default:
|
||||||
observedGeneration: -1
|
observedGeneration: -1
|
||||||
description: GitRepositoryStatus defines the observed state of a Git repository.
|
description: GitRepositoryStatus records the observed state of a Git repository.
|
||||||
properties:
|
properties:
|
||||||
artifact:
|
artifact:
|
||||||
description: Artifact represents the output of the last successful
|
description: Artifact represents the last successful GitRepository
|
||||||
repository sync.
|
reconciliation.
|
||||||
properties:
|
properties:
|
||||||
checksum:
|
checksum:
|
||||||
description: Checksum is the SHA256 checksum of the Artifact file.
|
description: Checksum is the SHA256 checksum of the Artifact file.
|
||||||
|
@ -643,8 +655,8 @@ spec:
|
||||||
type: object
|
type: object
|
||||||
type: array
|
type: array
|
||||||
includedArtifacts:
|
includedArtifacts:
|
||||||
description: IncludedArtifacts represents the included artifacts from
|
description: IncludedArtifacts contains a list of the last successfully
|
||||||
the last successful repository sync.
|
included Artifacts as instructed by GitRepositorySpec.Include.
|
||||||
items:
|
items:
|
||||||
description: Artifact represents the output of a Source reconciliation.
|
description: Artifact represents the output of a Source reconciliation.
|
||||||
properties:
|
properties:
|
||||||
|
@ -689,12 +701,14 @@ spec:
|
||||||
be detected.
|
be detected.
|
||||||
type: string
|
type: string
|
||||||
observedGeneration:
|
observedGeneration:
|
||||||
description: ObservedGeneration is the last observed generation.
|
description: ObservedGeneration is the last observed generation of
|
||||||
|
the GitRepository object.
|
||||||
format: int64
|
format: int64
|
||||||
type: integer
|
type: integer
|
||||||
url:
|
url:
|
||||||
description: URL is the fetch link for the artifact output of the
|
description: URL is the dynamic fetch link for the latest Artifact.
|
||||||
last repository sync.
|
It is provided on a "best effort" basis, and using the precise GitRepositoryStatus.Artifact
|
||||||
|
data is recommended.
|
||||||
type: string
|
type: string
|
||||||
type: object
|
type: object
|
||||||
type: object
|
type: object
|
||||||
|
|
|
@ -54,9 +54,9 @@ import (
|
||||||
"github.com/fluxcd/source-controller/pkg/sourceignore"
|
"github.com/fluxcd/source-controller/pkg/sourceignore"
|
||||||
)
|
)
|
||||||
|
|
||||||
// gitRepoReadyConditions contains all the conditions information needed
|
// gitRepositoryReadyCondition contains the information required to summarize a
|
||||||
// for GitRepository Ready status conditions summary calculation.
|
// v1beta2.GitRepository Ready Condition.
|
||||||
var gitRepoReadyConditions = summarize.Conditions{
|
var gitRepositoryReadyCondition = summarize.Conditions{
|
||||||
Target: meta.ReadyCondition,
|
Target: meta.ReadyCondition,
|
||||||
Owned: []string{
|
Owned: []string{
|
||||||
sourcev1.SourceVerifiedCondition,
|
sourcev1.SourceVerifiedCondition,
|
||||||
|
@ -89,7 +89,7 @@ var gitRepoReadyConditions = summarize.Conditions{
|
||||||
// +kubebuilder:rbac:groups=source.toolkit.fluxcd.io,resources=gitrepositories/finalizers,verbs=get;create;update;patch;delete
|
// +kubebuilder:rbac:groups=source.toolkit.fluxcd.io,resources=gitrepositories/finalizers,verbs=get;create;update;patch;delete
|
||||||
// +kubebuilder:rbac:groups="",resources=events,verbs=create;patch
|
// +kubebuilder:rbac:groups="",resources=events,verbs=create;patch
|
||||||
|
|
||||||
// GitRepositoryReconciler reconciles a GitRepository object
|
// GitRepositoryReconciler reconciles a v1beta2.GitRepository object.
|
||||||
type GitRepositoryReconciler struct {
|
type GitRepositoryReconciler struct {
|
||||||
client.Client
|
client.Client
|
||||||
kuberecorder.EventRecorder
|
kuberecorder.EventRecorder
|
||||||
|
@ -106,9 +106,9 @@ type GitRepositoryReconcilerOptions struct {
|
||||||
DependencyRequeueInterval time.Duration
|
DependencyRequeueInterval time.Duration
|
||||||
}
|
}
|
||||||
|
|
||||||
// gitRepoReconcilerFunc is the function type for all the Git repository
|
// gitRepositoryReconcileFunc is the function type for all the
|
||||||
// reconciler functions.
|
// v1beta2.GitRepository (sub)reconcile functions.
|
||||||
type gitRepoReconcilerFunc func(ctx context.Context, obj *sourcev1.GitRepository, commit *git.Commit, includes *artifactSet, dir string) (sreconcile.Result, error)
|
type gitRepositoryReconcileFunc func(ctx context.Context, obj *sourcev1.GitRepository, commit *git.Commit, includes *artifactSet, dir string) (sreconcile.Result, error)
|
||||||
|
|
||||||
func (r *GitRepositoryReconciler) SetupWithManager(mgr ctrl.Manager) error {
|
func (r *GitRepositoryReconciler) SetupWithManager(mgr ctrl.Manager) error {
|
||||||
return r.SetupWithManagerAndOptions(mgr, GitRepositoryReconcilerOptions{})
|
return r.SetupWithManagerAndOptions(mgr, GitRepositoryReconcilerOptions{})
|
||||||
|
@ -158,7 +158,7 @@ func (r *GitRepositoryReconciler) Reconcile(ctx context.Context, req ctrl.Reques
|
||||||
defer func() {
|
defer func() {
|
||||||
summarizeHelper := summarize.NewHelper(r.EventRecorder, patchHelper)
|
summarizeHelper := summarize.NewHelper(r.EventRecorder, patchHelper)
|
||||||
summarizeOpts := []summarize.Option{
|
summarizeOpts := []summarize.Option{
|
||||||
summarize.WithConditions(gitRepoReadyConditions),
|
summarize.WithConditions(gitRepositoryReadyCondition),
|
||||||
summarize.WithReconcileResult(recResult),
|
summarize.WithReconcileResult(recResult),
|
||||||
summarize.WithReconcileError(retErr),
|
summarize.WithReconcileError(retErr),
|
||||||
summarize.WithIgnoreNotFound(),
|
summarize.WithIgnoreNotFound(),
|
||||||
|
@ -166,7 +166,7 @@ func (r *GitRepositoryReconciler) Reconcile(ctx context.Context, req ctrl.Reques
|
||||||
summarize.RecordContextualError,
|
summarize.RecordContextualError,
|
||||||
summarize.RecordReconcileReq,
|
summarize.RecordReconcileReq,
|
||||||
),
|
),
|
||||||
summarize.WithResultBuilder(sreconcile.AlwaysRequeueResultBuilder{RequeueAfter: obj.GetInterval().Duration}),
|
summarize.WithResultBuilder(sreconcile.AlwaysRequeueResultBuilder{RequeueAfter: obj.GetRequeueAfter()}),
|
||||||
summarize.WithPatchFieldOwner(r.ControllerName),
|
summarize.WithPatchFieldOwner(r.ControllerName),
|
||||||
}
|
}
|
||||||
result, retErr = summarizeHelper.SummarizeAndPatch(ctx, obj, summarizeOpts...)
|
result, retErr = summarizeHelper.SummarizeAndPatch(ctx, obj, summarizeOpts...)
|
||||||
|
@ -191,7 +191,7 @@ func (r *GitRepositoryReconciler) Reconcile(ctx context.Context, req ctrl.Reques
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reconcile actual object
|
// Reconcile actual object
|
||||||
reconcilers := []gitRepoReconcilerFunc{
|
reconcilers := []gitRepositoryReconcileFunc{
|
||||||
r.reconcileStorage,
|
r.reconcileStorage,
|
||||||
r.reconcileSource,
|
r.reconcileSource,
|
||||||
r.reconcileInclude,
|
r.reconcileInclude,
|
||||||
|
@ -201,17 +201,15 @@ func (r *GitRepositoryReconciler) Reconcile(ctx context.Context, req ctrl.Reques
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// reconcile steps iterates through the actual reconciliation tasks for objec,
|
// reconcile iterates through the gitRepositoryReconcileFunc tasks for the
|
||||||
// it returns early on the first step that returns ResultRequeue or produces an
|
// object. It returns early on the first call that returns
|
||||||
// error.
|
// reconcile.ResultRequeue, or produces an error.
|
||||||
func (r *GitRepositoryReconciler) reconcile(ctx context.Context, obj *sourcev1.GitRepository, reconcilers []gitRepoReconcilerFunc) (sreconcile.Result, error) {
|
func (r *GitRepositoryReconciler) reconcile(ctx context.Context, obj *sourcev1.GitRepository, reconcilers []gitRepositoryReconcileFunc) (sreconcile.Result, error) {
|
||||||
|
// Mark as reconciling if generation differs
|
||||||
if obj.Generation != obj.Status.ObservedGeneration {
|
if obj.Generation != obj.Status.ObservedGeneration {
|
||||||
conditions.MarkReconciling(obj, "NewGeneration", "reconciling new object generation (%d)", obj.Generation)
|
conditions.MarkReconciling(obj, "NewGeneration", "reconciling new object generation (%d)", obj.Generation)
|
||||||
}
|
}
|
||||||
|
|
||||||
var commit git.Commit
|
|
||||||
var includes artifactSet
|
|
||||||
|
|
||||||
// Create temp dir for Git clone
|
// Create temp dir for Git clone
|
||||||
tmpDir, err := util.TempDirForObj("", obj)
|
tmpDir, err := util.TempDirForObj("", obj)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -220,11 +218,20 @@ func (r *GitRepositoryReconciler) reconcile(ctx context.Context, obj *sourcev1.G
|
||||||
Reason: sourcev1.StorageOperationFailedReason,
|
Reason: sourcev1.StorageOperationFailedReason,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
defer os.RemoveAll(tmpDir)
|
defer func() {
|
||||||
|
if err = os.RemoveAll(tmpDir); err != nil {
|
||||||
|
ctrl.LoggerFrom(ctx).Error(err, "failed to remove temporary working directory")
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
// Run the sub-reconcilers and build the result of reconciliation.
|
// Run the sub-reconcilers and build the result of reconciliation.
|
||||||
var res sreconcile.Result
|
var (
|
||||||
var resErr error
|
commit git.Commit
|
||||||
|
includes artifactSet
|
||||||
|
|
||||||
|
res sreconcile.Result
|
||||||
|
resErr error
|
||||||
|
)
|
||||||
for _, rec := range reconcilers {
|
for _, rec := range reconcilers {
|
||||||
recResult, err := rec(ctx, obj, &commit, &includes, tmpDir)
|
recResult, err := rec(ctx, obj, &commit, &includes, tmpDir)
|
||||||
// Exit immediately on ResultRequeue.
|
// Exit immediately on ResultRequeue.
|
||||||
|
@ -244,14 +251,19 @@ func (r *GitRepositoryReconciler) reconcile(ctx context.Context, obj *sourcev1.G
|
||||||
return res, resErr
|
return res, resErr
|
||||||
}
|
}
|
||||||
|
|
||||||
// reconcileStorage ensures the current state of the storage matches the desired and previously observed state.
|
// reconcileStorage ensures the current state of the storage matches the
|
||||||
|
// desired and previously observed state.
|
||||||
//
|
//
|
||||||
// All artifacts for the resource except for the current one are garbage collected from the storage.
|
// All Artifacts for the object except for the current one in the Status are
|
||||||
// If the artifact in the Status object of the resource disappeared from storage, it is removed from the object.
|
// garbage collected from the Storage.
|
||||||
// If the object does not have an artifact in its Status object, a v1beta1.ArtifactUnavailableCondition is set.
|
// If the Artifact in the Status of the object disappeared from the Storage,
|
||||||
// If the hostname of any of the URLs on the object do not match the current storage server hostname, they are updated.
|
// it is removed from the object.
|
||||||
|
// If the object does not have an Artifact in its Status, a Reconciling
|
||||||
|
// condition is added.
|
||||||
|
// The hostname of any URL in the Status of the object are updated, to ensure
|
||||||
|
// they match the Storage server hostname of current runtime.
|
||||||
func (r *GitRepositoryReconciler) reconcileStorage(ctx context.Context,
|
func (r *GitRepositoryReconciler) reconcileStorage(ctx context.Context,
|
||||||
obj *sourcev1.GitRepository, _ *git.Commit, includes *artifactSet, dir string) (sreconcile.Result, error) {
|
obj *sourcev1.GitRepository, _ *git.Commit, _ *artifactSet, _ string) (sreconcile.Result, error) {
|
||||||
// Garbage collect previous advertised artifact(s) from storage
|
// Garbage collect previous advertised artifact(s) from storage
|
||||||
_ = r.garbageCollect(ctx, obj)
|
_ = r.garbageCollect(ctx, obj)
|
||||||
|
|
||||||
|
@ -275,17 +287,24 @@ func (r *GitRepositoryReconciler) reconcileStorage(ctx context.Context,
|
||||||
return sreconcile.ResultSuccess, nil
|
return sreconcile.ResultSuccess, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// reconcileSource ensures the upstream Git repository can be reached and checked out using the declared configuration,
|
// reconcileSource ensures the upstream Git repository and reference can be
|
||||||
// and observes its state.
|
// cloned and checked out using the specified configuration, and observes its
|
||||||
|
// state.
|
||||||
//
|
//
|
||||||
// The repository is checked out to the given dir using the defined configuration, and in case of an error during the
|
// The repository is cloned to the given dir, using the specified configuration
|
||||||
// checkout process (including transient errors), it records v1beta1.FetchFailedCondition=True and returns early.
|
// to check out the reference. In case of an error during this process
|
||||||
// On a successful checkout it removes v1beta1.FetchFailedCondition, and compares the current revision of HEAD to the
|
// (including transient errors), it records v1beta2.FetchFailedCondition=True
|
||||||
// artifact on the object, and records v1beta1.ArtifactOutdatedCondition if they differ.
|
// and returns early.
|
||||||
// If instructed, the signature of the commit is verified if and recorded as v1beta1.SourceVerifiedCondition. If the
|
// On a successful checkout, it removes v1beta2.FetchFailedCondition and
|
||||||
// signature can not be verified or the verification fails, the Condition=False and it returns early.
|
// compares the current revision of HEAD to the revision of the Artifact in the
|
||||||
// If both the checkout and signature verification are successful, the given artifact pointer is set to a new artifact
|
// Status of the object. It records v1beta2.ArtifactOutdatedCondition=True when
|
||||||
// with the available metadata.
|
// they differ.
|
||||||
|
// If specified, the signature of the Git commit is verified. If the signature
|
||||||
|
// can not be verified or the verification fails, it records
|
||||||
|
// v1beta2.SourceVerifiedCondition=False and returns early. When successful,
|
||||||
|
// it records v1beta2.SourceVerifiedCondition=True.
|
||||||
|
// When all the above is successful, the given Commit pointer is set to the
|
||||||
|
// commit of the checked out Git repository.
|
||||||
func (r *GitRepositoryReconciler) reconcileSource(ctx context.Context,
|
func (r *GitRepositoryReconciler) reconcileSource(ctx context.Context,
|
||||||
obj *sourcev1.GitRepository, commit *git.Commit, _ *artifactSet, dir string) (sreconcile.Result, error) {
|
obj *sourcev1.GitRepository, commit *git.Commit, _ *artifactSet, dir string) (sreconcile.Result, error) {
|
||||||
// Configure authentication strategy to access the source
|
// Configure authentication strategy to access the source
|
||||||
|
@ -376,15 +395,17 @@ func (r *GitRepositoryReconciler) reconcileSource(ctx context.Context,
|
||||||
return sreconcile.ResultSuccess, nil
|
return sreconcile.ResultSuccess, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// reconcileArtifact archives a new artifact to the storage, if the current observation on the object does not match the
|
// reconcileArtifact archives a new Artifact to the Storage, if the current
|
||||||
// given data.
|
// (Status) data on the object does not match the given.
|
||||||
//
|
//
|
||||||
// The inspection of the given data to the object is differed, ensuring any stale observations as
|
// The inspection of the given data to the object is differed, ensuring any
|
||||||
// v1beta1.ArtifactUnavailableCondition and v1beta1.ArtifactOutdatedCondition are always deleted.
|
// stale observations like v1beta2.ArtifactOutdatedCondition are removed.
|
||||||
// If the given artifact and/or includes do not differ from the object's current, it returns early.
|
// If the given Artifact and/or artifactSet (includes) do not differ from the
|
||||||
// Source ignore patterns are loaded, and the given directory is archived.
|
// object's current, it returns early.
|
||||||
// On a successful archive, the artifact and includes in the status of the given object are set, and the symlink in the
|
// Source ignore patterns are loaded, and the given directory is archived while
|
||||||
// storage is updated to its path.
|
// taking these patterns into account.
|
||||||
|
// On a successful archive, the Artifact and Includes in the Status of the
|
||||||
|
// object are set, and the 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
|
||||||
|
@ -477,14 +498,19 @@ func (r *GitRepositoryReconciler) reconcileArtifact(ctx context.Context,
|
||||||
return sreconcile.ResultSuccess, nil
|
return sreconcile.ResultSuccess, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// reconcileInclude reconciles the declared includes from the object by copying their artifact (sub)contents to the
|
// reconcileInclude reconciles the on the object specified
|
||||||
// declared paths in the given directory.
|
// v1beta2.GitRepositoryInclude list by copying their Artifact (sub)contents to
|
||||||
|
// the specified paths in the given directory.
|
||||||
//
|
//
|
||||||
// If an include is unavailable, it marks the object with v1beta1.IncludeUnavailableCondition and returns early.
|
// When one of the includes is unavailable, it marks the object with
|
||||||
// If the copy operations are successful, it deletes the v1beta1.IncludeUnavailableCondition from the object.
|
// v1beta2.IncludeUnavailableCondition=True and returns early.
|
||||||
// If the artifactSet differs from the current set, it marks the object with v1beta1.ArtifactOutdatedCondition.
|
// When the copy operations are successful, it removes the
|
||||||
|
// v1beta2.IncludeUnavailableCondition from the object.
|
||||||
|
// When the composed artifactSet differs from the current set in the Status of
|
||||||
|
// the object, it marks the object with v1beta2.ArtifactOutdatedCondition=True.
|
||||||
func (r *GitRepositoryReconciler) reconcileInclude(ctx context.Context,
|
func (r *GitRepositoryReconciler) reconcileInclude(ctx context.Context,
|
||||||
obj *sourcev1.GitRepository, _ *git.Commit, includes *artifactSet, dir string) (sreconcile.Result, error) {
|
obj *sourcev1.GitRepository, _ *git.Commit, includes *artifactSet, dir string) (sreconcile.Result, error) {
|
||||||
|
|
||||||
artifacts := make(artifactSet, len(obj.Spec.Include))
|
artifacts := make(artifactSet, len(obj.Spec.Include))
|
||||||
for i, incl := range obj.Spec.Include {
|
for i, incl := range obj.Spec.Include {
|
||||||
// Do this first as it is much cheaper than copy operations
|
// Do this first as it is much cheaper than copy operations
|
||||||
|
@ -546,25 +572,16 @@ func (r *GitRepositoryReconciler) reconcileInclude(ctx context.Context,
|
||||||
return sreconcile.ResultSuccess, nil
|
return sreconcile.ResultSuccess, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// reconcileDelete handles the delete of an object. It first garbage collects all artifacts for the object from the
|
// verifyCommitSignature verifies the signature of the given Git commit, if a
|
||||||
// artifact storage, if successful, the finalizer is removed from the object.
|
// verification mode is specified on the object.
|
||||||
func (r *GitRepositoryReconciler) reconcileDelete(ctx context.Context, obj *sourcev1.GitRepository) (sreconcile.Result, error) {
|
// If the signature can not be verified or the verification fails, it records
|
||||||
// Garbage collect the resource's artifacts
|
// v1beta2.SourceVerifiedCondition=False and returns.
|
||||||
if err := r.garbageCollect(ctx, obj); err != nil {
|
// When successful, it records v1beta2.SourceVerifiedCondition=True.
|
||||||
// Return the error so we retry the failed garbage collection
|
// If no verification mode is specified on the object, the
|
||||||
return sreconcile.ResultEmpty, err
|
// v1beta2.SourceVerifiedCondition Condition is removed.
|
||||||
}
|
|
||||||
|
|
||||||
// Remove our finalizer from the list
|
|
||||||
controllerutil.RemoveFinalizer(obj, sourcev1.SourceFinalizer)
|
|
||||||
|
|
||||||
// Stop reconciliation as the object is being deleted
|
|
||||||
return sreconcile.ResultEmpty, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// verifyCommitSignature verifies the signature of the given commit if a verification mode is configured on the object.
|
|
||||||
func (r *GitRepositoryReconciler) verifyCommitSignature(ctx context.Context, obj *sourcev1.GitRepository, commit git.Commit) (sreconcile.Result, error) {
|
func (r *GitRepositoryReconciler) verifyCommitSignature(ctx context.Context, obj *sourcev1.GitRepository, commit git.Commit) (sreconcile.Result, error) {
|
||||||
// Check if there is a commit verification is configured and remove any old observations if there is none
|
// Check if there is a commit verification is configured and remove any old
|
||||||
|
// observations if there is none
|
||||||
if obj.Spec.Verification == nil || obj.Spec.Verification.Mode == "" {
|
if obj.Spec.Verification == nil || obj.Spec.Verification.Mode == "" {
|
||||||
conditions.Delete(obj, sourcev1.SourceVerifiedCondition)
|
conditions.Delete(obj, sourcev1.SourceVerifiedCondition)
|
||||||
return sreconcile.ResultSuccess, nil
|
return sreconcile.ResultSuccess, nil
|
||||||
|
@ -607,9 +624,28 @@ func (r *GitRepositoryReconciler) verifyCommitSignature(ctx context.Context, obj
|
||||||
return sreconcile.ResultSuccess, nil
|
return sreconcile.ResultSuccess, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// garbageCollect performs a garbage collection for the given v1beta1.GitRepository. It removes all but the current
|
// reconcileDelete handles the deletion of the object.
|
||||||
// artifact except for when the deletion timestamp is set, which will result in the removal of all artifacts for the
|
// It first garbage collects all Artifacts for the object from the Storage.
|
||||||
// resource.
|
// Removing the finalizer from the object if successful.
|
||||||
|
func (r *GitRepositoryReconciler) reconcileDelete(ctx context.Context, obj *sourcev1.GitRepository) (sreconcile.Result, error) {
|
||||||
|
// Garbage collect the resource's artifacts
|
||||||
|
if err := r.garbageCollect(ctx, obj); err != nil {
|
||||||
|
// Return the error so we retry the failed garbage collection
|
||||||
|
return sreconcile.ResultEmpty, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove our finalizer from the list
|
||||||
|
controllerutil.RemoveFinalizer(obj, sourcev1.SourceFinalizer)
|
||||||
|
|
||||||
|
// Stop reconciliation as the object is being deleted
|
||||||
|
return sreconcile.ResultEmpty, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// garbageCollect performs a garbage collection for the given object.
|
||||||
|
//
|
||||||
|
// It removes all but the current Artifact from the Storage, unless the
|
||||||
|
// deletion timestamp on the object is set. Which will result in the
|
||||||
|
// removal of all Artifacts for the objects.
|
||||||
func (r *GitRepositoryReconciler) garbageCollect(ctx context.Context, obj *sourcev1.GitRepository) error {
|
func (r *GitRepositoryReconciler) garbageCollect(ctx context.Context, obj *sourcev1.GitRepository) error {
|
||||||
if !obj.DeletionTimestamp.IsZero() {
|
if !obj.DeletionTimestamp.IsZero() {
|
||||||
if deleted, err := r.Storage.RemoveAll(r.Storage.NewArtifactFor(obj.Kind, obj.GetObjectMeta(), "", "*")); err != nil {
|
if deleted, err := r.Storage.RemoveAll(r.Storage.NewArtifactFor(obj.Kind, obj.GetObjectMeta(), "", "*")); err != nil {
|
||||||
|
@ -637,9 +673,11 @@ func (r *GitRepositoryReconciler) garbageCollect(ctx context.Context, obj *sourc
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// eventLog records event and logs at the same time. This log is different from
|
// eventLogf records event and logs at the same time.
|
||||||
// the debug log in the event recorder in the sense that this is a simple log,
|
//
|
||||||
// the event recorder debug log contains complete details about the event.
|
// This log is different from the debug log in the EventRecorder, in the sense
|
||||||
|
// that this is a simple log. While the debug log contains complete details
|
||||||
|
// about the event.
|
||||||
func (r *GitRepositoryReconciler) eventLogf(ctx context.Context, obj runtime.Object, eventType string, reason string, messageFmt string, args ...interface{}) {
|
func (r *GitRepositoryReconciler) eventLogf(ctx context.Context, obj runtime.Object, eventType string, reason string, messageFmt string, args ...interface{}) {
|
||||||
msg := fmt.Sprintf(messageFmt, args...)
|
msg := fmt.Sprintf(messageFmt, args...)
|
||||||
// Log and emit event.
|
// Log and emit event.
|
||||||
|
|
|
@ -193,7 +193,7 @@ func TestGitRepositoryReconciler_Reconcile(t *testing.T) {
|
||||||
}, timeout).Should(BeTrue())
|
}, timeout).Should(BeTrue())
|
||||||
|
|
||||||
// Check if the object status is valid.
|
// Check if the object status is valid.
|
||||||
condns := &status.Conditions{NegativePolarity: gitRepoReadyConditions.NegativePolarity}
|
condns := &status.Conditions{NegativePolarity: gitRepositoryReadyCondition.NegativePolarity}
|
||||||
checker := status.NewChecker(testEnv.Client, testEnv.GetScheme(), condns)
|
checker := status.NewChecker(testEnv.Client, testEnv.GetScheme(), condns)
|
||||||
checker.CheckErr(ctx, obj)
|
checker.CheckErr(ctx, obj)
|
||||||
|
|
||||||
|
|
|
@ -240,7 +240,7 @@ BucketStatus
|
||||||
</div>
|
</div>
|
||||||
<h3 id="source.toolkit.fluxcd.io/v1beta2.GitRepository">GitRepository
|
<h3 id="source.toolkit.fluxcd.io/v1beta2.GitRepository">GitRepository
|
||||||
</h3>
|
</h3>
|
||||||
<p>GitRepository is the Schema for the gitrepositories API</p>
|
<p>GitRepository is the Schema for the gitrepositories API.</p>
|
||||||
<div class="md-typeset__scrollwrap">
|
<div class="md-typeset__scrollwrap">
|
||||||
<div class="md-typeset__table">
|
<div class="md-typeset__table">
|
||||||
<table>
|
<table>
|
||||||
|
@ -303,7 +303,7 @@ string
|
||||||
</em>
|
</em>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<p>The repository URL, can be a HTTP/S or SSH address.</p>
|
<p>URL specifies the Git repository URL, it can be an HTTP/S or SSH address.</p>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -317,9 +317,12 @@ github.com/fluxcd/pkg/apis/meta.LocalObjectReference
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<em>(Optional)</em>
|
<em>(Optional)</em>
|
||||||
<p>The secret name containing the Git credentials.
|
<p>SecretRef specifies the Secret containing authentication credentials for
|
||||||
For HTTPS repositories the secret must contain username and password fields.
|
the GitRepository.
|
||||||
For SSH repositories the secret must contain ‘identity’, ‘identity.pub’ and ‘known_hosts’ fields.</p>
|
For HTTPS repositories the Secret must contain ‘username’ and ‘password’
|
||||||
|
fields.
|
||||||
|
For SSH repositories the Secret must contain ‘identity’, ‘identity.pub’
|
||||||
|
and ‘known_hosts’ fields.</p>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -332,7 +335,7 @@ Kubernetes meta/v1.Duration
|
||||||
</em>
|
</em>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<p>The interval at which to check for repository updates.</p>
|
<p>Interval at which to check the GitRepository for updates.</p>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -346,7 +349,7 @@ Kubernetes meta/v1.Duration
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<em>(Optional)</em>
|
<em>(Optional)</em>
|
||||||
<p>The timeout for remote Git operations like cloning, defaults to 60s.</p>
|
<p>Timeout for Git operations like cloning, defaults to 60s.</p>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -360,8 +363,8 @@ GitRepositoryRef
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<em>(Optional)</em>
|
<em>(Optional)</em>
|
||||||
<p>The Git reference to checkout and monitor for changes, defaults to
|
<p>Reference specifies the Git reference to resolve and monitor for
|
||||||
master branch.</p>
|
changes, defaults to the ‘master’ branch.</p>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -375,7 +378,8 @@ GitRepositoryVerification
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<em>(Optional)</em>
|
<em>(Optional)</em>
|
||||||
<p>Verification defines the configuration to verify the OpenPGP signature for the Git commit HEAD points to.</p>
|
<p>Verification specifies the configuration to verify the Git commit
|
||||||
|
signature(s).</p>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -387,8 +391,9 @@ string
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<em>(Optional)</em>
|
<em>(Optional)</em>
|
||||||
<p>Ignore overrides the set of excluded patterns in the .sourceignore format (which is the same as .gitignore).
|
<p>Ignore overrides the set of excluded patterns in the .sourceignore format
|
||||||
If not provided, a default will be used, consult the documentation for your version to find out what those are.</p>
|
(which is the same as .gitignore). If not provided, a default will be used,
|
||||||
|
consult the documentation for your version to find out what those are.</p>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -400,8 +405,8 @@ bool
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<em>(Optional)</em>
|
<em>(Optional)</em>
|
||||||
<p>Suspend tells the controller to suspend the reconciliation of this source.
|
<p>Suspend tells the controller to suspend the reconciliation of this
|
||||||
This flag tells the controller to suspend the reconciliation of this source.</p>
|
GitRepository.</p>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -413,8 +418,8 @@ string
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<em>(Optional)</em>
|
<em>(Optional)</em>
|
||||||
<p>Determines which git client library to use.
|
<p>GitImplementation specifies which Git client library implementation to
|
||||||
Defaults to go-git, valid values are (‘go-git’, ‘libgit2’).</p>
|
use. Defaults to ‘go-git’, valid values are (‘go-git’, ‘libgit2’).</p>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -426,7 +431,8 @@ bool
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<em>(Optional)</em>
|
<em>(Optional)</em>
|
||||||
<p>When enabled, after the clone is created, initializes all submodules within, using their default settings.
|
<p>RecurseSubmodules enables the initialization of all submodules within
|
||||||
|
the GitRepository as cloned from the URL, using their default settings.
|
||||||
This option is available only when using the ‘go-git’ GitImplementation.</p>
|
This option is available only when using the ‘go-git’ GitImplementation.</p>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
@ -440,8 +446,8 @@ This option is available only when using the ‘go-git’ GitImplementat
|
||||||
</em>
|
</em>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<p>Include defines a list of GitRepository resources which artifacts should be included in the artifact produced for
|
<p>Include specifies a list of GitRepository resources which Artifacts
|
||||||
this resource.</p>
|
should be included in the Artifact produced for this GitRepository.</p>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -455,7 +461,9 @@ github.com/fluxcd/pkg/apis/acl.AccessFrom
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<em>(Optional)</em>
|
<em>(Optional)</em>
|
||||||
<p>AccessFrom defines an Access Control List for allowing cross-namespace references to this object.</p>
|
<p>AccessFrom specifies an Access Control List for allowing cross-namespace
|
||||||
|
references to this object.
|
||||||
|
NOTE: Not implemented, provisional as of <a href="https://github.com/fluxcd/flux2/pull/2092">https://github.com/fluxcd/flux2/pull/2092</a></p>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
@ -1218,7 +1226,8 @@ github.com/fluxcd/pkg/apis/meta.ReconcileRequestStatus
|
||||||
(<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>)
|
||||||
</p>
|
</p>
|
||||||
<p>GitRepositoryInclude defines a source with a from and to path.</p>
|
<p>GitRepositoryInclude specifies a local reference to a GitRepository which
|
||||||
|
Artifact (sub-)contents must be included, and where they should be placed.</p>
|
||||||
<div class="md-typeset__scrollwrap">
|
<div class="md-typeset__scrollwrap">
|
||||||
<div class="md-typeset__table">
|
<div class="md-typeset__table">
|
||||||
<table>
|
<table>
|
||||||
|
@ -1239,7 +1248,8 @@ github.com/fluxcd/pkg/apis/meta.LocalObjectReference
|
||||||
</em>
|
</em>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<p>Reference to a GitRepository to include.</p>
|
<p>GitRepositoryRef specifies the GitRepository which Artifact contents
|
||||||
|
must be included.</p>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -1251,7 +1261,8 @@ string
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<em>(Optional)</em>
|
<em>(Optional)</em>
|
||||||
<p>The path to copy contents from, defaults to the root directory.</p>
|
<p>FromPath specifies the path to copy contents from, defaults to the root
|
||||||
|
of the Artifact.</p>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -1263,7 +1274,8 @@ string
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<em>(Optional)</em>
|
<em>(Optional)</em>
|
||||||
<p>The path to copy contents to, defaults to the name of the source ref.</p>
|
<p>ToPath specifies the path to copy contents to, defaults to the name of
|
||||||
|
the GitRepositoryRef.</p>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
|
@ -1276,7 +1288,7 @@ string
|
||||||
(<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>)
|
||||||
</p>
|
</p>
|
||||||
<p>GitRepositoryRef defines the Git ref used for pull and checkout operations.</p>
|
<p>GitRepositoryRef specifies the Git reference to resolve and checkout.</p>
|
||||||
<div class="md-typeset__scrollwrap">
|
<div class="md-typeset__scrollwrap">
|
||||||
<div class="md-typeset__table">
|
<div class="md-typeset__table">
|
||||||
<table>
|
<table>
|
||||||
|
@ -1296,7 +1308,9 @@ string
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<em>(Optional)</em>
|
<em>(Optional)</em>
|
||||||
<p>The Git branch to checkout, defaults to master.</p>
|
<p>Branch to checkout, defaults to ‘master’ if no other field is defined.</p>
|
||||||
|
<p>When GitRepositorySpec.GitImplementation is set to ‘go-git’, a shallow
|
||||||
|
clone of the specified branch is performed.</p>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -1308,7 +1322,7 @@ string
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<em>(Optional)</em>
|
<em>(Optional)</em>
|
||||||
<p>The Git tag to checkout, takes precedence over Branch.</p>
|
<p>Tag to checkout, takes precedence over Branch.</p>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -1320,7 +1334,7 @@ string
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<em>(Optional)</em>
|
<em>(Optional)</em>
|
||||||
<p>The Git tag semver expression, takes precedence over Tag.</p>
|
<p>SemVer tag expression to checkout, takes precedence over Tag.</p>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -1332,7 +1346,10 @@ string
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<em>(Optional)</em>
|
<em>(Optional)</em>
|
||||||
<p>The Git commit SHA to checkout, if specified Tag filters will be ignored.</p>
|
<p>Commit SHA to checkout, takes precedence over all reference fields.</p>
|
||||||
|
<p>When GitRepositorySpec.GitImplementation is set to ‘go-git’, this can be
|
||||||
|
combined with Branch to shallow clone the branch, in which the commit is
|
||||||
|
expected to exist.</p>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
|
@ -1345,7 +1362,8 @@ string
|
||||||
(<em>Appears on:</em>
|
(<em>Appears on:</em>
|
||||||
<a href="#source.toolkit.fluxcd.io/v1beta2.GitRepository">GitRepository</a>)
|
<a href="#source.toolkit.fluxcd.io/v1beta2.GitRepository">GitRepository</a>)
|
||||||
</p>
|
</p>
|
||||||
<p>GitRepositorySpec defines the desired state of a Git repository.</p>
|
<p>GitRepositorySpec specifies the required configuration to produce an
|
||||||
|
Artifact for a Git repository.</p>
|
||||||
<div class="md-typeset__scrollwrap">
|
<div class="md-typeset__scrollwrap">
|
||||||
<div class="md-typeset__table">
|
<div class="md-typeset__table">
|
||||||
<table>
|
<table>
|
||||||
|
@ -1364,7 +1382,7 @@ string
|
||||||
</em>
|
</em>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<p>The repository URL, can be a HTTP/S or SSH address.</p>
|
<p>URL specifies the Git repository URL, it can be an HTTP/S or SSH address.</p>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -1378,9 +1396,12 @@ github.com/fluxcd/pkg/apis/meta.LocalObjectReference
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<em>(Optional)</em>
|
<em>(Optional)</em>
|
||||||
<p>The secret name containing the Git credentials.
|
<p>SecretRef specifies the Secret containing authentication credentials for
|
||||||
For HTTPS repositories the secret must contain username and password fields.
|
the GitRepository.
|
||||||
For SSH repositories the secret must contain ‘identity’, ‘identity.pub’ and ‘known_hosts’ fields.</p>
|
For HTTPS repositories the Secret must contain ‘username’ and ‘password’
|
||||||
|
fields.
|
||||||
|
For SSH repositories the Secret must contain ‘identity’, ‘identity.pub’
|
||||||
|
and ‘known_hosts’ fields.</p>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -1393,7 +1414,7 @@ Kubernetes meta/v1.Duration
|
||||||
</em>
|
</em>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<p>The interval at which to check for repository updates.</p>
|
<p>Interval at which to check the GitRepository for updates.</p>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -1407,7 +1428,7 @@ Kubernetes meta/v1.Duration
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<em>(Optional)</em>
|
<em>(Optional)</em>
|
||||||
<p>The timeout for remote Git operations like cloning, defaults to 60s.</p>
|
<p>Timeout for Git operations like cloning, defaults to 60s.</p>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -1421,8 +1442,8 @@ GitRepositoryRef
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<em>(Optional)</em>
|
<em>(Optional)</em>
|
||||||
<p>The Git reference to checkout and monitor for changes, defaults to
|
<p>Reference specifies the Git reference to resolve and monitor for
|
||||||
master branch.</p>
|
changes, defaults to the ‘master’ branch.</p>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -1436,7 +1457,8 @@ GitRepositoryVerification
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<em>(Optional)</em>
|
<em>(Optional)</em>
|
||||||
<p>Verification defines the configuration to verify the OpenPGP signature for the Git commit HEAD points to.</p>
|
<p>Verification specifies the configuration to verify the Git commit
|
||||||
|
signature(s).</p>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -1448,8 +1470,9 @@ string
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<em>(Optional)</em>
|
<em>(Optional)</em>
|
||||||
<p>Ignore overrides the set of excluded patterns in the .sourceignore format (which is the same as .gitignore).
|
<p>Ignore overrides the set of excluded patterns in the .sourceignore format
|
||||||
If not provided, a default will be used, consult the documentation for your version to find out what those are.</p>
|
(which is the same as .gitignore). If not provided, a default will be used,
|
||||||
|
consult the documentation for your version to find out what those are.</p>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -1461,8 +1484,8 @@ bool
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<em>(Optional)</em>
|
<em>(Optional)</em>
|
||||||
<p>Suspend tells the controller to suspend the reconciliation of this source.
|
<p>Suspend tells the controller to suspend the reconciliation of this
|
||||||
This flag tells the controller to suspend the reconciliation of this source.</p>
|
GitRepository.</p>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -1474,8 +1497,8 @@ string
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<em>(Optional)</em>
|
<em>(Optional)</em>
|
||||||
<p>Determines which git client library to use.
|
<p>GitImplementation specifies which Git client library implementation to
|
||||||
Defaults to go-git, valid values are (‘go-git’, ‘libgit2’).</p>
|
use. Defaults to ‘go-git’, valid values are (‘go-git’, ‘libgit2’).</p>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -1487,7 +1510,8 @@ bool
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<em>(Optional)</em>
|
<em>(Optional)</em>
|
||||||
<p>When enabled, after the clone is created, initializes all submodules within, using their default settings.
|
<p>RecurseSubmodules enables the initialization of all submodules within
|
||||||
|
the GitRepository as cloned from the URL, using their default settings.
|
||||||
This option is available only when using the ‘go-git’ GitImplementation.</p>
|
This option is available only when using the ‘go-git’ GitImplementation.</p>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
@ -1501,8 +1525,8 @@ This option is available only when using the ‘go-git’ GitImplementat
|
||||||
</em>
|
</em>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<p>Include defines a list of GitRepository resources which artifacts should be included in the artifact produced for
|
<p>Include specifies a list of GitRepository resources which Artifacts
|
||||||
this resource.</p>
|
should be included in the Artifact produced for this GitRepository.</p>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -1516,7 +1540,9 @@ github.com/fluxcd/pkg/apis/acl.AccessFrom
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<em>(Optional)</em>
|
<em>(Optional)</em>
|
||||||
<p>AccessFrom defines an Access Control List for allowing cross-namespace references to this object.</p>
|
<p>AccessFrom specifies an Access Control List for allowing cross-namespace
|
||||||
|
references to this object.
|
||||||
|
NOTE: Not implemented, provisional as of <a href="https://github.com/fluxcd/flux2/pull/2092">https://github.com/fluxcd/flux2/pull/2092</a></p>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
|
@ -1529,7 +1555,7 @@ github.com/fluxcd/pkg/apis/acl.AccessFrom
|
||||||
(<em>Appears on:</em>
|
(<em>Appears on:</em>
|
||||||
<a href="#source.toolkit.fluxcd.io/v1beta2.GitRepository">GitRepository</a>)
|
<a href="#source.toolkit.fluxcd.io/v1beta2.GitRepository">GitRepository</a>)
|
||||||
</p>
|
</p>
|
||||||
<p>GitRepositoryStatus defines the observed state of a Git repository.</p>
|
<p>GitRepositoryStatus records the observed state of a Git repository.</p>
|
||||||
<div class="md-typeset__scrollwrap">
|
<div class="md-typeset__scrollwrap">
|
||||||
<div class="md-typeset__table">
|
<div class="md-typeset__table">
|
||||||
<table>
|
<table>
|
||||||
|
@ -1549,7 +1575,8 @@ int64
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<em>(Optional)</em>
|
<em>(Optional)</em>
|
||||||
<p>ObservedGeneration is the last observed generation.</p>
|
<p>ObservedGeneration is the last observed generation of the GitRepository
|
||||||
|
object.</p>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -1575,7 +1602,9 @@ string
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<em>(Optional)</em>
|
<em>(Optional)</em>
|
||||||
<p>URL is the fetch link for the artifact output of the last repository sync.</p>
|
<p>URL is the dynamic fetch link for the latest Artifact.
|
||||||
|
It is provided on a “best effort” basis, and using the precise
|
||||||
|
GitRepositoryStatus.Artifact data is recommended.</p>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -1589,7 +1618,7 @@ Artifact
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<em>(Optional)</em>
|
<em>(Optional)</em>
|
||||||
<p>Artifact represents the output of the last successful repository sync.</p>
|
<p>Artifact represents the last successful GitRepository reconciliation.</p>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -1603,7 +1632,8 @@ Artifact
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<em>(Optional)</em>
|
<em>(Optional)</em>
|
||||||
<p>IncludedArtifacts represents the included artifacts from the last successful repository sync.</p>
|
<p>IncludedArtifacts contains a list of the last successfully included
|
||||||
|
Artifacts as instructed by GitRepositorySpec.Include.</p>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -1631,7 +1661,8 @@ github.com/fluxcd/pkg/apis/meta.ReconcileRequestStatus
|
||||||
(<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>)
|
||||||
</p>
|
</p>
|
||||||
<p>GitRepositoryVerification defines the OpenPGP signature verification process.</p>
|
<p>GitRepositoryVerification specifies the Git commit signature verification
|
||||||
|
strategy.</p>
|
||||||
<div class="md-typeset__scrollwrap">
|
<div class="md-typeset__scrollwrap">
|
||||||
<div class="md-typeset__table">
|
<div class="md-typeset__table">
|
||||||
<table>
|
<table>
|
||||||
|
@ -1650,7 +1681,7 @@ string
|
||||||
</em>
|
</em>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<p>Mode describes what Git object should be verified, currently (‘head’).</p>
|
<p>Mode specifies what Git object should be verified, currently (‘head’).</p>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -1663,7 +1694,8 @@ github.com/fluxcd/pkg/apis/meta.LocalObjectReference
|
||||||
</em>
|
</em>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<p>SecretRef containing the public keys of all trusted Git authors.</p>
|
<p>SecretRef specifies the Secret containing the public keys of trusted Git
|
||||||
|
authors.</p>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
|
|
|
@ -5,7 +5,7 @@ This is the v1beta2 API specification for defining the desired state sources of
|
||||||
## Specification
|
## Specification
|
||||||
|
|
||||||
* Source kinds:
|
* Source kinds:
|
||||||
+ GitRepository
|
+ [GitRepository](gitrepositories.md)
|
||||||
+ [HelmRepository](helmrepositories.md)
|
+ [HelmRepository](helmrepositories.md)
|
||||||
+ HelmChart
|
+ HelmChart
|
||||||
+ [Bucket](buckets.md)
|
+ [Bucket](buckets.md)
|
||||||
|
|
|
@ -0,0 +1,814 @@
|
||||||
|
# Git Repositories
|
||||||
|
|
||||||
|
The `GitRepository` API defines a Source to produce an Artifact for a Git
|
||||||
|
repository revision.
|
||||||
|
|
||||||
|
## Example
|
||||||
|
|
||||||
|
The following is an example of a GitRepository. It creates a tarball
|
||||||
|
(`.tar.gz`) Artifact with the fetched data from a Git repository for the
|
||||||
|
resolved reference.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
---
|
||||||
|
apiVersion: source.toolkit.fluxcd.io/v1beta2
|
||||||
|
kind: GitRepository
|
||||||
|
metadata:
|
||||||
|
name: podinfo
|
||||||
|
namespace: default
|
||||||
|
spec:
|
||||||
|
interval: 5m0s
|
||||||
|
url: https://github.com/stefanprodan/podinfo
|
||||||
|
ref:
|
||||||
|
branch: master
|
||||||
|
```
|
||||||
|
|
||||||
|
In the above example:
|
||||||
|
|
||||||
|
- A GitRepository named `podinfo` is created, indicated by the
|
||||||
|
`.metadata.name` field.
|
||||||
|
- The source-controller checks the Git repository every five minutes, indicated
|
||||||
|
by the `.spec.interval` field.
|
||||||
|
- It clones the `master` branch of the `https://github.com/stefanprodan/podinfo`
|
||||||
|
repository, indicated by the `.spec.ref.branch` and `.spec.url` fields.
|
||||||
|
- The specified branch and resolved HEAD revision are used as the Artifact
|
||||||
|
revision, reported in-cluster in the `.status.artifact.revision` field.
|
||||||
|
- When the current GitRepository revision differs from the latest fetched
|
||||||
|
revision, a new Artifact is archived.
|
||||||
|
- The new Artifact is reported in the `.status.artifact` field.
|
||||||
|
|
||||||
|
You can run this example by saving the manifest into `gitrepository.yaml`.
|
||||||
|
|
||||||
|
1. Apply the resource on the cluster:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
kubectl apply -f gitrepository.yaml
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Run `kubectl get gitrepository` to see the GitRepository:
|
||||||
|
|
||||||
|
```console
|
||||||
|
NAME URL READY STATUS AGE
|
||||||
|
podinfo https://github.com/stefanprodan/podinfo True stored artifact for revision 'master/132f4e719209eb10b9485302f8593fc0e680f4fc' 5s
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Run `kubectl describe gitrepository podinfo` to see the [Artifact](#artifact)
|
||||||
|
and [Conditions](#conditions) in the GitRepository's Status:
|
||||||
|
|
||||||
|
```console
|
||||||
|
...
|
||||||
|
Status:
|
||||||
|
Artifact:
|
||||||
|
Checksum: 95e386f421272710c4cedbbd8607dbbaa019d500e7a5a0b6720bc7bebefc7bf2
|
||||||
|
Last Update Time: 2022-02-14T11:23:36Z
|
||||||
|
Path: gitrepository/default/podinfo/132f4e719209eb10b9485302f8593fc0e680f4fc.tar.gz
|
||||||
|
Revision: master/132f4e719209eb10b9485302f8593fc0e680f4fc
|
||||||
|
URL: http://source-controller.source-system.svc.cluster.local./gitrepository/default/podinfo/132f4e719209eb10b9485302f8593fc0e680f4fc.tar.gz
|
||||||
|
Conditions:
|
||||||
|
Last Transition Time: 2022-02-14T11:23:36Z
|
||||||
|
Message: stored artifact for revision 'master/132f4e719209eb10b9485302f8593fc0e680f4fc'
|
||||||
|
Observed Generation: 1
|
||||||
|
Reason: Succeeded
|
||||||
|
Status: True
|
||||||
|
Type: Ready
|
||||||
|
Observed Generation: 1
|
||||||
|
URL: http://source-controller.source-system.svc.cluster.local./gitrepository/default/podinfo/latest.tar.gz
|
||||||
|
Events:
|
||||||
|
Type Reason Age From Message
|
||||||
|
---- ------ ---- ---- -------
|
||||||
|
Normal GitOperationSucceed 62s source-controller cloned 'https://github.com/stefanprodan/podinfo' and checked out revision 'master/132f4e719209eb10b9485302f8593fc0e680f4fc'
|
||||||
|
Normal NewArtifact 62s source-controller stored artifact for revision 'master/132f4e719209eb10b9485302f8593fc0e680f4fc'
|
||||||
|
```
|
||||||
|
|
||||||
|
## Writing a GitRepository spec
|
||||||
|
|
||||||
|
As with all other Kubernetes config, a GitRepository needs `apiVersion`,
|
||||||
|
`kind`, and `metadata` fields. The name of a GitRepository object must be a
|
||||||
|
valid [DNS subdomain name](https://kubernetes.io/docs/concepts/overview/working-with-objects/names#dns-subdomain-names).
|
||||||
|
|
||||||
|
A GitRepository also needs a
|
||||||
|
[`.spec` section](https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#spec-and-status).
|
||||||
|
|
||||||
|
### URL
|
||||||
|
|
||||||
|
`.spec.url` is a required field that specifies the HTTP/S or SSH address of the
|
||||||
|
Git repository.
|
||||||
|
|
||||||
|
**Note:** Unlike using `git`, the
|
||||||
|
[shorter scp-like syntax](https://git-scm.com/book/en/v2/Git-on-the-Server-The-Protocols#_the_ssh_protocol)
|
||||||
|
is not supported for SSH addresses (e.g. `user@example.com:repository.git`).
|
||||||
|
Instead, the valid URL format is `ssh://user@example.com:22/repository.git`.
|
||||||
|
|
||||||
|
### Secret reference
|
||||||
|
|
||||||
|
`.spec.secretRef.name` is an optional field to specify a name reference to a
|
||||||
|
Secret in the same namespace as the GitRepository, containing authentication
|
||||||
|
credentials for the Git repository.
|
||||||
|
|
||||||
|
The required fields in the Secret depend on the specified protocol in the
|
||||||
|
[URL](#url).
|
||||||
|
|
||||||
|
#### Basic access authentication
|
||||||
|
|
||||||
|
To authenticate towards a Git repository over HTTPS using basic access
|
||||||
|
authentication (in other words: using a username and password), the referenced
|
||||||
|
Secret is expected to contain `.data.username` and `.data.password` values.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Secret
|
||||||
|
metadata:
|
||||||
|
name: basic-access-auth
|
||||||
|
type: Opaque
|
||||||
|
data:
|
||||||
|
username: <BASE64>
|
||||||
|
password: <BASE64>
|
||||||
|
```
|
||||||
|
|
||||||
|
#### HTTPS Certificate Authority
|
||||||
|
|
||||||
|
To provide a Certificate Authority to trust while connecting with a Git
|
||||||
|
repository over HTTPS, the referenced Secret can contain a `.data.caFile`
|
||||||
|
value.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Secret
|
||||||
|
metadata:
|
||||||
|
name: https-ca-credentials
|
||||||
|
namespace: default
|
||||||
|
type: Opaque
|
||||||
|
data:
|
||||||
|
caFile: <BASE64>
|
||||||
|
```
|
||||||
|
|
||||||
|
#### SSH authentication
|
||||||
|
|
||||||
|
To authenticate towards a Git repository over SSH, the referenced Secret is
|
||||||
|
expected to contain `.data.identity`, `.data.identity.pub` and `known_hosts`
|
||||||
|
fields. With the respective private and public key of the SSH key pair, and the
|
||||||
|
host keys of the Git repository.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Secret
|
||||||
|
metadata:
|
||||||
|
name: ssh-credentials
|
||||||
|
type: Opaque
|
||||||
|
data:
|
||||||
|
identity: <BASE64>
|
||||||
|
identity.pub: <BASE64>
|
||||||
|
known_hosts: <BASE64>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Interval
|
||||||
|
|
||||||
|
`.spec.interval` is a required field that specifies the interval at which the
|
||||||
|
Git repository must be fetched.
|
||||||
|
|
||||||
|
After successfully reconciling the object, the source-controller requeues it
|
||||||
|
for inspection after the specified interval. The value must be in a
|
||||||
|
[Go recognized duration string format](https://pkg.go.dev/time#ParseDuration),
|
||||||
|
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.
|
||||||
|
|
||||||
|
### Timeout
|
||||||
|
|
||||||
|
`.spec.timeout` is an optional field to specify a timeout for Git operations
|
||||||
|
like cloning. The value must be in a
|
||||||
|
[Go recognized duration string format](https://pkg.go.dev/time#ParseDuration),
|
||||||
|
e.g. `1m30s` for a timeout of one minute and thirty seconds. The default value
|
||||||
|
is `60s`.
|
||||||
|
|
||||||
|
### Reference
|
||||||
|
|
||||||
|
`.spec.ref` is an optional field to specify the Git reference to resolve and
|
||||||
|
watch for changes. References are specified in one or more subfields
|
||||||
|
(`.branch`, `.tag`, `.semver`, `.commit`), with latter listed fields taking
|
||||||
|
precedence over earlier ones. If not specified, it defaults to a `master`
|
||||||
|
branch reference.
|
||||||
|
|
||||||
|
#### Branch example
|
||||||
|
|
||||||
|
To Git checkout a specified branch, use `.spec.ref.branch`:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
---
|
||||||
|
apiVersion: source.toolkit.fluxcd.io/v1beta2
|
||||||
|
kind: GitRepository
|
||||||
|
metadata:
|
||||||
|
name: <repository-name>
|
||||||
|
spec:
|
||||||
|
ref:
|
||||||
|
branch: <branch-name>
|
||||||
|
```
|
||||||
|
|
||||||
|
Using the [`go-git` Git implementation](#git-implementation), this will perform
|
||||||
|
a shallow clone to only fetch the specified branch.
|
||||||
|
|
||||||
|
#### Tag example
|
||||||
|
|
||||||
|
To Git checkout a specified tag, use `.spec.ref.tag`:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
---
|
||||||
|
apiVersion: source.toolkit.fluxcd.io/v1beta2
|
||||||
|
kind: GitRepository
|
||||||
|
metadata:
|
||||||
|
name: <repository-name>
|
||||||
|
spec:
|
||||||
|
ref:
|
||||||
|
tag: <tag-name>
|
||||||
|
```
|
||||||
|
|
||||||
|
This field takes precedence over [`.branch`](#branch-example).
|
||||||
|
|
||||||
|
#### SemVer example
|
||||||
|
|
||||||
|
To Git checkout a tag based on a
|
||||||
|
[SemVer range](https://github.com/Masterminds/semver#checking-version-constraints),
|
||||||
|
use `.spec.ref.semver`:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
---
|
||||||
|
apiVersion: source.toolkit.fluxcd.io/v1beta2
|
||||||
|
kind: GitRepository
|
||||||
|
metadata:
|
||||||
|
name: <repository-name>
|
||||||
|
spec:
|
||||||
|
ref:
|
||||||
|
# SemVer range reference: https://github.com/Masterminds/semver#checking-version-constraints
|
||||||
|
semver: "<semver-range>"
|
||||||
|
```
|
||||||
|
|
||||||
|
This field takes precedence over [`.branch`](#branch-example) and
|
||||||
|
[`.tag`](#tag-example).
|
||||||
|
|
||||||
|
#### Commit example
|
||||||
|
|
||||||
|
To Git checkout a specified commit, use `.spec.ref.commit`:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
---
|
||||||
|
apiVersion: source.toolkit.fluxcd.io/v1beta2
|
||||||
|
kind: GitRepository
|
||||||
|
metadata:
|
||||||
|
name: <repository-name>
|
||||||
|
spec:
|
||||||
|
ref:
|
||||||
|
commit: "<commit SHA>"
|
||||||
|
```
|
||||||
|
|
||||||
|
This field takes precedence over all other fields. Using the [`go-git` Git
|
||||||
|
implementation](#git-implementation), it can be combined with `.spec.ref.branch`
|
||||||
|
to perform a shallow clone of the branch, in which the commit must exist:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
---
|
||||||
|
apiVersion: source.toolkit.fluxcd.io/v1beta2
|
||||||
|
kind: GitRepository
|
||||||
|
metadata:
|
||||||
|
name: <repository-name>
|
||||||
|
spec:
|
||||||
|
ref:
|
||||||
|
branch: <branch>
|
||||||
|
commit: "<commit SHA within branch>"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Verification
|
||||||
|
|
||||||
|
`.spec.verify` is an optional field to enable the verification of Git commit
|
||||||
|
signatures. The field offers two subfields:
|
||||||
|
|
||||||
|
- `.mode`, to specify what Git commit object should be verified. Only supports
|
||||||
|
`head` at present.
|
||||||
|
- `.secretRef.name`, to specify a reference to a Secret in the same namespace as
|
||||||
|
the GitRepository. Containing the (PGP) public keys of trusted Git authors.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
---
|
||||||
|
apiVersion: source.toolkit.fluxcd.io/v1beta1
|
||||||
|
kind: GitRepository
|
||||||
|
metadata:
|
||||||
|
name: podinfo
|
||||||
|
namespace: default
|
||||||
|
spec:
|
||||||
|
interval: 1m
|
||||||
|
url: https://github.com/stefanprodan/podinfo
|
||||||
|
ref:
|
||||||
|
branch: master
|
||||||
|
verify:
|
||||||
|
mode: head
|
||||||
|
secretRef:
|
||||||
|
name: pgp-public-keys
|
||||||
|
```
|
||||||
|
|
||||||
|
When the verification succeeds, the controller adds a Condition with the
|
||||||
|
following attributes to the GitRepository's `.status.conditions`:
|
||||||
|
|
||||||
|
- `type: SourceVerifiedCondition`
|
||||||
|
- `status: "True"`
|
||||||
|
- `reason: Succeeded`
|
||||||
|
|
||||||
|
#### Verification Secret example
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Secret
|
||||||
|
metadata:
|
||||||
|
name: pgp-public-keys
|
||||||
|
namespace: default
|
||||||
|
type: Opaque
|
||||||
|
data:
|
||||||
|
author1.asc: <BASE64>
|
||||||
|
author2.asc: <BASE64>
|
||||||
|
```
|
||||||
|
|
||||||
|
Exporting armored public keys (`.asc` files) using `gpg`, and generating a
|
||||||
|
Secret:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
# Export armored public keys
|
||||||
|
gpg --export --armor 3CB12BA185C47B67 > author1.asc
|
||||||
|
gpg --export --armor 6A7436E8790F8689 > author2.asc
|
||||||
|
# Generate secret
|
||||||
|
kubectl create secret generic pgp-public-keys \
|
||||||
|
--from-file=author1.asc \
|
||||||
|
--from-file=author2.asc \
|
||||||
|
-o yaml
|
||||||
|
```
|
||||||
|
|
||||||
|
### Ignore
|
||||||
|
|
||||||
|
`.spec.ignore` is an optional field to specify rules in [the `.gitignore`
|
||||||
|
pattern format](https://git-scm.com/docs/gitignore#_pattern_format). Paths
|
||||||
|
matching the defined rules are excluded while archiving.
|
||||||
|
|
||||||
|
When specified, `.spec.ignore` overrides the [default exclusion
|
||||||
|
list](#default-exclusions), and may overrule the [`.sourceignore` file
|
||||||
|
exclusions](#sourceignore-file). See [excluding files](#excluding-files)
|
||||||
|
for more information.
|
||||||
|
|
||||||
|
### Suspend
|
||||||
|
|
||||||
|
`.spec.suspend` is an optional field to suspend the reconciliation of a
|
||||||
|
GitRepository. When set to `true`, the controller will stop reconciling the
|
||||||
|
GitRepository, and changes to the resource or in the Git repository will not
|
||||||
|
result in a new Artifact. When the field is set to `false` or removed, it will
|
||||||
|
resume.
|
||||||
|
|
||||||
|
### Git implementation
|
||||||
|
|
||||||
|
`.spec.gitImplementation` is an optional field to change the client library
|
||||||
|
implementation used for Git operations (e.g. clone, checkout). The default
|
||||||
|
value is `go-git`.
|
||||||
|
|
||||||
|
Unless you need support for a specific Git wire protocol functionality not
|
||||||
|
supported by the default implementation (as documented below), changing the
|
||||||
|
implementation is generally not recommended as it can come with its own set of
|
||||||
|
drawbacks. For example, not being able to make use of shallow clones forces the
|
||||||
|
controller to fetch the whole Git history tree instead of a specific one,
|
||||||
|
resulting in an increase of disk space and traffic usage.
|
||||||
|
|
||||||
|
| Git Implementation | Shallow Clones | Git Submodules | V2 Protocol Support |
|
||||||
|
|--------------------|----------------|----------------|---------------------|
|
||||||
|
| `go-git` | true | true | false |
|
||||||
|
| `libgit2` | false | false | true |
|
||||||
|
|
||||||
|
Some Git providers like Azure DevOps _require_ the `libgit2` implementation, as
|
||||||
|
their Git servers provide only support for the
|
||||||
|
[v2 protocol](https://git-scm.com/docs/protocol-v2).
|
||||||
|
|
||||||
|
#### Proxy support
|
||||||
|
|
||||||
|
When a proxy is configured in the source-controller Pod through the appropriate
|
||||||
|
environment variables, for example `HTTPS_PROXY`, `NO_PROXY`, etc. There may be
|
||||||
|
some limitations in the proxy support based on the Git implementation.
|
||||||
|
|
||||||
|
| Git Implementation | HTTP_PROXY | HTTPS_PROXY | NO_PROXY | Self-signed Certs |
|
||||||
|
|--------------------|------------|-------------|----------|-------------------|
|
||||||
|
| `go-git` | true | true | true | false |n
|
||||||
|
| `libgit2` | true | true | true | true |
|
||||||
|
|
||||||
|
### Recurse submodules
|
||||||
|
|
||||||
|
`.spec.recurseSubmodules` is an optional field to enable the initialization of
|
||||||
|
all submodules within the cloned Git repository, using their default settings.
|
||||||
|
This option is only available when using the (default) `go-git` [Git
|
||||||
|
implementation](#git-implementation), and defaults to `false`.
|
||||||
|
|
||||||
|
Note that for most Git providers (e.g. GitHub and GitLab), deploy keys can not
|
||||||
|
be used as reusing a key across multiple repositories is not allowed. You have
|
||||||
|
to use either [HTTPS token-based authentication](#basic-access-authentication),
|
||||||
|
or an SSH key belonging to a (bot) user who has access to the main repository
|
||||||
|
and all submodules.
|
||||||
|
|
||||||
|
### Include
|
||||||
|
|
||||||
|
`.spec.include` is an optional field to map the contents of GitRepository
|
||||||
|
Artifacts into another. This may look identical to Git submodules but has
|
||||||
|
multiple benefits over regular submodules:
|
||||||
|
|
||||||
|
- Including a `GitRepository` allows you to use different authentication
|
||||||
|
methods for different repositories.
|
||||||
|
- A change in the included repository will trigger an update of the including
|
||||||
|
repository.
|
||||||
|
- Multiple `GitRepository` objects could include the same repository, which
|
||||||
|
decreases the amount of cloning done compared to using submodules.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
---
|
||||||
|
apiVersion: source.toolkit.fluxcd.io/v1beta2
|
||||||
|
kind: GitRepository
|
||||||
|
metadata:
|
||||||
|
name: include-example
|
||||||
|
spec:
|
||||||
|
include:
|
||||||
|
- repository:
|
||||||
|
name: other-repository
|
||||||
|
fromPath: deploy/kubernetes
|
||||||
|
toPath: base/app
|
||||||
|
```
|
||||||
|
|
||||||
|
The `.fromPath` and `.toPath` fields allow you to limit the files included, and
|
||||||
|
where they will be copied to. If you do not specify a value for `.fromPath`,
|
||||||
|
all files from the referenced GitRepository Artifact will be included. The
|
||||||
|
`.toPath` defaults to the `.repository.name` (e.g. `./other-repository/*`).
|
||||||
|
|
||||||
|
## Working with GitRepositories
|
||||||
|
|
||||||
|
### Excluding files
|
||||||
|
|
||||||
|
By default, files which match the [default exclusion rules](#default-exclusions)
|
||||||
|
are excluded while archiving the Git repository contents as an Artifact. It is
|
||||||
|
possible to overwrite and/or overrule the default exclusions using a file in
|
||||||
|
the Git repository and/or an in-spec set of rules.
|
||||||
|
|
||||||
|
#### `.sourceignore` file
|
||||||
|
|
||||||
|
Excluding files is possible by adding a `.sourceignore` file in the Git
|
||||||
|
repository. The `.sourceignore` file follows [the `.gitignore` pattern
|
||||||
|
format](https://git-scm.com/docs/gitignore#_pattern_format), and
|
||||||
|
pattern entries may overrule [default exclusions](#default-exclusions).
|
||||||
|
|
||||||
|
#### Ignore spec
|
||||||
|
|
||||||
|
Another option is to define the exclusions within the GitRepository spec, using
|
||||||
|
the [`.spec.ignore` field](#ignore). Specified rules override the [default
|
||||||
|
exclusion list](#default-exclusions), and may overrule `.sourceignore` file
|
||||||
|
exclusions.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
---
|
||||||
|
apiVersion: source.toolkit.fluxcd.io/v1beta2
|
||||||
|
kind: GitRepository
|
||||||
|
metadata:
|
||||||
|
name: <repository-name>
|
||||||
|
spec:
|
||||||
|
ignore: |
|
||||||
|
# exclude all
|
||||||
|
/*
|
||||||
|
# include deploy dir
|
||||||
|
!/deploy
|
||||||
|
# exclude file extensions from deploy dir
|
||||||
|
/deploy/**/*.md
|
||||||
|
/deploy/**/*.txt
|
||||||
|
```
|
||||||
|
|
||||||
|
### Triggering a reconcile
|
||||||
|
|
||||||
|
To manually tell the source-controller to reconcile a GitRepository outside the
|
||||||
|
[specified interval window](#interval), a GitRepository can be annotated with
|
||||||
|
`reconcile.fluxcd.io/requestedAt: <arbitrary value>`. Annotating the resource
|
||||||
|
queues the GitRepository for reconciliation if the `<arbitrary-value>` differs
|
||||||
|
from the last value the controller acted on, as reported in
|
||||||
|
[`.status.lastHandledReconcileAt`](#last-handled-reconcile-at).
|
||||||
|
|
||||||
|
Using `kubectl`:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
kubectl annotate --overwrite gitrepository/<repository-name> reconcile.fluxcd.io/requestedAt="$(date +%s)"
|
||||||
|
```
|
||||||
|
|
||||||
|
Using `flux`:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
flux reconcile source git <repository-name>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Waiting for `Ready`
|
||||||
|
|
||||||
|
When a change is applied, it is possible to wait for the GitRepository to reach
|
||||||
|
a [ready state](#ready-gitrepository) using `kubectl`:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
kubectl wait gitrepository/<repository-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 GitRepository, you can suspend it using the
|
||||||
|
[`.spec.suspend` field](#suspend).
|
||||||
|
|
||||||
|
#### Suspend a GitRepository
|
||||||
|
|
||||||
|
In your YAML declaration:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
---
|
||||||
|
apiVersion: source.toolkit.fluxcd.io/v1beta2
|
||||||
|
kind: GitRepository
|
||||||
|
metadata:
|
||||||
|
name: <repository-name>
|
||||||
|
spec:
|
||||||
|
suspend: true
|
||||||
|
```
|
||||||
|
|
||||||
|
Using `kubectl`:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
kubectl patch gitrepository <repository-name> -p '{\"spec\": {\"suspend\" : true }}'
|
||||||
|
```
|
||||||
|
|
||||||
|
Using `flux`:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
flux suspend source git <repository-name>
|
||||||
|
```
|
||||||
|
|
||||||
|
**Note:** When a GitRepository has an Artifact and is suspended, and this
|
||||||
|
Artifact later disappears from the storage due to e.g. the source-controller
|
||||||
|
Pod being evicted from a Node, this will not be reflected in the
|
||||||
|
GitRepository's Status until it is resumed.
|
||||||
|
|
||||||
|
#### Resume a GitRepository
|
||||||
|
|
||||||
|
In your YAML declaration, comment out (or remove) the field:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
---
|
||||||
|
apiVersion: source.toolkit.fluxcd.io/v1beta2
|
||||||
|
kind: GitRepository
|
||||||
|
metadata:
|
||||||
|
name: <repository-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`:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
kubectl patch gitrepository <repository-name> -p '{\"spec\" : {\"suspend\" : false }}'
|
||||||
|
```
|
||||||
|
|
||||||
|
Using `flux`:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
flux resume source git <repository-name>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Debugging a GitRepository
|
||||||
|
|
||||||
|
There are several ways to gather information about a GitRepository for
|
||||||
|
debugging purposes.
|
||||||
|
|
||||||
|
#### Describe the GitRepository
|
||||||
|
|
||||||
|
Describing a GitRepository using
|
||||||
|
`kubectl describe gitrepository <repository-name>`
|
||||||
|
displays the latest recorded information for the resource in the `Status` and
|
||||||
|
`Events` sections:
|
||||||
|
|
||||||
|
```console
|
||||||
|
...
|
||||||
|
Status:
|
||||||
|
...
|
||||||
|
Conditions:
|
||||||
|
Last Transition Time: 2022-02-14T09:40:27Z
|
||||||
|
Message: reconciling new generation 2
|
||||||
|
Observed Generation: 2
|
||||||
|
Reason: NewGeneration
|
||||||
|
Status: True
|
||||||
|
Type: Reconciling
|
||||||
|
Last Transition Time: 2022-02-14T09:40:27Z
|
||||||
|
Message: failed to checkout and determine revision: unable to clone 'https://github.com/stefanprodan/podinfo': couldn't find remote ref "refs/heads/invalid"
|
||||||
|
Observed Generation: 2
|
||||||
|
Reason: GitOperationFailed
|
||||||
|
Status: False
|
||||||
|
Type: Ready
|
||||||
|
Last Transition Time: 2022-02-14T09:40:27Z
|
||||||
|
Message: failed to checkout and determine revision: unable to clone 'https://github.com/stefanprodan/podinfo': couldn't find remote ref "refs/heads/invalid"
|
||||||
|
Observed Generation: 2
|
||||||
|
Reason: GitOperationFailed
|
||||||
|
Status: True
|
||||||
|
Type: FetchFailed
|
||||||
|
Observed Generation: 1
|
||||||
|
URL: http://source-controller.source-system.svc.cluster.local./gitrepository/default/gitrepository-sample/latest.tar.gz
|
||||||
|
Events:
|
||||||
|
Type Reason Age From Message
|
||||||
|
---- ------ ---- ---- -------
|
||||||
|
Warning GitOperationFailed 2s (x9 over 4s) source-controller failed to checkout and determine revision: unable to clone 'https://github.com/stefanprodan/podinfo': couldn't find remote ref "refs/heads/invalid"
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Trace emitted Events
|
||||||
|
|
||||||
|
To view events for specific GitRepository(s), `kubectl get events` can be used
|
||||||
|
in combination with `--field-sector` to list the Events for specific objects.
|
||||||
|
For example, running
|
||||||
|
|
||||||
|
```sh
|
||||||
|
kubectl get events --field-selector involvedObject.kind=GitRepository,involvedObject.name=<repository-name>
|
||||||
|
```
|
||||||
|
|
||||||
|
lists
|
||||||
|
|
||||||
|
```console
|
||||||
|
LAST SEEN TYPE REASON OBJECT MESSAGE
|
||||||
|
2m14s Normal GitOperationSucceed gitrepository/<repository-name> cloned 'https://github.com/stefanprodan/podinfo' and checked out revision 'master/132f4e719209eb10b9485302f8593fc0e680f4fc'
|
||||||
|
2m14s Normal NewArtifact gitrepository/<repository-name> stored artifact for revision 'master/132f4e719209eb10b9485302f8593fc0e680f4fc'
|
||||||
|
94s Warning GitOperationFailed gitrepository/gitrepository-sample failed to checkout and determine revision: unable to clone 'https://github.com/stefanprodan/podinfo': couldn't find remote ref "refs/heads/invalid"
|
||||||
|
```
|
||||||
|
|
||||||
|
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 GitRepository, e.g.
|
||||||
|
`flux logs --level=error --kind=GitRepository --name=<repository-name>`.
|
||||||
|
|
||||||
|
## GitRepository Status
|
||||||
|
|
||||||
|
### Artifact
|
||||||
|
|
||||||
|
The GitRepository reports the latest synchronized state from the Git repository
|
||||||
|
as an Artifact object in the `.status.artifact` of the resource.
|
||||||
|
|
||||||
|
The Artifact file is a gzip compressed TAR archive (`<commit sha>.tar.gz`), and
|
||||||
|
can be retrieved in-cluster from the `.status.artifact.url` HTTP address.
|
||||||
|
|
||||||
|
#### Artifact example
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
---
|
||||||
|
apiVersion: source.toolkit.fluxcd.io/v1beta2
|
||||||
|
kind: GitRepository
|
||||||
|
metadata:
|
||||||
|
name: <repository-name>
|
||||||
|
status:
|
||||||
|
artifact:
|
||||||
|
checksum: e750c7a46724acaef8f8aa926259af30bbd9face2ae065ae8896ba5ee5ab832b
|
||||||
|
lastUpdateTime: "2022-01-29T06:59:23Z"
|
||||||
|
path: gitrepository/<namespace>/<repository-name>/c3ab8ff13720e8ad9047dd39466b3c8974e592c2fa383d4a3960714caef0c4f2.tar.gz
|
||||||
|
revision: master/363a6a8fe6a7f13e05d34c163b0ef02a777da20a
|
||||||
|
url: http://source-controller.<namespace>.svc.cluster.local./gitrepository/<namespace>/<repository-name>/363a6a8fe6a7f13e05d34c163b0ef02a777da20a.tar.gz
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Default exclusions
|
||||||
|
|
||||||
|
The following files and extensions are excluded from the Artifact by
|
||||||
|
default:
|
||||||
|
|
||||||
|
- Git files (`.git/, .gitignore, .gitmodules, .gitattributes`)
|
||||||
|
- File extensions (`.jpg, .jpeg, .gif, .png, .wmv, .flv, .tar.gz, .zip`)
|
||||||
|
- CI configs (`.github/, .circleci/, .travis.yml, .gitlab-ci.yml, appveyor.yml, .drone.yml, cloudbuild.yaml, codeship-services.yml, codeship-steps.yml`)
|
||||||
|
- CLI configs (`.goreleaser.yml, .sops.yaml`)
|
||||||
|
- Flux v1 config (`.flux.yaml`)
|
||||||
|
|
||||||
|
To define your own exclusion rules, see [excluding files](#excluding-files).
|
||||||
|
|
||||||
|
### Conditions
|
||||||
|
|
||||||
|
A GitRepository enters various states during its lifecycle, reflected as
|
||||||
|
[Kubernetes Conditions][typical-status-properties].
|
||||||
|
It can be [reconciling](#reconciling-gitrepository) while fetching the Git
|
||||||
|
state, it can be [ready](#ready-gitrepository), or it can [fail during
|
||||||
|
reconciliation](#failed-gitrepository).
|
||||||
|
|
||||||
|
The GitRepository API is compatible with the [kstatus specification][kstatus-spec],
|
||||||
|
and reports `Reconciling` and `Stalled` conditions where applicable to
|
||||||
|
provide better (timeout) support to solutions polling the GitRepository to
|
||||||
|
become `Ready`.
|
||||||
|
|
||||||
|
#### Reconciling GitRepository
|
||||||
|
|
||||||
|
The source-controller marks a GitRepository as _reconciling_ when one of the
|
||||||
|
following is true:
|
||||||
|
|
||||||
|
- There is no current Artifact for the GitRepository, or the reported Artifact
|
||||||
|
is determined to have disappeared from the storage.
|
||||||
|
- The generation of the GitRepository is newer than the [Observed
|
||||||
|
Generation](#observed-generation).
|
||||||
|
- The newly resolved Artifact revision differs from the current Artifact.
|
||||||
|
|
||||||
|
When the GitRepository is "reconciling", the `Ready` Condition status becomes
|
||||||
|
`False`, and the controller adds a Condition with the following attributes to
|
||||||
|
the GitRepository's `.status.conditions`:
|
||||||
|
|
||||||
|
- `type: Reconciling`
|
||||||
|
- `status: "True"`
|
||||||
|
- `reason: NewGeneration` | `reason: NoArtifact` | `reason: NewRevision`
|
||||||
|
|
||||||
|
If the reconciling state is due to a new revision, an additional Condition is
|
||||||
|
added with the following attributes:
|
||||||
|
|
||||||
|
- `type: ArtifactOutdated`
|
||||||
|
- `status: "True"`
|
||||||
|
- `reason: NewRevision`
|
||||||
|
|
||||||
|
Both Conditions have a ["negative polarity"][typical-status-properties],
|
||||||
|
and are only present on the GitRepository while their status value is `"True"`.
|
||||||
|
|
||||||
|
#### Ready GitRepository
|
||||||
|
|
||||||
|
The source-controller marks a GitRepository as _ready_ when it has the
|
||||||
|
following characteristics:
|
||||||
|
|
||||||
|
- The GitRepository reports an [Artifact](#artifact).
|
||||||
|
- The reported Artifact exists in the controller's Artifact storage.
|
||||||
|
- The controller was able to communicate with the remote Git repository using
|
||||||
|
the current spec.
|
||||||
|
- The revision of the reported Artifact is up-to-date with the latest
|
||||||
|
resolved revision of the remote Git repository.
|
||||||
|
|
||||||
|
When the GitRepository is "ready", the controller sets a Condition with the
|
||||||
|
following attributes in the GitRepository's `.status.conditions`:
|
||||||
|
|
||||||
|
- `type: Ready`
|
||||||
|
- `status: "True"`
|
||||||
|
- `reason: Succeeded`
|
||||||
|
|
||||||
|
This `Ready` Condition will retain a status value of `"True"` until the
|
||||||
|
GitRepository is marked as [reconciling](#reconciling-gitrepository), or e.g. a
|
||||||
|
[transient error](#failed-gitrepository) occurs due to a temporary network issue.
|
||||||
|
|
||||||
|
#### Failed GitRepository
|
||||||
|
|
||||||
|
The source-controller may get stuck trying to produce an Artifact for a
|
||||||
|
GitRepository without completing. This can occur due to some of the following
|
||||||
|
factors:
|
||||||
|
|
||||||
|
- The remote Git repository [URL](#url) is temporarily unavailable.
|
||||||
|
- The Git repository does not exist.
|
||||||
|
- The [Secret reference](#secret-reference) contains a reference to a
|
||||||
|
non-existing Secret.
|
||||||
|
- A specified Include is unavailable.
|
||||||
|
- The verification of the Git commit signature failed.
|
||||||
|
- The credentials in the referenced Secret are invalid.
|
||||||
|
- The GitRepository spec contains a generic misconfiguration.
|
||||||
|
|
||||||
|
When this happens, the controller sets the `Ready` Condition status to `False`,
|
||||||
|
and adds a Condition with the following attributes to the GitRepository's
|
||||||
|
`.status.conditions`:
|
||||||
|
|
||||||
|
- `type: FetchFailed` | `type: IncludeUnavailableCondition`
|
||||||
|
- `status: "True"`
|
||||||
|
- `reason: AuthenticationFailed` | `reason: GitOperationFailed` | `reason: StorageOperationFailed`
|
||||||
|
|
||||||
|
This condition has a ["negative polarity"][typical-status-properties],
|
||||||
|
and is only present on the GitRepository while the status value is `"True"`.
|
||||||
|
|
||||||
|
In addition to the above Condition types, when the
|
||||||
|
[verification of a Git commit signature](#verification) fails. A condition with
|
||||||
|
the following attributes is added to the GitRepository's `.status.conditions`:
|
||||||
|
|
||||||
|
- `type: SourceVerifiedCondition`
|
||||||
|
- `status: "False"`
|
||||||
|
- `reason: Failed`
|
||||||
|
|
||||||
|
While the GitRepository has one or more of these Conditions, the controller
|
||||||
|
will continue to attempt to produce an Artifact for the resource with an
|
||||||
|
exponential backoff, until it succeeds and the GitRepository is marked as
|
||||||
|
[ready](#ready-gitrepository).
|
||||||
|
|
||||||
|
Note that a GitRepository can be [reconciling](#reconciling-gitrepository)
|
||||||
|
while failing at the same time, for example due to a newly introduced
|
||||||
|
configuration issue in the GitRepository spec.
|
||||||
|
|
||||||
|
### Observed Generation
|
||||||
|
|
||||||
|
The source-controller reports an [observed generation][typical-status-properties]
|
||||||
|
in the GitRepository's `.status.observedGeneration`. The observed generation is
|
||||||
|
the latest `.metadata.generation` which resulted in either a [ready state](#ready-gitrepository),
|
||||||
|
or stalled due to error it can not recover from without human
|
||||||
|
intervention.
|
||||||
|
|
||||||
|
### Last Handled Reconcile At
|
||||||
|
|
||||||
|
The source-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](#triggering-a-reconcile).
|
||||||
|
|
||||||
|
[typical-status-properties]: https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#typical-status-properties
|
||||||
|
[kstatus-spec]: https://github.com/kubernetes-sigs/cli-utils/tree/master/pkg/kstatus
|
Loading…
Reference in New Issue