vagrant-omnibus 1.4.1 → 1.5.0

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/TODO.md CHANGED
@@ -1,5 +1,5 @@
1
- # TODO
2
-
3
- * Add support for installing pre-release versions of Chef.
4
- * Better acceptance test coverage.
5
- * Unit test coverage.
1
+ # TODO
2
+
3
+ - Add support for installing pre-release versions of Chef.
4
+ - Better acceptance test coverage.
5
+ - Unit test coverage.
@@ -1,31 +1,31 @@
1
- #
2
- # Copyright (c) 2013, Seth Chisamore
3
- #
4
- # Licensed under the Apache License, Version 2.0 (the "License");
5
- # you may not use this file except in compliance with the License.
6
- # You may obtain a copy of the License at
7
- #
8
- # http://www.apache.org/licenses/LICENSE-2.0
9
- #
10
- # Unless required by applicable law or agreed to in writing, software
11
- # distributed under the License is distributed on an "AS IS" BASIS,
12
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
- # See the License for the specific language governing permissions and
14
- # limitations under the License.
15
- #
16
-
17
- require 'vagrant'
18
- require 'vagrant-omnibus/plugin'
19
- require 'vagrant-omnibus/config'
20
-
21
- module VagrantPlugins
22
- #
23
- module Omnibus
24
- def self.source_root
25
- @source_root ||= Pathname.new(File.expand_path('../../', __FILE__))
26
- end
27
-
28
- I18n.load_path << File.expand_path('locales/en.yml', source_root)
29
- I18n.reload!
30
- end
31
- end
1
+ #
2
+ # Copyright (c) 2013, Seth Chisamore
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+
17
+ require "vagrant"
18
+ require "vagrant-omnibus/plugin"
19
+ require "vagrant-omnibus/config"
20
+
21
+ module VagrantPlugins
22
+ #
23
+ module Omnibus
24
+ def self.source_root
25
+ @source_root ||= Pathname.new(File.expand_path("../../", __FILE__))
26
+ end
27
+
28
+ I18n.load_path << File.expand_path("locales/en.yml", source_root)
29
+ I18n.reload!
30
+ end
31
+ end
@@ -1,258 +1,272 @@
1
- #
2
- # Copyright (c) 2013, Seth Chisamore
3
- #
4
- # Licensed under the Apache License, Version 2.0 (the "License");
5
- # you may not use this file except in compliance with the License.
6
- # You may obtain a copy of the License at
7
- #
8
- # http://www.apache.org/licenses/LICENSE-2.0
9
- #
10
- # Unless required by applicable law or agreed to in writing, software
11
- # distributed under the License is distributed on an "AS IS" BASIS,
12
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
- # See the License for the specific language governing permissions and
14
- # limitations under the License.
15
- #
16
-
17
- require 'log4r'
18
- require 'shellwords'
19
-
20
- require 'vagrant/util/downloader'
21
-
22
- module VagrantPlugins
23
- module Omnibus
24
- module Action
25
- # @author Seth Chisamore <schisamo@opscode.com>
26
- #
27
- # This action installs Chef Omnibus packages at the desired version.
28
- class InstallChef
29
- def initialize(app, env)
30
- @app = app
31
- @logger =
32
- Log4r::Logger.new('vagrantplugins::omnibus::action::installchef')
33
- @machine = env[:machine]
34
- @install_script = find_install_script
35
- end
36
-
37
- def call(env)
38
- @app.call(env)
39
-
40
- return unless @machine.communicate.ready? && provision_enabled?(env)
41
-
42
- # Perform delayed validation
43
- @machine.config.omnibus.validate!(@machine)
44
-
45
- desired_version = @machine.config.omnibus.chef_version
46
- unless desired_version.nil?
47
- if installed_version == desired_version
48
- env[:ui].info I18n.t(
49
- 'vagrant-omnibus.action.installed',
50
- version: desired_version
51
- )
52
- else
53
- fetch_or_create_install_script(env)
54
- env[:ui].info I18n.t(
55
- 'vagrant-omnibus.action.installing',
56
- version: desired_version
57
- )
58
- install(desired_version, env)
59
- recover(env)
60
- end
61
- end
62
- end
63
-
64
- private
65
-
66
- # Determines which install script should be used to install the
67
- # Omnibus Chef package. Order of precedence:
68
- # 1. from config
69
- # 2. from env var
70
- # 3. default
71
- def find_install_script
72
- config_install_url || env_install_url || default_install_url
73
- end
74
-
75
- def default_install_url
76
- if windows_guest?
77
- 'http://www.getchef.com/chef/install.msi'
78
- else
79
- 'https://www.getchef.com/chef/install.sh'
80
- end
81
- end
82
-
83
- def config_install_url
84
- @machine.config.omnibus.install_url
85
- end
86
-
87
- def env_install_url
88
- ENV['OMNIBUS_INSTALL_URL']
89
- end
90
-
91
- def cached_omnibus_download_dir
92
- '/tmp/vagrant-cache/vagrant_omnibus'
93
- end
94
-
95
- def cache_packages?
96
- @machine.config.omnibus.cache_packages
97
- end
98
-
99
- def cachier_present?
100
- defined?(VagrantPlugins::Cachier::Plugin)
101
- end
102
-
103
- def cachier_autodetect_enabled?
104
- @machine.config.cache.auto_detect
105
- end
106
-
107
- def download_to_cached_dir?
108
- cache_packages? && cachier_present? && cachier_autodetect_enabled?
109
- end
110
-
111
- def install_script_name
112
- if windows_guest?
113
- 'install.bat'
114
- else
115
- 'install.sh'
116
- end
117
- end
118
-
119
- def windows_guest?
120
- @machine.config.vm.guest.eql?(:windows)
121
- end
122
-
123
- def provision_enabled?(env)
124
- env.fetch(:provision_enabled, true)
125
- end
126
-
127
- def communication_opts
128
- if windows_guest?
129
- { shell: 'cmd' }
130
- else
131
- { shell: 'sh' }
132
- end
133
- end
134
-
135
- def installed_version
136
- version = nil
137
- opts = communication_opts
138
- if windows_guest?
139
- command = 'cmd.exe /c chef-solo -v'
140
- opts[:error_check] = false
141
- else
142
- command = 'echo $(chef-solo -v)'
143
- end
144
- @machine.communicate.sudo(command, opts) do |type, data|
145
- if [:stderr, :stdout].include?(type)
146
- version_match = data.match(/^Chef: (.+)/)
147
- version = version_match.captures[0].strip if version_match
148
- end
149
- end
150
- version
151
- end
152
-
153
- #
154
- # Upload install script from Host's Vagrant TMP directory to guest
155
- # and executes.
156
- #
157
- def install(version, env)
158
- shell_escaped_version = Shellwords.escape(version)
159
-
160
- @machine.communicate.tap do |comm|
161
- comm.upload(@script_tmp_path, install_script_name)
162
- if windows_guest?
163
- install_cmd = "cmd.exe /c #{install_script_name} #{version}"
164
- else
165
- install_cmd = "sh #{install_script_name}"
166
- install_cmd << " -v #{shell_escaped_version}"
167
- if download_to_cached_dir?
168
- install_cmd << " -d #{cached_omnibus_download_dir}"
169
- end
170
- install_cmd << ' 2>&1'
171
- end
172
- comm.sudo(install_cmd, communication_opts) do |type, data|
173
- if [:stderr, :stdout].include?(type)
174
- next if data =~ /stdin: is not a tty/
175
- env[:ui].info(data)
176
- end
177
- end
178
- end
179
- end
180
-
181
- #
182
- # Fetches or creates a platform specific install script to the Host's
183
- # Vagrant TMP directory.
184
- #
185
- def fetch_or_create_install_script(env)
186
- @script_tmp_path =
187
- env[:tmp_path].join("#{Time.now.to_i.to_s}-#{install_script_name}")
188
-
189
- @logger.info("Generating install script at: #{@script_tmp_path}")
190
-
191
- url = @install_script
192
-
193
- if File.file?(url) || url !~ /^[a-z0-9]+:.*$/i
194
- @logger.info('Assuming URL is a file.')
195
- file_path = File.expand_path(url)
196
- file_path = Vagrant::Util::Platform.cygwin_windows_path(file_path)
197
- url = "file:#{file_path}"
198
- end
199
-
200
- # Download the install.sh or create install.bat file to a temporary
201
- # path. We store the temporary path as an instance variable so that
202
- # the `#recover` method can access it.
203
- begin
204
- if windows_guest?
205
- # generate a install.bat file at the `@script_tmp_path` location
206
- #
207
- # We'll also disable Rubocop for this embedded PowerShell code:
208
- #
209
- # rubocop:disable LineLength, SpaceAroundBlockBraces
210
- #
211
- File.open(@script_tmp_path, 'w') do |f|
212
- f.puts <<-EOH.gsub(/^\s{18}/, '')
213
- @echo off
214
- set version=%1
215
- set dest=%~dp0chef-client-%version%-1.windows.msi
216
- echo Downloading Chef %version% for Windows...
217
- powershell -command "(New-Object System.Net.WebClient).DownloadFile('#{url}?v=%version%', '%dest%')"
218
- echo Installing Chef %version%
219
- msiexec /q /i %dest%
220
- EOH
221
- end
222
- # rubocop:enable LineLength, SpaceAroundBlockBraces
223
- else
224
- downloader = Vagrant::Util::Downloader.new(
225
- url,
226
- @script_tmp_path,
227
- {}
228
- )
229
- downloader.download!
230
- end
231
- rescue Vagrant::Errors::DownloaderInterrupted
232
- # The downloader was interrupted, so just return, because that
233
- # means we were interrupted as well.
234
- env[:ui].info(I18n.t('vagrant-omnibus.download.interrupted'))
235
- return
236
- end
237
- end
238
-
239
- def recover(env)
240
- if @script_tmp_path && File.exist?(@script_tmp_path)
241
- # Try extra hard to unlink the file so that it reliably works
242
- # on Windows hosts as well, see:
243
- # http://alx.github.io/2009/01/27/ruby-wundows-unlink.html
244
- file_deleted = false
245
- until file_deleted
246
- begin
247
- File.unlink(@script_tmp_path)
248
- file_deleted = true
249
- rescue Errno::EACCES
250
- @logger.debug("failed to unlink #{@script_tmp_path}. retry...")
251
- end
252
- end
253
- end
254
- end
255
- end
256
- end
257
- end
258
- end
1
+ #
2
+ # Copyright (c) 2013, Seth Chisamore
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+
17
+ require "log4r"
18
+ require "shellwords"
19
+
20
+ require "vagrant/util/downloader"
21
+
22
+ module VagrantPlugins
23
+ module Omnibus
24
+ module Action
25
+ # @author Seth Chisamore <schisamo@chef.io>
26
+ #
27
+ # This action installs Chef Omnibus packages at the desired version.
28
+ class InstallChef
29
+ def initialize(app, env)
30
+ @app = app
31
+ @logger =
32
+ Log4r::Logger.new("vagrantplugins::omnibus::action::installchef")
33
+ @machine = env[:machine]
34
+ @install_script = find_install_script
35
+ end
36
+
37
+ def call(env)
38
+ @app.call(env)
39
+
40
+ return unless @machine.communicate.ready? && provision_enabled?(env)
41
+
42
+ # Perform delayed validation
43
+ @machine.config.omnibus.validate!(@machine)
44
+
45
+ desired_version = @machine.config.omnibus.chef_version
46
+ unless desired_version.nil?
47
+ if installed_version == desired_version
48
+ env[:ui].info I18n.t(
49
+ "vagrant-omnibus.action.installed",
50
+ version: desired_version
51
+ )
52
+ else
53
+ fetch_or_create_install_script(env)
54
+ env[:ui].info I18n.t(
55
+ "vagrant-omnibus.action.installing",
56
+ version: desired_version
57
+ )
58
+ install(desired_version, env)
59
+ recover(env)
60
+ end
61
+ end
62
+ end
63
+
64
+ private
65
+
66
+ # Determines which install script should be used to install the
67
+ # Omnibus Chef package. Order of precedence:
68
+ # 1. from config
69
+ # 2. from env var
70
+ # 3. default
71
+ def find_install_script
72
+ config_install_url || env_install_url || default_install_url
73
+ end
74
+
75
+ def default_install_url
76
+ if windows_guest?
77
+ "http://www.chef.io/chef/install.msi"
78
+ else
79
+ "https://www.chef.io/chef/install.sh"
80
+ end
81
+ end
82
+
83
+ def config_install_url
84
+ @machine.config.omnibus.install_url
85
+ end
86
+
87
+ def env_install_url
88
+ ENV["OMNIBUS_INSTALL_URL"]
89
+ end
90
+
91
+ def cached_omnibus_download_dir
92
+ "/tmp/vagrant-cache/vagrant_omnibus"
93
+ end
94
+
95
+ def cache_packages?
96
+ @machine.config.omnibus.cache_packages
97
+ end
98
+
99
+ def cachier_present?
100
+ defined?(VagrantPlugins::Cachier::Plugin)
101
+ end
102
+
103
+ def cachier_autodetect_enabled?
104
+ @machine.config.cache.auto_detect
105
+ end
106
+
107
+ def download_to_cached_dir?
108
+ cache_packages? && cachier_present? && cachier_autodetect_enabled?
109
+ end
110
+
111
+ def install_script_name
112
+ if windows_guest?
113
+ "install.bat"
114
+ else
115
+ "install.sh"
116
+ end
117
+ end
118
+
119
+ def install_script_folder
120
+ if windows_guest?
121
+ "$env:temp/vagrant-omnibus"
122
+ else
123
+ "/tmp/vagrant-omnibus"
124
+ end
125
+ end
126
+
127
+ def install_script_path
128
+ File.join(install_script_folder, install_script_name)
129
+ end
130
+
131
+ def windows_guest?
132
+ @machine.config.vm.guest.eql?(:windows)
133
+ end
134
+
135
+ def provision_enabled?(env)
136
+ env.fetch(:provision_enabled, true)
137
+ end
138
+
139
+ def communication_opts
140
+ if windows_guest?
141
+ { shell: "powershell" }
142
+ else
143
+ { shell: "sh" }
144
+ end
145
+ end
146
+
147
+ def installed_version
148
+ version = nil
149
+ opts = communication_opts
150
+ opts[:error_check] = false if windows_guest?
151
+ command = "echo $(chef-solo -v)"
152
+ @machine.communicate.sudo(command, opts) do |type, data|
153
+ if [:stderr, :stdout].include?(type)
154
+ version_match = data.match(/^Chef: (.+)/)
155
+ version = version_match.captures[0].strip if version_match
156
+ end
157
+ end
158
+ version
159
+ end
160
+
161
+ #
162
+ # Upload install script from Host's Vagrant TMP directory to guest
163
+ # and executes.
164
+ #
165
+ def install(version, env)
166
+ shell_escaped_version = Shellwords.escape(version)
167
+
168
+ @machine.communicate.tap do |comm|
169
+ unless windows_guest?
170
+ comm.execute("mkdir -p #{install_script_folder}")
171
+ end
172
+
173
+ comm.upload(@script_tmp_path, install_script_path)
174
+
175
+ if windows_guest?
176
+ install_cmd = "& #{install_script_path} #{version}"
177
+ else
178
+ install_cmd = "sh #{install_script_path}"
179
+ install_cmd << " -v #{shell_escaped_version}"
180
+ if download_to_cached_dir?
181
+ install_cmd << " -d #{cached_omnibus_download_dir}"
182
+ end
183
+ install_cmd << " 2>&1"
184
+ end
185
+ comm.sudo(install_cmd, communication_opts) do |type, data|
186
+ if [:stderr, :stdout].include?(type)
187
+ next if data =~ /stdin: is not a tty/
188
+ env[:ui].info(data)
189
+ end
190
+ end
191
+ end
192
+ end
193
+
194
+ #
195
+ # Fetches or creates a platform specific install script to the Host's
196
+ # Vagrant TMP directory.
197
+ #
198
+ def fetch_or_create_install_script(env)
199
+ @script_tmp_path = env[:tmp_path].join(
200
+ "#{Time.now.to_i}-#{install_script_name}"
201
+ ).to_s
202
+
203
+ @logger.info("Generating install script at: #{@script_tmp_path}")
204
+
205
+ url = @install_script
206
+
207
+ if File.file?(url) || url !~ /^[a-z0-9]+:.*$/i
208
+ @logger.info("Assuming URL is a file.")
209
+ file_path = File.expand_path(url)
210
+ file_path = Vagrant::Util::Platform.cygwin_windows_path(file_path)
211
+ url = "file:#{file_path}"
212
+ end
213
+
214
+ # Download the install.sh or create install.bat file to a temporary
215
+ # path. We store the temporary path as an instance variable so that
216
+ # the `#recover` method can access it.
217
+ begin
218
+ if windows_guest?
219
+ # generate a install.bat file at the `@script_tmp_path` location
220
+ #
221
+ # We'll also disable Rubocop for this embedded PowerShell code:
222
+ #
223
+ # rubocop:disable LineLength, SpaceAroundBlockBraces
224
+ #
225
+ File.open(@script_tmp_path, "w") do |f|
226
+ f.puts <<-EOH.gsub(/^\s{18}/, "")
227
+ @echo off
228
+ set version=%1
229
+ set dest=%~dp0chef-client-%version%-1.windows.msi
230
+ echo Downloading Chef %version% for Windows...
231
+ powershell -command "(New-Object System.Net.WebClient).DownloadFile('#{url}?v=%version%', '%dest%')"
232
+ echo Installing Chef %version%
233
+ msiexec /q /i %dest%
234
+ EOH
235
+ end
236
+ # rubocop:enable LineLength, SpaceAroundBlockBraces
237
+ else
238
+ downloader = Vagrant::Util::Downloader.new(
239
+ url,
240
+ @script_tmp_path,
241
+ {}
242
+ )
243
+ downloader.download!
244
+ end
245
+ rescue Vagrant::Errors::DownloaderInterrupted
246
+ # The downloader was interrupted, so just return, because that
247
+ # means we were interrupted as well.
248
+ env[:ui].info(I18n.t("vagrant-omnibus.download.interrupted"))
249
+ return
250
+ end
251
+ end
252
+
253
+ def recover(env)
254
+ if @script_tmp_path && File.exist?(@script_tmp_path)
255
+ # Try extra hard to unlink the file so that it reliably works
256
+ # on Windows hosts as well, see:
257
+ # http://alx.github.io/2009/01/27/ruby-wundows-unlink.html
258
+ file_deleted = false
259
+ until file_deleted
260
+ begin
261
+ File.unlink(@script_tmp_path)
262
+ file_deleted = true
263
+ rescue Errno::EACCES
264
+ @logger.debug("failed to unlink #{@script_tmp_path}. retry...")
265
+ end
266
+ end
267
+ end
268
+ end
269
+ end
270
+ end
271
+ end
272
+ end