Add a concurrency lock for download/install against the same destination

combineDirTrees' merge logic assumes it's the only thing moving files
into a given target at a time; two `vintner download`/`install` runs
racing against the same --dest could otherwise interleave os.Rename
calls and corrupt the tree instead of erroring cleanly. Take an
exclusive, non-blocking flock(2) on the destination for the duration
of each run, so a second invocation fails immediately with a clear
message instead of silently colliding with the first.
This commit is contained in:
Cheviiot
2026-07-25 18:10:56 +10:00
parent 738234186d
commit b366dfa9ac
4 changed files with 187 additions and 0 deletions
+7
View File
@@ -10,6 +10,7 @@ import (
"github.com/Cheviiot/vintner/internal/download"
"github.com/Cheviiot/vintner/internal/i18n"
"github.com/Cheviiot/vintner/internal/lock"
)
func runDownload(args []string) int {
@@ -177,6 +178,12 @@ func runDownload(args []string) int {
fmt.Fprintln(os.Stderr, "vintner download:", err)
return 1
}
unlock, err := lock.Acquire(destAbs)
if err != nil {
fmt.Fprintln(os.Stderr, "vintner download:", err)
return 1
}
defer unlock()
unpack := destAbs
if !*onlyUnpack {