tnargav 1.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +31 -0
- data/.gitsetup.yml +5 -0
- data/.travis.yml +7 -0
- data/.yardopts +1 -0
- data/CHANGELOG.md +1067 -0
- data/Gemfile +3 -0
- data/LICENSE +21 -0
- data/README.md +89 -0
- data/Rakefile +18 -0
- data/bin/vagrant +106 -0
- data/config/default.rb +36 -0
- data/contrib/README.md +12 -0
- data/contrib/bash/completion.sh +3 -0
- data/contrib/emacs/vagrant.el +8 -0
- data/contrib/vim/vagrantfile.vim +9 -0
- data/keys/README.md +17 -0
- data/keys/vagrant +27 -0
- data/keys/vagrant.pub +1 -0
- data/lib/vagrant/action/builder.rb +174 -0
- data/lib/vagrant/action/builtin/box_add.rb +81 -0
- data/lib/vagrant/action/builtin/call.rb +67 -0
- data/lib/vagrant/action/builtin/config_validate.rb +30 -0
- data/lib/vagrant/action/builtin/confirm.rb +38 -0
- data/lib/vagrant/action/builtin/destroy_confirm.rb +21 -0
- data/lib/vagrant/action/builtin/env_set.rb +24 -0
- data/lib/vagrant/action/builtin/graceful_halt.rb +73 -0
- data/lib/vagrant/action/builtin/handle_box_url.rb +77 -0
- data/lib/vagrant/action/builtin/handle_forwarded_port_collisions.rb +134 -0
- data/lib/vagrant/action/builtin/lock.rb +57 -0
- data/lib/vagrant/action/builtin/nfs.rb +118 -0
- data/lib/vagrant/action/builtin/provision.rb +70 -0
- data/lib/vagrant/action/builtin/set_hostname.rb +27 -0
- data/lib/vagrant/action/builtin/ssh_exec.rb +42 -0
- data/lib/vagrant/action/builtin/ssh_run.rb +43 -0
- data/lib/vagrant/action/general/package.rb +103 -0
- data/lib/vagrant/action/hook.rb +107 -0
- data/lib/vagrant/action/runner.rb +69 -0
- data/lib/vagrant/action/warden.rb +103 -0
- data/lib/vagrant/action.rb +43 -0
- data/lib/vagrant/batch_action.rb +113 -0
- data/lib/vagrant/box.rb +97 -0
- data/lib/vagrant/box_collection.rb +375 -0
- data/lib/vagrant/cli.rb +82 -0
- data/lib/vagrant/config/loader.rb +222 -0
- data/lib/vagrant/config/v1/dummy_config.rb +13 -0
- data/lib/vagrant/config/v1/loader.rb +105 -0
- data/lib/vagrant/config/v1/root.rb +60 -0
- data/lib/vagrant/config/v1.rb +9 -0
- data/lib/vagrant/config/v2/dummy_config.rb +13 -0
- data/lib/vagrant/config/v2/loader.rb +141 -0
- data/lib/vagrant/config/v2/root.rb +105 -0
- data/lib/vagrant/config/v2/util.rb +21 -0
- data/lib/vagrant/config/v2.rb +9 -0
- data/lib/vagrant/config/version_base.rb +80 -0
- data/lib/vagrant/config.rb +61 -0
- data/lib/vagrant/environment.rb +843 -0
- data/lib/vagrant/errors.rb +570 -0
- data/lib/vagrant/guest.rb +163 -0
- data/lib/vagrant/hosts.rb +28 -0
- data/lib/vagrant/machine.rb +325 -0
- data/lib/vagrant/machine_state.rb +45 -0
- data/lib/vagrant/plugin/v1/command.rb +169 -0
- data/lib/vagrant/plugin/v1/communicator.rb +98 -0
- data/lib/vagrant/plugin/v1/config.rb +112 -0
- data/lib/vagrant/plugin/v1/errors.rb +15 -0
- data/lib/vagrant/plugin/v1/guest.rb +92 -0
- data/lib/vagrant/plugin/v1/host.rb +66 -0
- data/lib/vagrant/plugin/v1/manager.rb +131 -0
- data/lib/vagrant/plugin/v1/plugin.rb +229 -0
- data/lib/vagrant/plugin/v1/provider.rb +68 -0
- data/lib/vagrant/plugin/v1/provisioner.rb +50 -0
- data/lib/vagrant/plugin/v1.rb +19 -0
- data/lib/vagrant/plugin/v2/command.rb +234 -0
- data/lib/vagrant/plugin/v2/communicator.rb +98 -0
- data/lib/vagrant/plugin/v2/components.rb +47 -0
- data/lib/vagrant/plugin/v2/config.rb +136 -0
- data/lib/vagrant/plugin/v2/errors.rb +15 -0
- data/lib/vagrant/plugin/v2/guest.rb +78 -0
- data/lib/vagrant/plugin/v2/host.rb +66 -0
- data/lib/vagrant/plugin/v2/manager.rb +173 -0
- data/lib/vagrant/plugin/v2/plugin.rb +226 -0
- data/lib/vagrant/plugin/v2/provider.rb +69 -0
- data/lib/vagrant/plugin/v2/provisioner.rb +47 -0
- data/lib/vagrant/plugin/v2.rb +22 -0
- data/lib/vagrant/plugin.rb +6 -0
- data/lib/vagrant/registry.rb +78 -0
- data/lib/vagrant/ui.rb +215 -0
- data/lib/vagrant/util/ansi_escape_code_remover.rb +34 -0
- data/lib/vagrant/util/busy.rb +59 -0
- data/lib/vagrant/util/counter.rb +24 -0
- data/lib/vagrant/util/downloader.rb +146 -0
- data/lib/vagrant/util/file_checksum.rb +38 -0
- data/lib/vagrant/util/file_mode.rb +12 -0
- data/lib/vagrant/util/hash_with_indifferent_access.rb +63 -0
- data/lib/vagrant/util/is_port_open.rb +38 -0
- data/lib/vagrant/util/line_ending_helpers.rb +14 -0
- data/lib/vagrant/util/network_ip.rb +28 -0
- data/lib/vagrant/util/platform.rb +58 -0
- data/lib/vagrant/util/retryable.rb +31 -0
- data/lib/vagrant/util/safe_chdir.rb +33 -0
- data/lib/vagrant/util/safe_exec.rb +36 -0
- data/lib/vagrant/util/safe_puts.rb +31 -0
- data/lib/vagrant/util/scoped_hash_override.rb +45 -0
- data/lib/vagrant/util/ssh.rb +150 -0
- data/lib/vagrant/util/stacked_proc_runner.rb +35 -0
- data/lib/vagrant/util/string_block_editor.rb +77 -0
- data/lib/vagrant/util/subprocess.rb +273 -0
- data/lib/vagrant/util/template_renderer.rb +83 -0
- data/lib/vagrant/util/which.rb +43 -0
- data/lib/vagrant/util.rb +12 -0
- data/lib/vagrant/version.rb +6 -0
- data/lib/vagrant.rb +258 -0
- data/plugins/README.md +5 -0
- data/plugins/commands/box/command/add.rb +51 -0
- data/plugins/commands/box/command/list.rb +41 -0
- data/plugins/commands/box/command/remove.rb +37 -0
- data/plugins/commands/box/command/repackage.rb +43 -0
- data/plugins/commands/box/command/root.rb +75 -0
- data/plugins/commands/box/plugin.rb +15 -0
- data/plugins/commands/destroy/command.rb +31 -0
- data/plugins/commands/destroy/plugin.rb +18 -0
- data/plugins/commands/halt/command.rb +33 -0
- data/plugins/commands/halt/plugin.rb +18 -0
- data/plugins/commands/init/command.rb +40 -0
- data/plugins/commands/init/plugin.rb +18 -0
- data/plugins/commands/package/command.rb +83 -0
- data/plugins/commands/package/plugin.rb +18 -0
- data/plugins/commands/plugin/action/bundler_check.rb +25 -0
- data/plugins/commands/plugin/action/install_gem.rb +81 -0
- data/plugins/commands/plugin/action/license_plugin.rb +54 -0
- data/plugins/commands/plugin/action/list_plugins.rb +54 -0
- data/plugins/commands/plugin/action/prune_gems.rb +149 -0
- data/plugins/commands/plugin/action/uninstall_plugin.rb +23 -0
- data/plugins/commands/plugin/action.rb +52 -0
- data/plugins/commands/plugin/command/base.rb +22 -0
- data/plugins/commands/plugin/command/install.rb +58 -0
- data/plugins/commands/plugin/command/license.rb +31 -0
- data/plugins/commands/plugin/command/list.rb +28 -0
- data/plugins/commands/plugin/command/root.rb +75 -0
- data/plugins/commands/plugin/command/uninstall.rb +28 -0
- data/plugins/commands/plugin/gem_helper.rb +74 -0
- data/plugins/commands/plugin/plugin.rb +22 -0
- data/plugins/commands/plugin/state_file.rb +57 -0
- data/plugins/commands/provision/command.rb +34 -0
- data/plugins/commands/provision/plugin.rb +18 -0
- data/plugins/commands/reload/command.rb +37 -0
- data/plugins/commands/reload/plugin.rb +18 -0
- data/plugins/commands/resume/command.rb +25 -0
- data/plugins/commands/resume/plugin.rb +17 -0
- data/plugins/commands/ssh/command.rb +63 -0
- data/plugins/commands/ssh/plugin.rb +17 -0
- data/plugins/commands/ssh_config/command.rb +49 -0
- data/plugins/commands/ssh_config/plugin.rb +18 -0
- data/plugins/commands/status/command.rb +39 -0
- data/plugins/commands/status/plugin.rb +18 -0
- data/plugins/commands/suspend/command.rb +25 -0
- data/plugins/commands/suspend/plugin.rb +18 -0
- data/plugins/commands/up/command.rb +57 -0
- data/plugins/commands/up/plugin.rb +17 -0
- data/plugins/commands/up/start_mixins.rb +26 -0
- data/plugins/communicators/ssh/communicator.rb +342 -0
- data/plugins/communicators/ssh/plugin.rb +19 -0
- data/plugins/guests/arch/cap/change_host_name.rb +18 -0
- data/plugins/guests/arch/cap/configure_networks.rb +23 -0
- data/plugins/guests/arch/guest.rb +11 -0
- data/plugins/guests/arch/plugin.rb +25 -0
- data/plugins/guests/debian/cap/change_host_name.rb +18 -0
- data/plugins/guests/debian/cap/configure_networks.rb +61 -0
- data/plugins/guests/debian/guest.rb +9 -0
- data/plugins/guests/debian/plugin.rb +25 -0
- data/plugins/guests/fedora/cap/configure_networks.rb +59 -0
- data/plugins/guests/fedora/cap/network_scripts_dir.rb +15 -0
- data/plugins/guests/fedora/guest.rb +11 -0
- data/plugins/guests/fedora/plugin.rb +25 -0
- data/plugins/guests/freebsd/cap/change_host_name.rb +14 -0
- data/plugins/guests/freebsd/cap/configure_networks.rb +39 -0
- data/plugins/guests/freebsd/cap/halt.rb +16 -0
- data/plugins/guests/freebsd/cap/mount_nfs_folder.rb +14 -0
- data/plugins/guests/freebsd/guest.rb +14 -0
- data/plugins/guests/freebsd/plugin.rb +35 -0
- data/plugins/guests/gentoo/cap/change_host_name.rb +17 -0
- data/plugins/guests/gentoo/cap/configure_networks.rb +43 -0
- data/plugins/guests/gentoo/guest.rb +9 -0
- data/plugins/guests/gentoo/plugin.rb +25 -0
- data/plugins/guests/linux/cap/halt.rb +16 -0
- data/plugins/guests/linux/cap/mount_nfs.rb +30 -0
- data/plugins/guests/linux/cap/mount_virtualbox_shared_folder.rb +40 -0
- data/plugins/guests/linux/cap/read_ip_address.rb +17 -0
- data/plugins/guests/linux/cap/shell_expand_guest_path.rb +26 -0
- data/plugins/guests/linux/guest.rb +11 -0
- data/plugins/guests/linux/plugin.rb +40 -0
- data/plugins/guests/openbsd/cap/halt.rb +16 -0
- data/plugins/guests/openbsd/guest.rb +11 -0
- data/plugins/guests/openbsd/plugin.rb +20 -0
- data/plugins/guests/pld/cap/network_scripts_dir.rb +11 -0
- data/plugins/guests/pld/guest.rb +11 -0
- data/plugins/guests/pld/plugin.rb +20 -0
- data/plugins/guests/redhat/cap/change_host_name.rb +18 -0
- data/plugins/guests/redhat/cap/configure_networks.rb +60 -0
- data/plugins/guests/redhat/cap/network_scripts_dir.rb +11 -0
- data/plugins/guests/redhat/guest.rb +11 -0
- data/plugins/guests/redhat/plugin.rb +30 -0
- data/plugins/guests/solaris/cap/change_host_name.rb +17 -0
- data/plugins/guests/solaris/cap/configure_networks.rb +25 -0
- data/plugins/guests/solaris/cap/halt.rb +21 -0
- data/plugins/guests/solaris/cap/mount_virtualbox_shared_folder.rb +28 -0
- data/plugins/guests/solaris/config.rb +18 -0
- data/plugins/guests/solaris/guest.rb +14 -0
- data/plugins/guests/solaris/plugin.rb +40 -0
- data/plugins/guests/suse/cap/change_host_name.rb +18 -0
- data/plugins/guests/suse/cap/network_scripts_dir.rb +11 -0
- data/plugins/guests/suse/guest.rb +11 -0
- data/plugins/guests/suse/plugin.rb +25 -0
- data/plugins/guests/ubuntu/cap/change_host_name.rb +23 -0
- data/plugins/guests/ubuntu/guest.rb +32 -0
- data/plugins/guests/ubuntu/plugin.rb +20 -0
- data/plugins/hosts/arch/host.rb +68 -0
- data/plugins/hosts/arch/plugin.rb +15 -0
- data/plugins/hosts/bsd/host.rb +102 -0
- data/plugins/hosts/bsd/plugin.rb +15 -0
- data/plugins/hosts/fedora/host.rb +51 -0
- data/plugins/hosts/fedora/plugin.rb +15 -0
- data/plugins/hosts/freebsd/host.rb +43 -0
- data/plugins/hosts/freebsd/plugin.rb +15 -0
- data/plugins/hosts/gentoo/host.rb +24 -0
- data/plugins/hosts/gentoo/plugin.rb +15 -0
- data/plugins/hosts/linux/host.rb +95 -0
- data/plugins/hosts/linux/plugin.rb +15 -0
- data/plugins/hosts/opensuse/host.rb +34 -0
- data/plugins/hosts/opensuse/plugin.rb +15 -0
- data/plugins/hosts/windows/host.rb +17 -0
- data/plugins/hosts/windows/plugin.rb +15 -0
- data/plugins/kernel_v1/config/nfs.rb +20 -0
- data/plugins/kernel_v1/config/package.rb +17 -0
- data/plugins/kernel_v1/config/ssh.rb +46 -0
- data/plugins/kernel_v1/config/vagrant.rb +31 -0
- data/plugins/kernel_v1/config/vm.rb +184 -0
- data/plugins/kernel_v1/plugin.rb +44 -0
- data/plugins/kernel_v2/config/nfs.rb +14 -0
- data/plugins/kernel_v2/config/package.rb +13 -0
- data/plugins/kernel_v2/config/ssh.rb +76 -0
- data/plugins/kernel_v2/config/ssh_connect.rb +40 -0
- data/plugins/kernel_v2/config/vagrant.rb +13 -0
- data/plugins/kernel_v2/config/vm.rb +416 -0
- data/plugins/kernel_v2/config/vm_provisioner.rb +55 -0
- data/plugins/kernel_v2/config/vm_subvm.rb +30 -0
- data/plugins/kernel_v2/plugin.rb +44 -0
- data/plugins/providers/virtualbox/action/boot.rb +49 -0
- data/plugins/providers/virtualbox/action/check_accessible.rb +23 -0
- data/plugins/providers/virtualbox/action/check_created.rb +21 -0
- data/plugins/providers/virtualbox/action/check_guest_additions.rb +45 -0
- data/plugins/providers/virtualbox/action/check_running.rb +21 -0
- data/plugins/providers/virtualbox/action/check_virtualbox.rb +22 -0
- data/plugins/providers/virtualbox/action/clean_machine_folder.rb +43 -0
- data/plugins/providers/virtualbox/action/clear_forwarded_ports.rb +18 -0
- data/plugins/providers/virtualbox/action/clear_network_interfaces.rb +31 -0
- data/plugins/providers/virtualbox/action/clear_shared_folders.rb +17 -0
- data/plugins/providers/virtualbox/action/created.rb +20 -0
- data/plugins/providers/virtualbox/action/customize.rb +36 -0
- data/plugins/providers/virtualbox/action/destroy.rb +19 -0
- data/plugins/providers/virtualbox/action/destroy_unused_network_interfaces.rb +16 -0
- data/plugins/providers/virtualbox/action/discard_state.rb +20 -0
- data/plugins/providers/virtualbox/action/export.rb +57 -0
- data/plugins/providers/virtualbox/action/forced_halt.rb +25 -0
- data/plugins/providers/virtualbox/action/forward_ports.rb +87 -0
- data/plugins/providers/virtualbox/action/import.rb +51 -0
- data/plugins/providers/virtualbox/action/is_paused.rb +20 -0
- data/plugins/providers/virtualbox/action/is_running.rb +20 -0
- data/plugins/providers/virtualbox/action/is_saved.rb +20 -0
- data/plugins/providers/virtualbox/action/match_mac_address.rb +21 -0
- data/plugins/providers/virtualbox/action/message_already_running.rb +16 -0
- data/plugins/providers/virtualbox/action/message_not_created.rb +16 -0
- data/plugins/providers/virtualbox/action/message_not_running.rb +16 -0
- data/plugins/providers/virtualbox/action/message_will_not_destroy.rb +17 -0
- data/plugins/providers/virtualbox/action/network.rb +410 -0
- data/plugins/providers/virtualbox/action/package.rb +20 -0
- data/plugins/providers/virtualbox/action/package_vagrantfile.rb +33 -0
- data/plugins/providers/virtualbox/action/prepare_forwarded_port_collision_params.rb +35 -0
- data/plugins/providers/virtualbox/action/prepare_nfs_settings.rb +64 -0
- data/plugins/providers/virtualbox/action/prune_nfs_exports.rb +20 -0
- data/plugins/providers/virtualbox/action/resume.rb +25 -0
- data/plugins/providers/virtualbox/action/sane_defaults.rb +91 -0
- data/plugins/providers/virtualbox/action/set_name.rb +40 -0
- data/plugins/providers/virtualbox/action/setup_package_files.rb +51 -0
- data/plugins/providers/virtualbox/action/share_folders.rb +128 -0
- data/plugins/providers/virtualbox/action/suspend.rb +20 -0
- data/plugins/providers/virtualbox/action.rb +311 -0
- data/plugins/providers/virtualbox/config.rb +86 -0
- data/plugins/providers/virtualbox/driver/base.rb +360 -0
- data/plugins/providers/virtualbox/driver/meta.rb +142 -0
- data/plugins/providers/virtualbox/driver/version_4_0.rb +485 -0
- data/plugins/providers/virtualbox/driver/version_4_1.rb +485 -0
- data/plugins/providers/virtualbox/driver/version_4_2.rb +482 -0
- data/plugins/providers/virtualbox/model/forwarded_port.rb +58 -0
- data/plugins/providers/virtualbox/plugin.rb +42 -0
- data/plugins/providers/virtualbox/provider.rb +92 -0
- data/plugins/providers/virtualbox/util/compile_forwarded_ports.rb +31 -0
- data/plugins/provisioners/ansible/config.rb +72 -0
- data/plugins/provisioners/ansible/plugin.rb +23 -0
- data/plugins/provisioners/ansible/provisioner.rb +45 -0
- data/plugins/provisioners/cfengine/cap/debian/cfengine_install.rb +19 -0
- data/plugins/provisioners/cfengine/cap/linux/cfengine_installed.rb +14 -0
- data/plugins/provisioners/cfengine/cap/linux/cfengine_needs_bootstrap.rb +34 -0
- data/plugins/provisioners/cfengine/cap/redhat/cfengine_install.rb +24 -0
- data/plugins/provisioners/cfengine/config.rb +120 -0
- data/plugins/provisioners/cfengine/plugin.rb +42 -0
- data/plugins/provisioners/cfengine/provisioner.rb +136 -0
- data/plugins/provisioners/chef/config/base.rb +85 -0
- data/plugins/provisioners/chef/config/chef_client.rb +57 -0
- data/plugins/provisioners/chef/config/chef_solo.rb +87 -0
- data/plugins/provisioners/chef/plugin.rb +33 -0
- data/plugins/provisioners/chef/provisioner/base.rb +93 -0
- data/plugins/provisioners/chef/provisioner/chef_client.rb +107 -0
- data/plugins/provisioners/chef/provisioner/chef_solo.rb +192 -0
- data/plugins/provisioners/puppet/config/puppet.rb +70 -0
- data/plugins/provisioners/puppet/config/puppet_server.rb +16 -0
- data/plugins/provisioners/puppet/plugin.rb +33 -0
- data/plugins/provisioners/puppet/provisioner/puppet.rb +117 -0
- data/plugins/provisioners/puppet/provisioner/puppet_server.rb +67 -0
- data/plugins/provisioners/shell/config.rb +56 -0
- data/plugins/provisioners/shell/plugin.rb +23 -0
- data/plugins/provisioners/shell/provisioner.rb +86 -0
- data/tasks/acceptance.rake +113 -0
- data/tasks/bundler.rake +3 -0
- data/tasks/test.rake +20 -0
- data/templates/commands/init/Vagrantfile.erb +111 -0
- data/templates/commands/ssh_config/config.erb +16 -0
- data/templates/config/messages.erb +14 -0
- data/templates/config/validation_failed.erb +7 -0
- data/templates/guests/arch/network_dhcp.erb +4 -0
- data/templates/guests/arch/network_static.erb +6 -0
- data/templates/guests/debian/network_dhcp.erb +11 -0
- data/templates/guests/debian/network_static.erb +7 -0
- data/templates/guests/fedora/network_dhcp.erb +6 -0
- data/templates/guests/fedora/network_static.erb +13 -0
- data/templates/guests/freebsd/network_dhcp.erb +3 -0
- data/templates/guests/freebsd/network_static.erb +3 -0
- data/templates/guests/gentoo/network_dhcp.erb +4 -0
- data/templates/guests/gentoo/network_static.erb +4 -0
- data/templates/guests/redhat/network_dhcp.erb +6 -0
- data/templates/guests/redhat/network_static.erb +8 -0
- data/templates/locales/en.yml +1126 -0
- data/templates/nfs/exports.erb +5 -0
- data/templates/nfs/exports_freebsd.erb +5 -0
- data/templates/nfs/exports_linux.erb +5 -0
- data/templates/package_Vagrantfile.erb +11 -0
- data/templates/provisioners/chef_client/client.erb +32 -0
- data/templates/provisioners/chef_solo/solo.erb +25 -0
- data/templates/rgloader.rb +9 -0
- data/test/acceptance/base.rb +48 -0
- data/test/acceptance/box_test.rb +99 -0
- data/test/acceptance/destroy_test.rb +37 -0
- data/test/acceptance/halt_test.rb +72 -0
- data/test/acceptance/init_test.rb +33 -0
- data/test/acceptance/networking/host_only_test.rb +37 -0
- data/test/acceptance/networking/port_forward_test.rb +125 -0
- data/test/acceptance/package_test.rb +46 -0
- data/test/acceptance/provisioning/basic_test.rb +61 -0
- data/test/acceptance/provisioning/chef_solo_test.rb +37 -0
- data/test/acceptance/provisioning/shell_test.rb +53 -0
- data/test/acceptance/resume_test.rb +17 -0
- data/test/acceptance/shared_folders_test.rb +84 -0
- data/test/acceptance/skeletons/chef_solo_basic/README.md +3 -0
- data/test/acceptance/skeletons/chef_solo_basic/cookbooks/basic/recipes/default.rb +5 -0
- data/test/acceptance/skeletons/chef_solo_json/README.md +3 -0
- data/test/acceptance/skeletons/chef_solo_json/cookbooks/basic/recipes/default.rb +6 -0
- data/test/acceptance/skeletons/provisioner_multi/README.md +3 -0
- data/test/acceptance/skeletons/provisioner_multi/cookbooks/basic/recipes/default.rb +5 -0
- data/test/acceptance/ssh_test.rb +46 -0
- data/test/acceptance/support/config.rb +42 -0
- data/test/acceptance/support/isolated_environment.rb +118 -0
- data/test/acceptance/support/matchers/have_color.rb +9 -0
- data/test/acceptance/support/matchers/match_output.rb +14 -0
- data/test/acceptance/support/matchers/succeed.rb +14 -0
- data/test/acceptance/support/network_tests.rb +29 -0
- data/test/acceptance/support/output.rb +95 -0
- data/test/acceptance/support/shared/base_context.rb +72 -0
- data/test/acceptance/support/shared/command_examples.rb +33 -0
- data/test/acceptance/support/virtualbox.rb +36 -0
- data/test/acceptance/suspend_test.rb +56 -0
- data/test/acceptance/up_basic_test.rb +33 -0
- data/test/acceptance/up_with_box_url.rb +40 -0
- data/test/acceptance/vagrant_test.rb +47 -0
- data/test/acceptance/version_test.rb +15 -0
- data/test/config/acceptance_boxes.yml +7 -0
- data/test/support/isolated_environment.rb +46 -0
- data/test/support/tempdir.rb +43 -0
- data/test/unit/base.rb +27 -0
- data/test/unit/support/dummy_provider.rb +16 -0
- data/test/unit/support/isolated_environment.rb +179 -0
- data/test/unit/support/shared/base_context.rb +104 -0
- data/test/unit/vagrant/action/builder_test.rb +242 -0
- data/test/unit/vagrant/action/builtin/call_test.rb +145 -0
- data/test/unit/vagrant/action/builtin/confirm_test.rb +36 -0
- data/test/unit/vagrant/action/builtin/env_set_test.rb +20 -0
- data/test/unit/vagrant/action/builtin/graceful_halt_test.rb +61 -0
- data/test/unit/vagrant/action/builtin/lock_test.rb +98 -0
- data/test/unit/vagrant/action/builtin/ssh_exec_test.rb +57 -0
- data/test/unit/vagrant/action/hook_test.rb +120 -0
- data/test/unit/vagrant/action/runner_test.rb +71 -0
- data/test/unit/vagrant/action/warden_test.rb +92 -0
- data/test/unit/vagrant/batch_action_test.rb +36 -0
- data/test/unit/vagrant/box_collection_test.rb +237 -0
- data/test/unit/vagrant/box_test.rb +122 -0
- data/test/unit/vagrant/cli_test.rb +27 -0
- data/test/unit/vagrant/config/loader_test.rb +184 -0
- data/test/unit/vagrant/config/v1/dummy_config_test.rb +24 -0
- data/test/unit/vagrant/config/v1/loader_test.rb +145 -0
- data/test/unit/vagrant/config/v1/root_test.rb +40 -0
- data/test/unit/vagrant/config/v2/dummy_config_test.rb +24 -0
- data/test/unit/vagrant/config/v2/loader_test.rb +151 -0
- data/test/unit/vagrant/config/v2/root_test.rb +97 -0
- data/test/unit/vagrant/config/v2/util_test.rb +21 -0
- data/test/unit/vagrant/config_test.rb +66 -0
- data/test/unit/vagrant/environment_test.rb +721 -0
- data/test/unit/vagrant/guest_test.rb +166 -0
- data/test/unit/vagrant/hosts_test.rb +37 -0
- data/test/unit/vagrant/machine_state_test.rb +26 -0
- data/test/unit/vagrant/machine_test.rb +384 -0
- data/test/unit/vagrant/plugin/v1/command_test.rb +143 -0
- data/test/unit/vagrant/plugin/v1/communicator_test.rb +9 -0
- data/test/unit/vagrant/plugin/v1/config_test.rb +50 -0
- data/test/unit/vagrant/plugin/v1/host_test.rb +5 -0
- data/test/unit/vagrant/plugin/v1/manager_test.rb +114 -0
- data/test/unit/vagrant/plugin/v1/plugin_test.rb +267 -0
- data/test/unit/vagrant/plugin/v1/provider_test.rb +18 -0
- data/test/unit/vagrant/plugin/v2/command_test.rb +238 -0
- data/test/unit/vagrant/plugin/v2/communicator_test.rb +9 -0
- data/test/unit/vagrant/plugin/v2/components_test.rb +17 -0
- data/test/unit/vagrant/plugin/v2/config_test.rb +60 -0
- data/test/unit/vagrant/plugin/v2/host_test.rb +5 -0
- data/test/unit/vagrant/plugin/v2/manager_test.rb +174 -0
- data/test/unit/vagrant/plugin/v2/plugin_test.rb +305 -0
- data/test/unit/vagrant/plugin/v2/provider_test.rb +18 -0
- data/test/unit/vagrant/registry_test.rb +128 -0
- data/test/unit/vagrant/util/ansi_escape_code_remover_test.rb +16 -0
- data/test/unit/vagrant/util/downloader_test.rb +57 -0
- data/test/unit/vagrant/util/file_checksum_test.rb +23 -0
- data/test/unit/vagrant/util/hash_with_indifferent_access_test.rb +38 -0
- data/test/unit/vagrant/util/is_port_open_test.rb +53 -0
- data/test/unit/vagrant/util/line_endings_helper_test.rb +16 -0
- data/test/unit/vagrant/util/network_ip_test.rb +17 -0
- data/test/unit/vagrant/util/retryable_test.rb +106 -0
- data/test/unit/vagrant/util/safe_chdir_test.rb +43 -0
- data/test/unit/vagrant/util/scoped_hash_override_test.rb +48 -0
- data/test/unit/vagrant/util/ssh_test.rb +30 -0
- data/test/unit/vagrant/util/string_block_editor_test.rb +106 -0
- data/test/unit/vagrant/util/which_test.rb +43 -0
- data/test/unit/vagrant_test.rb +56 -0
- data/tnargav.gemspec +69 -0
- data/vagrant.gemspec +69 -0
- metadata +730 -0
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
module Vagrant
|
|
2
|
+
module Action
|
|
3
|
+
module Builtin
|
|
4
|
+
# This middleware class allows a sort of "conditional" run within
|
|
5
|
+
# a single middlware sequence. It takes another middleware runnable,
|
|
6
|
+
# runs it with the same environment, then yields the resulting env to a block,
|
|
7
|
+
# allowing that block to determine the next course of action in the
|
|
8
|
+
# middleware sequence.
|
|
9
|
+
#
|
|
10
|
+
# The first argument to this middleware sequence is anywhere middleware
|
|
11
|
+
# runnable, whether it be a class, lambda, or something else that
|
|
12
|
+
# responds to `call`. This middleware runnable is run with the same
|
|
13
|
+
# environment as this class.
|
|
14
|
+
#
|
|
15
|
+
# After running, {Call} takes the environment and yields it to a block
|
|
16
|
+
# given to initialize the class, along with an instance of {Builder}.
|
|
17
|
+
# The result is used to build up a new sequence on the given builder.
|
|
18
|
+
# This builder is then run.
|
|
19
|
+
class Call
|
|
20
|
+
# For documentation, read the description of the {Call} class.
|
|
21
|
+
#
|
|
22
|
+
# @param [Object] callable A valid middleware runnable object. This
|
|
23
|
+
# can be a class, a lambda, or an object that responds to `call`.
|
|
24
|
+
# @yield [result, builder] This block is expected to build on `builder`
|
|
25
|
+
# which is the next middleware sequence that will be run.
|
|
26
|
+
def initialize(app, env, callable, *callable_args, &block)
|
|
27
|
+
raise ArgumentError, "A block must be given to Call" if !block
|
|
28
|
+
|
|
29
|
+
@app = app
|
|
30
|
+
@callable = callable
|
|
31
|
+
@callable_args = callable_args
|
|
32
|
+
@block = block
|
|
33
|
+
@child_app = nil
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def call(env)
|
|
37
|
+
runner = Runner.new
|
|
38
|
+
|
|
39
|
+
# Build the callable that we'll run
|
|
40
|
+
callable = Builder.build(@callable, *@callable_args)
|
|
41
|
+
|
|
42
|
+
# Run our callable with our environment
|
|
43
|
+
new_env = runner.run(callable, env)
|
|
44
|
+
|
|
45
|
+
# Build our new builder based on the result
|
|
46
|
+
builder = Builder.new
|
|
47
|
+
@block.call(new_env, builder)
|
|
48
|
+
|
|
49
|
+
# Run the result with our new environment
|
|
50
|
+
@child_app = builder.to_app(new_env)
|
|
51
|
+
final_env = runner.run(@child_app, new_env)
|
|
52
|
+
|
|
53
|
+
# Merge the environment into our original environment
|
|
54
|
+
env.merge!(final_env)
|
|
55
|
+
|
|
56
|
+
# Call the next step using our final environment
|
|
57
|
+
@app.call(env)
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def recover(env)
|
|
61
|
+
# Call back into our compiled application and recover it.
|
|
62
|
+
@child_app.recover(env) if @child_app
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
require "vagrant/util/template_renderer"
|
|
2
|
+
|
|
3
|
+
module Vagrant
|
|
4
|
+
module Action
|
|
5
|
+
module Builtin
|
|
6
|
+
# This class validates the configuration and raises an exception
|
|
7
|
+
# if there are any validation errors.
|
|
8
|
+
class ConfigValidate
|
|
9
|
+
def initialize(app, env)
|
|
10
|
+
@app = app
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def call(env)
|
|
14
|
+
if !env.has_key?(:config_validate) || env[:config_validate]
|
|
15
|
+
errors = env[:machine].config.validate(env[:machine])
|
|
16
|
+
|
|
17
|
+
if errors && !errors.empty?
|
|
18
|
+
raise Errors::ConfigInvalid,
|
|
19
|
+
:errors => Util::TemplateRenderer.render(
|
|
20
|
+
"config/validation_failed",
|
|
21
|
+
:errors => errors)
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
@app.call(env)
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
module Vagrant
|
|
2
|
+
module Action
|
|
3
|
+
module Builtin
|
|
4
|
+
# This class asks the user to confirm some sort of question with
|
|
5
|
+
# a "Y/N" question. The only parameter is the text to ask the user.
|
|
6
|
+
# The result is placed in `env[:result]` so that it can be used
|
|
7
|
+
# with the {Call} class.
|
|
8
|
+
class Confirm
|
|
9
|
+
# For documentation, read the description of the {Confirm} class.
|
|
10
|
+
#
|
|
11
|
+
# @param [String] message The message to ask the user.
|
|
12
|
+
# @param [Symbol] force_key The key that if present and true in
|
|
13
|
+
# the environment hash will skip the confirmation question.
|
|
14
|
+
def initialize(app, env, message, force_key=nil)
|
|
15
|
+
@app = app
|
|
16
|
+
@message = message
|
|
17
|
+
@force_key = force_key
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def call(env)
|
|
21
|
+
choice = nil
|
|
22
|
+
|
|
23
|
+
# If we have a force key set and we're forcing, then set
|
|
24
|
+
# the result to "Y"
|
|
25
|
+
choice = "Y" if @force_key && env[@force_key]
|
|
26
|
+
|
|
27
|
+
# If we haven't chosen yes, then ask the user via TTY
|
|
28
|
+
choice = env[:ui].ask(@message) if !choice
|
|
29
|
+
|
|
30
|
+
# The result is only true if the user said "Y"
|
|
31
|
+
env[:result] = choice && choice.upcase == "Y"
|
|
32
|
+
|
|
33
|
+
@app.call(env)
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
require_relative "confirm"
|
|
2
|
+
|
|
3
|
+
module Vagrant
|
|
4
|
+
module Action
|
|
5
|
+
module Builtin
|
|
6
|
+
# This class asks the user to confirm the destruction of a machine
|
|
7
|
+
# that Vagrant manages. This is provided as a built-in on top of
|
|
8
|
+
# {Confirm} because it sets up the proper keys and such so that
|
|
9
|
+
# `vagrant destroy -f` works properly.
|
|
10
|
+
class DestroyConfirm < Confirm
|
|
11
|
+
def initialize(app, env)
|
|
12
|
+
force_key = :force_confirm_destroy
|
|
13
|
+
message = I18n.t("vagrant.commands.destroy.confirmation",
|
|
14
|
+
:name => env[:machine].name)
|
|
15
|
+
|
|
16
|
+
super(app, env, message, force_key)
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
module Vagrant
|
|
2
|
+
module Action
|
|
3
|
+
module Builtin
|
|
4
|
+
# This middleware class allows you to modify the environment hash
|
|
5
|
+
# in the middle of a middleware sequence. The new environmental data
|
|
6
|
+
# will take affect at this stage in the middleware and will persist
|
|
7
|
+
# through.
|
|
8
|
+
class EnvSet
|
|
9
|
+
def initialize(app, env, new_env=nil)
|
|
10
|
+
@app = app
|
|
11
|
+
@new_env = new_env || {}
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def call(env)
|
|
15
|
+
# Merge in the new data
|
|
16
|
+
env.merge!(@new_env)
|
|
17
|
+
|
|
18
|
+
# Carry on
|
|
19
|
+
@app.call(env)
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
require "log4r"
|
|
2
|
+
|
|
3
|
+
module Vagrant
|
|
4
|
+
module Action
|
|
5
|
+
module Builtin
|
|
6
|
+
# This middleware class will attempt to perform a graceful shutdown
|
|
7
|
+
# of the machine using the guest implementation. This middleware is
|
|
8
|
+
# compatible with the {Call} middleware so you can branch based on
|
|
9
|
+
# the result, which is true if the halt succeeded and false otherwise.
|
|
10
|
+
class GracefulHalt
|
|
11
|
+
# Note: Any of the arguments can be arrays as well.
|
|
12
|
+
#
|
|
13
|
+
# @param [Symbol] target_state The target state ID that means that
|
|
14
|
+
# the machine was properly shut down.
|
|
15
|
+
# @param [Symbol] source_state The source state ID that the machine
|
|
16
|
+
# must be in to be shut down.
|
|
17
|
+
def initialize(app, env, target_state, source_state=nil)
|
|
18
|
+
@app = app
|
|
19
|
+
@logger = Log4r::Logger.new("vagrant::action::builtin::graceful_halt")
|
|
20
|
+
@source_state = source_state
|
|
21
|
+
@target_state = target_state
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def call(env)
|
|
25
|
+
graceful = true
|
|
26
|
+
graceful = !env[:force_halt] if env.has_key?(:force_halt)
|
|
27
|
+
|
|
28
|
+
# By default, we didn't succeed.
|
|
29
|
+
env[:result] = false
|
|
30
|
+
|
|
31
|
+
if graceful && @source_state
|
|
32
|
+
@logger.info("Verifying source state of machine: #{@source_state.inspect}")
|
|
33
|
+
|
|
34
|
+
# If we're not in the proper source state, then we don't
|
|
35
|
+
# attempt to halt the machine
|
|
36
|
+
current_state = env[:machine].state.id
|
|
37
|
+
if current_state != @source_state
|
|
38
|
+
@logger.info("Invalid source state, not halting: #{current_state}")
|
|
39
|
+
graceful = false
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# Only attempt to perform graceful shutdown under certain cases
|
|
44
|
+
# checked above.
|
|
45
|
+
if graceful
|
|
46
|
+
env[:ui].info I18n.t("vagrant.actions.vm.halt.graceful")
|
|
47
|
+
env[:machine].guest.capability(:halt)
|
|
48
|
+
|
|
49
|
+
@logger.debug("Waiting for target graceful halt state: #{@target_state}")
|
|
50
|
+
count = 0
|
|
51
|
+
while env[:machine].state.id != @target_state
|
|
52
|
+
count += 1
|
|
53
|
+
return if count >= env[:machine].config.vm.graceful_halt_retry_count
|
|
54
|
+
sleep env[:machine].config.vm.graceful_halt_retry_interval
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# The result of this matters on whether we reached our
|
|
58
|
+
# proper target state or not.
|
|
59
|
+
env[:result] = env[:machine].state.id == @target_state
|
|
60
|
+
|
|
61
|
+
if env[:result]
|
|
62
|
+
@logger.info("Gracefully halted.")
|
|
63
|
+
else
|
|
64
|
+
@logger.info("Graceful halt failed.")
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
@app.call(env)
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
require "thread"
|
|
2
|
+
|
|
3
|
+
module Vagrant
|
|
4
|
+
module Action
|
|
5
|
+
module Builtin
|
|
6
|
+
# This built-in middleware handles the `box_url` setting, downloading
|
|
7
|
+
# the box if necessary. You should place this early in your middleware
|
|
8
|
+
# sequence for a provider after configuration validation but before
|
|
9
|
+
# you attempt to use any box.
|
|
10
|
+
class HandleBoxUrl
|
|
11
|
+
@@big_lock = Mutex.new
|
|
12
|
+
@@handle_box_url_locks = Hash.new { |h,k| h[k] = Mutex.new }
|
|
13
|
+
|
|
14
|
+
def initialize(app, env)
|
|
15
|
+
@app = app
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def call(env)
|
|
19
|
+
if !env[:machine].box
|
|
20
|
+
# Get a "big lock" to make sure that our more fine grained
|
|
21
|
+
# lock access is thread safe.
|
|
22
|
+
lock = nil
|
|
23
|
+
@@big_lock.synchronize do
|
|
24
|
+
lock = @@handle_box_url_locks[env[:machine].config.vm.box]
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# We can assume a box URL is set because the Vagrantfile
|
|
28
|
+
# validation should do this for us. If not, though, we do
|
|
29
|
+
# raise a terrible runtime error.
|
|
30
|
+
box_name = env[:machine].config.vm.box
|
|
31
|
+
box_url = env[:machine].config.vm.box_url
|
|
32
|
+
|
|
33
|
+
lock.synchronize do
|
|
34
|
+
# First see if we actually have the box now.
|
|
35
|
+
has_box = false
|
|
36
|
+
|
|
37
|
+
formats = env[:machine].provider_options[:box_format] ||
|
|
38
|
+
env[:machine].provider_name
|
|
39
|
+
[formats].flatten.each do |format|
|
|
40
|
+
if env[:box_collection].find(box_name, format)
|
|
41
|
+
has_box = true
|
|
42
|
+
break
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
if !has_box
|
|
47
|
+
# Add the box then reload the box collection so that it becomes
|
|
48
|
+
# aware of it.
|
|
49
|
+
env[:ui].info I18n.t(
|
|
50
|
+
"vagrant.actions.vm.check_box.not_found",
|
|
51
|
+
:name => box_name,
|
|
52
|
+
:provider => env[:machine].provider_name)
|
|
53
|
+
|
|
54
|
+
begin
|
|
55
|
+
env[:action_runner].run(Vagrant::Action.action_box_add, {
|
|
56
|
+
:box_name => box_name,
|
|
57
|
+
:box_provider => env[:machine].provider_name,
|
|
58
|
+
:box_url => box_url
|
|
59
|
+
})
|
|
60
|
+
rescue Errors::BoxAlreadyExists
|
|
61
|
+
# Just ignore this, since it means the next part will succeed!
|
|
62
|
+
# This can happen in a multi-threaded environment.
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
# Reload the environment and set the VM to be the new loaded VM.
|
|
68
|
+
env[:machine] = env[:machine].env.machine(
|
|
69
|
+
env[:machine].name, env[:machine].provider_name, true)
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
@app.call(env)
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
end
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
require "set"
|
|
2
|
+
|
|
3
|
+
require "log4r"
|
|
4
|
+
|
|
5
|
+
require "vagrant/util/is_port_open"
|
|
6
|
+
|
|
7
|
+
module Vagrant
|
|
8
|
+
module Action
|
|
9
|
+
module Builtin
|
|
10
|
+
# This middleware class will detect and handle collisions with
|
|
11
|
+
# forwarded ports, whether that means raising an error or repairing
|
|
12
|
+
# them automatically.
|
|
13
|
+
#
|
|
14
|
+
# Parameters it takes from the environment hash:
|
|
15
|
+
#
|
|
16
|
+
# * `:port_collision_repair` - If true, it will attempt to repair
|
|
17
|
+
# port collisions. If false, it will raise an exception when
|
|
18
|
+
# there is a collision.
|
|
19
|
+
#
|
|
20
|
+
# * `:port_collision_extra_in_use` - An array of ports that are
|
|
21
|
+
# considered in use.
|
|
22
|
+
#
|
|
23
|
+
# * `:port_collision_remap` - A hash remapping certain host ports
|
|
24
|
+
# to other host ports.
|
|
25
|
+
#
|
|
26
|
+
class HandleForwardedPortCollisions
|
|
27
|
+
include Util::IsPortOpen
|
|
28
|
+
|
|
29
|
+
def initialize(app, env)
|
|
30
|
+
@app = app
|
|
31
|
+
@logger = Log4r::Logger.new("vagrant::action::builtin::handle_port_collisions")
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def call(env)
|
|
35
|
+
@logger.info("Detecting any forwarded port collisions...")
|
|
36
|
+
|
|
37
|
+
# Get the extra ports we consider in use
|
|
38
|
+
extra_in_use = env[:port_collision_extra_in_use] || []
|
|
39
|
+
|
|
40
|
+
# Get the remap
|
|
41
|
+
remap = env[:port_collision_remap] || {}
|
|
42
|
+
|
|
43
|
+
# Determine the handler we'll use if we have any port collisions
|
|
44
|
+
repair = !!env[:port_collision_repair]
|
|
45
|
+
|
|
46
|
+
# Log out some of our parameters
|
|
47
|
+
@logger.debug("Extra in use: #{extra_in_use.inspect}")
|
|
48
|
+
@logger.debug("Remap: #{remap.inspect}")
|
|
49
|
+
@logger.debug("Repair: #{repair.inspect}")
|
|
50
|
+
|
|
51
|
+
# Determine a list of usable ports for repair
|
|
52
|
+
usable_ports = Set.new(env[:machine].config.vm.usable_port_range)
|
|
53
|
+
usable_ports.subtract(extra_in_use)
|
|
54
|
+
|
|
55
|
+
# Pass one, remove all defined host ports from usable ports
|
|
56
|
+
with_forwarded_ports(env) do |options|
|
|
57
|
+
usable_ports.delete(options[:host])
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
# Pass two, detect/handle any collisions
|
|
61
|
+
with_forwarded_ports(env) do |options|
|
|
62
|
+
guest_port = options[:guest]
|
|
63
|
+
host_port = options[:host]
|
|
64
|
+
|
|
65
|
+
if remap[host_port]
|
|
66
|
+
remap_port = remap[host_port]
|
|
67
|
+
@logger.debug("Remap port override: #{host_port} => #{remap_port}")
|
|
68
|
+
host_port = remap_port
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
# If the port is open (listening for TCP connections)
|
|
72
|
+
if extra_in_use.include?(host_port) || is_port_open?("127.0.0.1", host_port)
|
|
73
|
+
if !repair
|
|
74
|
+
raise Errors::ForwardPortCollision,
|
|
75
|
+
:guest_port => guest_port.to_s,
|
|
76
|
+
:host_port => host_port.to_s
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
@logger.info("Attempting to repair FP collision: #{host_port}")
|
|
80
|
+
|
|
81
|
+
repaired_port = nil
|
|
82
|
+
while !usable_ports.empty?
|
|
83
|
+
# Attempt to repair the forwarded port
|
|
84
|
+
repaired_port = usable_ports.to_a.sort[0]
|
|
85
|
+
usable_ports.delete(repaired_port)
|
|
86
|
+
|
|
87
|
+
# If the port is in use, then we can't use this either...
|
|
88
|
+
if extra_in_use.include?(repaired_port) || is_port_open?("127.0.0.1", repaired_port)
|
|
89
|
+
@logger.info("Reparied port also in use: #{repaired_port}. Trying another...")
|
|
90
|
+
next
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
# We have a port so break out
|
|
94
|
+
break
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
# If we have no usable ports then we can't repair
|
|
98
|
+
if !repaired_port && usable_ports.empty?
|
|
99
|
+
raise Errors::ForwardPortAutolistEmpty,
|
|
100
|
+
:vm_name => env[:machine].name,
|
|
101
|
+
:guest_port => guest_port.to_s,
|
|
102
|
+
:host_port => host_port.to_s
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
# Modify the args in place
|
|
106
|
+
options[:host] = repaired_port
|
|
107
|
+
|
|
108
|
+
@logger.info("Repaired FP collision: #{host_port} to #{repaired_port}")
|
|
109
|
+
|
|
110
|
+
# Notify the user
|
|
111
|
+
env[:ui].info(I18n.t("vagrant.actions.vm.forward_ports.fixed_collision",
|
|
112
|
+
:host_port => host_port.to_s,
|
|
113
|
+
:guest_port => guest_port.to_s,
|
|
114
|
+
:new_port => repaired_port.to_s))
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
@app.call(env)
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
protected
|
|
122
|
+
|
|
123
|
+
def with_forwarded_ports(env)
|
|
124
|
+
env[:machine].config.vm.networks.each do |type, options|
|
|
125
|
+
# Ignore anything but forwarded ports
|
|
126
|
+
next if type != :forwarded_port
|
|
127
|
+
|
|
128
|
+
yield options
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
end
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
require "log4r"
|
|
2
|
+
|
|
3
|
+
module Vagrant
|
|
4
|
+
module Action
|
|
5
|
+
module Builtin
|
|
6
|
+
# This class creates a multi-process lock using `flock`. The lock
|
|
7
|
+
# is active for the remainder of the middleware stack.
|
|
8
|
+
class Lock
|
|
9
|
+
def initialize(app, env, options=nil)
|
|
10
|
+
@app = app
|
|
11
|
+
@logger = Log4r::Logger.new("vagrant::action::builtin::lock")
|
|
12
|
+
@options ||= options || {}
|
|
13
|
+
raise ArgumentError, "Please specify a lock path" if !@options[:path]
|
|
14
|
+
raise ArgumentError, "Please specify an exception." if !@options[:exception]
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def call(env)
|
|
18
|
+
lock_path = @options[:path]
|
|
19
|
+
lock_path = lock_path.call(env) if lock_path.is_a?(Proc)
|
|
20
|
+
|
|
21
|
+
env_key = "has_lock_#{lock_path}"
|
|
22
|
+
|
|
23
|
+
if !env[env_key]
|
|
24
|
+
# If we already have the key in our environment we assume the
|
|
25
|
+
# lock is held by our middleware stack already and we allow
|
|
26
|
+
# nesting.
|
|
27
|
+
File.open(lock_path, "w+") do |f|
|
|
28
|
+
# The file locking fails only if it returns "false." If it
|
|
29
|
+
# succeeds it returns a 0, so we must explicitly check for
|
|
30
|
+
# the proper error case.
|
|
31
|
+
@logger.info("Locking: #{lock_path}")
|
|
32
|
+
if f.flock(File::LOCK_EX | File::LOCK_NB) === false
|
|
33
|
+
exception = @options[:exception]
|
|
34
|
+
exception = exception.call(env) if exception.is_a?(Proc)
|
|
35
|
+
raise exception
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# Set that we gained the lock and call deeper into the
|
|
39
|
+
# middleware, but make sure we UNSET the lock when we leave.
|
|
40
|
+
begin
|
|
41
|
+
env[env_key] = true
|
|
42
|
+
@app.call(env)
|
|
43
|
+
ensure
|
|
44
|
+
@logger.info("Unlocking: #{lock_path}")
|
|
45
|
+
env[env_key] = false
|
|
46
|
+
f.flock(File::LOCK_UN)
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
else
|
|
50
|
+
# Just call up the middleware because we already hold the lock
|
|
51
|
+
@app.call(env)
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
require 'digest/md5'
|
|
2
|
+
require 'fileutils'
|
|
3
|
+
require 'pathname'
|
|
4
|
+
|
|
5
|
+
require "log4r"
|
|
6
|
+
|
|
7
|
+
module Vagrant
|
|
8
|
+
module Action
|
|
9
|
+
module Builtin
|
|
10
|
+
# This built-in middleware exports and mounts NFS shared folders.
|
|
11
|
+
#
|
|
12
|
+
# To use this middleware, two configuration parameters must be given
|
|
13
|
+
# via the environment hash:
|
|
14
|
+
#
|
|
15
|
+
# - `:nfs_host_ip` - The IP of where to mount the NFS folder from.
|
|
16
|
+
# - `:nfs_machine_ip` - The IP of the machine where the NFS folder
|
|
17
|
+
# will be mounted.
|
|
18
|
+
#
|
|
19
|
+
class NFS
|
|
20
|
+
def initialize(app, env)
|
|
21
|
+
@app = app
|
|
22
|
+
@logger = Log4r::Logger.new("vagrant::action::builtin::nfs")
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def call(env)
|
|
26
|
+
# We forward things along first. We do everything on the tail
|
|
27
|
+
# end of the middleware call.
|
|
28
|
+
@app.call(env)
|
|
29
|
+
|
|
30
|
+
# Used by prepare_permission, so we need to save it
|
|
31
|
+
@env = env
|
|
32
|
+
|
|
33
|
+
folders = {}
|
|
34
|
+
env[:machine].config.vm.synced_folders.each do |id, opts|
|
|
35
|
+
# If this synced folder doesn't enable NFS, ignore it.
|
|
36
|
+
next if !opts[:nfs]
|
|
37
|
+
|
|
38
|
+
# Expand the host path, create it if we have to and
|
|
39
|
+
# store away the folder.
|
|
40
|
+
hostpath = Pathname.new(opts[:hostpath]).expand_path(env[:root_path])
|
|
41
|
+
|
|
42
|
+
if !hostpath.directory? && opts[:create]
|
|
43
|
+
# Host path doesn't exist, so let's create it.
|
|
44
|
+
@logger.debug("Host path doesn't exist, creating: #{hostpath}")
|
|
45
|
+
|
|
46
|
+
begin
|
|
47
|
+
FileUtils.mkpath(hostpath)
|
|
48
|
+
rescue Errno::EACCES
|
|
49
|
+
raise Vagrant::Errors::SharedFolderCreateFailed,
|
|
50
|
+
:path => hostpath.to_s
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# Set the hostpath back on the options and save it
|
|
55
|
+
opts[:hostpath] = hostpath.to_s
|
|
56
|
+
folders[id] = opts
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
if !folders.empty?
|
|
60
|
+
raise Errors::NFSNoHostIP if !env[:nfs_host_ip]
|
|
61
|
+
raise Errors::NFSNoGuestIP if !env[:nfs_machine_ip]
|
|
62
|
+
|
|
63
|
+
# Prepare the folder, this means setting up various options
|
|
64
|
+
# and such on the folder itself.
|
|
65
|
+
folders.each { |id, opts| prepare_folder(opts) }
|
|
66
|
+
|
|
67
|
+
# Export the folders
|
|
68
|
+
env[:ui].info I18n.t("vagrant.actions.vm.nfs.exporting")
|
|
69
|
+
env[:host].nfs_export(env[:machine].id, env[:nfs_machine_ip], folders)
|
|
70
|
+
|
|
71
|
+
# Mount
|
|
72
|
+
env[:ui].info I18n.t("vagrant.actions.vm.nfs.mounting")
|
|
73
|
+
|
|
74
|
+
# Only mount folders that have a guest path specified.
|
|
75
|
+
mount_folders = {}
|
|
76
|
+
folders.each do |id, opts|
|
|
77
|
+
mount_folders[id] = opts.dup if opts[:guestpath]
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
# Mount them!
|
|
81
|
+
env[:machine].guest.capability(
|
|
82
|
+
:mount_nfs_folder, env[:nfs_host_ip], mount_folders)
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
protected
|
|
87
|
+
|
|
88
|
+
def prepare_folder(opts)
|
|
89
|
+
opts[:map_uid] = prepare_permission(:uid, opts)
|
|
90
|
+
opts[:map_gid] = prepare_permission(:gid, opts)
|
|
91
|
+
opts[:nfs_version] ||= 3
|
|
92
|
+
|
|
93
|
+
# The poor man's UUID. An MD5 hash here is sufficient since
|
|
94
|
+
# we need a 32 character "uuid" to represent the filesystem
|
|
95
|
+
# of an export. Hashing the host path is safe because two of
|
|
96
|
+
# the same host path will hash to the same fsid.
|
|
97
|
+
opts[:uuid] = Digest::MD5.hexdigest(opts[:hostpath])
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
# Prepares the UID/GID settings for a single folder.
|
|
101
|
+
def prepare_permission(perm, opts)
|
|
102
|
+
key = "map_#{perm}".to_sym
|
|
103
|
+
return nil if opts.has_key?(key) && opts[key].nil?
|
|
104
|
+
|
|
105
|
+
# The options on the hash get priority, then the default
|
|
106
|
+
# values
|
|
107
|
+
value = opts.has_key?(key) ? opts[key] : @env[:machine].config.nfs.send(key)
|
|
108
|
+
return value if value != :auto
|
|
109
|
+
|
|
110
|
+
# Get UID/GID from folder if we've made it this far
|
|
111
|
+
# (value == :auto)
|
|
112
|
+
stat = File.stat(opts[:hostpath])
|
|
113
|
+
return stat.send(perm)
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
end
|