Thread overview
The std.file rename method fails in the docker environment.
Mar 13
Sergey
March 13

upload file to server in docker, but upload directory volume to host machine.

Exception error:

Invalid cross-device link

Have other function like move(a, b) ?

https://github.com/huntlabs/hunt-framework/blob/master/source/hunt/framework/file/File.d#L102

March 13
On Wednesday, March 13, 2024 3:03:30 PM MDT zoujiaqing via Digitalmars-d-learn wrote:
> upload file to server in docker, but upload directory volume to host machine.
>
> Exception error:
> ```
> Invalid cross-device link
> ```
>
> Have other function like move(a, b) ?
>
> https://github.com/huntlabs/hunt-framework/blob/master/source/hunt/framework /file/File.d#L102

Well, the subject of your post mentions std.file, and then you link to a framework that does basically the same thing. So, I don't know what you're actually using.

However, both of those functions use the OS function, rename, which renames the file within a file system, but it can't move files across file systems. Strictly speaking, it's not possible to move a file across file systems. What a program like mv does when the destination is on a different file system from the source file is copy the file and then delete the original. So, if you want to "move" a file across file systems within your program, you'll have to do the same thing.

There may be a projcet on code.dlang.org which has a function which tries to move the file within the file system and then does a copy and remove instead if moving within the file system doesn't work, but otherwise, you'll have to implement that yourself, which could be as simple as catching the any exceptions from move and then attempting to copy the file and then remove it if an exception was thrown.

- Jonathan M Davis



March 13

On Wednesday, 13 March 2024 at 21:21:21 UTC, Jonathan M Davis wrote:

>

On Wednesday, March 13, 2024 3:03:30 PM MDT zoujiaqing via Digitalmars-d-learn wrote:

>

upload file to server in docker, but upload directory volume to host machine.

Exception error:

Invalid cross-device link

Have other function like move(a, b) ?

https://github.com/huntlabs/hunt-framework/blob/master/source/hunt/framework /file/File.d#L102

Well, the subject of your post mentions std.file, and then you link to a framework that does basically the same thing. So, I don't know what you're actually using.

However, both of those functions use the OS function, rename, which renames the file within a file system, but it can't move files across file systems. Strictly speaking, it's not possible to move a file across file systems. What a program like mv does when the destination is on a different file system from the source file is copy the file and then delete the original. So, if you want to "move" a file across file systems within your program, you'll have to do the same thing.

There may be a projcet on code.dlang.org which has a function which tries to move the file within the file system and then does a copy and remove instead if moving within the file system doesn't work, but otherwise, you'll have to implement that yourself, which could be as simple as catching the any exceptions from move and then attempting to copy the file and then remove it if an exception was thrown.

  • Jonathan M Davis

this is bug in D.

Docker run app code:

reanme("/tmp/aaa", "/data/attachments/aaa");

docker volume path:

VOLUME /data/attachments

docker compose yml:

    volumes:
      - /data/attachments:/data/attachments

Error exception:

Invalid cross-device link
March 13
On Wednesday, March 13, 2024 3:49:55 PM MDT zoujiaqing via Digitalmars-d-learn wrote:
> On Wednesday, 13 March 2024 at 21:21:21 UTC, Jonathan M Davis
>
> wrote:
> > On Wednesday, March 13, 2024 3:03:30 PM MDT zoujiaqing via
> >
> > Digitalmars-d-learn wrote:
> >> upload file to server in docker, but upload directory volume to host machine.
> >>
> >> Exception error:
> >> ```
> >> Invalid cross-device link
> >> ```
> >>
> >> Have other function like move(a, b) ?
> >>
> >> https://github.com/huntlabs/hunt-framework/blob/master/source/hunt/framew ork /file/File.d#L102>
> > Well, the subject of your post mentions std.file, and then you link to a framework that does basically the same thing. So, I don't know what you're actually using.
> >
> > However, both of those functions use the OS function, rename, which renames the file within a file system, but it can't move files across file systems. Strictly speaking, it's not possible to move a file across file systems. What a program like mv does when the destination is on a different file system from the source file is copy the file and then delete the original. So, if you want to "move" a file across file systems within your program, you'll have to do the same thing.
> >
> > There may be a projcet on code.dlang.org which has a function which tries to move the file within the file system and then does a copy and remove instead if moving within the file system doesn't work, but otherwise, you'll have to implement that yourself, which could be as simple as catching the any exceptions from move and then attempting to copy the file and then remove it if an exception was thrown.
> >
> > - Jonathan M Davis
>
> this is bug in D.
>
> Docker run app code:
> ```d
> reanme("/tmp/aaa", "/data/attachments/aaa");
> ```
>
> docker volume path:
> ```txt
> VOLUME /data/attachments
> ```
>
> docker compose yml:
> ```yml
>      volumes:
>        - /data/attachments:/data/attachments
> ```
>
> Error exception:
> ```
> Invalid cross-device link
> ```

How is it a bug in D? You are attempting to rename a file across filesystems, and that's not possible. The error is coming from the OS function - https://www.man7.org/linux/man-pages/man2/rename.2.html - and it's telling you what the problem is. You are attempting to rename a file across devices / filesystems, which rename does not support. Linux's rename doesn't even support renaming across different mount points if that filesystem is mounted in multiple places. It's designed to do an atomic move within a filesystem, and that's it.

The documentation for std.file's rename even explains that it won't work across filesystems / mount points / drives:

https://dlang.org/phobos/std_file.html#rename

If you want to move a file between two separate filesystems, then you need to copy the file, not rename it, and then if you want the original to be gone, you can then remove it.

You may not like that, but you're trying to use rename to do something that it does not support, because the OS function that it's a wrapper for does not support it. std.file could theoretically add a higher level wrapper that attempted to use rename and then copied the file and removed the original if rename failed, but std.file does not currently provide such a function, and rename is not intended to be that function. It's just a cross-platform wrapper around the OS function, rename.

So, while rename may not do what you want, it is working as intended, and it's not a bug.

- Jonathan M Davis



March 13

On Wednesday, 13 March 2024 at 21:49:55 UTC, zoujiaqing wrote:

>

this is bug in D.

It seems like a bug in Hunt-framework.
And Hunt - is an abandoned project.

March 13

On Wednesday, 13 March 2024 at 22:16:13 UTC, Sergey wrote:

>

On Wednesday, 13 March 2024 at 21:49:55 UTC, zoujiaqing wrote:

>

this is bug in D.

It seems like a bug in Hunt-framework.
And Hunt - is an abandoned project.

Hunt Framework call std.file rename function.
but this function can't move file from docker container to host machine.

March 14

On Wednesday, 13 March 2024 at 23:59:24 UTC, zoujiaqing wrote:

>

On Wednesday, 13 March 2024 at 22:16:13 UTC, Sergey wrote:

>

On Wednesday, 13 March 2024 at 21:49:55 UTC, zoujiaqing wrote:

>

this is bug in D.

It seems like a bug in Hunt-framework.
And Hunt - is an abandoned project.

Hunt Framework call std.file rename function.
but this function can't move file from docker container to host machine.

As Jonathan said, it's NOT possible to move aka rename files across different filesystems.
You can NOT do that in D, in C, in Python, every language ... is a OS error.

Try to copy the file, and then delete the original one.

/P