am trying to run a golang application on docker. But when i try to move created file in the container to the folder the created volume is mounted on,i get an error :rename /mygo/newt /mygo/store/newt: invalid cross-device link
my golang code
package main
import (
"bufio"
"fmt"
"os"
"path/filepath"
"strings"
)
func main() {
for {
fmt.Println("do you want to create a file,y for yes, n for no")
var ans string
fmt.Scanln(&ans)
if ans == "y" {
var userFile string
fmt.Println("enter name of file")
fmt.Scanln(&userFile)
myfile, err := os.Create(userFile)
if err != nil {
fmt.Printf("error creating file::%v\n", err)
return
}
fmt.Println("enter text to write in file")
reader := bufio.NewReader(os.Stdin)
input, err := reader.ReadString('\t')
if err != nil {
fmt.Println("an error occured while reading::", err)
return
}
input = strings.TrimSuffix(input, "\t")
num, err := myfile.WriteString(input)
if err != nil {
fmt.Println("error while writing to file", err)
}
fmt.Printf("%v characters entered \n", num)
defer myfile.Close()
fmt.Println("created a file", userFile)
fmt.Println("===========")
fmt.Println("moving file to default folder")
pwd, err_pwd := os.Getwd()
if err_pwd != nil {
fmt.Printf("could not get current working directory::%v\n", err_pwd)
}
userFilePath := pwd "/" userFile
fmt.Println(pwd)
destinationFilePath := pwd "/store/" userFile
//destinationFilePath := pwd "/default/" userFile
err_moving := os.Rename(userFilePath, destinationFilePath)
if err_moving != nil {
fmt.Printf("Error occured while moving file::%v\n", err_moving)
return
}
fmt.Println("file moved")
continue
}
pwd, err_pwd := os.Getwd()
if err_pwd != nil {
fmt.Printf("could not get current working directory::%v\n", err_pwd)
}
fmt.Println("enter full path to move to default location")
var userFilePath string
fmt.Scanln(&userFilePath)
userFileName := filepath.Base(userFilePath)
destinationFilePath := pwd "/" userFileName
err_move := os.Rename(userFilePath, destinationFilePath)
if err_move != nil {
fmt.Printf("error occured while moving file:::%v", err_move)
return
}
fmt.Println("file moved")
continue
}
}
dockerfile
FROM golang
WORKDIR /mygo
COPY . .
RUN go build -o app
CMD ["./app"]
the program exits after the error
CodePudding user response:
There are two ways to "rename" a file in Linux.
Move the directory entry to a new place, but keep the file contents unchanged.
This has the advantage of being fast. It has the disadvantage that it doesn't work when moving a file from one filesystem to another.
Create a new file, copy the data to the new file, and delete the old file.
However, it will work if the source and destination are on two different filesystems.
Method #1 will not work in this case. You need method #2.
More resources:
- This golang-dev discussion explains why this happens.
- This question talks about the same problem, but in the context of C .
- Go uses the
renameat()
syscall internally. This manual page explains how it works. The specific error you're encountering is the EXDEV error: "oldpath and newpath are not on the same mounted filesystem. (Linux permits a filesystem to be mounted at multiple points, but rename() does not work across different mount points, even if the same filesystem is mounted on both.)"