Skip to content

Commit 0dfd5e8

Browse files
committed
SparseCheckout when Spec.Update.Path specified
Signed-off-by: kane8n <[email protected]>
1 parent 42af338 commit 0dfd5e8

File tree

8 files changed

+80
-8
lines changed

8 files changed

+80
-8
lines changed

api/v1beta2/imageupdateautomation_types.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,8 @@ type UpdateStrategy struct {
9090
// Path to the directory containing the manifests to be updated.
9191
// Defaults to 'None', which translates to the root path
9292
// of the GitRepositoryRef.
93+
// When a path is specified, sparse checkout will be enabled to limit the checkout scope
94+
// to the specified directory, reducing clone size and time.
9395
// +optional
9496
Path string `json:"path,omitempty"`
9597
}

config/crd/bases/image.toolkit.fluxcd.io_imageupdateautomations.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -586,6 +586,8 @@ spec:
586586
Path to the directory containing the manifests to be updated.
587587
Defaults to 'None', which translates to the root path
588588
of the GitRepositoryRef.
589+
When a path is specified, sparse checkout will be enabled to limit the checkout scope
590+
to the specified directory, reducing clone size and time.
589591
type: string
590592
strategy:
591593
default: Setters

docs/api/v1beta2/image-automation.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -887,7 +887,9 @@ string
887887
<em>(Optional)</em>
888888
<p>Path to the directory containing the manifests to be updated.
889889
Defaults to &lsquo;None&rsquo;, which translates to the root path
890-
of the GitRepositoryRef.</p>
890+
of the GitRepositoryRef.
891+
When a path is specified, sparse checkout will be enabled to limit the checkout scope
892+
to the specified directory, reducing clone size and time.</p>
891893
</td>
892894
</tr>
893895
</tbody>

docs/spec/v1beta1/imageupdateautomations.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -611,11 +611,17 @@ type UpdateStrategy struct {
611611
// Path to the directory containing the manifests to be updated.
612612
// Defaults to 'None', which translates to the root path
613613
// of the GitRepositoryRef.
614+
// When a path is specified, sparse checkout will be enabled to limit the checkout scope
615+
// to the specified directory, reducing clone size and time.
614616
// +optional
615617
Path string `json:"path,omitempty"`
616618
}
617619
```
618620

621+
By default, the `path` is empty, which means that the root of the git repository is used.
622+
If a path is specified, the controller will use a sparse checkout to limit the checkout scope to the specified directory, which can reduce clone size and time.
623+
But this can be disabled by starting the controller with `--feature-gates=GitSparseCheckout=false`.
624+
619625
**Setters strategy**
620626

621627
At present, there is one strategy: "Setters". This uses field markers referring to image policies,

internal/controller/imageupdateautomation_controller.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -396,6 +396,10 @@ func (r *ImageUpdateAutomationReconciler) reconcile(ctx context.Context, sp *pat
396396
if r.features[features.GitShallowClone] {
397397
checkoutOpts = append(checkoutOpts, source.WithCheckoutOptionShallowClone())
398398
}
399+
if r.features[features.GitSparseCheckout] && obj.Spec.Update.Path != "" {
400+
checkoutOpts = append(checkoutOpts, source.WithCheckoutOptionSparseCheckoutDirectories(obj.Spec.Update.Path))
401+
}
402+
399403
// If full sync is still not needed, configure last observed commit to
400404
// perform optimized clone and obtain a non-concrete commit if the remote
401405
// has not changed.

internal/features/features.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@ const (
3434
// GitAllBranchReferences enables the download of all branch head references
3535
// when push branches are configured. When enabled fixes fluxcd/flux2#3384.
3636
GitAllBranchReferences = "GitAllBranchReferences"
37+
// GitSparseCheckout enables the use of sparse checkout when pulling source from
38+
// Git repositories.
39+
GitSparseCheckout = "GitSparseCheckout"
3740
// CacheSecretsAndConfigMaps controls whether Secrets and ConfigMaps should
3841
// be cached.
3942
//
@@ -55,6 +58,10 @@ var features = map[string]bool{
5558
// opt-out from v0.28
5659
GitAllBranchReferences: true,
5760

61+
// GitSparseCheckout
62+
// opt-out from v0.42
63+
GitSparseCheckout: true,
64+
5865
// CacheSecretsAndConfigMaps
5966
// opt-in from v0.29
6067
CacheSecretsAndConfigMaps: false,

internal/source/source.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import (
2121
"errors"
2222
"fmt"
2323
"os"
24+
"path/filepath"
2425
"strings"
2526
"text/template"
2627
"time"
@@ -196,6 +197,14 @@ func WithCheckoutOptionShallowClone() CheckoutOption {
196197
}
197198
}
198199

200+
// WithCheckoutOptionRecurseSubmodules is a CheckoutOption option to configure
201+
// SparseCheckoutDirectories.
202+
func WithCheckoutOptionSparseCheckoutDirectories(updatePath string) CheckoutOption {
203+
return func(cc *repository.CloneConfig) {
204+
cc.SparseCheckoutDirectories = []string{filepath.Clean(updatePath)}
205+
}
206+
}
207+
199208
// CheckoutSource clones and checks out the source. If a push branch is
200209
// configured that doesn't match with the checkout branch, a checkout to the
201210
// push branch is also performed. This ensures any change and push operation

internal/source/source_test.go

Lines changed: 47 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -222,13 +222,14 @@ func TestSourceManager_CheckoutSource(t *testing.T) {
222222

223223
func test_sourceManager_CheckoutSource(t *testing.T, proto string) {
224224
tests := []struct {
225-
name string
226-
autoGitSpec *imagev1.GitSpec
227-
gitRepoRef *sourcev1.GitRepositoryRef
228-
shallowClone bool
229-
lastObserved bool
230-
wantErr bool
231-
wantRef string
225+
name string
226+
autoGitSpec *imagev1.GitSpec
227+
gitRepoRef *sourcev1.GitRepositoryRef
228+
shallowClone bool
229+
sparseCheckoutDirectory string
230+
lastObserved bool
231+
wantErr bool
232+
wantRef string
232233
}{
233234
{
234235
name: "checkout for single branch",
@@ -275,6 +276,42 @@ func test_sourceManager_CheckoutSource(t *testing.T, proto string) {
275276
wantErr: false,
276277
wantRef: "main",
277278
},
279+
{
280+
name: "with sparse checkout",
281+
autoGitSpec: &imagev1.GitSpec{
282+
Push: &imagev1.PushSpec{Branch: "main"},
283+
Checkout: &imagev1.GitCheckoutSpec{
284+
Reference: sourcev1.GitRepositoryRef{Branch: "main"},
285+
},
286+
},
287+
sparseCheckoutDirectory: "testdata/appconfig/deploy.yaml",
288+
wantErr: false,
289+
wantRef: "main",
290+
},
291+
{
292+
name: "with sparse checkout for current directory",
293+
autoGitSpec: &imagev1.GitSpec{
294+
Push: &imagev1.PushSpec{Branch: "main"},
295+
Checkout: &imagev1.GitCheckoutSpec{
296+
Reference: sourcev1.GitRepositoryRef{Branch: "main"},
297+
},
298+
},
299+
sparseCheckoutDirectory: "./",
300+
wantErr: false,
301+
wantRef: "main",
302+
},
303+
{
304+
name: "with sparse checkout for different push branch",
305+
autoGitSpec: &imagev1.GitSpec{
306+
Push: &imagev1.PushSpec{Branch: "foo"},
307+
Checkout: &imagev1.GitCheckoutSpec{
308+
Reference: sourcev1.GitRepositoryRef{Branch: "main"},
309+
},
310+
},
311+
sparseCheckoutDirectory: "testdata/appconfig/deploy.yaml",
312+
wantErr: false,
313+
wantRef: "foo",
314+
},
278315
{
279316
name: "with last observed commit",
280317
autoGitSpec: &imagev1.GitSpec{
@@ -386,6 +423,9 @@ func test_sourceManager_CheckoutSource(t *testing.T, proto string) {
386423
if tt.shallowClone {
387424
opts = append(opts, WithCheckoutOptionShallowClone())
388425
}
426+
if tt.sparseCheckoutDirectory != "" {
427+
opts = append(opts, WithCheckoutOptionSparseCheckoutDirectories(tt.sparseCheckoutDirectory))
428+
}
389429
if tt.lastObserved {
390430
opts = append(opts, WithCheckoutOptionLastObserved(headRev))
391431
}

0 commit comments

Comments
 (0)