knife-windows 1.8.0 → 1.9.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -6,12 +6,12 @@ Example Note:
6
6
  ## Example Heading
7
7
  Details about the thing that changed that needs to get included in the Release Notes in markdown.
8
8
  -->
9
- # knife-windows 1.8.0 release notes:
9
+ # knife-windows 1.9.0 release notes:
10
10
 
11
- This release allows user to specify `config_log_location` and `config_log_level` options in config.rb/knife.rb. This sets the default `log_location` and `log_level` in the `client.rb` file of the node being bootstrapped.
11
+ This release re-introduces support for concurrent WinRM connections when
12
+ running `knife winrm`. Simply specify the number of concurrent connections
13
+ you would like using the `-C` (or `--concurrency`) flag.
12
14
 
13
- This is how you can pass the values in config.rb/knife.rb:
14
15
  ```
15
- chef_log_level :debug
16
- chef_log_location "C:/chef.log" #please make sure that the path exists
16
+ knife winrm "role:web" "net stats srv" -X Administrator -P 'super_secret_password' -C 4
17
17
  ```
data/Rakefile CHANGED
@@ -1,21 +1,21 @@
1
- require 'bundler'
2
- Bundler::GemHelper.install_tasks
3
-
4
- begin
5
- require 'rspec/core/rake_task'
6
-
7
- task :default => [:unit_spec, :functional_spec]
8
-
9
- desc "Run all functional specs in spec directory"
10
- RSpec::Core::RakeTask.new(:functional_spec) do |t|
11
- t.pattern = 'spec/functional/**/*_spec.rb'
12
- end
13
-
14
- desc "Run all unit specs in spec directory"
15
- RSpec::Core::RakeTask.new(:unit_spec) do |t|
16
- t.pattern = 'spec/unit/**/*_spec.rb'
17
- end
18
-
19
- rescue LoadError
20
- STDERR.puts "\n*** RSpec not available. (sudo) gem install rspec to run unit tests. ***\n\n"
21
- end
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
3
+
4
+ begin
5
+ require 'rspec/core/rake_task'
6
+
7
+ task :default => [:unit_spec, :functional_spec]
8
+
9
+ desc "Run all functional specs in spec directory"
10
+ RSpec::Core::RakeTask.new(:functional_spec) do |t|
11
+ t.pattern = 'spec/functional/**/*_spec.rb'
12
+ end
13
+
14
+ desc "Run all unit specs in spec directory"
15
+ RSpec::Core::RakeTask.new(:unit_spec) do |t|
16
+ t.pattern = 'spec/unit/**/*_spec.rb'
17
+ end
18
+
19
+ rescue LoadError
20
+ STDERR.puts "\n*** RSpec not available. (sudo) gem install rspec to run unit tests. ***\n\n"
21
+ end
@@ -8,9 +8,6 @@ environment:
8
8
  bundle_gemfile: ci.gemfile
9
9
 
10
10
  matrix:
11
- - ruby_version: "20"
12
- chef_version: "< 12"
13
-
14
11
  - ruby_version: "23"
15
12
  chef_version: "~> 12.0"
16
13
 
@@ -1,20 +1,20 @@
1
- Feature: Ensure that the help works as designed
2
- In order to test the help via CLI
3
- As an Operator
4
- I want to run the CLI with different arguments
5
-
6
- Scenario: Running the windows sub-command shows available commands
7
- When I run `knife windows`
8
- And the output should contain "Available windows subcommands: (for details, knife SUB-COMMAND --help)\n\n** WINDOWS COMMANDS **\nknife bootstrap windows winrm FQDN (options)\nknife bootstrap windows ssh FQDN (options)\nknife winrm QUERY COMMAND (options)"
9
-
10
- Scenario: Running the windows sub-command shows available commands
11
- When I run `knife windows --help`
12
- And the output should contain "Available windows subcommands: (for details, knife SUB-COMMAND --help)\n\n** WINDOWS COMMANDS **\nknife bootstrap windows winrm FQDN (options)\nknife bootstrap windows ssh FQDN (options)\nknife winrm QUERY COMMAND (options)"
13
-
14
- Scenario: Running the windows sub-command shows available commands
15
- When I run `knife windows help`
16
- And the output should contain "Available windows subcommands: (for details, knife SUB-COMMAND --help)\n\n** WINDOWS COMMANDS **\nknife bootstrap windows winrm FQDN (options)\nknife bootstrap windows ssh FQDN (options)\nknife winrm QUERY COMMAND (options)"
17
-
18
- Scenario: Running the knife command shows available windows command"
19
- When I run `knife`
20
- And the output should contain "** WINDOWS COMMANDS **\nknife bootstrap windows winrm FQDN (options)\nknife bootstrap windows ssh FQDN (options)\nknife winrm QUERY COMMAND (options)"
1
+ Feature: Ensure that the help works as designed
2
+ In order to test the help via CLI
3
+ As an Operator
4
+ I want to run the CLI with different arguments
5
+
6
+ Scenario: Running the windows sub-command shows available commands
7
+ When I run `knife windows`
8
+ And the output should contain "Available windows subcommands: (for details, knife SUB-COMMAND --help)\n\n** WINDOWS COMMANDS **\nknife bootstrap windows winrm FQDN (options)\nknife bootstrap windows ssh FQDN (options)\nknife winrm QUERY COMMAND (options)"
9
+
10
+ Scenario: Running the windows sub-command shows available commands
11
+ When I run `knife windows --help`
12
+ And the output should contain "Available windows subcommands: (for details, knife SUB-COMMAND --help)\n\n** WINDOWS COMMANDS **\nknife bootstrap windows winrm FQDN (options)\nknife bootstrap windows ssh FQDN (options)\nknife winrm QUERY COMMAND (options)"
13
+
14
+ Scenario: Running the windows sub-command shows available commands
15
+ When I run `knife windows help`
16
+ And the output should contain "Available windows subcommands: (for details, knife SUB-COMMAND --help)\n\n** WINDOWS COMMANDS **\nknife bootstrap windows winrm FQDN (options)\nknife bootstrap windows ssh FQDN (options)\nknife winrm QUERY COMMAND (options)"
17
+
18
+ Scenario: Running the knife command shows available windows command"
19
+ When I run `knife`
20
+ And the output should contain "** WINDOWS COMMANDS **\nknife bootstrap windows winrm FQDN (options)\nknife bootstrap windows ssh FQDN (options)\nknife winrm QUERY COMMAND (options)"
@@ -1,5 +1,5 @@
1
- require 'aruba/cucumber'
2
-
3
- Before do
4
- @aruba_timeout_seconds = 5
5
- end
1
+ require 'aruba/cucumber'
2
+
3
+ Before do
4
+ @aruba_timeout_seconds = 5
5
+ end
@@ -330,20 +330,22 @@ class Chef
330
330
  # create a bootstrap.bat file on the node
331
331
  # we have to run the remote commands in 2047 char chunks
332
332
  create_bootstrap_bat_command do |command_chunk|
333
- begin
334
- render_command_result = run_command(command_chunk)
335
- ui.error("Batch render command returned #{render_command_result}") if render_command_result != 0
336
- render_command_result
337
- rescue SystemExit => e
338
- raise unless e.success?
333
+ render_command_result = run_command(command_chunk)
334
+ unless render_command_result == 0
335
+ ui.error("Batch render command returned #{render_command_result}")
336
+ exit render_command_result
339
337
  end
340
338
  end
341
339
 
342
340
  # execute the bootstrap.bat file
343
341
  bootstrap_command_result = run_command(bootstrap_command)
344
- ui.error("Bootstrap command returned #{bootstrap_command_result}") if bootstrap_command_result != 0
342
+ unless bootstrap_command_result == 0
343
+ ui.error("Bootstrap command returned #{bootstrap_command_result}")
344
+ exit bootstrap_command_result
345
+ end
345
346
 
346
- bootstrap_command_result
347
+ # exit 0
348
+ 0
347
349
  end
348
350
 
349
351
  protected
@@ -49,7 +49,12 @@ class Chef
49
49
  STDOUT.sync = STDERR.sync = true
50
50
 
51
51
  configure_session
52
- execute_remote_command
52
+ exit_status = execute_remote_command
53
+ if exit_status != 0
54
+ exit exit_status
55
+ else
56
+ exit_status
57
+ end
53
58
  end
54
59
 
55
60
  def execute_remote_command
@@ -112,42 +112,49 @@ class Chef
112
112
 
113
113
  def run_command(command = '')
114
114
  relay_winrm_command(command)
115
-
116
115
  check_for_errors!
117
-
118
- # Knife seems to ignore the return value of this method,
119
- # so we exit to force the process exit code for this
120
- # subcommand if returns is set
121
- exit @exit_code if @exit_code && @exit_code != 0
122
- 0
116
+ @exit_code
123
117
  end
124
118
 
125
119
  def relay_winrm_command(command)
126
120
  Chef::Log.debug(command)
127
- session_results = []
128
- @winrm_sessions.each do |s|
129
- begin
130
- session_results << s.relay_command(command)
131
- rescue WinRM::WinRMHTTPTransportError, WinRM::WinRMAuthorizationError => e
132
- if authorization_error?(e)
133
- if ! config[:suppress_auth_failure]
134
- # Display errors if the caller hasn't opted to retry
135
- ui.error "Failed to authenticate to #{s.host} as #{locate_config_value(:winrm_user)}"
136
- ui.info "Response: #{e.message}"
137
- ui.info get_failed_authentication_hint
138
- raise e
139
- end
140
- @exit_code = 401
141
- else
142
- raise e
121
+ @session_results = []
122
+
123
+ queue = Queue.new
124
+ @winrm_sessions.each { |s| queue << s }
125
+ # These nils will kill the Threads once no more sessions are left
126
+ locate_config_value(:concurrency).times { queue << nil }
127
+
128
+ threads = []
129
+ locate_config_value(:concurrency).times do
130
+ threads << Thread.new do
131
+ while session = queue.pop
132
+ run_command_in_thread(session, command)
143
133
  end
144
134
  end
145
135
  end
146
- session_results
136
+ threads.map(&:join)
137
+ @session_results
147
138
  end
148
139
 
149
140
  private
150
141
 
142
+ def run_command_in_thread(s, command)
143
+ @session_results << s.relay_command(command)
144
+ rescue WinRM::WinRMHTTPTransportError, WinRM::WinRMAuthorizationError => e
145
+ if authorization_error?(e)
146
+ if ! config[:suppress_auth_failure]
147
+ # Display errors if the caller hasn't opted to retry
148
+ ui.error "Failed to authenticate to #{s.host} as #{locate_config_value(:winrm_user)}"
149
+ ui.info "Response: #{e.message}"
150
+ ui.info get_failed_authentication_hint
151
+ raise e
152
+ end
153
+ else
154
+ raise e
155
+ end
156
+ end
157
+
151
158
  def get_failed_authentication_hint
152
159
  if @session_opts[:basic_auth_only]
153
160
  FAILED_BASIC_HINT
@@ -162,10 +169,11 @@ class Chef
162
169
  end
163
170
 
164
171
  def check_for_errors!
172
+ @exit_code ||= 0
165
173
  @winrm_sessions.each do |session|
166
174
  session_exit_code = session.exit_code
167
175
  unless success_return_codes.include? session_exit_code.to_i
168
- @exit_code = session_exit_code.to_i
176
+ @exit_code = [@exit_code, session_exit_code.to_i].max
169
177
  ui.error "Failed to execute command on #{session.host} return code #{session_exit_code}"
170
178
  end
171
179
  end
@@ -73,6 +73,9 @@ class Chef
73
73
  end
74
74
  @exit_code = session_result.exitcode
75
75
  session_result
76
+ rescue WinRM::WinRMHTTPTransportError, WinRM::WinRMAuthorizationError => e
77
+ @exit_code = 401
78
+ raise e
76
79
  end
77
80
 
78
81
  private
@@ -39,6 +39,13 @@ class Chef
39
39
  :long => "--attribute ATTR",
40
40
  :description => "The attribute to use for opening the connection - default is fqdn",
41
41
  :default => "fqdn"
42
+
43
+ option :concurrency,
44
+ :short => "-C NUM",
45
+ :long => "--concurrency NUM",
46
+ :description => "The number of allowed concurrent connections",
47
+ :default => 1,
48
+ :proc => lambda { |o| o.to_i }
42
49
  end
43
50
  end
44
51
 
@@ -1,6 +1,6 @@
1
1
  module Knife
2
2
  module Windows
3
- VERSION = "1.8.0"
3
+ VERSION = "1.9.0"
4
4
  MAJOR, MINOR, TINY = VERSION.split('.')
5
5
  end
6
6
  end
@@ -1,246 +1,246 @@
1
- @rem
2
- @rem Author:: Seth Chisamore (<schisamo@opscode.com>)
3
- @rem Copyright:: Copyright (c) 2011 Opscode, Inc.
4
- @rem License:: Apache License, Version 2.0
5
- @rem
6
- @rem Licensed under the Apache License, Version 2.0 (the "License");
7
- @rem you may not use this file except in compliance with the License.
8
- @rem You may obtain a copy of the License at
9
- @rem
10
- @rem http://www.apache.org/licenses/LICENSE-2.0
11
- @rem
12
- @rem Unless required by applicable law or agreed to in writing, software
13
- @rem distributed under the License is distributed on an "AS IS" BASIS,
14
- @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
- @rem See the License for the specific language governing permissions and
16
- @rem limitations under the License.
17
- @rem
18
-
19
- @rem Use delayed environment expansion so that ERRORLEVEL can be evaluated with the
20
- @rem !ERRORLEVEL! syntax which evaluates at execution of the line of script, not when
21
- @rem the line is read. See help for the /E switch from cmd.exe /? .
22
- @setlocal ENABLEDELAYEDEXPANSION
23
-
24
- <%= "SETX HTTP_PROXY \"#{knife_config[:bootstrap_proxy]}\"" if knife_config[:bootstrap_proxy] %>
25
-
26
- @set BOOTSTRAP_DIRECTORY=<%= bootstrap_directory %>
27
- @echo Checking for existing directory "%BOOTSTRAP_DIRECTORY%"...
28
- @if NOT EXIST %BOOTSTRAP_DIRECTORY% (
29
- @echo Existing directory not found, creating.
30
- @mkdir %BOOTSTRAP_DIRECTORY%
31
- ) else (
32
- @echo Existing directory found, skipping creation.
33
- )
34
-
35
- > <%= bootstrap_directory %>\wget.vbs (
36
- <%= win_wget %>
37
- )
38
-
39
- > <%= bootstrap_directory %>\wget.ps1 (
40
- <%= win_wget_ps %>
41
- )
42
-
43
- @rem Determine the version and the architecture
44
-
45
- @FOR /F "usebackq tokens=1-8 delims=.[] " %%A IN (`ver`) DO (
46
- @set WinMajor=%%D
47
- @set WinMinor=%%E
48
- @set WinBuild=%%F
49
- )
50
-
51
- @echo Detected Windows Version %WinMajor%.%WinMinor% Build %WinBuild%
52
-
53
- @set LATEST_OS_VERSION_MAJOR=6
54
- @set LATEST_OS_VERSION_MINOR=3
55
-
56
- @if /i %WinMajor% GTR %LATEST_OS_VERSION_MAJOR% goto VersionUnknown
57
- @if /i %WinMajor% EQU %LATEST_OS_VERSION_MAJOR% (
58
- @if /i %WinMinor% GTR %LATEST_OS_VERSION_MINOR% goto VersionUnknown
59
- )
60
-
61
- goto Version%WinMajor%.%WinMinor%
62
-
63
- :VersionUnknown
64
- @rem If this is an unknown version of windows set the default
65
- @set MACHINE_OS=2008r2
66
- @echo Warning: Unknown version of Windows, assuming default of Windows %MACHINE_OS%
67
- goto architecture_select
68
-
69
- :Version6.0
70
- @set MACHINE_OS=2008
71
- goto architecture_select
72
-
73
- :Version5.2
74
- @set MACHINE_OS=2003r2
75
- goto architecture_select
76
-
77
- :Version6.1
78
- @set MACHINE_OS=2008r2
79
- goto architecture_select
80
-
81
- :Version6.2
82
- @set MACHINE_OS=2012
83
- goto architecture_select
84
-
85
- @rem Currently Windows Server 2012 R2 is treated as equivalent to Windows Server 2012
86
- :Version6.3
87
- goto Version6.2
88
-
89
- :architecture_select
90
- goto Architecture%PROCESSOR_ARCHITEW6432%
91
-
92
- :Architecture
93
- goto Architecture%PROCESSOR_ARCHITECTURE%
94
-
95
- @rem If this is an unknown architecture set the default
96
- @set MACHINE_ARCH=i686
97
- goto install
98
-
99
- :Architecturex86
100
- @set MACHINE_ARCH=i686
101
- goto install
102
-
103
- :Architectureamd64
104
- @set MACHINE_ARCH=x86_64
105
- goto install
106
-
107
- :install
108
- @rem If user has provided the custom installation command for chef-client then execute it
109
- <% if @chef_config[:knife][:bootstrap_install_command] %>
110
- <%= @chef_config[:knife][:bootstrap_install_command] %>
111
- <% else %>
112
- @rem Install Chef using chef-client MSI installer
113
-
114
- @set "LOCAL_DESTINATION_MSI_PATH=<%= local_download_path %>"
115
- @set "CHEF_CLIENT_MSI_LOG_PATH=%TEMP%\chef-client-msi%RANDOM%.log"
116
-
117
- @rem Clear any pre-existing downloads
118
- @echo Checking for existing downloaded package at "%LOCAL_DESTINATION_MSI_PATH%"
119
- @if EXIST "%LOCAL_DESTINATION_MSI_PATH%" (
120
- @echo Found existing downloaded package, deleting.
121
- @del /f /q "%LOCAL_DESTINATION_MSI_PATH%"
122
- @if ERRORLEVEL 1 (
123
- echo Warning: Failed to delete pre-existing package with status code !ERRORLEVEL! > "&2"
124
- )
125
- ) else (
126
- echo No existing downloaded packages to delete.
127
- )
128
-
129
- @rem If there is somehow a name collision, remove pre-existing log
130
- @if EXIST "%CHEF_CLIENT_MSI_LOG_PATH%" del /f /q "%CHEF_CLIENT_MSI_LOG_PATH%"
131
-
132
- @echo Attempting to download client package using PowerShell if available...
133
- @set "REMOTE_SOURCE_MSI_URL=<%= msi_url('%MACHINE_OS%', '%MACHINE_ARCH%', 'PowerShell') %>"
134
- @set powershell_download=powershell.exe -ExecutionPolicy Unrestricted -NoProfile -NonInteractive -File <%= bootstrap_directory %>\wget.ps1 "%REMOTE_SOURCE_MSI_URL%" "%LOCAL_DESTINATION_MSI_PATH%"
135
- @echo !powershell_download!
136
- @call !powershell_download!
137
-
138
- @set DOWNLOAD_ERROR_STATUS=!ERRORLEVEL!
139
-
140
- @if ERRORLEVEL 1 (
141
- @echo Failed PowerShell download with status code !DOWNLOAD_ERROR_STATUS! > "&2"
142
- @if !DOWNLOAD_ERROR_STATUS!==0 set DOWNLOAD_ERROR_STATUS=2
143
- ) else (
144
- @rem Sometimes the error level is not set even when the download failed,
145
- @rem so check for the file to be sure it is there -- if it is not, we will retry
146
- @if NOT EXIST "%LOCAL_DESTINATION_MSI_PATH%" (
147
- echo Failed download: download completed, but downloaded file not found > "&2"
148
- set DOWNLOAD_ERROR_STATUS=2
149
- ) else (
150
- echo Download via PowerShell succeeded.
151
- )
152
- )
153
-
154
- @if NOT %DOWNLOAD_ERROR_STATUS%==0 (
155
- @echo Warning: Failed to download "%REMOTE_SOURCE_MSI_URL%" to "%LOCAL_DESTINATION_MSI_PATH%"
156
- @echo Warning: Retrying download with cscript ...
157
-
158
- @if EXIST "%LOCAL_DESTINATION_MSI_PATH%" del /f /q "%LOCAL_DESTINATION_MSI_PATH%"
159
-
160
- @set "REMOTE_SOURCE_MSI_URL=<%= msi_url('%MACHINE_OS%', '%MACHINE_ARCH%') %>"
161
- cscript /nologo <%= bootstrap_directory %>\wget.vbs /url:"%REMOTE_SOURCE_MSI_URL%" /path:"%LOCAL_DESTINATION_MSI_PATH%"
162
-
163
- @if NOT ERRORLEVEL 1 (
164
- @rem Sometimes the error level is not set even when the download failed,
165
- @rem so check for the file to be sure it is there.
166
- @if NOT EXIST "%LOCAL_DESTINATION_MSI_PATH%" (
167
- echo Failed download: download completed, but downloaded file not found > "&2"
168
- echo Exiting without bootstrapping due to download failure. > "&2"
169
- exit /b 1
170
- ) else (
171
- echo Download via cscript succeeded.
172
- )
173
- ) else (
174
- echo Failed to download "%REMOTE_SOURCE_MSI_URL%" with status code !ERRORLEVEL!. > "&2"
175
- echo Exiting without bootstrapping due to download failure. > "&2"
176
- exit /b 1
177
- )
178
- )
179
-
180
- @echo Installing downloaded client package...
181
-
182
- <%= install_chef %>
183
-
184
- @if ERRORLEVEL 1 (
185
- echo Chef-client package failed to install with status code !ERRORLEVEL!. > "&2"
186
- echo See installation log for additional detail: %CHEF_CLIENT_MSI_LOG_PATH%. > "&2"
187
- ) else (
188
- @echo Installation completed successfully
189
- del /f /q "%CHEF_CLIENT_MSI_LOG_PATH%"
190
- )
191
-
192
- <% end %>
193
-
194
- @endlocal
195
-
196
- @echo off
197
-
198
- <% if client_pem -%>
199
- > <%= bootstrap_directory %>\client.pem (
200
- <%= escape_and_echo(::File.read(::File.expand_path(client_pem))) %>
201
- )
202
- <% end -%>
203
-
204
- echo Writing validation key...
205
-
206
- <% if validation_key -%>
207
- > <%= bootstrap_directory %>\validation.pem (
208
- <%= escape_and_echo(validation_key) %>
209
- )
210
- <% end -%>
211
-
212
- echo Validation key written.
213
- @echo on
214
-
215
- <% if @config[:secret] -%>
216
- > <%= bootstrap_directory %>\encrypted_data_bag_secret (
217
- <%= secret %>
218
- )
219
- <% end -%>
220
-
221
- <% unless trusted_certs_script.empty? -%>
222
- mkdir <%= bootstrap_directory %>\trusted_certs
223
- <%= trusted_certs_script %>
224
- <% end -%>
225
-
226
- <%# Generate Ohai Hints -%>
227
- <% unless @chef_config[:knife][:hints].nil? || @chef_config[:knife][:hints].empty? -%>
228
- mkdir <%= bootstrap_directory %>\ohai\hints
229
-
230
- <% @chef_config[:knife][:hints].each do |name, hash| -%>
231
- > <%= bootstrap_directory %>\ohai\hints\<%= name %>.json (
232
- <%= escape_and_echo(hash.to_json) %>
233
- )
234
- <% end -%>
235
- <% end -%>
236
-
237
- > <%= bootstrap_directory %>\client.rb (
238
- <%= config_content %>
239
- )
240
-
241
- > <%= bootstrap_directory %>\first-boot.json (
242
- <%= first_boot %>
243
- )
244
-
245
- @echo Starting chef to bootstrap the node...
246
- <%= start_chef %>
1
+ @rem
2
+ @rem Author:: Seth Chisamore (<schisamo@opscode.com>)
3
+ @rem Copyright:: Copyright (c) 2011 Opscode, Inc.
4
+ @rem License:: Apache License, Version 2.0
5
+ @rem
6
+ @rem Licensed under the Apache License, Version 2.0 (the "License");
7
+ @rem you may not use this file except in compliance with the License.
8
+ @rem You may obtain a copy of the License at
9
+ @rem
10
+ @rem http://www.apache.org/licenses/LICENSE-2.0
11
+ @rem
12
+ @rem Unless required by applicable law or agreed to in writing, software
13
+ @rem distributed under the License is distributed on an "AS IS" BASIS,
14
+ @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ @rem See the License for the specific language governing permissions and
16
+ @rem limitations under the License.
17
+ @rem
18
+
19
+ @rem Use delayed environment expansion so that ERRORLEVEL can be evaluated with the
20
+ @rem !ERRORLEVEL! syntax which evaluates at execution of the line of script, not when
21
+ @rem the line is read. See help for the /E switch from cmd.exe /? .
22
+ @setlocal ENABLEDELAYEDEXPANSION
23
+
24
+ <%= "SETX HTTP_PROXY \"#{knife_config[:bootstrap_proxy]}\"" if knife_config[:bootstrap_proxy] %>
25
+
26
+ @set BOOTSTRAP_DIRECTORY=<%= bootstrap_directory %>
27
+ @echo Checking for existing directory "%BOOTSTRAP_DIRECTORY%"...
28
+ @if NOT EXIST %BOOTSTRAP_DIRECTORY% (
29
+ @echo Existing directory not found, creating.
30
+ @mkdir %BOOTSTRAP_DIRECTORY%
31
+ ) else (
32
+ @echo Existing directory found, skipping creation.
33
+ )
34
+
35
+ > <%= bootstrap_directory %>\wget.vbs (
36
+ <%= win_wget %>
37
+ )
38
+
39
+ > <%= bootstrap_directory %>\wget.ps1 (
40
+ <%= win_wget_ps %>
41
+ )
42
+
43
+ @rem Determine the version and the architecture
44
+
45
+ @FOR /F "usebackq tokens=1-8 delims=.[] " %%A IN (`ver`) DO (
46
+ @set WinMajor=%%D
47
+ @set WinMinor=%%E
48
+ @set WinBuild=%%F
49
+ )
50
+
51
+ @echo Detected Windows Version %WinMajor%.%WinMinor% Build %WinBuild%
52
+
53
+ @set LATEST_OS_VERSION_MAJOR=6
54
+ @set LATEST_OS_VERSION_MINOR=3
55
+
56
+ @if /i %WinMajor% GTR %LATEST_OS_VERSION_MAJOR% goto VersionUnknown
57
+ @if /i %WinMajor% EQU %LATEST_OS_VERSION_MAJOR% (
58
+ @if /i %WinMinor% GTR %LATEST_OS_VERSION_MINOR% goto VersionUnknown
59
+ )
60
+
61
+ goto Version%WinMajor%.%WinMinor%
62
+
63
+ :VersionUnknown
64
+ @rem If this is an unknown version of windows set the default
65
+ @set MACHINE_OS=2008r2
66
+ @echo Warning: Unknown version of Windows, assuming default of Windows %MACHINE_OS%
67
+ goto architecture_select
68
+
69
+ :Version6.0
70
+ @set MACHINE_OS=2008
71
+ goto architecture_select
72
+
73
+ :Version5.2
74
+ @set MACHINE_OS=2003r2
75
+ goto architecture_select
76
+
77
+ :Version6.1
78
+ @set MACHINE_OS=2008r2
79
+ goto architecture_select
80
+
81
+ :Version6.2
82
+ @set MACHINE_OS=2012
83
+ goto architecture_select
84
+
85
+ @rem Currently Windows Server 2012 R2 is treated as equivalent to Windows Server 2012
86
+ :Version6.3
87
+ goto Version6.2
88
+
89
+ :architecture_select
90
+ goto Architecture%PROCESSOR_ARCHITEW6432%
91
+
92
+ :Architecture
93
+ goto Architecture%PROCESSOR_ARCHITECTURE%
94
+
95
+ @rem If this is an unknown architecture set the default
96
+ @set MACHINE_ARCH=i686
97
+ goto install
98
+
99
+ :Architecturex86
100
+ @set MACHINE_ARCH=i686
101
+ goto install
102
+
103
+ :Architectureamd64
104
+ @set MACHINE_ARCH=x86_64
105
+ goto install
106
+
107
+ :install
108
+ @rem If user has provided the custom installation command for chef-client then execute it
109
+ <% if @chef_config[:knife][:bootstrap_install_command] %>
110
+ <%= @chef_config[:knife][:bootstrap_install_command] %>
111
+ <% else %>
112
+ @rem Install Chef using chef-client MSI installer
113
+
114
+ @set "LOCAL_DESTINATION_MSI_PATH=<%= local_download_path %>"
115
+ @set "CHEF_CLIENT_MSI_LOG_PATH=%TEMP%\chef-client-msi%RANDOM%.log"
116
+
117
+ @rem Clear any pre-existing downloads
118
+ @echo Checking for existing downloaded package at "%LOCAL_DESTINATION_MSI_PATH%"
119
+ @if EXIST "%LOCAL_DESTINATION_MSI_PATH%" (
120
+ @echo Found existing downloaded package, deleting.
121
+ @del /f /q "%LOCAL_DESTINATION_MSI_PATH%"
122
+ @if ERRORLEVEL 1 (
123
+ echo Warning: Failed to delete pre-existing package with status code !ERRORLEVEL! > "&2"
124
+ )
125
+ ) else (
126
+ echo No existing downloaded packages to delete.
127
+ )
128
+
129
+ @rem If there is somehow a name collision, remove pre-existing log
130
+ @if EXIST "%CHEF_CLIENT_MSI_LOG_PATH%" del /f /q "%CHEF_CLIENT_MSI_LOG_PATH%"
131
+
132
+ @echo Attempting to download client package using PowerShell if available...
133
+ @set "REMOTE_SOURCE_MSI_URL=<%= msi_url('%MACHINE_OS%', '%MACHINE_ARCH%', 'PowerShell') %>"
134
+ @set powershell_download=powershell.exe -ExecutionPolicy Unrestricted -NoProfile -NonInteractive -File <%= bootstrap_directory %>\wget.ps1 "%REMOTE_SOURCE_MSI_URL%" "%LOCAL_DESTINATION_MSI_PATH%"
135
+ @echo !powershell_download!
136
+ @call !powershell_download!
137
+
138
+ @set DOWNLOAD_ERROR_STATUS=!ERRORLEVEL!
139
+
140
+ @if ERRORLEVEL 1 (
141
+ @echo Failed PowerShell download with status code !DOWNLOAD_ERROR_STATUS! > "&2"
142
+ @if !DOWNLOAD_ERROR_STATUS!==0 set DOWNLOAD_ERROR_STATUS=2
143
+ ) else (
144
+ @rem Sometimes the error level is not set even when the download failed,
145
+ @rem so check for the file to be sure it is there -- if it is not, we will retry
146
+ @if NOT EXIST "%LOCAL_DESTINATION_MSI_PATH%" (
147
+ echo Failed download: download completed, but downloaded file not found > "&2"
148
+ set DOWNLOAD_ERROR_STATUS=2
149
+ ) else (
150
+ echo Download via PowerShell succeeded.
151
+ )
152
+ )
153
+
154
+ @if NOT %DOWNLOAD_ERROR_STATUS%==0 (
155
+ @echo Warning: Failed to download "%REMOTE_SOURCE_MSI_URL%" to "%LOCAL_DESTINATION_MSI_PATH%"
156
+ @echo Warning: Retrying download with cscript ...
157
+
158
+ @if EXIST "%LOCAL_DESTINATION_MSI_PATH%" del /f /q "%LOCAL_DESTINATION_MSI_PATH%"
159
+
160
+ @set "REMOTE_SOURCE_MSI_URL=<%= msi_url('%MACHINE_OS%', '%MACHINE_ARCH%') %>"
161
+ cscript /nologo <%= bootstrap_directory %>\wget.vbs /url:"%REMOTE_SOURCE_MSI_URL%" /path:"%LOCAL_DESTINATION_MSI_PATH%"
162
+
163
+ @if NOT ERRORLEVEL 1 (
164
+ @rem Sometimes the error level is not set even when the download failed,
165
+ @rem so check for the file to be sure it is there.
166
+ @if NOT EXIST "%LOCAL_DESTINATION_MSI_PATH%" (
167
+ echo Failed download: download completed, but downloaded file not found > "&2"
168
+ echo Exiting without bootstrapping due to download failure. > "&2"
169
+ exit /b 1
170
+ ) else (
171
+ echo Download via cscript succeeded.
172
+ )
173
+ ) else (
174
+ echo Failed to download "%REMOTE_SOURCE_MSI_URL%" with status code !ERRORLEVEL!. > "&2"
175
+ echo Exiting without bootstrapping due to download failure. > "&2"
176
+ exit /b 1
177
+ )
178
+ )
179
+
180
+ @echo Installing downloaded client package...
181
+
182
+ <%= install_chef %>
183
+
184
+ @if ERRORLEVEL 1 (
185
+ echo Chef-client package failed to install with status code !ERRORLEVEL!. > "&2"
186
+ echo See installation log for additional detail: %CHEF_CLIENT_MSI_LOG_PATH%. > "&2"
187
+ ) else (
188
+ @echo Installation completed successfully
189
+ del /f /q "%CHEF_CLIENT_MSI_LOG_PATH%"
190
+ )
191
+
192
+ <% end %>
193
+
194
+ @endlocal
195
+
196
+ @echo off
197
+
198
+ <% if client_pem -%>
199
+ > <%= bootstrap_directory %>\client.pem (
200
+ <%= escape_and_echo(::File.read(::File.expand_path(client_pem))) %>
201
+ )
202
+ <% end -%>
203
+
204
+ echo Writing validation key...
205
+
206
+ <% if validation_key -%>
207
+ > <%= bootstrap_directory %>\validation.pem (
208
+ <%= escape_and_echo(validation_key) %>
209
+ )
210
+ <% end -%>
211
+
212
+ echo Validation key written.
213
+ @echo on
214
+
215
+ <% if @config[:secret] -%>
216
+ > <%= bootstrap_directory %>\encrypted_data_bag_secret (
217
+ <%= secret %>
218
+ )
219
+ <% end -%>
220
+
221
+ <% unless trusted_certs_script.empty? -%>
222
+ mkdir <%= bootstrap_directory %>\trusted_certs
223
+ <%= trusted_certs_script %>
224
+ <% end -%>
225
+
226
+ <%# Generate Ohai Hints -%>
227
+ <% unless @chef_config[:knife][:hints].nil? || @chef_config[:knife][:hints].empty? -%>
228
+ mkdir <%= bootstrap_directory %>\ohai\hints
229
+
230
+ <% @chef_config[:knife][:hints].each do |name, hash| -%>
231
+ > <%= bootstrap_directory %>\ohai\hints\<%= name %>.json (
232
+ <%= escape_and_echo(hash.to_json) %>
233
+ )
234
+ <% end -%>
235
+ <% end -%>
236
+
237
+ > <%= bootstrap_directory %>\client.rb (
238
+ <%= config_content %>
239
+ )
240
+
241
+ > <%= bootstrap_directory %>\first-boot.json (
242
+ <%= first_boot %>
243
+ )
244
+
245
+ @echo Starting chef to bootstrap the node...
246
+ <%= start_chef %>