Skip to content

Commit e334b62

Browse files
committed
fix: avoid deleting root filesystem when KANIKO_DIR not set
1 parent f92dc3f commit e334b62

File tree

4 files changed

+59
-3
lines changed

4 files changed

+59
-3
lines changed

README.md

+5
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,11 @@ $ vim .devcontainer/Dockerfile
4747

4848
Exit the container, and re-run the `docker run` command... after the build completes, `htop` should exist in the container! 🥳
4949

50+
> **Note:** Envbuilder performs destructive filesystem operations! To guard against accidental data
51+
> loss, it will refuse to run if it detects that KANIKO_DIR is not set to a specific value.
52+
> If you need to bypass this behaviour for any reason, you can bypass this safety check by setting
53+
> `FORCE_SAFE=true`.
54+
5055
### Git Branch Selection
5156

5257
Choose a branch using `GIT_URL` with a _ref/heads_ reference. For instance:

cmd/envbuilder/main.go

-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ func main() {
3131
SilenceErrors: true,
3232
RunE: func(cmd *cobra.Command, args []string) error {
3333
options := envbuilder.OptionsFromEnv(os.LookupEnv)
34-
3534
var sendLogs func(ctx context.Context, log ...agentsdk.Log) error
3635
agentURL := os.Getenv("CODER_AGENT_URL")
3736
agentToken := os.Getenv("CODER_AGENT_TOKEN")

envbuilder.go

+18-2
Original file line numberDiff line numberDiff line change
@@ -597,8 +597,7 @@ func Run(ctx context.Context, options Options) error {
597597

598598
// It's possible that the container will already have files in it, and
599599
// we don't want to merge a new container with the old one.
600-
err = util.DeleteFilesystem()
601-
if err != nil {
600+
if err := maybeDeleteFilesystem(options.ForceSafe); err != nil {
602601
return nil, fmt.Errorf("delete filesystem: %w", err)
603602
}
604603

@@ -1270,3 +1269,20 @@ func findDevcontainerJSON(options Options) (string, string, error) {
12701269

12711270
return "", "", errors.New("can't find devcontainer.json, is it a correct spec?")
12721271
}
1272+
1273+
// maybeDeleteFilesystem wraps util.DeleteFilesystem with a guard to hopefully stop
1274+
// folks from unwittingly deleting their entire root directory.
1275+
func maybeDeleteFilesystem(force bool) error {
1276+
kanikoDir, ok := os.LookupEnv("KANIKO_DIR")
1277+
if !ok || strings.TrimSpace(kanikoDir) != MagicDir {
1278+
if force {
1279+
_, _ = fmt.Fprintf(os.Stderr, "WARNING! BYPASSING SAFETY CHECK! THIS WILL DELETE %s!\n", kanikoDir)
1280+
} else {
1281+
_, _ = fmt.Fprintf(os.Stderr, "KANIKO_DIR is not set to %s. Bailing!\n", MagicDir)
1282+
_, _ = fmt.Fprintln(os.Stderr, "To bypass this check, set FORCE_SAFE=true.")
1283+
return errors.New("safety check failed")
1284+
}
1285+
}
1286+
1287+
return util.DeleteFilesystem()
1288+
}

integration/integration_test.go

+36
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,42 @@ const (
4444
testImageUbuntu = "localhost:5000/envbuilder-test-ubuntu:latest"
4545
)
4646

47+
func TestForceSafe(t *testing.T) {
48+
t.Parallel()
49+
50+
t.Run("Safe", func(t *testing.T) {
51+
t.Parallel()
52+
srv := createGitServer(t, gitServerOptions{
53+
files: map[string]string{
54+
"Dockerfile": "FROM " + testImageAlpine,
55+
},
56+
})
57+
_, err := runEnvbuilder(t, options{env: []string{
58+
"GIT_URL=" + srv.URL,
59+
"KANIKO_DIR=/not/envbuilder",
60+
"DOCKERFILE_PATH=Dockerfile",
61+
}})
62+
require.ErrorContains(t, err, "delete filesystem: safety check failed")
63+
})
64+
65+
// Careful with this one!
66+
t.Run("Unsafe", func(t *testing.T) {
67+
t.Parallel()
68+
srv := createGitServer(t, gitServerOptions{
69+
files: map[string]string{
70+
"Dockerfile": "FROM " + testImageAlpine,
71+
},
72+
})
73+
_, err := runEnvbuilder(t, options{env: []string{
74+
"GIT_URL=" + srv.URL,
75+
"KANIKO_DIR=/not/envbuilder",
76+
"FORCE_SAFE=true",
77+
"DOCKERFILE_PATH=Dockerfile",
78+
}})
79+
require.NoError(t, err)
80+
})
81+
}
82+
4783
func TestFailsGitAuth(t *testing.T) {
4884
t.Parallel()
4985
srv := createGitServer(t, gitServerOptions{

0 commit comments

Comments
 (0)