archiver
archiver copied to clipboard
Can't create archive with broken symlinks
What version of the package or command are you using?
v4.0.0-alpha.8
What are you trying to do?
I've got a process that archives nested folders on a server.
I'm trying to compress directories containing symlinks, some of which may point to things that no longer exist.
I am getting the error open symlink.file: no such file or directory even though I have FollowSymlinks: false,
What steps did you take?
https://github.com/donatj/archivertest - here's the problem boiled down to an example project.
The gist of that project is
zf, err := os.Create("output.zip")
if err != nil {
log.Fatal("error creating zip file", err)
}
filesForZip, err := archiver.FilesFromDisk(&archiver.FromDiskOptions{
FollowSymlinks: false,
}, map[string]string{
"toArchive": "toArchive",
})
if err != nil {
log.Fatal("error walking files to create archive", err)
}
format := archiver.CompressedArchive{
Archival: archiver.Zip{
SelectiveCompression: true,
},
}
// create the archive
err = format.Archive(context.Background(), zf, filesForZip)
if err != nil {
log.Fatal("error creating archive", err)
}
The toArchive directory contains a link-logo.png symlink that points to a logo.png that no longer exists.
$ go run .
2024/01/05 17:23:58 error creating archivewriting file 1: link-logo.png: open toArchive/link-logo.png: no such file or directory
exit status 1
What did you expect to happen, and what actually happened instead?
I just a zip with the broken symlink in it like most compression tools give. This throws an error.
How do you think this should be fixed?
Some part of the code is trying to follow the symlink, even though FollowSymlinks is turned off. That should be corrected and the symlink should just be archived as-is.
Please link to any related issues, pull requests, and/or discussion
Example project
https://github.com/donatj/archivertest
Bonus: What do you use archiver for, and do you find it useful?
I've got a number of CLI tools using it for creating archives.
Ah, this might have something to do with the fact that zip archives don't seem to natively support symlinks. The tar headers do accept the symlink targets, but zip does not.
Apparently the zip command has a --symlinks option that does preserve them, to an extent, but with caveats: https://askubuntu.com/questions/1203925/using-zip-command-to-transfer-ubuntu-folders-with-symbol-links-in-them-to-window
Short answer: you can't [preserve symlinks] unless 1) the receiving file system supports linux symbolic links and 2) the target files/folders of the link are present
Thanks for setting up a reproducer. I'm just quickly triaging my backlog right now. Could you tell me if the error happens with tar archives too?
Anyway, the error shouldn't happen, I agree, I'm just trying to make sure I understand it well enough to make the right fix.
.tar.gz does appear to work as expected.
the target files/folders of the link are present
Hmm, interesting. This does seem to be the case, but it just silently skips them. That's… terrible.
For what it's worth, the macOS compression utility is able to store them fine.
https://github.com/mholt/archiver/assets/133747/1324293f-ab6f-43b1-a8aa-3b1d009c6d4b
Which created - which the cli unzip command doesn't even have an issue with
Thanks; I agree something should be fixed, just not quite sure how yet. The ZIP file header doesn't seem to support symlink information, so I'm not sure how to archive the link? I can see how we can dereference the symlink and archive the target file, but not the symlink.