vagrantup 0.8.7 → 0.8.8
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.
- checksums.yaml +4 -4
- data/.gitignore +21 -0
- data/CHANGELOG.md +25 -0
- data/README.md +38 -8
- data/Rakefile +13 -6
- data/bin/vagrant +6 -1
- data/config/default.rb +2 -2
- data/lib/vagrant/action/box/download.rb +14 -2
- data/lib/vagrant/action/vm/check_box.rb +8 -1
- data/lib/vagrant/action/vm/check_guest_additions.rb +6 -3
- data/lib/vagrant/action/vm/share_folders.rb +12 -1
- data/lib/vagrant/command/init.rb +1 -1
- data/lib/vagrant/downloaders/http.rb +29 -2
- data/lib/vagrant/hosts.rb +1 -0
- data/lib/vagrant/hosts/bsd.rb +1 -0
- data/lib/vagrant/hosts/freebsd.rb +51 -0
- data/lib/vagrant/provisioners/chef.rb +6 -5
- data/lib/vagrant/provisioners/chef_client.rb +1 -1
- data/lib/vagrant/provisioners/chef_solo.rb +13 -4
- data/lib/vagrant/ssh.rb +24 -49
- data/lib/vagrant/ssh/session.rb +1 -1
- data/lib/vagrant/systems/solaris.rb +57 -11
- data/lib/vagrant/test_helpers.rb +23 -0
- data/lib/vagrant/ui.rb +1 -1
- data/lib/vagrant/util.rb +0 -1
- data/lib/vagrant/util/file_checksum.rb +38 -0
- data/lib/vagrant/util/platform.rb +1 -1
- data/lib/vagrant/util/safe_exec.rb +2 -1
- data/lib/vagrant/version.rb +1 -1
- data/tasks/acceptance.rake +113 -0
- data/tasks/bundler.rake +3 -0
- data/tasks/test.rake +15 -0
- data/templates/commands/init/Vagrantfile.erb +3 -0
- data/templates/locales/en.yml +1 -1
- data/test/acceptance/base.rb +48 -0
- data/test/acceptance/box_test.rb +77 -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/resume_test.rb +17 -0
- data/test/acceptance/ssh_test.rb +41 -0
- data/test/acceptance/support/config.rb +42 -0
- data/test/acceptance/support/isolated_environment.rb +226 -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/output.rb +87 -0
- data/test/acceptance/support/shared/base_context.rb +65 -0
- data/test/acceptance/support/shared/command_examples.rb +33 -0
- data/test/acceptance/support/tempdir.rb +34 -0
- data/test/acceptance/support/virtualbox.rb +36 -0
- data/test/acceptance/suspend_test.rb +56 -0
- data/test/acceptance/up_basic_test.rb +58 -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 +20 -0
- data/test/buildbot/README.md +72 -0
- data/test/buildbot/buildbot_config/__init__.py +0 -0
- data/test/buildbot/buildbot_config/config/__init__.py +0 -0
- data/test/buildbot/buildbot_config/config/loader.py +24 -0
- data/test/buildbot/buildbot_config/config/master.py +24 -0
- data/test/buildbot/buildbot_config/config/slave.py +22 -0
- data/test/buildbot/buildbot_config/master/__init__.py +6 -0
- data/test/buildbot/buildbot_config/master/builders.py +78 -0
- data/test/buildbot/buildbot_config/master/buildsteps.py +100 -0
- data/test/buildbot/buildbot_config/master/change_sources.py +8 -0
- data/test/buildbot/buildbot_config/master/schedulers.py +32 -0
- data/test/buildbot/buildbot_config/master/slaves.py +60 -0
- data/test/buildbot/buildbot_config/master/status.py +52 -0
- data/test/buildbot/master/Makefile.sample +28 -0
- data/test/buildbot/master/buildbot.tac +36 -0
- data/test/buildbot/master/master.cfg +67 -0
- data/test/buildbot/master/public_html/bg_gradient.jpg +0 -0
- data/test/buildbot/master/public_html/default.css +545 -0
- data/test/buildbot/master/public_html/favicon.ico +0 -0
- data/test/buildbot/master/public_html/robots.txt +10 -0
- data/test/buildbot/master/public_html/static/css/bootstrap-1.4.0.min.css +356 -0
- data/test/buildbot/master/public_html/static/css/prettify.css +97 -0
- data/test/buildbot/master/public_html/static/css/syntax.css +60 -0
- data/test/buildbot/master/public_html/static/css/vagrant.base.css +205 -0
- data/test/buildbot/master/public_html/static/images/base_box_mac.jpg +0 -0
- data/test/buildbot/master/public_html/static/images/getting-started/success.jpg +0 -0
- data/test/buildbot/master/public_html/static/images/icons/error.png +0 -0
- data/test/buildbot/master/public_html/static/images/vagrant_chilling.png +0 -0
- data/test/buildbot/master/public_html/static/images/vagrant_holding.png +0 -0
- data/test/buildbot/master/public_html/static/images/vagrant_looking.png +0 -0
- data/test/buildbot/master/public_html/static/images/windows/alter_path.jpg +0 -0
- data/test/buildbot/master/public_html/static/images/windows/edit_path.jpg +0 -0
- data/test/buildbot/master/public_html/static/images/windows/environment_variables_button.jpg +0 -0
- data/test/buildbot/master/public_html/static/images/windows/port_and_ppk_path.jpg +0 -0
- data/test/buildbot/master/public_html/static/images/windows/ppk_selection.jpg +0 -0
- data/test/buildbot/master/public_html/static/images/windows/putty_first_screen.jpg +0 -0
- data/test/buildbot/master/public_html/static/images/windows/save_result.jpg +0 -0
- data/test/buildbot/master/public_html/static/images/windows/vbox_manage_default_location.jpg +0 -0
- data/test/buildbot/master/public_html/static/js/bootstrap-tabs.js +80 -0
- data/test/buildbot/master/public_html/static/js/jquery-1.7.min.js +4 -0
- data/test/buildbot/master/templates/authfail.html +9 -0
- data/test/buildbot/master/templates/build.html +205 -0
- data/test/buildbot/master/templates/builder.html +118 -0
- data/test/buildbot/master/templates/builders.html +33 -0
- data/test/buildbot/master/templates/buildslave.html +72 -0
- data/test/buildbot/master/templates/buildslaves.html +70 -0
- data/test/buildbot/master/templates/change.html +15 -0
- data/test/buildbot/master/templates/layouts/base.html +58 -0
- data/test/buildbot/master/templates/macros/box.html +37 -0
- data/test/buildbot/master/templates/macros/build_line.html +50 -0
- data/test/buildbot/master/templates/macros/change.html +81 -0
- data/test/buildbot/master/templates/macros/forms.html +300 -0
- data/test/buildbot/master/templates/root.html +42 -0
- data/test/buildbot/master/templates/waterfall.html +53 -0
- data/test/buildbot/requirements.txt +4 -0
- data/test/buildbot/scripts/deploy.sh +38 -0
- data/test/buildbot/scripts/setup.sh +107 -0
- data/test/buildbot/slave/buildbot.tac +43 -0
- data/test/buildbot/slave/info/admin +1 -0
- data/test/buildbot/slave/info/host +1 -0
- data/test/buildbot/tests/__init__.py +0 -0
- data/test/buildbot/tests/master/__init__.py +0 -0
- data/test/buildbot/tests/master/test_slaves.py +41 -0
- data/test/buildbot/vendor/choices-0.4.0.tar.gz +0 -0
- data/test/config/acceptance_boxes.yml +7 -0
- data/test/unit/test_helper.rb +4 -0
- data/test/unit/vagrant/action/box/download_test.rb +2 -2
- data/test/unit/vagrant/action/vm/check_box_test.rb +6 -1
- data/test/unit/vagrant/action/vm/share_folders_test.rb +1 -1
- data/test/unit/vagrant/command/init_test.rb +10 -0
- data/test/unit/vagrant/downloaders/http_test.rb +12 -1
- data/test/unit/vagrant/provisioners/chef_test.rb +7 -0
- data/test/unit/vagrant/ssh/session_test.rb +2 -2
- data/test/unit/vagrant/ssh_test.rb +5 -8
- data/vagrant.gemspec +6 -0
- metadata +177 -1
|
@@ -26,7 +26,7 @@ module Vagrant
|
|
|
26
26
|
@file_cache_path = "/srv/chef/file_store"
|
|
27
27
|
@file_backup_path = "/srv/chef/cache"
|
|
28
28
|
@encrypted_data_bag_secret_key_path = nil
|
|
29
|
-
@encrypted_data_bag_secret = "/
|
|
29
|
+
@encrypted_data_bag_secret = "/tmp/encrypted_data_bag_secret"
|
|
30
30
|
end
|
|
31
31
|
|
|
32
32
|
def validate(errors)
|
|
@@ -36,9 +36,9 @@ module Vagrant
|
|
|
36
36
|
attr_reader :data_bags_folders
|
|
37
37
|
|
|
38
38
|
def prepare
|
|
39
|
-
@cookbook_folders = expanded_folders(config.cookbooks_path)
|
|
40
|
-
@role_folders = expanded_folders(config.roles_path)
|
|
41
|
-
@data_bags_folders = expanded_folders(config.data_bags_path)
|
|
39
|
+
@cookbook_folders = expanded_folders(config.cookbooks_path, "cookbooks")
|
|
40
|
+
@role_folders = expanded_folders(config.roles_path, "roles")
|
|
41
|
+
@data_bags_folders = expanded_folders(config.data_bags_path, "data_bags")
|
|
42
42
|
|
|
43
43
|
share_folders("csc", @cookbook_folders)
|
|
44
44
|
share_folders("csr", @role_folders)
|
|
@@ -54,7 +54,7 @@ module Vagrant
|
|
|
54
54
|
end
|
|
55
55
|
|
|
56
56
|
# Converts paths to a list of properly expanded paths with types.
|
|
57
|
-
def expanded_folders(paths)
|
|
57
|
+
def expanded_folders(paths, appended_folder=nil)
|
|
58
58
|
return [] if paths.nil?
|
|
59
59
|
|
|
60
60
|
# Convert the path to an array if it is a string or just a single
|
|
@@ -77,8 +77,17 @@ module Vagrant
|
|
|
77
77
|
# Path already exists on the virtual machine. Expand it
|
|
78
78
|
# relative to where we're provisioning.
|
|
79
79
|
remote_path = File.expand_path(path, config.provisioning_path)
|
|
80
|
+
|
|
81
|
+
# Remove drive letter if running on a windows host. This is a bit
|
|
82
|
+
# of a hack but is the most portable way I can think of at the moment
|
|
83
|
+
# to achieve this. Otherwise, Vagrant attempts to share at some crazy
|
|
84
|
+
# path like /home/vagrant/c:/foo/bar
|
|
85
|
+
remote_path = remote_path.gsub(/^[a-zA-Z]:/, "")
|
|
80
86
|
end
|
|
81
87
|
|
|
88
|
+
# If we have specified a folder name to append then append it
|
|
89
|
+
remote_path += "/#{appended_folder}" if appended_folder
|
|
90
|
+
|
|
82
91
|
# Return the result
|
|
83
92
|
[type, local_path, remote_path]
|
|
84
93
|
end
|
data/lib/vagrant/ssh.rb
CHANGED
|
@@ -19,7 +19,6 @@ module Vagrant
|
|
|
19
19
|
|
|
20
20
|
def initialize(environment)
|
|
21
21
|
@env = environment
|
|
22
|
-
@current_session = nil
|
|
23
22
|
end
|
|
24
23
|
|
|
25
24
|
# Connects to the environment's virtual machine, replacing the ruby
|
|
@@ -53,9 +52,6 @@ module Vagrant
|
|
|
53
52
|
command_options << "-o ForwardX11Trusted=yes"
|
|
54
53
|
end
|
|
55
54
|
|
|
56
|
-
# Some hackery going on here. On Mac OS X Leopard (10.5), exec fails
|
|
57
|
-
# (GH-51). As a workaround, we fork and wait. On all other platforms,
|
|
58
|
-
# we simply exec.
|
|
59
55
|
command = "ssh #{command_options.join(" ")} #{options[:username]}@#{options[:host]}".strip
|
|
60
56
|
env.logger.info("ssh") { "Invoking SSH: #{command}" }
|
|
61
57
|
safe_exec(command)
|
|
@@ -72,47 +68,22 @@ module Vagrant
|
|
|
72
68
|
opts[:forward_agent] = true if env.config.ssh.forward_agent
|
|
73
69
|
opts[:port] ||= port
|
|
74
70
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
#
|
|
78
|
-
#
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
end
|
|
92
|
-
|
|
93
|
-
if !session || options != opts
|
|
94
|
-
env.logger.info("ssh") { "Connecting to SSH: #{env.config.ssh.host} #{opts[:port]}" }
|
|
95
|
-
|
|
96
|
-
# The exceptions which are acceptable to retry on during
|
|
97
|
-
# attempts to connect to SSH
|
|
98
|
-
exceptions = [Errno::ECONNREFUSED, Net::SSH::Disconnect]
|
|
99
|
-
|
|
100
|
-
# Connect to SSH and gather the session
|
|
101
|
-
session = retryable(:tries => 5, :on => exceptions) do
|
|
102
|
-
connection = Net::SSH.start(env.config.ssh.host,
|
|
103
|
-
env.config.ssh.username,
|
|
104
|
-
opts.merge( :keys => [env.config.ssh.private_key_path],
|
|
105
|
-
:keys_only => true,
|
|
106
|
-
:user_known_hosts_file => [],
|
|
107
|
-
:paranoid => false,
|
|
108
|
-
:config => false))
|
|
109
|
-
SSH::Session.new(connection, env)
|
|
110
|
-
end
|
|
111
|
-
|
|
112
|
-
# Save the new session along with the options which created it
|
|
113
|
-
@current_session = [session, opts]
|
|
114
|
-
else
|
|
115
|
-
env.logger.info("ssh") { "Using cached SSH session: #{session}" }
|
|
71
|
+
env.logger.info("ssh") { "Connecting to SSH: #{env.config.ssh.host} #{opts[:port]}" }
|
|
72
|
+
|
|
73
|
+
# The exceptions which are acceptable to retry on during
|
|
74
|
+
# attempts to connect to SSH
|
|
75
|
+
exceptions = [Errno::ECONNREFUSED, Net::SSH::Disconnect]
|
|
76
|
+
|
|
77
|
+
# Connect to SSH and gather the session
|
|
78
|
+
session = retryable(:tries => env.config.ssh.max_tries, :on => exceptions) do
|
|
79
|
+
connection = Net::SSH.start(env.config.ssh.host,
|
|
80
|
+
env.config.ssh.username,
|
|
81
|
+
opts.merge( :keys => [env.config.ssh.private_key_path],
|
|
82
|
+
:keys_only => true,
|
|
83
|
+
:user_known_hosts_file => [],
|
|
84
|
+
:paranoid => false,
|
|
85
|
+
:config => false))
|
|
86
|
+
SSH::Session.new(connection, env)
|
|
116
87
|
end
|
|
117
88
|
|
|
118
89
|
# Yield our session for executing
|
|
@@ -144,15 +115,19 @@ module Vagrant
|
|
|
144
115
|
|
|
145
116
|
require 'timeout'
|
|
146
117
|
Timeout.timeout(env.config.ssh.timeout) do
|
|
147
|
-
execute(:timeout => env.config.ssh.timeout,
|
|
148
|
-
|
|
118
|
+
execute(:timeout => env.config.ssh.timeout, :port => ssh_port) do |ssh|
|
|
119
|
+
# We run a basic command to test that the shell is up and
|
|
120
|
+
# ready to receive commands. Only then is our SSH connection
|
|
121
|
+
# truly "up"
|
|
122
|
+
return ssh.exec!("echo hello") == "hello\n"
|
|
123
|
+
end
|
|
149
124
|
end
|
|
150
125
|
|
|
151
|
-
|
|
126
|
+
false
|
|
152
127
|
rescue Net::SSH::AuthenticationFailed
|
|
153
128
|
raise Errors::SSHAuthenticationFailed
|
|
154
129
|
rescue Timeout::Error, Errno::ECONNREFUSED, Net::SSH::Disconnect,
|
|
155
|
-
Errors::SSHConnectionRefused
|
|
130
|
+
Errors::SSHConnectionRefused
|
|
156
131
|
return false
|
|
157
132
|
end
|
|
158
133
|
|
data/lib/vagrant/ssh/session.rb
CHANGED
|
@@ -61,7 +61,7 @@ module Vagrant
|
|
|
61
61
|
# the actual `exec!` implementation, except that this
|
|
62
62
|
# implementation also reports `:exit_status` to the block if given.
|
|
63
63
|
def exec!(commands, options=nil, &block)
|
|
64
|
-
retryable(:tries =>
|
|
64
|
+
retryable(:tries => env.config.ssh.max_tries, :on => [IOError, Net::SSH::Disconnect], :sleep => 1.0) do
|
|
65
65
|
metach = session.open_channel do |ch|
|
|
66
66
|
ch.exec("#{env.config.ssh.shell} -l") do |ch2, success|
|
|
67
67
|
# Set the terminal
|
|
@@ -15,11 +15,13 @@ module Vagrant
|
|
|
15
15
|
attr_accessor :halt_check_interval
|
|
16
16
|
# This sets the command to use to execute items as a superuser. sudo is default
|
|
17
17
|
attr_accessor :suexec_cmd
|
|
18
|
+
attr_accessor :device
|
|
18
19
|
|
|
19
20
|
def initialize
|
|
20
21
|
@halt_timeout = 30
|
|
21
22
|
@halt_check_interval = 1
|
|
22
23
|
@suexec_cmd = 'sudo'
|
|
24
|
+
@device = "e1000g"
|
|
23
25
|
end
|
|
24
26
|
end
|
|
25
27
|
|
|
@@ -28,6 +30,33 @@ module Vagrant
|
|
|
28
30
|
error_namespace("vagrant.systems.solaris")
|
|
29
31
|
end
|
|
30
32
|
|
|
33
|
+
def prepare_host_only_network(net_options=nil)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def enable_host_only_network(net_options)
|
|
37
|
+
device = "#{vm.env.config.solaris.device}#{net_options[:adapter]}"
|
|
38
|
+
su_cmd = vm.env.config.solaris.suexec_cmd
|
|
39
|
+
ifconfig_cmd = "#{su_cmd} /sbin/ifconfig #{device}"
|
|
40
|
+
vm.ssh.execute do |ssh|
|
|
41
|
+
ssh.exec!("#{ifconfig_cmd} plumb")
|
|
42
|
+
ssh.exec!("#{ifconfig_cmd} inet #{net_options[:ip]} netmask #{net_options[:netmask]}")
|
|
43
|
+
ssh.exec!("#{ifconfig_cmd} up")
|
|
44
|
+
ssh.exec!("#{su_cmd} sh -c \"echo '#{net_options[:ip]}' > /etc/hostname.#{device}\"")
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def change_host_name(name)
|
|
49
|
+
su_cmd = vm.env.config.solaris.suexec_cmd
|
|
50
|
+
vm.ssh.execute do |ssh|
|
|
51
|
+
# Only do this if the hostname is not already set
|
|
52
|
+
if !ssh.test?("#{su_cmd} hostname | grep '#{name}'")
|
|
53
|
+
ssh.exec!("#{su_cmd} sh -c \"echo '#{name}' > /etc/nodename\"")
|
|
54
|
+
ssh.exec!("#{su_cmd} uname -S #{name}")
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
|
|
31
60
|
# There should be an exception raised if the line
|
|
32
61
|
#
|
|
33
62
|
# vagrant::::profiles=Primary Administrator
|
|
@@ -36,19 +65,36 @@ module Vagrant
|
|
|
36
65
|
def halt
|
|
37
66
|
vm.env.ui.info I18n.t("vagrant.systems.solaris.attempting_halt")
|
|
38
67
|
vm.ssh.execute do |ssh|
|
|
39
|
-
|
|
40
|
-
|
|
68
|
+
# Wait until the VM's state is actually powered off. If this doesn't
|
|
69
|
+
# occur within a reasonable amount of time (15 seconds by default),
|
|
70
|
+
# then simply return and allow Vagrant to kill the machine.
|
|
71
|
+
count = 0
|
|
72
|
+
last_error = nil
|
|
73
|
+
while vm.vm.state != :powered_off
|
|
74
|
+
begin
|
|
75
|
+
ssh.exec!("#{vm.env.config.solaris.suexec_cmd} /usr/sbin/poweroff")
|
|
76
|
+
rescue IOError => e
|
|
77
|
+
# Save the last error; if it's not shutdown in a reasonable amount
|
|
78
|
+
# of attempts we will re-raise the error so it's not hidden for
|
|
79
|
+
# all time
|
|
80
|
+
last_error = e
|
|
81
|
+
end
|
|
41
82
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
83
|
+
count += 1
|
|
84
|
+
if count >= vm.env.config.solaris.halt_timeout
|
|
85
|
+
# Check for last error and re-raise it
|
|
86
|
+
if last_error != nil
|
|
87
|
+
raise last_error
|
|
88
|
+
else
|
|
89
|
+
# Otherwise, just return
|
|
90
|
+
return
|
|
91
|
+
end
|
|
92
|
+
end
|
|
48
93
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
94
|
+
# Still opportunities remaining; sleep and loop
|
|
95
|
+
sleep vm.env.config.solaris.halt_check_interval
|
|
96
|
+
end # while
|
|
97
|
+
end # do
|
|
52
98
|
end
|
|
53
99
|
|
|
54
100
|
def mount_shared_folder(ssh, name, guestpath, owner, group)
|
data/lib/vagrant/test_helpers.rb
CHANGED
|
@@ -84,6 +84,29 @@ module Vagrant
|
|
|
84
84
|
[app, env]
|
|
85
85
|
end
|
|
86
86
|
|
|
87
|
+
# Utility method for capturing output streams.
|
|
88
|
+
# @example Evaluate the output
|
|
89
|
+
# output = capture(:stdout){ env.cli("foo") }
|
|
90
|
+
# assert_equal "bar", output
|
|
91
|
+
# @example Silence the output
|
|
92
|
+
# silence(:stdout){ env.cli("init") }
|
|
93
|
+
# @param [:stdout, :stderr] stream The stream to capture
|
|
94
|
+
# @yieldreturn String
|
|
95
|
+
# @see https://github.com/wycats/thor/blob/master/spec/spec_helper.rb
|
|
96
|
+
def capture(stream)
|
|
97
|
+
begin
|
|
98
|
+
stream = stream.to_s
|
|
99
|
+
eval "$#{stream} = StringIO.new"
|
|
100
|
+
yield
|
|
101
|
+
result = eval("$#{stream}").string
|
|
102
|
+
ensure
|
|
103
|
+
eval("$#{stream} = #{stream.upcase}")
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
result
|
|
107
|
+
end
|
|
108
|
+
alias :silence :capture
|
|
109
|
+
|
|
87
110
|
#------------------------------------------------------------
|
|
88
111
|
# Path helpers
|
|
89
112
|
#------------------------------------------------------------
|
data/lib/vagrant/ui.rb
CHANGED
data/lib/vagrant/util.rb
CHANGED
|
@@ -2,7 +2,6 @@ module Vagrant
|
|
|
2
2
|
module Util
|
|
3
3
|
autoload :Busy, 'vagrant/util/busy'
|
|
4
4
|
autoload :Counter, 'vagrant/util/counter'
|
|
5
|
-
autoload :GlobLoader, 'vagrant/util/glob_loader'
|
|
6
5
|
autoload :HashWithIndifferentAccess, 'vagrant/util/hash_with_indifferent_access'
|
|
7
6
|
autoload :Platform, 'vagrant/util/platform'
|
|
8
7
|
autoload :Retryable, 'vagrant/util/retryable'
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# This is an "interface" that should be implemented by any digest class
|
|
2
|
+
# passed into FileChecksum. Note that this isn't strictly enforced at
|
|
3
|
+
# the moment, and this class isn't directly used. It is merely here for
|
|
4
|
+
# documentation of structure of the class.
|
|
5
|
+
class DigestClass
|
|
6
|
+
def update(string); end
|
|
7
|
+
def hexdigest; end
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
class FileChecksum
|
|
11
|
+
BUFFER_SIZE = 1024
|
|
12
|
+
|
|
13
|
+
# Initializes an object to calculate the checksum of a file. The given
|
|
14
|
+
# ``digest_klass`` should implement the ``DigestClass`` interface. Note
|
|
15
|
+
# that the built-in Ruby digest classes duck type this properly:
|
|
16
|
+
# Digest::MD5, Digest::SHA1, etc.
|
|
17
|
+
def initialize(path, digest_klass)
|
|
18
|
+
@digest_klass = digest_klass
|
|
19
|
+
@path = path
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# This calculates the checksum of the file and returns it as a
|
|
23
|
+
# string.
|
|
24
|
+
#
|
|
25
|
+
# @return [String]
|
|
26
|
+
def checksum
|
|
27
|
+
digest= @digest_klass.new
|
|
28
|
+
|
|
29
|
+
File.open(@path, "r") do |f|
|
|
30
|
+
while !f.eof
|
|
31
|
+
buf = f.readpartial(BUFFER_SIZE)
|
|
32
|
+
digest.update(buf)
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
return digest.hexdigest
|
|
37
|
+
end
|
|
38
|
+
end
|
|
@@ -2,7 +2,7 @@ module Vagrant
|
|
|
2
2
|
module Util
|
|
3
3
|
# This module provies a `safe_exec` method which is a drop-in
|
|
4
4
|
# replacement for `Kernel.exec` which addresses a specific issue
|
|
5
|
-
# which manifests on OS X 10.5 and perhaps other operating systems.
|
|
5
|
+
# which manifests on OS X 10.5 (GH-51) and perhaps other operating systems.
|
|
6
6
|
# This issue causes `exec` to fail if there is more than one system
|
|
7
7
|
# thread. In that case, `safe_exec` automatically falls back to
|
|
8
8
|
# forking.
|
|
@@ -14,6 +14,7 @@ module Vagrant
|
|
|
14
14
|
rescue_from = []
|
|
15
15
|
rescue_from << Errno::EOPNOTSUPP if defined?(Errno::EOPNOTSUPP)
|
|
16
16
|
rescue_from << Errno::E045 if defined?(Errno::E045)
|
|
17
|
+
rescue_from << SystemCallError
|
|
17
18
|
|
|
18
19
|
fork_instead = false
|
|
19
20
|
begin
|
data/lib/vagrant/version.rb
CHANGED
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
require 'digest/sha1'
|
|
2
|
+
require 'net/http'
|
|
3
|
+
require 'pathname'
|
|
4
|
+
require 'uri'
|
|
5
|
+
require 'yaml'
|
|
6
|
+
|
|
7
|
+
require 'childprocess'
|
|
8
|
+
|
|
9
|
+
require 'vagrant/util/file_checksum'
|
|
10
|
+
|
|
11
|
+
namespace :acceptance do
|
|
12
|
+
desc "Downloads the boxes required for running the acceptance tests."
|
|
13
|
+
task :boxes, :directory do |t, args|
|
|
14
|
+
# Create the directory where the boxes will be downloaded
|
|
15
|
+
box_dir = Pathname.new(args[:directory] || File.expand_path("../../test/tmp/boxes", __FILE__))
|
|
16
|
+
box_dir.mkpath
|
|
17
|
+
puts "Boxes will be placed in: #{box_dir}"
|
|
18
|
+
|
|
19
|
+
# Load the required boxes
|
|
20
|
+
boxes = YAML.load_file(File.expand_path("../../test/config/acceptance_boxes.yml", __FILE__))
|
|
21
|
+
|
|
22
|
+
boxes.each do |box|
|
|
23
|
+
puts "Box: #{box["name"]}"
|
|
24
|
+
box_file = box_dir.join("#{box["name"]}.box")
|
|
25
|
+
checksum = FileChecksum.new(box_file, Digest::SHA1)
|
|
26
|
+
|
|
27
|
+
# If the box exists, we need to check the checksum and determine if we need
|
|
28
|
+
# to redownload the file.
|
|
29
|
+
if box_file.exist?
|
|
30
|
+
print "Box exists, checking SHA1 sum... "
|
|
31
|
+
if checksum.checksum == box["checksum"]
|
|
32
|
+
print "OK\n"
|
|
33
|
+
next
|
|
34
|
+
else
|
|
35
|
+
print "FAIL\n"
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# Download the file. Note that this has no error checking and just uses
|
|
40
|
+
# pure net/http. There could be a better way.
|
|
41
|
+
puts "Downloading: #{box["url"]}"
|
|
42
|
+
destination = box_file.open("wb")
|
|
43
|
+
uri = URI.parse(box["url"])
|
|
44
|
+
Net::HTTP.new(uri.host, uri.port).start do |http|
|
|
45
|
+
http.request_get(uri.request_uri) do |response|
|
|
46
|
+
total = response.content_length
|
|
47
|
+
progress = 0
|
|
48
|
+
count = 0
|
|
49
|
+
|
|
50
|
+
response.read_body do |segment|
|
|
51
|
+
# Really elementary progress meter
|
|
52
|
+
progress += segment.length
|
|
53
|
+
count += 1
|
|
54
|
+
puts "Progress: #{(progress.to_f / total.to_f) * 100}%" if count % 300 == 0
|
|
55
|
+
|
|
56
|
+
# Write out to the destination file
|
|
57
|
+
destination.write(segment)
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
destination.close
|
|
63
|
+
|
|
64
|
+
# Check the checksum of the new file to verify that it
|
|
65
|
+
# downloaded properly. This shouldn't happen, but it can!
|
|
66
|
+
if checksum.checksum != box["checksum"]
|
|
67
|
+
puts "Checksum didn't match! Download was corrupt!"
|
|
68
|
+
abort
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
desc "Generates the configuration for acceptance tests from current source."
|
|
74
|
+
task :config, :box_dir do |t, args|
|
|
75
|
+
require File.expand_path("../../lib/vagrant/version", __FILE__)
|
|
76
|
+
require File.expand_path('../../test/acceptance/support/tempdir', __FILE__)
|
|
77
|
+
|
|
78
|
+
# Get the directory for the boxes
|
|
79
|
+
box_dir = Pathname.new(args[:box_dir] || File.expand_path("../../test/tmp/boxes", __FILE__))
|
|
80
|
+
|
|
81
|
+
# Generate the binstubs for the Vagrant binary
|
|
82
|
+
tempdir = Tempdir.new
|
|
83
|
+
process = ChildProcess.build("bundle", "install", "--binstubs", tempdir.path)
|
|
84
|
+
process.io.inherit!
|
|
85
|
+
process.start
|
|
86
|
+
process.poll_for_exit(64000)
|
|
87
|
+
if process.exit_code != 0
|
|
88
|
+
# Bundle install failed...
|
|
89
|
+
puts "Bundle install failed!"
|
|
90
|
+
abort
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
# Generate the actual configuration
|
|
94
|
+
config = {
|
|
95
|
+
"vagrant_path" => File.join(tempdir.path, "vagrant"),
|
|
96
|
+
"vagrant_version" => Vagrant::VERSION,
|
|
97
|
+
"env" => {
|
|
98
|
+
"BUNDLE_GEMFILE" => File.expand_path("../../Gemfile", __FILE__)
|
|
99
|
+
},
|
|
100
|
+
"box_directory" => box_dir.to_s
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
File.open("acceptance_config.yml", "w+") do |f|
|
|
104
|
+
f.write(YAML.dump(config))
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
puts <<-OUTPUT
|
|
108
|
+
Acceptance test configuration is now in this directory in
|
|
109
|
+
"acceptance_config.yml." Set your ACCEPTANCE_CONFIG environmental
|
|
110
|
+
variable to this file and run any of the acceptance tests now.
|
|
111
|
+
OUTPUT
|
|
112
|
+
end
|
|
113
|
+
end
|