# -*- mode: ruby -*- # vi: set ft=ruby : # VAGRANTFILE 2022-08-08 require 'yaml' require 'mkmf' require 'fileutils' require 'socket' if Vagrant.has_plugin? 'vagrant-hostsupdater' puts '' puts 'Your Vagrant environment seems to be from an older version of Seravo Vagrant box.' puts 'To use the latest Seravo Vagrant box, take the following steps to clean up the old one:' puts '' puts '- Remove plugin "vagrant-hostsupdater", it\'s no longer supported:' puts ' * `vagrant plugin uninstall vagrant-hostsupdater`' puts ' * `vagrant plugin --local uninstall vagrant-hostsupdater`' puts '' puts '- Also be sure to destroy any old machines. You can view the existing machines:' puts ' * `vagrant status`' puts ' * `vagrant global-status`' exit 1 end # Prevent logs from mkmf module MakeMakefile::Logging @logfile = File::NULL end DIR = File.dirname(__FILE__) # Create .vagrant folder unless File.exist?(File.join(DIR,'.vagrant')) FileUtils.mkdir_p( File.join(DIR,'.vagrant') ) end # Create config file config_file = File.join(DIR, 'config.yml') sample_file = File.join(DIR, 'config-sample.yml') unless File.exists?(config_file) # Use sample instead FileUtils.copy sample_file, config_file puts '==> default: config.yml was not found. Copying defaults from sample configs..' end site_config = YAML.load_file(config_file) # Create private ip address in file private_ip_file = File.join(DIR,'.vagrant','private.ip') private_ip = nil if File.exists?(private_ip_file) private_ip = File.open(private_ip_file, 'rb') { |file| file.read } end if private_ip.nil? || !private_ip.start_with?('192.168.56.') private_ip = "192.168.56.#{rand(2..254)}" File.write(private_ip_file, private_ip) end Vagrant.require_version '>= 2.2.0' Vagrant.configure('2') do |config| config.vagrant.plugins = ['vagrant-goodhosts'] # Use host-machine ssh-key so we can log into production config.ssh.forward_agent = true # Minimum box version requirement for this Vagrantfile revision config.vm.box_version = ">= 20220800.0.0" # Use precompiled box config.vm.box = 'seravo/wordpress' # Use the name of the box as the hostname config.vm.hostname = site_config['name'] # Only use avahi if config has this # development: # avahi: true if site_config['development']['avahi'] && has_internet? and is_osx? # The box uses avahi-daemon to make itself available to local network config.vm.network "public_network", bridge: [ "en0: Wi-Fi (Wireless)", "en1: Wi-Fi (Wireless)", "en0: Wi-Fi (AirPort)", "en1: Wi-Fi (AirPort)", "wlan0" ] end # Use random ip address for box # This is needed for updating the /etc/hosts file config.vm.network :private_network, ip: private_ip config.vm.define "#{site_config['name']}-box" domains = get_domains(site_config) config.goodhosts.remove_on_suspend = true config.goodhosts.aliases = domains - [config.vm.hostname] # Disable default vagrant share config.vm.synced_folder ".", "/vagrant", disabled: true # Sync the folders # We have tried using NFS but it's super slow compared to synced_folder config.vm.synced_folder DIR, '/data/wordpress/', owner: 'vagrant', group: 'vagrant', mount_options: ['dmode=775', 'fmode=775'] # For Self-signed ssl-certificate ssl_cert_path = File.join(DIR,'.vagrant','ssl') unless File.exists? File.join(ssl_cert_path,'development.crt') config.vm.provision :shell, :inline => "wp-generate-ssl" end # Add SSH Public Key from developer home folder into vagrant if File.exists? File.join(Dir.home, ".ssh", "id_rsa.pub") id_rsa_ssh_key_pub = File.read(File.join(Dir.home, ".ssh", "id_rsa.pub")) config.vm.provision :shell, :inline => "echo '#{id_rsa_ssh_key_pub }' >> /home/vagrant/.ssh/authorized_keys && chmod 600 /home/vagrant/.ssh/authorized_keys" end vagrant_triggers(config, site_config) config.vm.provider 'virtualbox' do |vb| vb.memory = 1536 vb.cpus = 2 # Fix for slow external network connections vb.customize ['modifyvm', :id, '--natdnshostresolver1', 'on'] vb.customize ['modifyvm', :id, '--natdnsproxy1', 'on'] vb.customize ['modifyvm', :id, '--uartmode1', 'file', File::NULL] end end ## # Run native Vagrant triggers # https://www.vagrantup.com/docs/triggers/usage ## def vagrant_triggers(vagrant_config, site_config) vagrant_config.trigger.after :up do |trigger| trigger.ruby do |env, machine| # Run all system commands inside project root Dir.chdir(DIR) # Always wait a couple of seconds before running triggers so that the # machine internals have time to bootstrap sleep 3 # Since neither communicate.sudo nor trigger.run_remote supports interactive # mode (on other than some special Windows admin mode), call out to system # to call back to Vagrant as a hacky way to get interactive mode, and thus # wp-development-up can ask the various "pull x, y and z" questions. # https://www.rubydoc.info/github/mitchellh/vagrant/Vagrant/Plugin/V2/Communicator#execute-instance_method # https://www.vagrantup.com/docs/provisioning/shell system "vagrant ssh -c wp-development-up" # Don't activate git hooks, just notify them if File.exists?( File.join(DIR,'.git', 'hooks', 'pre-commit') ) puts "If you want to use a git pre-commit hook please run 'wp-activate-git-hooks' inside the Vagrant box." end case RbConfig::CONFIG['host_os'] when /darwin/ # Do OS X specific things # Trust the self-signed cert in keychain ssl_cert_path = File.join(DIR,'.vagrant','ssl') unless File.exists?(File.join(ssl_cert_path,'trust.lock')) if File.exists?(File.join(ssl_cert_path,'development.crt')) and confirm "Trust the generated ssl-certificate in OS-X keychain?" system "sudo security add-trusted-cert -d -r trustRoot -k '/Library/Keychains/System.keychain' '#{ssl_cert_path}/development.crt'" # Write lock file so we can remove it too touch_file File.join(ssl_cert_path,'trust.lock') end end when /linux/ # Do linux specific things end # Run 'vagrant up' customizer script if it exists if File.exist?(File.join(DIR, 'vagrant-up-customizer.sh')) notice 'Found vagrant-up-customizer.sh and running it ...' Dir.chdir(DIR) system 'sh ./vagrant-up-customizer.sh' end end end vagrant_config.trigger.before [:halt, :destroy] do |trigger| trigger.ruby do |env, machine| # dump database when closing vagrant if vagrant_running? begin # Note! This will run as root run_command("wp-vagrant-dump-db", machine) rescue => e notice "Couldn't dump database. Skipping..." end end end end end ## # Helper function to run a command in a vagrant machine by providing the command # and a Vagrant::Machine object as parameters. Heavily influenced by # https://github.com/emyl/vagrant-triggers/blob/master/lib/vagrant-triggers/dsl.rb ## def run_command(cmd, machine) exit_code = 1 good_exit_codes = (0..255).to_a begin exit_code = machine.communicate.sudo(cmd, :elevated => true, :good_exit => good_exit_codes) do |channel, data| machine.ui.send(:info, data) end rescue => e machine.ui.send(:error, e.message) end if !good_exit_codes.include? exit_code exit exit_code end return exit_code end ## # Custom helpers ## def notice(text) puts "==> trigger: #{text}" end ## # Dump database into file in vagrant ## def dump_wordpress_database if vagrant_running? begin run_remote "wp-vagrant-dump-db" rescue => e notice "Couldn't dump database. Skipping..." end end end ## # Create empty file ## def touch_file(path) File.open(path, "w") {} end ## # Generate /etc/hosts domain additions ## def get_domains(config) unless config['development'].nil? domains = config['development']['domains'] || [] domains << config['development']['domain'] unless config['development']['domain'].nil? else domains = [] end # The main domain domains << config['name']+".local" # Add domain names for included applications for easier usage subdomains = %w( www webgrind adminer mailcatcher browsersync info ) subdomains.each do |domain| domains << "#{domain}.#{config['name']}.local" end domains.uniq #remove duplicates end ## # Get boolean answer for question string ## def confirm(question,default=true) if default default = "yes" else default = "no" end confirm = nil until ["Y","N","YES","NO",""].include?(confirm) print "#{question} (#{default}): " confirm = STDIN.gets.chomp if (confirm.nil? or confirm.empty?) confirm = default end confirm.strip! confirm.upcase! end if confirm.empty? or confirm == "Y" or confirm == "YES" return true end return false end ## # This is quite hacky but for my understanding the only way to check if the current box state ## def vagrant_running? system("vagrant status --machine-readable | grep state,running --quiet") end ## # On OS X we can use a few more features like zeroconf (discovery of .local addresses in local network) ## def is_osx? RbConfig::CONFIG['host_os'].include? 'darwin' end ## # Modified from: https://coderrr.wordpress.com/2008/05/28/get-your-local-ip-address/ # Returns true/false ## def has_internet? orig, Socket.do_not_reverse_lookup = Socket.do_not_reverse_lookup, true # turn off reverse DNS resolution temporarily begin UDPSocket.open { |s| s.connect '8.8.8.8', 1 } return true rescue Errno::ENETUNREACH return false # Network is not reachable end ensure Socket.do_not_reverse_lookup = orig end