diff --git a/CHANGELOG.md b/CHANGELOG.md index e5901fa74..3ecd67de9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,18 +1,68 @@ -## 1.7.2 (unreleased) +## 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) diff --git a/LICENSE b/LICENSE index 661398b6b..91ca85a81 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ 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 of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index 7e1325dbf..ee1026409 100644 --- a/README.md +++ b/README.md @@ -68,7 +68,7 @@ like so: 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 (it does not respect your Gemfile), because it uses Bundler to manage plugin dependencies. diff --git a/Vagrantfile b/Vagrantfile index d21f2468d..e928b3c6b 100644 --- a/Vagrantfile +++ b/Vagrantfile @@ -6,7 +6,7 @@ Vagrant.configure("2") do |config| 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| v.memory = "1024" end diff --git a/contrib/bash/completion.sh b/contrib/bash/completion.sh index 636795744..e21dc8dcf 100644 --- a/contrib/bash/completion.sh +++ b/contrib/bash/completion.sh @@ -65,7 +65,7 @@ _vagrant() { then case "$prev" in "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})) return 0 ;; @@ -111,7 +111,7 @@ _vagrant() { then case "$prev" in "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})) return 0 ;; diff --git a/lib/vagrant.rb b/lib/vagrant.rb index 4b5dc84ba..1fb9c49d6 100644 --- a/lib/vagrant.rb +++ b/lib/vagrant.rb @@ -156,7 +156,7 @@ module Vagrant Plugin::Manager.instance.installed_specs.any? do |s| match = s.name == name next match if !version - next version.satisfied_by?(s.version) + next match && version.satisfied_by?(s.version) end end diff --git a/lib/vagrant/action/builtin/box_add.rb b/lib/vagrant/action/builtin/box_add.rb index 13688bae5..deed8b9ef 100644 --- a/lib/vagrant/action/builtin/box_add.rb +++ b/lib/vagrant/action/builtin/box_add.rb @@ -369,7 +369,7 @@ module Vagrant # # @return [Hash] 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)) @logger.info("Downloading box: #{url} => #{temp_path}") @@ -409,7 +409,7 @@ module Vagrant end 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) diff --git a/lib/vagrant/action/builtin/config_validate.rb b/lib/vagrant/action/builtin/config_validate.rb index e4fd44cdd..3c4461a10 100644 --- a/lib/vagrant/action/builtin/config_validate.rb +++ b/lib/vagrant/action/builtin/config_validate.rb @@ -11,7 +11,7 @@ module Vagrant end 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]) if errors && !errors.empty? diff --git a/lib/vagrant/action/builtin/graceful_halt.rb b/lib/vagrant/action/builtin/graceful_halt.rb index 5ccd8389d..33f6cfb9b 100644 --- a/lib/vagrant/action/builtin/graceful_halt.rb +++ b/lib/vagrant/action/builtin/graceful_halt.rb @@ -24,7 +24,7 @@ module Vagrant def call(env) 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. env[:result] = false diff --git a/lib/vagrant/action/builtin/mixin_synced_folders.rb b/lib/vagrant/action/builtin/mixin_synced_folders.rb index da8437dee..5a44c5ac8 100644 --- a/lib/vagrant/action/builtin/mixin_synced_folders.rb +++ b/lib/vagrant/action/builtin/mixin_synced_folders.rb @@ -129,7 +129,7 @@ module Vagrant # If we have folders with the "default" key, then determine the # most appropriate implementation for this. - if folders.has_key?("") && !folders[""].empty? + if folders.key?("") && !folders[""].empty? default_impl = default_synced_folder_type(machine, plugins) if !default_impl types = plugins.to_hash.keys.map { |t| t.to_s }.sort.join(", ") diff --git a/lib/vagrant/action/builtin/provision.rb b/lib/vagrant/action/builtin/provision.rb index 2163a2c6a..02868c735 100644 --- a/lib/vagrant/action/builtin/provision.rb +++ b/lib/vagrant/action/builtin/provision.rb @@ -24,13 +24,13 @@ module Vagrant # Tracks whether we were configured to provision 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 provision_enabled = true ignore_sentinel = true - if env.has_key?(:provision_ignore_sentinel) + if env.key?(:provision_ignore_sentinel) ignore_sentinel = env[:provision_ignore_sentinel] end if ignore_sentinel @@ -69,7 +69,7 @@ module Vagrant end # 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 provisioner_instances(env).each do |p, _| diff --git a/lib/vagrant/action/runner.rb b/lib/vagrant/action/runner.rb index 6d4a2e409..bfb187709 100644 --- a/lib/vagrant/action/runner.rb +++ b/lib/vagrant/action/runner.rb @@ -49,7 +49,7 @@ module Vagrant # Run the action chain in a busy block, marking the environment as # interrupted if a SIGINT occurs, and exiting cleanly once the # chain has been run. - ui = environment[:ui] if environment.has_key?(:ui) + ui = environment[:ui] if environment.key?(:ui) int_callback = lambda do if environment[:interrupted] ui.error I18n.t("vagrant.actions.runner.exit_immediately") if ui diff --git a/lib/vagrant/capability_host.rb b/lib/vagrant/capability_host.rb index e3b579a49..47491deef 100644 --- a/lib/vagrant/capability_host.rb +++ b/lib/vagrant/capability_host.rb @@ -165,7 +165,7 @@ module Vagrant @cap_logger.debug("Checking in: #{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}") return caps[cap_name] end diff --git a/lib/vagrant/config/loader.rb b/lib/vagrant/config/loader.rb index f57b5d31e..35b0d0828 100644 --- a/lib/vagrant/config/loader.rb +++ b/lib/vagrant/config/loader.rb @@ -49,7 +49,7 @@ module Vagrant # Gather the procs for every source, since that is what we care about. procs = [] 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 # avoids the issue where a file may have side effects when loading # and loading it multiple times causes unexpected behavior. @@ -92,10 +92,10 @@ module Vagrant errors = [] order.each do |key| - next if !@sources.has_key?(key) + next if !@sources.key?(key) @sources[key].each do |version, proc| - if !@config_cache.has_key?(proc) + if !@config_cache.key?(proc) @logger.debug("Loading from: #{key} (evaluating)") # Get the proper version loader for this version and load diff --git a/lib/vagrant/config/v1/loader.rb b/lib/vagrant/config/v1/loader.rb index 910ae3dda..e26c88e44 100644 --- a/lib/vagrant/config/v1/loader.rb +++ b/lib/vagrant/config/v1/loader.rb @@ -60,7 +60,7 @@ module Vagrant new_keys = new_state["keys"] keys = {} 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 # on the config class itself. keys[key] = old_value.merge(new_keys[key]) @@ -72,7 +72,7 @@ module Vagrant new_keys.each do |key, new_value| # 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 end end diff --git a/lib/vagrant/config/v1/root.rb b/lib/vagrant/config/v1/root.rb index 1f7db9763..975a9e4d3 100644 --- a/lib/vagrant/config/v1/root.rb +++ b/lib/vagrant/config/v1/root.rb @@ -20,7 +20,7 @@ module Vagrant # used for Vagrant and load the proper configuration classes for # each. 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] if config_klass diff --git a/lib/vagrant/config/v2/loader.rb b/lib/vagrant/config/v2/loader.rb index 1c3bc0224..2f5b6cbac 100644 --- a/lib/vagrant/config/v2/loader.rb +++ b/lib/vagrant/config/v2/loader.rb @@ -70,7 +70,7 @@ module Vagrant new_keys = new_state["keys"] keys = {} 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 # on the config class itself. keys[key] = old_value.merge(new_keys[key]) @@ -82,7 +82,7 @@ module Vagrant new_keys.each do |key, new_value| # 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 end end diff --git a/lib/vagrant/config/v2/root.rb b/lib/vagrant/config/v2/root.rb index f64129dad..f4a18c10b 100644 --- a/lib/vagrant/config/v2/root.rb +++ b/lib/vagrant/config/v2/root.rb @@ -22,7 +22,7 @@ module Vagrant # used for Vagrant and load the proper configuration classes for # each. 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] if config_klass @@ -41,7 +41,7 @@ module Vagrant # mutate itself. def finalize! @config_map.each do |key, klass| - if !@keys.has_key?(key) + if !@keys.key?(key) @keys[key] = klass.new end end @@ -102,9 +102,9 @@ module Vagrant # 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. def __set_internal_state(state) - @config_map = state["config_map"] if state.has_key?("config_map") - @keys = state["keys"] if state.has_key?("keys") - @missing_key_calls = state["missing_key_calls"] if state.has_key?("missing_key_calls") + @config_map = state["config_map"] if state.key?("config_map") + @keys = state["keys"] if state.key?("keys") + @missing_key_calls = state["missing_key_calls"] if state.key?("missing_key_calls") end end end diff --git a/lib/vagrant/environment.rb b/lib/vagrant/environment.rb index acda0c178..b57092b03 100644 --- a/lib/vagrant/environment.rb +++ b/lib/vagrant/environment.rb @@ -80,7 +80,7 @@ module Vagrant }.merge(opts || {}) # 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] = Pathname.new(opts[:cwd]) if !opts[:cwd].directory? @@ -94,7 +94,7 @@ module Vagrant # Set the Vagrantfile name up. We append "Vagrantfile" and "vagrantfile" so that # those continue to work as well, but anything custom will take precedence. 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].is_a?(Array) @@ -307,7 +307,7 @@ module Vagrant # @return [Symbol] Name of the default provider. def default_provider(**opts) 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 = nil if default == "" @@ -351,15 +351,15 @@ module Vagrant # Skip providers that can't be defaulted, unless they're in our # config, in which case someone made our decision for us. - if !config.has_key?(key) - next if popts.has_key?(:defaultable) && !popts[:defaultable] + if !config.key?(key) + next if popts.key?(:defaultable) && !popts[:defaultable] end # 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 # is never higher than the configuration keys. 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] end @@ -596,7 +596,7 @@ module Vagrant @machines.delete(cache_key) end - if @machines.has_key?(cache_key) + if @machines.key?(cache_key) @logger.info("Returning cached machine: #{name} (#{provider})") return @machines[cache_key] end diff --git a/lib/vagrant/machine.rb b/lib/vagrant/machine.rb index 07489e977..03ca19f07 100644 --- a/lib/vagrant/machine.rb +++ b/lib/vagrant/machine.rb @@ -150,12 +150,14 @@ module Vagrant # @param [Hash] extra_env This data will be passed into the action runner # as extra data set on the environment hash for the middleware # runner. - def action(name, **opts) + def action(name, opts=nil) @logger.info("Calling action: #{name} on provider #{@provider}") + opts ||= {} + # Determine whether we lock or not 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 = opts.dup diff --git a/lib/vagrant/plugin/manager.rb b/lib/vagrant/plugin/manager.rb index 0cd71c8ba..dfaab2ecf 100644 --- a/lib/vagrant/plugin/manager.rb +++ b/lib/vagrant/plugin/manager.rb @@ -143,7 +143,7 @@ module Vagrant # If we already have a newer version in our list of installed, # 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] = spec diff --git a/lib/vagrant/plugin/state_file.rb b/lib/vagrant/plugin/state_file.rb index 4a39a52bc..f41da1b86 100644 --- a/lib/vagrant/plugin/state_file.rb +++ b/lib/vagrant/plugin/state_file.rb @@ -61,7 +61,7 @@ module Vagrant # # @return [Boolean] def has_plugin?(name) - @data["installed"].has_key?(name) + @data["installed"].key?(name) end # Remove a plugin that is installed from the state file. diff --git a/lib/vagrant/plugin/v2/plugin.rb b/lib/vagrant/plugin/v2/plugin.rb index a39b3cf10..025032fd9 100644 --- a/lib/vagrant/plugin/v2/plugin.rb +++ b/lib/vagrant/plugin/v2/plugin.rb @@ -88,7 +88,7 @@ module Vagrant end # By default, the command is primary - opts[:primary] = true if !opts.has_key?(:primary) + opts[:primary] = true if !opts.key?(:primary) # Register the command components.commands.register(name.to_sym) do diff --git a/lib/vagrant/registry.rb b/lib/vagrant/registry.rb index f3c86edec..d84a745a5 100644 --- a/lib/vagrant/registry.rb +++ b/lib/vagrant/registry.rb @@ -22,8 +22,8 @@ module Vagrant # This will evaluate the block given to `register` and return the # resulting value. def get(key) - return nil if !@items.has_key?(key) - return @results_cache[key] if @results_cache.has_key?(key) + return nil if !@items.key?(key) + return @results_cache[key] if @results_cache.key?(key) @results_cache[key] = @items[key].call end alias :[] :get @@ -31,9 +31,10 @@ module Vagrant # Checks if the given key is registered with the registry. # # @return [Boolean] - def has_key?(key) - @items.has_key?(key) + def key?(key) + @items.key?(key) end + alias_method :has_key?, :key? # Returns an array populated with the keys of this object. # diff --git a/lib/vagrant/shared_helpers.rb b/lib/vagrant/shared_helpers.rb index b195c36df..12545ae4f 100644 --- a/lib/vagrant/shared_helpers.rb +++ b/lib/vagrant/shared_helpers.rb @@ -52,6 +52,13 @@ module Vagrant !!ENV["VAGRANT_I_KNOW_WHAT_IM_DOING_PLEASE_BE_QUIET"] end + # The current log level for Vagrant + # + # @return [String] + def self.log_level + ENV["VAGRANT_LOG"] + end + # Returns the URL prefix to the server. # # @return [String] diff --git a/lib/vagrant/ui.rb b/lib/vagrant/ui.rb index 4b47c3e1f..a84448a1c 100644 --- a/lib/vagrant/ui.rb +++ b/lib/vagrant/ui.rb @@ -136,9 +136,9 @@ module Vagrant # Setup the options so that the new line is suppressed opts ||= {} - opts[:echo] = true if !opts.has_key?(:echo) - opts[:new_line] = false if !opts.has_key?(:new_line) - opts[:prefix] = false if !opts.has_key?(:prefix) + opts[:echo] = true if !opts.key?(:echo) + opts[:new_line] = false if !opts.key?(:new_line) + opts[:prefix] = false if !opts.key?(:prefix) # Output the data say(:info, message, opts) @@ -249,7 +249,7 @@ module Vagrant class_eval <<-CODE def #{method}(message, *args, **opts) 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 && \ #{method.inspect} != :ask end @@ -284,7 +284,7 @@ module Vagrant opts = self.opts.merge(opts) prefix = "" - if !opts.has_key?(:prefix) || opts[:prefix] + if !opts.key?(:prefix) || opts[:prefix] prefix = OUTPUT_PREFIX prefix = " " * OUTPUT_PREFIX.length if \ type == :detail || type == :ask || opts[:prefix_spaces] @@ -294,7 +294,7 @@ module Vagrant return message if prefix.empty? 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 # is an empty string, then we want to still use the empty string. diff --git a/lib/vagrant/util/env.rb b/lib/vagrant/util/env.rb index e7c23ccc6..3d3200f17 100644 --- a/lib/vagrant/util/env.rb +++ b/lib/vagrant/util/env.rb @@ -26,7 +26,7 @@ module Vagrant # @param [Proc] block # the block to execute with the cleaned environment # - def with_clean_env(&block) + def self.with_clean_env(&block) original = ENV.to_hash ENV.delete('_ORIGINAL_GEM_PATH') diff --git a/lib/vagrant/util/is_port_open.rb b/lib/vagrant/util/is_port_open.rb index e98dd4c24..63652ee28 100644 --- a/lib/vagrant/util/is_port_open.rb +++ b/lib/vagrant/util/is_port_open.rb @@ -29,7 +29,8 @@ module Vagrant # to connect. return true 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. return false end diff --git a/lib/vagrant/util/platform.rb b/lib/vagrant/util/platform.rb index d2b399616..c452eb295 100644 --- a/lib/vagrant/util/platform.rb +++ b/lib/vagrant/util/platform.rb @@ -148,7 +148,7 @@ module Vagrant # output. def terminal_supports_colors? if windows? - return true if ENV.has_key?("ANSICON") + return true if ENV.key?("ANSICON") return true if cygwin? return true if ENV["TERM"] == "cygwin" return false diff --git a/plugins/commands/destroy/command.rb b/plugins/commands/destroy/command.rb index e7a2f603f..141bfd38b 100644 --- a/plugins/commands/destroy/command.rb +++ b/plugins/commands/destroy/command.rb @@ -32,7 +32,7 @@ module VagrantPlugins :destroy, force_confirm_destroy: options[:force]) 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 end diff --git a/plugins/commands/login/client.rb b/plugins/commands/login/client.rb index 64a8dd1c5..63b01f335 100644 --- a/plugins/commands/login/client.rb +++ b/plugins/commands/login/client.rb @@ -7,11 +7,13 @@ module VagrantPlugins # # @param [Vagrant::Environment] env def initialize(env) - @env = env + @logger = Log4r::Logger.new("vagrant::login::client") + @env = env end # Removes the token, effectively logging the user out. def clear_token + @logger.info("Clearing token") token_path.delete if token_path.file? end @@ -38,6 +40,8 @@ module VagrantPlugins # @param [String] pass # @return [String] token The access token, or nil if auth failed. def login(user, pass) + @logger.info("Logging in '#{user}'") + with_error_handling do url = "#{Vagrant.server_url}/api/v1/authenticate" request = { "user" => { "login" => user, "password" => pass } } @@ -52,9 +56,12 @@ module VagrantPlugins # # @param [String] token def store_token(token) + @logger.info("Storing token in #{token_path}") + token_path.open("w") do |f| f.write(token) end + nil end @@ -65,13 +72,17 @@ module VagrantPlugins # @return [String] def token if ENV["ATLAS_TOKEN"] && !ENV["ATLAS_TOKEN"].empty? + @logger.debug("Using authentication token from environment variable") return ENV["ATLAS_TOKEN"] end if token_path.exist? + @logger.debug("Using authentication token from disk at #{token_path}") return token_path.read.strip end + @logger.debug("No authentication token in environment or #{token_path}") + nil end @@ -80,8 +91,13 @@ module VagrantPlugins def with_error_handling(&block) yield rescue RestClient::Unauthorized + @logger.debug("Unauthorized!") false rescue RestClient::NotAcceptable => e + @logger.debug("Got unacceptable response:") + @logger.debug(e.message) + @logger.debug(e.backtrace.join("\n")) + begin errors = JSON.parse(e.response)["errors"].join("\n") raise Errors::ServerError, errors: errors @@ -89,6 +105,7 @@ module VagrantPlugins raise "An unexpected error occurred: #{e.inspect}" rescue SocketError + @logger.info("Socket error") raise Errors::ServerUnreachable, url: Vagrant.server_url.to_s end diff --git a/plugins/commands/login/command.rb b/plugins/commands/login/command.rb index e16b1afaf..203b09009 100644 --- a/plugins/commands/login/command.rb +++ b/plugins/commands/login/command.rb @@ -18,6 +18,10 @@ module VagrantPlugins o.on("-k", "--logout", "Logs you out if you're logged in") do |k| options[:logout] = k end + + o.on("-t", "--token TOKEN", String, "Set the Atlas token") do |t| + options[:token] = t + end end # Parse the options @@ -31,6 +35,8 @@ module VagrantPlugins return execute_check elsif options[:logout] return execute_logout + elsif options[:token] + return execute_token(options[:token]) end # Let the user know what is going on. @@ -78,6 +84,19 @@ module VagrantPlugins @env.ui.success(I18n.t("login_command.logged_out")) return 0 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 diff --git a/plugins/commands/login/locales/en.yml b/plugins/commands/login/locales/en.yml index 51020df1d..dba4d52d7 100644 --- a/plugins/commands/login/locales/en.yml +++ b/plugins/commands/login/locales/en.yml @@ -24,7 +24,11 @@ en: https://atlas.hashicorp.com. invalid_login: |- Invalid username or password. Please try again. + invalid_token: |- + Invalid token. Please try again. logged_in: |- You are now logged in. logged_out: |- You are logged out. + token_saved: |- + The token was successfully saved. diff --git a/plugins/commands/package/command.rb b/plugins/commands/package/command.rb index e54335475..3bb2cf563 100644 --- a/plugins/commands/package/command.rb +++ b/plugins/commands/package/command.rb @@ -80,7 +80,7 @@ module VagrantPlugins acc end - vm.action(:package, **opts) + vm.action(:package, opts) end end end diff --git a/plugins/commands/plugin/action/plugin_exists_check.rb b/plugins/commands/plugin/action/plugin_exists_check.rb index 7a369976e..b7b7b9623 100644 --- a/plugins/commands/plugin/action/plugin_exists_check.rb +++ b/plugins/commands/plugin/action/plugin_exists_check.rb @@ -12,7 +12,7 @@ module VagrantPlugins def call(env) installed = Vagrant::Plugin::Manager.instance.installed_plugins - if !installed.has_key?(env[:plugin_name]) + if !installed.key?(env[:plugin_name]) raise Vagrant::Errors::PluginNotInstalled, name: env[:plugin_name] end diff --git a/plugins/commands/push/command.rb b/plugins/commands/push/command.rb index dabe74bb6..902a0c946 100644 --- a/plugins/commands/push/command.rb +++ b/plugins/commands/push/command.rb @@ -19,6 +19,11 @@ module VagrantPlugins 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}'") @env.push(name) diff --git a/plugins/commands/up/command.rb b/plugins/commands/up/command.rb index d7b3bd7dc..826bea0ae 100644 --- a/plugins/commands/up/command.rb +++ b/plugins/commands/up/command.rb @@ -60,8 +60,8 @@ module VagrantPlugins if names.empty? autostart = false @env.vagrantfile.machine_names_and_options.each do |n, o| - autostart = true if o.has_key?(:autostart) - o[:autostart] = true if !o.has_key?(:autostart) + autostart = true if o.key?(:autostart) + o[:autostart] = true if !o.key?(:autostart) names << n.to_s if o[:autostart] end diff --git a/plugins/commands/up/start_mixins.rb b/plugins/commands/up/start_mixins.rb index e0aeb6de2..548d889ca 100644 --- a/plugins/commands/up/start_mixins.rb +++ b/plugins/commands/up/start_mixins.rb @@ -19,6 +19,8 @@ module VagrantPlugins parser.on("--provision-with x,y,z", Array, "Enable only certain provisioners, by type.") do |list| options[:provision_types] = list.map { |type| type.to_sym } + options[:provision_enabled] = true + options[:provision_ignore_sentinel] = true end end diff --git a/plugins/communicators/ssh/communicator.rb b/plugins/communicators/ssh/communicator.rb index 35506e31e..64455042b 100644 --- a/plugins/communicators/ssh/communicator.rb +++ b/plugins/communicators/ssh/communicator.rb @@ -320,7 +320,7 @@ module VagrantPlugins raise Vagrant::Errors::SSHNotReady if ssh_info.nil? # 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 common_connect_opts = { diff --git a/plugins/communicators/winrm/command_filters/mkdir.rb b/plugins/communicators/winrm/command_filters/mkdir.rb old mode 100755 new mode 100644 diff --git a/plugins/communicators/winrm/shell.rb b/plugins/communicators/winrm/shell.rb index 700408940..794c3135d 100644 --- a/plugins/communicators/winrm/shell.rb +++ b/plugins/communicators/winrm/shell.rb @@ -91,7 +91,23 @@ module VagrantPlugins block.call(:stdout, out) if block_given? && out block.call(:stderr, err) if block_given? && err end + @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 end end diff --git a/plugins/guests/darwin/cap/rsync.rb b/plugins/guests/darwin/cap/rsync.rb index e98d6e5ae..7e5d6d9a5 100644 --- a/plugins/guests/darwin/cap/rsync.rb +++ b/plugins/guests/darwin/cap/rsync.rb @@ -17,7 +17,7 @@ module VagrantPlugins end def self.rsync_post(machine, opts) - if opts.has_key?(:chown) && !opts[:chown] + if opts.key?(:chown) && !opts[:chown] return end diff --git a/plugins/guests/fedora/cap/configure_networks.rb b/plugins/guests/fedora/cap/configure_networks.rb index 549a99dff..2f67099cd 100644 --- a/plugins/guests/fedora/cap/configure_networks.rb +++ b/plugins/guests/fedora/cap/configure_networks.rb @@ -26,7 +26,7 @@ module VagrantPlugins end interface_names = networks.map do |network| - "eth#{network[:interface]}" + "#{interface_names[network[:interface]]}" end else machine.communicate.sudo("/usr/sbin/biosdevname -d | grep Kernel | cut -f2 -d: | sed -e 's/ //;'") do |_, result| diff --git a/plugins/guests/freebsd/cap/rsync.rb b/plugins/guests/freebsd/cap/rsync.rb index 2876b5943..c8fb36006 100644 --- a/plugins/guests/freebsd/cap/rsync.rb +++ b/plugins/guests/freebsd/cap/rsync.rb @@ -31,7 +31,7 @@ module VagrantPlugins end def self.rsync_post(machine, opts) - if opts.has_key?(:chown) && !opts[:chown] + if opts.key?(:chown) && !opts[:chown] return end diff --git a/plugins/guests/funtoo/cap/configure_networks.rb b/plugins/guests/funtoo/cap/configure_networks.rb index 466e3a57b..c52182b6f 100644 --- a/plugins/guests/funtoo/cap/configure_networks.rb +++ b/plugins/guests/funtoo/cap/configure_networks.rb @@ -28,7 +28,7 @@ module VagrantPlugins temp.binmode temp.write(entry) 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("chmod 0644 /etc/conf.d/#{ifFile}") comm.sudo("ln -fs /etc/init.d/netif.tmpl /etc/init.d/#{ifFile}") diff --git a/plugins/guests/linux/cap/rsync.rb b/plugins/guests/linux/cap/rsync.rb index 113b18dd0..424d20f46 100644 --- a/plugins/guests/linux/cap/rsync.rb +++ b/plugins/guests/linux/cap/rsync.rb @@ -17,7 +17,7 @@ module VagrantPlugins end def self.rsync_post(machine, opts) - if opts.has_key?(:chown) && !opts[:chown] + if opts.key?(:chown) && !opts[:chown] return end diff --git a/plugins/guests/solaris/cap/rsync.rb b/plugins/guests/solaris/cap/rsync.rb index d060a8020..0d0220f40 100644 --- a/plugins/guests/solaris/cap/rsync.rb +++ b/plugins/guests/solaris/cap/rsync.rb @@ -17,10 +17,10 @@ module VagrantPlugins end def self.rsync_post(machine, opts) - su_cmd = machine.config.solaris.su_cmd + suexec_cmd = machine.config.solaris.suexec_cmd machine.communicate.execute( - "#{su_cmd} find '#{opts[:guestpath]}' '(' ! -user #{opts[:owner]} -or ! -group #{opts[:group]} ')' -print0 | " + - "xargs -0 -r chown #{opts[:owner]}:#{opts[:group]}") + "#{suexec_cmd} find '#{opts[:guestpath]}' '(' ! -user #{opts[:owner]} -or ! -group #{opts[:group]} ')' -print0 | " + + "xargs -0 chown #{opts[:owner]}:#{opts[:group]}") end end end diff --git a/plugins/guests/solaris/config.rb b/plugins/guests/solaris/config.rb index e0a6a486b..5983b6837 100644 --- a/plugins/guests/solaris/config.rb +++ b/plugins/guests/solaris/config.rb @@ -3,24 +3,28 @@ module VagrantPlugins class Config < Vagrant.plugin("2", :config) attr_accessor :halt_timeout 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 :device def initialize @halt_timeout = UNSET_VALUE @halt_check_interval = UNSET_VALUE - @suexec_cmd = 'sudo' - @device = "e1000g" + @suexec_cmd = UNSET_VALUE + @device = UNSET_VALUE end def finalize! if @halt_timeout != UNSET_VALUE puts "solaris.halt_timeout is deprecated and will be removed in Vagrant 1.7" end + if @halt_check_interval != UNSET_VALUE puts "solaris.halt_check_interval is deprecated and will be removed in Vagrant 1.7" end + + @suexec_cmd = "sudo" if @suexec_cmd == UNSET_VALUE + @device = "e1000g" if @device == UNSET_VALUE end end end diff --git a/plugins/guests/solaris11/cap/rsync.rb b/plugins/guests/solaris11/cap/rsync.rb index 039602172..95df046c9 100644 --- a/plugins/guests/solaris11/cap/rsync.rb +++ b/plugins/guests/solaris11/cap/rsync.rb @@ -17,10 +17,10 @@ module VagrantPlugins end def self.rsync_post(machine, opts) - su_cmd = machine.config.solaris11.su_cmd + suexec_cmd = machine.config.solaris11.suexec_cmd machine.communicate.execute( - "#{su_cmd} '#{opts[:guestpath]}' '(' ! -user #{opts[:owner]} -or ! -group #{opts[:group]} ')' -print0 | " + - "xargs -0 -r chown #{opts[:owner]}:#{opts[:group]}") + "#{suexec_cmd} '#{opts[:guestpath]}' '(' ! -user #{opts[:owner]} -or ! -group #{opts[:group]} ')' -print0 | " + + "xargs -0 chown #{opts[:owner]}:#{opts[:group]}") end end end diff --git a/plugins/hosts/bsd/cap/nfs.rb b/plugins/hosts/bsd/cap/nfs.rb index 9fd1f7ef8..5d31c3cc1 100644 --- a/plugins/hosts/bsd/cap/nfs.rb +++ b/plugins/hosts/bsd/cap/nfs.rb @@ -137,7 +137,7 @@ module VagrantPlugins user = Process.uid 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) logger.debug("Valid ID: #{id}") else diff --git a/plugins/hosts/linux/cap/nfs.rb b/plugins/hosts/linux/cap/nfs.rb index 189800db4..bf10aff9e 100644 --- a/plugins/hosts/linux/cap/nfs.rb +++ b/plugins/hosts/linux/cap/nfs.rb @@ -71,7 +71,7 @@ module VagrantPlugins user = Process.uid 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) logger.debug("Valid ID: #{id}") else diff --git a/plugins/kernel_v2/config/push.rb b/plugins/kernel_v2/config/push.rb index e1cb95734..ccba3826d 100644 --- a/plugins/kernel_v2/config/push.rb +++ b/plugins/kernel_v2/config/push.rb @@ -115,6 +115,22 @@ module VagrantPlugins 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. # # @return [Hash>] diff --git a/plugins/kernel_v2/config/vm.rb b/plugins/kernel_v2/config/vm.rb index fd08f436a..11947a30c 100644 --- a/plugins/kernel_v2/config/vm.rb +++ b/plugins/kernel_v2/config/vm.rb @@ -96,7 +96,7 @@ module VagrantPlugins end 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 else new_defined_vms[key].config_procs.concat(subvm.config_procs) @@ -197,7 +197,7 @@ module VagrantPlugins options ||= {} options[:guestpath] = guestpath.to_s.gsub(/\/$/, '') options[:hostpath] = hostpath - options[:disabled] = false if !options.has_key?(:disabled) + options[:disabled] = false if !options.key?(:disabled) options = (@__synced_folders[options[:guestpath]] || {}). merge(options.dup) @@ -247,7 +247,7 @@ module VagrantPlugins id = "#{type}-#{id}" # Merge in the previous settings if we have them. - if @__networks.has_key?(id) + if @__networks.key?(id) options = @__networks[id][1].merge(options) end @@ -279,13 +279,13 @@ module VagrantPlugins def provision(name, **options, &block) type = name - if options.has_key?(:type) + if options.key?(:type) type = options.delete(:type) else name = nil end - if options.has_key?(:id) + if options.key?(:id) puts "Setting `id` on a provisioner is deprecated. Please use the" puts "new syntax of `config.vm.provision \"name\", type: \"type\"" puts "where \"name\" is the replacement for `id`. This will be" @@ -306,8 +306,8 @@ module VagrantPlugins end prov.preserve_order = !!options.delete(:preserve_order) if \ - options.has_key?(:preserve_order) - prov.run = options.delete(:run) if options.has_key?(:run) + options.key?(:preserve_order) + prov.run = options.delete(:run) if options.key?(:run) prov.add_config(options, &block) nil end diff --git a/plugins/providers/docker/action/host_machine_sync_folders.rb b/plugins/providers/docker/action/host_machine_sync_folders.rb index 2c10df337..9a6f03893 100644 --- a/plugins/providers/docker/action/host_machine_sync_folders.rb +++ b/plugins/providers/docker/action/host_machine_sync_folders.rb @@ -22,7 +22,7 @@ module VagrantPlugins def call(env) 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 end @@ -115,7 +115,7 @@ module VagrantPlugins # Add this synced folder onto the new config if we haven't # 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 # folder as transient. This can be removed once # the VirtualBox synced folder mechanism is smarter. diff --git a/plugins/providers/docker/hostmachine/Vagrantfile b/plugins/providers/docker/hostmachine/Vagrantfile index 752ba888d..79cd59f8c 100644 --- a/plugins/providers/docker/hostmachine/Vagrantfile +++ b/plugins/providers/docker/hostmachine/Vagrantfile @@ -18,4 +18,9 @@ Vagrant.configure("2") do |config| # b2d doesn't support NFS 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 diff --git a/plugins/providers/hyperv/action/import.rb b/plugins/providers/hyperv/action/import.rb index 0687503af..468a55c57 100644 --- a/plugins/providers/hyperv/action/import.rb +++ b/plugins/providers/hyperv/action/import.rb @@ -14,6 +14,15 @@ module VagrantPlugins def call(env) vm_dir = env[:machine].box.directory.join("Virtual Machines") 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? raise Errors::BoxInvalid @@ -78,6 +87,10 @@ module VagrantPlugins image_path: image_path.to_s.gsub("/", "\\") } 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...") server = env[:machine].provider.driver.import(options) diff --git a/plugins/providers/hyperv/config.rb b/plugins/providers/hyperv/config.rb index ad69e3059..89b51c0a6 100644 --- a/plugins/providers/hyperv/config.rb +++ b/plugins/providers/hyperv/config.rb @@ -8,15 +8,27 @@ module VagrantPlugins # # @return [Integer] attr_accessor :ip_address_timeout + attr_accessor :memory + attr_accessor :maxmemory + attr_accessor :cpus + attr_accessor :vmname def initialize @ip_address_timeout = UNSET_VALUE + @memory = UNSET_VALUE + @maxmemory = UNSET_VALUE + @cpus = UNSET_VALUE + @vmname = UNSET_VALUE end def finalize! if @ip_address_timeout == UNSET_VALUE @ip_address_timeout = 120 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 def validate(machine) diff --git a/plugins/providers/hyperv/scripts/import_vm.ps1 b/plugins/providers/hyperv/scripts/import_vm.ps1 index 0b1d74a7e..5aea63875 100644 --- a/plugins/providers/hyperv/scripts/import_vm.ps1 +++ b/plugins/providers/hyperv/scripts/import_vm.ps1 @@ -4,7 +4,11 @@ Param( [Parameter(Mandatory=$true)] [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 @@ -13,10 +17,22 @@ $Dir = Split-Path $script:MyInvocation.MyCommand.Path [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 +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) { Get-VM | ForEach-Object -Process { if ($name -eq $_.Name) { @@ -31,18 +47,34 @@ do { $vm_name = GetUniqueName $name } while ($vm_name -ne $name) -$memory = (Select-Xml -xml $vmconfig -XPath "//memory").node.Bank -if ($memory.dynamic_memory_enabled."#text" -eq "True") { - $dynamicmemory = $True +if (!$memory) { + $xmlmemory = (Select-Xml -xml $vmconfig -XPath "//memory").node.Bank + 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 { - $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) { # Get the name of the virtual switch diff --git a/plugins/providers/hyperv/scripts/start_vm.ps1 b/plugins/providers/hyperv/scripts/start_vm.ps1 index 937ce75ed..54025c9a4 100644 --- a/plugins/providers/hyperv/scripts/start_vm.ps1 +++ b/plugins/providers/hyperv/scripts/start_vm.ps1 @@ -10,7 +10,7 @@ forEach ($module in $modules) { . $module } try { $vm = Get-VM -Id $VmId -ErrorAction "stop" - Start-VM $vm + Start-VM $vm -ErrorAction "stop" $state = $vm.state $status = $vm.status $name = $vm.name @@ -24,4 +24,4 @@ try { } catch { Write-Error-Message "Failed to start a VM $_" -} +} \ No newline at end of file diff --git a/plugins/providers/virtualbox/action/prepare_nfs_settings.rb b/plugins/providers/virtualbox/action/prepare_nfs_settings.rb index c5f95af1f..d3edf3e93 100644 --- a/plugins/providers/virtualbox/action/prepare_nfs_settings.rb +++ b/plugins/providers/virtualbox/action/prepare_nfs_settings.rb @@ -24,7 +24,7 @@ module VagrantPlugins } 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") add_ips_to_env!(env) end diff --git a/plugins/providers/virtualbox/action/set_name.rb b/plugins/providers/virtualbox/action/set_name.rb index 3cbcf131a..0e80f4591 100644 --- a/plugins/providers/virtualbox/action/set_name.rb +++ b/plugins/providers/virtualbox/action/set_name.rb @@ -32,9 +32,9 @@ module VagrantPlugins # Verify the name is not taken vms = env[:machine].provider.driver.read_vms 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.") else env[:ui].info(I18n.t( diff --git a/plugins/providers/virtualbox/config.rb b/plugins/providers/virtualbox/config.rb index aed1c692c..5bb1e754b 100644 --- a/plugins/providers/virtualbox/config.rb +++ b/plugins/providers/virtualbox/config.rb @@ -143,7 +143,7 @@ module VagrantPlugins def validate(machine) 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, _| if !valid_events.include?(event) errors << I18n.t( diff --git a/plugins/providers/virtualbox/driver/base.rb b/plugins/providers/virtualbox/driver/base.rb index 3002418f7..da019eae8 100644 --- a/plugins/providers/virtualbox/driver/base.rb +++ b/plugins/providers/virtualbox/driver/base.rb @@ -30,8 +30,8 @@ module VagrantPlugins # On Windows, we use the VBOX_INSTALL_PATH environmental # variable to find VBoxManage. - if ENV.has_key?("VBOX_INSTALL_PATH") || - ENV.has_key?("VBOX_MSI_INSTALL_PATH") + if ENV.key?("VBOX_INSTALL_PATH") || + ENV.key?("VBOX_MSI_INSTALL_PATH") # Get the path. path = ENV["VBOX_INSTALL_PATH"] || ENV["VBOX_MSI_INSTALL_PATH"] @logger.debug("VBOX_INSTALL_PATH value: #{path}") diff --git a/plugins/providers/virtualbox/driver/version_4_0.rb b/plugins/providers/virtualbox/driver/version_4_0.rb index 04070b559..a29193842 100644 --- a/plugins/providers/virtualbox/driver/version_4_0.rb +++ b/plugins/providers/virtualbox/driver/version_4_0.rb @@ -445,7 +445,7 @@ module VagrantPlugins folder[:name], "--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) end end diff --git a/plugins/providers/virtualbox/driver/version_4_1.rb b/plugins/providers/virtualbox/driver/version_4_1.rb index b3fd44978..c22042b6b 100644 --- a/plugins/providers/virtualbox/driver/version_4_1.rb +++ b/plugins/providers/virtualbox/driver/version_4_1.rb @@ -450,13 +450,13 @@ module VagrantPlugins folder[:name], "--hostpath", folder[:hostpath]] - args << "--transient" if folder.has_key?(:transient) && folder[:transient] - - # Add the shared folder - execute("sharedfolder", "add", @uuid, *args) + args << "--transient" if folder.key?(:transient) && folder[:transient] # Enable symlinks on the shared folder execute("setextradata", @uuid, "VBoxInternal2/SharedFoldersEnableSymlinksCreate/#{folder[:name]}", "1") + + # Add the shared folder + execute("sharedfolder", "add", @uuid, *args) end end diff --git a/plugins/providers/virtualbox/driver/version_4_2.rb b/plugins/providers/virtualbox/driver/version_4_2.rb index 765855e77..d976d973c 100644 --- a/plugins/providers/virtualbox/driver/version_4_2.rb +++ b/plugins/providers/virtualbox/driver/version_4_2.rb @@ -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 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 - 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 - 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 @@ -481,13 +481,13 @@ module VagrantPlugins folder[:name], "--hostpath", folder[:hostpath]] - args << "--transient" if folder.has_key?(:transient) && folder[:transient] - - # Add the shared folder - execute("sharedfolder", "add", @uuid, *args) + args << "--transient" if folder.key?(:transient) && folder[:transient] # Enable symlinks on the shared folder execute("setextradata", @uuid, "VBoxInternal2/SharedFoldersEnableSymlinksCreate/#{folder[:name]}", "1") + + # Add the shared folder + execute("sharedfolder", "add", @uuid, *args) end end diff --git a/plugins/providers/virtualbox/driver/version_4_3.rb b/plugins/providers/virtualbox/driver/version_4_3.rb index ad3cc4cd9..28e6539d4 100644 --- a/plugins/providers/virtualbox/driver/version_4_3.rb +++ b/plugins/providers/virtualbox/driver/version_4_3.rb @@ -498,13 +498,13 @@ module VagrantPlugins folder[:name], "--hostpath", folder[:hostpath]] - args << "--transient" if folder.has_key?(:transient) && folder[:transient] - - # Add the shared folder - execute("sharedfolder", "add", @uuid, *args) + args << "--transient" if folder.key?(:transient) && folder[:transient] # Enable symlinks on the shared folder execute("setextradata", @uuid, "VBoxInternal2/SharedFoldersEnableSymlinksCreate/#{folder[:name]}", "1") + + # Add the shared folder + execute("sharedfolder", "add", @uuid, *args) end end diff --git a/plugins/providers/virtualbox/model/forwarded_port.rb b/plugins/providers/virtualbox/model/forwarded_port.rb index 2229519f7..03107408e 100644 --- a/plugins/providers/virtualbox/model/forwarded_port.rb +++ b/plugins/providers/virtualbox/model/forwarded_port.rb @@ -51,7 +51,7 @@ module VagrantPlugins options ||= {} @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 @guest_ip = options[:guest_ip] || nil @host_ip = options[:host_ip] || nil diff --git a/plugins/provisioners/ansible/provisioner.rb b/plugins/provisioners/ansible/provisioner.rb index eea544abe..9e2cb155b 100644 --- a/plugins/provisioners/ansible/provisioner.rb +++ b/plugins/provisioners/ansible/provisioner.rb @@ -1,3 +1,5 @@ +require "vagrant/util/platform" + module VagrantPlugins module Ansible class Provisioner < Vagrant.plugin("2", :provisioner) @@ -23,6 +25,12 @@ module VagrantPlugins # but can be enabled via raw_arguments option. 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 # this can be overridden by the `limit` option. if config.limit @@ -209,6 +217,12 @@ module VagrantPlugins # 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 + # 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 @ssh_info[:private_key_path].drop(1).each do |key| ssh_options << "-o IdentityFile=#{key}" diff --git a/plugins/provisioners/chef/cap/omnios/chef_install.rb b/plugins/provisioners/chef/cap/omnios/chef_install.rb new file mode 100644 index 000000000..b20332638 --- /dev/null +++ b/plugins/provisioners/chef/cap/omnios/chef_install.rb @@ -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 diff --git a/plugins/provisioners/chef/cap/omnios/chef_installed.rb b/plugins/provisioners/chef/cap/omnios/chef_installed.rb new file mode 100644 index 000000000..2345d3b6a --- /dev/null +++ b/plugins/provisioners/chef/cap/omnios/chef_installed.rb @@ -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 diff --git a/plugins/provisioners/chef/config/base.rb b/plugins/provisioners/chef/config/base.rb index 4adb0d148..370736fd6 100644 --- a/plugins/provisioners/chef/config/base.rb +++ b/plugins/provisioners/chef/config/base.rb @@ -1,11 +1,7 @@ -require "vagrant/util/counter" - module VagrantPlugins module Chef module Config class Base < Vagrant.plugin("2", :config) - extend Vagrant::Util::Counter - # The path to Chef's bin/ directory. # @return [String] attr_accessor :binary_path @@ -48,11 +44,11 @@ module VagrantPlugins # @return [String] attr_accessor :version - # The path where the Chef installer will be downloaded to. Only valid if + # 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. - # + # omnibus installer will choose the destination and you have no control + # over it. + # # @return [String] attr_accessor :installer_download_path diff --git a/plugins/provisioners/chef/config/base_runner.rb b/plugins/provisioners/chef/config/base_runner.rb index 334c9b739..12ac0aabd 100644 --- a/plugins/provisioners/chef/config/base_runner.rb +++ b/plugins/provisioners/chef/config/base_runner.rb @@ -81,7 +81,7 @@ module VagrantPlugins @https_proxy_pass = nil if @https_proxy_pass == UNSET_VALUE @no_proxy = nil if @no_proxy == 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_cache_path = "/var/chef/cache" if @file_cache_path == 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 @encrypted_data_bag_secret_key_path = nil 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 def merge(other) diff --git a/plugins/provisioners/chef/config/chef_apply.rb b/plugins/provisioners/chef/config/chef_apply.rb index 9f313b790..8f7081875 100644 --- a/plugins/provisioners/chef/config/chef_apply.rb +++ b/plugins/provisioners/chef/config/chef_apply.rb @@ -24,11 +24,7 @@ module VagrantPlugins super @recipe = nil if @recipe == UNSET_VALUE - - if @upload_path == UNSET_VALUE - counter = self.class.get_and_update_counter(:chef_apply) - @upload_path = "/tmp/vagrant-chef-apply-#{counter}" - end + @upload_path = "/tmp/vagrant-chef-apply" if @upload_path == UNSET_VALUE end def validate(machine) diff --git a/plugins/provisioners/chef/plugin.rb b/plugins/provisioners/chef/plugin.rb index b2fb5cef5..5a1b2876f 100644 --- a/plugins/provisioners/chef/plugin.rb +++ b/plugins/provisioners/chef/plugin.rb @@ -10,7 +10,7 @@ module VagrantPlugins name "chef" description <<-DESC 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 config(:chef_apply, :provisioner) do @@ -67,6 +67,17 @@ module VagrantPlugins require_relative "cap/redhat/chef_install" Cap::Redhat::ChefInstall 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 diff --git a/plugins/provisioners/chef/provisioner/chef_apply.rb b/plugins/provisioners/chef/provisioner/chef_apply.rb index ed857c3b3..1ff4790b6 100644 --- a/plugins/provisioners/chef/provisioner/chef_apply.rb +++ b/plugins/provisioners/chef/provisioner/chef_apply.rb @@ -1,3 +1,4 @@ +require "digest/md5" require "tempfile" require_relative "base" @@ -42,7 +43,8 @@ module VagrantPlugins # The destination (on the guest) where the recipe will live # @return [String] 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 # Write the raw recipe contents to a tempfile and upload that to the diff --git a/plugins/provisioners/chef/provisioner/chef_solo.rb b/plugins/provisioners/chef/provisioner/chef_solo.rb index d05794f18..18bdc9e1d 100644 --- a/plugins/provisioners/chef/provisioner/chef_solo.rb +++ b/plugins/provisioners/chef/provisioner/chef_solo.rb @@ -1,3 +1,7 @@ +require "digest/md5" +require "securerandom" +require "set" + require "log4r" require "vagrant/util/counter" @@ -11,6 +15,8 @@ module VagrantPlugins class ChefSolo < Base extend Vagrant::Util::Counter include Vagrant::Util::Counter + include Vagrant::Action::Builtin::MixinSyncedFolders + attr_reader :environments_folders attr_reader :cookbook_folders attr_reader :role_folders @@ -28,13 +34,14 @@ module VagrantPlugins @data_bags_folders = expanded_folders(@config.data_bags_path, "data_bags") @environments_folders = expanded_folders(@config.environments_path, "environments") - share_folders(root_config, "csc", @cookbook_folders) - share_folders(root_config, "csr", @role_folders) - share_folders(root_config, "csdb", @data_bags_folders) - share_folders(root_config, "cse", @environments_folders) + existing = synced_folders(@machine, cached: true) + share_folders(root_config, "csc", @cookbook_folders, existing) + share_folders(root_config, "csr", @role_folders, existing) + share_folders(root_config, "csdb", @data_bags_folders, existing) + share_folders(root_config, "cse", @environments_folders, existing) end - def provision + def provision(mode = :solo) install_chef # Verify that the proper shared folders exist. check = [] @@ -51,7 +58,7 @@ module VagrantPlugins upload_encrypted_data_bag_secret setup_json setup_solo_config - run_chef_solo + run_chef(mode) delete_encrypted_data_bag_secret end @@ -72,8 +79,10 @@ module VagrantPlugins local_path = File.expand_path(path, @machine.env.root_path) if File.exist?(local_path) - # Path exists on the host, setup the remote path - remote_path = "#{@config.provisioning_path}/chef-solo-#{get_and_update_counter(:cookbooks_path)}" + # Path exists on the host, setup the remote path. We use + # the MD5 of the local path so that it is predictable. + key = Digest::MD5.hexdigest(local_path) + remote_path = "#{@config.provisioning_path}/#{key}" else @machine.ui.warn(I18n.t("vagrant.provisioners.chef.cookbook_folder_not_found_warning", path: local_path.to_s)) @@ -103,16 +112,31 @@ module VagrantPlugins # Shares the given folders with the given prefix. The folders should # be of the structure resulting from the `expanded_folders` function. - def share_folders(root_config, prefix, folders) - folders.each do |type, local_path, remote_path| - if type == :host - 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) + def share_folders(root_config, prefix, folders, existing=nil) + existing_set = Set.new + (existing || []).each do |_, fs| + fs.each do |id, data| + existing_set.add(data[:guestpath]) 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 end @@ -130,7 +154,7 @@ module VagrantPlugins } end - def run_chef_solo + def run_chef(mode) if @config.run_list && @config.run_list.empty? @machine.ui.warn(I18n.t("vagrant.chef_run_list_empty")) end @@ -143,9 +167,9 @@ module VagrantPlugins @config.attempts.times do |attempt| if attempt == 0 - @machine.ui.info I18n.t("vagrant.provisioners.chef.running_solo") + @machine.ui.info I18n.t("vagrant.provisioners.chef.running_#{mode}") else - @machine.ui.info I18n.t("vagrant.provisioners.chef.running_solo_again") + @machine.ui.info I18n.t("vagrant.provisioners.chef.running_#{mode}_again") end opts = { error_check: false, elevated: true } diff --git a/plugins/provisioners/chef/provisioner/chef_zero.rb b/plugins/provisioners/chef/provisioner/chef_zero.rb index 8ccae6130..f634bc9a7 100644 --- a/plugins/provisioners/chef/provisioner/chef_zero.rb +++ b/plugins/provisioners/chef/provisioner/chef_zero.rb @@ -22,6 +22,10 @@ module VagrantPlugins share_folders(root_config, "csn", @node_folders) end + def provision + super(:zero) + end + def solo_config super.merge( local_mode: true, diff --git a/plugins/provisioners/docker/cap/debian/docker_install.rb b/plugins/provisioners/docker/cap/debian/docker_install.rb index 5db0f12ba..4e4a2ae6e 100644 --- a/plugins/provisioners/docker/cap/debian/docker_install.rb +++ b/plugins/provisioners/docker/cap/debian/docker_install.rb @@ -14,8 +14,8 @@ module VagrantPlugins end comm.sudo("apt-get update -y") comm.sudo("apt-get install -y --force-yes -q curl") - comm.sudo("curl -sSL https://get.docker.io/gpg | apt-key add -") - comm.sudo("echo deb http://get.docker.io/ubuntu docker main > /etc/apt/sources.list.d/docker.list") + comm.sudo("curl -sSL https://get.docker.com/gpg | apt-key add -") + 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("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'") diff --git a/plugins/provisioners/docker/config.rb b/plugins/provisioners/docker/config.rb index c96e97305..7e6c37787 100644 --- a/plugins/provisioners/docker/config.rb +++ b/plugins/provisioners/docker/config.rb @@ -70,8 +70,8 @@ module VagrantPlugins @__containers.each do |name, params| params[:image] ||= name - params[:auto_assign_name] = true if !params.has_key?(:auto_assign_name) - params[:daemonize] = true if !params.has_key?(:daemonize) + params[:auto_assign_name] = true if !params.key?(:auto_assign_name) + params[:daemonize] = true if !params.key?(:daemonize) end end end diff --git a/plugins/provisioners/puppet/config/puppet.rb b/plugins/provisioners/puppet/config/puppet.rb index 3117f9f6f..1810b989b 100644 --- a/plugins/provisioners/puppet/config/puppet.rb +++ b/plugins/provisioners/puppet/config/puppet.rb @@ -1,11 +1,7 @@ -require "vagrant/util/counter" - module VagrantPlugins module Puppet module Config class Puppet < Vagrant.plugin("2", :config) - extend Vagrant::Util::Counter - attr_accessor :facter attr_accessor :hiera_config_path attr_accessor :manifest_file @@ -65,15 +61,8 @@ module VagrantPlugins @manifest_file = "default.pp" if @manifest_file == UNSET_VALUE @module_path = nil if @module_path == 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 - - # 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 # Returns the module paths as an array of paths expanded relative to the diff --git a/plugins/provisioners/puppet/provisioner/puppet.rb b/plugins/provisioners/puppet/provisioner/puppet.rb index 62c32efa2..c1e01c966 100644 --- a/plugins/provisioners/puppet/provisioner/puppet.rb +++ b/plugins/provisioners/puppet/provisioner/puppet.rb @@ -1,3 +1,5 @@ +require "digest/md5" + require "log4r" module VagrantPlugins @@ -22,8 +24,9 @@ module VagrantPlugins # Setup the module paths @module_paths = [] - @expanded_module_paths.each_with_index do |path, i| - @module_paths << [path, File.join(config.temp_dir, "modules-#{i}")] + @expanded_module_paths.each_with_index do |path, _| + key = Digest::MD5.hexdigest(path.to_s) + @module_paths << [path, File.join(config.temp_dir, "modules-#{key}")] end folder_opts = {} @@ -85,7 +88,8 @@ module VagrantPlugins def manifests_guest_path if config.manifests_path[0] == :host # 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 # The path is on the VM, so just point directly to it config.manifests_path[1] diff --git a/plugins/pushes/atlas/push.rb b/plugins/pushes/atlas/push.rb index 24a6d28b0..8a892fa2c 100644 --- a/plugins/pushes/atlas/push.rb +++ b/plugins/pushes/atlas/push.rb @@ -23,6 +23,7 @@ module VagrantPlugins # if we're on a system that doesn't support exec, so handle that properly. def execute(uploader) cmd = [] + cmd << "-debug" if !Vagrant.log_level.nil? cmd << "-vcs" if config.vcs cmd += config.includes.map { |v| ["-include", v] } cmd += config.excludes.map { |v| ["-exclude", v] } diff --git a/plugins/pushes/ftp/adapter.rb b/plugins/pushes/ftp/adapter.rb index f370d411f..8a9414376 100644 --- a/plugins/pushes/ftp/adapter.rb +++ b/plugins/pushes/ftp/adapter.rb @@ -1,3 +1,5 @@ +require "pathname" + module VagrantPlugins module FTPPush class Adapter @@ -50,7 +52,7 @@ module VagrantPlugins end def default_port - 20 + 21 end def connect(&block) @@ -67,16 +69,25 @@ module VagrantPlugins end 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 - if !@server.list("/").any? { |f| f.start_with?(parent) } - @server.mkdir(parent) + # Create the parent directories if they does not exist (naive mkdir -p) + fullpath.descend do |path| + if @server.list(path.to_s).empty? + @server.mkdir(path.to_s) + end end # Upload the file @server.putbinaryfile(local, remote) end + + private + + def pwd + @pwd ||= @server.pwd + end end # diff --git a/plugins/pushes/ftp/push.rb b/plugins/pushes/ftp/push.rb index 3cf4169a0..7a69c4f02 100644 --- a/plugins/pushes/ftp/push.rb +++ b/plugins/pushes/ftp/push.rb @@ -7,6 +7,12 @@ module VagrantPlugins module FTPPush class Push < Vagrant.plugin("2", :push) 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 # 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| relative_path = relative_path_for(file, config.dir) destination = File.expand_path(File.join(config.destination, relative_path)) + file = File.expand_path(file, env.root_path) [file, destination] end] + ftp = "#{config.username}@#{config.host}:#{config.destination}" + env.ui.info "Uploading #{env.root_path} to #{ftp}" + connect do |ftp| files.each do |local, remote| + @logger.info "Uploading #{local} => #{remote}" ftp.upload(local, remote) end end @@ -33,16 +44,6 @@ module VagrantPlugins ftp.connect(&block) 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 # only returns **files**, not folders or symlinks! # @return [Array] @@ -72,7 +73,10 @@ module VagrantPlugins # @param [Array] excludes # the exclude patterns or files 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| basename = relative_path_for(file, config.dir) diff --git a/plugins/synced_folders/nfs/synced_folder.rb b/plugins/synced_folders/nfs/synced_folder.rb index f2cdbd0dd..7cf51aabe 100644 --- a/plugins/synced_folders/nfs/synced_folder.rb +++ b/plugins/synced_folders/nfs/synced_folder.rb @@ -64,7 +64,7 @@ module VagrantPlugins export_folders = folders.dup export_folders.keys.each do |id| opts = export_folders[id] - if opts.has_key?(:nfs_export) && !opts[:nfs_export] + if opts.key?(:nfs_export) && !opts[:nfs_export] export_folders.delete(id) end end @@ -117,7 +117,7 @@ module VagrantPlugins def prepare_folder(machine, opts) opts[:map_uid] = prepare_permission(machine, :uid, opts) opts[:map_gid] = prepare_permission(machine, :gid, opts) - opts[:nfs_udp] = true if !opts.has_key?(:nfs_udp) + opts[:nfs_udp] = true if !opts.key?(:nfs_udp) opts[:nfs_version] ||= 3 # We use a CRC32 to generate a 32-bit checksum so that the @@ -128,11 +128,11 @@ module VagrantPlugins # Prepares the UID/GID settings for a single folder. def prepare_permission(machine, perm, opts) key = "map_#{perm}".to_sym - return nil if opts.has_key?(key) && opts[key].nil? + return nil if opts.key?(key) && opts[key].nil? # The options on the hash get priority, then the default # values - value = opts.has_key?(key) ? opts[key] : machine.config.nfs.send(key) + value = opts.key?(key) ? opts[key] : machine.config.nfs.send(key) return value if value != :auto # Get UID/GID from folder if we've made it this far diff --git a/plugins/synced_folders/rsync/command/rsync_auto.rb b/plugins/synced_folders/rsync/command/rsync_auto.rb index 802fb6e58..b2a4adc0b 100644 --- a/plugins/synced_folders/rsync/command/rsync_auto.rb +++ b/plugins/synced_folders/rsync/command/rsync_auto.rb @@ -83,7 +83,7 @@ module VagrantPlugins folders.each do |id, folder_opts| # If we marked this folder to not auto sync, then # don't do it. - next if folder_opts.has_key?(:auto) && !folder_opts[:auto] + next if folder_opts.key?(:auto) && !folder_opts[:auto] hostpath = folder_opts[:hostpath] hostpath = File.expand_path(hostpath, machine.env.root_path) diff --git a/templates/locales/en.yml b/templates/locales/en.yml index 3b60c1c76..155cd77dc 100644 --- a/templates/locales/en.yml +++ b/templates/locales/en.yml @@ -144,7 +144,7 @@ en: inserting_random_key: |- Inserting generated public key within guest... inserting_remove_key: |- - Removing insecure key from the guest if its present... + Removing insecure key from the guest if it's present... list_commands: |- Below is a listing of all available Vagrant commands and a brief description of what they do. @@ -1809,6 +1809,8 @@ en: running_apply: "Running chef-apply..." running_solo: "Running chef-solo..." running_solo_again: "Running chef-solo again (failed to converge)..." + running_zero: "Running chef-zero..." + running_zero_again: "Running chef-zero again (failed to converge)..." missing_shared_folders: |- Shared folders that Chef requires are missing on the virtual machine. This is usually due to configuration changing after already booting the diff --git a/test/unit/plugins/commands/login/command_test.rb b/test/unit/plugins/commands/login/command_test.rb new file mode 100644 index 000000000..c92c51174 --- /dev/null +++ b/test/unit/plugins/commands/login/command_test.rb @@ -0,0 +1,96 @@ +require File.expand_path("../../../../base", __FILE__) + +require Vagrant.source_root.join("plugins/commands/login/command") + +describe VagrantPlugins::LoginCommand::Command do + include_context "unit" + + let(:env) { isolated_environment.create_vagrant_env } + + let(:token_path) { env.data_dir.join("vagrant_login_token") } + + let(:stdout) { StringIO.new } + let(:stderr) { StringIO.new } + + subject { described_class.new(argv, env) } + + before do + stub_env("ATLAS_TOKEN" => "") + end + + describe "#execute" do + context "with no args" do + let(:argv) { [] } + end + + context "with --check" do + let(:argv) { ["--check"] } + + context "when there is a token" do + before do + stub_request(:get, %r{^#{Vagrant.server_url}/api/v1/authenticate}) + .to_return(status: 200) + end + + before do + File.open(token_path, "w+") { |f| f.write("abcd1234") } + end + + it "returns 0" do + expect(subject.execute).to eq(0) + end + end + + context "when there is no token" do + it "returns 1" do + expect(subject.execute).to eq(1) + end + end + end + + context "with --logout" do + let(:argv) { ["--logout"] } + + it "returns 0" do + expect(subject.execute).to eq(0) + end + + it "clears the token" do + subject.execute + expect(File.exist?(token_path)).to be(false) + end + end + + context "with --token" do + let(:argv) { ["--token", "efgh5678"] } + + context "when the token is valid" do + before do + stub_request(:get, %r{^#{Vagrant.server_url}/api/v1/authenticate}) + .to_return(status: 200) + end + + it "sets the token" do + subject.execute + token = File.read(token_path).strip + expect(token).to eq("efgh5678") + end + + it "returns 0" do + expect(subject.execute).to eq(0) + end + end + + context "when the token is invalid" do + before do + stub_request(:get, %r{^#{Vagrant.server_url}/api/v1/authenticate}) + .to_return(status: 401) + end + + it "returns 1" do + expect(subject.execute).to eq(1) + end + end + end + end +end diff --git a/test/unit/plugins/commands/push/command_test.rb b/test/unit/plugins/commands/push/command_test.rb index 06995d51d..a97f4caba 100644 --- a/test/unit/plugins/commands/push/command_test.rb +++ b/test/unit/plugins/commands/push/command_test.rb @@ -6,11 +6,14 @@ describe VagrantPlugins::CommandPush::Command do include_context "unit" include_context "command plugin helpers" + let(:iso_env) { isolated_environment } let(:env) do - isolated_environment.tap do |env| - env.vagrantfile("") - env.create_vagrant_env - end + iso_env.vagrantfile(<<-VF) + Vagrant.configure("2") do |config| + config.vm.box = "hashicorp/precise64" + end + VF + iso_env.create_vagrant_env end let(:argv) { [] } @@ -39,6 +42,26 @@ describe VagrantPlugins::CommandPush::Command do expect(env).to receive(:push).once subject.execute end + + it "validates the configuration" do + iso_env.vagrantfile <<-EOH + Vagrant.configure("2") do |config| + config.vm.box = "hashicorp/precise64" + + config.push.define "noop" do |push| + push.bad = "ham" + end + end + EOH + + subject = described_class.new(argv, iso_env.create_vagrant_env) + allow(subject).to receive(:validate_pushes!) + .and_return(:noop) + + expect { subject.execute }.to raise_error(Vagrant::Errors::ConfigInvalid) { |err| + expect(err.message).to include("The following settings shouldn't exist: bad") + } + end end describe "#validate_pushes!" do diff --git a/test/unit/plugins/providers/hyperv/config_test.rb b/test/unit/plugins/providers/hyperv/config_test.rb index 5177dca59..a3c46c619 100644 --- a/test/unit/plugins/providers/hyperv/config_test.rb +++ b/test/unit/plugins/providers/hyperv/config_test.rb @@ -9,10 +9,37 @@ describe VagrantPlugins::HyperV::Config do subject.finalize! expect(subject.ip_address_timeout).to eq(180) end - it "defaults to a number" do subject.finalize! expect(subject.ip_address_timeout).to eq(120) end end + describe "#vmname" do + it "can be set" do + subject.vmname = "test" + subject.finalize! + expect(subject.vmname).to eq("test") + end + end + describe "#memory" do + it "can be set" do + subject.memory = 512 + subject.finalize! + expect(subject.memory).to eq(512) + end + end + describe "#maxmemory" do + it "can be set" do + subject.maxmemory = 1024 + subject.finalize! + expect(subject.maxmemory).to eq(1024) + end + end + describe "#cpus" do + it "can be set" do + subject.cpus = 2 + subject.finalize! + expect(subject.cpus).to eq(2) + end + end end diff --git a/test/unit/plugins/provisioners/ansible/provisioner_test.rb b/test/unit/plugins/provisioners/ansible/provisioner_test.rb index 756f95769..05fa8fae3 100644 --- a/test/unit/plugins/provisioners/ansible/provisioner_test.rb +++ b/test/unit/plugins/provisioners/ansible/provisioner_test.rb @@ -50,6 +50,7 @@ VF let(:generated_inventory_file) { File.join(generated_inventory_dir, 'vagrant_ansible_inventory') } before do + Vagrant::Util::Platform.stub(solaris?: false) subject.instance_variable_get(:@logger).stub(:debug?).and_return(false) machine.stub(ssh_info: ssh_info) @@ -63,7 +64,7 @@ VF # def self.it_should_set_arguments_and_environment_variables( - expected_args_count = 6, expected_vars_count = 4, expected_host_key_checking = false, expected_transport_mode = "ssh") + expected_args_count = 7, expected_vars_count = 4, expected_host_key_checking = false, expected_transport_mode = "ssh") it "sets implicit arguments in a specific order" do expect(Vagrant::Util::Subprocess).to receive(:execute).with { |*args| @@ -72,6 +73,7 @@ VF expect(args[1]).to eq("--private-key=#{machine.ssh_info[:private_key_path][0]}") expect(args[2]).to eq("--user=#{machine.ssh_info[:username]}") expect(args[3]).to eq("--connection=ssh") + expect(args[4]).to eq("--timeout=30") inventory_count = args.count { |x| x =~ /^--inventory-file=.+$/ } expect(inventory_count).to be > 0 @@ -103,10 +105,11 @@ VF cmd_opts = args.last if expected_host_key_checking - expect(cmd_opts[:env]['ANSIBLE_SSH_ARGS']).to be_nil unless config.raw_arguments + expect(cmd_opts[:env]['ANSIBLE_SSH_ARGS']).to_not include("-o UserKnownHostsFile=/dev/null") else expect(cmd_opts[:env]['ANSIBLE_SSH_ARGS']).to include("-o UserKnownHostsFile=/dev/null") end + expect(cmd_opts[:env]['ANSIBLE_SSH_ARGS']).to include("-o IdentitiesOnly=yes") expect(cmd_opts[:env]['ANSIBLE_FORCE_COLOR']).to eql("true") expect(cmd_opts[:env]['ANSIBLE_HOST_KEY_CHECKING']).to eql(expected_host_key_checking.to_s) expect(cmd_opts[:env]['PYTHONUNBUFFERED']).to eql(1) @@ -270,7 +273,7 @@ VF config.host_key_checking = true end - it_should_set_arguments_and_environment_variables 6, 3, true + it_should_set_arguments_and_environment_variables 7, 4, true end describe "with boolean (flag) options disabled" do @@ -282,7 +285,7 @@ VF config.sudo_user = 'root' end - it_should_set_arguments_and_environment_variables 7 + it_should_set_arguments_and_environment_variables 8 it_should_set_optional_arguments({ "sudo_user" => "--sudo-user=root" }) it "it does not set boolean flag when corresponding option is set to false" do @@ -311,7 +314,7 @@ VF "--new-arg=yeah"] end - it_should_set_arguments_and_environment_variables 17, 4, false, "paramiko" + it_should_set_arguments_and_environment_variables 18, 4, false, "paramiko" it "sets all raw arguments" do expect(Vagrant::Util::Subprocess).to receive(:execute).with { |*args| @@ -367,7 +370,7 @@ VF config.ask_vault_pass = true end - it_should_set_arguments_and_environment_variables 7 + it_should_set_arguments_and_environment_variables 8 it "should ask the vault password" do expect(Vagrant::Util::Subprocess).to receive(:execute).with { |*args| @@ -381,7 +384,7 @@ VF config.vault_password_file = existing_file end - it_should_set_arguments_and_environment_variables 7 + it_should_set_arguments_and_environment_variables 8 it "uses the given vault password file" do expect(Vagrant::Util::Subprocess).to receive(:execute).with { |*args| @@ -395,7 +398,7 @@ VF config.raw_ssh_args = ['-o ControlMaster=no', '-o ForwardAgent=no'] end - it_should_set_arguments_and_environment_variables 6, 4 + it_should_set_arguments_and_environment_variables 7, 4 it_should_explicitly_enable_ansible_ssh_control_persist_defaults it "passes custom SSH options via ANSIBLE_SSH_ARGS with the highest priority" do @@ -429,7 +432,7 @@ VF ssh_info[:private_key_path] = ['/path/to/my/key', '/an/other/identity', '/yet/an/other/key'] end - it_should_set_arguments_and_environment_variables 6, 4 + it_should_set_arguments_and_environment_variables 7, 4 it_should_explicitly_enable_ansible_ssh_control_persist_defaults it "passes additional Identity Files via ANSIBLE_SSH_ARGS" do @@ -446,7 +449,7 @@ VF ssh_info[:forward_agent] = true end - it_should_set_arguments_and_environment_variables 6, 4 + it_should_set_arguments_and_environment_variables 7, 4 it_should_explicitly_enable_ansible_ssh_control_persist_defaults it "enables SSH-Forwarding via ANSIBLE_SSH_ARGS" do @@ -465,7 +468,7 @@ VF it "shows the ansible-playbook command" do expect(machine.env.ui).to receive(:detail).with { |full_command| - expect(full_command).to eq("PYTHONUNBUFFERED=1 ANSIBLE_FORCE_COLOR=true ANSIBLE_HOST_KEY_CHECKING=false ANSIBLE_SSH_ARGS='-o UserKnownHostsFile=/dev/null -o ControlMaster=auto -o ControlPersist=60s' ansible-playbook --private-key=/path/to/my/key --user=testuser --connection=ssh --limit='machine1' --inventory-file=#{generated_inventory_dir} playbook.yml") + expect(full_command).to eq("PYTHONUNBUFFERED=1 ANSIBLE_FORCE_COLOR=true ANSIBLE_HOST_KEY_CHECKING=false ANSIBLE_SSH_ARGS='-o UserKnownHostsFile=/dev/null -o IdentitiesOnly=yes -o ControlMaster=auto -o ControlPersist=60s' ansible-playbook --private-key=/path/to/my/key --user=testuser --connection=ssh --timeout=30 --limit='machine1' --inventory-file=#{generated_inventory_dir} playbook.yml") } end end @@ -475,12 +478,12 @@ VF config.verbose = 'v' end - it_should_set_arguments_and_environment_variables 7 + it_should_set_arguments_and_environment_variables 8 it_should_set_optional_arguments({ "verbose" => "-v" }) it "shows the ansible-playbook command" do expect(machine.env.ui).to receive(:detail).with { |full_command| - expect(full_command).to eq("PYTHONUNBUFFERED=1 ANSIBLE_FORCE_COLOR=true ANSIBLE_HOST_KEY_CHECKING=false ANSIBLE_SSH_ARGS='-o UserKnownHostsFile=/dev/null -o ControlMaster=auto -o ControlPersist=60s' ansible-playbook --private-key=/path/to/my/key --user=testuser --connection=ssh --limit='machine1' --inventory-file=#{generated_inventory_dir} -v playbook.yml") + expect(full_command).to eq("PYTHONUNBUFFERED=1 ANSIBLE_FORCE_COLOR=true ANSIBLE_HOST_KEY_CHECKING=false ANSIBLE_SSH_ARGS='-o UserKnownHostsFile=/dev/null -o IdentitiesOnly=yes -o ControlMaster=auto -o ControlPersist=60s' ansible-playbook --private-key=/path/to/my/key --user=testuser --connection=ssh --timeout=30 --limit='machine1' --inventory-file=#{generated_inventory_dir} -v playbook.yml") } end end @@ -513,7 +516,7 @@ VF config.raw_ssh_args = ['-o ControlMaster=no'] end - it_should_set_arguments_and_environment_variables 20, 4, true + it_should_set_arguments_and_environment_variables 21, 4, true it_should_explicitly_enable_ansible_ssh_control_persist_defaults it_should_set_optional_arguments({ "extra_vars" => "--extra-vars=@#{File.expand_path(__FILE__)}", "sudo" => "--sudo", @@ -538,10 +541,84 @@ VF it "shows the ansible-playbook command, with additional quotes when required" do expect(machine.env.ui).to receive(:detail).with { |full_command| - expect(full_command).to eq("PYTHONUNBUFFERED=1 ANSIBLE_FORCE_COLOR=true ANSIBLE_HOST_KEY_CHECKING=true ANSIBLE_SSH_ARGS='-o IdentityFile=/my/key2 -o ForwardAgent=yes -o ControlMaster=no -o ControlMaster=auto -o ControlPersist=60s' ansible-playbook --private-key=/my/key1 --user=testuser --connection=ssh --limit='machine*:&vagrant:!that_one' --inventory-file=#{generated_inventory_dir} --extra-vars=@#{File.expand_path(__FILE__)} --sudo --sudo-user=deployer -vvv --ask-sudo-pass --ask-vault-pass --vault-password-file=#{File.expand_path(__FILE__)} --tags=db,www --skip-tags=foo,bar --start-at-task='an awesome task' --why-not --su-user=foot --ask-su-pass --limit='all' playbook.yml") + expect(full_command).to eq("PYTHONUNBUFFERED=1 ANSIBLE_FORCE_COLOR=true ANSIBLE_HOST_KEY_CHECKING=true ANSIBLE_SSH_ARGS='-o IdentitiesOnly=yes -o IdentityFile=/my/key2 -o ForwardAgent=yes -o ControlMaster=no -o ControlMaster=auto -o ControlPersist=60s' ansible-playbook --private-key=/my/key1 --user=testuser --connection=ssh --timeout=30 --limit='machine*:&vagrant:!that_one' --inventory-file=#{generated_inventory_dir} --extra-vars=@#{File.expand_path(__FILE__)} --sudo --sudo-user=deployer -vvv --ask-sudo-pass --ask-vault-pass --vault-password-file=#{File.expand_path(__FILE__)} --tags=db,www --skip-tags=foo,bar --start-at-task='an awesome task' --why-not --su-user=foot --ask-su-pass --limit='all' playbook.yml") } end end + # + # Special cases related to the VM provider context + # + + context "with Docker provider on a non-Linux host" do + + let(:fake_host_ssh_info) {{ + private_key_path: ['/path/to/docker/host/key'], + username: 'boot9docker', + host: '127.0.0.1', + port: 2299 + }} + let(:fake_host_vm) { + double("host_vm").tap do |h| + h.stub(ssh_info: fake_host_ssh_info) + end + } + + before do + machine.stub(provider_name: :docker) + machine.provider.stub(host_vm?: true) + machine.provider.stub(host_vm: fake_host_vm) + end + + it "uses an SSH ProxyCommand to reach the VM" do + expect(Vagrant::Util::Subprocess).to receive(:execute).with { |*args| + cmd_opts = args.last + expect(cmd_opts[:env]['ANSIBLE_SSH_ARGS']).to include("-o ProxyCommand='ssh boot9docker@127.0.0.1 -p 2299 -i /path/to/docker/host/key -o Compression=yes -o ConnectTimeout=5 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no exec nc %h %p 2>/dev/null'") + } + end + end + + # + # Special cases related to the Vagrant Host operating system in use + # + + context "with a Solaris-like host" do + before do + Vagrant::Util::Platform.stub(solaris?: true) + end + + it "does not set IdentitiesOnly=yes in ANSIBLE_SSH_ARGS" do + expect(Vagrant::Util::Subprocess).to receive(:execute).with { |*args| + cmd_opts = args.last + expect(cmd_opts[:env]['ANSIBLE_SSH_ARGS']).to_not include("-o IdentitiesOnly=yes") + + # Note: + # The expectation below is a workaround to a possible misuse (or bug) in RSpec/Ruby stack. + # If 'args' variable is not required by in this block, the "Vagrant::Util::Subprocess).to receive" + # surprisingly expects to receive "no args". + # This problem can be "solved" by using args the "unnecessary" (but harmless) expectation below: + expect(true).to be_true + } + end + + describe "and with host_key_checking option enabled" do + it "does not set ANSIBLE_SSH_ARGS environment variable" do + config.host_key_checking = true + + expect(Vagrant::Util::Subprocess).to receive(:execute).with { |*args| + cmd_opts = args.last + expect(cmd_opts[:env]).to_not include('ANSIBLE_SSH_ARGS') + + # Note: + # The expectation below is a workaround to a possible misuse (or bug) in RSpec/Ruby stack. + # If 'args' variable is not required by in this block, the "Vagrant::Util::Subprocess).to receive" + # surprisingly expects to receive "no args". + # This problem can be "solved" by using args the "unnecessary" (but harmless) expectation below: + expect(true).to be_true + } + end + end + + end end end diff --git a/test/unit/plugins/provisioners/chef/config/base_runner_test.rb b/test/unit/plugins/provisioners/chef/config/base_runner_test.rb index 591ec743e..330c31616 100644 --- a/test/unit/plugins/provisioners/chef/config/base_runner_test.rb +++ b/test/unit/plugins/provisioners/chef/config/base_runner_test.rb @@ -123,7 +123,7 @@ describe VagrantPlugins::Chef::Config::BaseRunner do describe "#provisioning_path" do it "defaults to a tmp_path" do subject.finalize! - expect(subject.provisioning_path).to match(%r{/tmp/vagrant-chef-\d+}) + expect(subject.provisioning_path).to eq("/tmp/vagrant-chef") end end diff --git a/test/unit/plugins/provisioners/chef/config/chef_apply_test.rb b/test/unit/plugins/provisioners/chef/config/chef_apply_test.rb index 242eda7ad..135c04213 100644 --- a/test/unit/plugins/provisioners/chef/config/chef_apply_test.rb +++ b/test/unit/plugins/provisioners/chef/config/chef_apply_test.rb @@ -23,7 +23,7 @@ describe VagrantPlugins::Chef::Config::ChefApply do describe "#upload_path" do it "defaults to /tmp/vagrant-chef-apply.rb" do subject.finalize! - expect(subject.upload_path).to match(%r{/tmp/vagrant-chef-apply-\d+}) + expect(subject.upload_path).to eq("/tmp/vagrant-chef-apply") end end diff --git a/test/unit/plugins/provisioners/chef/omnibus_test.rb b/test/unit/plugins/provisioners/chef/omnibus_test.rb index 3242be290..b053f94bc 100644 --- a/test/unit/plugins/provisioners/chef/omnibus_test.rb +++ b/test/unit/plugins/provisioners/chef/omnibus_test.rb @@ -2,7 +2,7 @@ require_relative "../../../base" require Vagrant.source_root.join("plugins/provisioners/chef/omnibus") -describe VagrantPlugins::Chef::Omnibus, :focus do +describe VagrantPlugins::Chef::Omnibus do let(:prefix) { "curl -sL #{described_class.const_get(:OMNITRUCK)}" } let(:version) { :latest } diff --git a/test/unit/plugins/pushes/ftp/adapter_test.rb b/test/unit/plugins/pushes/ftp/adapter_test.rb index 54bacc1d1..e929078cd 100644 --- a/test/unit/plugins/pushes/ftp/adapter_test.rb +++ b/test/unit/plugins/pushes/ftp/adapter_test.rb @@ -54,8 +54,8 @@ describe VagrantPlugins::FTPPush::FTPAdapter do end describe "#default_port" do - it "is 20" do - expect(subject.default_port).to eq(20) + it "is 21" do + expect(subject.default_port).to eq(21) end end diff --git a/test/unit/plugins/pushes/ftp/push_test.rb b/test/unit/plugins/pushes/ftp/push_test.rb index 5b5ec7c10..1f6773e24 100644 --- a/test/unit/plugins/pushes/ftp/push_test.rb +++ b/test/unit/plugins/pushes/ftp/push_test.rb @@ -17,9 +17,21 @@ describe VagrantPlugins::FTPPush::Push do destination: "/var/www/site", ) end + let(:ui) do + double("ui", + info: nil, + ) + end subject { described_class.new(env, config) } + before do + allow(env).to receive(:root_path) + .and_return(File.expand_path("..", __FILE__)) + allow(env).to receive(:ui) + .and_return(ui) + end + describe "#push" do before(:all) do @server = FakeFtp::Server.new(51234, 21213) @@ -93,34 +105,6 @@ describe VagrantPlugins::FTPPush::Push do end end - describe "#parse_host" do - let(:result) { subject.parse_host(host) } - - context "when no port is given" do - let(:host) { "127.0.0.1" } - - it "returns the url and port 22" do - expect(result).to eq(["127.0.0.1", "22"]) - end - end - - context "when a port is given" do - let(:host) { "127.0.0.1:23456" } - - it "returns the url and port 23456" do - expect(result).to eq(["127.0.0.1", "23456"]) - end - end - - context "when more than more port is given" do - let(:host) { "127.0.0.1:22:33:44" } - - it "returns the url and everything after" do - expect(result).to eq(["127.0.0.1", "22:33:44"]) - end - end - end - describe "#all_files" do before(:all) do @dir = Dir.mktmpdir diff --git a/test/unit/vagrant/action/warden_test.rb b/test/unit/vagrant/action/warden_test.rb index b9758be7a..9c668e371 100644 --- a/test/unit/vagrant/action/warden_test.rb +++ b/test/unit/vagrant/action/warden_test.rb @@ -87,6 +87,6 @@ describe Vagrant::Action::Warden do expect { instance.call(data) }.to raise_error(SystemExit) # The recover should not have been called - expect(data.has_key?(:recover)).not_to be + expect(data.key?(:recover)).not_to be end end diff --git a/test/unit/vagrant/environment_test.rb b/test/unit/vagrant/environment_test.rb index 02effd7db..c5cf8370d 100644 --- a/test/unit/vagrant/environment_test.rb +++ b/test/unit/vagrant/environment_test.rb @@ -991,7 +991,7 @@ VF end def push - !!self.class.class_variable_set(:@@pushed, true) + self.class.class_variable_set(:@@pushed, true) end end end diff --git a/test/unit/vagrant/machine_test.rb b/test/unit/vagrant/machine_test.rb index 128df3d6f..5da1be84f 100644 --- a/test/unit/vagrant/machine_test.rb +++ b/test/unit/vagrant/machine_test.rb @@ -263,6 +263,17 @@ describe Vagrant::Machine do expect(foo).to eq(:bar) end + it "should pass any extra options to the environment as strings" do + action_name = :up + foo = nil + callable = lambda { |env| foo = env["foo"] } + + allow(provider).to receive(:action).with(action_name).and_return(callable) + instance.action(:up, "foo" => :bar) + + expect(foo).to eq(:bar) + end + it "should return the environment as a result" do action_name = :up callable = lambda { |env| env[:result] = "FOO" } diff --git a/test/unit/vagrant/util/hash_with_indifferent_access_test.rb b/test/unit/vagrant/util/hash_with_indifferent_access_test.rb index 397773eed..fdebeb374 100644 --- a/test/unit/vagrant/util/hash_with_indifferent_access_test.rb +++ b/test/unit/vagrant/util/hash_with_indifferent_access_test.rb @@ -22,7 +22,7 @@ describe Vagrant::Util::HashWithIndifferentAccess do it "allows indifferent key lookup" do instance["foo"] = "bar" expect(instance.key?(:foo)).to be - expect(instance.has_key?(:foo)).to be + expect(instance.key?(:foo)).to be expect(instance.include?(:foo)).to be expect(instance.member?(:foo)).to be end diff --git a/test/unit/vagrant_test.rb b/test/unit/vagrant_test.rb index 613e3a98b..ec317a628 100644 --- a/test/unit/vagrant_test.rb +++ b/test/unit/vagrant_test.rb @@ -75,7 +75,7 @@ describe Vagrant do expect(described_class.has_plugin?("bar")).to be_false end - it "finds plugins by gem version" do + it "finds plugins by gem name and version" do specs = [Gem::Specification.new] specs[0].name = "foo" specs[0].version = "1.2.3" @@ -83,6 +83,7 @@ describe Vagrant do expect(described_class.has_plugin?("foo", "~> 1.2.0")).to be_true expect(described_class.has_plugin?("foo", "~> 1.0.0")).to be_false + expect(described_class.has_plugin?("bar", "~> 1.2.0")).to be_false end end diff --git a/vagrant.gemspec b/vagrant.gemspec index 7fe457f22..3fb550b26 100644 --- a/vagrant.gemspec +++ b/vagrant.gemspec @@ -19,7 +19,7 @@ Gem::Specification.new do |s| s.add_dependency "childprocess", "~> 0.5.0" s.add_dependency "erubis", "~> 2.7.0" s.add_dependency "i18n", "~> 0.6.0" - s.add_dependency "listen", "~> 2.7.11" + s.add_dependency "listen", "~> 2.8.0" s.add_dependency "hashicorp-checkpoint", "~> 0.1.1" s.add_dependency "log4r", "~> 1.1.9", "< 1.1.11" s.add_dependency "net-ssh", ">= 2.6.6", "< 2.10.0" diff --git a/version.txt b/version.txt index 648dc5700..f8a696c8d 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -1.7.2.dev +1.7.2 diff --git a/website/docs/Gemfile.lock b/website/docs/Gemfile.lock index 7e3a024b4..cced2615a 100644 --- a/website/docs/Gemfile.lock +++ b/website/docs/Gemfile.lock @@ -23,7 +23,7 @@ GEM compass-import-once (1.0.5) sass (>= 3.2, < 3.5) daemons (1.1.9) - eventmachine (1.0.3) + eventmachine (1.0.4) execjs (1.4.1) multi_json (~> 1.0) ffi (1.9.6) diff --git a/website/docs/source/stylesheets/_base.less b/website/docs/source/stylesheets/_base.less index d78333d04..68790ad40 100644 --- a/website/docs/source/stylesheets/_base.less +++ b/website/docs/source/stylesheets/_base.less @@ -1,11 +1,11 @@ html { - font-size: 100%; - -webkit-text-size-adjust: 100%; - -ms-text-size-adjust: 100%; - text-rendering: optimizeLegibility; - -webkit-tap-highlight-color: transparent; -} + font-size: 100%; + -webkit-text-size-adjust: 100%; + -ms-text-size-adjust: 100%; + text-rendering: optimizeLegibility; + -webkit-tap-highlight-color: transparent; +} body { font-family: @sans-serif-stack; font-size: @base-font-size; @@ -14,17 +14,18 @@ body { background-color: @white; letter-spacing: 2px; .museo-sans-regular; -} +} .wrapper { -margin-top: 80px; -} + margin-top: 80px; +} .container { -z-index: 999; //keep content on top -position: relative; -} + z-index: 999; + //keep content on top + position: relative; +} h1, h2, h3, @@ -36,272 +37,298 @@ h6 { color: inherit; text-rendering: optimizelegibility; .museo-sans-bold; + } +h1 { + @font-size: 70px; + font-size: @font-size; + line-height: 80px; + letter-spacing: 3px; - h1 { - @font-size: 70px; - font-size: @font-size; - line-height: 80px; - letter-spacing: 3px; + span { + font-size: @headline-span-size; + display: block; - span { - font-size: @headline-span-size; - display: block; - } + } + &.all-caps { + text-transform: uppercase; + text-align: center; + font-size: 40px; + } - &.all-caps { - text-transform: uppercase; - text-align: center; - font-size: 40px; - } - } - - h2 { - @font-size: 30px; - font-size: @font-size; - line-height: 35px; - } - - h3 { - @font-size: 30px; - font-size: @font-size; - line-height: @font-size; - } - - h4 { - @font-size: 24px; - font-size: @font-size; - line-height: @font-size; - } - - h5 { - @font-size: 20px; - font-size: @font-size; - line-height: @font-size; - } - - h6 { - @font-size: 12px; - font-size: @font-size; - line-height: @font-size; - } - -p, td { - letter-spacing: normal; - line-height: 32px; - - a { - color: @docs-blue; - text-decoration: none; - border-bottom: 1px solid @docs-blue; - - &:hover { - text-decoration: none; - color: darken(@blue, 10%); - border-bottom: 1px solid darken(@blue, 10%); - } - } } +h2 { + @font-size: 30px; + font-size: @font-size; + line-height: 35px; +} +h3 { + @font-size: 30px; + font-size: @font-size; + line-height: @font-size; + +} +h4 { + @font-size: 24px; + font-size: @font-size; + line-height: @font-size; + +} +h5 { + @font-size: 20px; + font-size: @font-size; + line-height: @font-size; + +} +h6 { + @font-size: 12px; + font-size: @font-size; + line-height: @font-size; + +} +p, +td { + letter-spacing: normal; + line-height: 32px; + + a { + color: @docs-blue; + text-decoration: none; + border-bottom: 1px solid @docs-blue; + + &:hover { + text-decoration: none; + color: darken(@blue, 10%); + border-bottom: 1px solid darken(@blue, 10%); + } + } + +} a { - color: inherit; - text-decoration: none; + color: inherit; + text-decoration: none; + &:hover { + text-decoration: none; + color: @purple; + .animate-text-color; - &:hover { - text-decoration: none; - color: @purple; - .animate-text-color; - } + } + &:active { + color: @blue; - &:active { - color: @blue; - } + } + &:visited { - &:visited { + } - } } - ul { -} +} li { -line-height: @base-line-height; -} + line-height: @base-line-height; +} blockquote { - border: none; + border: none; margin: 60px; - p { // blockquote p - font-size: @base-font-size * 2; - line-height: @base-line-height * 2; - font-style: italic; + p { + // blockquote p + font-size: @base-font-size * 2; + line-height: @base-line-height * 2; + font-style: italic; } -} +} strong { -.museo-sans-bold; -} + .museo-sans-bold; +} em { -.museo-sans-regular-italic; -} + .museo-sans-regular-italic; +} br { -display:block; -line-height: (@baseline * 2); -} + display: block; + line-height: (@baseline * 2); +} pre, code { -font-family: @mono-stack; -} + font-family: @mono-stack; +} code { -font-size: inherit; -} + font-size: inherit; +} pre { -border: none; -font-size: @base-font-size; -background: @black; -color: @white; -padding: 20px; -line-height: @base-line-height; -margin-top: 20px; -margin-bottom: 20px; + border: none; + font-size: @base-font-size; + background: @black; + color: @white; + padding: 20px; + line-height: @base-line-height; + margin-top: 20px; + margin-bottom: 20px; + + span { + color: @code-highlight-text; + } - span { - color: @code-highlight-text; - } } - hr { -} +} .vr { -width: 2px; -height: 100%; -} + width: 2px; + height: 100%; +} form { -} +} input { -letter-spacing: 3px; + letter-spacing: 3px; - &:focus { - outline: none; - } + &:focus { + outline: none; + } } +::-webkit-input-placeholder { - ::-webkit-input-placeholder { - overflow: visible; - padding-top: 3px; - color: @light-gray-text; - } - - input:-moz-placeholder { - overflow: visible; - padding-top: 3px; - color: @light-gray-text; - } + overflow: visible; + padding-top: 3px; + color: @light-gray-text; +} +input:-moz-placeholder { + overflow: visible; + padding-top: 3px; + color: @light-gray-text; +} /* type and styles */ .meta, .legal, .date { -color: @medium-gray-text; -line-height: @base-line-height; -.museo-sans-regular; + color: @medium-gray-text; + line-height: @base-line-height; + .museo-sans-regular; + } +.date { + text-transform: uppercase; - .date { - text-transform: uppercase; - } - +} .button { -color: @white; -text-align: center; -background-color: @primary-button-color; -display: block; -padding: 15px 0; -margin-top: 20px !important; -text-transform: uppercase; -font-size: 25px; -letter-spacing: 5px; -.museo-sans-light; -.rounded; -.hover; + color: @white; + text-align: center; + background-color: @primary-button-color; + display: block; + padding: 15px 0; + margin-top: 20px !important; + text-transform: uppercase; + font-size: 25px; + letter-spacing: 5px; + .museo-sans-light; + .rounded; + .hover; - &.inline-button { - background-color: @vagrant-blue; - padding: 5px 20px; - color: @white !important; - font-size: 15px; - letter-spacing: 1px; - .rounded; + &.inline-button { + background-color: @vagrant-blue; + padding: 5px 20px; + color: @white !important; + font-size: 15px; + letter-spacing: 1px; + .rounded; + + a, + a:hover { + color: @white; + } + &.next-button, + &.prev-button { + max-width: 33%; + white-space: nowrap; + } + &.next-button { + float: right; + &:before { + content: "Next:"; + display: inline-block; + padding-right: 3px; + } + &:after { + content: "\00BB"; + display: inline-block; + padding-left: 3px; + } + + } + &.prev-button { + float: left; + &:before { + content: "\00AB\0020Previous: "; + display: inline-block; + padding-right: 3px; + } + } - a, - a:hover { - color: @white; } -} + &.white-button { + background: fade(@white, 20%); -&.white-button { - background: fade(@white, 20%); + &:hover { + background: fade(@white, 30%); + } + } + &.secondary-button { + background: @light-gray; + + &:hover { + background: @purple; + } + + } + &.with-carat span { + margin-right: -10px; + //recenter text if there's a carat after text + + } + span { + // button text styles can go here + + } &:hover { - background: fade(@white, 30%); + background-color: @purple; + .animate-background-color; + } -} + &:active { -&.secondary-button { - background: @light-gray; - &:hover { - background: @purple; } -} - -&.with-carat span { - margin-right: -10px; //recenter text if there's a carat after text + &.disabled { + background-color: @light-gray-background; + } } - -span { - // button text styles can go here -} - -&:hover { - background-color: @purple; - .animate-background-color; -} - -&:active { - -} - -&.disabled { - background-color: @light-gray-background; -} - -} - a.read-more { color: @blue; &:hover { color: darken(@blue, 10%); } -} +} // misc. styles .loading { text-align: center; @@ -310,8 +337,8 @@ a.read-more { letter-spacing: 5px; color: @medium-gray-text; padding: 30px 0 20px; -} -.pinned { - position:fixed; +} +.pinned { + position: fixed; } diff --git a/website/docs/source/v2/cli/login.html.md b/website/docs/source/v2/cli/login.html.md index c8f6ee7d9..1ff6e9c6d 100644 --- a/website/docs/source/v2/cli/login.html.md +++ b/website/docs/source/v2/cli/login.html.md @@ -19,6 +19,7 @@ boxes or [Vagrant Share](/v2/share/index.html) require a login. The reference of available command-line flags to this command is available below. + ## Options * `--check` - This will check if you're logged in. In addition to outputting @@ -28,3 +29,32 @@ is available below. * `--logout` - This will log you out if you're logged in. If you're already logged out, this command will do nothing. It is not an error to call this command if you're already logged out. + +* `--token` - This will set the Atlas login token manually to the provided + string. It is assumed this token is a valid Atlas access token. + + +## Examples + +Securely authenticate to Atlas using a username and password: + +```text +$ vagrant login +# ... +Atlas username: +Atlas password: +``` + +Check if the current user is authenticated: + +```text +$ vagrant login --check +You are already logged in. +``` + +Securely authenticate with Atlas using a token: + +```text +$ vagrant login --token ABCD1234 +The token was successfully saved. +``` diff --git a/website/docs/source/v2/docker/basics.html.md b/website/docs/source/v2/docker/basics.html.md index 6f2f41c48..9f4dd97a6 100644 --- a/website/docs/source/v2/docker/basics.html.md +++ b/website/docs/source/v2/docker/basics.html.md @@ -65,6 +65,8 @@ and networking options into Docker volumes and forwarded ports. You don't have to use the Docker-specific configurations to do this. This helps keep your Vagrantfile similar to how it has always looked. +Private and public networks are not currently supported. + ## Host VM On systems that can't run Linux containers natively, such as Mac OS X diff --git a/website/docs/source/v2/getting-started/boxes.html.md b/website/docs/source/v2/getting-started/boxes.html.md index 7ed1f83d7..9d165d2ad 100644 --- a/website/docs/source/v2/getting-started/boxes.html.md +++ b/website/docs/source/v2/getting-started/boxes.html.md @@ -72,3 +72,6 @@ feature to allow you to find the box you care about. In addition to finding free boxes, HashiCorp's Atlas lets you host your own boxes, as well as private boxes if you intend on creating boxes for your own organization. + +Project Setup +Up And SSH diff --git a/website/docs/source/v2/getting-started/index.html.md b/website/docs/source/v2/getting-started/index.html.md index 687294274..26cbae2cb 100644 --- a/website/docs/source/v2/getting-started/index.html.md +++ b/website/docs/source/v2/getting-started/index.html.md @@ -17,7 +17,7 @@ since it is free, available on every major platform, and built-in to Vagrant. After reading the guide though, don't forget that Vagrant can work with [many other providers](/v2/getting-started/providers.html). -Before diving into your first project, please [install Vagrant](/v2/installation/index.html). +Before diving into your first project, please [install the latest version of Vagrant](/v2/installation/index.html). And because we'll be using [VirtualBox](http://www.virtualbox.org) as our provider for the getting started guide, please install that as well. @@ -54,3 +54,5 @@ comfort of your own machine. The rest of this guide will walk you through setting up a more complete project, covering more features of Vagrant. + +Project Setup diff --git a/website/docs/source/v2/getting-started/networking.html.md b/website/docs/source/v2/getting-started/networking.html.md index 150b4cab1..69ac4c3fc 100644 --- a/website/docs/source/v2/getting-started/networking.html.md +++ b/website/docs/source/v2/getting-started/networking.html.md @@ -43,3 +43,6 @@ Vagrant also has other forms of networking, allowing you to assign a static IP address to the guest machine, or to bridge the guest machine onto an existing network. If you're interested in other options, read the [networking](/v2/networking/index.html) page. + +Provisioning +Share diff --git a/website/docs/source/v2/getting-started/project_setup.html.md b/website/docs/source/v2/getting-started/project_setup.html.md index e36fac01c..1a2029bd1 100644 --- a/website/docs/source/v2/getting-started/project_setup.html.md +++ b/website/docs/source/v2/getting-started/project_setup.html.md @@ -36,3 +36,6 @@ set up Vagrant for an existing project. The Vagrantfile is meant to be committed to version control with your project, if you use version control. This way, every person working with that project can benefit from Vagrant without any upfront work. + +Getting Started +Boxes diff --git a/website/docs/source/v2/getting-started/providers.html.md b/website/docs/source/v2/getting-started/providers.html.md index abda2deec..9dfd31d71 100644 --- a/website/docs/source/v2/getting-started/providers.html.md +++ b/website/docs/source/v2/getting-started/providers.html.md @@ -35,3 +35,5 @@ flags necessary. For more information on providers, read the full documentation on [providers](/v2/providers/index.html). + +Rebuild diff --git a/website/docs/source/v2/getting-started/provisioning.html.md b/website/docs/source/v2/getting-started/provisioning.html.md index ad2b24150..ceb79e82d 100644 --- a/website/docs/source/v2/getting-started/provisioning.html.md +++ b/website/docs/source/v2/getting-started/provisioning.html.md @@ -75,3 +75,6 @@ directory, which is the default synced folder setup by Vagrant. You can play around some more by creating some more files and viewing them from the terminal, but in the next step we'll cover networking options so that you can use your own browser to access the guest machine. + +Synced Folders +Networking diff --git a/website/docs/source/v2/getting-started/rebuild.html.md b/website/docs/source/v2/getting-started/rebuild.html.md index aa5a3bc40..1555ca6b5 100644 --- a/website/docs/source/v2/getting-started/rebuild.html.md +++ b/website/docs/source/v2/getting-started/rebuild.html.md @@ -15,3 +15,6 @@ $ vagrant up That's it! Since the Vagrant environment is already all configured via the Vagrantfile, you or any of your coworkers simply have to run a `vagrant up` at any time and Vagrant will recreate your work environment. + +Teardown +Providers diff --git a/website/docs/source/v2/getting-started/share.html.md b/website/docs/source/v2/getting-started/share.html.md index 694bd5d15..46cde9c70 100644 --- a/website/docs/source/v2/getting-started/share.html.md +++ b/website/docs/source/v2/getting-started/share.html.md @@ -54,3 +54,6 @@ the URL again to verify that your environment is no longer being shared. Vagrant Share is much more powerful than simply HTTP sharing. For more details, see the [complete Vagrant Share documentation](/v2/share/index.html). + +Networking +Teardown diff --git a/website/docs/source/v2/getting-started/synced_folders.html.md b/website/docs/source/v2/getting-started/synced_folders.html.md index 11612e84c..80c42c876 100644 --- a/website/docs/source/v2/getting-started/synced_folders.html.md +++ b/website/docs/source/v2/getting-started/synced_folders.html.md @@ -40,3 +40,6 @@ the folders in sync. With [synced folders](/v2/synced-folders/index.html), you can continue to use your own editor on your host machine and have the files sync into the guest machine. + +Up And SSH +Provisioning diff --git a/website/docs/source/v2/getting-started/teardown.html.md b/website/docs/source/v2/getting-started/teardown.html.md index 764de1969..04ce15f9f 100644 --- a/website/docs/source/v2/getting-started/teardown.html.md +++ b/website/docs/source/v2/getting-started/teardown.html.md @@ -23,19 +23,22 @@ work. The downside is that the virtual machine still eats up your disk space, and requires even more disk space to store all the state of the virtual machine RAM on disk. -**Halting** the virtual machine by calling `vagrant halt` will gracefully -shut down the guest operating system and power down the guest machine. -You can use `vagrant up` when you're ready to boot it again. The benefit of -this method is that it will cleanly shut down your machine, preserving the +**Halting** the virtual machine by calling `vagrant halt` will gracefully +shut down the guest operating system and power down the guest machine. +You can use `vagrant up` when you're ready to boot it again. The benefit of +this method is that it will cleanly shut down your machine, preserving the contents of disk, and allowing it to be cleanly started again. The downside is that it'll take some extra time to start from a cold boot, and the guest machine still consumes disk space. -**Destroying** the virtual machine by calling `vagrant destroy` will remove -all traces of the guest machine from your system. It'll stop the guest machine, -power it down, and remove all of the guest hard disks. Again, when you're ready to +**Destroying** the virtual machine by calling `vagrant destroy` will remove +all traces of the guest machine from your system. It'll stop the guest machine, +power it down, and remove all of the guest hard disks. Again, when you're ready to work again, just issue a `vagrant up`. The benefit of this is that _no cruft_ is left on your machine. The disk space and RAM consumed by the guest machine is reclaimed and your host machine is left clean. The downside is that `vagrant up` to get working again will take some extra time since it has to reimport the machine and reprovision it. + +Share +Rebuild diff --git a/website/docs/source/v2/getting-started/up.html.md b/website/docs/source/v2/getting-started/up.html.md index 3a9686afa..f1e59a6cf 100644 --- a/website/docs/source/v2/getting-started/up.html.md +++ b/website/docs/source/v2/getting-started/up.html.md @@ -33,3 +33,6 @@ virtual machine. Cool. When you're done fiddling around with the machine, run `vagrant destroy` back on your host machine, and Vagrant will remove all traces of the virtual machine. + +Boxes +Synced Folders diff --git a/website/docs/source/v2/hyperv/configuration.html.md b/website/docs/source/v2/hyperv/configuration.html.md index 2459c7c0d..18ed9e89c 100644 --- a/website/docs/source/v2/hyperv/configuration.html.md +++ b/website/docs/source/v2/hyperv/configuration.html.md @@ -8,6 +8,15 @@ sidebar_current: "hyperv-configuration" The Hyper-V provider has some provider-specific configuration options you may set. A complete reference is shown below: + * `vmname` (string) - Name of virtual mashine as shown in Hyper-V manager. + Defaults is taken from box image XML. + * `cpus` (integer) - Number of virtual CPU given to mashine. + Defaults is taken from box image XML. + * `memory` (integer) - Number of MegaBytes allocated to VM at startup. + Defaults is taken from box image XML. + * `maxmemory` (integer) - Number of MegaBytes maximal allowed to allocate for VM + This parameter is switch on Dynamic Allocation of memory. + Defaults is taken from box image XML. * `ip_address_timeout` (integer) - The time in seconds to wait for the virtual machine to report an IP address. This defaults to 120 seconds. This may have to be increased if your VM takes longer to boot. diff --git a/website/docs/source/v2/plugins/hosts.html.md b/website/docs/source/v2/plugins/hosts.html.md index aaf1d6bdf..aed652f84 100644 --- a/website/docs/source/v2/plugins/hosts.html.md +++ b/website/docs/source/v2/plugins/hosts.html.md @@ -47,7 +47,7 @@ Implementations of hosts subclass `Vagrant.plugin("2", "host")`. Within this implementation, only the `detect?` method needs to be implemented. The `detect?` method is called by Vagrant very early on in its initialization -process to determine if the OS that Vagrant is running on is this hsot. +process to determine if the OS that Vagrant is running on is this host. If you detect that it is your operating system, return `true` from `detect?`. Otherwise, return `false`. diff --git a/website/docs/source/v2/provisioning/ansible.html.md b/website/docs/source/v2/provisioning/ansible.html.md index 9301e0fb8..10fd1fc6d 100644 --- a/website/docs/source/v2/provisioning/ansible.html.md +++ b/website/docs/source/v2/provisioning/ansible.html.md @@ -33,30 +33,30 @@ a single page of documentation. ## Inventory File When using Ansible, it needs to know on which machines a given playbook should run. It does -this by way of an [inventory](http://docs.ansible.com/intro_inventory.html) file which lists those machines. In the context of Vagrant, -there are two ways to approach working with inventory files. +this by way of an [inventory](http://docs.ansible.com/intro_inventory.html) file which lists those machines. +In the context of Vagrant, there are two ways to approach working with inventory files. + +### Auto-Generated Inventory The first and simplest option is to not provide one to Vagrant at all. Vagrant will generate an inventory file encompassing all of the virtual machines it manages, and use it for provisioning machines. The generated inventory file is stored as part of your local Vagrant environment in `.vagrant/provisioners/ansible/inventory/vagrant_ansible_inventory`. -The `ansible.groups` option can be used to pass a hash of group -names and group members to be included in the generated inventory file. Group variables -are intentionally not supported, as this practice is not recommended. -For example: +**Groups of Hosts** + +The `ansible.groups` option can be used to pass a hash of group names and group members to be included in the generated inventory file. + +With this configuration example: ``` ansible.groups = { "group1" => ["machine1"], - "group2" => ["machine2", "machine3"], - "all_groups:children" => ["group1", "group2", "group3"] + "group2" => ["machine2"], + "all_groups:children" => ["group1", "group2"] } ``` -Note that unmanaged machines and undefined groups are not added to the inventory. -For example, `group3` in the above example would not be added to the inventory file. - -A generated inventory might look like: +Vagrant would generate an inventory file that might look like: ``` # Generated by Vagrant @@ -75,6 +75,24 @@ group1 group2 ``` +**Notes** + + * The generation of group variables blocks (e.g. `[group1:vars]`) are intentionally not supported, as it is [not recommended to store group variables in the main inventory file](http://docs.ansible.com/intro_inventory.html#splitting-out-host-and-group-specific-data). A good practice is to store these group (or host) variables in `YAML` files stored in `group_vars/` or `host_vars/` directories in the playbook (or inventory) directory. + * Unmanaged machines and undefined groups are not added to the inventory, to avoid useless Ansible errors (e.g. *unreachable host* or *undefined child group*) + +For example, `machine3`, `group3` and `group1:vars` in the example below would not be added to the generated inventory file: + +``` +ansible.groups = { + "group1" => ["machine1"], + "group2" => ["machine2", "machine3"], + "all_groups:children" => ["group1", "group2", "group3"], + "group1:vars" => { "variable1" => 9, "variable2" => "example" } +} +``` + +### Static Inventory + The second option is for situations where you'd like to have more control over the inventory management. With the `ansible.inventory_path` option, you can reference a specific inventory resource (e.g. a static inventory file, a [dynamic inventory script](http://docs.ansible.com/intro_dynamic_inventory.html) or even [multiple inventories stored in the same directory](http://docs.ansible.com/intro_dynamic_inventory.html#using-multiple-inventory-sources)). Vagrant will then use this inventory information instead of generating it. @@ -90,8 +108,10 @@ Where the above IP address is one set in your Vagrantfile: config.vm.network :private_network, ip: "192.168.111.222" ``` -Note that machine names in `Vagrantfile` and `ansible.inventory_path` file should correspond, -unless you use `ansible.limit` option to reference the correct machines. +**Notes:** + + * The machine names in `Vagrantfile` and `ansible.inventory_path` files should correspond, unless you use `ansible.limit` option to reference the correct machines. + * The SSH host addresses (and ports) must obviously be specified twice, in `Vagrantfile` and `ansible.inventory_path` files. ## Playbook @@ -207,6 +227,12 @@ by the sudo command. Vagrant is designed to provision [multi-machine environments](/v2/multi-machine) in sequence, but the following configuration pattern can be used to take advantage of Ansible parallelism: ``` + # By default, Vagrant 1.7+ automatically inserts a different + # insecure keypair for each new VM created. The easiest way + # to use the same keypair for all the machines is to disable + # this feature and rely on the legacy insecure key. + config.ssh.insert_key = false + config.vm.define 'machine2' do |machine| machine.vm.hostname = 'machine2' machine.vm.network "private_network", ip: "192.168.77.22" diff --git a/website/docs/source/v2/synced-folders/rsync.html.md b/website/docs/source/v2/synced-folders/rsync.html.md index 62e88d0dd..0d242676e 100644 --- a/website/docs/source/v2/synced-folders/rsync.html.md +++ b/website/docs/source/v2/synced-folders/rsync.html.md @@ -44,7 +44,7 @@ the destination folder. The rsync synced folder type accepts the following options: * `rsync__args` (array of strings) - A list of arguments to supply - to `rsync`. By default this is `["--verbose", "--archive", "--delete", "-z"]`. + to `rsync`. By default this is `["--verbose", "--archive", "--delete", "-z", "--copy-links"]`. * `rsync__auto` (boolean) - If false, then `rsync-auto` will not watch and automatically sync this folder. By default, this is true. @@ -81,7 +81,7 @@ permissions, use `"--rsync-path='sudo rsync'"` to run rsync with sudo on the gue
 Vagrant.configure("2") do |config|
   config.vm.synced_folder "bin", "/usr/local/bin", type: "rsync",
-    rsync__exclude: ".git/"
+    rsync__exclude: ".git/",
     rsync__args: ["--verbose", "--rsync-path='sudo rsync'", "--archive", "--delete", "-z"]
 end
 
diff --git a/website/docs/source/v2/vagrantfile/machine_settings.html.md b/website/docs/source/v2/vagrantfile/machine_settings.html.md index 8ea060de5..26565200e 100644 --- a/website/docs/source/v2/vagrantfile/machine_settings.html.md +++ b/website/docs/source/v2/vagrantfile/machine_settings.html.md @@ -64,7 +64,7 @@ bundle. `config.vm.box_download_ca_path` - Path to a directory containing CA certificates for downloading a box directly. By default, Vagrant will -use the Mozilla CA cert bundle.. +use the Mozilla CA cert bundle.
`config.vm.box_download_insecure` - If true, then SSL certificates diff --git a/website/docs/source/v2/vagrantfile/winrm_settings.html.md b/website/docs/source/v2/vagrantfile/winrm_settings.html.md index 462ccf56e..add316a40 100644 --- a/website/docs/source/v2/vagrantfile/winrm_settings.html.md +++ b/website/docs/source/v2/vagrantfile/winrm_settings.html.md @@ -44,3 +44,17 @@ example, if this is set to 5985 (the default), and Vagrant detects a forwarded port to port 5985 on the guest from port 4567 on the host, Vagrant will attempt to use port 4567 to talk to the guest if there is no other option. +
+ +Warning: In order for Vagrant to communicate with a Windows +guest, you must allow unencrypted WinRM connections on the guest machine +itself. Some public boxes already have this configured, but if you are +attempting to `vagrant up` a Windows box and the command hangs at +`Waiting for WinRM to become available...`, then you will need to run the +commands below on the guest machine itself, at the box setup stage, +after provisioning, or through a start up script. + +
+Set-Item WSMan:\localhost\Service\AllowUnencrypted -Value True
+Set-Item WSMan:\localhost\Service\Auth\Basic -Value True
+
\ No newline at end of file diff --git a/website/docs/source/v2/vmware/installation.html.md b/website/docs/source/v2/vmware/installation.html.md index c9a7ca561..972e2266e 100644 --- a/website/docs/source/v2/vmware/installation.html.md +++ b/website/docs/source/v2/vmware/installation.html.md @@ -5,36 +5,149 @@ sidebar_current: "vmware-installation" # Installation -The VMware provider is installed using -[standard plugin installation procedures](/v2/plugins/usage.html). -In addition to installing the plugin, a license must be provided so that -it can be loaded properly. +The Vagrant VMware provider can be installed using the standard plugin +installation procedure. VMware Fusion users should run: -To purchase a license, visit the [Vagrant VMware provider](http://www.vagrantup.com/vmware) -page. After purchasing a license, a link to download it will be emailed -to you. Download this file. - -Installing the plugin and license is easy using the `vagrant plugin` -interface. Both steps are shown below. Note that the plugin name is different -depending on the provider you're using. If you're using the Fusion provider, -it is `vagrant-vmware-fusion`. If you're using the Workstation provider, -it is `vagrant-vmware-workstation`. - -``` +```text $ vagrant plugin install vagrant-vmware-fusion -... -$ vagrant plugin license vagrant-vmware-fusion license.lic -... ``` -For licensing, the first parameter is the name of the plugin, which is -`vagrant-vmware-fusion` for the VMware Fusion provider, or `vagrant-vmware-workstation` -for the VMware Workstation provider. The second parameter is the path to the license itself. +VMware Workstation users should run: -You can verify the license is properly installed by running any -Vagrant command, such as `vagrant plugin list`. The VMware -provider will show an error message if you are missing a license or using an -invalid license. +```text +$ vagrant plugin install vagrant-vmware-workstation +``` -If there are problems installing the plugin, please contact -[support](http://www.vagrantup.com/support.html). +For more information on plugin installation, please see the +[Vagrant plugin usage documentation](/v2/plugins/usage.html). + +The Vagrant VMware plugins are commercial products provided by +[HashiCorp](https://www.hashicorp.com) and **require the purchase of a license** +to operate. To purchase a license, please visit the +[Vagrant VMware provider](http://www.vagrantup.com/vmware#buy-now) page. Upon +purchasing a license, you will receive a license file in your inbox. Download +this file and save it to a temporary location on your computer. + +
+ Warning! You cannot use your VMware product license as a + Vagrant VMware plugin license. They are separate commercial products, each + requiring their own license. +
+ +After installing the correct Vagrant VMware product plugin for your system, you +will need to install the license. For VMware Fusion users: + +```text +$ vagrant plugin license vagrant-vmware-fusion ~/license.lic +``` + +For VMware Workstation users: + +```text +$ vagrant plugin license vagrant-vmware-workstation ~/license.lic +``` + +The first parameter is the name of the plugin, and the second parameter is the +path to the license file on disk. Please be sure to replace `~/license.lic` +with the path where you temporarily saved the downloaded license file to disk. +After you have installed the plugin license, you may remove the temporary file. + +To verify the license installation, run: + +```text +$ vagrant plugin list +``` + +If the license is not installed correctly, you will see an error message. + + +## Frequently Asked Questions + +**Q: I purchased a Vagrant VMware plugin license, but I did not receive an email?**
+First, please check your JUNK or SPAM folders. Since the license comes from an +automated system, it might have been flagged as spam by your email provider. If +you do not see the email there, please [contact support](mailto:support@hashicorp.com?subject=License Not Received) +and include the original order number. + +**Q: Do you offer trial periods for the Vagrant VMware plugins?**
+We do not offer a trial mechanism at this time, but we do offer a 30-day, no +questions asked, 100% money-back guarantee. If you are not satisfied with the +product, contact us within 30 days and you will receive a full refund. + +**Q: Do you offer educational discounts on the Vagrant VMware plugins?**
+A select number of educational discounts are available for students, staff, and +faculty. Please [contact support](mailto:support@hashicorp.com?subject=Educational Discounts&body=Hello support! I would like to learn more about educational discounts on the Vagrant VMware plugins. Thanks!) for more +information. You will be asked to verify your status as an employee of active +student. + +**Q: Do I need to keep the Vagrant VMware plugin license file on disk?**
+After you have installed the Vagrant VMware plugin license, it is safe to remove +your copy from disk. Vagrant copies the license into its structure for reference +on boot. + +**Q: I lost my original email, where can I download my Vagrant VMware plugin license again?**
+Please [contact support](mailto:support@hashicorp.com?subject=Lost My License&body=Hello support! I seem to have misplaced my Vagrant VMware license. Could you please send it to me? Thanks!). **Note:** +please contact support using the email address with which you made the +original purchase. If you use an alternate email, you will be asked to verify +that you are the owner of the requested license. + +**Q: Where can I find the EULA for the Vagrant VMware plugins?**
+The [EULA for the Vagrant VMware plugins](http://www.vagrantup.com/vmware/eula) +is available on the Vagrant website. + +**Q: Do you offer bulk/volume discounts for the Vagrant VMware plugins?**
+We certainly do! [Email support](mailto:support@hashicorp.com?subject=Bulk Discounts) +with the number of licenses you need and we can give you bulk pricing +information. Please note that bulk pricing requires the purchase of at least 150 +seats. + +**Q: I upgraded my VMware product and now my license is invalid?**
+The Vagrant VMware plugin licenses are valid for specific VMware product +versions at the time of purchase. When new versions of VMware products are +released, significant changes to the plugin code are often required to support +this new version. For this reason, you may need to upgrade your current license +to work with the new version of the VMware product. Customers can check their +license upgrade eligibility by visiting the [License Upgrade Center](http://license.hashicorp.com/upgrade/vmware2014) +and entering the email address with which they made the original purchase. + +Your existing license will continue to work with all previous versions of the +VMware products. If you do not wish to update at this time, you can rollback +your VMware installation to an older version. + +**Q: Why is the Vagrant VMware plugin not working with my trial version of VMware Fusion/Workstation?**
+The Vagrant VMware Fusion and Vagrant VMware Workstation plugins are not +compatible with trial versions of the VMware products. We apologize for the +inconvenience. + +**Q: I accidentally bought the wrong Vagrant VMware plugin, can I switch?**
+Sure! Even though the Vagrant VMware Fusion plugin and the Vagrant VMware +Workstation plugin are different products, they are the same price and fall +under the same EULA. As such, we can transfer the license for you. Please +[contact support](mailto:support@hashicorp.com?subject=Transfer License). + +**Q: Since each license comes with two "seats", can I use one seat for the Vagrant VMware Fusion plugin and one seat for the Vagrant VMware Workstation plugin?**
+Unfortunately this is not permitted. The Vagrant VMware Fusion plugin and the +Vagrant VMware Workstation plugin are separate products and cannot be shared in +this manner. We apologize for the inconvenience. + +**Q: How do I upgrade my currently installed Vagrant VMware plugin?**
+You can update the Vagrant VMware plugin to the latest version by re-running the +install command. For VMware Fusion: + +```text +$ vagrant plugin install vagrant-vmware-fusion +``` + +For VMWare Workstation: + +```text +$ vagrant plugin install vagrant-vmware-workstation +``` + + +## Support +If you have any issues purchasing, installing, or using the Vagrant VMware +plugins, please [contact support](http://www.vagrantup.com/support.html). To +expedite the support process, please include the +[Vagrant debug output](/v2/other/debugging.html) as a Gist or pastebin if +applicable. This will help us more quickly diagnose your issue. diff --git a/website/www/version.txt b/website/www/version.txt index b958192dc..373d87e82 100644 --- a/website/www/version.txt +++ b/website/www/version.txt @@ -1,4 +1,4 @@ This is just used to force a deploy on Heroku. Just update this number whenever you want: -11 +12