OS X 上没有 sudo 无法安装 vagrant 插件

Cannot install vagrant plugins without sudo on OS X

我之前在 vagrant 中安装过插件。现在在另一台 MacBook 上,我正在尝试安装一些我在旧 MacBook 上使用的相同插件。

例如,当我尝试安装 vagrant-hostmanager 时,出现 ruby 权限错误:

$ vagrant plugin install vagrant-hostmanager
Installing the 'vagrant-hostmanager' plugin. This can take a few minutes...
Bundler, the underlying system Vagrant uses to install plugins,
reported an error. The error is shown below. These errors are usually
caused by misconfigured plugin installations or transient network
issues. The error from Bundler is:

An error occurred while installing ffi (1.9.8), and Bundler cannot continue.
Make sure that `gem install ffi -v '1.9.8'` succeeds before bundling.

Gem::Installer::ExtensionBuildError: ERROR: Failed to build gem native extension.

    /opt/vagrant/embedded/bin/ruby extconf.rb
checking for ffi.h... *** extconf.rb failed ***
Could not create Makefile due to some reason, probably lack of necessary
libraries and/or headers.  Check the mkmf.log file for more details.  You may
need configuration options.

Provided configuration options:
    --with-opt-dir
    --with-opt-include
    --without-opt-include=${opt-dir}/include
    --with-opt-lib
    --without-opt-lib=${opt-dir}/lib
    --with-make-prog
    --without-make-prog
    --srcdir=.
    --curdir
    --ruby=/opt/vagrant/embedded/bin/ruby
    --with-ffi_c-dir
    --without-ffi_c-dir
    --with-ffi_c-include
    --without-ffi_c-include=${ffi_c-dir}/include
    --with-ffi_c-lib
    --without-ffi_c-lib=${ffi_c-dir}/
    --with-libffi-config
    --without-libffi-config
    --with-pkg-config
    --without-pkg-config
/opt/vagrant/embedded/lib/ruby/2.0.0/tmpdir.rb:92:in `mktmpdir': parent directory is world writable but not sticky (ArgumentError)
    from /opt/vagrant/embedded/lib/ruby/2.0.0/mkmf.rb:510:in `try_link0'
    from /opt/vagrant/embedded/lib/ruby/2.0.0/mkmf.rb:534:in `try_link'
    from /opt/vagrant/embedded/lib/ruby/2.0.0/mkmf.rb:427:in `have_devel?'
    from /opt/vagrant/embedded/lib/ruby/2.0.0/mkmf.rb:433:in `try_do'
    from /opt/vagrant/embedded/lib/ruby/2.0.0/mkmf.rb:549:in `block in try_compile'
    from /opt/vagrant/embedded/lib/ruby/2.0.0/mkmf.rb:502:in `with_werror'
    from /opt/vagrant/embedded/lib/ruby/2.0.0/mkmf.rb:549:in `try_compile'
    from /opt/vagrant/embedded/lib/ruby/2.0.0/mkmf.rb:1044:in `block in have_header'
    from /opt/vagrant/embedded/lib/ruby/2.0.0/mkmf.rb:895:in `block in checking_for'
    from /opt/vagrant/embedded/lib/ruby/2.0.0/mkmf.rb:340:in `block (2 levels) in postpone'
    from /opt/vagrant/embedded/lib/ruby/2.0.0/mkmf.rb:310:in `open'
    from /opt/vagrant/embedded/lib/ruby/2.0.0/mkmf.rb:340:in `block in postpone'
    from /opt/vagrant/embedded/lib/ruby/2.0.0/mkmf.rb:310:in `open'
    from /opt/vagrant/embedded/lib/ruby/2.0.0/mkmf.rb:336:in `postpone'
    from /opt/vagrant/embedded/lib/ruby/2.0.0/mkmf.rb:894:in `checking_for'
    from /opt/vagrant/embedded/lib/ruby/2.0.0/mkmf.rb:1043:in `have_header'
    from extconf.rb:16:in `<main>'


Gem files will remain installed in /Volumes/Passport/vagrant.d/gems/gems/ffi-1.9.8 for inspection.
Results logged to /Volumes/Passport/vagrant.d/gems/gems/ffi-1.9.8/ext/ffi_c/gem_make.out

有一点不同,因为我在本地 SSD 上 space 很紧张,所以我在我的 .bashrc 中定义了以下内容:

export VAGRANT_HOME=/Volumes/Passport/vagrant.d

所以我的盒子文件存储在 2TB USB3 驱动器上,而不是占用宝贵的 SSD space。

现在我可以使用 sudo 执行插件安装,但这成为一个级联问题,因为 vagrant up 现在不执行 sudo vagrant up 就无法在 Vagrantfile 中看到插件。然后 VM 归 root 所有...您可以看到这是如何级联失控的。

有人知道怎么回事吗?我该如何解决?

编辑:我发现如果我将 VAGRANT_HOME 改回默认值 ~/.vagrant.d,我可以安装插件 - 但是我的盒子现在位于默认情况下无法访问的卷上环境。显然这是一个 Ruby 限制。

TIA!

我怀疑 /Volumes/Passport 上的权限可能很奇怪。您可能想尝试:

> sudo chown -R `whoami` /Volumes/Passport
> sudo chmod 755 /Volumes/Passport

然后重试安装。

好的,我发现了这个问题,但不清楚解决这个问题的责任在哪里 - 我认为这是 OS X 上的一个 Ruby 错误(至少对于嵌入式版本在 Vagrant 中)。

原来 Dir.mktmpdir 期望 $TMPDIR 变量设置了粘滞位。在 OS X 上,$TMPDIR 变量指向每个用户唯一的目录,如:

/var/folders/yl/y9zbwwm951v3x6p62yn24ckw0000gn/T

使用

更改粘滞位
chmod +t $TMPDIR

还是真的更合适

chmod 700 $TMPDIR

解决了这个问题。

注意:我不确定我的 $TMPDIR 为什么或如何获得 777 权限,我检查了其他 OS X 10.10 安装并发现 $TMPDIR 正确具有 700 权限。