knife-windows 1.9.6 → 3.0.3

Sign up to get free protection for your applications and to get access to all the features.
data/Rakefile DELETED
@@ -1,21 +0,0 @@
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
data/ci.gemfile DELETED
@@ -1,16 +0,0 @@
1
- source "https://rubygems.org"
2
-
3
- # Specify your gem's dependencies in knife-windows.gemspec
4
- gemspec
5
-
6
- if ENV['CHEF_VERSION'] == 'master'
7
- gem 'chef', github: 'chef/chef'
8
- gem 'ohai', github: 'chef/ohai'
9
- else
10
- gem 'chef', ENV['CHEF_VERSION']
11
- end
12
-
13
- gem "rspec", '~> 3.0'
14
- gem "ruby-wmi"
15
- gem "httpclient"
16
- gem 'rake'
@@ -1,26 +0,0 @@
1
- # -*- encoding: utf-8 -*-
2
- $:.push File.expand_path("../lib", __FILE__)
3
- require "knife-windows/version"
4
-
5
- Gem::Specification.new do |s|
6
- s.name = "knife-windows"
7
- s.version = Knife::Windows::VERSION
8
- s.platform = Gem::Platform::RUBY
9
- s.authors = ["Seth Chisamore"]
10
- s.email = ["schisamo@chef.io"]
11
- s.license = "Apache-2.0"
12
- s.homepage = "https://github.com/chef/knife-windows"
13
- s.summary = %q{Plugin that adds functionality to Chef's Knife CLI for configuring/interacting with nodes running Microsoft Windows}
14
- s.description = s.summary
15
-
16
- s.required_ruby_version = ">= 1.9.1"
17
- s.add_dependency "winrm", "~> 2.1"
18
- s.add_dependency "winrm-elevated", "~> 1.0"
19
-
20
- s.add_development_dependency 'pry'
21
-
22
- s.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(\..*|DOC_CHANGES.md|VERSION|appveyor.yml|RELEASE_NOTES.md)}) }
23
- s.test_files = `git ls-files -- spec/*`.split("\n")
24
- s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
25
- s.require_paths = ["lib"]
26
- end
@@ -1,259 +0,0 @@
1
- @rem
2
- @rem Author:: Seth Chisamore (<schisamo@chef.io>)
3
- @rem Copyright:: Copyright (c) 2011-2017 Chef Software, 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=10
54
- @set LATEST_OS_VERSION_MINOR=1
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=2012r2
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
- @set MACHINE_OS=2012r2
88
- goto architecture_select
89
-
90
- :Version10.0
91
- @set MACHINE_OS=2016
92
- goto architecture_select
93
-
94
- @rem Currently Windows Server 2016 R2 is treated as equivalent to Windows Server 2016
95
- :Version10.1
96
- goto Version10.0
97
-
98
- :architecture_select
99
- <% if knife_config[:architecture] %>
100
- @set MACHINE_ARCH=<%= knife_config[:architecture] %>
101
-
102
- <% if knife_config[:architecture] == "x86_64" %>
103
- IF "%PROCESSOR_ARCHITECTURE%"=="x86" IF not defined PROCESSOR_ARCHITEW6432 (
104
- echo You specified bootstrap_architecture as x86_64 but the target machine is i386. A 64 bit program cannot run on a 32 bit machine. > "&2"
105
- echo Exiting without bootstrapping. > "&2"
106
- exit /b 1
107
- )
108
- <% end %>
109
- <% else %>
110
- @set MACHINE_ARCH=x86_64
111
- IF "%PROCESSOR_ARCHITECTURE%"=="x86" IF not defined PROCESSOR_ARCHITEW6432 @set MACHINE_ARCH=i686
112
- <% end %>
113
- goto install
114
-
115
- :install
116
- @rem If user has provided the custom installation command for chef-client then execute it
117
- <% if @chef_config[:knife][:bootstrap_install_command] %>
118
- <%= @chef_config[:knife][:bootstrap_install_command] %>
119
- <% else %>
120
- @rem Install Chef using chef-client MSI installer
121
-
122
- @set "LOCAL_DESTINATION_MSI_PATH=<%= local_download_path %>"
123
- @set "CHEF_CLIENT_MSI_LOG_PATH=%TEMP%\chef-client-msi%RANDOM%.log"
124
-
125
- @rem Clear any pre-existing downloads
126
- @echo Checking for existing downloaded package at "%LOCAL_DESTINATION_MSI_PATH%"
127
- @if EXIST "%LOCAL_DESTINATION_MSI_PATH%" (
128
- @echo Found existing downloaded package, deleting.
129
- @del /f /q "%LOCAL_DESTINATION_MSI_PATH%"
130
- @if ERRORLEVEL 1 (
131
- echo Warning: Failed to delete pre-existing package with status code !ERRORLEVEL! > "&2"
132
- )
133
- ) else (
134
- echo No existing downloaded packages to delete.
135
- )
136
-
137
- @rem If there is somehow a name collision, remove pre-existing log
138
- @if EXIST "%CHEF_CLIENT_MSI_LOG_PATH%" del /f /q "%CHEF_CLIENT_MSI_LOG_PATH%"
139
-
140
- @echo Attempting to download client package using PowerShell if available...
141
- @set "REMOTE_SOURCE_MSI_URL=<%= msi_url('%MACHINE_OS%', '%MACHINE_ARCH%', 'PowerShell') %>"
142
- @set powershell_download=powershell.exe -ExecutionPolicy Unrestricted -InputFormat None -NoProfile -NonInteractive -File <%= bootstrap_directory %>\wget.ps1 "%REMOTE_SOURCE_MSI_URL%" "%LOCAL_DESTINATION_MSI_PATH%"
143
- @echo !powershell_download!
144
- @call !powershell_download!
145
-
146
- @set DOWNLOAD_ERROR_STATUS=!ERRORLEVEL!
147
-
148
- @if ERRORLEVEL 1 (
149
- @echo Failed PowerShell download with status code !DOWNLOAD_ERROR_STATUS! > "&2"
150
- @if !DOWNLOAD_ERROR_STATUS!==0 set DOWNLOAD_ERROR_STATUS=2
151
- ) else (
152
- @rem Sometimes the error level is not set even when the download failed,
153
- @rem so check for the file to be sure it is there -- if it is not, we will retry
154
- @if NOT EXIST "%LOCAL_DESTINATION_MSI_PATH%" (
155
- echo Failed download: download completed, but downloaded file not found > "&2"
156
- set DOWNLOAD_ERROR_STATUS=2
157
- ) else (
158
- echo Download via PowerShell succeeded.
159
- )
160
- )
161
-
162
- @if NOT %DOWNLOAD_ERROR_STATUS%==0 (
163
- @echo Warning: Failed to download "%REMOTE_SOURCE_MSI_URL%" to "%LOCAL_DESTINATION_MSI_PATH%"
164
- @echo Warning: Retrying download with cscript ...
165
-
166
- @if EXIST "%LOCAL_DESTINATION_MSI_PATH%" del /f /q "%LOCAL_DESTINATION_MSI_PATH%"
167
-
168
- @set "REMOTE_SOURCE_MSI_URL=<%= msi_url('%MACHINE_OS%', '%MACHINE_ARCH%') %>"
169
- cscript /nologo <%= bootstrap_directory %>\wget.vbs /url:"%REMOTE_SOURCE_MSI_URL%" /path:"%LOCAL_DESTINATION_MSI_PATH%"
170
-
171
- @if NOT ERRORLEVEL 1 (
172
- @rem Sometimes the error level is not set even when the download failed,
173
- @rem so check for the file to be sure it is there.
174
- @if NOT EXIST "%LOCAL_DESTINATION_MSI_PATH%" (
175
- echo Failed download: download completed, but downloaded file not found > "&2"
176
- echo Exiting without bootstrapping due to download failure. > "&2"
177
- exit /b 1
178
- ) else (
179
- echo Download via cscript succeeded.
180
- )
181
- ) else (
182
- echo Failed to download "%REMOTE_SOURCE_MSI_URL%" with status code !ERRORLEVEL!. > "&2"
183
- echo Exiting without bootstrapping due to download failure. > "&2"
184
- exit /b 1
185
- )
186
- )
187
-
188
- @echo Installing downloaded client package...
189
-
190
- <%= install_chef %>
191
-
192
- @if ERRORLEVEL 1 (
193
- echo Chef-client package failed to install with status code !ERRORLEVEL!. > "&2"
194
- echo See installation log for additional detail: %CHEF_CLIENT_MSI_LOG_PATH%. > "&2"
195
- ) else (
196
- @echo Installation completed successfully
197
- del /f /q "%CHEF_CLIENT_MSI_LOG_PATH%"
198
- )
199
-
200
- <% end %>
201
-
202
- @endlocal
203
-
204
- @echo off
205
-
206
- <% if client_pem -%>
207
- > <%= bootstrap_directory %>\client.pem (
208
- <%= escape_and_echo(::File.read(::File.expand_path(client_pem))) %>
209
- )
210
- <% end -%>
211
-
212
- echo Writing validation key...
213
-
214
- <% if validation_key -%>
215
- > <%= bootstrap_directory %>\validation.pem (
216
- <%= escape_and_echo(validation_key) %>
217
- )
218
- <% end -%>
219
-
220
- echo Validation key written.
221
- @echo on
222
-
223
- <% if @config[:secret] -%>
224
- > <%= bootstrap_directory %>\encrypted_data_bag_secret (
225
- <%= secret %>
226
- )
227
- <% end -%>
228
-
229
- <% unless trusted_certs_script.empty? -%>
230
- mkdir <%= bootstrap_directory %>\trusted_certs
231
- <%= trusted_certs_script %>
232
- <% end -%>
233
-
234
- <%# Generate Ohai Hints -%>
235
- <% unless @chef_config[:knife][:hints].nil? || @chef_config[:knife][:hints].empty? -%>
236
- mkdir <%= bootstrap_directory %>\ohai\hints
237
-
238
- <% @chef_config[:knife][:hints].each do |name, hash| -%>
239
- > <%= bootstrap_directory %>\ohai\hints\<%= name %>.json (
240
- <%= escape_and_echo(hash.to_json) %>
241
- )
242
- <% end -%>
243
- <% end -%>
244
-
245
- > <%= bootstrap_directory %>\client.rb (
246
- <%= config_content %>
247
- )
248
-
249
- > <%= bootstrap_directory %>\first-boot.json (
250
- <%= first_boot %>
251
- )
252
-
253
- <% unless client_d.empty? -%>
254
- mkdir <%= bootstrap_directory %>\client.d
255
- <%= client_d %>
256
- <% end -%>
257
-
258
- @echo Starting chef to bootstrap the node...
259
- <%= start_chef %>
@@ -1,417 +0,0 @@
1
- #
2
- # Author:: Seth Chisamore (<schisamo@chef.io>)
3
- # Copyright:: Copyright (c) 2011-2016 Chef Software, Inc.
4
- # License:: Apache License, Version 2.0
5
- #
6
- # Licensed under the Apache License, Version 2.0 (the "License");
7
- # you may not use this file except in compliance with the License.
8
- # You may obtain a copy of the License at
9
- #
10
- # http://www.apache.org/licenses/LICENSE-2.0
11
- #
12
- # Unless required by applicable law or agreed to in writing, software
13
- # distributed under the License is distributed on an "AS IS" BASIS,
14
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
- # See the License for the specific language governing permissions and
16
- # limitations under the License.
17
- #
18
-
19
- require 'chef/knife/core/bootstrap_context'
20
- # Chef::Util::PathHelper in Chef 11 is a bit juvenile still
21
- require 'knife-windows/path_helper'
22
- # require 'chef/util/path_helper'
23
-
24
- class Chef
25
- class Knife
26
- module Core
27
- # Instances of BootstrapContext are the context objects (i.e., +self+) for
28
- # bootstrap templates. For backwards compatability, they +must+ set the
29
- # following instance variables:
30
- # * @config - a hash of knife's config values
31
- # * @run_list - the run list for the node to boostrap
32
- #
33
- class WindowsBootstrapContext < BootstrapContext
34
- PathHelper = ::Knife::Windows::PathHelper
35
-
36
- attr_accessor :client_pem
37
-
38
- def initialize(config, run_list, chef_config, secret=nil)
39
- @config = config
40
- @run_list = run_list
41
- @chef_config = chef_config
42
- @secret = secret
43
- # Compatibility with Chef 12 and Chef 11 versions
44
- begin
45
- # Pass along the secret parameter for Chef 12
46
- super(config, run_list, chef_config, secret)
47
- rescue ArgumentError
48
- # The Chef 11 base class only has parameters for initialize
49
- super(config, run_list, chef_config)
50
- end
51
- end
52
-
53
- def validation_key
54
- if File.exist?(File.expand_path(@chef_config[:validation_key]))
55
- IO.read(File.expand_path(@chef_config[:validation_key]))
56
- else
57
- false
58
- end
59
- end
60
-
61
- def secret
62
- escape_and_echo(@config[:secret])
63
- end
64
-
65
- def trusted_certs_script
66
- @trusted_certs_script ||= trusted_certs_content
67
- end
68
-
69
- def config_content
70
- client_rb = <<-CONFIG
71
- chef_server_url "#{@chef_config[:chef_server_url]}"
72
- validation_client_name "#{@chef_config[:validation_client_name]}"
73
- file_cache_path "c:/chef/cache"
74
- file_backup_path "c:/chef/backup"
75
- cache_options ({:path => "c:/chef/cache/checksums", :skip_expires => true})
76
- CONFIG
77
- if @config[:chef_node_name]
78
- client_rb << %Q{node_name "#{@config[:chef_node_name]}"\n}
79
- else
80
- client_rb << "# Using default node name (fqdn)\n"
81
- end
82
-
83
- if @chef_config[:config_log_level]
84
- client_rb << %Q{log_level :#{@chef_config[:config_log_level]}\n}
85
- else
86
- client_rb << "log_level :info\n"
87
- end
88
-
89
- client_rb << "log_location #{get_log_location}"
90
-
91
- # We configure :verify_api_cert only when it's overridden on the CLI
92
- # or when specified in the knife config.
93
- if !@config[:node_verify_api_cert].nil? || knife_config.has_key?(:verify_api_cert)
94
- value = @config[:node_verify_api_cert].nil? ? knife_config[:verify_api_cert] : @config[:node_verify_api_cert]
95
- client_rb << %Q{verify_api_cert #{value}\n}
96
- end
97
-
98
- # We configure :ssl_verify_mode only when it's overridden on the CLI
99
- # or when specified in the knife config.
100
- if @config[:node_ssl_verify_mode] || knife_config.has_key?(:ssl_verify_mode)
101
- value = case @config[:node_ssl_verify_mode]
102
- when "peer"
103
- :verify_peer
104
- when "none"
105
- :verify_none
106
- when nil
107
- knife_config[:ssl_verify_mode]
108
- else
109
- nil
110
- end
111
-
112
- if value
113
- client_rb << %Q{ssl_verify_mode :#{value}\n}
114
- end
115
- end
116
-
117
- if @config[:ssl_verify_mode]
118
- client_rb << %Q{ssl_verify_mode :#{knife_config[:ssl_verify_mode]}\n}
119
- end
120
-
121
- if knife_config[:bootstrap_proxy]
122
- client_rb << "\n"
123
- client_rb << %Q{http_proxy "#{knife_config[:bootstrap_proxy]}"\n}
124
- client_rb << %Q{https_proxy "#{knife_config[:bootstrap_proxy]}"\n}
125
- client_rb << %Q{no_proxy "#{knife_config[:bootstrap_no_proxy]}"\n} if knife_config[:bootstrap_no_proxy]
126
- end
127
-
128
- if knife_config[:bootstrap_no_proxy]
129
- client_rb << %Q{no_proxy "#{knife_config[:bootstrap_no_proxy]}"\n}
130
- end
131
-
132
- if @config[:secret]
133
- client_rb << %Q{encrypted_data_bag_secret "c:/chef/encrypted_data_bag_secret"\n}
134
- end
135
-
136
- unless trusted_certs_script.empty?
137
- client_rb << %Q{trusted_certs_dir "c:/chef/trusted_certs"\n}
138
- end
139
-
140
- if Chef::Config[:fips]
141
- client_rb << <<-CONFIG
142
- fips true
143
- chef_version = ::Chef::VERSION.split(".")
144
- unless chef_version[0].to_i > 12 || (chef_version[0].to_i == 12 && chef_version[1].to_i >= 8)
145
- raise "FIPS Mode requested but not supported by this client"
146
- end
147
- CONFIG
148
- end
149
-
150
- escape_and_echo(client_rb)
151
- end
152
-
153
- def get_log_location
154
- if @chef_config[:config_log_location].equal?(:win_evt)
155
- %Q{:#{@chef_config[:config_log_location]}\n}
156
- elsif @chef_config[:config_log_location].equal?(:syslog)
157
- raise "syslog is not supported for log_location on Windows OS\n"
158
- elsif (@chef_config[:config_log_location].equal?(STDOUT))
159
- "STDOUT\n"
160
- elsif (@chef_config[:config_log_location].equal?(STDERR))
161
- "STDERR\n"
162
- elsif @chef_config[:config_log_location].nil? || @chef_config[:config_log_location].empty?
163
- "STDOUT\n"
164
- elsif @chef_config[:config_log_location]
165
- %Q{"#{@chef_config[:config_log_location]}"\n}
166
- else
167
- "STDOUT\n"
168
- end
169
- end
170
-
171
- def start_chef
172
- bootstrap_environment_option = bootstrap_environment.nil? ? '' : " -E #{bootstrap_environment}"
173
- start_chef = "SET \"PATH=%SystemRoot%\\system32;%SystemRoot%;%SystemRoot%\\System32\\Wbem;%SYSTEMROOT%\\System32\\WindowsPowerShell\\v1.0\\;C:\\ruby\\bin;C:\\opscode\\chef\\bin;C:\\opscode\\chef\\embedded\\bin\"\n"
174
- start_chef << "chef-client -c c:/chef/client.rb -j c:/chef/first-boot.json#{bootstrap_environment_option}\n"
175
- end
176
-
177
- def latest_current_windows_chef_version_query
178
- installer_version_string = nil
179
- if @config[:prerelease]
180
- installer_version_string = "&prerelease=true"
181
- else
182
- chef_version_string = if knife_config[:bootstrap_version]
183
- knife_config[:bootstrap_version]
184
- else
185
- Chef::VERSION.split(".").first
186
- end
187
-
188
- installer_version_string = "&v=#{chef_version_string}"
189
-
190
- # If bootstrapping a pre-release version add the prerelease query string
191
- if chef_version_string.split(".").length > 3
192
- installer_version_string << "&prerelease=true"
193
- end
194
- end
195
-
196
- installer_version_string
197
- end
198
-
199
- def win_wget
200
- # I tried my best to figure out how to properly url decode and switch / to \
201
- # but this is VBScript - so I don't really care that badly.
202
- win_wget = <<-WGET
203
- url = WScript.Arguments.Named("url")
204
- path = WScript.Arguments.Named("path")
205
- proxy = null
206
- '* Vaguely attempt to handle file:// scheme urls by url unescaping and switching all
207
- '* / into \. Also assume that file:/// is a local absolute path and that file://<foo>
208
- '* is possibly a network file path.
209
- If InStr(url, "file://") = 1 Then
210
- url = Unescape(url)
211
- If InStr(url, "file:///") = 1 Then
212
- sourcePath = Mid(url, Len("file:///") + 1)
213
- Else
214
- sourcePath = Mid(url, Len("file:") + 1)
215
- End If
216
- sourcePath = Replace(sourcePath, "/", "\\")
217
-
218
- Set objFSO = CreateObject("Scripting.FileSystemObject")
219
- If objFSO.Fileexists(path) Then objFSO.DeleteFile path
220
- objFSO.CopyFile sourcePath, path, true
221
- Set objFSO = Nothing
222
-
223
- Else
224
- Set objXMLHTTP = CreateObject("MSXML2.ServerXMLHTTP")
225
- Set wshShell = CreateObject( "WScript.Shell" )
226
- Set objUserVariables = wshShell.Environment("USER")
227
-
228
- rem http proxy is optional
229
- rem attempt to read from HTTP_PROXY env var first
230
- On Error Resume Next
231
-
232
- If NOT (objUserVariables("HTTP_PROXY") = "") Then
233
- proxy = objUserVariables("HTTP_PROXY")
234
-
235
- rem fall back to named arg
236
- ElseIf NOT (WScript.Arguments.Named("proxy") = "") Then
237
- proxy = WScript.Arguments.Named("proxy")
238
- End If
239
-
240
- If NOT isNull(proxy) Then
241
- rem setProxy method is only available on ServerXMLHTTP 6.0+
242
- Set objXMLHTTP = CreateObject("MSXML2.ServerXMLHTTP.6.0")
243
- objXMLHTTP.setProxy 2, proxy
244
- End If
245
-
246
- On Error Goto 0
247
-
248
- objXMLHTTP.open "GET", url, false
249
- objXMLHTTP.send()
250
- If objXMLHTTP.Status = 200 Then
251
- Set objADOStream = CreateObject("ADODB.Stream")
252
- objADOStream.Open
253
- objADOStream.Type = 1
254
- objADOStream.Write objXMLHTTP.ResponseBody
255
- objADOStream.Position = 0
256
- Set objFSO = Createobject("Scripting.FileSystemObject")
257
- If objFSO.Fileexists(path) Then objFSO.DeleteFile path
258
- Set objFSO = Nothing
259
- objADOStream.SaveToFile path
260
- objADOStream.Close
261
- Set objADOStream = Nothing
262
- End If
263
- Set objXMLHTTP = Nothing
264
- End If
265
- WGET
266
- escape_and_echo(win_wget)
267
- end
268
-
269
- def win_wget_ps
270
- win_wget_ps = <<-WGET_PS
271
- param(
272
- [String] $remoteUrl,
273
- [String] $localPath
274
- )
275
-
276
- $ProxyUrl = $env:http_proxy;
277
- $webClient = new-object System.Net.WebClient;
278
-
279
- if ($ProxyUrl -ne '') {
280
- $WebProxy = New-Object System.Net.WebProxy($ProxyUrl,$true)
281
- $WebClient.Proxy = $WebProxy
282
- }
283
-
284
- $webClient.DownloadFile($remoteUrl, $localPath);
285
- WGET_PS
286
-
287
- escape_and_echo(win_wget_ps)
288
- end
289
-
290
- def install_chef
291
- # The normal install command uses regular double quotes in
292
- # the install command, so request such a string from install_command
293
- install_chef = install_command('"') + "\n" + fallback_install_task_command
294
- end
295
-
296
- def bootstrap_directory
297
- bootstrap_directory = "C:\\chef"
298
- end
299
-
300
- def local_download_path
301
- local_download_path = "%TEMP%\\chef-client-latest.msi"
302
- end
303
-
304
- def msi_url(machine_os=nil, machine_arch=nil, download_context=nil)
305
- # The default msi path has a number of url query parameters - we attempt to substitute
306
- # such parameters in as long as they are provided by the template.
307
-
308
- if @config[:msi_url].nil? || @config[:msi_url].empty?
309
- url = "https://www.chef.io/chef/download?p=windows"
310
- url += "&pv=#{machine_os}" unless machine_os.nil?
311
- url += "&m=#{machine_arch}" unless machine_arch.nil?
312
- url += "&DownloadContext=#{download_context}" unless download_context.nil?
313
- url += latest_current_windows_chef_version_query
314
- else
315
- @config[:msi_url]
316
- end
317
- end
318
-
319
- def first_boot
320
- escape_and_echo(super.to_json)
321
- end
322
-
323
- # escape WIN BATCH special chars
324
- # and prefixes each line with an
325
- # echo
326
- def escape_and_echo(file_contents)
327
- file_contents.gsub(/^(.*)$/, 'echo.\1').gsub(/([(<|>)^])/, '^\1')
328
- end
329
-
330
- private
331
-
332
- def install_command(executor_quote)
333
- if @config[:install_as_service]
334
- "msiexec /qn /log #{executor_quote}%CHEF_CLIENT_MSI_LOG_PATH%#{executor_quote} /i #{executor_quote}%LOCAL_DESTINATION_MSI_PATH%#{executor_quote} ADDLOCAL=#{executor_quote}ChefClientFeature,ChefServiceFeature#{executor_quote}"
335
- else
336
- "msiexec /qn /log #{executor_quote}%CHEF_CLIENT_MSI_LOG_PATH%#{executor_quote} /i #{executor_quote}%LOCAL_DESTINATION_MSI_PATH%#{executor_quote}"
337
- end
338
- end
339
-
340
- # Returns a string for copying the trusted certificates on the workstation to the system being bootstrapped
341
- # This string should contain both the commands necessary to both create the files, as well as their content
342
- def trusted_certs_content
343
- content = ""
344
- if @chef_config[:trusted_certs_dir]
345
- Dir.glob(File.join(PathHelper.escape_glob_dir(@chef_config[:trusted_certs_dir]), "*.{crt,pem}")).each do |cert|
346
- content << "> #{bootstrap_directory}/trusted_certs/#{File.basename(cert)} (\n" +
347
- escape_and_echo(IO.read(File.expand_path(cert))) + "\n)\n"
348
- end
349
- end
350
- content
351
- end
352
-
353
- def client_d_content
354
- content = ""
355
- if @chef_config[:client_d_dir] && File.exist?(@chef_config[:client_d_dir])
356
- root = Pathname(@chef_config[:client_d_dir])
357
- root.find do |f|
358
- relative = f.relative_path_from(root)
359
- if f != root
360
- file_on_node = "#{bootstrap_directory}/client.d/#{relative}".gsub("/","\\")
361
- if f.directory?
362
- content << "mkdir #{file_on_node}\n"
363
- else
364
- content << "> #{file_on_node} (\n" +
365
- escape_and_echo(IO.read(File.expand_path(f))) + "\n)\n"
366
- end
367
- end
368
- end
369
- end
370
- content
371
- end
372
-
373
- def fallback_install_task_command
374
- # This command will be executed by schtasks.exe in the batch
375
- # code below. To handle tasks that contain arguments that
376
- # need to be double quoted, schtasks allows the use of single
377
- # quotes that will later be converted to double quotes
378
- command = install_command('\'')
379
- <<-EOH
380
- @set MSIERRORCODE=!ERRORLEVEL!
381
- @if ERRORLEVEL 1 (
382
- @echo WARNING: Failed to install Chef Client MSI package in remote context with status code !MSIERRORCODE!.
383
- @echo WARNING: This may be due to a defect in operating system update KB2918614: http://support.microsoft.com/kb/2918614
384
- @set OLDLOGLOCATION="%CHEF_CLIENT_MSI_LOG_PATH%-fail.log"
385
- @move "%CHEF_CLIENT_MSI_LOG_PATH%" "!OLDLOGLOCATION!" > NUL
386
- @echo WARNING: Saving installation log of failure at !OLDLOGLOCATION!
387
- @echo WARNING: Retrying installation with local context...
388
- @schtasks /create /f /sc once /st 00:00:00 /tn chefclientbootstraptask /ru SYSTEM /rl HIGHEST /tr \"cmd /c #{command} & sleep 2 & waitfor /s %computername% /si chefclientinstalldone\"
389
-
390
- @if ERRORLEVEL 1 (
391
- @echo ERROR: Failed to create Chef Client installation scheduled task with status code !ERRORLEVEL! > "&2"
392
- ) else (
393
- @echo Successfully created scheduled task to install Chef Client.
394
- @schtasks /run /tn chefclientbootstraptask
395
- @if ERRORLEVEL 1 (
396
- @echo ERROR: Failed to execut Chef Client installation scheduled task with status code !ERRORLEVEL!. > "&2"
397
- ) else (
398
- @echo Successfully started Chef Client installation scheduled task.
399
- @echo Waiting for installation to complete -- this may take a few minutes...
400
- waitfor chefclientinstalldone /t 600
401
- if ERRORLEVEL 1 (
402
- @echo ERROR: Timed out waiting for Chef Client package to install
403
- ) else (
404
- @echo Finished waiting for Chef Client package to install.
405
- )
406
- @schtasks /delete /f /tn chefclientbootstraptask > NUL
407
- )
408
- )
409
- ) else (
410
- @echo Successfully installed Chef Client package.
411
- )
412
- EOH
413
- end
414
- end
415
- end
416
- end
417
- end