Home > Net >  moving a file in a container to a folder that has a mounted volume docker
moving a file in a container to a folder that has a mounted volume docker

Time:10-07

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"]

running the container

the program exits after the error

CodePudding user response:

There are two ways to "rename" a file in Linux.

  1. 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.

  2. 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.)"
  • Related