Laravel 4 Permissions on a Vagrant box with Puppet - laravel

I have been using http://www.puphpet.com successfully to generate vagrant+puppet environments for a number of projects. Then this week I got tasked with writing a prototype for a project using Laravel 4. Since I'm not going to be the one working on the project full time, I figured it would be best to make a VM environment for it that the next person can just clone for the repo. Not having much experience with Laravel 4 I got everything to run in the dev environment just fine. Then I tried to run the first migration and here the problems start with the app/storage file permissions.
1. app/storage must be writable by the web user
Fine, took out id: vagrant from the synced folder provisioning and set the owner & group to www-data like so:
config.vm.synced_folder "./www", "/var/www", owner: "www-data", group: "www-data"
2. Artisan can only be run from inside the vagrant box to have access to the DB
Fine, vagrant ssh and run artisan from the www folder.
3. app/storage & app/database have to be writable by the vagrant user in order to use migrations
Grrr, ok, added the following awful piece of code to the vagrant file (note, tried to do this in Puppet first and it didn't take):
config.vm.provision :shell, :inline =>
"usermod -a -G www-data vagrant"
4. app/storage & app/database are not writeable by the group
Argh!!! Ok, let's try this Puppet directive:
file { "/var/www/app/storage":
source => "/var/www/app/storage/",
mode => 0775,
ensure => 'directory',
owner => 'www-data',
group => 'www-data',
recurse => true
}
Nope, doesn't work. Tried to do the same with the Puppet exec {} directive to no effect. It seems that permissions for the vagrant synced folder are set by the host machine, not the guest.
Finally ended up manually changing the permissions for the folder in the host machine. Is there any simpler way to do this? I would really just like to be able to give the next dev a worry free environment they can clone from the repo, not have them re-setup everything after cloning.
UPDATE
We've figured out that if we change the Apache run user, vagrant doesn't override it on reload. So we've done that manually and it's working better than changing the synced folder's permissions & owner. Now we're just trying to figure out how to make that change manually in Puppet.

After some discussion on Twitter, figured out the following:
There's a constraint from VirtualBox on vagrant that does not allow you to set permissions for the synced folder from inside the guest OS. See this issue on github.
You can use the following code to set the synced folder permissions from the vagrant file:
config.vm.synced_folder ".", "/vagrant", :mount_options => ["dmode=777","fmode=666"]
Or you can change the Apache runtime user to vagrant from the puppet manifest like so:
exec { "change_httpd_user":
command => "sed -i 's/www-data/vagrant/g' /etc/apache2/envvars",
onlyif => "/bin/grep -q 'www-data' '/etc/apache2/envvars'",
notify => Service['apache2'],
require => Package['apache2'],
}
file { "/var/lock/apache2":
ensure => "directory",
owner => "vagrant",
group => "vagrant",
require => Exec['change_httpd_user'],
}
Or any combination of the above

I'm not using pupphet in my setup and I came up with 2 solutions:
(1) In my bootstrap.sh file:
sudo sed -i 's/APACHE_RUN_USER=.*/APACHE_RUN_USER=vagrant/g' /etc/apache2/envvars
sudo sed -i 's/APACHE_RUN_GROUP=.*/APACHE_RUN_GROUP=www-data/g' /etc/apache2/envvars
(2) Im my VagrantFile:
config.vm.synced_folder "./", "/vagrant", id: "vagrant-root" , :owner => "vagrant", :group => "www-data"
config.vm.synced_folder "./app/storage", "/vagrant/app/storage", id: "vagrant-storage",
:owner => "vagrant",
:group => "www-data",
:mount_options => ["dmode=775","fmode=664"]
config.vm.synced_folder "./public", "/vagrant/public", id: "vagrant-public",
:owner => "vagrant",
:group => "www-data",
:mount_options => ["dmode=775","fmode=664"]

Have a look at this section of the Vagrant documentation http://docs.vagrantup.com/v2/synced-folders/basic_usage.html

Related

Issue configuring puppetlabs/apache module with Vagrant

I started using Vagrant and Puppet recently, and i am having bit of difficulty getting puppet to work.
With puppet i want to change apache user and group to vagrant to solve permission issue when sharing the folder.
I want to do it by using following puppet config
class { "apache":
user => "vagrant",
group => "vagrant",
}
Reference : http://ryansechrest.com/2014/04/unable-set-permissions-within-shared-folder-using-vagrant-virtualbox/
For this i installed puppet on my host and guest machine, on host machine i added following cofig in Vagrantfile
config.vm.provision :puppet do |puppet|
puppet.manifests_path = 'puppet/manifests'
puppet.module_path = 'puppet/modules'
end
And created the file puppet/manifests/default.pp on host machine with following content
node 'node1' {
include apache
class { "apache":
user => "vagrant",
group => "vagrant",
}
}
When i run vagrant provision, i get the following error
==> default: Error: Could not find default node or by name with 'localhost' on node localhost
==> default: Error: Could not find default node or by name with 'localhost' on node localhost
The SSH command responded with a non-zero exit status. Vagrant
assumes that this means the command failed. The output for this command
should be in the log above. Please read the output to determine what
went wrong.
Where am i going wrong?
Just keep it simple:
For this i installed puppet on my host and guest machine,
you only need puppet to be installed on your guest machine, you can keep your host clean
you reference and define puppet/manifests/default.pp which is fine, just remove the node part
Package {
allow_virtual => true,
}
class { "apache":
user => "vagrant",
group => "vagrant",
}
include apache
can you confirm you have an apache module in your host puppet/modules or installed on the guest - you can have provision to run something like
#!/bin/bash
mkdir -p /etc/puppet/modules;
if [ ! -d /etc/puppet/modules/puppetlabs-apache ]; then
puppet module install puppetlabs-apache
fi
assuming you talk about this apache module, else replace with the module you're using if it comes from the forge

Changing user during vagrant provisioning

I want to use vagrant to setup developer machines. Since the machine will talk to the servers inhouse, I thought it a good idea that they are setup with the same usernames the developers have on their host machine. I'm having trouble figuring out how to handle this in the provisioning step.
My simple Vagrantfile looks like this:
VAGRANT_COMMAND = ARGV[0]
Vagrant.configure(2) do |config|
user = ENV['USER']
config.vm.box = "ubuntu/trusty64"
config.vm.provision :shell, :path => "bootstrap.sh", :args => user
config.ssh.username = user
config.ssh.password = "heimskringla"
config.vm.synced_folder "~/src/", "/home/" + user + "/src"
config.vm.provision "file", source: "~/.gitconfig", destination: "/home/" + user + "/.gitconfig"
config.vm.provision "file", source: "~/.ssh", destination: "/home/" + user + "/.ssh"
end
bootstrap.sh takes $USER from the host machine as an input. If the user does not exist in the Vagrant machine, it is created and added to /etc/sudoers.d.
If I start with a clean slate and run "Vagrant up" on this, it starts using $USER at once, and since it does not exist yet, the setup fails.
As a test I've tried doing this:
if VAGRANT_COMMAND != "up"
config.ssh.username = user
config.ssh.password = "changeme"
end
Then the provisioning in bootstrap.sh works. The user is created, and my packages are installed. When it gets to the file and synced folder provisioning, however, it fails because of permission issues.
Failed to upload a file to the guest VM via SCP due to a permissions
error. This is normally because the SSH user doesn't have permission
to write to the destination location. Alternately, the user running
Vagrant on the host machine may not have permission to read the file.
I've tried doing "su $USER" in the bottom of bootstrap.sh, but that is apparently not the way it works.
Anyone know how I can fulfill my needs?
EDIT: possible solution
I decided not to work so hard to change Vagrant, and tried to use the vagrant user. Now I have the following Vagrantfile:
Vagrant.configure(2) do |config|
config.vm.box = "ubuntu/trusty64"
config.vm.provision :shell, :path => "vagrant/bootstrap.sh"
config.vm.synced_folder "~/src/", "/home/vagrant/src"
config.vm.provision "file", source: "~/.gitconfig", destination: ".gitconfig"
config.vm.provision "file", source: "~/.ssh", destination: ".ssh-from-host-machine"
config.vm.provision "file", source: "vagrant/.bash_aliases", destination: ".bash_aliases"
config.vm.provision :shell, privileged: false, :path => "vagrant/bootstrap_late.sh"
end
bootstrap.sh installs required packages, and bootstrap_late.sh does necessary setup for the vagrant user. This includes adding the ssh configs that makes it use $USER when talking to the server.

How do I use rsync shared folders in Vagrant on Windows?

I want to develop WordPress websites locally using Vagrant (Host: Windows 8 64-bit; Guest: Ubuntu 12.04 LTS). I am using Chris Wiegman's Primary Vagrant (an Apache version of VVV)
I got it working, but as soon as I added all my files the site ran incredibly slow. After research I'm guessing this is down to shared folders being slow. The work around as mention in this blog post on the Vagrant website, is to use rsync.
Despite their being no instructions on how to get rsync working on Windows, I came across this article which recommends the free version of cwrsync. I also had to add the path environmental variable so that rsync worked across all folders on Windows (this answer helped with this)
I edited the vagrant file so that rsync would be used by appending ,"rsync", rsync__exclude: ".git/" to the Primary Vagrant vagrant file:
config.vm.synced_folder "sites/stable.wordpress.vagrant", "/var/www/stable.wordpress.vagrant", :owner => "www-data", :mount_options => [ "dmode=775", "fmode=774" ],"rsync", rsync__exclude: ".git/"
config.vm.synced_folder "sites/stable.wordpress.vagrant/uploads", "/var/www/stable.wordpress.vagrant/wordpress/wp-content/uploads", :owner => "www-data", :mount_options => [ "dmode=775", "fmode=774" ],"rsync", rsync__exclude: ".git/"
config.vm.synced_folder "sites/trunk.wordpress.vagrant", "/var/www/trunk.wordpress.vagrant", :owner => "www-data", :mount_options => [ "dmode=775", "fmode=774" ],"rsync", rsync__exclude: ".git/"
config.vm.synced_folder "sites/trunk.wordpress.vagrant/uploads", "/var/www/trunk.wordpress.vagrant/wordpress/wp-content/uploads", :owner => "www-data", :mount_options => [ "dmode=775", "fmode=774" ],"rsync", rsync__exclude: ".git/"
config.vm.synced_folder "sites/Search-Replace-DB", "/var/www/replacedb.vagrant", :owner => "www-data", :mount_options => [ "dmode=775", "fmode=774" ],"rsync", rsync__exclude: ".git/"
config.vm.synced_folder "sites/phpmyadmin", "/var/www/phpmyadmin.vagrant", :owner => "www-data", :mount_options => [ "dmode=775", "fmode=774" ],"rsync", rsync__exclude: ".git/"
config.vm.synced_folder "sites/webgrind", "/var/www/webgrind.vagrant", :owner => "www-data", :mount_options => [ "dmode=775", "fmode=774" ],"rsync", rsync__exclude: ".git/"
Then I did a vagrant up --provision. But unfortunately I am getting the following error messages. Despite trying to find the issue online, I can't.
Here are the error messages:
==> default: Rsyncing folder: /cygdrive/c/Users/IanAnderson/Documents/Sites/Vagrants/Primary-Vagrant/vagrant-local/sites
/stable.wordpress.vagrant/ => /var/www/stable.wordpress.vagrant
==> default: - Exclude: [".vagrant/", ".git/"]
There was an error when attempting to rsync a synced folder.
Please inspect the error message below for more info.
Host path: /cygdrive/c/Users/IanAnderson/Documents/Sites/Vagrants/Primary-Vagrant/vagrant-local/sites/stable.wordpress.v
agrant/
Guest path: /var/www/stable.wordpress.vagrant
Command: rsync --verbose --archive --delete -z --chmod=ugo=rwX --no-perms -e ssh -p 2222 -o StrictHostKeyChecking=no -i
'C:/Users/IanAnderson/.vagrant.d/insecure_private_key' --exclude .vagrant/ --exclude .git/ /cygdrive/c/Users/IanAnderson
/Documents/Sites/Vagrants/Primary-Vagrant/vagrant-local/sites/stable.wordpress.vagrant/ vagrant#127.0.0.1:/var/www/stabl
e.wordpress.vagrant
Error: Warning: Permanently added '[127.0.0.1]:2222' (RSA) to the list of known hosts.
rsync: connection unexpectedly closed (0 bytes received so far) [Receiver]
rsync error: error in rsync protocol data stream (code 12) at io.c(605) [Receiver=3.0.9]
rsync: read error: Connection reset by peer (104)
rsync error: error in rsync protocol data stream (code 12) at io.c(759) [sender=3.0.6]
Try using MinGW. It brings its own ssh.exe in /bin
and rsync.exe in /msys/<version_number>/bin.
Adding these directories to my PATH made it work on my machine.
Adding to Sebastian Kliem's answer: for me it was necessary to add the MinGW /bin directory to the start of my PATH. I got the error you mentioned when using git's ssh with MinGW's rsync. Putting MinGW at the start made sure the two worked well together.
This is no rsync solution, but it works for sharing files to a windows host with better performace than regular virtual box shares.
I successfully used this plugin which starts a nfs daemon on windows: https://github.com/winnfsd/vagrant-winnfsd
I haven't tested it thoroughly because it is a work in progress and first time supporting windows on my project. It seems to do the trick and performs decently so far. Haven't tried it with MySQL data shared onto the host, which was the slowest resource of the server stack.
Also, i use it along the vagrant-bindfs plugin to route the user uid/gid. This probably ads overhead to the mix though but automates the whole process.
I know this question is older than the issue, but in case this might help someone: there is a known issue with Vagrant >=1.8.0 and Windows hosts that triggers this kind of error messages.
To prevent this, try removing the following lines (77 to 79) in $VAGRANT_HOME\embedded\gems\gems\vagrant-1.8.0\plugins\synced_folders\rsync\helper.rb :
"-o ControlMaster=auto " +
"-o ControlPath=#{controlpath} " +
"-o ControlPersist=10m " +
Source

config.vm.share_folder setting not found

I am getting this error with this line in my Vagrantfile during vagrant up, until I comment it out.
The setting is documented here:
http://docs-v1.vagrantup.com/v1/docs/config/vm/share_folder.html
Not sure why the following documented paramenter causes an error
config.vm.share_folder "puppetdir", "/etc/puppet", "/vagrant/mypuppetdir"
Bringing machine 'default' up with 'virtualbox' provider...
There are errors in the configuration of this machine. Please fix
the following errors and try again:
vm:
* The following settings don't exist: share_folder
The latest virtualbox and latest vagrant. everything else works fine.
On Vagrant 1.1+ you should use config.vm.synced_folder, the docs you are looking at are for older versions. Please refer to the updated documentation for more info: http://docs.vagrantup.com/v2/synced-folders/basic_usage.html
Shared Folders has been renamed to Synded Folder since 1.1.
In your Vagrantfile you should be using the following
config.vm.synced_folder "../data", "/vagrant_data"
# by default enabled, uncomment to disable
# config.vm.synced_folder ".", "/vagrant", disabled: true
NOTE: By default, Vagrant will share your project directory (the directory where Vagrantfile resides) to /vagrant.
config.vm.synced_folder ".", "/vagrant", disabled: true
More flexible example
vagrant_data = File.expand_path("../vagrant_data", __FILE__)
Dir::mkdir(vagrant_data) unless FileTest::directory?(vagrant_data)
config.vm.synced_folder "vagrant_data", "/vagrant_data"
Take a look at this for more information => shared folders VS synced folders
Extending from https://github.com/mitchellh/vagrant/issues/936#issuecomment-7179034
if you need to mount a volume as a user that doesn't exist when the vm boots you can get there like so:
# Vagrantfile line
config.vm.synced_folder "host_folder", "/svr/fake_mount_folder", id: "whatever_name"
# ...
config.vm.provision "shell", inline: <<-SHELL
# ...
# In my case a package installed a user with UID 110, GID 116
mount -t vboxsf -o uid=110,gid=116 whatever_name /media/actual_mounted_folder
# ...
SHELL

Vagrant failed permissions with nfs only when mounting to apache folders

I am using Linux Mint as Host and CentOS as guest, whenever i am trying to share a folder to an apache folder (example below) it fails and all other apache actions fail to.
config.vm.share_folder "apache", "/var/www/html", "../src", :extra => 'dmode=775,fmode=775', :nfs => (FFI::Platform::IS_WINDOWS ? false: true)
I get following error then:
error: unpacking of archive failed on file /var/www/html: cpio: chown failed - Operation not permitted
However, when i mount the folder to lets say /html, there is not a single problem and my vagrant runs clean.
I am desperatly trying to get things in the folders they are meant to be, any idea how i can fix this?
here we've having some kind of this problem too.
The way it worked here was to adjust the syntax of nfs exporting to:
config.vm.synced_folder ".", "/vagrant", :nfs => { :mount_options => ["dmode=777","fmode=777"] }
as stated in 26710386
note the :nfs line and mount options. You must to use it as
nfs => { :mount_options => ["dmode=777","fmode=777"] }
and not as the latter way type: "nfs", mount_options: ... was.
Hope it helps.

Resources