Merge branch 'master' of github.com:mitchellh/vagrant into winrmssl

This commit is contained in:
Max Lincoln 2015-01-20 16:00:20 -05:00
commit e07f229f6e
171 changed files with 1874 additions and 825 deletions

View File

@ -1,3 +1,79 @@
## 1.7.3 (unreleased)
BUG FIXES:
- core: push configurations are validated with global configs [GH-5130]
- core: remove executable permissions on internal file [GH-5220]
- core: check name and version in `has_plugin?` [GH-5218]
- hosts/nfs: allow colons (`:`) in NFS IDs [GH-5222]
- guests/funtoo: fix incorrect path in configure networks [GH-4812]
- plugins/login: allow users to login with a token [GH-5145]
- providers/hyperv: allow users to configure memory, cpu count, and vmname [GH-5183]
- provisioners/ansible: fix SSH settings to support more than 5 ssh keys [GH-5017]
- provisioners/ansible: increase ansible connection timeout to 30 seconds [GH-5018]
- provisioners/docker: use docker.com instead of docker.io [GH-5216]
## 1.7.2 (January 6, 2015)
BREAKING CHANGES:
- If you depended on the paths that Chef/Puppet provisioners use to
store cookbooks (ex. "/tmp/vagrant-chef-1"), these will no longer be
correct. Without this change, Chef/Puppet didn't work at all with
`vagrant provision`. We expect this to affect only a minor number of
people, since it's not something that was ever documented or recommended
by Vagrant, or even meant to be supported.
FEATURES:
- provisioners/salt: add support for grains [GH-4895]
IMPROVEMENTS:
- commands/reload,up: `--provision-with` implies `--provision` [GH-5085]
BUG FIXES:
- core: private boxes still referencing vagrantcloud.com will have
their vagrant login access token properly appended
- core: push plugin configuration is properly validated
- core: restore box packaging functionality
- commands/package: fix crash
- commands/push: push lookups are by user-defined name, not push
strategy name [GH-4975]
- commands/push: validate the configuration
- communicators/winrm: detect parse errors in PowerShell and error
- guests/arch: fix network configuration due to poor line breaks. [GH-4964]
- guests/solaris: Merge configurations properly so configs can be set
in default Vagrantfiles. [GH-5092]
- installer: SSL cert bundle contains 1024-bit keys, fixing SSL verification
for a lot of sites.
- installer: vagrant executable properly `cygpaths` the SSL bundle path
for Cygwin
- installer: Nokogiri (XML lib used by Vagrant and dependencies) linker
dependencies fixed, fixing load issues on some platforms
- providers/docker: Symlinks in shared folders work. [GH-5093]
- providers/hyperv: VM start errors turn into proper Vagrant errors. [GH-5101]
- provisioners/chef: fix missing shared folder error [GH-4988]
- provisioners/chef: remove Chef version check from solo.rb generation and
make `roles_path` populate correctly
- provisioners/chef: fix bad invocation of `with_clean_env` [GH-5021]
- pushes/atlas: support more verbose logging
- pushes/ftp: expand file paths relative to the Vagrantfile
- pushes/ftp: improved debugging output
- pushes/ftp: create parent directories if they do not exist on the remote
server
## 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 +178,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]

View File

@ -1,6 +1,6 @@
The MIT License The MIT License
Copyright (c) 2010-2014 Mitchell Hashimoto Copyright (c) 2010-2015 Mitchell Hashimoto
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View File

@ -68,7 +68,7 @@ like so:
bundle exec vagrant help bundle exec vagrant help
**NOTE:** By default running Vagrant in via `bundle` will disable plugins. **NOTE:** By default running Vagrant via `bundle` will disable plugins.
This is necessary because Vagrant creates its own private Bundler context This is necessary because Vagrant creates its own private Bundler context
(it does not respect your Gemfile), because it uses Bundler to manage plugin (it does not respect your Gemfile), because it uses Bundler to manage plugin
dependencies. dependencies.

10
Vagrantfile vendored
View File

@ -6,13 +6,21 @@
Vagrant.configure("2") do |config| Vagrant.configure("2") do |config|
config.vm.box = "hashicorp/precise64" config.vm.box = "hashicorp/precise64"
["virtualbox", "vmware_fusion", "vmware_workstation"].each do |provider| ["vmware_fusion", "vmware_workstation", "virtualbox"].each do |provider|
config.vm.provider provider do |v, override| config.vm.provider provider do |v, override|
v.memory = "1024" v.memory = "1024"
end end
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

@ -65,7 +65,7 @@ _vagrant() {
then then
case "$prev" in case "$prev" in
"init") "init")
local box_list=$(find $HOME/.vagrant.d/boxes -mindepth 1 -maxdepth 1 -type d -exec basename {} \;) local box_list=$(find "${VAGRANT_HOME:-${HOME}/.vagrant.d}/boxes" -mindepth 1 -maxdepth 1 -type d -exec basename {} \;)
COMPREPLY=($(compgen -W "${box_list}" -- ${cur})) COMPREPLY=($(compgen -W "${box_list}" -- ${cur}))
return 0 return 0
;; ;;
@ -111,7 +111,7 @@ _vagrant() {
then then
case "$prev" in case "$prev" in
"remove"|"repackage") "remove"|"repackage")
local box_list=$(find $HOME/.vagrant.d/boxes -mindepth 1 -maxdepth 1 -type d -exec basename {} \;) local box_list=$(find "${VAGRANT_HOME:-${HOME}/.vagrant.d}/boxes" -mindepth 1 -maxdepth 1 -type d -exec basename {} \;)
COMPREPLY=($(compgen -W "${box_list}" -- ${cur})) COMPREPLY=($(compgen -W "${box_list}" -- ${cur}))
return 0 return 0
;; ;;

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

@ -156,7 +156,7 @@ module Vagrant
Plugin::Manager.instance.installed_specs.any? do |s| Plugin::Manager.instance.installed_specs.any? do |s|
match = s.name == name match = s.name == name
next match if !version next match if !version
next version.satisfied_by?(s.version) next match && version.satisfied_by?(s.version)
end end
end end

View File

@ -369,7 +369,7 @@ module Vagrant
# #
# @return [Hash] # @return [Hash]
def downloader(url, env, **opts) def downloader(url, env, **opts)
opts[:ui] = true if !opts.has_key?(:ui) opts[:ui] = true if !opts.key?(:ui)
temp_path = env[:tmp_path].join("box" + Digest::SHA1.hexdigest(url)) temp_path = env[:tmp_path].join("box" + Digest::SHA1.hexdigest(url))
@logger.info("Downloading box: #{url} => #{temp_path}") @logger.info("Downloading box: #{url} => #{temp_path}")
@ -409,7 +409,7 @@ module Vagrant
end end
def download(url, env, **opts) def download(url, env, **opts)
opts[:ui] = true if !opts.has_key?(:ui) opts[:ui] = true if !opts.key?(:ui)
d = downloader(url, env, **opts) d = downloader(url, env, **opts)

View File

@ -11,7 +11,7 @@ module Vagrant
end end
def call(env) def call(env)
if !env.has_key?(:config_validate) || env[:config_validate] if !env.key?(:config_validate) || env[:config_validate]
errors = env[:machine].config.validate(env[:machine]) errors = env[:machine].config.validate(env[:machine])
if errors && !errors.empty? if errors && !errors.empty?

View File

@ -24,7 +24,7 @@ module Vagrant
def call(env) def call(env)
graceful = true graceful = true
graceful = !env[:force_halt] if env.has_key?(:force_halt) graceful = !env[:force_halt] if env.key?(:force_halt)
# By default, we didn't succeed. # By default, we didn't succeed.
env[:result] = false env[:result] = false

View File

@ -129,7 +129,7 @@ module Vagrant
# If we have folders with the "default" key, then determine the # If we have folders with the "default" key, then determine the
# most appropriate implementation for this. # most appropriate implementation for this.
if folders.has_key?("") && !folders[""].empty? if folders.key?("") && !folders[""].empty?
default_impl = default_synced_folder_type(machine, plugins) default_impl = default_synced_folder_type(machine, plugins)
if !default_impl if !default_impl
types = plugins.to_hash.keys.map { |t| t.to_s }.sort.join(", ") types = plugins.to_hash.keys.map { |t| t.to_s }.sort.join(", ")

View File

@ -24,13 +24,13 @@ module Vagrant
# Tracks whether we were configured to provision # Tracks whether we were configured to provision
config_enabled = true config_enabled = true
config_enabled = env[:provision_enabled] if env.has_key?(:provision_enabled) config_enabled = env[:provision_enabled] if env.key?(:provision_enabled)
# Check if we already provisioned, and if so, disable the rest # Check if we already provisioned, and if so, disable the rest
provision_enabled = true provision_enabled = true
ignore_sentinel = true ignore_sentinel = true
if env.has_key?(:provision_ignore_sentinel) if env.key?(:provision_ignore_sentinel)
ignore_sentinel = env[:provision_ignore_sentinel] ignore_sentinel = env[:provision_ignore_sentinel]
end end
if ignore_sentinel if ignore_sentinel
@ -69,7 +69,7 @@ module Vagrant
end end
# Store the value so that other actions can use it # Store the value so that other actions can use it
env[:provision_enabled] = provision_enabled if !env.has_key?(:provision_enabled) env[:provision_enabled] = provision_enabled if !env.key?(:provision_enabled)
# Ask the provisioners to modify the configuration if needed # Ask the provisioners to modify the configuration if needed
provisioner_instances(env).each do |p, _| provisioner_instances(env).each do |p, _|

View File

@ -49,7 +49,7 @@ module Vagrant
# Run the action chain in a busy block, marking the environment as # Run the action chain in a busy block, marking the environment as
# interrupted if a SIGINT occurs, and exiting cleanly once the # interrupted if a SIGINT occurs, and exiting cleanly once the
# chain has been run. # chain has been run.
ui = environment[:ui] if environment.has_key?(:ui) ui = environment[:ui] if environment.key?(:ui)
int_callback = lambda do int_callback = lambda do
if environment[:interrupted] if environment[:interrupted]
ui.error I18n.t("vagrant.actions.runner.exit_immediately") if ui ui.error I18n.t("vagrant.actions.runner.exit_immediately") if ui

View File

@ -165,7 +165,7 @@ module Vagrant
@cap_logger.debug("Checking in: #{host_name}") @cap_logger.debug("Checking in: #{host_name}")
caps = @cap_caps[host_name] caps = @cap_caps[host_name]
if caps && caps.has_key?(cap_name) if caps && caps.key?(cap_name)
@cap_logger.debug("Found cap: #{cap_name} in #{host_name}") @cap_logger.debug("Found cap: #{cap_name} in #{host_name}")
return caps[cap_name] return caps[cap_name]
end end

View File

@ -49,7 +49,7 @@ module Vagrant
# Gather the procs for every source, since that is what we care about. # Gather the procs for every source, since that is what we care about.
procs = [] procs = []
sources.each do |source| sources.each do |source|
if !@proc_cache.has_key?(source) if !@proc_cache.key?(source)
# Load the procs for this source and cache them. This caching # Load the procs for this source and cache them. This caching
# avoids the issue where a file may have side effects when loading # avoids the issue where a file may have side effects when loading
# and loading it multiple times causes unexpected behavior. # and loading it multiple times causes unexpected behavior.
@ -92,10 +92,10 @@ module Vagrant
errors = [] errors = []
order.each do |key| order.each do |key|
next if !@sources.has_key?(key) next if !@sources.key?(key)
@sources[key].each do |version, proc| @sources[key].each do |version, proc|
if !@config_cache.has_key?(proc) if !@config_cache.key?(proc)
@logger.debug("Loading from: #{key} (evaluating)") @logger.debug("Loading from: #{key} (evaluating)")
# Get the proper version loader for this version and load # Get the proper version loader for this version and load

View File

@ -60,7 +60,7 @@ module Vagrant
new_keys = new_state["keys"] new_keys = new_state["keys"]
keys = {} keys = {}
old_keys.each do |key, old_value| old_keys.each do |key, old_value|
if new_keys.has_key?(key) if new_keys.key?(key)
# We need to do a merge, which we expect to be available # We need to do a merge, which we expect to be available
# on the config class itself. # on the config class itself.
keys[key] = old_value.merge(new_keys[key]) keys[key] = old_value.merge(new_keys[key])
@ -72,7 +72,7 @@ module Vagrant
new_keys.each do |key, new_value| new_keys.each do |key, new_value|
# Add in the keys that the new class has that we haven't merged. # Add in the keys that the new class has that we haven't merged.
if !keys.has_key?(key) if !keys.key?(key)
keys[key] = new_value.dup keys[key] = new_value.dup
end end
end end

View File

@ -20,7 +20,7 @@ module Vagrant
# used for Vagrant and load the proper configuration classes for # used for Vagrant and load the proper configuration classes for
# each. # each.
def method_missing(name, *args) def method_missing(name, *args)
return @keys[name] if @keys.has_key?(name) return @keys[name] if @keys.key?(name)
config_klass = @config_map[name.to_sym] config_klass = @config_map[name.to_sym]
if config_klass if config_klass

View File

@ -70,7 +70,7 @@ module Vagrant
new_keys = new_state["keys"] new_keys = new_state["keys"]
keys = {} keys = {}
old_keys.each do |key, old_value| old_keys.each do |key, old_value|
if new_keys.has_key?(key) if new_keys.key?(key)
# We need to do a merge, which we expect to be available # We need to do a merge, which we expect to be available
# on the config class itself. # on the config class itself.
keys[key] = old_value.merge(new_keys[key]) keys[key] = old_value.merge(new_keys[key])
@ -82,7 +82,7 @@ module Vagrant
new_keys.each do |key, new_value| new_keys.each do |key, new_value|
# Add in the keys that the new class has that we haven't merged. # Add in the keys that the new class has that we haven't merged.
if !keys.has_key?(key) if !keys.key?(key)
keys[key] = new_value.dup keys[key] = new_value.dup
end end
end end

View File

@ -22,7 +22,7 @@ module Vagrant
# used for Vagrant and load the proper configuration classes for # used for Vagrant and load the proper configuration classes for
# each. # each.
def method_missing(name, *args) def method_missing(name, *args)
return @keys[name] if @keys.has_key?(name) return @keys[name] if @keys.key?(name)
config_klass = @config_map[name.to_sym] config_klass = @config_map[name.to_sym]
if config_klass if config_klass
@ -41,7 +41,7 @@ module Vagrant
# mutate itself. # mutate itself.
def finalize! def finalize!
@config_map.each do |key, klass| @config_map.each do |key, klass|
if !@keys.has_key?(key) if !@keys.key?(key)
@keys[key] = klass.new @keys[key] = klass.new
end end
end end
@ -102,9 +102,9 @@ module Vagrant
# This sets the internal state. This is used by the core to do some # This sets the internal state. This is used by the core to do some
# merging logic and shouldn't be used by the general public. # merging logic and shouldn't be used by the general public.
def __set_internal_state(state) def __set_internal_state(state)
@config_map = state["config_map"] if state.has_key?("config_map") @config_map = state["config_map"] if state.key?("config_map")
@keys = state["keys"] if state.has_key?("keys") @keys = state["keys"] if state.key?("keys")
@missing_key_calls = state["missing_key_calls"] if state.has_key?("missing_key_calls") @missing_key_calls = state["missing_key_calls"] if state.key?("missing_key_calls")
end end
end end
end end

View File

@ -80,7 +80,7 @@ module Vagrant
}.merge(opts || {}) }.merge(opts || {})
# Set the default working directory to look for the vagrantfile # Set the default working directory to look for the vagrantfile
opts[:cwd] ||= ENV["VAGRANT_CWD"] if ENV.has_key?("VAGRANT_CWD") opts[:cwd] ||= ENV["VAGRANT_CWD"] if ENV.key?("VAGRANT_CWD")
opts[:cwd] ||= Dir.pwd opts[:cwd] ||= Dir.pwd
opts[:cwd] = Pathname.new(opts[:cwd]) opts[:cwd] = Pathname.new(opts[:cwd])
if !opts[:cwd].directory? if !opts[:cwd].directory?
@ -94,7 +94,7 @@ module Vagrant
# Set the Vagrantfile name up. We append "Vagrantfile" and "vagrantfile" so that # Set the Vagrantfile name up. We append "Vagrantfile" and "vagrantfile" so that
# those continue to work as well, but anything custom will take precedence. # those continue to work as well, but anything custom will take precedence.
opts[:vagrantfile_name] ||= ENV["VAGRANT_VAGRANTFILE"] if \ opts[:vagrantfile_name] ||= ENV["VAGRANT_VAGRANTFILE"] if \
ENV.has_key?("VAGRANT_VAGRANTFILE") ENV.key?("VAGRANT_VAGRANTFILE")
opts[:vagrantfile_name] = [opts[:vagrantfile_name]] if \ opts[:vagrantfile_name] = [opts[:vagrantfile_name]] if \
opts[:vagrantfile_name] && !opts[:vagrantfile_name].is_a?(Array) opts[:vagrantfile_name] && !opts[:vagrantfile_name].is_a?(Array)
@ -307,7 +307,7 @@ module Vagrant
# @return [Symbol] Name of the default provider. # @return [Symbol] Name of the default provider.
def default_provider(**opts) def default_provider(**opts)
opts[:exclude] = Set.new(opts[:exclude]) if opts[:exclude] opts[:exclude] = Set.new(opts[:exclude]) if opts[:exclude]
opts[:force_default] = true if !opts.has_key?(:force_default) opts[:force_default] = true if !opts.key?(:force_default)
default = ENV["VAGRANT_DEFAULT_PROVIDER"] default = ENV["VAGRANT_DEFAULT_PROVIDER"]
default = nil if default == "" default = nil if default == ""
@ -351,15 +351,15 @@ module Vagrant
# Skip providers that can't be defaulted, unless they're in our # Skip providers that can't be defaulted, unless they're in our
# config, in which case someone made our decision for us. # config, in which case someone made our decision for us.
if !config.has_key?(key) if !config.key?(key)
next if popts.has_key?(:defaultable) && !popts[:defaultable] next if popts.key?(:defaultable) && !popts[:defaultable]
end end
# The priority is higher if it is in our config. Otherwise, it is # The priority is higher if it is in our config. Otherwise, it is
# the priority it set PLUS the length of the config to make sure it # the priority it set PLUS the length of the config to make sure it
# is never higher than the configuration keys. # is never higher than the configuration keys.
priority = popts[:priority] priority = popts[:priority]
priority = config[key] + max_priority if config.has_key?(key) priority = config[key] + max_priority if config.key?(key)
ordered << [priority, key, impl, popts] ordered << [priority, key, impl, popts]
end end
@ -596,7 +596,7 @@ module Vagrant
@machines.delete(cache_key) @machines.delete(cache_key)
end end
if @machines.has_key?(cache_key) if @machines.key?(cache_key)
@logger.info("Returning cached machine: #{name} (#{provider})") @logger.info("Returning cached machine: #{name} (#{provider})")
return @machines[cache_key] return @machines[cache_key]
end end

View File

@ -150,12 +150,14 @@ module Vagrant
# @param [Hash] extra_env This data will be passed into the action runner # @param [Hash] extra_env This data will be passed into the action runner
# as extra data set on the environment hash for the middleware # as extra data set on the environment hash for the middleware
# runner. # runner.
def action(name, **opts) def action(name, opts=nil)
@logger.info("Calling action: #{name} on provider #{@provider}") @logger.info("Calling action: #{name} on provider #{@provider}")
opts ||= {}
# Determine whether we lock or not # Determine whether we lock or not
lock = true lock = true
lock = opts.delete(:lock) if opts.has_key?(:lock) lock = opts.delete(:lock) if opts.key?(:lock)
# Extra env keys are the remaining opts # Extra env keys are the remaining opts
extra_env = opts.dup extra_env = opts.dup

View File

@ -143,7 +143,7 @@ module Vagrant
# If we already have a newer version in our list of installed, # If we already have a newer version in our list of installed,
# then ignore it # then ignore it
next if installed_map.has_key?(spec.name) && next if installed_map.key?(spec.name) &&
installed_map[spec.name].version >= spec.version installed_map[spec.name].version >= spec.version
installed_map[spec.name] = spec installed_map[spec.name] = spec

View File

@ -61,7 +61,7 @@ module Vagrant
# #
# @return [Boolean] # @return [Boolean]
def has_plugin?(name) def has_plugin?(name)
@data["installed"].has_key?(name) @data["installed"].key?(name)
end end
# Remove a plugin that is installed from the state file. # Remove a plugin that is installed from the state file.

View File

@ -88,7 +88,7 @@ module Vagrant
end end
# By default, the command is primary # By default, the command is primary
opts[:primary] = true if !opts.has_key?(:primary) opts[:primary] = true if !opts.key?(:primary)
# Register the command # Register the command
components.commands.register(name.to_sym) do components.commands.register(name.to_sym) do

View File

@ -22,8 +22,8 @@ module Vagrant
# This will evaluate the block given to `register` and return the # This will evaluate the block given to `register` and return the
# resulting value. # resulting value.
def get(key) def get(key)
return nil if !@items.has_key?(key) return nil if !@items.key?(key)
return @results_cache[key] if @results_cache.has_key?(key) return @results_cache[key] if @results_cache.key?(key)
@results_cache[key] = @items[key].call @results_cache[key] = @items[key].call
end end
alias :[] :get alias :[] :get
@ -31,9 +31,10 @@ module Vagrant
# Checks if the given key is registered with the registry. # Checks if the given key is registered with the registry.
# #
# @return [Boolean] # @return [Boolean]
def has_key?(key) def key?(key)
@items.has_key?(key) @items.key?(key)
end end
alias_method :has_key?, :key?
# Returns an array populated with the keys of this object. # Returns an array populated with the keys of this object.
# #

View File

@ -52,6 +52,13 @@ module Vagrant
!!ENV["VAGRANT_I_KNOW_WHAT_IM_DOING_PLEASE_BE_QUIET"] !!ENV["VAGRANT_I_KNOW_WHAT_IM_DOING_PLEASE_BE_QUIET"]
end end
# The current log level for Vagrant
#
# @return [String]
def self.log_level
ENV["VAGRANT_LOG"]
end
# Returns the URL prefix to the server. # Returns the URL prefix to the server.
# #
# @return [String] # @return [String]

View File

@ -136,9 +136,9 @@ module Vagrant
# Setup the options so that the new line is suppressed # Setup the options so that the new line is suppressed
opts ||= {} opts ||= {}
opts[:echo] = true if !opts.has_key?(:echo) opts[:echo] = true if !opts.key?(:echo)
opts[:new_line] = false if !opts.has_key?(:new_line) opts[:new_line] = false if !opts.key?(:new_line)
opts[:prefix] = false if !opts.has_key?(:prefix) opts[:prefix] = false if !opts.key?(:prefix)
# Output the data # Output the data
say(:info, message, opts) say(:info, message, opts)
@ -249,7 +249,7 @@ module Vagrant
class_eval <<-CODE class_eval <<-CODE
def #{method}(message, *args, **opts) def #{method}(message, *args, **opts)
super(message) super(message)
if !@ui.opts.has_key?(:bold) && !opts.has_key?(:bold) if !@ui.opts.key?(:bold) && !opts.key?(:bold)
opts[:bold] = #{method.inspect} != :detail && \ opts[:bold] = #{method.inspect} != :detail && \
#{method.inspect} != :ask #{method.inspect} != :ask
end end
@ -284,7 +284,7 @@ module Vagrant
opts = self.opts.merge(opts) opts = self.opts.merge(opts)
prefix = "" prefix = ""
if !opts.has_key?(:prefix) || opts[:prefix] if !opts.key?(:prefix) || opts[:prefix]
prefix = OUTPUT_PREFIX prefix = OUTPUT_PREFIX
prefix = " " * OUTPUT_PREFIX.length if \ prefix = " " * OUTPUT_PREFIX.length if \
type == :detail || type == :ask || opts[:prefix_spaces] type == :detail || type == :ask || opts[:prefix_spaces]
@ -294,7 +294,7 @@ module Vagrant
return message if prefix.empty? return message if prefix.empty?
target = @prefix target = @prefix
target = opts[:target] if opts.has_key?(:target) target = opts[:target] if opts.key?(:target)
# Get the lines. The first default is because if the message # Get the lines. The first default is because if the message
# is an empty string, then we want to still use the empty string. # is an empty string, then we want to still use the empty string.

View File

@ -26,7 +26,7 @@ module Vagrant
# @param [Proc] block # @param [Proc] block
# the block to execute with the cleaned environment # the block to execute with the cleaned environment
# #
def with_clean_env(&block) def self.with_clean_env(&block)
original = ENV.to_hash original = ENV.to_hash
ENV.delete('_ORIGINAL_GEM_PATH') ENV.delete('_ORIGINAL_GEM_PATH')

View File

@ -29,7 +29,8 @@ module Vagrant
# to connect. # to connect.
return true return true
end end
rescue Timeout::Error, Errno::ECONNREFUSED, Errno::EHOSTUNREACH, Errno::ENETUNREACH rescue Timeout::Error, Errno::ECONNREFUSED, Errno::EHOSTUNREACH, \
Errno::ENETUNREACH, Errno::EACCES
# Any of the above exceptions signal that the port is closed. # Any of the above exceptions signal that the port is closed.
return false return false
end end

View File

@ -148,7 +148,7 @@ module Vagrant
# output. # output.
def terminal_supports_colors? def terminal_supports_colors?
if windows? if windows?
return true if ENV.has_key?("ANSICON") return true if ENV.key?("ANSICON")
return true if cygwin? return true if cygwin?
return true if ENV["TERM"] == "cygwin" return true if ENV["TERM"] == "cygwin"
return false return false

View File

@ -32,7 +32,7 @@ module VagrantPlugins
:destroy, force_confirm_destroy: options[:force]) :destroy, force_confirm_destroy: options[:force])
total += 1 total += 1
declined += 1 if action_env.has_key?(:force_confirm_destroy_result) && declined += 1 if action_env.key?(:force_confirm_destroy_result) &&
action_env[:force_confirm_destroy_result] == false action_env[:force_confirm_destroy_result] == false
end end

View File

@ -7,11 +7,13 @@ module VagrantPlugins
# #
# @param [Vagrant::Environment] env # @param [Vagrant::Environment] env
def initialize(env) def initialize(env)
@env = env @logger = Log4r::Logger.new("vagrant::login::client")
@env = env
end end
# Removes the token, effectively logging the user out. # Removes the token, effectively logging the user out.
def clear_token def clear_token
@logger.info("Clearing token")
token_path.delete if token_path.file? token_path.delete if token_path.file?
end end
@ -38,6 +40,8 @@ module VagrantPlugins
# @param [String] pass # @param [String] pass
# @return [String] token The access token, or nil if auth failed. # @return [String] token The access token, or nil if auth failed.
def login(user, pass) def login(user, pass)
@logger.info("Logging in '#{user}'")
with_error_handling do with_error_handling do
url = "#{Vagrant.server_url}/api/v1/authenticate" url = "#{Vagrant.server_url}/api/v1/authenticate"
request = { "user" => { "login" => user, "password" => pass } } request = { "user" => { "login" => user, "password" => pass } }
@ -52,9 +56,12 @@ module VagrantPlugins
# #
# @param [String] token # @param [String] token
def store_token(token) def store_token(token)
@logger.info("Storing token in #{token_path}")
token_path.open("w") do |f| token_path.open("w") do |f|
f.write(token) f.write(token)
end end
nil nil
end end
@ -65,13 +72,17 @@ module VagrantPlugins
# @return [String] # @return [String]
def token def token
if ENV["ATLAS_TOKEN"] && !ENV["ATLAS_TOKEN"].empty? if ENV["ATLAS_TOKEN"] && !ENV["ATLAS_TOKEN"].empty?
@logger.debug("Using authentication token from environment variable")
return ENV["ATLAS_TOKEN"] return ENV["ATLAS_TOKEN"]
end end
if token_path.exist? if token_path.exist?
@logger.debug("Using authentication token from disk at #{token_path}")
return token_path.read.strip return token_path.read.strip
end end
@logger.debug("No authentication token in environment or #{token_path}")
nil nil
end end
@ -80,18 +91,21 @@ module VagrantPlugins
def with_error_handling(&block) def with_error_handling(&block)
yield yield
rescue RestClient::Unauthorized rescue RestClient::Unauthorized
@logger.debug("Unauthorized!")
false false
rescue RestClient::NotAcceptable => e rescue RestClient::NotAcceptable => e
begin @logger.debug("Got unacceptable response:")
errors = JSON.parse(e.response)["errors"] @logger.debug(e.message)
.map { |h| h["message"] } @logger.debug(e.backtrace.join("\n"))
.join("\n")
begin
errors = JSON.parse(e.response)["errors"].join("\n")
raise Errors::ServerError, errors: errors raise Errors::ServerError, errors: errors
rescue JSON::ParserError; end rescue JSON::ParserError; end
raise "An unexpected error occurred: #{e.inspect}" raise "An unexpected error occurred: #{e.inspect}"
rescue SocketError rescue SocketError
@logger.info("Socket error")
raise Errors::ServerUnreachable, url: Vagrant.server_url.to_s raise Errors::ServerUnreachable, url: Vagrant.server_url.to_s
end end

View File

@ -18,6 +18,10 @@ module VagrantPlugins
o.on("-k", "--logout", "Logs you out if you're logged in") do |k| o.on("-k", "--logout", "Logs you out if you're logged in") do |k|
options[:logout] = k options[:logout] = k
end end
o.on("-t", "--token TOKEN", String, "Set the Atlas token") do |t|
options[:token] = t
end
end end
# Parse the options # Parse the options
@ -31,6 +35,8 @@ module VagrantPlugins
return execute_check return execute_check
elsif options[:logout] elsif options[:logout]
return execute_logout return execute_logout
elsif options[:token]
return execute_token(options[:token])
end end
# Let the user know what is going on. # Let the user know what is going on.
@ -78,6 +84,19 @@ module VagrantPlugins
@env.ui.success(I18n.t("login_command.logged_out")) @env.ui.success(I18n.t("login_command.logged_out"))
return 0 return 0
end end
def execute_token(token)
@client.store_token(token)
@env.ui.success(I18n.t("login_command.token_saved"))
if @client.logged_in?
@env.ui.success(I18n.t("login_command.check_logged_in"))
return 0
else
@env.ui.error(I18n.t("login_command.invalid_token"))
return 1
end
end
end end
end end
end end

View File

@ -24,7 +24,11 @@ en:
https://atlas.hashicorp.com. https://atlas.hashicorp.com.
invalid_login: |- invalid_login: |-
Invalid username or password. Please try again. Invalid username or password. Please try again.
invalid_token: |-
Invalid token. Please try again.
logged_in: |- logged_in: |-
You are now logged in. You are now logged in.
logged_out: |- logged_out: |-
You are logged out. You are logged out.
token_saved: |-
The token was successfully saved.

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

@ -12,7 +12,7 @@ module VagrantPlugins
def call(env) def call(env)
installed = Vagrant::Plugin::Manager.instance.installed_plugins installed = Vagrant::Plugin::Manager.instance.installed_plugins
if !installed.has_key?(env[:plugin_name]) if !installed.key?(env[:plugin_name])
raise Vagrant::Errors::PluginNotInstalled, raise Vagrant::Errors::PluginNotInstalled,
name: env[:plugin_name] name: env[:plugin_name]
end end

View File

@ -19,6 +19,11 @@ module VagrantPlugins
name = validate_pushes!(@env.pushes, argv[0]) name = validate_pushes!(@env.pushes, argv[0])
# Validate the configuration
@env.machine(@env.machine_names.first, @env.default_provider).action_raw(
:config_validate,
Vagrant::Action::Builtin::ConfigValidate)
@logger.debug("'push' environment with strategy: `#{name}'") @logger.debug("'push' environment with strategy: `#{name}'")
@env.push(name) @env.push(name)
@ -51,17 +56,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

@ -60,8 +60,8 @@ module VagrantPlugins
if names.empty? if names.empty?
autostart = false autostart = false
@env.vagrantfile.machine_names_and_options.each do |n, o| @env.vagrantfile.machine_names_and_options.each do |n, o|
autostart = true if o.has_key?(:autostart) autostart = true if o.key?(:autostart)
o[:autostart] = true if !o.has_key?(:autostart) o[:autostart] = true if !o.key?(:autostart)
names << n.to_s if o[:autostart] names << n.to_s if o[:autostart]
end end

View File

@ -19,6 +19,8 @@ module VagrantPlugins
parser.on("--provision-with x,y,z", Array, parser.on("--provision-with x,y,z", Array,
"Enable only certain provisioners, by type.") do |list| "Enable only certain provisioners, by type.") do |list|
options[:provision_types] = list.map { |type| type.to_sym } options[:provision_types] = list.map { |type| type.to_sym }
options[:provision_enabled] = true
options[:provision_ignore_sentinel] = true
end end
end end

View File

@ -320,7 +320,7 @@ module VagrantPlugins
raise Vagrant::Errors::SSHNotReady if ssh_info.nil? raise Vagrant::Errors::SSHNotReady if ssh_info.nil?
# Default some options # Default some options
opts[:retries] = 5 if !opts.has_key?(:retries) opts[:retries] = 5 if !opts.key?(:retries)
# Build the options we'll use to initiate the connection via Net::SSH # Build the options we'll use to initiate the connection via Net::SSH
common_connect_opts = { common_connect_opts = {

0
plugins/communicators/winrm/command_filters/mkdir.rb Executable file → Normal file
View File

View File

@ -79,12 +79,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)
@ -153,8 +162,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,
@ -164,6 +173,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

@ -91,7 +91,23 @@ module VagrantPlugins
block.call(:stdout, out) if block_given? && out block.call(:stdout, out) if block_given? && out
block.call(:stderr, err) if block_given? && err block.call(:stderr, err) if block_given? && err
end end
@logger.debug("Output: #{output.inspect}") @logger.debug("Output: #{output.inspect}")
# Verify that we didn't get a parser error, and if so we should
# set the exit code to 1. Parse errors return exit code 0 so we
# need to do this.
if output[:exitcode] == 0
(output[:data] || []).each do |data|
next if !data[:stderr]
if data[:stderr].include?("ParserError")
@logger.warn("Detected ParserError, setting exit code to 1")
output[:exitcode] = 1
break
end
end
end
return output return output
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

@ -17,7 +17,7 @@ module VagrantPlugins
end end
def self.rsync_post(machine, opts) def self.rsync_post(machine, opts)
if opts.has_key?(:chown) && !opts[:chown] if opts.key?(:chown) && !opts[:chown]
return return
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

@ -26,7 +26,7 @@ module VagrantPlugins
end end
interface_names = networks.map do |network| interface_names = networks.map do |network|
"eth#{network[:interface]}" "#{interface_names[network[:interface]]}"
end end
else else
machine.communicate.sudo("/usr/sbin/biosdevname -d | grep Kernel | cut -f2 -d: | sed -e 's/ //;'") do |_, result| machine.communicate.sudo("/usr/sbin/biosdevname -d | grep Kernel | cut -f2 -d: | sed -e 's/ //;'") do |_, result|

View File

@ -31,7 +31,7 @@ module VagrantPlugins
end end
def self.rsync_post(machine, opts) def self.rsync_post(machine, opts)
if opts.has_key?(:chown) && !opts[:chown] if opts.key?(:chown) && !opts[:chown]
return return
end end

View File

@ -28,7 +28,7 @@ module VagrantPlugins
temp.binmode temp.binmode
temp.write(entry) temp.write(entry)
temp.close temp.close
comm.upload(temp.path, "/tmp/vagrant-network-entry-#{ifFile}") comm.upload(temp.path, "/tmp/vagrant-#{ifFile}")
comm.sudo("cp /tmp/vagrant-#{ifFile} /etc/conf.d/#{ifFile}") comm.sudo("cp /tmp/vagrant-#{ifFile} /etc/conf.d/#{ifFile}")
comm.sudo("chmod 0644 /etc/conf.d/#{ifFile}") comm.sudo("chmod 0644 /etc/conf.d/#{ifFile}")
comm.sudo("ln -fs /etc/init.d/netif.tmpl /etc/init.d/#{ifFile}") comm.sudo("ln -fs /etc/init.d/netif.tmpl /etc/init.d/#{ifFile}")

View File

@ -17,7 +17,7 @@ module VagrantPlugins
end end
def self.rsync_post(machine, opts) def self.rsync_post(machine, opts)
if opts.has_key?(:chown) && !opts[:chown] if opts.key?(:chown) && !opts[:chown]
return return
end end

View File

@ -17,10 +17,10 @@ module VagrantPlugins
end end
def self.rsync_post(machine, opts) def self.rsync_post(machine, opts)
su_cmd = machine.config.solaris.su_cmd suexec_cmd = machine.config.solaris.suexec_cmd
machine.communicate.execute( machine.communicate.execute(
"#{su_cmd} find '#{opts[:guestpath]}' '(' ! -user #{opts[:owner]} -or ! -group #{opts[:group]} ')' -print0 | " + "#{suexec_cmd} find '#{opts[:guestpath]}' '(' ! -user #{opts[:owner]} -or ! -group #{opts[:group]} ')' -print0 | " +
"xargs -0 -r chown #{opts[:owner]}:#{opts[:group]}") "xargs -0 chown #{opts[:owner]}:#{opts[:group]}")
end end
end end
end end

View File

@ -3,24 +3,28 @@ module VagrantPlugins
class Config < Vagrant.plugin("2", :config) class Config < Vagrant.plugin("2", :config)
attr_accessor :halt_timeout attr_accessor :halt_timeout
attr_accessor :halt_check_interval attr_accessor :halt_check_interval
# This sets the command to use to execute items as a superuser. sudo is default
attr_accessor :suexec_cmd attr_accessor :suexec_cmd
attr_accessor :device attr_accessor :device
def initialize def initialize
@halt_timeout = UNSET_VALUE @halt_timeout = UNSET_VALUE
@halt_check_interval = UNSET_VALUE @halt_check_interval = UNSET_VALUE
@suexec_cmd = 'sudo' @suexec_cmd = UNSET_VALUE
@device = "e1000g" @device = UNSET_VALUE
end end
def finalize! def finalize!
if @halt_timeout != UNSET_VALUE if @halt_timeout != UNSET_VALUE
puts "solaris.halt_timeout is deprecated and will be removed in Vagrant 1.7" puts "solaris.halt_timeout is deprecated and will be removed in Vagrant 1.7"
end end
if @halt_check_interval != UNSET_VALUE if @halt_check_interval != UNSET_VALUE
puts "solaris.halt_check_interval is deprecated and will be removed in Vagrant 1.7" puts "solaris.halt_check_interval is deprecated and will be removed in Vagrant 1.7"
end end
@suexec_cmd = "sudo" if @suexec_cmd == UNSET_VALUE
@device = "e1000g" if @device == UNSET_VALUE
end end
end end
end end

View File

@ -17,10 +17,10 @@ module VagrantPlugins
end end
def self.rsync_post(machine, opts) def self.rsync_post(machine, opts)
su_cmd = machine.config.solaris11.su_cmd suexec_cmd = machine.config.solaris11.suexec_cmd
machine.communicate.execute( machine.communicate.execute(
"#{su_cmd} '#{opts[:guestpath]}' '(' ! -user #{opts[:owner]} -or ! -group #{opts[:group]} ')' -print0 | " + "#{suexec_cmd} '#{opts[:guestpath]}' '(' ! -user #{opts[:owner]} -or ! -group #{opts[:group]} ')' -print0 | " +
"xargs -0 -r chown #{opts[:owner]}:#{opts[:group]}") "xargs -0 chown #{opts[:owner]}:#{opts[:group]}")
end end
end end
end end

View File

@ -137,7 +137,7 @@ module VagrantPlugins
user = Process.uid user = Process.uid
File.read("/etc/exports").lines.each do |line| File.read("/etc/exports").lines.each do |line|
if id = line[/^# VAGRANT-BEGIN:( #{user})? ([\.\/A-Za-z0-9\-_]+?)$/, 2] if id = line[/^# VAGRANT-BEGIN:( #{user})? ([\.\/A-Za-z0-9\-_:]+?)$/, 2]
if valid_ids.include?(id) if valid_ids.include?(id)
logger.debug("Valid ID: #{id}") logger.debug("Valid ID: #{id}")
else else

View File

@ -71,7 +71,7 @@ module VagrantPlugins
user = Process.uid user = Process.uid
File.read("/etc/exports").lines.each do |line| File.read("/etc/exports").lines.each do |line|
if id = line[/^# VAGRANT-BEGIN:( #{user})? ([\.\/A-Za-z0-9\-_]+?)$/, 2] if id = line[/^# VAGRANT-BEGIN:( #{user})? ([\.\/A-Za-z0-9\-_:]+?)$/, 2]
if valid_ids.include?(id) if valid_ids.include?(id)
logger.debug("Valid ID: #{id}") logger.debug("Valid ID: #{id}")
else else

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
@ -115,6 +115,22 @@ module VagrantPlugins
end end
end end
# Validate all pushes
def validate(machine)
errors = { "push" => _detected_errors }
__compiled_pushes.each do |_, push|
config = push[1]
push_errors = config.validate(machine)
if push_errors
errors = Vagrant::Config::V2::Util.merge_errors(errors, push_errors)
end
end
errors
end
# This returns the list of compiled pushes as a hash by name. # This returns the list of compiled pushes as a hash by name.
# #
# @return [Hash<Symbol, Array<Class, Object>>] # @return [Hash<Symbol, Array<Class, Object>>]

View File

@ -96,7 +96,7 @@ module VagrantPlugins
end end
other_defined_vms.each do |key, subvm| other_defined_vms.each do |key, subvm|
if !new_defined_vms.has_key?(key) if !new_defined_vms.key?(key)
new_defined_vms[key] = subvm.clone new_defined_vms[key] = subvm.clone
else else
new_defined_vms[key].config_procs.concat(subvm.config_procs) new_defined_vms[key].config_procs.concat(subvm.config_procs)
@ -197,7 +197,7 @@ module VagrantPlugins
options ||= {} options ||= {}
options[:guestpath] = guestpath.to_s.gsub(/\/$/, '') options[:guestpath] = guestpath.to_s.gsub(/\/$/, '')
options[:hostpath] = hostpath options[:hostpath] = hostpath
options[:disabled] = false if !options.has_key?(:disabled) options[:disabled] = false if !options.key?(:disabled)
options = (@__synced_folders[options[:guestpath]] || {}). options = (@__synced_folders[options[:guestpath]] || {}).
merge(options.dup) merge(options.dup)
@ -247,7 +247,7 @@ module VagrantPlugins
id = "#{type}-#{id}" id = "#{type}-#{id}"
# Merge in the previous settings if we have them. # Merge in the previous settings if we have them.
if @__networks.has_key?(id) if @__networks.key?(id)
options = @__networks[id][1].merge(options) options = @__networks[id][1].merge(options)
end end
@ -279,13 +279,13 @@ module VagrantPlugins
def provision(name, **options, &block) def provision(name, **options, &block)
type = name type = name
if options.has_key?(:type) if options.key?(:type)
type = options.delete(:type) type = options.delete(:type)
else else
name = nil name = nil
end end
if options.has_key?(:id) if options.key?(:id)
puts "Setting `id` on a provisioner is deprecated. Please use the" puts "Setting `id` on a provisioner is deprecated. Please use the"
puts "new syntax of `config.vm.provision \"name\", type: \"type\"" puts "new syntax of `config.vm.provision \"name\", type: \"type\""
puts "where \"name\" is the replacement for `id`. This will be" puts "where \"name\" is the replacement for `id`. This will be"
@ -306,8 +306,8 @@ module VagrantPlugins
end end
prov.preserve_order = !!options.delete(:preserve_order) if \ prov.preserve_order = !!options.delete(:preserve_order) if \
options.has_key?(:preserve_order) options.key?(:preserve_order)
prov.run = options.delete(:run) if options.has_key?(:run) prov.run = options.delete(:run) if options.key?(:run)
prov.add_config(options, &block) prov.add_config(options, &block)
nil nil
end end

View File

@ -22,7 +22,7 @@ module VagrantPlugins
def call(env) def call(env)
return @app.call(env) if !env[:machine].provider.host_vm? return @app.call(env) if !env[:machine].provider.host_vm?
if !env.has_key?(:host_machine_sync_folders) if !env.key?(:host_machine_sync_folders)
env[:host_machine_sync_folders] = true env[:host_machine_sync_folders] = true
end end
@ -115,7 +115,7 @@ module VagrantPlugins
# Add this synced folder onto the new config if we haven't # Add this synced folder onto the new config if we haven't
# already shared it before. # already shared it before.
if !existing_ids.has_key?(id) if !existing_ids.key?(id)
# A bit of a hack for VirtualBox to mount our # A bit of a hack for VirtualBox to mount our
# folder as transient. This can be removed once # folder as transient. This can be removed once
# the VirtualBox synced folder mechanism is smarter. # the VirtualBox synced folder mechanism is smarter.

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

@ -18,4 +18,9 @@ Vagrant.configure("2") do |config|
# b2d doesn't support NFS # b2d doesn't support NFS
config.nfs.functional = false config.nfs.functional = false
# b2d doesn't persist filesystem between reboots
if config.ssh.respond_to?(:insert_key)
config.ssh.insert_key = false
end
end end

View File

@ -14,6 +14,15 @@ module VagrantPlugins
def call(env) def call(env)
vm_dir = env[:machine].box.directory.join("Virtual Machines") vm_dir = env[:machine].box.directory.join("Virtual Machines")
hd_dir = env[:machine].box.directory.join("Virtual Hard Disks") hd_dir = env[:machine].box.directory.join("Virtual Hard Disks")
memory = env[:machine].provider_config.memory
maxmemory = env[:machine].provider_config.maxmemory
cpus = env[:machine].provider_config.cpus
vmname = env[:machine].provider_config.vmname
env[:ui].output("Configured Dynamical memory allocation, maxmemory is #{maxmemory}") if maxmemory
env[:ui].output("Configured startup memory is #{memory}") if memory
env[:ui].output("Configured cpus number is #{cpus}") if cpus
env[:ui].output("Configured vmname is #{vmname}") if vmname
if !vm_dir.directory? || !hd_dir.directory? if !vm_dir.directory? || !hd_dir.directory?
raise Errors::BoxInvalid raise Errors::BoxInvalid
@ -78,6 +87,10 @@ module VagrantPlugins
image_path: image_path.to_s.gsub("/", "\\") image_path: image_path.to_s.gsub("/", "\\")
} }
options[:switchname] = switch if switch options[:switchname] = switch if switch
options[:memory] = memory if memory
options[:maxmemory] = maxmemory if maxmemory
options[:cpus] = cpus if cpus
options[:vmname] = vmname if vmname
env[:ui].detail("Creating and registering the VM...") env[:ui].detail("Creating and registering the VM...")
server = env[:machine].provider.driver.import(options) server = env[:machine].provider.driver.import(options)

View File

@ -8,15 +8,27 @@ module VagrantPlugins
# #
# @return [Integer] # @return [Integer]
attr_accessor :ip_address_timeout attr_accessor :ip_address_timeout
attr_accessor :memory
attr_accessor :maxmemory
attr_accessor :cpus
attr_accessor :vmname
def initialize def initialize
@ip_address_timeout = UNSET_VALUE @ip_address_timeout = UNSET_VALUE
@memory = UNSET_VALUE
@maxmemory = UNSET_VALUE
@cpus = UNSET_VALUE
@vmname = UNSET_VALUE
end end
def finalize! def finalize!
if @ip_address_timeout == UNSET_VALUE if @ip_address_timeout == UNSET_VALUE
@ip_address_timeout = 120 @ip_address_timeout = 120
end end
@memory = nil if @memory == UNSET_VALUE
@maxmemory = nil if @maxmemory == UNSET_VALUE
@cpus = nil if @cpus == UNSET_VALUE
@vmname = nil if @vmname == UNSET_VALUE
end end
def validate(machine) def validate(machine)

View File

@ -4,7 +4,11 @@ Param(
[Parameter(Mandatory=$true)] [Parameter(Mandatory=$true)]
[string]$image_path, [string]$image_path,
[string]$switchname=$null [string]$switchname=$null,
[string]$memory=$null,
[string]$maxmemory=$null,
[string]$cpus=$null,
[string]$vmname=$null
) )
# Include the following modules # Include the following modules
@ -13,10 +17,22 @@ $Dir = Split-Path $script:MyInvocation.MyCommand.Path
[xml]$vmconfig = Get-Content -Path $vm_xml_config [xml]$vmconfig = Get-Content -Path $vm_xml_config
$vm_name = $vmconfig.configuration.properties.name.'#text'
$processors = $vmconfig.configuration.settings.processors.count.'#text'
$generation = [int]($vmconfig.configuration.properties.subtype.'#text')+1 $generation = [int]($vmconfig.configuration.properties.subtype.'#text')+1
if (!$vmname) {
# Get the name of the vm
$vm_name = $vmconfig.configuration.properties.name.'#text'
}else {
$vm_name = $vmname
}
if (!$cpus) {
# Get the name of the vm
$processors = $vmconfig.configuration.settings.processors.count.'#text'
}else {
$processors = $cpus
}
function GetUniqueName($name) { function GetUniqueName($name) {
Get-VM | ForEach-Object -Process { Get-VM | ForEach-Object -Process {
if ($name -eq $_.Name) { if ($name -eq $_.Name) {
@ -31,18 +47,34 @@ do {
$vm_name = GetUniqueName $name $vm_name = GetUniqueName $name
} while ($vm_name -ne $name) } while ($vm_name -ne $name)
$memory = (Select-Xml -xml $vmconfig -XPath "//memory").node.Bank if (!$memory) {
if ($memory.dynamic_memory_enabled."#text" -eq "True") { $xmlmemory = (Select-Xml -xml $vmconfig -XPath "//memory").node.Bank
$dynamicmemory = $True if ($xmlmemory.dynamic_memory_enabled."#text" -eq "True") {
$dynamicmemory = $True
}
else {
$dynamicmemory = $False
}
# Memory values need to be in bytes
$MemoryMaximumBytes = ($xmlmemory.limit."#text" -as [int]) * 1MB
$MemoryStartupBytes = ($xmlmemory.size."#text" -as [int]) * 1MB
$MemoryMinimumBytes = ($xmlmemory.reservation."#text" -as [int]) * 1MB
} }
else { else {
$dynamicmemory = $False if (!$maxmemory){
$dynamicmemory = $False
$MemoryMaximumBytes = ($memory -as [int]) * 1MB
$MemoryStartupBytes = ($memory -as [int]) * 1MB
$MemoryMinimumBytes = ($memory -as [int]) * 1MB
}
else {
$dynamicmemory = $True
$MemoryMaximumBytes = ($maxmemory -as [int]) * 1MB
$MemoryStartupBytes = ($memory -as [int]) * 1MB
$MemoryMinimumBytes = ($memory -as [int]) * 1MB
}
} }
# Memory values need to be in bytes
$MemoryMaximumBytes = ($memory.limit."#text" -as [int]) * 1MB
$MemoryStartupBytes = ($memory.size."#text" -as [int]) * 1MB
$MemoryMinimumBytes = ($memory.reservation."#text" -as [int]) * 1MB
if (!$switchname) { if (!$switchname) {
# Get the name of the virtual switch # Get the name of the virtual switch

View File

@ -10,7 +10,7 @@ forEach ($module in $modules) { . $module }
try { try {
$vm = Get-VM -Id $VmId -ErrorAction "stop" $vm = Get-VM -Id $VmId -ErrorAction "stop"
Start-VM $vm Start-VM $vm -ErrorAction "stop"
$state = $vm.state $state = $vm.state
$status = $vm.status $status = $vm.status
$name = $vm.name $name = $vm.name
@ -24,4 +24,4 @@ try {
} }
catch { catch {
Write-Error-Message "Failed to start a VM $_" Write-Error-Message "Failed to start a VM $_"
} }

View File

@ -24,7 +24,7 @@ module VagrantPlugins
} }
folders = synced_folders(env[:machine], **opts) folders = synced_folders(env[:machine], **opts)
if folders.has_key?(:nfs) if folders.key?(:nfs)
@logger.info("Using NFS, preparing NFS settings by reading host IP and machine IP") @logger.info("Using NFS, preparing NFS settings by reading host IP and machine IP")
add_ips_to_env!(env) add_ips_to_env!(env)
end end

View File

@ -32,9 +32,9 @@ module VagrantPlugins
# Verify the name is not taken # Verify the name is not taken
vms = env[:machine].provider.driver.read_vms vms = env[:machine].provider.driver.read_vms
raise Vagrant::Errors::VMNameExists, name: name if \ raise Vagrant::Errors::VMNameExists, name: name if \
vms.has_key?(name) && vms[name] != env[:machine].id vms.key?(name) && vms[name] != env[:machine].id
if vms.has_key?(name) if vms.key?(name)
@logger.info("Not setting the name because our name is already set.") @logger.info("Not setting the name because our name is already set.")
else else
env[:ui].info(I18n.t( env[:ui].info(I18n.t(

View File

@ -143,7 +143,7 @@ module VagrantPlugins
def validate(machine) def validate(machine)
errors = _detected_errors errors = _detected_errors
valid_events = ["pre-import", "pre-boot", "post-boot"] valid_events = ["pre-import", "pre-boot", "post-boot", "post-comm"]
@customizations.each do |event, _| @customizations.each do |event, _|
if !valid_events.include?(event) if !valid_events.include?(event)
errors << I18n.t( errors << I18n.t(

View File

@ -30,8 +30,8 @@ module VagrantPlugins
# On Windows, we use the VBOX_INSTALL_PATH environmental # On Windows, we use the VBOX_INSTALL_PATH environmental
# variable to find VBoxManage. # variable to find VBoxManage.
if ENV.has_key?("VBOX_INSTALL_PATH") || if ENV.key?("VBOX_INSTALL_PATH") ||
ENV.has_key?("VBOX_MSI_INSTALL_PATH") ENV.key?("VBOX_MSI_INSTALL_PATH")
# Get the path. # Get the path.
path = ENV["VBOX_INSTALL_PATH"] || ENV["VBOX_MSI_INSTALL_PATH"] path = ENV["VBOX_INSTALL_PATH"] || ENV["VBOX_MSI_INSTALL_PATH"]
@logger.debug("VBOX_INSTALL_PATH value: #{path}") @logger.debug("VBOX_INSTALL_PATH value: #{path}")

View File

@ -445,7 +445,7 @@ module VagrantPlugins
folder[:name], folder[:name],
"--hostpath", "--hostpath",
folder[:hostpath]] folder[:hostpath]]
args << "--transient" if folder.has_key?(:transient) && folder[:transient] args << "--transient" if folder.key?(:transient) && folder[:transient]
execute("sharedfolder", "add", @uuid, *args) execute("sharedfolder", "add", @uuid, *args)
end end
end end

View File

@ -450,13 +450,13 @@ module VagrantPlugins
folder[:name], folder[:name],
"--hostpath", "--hostpath",
folder[:hostpath]] folder[:hostpath]]
args << "--transient" if folder.has_key?(:transient) && folder[:transient] args << "--transient" if folder.key?(:transient) && folder[:transient]
# Add the shared folder
execute("sharedfolder", "add", @uuid, *args)
# Enable symlinks on the shared folder # Enable symlinks on the shared folder
execute("setextradata", @uuid, "VBoxInternal2/SharedFoldersEnableSymlinksCreate/#{folder[:name]}", "1") execute("setextradata", @uuid, "VBoxInternal2/SharedFoldersEnableSymlinksCreate/#{folder[:name]}", "1")
# Add the shared folder
execute("sharedfolder", "add", @uuid, *args)
end end
end end

View File

@ -189,9 +189,9 @@ module VagrantPlugins
# we use the block form of sub here to ensure that if the specified_name happens to end with a number (which is fairly likely) then # we use the block form of sub here to ensure that if the specified_name happens to end with a number (which is fairly likely) then
# we won't end up having the character sequence of a \ followed by a number be interpreted as a back reference. For example, if # we won't end up having the character sequence of a \ followed by a number be interpreted as a back reference. For example, if
# specified_name were "abc123", then "\\abc123\\".reverse would be "\\321cba\\", and the \3 would be treated as a back reference by the sub # specified_name were "abc123", then "\\abc123\\".reverse would be "\\321cba\\", and the \3 would be treated as a back reference by the sub
disk_params << path.reverse.sub("\\#{suggested_name}\\".reverse) { "\\#{specified_name}\\".reverse }.reverse # Replace only last occurrence disk_params << path.reverse.sub("\\#{suggested_name}\\".reverse) { "\\#{specified_name}\\".reverse }.reverse # Replace only last occurrence
else else
disk_params << path.reverse.sub("/#{suggested_name}/".reverse, "/#{specified_name}/".reverse).reverse # Replace only last occurrence disk_params << path.reverse.sub("/#{suggested_name}/".reverse, "/#{specified_name}/".reverse).reverse # Replace only last occurrence
end end
end end
@ -481,13 +481,13 @@ module VagrantPlugins
folder[:name], folder[:name],
"--hostpath", "--hostpath",
folder[:hostpath]] folder[:hostpath]]
args << "--transient" if folder.has_key?(:transient) && folder[:transient] args << "--transient" if folder.key?(:transient) && folder[:transient]
# Add the shared folder
execute("sharedfolder", "add", @uuid, *args)
# Enable symlinks on the shared folder # Enable symlinks on the shared folder
execute("setextradata", @uuid, "VBoxInternal2/SharedFoldersEnableSymlinksCreate/#{folder[:name]}", "1") execute("setextradata", @uuid, "VBoxInternal2/SharedFoldersEnableSymlinksCreate/#{folder[:name]}", "1")
# Add the shared folder
execute("sharedfolder", "add", @uuid, *args)
end end
end end

View File

@ -498,13 +498,13 @@ module VagrantPlugins
folder[:name], folder[:name],
"--hostpath", "--hostpath",
folder[:hostpath]] folder[:hostpath]]
args << "--transient" if folder.has_key?(:transient) && folder[:transient] args << "--transient" if folder.key?(:transient) && folder[:transient]
# Add the shared folder
execute("sharedfolder", "add", @uuid, *args)
# Enable symlinks on the shared folder # Enable symlinks on the shared folder
execute("setextradata", @uuid, "VBoxInternal2/SharedFoldersEnableSymlinksCreate/#{folder[:name]}", "1") execute("setextradata", @uuid, "VBoxInternal2/SharedFoldersEnableSymlinksCreate/#{folder[:name]}", "1")
# Add the shared folder
execute("sharedfolder", "add", @uuid, *args)
end end
end end

View File

@ -51,7 +51,7 @@ module VagrantPlugins
options ||= {} options ||= {}
@auto_correct = false @auto_correct = false
@auto_correct = options[:auto_correct] if options.has_key?(:auto_correct) @auto_correct = options[:auto_correct] if options.key?(:auto_correct)
@adapter = (options[:adapter] || 1).to_i @adapter = (options[:adapter] || 1).to_i
@guest_ip = options[:guest_ip] || nil @guest_ip = options[:guest_ip] || nil
@host_ip = options[:host_ip] || nil @host_ip = options[:host_ip] || nil

View File

@ -1,3 +1,5 @@
require "vagrant/util/platform"
module VagrantPlugins module VagrantPlugins
module Ansible module Ansible
class Provisioner < Vagrant.plugin("2", :provisioner) class Provisioner < Vagrant.plugin("2", :provisioner)
@ -23,6 +25,12 @@ module VagrantPlugins
# but can be enabled via raw_arguments option. # but can be enabled via raw_arguments option.
options << "--connection=ssh" options << "--connection=ssh"
# Increase the SSH connection timeout, as the Ansible default value (10 seconds)
# is a bit demanding for some overloaded developer boxes. This is particularly
# helpful when additional virtual networks are configured, as their availability
# is not controlled during vagrant boot process.
options << "--timeout=30"
# By default we limit by the current machine, but # By default we limit by the current machine, but
# this can be overridden by the `limit` option. # this can be overridden by the `limit` option.
if config.limit if config.limit
@ -188,9 +196,33 @@ 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
# Set IdentitiesOnly=yes to avoid authentication errors when the host has more than 5 ssh keys.
# Notes:
# - Solaris/OpenSolaris/Illumos uses SunSSH which doesn't support the IdentitiesOnly option.
# - this could be improved by sharing logic with lib/vagrant/util/ssh.rb
ssh_options << "-o IdentitiesOnly=yes" unless Vagrant::Util::Platform.solaris?
# Multiple Private Keys # Multiple Private Keys
@ssh_info[:private_key_path].drop(1).each do |key| @ssh_info[:private_key_path].drop(1).each do |key|
ssh_options << "-o IdentityFile=#{key}" ssh_options << "-o IdentityFile=#{key}"

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

@ -0,0 +1,20 @@
require_relative "../../omnibus"
module VagrantPlugins
module Chef
module Cap
module OmniOS
module ChefInstall
def self.chef_install(machine, version, prerelease, download_path)
su_cmd = machine.config.solaris.suexec_cmd
machine.communicate.execute("#{su_cmd} pkg list --no-refresh web/curl > /dev/null 2>&1 || pkg install -q --accept web/curl")
command = VagrantPlugins::Chef::Omnibus.build_command(version, prerelease, download_path)
machine.communicate.execute(su_cmd + ' ' + command)
end
end
end
end
end
end

View File

@ -0,0 +1,23 @@
module VagrantPlugins
module Chef
module Cap
module OmniOS
module ChefInstalled
# TODO: this is the same code as cap/linux/chef_installed, consider merging
# Check if Chef is installed at the given version.
# @return [true, false]
def self.chef_installed(machine, version)
knife = "/opt/chef/bin/knife"
command = "test -x #{knife}"
if version != :latest
command << "&& #{knife} --version | grep 'Chef: #{version}'"
end
machine.communicate.test(command, sudo: true)
end
end
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

@ -1,11 +1,7 @@
require "vagrant/util/counter"
module VagrantPlugins module VagrantPlugins
module Chef module Chef
module Config module Config
class Base < Vagrant.plugin("2", :config) class Base < Vagrant.plugin("2", :config)
extend Vagrant::Util::Counter
# The path to Chef's bin/ directory. # The path to Chef's bin/ directory.
# @return [String] # @return [String]
attr_accessor :binary_path attr_accessor :binary_path
@ -48,6 +44,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 +61,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 +71,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

@ -81,7 +81,7 @@ module VagrantPlugins
@https_proxy_pass = nil if @https_proxy_pass == UNSET_VALUE @https_proxy_pass = nil if @https_proxy_pass == UNSET_VALUE
@no_proxy = nil if @no_proxy == UNSET_VALUE @no_proxy = nil if @no_proxy == UNSET_VALUE
@node_name = nil if @node_name == UNSET_VALUE @node_name = nil if @node_name == UNSET_VALUE
@provisioning_path = nil if @provisioning_path == UNSET_VALUE @provisioning_path = "/tmp/vagrant-chef" if @provisioning_path == UNSET_VALUE
@file_backup_path = "/var/chef/backup" if @file_backup_path == UNSET_VALUE @file_backup_path = "/var/chef/backup" if @file_backup_path == UNSET_VALUE
@file_cache_path = "/var/chef/cache" if @file_cache_path == UNSET_VALUE @file_cache_path = "/var/chef/cache" if @file_cache_path == UNSET_VALUE
@verbose_logging = false if @verbose_logging == UNSET_VALUE @verbose_logging = false if @verbose_logging == UNSET_VALUE
@ -89,12 +89,6 @@ module VagrantPlugins
if @encrypted_data_bag_secret_key_path == UNSET_VALUE if @encrypted_data_bag_secret_key_path == UNSET_VALUE
@encrypted_data_bag_secret_key_path = nil @encrypted_data_bag_secret_key_path = nil
end end
# Set the default provisioning path to be a unique path in /tmp
if !@provisioning_path
counter = self.class.get_and_update_counter(:chef_config)
@provisioning_path = "/tmp/vagrant-chef-#{counter}"
end
end end
def merge(other) def merge(other)

View File

@ -24,11 +24,7 @@ module VagrantPlugins
super super
@recipe = nil if @recipe == UNSET_VALUE @recipe = nil if @recipe == UNSET_VALUE
@upload_path = "/tmp/vagrant-chef-apply" if @upload_path == UNSET_VALUE
if @upload_path == UNSET_VALUE
counter = self.class.get_and_update_counter(:chef_apply)
@upload_path = "/tmp/vagrant-chef-apply-#{counter}"
end
end end
def validate(machine) def validate(machine)

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

@ -10,7 +10,7 @@ module VagrantPlugins
name "chef" name "chef"
description <<-DESC description <<-DESC
Provides support for provisioning your virtual machines with Provides support for provisioning your virtual machines with
Chef via `chef-solo`, `chef-client`, or `chef-apply`. Chef via `chef-solo`, `chef-client`, `chef-zero` or `chef-apply`.
DESC DESC
config(:chef_apply, :provisioner) do config(:chef_apply, :provisioner) do
@ -67,6 +67,17 @@ module VagrantPlugins
require_relative "cap/redhat/chef_install" require_relative "cap/redhat/chef_install"
Cap::Redhat::ChefInstall Cap::Redhat::ChefInstall
end end
guest_capability(:omnios, :chef_installed) do
require_relative "cap/omnios/chef_installed"
Cap::OmniOS::ChefInstalled
end
guest_capability(:omnios, :chef_install) do
require_relative "cap/omnios/chef_install"
Cap::OmniOS::ChefInstall
end
end end
end end
end end

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

@ -1,3 +1,4 @@
require "digest/md5"
require "tempfile" require "tempfile"
require_relative "base" require_relative "base"
@ -42,7 +43,8 @@ module VagrantPlugins
# The destination (on the guest) where the recipe will live # The destination (on the guest) where the recipe will live
# @return [String] # @return [String]
def target_recipe_path def target_recipe_path
File.join(config.upload_path, "recipe.rb") key = Digest::MD5.hexdigest(config.recipe)
File.join(config.upload_path, "recipe-#{key}.rb")
end end
# Write the raw recipe contents to a tempfile and upload that to the # Write the raw recipe contents to a tempfile and upload that to the

View File

@ -1,3 +1,7 @@
require "digest/md5"
require "securerandom"
require "set"
require "log4r" require "log4r"
require "vagrant/util/counter" require "vagrant/util/counter"
@ -11,6 +15,8 @@ module VagrantPlugins
class ChefSolo < Base class ChefSolo < Base
extend Vagrant::Util::Counter extend Vagrant::Util::Counter
include Vagrant::Util::Counter include Vagrant::Util::Counter
include Vagrant::Action::Builtin::MixinSyncedFolders
attr_reader :environments_folders attr_reader :environments_folders
attr_reader :cookbook_folders attr_reader :cookbook_folders
attr_reader :role_folders attr_reader :role_folders
@ -28,13 +34,14 @@ module VagrantPlugins
@data_bags_folders = expanded_folders(@config.data_bags_path, "data_bags") @data_bags_folders = expanded_folders(@config.data_bags_path, "data_bags")
@environments_folders = expanded_folders(@config.environments_path, "environments") @environments_folders = expanded_folders(@config.environments_path, "environments")
share_folders(root_config, "csc", @cookbook_folders) existing = synced_folders(@machine, cached: true)
share_folders(root_config, "csr", @role_folders) share_folders(root_config, "csc", @cookbook_folders, existing)
share_folders(root_config, "csdb", @data_bags_folders) share_folders(root_config, "csr", @role_folders, existing)
share_folders(root_config, "cse", @environments_folders) share_folders(root_config, "csdb", @data_bags_folders, existing)
share_folders(root_config, "cse", @environments_folders, existing)
end end
def provision def provision(mode = :solo)
install_chef install_chef
# Verify that the proper shared folders exist. # Verify that the proper shared folders exist.
check = [] check = []
@ -51,7 +58,7 @@ module VagrantPlugins
upload_encrypted_data_bag_secret upload_encrypted_data_bag_secret
setup_json setup_json
setup_solo_config setup_solo_config
run_chef_solo run_chef(mode)
delete_encrypted_data_bag_secret delete_encrypted_data_bag_secret
end end
@ -72,8 +79,10 @@ module VagrantPlugins
local_path = File.expand_path(path, @machine.env.root_path) local_path = File.expand_path(path, @machine.env.root_path)
if File.exist?(local_path) if File.exist?(local_path)
# Path exists on the host, setup the remote path # Path exists on the host, setup the remote path. We use
remote_path = "#{@config.provisioning_path}/chef-solo-#{get_and_update_counter(:cookbooks_path)}" # the MD5 of the local path so that it is predictable.
key = Digest::MD5.hexdigest(local_path)
remote_path = "#{@config.provisioning_path}/#{key}"
else else
@machine.ui.warn(I18n.t("vagrant.provisioners.chef.cookbook_folder_not_found_warning", @machine.ui.warn(I18n.t("vagrant.provisioners.chef.cookbook_folder_not_found_warning",
path: local_path.to_s)) path: local_path.to_s))
@ -103,16 +112,31 @@ module VagrantPlugins
# Shares the given folders with the given prefix. The folders should # Shares the given folders with the given prefix. The folders should
# be of the structure resulting from the `expanded_folders` function. # be of the structure resulting from the `expanded_folders` function.
def share_folders(root_config, prefix, folders) def share_folders(root_config, prefix, folders, existing=nil)
folders.each do |type, local_path, remote_path| existing_set = Set.new
if type == :host (existing || []).each do |_, fs|
opts = {} fs.each do |id, data|
opts[:id] = "v-#{prefix}-#{self.class.get_and_update_counter(:shared_folder)}" existing_set.add(data[:guestpath])
opts[:type] = @config.synced_folder_type if @config.synced_folder_type
root_config.vm.synced_folder(local_path, remote_path, opts)
end end
end end
folders.each do |type, local_path, remote_path|
next if type != :host
# If this folder already exists, then we don't share it, it means
# it was already put down on disk.
if existing_set.include?(remote_path)
@logger.debug("Not sharing #{local_path}, exists as #{remote_path}")
next
end
opts = {}
opts[:id] = "v-#{prefix}-#{self.class.get_and_update_counter(:shared_folder)}"
opts[:type] = @config.synced_folder_type if @config.synced_folder_type
root_config.vm.synced_folder(local_path, remote_path, opts)
end
@shared_folders += folders @shared_folders += folders
end end
@ -130,7 +154,7 @@ module VagrantPlugins
} }
end end
def run_chef_solo def run_chef(mode)
if @config.run_list && @config.run_list.empty? if @config.run_list && @config.run_list.empty?
@machine.ui.warn(I18n.t("vagrant.chef_run_list_empty")) @machine.ui.warn(I18n.t("vagrant.chef_run_list_empty"))
end end
@ -143,9 +167,9 @@ module VagrantPlugins
@config.attempts.times do |attempt| @config.attempts.times do |attempt|
if attempt == 0 if attempt == 0
@machine.ui.info I18n.t("vagrant.provisioners.chef.running_solo") @machine.ui.info I18n.t("vagrant.provisioners.chef.running_#{mode}")
else else
@machine.ui.info I18n.t("vagrant.provisioners.chef.running_solo_again") @machine.ui.info I18n.t("vagrant.provisioners.chef.running_#{mode}_again")
end end
opts = { error_check: false, elevated: true } opts = { error_check: false, elevated: true }

View File

@ -22,6 +22,10 @@ module VagrantPlugins
share_folders(root_config, "csn", @node_folders) share_folders(root_config, "csn", @node_folders)
end end
def provision
super(:zero)
end
def solo_config def solo_config
super.merge( super.merge(
local_mode: true, local_mode: true,

View File

@ -14,8 +14,8 @@ module VagrantPlugins
end end
comm.sudo("apt-get update -y") comm.sudo("apt-get update -y")
comm.sudo("apt-get install -y --force-yes -q curl") comm.sudo("apt-get install -y --force-yes -q curl")
comm.sudo("curl -sSL https://get.docker.io/gpg | apt-key add -") comm.sudo("curl -sSL https://get.docker.com/gpg | apt-key add -")
comm.sudo("echo deb http://get.docker.io/ubuntu docker main > /etc/apt/sources.list.d/docker.list") comm.sudo("echo deb http://get.docker.com/ubuntu docker main > /etc/apt/sources.list.d/docker.list")
comm.sudo("apt-get update") comm.sudo("apt-get update")
comm.sudo("echo lxc lxc/directory string /var/lib/lxc | debconf-set-selections") comm.sudo("echo lxc lxc/directory string /var/lib/lxc | debconf-set-selections")
comm.sudo("apt-get install -y --force-yes -q xz-utils #{package} -o Dpkg::Options::='--force-confdef' -o Dpkg::Options::='--force-confold'") comm.sudo("apt-get install -y --force-yes -q xz-utils #{package} -o Dpkg::Options::='--force-confdef' -o Dpkg::Options::='--force-confold'")

View File

@ -70,8 +70,8 @@ module VagrantPlugins
@__containers.each do |name, params| @__containers.each do |name, params|
params[:image] ||= name params[:image] ||= name
params[:auto_assign_name] = true if !params.has_key?(:auto_assign_name) params[:auto_assign_name] = true if !params.key?(:auto_assign_name)
params[:daemonize] = true if !params.has_key?(:daemonize) params[:daemonize] = true if !params.key?(:daemonize)
end end
end end
end end

View File

@ -1,11 +1,7 @@
require "vagrant/util/counter"
module VagrantPlugins module VagrantPlugins
module Puppet module Puppet
module Config module Config
class Puppet < Vagrant.plugin("2", :config) class Puppet < Vagrant.plugin("2", :config)
extend Vagrant::Util::Counter
attr_accessor :facter attr_accessor :facter
attr_accessor :hiera_config_path attr_accessor :hiera_config_path
attr_accessor :manifest_file attr_accessor :manifest_file
@ -65,15 +61,8 @@ module VagrantPlugins
@manifest_file = "default.pp" if @manifest_file == UNSET_VALUE @manifest_file = "default.pp" if @manifest_file == UNSET_VALUE
@module_path = nil if @module_path == UNSET_VALUE @module_path = nil if @module_path == UNSET_VALUE
@synced_folder_type = nil if @synced_folder_type == UNSET_VALUE @synced_folder_type = nil if @synced_folder_type == UNSET_VALUE
@temp_dir = nil if @temp_dir == UNSET_VALUE @temp_dir = "/tmp/vagrant-puppet" if @temp_dir == UNSET_VALUE
@working_directory = nil if @working_directory == UNSET_VALUE @working_directory = nil if @working_directory == UNSET_VALUE
# Set a default temp dir that has an increasing counter so
# that multiple Puppet definitions won't overwrite each other
if !@temp_dir
counter = self.class.get_and_update_counter(:puppet_config)
@temp_dir = "/tmp/vagrant-puppet-#{counter}"
end
end end
# Returns the module paths as an array of paths expanded relative to the # Returns the module paths as an array of paths expanded relative to the

View File

@ -1,3 +1,5 @@
require "digest/md5"
require "log4r" require "log4r"
module VagrantPlugins module VagrantPlugins
@ -22,8 +24,9 @@ module VagrantPlugins
# Setup the module paths # Setup the module paths
@module_paths = [] @module_paths = []
@expanded_module_paths.each_with_index do |path, i| @expanded_module_paths.each_with_index do |path, _|
@module_paths << [path, File.join(config.temp_dir, "modules-#{i}")] key = Digest::MD5.hexdigest(path.to_s)
@module_paths << [path, File.join(config.temp_dir, "modules-#{key}")]
end end
folder_opts = {} folder_opts = {}
@ -85,7 +88,8 @@ module VagrantPlugins
def manifests_guest_path def manifests_guest_path
if config.manifests_path[0] == :host if config.manifests_path[0] == :host
# The path is on the host, so point to where it is shared # The path is on the host, so point to where it is shared
File.join(config.temp_dir, "manifests") key = Digest::MD5.hexdigest(config.manifests_path[1])
File.join(config.temp_dir, "manifests-#{key}")
else else
# The path is on the VM, so just point directly to it # The path is on the VM, so just point directly to it
config.manifests_path[1] config.manifests_path[1]

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

@ -23,6 +23,7 @@ module VagrantPlugins
# if we're on a system that doesn't support exec, so handle that properly. # if we're on a system that doesn't support exec, so handle that properly.
def execute(uploader) def execute(uploader)
cmd = [] cmd = []
cmd << "-debug" if !Vagrant.log_level.nil?
cmd << "-vcs" if config.vcs cmd << "-vcs" if config.vcs
cmd += config.includes.map { |v| ["-include", v] } cmd += config.includes.map { |v| ["-include", v] }
cmd += config.excludes.map { |v| ["-exclude", v] } cmd += config.excludes.map { |v| ["-exclude", v] }

View File

@ -1,3 +1,5 @@
require "pathname"
module VagrantPlugins module VagrantPlugins
module FTPPush module FTPPush
class Adapter class Adapter
@ -50,7 +52,7 @@ module VagrantPlugins
end end
def default_port def default_port
20 21
end end
def connect(&block) def connect(&block)
@ -67,16 +69,25 @@ module VagrantPlugins
end end
def upload(local, remote) def upload(local, remote)
parent = File.dirname(remote) parent = File.dirname(remote)
fullpath = Pathname.new(File.expand_path(parent, pwd))
# Create the parent directory if it does not exist # Create the parent directories if they does not exist (naive mkdir -p)
if !@server.list("/").any? { |f| f.start_with?(parent) } fullpath.descend do |path|
@server.mkdir(parent) if @server.list(path.to_s).empty?
@server.mkdir(path.to_s)
end
end end
# Upload the file # Upload the file
@server.putbinaryfile(local, remote) @server.putbinaryfile(local, remote)
end end
private
def pwd
@pwd ||= @server.pwd
end
end end
# #

View File

@ -7,6 +7,12 @@ module VagrantPlugins
module FTPPush module FTPPush
class Push < Vagrant.plugin("2", :push) class Push < Vagrant.plugin("2", :push)
IGNORED_FILES = %w(. ..).freeze IGNORED_FILES = %w(. ..).freeze
DEFAULT_EXCLUDES = %w(.git .hg .svn .vagrant).freeze
def initialize(*)
super
@logger = Log4r::Logger.new("vagrant::pushes::ftp")
end
def push def push
# Grab files early so if there's an exception or issue, we don't have to # Grab files early so if there's an exception or issue, we don't have to
@ -14,11 +20,16 @@ module VagrantPlugins
files = Hash[*all_files.flat_map do |file| files = Hash[*all_files.flat_map do |file|
relative_path = relative_path_for(file, config.dir) relative_path = relative_path_for(file, config.dir)
destination = File.expand_path(File.join(config.destination, relative_path)) destination = File.expand_path(File.join(config.destination, relative_path))
file = File.expand_path(file, env.root_path)
[file, destination] [file, destination]
end] end]
ftp = "#{config.username}@#{config.host}:#{config.destination}"
env.ui.info "Uploading #{env.root_path} to #{ftp}"
connect do |ftp| connect do |ftp|
files.each do |local, remote| files.each do |local, remote|
@logger.info "Uploading #{local} => #{remote}"
ftp.upload(local, remote) ftp.upload(local, remote)
end end
end end
@ -33,16 +44,6 @@ module VagrantPlugins
ftp.connect(&block) ftp.connect(&block)
end end
# Parse the host into it's url and port parts.
# @return [Array]
def parse_host(host)
if host.include?(":")
host.split(":", 2)
else
[host, "22"]
end
end
# The list of all files that should be pushed by this push. This method # The list of all files that should be pushed by this push. This method
# only returns **files**, not folders or symlinks! # only returns **files**, not folders or symlinks!
# @return [Array<String>] # @return [Array<String>]
@ -72,7 +73,10 @@ module VagrantPlugins
# @param [Array<String>] excludes # @param [Array<String>] excludes
# the exclude patterns or files # the exclude patterns or files
def filter_excludes!(list, excludes) def filter_excludes!(list, excludes)
excludes = Array(excludes).flat_map { |e| [e, "#{e}/*"] } excludes = Array(excludes)
excludes = excludes + DEFAULT_EXCLUDES
excludes = excludes.flat_map { |e| [e, "#{e}/*"] }
list.reject! do |file| list.reject! do |file|
basename = relative_path_for(file, config.dir) basename = relative_path_for(file, config.dir)

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

Some files were not shown because too many files have changed in this diff Show More