Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Storage export Stat/Load issue #6688

Open
mastercoding opened this issue Nov 13, 2024 · 4 comments
Open

Storage export Stat/Load issue #6688

mastercoding opened this issue Nov 13, 2024 · 4 comments
Labels
bug 🐞 Something isn't working good first issue 🐤 Good for newcomers

Comments

@mastercoding
Copy link

mastercoding commented Nov 13, 2024

I'm trying to export a live caddy instance, but due to the size of my database, some keys get removed before caddy can actually dump it to file. I'm not sure why this is implemented this way, but I feel like the Stat call here:

https://github.com/caddyserver/caddy/blob/master/cmd/storagefuncs.go#L192-L194

and the Load call here

https://github.com/caddyserver/caddy/blob/master/cmd/storagefuncs.go#L197-L200

Should not terminate the storage export. It happens a lot with challenge tokens, but also with other types of stored data (that by the time the exporter gets to that key, is deleted from the storage). My storage currently has ~300k keys, but it happens within the first 100 records.

Maybe a --ignore-deleted option or something similar would be the way to go?

@mholt
Copy link
Member

mholt commented Nov 13, 2024

Interesting, not sure we had live exports in mind, but I think I agree; if the key doesn't exist anymore by the time we iterate to it, we should probably log, but ultimately ignore, the error, and carry on. We can do if errors.Is(err, fs.ErrNotExist).

@mholt mholt added bug 🐞 Something isn't working good first issue 🐤 Good for newcomers labels Nov 13, 2024
@santhoshTpixler
Copy link
Contributor

Something like this work?

for _, k := range keys {
		info, err := stor.Stat(ctx, k)
		if err != nil {
			if errors.Is(err, fs.ErrNotExist) {
				caddy.Log().Warn(fmt.Sprintf("key: %s removed before exporting", k))
				continue
			}
			return caddy.ExitCodeFailedQuit, err
		}

		if info.IsTerminal {
			v, err := stor.Load(ctx, k)
			if err != nil {
				if errors.Is(err, fs.ErrNotExist) {
					caddy.Log().Warn(fmt.Sprintf("key: %s removed before exporting", k))
					continue
				}
				return caddy.ExitCodeFailedQuit, err
			}

			hdr := &tar.Header{
				Name:    k,
				Mode:    0o600,
				Size:    int64(len(v)),
				ModTime: info.Modified,
			}

			if err = tw.WriteHeader(hdr); err != nil {
				return caddy.ExitCodeFailedQuit, fmt.Errorf("writing archive: %v", err)
			}
			if _, err = tw.Write(v); err != nil {
				return caddy.ExitCodeFailedQuit, fmt.Errorf("writing archive: %v", err)
			}
		}
	}

@francislavoie
Copy link
Member

PRs welcome if you have a proposed fix.

@mholt
Copy link
Member

mholt commented Nov 14, 2024

@santhoshTpixler Yes, exactly like that! Submit a PR :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug 🐞 Something isn't working good first issue 🐤 Good for newcomers
Projects
None yet
Development

No branches or pull requests

4 participants