Skip to content

Commit f6be4ac

Browse files
committed
Add Vagrant config support
Adds a new `vagrant.default.yml` config file which is used for Vagrant related settings in `Vagrantfile.` `vagrant.local.yml` is also supported as a local, untracked config file which takes precedence over the default.
1 parent 1f165ea commit f6be4ac

File tree

4 files changed

+124
-78
lines changed

4 files changed

+124
-78
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
### HEAD
22
* Ansible 2.3 compatibility ([#813](https://github.com/roots/trellis/pull/813))
3+
* Add Vagrant config ([#828](https://github.com/roots/trellis/pull/828))
34
* Remove potentially dangerous `db_import` option ([#825](https://github.com/roots/trellis/pull/825))
45

56
### 1.0.0-rc.1: April 7th, 2017

Vagrantfile

+41-78
Original file line numberDiff line numberDiff line change
@@ -1,73 +1,50 @@
11
# -*- mode: ruby -*-
22
# vi: set ft=ruby :
33

4-
require 'yaml'
5-
6-
ip = '192.168.50.5' # pick any local IP
7-
cpus = 1
8-
memory = 1024 # in MB
9-
104
ANSIBLE_PATH = __dir__ # absolute path to Ansible directory on host machine
115
ANSIBLE_PATH_ON_VM = '/home/vagrant/trellis' # absolute path to Ansible directory on virtual machine
126

13-
# Set Ansible paths relative to Ansible directory
14-
ENV['ANSIBLE_CONFIG'] = ANSIBLE_PATH
15-
ENV['ANSIBLE_CALLBACK_PLUGINS'] = "~/.ansible/plugins/callback_plugins/:/usr/share/ansible_plugins/callback_plugins:#{File.join(ANSIBLE_PATH, 'lib/trellis/plugins/callback')}"
16-
ENV['ANSIBLE_FILTER_PLUGINS'] = "~/.ansible/plugins/filter_plugins/:/usr/share/ansible_plugins/filter_plugins:#{File.join(ANSIBLE_PATH, 'lib/trellis/plugins/filter')}"
17-
ENV['ANSIBLE_LIBRARY'] = "/usr/share/ansible:#{File.join(ANSIBLE_PATH, 'lib/trellis/modules')}"
18-
ENV['ANSIBLE_ROLES_PATH'] = File.join(ANSIBLE_PATH, 'vendor', 'roles')
19-
ENV['ANSIBLE_VARS_PLUGINS'] = "~/.ansible/plugins/vars_plugins/:/usr/share/ansible_plugins/vars_plugins:#{File.join(ANSIBLE_PATH, 'lib/trellis/plugins/vars')}"
7+
require File.join(ANSIBLE_PATH, 'lib', 'trellis', 'vagrant')
8+
require 'yaml'
209

21-
config_file = File.join(ANSIBLE_PATH, 'group_vars', 'development', 'wordpress_sites.yml')
10+
vconfig = YAML.load_file("#{ANSIBLE_PATH}/vagrant.default.yml")
2211

23-
def fail_with_message(msg)
24-
fail Vagrant::Errors::VagrantError.new, msg
12+
if File.exist?("#{ANSIBLE_PATH}/vagrant.local.yml")
13+
local_config = YAML.load_file("#{ANSIBLE_PATH}/vagrant.local.yml")
14+
vconfig.merge!(local_config) if local_config
2515
end
2616

27-
if File.exists?(config_file)
28-
wordpress_sites = YAML.load_file(config_file)['wordpress_sites']
29-
fail_with_message "No sites found in #{config_file}." if wordpress_sites.to_h.empty?
30-
else
31-
fail_with_message "#{config_file} was not found. Please set `ANSIBLE_PATH` in your Vagrantfile."
32-
end
17+
wordpress_sites = load_wordpress_sites
18+
site_hosts = hosts(wordpress_sites)
3319

3420
Vagrant.require_version '>= 1.8.5'
3521

3622
Vagrant.configure('2') do |config|
37-
config.vm.box = 'bento/ubuntu-16.04'
38-
config.vm.box_version = '2.2.9'
23+
config.vm.box = vconfig.fetch('vagrant_box')
24+
config.vm.box_version = vconfig.fetch('vagrant_box_version')
3925
config.ssh.forward_agent = true
40-
4126
config.vm.post_up_message = post_up_message
4227

4328
# Fix for: "stdin: is not a tty"
4429
# https://github.com/mitchellh/vagrant/issues/1673#issuecomment-28288042
4530
config.ssh.shell = %{bash -c 'BASH_ENV=/etc/profile exec bash'}
4631

4732
# Required for NFS to work
48-
config.vm.network :private_network, ip: ip, hostsupdater: 'skip'
49-
50-
site_hosts = wordpress_sites.flat_map { |(_name, site)| site['site_hosts'] }
51-
52-
site_hosts.each do |host|
53-
if !host.is_a?(Hash) or !host.has_key?('canonical')
54-
fail_with_message File.read(File.join(ANSIBLE_PATH, 'roles/common/templates/site_hosts.j2')).sub!('{{ env }}', 'development').gsub!(/com$/, 'dev')
55-
end
56-
end
33+
config.vm.network :private_network, ip: vconfig.fetch('vagrant_ip'), hostsupdater: 'skip'
5734

5835
main_hostname, *hostnames = site_hosts.map { |host| host['canonical'] }
5936
config.vm.hostname = main_hostname
6037

61-
redirects = site_hosts.flat_map { |host| host['redirects'] }.compact
62-
6338
if Vagrant.has_plugin?('vagrant-hostmanager') && !multisite_subdomains?(wordpress_sites)
39+
redirects = site_hosts.flat_map { |host| host['redirects'] }.compact
40+
6441
config.hostmanager.enabled = true
6542
config.hostmanager.manage_host = true
6643
config.hostmanager.aliases = hostnames + redirects
6744
elsif Vagrant.has_plugin?('landrush') && multisite_subdomains?(wordpress_sites)
6845
config.landrush.enabled = true
6946
config.landrush.tld = config.vm.hostname
70-
hostnames.each { |host| config.landrush.host host, ip }
47+
hostnames.each { |host| config.landrush.host host, vconfig.fetch('vagrant_ip') }
7148
else
7249
fail_with_message "vagrant-hostmanager missing, please install the plugin with this command:\nvagrant plugin install vagrant-hostmanager\n\nOr install landrush for multisite subdomains:\nvagrant plugin install landrush"
7350
end
@@ -78,6 +55,7 @@ Vagrant.configure('2') do |config|
7855
wordpress_sites.each_pair do |name, site|
7956
config.vm.synced_folder local_site_path(site), remote_site_path(name, site), owner: 'vagrant', group: 'www-data', mount_options: ['dmode=776', 'fmode=775']
8057
end
58+
8159
config.vm.synced_folder ANSIBLE_PATH, ANSIBLE_PATH_ON_VM, mount_options: ['dmode=755', 'fmode=644']
8260
config.vm.synced_folder File.join(ANSIBLE_PATH, 'bin'), bin_path, mount_options: ['dmode=755', 'fmode=755']
8361
else
@@ -88,37 +66,49 @@ Vagrant.configure('2') do |config|
8866
config.vm.synced_folder local_site_path(site), nfs_path(name), type: 'nfs'
8967
config.bindfs.bind_folder nfs_path(name), remote_site_path(name, site), u: 'vagrant', g: 'www-data', o: 'nonempty'
9068
end
69+
9170
config.vm.synced_folder ANSIBLE_PATH, '/ansible-nfs', type: 'nfs'
9271
config.bindfs.bind_folder '/ansible-nfs', ANSIBLE_PATH_ON_VM, o: 'nonempty', p: '0644,a+D'
9372
config.bindfs.bind_folder bin_path, bin_path, perms: '0755'
9473
end
9574
end
9675

76+
vconfig.fetch('vagrant_synced_folders', []).each do |folder|
77+
options = {
78+
type: folder.fetch('type', 'nfs'),
79+
create: folder.fetch('create', false),
80+
mount_options: folder.fetch('mount_options', [])
81+
}
82+
83+
config.vm.synced_folder folder['local_path'], folder['destination'], options
84+
85+
if folder.fetch('bindfs', true)
86+
config.bindfs.bind_folder folder['local_path'], folder['destination'], options
87+
end
88+
end
89+
9790
provisioner = Vagrant::Util::Platform.windows? ? :ansible_local : :ansible
9891
provisioning_path = Vagrant::Util::Platform.windows? ? ANSIBLE_PATH_ON_VM : ANSIBLE_PATH
92+
9993
config.vm.provision provisioner do |ansible|
10094
if Vagrant::Util::Platform.windows?
10195
ansible.install_mode = 'pip'
10296
ansible.provisioning_path = provisioning_path
103-
ansible.version = '2.2.0'
97+
ansible.version = vconfig.fetch('vagrant_ansible_version')
10498
end
10599

106100
ansible.playbook = File.join(provisioning_path, 'dev.yml')
107-
unless ENV['SKIP_GALAXY']
108-
ansible.galaxy_role_file = File.join(provisioning_path, 'requirements.yml')
109-
end
101+
ansible.galaxy_role_file = File.join(provisioning_path, 'requirements.yml') unless vconfig.fetch('vagrant_skip_galaxy') || ENV['SKIP_GALAXY']
110102
ansible.galaxy_roles_path = File.join(provisioning_path, 'vendor/roles')
111103

112104
ansible.groups = {
113105
'web' => ['default'],
114106
'development' => ['default']
115107
}
116108

117-
if tags = ENV['ANSIBLE_TAGS']
118-
ansible.tags = tags
119-
end
109+
ansible.tags = ENV['ANSIBLE_TAGS']
110+
ansible.extra_vars = { 'vagrant_version' => Vagrant::VERSION }
120111

121-
ansible.extra_vars = {'vagrant_version' => Vagrant::VERSION}
122112
if vars = ENV['ANSIBLE_VARS']
123113
extra_vars = Hash[vars.split(',').map { |pair| pair.split('=') }]
124114
ansible.extra_vars.merge(extra_vars)
@@ -128,8 +118,8 @@ Vagrant.configure('2') do |config|
128118
# Virtualbox settings
129119
config.vm.provider 'virtualbox' do |vb|
130120
vb.name = config.vm.hostname
131-
vb.customize ['modifyvm', :id, '--cpus', cpus]
132-
vb.customize ['modifyvm', :id, '--memory', memory]
121+
vb.customize ['modifyvm', :id, '--cpus', vconfig.fetch('vagrant_cpus')]
122+
vb.customize ['modifyvm', :id, '--memory', vconfig.fetch('vagrant_memory')]
133123

134124
# Fix for slow external network connections
135125
vb.customize ['modifyvm', :id, '--natdnshostresolver1', 'on']
@@ -140,43 +130,16 @@ Vagrant.configure('2') do |config|
140130
['vmware_fusion', 'vmware_workstation'].each do |provider|
141131
config.vm.provider provider do |vmw, override|
142132
vmw.name = config.vm.hostname
143-
vmw.vmx['numvcpus'] = cpus
144-
vmw.vmx['memsize'] = memory
133+
vmw.vmx['numvcpus'] = vconfig.fetch('vagrant_cpus')
134+
vmw.vmx['memsize'] = vconfig.fetch('vagrant_memory')
145135
end
146136
end
147137

148138
# Parallels settings
149139
config.vm.provider 'parallels' do |prl, override|
150140
prl.name = config.vm.hostname
151-
prl.cpus = cpus
141+
prl.cpus = vconfig.fetch('vagrant_cpus')
142+
prl.memory = vconfig.fetch('vagrant_memory')
152143
prl.update_guest_tools = true
153-
prl.memory = memory
154144
end
155-
156-
end
157-
158-
def local_site_path(site)
159-
File.expand_path(site['local_path'], ANSIBLE_PATH)
160-
end
161-
162-
def multisite_subdomains?(wordpress_sites)
163-
wordpress_sites.any? { |(_name, site)| site['multisite'].fetch('enabled', false) && site['multisite'].fetch('subdomains', false) }
164-
end
165-
166-
def nfs_path(site_name)
167-
"/vagrant-nfs-#{site_name}"
168-
end
169-
170-
def post_up_message
171-
msg = 'Your Trellis Vagrant box is ready to use!'
172-
msg << "\n* Composer and WP-CLI commands need to be run on the virtual machine."
173-
msg << "\n* You can SSH into the machine with `vagrant ssh`."
174-
msg << "\n* Then navigate to your WordPress sites at `/srv/www`"
175-
msg << "\n or to your Trellis files at `#{ANSIBLE_PATH_ON_VM}`."
176-
177-
msg
178-
end
179-
180-
def remote_site_path(site_name, site)
181-
"/srv/www/#{site_name}/#{site['current_path'] || 'current'}"
182145
end

lib/trellis/vagrant.rb

+64
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
# Set Ansible paths relative to Ansible directory
2+
ENV['ANSIBLE_CONFIG'] = ANSIBLE_PATH
3+
ENV['ANSIBLE_CALLBACK_PLUGINS'] = "~/.ansible/plugins/callback_plugins/:/usr/share/ansible_plugins/callback_plugins:#{File.join(ANSIBLE_PATH, 'lib/trellis/plugins/callback')}"
4+
ENV['ANSIBLE_FILTER_PLUGINS'] = "~/.ansible/plugins/filter_plugins/:/usr/share/ansible_plugins/filter_plugins:#{File.join(ANSIBLE_PATH, 'lib/trellis/plugins/filter')}"
5+
ENV['ANSIBLE_LIBRARY'] = "/usr/share/ansible:#{File.join(ANSIBLE_PATH, 'lib/trellis/modules')}"
6+
ENV['ANSIBLE_ROLES_PATH'] = File.join(ANSIBLE_PATH, 'vendor', 'roles')
7+
ENV['ANSIBLE_VARS_PLUGINS'] = "~/.ansible/plugins/vars_plugins/:/usr/share/ansible_plugins/vars_plugins:#{File.join(ANSIBLE_PATH, 'lib/trellis/plugins/vars')}"
8+
9+
def fail_with_message(msg)
10+
fail Vagrant::Errors::VagrantError.new, msg
11+
end
12+
13+
def load_wordpress_sites
14+
config_file = File.join(ANSIBLE_PATH, 'group_vars', 'development', 'wordpress_sites.yml')
15+
16+
if File.exists?(config_file)
17+
wordpress_sites = YAML.load_file(config_file)['wordpress_sites']
18+
fail_with_message "No sites found in #{config_file}." if wordpress_sites.to_h.empty?
19+
else
20+
fail_with_message "#{config_file} was not found. Please set `ANSIBLE_PATH` in your Vagrantfile."
21+
end
22+
23+
wordpress_sites
24+
end
25+
26+
def local_site_path(site)
27+
File.expand_path(site['local_path'], ANSIBLE_PATH)
28+
end
29+
30+
def multisite_subdomains?(wordpress_sites)
31+
wordpress_sites.any? do |(_name, site)|
32+
site['multisite'].fetch('enabled', false) && site['multisite'].fetch('subdomains', false)
33+
end
34+
end
35+
36+
def nfs_path(site_name)
37+
"/vagrant-nfs-#{site_name}"
38+
end
39+
40+
def post_up_message
41+
msg = 'Your Trellis Vagrant box is ready to use!'
42+
msg << "\n* Composer and WP-CLI commands need to be run on the virtual machine."
43+
msg << "\n* You can SSH into the machine with `vagrant ssh`."
44+
msg << "\n* Then navigate to your WordPress sites at `/srv/www`"
45+
msg << "\n or to your Trellis files at `#{ANSIBLE_PATH_ON_VM}`."
46+
47+
msg
48+
end
49+
50+
def remote_site_path(site_name, site)
51+
"/srv/www/#{site_name}/#{site['current_path'] || 'current'}"
52+
end
53+
54+
def hosts(sites)
55+
site_hosts = sites.flat_map { |(_name, site)| site['site_hosts'] }
56+
57+
site_hosts.each do |host|
58+
if !host.is_a?(Hash) || !host.has_key?('canonical')
59+
fail_with_message File.read(File.join(ANSIBLE_PATH, 'roles/common/templates/site_hosts.j2')).sub!('{{ env }}', 'development').gsub!(/com$/, 'dev')
60+
end
61+
end
62+
63+
site_hosts
64+
end

vagrant.default.yml

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
---
2+
vagrant_ip: '192.168.50.5'
3+
vagrant_cpus: 1
4+
vagrant_memory: 1024 # in MB
5+
vagrant_box: 'bento/ubuntu-16.04'
6+
vagrant_box_version: '2.2.9'
7+
vagrant_ansible_version: '2.2.2'
8+
vagrant_skip_galaxy: false
9+
10+
# Array of synced folders:
11+
# - local_path: .
12+
# destination: /path/on/vm
13+
# create: false
14+
# type: nfs
15+
# bindfs: true
16+
# mount_options: []
17+
# See https://www.vagrantup.com/docs/synced-folders/basic_usage.html#mount_options
18+
vagrant_synced_folders: []

0 commit comments

Comments
 (0)