Vagrant中的符号链接和同步文件夹

107

我想使用Vagrant为我的团队提供一个共同的开发环境。主机完全不同:

  • 有些人使用OS X,有些人使用Linux,还有些人使用Windows。
  • 有些人使用VMware,有些人使用VirtualBox。

在虚拟机内部,我们想要运行Linux。

到目前为止,一切都还好。

现在我们的想法是,每个开发人员都可以使用他们选择的IDE,因此我们引入了一个同步文件夹,在主机和虚拟机之间共享源代码。这基本上工作正常......除了符号链接。

实际上,我们在源代码中确实有一些符号链接,在虚拟机内部的Linux中不是问题,但在Windows主机上会导致问题。我们唯一不能做的事情就是摆脱符号链接,所以我们需要另一种处理方法。

到目前为止,我们尝试了许多选项:

  • 在Vagrant的一个问题中提到了一种解决方法,不幸的是,这仅适用于VirtualBox,不能帮助那些运行VMware的人。到目前为止,我们没有找到在Vagrantfile中根据使用的提供程序运行代码的方法。
  • 我们现在尝试使用rsync类型而不是使用标准共享文件夹。这在Windows上可以工作,但在OS X上崩溃,并且会产生许多错误,告诉我们symlink has no referent(每个符号链接一个错误)。
  • 我们考虑过NFS,但只有在不使用Windows作为主机时才能使用。
  • 我们还考虑过SMB,但这仅适用于Windows作为主机的情况。

我无法想象我们是地球上唯一或第一个遇到多平台主机和共享文件夹中符号链接问题的人。

如何解决这个问题,以便我们可以保留符号链接,但仍然可以使用不同的主机操作系统?


讨论在这里:https://github.com/mitchellh/vagrant/issues/713#issuecomment-4416384 - Steve Bennett
@SteveBennett,当前被接受的答案所提到的问题已经在Vagrant 1.1中得到解决,而该版本发布时间比OP提问早15个月。此外,这个问题与VirtualBox共享文件夹有关,而不是rsync文件夹。请参见我的下面的答案(被接受的答案是错误的)。 - jdunk
6个回答

97

被接受的答案不好。问题描述了与同步文件夹有关的问题,而不是共享文件夹。提出的解决方案对于rsynced(非共享)文件夹没有影响。即使OP使用的是共享文件夹,被接受的答案的建议也是在OP发布问题之前15个月的1.1版本中已经被整合到vagrant中(更不用说VirtualBox的共享文件夹非常慢)。


我遇到了同样的问题:在OS X上,我得到了rsync错误symlink has no referent。我个人通过向我的vagrantfile添加特定的rsync参数来解决了这个问题:

config.vm.synced_folder ".", "/var/www", type: "rsync", rsync__args: ["--verbose", "--archive", "--delete", "-z"]

我还在vagrant的github上开了这个问题,指出他们默认值rsync__args中似乎有些问题(具体来说,其中一个默认参数--copy-links似乎会破坏另一个参数--archive,至少在复制损坏的符号链接方面是如此)。


1
好的,感谢@jdunk的提醒。根据Vagrant文档,--copy-links选项默认已设置。这就是我的问题所在。通过使用您上面的答案来删除它,问题得到了解决。 - Phil Birnie
1
非常有用,谢谢。虽然我希望有Windows的替代方案。 - Aleksandr Makov
5
请注意,根据Vagrant文档,共享文件夹是虚拟机VirtualBox用户的默认同步文件夹类型:“如果您正在使用VirtualBox提供程序,则VirtualBox共享文件夹是默认的同步文件夹类型。”(http://docs.vagrantup.com/v2/synced-folders/virtualbox.html)楼主的问题似乎也意味着VirtualBox共享文件夹是一个问题,因此被接受的答案确实试图解决部分问题(并且确实为我解决了问题)。 - Ajedi32
1
非常感谢您救了我的命,我在互联网上到处寻找,终于有人理解这个问题! - Dovizu
1
谢谢。这就是解决我的问题的方法(标题中的那个问题,也是我来到这里寻找解决方案的问题,令人困惑的是,这不是被问到的问题)。 - johncip
显示剩余3条评论

68

出于安全考虑,Virtualbox不允许在共享文件夹中使用符号链接。要启用符号链接,需要在Vagrantfile中的vm提供程序配置块中添加以下行:

config.vm.provider "virtualbox" do |v|
    v.customize ["setextradata", :id, "VBoxInternal2/SharedFoldersEnableSymlinksCreate/v-root", "1"]
end

此外,在Windows上,需要在拥有管理员权限的Shell中执行vagrant up命令。不需要任何解决方法。


9
我猜测提问者和许多查看这个问题的人混淆了“共享”和“同步”这两个术语。请注意提问者的第二个要点,它强烈暗示他一开始使用的是共享文件夹,但尝试切换到rsynced文件夹因为共享文件夹不起作用。如果我没记错的话,这里提供的解决方案解决了我当时遇到的问题。 - Steve Bennett
2
@SteveBennett,同意关于潜在混淆的观点。更有理由去澄清。很难想象这个建议会解决你的问题,因为它涉及到一个早已解决的老问题,除非你使用的是相当老的vagrant版本。即使如此,在我看来,考虑到VBox在共享目录方面的可怕文件系统性能(例如,“git status”需要几秒钟),它也几乎没有什么帮助,尽管你可能只分享了一个非常少的文件的小项目。http://mitchellh.com/comparing-filesystem-performance-in-virtual-machines - jdunk
6
在拥有管理员权限的 shell 中运行 vagrant up 即可,如@jdunk所指出的,在此答案发布近一年之前,Vagrant 的默认配置已经包含了该选项,见 此提交记录。话虽如此,我在拥有管理员权限的 shell 中运行 vagrant up 后问题得以解决。 - Ajedi32
2
不回答问题。它在同步文件夹上无法工作。 - Manel
这个答案有两个主要的错误。1.它涉及VBox共享文件夹,而不是rsync同步的目录 - 两者完全不同。2.在OP的问题发布15个月之前,这个设置已经成为Vagrant 1.1的默认设置。请查看我的答案获取更多信息。 - jdunk
在 Windows 上,需要在具有管理员权限的 shell 中执行 Vagrant up。 - Muhammad Usama

8

我尝试了所有这些选项来解决运行npm install时出现的错误。

仅在管理员提示符中运行vagrant并加载虚拟机(vagrant reload)即可解决问题。

我回过头去从Vagrantfile中删除了SharedFoldersEnableSymlinksCreate配置,一切都还好。


“npm update” 在我的 vagrant 共享文件夹中无法工作。这个解决方案出于某种原因修复了它。 - Emre
1
经过更多的研究,发现在Windows中创建符号链接默认需要管理员权限。要修改权限,请参见此处的答案: https://superuser.com/a/125981 - gameweld
在 Windows 10 机器上以管理员身份运行 Vagrant 和命令提示符对我来说很有效,在 npx create-react-app 'project_name' 上也是如此。 - sybozz

2
默认的同步文件夹类型是 vboxsf,但它在处理大量文件/目录时存在性能问题,并且缺乏对符号链接和硬链接的支持(请参见票务818 - 一个7年以上的bug)。建议避免使用它。
rsync 类型的同步文件夹可能是您的最佳选择。
您提到它崩溃了,您运行的 rsync 版本是什么?尝试通过 brew 更新到 3.1.0,我知道 OOTB 的版本太旧了(2.x),这可能会导致问题。

[wdd@localhost ~]$ sudo mount -t rsync node share mount: unknown filesystem type 'rsync' - Musa Haidari
1
当我读到这个答案时,我感到很高兴,认为它会解决我的问题,但是当我执行sudo mount -t rsync shared /var/www时,我得到了与上面相同的错误,错误是mount: unknown filesystem type 'rsync' - samayo
rsync 不是文件系统类型,因此您无法挂载它。 - Terry Wang
@samyo 参考 https://www.vagrantup.com/docs/synced-folders/rsync.html,你需要在 Vagrantfile 中进行配置,并手动运行 vagrant rsyncvagrant rsync-auto。否则,它只会在启动和重新加载时同步。 - Terry Wang

1
在试验了几个不同的解决方案(vagrant-vbguest,Marvin提供的修复程序)大约一个小时之后,我无法让虚拟机4.8.10和Vagrant 1.5.1中的共享文件夹符号链接正常工作。我发现一个更简单的解决方案是配置一个单独的共享文件夹,然后使用Ruby的File.readlink来读取底层路径:
config.vm.synced_folder File.readlink('SYMLINK'), "/mount/path"

1
我不明白,请你举个例子解释一下好吗?谢谢。 - Cassiano

1
向Vagrantfile文件中添加以下行:
config.vm.provider "virtualbox" do |v|
    v.customize ["setextradata", :id, "VBoxInternal2/SharedFoldersEnableSymlinksCreate/v-root", "1"]
end

这对我只有在将VirtualBox 6.0.8降级为6.0.4和Vagrant 2.2.4降级为2.2.1后才有效。当您使用"以管理员身份运行"打开终端时(我在Windows 10上使用Git Bash)。在项目文件中,也尝试更改以下内容:$ vim .git/config,更改为symlinks = true
[core]
        repositoryformatversion = 0
        filemode = false
        bare = false
        logallrefupdates = true
        symlinks = true
        ignorecase = true
[remote "origin"]
        fetch = +refs/heads/*:refs/remotes/origin/*
[branch "master"]
        remote = origin
        merge = refs/heads/master

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接