Merge branch 'master' into winrm_error_handling

This commit is contained in:
Max Lincoln 2015-01-20 16:07:00 -05:00
commit edc867986b
57 changed files with 588 additions and 311 deletions

View File

@ -1,3 +1,29 @@
## 1.7.2 (unreleased)
FEATURES:
- provisioners/salt: add support for grains [GH-4895]
BUG FIXES:
- core: private boxes still referencing vagrantcloud.com will have
their vagrant login access token properly appended
- commands/push: push lookups are by user-defined name, not push
strategy name [GH-4975]
- guests/arch: fix network configuration due to poor line breaks. [GH-4964]
- provisioners/chef: remove Chef version check from solo.rb generation and
make `roles_path` populate correctly
## 1.7.1 (December 11, 2014)
IMPROVEMENTS:
- provisioners/ansible: Use Docker proxy if needed. [GH-4906]
BUG FIXES:
- providers/docker: Add support of SSH agent forwarding. [GH-4905]
## 1.7.0 (December 9, 2014) ## 1.7.0 (December 9, 2014)
BREAKING CHANGES: BREAKING CHANGES:
@ -102,6 +128,7 @@ BUG FIXES:
- provisioners/ansible: Force `ssh` (OpenSSH) connection by default [GH-3396] - provisioners/ansible: Force `ssh` (OpenSSH) connection by default [GH-3396]
- provisioners/ansible: Don't use or modify `~/.ssh/known_hosts` file by default, - provisioners/ansible: Don't use or modify `~/.ssh/known_hosts` file by default,
similarly to native vagrant commands [GH-3900] similarly to native vagrant commands [GH-3900]
- provisioners/ansible: Use intermediate Docker host when needed. [GH-4071]
- provisioners/docker: Get GPG key over SSL. [GH-4597] - provisioners/docker: Get GPG key over SSL. [GH-4597]
- provisioners/docker: Search for docker binary in multiple places. [GH-4580] - provisioners/docker: Search for docker binary in multiple places. [GH-4580]
- provisioners/salt: Highstate works properly with a master. [GH-4471] - provisioners/salt: Highstate works properly with a master. [GH-4471]

8
Vagrantfile vendored
View File

@ -13,6 +13,14 @@ Vagrant.configure("2") do |config|
end end
config.vm.provision "shell", inline: $shell config.vm.provision "shell", inline: $shell
config.push.define "www", strategy: "local-exec" do |push|
push.script = "scripts/website_push_www.sh"
end
config.push.define "docs", strategy: "local-exec" do |push|
push.script = "scripts/website_push_docs.sh"
end
end end
$shell = <<-CONTENTS $shell = <<-CONTENTS

View File

@ -0,0 +1,6 @@
Cmnd_Alias VAGRANT_EXPORTS_ADD = /usr/bin/tee -a /etc/exports
Cmnd_Alias VAGRANT_NFSD_CHECK = /usr/bin/systemctl status nfs-server.service
Cmnd_Alias VAGRANT_NFSD_START = /usr/bin/systemctl start nfs-server.service
Cmnd_Alias VAGRANT_NFSD_APPLY = /usr/sbin/exportfs -ar
Cmnd_Alias VAGRANT_EXPORTS_REMOVE = /bin/sed -r -e * d -ibak /etc/exports
%vagrant ALL=(root) NOPASSWD: VAGRANT_EXPORTS_ADD, VAGRANT_NFSD_CHECK, VAGRANT_NFSD_START, VAGRANT_NFSD_APPLY, VAGRANT_EXPORTS_REMOVE

View File

@ -83,10 +83,7 @@ module VagrantPlugins
false false
rescue RestClient::NotAcceptable => e rescue RestClient::NotAcceptable => e
begin begin
errors = JSON.parse(e.response)["errors"] errors = JSON.parse(e.response)["errors"].join("\n")
.map { |h| h["message"] }
.join("\n")
raise Errors::ServerError, errors: errors raise Errors::ServerError, errors: errors
rescue JSON::ParserError; end rescue JSON::ParserError; end

View File

@ -18,7 +18,17 @@ module VagrantPlugins
env[:box_urls].map! do |url| env[:box_urls].map! do |url|
u = URI.parse(url) u = URI.parse(url)
if u.host == server_uri.host replace = u.host == server_uri.host
if !replace
# We need this in here for the transition we made from
# Vagrant Cloud to Atlas. This preserves access tokens
# appending to both without leaking access tokens to
# unsavory URLs.
replace = u.host == "vagrantcloud.com" &&
server_uri.host == "atlas.hashicorp.com"
end
if replace
u.query ||= "" u.query ||= ""
u.query += "&" if u.query != "" u.query += "&" if u.query != ""
u.query += "access_token=#{token}" u.query += "access_token=#{token}"

View File

@ -80,7 +80,7 @@ module VagrantPlugins
acc acc
end end
vm.action(:package, opts) vm.action(:package, **opts)
end end
end end
end end

View File

@ -51,17 +51,19 @@ module VagrantPlugins
if pushes.length == 1 if pushes.length == 1
return pushes.first.to_sym return pushes.first.to_sym
else else
raise Vagrant::Errors::PushStrategyNotProvided, pushes: pushes raise Vagrant::Errors::PushStrategyNotProvided,
pushes: pushes.map(&:to_s)
end end
end end
name = name.to_sym
if !pushes.include?(name) if !pushes.include?(name)
raise Vagrant::Errors::PushStrategyNotDefined, raise Vagrant::Errors::PushStrategyNotDefined,
name: name, name: name.to_s,
pushes: pushes pushes: pushes.map(&:to_s)
end end
return name.to_sym return name
end end
end end
end end

View File

@ -146,12 +146,21 @@ module VagrantPlugins
alias_method :sudo, :execute alias_method :sudo, :execute
def test(command, opts=nil) def test(command, opts=nil)
# If this is a *nix command with no Windows equivilant, assume failure # If this is a *nix command (which we know about) with no Windows
# equivilant, assume failure
command = @cmd_filter.filter(command) command = @cmd_filter.filter(command)
return false if command.empty? return false if command.empty?
opts = { error_check: false }.merge(opts || {}) opts = {
execute(command, opts) == 0 command: command,
elevated: false,
error_check: false,
}.merge(opts || {})
# If we're passed a *nix command which PS can't parse we get exit code
# 0, but output in stderr. We need to check both exit code and stderr.
output = shell.send(:powershell, command)
return output[:exitcode] == 0 && flatten_stderr(output).length == 0
end end
def upload(from, to) def upload(from, to)
@ -220,8 +229,8 @@ module VagrantPlugins
def raise_execution_error(output, opts) def raise_execution_error(output, opts)
# WinRM can return multiple stderr and stdout entries # WinRM can return multiple stderr and stdout entries
error_opts = opts.merge( error_opts = opts.merge(
stdout: output[:data].collect { |e| e[:stdout] }.join, stdout: flatten_stdout(output),
stderr: output[:data].collect { |e| e[:stderr] }.join stderr: flatten_stderr(output)
) )
# Use a different error message key if the caller gave us one, # Use a different error message key if the caller gave us one,
@ -231,6 +240,20 @@ module VagrantPlugins
# Raise the error, use the type the caller gave us or the comm default # Raise the error, use the type the caller gave us or the comm default
raise opts[:error_class], error_opts raise opts[:error_class], error_opts
end end
# TODO: Replace with WinRM Output class when WinRM 1.3 is released
def flatten_stderr(output)
output[:data].map do | line |
line[:stderr]
end.compact.join
end
def flatten_stdout(output)
output[:data].map do | line |
line[:flatten_stdout]
end.compact.join
end
end #WinRM class end #WinRM class
end end
end end

View File

@ -11,20 +11,14 @@ module VagrantPlugins
def self.configure_networks(machine, networks) def self.configure_networks(machine, networks)
interfaces = Array.new interfaces = Array.new
machine.communicate.sudo("ip -o -0 addr | grep -v LOOPBACK | awk machine.communicate.sudo("ip -o -0 addr | grep -v LOOPBACK | awk '{print $2}' | sed 's/://'") do |_, result|
'{print $2}' | sed 's/://'") do |_, result|
interfaces = result.split("\n") interfaces = result.split("\n")
end end
networks.each do |network| networks.each do |network|
# We use :device in the template instead of
# eth#{network[:interface]} in order to support Predictable
# Network Interfaces
network[:device] = interfaces[network[:interface]] network[:device] = interfaces[network[:interface]]
entry = entry = TemplateRenderer.render("guests/arch/network_#{network[:type]}", options: network)
TemplateRenderer.render("guests/arch/network_#{network[:type]}",
options: network)
temp = Tempfile.new("vagrant") temp = Tempfile.new("vagrant")
temp.binmode temp.binmode
@ -32,10 +26,8 @@ module VagrantPlugins
temp.close temp.close
machine.communicate.upload(temp.path, "/tmp/vagrant_network") machine.communicate.upload(temp.path, "/tmp/vagrant_network")
machine.communicate.sudo("mv /tmp/vagrant_network machine.communicate.sudo("mv /tmp/vagrant_network /etc/netctl/#{network[:device]}")
/etc/netctl/#{network[:device]}") machine.communicate.sudo("ip link set #{network[:device]} down && netctl start #{network[:device]}")
machine.communicate.sudo("ip link set #{network[:device]} down &&
netctl start #{network[:device]}")
end end
end end
end end

View File

@ -13,9 +13,8 @@ module VagrantPlugins
machine.communicate.tap do |comm| machine.communicate.tap do |comm|
# First, remove any previous network modifications # First, remove any previous network modifications
# from the interface file. # from the interface file.
comm.sudo("sed -e '/^#VAGRANT-BEGIN/,/^#VAGRANT-END/ d' /etc/network/interfaces > /tmp/vagrant-network-interfaces") comm.sudo("sed -e '/^#VAGRANT-BEGIN/,$ d' /etc/network/interfaces > /tmp/vagrant-network-interfaces.pre")
comm.sudo("su -c 'cat /tmp/vagrant-network-interfaces > /etc/network/interfaces'") comm.sudo("sed -ne '/^#VAGRANT-END/,$ p' /etc/network/interfaces | tail -n +2 > /tmp/vagrant-network-interfaces.post")
comm.sudo("rm -f /tmp/vagrant-network-interfaces")
# Accumulate the configurations to add to the interfaces file as # Accumulate the configurations to add to the interfaces file as
# well as what interfaces we're actually configuring since we use that # well as what interfaces we're actually configuring since we use that
@ -47,8 +46,8 @@ module VagrantPlugins
comm.sudo("/sbin/ip addr flush dev eth#{interface} 2> /dev/null") comm.sudo("/sbin/ip addr flush dev eth#{interface} 2> /dev/null")
end end
comm.sudo("cat /tmp/vagrant-network-entry >> /etc/network/interfaces") comm.sudo('cat /tmp/vagrant-network-interfaces.pre /tmp/vagrant-network-entry /tmp/vagrant-network-interfaces.post > /etc/network/interfaces')
comm.sudo("rm -f /tmp/vagrant-network-entry") comm.sudo('rm -f /tmp/vagrant-network-interfaces.pre /tmp/vagrant-network-entry /tmp/vagrant-network-interfaces.post')
# Bring back up each network interface, reconfigured # Bring back up each network interface, reconfigured
interfaces.each do |interface| interfaces.each do |interface|

View File

@ -21,18 +21,18 @@ module VagrantPlugins
# Compile all the provider configurations # Compile all the provider configurations
@__defined_pushes.each do |name, tuples| @__defined_pushes.each do |name, tuples|
# Find the configuration class for this push
config_class = Vagrant.plugin("2").manager.push_configs[name]
config_class ||= Vagrant::Config::V2::DummyConfig
# Load it up
config = config_class.new
# Capture the strategy so we can use it later. This will be used in # Capture the strategy so we can use it later. This will be used in
# the block iteration for merging/overwriting # the block iteration for merging/overwriting
strategy = name strategy = name
strategy = tuples[0][0] if tuples[0] strategy = tuples[0][0] if tuples[0]
# Find the configuration class for this push
config_class = Vagrant.plugin("2").manager.push_configs[strategy]
config_class ||= Vagrant::Config::V2::DummyConfig
# Load it up
config = config_class.new
begin begin
tuples.each do |s, b| tuples.each do |s, b|
# Update the strategy if it has changed, reseting the current # Update the strategy if it has changed, reseting the current

View File

@ -19,14 +19,19 @@ module VagrantPlugins
# Modify the SSH options for when we `vagrant ssh`... # Modify the SSH options for when we `vagrant ssh`...
ssh_opts = env[:ssh_opts] || {} ssh_opts = env[:ssh_opts] || {}
# Build the command we'll execute within the host machine # Build the command we'll execute within the Docker host machine:
ssh_command = env[:machine].communicate.container_ssh_command ssh_command = env[:machine].communicate.container_ssh_command
if !Array(ssh_opts[:extra_args]).empty? if !Array(ssh_opts[:extra_args]).empty?
ssh_command << " #{Array(ssh_opts[:extra_args]).join(" ")}" ssh_command << " #{Array(ssh_opts[:extra_args]).join(" ")}"
end end
# Modify the SSH options for the original command:
# Append "-t" to force a TTY allocation # Append "-t" to force a TTY allocation
ssh_opts[:extra_args] = ["-t"] ssh_opts[:extra_args] = ["-t"]
# Enable Agent forwarding when requested for the target VM
if env[:machine].ssh_info[:forward_agent]
ssh_opts[:extra_args] << "-o ForwardAgent=yes"
end
ssh_opts[:extra_args] << ssh_command ssh_opts[:extra_args] << ssh_command
# Set the opts # Set the opts

View File

@ -137,18 +137,21 @@ module VagrantPlugins
info[:port] ||= 22 info[:port] ||= 22
# Make sure our private keys are synced over to the host VM # Make sure our private keys are synced over to the host VM
key_args = sync_private_keys(info).map do |path| ssh_args = sync_private_keys(info).map do |path|
"-i #{path}" "-i #{path}"
end.join(" ") end
# Use ad-hoc SSH options for the hop on the docker proxy
if info[:forward_agent]
ssh_args << "-o ForwardAgent=yes"
end
ssh_args.concat(["-o Compression=yes",
"-o ConnectTimeout=5",
"-o StrictHostKeyChecking=no",
"-o UserKnownHostsFile=/dev/null"])
# Build the SSH command # Build the SSH command
"ssh #{key_args} " + "ssh #{info[:username]}@#{info[:host]} -p#{info[:port]} #{ssh_args.join(" ")}"
"-o Compression=yes " +
"-o ConnectTimeout=5 " +
"-o StrictHostKeyChecking=no " +
"-o UserKnownHostsFile=/dev/null " +
"-p#{info[:port]} " +
"#{info[:username]}@#{info[:host]}"
end end
protected protected

View File

@ -188,6 +188,24 @@ module VagrantPlugins
def get_ansible_ssh_args def get_ansible_ssh_args
ssh_options = [] ssh_options = []
# Use an SSH ProxyCommand when using the Docker provider with the intermediate host
if @machine.provider_name == :docker && machine.provider.host_vm?
docker_host_ssh_info = machine.provider.host_vm.ssh_info
proxy_cmd = "ssh #{docker_host_ssh_info[:username]}@#{docker_host_ssh_info[:host]}" +
" -p #{docker_host_ssh_info[:port]} -i #{docker_host_ssh_info[:private_key_path][0]}"
# Use same options than plugins/providers/docker/communicator.rb
# Note: this could be improved (DRY'ed) by sharing these settings.
proxy_cmd += " -o Compression=yes -o ConnectTimeout=5 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no"
proxy_cmd += " -o ForwardAgent=yes" if @ssh_info[:forward_agent]
proxy_cmd += " exec nc %h %p 2>/dev/null"
ssh_options << "-o ProxyCommand='#{ proxy_cmd }'"
end
# Don't access user's known_hosts file, except when host_key_checking is enabled. # Don't access user's known_hosts file, except when host_key_checking is enabled.
ssh_options << "-o UserKnownHostsFile=/dev/null" unless config.host_key_checking ssh_options << "-o UserKnownHostsFile=/dev/null" unless config.host_key_checking

View File

@ -5,11 +5,11 @@ module VagrantPlugins
module Cap module Cap
module Debian module Debian
module ChefInstall module ChefInstall
def self.chef_install(machine, version, prerelease) def self.chef_install(machine, version, prerelease, download_path)
machine.communicate.sudo("apt-get update -y -qq") machine.communicate.sudo("apt-get update -y -qq")
machine.communicate.sudo("apt-get install -y -qq curl") machine.communicate.sudo("apt-get install -y -qq curl")
command = Omnibus.build_command(version, prerelease) command = Omnibus.build_command(version, prerelease, download_path)
machine.communicate.sudo(command) machine.communicate.sudo(command)
end end
end end

View File

@ -5,10 +5,10 @@ module VagrantPlugins
module Cap module Cap
module Redhat module Redhat
module ChefInstall module ChefInstall
def self.chef_install(machine, version, prerelease) def self.chef_install(machine, version, prerelease, download_path)
machine.communicate.sudo("yum install -y -q curl") machine.communicate.sudo("yum install -y -q curl")
command = Omnibus.build_command(version, prerelease) command = Omnibus.build_command(version, prerelease, download_path)
machine.communicate.sudo(command) machine.communicate.sudo(command)
end end
end end

View File

@ -48,6 +48,14 @@ module VagrantPlugins
# @return [String] # @return [String]
attr_accessor :version attr_accessor :version
# The path where the Chef installer will be downloaded to. Only valid if
# install is true or "force". It defaults to nil, which means that the
# omnibus installer will choose the destination and you have no control
# over it.
#
# @return [String]
attr_accessor :installer_download_path
def initialize def initialize
super super
@ -57,6 +65,7 @@ module VagrantPlugins
@log_level = UNSET_VALUE @log_level = UNSET_VALUE
@prerelease = UNSET_VALUE @prerelease = UNSET_VALUE
@version = UNSET_VALUE @version = UNSET_VALUE
@installer_download_path = UNSET_VALUE
end end
def finalize! def finalize!
@ -66,6 +75,7 @@ module VagrantPlugins
@log_level = :info if @log_level == UNSET_VALUE @log_level = :info if @log_level == UNSET_VALUE
@prerelease = false if @prerelease == UNSET_VALUE @prerelease = false if @prerelease == UNSET_VALUE
@version = :latest if @version == UNSET_VALUE @version = :latest if @version == UNSET_VALUE
@installer_download_path = nil if @installer_download_path == UNSET_VALUE
# Make sure the install is a symbol if it's not a boolean # Make sure the install is a symbol if it's not a boolean
if @install.respond_to?(:to_sym) if @install.respond_to?(:to_sym)

View File

@ -6,6 +6,7 @@ module VagrantPlugins
@version = options.fetch(:version, :latest) @version = options.fetch(:version, :latest)
@prerelease = options.fetch(:prerelease, :latest) @prerelease = options.fetch(:prerelease, :latest)
@force = options.fetch(:force, false) @force = options.fetch(:force, false)
@download_path = options.fetch(:download_path, nil)
end end
# This handles verifying the Chef installation, installing it if it was # This handles verifying the Chef installation, installing it if it was
@ -27,7 +28,7 @@ module VagrantPlugins
@machine.ui.detail(I18n.t("vagrant.chef_installing", @machine.ui.detail(I18n.t("vagrant.chef_installing",
version: @version.to_s)) version: @version.to_s))
@machine.guest.capability(:chef_install, @version, @prerelease) @machine.guest.capability(:chef_install, @version, @prerelease, @download_path)
if !@machine.guest.capability(:chef_installed, @version) if !@machine.guest.capability(:chef_installed, @version)
raise Provisioner::Base::ChefError, :install_failed raise Provisioner::Base::ChefError, :install_failed

View File

@ -1,14 +1,14 @@
module VagrantPlugins module VagrantPlugins
module Chef module Chef
module Omnibus module Omnibus
OMNITRUCK = "https://www.getchef.com/chef/install.sh".freeze OMNITRUCK = "https://www.chef.io/chef/install.sh".freeze
# Read more about the Omnibus installer here: # Read more about the Omnibus installer here:
# https://docs.getchef.com/install_omnibus.html # https://docs.getchef.com/install_omnibus.html
def build_command(version, prerelease = false) def build_command(version, prerelease = false, download_path = nil)
command = "curl -sL #{OMNITRUCK} | sudo bash" command = "curl -sL #{OMNITRUCK} | sudo bash"
if prerelease || version != :latest if prerelease || version != :latest || download_path != nil
command << " -s --" command << " -s --"
end end
@ -20,6 +20,10 @@ module VagrantPlugins
command << " -v \"#{version}\"" command << " -v \"#{version}\""
end end
if download_path
command << " -d \"#{download_path}\""
end
command command
end end
module_function :build_command module_function :build_command

View File

@ -29,6 +29,7 @@ module VagrantPlugins
force: config.install == :force, force: config.install == :force,
version: config.version, version: config.version,
prerelease: config.prerelease, prerelease: config.prerelease,
download_path: config.installer_download_path
) )
installer.ensure_installed installer.ensure_installed
end end

View File

@ -12,6 +12,7 @@ module VagrantPlugins
attr_accessor :master_config attr_accessor :master_config
attr_accessor :master_key attr_accessor :master_key
attr_accessor :master_pub attr_accessor :master_pub
attr_accessor :grains_config
attr_accessor :run_highstate attr_accessor :run_highstate
attr_accessor :run_overstate attr_accessor :run_overstate
attr_accessor :always_install attr_accessor :always_install
@ -38,6 +39,7 @@ module VagrantPlugins
@master_config = UNSET_VALUE @master_config = UNSET_VALUE
@master_key = UNSET_VALUE @master_key = UNSET_VALUE
@master_pub = UNSET_VALUE @master_pub = UNSET_VALUE
@grains_config = UNSET_VALUE
@run_highstate = UNSET_VALUE @run_highstate = UNSET_VALUE
@run_overstate = UNSET_VALUE @run_overstate = UNSET_VALUE
@always_install = UNSET_VALUE @always_install = UNSET_VALUE
@ -63,6 +65,7 @@ module VagrantPlugins
@master_config = nil if @master_config == UNSET_VALUE @master_config = nil if @master_config == UNSET_VALUE
@master_key = nil if @master_key == UNSET_VALUE @master_key = nil if @master_key == UNSET_VALUE
@master_pub = nil if @master_pub == UNSET_VALUE @master_pub = nil if @master_pub == UNSET_VALUE
@grains_config = nil if @grains_config == UNSET_VALUE
@run_highstate = nil if @run_highstate == UNSET_VALUE @run_highstate = nil if @run_highstate == UNSET_VALUE
@run_overstate = nil if @run_overstate == UNSET_VALUE @run_overstate = nil if @run_overstate == UNSET_VALUE
@always_install = nil if @always_install == UNSET_VALUE @always_install = nil if @always_install == UNSET_VALUE
@ -115,6 +118,13 @@ module VagrantPlugins
end end
end end
if @grains_config
expanded = Pathname.new(@grains_config).expand_path(machine.env.root_path)
if !expanded.file?
errors << I18n.t("vagrant.provisioners.salt.grains_config_nonexist")
end
end
if @install_master && !@no_minion && !@seed_master && @run_highstate if @install_master && !@no_minion && !@seed_master && @run_highstate
errors << I18n.t("vagrant.provisioners.salt.must_accept_keys") errors << I18n.t("vagrant.provisioners.salt.must_accept_keys")
end end

View File

@ -75,7 +75,7 @@ module VagrantPlugins
end end
def need_configure def need_configure
@config.minion_config or @config.minion_key or @config.master_config or @config.master_key @config.minion_config or @config.minion_key or @config.master_config or @config.master_key or @config.grains_config
end end
def need_install def need_install
@ -181,6 +181,11 @@ module VagrantPlugins
@machine.env.ui.info "Copying salt master config to vm." @machine.env.ui.info "Copying salt master config to vm."
@machine.communicate.upload(expanded_path(@config.master_config).to_s, temp_config_dir + "/master") @machine.communicate.upload(expanded_path(@config.master_config).to_s, temp_config_dir + "/master")
end end
if @config.grains_config
@machine.env.ui.info "Copying salt grains config to vm."
@machine.communicate.upload(expanded_path(@config.grains_config).to_s, temp_config_dir + "/grains")
end
end end
# Copy master and minion keys to VM # Copy master and minion keys to VM

View File

@ -8,13 +8,13 @@ module VagrantPlugins
Run a local command or script to push Run a local command or script to push
DESC DESC
config(:local_exec, :push) do config(:"local-exec", :push) do
require File.expand_path("../config", __FILE__) require File.expand_path("../config", __FILE__)
init! init!
Config Config
end end
push(:local_exec) do push(:"local-exec") do
require File.expand_path("../push", __FILE__) require File.expand_path("../push", __FILE__)
init! init!
Push Push

View File

@ -1,6 +1,6 @@
require "fileutils" require "fileutils"
require "tempfile" require "tempfile"
require "vagrant/util/subprocess" require "vagrant/util/safe_exec"
require_relative "errors" require_relative "errors"
@ -38,16 +38,7 @@ module VagrantPlugins
# Execute the script, raising an exception if it fails. # Execute the script, raising an exception if it fails.
def execute!(*cmd) def execute!(*cmd)
result = Vagrant::Util::Subprocess.execute(*cmd) Vagrant::Util::SafeExec.exec(cmd[0], *cmd[1..-1])
if result.exit_code != 0
raise Errors::CommandFailed,
cmd: cmd.join(" "),
stdout: result.stdout,
stderr: result.stderr
end
result
end end
end end
end end

View File

@ -8,5 +8,10 @@ DIR="$( cd -P "$( dirname "$SOURCE" )/.." && pwd )"
# Change into that directory # Change into that directory
cd $DIR cd $DIR
# Add the git remote if it doesn't exist
git remote | grep heroku-docs || {
git remote add heroku-docs git@heroku.com:vagrantup-docs.git
}
# Push the subtree (force) # Push the subtree (force)
git push heroku-docs `git subtree split --prefix website/docs master`:master --force git push heroku-docs `git subtree split --prefix website/docs master`:master --force

View File

@ -8,5 +8,10 @@ DIR="$( cd -P "$( dirname "$SOURCE" )/.." && pwd )"
# Change into that directory # Change into that directory
cd $DIR cd $DIR
# Add the git remote if it doesn't exist
git remote | grep heroku-www || {
git remote add heroku-www git@heroku.com:vagrantup-www.git
}
# Push the subtree (force) # Push the subtree (force)
git push heroku-www `git subtree split --prefix website/www master`:master --force git push heroku-www `git subtree split --prefix website/www master`:master --force

View File

@ -8,9 +8,10 @@
Vagrant.configure(2) do |config| Vagrant.configure(2) do |config|
# The most common configuration options are documented and commented below. # The most common configuration options are documented and commented below.
# For a complete reference, please see the online documentation at # For a complete reference, please see the online documentation at
# vagrantup.com # https://docs.vagrantup.com.
# Every Vagrant virtual environment requires a box to build off of. # Every Vagrant development environment requires a box. You can search for
# boxes at https://atlas.hashicorp.com/search.
config.vm.box = "<%= box_name %>" config.vm.box = "<%= box_name %>"
<% if box_url -%> <% if box_url -%>
@ -38,10 +39,6 @@ Vagrant.configure(2) do |config|
# your network. # your network.
# config.vm.network "public_network" # config.vm.network "public_network"
# If true, then any SSH connections made will enable agent forwarding.
# Default value: false
# config.ssh.forward_agent = true
# Share an additional folder to the guest VM. The first argument is # Share an additional folder to the guest VM. The first argument is
# the path on the host to the actual folder. The second argument is # the path on the host to the actual folder. The second argument is
# the path on the guest to mount the folder. And the optional third # the path on the guest to mount the folder. And the optional third
@ -53,134 +50,28 @@ Vagrant.configure(2) do |config|
# Example for VirtualBox: # Example for VirtualBox:
# #
# config.vm.provider "virtualbox" do |vb| # config.vm.provider "virtualbox" do |vb|
# # Don't boot with headless mode # # Display the VirtualBox GUI when booting the machine
# vb.gui = true # vb.gui = true
# #
# # Use VBoxManage to customize the VM. For example to change memory: # # Customize the amount of memory on the VM:
# vb.customize ["modifyvm", :id, "--memory", "1024"] # vb.memory = "1024"
# end # end
# #
# View the documentation for the provider you're using for more # View the documentation for the provider you are using for more
# information on available options. # information on available options.
# Enable provisioning with CFEngine. CFEngine Community packages are # Define a Vagrant Push strategy for pushing to Atlas. Other push strategies
# automatically installed. For example, configure the host as a # such as FTP and Heroku are also available. See the documentation at
# policy server and optionally a policy file to run: # https://docs.vagrantup.com/v2/push/atlas.html for more information.
# # config.push.define "atlas" do |push|
# config.vm.provision "cfengine" do |cf| # push.app = "YOUR_ATLAS_USERNAME/YOUR_APPLICATION_NAME"
# cf.am_policy_hub = true
# # cf.run_file = "motd.cf"
# end
#
# You can also configure and bootstrap a client to an existing
# policy server:
#
# config.vm.provision "cfengine" do |cf|
# cf.policy_server_address = "10.0.2.15"
# end # end
# Enable provisioning with Puppet stand alone. Puppet manifests # Enable provisioning with a shell script. Additional provisioners such as
# are contained in a directory path relative to this Vagrantfile. # Puppet, Chef, Ansible, Salt, and Docker are also available. Please see the
# You will need to create the manifests directory and a manifest in # documentation for more information about their specific syntax and use.
# the file default.pp in the manifests_path directory. # config.vm.provision "shell", inline: <<-SHELL
# # sudo apt-get update
# config.vm.provision "puppet" do |puppet| # sudo apt-get install -y apache2
# puppet.manifests_path = "manifests" # SHELL
# puppet.manifest_file = "default.pp"
# end
# Enable provisioning with Chef Solo, specifying a cookbooks path, roles
# path, and data_bags path (all relative to this Vagrantfile), and adding
# some recipes and/or roles.
#
# config.vm.provision "chef_solo" do |chef|
# chef.cookbooks_path = "~/chef/cookbooks"
# chef.roles_path = "~/chef/roles"
# chef.data_bags_path = "~/chef/data_bags"
#
# chef.add_recipe "mysql"
# chef.add_role "web"
#
# chef.json = { mysql_password: "foo" }
# end
#
# Chef Solo will automatically install the latest version of Chef for you.
# This can be configured in the provisioner block:
#
# config.vm.provision "chef_solo" do |chef|
# chef.version = "11.16.4"
# end
#
# Alternative you can disable the installation of Chef entirely:
#
# config.vm.provision "chef_solo" do |chef|
# chef.install = false
# end
# Enable provisioning with Chef Zero. The Chef Zero provisioner accepts the
# exact same parameter as the Chef Solo provisioner:
#
# config.vm.provision "chef_zero" do |chef|
# chef.cookbooks_path = "~/chef/cookbooks"
# chef.roles_path = "~/chef/roles"
# chef.data_bags_path = "~/chef/data_bags"
#
# chef.add_recipe "mysql"
# chef.add_role "web"
#
# # You may also specify custom JSON attributes:
# chef.json = { mysql_password: "foo" }
# end
# Enable provisioning with Chef Server, specifying the chef server URL,
# and the path to the validation key (relative to this Vagrantfile).
#
# The Hosted Chef platform uses HTTPS. Substitute your organization for
# ORGNAME in the URL and validation key.
#
# If you have your own Chef Server, use the appropriate URL, which may be
# HTTP instead of HTTPS depending on your configuration. Also change the
# validation key to validation.pem.
#
# config.vm.provision "chef_client" do |chef|
# chef.chef_server_url = "https://api.opscode.com/organizations/ORGNAME"
# chef.validation_key_path = "ORGNAME-validator.pem"
# end
#
# If you're using the Hosted Chef platform, your validator client is
# ORGNAME-validator, replacing ORGNAME with your organization name.
#
# If you have your own Chef Server, the default validation client name is
# chef-validator, unless you changed the configuration.
#
# chef.validation_client_name = "ORGNAME-validator"
#
# Chef Client will automatically install the latest version of Chef for you.
# This can be configured in the provisioner block:
#
# config.vm.provision "chef_client" do |chef|
# chef.version = "11.16.4"
# end
#
# Alternative you can disable the installation of Chef entirely:
#
# config.vm.provision "chef_client" do |chef|
# chef.install = false
# end
# Enable provisioning with Chef Apply, specifying an inline recipe to execute
# on the target system.
#
# config.vm.provision "chef_apply" do |chef|
# chef.recipe = <<-RECIPE
# package "curl"
# RECIPE
# end
#
# Chef Apply will automatically install the latest version of Chef for you.
# This can be configured in the provisioner block:
#
# config.vm.provision "chef_apply" do |chef|
# chef.version = "11.16.4"
# end
end end

View File

@ -1,6 +1,3 @@
# -*- mode: ruby -*-
# vi: set ft=ruby :
Vagrant.configure(2) do |config| Vagrant.configure(2) do |config|
config.vm.box = "<%= box_name %>" config.vm.box = "<%= box_name %>"
<% if box_url -%> <% if box_url -%>

View File

@ -243,7 +243,7 @@ en:
Press ctrl-c now to exit if you want to remove some boxes or free Press ctrl-c now to exit if you want to remove some boxes or free
up some disk space. up some disk space.
Press any other key to continue. Press the Enter or Return key to continue.
version_current: |- version_current: |-
Installed Version: %{version} Installed Version: %{version}
version_latest: |- version_latest: |-
@ -1909,6 +1909,8 @@ en:
The specified minion_config file could not be found. The specified minion_config file could not be found.
master_config_nonexist: |- master_config_nonexist: |-
The specified master_config file could not be found. The specified master_config file could not be found.
grains_config_nonexist: |-
The specified grains_config file could not be found.
missing_key: |- missing_key: |-
You must include both public and private keys. You must include both public and private keys.
must_accept_keys: |- must_accept_keys: |-

View File

@ -5,11 +5,7 @@ file_cache_path "<%= file_cache_path %>"
file_backup_path "<%= file_backup_path %>" file_backup_path "<%= file_backup_path %>"
cookbook_path <%= cookbooks_path.inspect %> cookbook_path <%= cookbooks_path.inspect %>
<% if roles_path %> <% if roles_path %>
if Chef::VERSION.to_f < 11.8 role_path <%= roles_path.size == 1 ? roles_path.first.inspect : roles_path.inspect %>
role_path <%= roles_path.first.inspect %>
else
role_path <%= roles_path.inspect %>
end
<% end %> <% end %>
log_level <%= log_level.inspect %> log_level <%= log_level.inspect %>
verbose_logging <%= verbose_logging.inspect %> verbose_logging <%= verbose_logging.inspect %>

View File

@ -5,19 +5,12 @@ require Vagrant.source_root.join("plugins/commands/login/command")
describe VagrantPlugins::LoginCommand::Client do describe VagrantPlugins::LoginCommand::Client do
include_context "unit" include_context "unit"
def stub_env(key, value = nil)
allow(ENV).to receive(:[]).and_call_original
allow(ENV).to receive(:[])
.with(key)
.and_return(value)
end
let(:env) { isolated_environment.create_vagrant_env } let(:env) { isolated_environment.create_vagrant_env }
subject { described_class.new(env) } subject { described_class.new(env) }
before do before do
stub_env("ATLAS_TOKEN", nil) stub_env("ATLAS_TOKEN" => nil)
subject.clear_token subject.clear_token
end end
@ -101,7 +94,7 @@ describe VagrantPlugins::LoginCommand::Client do
describe "#token" do describe "#token" do
it "reads ATLAS_TOKEN" do it "reads ATLAS_TOKEN" do
stub_env("ATLAS_TOKEN", "ABCD1234") stub_env("ATLAS_TOKEN" => "ABCD1234")
expect(subject.token).to eq("ABCD1234") expect(subject.token).to eq("ABCD1234")
end end
@ -111,7 +104,7 @@ describe VagrantPlugins::LoginCommand::Client do
end end
it "prefers the environment variable" do it "prefers the environment variable" do
stub_env("ATLAS_TOKEN", "ABCD1234") stub_env("ATLAS_TOKEN" => "ABCD1234")
subject.store_token("EFGH5678") subject.store_token("EFGH5678")
expect(subject.token).to eq("ABCD1234") expect(subject.token).to eq("ABCD1234")
end end

View File

@ -17,6 +17,7 @@ describe VagrantPlugins::LoginCommand::AddAuthentication do
before do before do
allow(Vagrant).to receive(:server_url).and_return(server_url) allow(Vagrant).to receive(:server_url).and_return(server_url)
stub_env("ATLAS_TOKEN" => nil)
end end
describe "#call" do describe "#call" do
@ -60,5 +61,28 @@ describe VagrantPlugins::LoginCommand::AddAuthentication do
expect(env[:box_urls]).to eq(expected) expect(env[:box_urls]).to eq(expected)
end end
it "appends the access token to vagrantcloud.com URLs if Atlas" do
server_url = "https://atlas.hashicorp.com"
allow(Vagrant).to receive(:server_url).and_return(server_url)
token = "foobarbaz"
VagrantPlugins::LoginCommand::Client.new(iso_env).store_token(token)
original = [
"http://google.com/box.box",
"http://vagrantcloud.com/foo.box",
"http://vagrantcloud.com/bar.box?arg=true",
]
expected = original.dup
expected[1] = "#{original[1]}?access_token=#{token}"
expected[2] = "#{original[2]}&access_token=#{token}"
env[:box_urls] = original.dup
subject.call(env)
expect(env[:box_urls]).to eq(expected)
end
end end
end end

View File

@ -80,15 +80,23 @@ describe VagrantPlugins::CommunicatorWinRM::Communicator do
describe ".test" do describe ".test" do
it "returns true when exit code is zero" do it "returns true when exit code is zero" do
expect(shell).to receive(:powershell).with(kind_of(String)).and_return({ exitcode: 0 }) output = { exitcode: 0, data:[{ stderr: '' }] }
expect(shell).to receive(:powershell).with(kind_of(String)).and_return(output)
expect(subject.test("test -d c:/windows")).to be_true expect(subject.test("test -d c:/windows")).to be_true
end end
it "returns false when exit code is non-zero" do it "returns false when exit code is non-zero" do
expect(shell).to receive(:powershell).with(kind_of(String)).and_return({ exitcode: 1 }) output = { exitcode: 1, data:[{ stderr: '' }] }
expect(shell).to receive(:powershell).with(kind_of(String)).and_return(output)
expect(subject.test("test -d /tmp/foobar")).to be_false expect(subject.test("test -d /tmp/foobar")).to be_false
end end
it "returns false when stderr contains output" do
output = { exitcode: 0, data:[{ stderr: 'this is an error' }] }
expect(shell).to receive(:powershell).with(kind_of(String)).and_return(output)
expect(subject.test("[-x stuff] && foo")).to be_false
end
it "returns false when command is testing for linux OS" do it "returns false when command is testing for linux OS" do
expect(subject.test("uname -s | grep Debian")).to be_false expect(subject.test("uname -s | grep Debian")).to be_false
end end

View File

@ -89,6 +89,7 @@ describe VagrantPlugins::Kernel_V2::PushConfig do
let(:key) { pushes[:foo][0] } let(:key) { pushes[:foo][0] }
let(:config) { pushes[:foo][1] } let(:config) { pushes[:foo][1] }
let(:unset) { Vagrant.plugin("2", :config).const_get(:UNSET_VALUE) } let(:unset) { Vagrant.plugin("2", :config).const_get(:UNSET_VALUE) }
let(:dummy_klass) { Vagrant::Config::V2::DummyConfig }
before do before do
register_plugin("2") do |plugin| register_plugin("2") do |plugin|
@ -112,6 +113,62 @@ describe VagrantPlugins::Kernel_V2::PushConfig do
end end
end end
it "compiles the proper configuration with a single strategy" do
instance = described_class.new.tap do |i|
i.define "foo"
end
instance.finalize!
pushes = instance.__compiled_pushes
strategy, config = pushes[:foo]
expect(strategy).to eq(:foo)
expect(config.bar).to be(unset)
end
it "compiles the proper configuration with a single strategy and block" do
instance = described_class.new.tap do |i|
i.define "foo" do |b|
b.bar = 42
end
end
instance.finalize!
pushes = instance.__compiled_pushes
strategy, config = pushes[:foo]
expect(strategy).to eq(:foo)
expect(config.bar).to eq(42)
end
it "compiles the proper config with a name and explicit strategy" do
instance = described_class.new.tap do |i|
i.define "bar", strategy: "foo"
end
instance.finalize!
pushes = instance.__compiled_pushes
strategy, config = pushes[:bar]
expect(strategy).to eq(:foo)
expect(config.bar).to be(unset)
end
it "compiles the proper config with a name and explicit strategy with block" do
instance = described_class.new.tap do |i|
i.define "bar", strategy: "foo" do |b|
b.bar = 42
end
end
instance.finalize!
pushes = instance.__compiled_pushes
strategy, config = pushes[:bar]
expect(strategy).to eq(:foo)
expect(config.bar).to eq(42)
end
context "with the same name but different strategy" do context "with the same name but different strategy" do
context "with no block" do context "with no block" do
let(:a) do let(:a) do
@ -128,8 +185,7 @@ describe VagrantPlugins::Kernel_V2::PushConfig do
it "chooses the last config" do it "chooses the last config" do
expect(key).to eq(:zip) expect(key).to eq(:zip)
expect(config.bar).to be(unset) expect(config).to be_kind_of(dummy_klass)
expect(config.zip).to be(unset)
end end
end end
@ -152,8 +208,7 @@ describe VagrantPlugins::Kernel_V2::PushConfig do
it "chooses the last config" do it "chooses the last config" do
expect(key).to eq(:zip) expect(key).to eq(:zip)
expect(config.bar).to eq(unset) expect(config).to be_kind_of(dummy_klass)
expect(config.zip).to eq("b")
end end
end end
@ -174,8 +229,7 @@ describe VagrantPlugins::Kernel_V2::PushConfig do
it "chooses the last config" do it "chooses the last config" do
expect(key).to eq(:zip) expect(key).to eq(:zip)
expect(config.bar).to be(unset) expect(config).to be_kind_of(dummy_klass)
expect(config.zip).to be(unset)
end end
end end
@ -196,8 +250,7 @@ describe VagrantPlugins::Kernel_V2::PushConfig do
it "chooses the last config" do it "chooses the last config" do
expect(key).to eq(:zip) expect(key).to eq(:zip)
expect(config.bar).to eq("b") expect(config).to be_kind_of(dummy_klass)
expect(config.zip).to eq("b")
end end
end end
end end
@ -286,8 +339,7 @@ describe VagrantPlugins::Kernel_V2::PushConfig do
it "merges the configs" do it "merges the configs" do
expect(key).to eq(:zip) expect(key).to eq(:zip)
expect(config.bar).to eq(unset) expect(config).to be_kind_of(dummy_klass)
expect(config.zip).to eq("b")
end end
end end
end end

View File

@ -68,4 +68,11 @@ describe VagrantPlugins::Chef::Config::Base do
expect(subject.version).to eq(:latest) expect(subject.version).to eq(:latest)
end end
end end
describe "#installer_download_path" do
it "defaults to nil" do
subject.finalize!
expect(subject.installer_download_path).to be(nil)
end
end
end end

View File

@ -7,8 +7,9 @@ describe VagrantPlugins::Chef::Omnibus, :focus do
let(:version) { :latest } let(:version) { :latest }
let(:prerelease) { false } let(:prerelease) { false }
let(:download_path) { nil }
let(:build_command) { described_class.build_command(version, prerelease) } let(:build_command) { described_class.build_command(version, prerelease, download_path) }
context "when prerelease is given" do context "when prerelease is given" do
let(:prerelease) { true } let(:prerelease) { true }
@ -18,6 +19,14 @@ describe VagrantPlugins::Chef::Omnibus, :focus do
end end
end end
context "when download_path is given" do
let(:download_path) { '/tmp/path/to/omnibuses' }
it "returns the correct command" do
expect(build_command).to eq("#{prefix} | sudo bash -s -- -d \"/tmp/path/to/omnibuses\"")
end
end
context "when version is :latest" do context "when version is :latest" do
let(:version) { :latest } let(:version) { :latest }
@ -34,12 +43,13 @@ describe VagrantPlugins::Chef::Omnibus, :focus do
end end
end end
context "when prerelease and version are given" do context "when prerelease and version and download_path are given" do
let(:version) { "1.2.3" } let(:version) { "1.2.3" }
let(:prerelease) { true } let(:prerelease) { true }
let(:download_path) { "/some/path" }
it "returns the correct command" do it "returns the correct command" do
expect(build_command).to eq("#{prefix} | sudo bash -s -- -p -v \"1.2.3\"") expect(build_command).to eq("#{prefix} | sudo bash -s -- -p -v \"1.2.3\" -d \"/some/path\"")
end end
end end
end end

View File

@ -60,5 +60,23 @@ describe VagrantPlugins::Salt::Config do
expect(result[error_key]).to be_empty expect(result[error_key]).to be_empty
end end
end end
context "grains_config" do
it "fails if grains_config is set and missing" do
subject.grains_config = "/nope/still/not/here"
subject.finalize!
result = subject.validate(machine)
expect(result[error_key]).to_not be_empty
end
it "is valid if is set and not missing" do
subject.grains_config = File.expand_path(__FILE__)
subject.finalize!
result = subject.validate(machine)
expect(result[error_key]).to be_empty
end
end
end end
end end

View File

@ -9,7 +9,7 @@ describe VagrantPlugins::FTPPush::Push do
let(:env) { isolated_environment } let(:env) { isolated_environment }
let(:config) do let(:config) do
double("config", double("config",
host: "127.0.0.1:21212", host: "127.0.0.1:51234",
username: "sethvargo", username: "sethvargo",
password: "bacon", password: "bacon",
passive: false, passive: false,
@ -22,7 +22,7 @@ describe VagrantPlugins::FTPPush::Push do
describe "#push" do describe "#push" do
before(:all) do before(:all) do
@server = FakeFtp::Server.new(21212, 21213) @server = FakeFtp::Server.new(51234, 21213)
@server.start @server.start
@dir = Dir.mktmpdir @dir = Dir.mktmpdir

View File

@ -93,47 +93,9 @@ describe VagrantPlugins::LocalExecPush::Push do
end end
describe "#execute!" do describe "#execute!" do
let(:exit_code) { 0 } it "safe execs" do
let(:stdout) { "This is the output" } expect(Vagrant::Util::SafeExec).to receive(:exec)
let(:stderr) { "This is the errput" }
let(:process) do
double("process",
exit_code: exit_code,
stdout: stdout,
stderr: stderr,
)
end
before do
allow(Vagrant::Util::Subprocess).to receive(:execute)
.and_return(process)
end
it "creates a subprocess" do
expect(Vagrant::Util::Subprocess).to receive(:execute)
expect { subject.execute! }.to_not raise_error expect { subject.execute! }.to_not raise_error
end end
it "returns the resulting process" do
expect(subject.execute!).to be(process)
end
context "when the exit code is non-zero" do
let(:exit_code) { 1 }
it "raises an exception" do
klass = VagrantPlugins::LocalExecPush::Errors::CommandFailed
cmd = ["foo", "bar"]
expect { subject.execute!(*cmd) }.to raise_error(klass) { |error|
expect(error.message).to eq(I18n.t("local_exec_push.errors.command_failed",
cmd: cmd.join(" "),
stdout: stdout,
stderr: stderr,
))
}
end
end
end end
end end

View File

@ -83,6 +83,18 @@ shared_context "unit" do
return Pathname.new(d) return Pathname.new(d)
end end
# Stub the given environment in ENV, without actually touching ENV. Keys and
# values are converted to strings because that's how the real ENV works.
def stub_env(hash)
allow(ENV).to receive(:[]).and_call_original
hash.each do |key, value|
allow(ENV).to receive(:[])
.with(key.to_s)
.and_return(value.to_s)
end
end
# This helper provides temporary environmental variable changes. # This helper provides temporary environmental variable changes.
def with_temp_env(environment) def with_temp_env(environment)
# Build up the new environment, preserving the old values so we # Build up the new environment, preserving the old values so we

View File

@ -1 +1 @@
1.7.0 1.7.2.dev

View File

@ -173,6 +173,7 @@
<li<%= sidebar_current("provisioning-ansible") %>><a href="/v2/provisioning/ansible.html">Ansible</a></li> <li<%= sidebar_current("provisioning-ansible") %>><a href="/v2/provisioning/ansible.html">Ansible</a></li>
<li<%= sidebar_current("provisioning-cfengine") %>><a href="/v2/provisioning/cfengine.html">CFEngine</a></li> <li<%= sidebar_current("provisioning-cfengine") %>><a href="/v2/provisioning/cfengine.html">CFEngine</a></li>
<li<%= sidebar_current("provisioning-chefsolo") %>><a href="/v2/provisioning/chef_solo.html">Chef Solo</a></li> <li<%= sidebar_current("provisioning-chefsolo") %>><a href="/v2/provisioning/chef_solo.html">Chef Solo</a></li>
<li<%= sidebar_current("provisioning-chefzero") %>><a href="/v2/provisioning/chef_zero.html">Chef Zero</a></li>
<li<%= sidebar_current("provisioning-chefclient") %>><a href="/v2/provisioning/chef_client.html">Chef Client</a></li> <li<%= sidebar_current("provisioning-chefclient") %>><a href="/v2/provisioning/chef_client.html">Chef Client</a></li>
<li<%= sidebar_current("provisioning-chefapply") %>><a href="/v2/provisioning/chef_apply.html">Chef Apply</a></li> <li<%= sidebar_current("provisioning-chefapply") %>><a href="/v2/provisioning/chef_apply.html">Chef Apply</a></li>
<li<%= sidebar_current("provisioning-docker") %>><a href="/v2/provisioning/docker.html">Docker</a></li> <li<%= sidebar_current("provisioning-docker") %>><a href="/v2/provisioning/docker.html">Docker</a></li>

View File

@ -36,7 +36,8 @@ General settings:
but not to the host machine. Useful for links. but not to the host machine. Useful for links.
* `link` (method, string argument) - Link this container to another * `link` (method, string argument) - Link this container to another
by name. Example: `docker.link("db:db")`. Note, if you're linking to by name. The argument should be in the format of `(name:alias)`.
Example: `docker.link("db:db")`. Note, if you're linking to
another container in the same Vagrantfile, make sure you call another container in the same Vagrantfile, make sure you call
`vagrant up` with the `--no-parallel` flag. `vagrant up` with the `--no-parallel` flag.

View File

@ -45,7 +45,7 @@ it can greatly improve readability. Additionally, some provisioners, like
the Chef provisioner, have special methods that can be called within that the Chef provisioner, have special methods that can be called within that
block to ease configuration that can't be done with the key/value approach. block to ease configuration that can't be done with the key/value approach.
Provisioners can also be named. These names are used cosmetically for output Provisioners can also be named (since 1.7.0). These names are used cosmetically for output
as well as overriding provisioner settings (covered further below). An example as well as overriding provisioner settings (covered further below). An example
of naming provisioners is shown below: of naming provisioners is shown below:

View File

@ -29,9 +29,6 @@ This section lists the complete set of available options for the Chef Apply
provisioner. More detailed examples of how to use the provisioner are provisioner. More detailed examples of how to use the provisioner are
available below this section. available below this section.
Due to the unqiue nature of Chef Apply, the Chef Apply provisioner does not
inherit the [common options for other Chef provisioners](/v2/provisioning/chef_common.html).
* `recipe` (string) - The raw recipe contents to execute using Chef Apply on * `recipe` (string) - The raw recipe contents to execute using Chef Apply on
the guest. the guest.
@ -44,6 +41,9 @@ inherit the [common options for other Chef provisioners](/v2/provisioning/chef_c
`/tmp/vagrant-chef-apply-#` where `#` is a unique counter generated by `/tmp/vagrant-chef-apply-#` where `#` is a unique counter generated by
Vagrant to prevent collisions. Vagrant to prevent collisions.
In addition to all the options listed above, the Chef Apply provisioner supports
the [common options for all Chef provisioners](/v2/provisioning/chef_common.html).
## Specifying a Recipe ## Specifying a Recipe
The easiest way to get started with the Chef Apply provisioner is to just The easiest way to get started with the Chef Apply provisioner is to just

View File

@ -82,12 +82,15 @@ end
There are a few more configuration options available. These generally don't There are a few more configuration options available. These generally don't
need to be modified but are available if your Chef Server requires customization need to be modified but are available if your Chef Server requires customization
of these variables: of these variables.
* `client_key_path` * `client_key_path`
* `node_name` * `node_name`
* `validation_client_name` * `validation_client_name`
In addition to all the options listed above, the Chef Client provisioner supports
the [common options for all Chef provisioners](/v2/provisioning/chef_common.html).
## Cleanup ## Cleanup
When you provision your Vagrant virtual machine with Chef Server, it creates a When you provision your Vagrant virtual machine with Chef Server, it creates a

View File

@ -5,12 +5,55 @@ sidebar_current: "provisioning-chefcommon"
# Shared Chef Options # Shared Chef Options
This page documents the list of available options that are available in the ## All Chef Provisioners
[Chef Solo](/v2/provisioning/chef_solo.html),
[Chef Zero](/v2/provisioning/chef_zero.html) The following options are available to all Chef provisioners. Many of these
and options are for advanced users only and should not be used unless you understand
[Chef Client](/v2/provisioning/chef_client.html) their purpose.
provisioners.
- `binary_path` (string) - The path to Chef's `bin/` directory on the guest
machine.
- `binary_env` (string) - Arbitrary environment variables to set before running
the Chef provisioner command. This should be of the format `KEY=value` as a
string.
- `install` (boolean, string) - Install Chef on the system if it does not exist.
The default value is "true", which will use the official Omnibus installer
from Chef. This is a trinary attribute (it can have three values):
- `true` (boolean) - install Chef
- `false` (boolean) - do not install Chef
- `"force"` (string) - install Chef, even if it is already installed at the
proper version on the guest
- `installer_download_path` (string) - The path where the Chef installer will be
downloaded to. This option is only honored if the `install` attribute is
`true` or `"force"`. The default value is to use the path provided by Chef's
Omnibus installer, which varies between releases.
- `log_level` (string) - The Chef log level. See the Chef docs for acceptable
values.
- `prerelease` (boolean) - Install a prerelease version of Chef. The default
value is false.
- `version` (string) - The version of Chef to install on the guest. If Chef is
already installed on the system, the installed version is compared with the
requested version. If they match, no action is taken. If they do not match,
the value specified in this attribute will be installed in favor of the
existing version (a message will be displayed).
You can also specify "latest" (default), which will install the latest
version of Chef on the system. In this case, Chef will use whatever
version is on the system. To force the newest version of Chef to be
installed on every provision, set the {#install} option to "force".
## Runner Chef Provisioners
The following options are available to any of the Chef "runner" provisioners
which include [Chef Solo](/v2/provisioning/chef_solo.html), [Chef Zero](/v2/provisioning/chef_zero.html), and [Chef Client](/v2/provisioning/chef_client.html).
* `arguments` (string) - A list of additional arguments to pass on the * `arguments` (string) - A list of additional arguments to pass on the
command-line to Chef. Since these are passed in a shell-like environment, command-line to Chef. Since these are passed in a shell-like environment,
@ -21,9 +64,6 @@ provisioners.
This defaults to 1. This can be increased to a higher number if your Chef This defaults to 1. This can be increased to a higher number if your Chef
runs take multiple runs to reach convergence. runs take multiple runs to reach convergence.
* `binary_path` (string) - The path to the directory of the Chef executable
binaries. By default, Vagrant looks for the proper Chef binary on the PATH.
* `custom_config_path` (string) - A path to a custom Chef configuration local * `custom_config_path` (string) - A path to a custom Chef configuration local
on your machine that will be used as the Chef configuration. This Chef on your machine that will be used as the Chef configuration. This Chef
configuration will be loaded _after_ the Chef configuration that Vagrant configuration will be loaded _after_ the Chef configuration that Vagrant

View File

@ -32,10 +32,6 @@ This section lists the complete set of available options for the Chef Solo
provisioner. More detailed examples of how to use the provisioner are provisioner. More detailed examples of how to use the provisioner are
available below this section. available below this section.
Note that only the Chef-solo specific options are shown below. There is
also a large set of [common options](/v2/provisioning/chef_common.html)
that are available with all Chef provisioners.
* `cookbooks_path` (string or array) - A list of paths to where cookbooks * `cookbooks_path` (string or array) - A list of paths to where cookbooks
are stored. By default this is "cookbooks", expecting a cookbooks folder are stored. By default this is "cookbooks", expecting a cookbooks folder
relative to the Vagrantfile location. relative to the Vagrantfile location.
@ -62,6 +58,9 @@ that are available with all Chef provisioners.
this will use the default synced folder type. For example, you can set this this will use the default synced folder type. For example, you can set this
to "nfs" to use NFS synced folders. to "nfs" to use NFS synced folders.
In addition to all the options listed above, the Chef Solo provisioner supports
the [common options for all Chef provisioners](/v2/provisioning/chef_common.html).
## Specifying a Run List ## Specifying a Run List
The easiest way to get started with the Chef Solo provisioner is to just The easiest way to get started with the Chef Solo provisioner is to just

View File

@ -31,13 +31,12 @@ This section lists the complete set of available options for the Chef Zero
provisioner. More detailed examples of how to use the provisioner are provisioner. More detailed examples of how to use the provisioner are
available below this section. available below this section.
Note that only the Chef Zero specific options are shown below, but all [Chef
Solo options](/v2/provisioning/chef_solo.html), including the [common Chef
provisioner options](/v2/provisioning/chef_common.html), are also inherited.
* `nodes_path` (string) - A path where the Chef nodes are stored. Be default, * `nodes_path` (string) - A path where the Chef nodes are stored. Be default,
no node path is set. no node path is set.
In addition to all the options listed above, the Chef Zero provisioner supports
the [common options for all Chef provisioners](/v2/provisioning/chef_common.html).
## Usage ## Usage
The Chef Zero provisioner is configured basically the same way as the Chef Solo The Chef Zero provisioner is configured basically the same way as the Chef Solo

View File

@ -56,7 +56,7 @@ on this machine. Not supported on Windows.
`false`. Not supported on Windows. `false`. Not supported on Windows.
* `install_type` (stable | git | daily | testing) - Whether to install from a * `install_type` (stable | git | daily | testing) - Whether to install from a
distribution's stable package manager, git tree-ish, daily ppa, or testing repository. distribution's stable package manager, git tree-ish, daily ppa, or testing repository.
Not supported on Windows. Not supported on Windows.
* `install_args` (develop) - When performing a git install, * `install_args` (develop) - When performing a git install,
@ -77,6 +77,7 @@ a custom salt minion config file.
* `minion_pub` (salt/key/minion.pub) - Path to your minion * `minion_pub` (salt/key/minion.pub) - Path to your minion
public key public key
* `grains_config` (string) - Path to a custom salt grains file.
## Master Options ## Master Options
These only make sense when `install_master` is `true`. These only make sense when `install_master` is `true`.

View File

@ -10,7 +10,7 @@ description: |-
## Heroku Strategy ## Heroku Strategy
[Heroku][] is a public IAAS provider that makes it easy to deploy an [Heroku][] is a public PAAS provider that makes it easy to deploy an
application. The Vagrant Push Heroku strategy pushes your application's code to application. The Vagrant Push Heroku strategy pushes your application's code to
Heroku. Heroku.

View File

@ -29,7 +29,7 @@ machines. `vagrant connect` creates a tiny virtual machine that takes up
only around 20 MB in RAM, using VirtualBox or VMware (more provider support only around 20 MB in RAM, using VirtualBox or VMware (more provider support
is coming soon). is coming soon).
Any traffic sent to this tiny virtual machine is then proxies through to Any traffic sent to this tiny virtual machine is then proxied through to
the shared Vagrant environment as if it were directed at it. the shared Vagrant environment as if it were directed at it.
## Beware: Vagrant Insecure Key ## Beware: Vagrant Insecure Key

View File

@ -90,7 +90,7 @@ Cmnd_Alias VAGRANT_EXPORTS_REMOVE = /usr/bin/sed -E -e /*/ d -ibak /etc/exports
%admin ALL=(root) NOPASSWD: VAGRANT_EXPORTS_ADD, VAGRANT_NFSD, VAGRANT_EXPORTS_REMOVE %admin ALL=(root) NOPASSWD: VAGRANT_EXPORTS_ADD, VAGRANT_NFSD, VAGRANT_EXPORTS_REMOVE
``` ```
For Linux, sudoers should look like this: For Ubuntu Linux , sudoers should look like this:
``` ```
Cmnd_Alias VAGRANT_EXPORTS_ADD = /usr/bin/tee -a /etc/exports Cmnd_Alias VAGRANT_EXPORTS_ADD = /usr/bin/tee -a /etc/exports
@ -101,3 +101,14 @@ Cmnd_Alias VAGRANT_EXPORTS_REMOVE = /bin/sed -r -e * d -ibak /etc/exports
%sudo ALL=(root) NOPASSWD: VAGRANT_EXPORTS_ADD, VAGRANT_NFSD_CHECK, VAGRANT_NFSD_START, VAGRANT_NFSD_APPLY, VAGRANT_EXPORTS_REMOVE %sudo ALL=(root) NOPASSWD: VAGRANT_EXPORTS_ADD, VAGRANT_NFSD_CHECK, VAGRANT_NFSD_START, VAGRANT_NFSD_APPLY, VAGRANT_EXPORTS_REMOVE
``` ```
For Fedora Linux, sudoers might look like this (given your user
belongs to the vagrant group):
```
Cmnd_Alias VAGRANT_EXPORTS_ADD = /usr/bin/tee -a /etc/exports
Cmnd_Alias VAGRANT_NFSD_CHECK = /usr/bin/systemctl status nfs-server.service
Cmnd_Alias VAGRANT_NFSD_START = /usr/bin/systemctl start nfs-server.service
Cmnd_Alias VAGRANT_NFSD_APPLY = /usr/sbin/exportfs -ar
Cmnd_Alias VAGRANT_EXPORTS_REMOVE = /bin/sed -r -e * d -ibak /etc/exports
%vagrant ALL=(root) NOPASSWD: VAGRANT_EXPORTS_ADD, VAGRANT_NFSD_CHECK, VAGRANT_NFSD_START, VAGRANT_NFSD_APPLY, VAGRANT_EXPORTS_REMOVE
```

View File

@ -4,13 +4,11 @@
$script = <<SCRIPT $script = <<SCRIPT
sudo apt-get -y update sudo apt-get -y update
sudo apt-get -y install curl sudo apt-get -y install curl
curl -sSL https://get.rvm.io | bash -s stable sudo su -l -c 'gpg --keyserver hkp://keys.gnupg.net --recv-keys D39DC0E3' vagrant
. ~/.bashrc sudo su -l -c 'curl -L https://get.rvm.io | bash -s stable --auto-dotfiles' vagrant
. ~/.bash_profile sudo su -l -c 'rvm install 2.0.0' vagrant
rvm install 2.0.0 sudo su -l -c 'rvm --default use 2.0.0' vagrant
rvm --default use 2.0.0 sudo su -l -c 'cd /vagrant && bundle install --jobs 2' vagrant
cd /vagrant
bundle
SCRIPT SCRIPT
Vagrant.configure(2) do |config| Vagrant.configure(2) do |config|

View File

@ -0,0 +1,129 @@
---
page_title: "Vagrant Push: One Command to Deploy Any Application"
title: "Vagrant Push: One Command to Deploy Any Application"
author: "Mitchell Hashimoto"
author_url: https://github.com/mitchellh
---
Vagrant 1.7 comes with a new command: `vagrant push`. Just as "vagrant up"
is a single command to create a development environment for any application,
`vagrant push` is a single command to _deploy_ any application.
The goal of Vagrant is to give developers a single workflow to develop
applications effectively. "vagrant up" creates a development environment for any
application and "vagrant share" enables collaboration for any application.
Deploying was the next logical step for Vagrant, now possible with
"vagrant push".
Like every other component of Vagrant, push can be configured using multiple
strategies. "vagrant push" can deploy via FTP, Heroku,
[Atlas](https://atlas.hashicorp.com), or by executing any local script.
Other strategies can be added via plugins and more will be added to core
as time goes on.
Read on to learn more.
READMORE
### Demo
We've prepared a short video showing Vagrant Push in action.
<iframe src="//player.vimeo.com/video/114328000" width="680" height="382" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>
### Push to Deploy
`vagrant push` works like anything else in Vagrant: configure it in the
Vagrantfile, and it is immediately available to every developer. Push
configuration is simple and easy to understand:
```
config.push.define "ftp" do |push|
push.host = "ftp.company.com"
push.username = "username"
push.password = "mypassword"
end
```
And then to push the application to the FTP or SFTP server:
```
$ vagrant push
...
```
The "ftp" in the configuration above defines the strategy Vagrant will
use to push. Below, we cover strategies in more detail.
Additionally, multiple `config.push.define` declarations can be in a Vagrantfile to
define multiple pushes, perhaps one to staging and one to production, for
example. To learn more about multiple push definitions,
[read the complete documentation](https://docs.vagrantup.com/v2/push/index.html).
### A Single Command
The biggest benefit of Vagrant Push is being able to define a single command
to deploy any application. Whether the deploy process is complex or
is just a simple push to Heroku, developers only need to know that any
application within their organizations can be deployed with `vagrant push`.
For complicated deploys, the benefit is obvious. For simpler deploys, such
as a push to Heroku, Vagrant Push is still useful. Besides not having
to know that Heroku is being used under the hood, Vagrant Push will
automatically configure your Git remote so the push works. Prior to this,
you'd at least have to know the Heroku application name and configure
your local repository to be able to push to it.
Of course, not all applications stay that simple, and if your application
outgrows Heroku, then the deploy process doesn't change with Vagrant:
`vagrant push` to deploy any application.
### Push Strategies
Like providers, provisioners, and other features in Vagrant, pushes can
be configured with multiple _strategies_. Vagrant 1.7 ships with four
strategies:
* [Atlas](https://docs.vagrantup.com/v2/push/atlas.html) - Push application
to [Atlas](https://atlas.hashicorp.com), a commercial
product from HashiCorp.
* [FTP/SFTP](https://docs.vagrantup.com/v2/push/ftp.html) - Upload files
via FTP or SFTP to a remote server. This is great for static sites,
PHP, etc.
* [Heroku](https://docs.vagrantup.com/v2/push/heroku.html) - Push your
Git repository to Heroku, and configure the Git remote for you if
it doesn't already exist.
* [Local Exec](https://docs.vagrantup.com/v2/push/local-exec.html) -
Executes a local script on the system using a shell, deferring deployment
logic to the user. This is for custom behavior or more complicated
interactions with systems.
In addition to these built-in strategies, new strategies can be
[built just like any other Vagrant plugin](https://docs.vagrantup.com/v2/plugins/development-basics.html).
This allows 3rd parties to extend the capabilities of `vagrant push`, and
will surely result in future versions of Vagrant shipping with more push
strategies.
### Next
To learn all the details about Vagrant Push, please read the
[complete documentation](https://docs.vagrantup.com/v2/push/index.html).
This is a historic day for Vagrant. Vagrant 0.1 came out and defined
"vagrant up" to build a development environment for any application.
Vagrant 1.1 made it possible to have development environments on top of
any provider (VMware, Docker, etc.). Vagrant 1.5 introduced the "share"
command to collaborate. And now, Vagrant 1.7 completes the development
process with "push" to deploy.
The mission of Vagrant has been the same since day one: development
environments made easy. This mission spans any language choice, any
provider choice, and likewise any choice of how to deploy these
applications. Push continues this mission by adding a necessary
feature to the development workflow.
With Vagrant 1.7 available, we'll be blogging about more of the features
as well as creeping towards a 2.0!

View File

@ -14,7 +14,8 @@ page_title: "Download Vagrant"
Below are all available downloads for the latest version of Vagrant Below are all available downloads for the latest version of Vagrant
(<%= latest_version %>). Please download the proper package for your (<%= latest_version %>). Please download the proper package for your
operating system and architecture. You can find SHA256 checksums operating system and architecture. You can find SHA256 checksums
for packages <a href="https://dl.bintray.com/mitchellh/vagrant/<%= latest_version %>_SHA256SUMS?direct">here</a>. for packages <a href="https://dl.bintray.com/mitchellh/vagrant/<%= latest_version %>_SHA256SUMS?direct">here</a>,
and you can find the version changelog <a href="https://github.com/mitchellh/vagrant/blob/master/CHANGELOG.md">here</a>.
</p> </p>
</div> </div>