Skip to content

feat: add global omit_snapshot_on_delete setting, fixes #8263#8264

Open
marklabrecque-ab wants to merge 3 commits intoddev:mainfrom
marklabrecque-ab:20260328_marklabrecque-ab_global_default_omit_snapshot
Open

feat: add global omit_snapshot_on_delete setting, fixes #8263#8264
marklabrecque-ab wants to merge 3 commits intoddev:mainfrom
marklabrecque-ab:20260328_marklabrecque-ab_global_default_omit_snapshot

Conversation

@marklabrecque-ab
Copy link
Copy Markdown
Contributor

The Issue

Users who frequently delete projects without needing a snapshot must pass --omit-snapshot every time. There is no way to set this as a default.

How This PR Solves The Issue

Adds a new global configuration option omit_snapshot_on_delete (default false) that, when enabled, makes ddev delete skip the database snapshot by default. The explicit --omit-snapshot / --omit-snapshot=false flag on the command still takes precedence, so per-command overrides work in both directions.

Changes across five files:

  • pkg/globalconfig/global_config.go — new OmitSnapshotOnDelete bool field and documentation comment in WriteGlobalConfig
  • cmd/ddev/cmd/config-global.go — flag handler and registration for --omit-snapshot-on-delete
  • cmd/ddev/cmd/delete.go — applies global default when --omit-snapshot is not explicitly passed
  • pkg/globalconfig/schema.json — schema entry for the new option
  • cmd/ddev/cmd/config-global_test.go — test coverage

Manual Testing Instructions

  1. ddev config global --omit-snapshot-on-delete=true
  2. ddev delete <project> — should skip the snapshot without needing -O
  3. ddev delete --omit-snapshot=false <project> — should still create a snapshot
  4. ddev config global --omit-snapshot-on-delete=false to restore default

Automated Testing Overview

Extended TestCmdGlobalConfig to verify the new flag appears in output with its default value, can be set to true, and persists in the global config struct after EnsureGlobalConfig().

Release/Deployment Notes

Opt-in only. Existing behavior is unchanged unless a user explicitly enables the new setting. No migration or deployment steps required.

@marklabrecque-ab marklabrecque-ab requested a review from a team as a code owner March 29, 2026 06:22
@github-actions
Copy link
Copy Markdown

github-actions bot commented Mar 29, 2026

Copy link
Copy Markdown
Member

@rfay rfay left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This probably needs a little test of the functionality, right, or an extra stanza in an existing test?

I always use ddev delete -Oy which doesn't hurt my fingers too much.

@marklabrecque-ab
Copy link
Copy Markdown
Contributor Author

I've expanded the tests now and hopefully they cover all of the normal testing surfaces for this stuff. I tried to follow the patterns that I could find for tests like these. They all passed locally on my arm64 machine.

I also noticed that there was a package that was sharing a variable scope with another package, which probably is not a great practice, so I've isolated them as well. That should prevent tests from breaking if the tests are re-ordered or run in parallel.

In response to your suggestion, I actually missed that -O was possible in the documentation. Now that you mention it, I vaguely remember you suggesting this to me before and I completely forgot this option existed. I need to read --help closer next time. Happy to hear any additional feedback on my tests or approaches here, too.

All this to say that if you favor the existing -O approach over my solution, I completely understand. I learned alot in producing this PR, so even if it doesn't get merged, I call it a win.

Thanks!

@marklabrecque-ab
Copy link
Copy Markdown
Contributor Author

I took at look at the failing tests, but they didn't look related to what I was doing in this changeset. That being said, tests appear to be passing on stable. Perhaps I targetted the wrong branch with my PR? If you have any advice for how I would debug these tests on my end, much appreciated!

@rfay
Copy link
Copy Markdown
Member

rfay commented Mar 29, 2026

@rfay
Copy link
Copy Markdown
Member

rfay commented Mar 29, 2026

Claude's suggestion:

TestGetActiveAppRoot panic - root cause

The panic in TestGetActiveAppRoot (nil pointer dereference at err.Error() on line 150) is caused by a bug in TestOmitSnapshotOnDeleteGlobal's cleanup function.

What happens:

  1. TestOmitSnapshotOnDeleteGlobal captures origDir = the Go package directory (cmd/ddev/cmd/)
  2. Its t.Cleanup calls os.Chdir(origDir) first, then runs ddev config --auto — which creates a .ddev/config.yaml in the package directory
  3. All tests after that run with CWD = package dir, which now has a stray ddev config
  4. TestGetActiveAppRoot calls GetActiveAppRoot(""), expects an error (no project here), but finds the stray config and returns nil
  5. err.Error() on a nil error → panic

Fix run ddev config --auto from site.Dir instead of origDir, and use defer to ensure CWD is always restored even if a require.NoError terminates the cleanup early via runtime.Goexit().

@marklabrecque-ab
Copy link
Copy Markdown
Contributor Author

ah okay, I think I understand. Looks like my tests were creating stray DDEV config files because it found itself in a package directory of DDEV instead of the test site directory, so I guess I made some bad assumptions here. It looks like if I explicitly reset the directory at the beginning of each test, it might work better? Let's see how it goes

@rfay
Copy link
Copy Markdown
Member

rfay commented Mar 30, 2026

Tricky and weird stuff sometimes. Since we do so many end-to-end tests they can affect each other. It's not pretty sometimes.

@marklabrecque-ab
Copy link
Copy Markdown
Contributor Author

This fail might be a bit more incidental. Looks like it ran for 25 minutes, then stopped after the TestDdevExec setup finished, and idled for about 3h40m until the 4 hour timeout killed it entirely. Maybe you have run into this before?

@marklabrecque-ab
Copy link
Copy Markdown
Contributor Author

marklabrecque-ab commented Mar 30, 2026

From Claude:
Resolution: This is almost certainly a one-off flake. Re-running the build should pass. If it recurs specifically on this runner, it may be worth:

  • Restarting Colima on tb-macos-arm64-6 before the next run (colima stop colima-vz && colima start colima-vz)
  • Checking if the runner is low on disk/memory (the log did note 60% disk usage, which isn't critical but worth watching)
  • Checking if there's a newer Colima version — VZ mode has had stability improvements over time

Nothing in the log suggests your PR's code changes caused this.

Editorial note: All this with a grain of salt, because Claude was just going off of failed build's logfile. It does not have access to the build process itself.

@rfay
Copy link
Copy Markdown
Member

rfay commented Mar 30, 2026

The timeout/hang problem in https://buildkite.com/ddev/macos-colima-vz/builds/6156#019d3bd9-d3dd-4f2d-917a-0f21d254e742 is what Stas is working on in #8265

I'll restart this now, you have privs to restart buildkite stuff any time. (You have to be logged into buildkite)

@marklabrecque-ab marklabrecque-ab force-pushed the 20260328_marklabrecque-ab_global_default_omit_snapshot branch from 3ff181b to 1a4dab6 Compare April 3, 2026 06:07
@marklabrecque-ab
Copy link
Copy Markdown
Contributor Author

I rebased my branch onto main to bring it up to date. It looks like the last tests had passed, so I expect we are in the clear on this one. Appreciate the guidance on this one, @rfay - Thanks!

@rfay
Copy link
Copy Markdown
Member

rfay commented Apr 3, 2026

Please always use rebase, not merge of upstream, to update a PR. Merge makes it really hard to maintain.

@marklabrecque-ab
Copy link
Copy Markdown
Contributor Author

ok, that's good advice, thanks. I had performed a rebase of my branch, but it still said the branch needed updating, so I tried using the button in the Github UI to facilitate - turns out that was not a good idea. I will back out of that change and try rebasing again. It's possible there were some changes I didn't have in my original rebase attempt.

@rfay
Copy link
Copy Markdown
Member

rfay commented Apr 3, 2026

I'm sure you know the github web UI also has a "rebase" option, it's just hidden. Stas did an attempt to make rebase the default today but couldn't get it working.

@marklabrecque-ab marklabrecque-ab force-pushed the 20260328_marklabrecque-ab_global_default_omit_snapshot branch 2 times, most recently from 182463d to 00d8bc3 Compare April 3, 2026 20:14
@marklabrecque-ab
Copy link
Copy Markdown
Contributor Author

oh, thanks I didn't actually know that. For most of my work, I have always used Gitlab and am still not used to the Github UI. Good tip. I've rebased again to see if that fixes it. Hard to keep up with HEAD with such an active project! :)

@rfay
Copy link
Copy Markdown
Member

rfay commented Apr 5, 2026

It's not actually necessary to worry about the update all the time. Unfortunately, when we enable want the update/rebase option, it's done by enabling "always suggest update" and then it feels like it's putting pressure on you :) In a PR like this one, nothing is likely to conflict before it gets in, so there's no essential need to update it all the time.

What happens with doing a merge commit instead of a rebase: When some actual nontrivial divergence does happen, it's then no longer possible to fix with a rebase, because the merge commit was introduced.

@marklabrecque-ab
Copy link
Copy Markdown
Contributor Author

Yeah, understood. I'm pretty picky about history on my projects for this very reason. I've been burned by it more than once.

…pshot vars

- Add TestOmitSnapshotOnDeleteGlobal with table-driven tests covering all
  four combinations of global config and --omit-snapshot flag
- Scope package-level omitSnapshot var into deleteOmitSnapshot (delete.go)
  and stopOmitSnapshot (stop.go) to prevent shared mutable state between
  commands
…Global cleanup

The cleanup function was running `ddev config --auto` from the package
directory (origDir), creating a stray .ddev/config.yaml that caused
TestGetActiveAppRoot to panic with a nil error dereference. Run from
site.Dir instead and use defer for os.Chdir(origDir) to ensure CWD
restoration even if require.NoError triggers runtime.Goexit().
@marklabrecque-ab marklabrecque-ab force-pushed the 20260328_marklabrecque-ab_global_default_omit_snapshot branch from 00d8bc3 to 5c5f76c Compare April 7, 2026 05:43
@marklabrecque-ab marklabrecque-ab requested a review from rfay April 7, 2026 05:43
Copy link
Copy Markdown
Member

@stasadev stasadev left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Allow a global DDEV setting to default 'delete' to omit-snapshot

3 participants