agaric-coop/box/lib/drupalvm/vagrant.rb

139 lines
3.9 KiB
Ruby

require 'yaml'
# Cross-platform way of finding an executable in the $PATH.
def which(cmd)
exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : ['']
ENV['PATH'].split(File::PATH_SEPARATOR).each do |path|
exts.each do |ext|
exe = File.join(path, "#{cmd}#{ext}")
return exe if File.executable?(exe) && !File.directory?(exe)
end
end
nil
end
# Recursively walk an tree and run provided block on each value found.
def walk(obj, &fn)
if obj.is_a?(Array)
obj.map { |value| walk(value, &fn) }
elsif obj.is_a?(Hash)
obj.each_pair { |key, value| obj[key] = walk(value, &fn) }
else
obj = yield(obj)
end
end
# Resolve jinja variables in hash.
def resolve_jinja_variables(vconfig)
walk(vconfig) do |value|
while value.is_a?(String) && value.match(/{{ .* }}/)
value = value.gsub(/{{ (.*?) }}/) { vconfig[Regexp.last_match(1)] }
end
value
end
end
# Return the combined configuration content all files provided.
def load_config(files)
vconfig = {}
files.each do |config_file|
if File.exist?(config_file)
optional_config = YAML.load_file(config_file)
vconfig.merge!(optional_config) if optional_config
end
end
resolve_jinja_variables(vconfig)
end
# Return the path to the ansible-playbook executable.
def ansible_bin
@ansible_bin ||= which('ansible-playbook')
end
# Return the ansible version parsed from running the executable path provided.
def ansible_version
/^[^\s]+ (.+)$/.match(`#{ansible_bin} --version`) { |match| return match[1] }
end
# Require that if installed, the ansible version meets the requirements.
def require_ansible_version(requirement)
return unless ansible_bin
req = Gem::Requirement.new(requirement)
return if req.satisfied_by?(Gem::Version.new(ansible_version))
raise_message "You must install an Ansible version #{requirement} to use this version of Drupal VM."
end
def raise_message(msg)
raise Vagrant::Errors::VagrantError.new, msg
end
# Return which Vagrant provisioner to use.
def vagrant_provisioner
ansible_bin ? :ansible : :ansible_local
end
def ensure_plugins(plugins)
logger = Vagrant::UI::Colored.new
installed = false
plugins.each do |plugin|
plugin_name = plugin['name']
manager = Vagrant::Plugin::Manager.instance
next if manager.installed_plugins.key?(plugin_name)
logger.warn("Installing plugin #{plugin_name}")
manager.install_plugin(
plugin_name,
sources: plugin.fetch('source', %w[https://rubygems.org/ https://gems.hashicorp.com/]),
version: plugin['version']
)
installed = true
end
return unless installed
logger.warn('`vagrant up` must be re-run now that plugins are installed')
exit
end
def get_apache_vhosts(vhosts)
aliases = []
vhosts.each do |host|
aliases.push(host['servername'])
aliases.concat(host['serveralias'].split) if host['serveralias']
end
aliases
end
def get_nginx_vhosts(vhosts)
aliases = []
vhosts.each do |host|
aliases.push(host['server_name'])
aliases.concat(host['server_name_redirect'].split) if host['server_name_redirect']
end
aliases
end
# Return a list of all virtualhost server names and aliases from a config hash.
def get_vhost_aliases(vconfig)
if vconfig['drupalvm_webserver'] == 'apache'
aliases = get_apache_vhosts(vconfig['apache_vhosts'])
else
# @todo shim for `nginx_hosts`.
aliases = get_nginx_vhosts(vconfig.fetch('nginx_hosts', vconfig['nginx_vhosts']))
end
aliases = aliases.uniq - [vconfig['vagrant_ip']]
# Remove wildcard subdomains.
aliases.delete_if { |vhost| vhost.include?('*') }
end
# Return a default post_up_message.
def get_default_post_up_message(vconfig)
'Your Drupal VM Vagrant box is ready to use!'\
"\n* Visit the dashboard for an overview of your site: http://dashboard.#{vconfig['vagrant_hostname']} (or http://#{vconfig['vagrant_ip']})"\
"\n* You can SSH into your machine with `vagrant ssh`."\
"\n* Find out more in the Drupal VM documentation at http://docs.drupalvm.com"
end