Skip to content
This repository was archived by the owner on Feb 13, 2023. It is now read-only.

Commit f27806c

Browse files
authored
Merge pull request #1332 from oxyc/vagrantfile-cleanup
Vagrantfile cleanup
2 parents 90c671d + e3f5751 commit f27806c

File tree

3 files changed

+147
-101
lines changed

3 files changed

+147
-101
lines changed

.travis.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ script:
8989
- '[[ ! -z "${local_config}" ]] && docker exec ${container_id} bash -c "cp ${DRUPALVM_DIR}/${local_config} ${config_dir:-$DRUPALVM_DIR}/local.config.yml" || true'
9090

9191
# Vagrantfile syntax check.
92-
- 'rubocop ./Vagrantfile --except LineLength,Eval,MutableConstant,BlockLength'
92+
- 'rubocop ./Vagrantfile ./lib/drupalvm --except LineLength,Eval,MutableConstant,BlockLength,ConditionalAssignment,IndentArray,AlignParameters'
9393

9494
# Ansible syntax check.
9595
- 'docker exec --tty ${container_id} env TERM=xterm ansible-playbook ${DRUPALVM_DIR}/provisioning/playbook.yml --syntax-check'

Vagrantfile

Lines changed: 35 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# -*- mode: ruby -*-
22
# vi: set ft=ruby :
3-
VAGRANTFILE_API_VERSION = '2' unless defined? VAGRANTFILE_API_VERSION
3+
4+
require './lib/drupalvm/vagrant'
45

56
# Absolute paths on the host machine.
67
host_drupalvm_dir = File.dirname(File.expand_path(__FILE__))
@@ -14,58 +15,19 @@ guest_config_dir = ENV['DRUPALVM_CONFIG_DIR'] ? "/vagrant/#{ENV['DRUPALVM_CONFIG
1415

1516
drupalvm_env = ENV['DRUPALVM_ENV'] || 'vagrant'
1617

17-
# Cross-platform way of finding an executable in the $PATH.
18-
def which(cmd)
19-
exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : ['']
20-
ENV['PATH'].split(File::PATH_SEPARATOR).each do |path|
21-
exts.each do |ext|
22-
exe = File.join(path, "#{cmd}#{ext}")
23-
return exe if File.executable?(exe) && !File.directory?(exe)
24-
end
25-
end
26-
nil
27-
end
28-
29-
def get_ansible_version(exe)
30-
/^[^\s]+ (.+)$/.match(`#{exe} --version`) { |match| return match[1] }
31-
end
32-
33-
def walk(obj, &fn)
34-
if obj.is_a?(Array)
35-
obj.map { |value| walk(value, &fn) }
36-
elsif obj.is_a?(Hash)
37-
obj.each_pair { |key, value| obj[key] = walk(value, &fn) }
38-
else
39-
obj = yield(obj)
40-
end
18+
default_config_file = "#{host_drupalvm_dir}/default.config.yml"
19+
unless File.exist?(default_config_file)
20+
raise_message "Configuration file not found! Expected in #{default_config_file}"
4121
end
4222

43-
require 'yaml'
44-
# Load default VM configurations.
45-
vconfig = YAML.load_file("#{host_drupalvm_dir}/default.config.yml")
46-
# Use optional config.yml and local.config.yml for configuration overrides.
47-
['config.yml', 'local.config.yml', "#{drupalvm_env}.config.yml"].each do |config_file|
48-
if File.exist?("#{host_config_dir}/#{config_file}")
49-
optional_config = YAML.load_file("#{host_config_dir}/#{config_file}")
50-
vconfig.merge!(optional_config) if optional_config
51-
end
52-
end
53-
54-
# Replace jinja variables in config.
55-
vconfig = walk(vconfig) do |value|
56-
while value.is_a?(String) && value.match(/{{ .* }}/)
57-
value = value.gsub(/{{ (.*?) }}/) { vconfig[Regexp.last_match(1)] }
58-
end
59-
value
60-
end
61-
62-
Vagrant.require_version ">= #{vconfig['drupalvm_vagrant_version_min']}"
63-
64-
ansible_bin = which('ansible-playbook')
65-
ansible_version = Gem::Version.new(get_ansible_version(ansible_bin)) if ansible_bin
66-
ansible_version_min = Gem::Version.new(vconfig['drupalvm_ansible_version_min'])
23+
vconfig = load_config([
24+
default_config_file,
25+
"#{host_config_dir}/config.yml",
26+
"#{host_config_dir}/local.config.yml",
27+
"#{host_config_dir}/#{drupalvm_env}.config.yml"
28+
])
6729

68-
provisioner = ansible_bin && !vconfig['force_ansible_local'] ? :ansible : :ansible_local
30+
provisioner = vconfig['force_ansible_local'] ? :ansible_local : vagrant_provisioner
6931
if provisioner == :ansible
7032
playbook = "#{host_drupalvm_dir}/provisioning/playbook.yml"
7133
config_dir = host_config_dir
@@ -74,23 +36,23 @@ else
7436
config_dir = guest_config_dir
7537
end
7638

77-
if provisioner == :ansible && ansible_version < ansible_version_min
78-
raise Vagrant::Errors::VagrantError.new, "You must update Ansible to at least #{ansible_version_min} to use this version of Drupal VM."
79-
end
39+
# Verify version requirements.
40+
require_ansible_version ">= #{vconfig['drupalvm_ansible_version_min']}"
41+
Vagrant.require_version ">= #{vconfig['drupalvm_vagrant_version_min']}"
42+
43+
Vagrant.configure('2') do |config|
44+
# Set the name of the VM. See: http://stackoverflow.com/a/17864388/100134
45+
config.vm.define vconfig['vagrant_machine_name']
8046

81-
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
8247
# Networking configuration.
8348
config.vm.hostname = vconfig['vagrant_hostname']
84-
if vconfig['vagrant_ip'] == '0.0.0.0' && Vagrant.has_plugin?('vagrant-auto_network')
85-
config.vm.network :private_network, ip: vconfig['vagrant_ip'], auto_network: true
86-
else
87-
config.vm.network :private_network, ip: vconfig['vagrant_ip']
88-
end
49+
config.vm.network :private_network,
50+
ip: vconfig['vagrant_ip'],
51+
auto_network: vconfig['vagrant_ip'] == '0.0.0.0' && Vagrant.has_plugin?('vagrant-auto_network')
8952

90-
if !vconfig['vagrant_public_ip'].empty? && vconfig['vagrant_public_ip'] == '0.0.0.0'
91-
config.vm.network :public_network
92-
elsif !vconfig['vagrant_public_ip'].empty?
93-
config.vm.network :public_network, ip: vconfig['vagrant_public_ip']
53+
unless vconfig['vagrant_public_ip'].empty?
54+
config.vm.network :public_network,
55+
ip: vconfig['vagrant_public_ip'] != '0.0.0.0' ? vconfig['vagrant_public_ip'] : nil
9456
end
9557

9658
# SSH options.
@@ -100,32 +62,11 @@ Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
10062
# Vagrant box.
10163
config.vm.box = vconfig['vagrant_box']
10264

103-
if vconfig.include?('vagrant_post_up_message')
104-
config.vm.post_up_message = vconfig['vagrant_post_up_message']
105-
else
106-
config.vm.post_up_message = 'Your Drupal VM Vagrant box is ready to use!'\
107-
"\n* Visit the dashboard for an overview of your site: http://dashboard.#{vconfig['vagrant_hostname']} (or http://#{vconfig['vagrant_ip']})"\
108-
"\n* You can SSH into your machine with `vagrant ssh`."\
109-
"\n* Find out more in the Drupal VM documentation at http://docs.drupalvm.com"
110-
end
65+
# Display an introduction message after `vagrant up` and `vagrant provision`.
66+
config.vm.post_up_message = vconfig.fetch('vagrant_post_up_message', get_default_post_up_message(vconfig))
11167

11268
# If a hostsfile manager plugin is installed, add all server names as aliases.
113-
aliases = []
114-
if vconfig['drupalvm_webserver'] == 'apache'
115-
vconfig['apache_vhosts'].each do |host|
116-
aliases.push(host['servername'])
117-
aliases.concat(host['serveralias'].split) if host['serveralias']
118-
end
119-
else
120-
vconfig['nginx_hosts'].each do |host|
121-
aliases.concat(host['server_name'].split)
122-
aliases.concat(host['server_name_redirect'].split) if host['server_name_redirect']
123-
end
124-
end
125-
aliases = aliases.uniq - [config.vm.hostname, vconfig['vagrant_ip']]
126-
# Remove wildcard subdomains.
127-
aliases.delete_if { |vhost| vhost.include?('*') }
128-
69+
aliases = get_vhost_aliases(vconfig) - [config.vm.hostname]
12970
if Vagrant.has_plugin?('vagrant-hostsupdater')
13071
config.hostsupdater.aliases = aliases
13172
elsif Vagrant.has_plugin?('vagrant-hostmanager')
@@ -137,20 +78,17 @@ Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
13778
# Synced folders.
13879
vconfig['vagrant_synced_folders'].each do |synced_folder|
13980
options = {
140-
type: synced_folder.include?('type') ? synced_folder['type'] : vconfig['vagrant_synced_folder_default_type'],
141-
rsync__auto: 'true',
81+
type: synced_folder.fetch('type', vconfig['vagrant_synced_folder_default_type']),
14282
rsync__exclude: synced_folder['excluded_paths'],
143-
rsync__args: ['--verbose', '--archive', '--delete', '-z', '--chmod=ugo=rwX'],
83+
rsync__args: ['--verbose', '--archive', '--delete', '-z', '--copy-links', '--chmod=ugo=rwX'],
14484
id: synced_folder['id'],
145-
create: synced_folder.include?('create') ? synced_folder['create'] : false,
146-
mount_options: synced_folder.include?('mount_options') ? synced_folder['mount_options'] : []
85+
create: synced_folder.fetch('create', false),
86+
mount_options: synced_folder.fetch('mount_options', [])
14787
}
148-
if synced_folder.include?('options_override')
149-
synced_folder['options_override'].each do |key, value|
150-
options[key.to_sym] = value
151-
end
88+
synced_folder.fetch('options_override', {}).each do |key, value|
89+
options[key.to_sym] = value
15290
end
153-
config.vm.synced_folder synced_folder['local_path'], synced_folder['destination'], options
91+
config.vm.synced_folder synced_folder.fetch('local_path'), synced_folder.fetch('destination'), options
15492
end
15593

15694
# Allow override of the default synced folder type.
@@ -196,9 +134,6 @@ Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
196134
p.update_guest_tools = true
197135
end
198136

199-
# Set the name of the VM. See: http://stackoverflow.com/a/17864388/100134
200-
config.vm.define vconfig['vagrant_machine_name']
201-
202137
# Cache packages and dependencies if vagrant-cachier plugin is present.
203138
if Vagrant.has_plugin?('vagrant-cachier')
204139
config.cache.scope = :box

lib/drupalvm/vagrant.rb

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
require 'yaml'
2+
3+
# Cross-platform way of finding an executable in the $PATH.
4+
def which(cmd)
5+
exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : ['']
6+
ENV['PATH'].split(File::PATH_SEPARATOR).each do |path|
7+
exts.each do |ext|
8+
exe = File.join(path, "#{cmd}#{ext}")
9+
return exe if File.executable?(exe) && !File.directory?(exe)
10+
end
11+
end
12+
nil
13+
end
14+
15+
# Recursively walk an tree and run provided block on each value found.
16+
def walk(obj, &fn)
17+
if obj.is_a?(Array)
18+
obj.map { |value| walk(value, &fn) }
19+
elsif obj.is_a?(Hash)
20+
obj.each_pair { |key, value| obj[key] = walk(value, &fn) }
21+
else
22+
obj = yield(obj)
23+
end
24+
end
25+
26+
# Resolve jinja variables in hash.
27+
def resolve_jinja_variables(vconfig)
28+
walk(vconfig) do |value|
29+
while value.is_a?(String) && value.match(/{{ .* }}/)
30+
value = value.gsub(/{{ (.*?) }}/) { vconfig[Regexp.last_match(1)] }
31+
end
32+
value
33+
end
34+
end
35+
36+
# Return the combined configuration content all files provided.
37+
def load_config(files)
38+
vconfig = {}
39+
files.each do |config_file|
40+
if File.exist?(config_file)
41+
optional_config = YAML.load_file(config_file)
42+
vconfig.merge!(optional_config) if optional_config
43+
end
44+
end
45+
resolve_jinja_variables(vconfig)
46+
end
47+
48+
# Return the path to the ansible-playbook executable.
49+
def ansible_bin
50+
@ansible_bin ||= which('ansible-playbook')
51+
end
52+
53+
# Return the ansible version parsed from running the executable path provided.
54+
def ansible_version
55+
/^[^\s]+ (.+)$/.match(`#{ansible_bin} --version`) { |match| return match[1] }
56+
end
57+
58+
# Require that if installed, the ansible version meets the requirements.
59+
def require_ansible_version(requirement)
60+
return unless ansible_bin
61+
req = Gem::Requirement.new(requirement)
62+
return if req.satisfied_by?(Gem::Version.new(ansible_version))
63+
raise_message "You must install an Ansible version #{requirement} to use this version of Drupal VM."
64+
end
65+
66+
def raise_message(msg)
67+
raise Vagrant::Errors::VagrantError.new, msg
68+
end
69+
70+
# Return which Vagrant provisioner to use.
71+
def vagrant_provisioner
72+
ansible_bin ? :ansible : :ansible_local
73+
end
74+
75+
def get_apache_vhosts(vhosts)
76+
aliases = []
77+
vhosts.each do |host|
78+
aliases.push(host['servername'])
79+
aliases.concat(host['serveralias'].split) if host['serveralias']
80+
end
81+
aliases
82+
end
83+
84+
def get_nginx_vhosts(vhosts)
85+
aliases = []
86+
vhosts.each do |host|
87+
aliases.push(host['server_name'])
88+
aliases.concat(host['server_name_redirect'].split) if host['server_name_redirect']
89+
end
90+
aliases
91+
end
92+
93+
# Return a list of all virtualhost server names and aliases from a config hash.
94+
def get_vhost_aliases(vconfig)
95+
if vconfig['drupalvm_webserver'] == 'apache'
96+
aliases = get_apache_vhosts(vconfig['apache_vhosts'])
97+
else
98+
aliases = get_nginx_vhosts(vconfig['nginx_hosts'])
99+
end
100+
aliases = aliases.uniq - [vconfig['vagrant_ip']]
101+
# Remove wildcard subdomains.
102+
aliases.delete_if { |vhost| vhost.include?('*') }
103+
end
104+
105+
# Return a default post_up_message.
106+
def get_default_post_up_message(vconfig)
107+
'Your Drupal VM Vagrant box is ready to use!'\
108+
"\n* Visit the dashboard for an overview of your site: http://dashboard.#{vconfig['vagrant_hostname']} (or http://#{vconfig['vagrant_ip']})"\
109+
"\n* You can SSH into your machine with `vagrant ssh`."\
110+
"\n* Find out more in the Drupal VM documentation at http://docs.drupalvm.com"
111+
end

0 commit comments

Comments
 (0)