Merge pull request #1881 from fluxcd/external-artifact

[RFC-0012] Implement ExternalArtifact API
This commit is contained in:
Stefan Prodan 2025-09-04 14:13:16 +03:00 committed by GitHub
commit c8358d063c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
47 changed files with 1059 additions and 576 deletions

View File

@ -43,4 +43,7 @@ resources:
- group: source
kind: OCIRepository
version: v1
- group: source
kind: ExternalArtifact
version: v1
version: "2"

View File

@ -4,7 +4,7 @@ go 1.25.0
require (
github.com/fluxcd/pkg/apis/acl v0.9.0
github.com/fluxcd/pkg/apis/meta v1.20.0
github.com/fluxcd/pkg/apis/meta v1.21.0
k8s.io/apimachinery v0.34.0
sigs.k8s.io/controller-runtime v0.22.0
)

View File

@ -4,8 +4,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/fluxcd/pkg/apis/acl v0.9.0 h1:wBpgsKT+jcyZEcM//OmZr9RiF8klL3ebrDp2u2ThsnA=
github.com/fluxcd/pkg/apis/acl v0.9.0/go.mod h1:TttNS+gocsGLwnvmgVi3/Yscwqrjc17+vhgYfqkfrV4=
github.com/fluxcd/pkg/apis/meta v1.20.0 h1:l9h0kWoDZTcYV0WJkFMgDXq6Q4tSojrJ+bHpFJSsaW0=
github.com/fluxcd/pkg/apis/meta v1.20.0/go.mod h1:XUAEUgT4gkWDAEN79E141tmL+v4SV50tVZ/Ojpc/ueg=
github.com/fluxcd/pkg/apis/meta v1.21.0 h1:R+bN02chcs0HUmyVDQhqe/FHmYLjipVDMLnyYfNX850=
github.com/fluxcd/pkg/apis/meta v1.21.0/go.mod h1:XUAEUgT4gkWDAEN79E141tmL+v4SV50tVZ/Ojpc/ueg=
github.com/fxamacker/cbor/v2 v2.9.0 h1:NpKPmjDBgUfBms6tr6JZkTHtfFGcMKsw3eGcmD/sapM=
github.com/fxamacker/cbor/v2 v2.9.0/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ=
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=

View File

@ -1,93 +0,0 @@
/*
Copyright 2023 The Flux authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package v1
import (
"path"
"strings"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
// Artifact represents the output of a Source reconciliation.
type Artifact struct {
// Path is the relative file path of the Artifact. It can be used to locate
// the file in the root of the Artifact storage on the local file system of
// the controller managing the Source.
// +required
Path string `json:"path"`
// URL is the HTTP address of the Artifact as exposed by the controller
// managing the Source. It can be used to retrieve the Artifact for
// consumption, e.g. by another controller applying the Artifact contents.
// +required
URL string `json:"url"`
// Revision is a human-readable identifier traceable in the origin source
// system. It can be a Git commit SHA, Git tag, a Helm chart version, etc.
// +required
Revision string `json:"revision"`
// Digest is the digest of the file in the form of '<algorithm>:<checksum>'.
// +optional
// +kubebuilder:validation:Pattern="^[a-z0-9]+(?:[.+_-][a-z0-9]+)*:[a-zA-Z0-9=_-]+$"
Digest string `json:"digest,omitempty"`
// LastUpdateTime is the timestamp corresponding to the last update of the
// Artifact.
// +required
LastUpdateTime metav1.Time `json:"lastUpdateTime"`
// Size is the number of bytes in the file.
// +optional
Size *int64 `json:"size,omitempty"`
// Metadata holds upstream information such as OCI annotations.
// +optional
Metadata map[string]string `json:"metadata,omitempty"`
}
// HasRevision returns if the given revision matches the current Revision of
// the Artifact.
func (in *Artifact) HasRevision(revision string) bool {
if in == nil {
return false
}
return in.Revision == revision
}
// HasDigest returns if the given digest matches the current Digest of the
// Artifact.
func (in *Artifact) HasDigest(digest string) bool {
if in == nil {
return false
}
return in.Digest == digest
}
// ArtifactDir returns the artifact dir path in the form of
// '<kind>/<namespace>/<name>'.
func ArtifactDir(kind, namespace, name string) string {
kind = strings.ToLower(kind)
return path.Join(kind, namespace, name)
}
// ArtifactPath returns the artifact path in the form of
// '<kind>/<namespace>/name>/<filename>'.
func ArtifactPath(kind, namespace, name, filename string) string {
return path.Join(ArtifactDir(kind, namespace, name), filename)
}

View File

@ -209,7 +209,7 @@ type BucketStatus struct {
// Artifact represents the last successful Bucket reconciliation.
// +optional
Artifact *Artifact `json:"artifact,omitempty"`
Artifact *meta.Artifact `json:"artifact,omitempty"`
// ObservedIgnore is the observed exclusion patterns used for constructing
// the source artifact.
@ -245,7 +245,7 @@ func (in *Bucket) GetRequeueAfter() time.Duration {
}
// GetArtifact returns the latest artifact from the source if present in the status sub-resource.
func (in *Bucket) GetArtifact() *Artifact {
func (in *Bucket) GetArtifact() *meta.Artifact {
return in.Status.Artifact
}

View File

@ -0,0 +1,70 @@
/*
Copyright 2025 The Flux authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package v1
import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"github.com/fluxcd/pkg/apis/meta"
)
// ExternalArtifactSpec defines the desired state of ExternalArtifact
type ExternalArtifactSpec struct {
// SourceRef points to the Kubernetes custom resource for
// which the artifact is generated.
// +optional
SourceRef *meta.NamespacedObjectKindReference `json:"sourceRef,omitempty"`
}
// ExternalArtifactStatus defines the observed state of ExternalArtifact
type ExternalArtifactStatus struct {
// Artifact represents the output of an ExternalArtifact reconciliation.
// +optional
Artifact *meta.Artifact `json:"artifact,omitempty"`
// Conditions holds the conditions for the ExternalArtifact.
// +optional
Conditions []metav1.Condition `json:"conditions,omitempty"`
}
// +kubebuilder:object:root=true
// +kubebuilder:subresource:status
// +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp",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="Source",type="string",JSONPath=".spec.sourceRef.name",description=""
// ExternalArtifact is the Schema for the external artifacts API
type ExternalArtifact struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
Spec ExternalArtifactSpec `json:"spec,omitempty"`
Status ExternalArtifactStatus `json:"status,omitempty"`
}
// ExternalArtifactList contains a list of ExternalArtifact
// +kubebuilder:object:root=true
type ExternalArtifactList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []ExternalArtifact `json:"items"`
}
func init() {
SchemeBuilder.Register(&ExternalArtifact{}, &ExternalArtifactList{})
}

View File

@ -256,12 +256,12 @@ type GitRepositoryStatus struct {
// Artifact represents the last successful GitRepository reconciliation.
// +optional
Artifact *Artifact `json:"artifact,omitempty"`
Artifact *meta.Artifact `json:"artifact,omitempty"`
// IncludedArtifacts contains a list of the last successfully included
// Artifacts as instructed by GitRepositorySpec.Include.
// +optional
IncludedArtifacts []*Artifact `json:"includedArtifacts,omitempty"`
IncludedArtifacts []*meta.Artifact `json:"includedArtifacts,omitempty"`
// ObservedIgnore is the observed exclusion patterns used for constructing
// the source artifact.
@ -319,7 +319,7 @@ func (in GitRepository) GetRequeueAfter() time.Duration {
// GetArtifact returns the latest Artifact from the GitRepository if present in
// the status sub-resource.
func (in *GitRepository) GetArtifact() *Artifact {
func (in *GitRepository) GetArtifact() *meta.Artifact {
return in.Status.Artifact
}

View File

@ -149,7 +149,7 @@ type HelmChartStatus struct {
// Artifact represents the output of the last successful reconciliation.
// +optional
Artifact *Artifact `json:"artifact,omitempty"`
Artifact *meta.Artifact `json:"artifact,omitempty"`
meta.ReconcileRequestStatus `json:",inline"`
}
@ -182,7 +182,7 @@ func (in HelmChart) GetRequeueAfter() time.Duration {
// GetArtifact returns the latest artifact from the source if present in the
// status sub-resource.
func (in *HelmChart) GetArtifact() *Artifact {
func (in *HelmChart) GetArtifact() *meta.Artifact {
return in.Status.Artifact
}

View File

@ -150,7 +150,7 @@ type HelmRepositoryStatus struct {
// Artifact represents the last successful HelmRepository reconciliation.
// +optional
Artifact *Artifact `json:"artifact,omitempty"`
Artifact *meta.Artifact `json:"artifact,omitempty"`
meta.ReconcileRequestStatus `json:",inline"`
}
@ -191,7 +191,7 @@ func (in HelmRepository) GetTimeout() time.Duration {
// GetArtifact returns the latest artifact from the source if present in the
// status sub-resource.
func (in *HelmRepository) GetArtifact() *Artifact {
func (in *HelmRepository) GetArtifact() *meta.Artifact {
return in.Status.Artifact
}

View File

@ -200,7 +200,7 @@ type OCIRepositoryStatus struct {
// Artifact represents the output of the last successful OCI Repository sync.
// +optional
Artifact *Artifact `json:"artifact,omitempty"`
Artifact *meta.Artifact `json:"artifact,omitempty"`
// ObservedIgnore is the observed exclusion patterns used for constructing
// the source artifact.
@ -241,7 +241,7 @@ func (in OCIRepository) GetRequeueAfter() time.Duration {
// GetArtifact returns the latest Artifact from the OCIRepository if present in
// the status sub-resource.
func (in *OCIRepository) GetArtifact() *Artifact {
func (in *OCIRepository) GetArtifact() *meta.Artifact {
return in.Status.Artifact
}

View File

@ -20,6 +20,8 @@ import (
"time"
"k8s.io/apimachinery/pkg/runtime"
"github.com/fluxcd/pkg/apis/meta"
)
const (
@ -41,5 +43,5 @@ type Source interface {
GetRequeueAfter() time.Duration
// GetArtifact returns the latest artifact from the source if present in
// the status sub-resource.
GetArtifact() *Artifact
GetArtifact() *meta.Artifact
}

View File

@ -27,34 +27,6 @@ import (
"k8s.io/apimachinery/pkg/runtime"
)
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Artifact) DeepCopyInto(out *Artifact) {
*out = *in
in.LastUpdateTime.DeepCopyInto(&out.LastUpdateTime)
if in.Size != nil {
in, out := &in.Size, &out.Size
*out = new(int64)
**out = **in
}
if in.Metadata != nil {
in, out := &in.Metadata, &out.Metadata
*out = make(map[string]string, len(*in))
for key, val := range *in {
(*out)[key] = val
}
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Artifact.
func (in *Artifact) DeepCopy() *Artifact {
if in == nil {
return nil
}
out := new(Artifact)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Bucket) DeepCopyInto(out *Bucket) {
*out = *in
@ -197,7 +169,7 @@ func (in *BucketStatus) DeepCopyInto(out *BucketStatus) {
}
if in.Artifact != nil {
in, out := &in.Artifact, &out.Artifact
*out = new(Artifact)
*out = new(meta.Artifact)
(*in).DeepCopyInto(*out)
}
if in.ObservedIgnore != nil {
@ -218,6 +190,112 @@ func (in *BucketStatus) DeepCopy() *BucketStatus {
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ExternalArtifact) DeepCopyInto(out *ExternalArtifact) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
in.Spec.DeepCopyInto(&out.Spec)
in.Status.DeepCopyInto(&out.Status)
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExternalArtifact.
func (in *ExternalArtifact) DeepCopy() *ExternalArtifact {
if in == nil {
return nil
}
out := new(ExternalArtifact)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *ExternalArtifact) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
return nil
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ExternalArtifactList) DeepCopyInto(out *ExternalArtifactList) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ListMeta.DeepCopyInto(&out.ListMeta)
if in.Items != nil {
in, out := &in.Items, &out.Items
*out = make([]ExternalArtifact, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExternalArtifactList.
func (in *ExternalArtifactList) DeepCopy() *ExternalArtifactList {
if in == nil {
return nil
}
out := new(ExternalArtifactList)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *ExternalArtifactList) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
return nil
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ExternalArtifactSpec) DeepCopyInto(out *ExternalArtifactSpec) {
*out = *in
if in.SourceRef != nil {
in, out := &in.SourceRef, &out.SourceRef
*out = new(meta.NamespacedObjectKindReference)
**out = **in
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExternalArtifactSpec.
func (in *ExternalArtifactSpec) DeepCopy() *ExternalArtifactSpec {
if in == nil {
return nil
}
out := new(ExternalArtifactSpec)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ExternalArtifactStatus) DeepCopyInto(out *ExternalArtifactStatus) {
*out = *in
if in.Artifact != nil {
in, out := &in.Artifact, &out.Artifact
*out = new(meta.Artifact)
(*in).DeepCopyInto(*out)
}
if in.Conditions != nil {
in, out := &in.Conditions, &out.Conditions
*out = make([]metav1.Condition, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExternalArtifactStatus.
func (in *ExternalArtifactStatus) DeepCopy() *ExternalArtifactStatus {
if in == nil {
return nil
}
out := new(ExternalArtifactStatus)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *GitRepository) DeepCopyInto(out *GitRepository) {
*out = *in
@ -376,16 +454,16 @@ func (in *GitRepositoryStatus) DeepCopyInto(out *GitRepositoryStatus) {
}
if in.Artifact != nil {
in, out := &in.Artifact, &out.Artifact
*out = new(Artifact)
*out = new(meta.Artifact)
(*in).DeepCopyInto(*out)
}
if in.IncludedArtifacts != nil {
in, out := &in.IncludedArtifacts, &out.IncludedArtifacts
*out = make([]*Artifact, len(*in))
*out = make([]*meta.Artifact, len(*in))
for i := range *in {
if (*in)[i] != nil {
in, out := &(*in)[i], &(*out)[i]
*out = new(Artifact)
*out = new(meta.Artifact)
(*in).DeepCopyInto(*out)
}
}
@ -542,7 +620,7 @@ func (in *HelmChartStatus) DeepCopyInto(out *HelmChartStatus) {
}
if in.Artifact != nil {
in, out := &in.Artifact, &out.Artifact
*out = new(Artifact)
*out = new(meta.Artifact)
(*in).DeepCopyInto(*out)
}
out.ReconcileRequestStatus = in.ReconcileRequestStatus
@ -665,7 +743,7 @@ func (in *HelmRepositoryStatus) DeepCopyInto(out *HelmRepositoryStatus) {
}
if in.Artifact != nil {
in, out := &in.Artifact, &out.Artifact
*out = new(Artifact)
*out = new(meta.Artifact)
(*in).DeepCopyInto(*out)
}
out.ReconcileRequestStatus = in.ReconcileRequestStatus
@ -853,7 +931,7 @@ func (in *OCIRepositoryStatus) DeepCopyInto(out *OCIRepositoryStatus) {
}
if in.Artifact != nil {
in, out := &in.Artifact, &out.Artifact
*out = new(Artifact)
*out = new(meta.Artifact)
(*in).DeepCopyInto(*out)
}
if in.ObservedIgnore != nil {

View File

@ -229,7 +229,7 @@ type BucketStatus struct {
// Artifact represents the last successful Bucket reconciliation.
// +optional
Artifact *apiv1.Artifact `json:"artifact,omitempty"`
Artifact *meta.Artifact `json:"artifact,omitempty"`
// ObservedIgnore is the observed exclusion patterns used for constructing
// the source artifact.
@ -265,7 +265,7 @@ func (in Bucket) GetRequeueAfter() time.Duration {
}
// GetArtifact returns the latest artifact from the source if present in the status sub-resource.
func (in *Bucket) GetArtifact() *apiv1.Artifact {
func (in *Bucket) GetArtifact() *meta.Artifact {
return in.Status.Artifact
}

View File

@ -23,8 +23,6 @@ import (
"github.com/fluxcd/pkg/apis/acl"
"github.com/fluxcd/pkg/apis/meta"
apiv1 "github.com/fluxcd/source-controller/api/v1"
)
const (
@ -214,12 +212,12 @@ type GitRepositoryStatus struct {
// Artifact represents the last successful GitRepository reconciliation.
// +optional
Artifact *apiv1.Artifact `json:"artifact,omitempty"`
Artifact *meta.Artifact `json:"artifact,omitempty"`
// IncludedArtifacts contains a list of the last successfully included
// Artifacts as instructed by GitRepositorySpec.Include.
// +optional
IncludedArtifacts []*apiv1.Artifact `json:"includedArtifacts,omitempty"`
IncludedArtifacts []*meta.Artifact `json:"includedArtifacts,omitempty"`
// ContentConfigChecksum is a checksum of all the configurations related to
// the content of the source artifact:
@ -282,7 +280,7 @@ func (in GitRepository) GetRequeueAfter() time.Duration {
// GetArtifact returns the latest Artifact from the GitRepository if present in
// the status sub-resource.
func (in *GitRepository) GetArtifact() *apiv1.Artifact {
func (in *GitRepository) GetArtifact() *meta.Artifact {
return in.Status.Artifact
}

View File

@ -166,7 +166,7 @@ type HelmChartStatus struct {
// Artifact represents the output of the last successful reconciliation.
// +optional
Artifact *apiv1.Artifact `json:"artifact,omitempty"`
Artifact *meta.Artifact `json:"artifact,omitempty"`
meta.ReconcileRequestStatus `json:",inline"`
}
@ -199,7 +199,7 @@ func (in HelmChart) GetRequeueAfter() time.Duration {
// GetArtifact returns the latest artifact from the source if present in the
// status sub-resource.
func (in *HelmChart) GetArtifact() *apiv1.Artifact {
func (in *HelmChart) GetArtifact() *meta.Artifact {
return in.Status.Artifact
}

View File

@ -23,8 +23,6 @@ import (
"github.com/fluxcd/pkg/apis/acl"
"github.com/fluxcd/pkg/apis/meta"
apiv1 "github.com/fluxcd/source-controller/api/v1"
)
const (
@ -152,7 +150,7 @@ type HelmRepositoryStatus struct {
// Artifact represents the last successful HelmRepository reconciliation.
// +optional
Artifact *apiv1.Artifact `json:"artifact,omitempty"`
Artifact *meta.Artifact `json:"artifact,omitempty"`
meta.ReconcileRequestStatus `json:",inline"`
}
@ -193,7 +191,7 @@ func (in HelmRepository) GetTimeout() time.Duration {
// GetArtifact returns the latest artifact from the source if present in the
// status sub-resource.
func (in *HelmRepository) GetArtifact() *apiv1.Artifact {
func (in *HelmRepository) GetArtifact() *meta.Artifact {
return in.Status.Artifact
}

View File

@ -205,7 +205,7 @@ type OCIRepositoryStatus struct {
// Artifact represents the output of the last successful OCI Repository sync.
// +optional
Artifact *apiv1.Artifact `json:"artifact,omitempty"`
Artifact *meta.Artifact `json:"artifact,omitempty"`
// ContentConfigChecksum is a checksum of all the configurations related to
// the content of the source artifact:
@ -260,7 +260,7 @@ func (in OCIRepository) GetRequeueAfter() time.Duration {
// GetArtifact returns the latest Artifact from the OCIRepository if present in
// the status sub-resource.
func (in *OCIRepository) GetArtifact() *apiv1.Artifact {
func (in *OCIRepository) GetArtifact() *meta.Artifact {
return in.Status.Artifact
}

View File

@ -203,7 +203,7 @@ func (in *BucketStatus) DeepCopyInto(out *BucketStatus) {
}
if in.Artifact != nil {
in, out := &in.Artifact, &out.Artifact
*out = new(apiv1.Artifact)
*out = new(meta.Artifact)
(*in).DeepCopyInto(*out)
}
if in.ObservedIgnore != nil {
@ -377,16 +377,16 @@ func (in *GitRepositoryStatus) DeepCopyInto(out *GitRepositoryStatus) {
}
if in.Artifact != nil {
in, out := &in.Artifact, &out.Artifact
*out = new(apiv1.Artifact)
*out = new(meta.Artifact)
(*in).DeepCopyInto(*out)
}
if in.IncludedArtifacts != nil {
in, out := &in.IncludedArtifacts, &out.IncludedArtifacts
*out = make([]*apiv1.Artifact, len(*in))
*out = make([]*meta.Artifact, len(*in))
for i := range *in {
if (*in)[i] != nil {
in, out := &(*in)[i], &(*out)[i]
*out = new(apiv1.Artifact)
*out = new(meta.Artifact)
(*in).DeepCopyInto(*out)
}
}
@ -538,7 +538,7 @@ func (in *HelmChartStatus) DeepCopyInto(out *HelmChartStatus) {
}
if in.Artifact != nil {
in, out := &in.Artifact, &out.Artifact
*out = new(apiv1.Artifact)
*out = new(meta.Artifact)
(*in).DeepCopyInto(*out)
}
out.ReconcileRequestStatus = in.ReconcileRequestStatus
@ -661,7 +661,7 @@ func (in *HelmRepositoryStatus) DeepCopyInto(out *HelmRepositoryStatus) {
}
if in.Artifact != nil {
in, out := &in.Artifact, &out.Artifact
*out = new(apiv1.Artifact)
*out = new(meta.Artifact)
(*in).DeepCopyInto(*out)
}
out.ReconcileRequestStatus = in.ReconcileRequestStatus
@ -849,7 +849,7 @@ func (in *OCIRepositoryStatus) DeepCopyInto(out *OCIRepositoryStatus) {
}
if in.Artifact != nil {
in, out := &in.Artifact, &out.Artifact
*out = new(apiv1.Artifact)
*out = new(meta.Artifact)
(*in).DeepCopyInto(*out)
}
if in.ObservedIgnore != nil {

View File

@ -289,6 +289,7 @@ spec:
consumption, e.g. by another controller applying the Artifact contents.
type: string
required:
- digest
- lastUpdateTime
- path
- revision
@ -672,6 +673,7 @@ spec:
consumption, e.g. by another controller applying the Artifact contents.
type: string
required:
- digest
- lastUpdateTime
- path
- revision

View File

@ -0,0 +1,191 @@
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.19.0
name: externalartifacts.source.toolkit.fluxcd.io
spec:
group: source.toolkit.fluxcd.io
names:
kind: ExternalArtifact
listKind: ExternalArtifactList
plural: externalartifacts
singular: externalartifact
scope: Namespaced
versions:
- additionalPrinterColumns:
- jsonPath: .metadata.creationTimestamp
name: Age
type: date
- jsonPath: .status.conditions[?(@.type=="Ready")].status
name: Ready
type: string
- jsonPath: .status.conditions[?(@.type=="Ready")].message
name: Status
type: string
- jsonPath: .spec.sourceRef.name
name: Source
type: string
name: v1
schema:
openAPIV3Schema:
description: ExternalArtifact is the Schema for the external artifacts API
properties:
apiVersion:
description: |-
APIVersion defines the versioned schema of this representation of an object.
Servers should convert recognized schemas to the latest internal value, and
may reject unrecognized values.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
type: string
kind:
description: |-
Kind is a string value representing the REST resource this object represents.
Servers may infer this from the endpoint the client submits requests to.
Cannot be updated.
In CamelCase.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
type: string
metadata:
type: object
spec:
description: ExternalArtifactSpec defines the desired state of ExternalArtifact
properties:
sourceRef:
description: |-
SourceRef points to the Kubernetes custom resource for
which the artifact is generated.
properties:
apiVersion:
description: API version of the referent, if not specified the
Kubernetes preferred version will be used.
type: string
kind:
description: Kind of the referent.
type: string
name:
description: Name of the referent.
type: string
namespace:
description: Namespace of the referent, when not specified it
acts as LocalObjectReference.
type: string
required:
- kind
- name
type: object
type: object
status:
description: ExternalArtifactStatus defines the observed state of ExternalArtifact
properties:
artifact:
description: Artifact represents the output of an ExternalArtifact
reconciliation.
properties:
digest:
description: Digest is the digest of the file in the form of '<algorithm>:<checksum>'.
pattern: ^[a-z0-9]+(?:[.+_-][a-z0-9]+)*:[a-zA-Z0-9=_-]+$
type: string
lastUpdateTime:
description: |-
LastUpdateTime is the timestamp corresponding to the last update of the
Artifact.
format: date-time
type: string
metadata:
additionalProperties:
type: string
description: Metadata holds upstream information such as OCI annotations.
type: object
path:
description: |-
Path is the relative file path of the Artifact. It can be used to locate
the file in the root of the Artifact storage on the local file system of
the controller managing the Source.
type: string
revision:
description: |-
Revision is a human-readable identifier traceable in the origin source
system. It can be a Git commit SHA, Git tag, a Helm chart version, etc.
type: string
size:
description: Size is the number of bytes in the file.
format: int64
type: integer
url:
description: |-
URL is the HTTP address of the Artifact as exposed by the controller
managing the Source. It can be used to retrieve the Artifact for
consumption, e.g. by another controller applying the Artifact contents.
type: string
required:
- digest
- lastUpdateTime
- path
- revision
- url
type: object
conditions:
description: Conditions holds the conditions for the ExternalArtifact.
items:
description: Condition contains details for one aspect of the current
state of this API Resource.
properties:
lastTransitionTime:
description: |-
lastTransitionTime is the last time the condition transitioned from one status to another.
This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.
format: date-time
type: string
message:
description: |-
message is a human readable message indicating details about the transition.
This may be an empty string.
maxLength: 32768
type: string
observedGeneration:
description: |-
observedGeneration represents the .metadata.generation that the condition was set based upon.
For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date
with respect to the current state of the instance.
format: int64
minimum: 0
type: integer
reason:
description: |-
reason contains a programmatic identifier indicating the reason for the condition's last transition.
Producers of specific condition types may define expected values and meanings for this field,
and whether the values are considered a guaranteed API.
The value should be a CamelCase string.
This field may not be empty.
maxLength: 1024
minLength: 1
pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
type: string
status:
description: status of the condition, one of True, False, Unknown.
enum:
- "True"
- "False"
- Unknown
type: string
type:
description: type of condition in CamelCase or in foo.example.com/CamelCase.
maxLength: 316
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
type: string
required:
- lastTransitionTime
- message
- reason
- status
- type
type: object
type: array
type: object
type: object
served: true
storage: true
subresources:
status: {}

View File

@ -290,6 +290,7 @@ spec:
consumption, e.g. by another controller applying the Artifact contents.
type: string
required:
- digest
- lastUpdateTime
- path
- revision
@ -398,6 +399,7 @@ spec:
consumption, e.g. by another controller applying the Artifact contents.
type: string
required:
- digest
- lastUpdateTime
- path
- revision
@ -746,6 +748,7 @@ spec:
consumption, e.g. by another controller applying the Artifact contents.
type: string
required:
- digest
- lastUpdateTime
- path
- revision
@ -869,6 +872,7 @@ spec:
consumption, e.g. by another controller applying the Artifact contents.
type: string
required:
- digest
- lastUpdateTime
- path
- revision

View File

@ -244,6 +244,7 @@ spec:
consumption, e.g. by another controller applying the Artifact contents.
type: string
required:
- digest
- lastUpdateTime
- path
- revision
@ -613,6 +614,7 @@ spec:
consumption, e.g. by another controller applying the Artifact contents.
type: string
required:
- digest
- lastUpdateTime
- path
- revision

View File

@ -232,6 +232,7 @@ spec:
consumption, e.g. by another controller applying the Artifact contents.
type: string
required:
- digest
- lastUpdateTime
- path
- revision
@ -536,6 +537,7 @@ spec:
consumption, e.g. by another controller applying the Artifact contents.
type: string
required:
- digest
- lastUpdateTime
- path
- revision

View File

@ -299,6 +299,7 @@ spec:
consumption, e.g. by another controller applying the Artifact contents.
type: string
required:
- digest
- lastUpdateTime
- path
- revision
@ -696,6 +697,7 @@ spec:
consumption, e.g. by another controller applying the Artifact contents.
type: string
required:
- digest
- lastUpdateTime
- path
- revision

View File

@ -6,4 +6,5 @@ resources:
- bases/source.toolkit.fluxcd.io_helmcharts.yaml
- bases/source.toolkit.fluxcd.io_buckets.yaml
- bases/source.toolkit.fluxcd.io_ocirepositories.yaml
- bases/source.toolkit.fluxcd.io_externalartifacts.yaml
# +kubebuilder:scaffold:crdkustomizeresource

View File

@ -0,0 +1,24 @@
# permissions for end users to edit externalartifacts.
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: externalartifact-editor-role
rules:
- apiGroups:
- source.toolkit.fluxcd.io
resources:
- externalartifacts
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
- apiGroups:
- source.toolkit.fluxcd.io
resources:
- externalartifacts/status
verbs:
- get

View File

@ -0,0 +1,20 @@
# permissions for end users to view externalartifacts.
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: externalartifacts-viewer-role
rules:
- apiGroups:
- source.toolkit.fluxcd.io
resources:
- externalartifacts
verbs:
- get
- list
- watch
- apiGroups:
- source.toolkit.fluxcd.io
resources:
- externalartifacts/status
verbs:
- get

View File

@ -1327,119 +1327,6 @@ OCIRepositoryStatus
</table>
</div>
</div>
<h3 id="source.toolkit.fluxcd.io/v1.Artifact">Artifact
</h3>
<p>
(<em>Appears on:</em>
<a href="#source.toolkit.fluxcd.io/v1.BucketStatus">BucketStatus</a>,
<a href="#source.toolkit.fluxcd.io/v1.GitRepositoryStatus">GitRepositoryStatus</a>,
<a href="#source.toolkit.fluxcd.io/v1.HelmChartStatus">HelmChartStatus</a>,
<a href="#source.toolkit.fluxcd.io/v1.HelmRepositoryStatus">HelmRepositoryStatus</a>,
<a href="#source.toolkit.fluxcd.io/v1.OCIRepositoryStatus">OCIRepositoryStatus</a>)
</p>
<p>Artifact represents the output of a Source reconciliation.</p>
<div class="md-typeset__scrollwrap">
<div class="md-typeset__table">
<table>
<thead>
<tr>
<th>Field</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<code>path</code><br>
<em>
string
</em>
</td>
<td>
<p>Path is the relative file path of the Artifact. It can be used to locate
the file in the root of the Artifact storage on the local file system of
the controller managing the Source.</p>
</td>
</tr>
<tr>
<td>
<code>url</code><br>
<em>
string
</em>
</td>
<td>
<p>URL is the HTTP address of the Artifact as exposed by the controller
managing the Source. It can be used to retrieve the Artifact for
consumption, e.g. by another controller applying the Artifact contents.</p>
</td>
</tr>
<tr>
<td>
<code>revision</code><br>
<em>
string
</em>
</td>
<td>
<p>Revision is a human-readable identifier traceable in the origin source
system. It can be a Git commit SHA, Git tag, a Helm chart version, etc.</p>
</td>
</tr>
<tr>
<td>
<code>digest</code><br>
<em>
string
</em>
</td>
<td>
<em>(Optional)</em>
<p>Digest is the digest of the file in the form of &lsquo;<algorithm>:<checksum>&rsquo;.</p>
</td>
</tr>
<tr>
<td>
<code>lastUpdateTime</code><br>
<em>
<a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.19/#time-v1-meta">
Kubernetes meta/v1.Time
</a>
</em>
</td>
<td>
<p>LastUpdateTime is the timestamp corresponding to the last update of the
Artifact.</p>
</td>
</tr>
<tr>
<td>
<code>size</code><br>
<em>
int64
</em>
</td>
<td>
<em>(Optional)</em>
<p>Size is the number of bytes in the file.</p>
</td>
</tr>
<tr>
<td>
<code>metadata</code><br>
<em>
map[string]string
</em>
</td>
<td>
<em>(Optional)</em>
<p>Metadata holds upstream information such as OCI annotations.</p>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<h3 id="source.toolkit.fluxcd.io/v1.BucketSTSSpec">BucketSTSSpec
</h3>
<p>
@ -1827,8 +1714,8 @@ BucketStatus.Artifact data is recommended.</p>
<td>
<code>artifact</code><br>
<em>
<a href="#source.toolkit.fluxcd.io/v1.Artifact">
Artifact
<a href="https://pkg.go.dev/github.com/fluxcd/pkg/apis/meta#Artifact">
github.com/fluxcd/pkg/apis/meta.Artifact
</a>
</em>
</td>
@ -1869,6 +1756,165 @@ github.com/fluxcd/pkg/apis/meta.ReconcileRequestStatus
</table>
</div>
</div>
<h3 id="source.toolkit.fluxcd.io/v1.ExternalArtifact">ExternalArtifact
</h3>
<p>ExternalArtifact is the Schema for the external artifacts API</p>
<div class="md-typeset__scrollwrap">
<div class="md-typeset__table">
<table>
<thead>
<tr>
<th>Field</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<code>metadata</code><br>
<em>
<a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.19/#objectmeta-v1-meta">
Kubernetes meta/v1.ObjectMeta
</a>
</em>
</td>
<td>
Refer to the Kubernetes API documentation for the fields of the
<code>metadata</code> field.
</td>
</tr>
<tr>
<td>
<code>spec</code><br>
<em>
<a href="#source.toolkit.fluxcd.io/v1.ExternalArtifactSpec">
ExternalArtifactSpec
</a>
</em>
</td>
<td>
<br/>
<br/>
<table>
<tr>
<td>
<code>sourceRef</code><br>
<em>
<a href="https://pkg.go.dev/github.com/fluxcd/pkg/apis/meta#NamespacedObjectKindReference">
github.com/fluxcd/pkg/apis/meta.NamespacedObjectKindReference
</a>
</em>
</td>
<td>
<em>(Optional)</em>
<p>SourceRef points to the Kubernetes custom resource for
which the artifact is generated.</p>
</td>
</tr>
</table>
</td>
</tr>
<tr>
<td>
<code>status</code><br>
<em>
<a href="#source.toolkit.fluxcd.io/v1.ExternalArtifactStatus">
ExternalArtifactStatus
</a>
</em>
</td>
<td>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<h3 id="source.toolkit.fluxcd.io/v1.ExternalArtifactSpec">ExternalArtifactSpec
</h3>
<p>
(<em>Appears on:</em>
<a href="#source.toolkit.fluxcd.io/v1.ExternalArtifact">ExternalArtifact</a>)
</p>
<p>ExternalArtifactSpec defines the desired state of ExternalArtifact</p>
<div class="md-typeset__scrollwrap">
<div class="md-typeset__table">
<table>
<thead>
<tr>
<th>Field</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<code>sourceRef</code><br>
<em>
<a href="https://pkg.go.dev/github.com/fluxcd/pkg/apis/meta#NamespacedObjectKindReference">
github.com/fluxcd/pkg/apis/meta.NamespacedObjectKindReference
</a>
</em>
</td>
<td>
<em>(Optional)</em>
<p>SourceRef points to the Kubernetes custom resource for
which the artifact is generated.</p>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<h3 id="source.toolkit.fluxcd.io/v1.ExternalArtifactStatus">ExternalArtifactStatus
</h3>
<p>
(<em>Appears on:</em>
<a href="#source.toolkit.fluxcd.io/v1.ExternalArtifact">ExternalArtifact</a>)
</p>
<p>ExternalArtifactStatus defines the observed state of ExternalArtifact</p>
<div class="md-typeset__scrollwrap">
<div class="md-typeset__table">
<table>
<thead>
<tr>
<th>Field</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<code>artifact</code><br>
<em>
<a href="https://pkg.go.dev/github.com/fluxcd/pkg/apis/meta#Artifact">
github.com/fluxcd/pkg/apis/meta.Artifact
</a>
</em>
</td>
<td>
<em>(Optional)</em>
<p>Artifact represents the output of an ExternalArtifact reconciliation.</p>
</td>
</tr>
<tr>
<td>
<code>conditions</code><br>
<em>
<a href="https://pkg.go.dev/k8s.io/apimachinery/pkg/apis/meta/v1#Condition">
[]Kubernetes meta/v1.Condition
</a>
</em>
</td>
<td>
<em>(Optional)</em>
<p>Conditions holds the conditions for the ExternalArtifact.</p>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<h3 id="source.toolkit.fluxcd.io/v1.GitRepositoryInclude">GitRepositoryInclude
</h3>
<p>
@ -2286,8 +2332,8 @@ object.</p>
<td>
<code>artifact</code><br>
<em>
<a href="#source.toolkit.fluxcd.io/v1.Artifact">
Artifact
<a href="https://pkg.go.dev/github.com/fluxcd/pkg/apis/meta#Artifact">
github.com/fluxcd/pkg/apis/meta.Artifact
</a>
</em>
</td>
@ -2300,8 +2346,8 @@ Artifact
<td>
<code>includedArtifacts</code><br>
<em>
<a href="#source.toolkit.fluxcd.io/v1.Artifact">
[]Artifact
<a href="https://pkg.go.dev/github.com/fluxcd/pkg/apis/meta#Artifact">
[]github.com/fluxcd/pkg/apis/meta.Artifact
</a>
</em>
</td>
@ -2711,8 +2757,8 @@ BucketStatus.Artifact data is recommended.</p>
<td>
<code>artifact</code><br>
<em>
<a href="#source.toolkit.fluxcd.io/v1.Artifact">
Artifact
<a href="https://pkg.go.dev/github.com/fluxcd/pkg/apis/meta#Artifact">
github.com/fluxcd/pkg/apis/meta.Artifact
</a>
</em>
</td>
@ -3001,8 +3047,8 @@ HelmRepositoryStatus.Artifact data is recommended.</p>
<td>
<code>artifact</code><br>
<em>
<a href="#source.toolkit.fluxcd.io/v1.Artifact">
Artifact
<a href="https://pkg.go.dev/github.com/fluxcd/pkg/apis/meta#Artifact">
github.com/fluxcd/pkg/apis/meta.Artifact
</a>
</em>
</td>
@ -3497,8 +3543,8 @@ string
<td>
<code>artifact</code><br>
<em>
<a href="#source.toolkit.fluxcd.io/v1.Artifact">
Artifact
<a href="https://pkg.go.dev/github.com/fluxcd/pkg/apis/meta#Artifact">
github.com/fluxcd/pkg/apis/meta.Artifact
</a>
</em>
</td>

View File

@ -0,0 +1,114 @@
# External Artifacts
<!-- menuweight:100 -->
The `ExternalArtifact` is a generic API designed for interoperability with Flux.
It allows 3rd party controllers to produce and store [Artifact](#artifact) objects
in the same way as Flux's own source-controller.
For more details on the design and motivation behind this API,
see [RFC-0012](https://github.com/fluxcd/flux2/tree/main/rfcs/0012-external-artifact).
## Example
The following is an example of a ExternalArtifact produced by a 3rd party
source controller:
```yaml
apiVersion: source.toolkit.fluxcd.io/v1
kind: ExternalArtifact
metadata:
name: my-artifact
namespace: flux-system
spec:
sourceRef:
apiVersion: example.com/v1
kind: Source
name: my-source
status:
artifact:
digest: sha256:35d47c9db0eee6ffe08a404dfb416bee31b2b79eabc3f2eb26749163ce487f52
lastUpdateTime: "2025-08-21T13:37:31Z"
path: source/flux-system/my-source/35d47c9d.tar.gz
revision: v1.0.0@sha256:35d47c9db0eee6ffe08a404dfb416bee31b2b79eabc3f2eb26749163ce487f52
size: 20914
url: http://example-controller.flux-system.svc.cluster.local./source/flux-system/my-source/35d47c9d.tar.gz
conditions:
- lastTransitionTime: "2025-08-21T13:37:31Z"
message: stored artifact for revision v1.0.0
observedGeneration: 1
reason: Succeeded
status: "True"
type: Ready
```
## ExternalArtifact spec
### Source reference
The `spec.sourceRef` field is optional and contains a reference
to the custom resource that the ExternalArtifact is based on.
The `spec.sourceRef` contains the following fields:
- `apiVersion`: the API version of the custom resource.
- `kind`: the kind of the custom resource.
- `name`: the name of the custom resource.
- `namespace`: the namespace of the custom resource. If omitted, it defaults to the
namespace of the ExternalArtifact.
## ExternalArtifact status
### Artifact
The ExternalArtifact reports the latest synchronized state
as an Artifact object in the `.status.artifact`.
The `.status.artifact` contains the following fields:
- `digest`: The checksum of the tar.gz file in the format `<algorithm>:<checksum>`.
- `lastUpdateTime`: Timestamp of the last artifact update.
- `path`: Relative file path of the artifact in storage.
- `revision`: Human-readable identifier with version and checksum in the format `<human-readable-identifier>@<algorithm>:<checksum>`.
- `size`: Number of bytes in the tar.gz file.
- `url`: In-cluster HTTP address for artifact retrieval.
### Conditions
The ExternalArtifact reports its status using Kubernetes standard conditions.
#### Ready ExternalArtifact
When the 3rd party controller has successfully produced and stored an
Artifact in storage, it sets a Condition with the following
attributes in the ExternalArtifact's `.status.conditions`:
- `type: Ready`
- `status: "True"`
- `reason: Succeeded`
The `message` field should contain a human-readable message indicating
the successful storage of the artifact and the associated revision.
If the 3rd party controller performs a signature verification
of the artifact, and the verification is successful, a Condition with the
following attributes is added to the ExternalArtifact's `.status.conditions`:
- `type: SourceVerified`
- `status: "True"`
- `reason: Succeeded`
The `message` field should contain a human-readable message indicating
the successful verification of the artifact and the associated verification method.
#### Failed ExternalArtifact
If the 3rd party controller fails to produce and store an Artifact,
it sets the `Ready` Condition status to `False`, and adds a Condition with
the following attributes to the ExternalArtifact's `.status.conditions`:
- `type: Ready`
- `status: "False"`
- `reason: FetchFailed` | `reason: StorageOperationFailed` | `reason: VerificationFailed`
The `message` field should contain a human-readable message indicating
the reason for the failure.

4
go.mod
View File

@ -23,8 +23,8 @@ require (
github.com/elazarl/goproxy v1.7.2
github.com/fluxcd/cli-utils v0.36.0-flux.15
github.com/fluxcd/pkg/apis/event v0.19.0
github.com/fluxcd/pkg/apis/meta v1.20.0
github.com/fluxcd/pkg/auth v0.29.0
github.com/fluxcd/pkg/apis/meta v1.21.0
github.com/fluxcd/pkg/auth v0.30.0
github.com/fluxcd/pkg/cache v0.11.0
github.com/fluxcd/pkg/git v0.36.0
github.com/fluxcd/pkg/git/gogit v0.40.0

8
go.sum
View File

@ -376,10 +376,10 @@ github.com/fluxcd/pkg/apis/acl v0.9.0 h1:wBpgsKT+jcyZEcM//OmZr9RiF8klL3ebrDp2u2T
github.com/fluxcd/pkg/apis/acl v0.9.0/go.mod h1:TttNS+gocsGLwnvmgVi3/Yscwqrjc17+vhgYfqkfrV4=
github.com/fluxcd/pkg/apis/event v0.19.0 h1:ZJU2voontkzp5rNYA4JMOu40S4tRcrWi4Do59EnyFwg=
github.com/fluxcd/pkg/apis/event v0.19.0/go.mod h1:deuIyUb6lh+Z1Ccvwwxhm1wNM3kpSo+vF1IgRnpaZfQ=
github.com/fluxcd/pkg/apis/meta v1.20.0 h1:l9h0kWoDZTcYV0WJkFMgDXq6Q4tSojrJ+bHpFJSsaW0=
github.com/fluxcd/pkg/apis/meta v1.20.0/go.mod h1:XUAEUgT4gkWDAEN79E141tmL+v4SV50tVZ/Ojpc/ueg=
github.com/fluxcd/pkg/auth v0.29.0 h1:lLc63zjodqIqg5ydlU/Kp3Qa+wvh6G2khjop5MHALvk=
github.com/fluxcd/pkg/auth v0.29.0/go.mod h1:bjZ+6RMSGgsQQK+aPfVP8HWuBbb+FLlFxMiqd8ywzik=
github.com/fluxcd/pkg/apis/meta v1.21.0 h1:R+bN02chcs0HUmyVDQhqe/FHmYLjipVDMLnyYfNX850=
github.com/fluxcd/pkg/apis/meta v1.21.0/go.mod h1:XUAEUgT4gkWDAEN79E141tmL+v4SV50tVZ/Ojpc/ueg=
github.com/fluxcd/pkg/auth v0.30.0 h1:7JMnY1ClArvOsadt6hOxceu8Q2hLsYHFMt0DV3BQl4Q=
github.com/fluxcd/pkg/auth v0.30.0/go.mod h1:me38o1nDfSLw6YvnkT9Ce/zqJZICZSA7j5pNMR3JUbc=
github.com/fluxcd/pkg/cache v0.11.0 h1:fsE8S+una21fSNw4MDXGUIf0Gf1J+pqa4RbsVKf2aTI=
github.com/fluxcd/pkg/cache v0.11.0/go.mod h1:2RTIU6PsJniHmfnllQWFEo7fa5V8KQlnMgn4o0sme40=
github.com/fluxcd/pkg/git v0.36.0 h1:oakFKxTX5yiLcFzCS1SaV+mMXaODaF1Ic6/oCLfIe7I=

View File

@ -16,9 +16,11 @@ limitations under the License.
package controller
import sourcev1 "github.com/fluxcd/source-controller/api/v1"
import (
"github.com/fluxcd/pkg/apis/meta"
)
type artifactSet []*sourcev1.Artifact
type artifactSet []*meta.Artifact
// Diff returns true if any of the revisions in the artifactSet does not match any of the given artifacts.
func (s artifactSet) Diff(set artifactSet) bool {

View File

@ -19,24 +19,25 @@ package controller
import (
"fmt"
sourcev1 "github.com/fluxcd/source-controller/api/v1"
. "github.com/onsi/gomega"
"github.com/onsi/gomega/types"
"github.com/fluxcd/pkg/apis/meta"
)
// MatchArtifact returns a custom matcher to check equality of a v1beta1.Artifact, the timestamp and URL are ignored.
func MatchArtifact(expected *sourcev1.Artifact) types.GomegaMatcher {
func MatchArtifact(expected *meta.Artifact) types.GomegaMatcher {
return &matchArtifact{
expected: expected,
}
}
type matchArtifact struct {
expected *sourcev1.Artifact
expected *meta.Artifact
}
func (m matchArtifact) Match(actual interface{}) (success bool, err error) {
actualArtifact, ok := actual.(*sourcev1.Artifact)
actualArtifact, ok := actual.(*meta.Artifact)
if !ok {
return false, fmt.Errorf("actual should be a pointer to an Artifact")
}

View File

@ -201,7 +201,7 @@ func TestBucketReconciler_reconcileStorage(t *testing.T) {
beforeFunc func(obj *sourcev1.Bucket, storage *storage.Storage) error
want sreconcile.Result
wantErr bool
assertArtifact *sourcev1.Artifact
assertArtifact *meta.Artifact
assertConditions []metav1.Condition
assertPaths []string
}{
@ -211,7 +211,7 @@ func TestBucketReconciler_reconcileStorage(t *testing.T) {
revisions := []string{"a", "b", "c", "d"}
for n := range revisions {
v := revisions[n]
obj.Status.Artifact = &sourcev1.Artifact{
obj.Status.Artifact = &meta.Artifact{
Path: fmt.Sprintf("/reconcile-storage/%s.txt", v),
Revision: v,
}
@ -229,7 +229,7 @@ func TestBucketReconciler_reconcileStorage(t *testing.T) {
conditions.MarkTrue(obj, meta.ReadyCondition, "foo", "bar")
return nil
},
assertArtifact: &sourcev1.Artifact{
assertArtifact: &meta.Artifact{
Path: "/reconcile-storage/d.txt",
Revision: "d",
Digest: "sha256:18ac3e7343f016890c510e93f935261169d9e3f565436429830faf0934f4f8e4",
@ -258,7 +258,7 @@ func TestBucketReconciler_reconcileStorage(t *testing.T) {
{
name: "notices missing artifact in storage",
beforeFunc: func(obj *sourcev1.Bucket, storage *storage.Storage) error {
obj.Status.Artifact = &sourcev1.Artifact{
obj.Status.Artifact = &meta.Artifact{
Path: "/reconcile-storage/invalid.txt",
Revision: "d",
}
@ -279,7 +279,7 @@ func TestBucketReconciler_reconcileStorage(t *testing.T) {
beforeFunc: func(obj *sourcev1.Bucket, storage *storage.Storage) error {
f := "empty-digest.txt"
obj.Status.Artifact = &sourcev1.Artifact{
obj.Status.Artifact = &meta.Artifact{
Path: fmt.Sprintf("/reconcile-storage/%s.txt", f),
Revision: "fake",
}
@ -310,7 +310,7 @@ func TestBucketReconciler_reconcileStorage(t *testing.T) {
beforeFunc: func(obj *sourcev1.Bucket, storage *storage.Storage) error {
f := "digest-mismatch.txt"
obj.Status.Artifact = &sourcev1.Artifact{
obj.Status.Artifact = &meta.Artifact{
Path: fmt.Sprintf("/reconcile-storage/%s.txt", f),
Revision: "fake",
}
@ -339,7 +339,7 @@ func TestBucketReconciler_reconcileStorage(t *testing.T) {
{
name: "updates hostname on diff from current",
beforeFunc: func(obj *sourcev1.Bucket, storage *storage.Storage) error {
obj.Status.Artifact = &sourcev1.Artifact{
obj.Status.Artifact = &meta.Artifact{
Path: "/reconcile-storage/hostname.txt",
Revision: "f",
Digest: "sha256:3b9c358f36f0a31b6ad3e14f309c7cf198ac9246e8316f9ce543d5b19ac02b80",
@ -358,7 +358,7 @@ func TestBucketReconciler_reconcileStorage(t *testing.T) {
assertPaths: []string{
"/reconcile-storage/hostname.txt",
},
assertArtifact: &sourcev1.Artifact{
assertArtifact: &meta.Artifact{
Path: "/reconcile-storage/hostname.txt",
Revision: "f",
Digest: "sha256:3b9c358f36f0a31b6ad3e14f309c7cf198ac9246e8316f9ce543d5b19ac02b80",
@ -827,7 +827,7 @@ func TestBucketReconciler_reconcileSource_generic(t *testing.T) {
name: "Up-to-date artifact",
bucketName: "dummy",
beforeFunc: func(obj *sourcev1.Bucket) {
obj.Status.Artifact = &sourcev1.Artifact{
obj.Status.Artifact = &meta.Artifact{
Revision: "sha256:b4c2a60ce44b67f5b659a95ce4e4cc9e2a86baf13afb72bd397c5384cbc0e479",
}
conditions.MarkReconciling(obj, meta.ProgressingReason, "foo")
@ -885,7 +885,7 @@ func TestBucketReconciler_reconcileSource_generic(t *testing.T) {
},
},
beforeFunc: func(obj *sourcev1.Bucket) {
obj.Status.Artifact = &sourcev1.Artifact{
obj.Status.Artifact = &meta.Artifact{
Path: "some-path",
Revision: "some-rev",
}
@ -1219,7 +1219,7 @@ func TestBucketReconciler_reconcileSource_gcs(t *testing.T) {
name: "Up-to-date artifact",
bucketName: "dummy",
beforeFunc: func(obj *sourcev1.Bucket) {
obj.Status.Artifact = &sourcev1.Artifact{
obj.Status.Artifact = &meta.Artifact{
Revision: "sha256:b4c2a60ce44b67f5b659a95ce4e4cc9e2a86baf13afb72bd397c5384cbc0e479",
}
conditions.MarkReconciling(obj, meta.ProgressingReason, "foo")
@ -1277,7 +1277,7 @@ func TestBucketReconciler_reconcileSource_gcs(t *testing.T) {
},
},
beforeFunc: func(obj *sourcev1.Bucket) {
obj.Status.Artifact = &sourcev1.Artifact{
obj.Status.Artifact = &meta.Artifact{
Path: "some-path",
Revision: "some-rev",
}
@ -1488,7 +1488,7 @@ func TestBucketReconciler_reconcileArtifact(t *testing.T) {
revision := index.Digest(intdigest.Canonical)
obj.Spec.Interval = metav1.Duration{Duration: interval}
// Incomplete artifact
obj.Status.Artifact = &sourcev1.Artifact{Revision: revision.String()}
obj.Status.Artifact = &meta.Artifact{Revision: revision.String()}
conditions.MarkReconciling(obj, meta.ProgressingReason, "foo")
conditions.MarkUnknown(obj, meta.ReadyCondition, "foo", "bar")
},
@ -1751,7 +1751,7 @@ func TestBucketReconciler_notify(t *testing.T) {
res: sreconcile.ResultSuccess,
resErr: nil,
newObjBeforeFunc: func(obj *sourcev1.Bucket) {
obj.Status.Artifact = &sourcev1.Artifact{Revision: "xxx", Digest: "yyy"}
obj.Status.Artifact = &meta.Artifact{Revision: "xxx", Digest: "yyy"}
},
wantEvent: "Normal NewArtifact stored artifact with 2 fetched files from",
},
@ -1760,12 +1760,12 @@ func TestBucketReconciler_notify(t *testing.T) {
res: sreconcile.ResultSuccess,
resErr: nil,
oldObjBeforeFunc: func(obj *sourcev1.Bucket) {
obj.Status.Artifact = &sourcev1.Artifact{Revision: "xxx", Digest: "yyy"}
obj.Status.Artifact = &meta.Artifact{Revision: "xxx", Digest: "yyy"}
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, sourcev1.GitOperationFailedReason, "fail")
conditions.MarkFalse(obj, meta.ReadyCondition, meta.FailedReason, "foo")
},
newObjBeforeFunc: func(obj *sourcev1.Bucket) {
obj.Status.Artifact = &sourcev1.Artifact{Revision: "xxx", Digest: "yyy"}
obj.Status.Artifact = &meta.Artifact{Revision: "xxx", Digest: "yyy"}
conditions.MarkTrue(obj, meta.ReadyCondition, meta.SucceededReason, "ready")
},
wantEvent: "Normal Succeeded stored artifact with 2 fetched files from",
@ -1775,12 +1775,12 @@ func TestBucketReconciler_notify(t *testing.T) {
res: sreconcile.ResultSuccess,
resErr: nil,
oldObjBeforeFunc: func(obj *sourcev1.Bucket) {
obj.Status.Artifact = &sourcev1.Artifact{Revision: "xxx", Digest: "yyy"}
obj.Status.Artifact = &meta.Artifact{Revision: "xxx", Digest: "yyy"}
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, sourcev1.GitOperationFailedReason, "fail")
conditions.MarkFalse(obj, meta.ReadyCondition, meta.FailedReason, "foo")
},
newObjBeforeFunc: func(obj *sourcev1.Bucket) {
obj.Status.Artifact = &sourcev1.Artifact{Revision: "aaa", Digest: "bbb"}
obj.Status.Artifact = &meta.Artifact{Revision: "aaa", Digest: "bbb"}
conditions.MarkTrue(obj, meta.ReadyCondition, meta.SucceededReason, "ready")
},
wantEvent: "Normal NewArtifact stored artifact with 2 fetched files from",
@ -1790,11 +1790,11 @@ func TestBucketReconciler_notify(t *testing.T) {
res: sreconcile.ResultSuccess,
resErr: nil,
oldObjBeforeFunc: func(obj *sourcev1.Bucket) {
obj.Status.Artifact = &sourcev1.Artifact{Revision: "xxx", Digest: "yyy"}
obj.Status.Artifact = &meta.Artifact{Revision: "xxx", Digest: "yyy"}
conditions.MarkTrue(obj, meta.ReadyCondition, meta.SucceededReason, "ready")
},
newObjBeforeFunc: func(obj *sourcev1.Bucket) {
obj.Status.Artifact = &sourcev1.Artifact{Revision: "xxx", Digest: "yyy"}
obj.Status.Artifact = &meta.Artifact{Revision: "xxx", Digest: "yyy"}
conditions.MarkTrue(obj, meta.ReadyCondition, meta.SucceededReason, "ready")
},
},

View File

@ -938,7 +938,7 @@ func (r *GitRepositoryReconciler) reconcileInclude(ctx context.Context, sp *patc
// such that the index of artifactSet matches with the index of Include.
// Hence, index is used here to pick the associated artifact from
// includes.
var artifact *sourcev1.Artifact
var artifact *meta.Artifact
for j, art := range *includes {
if i == j {
artifact = art
@ -1271,7 +1271,7 @@ func gitContentConfigChanged(obj *sourcev1.GitRepository, includes *artifactSet)
// Convert artifactSet to index addressable artifacts and ensure that it and
// the included artifacts include all the include from the spec.
artifacts := []*sourcev1.Artifact(*includes)
artifacts := []*meta.Artifact(*includes)
if len(obj.Spec.Include) != len(artifacts) {
return true
}

View File

@ -699,7 +699,7 @@ func TestGitRepositoryReconciler_reconcileSource_authStrategy(t *testing.T) {
beforeFunc: func(obj *sourcev1.GitRepository) {
obj.Spec.SecretRef = &meta.LocalObjectReference{Name: "basic-auth"}
obj.Status = sourcev1.GitRepositoryStatus{
Artifact: &sourcev1.Artifact{
Artifact: &meta.Artifact{
Revision: "staging/some-revision",
Path: randStringRunes(10),
},
@ -1166,7 +1166,7 @@ func TestGitRepositoryReconciler_reconcileSource_checkoutStrategy(t *testing.T)
},
beforeFunc: func(obj *sourcev1.GitRepository, latestRev string) {
obj.Status = sourcev1.GitRepositoryStatus{
Artifact: &sourcev1.Artifact{
Artifact: &meta.Artifact{
Revision: "staging/some-revision",
Path: randStringRunes(10),
},
@ -1187,7 +1187,7 @@ func TestGitRepositoryReconciler_reconcileSource_checkoutStrategy(t *testing.T)
beforeFunc: func(obj *sourcev1.GitRepository, latestRev string) {
// Add existing artifact on the object and storage.
obj.Status = sourcev1.GitRepositoryStatus{
Artifact: &sourcev1.Artifact{
Artifact: &meta.Artifact{
Revision: "staging@sha1:" + latestRev,
Path: randStringRunes(10),
},
@ -1210,7 +1210,7 @@ func TestGitRepositoryReconciler_reconcileSource_checkoutStrategy(t *testing.T)
obj.Spec.Ignore = ptr.To("foo")
// Add existing artifact on the object and storage.
obj.Status = sourcev1.GitRepositoryStatus{
Artifact: &sourcev1.Artifact{
Artifact: &meta.Artifact{
Revision: "staging@sha1:" + latestRev,
Path: randStringRunes(10),
},
@ -1341,7 +1341,7 @@ func TestGitRepositoryReconciler_reconcileArtifact(t *testing.T) {
{
name: "Archiving artifact to storage with includes makes ArtifactInStorage=True",
dir: "testdata/git/repository",
includes: artifactSet{&sourcev1.Artifact{Revision: "main@sha1:b9b3feadba509cb9b22e968a5d27e96c2bc2ff91"}},
includes: artifactSet{&meta.Artifact{Revision: "main@sha1:b9b3feadba509cb9b22e968a5d27e96c2bc2ff91"}},
beforeFunc: func(obj *sourcev1.GitRepository) {
obj.Spec.Interval = metav1.Duration{Duration: interval}
obj.Spec.Include = []sourcev1.GitRepositoryInclude{
@ -1361,14 +1361,14 @@ func TestGitRepositoryReconciler_reconcileArtifact(t *testing.T) {
{
name: "Up-to-date artifact should not update status",
dir: "testdata/git/repository",
includes: artifactSet{&sourcev1.Artifact{Revision: "main@sha1:b9b3feadba509cb9b22e968a5d27e96c2bc2ff91", Digest: "some-checksum"}},
includes: artifactSet{&meta.Artifact{Revision: "main@sha1:b9b3feadba509cb9b22e968a5d27e96c2bc2ff91", Digest: "some-checksum"}},
beforeFunc: func(obj *sourcev1.GitRepository) {
obj.Spec.Interval = metav1.Duration{Duration: interval}
obj.Spec.Include = []sourcev1.GitRepositoryInclude{
{GitRepositoryRef: meta.LocalObjectReference{Name: "foo"}},
}
obj.Status.Artifact = &sourcev1.Artifact{Revision: "main@sha1:b9b3feadba509cb9b22e968a5d27e96c2bc2ff91"}
obj.Status.IncludedArtifacts = []*sourcev1.Artifact{{Revision: "main@sha1:b9b3feadba509cb9b22e968a5d27e96c2bc2ff91", Digest: "some-checksum"}}
obj.Status.Artifact = &meta.Artifact{Revision: "main@sha1:b9b3feadba509cb9b22e968a5d27e96c2bc2ff91"}
obj.Status.IncludedArtifacts = []*meta.Artifact{{Revision: "main@sha1:b9b3feadba509cb9b22e968a5d27e96c2bc2ff91", Digest: "some-checksum"}}
obj.Status.ObservedInclude = obj.Spec.Include
},
want: sreconcile.ResultSuccess,
@ -1587,7 +1587,7 @@ func TestGitRepositoryReconciler_reconcileInclude(t *testing.T) {
},
}
if d.withArtifact {
obj.Status.Artifact = &sourcev1.Artifact{
obj.Status.Artifact = &meta.Artifact{
Path: d.name + ".tar.gz",
Revision: d.name,
LastUpdateTime: metav1.Now(),
@ -1682,7 +1682,7 @@ func TestGitRepositoryReconciler_reconcileStorage(t *testing.T) {
beforeFunc func(obj *sourcev1.GitRepository, storage *storage.Storage) error
want sreconcile.Result
wantErr bool
assertArtifact *sourcev1.Artifact
assertArtifact *meta.Artifact
assertConditions []metav1.Condition
assertPaths []string
}{
@ -1692,7 +1692,7 @@ func TestGitRepositoryReconciler_reconcileStorage(t *testing.T) {
revisions := []string{"a", "b", "c", "d"}
for n := range revisions {
v := revisions[n]
obj.Status.Artifact = &sourcev1.Artifact{
obj.Status.Artifact = &meta.Artifact{
Path: fmt.Sprintf("/reconcile-storage/%s.txt", v),
Revision: v,
}
@ -1710,7 +1710,7 @@ func TestGitRepositoryReconciler_reconcileStorage(t *testing.T) {
conditions.MarkTrue(obj, meta.ReadyCondition, "foo", "bar")
return nil
},
assertArtifact: &sourcev1.Artifact{
assertArtifact: &meta.Artifact{
Path: "/reconcile-storage/d.txt",
Revision: "d",
Digest: "sha256:18ac3e7343f016890c510e93f935261169d9e3f565436429830faf0934f4f8e4",
@ -1739,7 +1739,7 @@ func TestGitRepositoryReconciler_reconcileStorage(t *testing.T) {
{
name: "notices missing artifact in storage",
beforeFunc: func(obj *sourcev1.GitRepository, storage *storage.Storage) error {
obj.Status.Artifact = &sourcev1.Artifact{
obj.Status.Artifact = &meta.Artifact{
Path: "/reconcile-storage/invalid.txt",
Revision: "e",
}
@ -1760,7 +1760,7 @@ func TestGitRepositoryReconciler_reconcileStorage(t *testing.T) {
beforeFunc: func(obj *sourcev1.GitRepository, storage *storage.Storage) error {
f := "empty-digest.txt"
obj.Status.Artifact = &sourcev1.Artifact{
obj.Status.Artifact = &meta.Artifact{
Path: fmt.Sprintf("/reconcile-storage/%s.txt", f),
Revision: "fake",
}
@ -1791,7 +1791,7 @@ func TestGitRepositoryReconciler_reconcileStorage(t *testing.T) {
beforeFunc: func(obj *sourcev1.GitRepository, storage *storage.Storage) error {
f := "digest-mismatch.txt"
obj.Status.Artifact = &sourcev1.Artifact{
obj.Status.Artifact = &meta.Artifact{
Path: fmt.Sprintf("/reconcile-storage/%s.txt", f),
Revision: "fake",
}
@ -1820,7 +1820,7 @@ func TestGitRepositoryReconciler_reconcileStorage(t *testing.T) {
{
name: "updates hostname on diff from current",
beforeFunc: func(obj *sourcev1.GitRepository, storage *storage.Storage) error {
obj.Status.Artifact = &sourcev1.Artifact{
obj.Status.Artifact = &meta.Artifact{
Path: "/reconcile-storage/hostname.txt",
Revision: "f",
Digest: "sha256:3b9c358f36f0a31b6ad3e14f309c7cf198ac9246e8316f9ce543d5b19ac02b80",
@ -1839,7 +1839,7 @@ func TestGitRepositoryReconciler_reconcileStorage(t *testing.T) {
assertPaths: []string{
"/reconcile-storage/hostname.txt",
},
assertArtifact: &sourcev1.Artifact{
assertArtifact: &meta.Artifact{
Path: "/reconcile-storage/hostname.txt",
Revision: "f",
Digest: "sha256:3b9c358f36f0a31b6ad3e14f309c7cf198ac9246e8316f9ce543d5b19ac02b80",
@ -2799,7 +2799,7 @@ func TestGitRepositoryReconciler_notify(t *testing.T) {
res: sreconcile.ResultSuccess,
resErr: nil,
newObjBeforeFunc: func(obj *sourcev1.GitRepository) {
obj.Status.Artifact = &sourcev1.Artifact{Revision: "xxx", Digest: "yyy"}
obj.Status.Artifact = &meta.Artifact{Revision: "xxx", Digest: "yyy"}
},
commit: concreteCommit,
wantEvent: "Normal NewArtifact stored artifact for commit 'test commit'",
@ -2809,12 +2809,12 @@ func TestGitRepositoryReconciler_notify(t *testing.T) {
res: sreconcile.ResultSuccess,
resErr: nil,
oldObjBeforeFunc: func(obj *sourcev1.GitRepository) {
obj.Status.Artifact = &sourcev1.Artifact{Revision: "xxx", Digest: "yyy"}
obj.Status.Artifact = &meta.Artifact{Revision: "xxx", Digest: "yyy"}
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, sourcev1.GitOperationFailedReason, "fail")
conditions.MarkFalse(obj, meta.ReadyCondition, meta.FailedReason, "foo")
},
newObjBeforeFunc: func(obj *sourcev1.GitRepository) {
obj.Status.Artifact = &sourcev1.Artifact{Revision: "xxx", Digest: "yyy"}
obj.Status.Artifact = &meta.Artifact{Revision: "xxx", Digest: "yyy"}
conditions.MarkTrue(obj, meta.ReadyCondition, meta.SucceededReason, "ready")
},
commit: concreteCommit,
@ -2825,12 +2825,12 @@ func TestGitRepositoryReconciler_notify(t *testing.T) {
res: sreconcile.ResultSuccess,
resErr: nil,
oldObjBeforeFunc: func(obj *sourcev1.GitRepository) {
obj.Status.Artifact = &sourcev1.Artifact{Revision: "xxx", Digest: "yyy"}
obj.Status.Artifact = &meta.Artifact{Revision: "xxx", Digest: "yyy"}
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, sourcev1.GitOperationFailedReason, "fail")
conditions.MarkFalse(obj, meta.ReadyCondition, meta.FailedReason, "foo")
},
newObjBeforeFunc: func(obj *sourcev1.GitRepository) {
obj.Status.Artifact = &sourcev1.Artifact{Revision: "aaa", Digest: "bbb"}
obj.Status.Artifact = &meta.Artifact{Revision: "aaa", Digest: "bbb"}
conditions.MarkTrue(obj, meta.ReadyCondition, meta.SucceededReason, "ready")
},
commit: concreteCommit,
@ -2841,11 +2841,11 @@ func TestGitRepositoryReconciler_notify(t *testing.T) {
res: sreconcile.ResultSuccess,
resErr: nil,
oldObjBeforeFunc: func(obj *sourcev1.GitRepository) {
obj.Status.Artifact = &sourcev1.Artifact{Revision: "xxx", Digest: "yyy"}
obj.Status.Artifact = &meta.Artifact{Revision: "xxx", Digest: "yyy"}
conditions.MarkTrue(obj, meta.ReadyCondition, meta.SucceededReason, "ready")
},
newObjBeforeFunc: func(obj *sourcev1.GitRepository) {
obj.Status.Artifact = &sourcev1.Artifact{Revision: "xxx", Digest: "yyy"}
obj.Status.Artifact = &meta.Artifact{Revision: "xxx", Digest: "yyy"}
conditions.MarkTrue(obj, meta.ReadyCondition, meta.SucceededReason, "ready")
},
},
@ -2854,12 +2854,12 @@ func TestGitRepositoryReconciler_notify(t *testing.T) {
res: sreconcile.ResultEmpty,
resErr: noopErr,
oldObjBeforeFunc: func(obj *sourcev1.GitRepository) {
obj.Status.Artifact = &sourcev1.Artifact{Revision: "xxx", Digest: "yyy"}
obj.Status.Artifact = &meta.Artifact{Revision: "xxx", Digest: "yyy"}
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, sourcev1.GitOperationFailedReason, "fail")
conditions.MarkFalse(obj, meta.ReadyCondition, meta.FailedReason, "foo")
},
newObjBeforeFunc: func(obj *sourcev1.GitRepository) {
obj.Status.Artifact = &sourcev1.Artifact{Revision: "xxx", Digest: "yyy"}
obj.Status.Artifact = &meta.Artifact{Revision: "xxx", Digest: "yyy"}
conditions.MarkTrue(obj, meta.ReadyCondition, meta.SucceededReason, "ready")
},
commit: partialCommit, // no-op will always result in partial commit.
@ -2950,7 +2950,7 @@ func TestGitRepositoryReconciler_fetchIncludes(t *testing.T) {
{name: "b", toPath: "b/", shouldExist: true},
},
wantErr: false,
wantArtifactSet: []*sourcev1.Artifact{
wantArtifactSet: []*meta.Artifact{
{Revision: "a"},
{Revision: "b"},
},
@ -3008,7 +3008,7 @@ func TestGitRepositoryReconciler_fetchIncludes(t *testing.T) {
},
}
if d.withArtifact {
obj.Status.Artifact = &sourcev1.Artifact{
obj.Status.Artifact = &meta.Artifact{
Path: d.name + ".tar.gz",
Revision: d.name,
LastUpdateTime: metav1.Now(),
@ -3166,7 +3166,7 @@ func TestGitContentConfigChanged(t *testing.T) {
tests := []struct {
name string
obj sourcev1.GitRepository
artifacts []*sourcev1.Artifact
artifacts []*meta.Artifact
want bool
}{
{
@ -3266,10 +3266,10 @@ func TestGitContentConfigChanged(t *testing.T) {
ToPath: "baz",
},
},
IncludedArtifacts: []*sourcev1.Artifact{{Revision: "aaa", Digest: "bbb"}},
IncludedArtifacts: []*meta.Artifact{{Revision: "aaa", Digest: "bbb"}},
},
},
artifacts: []*sourcev1.Artifact{
artifacts: []*meta.Artifact{
{Revision: "aaa", Digest: "bbb"},
},
want: false,
@ -3294,10 +3294,10 @@ func TestGitContentConfigChanged(t *testing.T) {
ToPath: "baz",
},
},
IncludedArtifacts: []*sourcev1.Artifact{{Revision: "aaa", Digest: "bbb"}},
IncludedArtifacts: []*meta.Artifact{{Revision: "aaa", Digest: "bbb"}},
},
},
artifacts: []*sourcev1.Artifact{
artifacts: []*meta.Artifact{
{Revision: "ccc", Digest: "bbb"},
},
want: true,
@ -3322,10 +3322,10 @@ func TestGitContentConfigChanged(t *testing.T) {
ToPath: "baz",
},
},
IncludedArtifacts: []*sourcev1.Artifact{{Revision: "aaa", Digest: "bbb"}},
IncludedArtifacts: []*meta.Artifact{{Revision: "aaa", Digest: "bbb"}},
},
},
artifacts: []*sourcev1.Artifact{
artifacts: []*meta.Artifact{
{Revision: "aaa", Digest: "ddd"},
},
want: true,
@ -3350,10 +3350,10 @@ func TestGitContentConfigChanged(t *testing.T) {
ToPath: "baz",
},
},
IncludedArtifacts: []*sourcev1.Artifact{{Revision: "aaa", Digest: "bbb"}},
IncludedArtifacts: []*meta.Artifact{{Revision: "aaa", Digest: "bbb"}},
},
},
artifacts: []*sourcev1.Artifact{
artifacts: []*meta.Artifact{
{Revision: "aaa", Digest: "bbb"},
},
want: true,
@ -3376,13 +3376,13 @@ func TestGitContentConfigChanged(t *testing.T) {
},
},
Status: sourcev1.GitRepositoryStatus{
IncludedArtifacts: []*sourcev1.Artifact{
IncludedArtifacts: []*meta.Artifact{
{Revision: "aaa", Digest: "bbb"},
{Revision: "ccc", Digest: "ccc"},
},
},
},
artifacts: []*sourcev1.Artifact{
artifacts: []*meta.Artifact{
{Revision: "aaa", Digest: "bbb"},
{Revision: "ccc", Digest: "ddd"},
},
@ -3418,13 +3418,13 @@ func TestGitContentConfigChanged(t *testing.T) {
ToPath: "baz",
},
},
IncludedArtifacts: []*sourcev1.Artifact{
IncludedArtifacts: []*meta.Artifact{
{Revision: "aaa", Digest: "bbb"},
{Revision: "ccc", Digest: "ccc"},
},
},
},
artifacts: []*sourcev1.Artifact{
artifacts: []*meta.Artifact{
{Revision: "aaa", Digest: "bbb"},
},
want: true,
@ -3459,12 +3459,12 @@ func TestGitContentConfigChanged(t *testing.T) {
ToPath: "baz",
},
},
IncludedArtifacts: []*sourcev1.Artifact{
IncludedArtifacts: []*meta.Artifact{
{Revision: "aaa", Digest: "bbb"},
},
},
},
artifacts: []*sourcev1.Artifact{
artifacts: []*meta.Artifact{
{Revision: "aaa", Digest: "bbb"},
{Revision: "ccc", Digest: "ccc"},
},

View File

@ -697,7 +697,7 @@ func (r *HelmChartReconciler) buildFromHelmRepository(ctx context.Context, obj *
// v1.Artifact.
// In case of a failure it records v1.FetchFailedCondition on the chart
// object, and returns early.
func (r *HelmChartReconciler) buildFromTarballArtifact(ctx context.Context, obj *sourcev1.HelmChart, source sourcev1.Artifact, b *chart.Build) (sreconcile.Result, error) {
func (r *HelmChartReconciler) buildFromTarballArtifact(ctx context.Context, obj *sourcev1.HelmChart, source meta.Artifact, b *chart.Build) (sreconcile.Result, error) {
// Create temporary working directory
tmpDir, err := util.TempDirForObj("", obj)
if err != nil {

View File

@ -336,7 +336,7 @@ func TestHelmChartReconciler_reconcileStorage(t *testing.T) {
beforeFunc func(obj *sourcev1.HelmChart, storage *storage.Storage) error
want sreconcile.Result
wantErr bool
assertArtifact *sourcev1.Artifact
assertArtifact *meta.Artifact
assertConditions []metav1.Condition
assertPaths []string
}{
@ -346,7 +346,7 @@ func TestHelmChartReconciler_reconcileStorage(t *testing.T) {
revisions := []string{"a", "b", "c", "d"}
for n := range revisions {
v := revisions[n]
obj.Status.Artifact = &sourcev1.Artifact{
obj.Status.Artifact = &meta.Artifact{
Path: fmt.Sprintf("/reconcile-storage/%s.txt", v),
Revision: v,
}
@ -364,7 +364,7 @@ func TestHelmChartReconciler_reconcileStorage(t *testing.T) {
conditions.MarkTrue(obj, meta.ReadyCondition, "foo", "bar")
return nil
},
assertArtifact: &sourcev1.Artifact{
assertArtifact: &meta.Artifact{
Path: "/reconcile-storage/d.txt",
Revision: "d",
Digest: "sha256:18ac3e7343f016890c510e93f935261169d9e3f565436429830faf0934f4f8e4",
@ -393,7 +393,7 @@ func TestHelmChartReconciler_reconcileStorage(t *testing.T) {
{
name: "notices missing artifact in storage",
beforeFunc: func(obj *sourcev1.HelmChart, storage *storage.Storage) error {
obj.Status.Artifact = &sourcev1.Artifact{
obj.Status.Artifact = &meta.Artifact{
Path: "/reconcile-storage/invalid.txt",
Revision: "d",
}
@ -414,7 +414,7 @@ func TestHelmChartReconciler_reconcileStorage(t *testing.T) {
beforeFunc: func(obj *sourcev1.HelmChart, storage *storage.Storage) error {
f := "empty-digest.txt"
obj.Status.Artifact = &sourcev1.Artifact{
obj.Status.Artifact = &meta.Artifact{
Path: fmt.Sprintf("/reconcile-storage/%s.txt", f),
Revision: "fake",
}
@ -445,7 +445,7 @@ func TestHelmChartReconciler_reconcileStorage(t *testing.T) {
beforeFunc: func(obj *sourcev1.HelmChart, storage *storage.Storage) error {
f := "digest-mismatch.txt"
obj.Status.Artifact = &sourcev1.Artifact{
obj.Status.Artifact = &meta.Artifact{
Path: fmt.Sprintf("/reconcile-storage/%s.txt", f),
Revision: "fake",
}
@ -474,7 +474,7 @@ func TestHelmChartReconciler_reconcileStorage(t *testing.T) {
{
name: "updates hostname on diff from current",
beforeFunc: func(obj *sourcev1.HelmChart, storage *storage.Storage) error {
obj.Status.Artifact = &sourcev1.Artifact{
obj.Status.Artifact = &meta.Artifact{
Path: "/reconcile-storage/hostname.txt",
Revision: "f",
Digest: "sha256:3b9c358f36f0a31b6ad3e14f309c7cf198ac9246e8316f9ce543d5b19ac02b80",
@ -493,7 +493,7 @@ func TestHelmChartReconciler_reconcileStorage(t *testing.T) {
assertPaths: []string{
"/reconcile-storage/hostname.txt",
},
assertArtifact: &sourcev1.Artifact{
assertArtifact: &meta.Artifact{
Path: "/reconcile-storage/hostname.txt",
Revision: "f",
Digest: "sha256:3b9c358f36f0a31b6ad3e14f309c7cf198ac9246e8316f9ce543d5b19ac02b80",
@ -574,7 +574,7 @@ func TestHelmChartReconciler_reconcileSource(t *testing.T) {
storage, err := storage.New(tmpDir, "example.com", retentionTTL, retentionRecords)
g.Expect(err).ToNot(HaveOccurred())
gitArtifact := &sourcev1.Artifact{
gitArtifact := &meta.Artifact{
Revision: "mock-ref/abcdefg12345678",
Path: "mock.tgz",
}
@ -641,7 +641,7 @@ func TestHelmChartReconciler_reconcileSource(t *testing.T) {
Name: "gitrepository",
Kind: sourcev1.GitRepositoryKind,
}
obj.Status.Artifact = &sourcev1.Artifact{
obj.Status.Artifact = &meta.Artifact{
Path: "some-path",
Revision: "some-rev",
}
@ -919,7 +919,7 @@ func TestHelmChartReconciler_buildFromHelmRepository(t *testing.T) {
beforeFunc: func(obj *sourcev1.HelmChart, repository *sourcev1.HelmRepository) {
obj.Spec.Chart = chartName
obj.Spec.Version = chartVersion
obj.Status.Artifact = &sourcev1.Artifact{Path: chartName + "-" + chartVersion + ".tgz"}
obj.Status.Artifact = &meta.Artifact{Path: chartName + "-" + chartVersion + ".tgz"}
},
want: sreconcile.ResultSuccess,
assertFunc: func(g *WithT, obj *sourcev1.HelmChart, build chart.Build) {
@ -934,7 +934,7 @@ func TestHelmChartReconciler_buildFromHelmRepository(t *testing.T) {
beforeFunc: func(obj *sourcev1.HelmChart, repository *sourcev1.HelmRepository) {
obj.Spec.Chart = chartName
obj.Spec.Version = chartVersion
obj.Status.Artifact = &sourcev1.Artifact{Path: chartName + "-" + chartVersion + ".tgz"}
obj.Status.Artifact = &meta.Artifact{Path: chartName + "-" + chartVersion + ".tgz"}
obj.Status.ObservedValuesFiles = []string{"values.yaml", "override.yaml"}
},
want: sreconcile.ResultSuccess,
@ -1017,7 +1017,7 @@ func TestHelmChartReconciler_buildFromHelmRepository(t *testing.T) {
obj.Spec.Version = chartVersion
obj.Status.ObservedGeneration = 2
obj.Status.Artifact = &sourcev1.Artifact{Path: chartName + "-" + chartVersion + ".tgz"}
obj.Status.Artifact = &meta.Artifact{Path: chartName + "-" + chartVersion + ".tgz"}
},
want: sreconcile.ResultSuccess,
assertFunc: func(g *WithT, obj *sourcev1.HelmChart, build chart.Build) {
@ -1135,7 +1135,7 @@ func TestHelmChartReconciler_buildFromHelmRepository(t *testing.T) {
Timeout: &metav1.Duration{Duration: timeout},
},
Status: sourcev1.HelmRepositoryStatus{
Artifact: &sourcev1.Artifact{
Artifact: &meta.Artifact{
Path: "index.yaml",
},
},
@ -1191,7 +1191,7 @@ func TestHelmChartReconciler_buildFromOCIHelmRepository(t *testing.T) {
storage, err := storage.New(tmpDir, "example.com", retentionTTL, retentionRecords)
g.Expect(err).ToNot(HaveOccurred())
cachedArtifact := &sourcev1.Artifact{
cachedArtifact := &meta.Artifact{
Revision: "0.1.0",
Path: metadata.Name + "-" + metadata.Version + ".tgz",
}
@ -1267,7 +1267,7 @@ func TestHelmChartReconciler_buildFromOCIHelmRepository(t *testing.T) {
beforeFunc: func(obj *sourcev1.HelmChart, repository *sourcev1.HelmRepository) {
obj.Spec.Chart = metadata.Name
obj.Spec.Version = metadata.Version
obj.Status.Artifact = &sourcev1.Artifact{Path: metadata.Name + "-" + metadata.Version + ".tgz"}
obj.Status.Artifact = &meta.Artifact{Path: metadata.Name + "-" + metadata.Version + ".tgz"}
},
want: sreconcile.ResultSuccess,
assertFunc: func(g *WithT, obj *sourcev1.HelmChart, build chart.Build) {
@ -1286,7 +1286,7 @@ func TestHelmChartReconciler_buildFromOCIHelmRepository(t *testing.T) {
obj.Spec.Version = metadata.Version
obj.Status.ObservedGeneration = 2
obj.Status.Artifact = &sourcev1.Artifact{Path: metadata.Name + "-" + metadata.Version + ".tgz"}
obj.Status.Artifact = &meta.Artifact{Path: metadata.Name + "-" + metadata.Version + ".tgz"}
},
want: sreconcile.ResultSuccess,
assertFunc: func(g *WithT, obj *sourcev1.HelmChart, build chart.Build) {
@ -1414,17 +1414,17 @@ func TestHelmChartReconciler_buildFromTarballArtifact(t *testing.T) {
storage, err := storage.New(tmpDir, "example.com", retentionTTL, retentionRecords)
g.Expect(err).ToNot(HaveOccurred())
chartsArtifact := &sourcev1.Artifact{
chartsArtifact := &meta.Artifact{
Revision: "mock-ref/abcdefg12345678",
Path: "mock.tgz",
}
g.Expect(storage.Archive(chartsArtifact, "testdata/charts", nil)).To(Succeed())
yamlArtifact := &sourcev1.Artifact{
yamlArtifact := &meta.Artifact{
Revision: "9876abcd",
Path: "values.yaml",
}
g.Expect(storage.CopyFromPath(yamlArtifact, "testdata/charts/helmchart/values.yaml")).To(Succeed())
cachedArtifact := &sourcev1.Artifact{
cachedArtifact := &meta.Artifact{
Revision: "0.1.0",
Path: "cached.tgz",
}
@ -1432,7 +1432,7 @@ func TestHelmChartReconciler_buildFromTarballArtifact(t *testing.T) {
tests := []struct {
name string
source sourcev1.Artifact
source meta.Artifact
beforeFunc func(obj *sourcev1.HelmChart)
want sreconcile.Result
wantErr error
@ -1563,7 +1563,7 @@ func TestHelmChartReconciler_buildFromTarballArtifact(t *testing.T) {
},
{
name: "Empty source artifact",
source: sourcev1.Artifact{},
source: meta.Artifact{},
want: sreconcile.ResultEmpty,
wantErr: &serror.Generic{Err: errors.New("no such file or directory")},
assertFunc: func(g *WithT, build chart.Build) {
@ -1678,7 +1678,7 @@ func TestHelmChartReconciler_reconcileArtifact(t *testing.T) {
Path: filepath.Join(testStorage.BasePath, "testdata/charts/helmchart-0.1.0.tgz"),
},
beforeFunc: func(obj *sourcev1.HelmChart) {
obj.Status.Artifact = &sourcev1.Artifact{
obj.Status.Artifact = &meta.Artifact{
Path: "testdata/charts/helmchart-0.1.0.tgz",
}
},
@ -1700,7 +1700,7 @@ func TestHelmChartReconciler_reconcileArtifact(t *testing.T) {
},
beforeFunc: func(obj *sourcev1.HelmChart) {
obj.Status.ObservedChartName = "helmchart"
obj.Status.Artifact = &sourcev1.Artifact{
obj.Status.Artifact = &meta.Artifact{
Revision: "0.1.0",
Path: "testdata/charts/helmchart-0.1.0.tgz",
}
@ -2298,7 +2298,7 @@ func TestHelmChartReconciler_notify(t *testing.T) {
res: sreconcile.ResultSuccess,
resErr: nil,
newObjBeforeFunc: func(obj *sourcev1.HelmChart) {
obj.Status.Artifact = &sourcev1.Artifact{Revision: "xxx", Digest: "yyy"}
obj.Status.Artifact = &meta.Artifact{Revision: "xxx", Digest: "yyy"}
},
wantEvent: "Normal ChartPackageSucceeded packaged",
},
@ -2307,12 +2307,12 @@ func TestHelmChartReconciler_notify(t *testing.T) {
res: sreconcile.ResultSuccess,
resErr: nil,
oldObjBeforeFunc: func(obj *sourcev1.HelmChart) {
obj.Status.Artifact = &sourcev1.Artifact{Revision: "xxx", Digest: "yyy"}
obj.Status.Artifact = &meta.Artifact{Revision: "xxx", Digest: "yyy"}
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, sourcev1.GitOperationFailedReason, "fail")
conditions.MarkFalse(obj, meta.ReadyCondition, meta.FailedReason, "foo")
},
newObjBeforeFunc: func(obj *sourcev1.HelmChart) {
obj.Status.Artifact = &sourcev1.Artifact{Revision: "xxx", Digest: "yyy"}
obj.Status.Artifact = &meta.Artifact{Revision: "xxx", Digest: "yyy"}
conditions.MarkTrue(obj, meta.ReadyCondition, meta.SucceededReason, "ready")
},
wantEvent: "Normal ChartPackageSucceeded packaged",
@ -2322,12 +2322,12 @@ func TestHelmChartReconciler_notify(t *testing.T) {
res: sreconcile.ResultSuccess,
resErr: nil,
oldObjBeforeFunc: func(obj *sourcev1.HelmChart) {
obj.Status.Artifact = &sourcev1.Artifact{Revision: "xxx", Digest: "yyy"}
obj.Status.Artifact = &meta.Artifact{Revision: "xxx", Digest: "yyy"}
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, sourcev1.GitOperationFailedReason, "fail")
conditions.MarkFalse(obj, meta.ReadyCondition, meta.FailedReason, "foo")
},
newObjBeforeFunc: func(obj *sourcev1.HelmChart) {
obj.Status.Artifact = &sourcev1.Artifact{Revision: "aaa", Digest: "bbb"}
obj.Status.Artifact = &meta.Artifact{Revision: "aaa", Digest: "bbb"}
conditions.MarkTrue(obj, meta.ReadyCondition, meta.SucceededReason, "ready")
},
wantEvent: "Normal ChartPackageSucceeded packaged",
@ -2337,11 +2337,11 @@ func TestHelmChartReconciler_notify(t *testing.T) {
res: sreconcile.ResultSuccess,
resErr: nil,
oldObjBeforeFunc: func(obj *sourcev1.HelmChart) {
obj.Status.Artifact = &sourcev1.Artifact{Revision: "xxx", Digest: "yyy"}
obj.Status.Artifact = &meta.Artifact{Revision: "xxx", Digest: "yyy"}
conditions.MarkTrue(obj, meta.ReadyCondition, meta.SucceededReason, "ready")
},
newObjBeforeFunc: func(obj *sourcev1.HelmChart) {
obj.Status.Artifact = &sourcev1.Artifact{Revision: "xxx", Digest: "yyy"}
obj.Status.Artifact = &meta.Artifact{Revision: "xxx", Digest: "yyy"}
conditions.MarkTrue(obj, meta.ReadyCondition, meta.SucceededReason, "ready")
},
},
@ -2901,7 +2901,7 @@ func TestHelmChartReconciler_reconcileSourceFromOCI_verifySignatureNotation(t *t
storage, err := storage.New(tmpDir, server.registryHost, retentionTTL, retentionRecords)
g.Expect(err).ToNot(HaveOccurred())
cachedArtifact := &sourcev1.Artifact{
cachedArtifact := &meta.Artifact{
Revision: "0.1.0",
Path: metadata.Name + "-" + metadata.Version + ".tgz",
}
@ -3006,7 +3006,7 @@ func TestHelmChartReconciler_reconcileSourceFromOCI_verifySignatureNotation(t *t
obj.Spec.Version = metadata.Version
obj.Spec.Verify = nil
conditions.MarkFalse(obj, sourcev1.SourceVerifiedCondition, "VerifyFailed", "fail msg")
obj.Status.Artifact = &sourcev1.Artifact{Path: metadata.Name + "-" + metadata.Version + ".tgz"}
obj.Status.Artifact = &meta.Artifact{Path: metadata.Name + "-" + metadata.Version + ".tgz"}
},
want: sreconcile.ResultSuccess,
assertConditions: []metav1.Condition{
@ -3225,7 +3225,7 @@ func TestHelmChartReconciler_reconcileSourceFromOCI_verifySignatureCosign(t *tes
storage, err := storage.New(tmpDir, server.registryHost, retentionTTL, retentionRecords)
g.Expect(err).ToNot(HaveOccurred())
cachedArtifact := &sourcev1.Artifact{
cachedArtifact := &meta.Artifact{
Revision: "0.1.0",
Path: metadata.Name + "-" + metadata.Version + ".tgz",
}
@ -3318,7 +3318,7 @@ func TestHelmChartReconciler_reconcileSourceFromOCI_verifySignatureCosign(t *tes
obj.Spec.Version = metadata.Version
obj.Spec.Verify = nil
conditions.MarkFalse(obj, sourcev1.SourceVerifiedCondition, "VerifyFailed", "fail msg")
obj.Status.Artifact = &sourcev1.Artifact{Path: metadata.Name + "-" + metadata.Version + ".tgz"}
obj.Status.Artifact = &meta.Artifact{Path: metadata.Name + "-" + metadata.Version + ".tgz"}
},
want: sreconcile.ResultSuccess,
assertConditions: []metav1.Condition{

View File

@ -128,7 +128,7 @@ type HelmRepositoryReconcilerOptions struct {
// v1.HelmRepository (sub)reconcile functions. The type implementations
// are grouped and executed serially to perform the complete reconcile of the
// object.
type helmRepositoryReconcileFunc func(ctx context.Context, sp *patch.SerialPatcher, obj *sourcev1.HelmRepository, artifact *sourcev1.Artifact, repo *repository.ChartRepository) (sreconcile.Result, error)
type helmRepositoryReconcileFunc func(ctx context.Context, sp *patch.SerialPatcher, obj *sourcev1.HelmRepository, artifact *meta.Artifact, repo *repository.ChartRepository) (sreconcile.Result, error)
func (r *HelmRepositoryReconciler) SetupWithManager(mgr ctrl.Manager) error {
return r.SetupWithManagerAndOptions(mgr, HelmRepositoryReconcilerOptions{})
@ -258,7 +258,7 @@ func (r *HelmRepositoryReconciler) reconcile(ctx context.Context, sp *patch.Seri
}
var chartRepo repository.ChartRepository
var artifact sourcev1.Artifact
var artifact meta.Artifact
// Run the sub-reconcilers and build the result of reconciliation.
var res sreconcile.Result
@ -330,7 +330,7 @@ func (r *HelmRepositoryReconciler) notify(ctx context.Context, oldObj, newObj *s
// 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 *HelmRepositoryReconciler) reconcileStorage(ctx context.Context, sp *patch.SerialPatcher,
obj *sourcev1.HelmRepository, _ *sourcev1.Artifact, _ *repository.ChartRepository) (sreconcile.Result, error) {
obj *sourcev1.HelmRepository, _ *meta.Artifact, _ *repository.ChartRepository) (sreconcile.Result, error) {
// Garbage collect previous advertised artifact(s) from storage
_ = r.garbageCollect(ctx, obj)
@ -393,7 +393,7 @@ func (r *HelmRepositoryReconciler) reconcileStorage(ctx context.Context, sp *pat
// v1.FetchFailedCondition is removed, and the repository.ChartRepository
// pointer is set to the newly fetched index.
func (r *HelmRepositoryReconciler) reconcileSource(ctx context.Context, sp *patch.SerialPatcher,
obj *sourcev1.HelmRepository, artifact *sourcev1.Artifact, chartRepo *repository.ChartRepository) (sreconcile.Result, error) {
obj *sourcev1.HelmRepository, artifact *meta.Artifact, chartRepo *repository.ChartRepository) (sreconcile.Result, error) {
// Ensure it's not an OCI URL. API validation ensures that only
// http/https/oci scheme are allowed.
if strings.HasPrefix(obj.Spec.URL, helmreg.OCIScheme) {
@ -530,7 +530,7 @@ func (r *HelmRepositoryReconciler) reconcileSource(ctx context.Context, sp *patc
// early.
// On a successful archive, the Artifact in the Status of the object is set,
// and the symlink in the Storage is updated to its path.
func (r *HelmRepositoryReconciler) reconcileArtifact(ctx context.Context, sp *patch.SerialPatcher, obj *sourcev1.HelmRepository, artifact *sourcev1.Artifact, chartRepo *repository.ChartRepository) (sreconcile.Result, error) {
func (r *HelmRepositoryReconciler) reconcileArtifact(ctx context.Context, sp *patch.SerialPatcher, obj *sourcev1.HelmRepository, artifact *meta.Artifact, chartRepo *repository.ChartRepository) (sreconcile.Result, error) {
// Set the ArtifactInStorageCondition if there's no drift.
defer func() {
if obj.GetArtifact().HasRevision(artifact.Revision) {

View File

@ -176,7 +176,7 @@ func TestHelmRepositoryReconciler_reconcileStorage(t *testing.T) {
beforeFunc func(obj *sourcev1.HelmRepository, storage *storage.Storage) error
want sreconcile.Result
wantErr bool
assertArtifact *sourcev1.Artifact
assertArtifact *meta.Artifact
assertConditions []metav1.Condition
assertPaths []string
}{
@ -186,7 +186,7 @@ func TestHelmRepositoryReconciler_reconcileStorage(t *testing.T) {
revisions := []string{"a", "b", "c", "d"}
for n := range revisions {
v := revisions[n]
obj.Status.Artifact = &sourcev1.Artifact{
obj.Status.Artifact = &meta.Artifact{
Path: fmt.Sprintf("/reconcile-storage/%s.txt", v),
Revision: v,
}
@ -204,7 +204,7 @@ func TestHelmRepositoryReconciler_reconcileStorage(t *testing.T) {
conditions.MarkTrue(obj, meta.ReadyCondition, "foo", "bar")
return nil
},
assertArtifact: &sourcev1.Artifact{
assertArtifact: &meta.Artifact{
Path: "/reconcile-storage/d.txt",
Revision: "d",
Digest: "sha256:18ac3e7343f016890c510e93f935261169d9e3f565436429830faf0934f4f8e4",
@ -233,7 +233,7 @@ func TestHelmRepositoryReconciler_reconcileStorage(t *testing.T) {
{
name: "notices missing artifact in storage",
beforeFunc: func(obj *sourcev1.HelmRepository, storage *storage.Storage) error {
obj.Status.Artifact = &sourcev1.Artifact{
obj.Status.Artifact = &meta.Artifact{
Path: "/reconcile-storage/invalid.txt",
Revision: "d",
}
@ -254,7 +254,7 @@ func TestHelmRepositoryReconciler_reconcileStorage(t *testing.T) {
beforeFunc: func(obj *sourcev1.HelmRepository, storage *storage.Storage) error {
f := "empty-digest.txt"
obj.Status.Artifact = &sourcev1.Artifact{
obj.Status.Artifact = &meta.Artifact{
Path: fmt.Sprintf("/reconcile-storage/%s.txt", f),
Revision: "fake",
}
@ -285,7 +285,7 @@ func TestHelmRepositoryReconciler_reconcileStorage(t *testing.T) {
beforeFunc: func(obj *sourcev1.HelmRepository, storage *storage.Storage) error {
f := "digest-mismatch.txt"
obj.Status.Artifact = &sourcev1.Artifact{
obj.Status.Artifact = &meta.Artifact{
Path: fmt.Sprintf("/reconcile-storage/%s.txt", f),
Revision: "fake",
}
@ -314,7 +314,7 @@ func TestHelmRepositoryReconciler_reconcileStorage(t *testing.T) {
{
name: "updates hostname on diff from current",
beforeFunc: func(obj *sourcev1.HelmRepository, storage *storage.Storage) error {
obj.Status.Artifact = &sourcev1.Artifact{
obj.Status.Artifact = &meta.Artifact{
Path: "/reconcile-storage/hostname.txt",
Revision: "f",
Digest: "sha256:3b9c358f36f0a31b6ad3e14f309c7cf198ac9246e8316f9ce543d5b19ac02b80",
@ -333,7 +333,7 @@ func TestHelmRepositoryReconciler_reconcileStorage(t *testing.T) {
assertPaths: []string{
"/reconcile-storage/hostname.txt",
},
assertArtifact: &sourcev1.Artifact{
assertArtifact: &meta.Artifact{
Path: "/reconcile-storage/hostname.txt",
Revision: "f",
Digest: "sha256:3b9c358f36f0a31b6ad3e14f309c7cf198ac9246e8316f9ce543d5b19ac02b80",
@ -375,7 +375,7 @@ func TestHelmRepositoryReconciler_reconcileStorage(t *testing.T) {
}()
var chartRepo repository.ChartRepository
var artifact sourcev1.Artifact
var artifact meta.Artifact
sp := patch.NewSerialPatcher(obj, r.Client)
got, err := r.reconcileStorage(context.TODO(), sp, obj, &artifact, &chartRepo)
@ -421,7 +421,7 @@ func TestHelmRepositoryReconciler_reconcileSource(t *testing.T) {
secret *corev1.Secret
beforeFunc func(t *WithT, obj *sourcev1.HelmRepository)
revFunc func(t *WithT, server *helmtestserver.HelmServer, secret *corev1.Secret) digest.Digest
afterFunc func(t *WithT, obj *sourcev1.HelmRepository, artifact sourcev1.Artifact, chartRepo *repository.ChartRepository)
afterFunc func(t *WithT, obj *sourcev1.HelmRepository, artifact meta.Artifact, chartRepo *repository.ChartRepository)
want sreconcile.Result
wantErr bool
assertConditions []metav1.Condition
@ -495,7 +495,7 @@ func TestHelmRepositoryReconciler_reconcileSource(t *testing.T) {
*conditions.TrueCondition(meta.ReconcilingCondition, meta.ProgressingReason, "building artifact: new index revision"),
*conditions.UnknownCondition(meta.ReadyCondition, meta.ProgressingReason, "building artifact: new index revision"),
},
afterFunc: func(t *WithT, obj *sourcev1.HelmRepository, artifact sourcev1.Artifact, chartRepo *repository.ChartRepository) {
afterFunc: func(t *WithT, obj *sourcev1.HelmRepository, artifact meta.Artifact, chartRepo *repository.ChartRepository) {
t.Expect(chartRepo.Path).ToNot(BeEmpty())
t.Expect(chartRepo.Index).ToNot(BeNil())
t.Expect(artifact.Revision).ToNot(BeEmpty())
@ -547,7 +547,7 @@ func TestHelmRepositoryReconciler_reconcileSource(t *testing.T) {
*conditions.TrueCondition(meta.ReconcilingCondition, meta.ProgressingReason, "building artifact: new index revision"),
*conditions.UnknownCondition(meta.ReadyCondition, meta.ProgressingReason, "building artifact: new index revision"),
},
afterFunc: func(t *WithT, obj *sourcev1.HelmRepository, artifact sourcev1.Artifact, chartRepo *repository.ChartRepository) {
afterFunc: func(t *WithT, obj *sourcev1.HelmRepository, artifact meta.Artifact, chartRepo *repository.ChartRepository) {
t.Expect(chartRepo.Path).ToNot(BeEmpty())
t.Expect(chartRepo.Index).ToNot(BeNil())
t.Expect(artifact.Revision).ToNot(BeEmpty())
@ -601,7 +601,7 @@ func TestHelmRepositoryReconciler_reconcileSource(t *testing.T) {
*conditions.TrueCondition(meta.ReconcilingCondition, meta.ProgressingReason, "building artifact: new index revision"),
*conditions.UnknownCondition(meta.ReadyCondition, meta.ProgressingReason, "building artifact: new index revision"),
},
afterFunc: func(t *WithT, obj *sourcev1.HelmRepository, artifact sourcev1.Artifact, chartRepo *repository.ChartRepository) {
afterFunc: func(t *WithT, obj *sourcev1.HelmRepository, artifact meta.Artifact, chartRepo *repository.ChartRepository) {
t.Expect(chartRepo.Path).ToNot(BeEmpty())
t.Expect(chartRepo.Index).ToNot(BeNil())
t.Expect(artifact.Revision).ToNot(BeEmpty())
@ -633,7 +633,7 @@ func TestHelmRepositoryReconciler_reconcileSource(t *testing.T) {
*conditions.TrueCondition(meta.ReconcilingCondition, meta.ProgressingReason, "building artifact: new index revision"),
*conditions.UnknownCondition(meta.ReadyCondition, meta.ProgressingReason, "building artifact: new index revision"),
},
afterFunc: func(t *WithT, obj *sourcev1.HelmRepository, artifact sourcev1.Artifact, chartRepo *repository.ChartRepository) {
afterFunc: func(t *WithT, obj *sourcev1.HelmRepository, artifact meta.Artifact, chartRepo *repository.ChartRepository) {
t.Expect(chartRepo.Path).ToNot(BeEmpty())
t.Expect(chartRepo.Index).ToNot(BeNil())
t.Expect(artifact.Revision).ToNot(BeEmpty())
@ -686,7 +686,7 @@ func TestHelmRepositoryReconciler_reconcileSource(t *testing.T) {
*conditions.TrueCondition(meta.ReconcilingCondition, meta.ProgressingReason, "building artifact: new index revision"),
*conditions.UnknownCondition(meta.ReadyCondition, meta.ProgressingReason, "building artifact: new index revision"),
},
afterFunc: func(t *WithT, obj *sourcev1.HelmRepository, artifact sourcev1.Artifact, chartRepo *repository.ChartRepository) {
afterFunc: func(t *WithT, obj *sourcev1.HelmRepository, artifact meta.Artifact, chartRepo *repository.ChartRepository) {
t.Expect(chartRepo.Path).ToNot(BeEmpty())
t.Expect(chartRepo.Index).ToNot(BeNil())
t.Expect(artifact.Revision).ToNot(BeEmpty())
@ -741,7 +741,7 @@ func TestHelmRepositoryReconciler_reconcileSource(t *testing.T) {
*conditions.TrueCondition(meta.ReconcilingCondition, meta.ProgressingReason, "building artifact: new index revision"),
*conditions.UnknownCondition(meta.ReadyCondition, meta.ProgressingReason, "building artifact: new index revision"),
},
afterFunc: func(t *WithT, obj *sourcev1.HelmRepository, artifact sourcev1.Artifact, chartRepo *repository.ChartRepository) {
afterFunc: func(t *WithT, obj *sourcev1.HelmRepository, artifact meta.Artifact, chartRepo *repository.ChartRepository) {
t.Expect(chartRepo.Path).ToNot(BeEmpty())
t.Expect(chartRepo.Index).ToNot(BeNil())
t.Expect(artifact.Revision).ToNot(BeEmpty())
@ -775,7 +775,7 @@ func TestHelmRepositoryReconciler_reconcileSource(t *testing.T) {
*conditions.TrueCondition(meta.ReconcilingCondition, meta.ProgressingReason, "foo"),
*conditions.UnknownCondition(meta.ReadyCondition, "foo", "bar"),
},
afterFunc: func(t *WithT, obj *sourcev1.HelmRepository, artifact sourcev1.Artifact, chartRepo *repository.ChartRepository) {
afterFunc: func(t *WithT, obj *sourcev1.HelmRepository, artifact meta.Artifact, chartRepo *repository.ChartRepository) {
// No repo index due to fetch fail.
t.Expect(chartRepo.Path).To(BeEmpty())
t.Expect(chartRepo.Index).To(BeNil())
@ -797,7 +797,7 @@ func TestHelmRepositoryReconciler_reconcileSource(t *testing.T) {
*conditions.TrueCondition(meta.ReconcilingCondition, meta.ProgressingReason, "foo"),
*conditions.UnknownCondition(meta.ReadyCondition, "foo", "bar"),
},
afterFunc: func(t *WithT, obj *sourcev1.HelmRepository, artifact sourcev1.Artifact, chartRepo *repository.ChartRepository) {
afterFunc: func(t *WithT, obj *sourcev1.HelmRepository, artifact meta.Artifact, chartRepo *repository.ChartRepository) {
// No repo index due to fetch fail.
t.Expect(chartRepo.Path).To(BeEmpty())
t.Expect(chartRepo.Index).To(BeNil())
@ -819,7 +819,7 @@ func TestHelmRepositoryReconciler_reconcileSource(t *testing.T) {
*conditions.TrueCondition(meta.ReconcilingCondition, meta.ProgressingReason, "foo"),
*conditions.UnknownCondition(meta.ReadyCondition, "foo", "bar"),
},
afterFunc: func(t *WithT, obj *sourcev1.HelmRepository, artifact sourcev1.Artifact, chartRepo *repository.ChartRepository) {
afterFunc: func(t *WithT, obj *sourcev1.HelmRepository, artifact meta.Artifact, chartRepo *repository.ChartRepository) {
// No repo index due to fetch fail.
t.Expect(chartRepo.Path).To(BeEmpty())
t.Expect(chartRepo.Index).To(BeNil())
@ -840,7 +840,7 @@ func TestHelmRepositoryReconciler_reconcileSource(t *testing.T) {
*conditions.TrueCondition(meta.ReconcilingCondition, meta.ProgressingReason, "foo"),
*conditions.UnknownCondition(meta.ReadyCondition, "foo", "bar"),
},
afterFunc: func(t *WithT, obj *sourcev1.HelmRepository, artifact sourcev1.Artifact, chartRepo *repository.ChartRepository) {
afterFunc: func(t *WithT, obj *sourcev1.HelmRepository, artifact meta.Artifact, chartRepo *repository.ChartRepository) {
// No repo index due to fetch fail.
t.Expect(chartRepo.Path).To(BeEmpty())
t.Expect(chartRepo.Index).To(BeNil())
@ -870,7 +870,7 @@ func TestHelmRepositoryReconciler_reconcileSource(t *testing.T) {
*conditions.TrueCondition(meta.ReconcilingCondition, meta.ProgressingReason, "foo"),
*conditions.UnknownCondition(meta.ReadyCondition, "foo", "bar"),
},
afterFunc: func(t *WithT, obj *sourcev1.HelmRepository, artifact sourcev1.Artifact, chartRepo *repository.ChartRepository) {
afterFunc: func(t *WithT, obj *sourcev1.HelmRepository, artifact meta.Artifact, chartRepo *repository.ChartRepository) {
// No repo index due to fetch fail.
t.Expect(chartRepo.Path).To(BeEmpty())
t.Expect(chartRepo.Index).To(BeNil())
@ -907,7 +907,7 @@ func TestHelmRepositoryReconciler_reconcileSource(t *testing.T) {
*conditions.TrueCondition(meta.ReconcilingCondition, meta.ProgressingReason, "foo"),
*conditions.UnknownCondition(meta.ReadyCondition, "foo", "bar"),
},
afterFunc: func(t *WithT, obj *sourcev1.HelmRepository, artifact sourcev1.Artifact, chartRepo *repository.ChartRepository) {
afterFunc: func(t *WithT, obj *sourcev1.HelmRepository, artifact meta.Artifact, chartRepo *repository.ChartRepository) {
t.Expect(chartRepo.Path).ToNot(BeEmpty())
t.Expect(chartRepo.Index).To(BeNil())
@ -919,7 +919,7 @@ func TestHelmRepositoryReconciler_reconcileSource(t *testing.T) {
name: "Stored index with different revision",
protocol: "http",
beforeFunc: func(t *WithT, obj *sourcev1.HelmRepository) {
obj.Status.Artifact = &sourcev1.Artifact{
obj.Status.Artifact = &meta.Artifact{
Revision: "80bb3dd67c63095d985850459834ea727603727a370079de90d221191d375a86",
}
conditions.MarkReconciling(obj, meta.ProgressingReason, "foo")
@ -931,7 +931,7 @@ func TestHelmRepositoryReconciler_reconcileSource(t *testing.T) {
*conditions.TrueCondition(meta.ReconcilingCondition, meta.ProgressingReason, "building artifact: new index revision"),
*conditions.UnknownCondition(meta.ReadyCondition, meta.ProgressingReason, "building artifact: new index revision"),
},
afterFunc: func(t *WithT, obj *sourcev1.HelmRepository, artifact sourcev1.Artifact, chartRepo *repository.ChartRepository) {
afterFunc: func(t *WithT, obj *sourcev1.HelmRepository, artifact meta.Artifact, chartRepo *repository.ChartRepository) {
t.Expect(chartRepo.Path).ToNot(BeEmpty())
t.Expect(chartRepo.Index).ToNot(BeNil())
@ -944,7 +944,7 @@ func TestHelmRepositoryReconciler_reconcileSource(t *testing.T) {
name: "Existing artifact makes ArtifactOutdated=True",
protocol: "http",
beforeFunc: func(t *WithT, obj *sourcev1.HelmRepository) {
obj.Status.Artifact = &sourcev1.Artifact{
obj.Status.Artifact = &meta.Artifact{
Path: "some-path",
Revision: "some-rev",
}
@ -1040,7 +1040,7 @@ func TestHelmRepositoryReconciler_reconcileSource(t *testing.T) {
// Special handling for tests that need to set revision after calculation
if tt.name == "Stored index with same revision" && rev != "" {
obj.Status.Artifact = &sourcev1.Artifact{
obj.Status.Artifact = &meta.Artifact{
Revision: rev.String(),
}
}
@ -1051,7 +1051,7 @@ func TestHelmRepositoryReconciler_reconcileSource(t *testing.T) {
}()
var chartRepo repository.ChartRepository
var artifact sourcev1.Artifact
var artifact meta.Artifact
sp := patch.NewSerialPatcher(obj, r.Client)
got, err := r.reconcileSource(context.TODO(), sp, obj, &artifact, &chartRepo)
@ -1076,7 +1076,7 @@ func TestHelmRepositoryReconciler_reconcileArtifact(t *testing.T) {
tests := []struct {
name string
cache *cache.Cache
beforeFunc func(t *WithT, obj *sourcev1.HelmRepository, artifact sourcev1.Artifact, index *repository.ChartRepository)
beforeFunc func(t *WithT, obj *sourcev1.HelmRepository, artifact meta.Artifact, index *repository.ChartRepository)
afterFunc func(t *WithT, obj *sourcev1.HelmRepository, cache *cache.Cache)
want sreconcile.Result
wantErr bool
@ -1084,7 +1084,7 @@ func TestHelmRepositoryReconciler_reconcileArtifact(t *testing.T) {
}{
{
name: "Archiving artifact to storage makes ArtifactInStorage=True and artifact is stored as JSON",
beforeFunc: func(t *WithT, obj *sourcev1.HelmRepository, artifact sourcev1.Artifact, index *repository.ChartRepository) {
beforeFunc: func(t *WithT, obj *sourcev1.HelmRepository, artifact meta.Artifact, index *repository.ChartRepository) {
obj.Spec.Interval = metav1.Duration{Duration: interval}
},
want: sreconcile.ResultSuccess,
@ -1101,7 +1101,7 @@ func TestHelmRepositoryReconciler_reconcileArtifact(t *testing.T) {
{
name: "Archiving (loaded) artifact to storage adds to cache",
cache: cache.New(10, time.Minute),
beforeFunc: func(t *WithT, obj *sourcev1.HelmRepository, artifact sourcev1.Artifact, index *repository.ChartRepository) {
beforeFunc: func(t *WithT, obj *sourcev1.HelmRepository, artifact meta.Artifact, index *repository.ChartRepository) {
index.Index = &repo.IndexFile{
APIVersion: "v1",
Generated: time.Now(),
@ -1120,7 +1120,7 @@ func TestHelmRepositoryReconciler_reconcileArtifact(t *testing.T) {
},
{
name: "Up-to-date artifact should not update status",
beforeFunc: func(t *WithT, obj *sourcev1.HelmRepository, artifact sourcev1.Artifact, index *repository.ChartRepository) {
beforeFunc: func(t *WithT, obj *sourcev1.HelmRepository, artifact meta.Artifact, index *repository.ChartRepository) {
obj.Spec.Interval = metav1.Duration{Duration: interval}
obj.Status.Artifact = artifact.DeepCopy()
},
@ -1134,7 +1134,7 @@ func TestHelmRepositoryReconciler_reconcileArtifact(t *testing.T) {
},
{
name: "Removes ArtifactOutdatedCondition after creating a new artifact",
beforeFunc: func(t *WithT, obj *sourcev1.HelmRepository, artifact sourcev1.Artifact, index *repository.ChartRepository) {
beforeFunc: func(t *WithT, obj *sourcev1.HelmRepository, artifact meta.Artifact, index *repository.ChartRepository) {
obj.Spec.Interval = metav1.Duration{Duration: interval}
conditions.MarkTrue(obj, sourcev1.ArtifactOutdatedCondition, "Foo", "")
},
@ -1145,7 +1145,7 @@ func TestHelmRepositoryReconciler_reconcileArtifact(t *testing.T) {
},
{
name: "Creates latest symlink to the created artifact",
beforeFunc: func(t *WithT, obj *sourcev1.HelmRepository, artifact sourcev1.Artifact, index *repository.ChartRepository) {
beforeFunc: func(t *WithT, obj *sourcev1.HelmRepository, artifact meta.Artifact, index *repository.ChartRepository) {
obj.Spec.Interval = metav1.Duration{Duration: interval}
},
afterFunc: func(t *WithT, obj *sourcev1.HelmRepository, _ *cache.Cache) {
@ -1227,7 +1227,7 @@ func TestHelmRepositoryReconciler_reconcileArtifact(t *testing.T) {
func TestHelmRepositoryReconciler_reconcileSubRecs(t *testing.T) {
// Helper to build simple helmRepositoryReconcileFunc with result and error.
buildReconcileFuncs := func(r sreconcile.Result, e error) helmRepositoryReconcileFunc {
return func(ctx context.Context, sp *patch.SerialPatcher, obj *sourcev1.HelmRepository, artifact *sourcev1.Artifact, repo *repository.ChartRepository) (sreconcile.Result, error) {
return func(ctx context.Context, sp *patch.SerialPatcher, obj *sourcev1.HelmRepository, artifact *meta.Artifact, repo *repository.ChartRepository) (sreconcile.Result, error) {
return r, e
}
}
@ -1282,11 +1282,11 @@ func TestHelmRepositoryReconciler_reconcileSubRecs(t *testing.T) {
{
name: "multiple object status conditions mutations",
reconcileFuncs: []helmRepositoryReconcileFunc{
func(ctx context.Context, sp *patch.SerialPatcher, obj *sourcev1.HelmRepository, artifact *sourcev1.Artifact, repo *repository.ChartRepository) (sreconcile.Result, error) {
func(ctx context.Context, sp *patch.SerialPatcher, obj *sourcev1.HelmRepository, artifact *meta.Artifact, repo *repository.ChartRepository) (sreconcile.Result, error) {
conditions.MarkTrue(obj, sourcev1.ArtifactOutdatedCondition, "NewRevision", "new index revision")
return sreconcile.ResultSuccess, nil
},
func(ctx context.Context, sp *patch.SerialPatcher, obj *sourcev1.HelmRepository, artifact *sourcev1.Artifact, repo *repository.ChartRepository) (sreconcile.Result, error) {
func(ctx context.Context, sp *patch.SerialPatcher, obj *sourcev1.HelmRepository, artifact *meta.Artifact, repo *repository.ChartRepository) (sreconcile.Result, error) {
conditions.MarkTrue(obj, meta.ReconcilingCondition, meta.ProgressingReason, "creating artifact")
return sreconcile.ResultSuccess, nil
},
@ -1481,7 +1481,7 @@ func TestHelmRepositoryReconciler_notify(t *testing.T) {
res: sreconcile.ResultSuccess,
resErr: nil,
newObjBeforeFunc: func(obj *sourcev1.HelmRepository) {
obj.Status.Artifact = &sourcev1.Artifact{Revision: "xxx", Digest: "yyy", Size: nil}
obj.Status.Artifact = &meta.Artifact{Revision: "xxx", Digest: "yyy", Size: nil}
},
wantEvent: "Normal NewArtifact stored fetched index of unknown size",
},
@ -1490,7 +1490,7 @@ func TestHelmRepositoryReconciler_notify(t *testing.T) {
res: sreconcile.ResultSuccess,
resErr: nil,
newObjBeforeFunc: func(obj *sourcev1.HelmRepository) {
obj.Status.Artifact = &sourcev1.Artifact{Revision: "xxx", Digest: "yyy", Size: &aSize}
obj.Status.Artifact = &meta.Artifact{Revision: "xxx", Digest: "yyy", Size: &aSize}
},
wantEvent: "Normal NewArtifact stored fetched index of size",
},
@ -1499,12 +1499,12 @@ func TestHelmRepositoryReconciler_notify(t *testing.T) {
res: sreconcile.ResultSuccess,
resErr: nil,
oldObjBeforeFunc: func(obj *sourcev1.HelmRepository) {
obj.Status.Artifact = &sourcev1.Artifact{Revision: "xxx", Digest: "yyy", Size: &aSize}
obj.Status.Artifact = &meta.Artifact{Revision: "xxx", Digest: "yyy", Size: &aSize}
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, sourcev1.GitOperationFailedReason, "fail")
conditions.MarkFalse(obj, meta.ReadyCondition, meta.FailedReason, "foo")
},
newObjBeforeFunc: func(obj *sourcev1.HelmRepository) {
obj.Status.Artifact = &sourcev1.Artifact{Revision: "xxx", Digest: "yyy", Size: &aSize}
obj.Status.Artifact = &meta.Artifact{Revision: "xxx", Digest: "yyy", Size: &aSize}
conditions.MarkTrue(obj, meta.ReadyCondition, meta.SucceededReason, "ready")
},
wantEvent: "Normal Succeeded stored fetched index of size",
@ -1514,12 +1514,12 @@ func TestHelmRepositoryReconciler_notify(t *testing.T) {
res: sreconcile.ResultSuccess,
resErr: nil,
oldObjBeforeFunc: func(obj *sourcev1.HelmRepository) {
obj.Status.Artifact = &sourcev1.Artifact{Revision: "xxx", Digest: "yyy", Size: &aSize}
obj.Status.Artifact = &meta.Artifact{Revision: "xxx", Digest: "yyy", Size: &aSize}
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, sourcev1.GitOperationFailedReason, "fail")
conditions.MarkFalse(obj, meta.ReadyCondition, meta.FailedReason, "foo")
},
newObjBeforeFunc: func(obj *sourcev1.HelmRepository) {
obj.Status.Artifact = &sourcev1.Artifact{Revision: "aaa", Digest: "bbb", Size: &aSize}
obj.Status.Artifact = &meta.Artifact{Revision: "aaa", Digest: "bbb", Size: &aSize}
conditions.MarkTrue(obj, meta.ReadyCondition, meta.SucceededReason, "ready")
},
wantEvent: "Normal NewArtifact stored fetched index of size",
@ -1529,11 +1529,11 @@ func TestHelmRepositoryReconciler_notify(t *testing.T) {
res: sreconcile.ResultSuccess,
resErr: nil,
oldObjBeforeFunc: func(obj *sourcev1.HelmRepository) {
obj.Status.Artifact = &sourcev1.Artifact{Revision: "xxx", Digest: "yyy", Size: &aSize}
obj.Status.Artifact = &meta.Artifact{Revision: "xxx", Digest: "yyy", Size: &aSize}
conditions.MarkTrue(obj, meta.ReadyCondition, meta.SucceededReason, "ready")
},
newObjBeforeFunc: func(obj *sourcev1.HelmRepository) {
obj.Status.Artifact = &sourcev1.Artifact{Revision: "xxx", Digest: "yyy", Size: &aSize}
obj.Status.Artifact = &meta.Artifact{Revision: "xxx", Digest: "yyy", Size: &aSize}
conditions.MarkTrue(obj, meta.ReadyCondition, meta.SucceededReason, "ready")
},
},

View File

@ -132,7 +132,7 @@ func (e invalidOCIURLError) Error() string {
// ociRepositoryReconcileFunc is the function type for all the v1.OCIRepository
// (sub)reconcile functions. The type implementations are grouped and
// executed serially to perform the complete reconcile of the object.
type ociRepositoryReconcileFunc func(ctx context.Context, sp *patch.SerialPatcher, obj *sourcev1.OCIRepository, metadata *sourcev1.Artifact, dir string) (sreconcile.Result, error)
type ociRepositoryReconcileFunc func(ctx context.Context, sp *patch.SerialPatcher, obj *sourcev1.OCIRepository, metadata *meta.Artifact, dir string) (sreconcile.Result, error)
// OCIRepositoryReconciler reconciles a v1.OCIRepository object
type OCIRepositoryReconciler struct {
@ -301,7 +301,7 @@ func (r *OCIRepositoryReconciler) reconcile(ctx context.Context, sp *patch.Seria
var (
res sreconcile.Result
resErr error
metadata = sourcev1.Artifact{}
metadata = meta.Artifact{}
)
// Run the sub-reconcilers and build the result of reconciliation.
@ -330,7 +330,7 @@ func (r *OCIRepositoryReconciler) reconcile(ctx context.Context, sp *patch.Seria
// reconcileSource fetches the upstream OCI artifact metadata and content.
// If this fails, it records v1.FetchFailedCondition=True on the object and returns early.
func (r *OCIRepositoryReconciler) reconcileSource(ctx context.Context, sp *patch.SerialPatcher,
obj *sourcev1.OCIRepository, metadata *sourcev1.Artifact, dir string) (sreconcile.Result, error) {
obj *sourcev1.OCIRepository, metadata *meta.Artifact, dir string) (sreconcile.Result, error) {
var authenticator authn.Authenticator
ctxTimeout, cancel := context.WithTimeout(ctx, obj.Spec.Timeout.Duration)
@ -455,7 +455,7 @@ func (r *OCIRepositoryReconciler) reconcileSource(ctx context.Context, sp *patch
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, e.Reason, "%s", e)
return sreconcile.ResultEmpty, e
}
metaArtifact := &sourcev1.Artifact{Revision: revision}
metaArtifact := &meta.Artifact{Revision: revision}
metaArtifact.DeepCopyInto(metadata)
// Mark observations about the revision on the object
@ -1024,7 +1024,7 @@ func (r *OCIRepositoryReconciler) getTLSConfig(ctx context.Context, obj *sourcev
// 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 *OCIRepositoryReconciler) reconcileStorage(ctx context.Context, sp *patch.SerialPatcher,
obj *sourcev1.OCIRepository, _ *sourcev1.Artifact, _ string) (sreconcile.Result, error) {
obj *sourcev1.OCIRepository, _ *meta.Artifact, _ string) (sreconcile.Result, error) {
// Garbage collect previous advertised artifact(s) from storage
_ = r.garbageCollect(ctx, obj)
@ -1087,7 +1087,7 @@ func (r *OCIRepositoryReconciler) reconcileStorage(ctx context.Context, sp *patc
// On a successful archive, the Artifact in the Status of the object is set,
// and the symlink in the Storage is updated to its path.
func (r *OCIRepositoryReconciler) reconcileArtifact(ctx context.Context, sp *patch.SerialPatcher,
obj *sourcev1.OCIRepository, metadata *sourcev1.Artifact, dir string) (sreconcile.Result, error) {
obj *sourcev1.OCIRepository, metadata *meta.Artifact, dir string) (sreconcile.Result, error) {
// Create artifact
artifact := r.Storage.NewArtifactFor(obj.Kind, obj, metadata.Revision,
fmt.Sprintf("%s.tar.gz", r.digestFromRevision(metadata.Revision)))

View File

@ -822,7 +822,7 @@ func TestOCIRepository_reconcileSource_authStrategy(t *testing.T) {
sp := patch.NewSerialPatcher(obj, r.Client)
tmpDir := t.TempDir()
got, err := r.reconcileSource(ctx, sp, obj, &sourcev1.Artifact{}, tmpDir)
got, err := r.reconcileSource(ctx, sp, obj, &meta.Artifact{}, tmpDir)
if tt.wantErr {
g.Expect(err).ToNot(BeNil())
} else {
@ -1289,7 +1289,7 @@ func TestOCIRepository_reconcileSource_remoteReference(t *testing.T) {
sp := patch.NewSerialPatcher(obj, r.Client)
artifact := &sourcev1.Artifact{}
artifact := &meta.Artifact{}
tmpDir := t.TempDir()
got, err := r.reconcileSource(ctx, sp, obj, artifact, tmpDir)
if tt.wantErr {
@ -1356,7 +1356,7 @@ func TestOCIRepository_reconcileSource_verifyOCISourceSignatureNotation(t *testi
beforeFunc: func(obj *sourcev1.OCIRepository, tag, revision string) {
conditions.MarkFalse(obj, sourcev1.SourceVerifiedCondition, "VerifyFailed", "fail msg")
obj.Spec.Verify = nil
obj.Status.Artifact = &sourcev1.Artifact{Revision: fmt.Sprintf("%s@%s", tag, revision)}
obj.Status.Artifact = &meta.Artifact{Revision: fmt.Sprintf("%s@%s", tag, revision)}
},
want: sreconcile.ResultSuccess,
},
@ -1365,7 +1365,7 @@ func TestOCIRepository_reconcileSource_verifyOCISourceSignatureNotation(t *testi
reference: &sourcev1.OCIRepositoryRef{Tag: "6.1.4"},
shouldSign: true,
beforeFunc: func(obj *sourcev1.OCIRepository, tag, revision string) {
obj.Status.Artifact = &sourcev1.Artifact{Revision: fmt.Sprintf("%s@%s", tag, revision)}
obj.Status.Artifact = &meta.Artifact{Revision: fmt.Sprintf("%s@%s", tag, revision)}
// Set Verified with old observed generation and different reason/message.
conditions.MarkTrue(obj, sourcev1.SourceVerifiedCondition, "Verified", "verified")
// Set new object generation.
@ -1382,7 +1382,7 @@ func TestOCIRepository_reconcileSource_verifyOCISourceSignatureNotation(t *testi
shouldSign: true,
beforeFunc: func(obj *sourcev1.OCIRepository, tag, revision string) {
// Artifact present and custom verified condition reason/message.
obj.Status.Artifact = &sourcev1.Artifact{Revision: fmt.Sprintf("%s@%s", tag, revision)}
obj.Status.Artifact = &meta.Artifact{Revision: fmt.Sprintf("%s@%s", tag, revision)}
conditions.MarkTrue(obj, sourcev1.SourceVerifiedCondition, "Verified", "verified")
},
want: sreconcile.ResultSuccess,
@ -1630,7 +1630,7 @@ func TestOCIRepository_reconcileSource_verifyOCISourceSignatureNotation(t *testi
sp := patch.NewSerialPatcher(obj, r.Client)
artifact := &sourcev1.Artifact{}
artifact := &meta.Artifact{}
got, err := r.reconcileSource(ctx, sp, obj, artifact, tmpDir)
if tt.wantErr {
tt.wantErrMsg = strings.ReplaceAll(tt.wantErrMsg, "<url>", artifactRef.String())
@ -1969,7 +1969,7 @@ func TestOCIRepository_reconcileSource_verifyOCISourceTrustPolicyNotation(t *tes
sp := patch.NewSerialPatcher(obj, r.Client)
artifact := &sourcev1.Artifact{}
artifact := &meta.Artifact{}
got, err := r.reconcileSource(ctx, sp, obj, artifact, tmpDir)
g.Expect(r.Delete(ctx, secret)).NotTo(HaveOccurred())
if tt.wantErr {
@ -2050,7 +2050,7 @@ func TestOCIRepository_reconcileSource_verifyOCISourceSignatureCosign(t *testing
beforeFunc: func(obj *sourcev1.OCIRepository, tag, revision string) {
conditions.MarkFalse(obj, sourcev1.SourceVerifiedCondition, "VerifyFailed", "fail msg")
obj.Spec.Verify = nil
obj.Status.Artifact = &sourcev1.Artifact{Revision: fmt.Sprintf("%s@%s", tag, revision)}
obj.Status.Artifact = &meta.Artifact{Revision: fmt.Sprintf("%s@%s", tag, revision)}
},
want: sreconcile.ResultSuccess,
},
@ -2059,7 +2059,7 @@ func TestOCIRepository_reconcileSource_verifyOCISourceSignatureCosign(t *testing
reference: &sourcev1.OCIRepositoryRef{Tag: "6.1.4"},
shouldSign: true,
beforeFunc: func(obj *sourcev1.OCIRepository, tag, revision string) {
obj.Status.Artifact = &sourcev1.Artifact{Revision: fmt.Sprintf("%s@%s", tag, revision)}
obj.Status.Artifact = &meta.Artifact{Revision: fmt.Sprintf("%s@%s", tag, revision)}
// Set Verified with old observed generation and different reason/message.
conditions.MarkTrue(obj, sourcev1.SourceVerifiedCondition, "Verified", "verified")
// Set new object generation.
@ -2076,7 +2076,7 @@ func TestOCIRepository_reconcileSource_verifyOCISourceSignatureCosign(t *testing
shouldSign: true,
beforeFunc: func(obj *sourcev1.OCIRepository, tag, revision string) {
// Artifact present and custom verified condition reason/message.
obj.Status.Artifact = &sourcev1.Artifact{Revision: fmt.Sprintf("%s@%s", tag, revision)}
obj.Status.Artifact = &meta.Artifact{Revision: fmt.Sprintf("%s@%s", tag, revision)}
conditions.MarkTrue(obj, sourcev1.SourceVerifiedCondition, "Verified", "verified")
},
want: sreconcile.ResultSuccess,
@ -2241,7 +2241,7 @@ func TestOCIRepository_reconcileSource_verifyOCISourceSignatureCosign(t *testing
sp := patch.NewSerialPatcher(obj, r.Client)
artifact := &sourcev1.Artifact{}
artifact := &meta.Artifact{}
got, err := r.reconcileSource(ctx, sp, obj, artifact, tmpDir)
if tt.wantErr {
tt.wantErrMsg = strings.ReplaceAll(tt.wantErrMsg, "<url>", artifactRef.String())
@ -2416,7 +2416,7 @@ func TestOCIRepository_reconcileSource_verifyOCISourceSignature_keyless(t *testi
sp := patch.NewSerialPatcher(obj, r.Client)
artifact := &sourcev1.Artifact{}
artifact := &meta.Artifact{}
got, err := r.reconcileSource(ctx, sp, obj, artifact, t.TempDir())
if tt.wantErr {
g.Expect(err).To(HaveOccurred())
@ -2452,22 +2452,22 @@ func TestOCIRepository_reconcileSource_noop(t *testing.T) {
tests := []struct {
name string
beforeFunc func(obj *sourcev1.OCIRepository)
afterFunc func(g *WithT, artifact *sourcev1.Artifact)
afterFunc func(g *WithT, artifact *meta.Artifact)
}{
{
name: "full reconcile - no existing artifact",
afterFunc: func(g *WithT, artifact *sourcev1.Artifact) {
afterFunc: func(g *WithT, artifact *meta.Artifact) {
g.Expect(artifact.Metadata).ToNot(BeEmpty())
},
},
{
name: "noop - artifact revisions match",
beforeFunc: func(obj *sourcev1.OCIRepository) {
obj.Status.Artifact = &sourcev1.Artifact{
obj.Status.Artifact = &meta.Artifact{
Revision: testRevision,
}
},
afterFunc: func(g *WithT, artifact *sourcev1.Artifact) {
afterFunc: func(g *WithT, artifact *meta.Artifact) {
g.Expect(artifact.Metadata).To(BeEmpty())
},
},
@ -2475,11 +2475,11 @@ func TestOCIRepository_reconcileSource_noop(t *testing.T) {
name: "full reconcile - same rev, unobserved ignore",
beforeFunc: func(obj *sourcev1.OCIRepository) {
obj.Status.ObservedIgnore = ptr.To("aaa")
obj.Status.Artifact = &sourcev1.Artifact{
obj.Status.Artifact = &meta.Artifact{
Revision: testRevision,
}
},
afterFunc: func(g *WithT, artifact *sourcev1.Artifact) {
afterFunc: func(g *WithT, artifact *meta.Artifact) {
g.Expect(artifact.Metadata).ToNot(BeEmpty())
},
},
@ -2488,11 +2488,11 @@ func TestOCIRepository_reconcileSource_noop(t *testing.T) {
beforeFunc: func(obj *sourcev1.OCIRepository) {
obj.Spec.Ignore = ptr.To("aaa")
obj.Status.ObservedIgnore = ptr.To("aaa")
obj.Status.Artifact = &sourcev1.Artifact{
obj.Status.Artifact = &meta.Artifact{
Revision: testRevision,
}
},
afterFunc: func(g *WithT, artifact *sourcev1.Artifact) {
afterFunc: func(g *WithT, artifact *meta.Artifact) {
g.Expect(artifact.Metadata).To(BeEmpty())
},
},
@ -2503,11 +2503,11 @@ func TestOCIRepository_reconcileSource_noop(t *testing.T) {
MediaType: "application/vnd.docker.image.rootfs.diff.tar.gzip",
Operation: sourcev1.OCILayerCopy,
}
obj.Status.Artifact = &sourcev1.Artifact{
obj.Status.Artifact = &meta.Artifact{
Revision: testRevision,
}
},
afterFunc: func(g *WithT, artifact *sourcev1.Artifact) {
afterFunc: func(g *WithT, artifact *meta.Artifact) {
g.Expect(artifact.Metadata).ToNot(BeEmpty())
},
},
@ -2522,11 +2522,11 @@ func TestOCIRepository_reconcileSource_noop(t *testing.T) {
MediaType: "application/vnd.docker.image.rootfs.diff.tar.gzip",
Operation: sourcev1.OCILayerCopy,
}
obj.Status.Artifact = &sourcev1.Artifact{
obj.Status.Artifact = &meta.Artifact{
Revision: testRevision,
}
},
afterFunc: func(g *WithT, artifact *sourcev1.Artifact) {
afterFunc: func(g *WithT, artifact *meta.Artifact) {
g.Expect(artifact.Metadata).To(BeEmpty())
},
},
@ -2541,11 +2541,11 @@ func TestOCIRepository_reconcileSource_noop(t *testing.T) {
MediaType: "application/vnd.docker.image.rootfs.diff.tar.gzip",
Operation: sourcev1.OCILayerCopy,
}
obj.Status.Artifact = &sourcev1.Artifact{
obj.Status.Artifact = &meta.Artifact{
Revision: testRevision,
}
},
afterFunc: func(g *WithT, artifact *sourcev1.Artifact) {
afterFunc: func(g *WithT, artifact *meta.Artifact) {
g.Expect(artifact.Metadata).ToNot(BeEmpty())
},
},
@ -2591,7 +2591,7 @@ func TestOCIRepository_reconcileSource_noop(t *testing.T) {
sp := patch.NewSerialPatcher(obj, r.Client)
artifact := &sourcev1.Artifact{}
artifact := &meta.Artifact{}
tmpDir := t.TempDir()
got, err := r.reconcileSource(ctx, sp, obj, artifact, tmpDir)
g.Expect(err).ToNot(HaveOccurred())
@ -2608,11 +2608,11 @@ func TestOCIRepository_reconcileArtifact(t *testing.T) {
tests := []struct {
name string
targetPath string
artifact *sourcev1.Artifact
artifact *meta.Artifact
beforeFunc func(obj *sourcev1.OCIRepository)
want sreconcile.Result
wantErr bool
assertArtifact *sourcev1.Artifact
assertArtifact *meta.Artifact
assertPaths []string
assertConditions []metav1.Condition
afterFunc func(g *WithT, obj *sourcev1.OCIRepository)
@ -2620,7 +2620,7 @@ func TestOCIRepository_reconcileArtifact(t *testing.T) {
{
name: "Archiving Artifact creates correct files and condition",
targetPath: "testdata/oci/repository",
artifact: &sourcev1.Artifact{
artifact: &meta.Artifact{
Revision: "revision",
},
beforeFunc: func(obj *sourcev1.OCIRepository) {
@ -2640,7 +2640,7 @@ func TestOCIRepository_reconcileArtifact(t *testing.T) {
{
name: "Artifact with source ignore",
targetPath: "testdata/oci/repository",
artifact: &sourcev1.Artifact{Revision: "revision"},
artifact: &meta.Artifact{Revision: "revision"},
beforeFunc: func(obj *sourcev1.OCIRepository) {
obj.Spec.Ignore = ptr.To("foo.txt")
},
@ -2657,17 +2657,17 @@ func TestOCIRepository_reconcileArtifact(t *testing.T) {
},
{
name: "No status changes if artifact is already present",
artifact: &sourcev1.Artifact{
artifact: &meta.Artifact{
Revision: "revision",
},
targetPath: "testdata/oci/repository",
want: sreconcile.ResultSuccess,
beforeFunc: func(obj *sourcev1.OCIRepository) {
obj.Status.Artifact = &sourcev1.Artifact{
obj.Status.Artifact = &meta.Artifact{
Revision: "revision",
}
},
assertArtifact: &sourcev1.Artifact{
assertArtifact: &meta.Artifact{
Revision: "revision",
},
assertConditions: []metav1.Condition{
@ -2677,11 +2677,11 @@ func TestOCIRepository_reconcileArtifact(t *testing.T) {
{
name: "Artifact already present, unobserved ignore, rebuild artifact",
targetPath: "testdata/oci/repository",
artifact: &sourcev1.Artifact{
artifact: &meta.Artifact{
Revision: "revision",
},
beforeFunc: func(obj *sourcev1.OCIRepository) {
obj.Status.Artifact = &sourcev1.Artifact{Revision: "revision"}
obj.Status.Artifact = &meta.Artifact{Revision: "revision"}
obj.Spec.Ignore = ptr.To("aaa")
},
want: sreconcile.ResultSuccess,
@ -2698,12 +2698,12 @@ func TestOCIRepository_reconcileArtifact(t *testing.T) {
{
name: "Artifact already present, unobserved layer selector, rebuild artifact",
targetPath: "testdata/oci/repository",
artifact: &sourcev1.Artifact{
artifact: &meta.Artifact{
Revision: "revision",
},
beforeFunc: func(obj *sourcev1.OCIRepository) {
obj.Spec.LayerSelector = &sourcev1.OCILayerSelector{MediaType: "foo"}
obj.Status.Artifact = &sourcev1.Artifact{Revision: "revision"}
obj.Status.Artifact = &meta.Artifact{Revision: "revision"}
},
want: sreconcile.ResultSuccess,
assertPaths: []string{
@ -2719,7 +2719,7 @@ func TestOCIRepository_reconcileArtifact(t *testing.T) {
{
name: "Artifact already present, observed layer selector changed, rebuild artifact",
targetPath: "testdata/oci/repository",
artifact: &sourcev1.Artifact{
artifact: &meta.Artifact{
Revision: "revision",
Path: "foo.txt",
},
@ -2728,7 +2728,7 @@ func TestOCIRepository_reconcileArtifact(t *testing.T) {
MediaType: "foo",
Operation: sourcev1.OCILayerCopy,
}
obj.Status.Artifact = &sourcev1.Artifact{Revision: "revision"}
obj.Status.Artifact = &meta.Artifact{Revision: "revision"}
},
want: sreconcile.ResultSuccess,
assertPaths: []string{
@ -2745,18 +2745,18 @@ func TestOCIRepository_reconcileArtifact(t *testing.T) {
{
name: "Artifact already present, observed ignore and layer selector, up-to-date",
targetPath: "testdata/oci/repository",
artifact: &sourcev1.Artifact{
artifact: &meta.Artifact{
Revision: "revision",
},
beforeFunc: func(obj *sourcev1.OCIRepository) {
obj.Spec.Ignore = ptr.To("aaa")
obj.Spec.LayerSelector = &sourcev1.OCILayerSelector{MediaType: "foo"}
obj.Status.Artifact = &sourcev1.Artifact{Revision: "revision"}
obj.Status.Artifact = &meta.Artifact{Revision: "revision"}
obj.Status.ObservedIgnore = ptr.To("aaa")
obj.Status.ObservedLayerSelector = &sourcev1.OCILayerSelector{MediaType: "foo"}
},
want: sreconcile.ResultSuccess,
assertArtifact: &sourcev1.Artifact{
assertArtifact: &meta.Artifact{
Revision: "revision",
},
assertConditions: []metav1.Condition{
@ -2810,7 +2810,7 @@ func TestOCIRepository_reconcileArtifact(t *testing.T) {
tt.beforeFunc(obj)
}
artifact := &sourcev1.Artifact{}
artifact := &meta.Artifact{}
if tt.artifact != nil {
artifact = tt.artifact
}
@ -3089,7 +3089,7 @@ func TestOCIRepository_reconcileStorage(t *testing.T) {
want sreconcile.Result
wantErr bool
assertConditions []metav1.Condition
assertArtifact *sourcev1.Artifact
assertArtifact *meta.Artifact
assertPaths []string
}{
{
@ -3099,7 +3099,7 @@ func TestOCIRepository_reconcileStorage(t *testing.T) {
for n := range revisions {
v := revisions[n]
obj.Status.Artifact = &sourcev1.Artifact{
obj.Status.Artifact = &meta.Artifact{
Path: fmt.Sprintf("/oci-reconcile-storage/%s.txt", v),
Revision: v,
}
@ -3120,7 +3120,7 @@ func TestOCIRepository_reconcileStorage(t *testing.T) {
conditions.MarkTrue(obj, meta.ReadyCondition, "foo", "bar")
return nil
},
assertArtifact: &sourcev1.Artifact{
assertArtifact: &meta.Artifact{
Path: "/oci-reconcile-storage/d.txt",
Revision: "d",
Digest: "sha256:18ac3e7343f016890c510e93f935261169d9e3f565436429830faf0934f4f8e4",
@ -3149,7 +3149,7 @@ func TestOCIRepository_reconcileStorage(t *testing.T) {
{
name: "notices missing artifact in storage",
beforeFunc: func(obj *sourcev1.OCIRepository, storage *storage.Storage) error {
obj.Status.Artifact = &sourcev1.Artifact{
obj.Status.Artifact = &meta.Artifact{
Path: "/oci-reconcile-storage/invalid.txt",
Revision: "e",
}
@ -3170,7 +3170,7 @@ func TestOCIRepository_reconcileStorage(t *testing.T) {
beforeFunc: func(obj *sourcev1.OCIRepository, storage *storage.Storage) error {
f := "empty-digest.txt"
obj.Status.Artifact = &sourcev1.Artifact{
obj.Status.Artifact = &meta.Artifact{
Path: fmt.Sprintf("/oci-reconcile-storage/%s.txt", f),
Revision: "fake",
}
@ -3201,7 +3201,7 @@ func TestOCIRepository_reconcileStorage(t *testing.T) {
beforeFunc: func(obj *sourcev1.OCIRepository, storage *storage.Storage) error {
f := "digest-mismatch.txt"
obj.Status.Artifact = &sourcev1.Artifact{
obj.Status.Artifact = &meta.Artifact{
Path: fmt.Sprintf("/oci-reconcile-storage/%s.txt", f),
Revision: "fake",
}
@ -3230,7 +3230,7 @@ func TestOCIRepository_reconcileStorage(t *testing.T) {
{
name: "updates hostname on diff from current",
beforeFunc: func(obj *sourcev1.OCIRepository, storage *storage.Storage) error {
obj.Status.Artifact = &sourcev1.Artifact{
obj.Status.Artifact = &meta.Artifact{
Path: "/oci-reconcile-storage/hostname.txt",
Revision: "f",
Digest: "sha256:3b9c358f36f0a31b6ad3e14f309c7cf198ac9246e8316f9ce543d5b19ac02b80",
@ -3249,7 +3249,7 @@ func TestOCIRepository_reconcileStorage(t *testing.T) {
assertPaths: []string{
"/oci-reconcile-storage/hostname.txt",
},
assertArtifact: &sourcev1.Artifact{
assertArtifact: &meta.Artifact{
Path: "/oci-reconcile-storage/hostname.txt",
Revision: "f",
Digest: "sha256:3b9c358f36f0a31b6ad3e14f309c7cf198ac9246e8316f9ce543d5b19ac02b80",
@ -3295,7 +3295,7 @@ func TestOCIRepository_reconcileStorage(t *testing.T) {
sp := patch.NewSerialPatcher(obj, r.Client)
got, err := r.reconcileStorage(ctx, sp, obj, &sourcev1.Artifact{}, "")
got, err := r.reconcileStorage(ctx, sp, obj, &meta.Artifact{}, "")
if tt.wantErr {
g.Expect(err).To(HaveOccurred())
} else {
@ -3382,7 +3382,7 @@ func TestOCIRepositoryReconciler_notify(t *testing.T) {
resErr: nil,
newObjBeforeFunc: func(obj *sourcev1.OCIRepository) {
obj.Spec.URL = "oci://newurl.io"
obj.Status.Artifact = &sourcev1.Artifact{
obj.Status.Artifact = &meta.Artifact{
Revision: "xxx",
Digest: "yyy",
Metadata: map[string]string{
@ -3398,13 +3398,13 @@ func TestOCIRepositoryReconciler_notify(t *testing.T) {
res: sreconcile.ResultSuccess,
resErr: nil,
oldObjBeforeFunc: func(obj *sourcev1.OCIRepository) {
obj.Status.Artifact = &sourcev1.Artifact{Revision: "xxx", Digest: "yyy"}
obj.Status.Artifact = &meta.Artifact{Revision: "xxx", Digest: "yyy"}
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, sourcev1.ReadOperationFailedReason, "fail")
conditions.MarkFalse(obj, meta.ReadyCondition, meta.FailedReason, "foo")
},
newObjBeforeFunc: func(obj *sourcev1.OCIRepository) {
obj.Spec.URL = "oci://newurl.io"
obj.Status.Artifact = &sourcev1.Artifact{Revision: "xxx", Digest: "yyy"}
obj.Status.Artifact = &meta.Artifact{Revision: "xxx", Digest: "yyy"}
conditions.MarkTrue(obj, meta.ReadyCondition, meta.SucceededReason, "ready")
},
wantEvent: "Normal Succeeded stored artifact with revision 'xxx' from 'oci://newurl.io'",
@ -3414,13 +3414,13 @@ func TestOCIRepositoryReconciler_notify(t *testing.T) {
res: sreconcile.ResultSuccess,
resErr: nil,
oldObjBeforeFunc: func(obj *sourcev1.OCIRepository) {
obj.Status.Artifact = &sourcev1.Artifact{Revision: "xxx", Digest: "yyy"}
obj.Status.Artifact = &meta.Artifact{Revision: "xxx", Digest: "yyy"}
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, sourcev1.ReadOperationFailedReason, "fail")
conditions.MarkFalse(obj, meta.ReadyCondition, meta.FailedReason, "foo")
},
newObjBeforeFunc: func(obj *sourcev1.OCIRepository) {
obj.Spec.URL = "oci://newurl.io"
obj.Status.Artifact = &sourcev1.Artifact{Revision: "aaa", Digest: "bbb"}
obj.Status.Artifact = &meta.Artifact{Revision: "aaa", Digest: "bbb"}
conditions.MarkTrue(obj, meta.ReadyCondition, meta.SucceededReason, "ready")
},
wantEvent: "Normal NewArtifact stored artifact with revision 'aaa' from 'oci://newurl.io'",
@ -3430,11 +3430,11 @@ func TestOCIRepositoryReconciler_notify(t *testing.T) {
res: sreconcile.ResultSuccess,
resErr: nil,
oldObjBeforeFunc: func(obj *sourcev1.OCIRepository) {
obj.Status.Artifact = &sourcev1.Artifact{Revision: "xxx", Digest: "yyy"}
obj.Status.Artifact = &meta.Artifact{Revision: "xxx", Digest: "yyy"}
conditions.MarkTrue(obj, meta.ReadyCondition, meta.SucceededReason, "ready")
},
newObjBeforeFunc: func(obj *sourcev1.OCIRepository) {
obj.Status.Artifact = &sourcev1.Artifact{Revision: "xxx", Digest: "yyy"}
obj.Status.Artifact = &meta.Artifact{Revision: "xxx", Digest: "yyy"}
conditions.MarkTrue(obj, meta.ReadyCondition, meta.SucceededReason, "ready")
},
},
@ -3443,7 +3443,7 @@ func TestOCIRepositoryReconciler_notify(t *testing.T) {
res: sreconcile.ResultRequeue,
resErr: nil,
oldObjBeforeFunc: func(obj *sourcev1.OCIRepository) {
obj.Status.Artifact = &sourcev1.Artifact{Revision: "xxx", Digest: "yyy"}
obj.Status.Artifact = &meta.Artifact{Revision: "xxx", Digest: "yyy"}
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, sourcev1.URLInvalidReason, "ready")
},
},

View File

@ -24,7 +24,7 @@ import (
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime"
sourcev1 "github.com/fluxcd/source-controller/api/v1"
"github.com/fluxcd/pkg/apis/meta"
)
var (
@ -148,7 +148,7 @@ func SetSuspend(obj runtime.Object, val bool) error {
}
// GetArtifact returns the status.artifact of a given runtime object.
func GetArtifact(obj runtime.Object) (*sourcev1.Artifact, error) {
func GetArtifact(obj runtime.Object) (*meta.Artifact, error) {
u, err := toUnstructured(obj)
if err != nil {
return nil, err
@ -165,7 +165,7 @@ func GetArtifact(obj runtime.Object) (*sourcev1.Artifact, error) {
if err != nil {
return nil, err
}
outArtifact := &sourcev1.Artifact{}
outArtifact := &meta.Artifact{}
if err := json.Unmarshal(enc, outArtifact); err != nil {
return nil, err
}

View File

@ -24,6 +24,8 @@ import (
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"github.com/fluxcd/pkg/apis/meta"
sourcev1 "github.com/fluxcd/source-controller/api/v1"
)
@ -127,7 +129,7 @@ func TestGetArtifact(t *testing.T) {
g.Expect(artifact).To(BeNil())
// Get set artifact value.
obj.Status.Artifact = &sourcev1.Artifact{Path: "aaa", Revision: "zzz"}
obj.Status.Artifact = &meta.Artifact{Path: "aaa", Revision: "zzz"}
artifact, err = GetArtifact(obj)
g.Expect(err).ToNot(HaveOccurred())
g.Expect(artifact).ToNot(BeNil())

View File

@ -160,7 +160,7 @@ func TestHelmRepositoryOCIMigrationPredicate_Update(t *testing.T) {
Type: sourcev1.HelmRepositoryTypeDefault,
}
oldObj.Status = sourcev1.HelmRepositoryStatus{
Artifact: &sourcev1.Artifact{},
Artifact: &meta.Artifact{},
URL: "http://some-address",
ObservedGeneration: 3,
}

View File

@ -25,12 +25,14 @@ import (
"io/fs"
"net/url"
"os"
"path"
"path/filepath"
"sort"
"strings"
"time"
securejoin "github.com/cyphar/filepath-securejoin"
"github.com/fluxcd/pkg/apis/meta"
"github.com/go-git/go-git/v5/plumbing/format/gitignore"
"github.com/opencontainers/go-digest"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@ -41,7 +43,6 @@ import (
"github.com/fluxcd/pkg/sourceignore"
pkgtar "github.com/fluxcd/pkg/tar"
v1 "github.com/fluxcd/source-controller/api/v1"
intdigest "github.com/fluxcd/source-controller/internal/digest"
)
@ -86,10 +87,10 @@ func New(basePath string, hostname string, artifactRetentionTTL time.Duration, a
}, nil
}
// NewArtifactFor returns a new v1.Artifact.
func (s Storage) NewArtifactFor(kind string, metadata metav1.Object, revision, fileName string) v1.Artifact {
path := v1.ArtifactPath(kind, metadata.GetNamespace(), metadata.GetName(), fileName)
artifact := v1.Artifact{
// NewArtifactFor returns a new meta.Artifact.
func (s Storage) NewArtifactFor(kind string, metadata metav1.Object, revision, fileName string) meta.Artifact {
path := ArtifactPath(kind, metadata.GetNamespace(), metadata.GetName(), fileName)
artifact := meta.Artifact{
Path: path,
Revision: revision,
}
@ -97,8 +98,8 @@ func (s Storage) NewArtifactFor(kind string, metadata metav1.Object, revision, f
return artifact
}
// SetArtifactURL sets the URL on the given v1.Artifact.
func (s Storage) SetArtifactURL(artifact *v1.Artifact) {
// SetArtifactURL sets the URL on the given meta.Artifact.
func (s Storage) SetArtifactURL(artifact *meta.Artifact) {
if artifact.Path == "" {
return
}
@ -119,19 +120,19 @@ func (s Storage) SetHostname(URL string) string {
return u.String()
}
// MkdirAll calls os.MkdirAll for the given v1.Artifact base dir.
func (s Storage) MkdirAll(artifact v1.Artifact) error {
// MkdirAll calls os.MkdirAll for the given meta.Artifact base dir.
func (s Storage) MkdirAll(artifact meta.Artifact) error {
dir := filepath.Dir(s.LocalPath(artifact))
return os.MkdirAll(dir, 0o700)
}
// Remove calls os.Remove for the given v1.Artifact path.
func (s Storage) Remove(artifact v1.Artifact) error {
// Remove calls os.Remove for the given meta.Artifact path.
func (s Storage) Remove(artifact meta.Artifact) error {
return os.Remove(s.LocalPath(artifact))
}
// RemoveAll calls os.RemoveAll for the given v1.Artifact base dir.
func (s Storage) RemoveAll(artifact v1.Artifact) (string, error) {
// RemoveAll calls os.RemoveAll for the given meta.Artifact base dir.
func (s Storage) RemoveAll(artifact meta.Artifact) (string, error) {
var deletedDir string
dir := filepath.Dir(s.LocalPath(artifact))
// Check if the dir exists.
@ -142,8 +143,8 @@ func (s Storage) RemoveAll(artifact v1.Artifact) (string, error) {
return deletedDir, os.RemoveAll(dir)
}
// RemoveAllButCurrent removes all files for the given v1.Artifact base dir, excluding the current one.
func (s Storage) RemoveAllButCurrent(artifact v1.Artifact) ([]string, error) {
// RemoveAllButCurrent removes all files for the given meta.Artifact base dir, excluding the current one.
func (s Storage) RemoveAllButCurrent(artifact meta.Artifact) ([]string, error) {
deletedFiles := []string{}
localPath := s.LocalPath(artifact)
dir := filepath.Dir(localPath)
@ -176,7 +177,7 @@ func (s Storage) RemoveAllButCurrent(artifact v1.Artifact) ([]string, error) {
// 1. collect all artifact files with an expired ttl
// 2. if we satisfy maxItemsToBeRetained, then return
// 3. else, collect all artifact files till the latest n files remain, where n=maxItemsToBeRetained
func (s Storage) getGarbageFiles(artifact v1.Artifact, totalCountLimit, maxItemsToBeRetained int, ttl time.Duration) (garbageFiles []string, _ error) {
func (s Storage) getGarbageFiles(artifact meta.Artifact, totalCountLimit, maxItemsToBeRetained int, ttl time.Duration) (garbageFiles []string, _ error) {
localPath := s.LocalPath(artifact)
dir := filepath.Dir(localPath)
artifactFilesWithCreatedTs := make(map[time.Time]string)
@ -263,7 +264,7 @@ func (s Storage) getGarbageFiles(artifact v1.Artifact, totalCountLimit, maxItems
// GarbageCollect removes all garbage files in the artifact dir according to the provided
// retention options.
func (s Storage) GarbageCollect(ctx context.Context, artifact v1.Artifact, timeout time.Duration) ([]string, error) {
func (s Storage) GarbageCollect(ctx context.Context, artifact meta.Artifact, timeout time.Duration) ([]string, error) {
delFilesChan := make(chan []string)
errChan := make(chan error)
// Abort if it takes more than the provided timeout duration.
@ -324,8 +325,8 @@ func stringInSlice(a string, list []string) bool {
return false
}
// ArtifactExist returns a boolean indicating whether the v1.Artifact exists in storage and is a regular file.
func (s Storage) ArtifactExist(artifact v1.Artifact) bool {
// ArtifactExist returns a boolean indicating whether the meta.Artifact exists in storage and is a regular file.
func (s Storage) ArtifactExist(artifact meta.Artifact) bool {
fi, err := os.Lstat(s.LocalPath(artifact))
if err != nil {
return false
@ -333,10 +334,10 @@ func (s Storage) ArtifactExist(artifact v1.Artifact) bool {
return fi.Mode().IsRegular()
}
// VerifyArtifact verifies if the Digest of the v1.Artifact matches the digest
// VerifyArtifact verifies if the Digest of the meta.Artifact matches the digest
// of the file in Storage. It returns an error if the digests don't match, or
// if it can't be verified.
func (s Storage) VerifyArtifact(artifact v1.Artifact) error {
func (s Storage) VerifyArtifact(artifact meta.Artifact) error {
if artifact.Digest == "" {
return fmt.Errorf("artifact has no digest")
}
@ -380,11 +381,11 @@ func SourceIgnoreFilter(ps []gitignore.Pattern, domain []string) ArchiveFileFilt
}
}
// Archive atomically archives the given directory as a tarball to the given v1.Artifact path, excluding
// Archive atomically archives the given directory as a tarball to the given meta.Artifact path, excluding
// directories and any ArchiveFileFilter matches. While archiving, any environment specific data (for example,
// the user and group name) is stripped from file headers.
// If successful, it sets the digest and last update time on the artifact.
func (s Storage) Archive(artifact *v1.Artifact, dir string, filter ArchiveFileFilter) (err error) {
func (s Storage) Archive(artifact *meta.Artifact, dir string, filter ArchiveFileFilter) (err error) {
if f, err := os.Stat(dir); os.IsNotExist(err) || !f.IsDir() {
return fmt.Errorf("invalid dir path: %s", dir)
}
@ -491,9 +492,9 @@ func (s Storage) Archive(artifact *v1.Artifact, dir string, filter ArchiveFileFi
return nil
}
// AtomicWriteFile atomically writes the io.Reader contents to the v1.Artifact path.
// AtomicWriteFile atomically writes the io.Reader contents to the meta.Artifact path.
// If successful, it sets the digest and last update time on the artifact.
func (s Storage) AtomicWriteFile(artifact *v1.Artifact, reader io.Reader, mode os.FileMode) (err error) {
func (s Storage) AtomicWriteFile(artifact *meta.Artifact, reader io.Reader, mode os.FileMode) (err error) {
localPath := s.LocalPath(*artifact)
tf, err := os.CreateTemp(filepath.Split(localPath))
if err != nil {
@ -533,9 +534,9 @@ func (s Storage) AtomicWriteFile(artifact *v1.Artifact, reader io.Reader, mode o
return nil
}
// Copy atomically copies the io.Reader contents to the v1.Artifact path.
// Copy atomically copies the io.Reader contents to the meta.Artifact path.
// If successful, it sets the digest and last update time on the artifact.
func (s Storage) Copy(artifact *v1.Artifact, reader io.Reader) (err error) {
func (s Storage) Copy(artifact *meta.Artifact, reader io.Reader) (err error) {
localPath := s.LocalPath(*artifact)
tf, err := os.CreateTemp(filepath.Split(localPath))
if err != nil {
@ -571,9 +572,9 @@ func (s Storage) Copy(artifact *v1.Artifact, reader io.Reader) (err error) {
return nil
}
// CopyFromPath atomically copies the contents of the given path to the path of the v1.Artifact.
// CopyFromPath atomically copies the contents of the given path to the path of the meta.Artifact.
// If successful, the digest and last update time on the artifact is set.
func (s Storage) CopyFromPath(artifact *v1.Artifact, path string) (err error) {
func (s Storage) CopyFromPath(artifact *meta.Artifact, path string) (err error) {
f, err := os.Open(path)
if err != nil {
return err
@ -588,7 +589,7 @@ func (s Storage) CopyFromPath(artifact *v1.Artifact, path string) (err error) {
}
// CopyToPath copies the contents in the (sub)path of the given artifact to the given path.
func (s Storage) CopyToPath(artifact *v1.Artifact, subPath, toPath string) error {
func (s Storage) CopyToPath(artifact *meta.Artifact, subPath, toPath string) error {
// create a tmp directory to store artifact
tmp, err := os.MkdirTemp("", "flux-include-")
if err != nil {
@ -626,8 +627,8 @@ func (s Storage) CopyToPath(artifact *v1.Artifact, subPath, toPath string) error
return nil
}
// Symlink creates or updates a symbolic link for the given v1.Artifact and returns the URL for the symlink.
func (s Storage) Symlink(artifact v1.Artifact, linkName string) (string, error) {
// Symlink creates or updates a symbolic link for the given meta.Artifact and returns the URL for the symlink.
func (s Storage) Symlink(artifact meta.Artifact, linkName string) (string, error) {
localPath := s.LocalPath(artifact)
dir := filepath.Dir(localPath)
link := filepath.Join(dir, linkName)
@ -648,15 +649,15 @@ func (s Storage) Symlink(artifact v1.Artifact, linkName string) (string, error)
return fmt.Sprintf("http://%s/%s", s.Hostname, filepath.Join(filepath.Dir(artifact.Path), linkName)), nil
}
// Lock creates a file lock for the given v1.Artifact.
func (s Storage) Lock(artifact v1.Artifact) (unlock func(), err error) {
// Lock creates a file lock for the given meta.Artifact.
func (s Storage) Lock(artifact meta.Artifact) (unlock func(), err error) {
lockFile := s.LocalPath(artifact) + ".lock"
mutex := lockedfile.MutexAt(lockFile)
return mutex.Lock()
}
// LocalPath returns the secure local path of the given artifact (that is: relative to the Storage.BasePath).
func (s Storage) LocalPath(artifact v1.Artifact) string {
func (s Storage) LocalPath(artifact meta.Artifact) string {
if artifact.Path == "" {
return ""
}
@ -717,3 +718,16 @@ func setDefaultMode(h *tar.Header) {
return
}
}
// ArtifactDir returns the artifact dir path in the form of
// '<kind>/<namespace>/<name>'.
func ArtifactDir(kind, namespace, name string) string {
kind = strings.ToLower(kind)
return path.Join(kind, namespace, name)
}
// ArtifactPath returns the artifact path in the form of
// '<kind>/<namespace>/name>/<filename>'.
func ArtifactPath(kind, namespace, name, filename string) string {
return path.Join(ArtifactDir(kind, namespace, name), filename)
}

View File

@ -34,7 +34,7 @@ import (
"github.com/go-git/go-git/v5/plumbing/format/gitignore"
. "github.com/onsi/gomega"
sourcev1 "github.com/fluxcd/source-controller/api/v1"
"github.com/fluxcd/pkg/apis/meta"
)
func TestStorageConstructor(t *testing.T) {
@ -141,7 +141,7 @@ func TestStorage_Archive(t *testing.T) {
return
}
matchFiles := func(t *testing.T, storage *Storage, artifact sourcev1.Artifact, files map[string]dummyFile, dirs []string) {
matchFiles := func(t *testing.T, storage *Storage, artifact meta.Artifact, files map[string]dummyFile, dirs []string) {
t.Helper()
for name, df := range files {
mustExist := !(name[0:1] == "!")
@ -289,7 +289,7 @@ func TestStorage_Archive(t *testing.T) {
return
}
defer os.RemoveAll(dir)
artifact := sourcev1.Artifact{
artifact := meta.Artifact{
Path: filepath.Join(randStringRunes(10), randStringRunes(10), randStringRunes(10)+".tar.gz"),
}
if err := storage.MkdirAll(artifact); err != nil {
@ -312,7 +312,7 @@ func TestStorage_Remove(t *testing.T) {
s, err := New(dir, "", 0, 0)
g.Expect(err).ToNot(HaveOccurred())
artifact := sourcev1.Artifact{
artifact := meta.Artifact{
Path: filepath.Join(dir, "test.txt"),
}
g.Expect(s.MkdirAll(artifact)).To(Succeed())
@ -331,7 +331,7 @@ func TestStorage_Remove(t *testing.T) {
s, err := New(dir, "", 0, 0)
g.Expect(err).ToNot(HaveOccurred())
artifact := sourcev1.Artifact{
artifact := meta.Artifact{
Path: filepath.Join(dir, "test.txt"),
}
@ -350,7 +350,7 @@ func TestStorageRemoveAllButCurrent(t *testing.T) {
t.Fatalf("Valid path did not successfully return: %v", err)
}
if _, err := s.RemoveAllButCurrent(sourcev1.Artifact{Path: filepath.Join(dir, "really", "nonexistent")}); err == nil {
if _, err := s.RemoveAllButCurrent(meta.Artifact{Path: filepath.Join(dir, "really", "nonexistent")}); err == nil {
t.Fatal("Did not error while pruning non-existent path")
}
})
@ -362,7 +362,7 @@ func TestStorageRemoveAllButCurrent(t *testing.T) {
s, err := New(dir, "hostname", time.Minute, 2)
g.Expect(err).ToNot(HaveOccurred(), "failed to create new storage")
artifact := sourcev1.Artifact{
artifact := meta.Artifact{
Path: filepath.Join("foo", "bar", "artifact1.tar.gz"),
}
@ -423,7 +423,7 @@ func TestStorageRemoveAll(t *testing.T) {
s, err := New(dir, "hostname", time.Minute, 2)
g.Expect(err).ToNot(HaveOccurred(), "failed to create new storage")
artifact := sourcev1.Artifact{
artifact := meta.Artifact{
Path: tt.artifactPath,
}
@ -469,7 +469,7 @@ func TestStorageCopyFromPath(t *testing.T) {
return
}
matchFile := func(t *testing.T, storage *Storage, artifact sourcev1.Artifact, file *File, expectMismatch bool) {
matchFile := func(t *testing.T, storage *Storage, artifact meta.Artifact, file *File, expectMismatch bool) {
c, err := os.ReadFile(storage.LocalPath(artifact))
if err != nil {
t.Fatalf("failed reading file: %v", err)
@ -516,7 +516,7 @@ func TestStorageCopyFromPath(t *testing.T) {
t.Error(err)
return
}
artifact := sourcev1.Artifact{
artifact := meta.Artifact{
Path: filepath.Join(randStringRunes(10), randStringRunes(10), randStringRunes(10)),
}
if err := storage.MkdirAll(artifact); err != nil {
@ -669,7 +669,7 @@ func TestStorage_getGarbageFiles(t *testing.T) {
s, err := New(dir, "hostname", tt.ttl, tt.maxItemsToBeRetained)
g.Expect(err).ToNot(HaveOccurred(), "failed to create new storage")
artifact := sourcev1.Artifact{
artifact := meta.Artifact{
Path: tt.artifactPaths[len(tt.artifactPaths)-1],
}
g.Expect(os.MkdirAll(filepath.Join(dir, artifactFolder), 0o750)).ToNot(HaveOccurred())
@ -752,7 +752,7 @@ func TestStorage_GarbageCollect(t *testing.T) {
s, err := New(dir, "hostname", time.Second*2, 2)
g.Expect(err).ToNot(HaveOccurred(), "failed to create new storage")
artifact := sourcev1.Artifact{
artifact := meta.Artifact{
Path: tt.artifactPaths[len(tt.artifactPaths)-1],
}
g.Expect(os.MkdirAll(filepath.Join(dir, artifactFolder), 0o750)).ToNot(HaveOccurred())
@ -807,7 +807,7 @@ func TestStorage_VerifyArtifact(t *testing.T) {
t.Run("artifact without digest", func(t *testing.T) {
g := NewWithT(t)
err := s.VerifyArtifact(sourcev1.Artifact{})
err := s.VerifyArtifact(meta.Artifact{})
g.Expect(err).To(HaveOccurred())
g.Expect(err).To(MatchError("artifact has no digest"))
})
@ -815,7 +815,7 @@ func TestStorage_VerifyArtifact(t *testing.T) {
t.Run("artifact with invalid digest", func(t *testing.T) {
g := NewWithT(t)
err := s.VerifyArtifact(sourcev1.Artifact{Digest: "invalid"})
err := s.VerifyArtifact(meta.Artifact{Digest: "invalid"})
g.Expect(err).To(HaveOccurred())
g.Expect(err).To(MatchError("failed to parse artifact digest 'invalid': invalid checksum digest format"))
})
@ -823,7 +823,7 @@ func TestStorage_VerifyArtifact(t *testing.T) {
t.Run("artifact with invalid path", func(t *testing.T) {
g := NewWithT(t)
err := s.VerifyArtifact(sourcev1.Artifact{
err := s.VerifyArtifact(meta.Artifact{
Digest: "sha256:9ba7a35ce8acd3557fe30680ef193ca7a36bb5dc62788f30de7122a0a5beab69",
Path: "invalid",
})
@ -834,7 +834,7 @@ func TestStorage_VerifyArtifact(t *testing.T) {
t.Run("artifact with digest mismatch", func(t *testing.T) {
g := NewWithT(t)
err := s.VerifyArtifact(sourcev1.Artifact{
err := s.VerifyArtifact(meta.Artifact{
Digest: "sha256:9ba7a35ce8acd3557fe30680ef193ca7a36bb5dc62788f30de7122a0a5beab69",
Path: "artifact",
})
@ -845,7 +845,7 @@ func TestStorage_VerifyArtifact(t *testing.T) {
t.Run("artifact with digest match", func(t *testing.T) {
g := NewWithT(t)
err := s.VerifyArtifact(sourcev1.Artifact{
err := s.VerifyArtifact(meta.Artifact{
Digest: "sha256:9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08",
Path: "artifact",
})