Skip to content

Commit d626aef

Browse files
authored
[cloud shell] respect gitignore file in --config directory to limit large data syncs (#387)
## Summary I discovered that the rust-stable project was not syncing, because it stores compiled artifacts in a child-directory: `.rustup`. This directory is in the `.gitignore` file but mutagen was syncing it. In the long run, we should not sync any files that are gitignored (agree?). However, code for that is a bit more involved, so as a first pass I implement looking for a .gitignore file in the `configDir` and passing its rules to mutagen as `--ignore` flags. Thankfully, mutagen's ignore rules match gitignore format. ## How was it tested? was able to start `devbox cloud shell` in the `rust-stable` example project
1 parent afd9f2b commit d626aef

File tree

3 files changed

+53
-7
lines changed

3 files changed

+53
-7
lines changed

internal/cloud/cloud.go

Lines changed: 40 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import (
1414

1515
"github.com/AlecAivazis/survey/v2"
1616
"github.com/fatih/color"
17+
"github.com/pkg/errors"
1718
"go.jetpack.io/devbox/internal/cloud/mutagen"
1819
"go.jetpack.io/devbox/internal/cloud/mutagenbox"
1920
"go.jetpack.io/devbox/internal/cloud/openssh"
@@ -137,6 +138,11 @@ func syncFiles(username, hostname, configDir string) error {
137138
return err
138139
}
139140

141+
ignorePaths, err := gitIgnorePaths(configDir)
142+
if err != nil {
143+
return err
144+
}
145+
140146
// TODO: instead of id, have the server return the machine's name and use that
141147
// here to. It'll make things easier to debug.
142148
machineID, _, _ := strings.Cut(hostname, ".")
@@ -150,11 +156,14 @@ func syncFiles(username, hostname, configDir string) error {
150156
// the projects files. If we pick a pre-existing directories with other files, those
151157
// files will be synced back to the local directory (due to two-way-sync) and pollute
152158
// the user's local project
153-
BetaPath: fmt.Sprintf("~/code/%s", projectName),
154-
EnvVars: env,
155-
IgnoreVCS: true,
156-
SyncMode: "two-way-resolved",
157-
Labels: mutagenbox.DefaultSyncLabels(machineID),
159+
BetaPath: fmt.Sprintf("~/code/%s", projectName),
160+
EnvVars: env,
161+
Ignore: mutagen.SessionIgnore{
162+
VCS: true,
163+
Paths: ignorePaths,
164+
},
165+
SyncMode: "two-way-resolved",
166+
Labels: mutagenbox.DefaultSyncLabels(machineID),
158167
})
159168
if err != nil {
160169
return err
@@ -202,3 +211,29 @@ func parseVMEnvVar() (username string, vmHostname string) {
202211
vmHostname = parts[1]
203212
return
204213
}
214+
215+
// Proof of concept: look for a gitignore file in the current directory.
216+
// To harden this, we must:
217+
// 1. Look for .gitignore file in each ancestor directory of configDir, and include
218+
// any rules that apply to configDir contents.
219+
// 2. Look for .gitignore file in each child directory of configDir and transform the
220+
// rules to be relative to configDir.
221+
func gitIgnorePaths(configDir string) ([]string, error) {
222+
223+
fpath := filepath.Join(configDir, ".gitignore")
224+
if _, err := os.Stat(fpath); err != nil {
225+
if os.IsNotExist(err) {
226+
return nil, nil
227+
} else {
228+
return nil, errors.WithStack(err)
229+
}
230+
}
231+
232+
contents, err := os.ReadFile(fpath)
233+
if err != nil {
234+
return nil, errors.WithStack(err)
235+
}
236+
237+
result := strings.Split(string(contents), "\n")
238+
return result, nil
239+
}

internal/cloud/mutagen/types.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,11 @@ import (
55
"strings"
66
)
77

8+
type SessionIgnore struct {
9+
VCS bool
10+
Paths []string
11+
}
12+
813
type SessionSpec struct {
914
AlphaAddress string
1015
AlphaPath string
@@ -14,7 +19,7 @@ type SessionSpec struct {
1419
Labels map[string]string
1520
Paused bool
1621
SyncMode string
17-
IgnoreVCS bool
22+
Ignore SessionIgnore
1823
EnvVars map[string]string
1924
}
2025

internal/cloud/mutagen/wrapper.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,16 @@ func Create(spec *SessionSpec) error {
4545
args = append(args, "--sync-mode", spec.SyncMode)
4646
}
4747

48-
if spec.IgnoreVCS {
48+
if spec.Ignore.VCS {
4949
args = append(args, "--ignore-vcs")
5050
}
5151

52+
if len(spec.Ignore.Paths) > 0 {
53+
for _, p := range spec.Ignore.Paths {
54+
args = append(args, "--ignore", p)
55+
}
56+
}
57+
5258
return execMutagen(args, spec.EnvVars)
5359
}
5460

0 commit comments

Comments
 (0)