Mark resource as stalled on invalid URL

Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
This commit is contained in:
Stefan Prodan 2022-08-04 15:59:46 +03:00
parent 63c94397f7
commit c52576c151
No known key found for this signature in database
GPG Key ID: 3299AEB0E4085BAF
2 changed files with 62 additions and 4 deletions

View File

@ -102,6 +102,14 @@ var ociRepositoryFailConditions = []string{
sourcev1.StorageOperationFailedCondition,
}
type invalidOCIURLError struct {
err error
}
func (e invalidOCIURLError) Error() string {
return e.err.Error()
}
// ociRepositoryReconcileFunc is the function type for all the v1beta2.OCIRepository
// (sub)reconcile functions. The type implementations are grouped and
// executed serially to perform the complete reconcile of the object.
@ -337,9 +345,17 @@ func (r *OCIRepositoryReconciler) reconcileSource(ctx context.Context, obj *sour
// Determine which artifact revision to pull
url, err := r.getArtifactURL(obj, options)
if err != nil {
if _, ok := err.(invalidOCIURLError); ok {
e := serror.NewStalling(
fmt.Errorf("failed to determine the artifact address for '%s': %w", obj.Spec.URL, err),
sourcev1.URLInvalidReason)
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, e.Reason, e.Err.Error())
return sreconcile.ResultEmpty, e
}
e := serror.NewGeneric(
fmt.Errorf("failed to determine the artifact address for '%s': %w", obj.Spec.URL, err),
sourcev1.URLInvalidReason)
fmt.Errorf("failed to determine the artifact tag for '%s': %w", obj.Spec.URL, err),
sourcev1.OCIOperationFailedReason)
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, e.Reason, e.Err.Error())
return sreconcile.ResultEmpty, e
}
@ -464,7 +480,7 @@ func (r *OCIRepositoryReconciler) parseRepositoryURL(obj *sourcev1.OCIRepository
func (r *OCIRepositoryReconciler) getArtifactURL(obj *sourcev1.OCIRepository, options []crane.Option) (string, error) {
url, err := r.parseRepositoryURL(obj)
if err != nil {
return "", err
return "", invalidOCIURLError{err}
}
if obj.Spec.Reference != nil {

View File

@ -772,7 +772,7 @@ func TestOCIRepository_reconcileSource_remoteReference(t *testing.T) {
want: sreconcile.ResultEmpty,
wantErr: true,
assertConditions: []metav1.Condition{
*conditions.TrueCondition(sourcev1.FetchFailedCondition, sourcev1.URLInvalidReason, "no match found for semver:"),
*conditions.TrueCondition(sourcev1.FetchFailedCondition, sourcev1.OCIOperationFailedReason, "failed to determine the artifact tag for 'oci://%s/podinfo': no match found for semver: <= 6.1.0", server.registryHost),
},
},
{
@ -1064,6 +1064,48 @@ func TestOCIRepository_getArtifactURL(t *testing.T) {
}
}
func TestOCIRepository_stalled(t *testing.T) {
g := NewWithT(t)
ns, err := testEnv.CreateNamespace(ctx, "ocirepository-stalled-test")
g.Expect(err).ToNot(HaveOccurred())
defer func() { g.Expect(testEnv.Delete(ctx, ns)).To(Succeed()) }()
obj := &sourcev1.OCIRepository{
ObjectMeta: metav1.ObjectMeta{
GenerateName: "ocirepository-reconcile",
Namespace: ns.Name,
},
Spec: sourcev1.OCIRepositorySpec{
URL: "oci://ghcr.io/test/test:v1",
Interval: metav1.Duration{Duration: 60 * time.Minute},
},
}
g.Expect(testEnv.Create(ctx, obj)).To(Succeed())
key := client.ObjectKey{Name: obj.Name, Namespace: obj.Namespace}
resultobj := sourcev1.OCIRepository{}
// Wait for the object to fail
g.Eventually(func() bool {
if err := testEnv.Get(ctx, key, &resultobj); err != nil {
return false
}
readyCondition := conditions.Get(&resultobj, meta.ReadyCondition)
if readyCondition == nil {
return false
}
return obj.Generation == readyCondition.ObservedGeneration &&
!conditions.IsReady(&resultobj)
}, timeout).Should(BeTrue())
// Verify that stalled condition is present in status
stalledCondition := conditions.Get(&resultobj, meta.StalledCondition)
g.Expect(stalledCondition).ToNot(BeNil())
g.Expect(stalledCondition.Reason).Should(Equal(sourcev1.URLInvalidReason))
}
func TestOCIRepository_reconcileStorage(t *testing.T) {
g := NewWithT(t)