natefinch / atomic

atomic is a go package for atomic file writing
MIT License
200 stars 12 forks source link

Doesn't work on Docker or Vagrant shared volume #6

Closed raxod502 closed 2 years ago

raxod502 commented 5 years ago

Calling atomic.FileWrite has no effect if the provided filename is in a Docker shared --volume or a Vagrant synced_folder. In other directories inside Docker and/or Vagrant (or both, or neither), the same code behaves as expected.

raxod502 commented 5 years ago

The error message is:

cannot replace "filename" with tempfile "/tmp/filename526718249": rename /tmp/filename526718249 filename: invalid cross-device link

This would be unsurprising, since the shared volume is presumably on a different filesystem from the temporary directory, but https://github.com/natefinch/atomic/issues/3 is closed so something seems wrong.

In my go.mod:

github.com/natefinch/atomic v0.0.0-20150920032501-a62ce929ffcc
sdassow commented 2 years ago

In my go.mod:

github.com/natefinch/atomic v0.0.0-20150920032501-a62ce929ffcc

Seems most likely related to the version, because it's rather old.

raxod502 commented 2 years ago

The most recent commit was from 2015 at the time this issue was posted :)

You think one of the subsequent commits starting in 2019 fixed the problem?

sdassow commented 2 years ago

There have been changes in the meantime, and specifically before 18c0533a5b0940dce8ed0747c81dfa2150143815 these types of cross-device rename errors could happen, so yeah, I think there's a high chance this is fixed :)

raxod502 commented 2 years ago

Awesome, I just put together a quick demo to reproduce the issue, and can confirm that it no longer occurs as described. Put this in main.go:

package main

import "bytes"
import "fmt"
import "github.com/natefinch/atomic"

func main() {
    err := atomic.WriteFile("hello", bytes.NewReader([]byte("hello")))
    fmt.Println("error:", err)
}

This in go.mod:

module github.com/raxod502/atomic-test

go 1.17

require github.com/natefinch/atomic v1.0.1 // indirect

This in go.sum:

github.com/natefinch/atomic v1.0.1 h1:ZPYKxkqQOx3KZ+RsbnP/YsgvxWQPGxjC0oBt2AhwV0A=
github.com/natefinch/atomic v1.0.1/go.mod h1:N/D/ELrljoqDyT3rZrsUmtsuzvHkeB/wWjHV22AZRbM=

Then, docker run -it --rm -v $PWD:/src -w /src golang go run main.go correctly writes hello!