diff --git a/Vagrantfile b/Vagrantfile index dfa537f..00fc35e 100644 --- a/Vagrantfile +++ b/Vagrantfile @@ -4,6 +4,18 @@ require 'yaml' host_vm_dir = File.dirname(File.expand_path(__FILE__)) vconfig = YAML.load_file("#{host_vm_dir}/config.yml") +# 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 + Vagrant.configure('2') do |config| config.vm.define :dev do |dev_config| dev_config.ssh.forward_agent = true @@ -29,8 +41,16 @@ Vagrant.configure('2') do |config| } dev_config.vm.synced_folder vconfig['synced_folder_path'] || '../www', '/home/vagrant/www', options - dev_config.vm.provision 'ansible' do |ansible| - ansible.playbook = './provisioning/playbook.yml' + # Provisioning. Use ansible if it's installed, JJG-Ansible-Windows if not. + if which('ansible-playbook') + dev_config.vm.provision 'ansible' do |ansible| + ansible.playbook = './provisioning/playbook.yml' + end + else + dev_config.vm.provision 'shell' do |sh| + sh.path = './provisioning/JJG-Ansible-Windows/windows.sh' + sh.args = '/vagrant/provisioning/playbook.yml' + end end end end diff --git a/backup.sql.gz b/backup.sql.gz new file mode 100644 index 0000000..95b7f80 Binary files /dev/null and b/backup.sql.gz differ diff --git a/provisioning/JJG-Ansible-Windows/LICENSE b/provisioning/JJG-Ansible-Windows/LICENSE new file mode 100644 index 0000000..378188a --- /dev/null +++ b/provisioning/JJG-Ansible-Windows/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2014 Jeff Geerling + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/provisioning/JJG-Ansible-Windows/README.md b/provisioning/JJG-Ansible-Windows/README.md new file mode 100644 index 0000000..e7548ef --- /dev/null +++ b/provisioning/JJG-Ansible-Windows/README.md @@ -0,0 +1,42 @@ +# JJG-Ansible-Windows + +> **Important Note**: Vagrant now includes an [`ansible_local` provisioner](https://docs.vagrantup.com/v2/provisioning/ansible_local.html), which provides a much more reliable Ansible provisioning experience within a Vagrant VM. This project will likely no longer be updated for use beyond Vagrant 1.7.x. + +Windows shell provisioning script to bootstrap Ansible from within a Vagrant VM running on Windows. + +This script is configured to use configure any Linux-based VM (Debian, Ubuntu, Fedora, RedHat, CentOS, etc.) so it can run Ansible playbooks from within the VM through Vagrant. + +Read more about this script, and other techniques for using Ansible within a Windows environment, on Server Check.in: [Running Ansible within Windows](https://servercheck.in/blog/running-ansible-within-windows). + +## Usage + +In your Vagrantfile, use a conditional provisioning statement if you want to use this script (which runs Ansible from within the VM instead of on your host—this example assumes your playbook is inside within a 'provisioning' folder, and this script is within provisioning/JJG-Ansible-Windows): + +```ruby +# Use rbconfig to determine if we're on a windows host or not. +require 'rbconfig' +is_windows = (RbConfig::CONFIG['host_os'] =~ /mswin|mingw|cygwin/) +if is_windows + # Provisioning configuration for shell script. + config.vm.provision "shell" do |sh| + sh.path = "provisioning/JJG-Ansible-Windows/windows.sh" + sh.args = "/vagrant/provisioning/playbook.yml" + end +else + # Provisioning configuration for Ansible (for Mac/Linux hosts). + config.vm.provision "ansible" do |ansible| + ansible.playbook = "provisioning/playbook.yml" + ansible.sudo = true + end +end +``` + +Note that the `windows.sh` script will run within the VM and will run the given playbook against localhost with `--connection=local` inside the VM. You shouldn't/can't pass a custom inventory file to the script, as you can using Vagrant's Ansible provisioner. + +### Role Requirements File + +If your playbook requires roles to be installed which are not present in a `roles` directory within the playbook's directory, then you should add the roles to a [role requirements](http://docs.ansible.com/galaxy.html#advanced-control-over-role-requirements-files) file. Place the resulting `requirements.txt` or `requirements.yml` file in the same directory as your playbook, and the roles will be installed automatically. + +## Licensing and More Info + +Created by [Jeff Geerling](http://jeffgeerling.com/) in 2014. Licensed under the MIT license; see the LICENSE file for more info. diff --git a/provisioning/JJG-Ansible-Windows/windows.sh b/provisioning/JJG-Ansible-Windows/windows.sh new file mode 100644 index 0000000..a96d516 --- /dev/null +++ b/provisioning/JJG-Ansible-Windows/windows.sh @@ -0,0 +1,79 @@ +#!/bin/bash +# +# Windows shell provisioner for Ansible playbooks, based on KSid's +# windows-vagrant-ansible: https://github.com/KSid/windows-vagrant-ansible +# +# @see README.md +# @author Jeff Geerling, 2014 + +# Uncomment if behind a proxy server. +# export {http,https,ftp}_proxy='http://username:password@proxy-host:80' + +args=() +extra_vars=("is_windows=true") + +# Process and remove all flags. +while (($#)); do + case $1 in + --extra-vars=*) extra_vars+=("${1#*=}") ;; + --extra-vars|-e) shift; extra_vars+=("$1") ;; + -*) echo "invalid option: $1" >&2; exit 1 ;; + *) args+=("$1") ;; + esac + shift +done + +# Restore the arguments without flags. +set -- "${args[@]}" + +ANSIBLE_PLAYBOOK=$1 +PLAYBOOK_DIR=${ANSIBLE_PLAYBOOK%/*} + +# Detect package management system. +YUM=$(which yum 2>/dev/null) +APT_GET=$(which apt-get 2>/dev/null) + +# Make sure Ansible playbook exists. +if [ ! -f "$ANSIBLE_PLAYBOOK" ]; then + echo "Cannot find Ansible playbook." + exit 1 +fi + +# Install Ansible and its dependencies if it's not installed already. +if ! command -v ansible >/dev/null; then + echo "Installing Ansible dependencies and Git." + if [[ ! -z ${YUM} ]]; then + yum install -y git python python-devel + elif [[ ! -z ${APT_GET} ]]; then + apt-get update + apt-get install -y git python python-dev + else + echo "Neither yum nor apt-get are available." + exit 1; + fi + + echo "Installing pip." + wget https://bootstrap.pypa.io/get-pip.py + python get-pip.py && rm -f get-pip.py + + echo "Installing required build tools." + if [[ ! -z $YUM ]]; then + yum install -y gcc libffi-devel openssl-devel + elif [[ ! -z $APT_GET ]]; then + apt-get install -y build-essential libssl-dev libffi-dev + fi + + echo "Installing required python modules." + pip install paramiko pyyaml jinja2 markupsafe + + echo "Installing Ansible." + pip install ansible +fi + +# Install requirements. +echo "Installing Ansible roles from requirements file, if available." +find "$PLAYBOOK_DIR" \( -name "requirements.yml" -o -name "requirements.txt" \) -exec sudo ansible-galaxy install --force --ignore-errors -r {} \; + +# Run the playbook. +echo "Running Ansible provisioner defined in Vagrantfile." +ansible-playbook -i 'localhost,' "${ANSIBLE_PLAYBOOK}" --extra-vars "${extra_vars[*]}" --connection=local