Server: - Add a --cache-path allowlist so a server can be limited to the caches it is meant to purge, defaulting to any path as before. - Set socket permissions explicitly (--socket-mode, default 0660) instead of inheriting the service manager's umask, which left the socket unreachable. - Refuse to remove a socket another instance is still serving. - Read keys both raw and decoded, so keys nginx stored with escapes and keys a caller escaped by hand both purge. - Add an exact= parameter for literal keys containing glob punctuation. - Report purge failures as 500 rather than 502, and send error bodies through http.Error so a failure is not reported as a successful purge. - Graceful shutdown with systemd readiness notification. Purge: - Group purge arguments into PurgeRequest and report the number of entries removed. - Compile exclude globs once, and fail the purge when one is invalid rather than purging the keys it was meant to keep. - Cap header scanning and tolerate entries nginx evicts mid-walk. - Switch to filepath.WalkDir to avoid an Lstat per cache file. New: - service command to install, start, stop, and remove the system service. - service install takes --cache-path, writing the allowlist into the unit it installs, so an installed service is restricted from its first start. - Makefile, VERSION, and build identifiers stamped via ldflags. - Tests for the server handler and the service command. Build: - Update to Go 1.25, kong v1, GoReleaser v2, and current GitHub Actions. - Add vet and test steps to CI. - Rename purgeCmd.go/serverCmd.go to Go's file naming convention. Bump version to 0.2.0.
28 lines
1 KiB
Go
28 lines
1 KiB
Go
package main
|
|
|
|
import "log"
|
|
|
|
// Purge command for CLI to purge cache keys.
|
|
type PurgeCmd struct {
|
|
CachePath string `arg:"" name:"cache-path" help:"Path to cache directory." type:"existingdir"`
|
|
Key string `arg:"" name:"key" help:"Cache key or wildcard match."`
|
|
ExcludeKeys []string `optional:"" name:"exclude-key" help:"Key to exclude, can be wild card and can add multiple excludes."`
|
|
Exact bool `optional:"" name:"exact" help:"Treat the key and excludes as literal keys rather than wildcard matches."`
|
|
}
|
|
|
|
// The purge command execution just runs the apps purge cache function, then
|
|
// says how much it removed. A key that matched nothing is not an error, so the
|
|
// count is the only thing that distinguishes it from a purge that worked.
|
|
func (a *PurgeCmd) Run() error {
|
|
purged, err := app.PurgeCache(PurgeRequest{
|
|
CachePath: a.CachePath,
|
|
Key: a.Key,
|
|
ExcludeKeys: a.ExcludeKeys,
|
|
Exact: a.Exact,
|
|
})
|
|
if err != nil {
|
|
return err
|
|
}
|
|
log.Printf("Purged %d cache entries matching %s.\n", purged, a.Key)
|
|
return nil
|
|
}
|