Skip to content

Commit 5a01112

Browse files
authored
Merge pull request #1021 from fluxcd/handle-empty-git-repository
Prevent panic when cloning empty git repository
2 parents ae3a81e + 14a4a5e commit 5a01112

File tree

2 files changed

+58
-0
lines changed

2 files changed

+58
-0
lines changed

controllers/gitrepository_controller.go

+8
Original file line numberDiff line numberDiff line change
@@ -537,6 +537,14 @@ func (r *GitRepositoryReconciler) reconcileSource(ctx context.Context, sp *patch
537537
if err != nil {
538538
return sreconcile.ResultEmpty, err
539539
}
540+
if c == nil {
541+
e := serror.NewGeneric(
542+
fmt.Errorf("git repository is empty"),
543+
"EmptyGitRepository",
544+
)
545+
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, e.Reason, e.Err.Error())
546+
return sreconcile.ResultEmpty, e
547+
}
540548
// Assign the commit to the shared commit reference.
541549
*commit = *c
542550

controllers/gitrepository_controller_test.go

+50
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,56 @@ func TestGitRepositoryReconciler_Reconcile(t *testing.T) {
220220
testSuspendedObjectDeleteWithArtifact(ctx, g, obj)
221221
}
222222

223+
func TestGitRepositoryReconciler_reconcileSource_emptyRepository(t *testing.T) {
224+
g := NewWithT(t)
225+
226+
server, err := gittestserver.NewTempGitServer()
227+
g.Expect(err).NotTo(HaveOccurred())
228+
defer os.RemoveAll(server.Root())
229+
server.AutoCreate()
230+
g.Expect(server.StartHTTP()).To(Succeed())
231+
defer server.StopHTTP()
232+
233+
obj := &sourcev1.GitRepository{
234+
ObjectMeta: metav1.ObjectMeta{
235+
GenerateName: "empty-",
236+
Generation: 1,
237+
},
238+
Spec: sourcev1.GitRepositorySpec{
239+
Interval: metav1.Duration{Duration: interval},
240+
Timeout: &metav1.Duration{Duration: timeout},
241+
URL: server.HTTPAddress() + "/test.git",
242+
},
243+
}
244+
245+
builder := fakeclient.NewClientBuilder().WithScheme(testEnv.GetScheme())
246+
247+
r := &GitRepositoryReconciler{
248+
Client: builder.Build(),
249+
EventRecorder: record.NewFakeRecorder(32),
250+
Storage: testStorage,
251+
patchOptions: getPatchOptions(gitRepositoryReadyCondition.Owned, "sc"),
252+
}
253+
254+
g.Expect(r.Client.Create(context.TODO(), obj)).ToNot(HaveOccurred())
255+
defer func() {
256+
g.Expect(r.Client.Delete(context.TODO(), obj)).ToNot(HaveOccurred())
257+
}()
258+
259+
var commit git.Commit
260+
var includes artifactSet
261+
sp := patch.NewSerialPatcher(obj, r.Client)
262+
263+
got, err := r.reconcileSource(context.TODO(), sp, obj, &commit, &includes, t.TempDir())
264+
assertConditions := []metav1.Condition{
265+
*conditions.TrueCondition(sourcev1.FetchFailedCondition, "EmptyGitRepository", "git repository is empty"),
266+
}
267+
g.Expect(obj.Status.Conditions).To(conditions.MatchConditions(assertConditions))
268+
g.Expect(err).To(HaveOccurred())
269+
g.Expect(got).To(Equal(sreconcile.ResultEmpty))
270+
g.Expect(commit).ToNot(BeNil())
271+
}
272+
223273
func TestGitRepositoryReconciler_reconcileSource_authStrategy(t *testing.T) {
224274
type options struct {
225275
username string

0 commit comments

Comments
 (0)