41

我的 Vagrant box 是从基础 linux(科学 linux)构建的,在配置期间(使用 shell 脚本),安装了 Apache。

我最近将 Vagrant 文件 (v2) 更改为:

config.vm.synced_folder "public", "/var/www/sites.d/example.com",
   :owner => "apache", :group => "apache"

如果盒子已经配置好并且刚刚重新启动,那么效果很好。

现在,在vagrant destroy && vagrant up我得到错误之后:

mount -t vboxsf -o uid=`id -u apache`,gid=`id -g apache` 
   /var/www/sites.d/example.com /var/www/sites.d/example.com
id: apache: User does not exist

这很清楚 - 在初始运行期间,尚未安装 apache。

一个丑陋的解决方法当然是对注释掉的内容进行基本配置,将其synced_folder注释掉,然后重新启动。

有什么干净的技巧可以解决这个问题吗?尤其是以vagrant up始终不间断运行的方式,即使盒子是新的。

4

5 回答 5

27

如果您可以修复 uid/gid 值,则可以在 mount 命令中使用它们 - 它们不必与现有用户/组相关

我对后来由 puppet 使用固定(匹配)uid / gid 值创建的用户执行此操作

config.vm.synced_folder "foo", "/var/www/foo",
   id: "foo", :mount_options => ["uid=510,gid=510"]
于 2013-10-30T12:29:40.510 回答
9

这就是我所做的:

config.vm.synced_folder "./MyApp", "/opt/MyApp", owner: 10002, group: 1007, create: true

config.vm.provision :shell do |shell|
  shell.inline = "groupadd -g 1007 myapp;
                  useradd -c 'MyApp User' -d /opt/MyApp -g myapp -m -u 10002 myapp;"
end

不要使用用户名和组(作为文本),而是使用 uid 和 gid。然后使用这些 ID 创建组和用户。这是因为错误实际上是:

mount -t vboxsf -o uid=`id -u myapp`,gid=`getent group myapp | cut -d: -f3` opt_MyApp /opt/MyApp
...
id: myapp: No such user

id 命令无法识别用户。因此,切换到 uid 和 gid 命令 id 不会被 vagrant 使用。

我使用这种方法得到的唯一警告是用户主目录 (/opt/MyApp) 已经存在,但我可以接受,或者您可以更改 useradd 命令以忽略主目录(如果已经存在)。

在此之前,我使用的解决方法是:

vagrant up; vagrant provision; vagrant reload

但是,它既不好也不干净。

于 2015-01-09T02:12:10.447 回答
8

Ryan Sechrest广泛地处理了这个问题

提出的解决方案之一是:

设置目录权限为777,文件权限为666

config.vm.synced_folder "/Users/ryansechrest/Projects/Sites", 
  "/var/www/domains", mount_options: ["dmode=777", "fmode=666"]
于 2016-02-10T10:31:42.920 回答
2

我如何解决这个问题是我首先将共享配置为 Vagrantfile,没有用户或组信息。然后在配置阶段我卸载共享并使用正确的用户和组信息重新安装它。例如:

exec {
'umount /share/location':
  command => 'umount /share/location';
} -> exec {
'mount /share/location':
  command => 'mount -t vboxsf -o uid=`id -u apache`,gid=`id -g apache` /share/name /share/location'

您可以从 virtualbox 或通过使用调试标志和非工作设置运行配置来检查共享名称(它会打印出实际的挂载命令)。我知道这是一种解决方法,可能不适用于所有情况,但它对我有用。

于 2013-08-14T08:17:11.707 回答
0

In my case i don't need the synced_folder to be mounted during provision phase. So i disable the synced_folder if the guest is not provisioned.

Check if it's provisioned in the Vagrantfile is a hack but it works.

And for me it's fair enough doing

vagrant up   # To build and provision the first time
vagrant halt # An intermediate step to mount the folder
vagrant up   # To have the folder mounted

So my Vagrantfile is something like:

def provisioned?(vm_name='default', provider='virtualbox')
  File.exist?(".vagrant/machines/#{vm_name}/#{provider}/action_provision")
end

Vagrant.configure(2) do |config|
  [ ... ]
  config.vm.synced_folder "../geoserver_data", "/var/lib/geoserver_data",
    disabled: !provisioned?,
    owner: "tomcat7",
    group: "tomcat7"
  [ ... ] 
于 2018-07-23T18:25:48.737 回答