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,150 @@
|
|
|
1
|
+
require "log4r"
|
|
2
|
+
|
|
3
|
+
require "vagrant/util/file_mode"
|
|
4
|
+
require "vagrant/util/platform"
|
|
5
|
+
require "vagrant/util/safe_exec"
|
|
6
|
+
require "vagrant/util/subprocess"
|
|
7
|
+
require "vagrant/util/which"
|
|
8
|
+
|
|
9
|
+
module Vagrant
|
|
10
|
+
module Util
|
|
11
|
+
# This is a class that has helpers on it for dealing with SSH. These
|
|
12
|
+
# helpers don't depend on any part of Vagrant except what is given
|
|
13
|
+
# via the parameters.
|
|
14
|
+
class SSH
|
|
15
|
+
LOGGER = Log4r::Logger.new("vagrant::util::ssh")
|
|
16
|
+
|
|
17
|
+
# Checks that the permissions for a private key are valid, and fixes
|
|
18
|
+
# them if possible. SSH requires that permissions on the private key
|
|
19
|
+
# are 0600 on POSIX based systems. This will make a best effort to
|
|
20
|
+
# fix these permissions if they are not properly set.
|
|
21
|
+
#
|
|
22
|
+
# @param [Pathname] key_path The path to the private key.
|
|
23
|
+
def self.check_key_permissions(key_path)
|
|
24
|
+
# Don't do anything if we're on Windows, since Windows doesn't worry
|
|
25
|
+
# about key permissions.
|
|
26
|
+
return if Platform.windows?
|
|
27
|
+
|
|
28
|
+
LOGGER.debug("Checking key permissions: #{key_path}")
|
|
29
|
+
stat = key_path.stat
|
|
30
|
+
|
|
31
|
+
if !stat.owned?
|
|
32
|
+
# The SSH key must be owned by ourselves
|
|
33
|
+
raise Errors::SSHKeyBadOwner, :key_path => key_path
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
if FileMode.from_octal(stat.mode) != "600"
|
|
37
|
+
LOGGER.info("Attempting to correct key permissions to 0600")
|
|
38
|
+
key_path.chmod(0600)
|
|
39
|
+
|
|
40
|
+
# Re-stat the file to get the new mode, and verify it worked
|
|
41
|
+
stat = key_path.stat
|
|
42
|
+
if FileMode.from_octal(stat.mode) != "600"
|
|
43
|
+
raise Errors::SSHKeyBadPermissions, :key_path => key_path
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
rescue Errno::EPERM
|
|
47
|
+
# This shouldn't happen since we verify we own the file, but
|
|
48
|
+
# it is possible in theory, so we raise an error.
|
|
49
|
+
raise Errors::SSHKeyBadPermissions, :key_path => key_path
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# Halts the running of this process and replaces it with a full-fledged
|
|
53
|
+
# SSH shell into a remote machine.
|
|
54
|
+
#
|
|
55
|
+
# Note: This method NEVER returns. The process ends after this.
|
|
56
|
+
#
|
|
57
|
+
# @param [Hash] ssh_info This is the SSH information. For the keys
|
|
58
|
+
# required please see the documentation of {Machine#ssh_info}.
|
|
59
|
+
# @param [Hash] opts These are additional options that are supported
|
|
60
|
+
# by exec.
|
|
61
|
+
def self.exec(ssh_info, opts={})
|
|
62
|
+
# Ensure the platform supports ssh. On Windows there are several programs which
|
|
63
|
+
# include ssh, notably git, mingw and cygwin, but make sure ssh is in the path!
|
|
64
|
+
ssh_path = Which.which("ssh")
|
|
65
|
+
if !ssh_path
|
|
66
|
+
if Platform.windows?
|
|
67
|
+
raise Errors::SSHUnavailableWindows,
|
|
68
|
+
:host => ssh_info[:host],
|
|
69
|
+
:port => ssh_info[:port],
|
|
70
|
+
:username => ssh_info[:username],
|
|
71
|
+
:key_path => ssh_info[:private_key_path]
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
raise Errors::SSHUnavailable
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
# On Windows, we need to detect whether SSH is actually "plink"
|
|
78
|
+
# underneath the covers. In this case, we tell the user.
|
|
79
|
+
if Platform.windows?
|
|
80
|
+
r = Subprocess.execute(ssh_path)
|
|
81
|
+
if r.stdout.include?("PuTTY Link")
|
|
82
|
+
raise Errors::SSHIsPuttyLink,
|
|
83
|
+
:host => ssh_info[:host],
|
|
84
|
+
:port => ssh_info[:port],
|
|
85
|
+
:username => ssh_info[:username],
|
|
86
|
+
:key_path => ssh_info[:private_key_path]
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
# If plain mode is enabled then we don't do any authentication (we don't
|
|
91
|
+
# set a user or an identity file)
|
|
92
|
+
plain_mode = opts[:plain_mode]
|
|
93
|
+
|
|
94
|
+
options = {}
|
|
95
|
+
options[:host] = ssh_info[:host]
|
|
96
|
+
options[:port] = ssh_info[:port]
|
|
97
|
+
options[:username] = ssh_info[:username]
|
|
98
|
+
options[:private_key_path] = ssh_info[:private_key_path]
|
|
99
|
+
|
|
100
|
+
# Command line options
|
|
101
|
+
command_options = [
|
|
102
|
+
"-p", options[:port].to_s,
|
|
103
|
+
"-o", "LogLevel=FATAL",
|
|
104
|
+
"-o", "StrictHostKeyChecking=no",
|
|
105
|
+
"-o", "UserKnownHostsFile=/dev/null"]
|
|
106
|
+
|
|
107
|
+
# Solaris/OpenSolaris/Illumos uses SunSSH which doesn't support the
|
|
108
|
+
# IdentitiesOnly option. Also, we don't enable it in plain mode so
|
|
109
|
+
# that SSH properly searches our identities and tries to do it itself.
|
|
110
|
+
if !Platform.solaris? && !plain_mode
|
|
111
|
+
command_options += ["-o", "IdentitiesOnly=yes"]
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
# If we're not in plain mode, attach the private key path.
|
|
115
|
+
command_options += ["-i", options[:private_key_path].to_s] if !plain_mode
|
|
116
|
+
|
|
117
|
+
if ssh_info[:forward_x11]
|
|
118
|
+
# Both are required so that no warnings are shown regarding X11
|
|
119
|
+
command_options += [
|
|
120
|
+
"-o", "ForwardX11=yes",
|
|
121
|
+
"-o", "ForwardX11Trusted=yes"]
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
# Configurables -- extra_args should always be last due to the way the
|
|
125
|
+
# ssh args parser works. e.g. if the user wants to use the -t option,
|
|
126
|
+
# any shell command(s) she'd like to run on the remote server would
|
|
127
|
+
# have to be the last part of the 'ssh' command:
|
|
128
|
+
#
|
|
129
|
+
# $ ssh localhost -t -p 2222 "cd mydirectory; bash"
|
|
130
|
+
#
|
|
131
|
+
# Without having extra_args be last, the user loses this ability
|
|
132
|
+
command_options += ["-o", "ForwardAgent=yes"] if ssh_info[:forward_agent]
|
|
133
|
+
command_options.concat(opts[:extra_args]) if opts[:extra_args]
|
|
134
|
+
|
|
135
|
+
# Build up the host string for connecting
|
|
136
|
+
host_string = options[:host]
|
|
137
|
+
host_string = "#{options[:username]}@#{host_string}" if !plain_mode
|
|
138
|
+
command_options.unshift(host_string)
|
|
139
|
+
|
|
140
|
+
# On Cygwin we want to get rid of any DOS file warnings because
|
|
141
|
+
# we really don't care since both work.
|
|
142
|
+
ENV["nodosfilewarning"] = "1" if Platform.cygwin?
|
|
143
|
+
|
|
144
|
+
# Invoke SSH with all our options
|
|
145
|
+
LOGGER.info("Invoking SSH: #{command_options.inspect}")
|
|
146
|
+
SafeExec.exec("ssh", *command_options)
|
|
147
|
+
end
|
|
148
|
+
end
|
|
149
|
+
end
|
|
150
|
+
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
module Vagrant
|
|
2
|
+
module Util
|
|
3
|
+
# Represents the "stacked proc runner" behavior which is used a
|
|
4
|
+
# couple places within Vagrant. This allows procs to "stack" on
|
|
5
|
+
# each other, then all execute in a single action. An example of
|
|
6
|
+
# its uses can be seen in the {Config} class.
|
|
7
|
+
module StackedProcRunner
|
|
8
|
+
# Returns the proc stack. This should always be called as the
|
|
9
|
+
# accessor of the stack. The instance variable itself should _never_
|
|
10
|
+
# be used.
|
|
11
|
+
#
|
|
12
|
+
# @return [Array<Proc>]
|
|
13
|
+
def proc_stack
|
|
14
|
+
@_proc_stack ||= []
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# Adds (pushes) a proc to the stack. The actual proc added here is
|
|
18
|
+
# not executed, but merely stored.
|
|
19
|
+
#
|
|
20
|
+
# @param [Proc] block
|
|
21
|
+
def push_proc(&block)
|
|
22
|
+
proc_stack << block
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# Executes all the procs on the stack, passing in the given arguments.
|
|
26
|
+
# The stack is not cleared afterwords. It is up to the user of this
|
|
27
|
+
# mixin to clear the stack by calling `proc_stack.clear`.
|
|
28
|
+
def run_procs!(*args)
|
|
29
|
+
proc_stack.each do |proc|
|
|
30
|
+
proc.call(*args)
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
module Vagrant
|
|
2
|
+
module Util
|
|
3
|
+
# This class modifies strings by creating and managing Vagrant-owned
|
|
4
|
+
# "blocks" via wrapping them in specially formed comments.
|
|
5
|
+
#
|
|
6
|
+
# This is useful when modifying a file that someone else owns and adding
|
|
7
|
+
# automatic entries into it. Example: /etc/exports or some other
|
|
8
|
+
# configuration file.
|
|
9
|
+
#
|
|
10
|
+
# Vagrant marks ownership of a block in the string by wrapping it in
|
|
11
|
+
# VAGRANT-BEGIN and VAGRANT-END comments with a unique ID. Example:
|
|
12
|
+
#
|
|
13
|
+
# foo
|
|
14
|
+
# # VAGRANT-BEGIN: id
|
|
15
|
+
# some contents
|
|
16
|
+
# created by vagrant
|
|
17
|
+
# # VAGRANT-END: id
|
|
18
|
+
#
|
|
19
|
+
# The goal of this class is to be able to insert and remove these
|
|
20
|
+
# blocks without modifying anything else in the string.
|
|
21
|
+
#
|
|
22
|
+
# The strings usually come from files but it is up to the caller to
|
|
23
|
+
# manage the file resource.
|
|
24
|
+
class StringBlockEditor
|
|
25
|
+
# The current string value. This is the value that is modified by
|
|
26
|
+
# the methods below.
|
|
27
|
+
#
|
|
28
|
+
# @return [String]
|
|
29
|
+
attr_reader :value
|
|
30
|
+
|
|
31
|
+
def initialize(string)
|
|
32
|
+
@value = string
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# This returns the keys (or ids) that are in the string.
|
|
36
|
+
#
|
|
37
|
+
# @return [<Array<String>]
|
|
38
|
+
def keys
|
|
39
|
+
regexp = /^#\s*VAGRANT-BEGIN:\s*(.+?)$\r?\n?(.*)$\r?\n?^#\s*VAGRANT-END:\s(\1)$/m
|
|
40
|
+
@value.scan(regexp).map do |match|
|
|
41
|
+
match[0]
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# This deletes the block with the given key if it exists.
|
|
46
|
+
def delete(key)
|
|
47
|
+
key = Regexp.quote(key)
|
|
48
|
+
regexp = /^#\s*VAGRANT-BEGIN:\s*#{key}$.*^#\s*VAGRANT-END:\s*#{key}$\r?\n?/m
|
|
49
|
+
@value.gsub!(regexp, "")
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# This gets the value of the block with the given key.
|
|
53
|
+
def get(key)
|
|
54
|
+
key = Regexp.quote(key)
|
|
55
|
+
regexp = /^#\s*VAGRANT-BEGIN:\s*#{key}$\r?\n?(.*?)\r?\n?^#\s*VAGRANT-END:\s*#{key}$\r?\n?/m
|
|
56
|
+
match = regexp.match(@value)
|
|
57
|
+
return nil if !match
|
|
58
|
+
match[1]
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# This inserts a block with the given key and value.
|
|
62
|
+
#
|
|
63
|
+
# @param [String] key
|
|
64
|
+
# @param [String] value
|
|
65
|
+
def insert(key, value)
|
|
66
|
+
# Insert the new block into the value
|
|
67
|
+
new_block = <<BLOCK
|
|
68
|
+
# VAGRANT-BEGIN: #{key}
|
|
69
|
+
#{value.strip}
|
|
70
|
+
# VAGRANT-END: #{key}
|
|
71
|
+
BLOCK
|
|
72
|
+
|
|
73
|
+
@value << new_block
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
end
|
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
require 'thread'
|
|
2
|
+
|
|
3
|
+
require 'childprocess'
|
|
4
|
+
require 'log4r'
|
|
5
|
+
|
|
6
|
+
require 'vagrant/util/platform'
|
|
7
|
+
require 'vagrant/util/safe_chdir'
|
|
8
|
+
|
|
9
|
+
module Vagrant
|
|
10
|
+
module Util
|
|
11
|
+
# Execute a command in a subprocess, gathering the results and
|
|
12
|
+
# exit status.
|
|
13
|
+
#
|
|
14
|
+
# This class also allows you to read the data as it is outputted
|
|
15
|
+
# from the subprocess in real time, by simply passing a block to
|
|
16
|
+
# the execute method.
|
|
17
|
+
class Subprocess
|
|
18
|
+
# The chunk size for reading from subprocess IO.
|
|
19
|
+
READ_CHUNK_SIZE = 4096
|
|
20
|
+
|
|
21
|
+
# Convenience method for executing a method.
|
|
22
|
+
def self.execute(*command, &block)
|
|
23
|
+
new(*command).execute(&block)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def initialize(*command)
|
|
27
|
+
@options = command.last.is_a?(Hash) ? command.pop : {}
|
|
28
|
+
@command = command
|
|
29
|
+
@logger = Log4r::Logger.new("vagrant::util::subprocess")
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def execute
|
|
33
|
+
# Get the timeout, if we have one
|
|
34
|
+
timeout = @options[:timeout]
|
|
35
|
+
|
|
36
|
+
# Get the working directory
|
|
37
|
+
workdir = @options[:workdir] || Dir.pwd
|
|
38
|
+
|
|
39
|
+
# Get what we're interested in being notified about
|
|
40
|
+
notify = @options[:notify] || []
|
|
41
|
+
notify = [notify] if !notify.is_a?(Array)
|
|
42
|
+
if notify.empty? && block_given?
|
|
43
|
+
# If a block is given, subscribers must be given, otherwise the
|
|
44
|
+
# block is never called. This is usually NOT what you want, so this
|
|
45
|
+
# is an error.
|
|
46
|
+
message = "A list of notify subscriptions must be given if a block is given"
|
|
47
|
+
raise ArgumentError, message
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# Let's get some more useful booleans that we access a lot so
|
|
51
|
+
# we're not constantly calling an `include` check
|
|
52
|
+
notify_table = {}
|
|
53
|
+
notify_table[:stderr] = notify.include?(:stderr)
|
|
54
|
+
notify_table[:stdout] = notify.include?(:stdout)
|
|
55
|
+
notify_stdin = notify.include?(:stdin)
|
|
56
|
+
|
|
57
|
+
# Build the ChildProcess
|
|
58
|
+
@logger.info("Starting process: #{@command.inspect}")
|
|
59
|
+
process = ChildProcess.build(*@command)
|
|
60
|
+
|
|
61
|
+
# Create the pipes so we can read the output in real time as
|
|
62
|
+
# we execute the command.
|
|
63
|
+
stdout, stdout_writer = IO.pipe
|
|
64
|
+
stderr, stderr_writer = IO.pipe
|
|
65
|
+
process.io.stdout = stdout_writer
|
|
66
|
+
process.io.stderr = stderr_writer
|
|
67
|
+
process.duplex = true
|
|
68
|
+
|
|
69
|
+
# Set the environment on the process if we must
|
|
70
|
+
if @options[:env]
|
|
71
|
+
@options[:env].each do |k, v|
|
|
72
|
+
process.environment[k] = v
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
# Start the process
|
|
77
|
+
begin
|
|
78
|
+
SafeChdir.safe_chdir(workdir) do
|
|
79
|
+
process.start
|
|
80
|
+
end
|
|
81
|
+
rescue ChildProcess::LaunchError => ex
|
|
82
|
+
# Raise our own version of the error so that users of the class
|
|
83
|
+
# don't need to be aware of ChildProcess
|
|
84
|
+
raise LaunchError.new(ex.message)
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
# Make sure the stdin does not buffer
|
|
88
|
+
process.io.stdin.sync = true
|
|
89
|
+
|
|
90
|
+
if RUBY_PLATFORM != "java"
|
|
91
|
+
# On Java, we have to close after. See down the method...
|
|
92
|
+
# Otherwise, we close the writers right here, since we're
|
|
93
|
+
# not on the writing side.
|
|
94
|
+
stdout_writer.close
|
|
95
|
+
stderr_writer.close
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
# Create a dictionary to store all the output we see.
|
|
99
|
+
io_data = { :stdout => "", :stderr => "" }
|
|
100
|
+
|
|
101
|
+
# Record the start time for timeout purposes
|
|
102
|
+
start_time = Time.now.to_i
|
|
103
|
+
|
|
104
|
+
@logger.debug("Selecting on IO")
|
|
105
|
+
while true
|
|
106
|
+
writers = notify_stdin ? [process.io.stdin] : []
|
|
107
|
+
results = IO.select([stdout, stderr], writers, nil, timeout || 0.1)
|
|
108
|
+
results ||= []
|
|
109
|
+
readers = results[0]
|
|
110
|
+
writers = results[1]
|
|
111
|
+
|
|
112
|
+
# Check if we have exceeded our timeout
|
|
113
|
+
raise TimeoutExceeded, process.pid if timeout && (Time.now.to_i - start_time) > timeout
|
|
114
|
+
|
|
115
|
+
# Check the readers to see if they're ready
|
|
116
|
+
if readers && !readers.empty?
|
|
117
|
+
readers.each do |r|
|
|
118
|
+
# Read from the IO object
|
|
119
|
+
data = read_io(r)
|
|
120
|
+
|
|
121
|
+
# We don't need to do anything if the data is empty
|
|
122
|
+
next if data.empty?
|
|
123
|
+
|
|
124
|
+
io_name = r == stdout ? :stdout : :stderr
|
|
125
|
+
@logger.debug("#{io_name}: #{data.chomp}")
|
|
126
|
+
|
|
127
|
+
io_data[io_name] += data
|
|
128
|
+
yield io_name, data if block_given? && notify_table[io_name]
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
# Break out if the process exited. We have to do this before
|
|
133
|
+
# attempting to write to stdin otherwise we'll get a broken pipe
|
|
134
|
+
# error.
|
|
135
|
+
break if process.exited?
|
|
136
|
+
|
|
137
|
+
# Check the writers to see if they're ready, and notify any listeners
|
|
138
|
+
if writers && !writers.empty?
|
|
139
|
+
yield :stdin, process.io.stdin if block_given?
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
# Wait for the process to end.
|
|
144
|
+
begin
|
|
145
|
+
remaining = (timeout || 32000) - (Time.now.to_i - start_time)
|
|
146
|
+
remaining = 0 if remaining < 0
|
|
147
|
+
@logger.debug("Waiting for process to exit. Remaining to timeout: #{remaining}")
|
|
148
|
+
|
|
149
|
+
process.poll_for_exit(remaining)
|
|
150
|
+
rescue ChildProcess::TimeoutError
|
|
151
|
+
raise TimeoutExceeded, process.pid
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
@logger.debug("Exit status: #{process.exit_code}")
|
|
155
|
+
|
|
156
|
+
# Read the final output data, since it is possible we missed a small
|
|
157
|
+
# amount of text between the time we last read data and when the
|
|
158
|
+
# process exited.
|
|
159
|
+
[stdout, stderr].each do |io|
|
|
160
|
+
# Read the extra data, ignoring if there isn't any
|
|
161
|
+
extra_data = read_io(io)
|
|
162
|
+
next if extra_data == ""
|
|
163
|
+
|
|
164
|
+
# Log it out and accumulate
|
|
165
|
+
io_name = io == stdout ? :stdout : :stderr
|
|
166
|
+
io_data[io_name] += extra_data
|
|
167
|
+
@logger.debug("#{io_name}: #{extra_data.chomp}")
|
|
168
|
+
|
|
169
|
+
# Yield to any listeners any remaining data
|
|
170
|
+
yield io_name, extra_data if block_given?
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
if RUBY_PLATFORM == "java"
|
|
174
|
+
# On JRuby, we need to close the writers after the process,
|
|
175
|
+
# for some reason. See GH-711.
|
|
176
|
+
stdout_writer.close
|
|
177
|
+
stderr_writer.close
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
# Return an exit status container
|
|
181
|
+
return Result.new(process.exit_code, io_data[:stdout], io_data[:stderr])
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
protected
|
|
185
|
+
|
|
186
|
+
# Reads data from an IO object while it can, returning the data it reads.
|
|
187
|
+
# When it encounters a case when it can't read anymore, it returns the
|
|
188
|
+
# data.
|
|
189
|
+
#
|
|
190
|
+
# @return [String]
|
|
191
|
+
def read_io(io)
|
|
192
|
+
data = ""
|
|
193
|
+
|
|
194
|
+
while true
|
|
195
|
+
begin
|
|
196
|
+
if Platform.windows?
|
|
197
|
+
# Windows doesn't support non-blocking reads on
|
|
198
|
+
# file descriptors or pipes so we have to get
|
|
199
|
+
# a bit more creative.
|
|
200
|
+
|
|
201
|
+
# Check if data is actually ready on this IO device.
|
|
202
|
+
# We have to do this since `readpartial` will actually block
|
|
203
|
+
# until data is available, which can cause blocking forever
|
|
204
|
+
# in some cases.
|
|
205
|
+
results = IO.select([io], nil, nil, 0.1)
|
|
206
|
+
break if !results || results[0].empty?
|
|
207
|
+
|
|
208
|
+
# Read!
|
|
209
|
+
data << io.readpartial(READ_CHUNK_SIZE)
|
|
210
|
+
else
|
|
211
|
+
# Do a simple non-blocking read on the IO object
|
|
212
|
+
data << io.read_nonblock(READ_CHUNK_SIZE)
|
|
213
|
+
end
|
|
214
|
+
rescue Exception => e
|
|
215
|
+
# The catch-all rescue here is to support multiple Ruby versions,
|
|
216
|
+
# since we use some Ruby 1.9 specific exceptions.
|
|
217
|
+
|
|
218
|
+
breakable = false
|
|
219
|
+
if e.is_a?(EOFError)
|
|
220
|
+
# An `EOFError` means this IO object is done!
|
|
221
|
+
breakable = true
|
|
222
|
+
elsif defined?(IO::WaitReadable) && e.is_a?(IO::WaitReadable)
|
|
223
|
+
# IO::WaitReadable is only available on Ruby 1.9+
|
|
224
|
+
|
|
225
|
+
# An IO::WaitReadable means there may be more IO but this
|
|
226
|
+
# IO object is not ready to be read from yet. No problem,
|
|
227
|
+
# we read as much as we can, so we break.
|
|
228
|
+
breakable = true
|
|
229
|
+
elsif e.is_a?(Errno::EAGAIN)
|
|
230
|
+
# Otherwise, we just look for the EAGAIN error which should be
|
|
231
|
+
# all that IO::WaitReadable does in Ruby 1.9.
|
|
232
|
+
breakable = true
|
|
233
|
+
end
|
|
234
|
+
|
|
235
|
+
# Break out if we're supposed to. Otherwise re-raise the error
|
|
236
|
+
# because it is a real problem.
|
|
237
|
+
break if breakable
|
|
238
|
+
raise
|
|
239
|
+
end
|
|
240
|
+
end
|
|
241
|
+
|
|
242
|
+
data
|
|
243
|
+
end
|
|
244
|
+
|
|
245
|
+
# An error which raises when a process fails to start
|
|
246
|
+
class LaunchError < StandardError; end
|
|
247
|
+
|
|
248
|
+
# An error which occurs when the process doesn't end within
|
|
249
|
+
# the given timeout.
|
|
250
|
+
class TimeoutExceeded < StandardError
|
|
251
|
+
attr_reader :pid
|
|
252
|
+
|
|
253
|
+
def initialize(pid)
|
|
254
|
+
super()
|
|
255
|
+
@pid = pid
|
|
256
|
+
end
|
|
257
|
+
end
|
|
258
|
+
|
|
259
|
+
# Container class to store the results of executing a subprocess.
|
|
260
|
+
class Result
|
|
261
|
+
attr_reader :exit_code
|
|
262
|
+
attr_reader :stdout
|
|
263
|
+
attr_reader :stderr
|
|
264
|
+
|
|
265
|
+
def initialize(exit_code, stdout, stderr)
|
|
266
|
+
@exit_code = exit_code
|
|
267
|
+
@stdout = stdout
|
|
268
|
+
@stderr = stderr
|
|
269
|
+
end
|
|
270
|
+
end
|
|
271
|
+
end
|
|
272
|
+
end
|
|
273
|
+
end
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
require 'ostruct'
|
|
2
|
+
require 'erubis'
|
|
3
|
+
|
|
4
|
+
module Vagrant
|
|
5
|
+
module Util
|
|
6
|
+
# This class is used to render the ERB templates in the
|
|
7
|
+
# `GEM_ROOT/templates` directory.
|
|
8
|
+
class TemplateRenderer < OpenStruct
|
|
9
|
+
class << self
|
|
10
|
+
# Render a given template and return the result. This method optionally
|
|
11
|
+
# takes a block which will be passed the renderer prior to rendering, which
|
|
12
|
+
# allows the caller to set any view variables within the renderer itself.
|
|
13
|
+
#
|
|
14
|
+
# @return [String] Rendered template
|
|
15
|
+
def render(*args)
|
|
16
|
+
render_with(:render, *args)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# Render a given string and return the result. This method optionally
|
|
20
|
+
# takes a block which will be passed the renderer prior to rendering, which
|
|
21
|
+
# allows the caller to set any view variables within the renderer itself.
|
|
22
|
+
#
|
|
23
|
+
# @param [String] template The template data string.
|
|
24
|
+
# @return [String] Rendered template
|
|
25
|
+
def render_string(*args)
|
|
26
|
+
render_with(:render_string, *args)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# Method used internally to DRY out the other renderers. This method
|
|
30
|
+
# creates and sets up the renderer before calling a specified method on it.
|
|
31
|
+
def render_with(method, template, data={})
|
|
32
|
+
renderer = new(template, data)
|
|
33
|
+
yield renderer if block_given?
|
|
34
|
+
renderer.send(method.to_sym)
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def initialize(template, data = {})
|
|
39
|
+
super()
|
|
40
|
+
|
|
41
|
+
data[:template] = template
|
|
42
|
+
data.each do |key, value|
|
|
43
|
+
send("#{key}=", value)
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# Renders the template using the class intance as the binding. Because the
|
|
48
|
+
# renderer inherits from `OpenStruct`, additional view variables can be
|
|
49
|
+
# added like normal accessors.
|
|
50
|
+
#
|
|
51
|
+
# @return [String]
|
|
52
|
+
def render
|
|
53
|
+
# TODO: Seems like a pretty dirty way to do this. Perhaps refactor this
|
|
54
|
+
old_template = template
|
|
55
|
+
result = nil
|
|
56
|
+
File.open(full_template_path, 'r') do |f|
|
|
57
|
+
self.template = f.read
|
|
58
|
+
result = render_string
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
result
|
|
62
|
+
ensure
|
|
63
|
+
self.template = old_template
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
# Renders a template, handling the template as a string, but otherwise
|
|
67
|
+
# acting the same way as {#render}.
|
|
68
|
+
#
|
|
69
|
+
# @return [String]
|
|
70
|
+
def render_string
|
|
71
|
+
Erubis::Eruby.new(template, :trim => true).result(binding)
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
# Returns the full path to the template, taking into accoun the gem directory
|
|
75
|
+
# and adding the `.erb` extension to the end.
|
|
76
|
+
#
|
|
77
|
+
# @return [String]
|
|
78
|
+
def full_template_path
|
|
79
|
+
Vagrant.source_root.join('templates', "#{template}.erb").to_s.squeeze("/")
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
end
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
require "vagrant/util/platform"
|
|
2
|
+
|
|
3
|
+
module Vagrant
|
|
4
|
+
module Util
|
|
5
|
+
class Which
|
|
6
|
+
# Cross-platform way of finding an executable in the PATH.
|
|
7
|
+
#
|
|
8
|
+
# which('ruby') #=> /usr/bin/ruby
|
|
9
|
+
#
|
|
10
|
+
# This code is adapted from the following post by mislav:
|
|
11
|
+
# http://stackoverflow.com/questions/2108727/which-in-ruby-checking-if-program-exists-in-path-from-ruby
|
|
12
|
+
#
|
|
13
|
+
# @param [String] cmd The command to search for in the PATH.
|
|
14
|
+
# @return [String] The full path to the executable or `nil` if not found.
|
|
15
|
+
def self.which(cmd)
|
|
16
|
+
exts = nil
|
|
17
|
+
|
|
18
|
+
if !Platform.windows? || ENV['PATHEXT'].nil?
|
|
19
|
+
# If the PATHEXT variable is empty, we're on *nix and need to find
|
|
20
|
+
# the exact filename
|
|
21
|
+
exts = ['']
|
|
22
|
+
elsif File.extname(cmd).length != 0
|
|
23
|
+
# On Windows: if filename contains an extension, we must match that
|
|
24
|
+
# exact filename
|
|
25
|
+
exts = ['']
|
|
26
|
+
else
|
|
27
|
+
# On Windows: otherwise try to match all possible executable file
|
|
28
|
+
# extensions (.EXE .COM .BAT etc.)
|
|
29
|
+
exts = ENV['PATHEXT'].split(';')
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
ENV['PATH'].split(File::PATH_SEPARATOR).each do |path|
|
|
33
|
+
exts.each do |ext|
|
|
34
|
+
exe = "#{path}#{File::SEPARATOR}#{cmd}#{ext}"
|
|
35
|
+
return exe if File.executable? exe
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
return nil
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
data/lib/vagrant/util.rb
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
module Vagrant
|
|
2
|
+
module Util
|
|
3
|
+
autoload :Busy, 'vagrant/util/busy'
|
|
4
|
+
autoload :Counter, 'vagrant/util/counter'
|
|
5
|
+
autoload :HashWithIndifferentAccess, 'vagrant/util/hash_with_indifferent_access'
|
|
6
|
+
autoload :Platform, 'vagrant/util/platform'
|
|
7
|
+
autoload :Retryable, 'vagrant/util/retryable'
|
|
8
|
+
autoload :SafeExec, 'vagrant/util/safe_exec'
|
|
9
|
+
autoload :StackedProcRunner, 'vagrant/util/stacked_proc_runner'
|
|
10
|
+
autoload :TemplateRenderer, 'vagrant/util/template_renderer'
|
|
11
|
+
end
|
|
12
|
+
end
|