web-dev-qa-db-ja.com

Vagrant Chicken-and-Egg:uid = Apacheユーザーの共有フォルダー

私のVagrantボックスはベースLinux(科学的Linux)からビルドされ、プロビジョニング(シェルスクリプトを使用)中に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が常に中断することなく実行される方法で。

40
Alex

Ryan Sechrest には この問題について広範囲に対応 があります。

提示されたソリューションの1つは次のとおりです。

ディレクトリの権限を777に、ファイルの権限を666に設定します

config.vm.synced_folder "/Users/ryansechrest/Projects/Sites", 
  "/var/www/domains", mount_options: ["dmode=777", "fmode=666"]
8
Markus Schulte

Uid/gid値を修正できる場合は、mountコマンドでこれらを使用できます。既存のユーザー/グループに関連する必要はありません。

固定(一致)uid/gid値を使用して後でpuppetによって作成されたユーザーでこれを行います

config.vm.synced_folder "foo", "/var/www/foo",
   id: "foo", :mount_options => ["uid=510,gid=510"]
26
Sean Burlington

これは私がやったことです:

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

しかし、それはきれいでもいいニースでもありません。

9
Johandry

これを解決した方法は、最初に共有を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から、またはデバッグフラグと機能しない設定でプロビジョニングを実行することで確認できます(実際のマウントコマンドが出力されます)。これはちょっとした回避策であり、すべての状況で機能するとは限らないことを私は知っていますが、それは私にとってはうまくいきました。

2
kontulai

私の場合、プロビジョニングフェーズでsynced_folderをマウントする必要はありません。したがって、ゲストがプロビジョニングされていない場合は、synced_folderを無効にします。

Vagrantfileでプロビジョニングされているかどうかを確認してください ハックですが機能します

そして私にとってそれは十分に公平です

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

だから私のVagrantfileは次のようなものです:

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"
  [ ... ] 
0
Francisco Puga