knife-winops 2.0.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.
- checksums.yaml +7 -0
- data/.gitignore +5 -0
- data/.rspec +3 -0
- data/.travis.yml +30 -0
- data/CHANGELOG.md +147 -0
- data/DOC_CHANGES.md +22 -0
- data/Gemfile +13 -0
- data/LICENSE +201 -0
- data/README.md +430 -0
- data/RELEASE_NOTES.md +17 -0
- data/Rakefile +21 -0
- data/appveyor.yml +36 -0
- data/ci.gemfile +15 -0
- data/knife-winops.gemspec +26 -0
- data/lib/chef/knife/bootstrap/Chef_bootstrap.erb +44 -0
- data/lib/chef/knife/bootstrap/bootstrap.ps1 +134 -0
- data/lib/chef/knife/bootstrap/tail.cmd +15 -0
- data/lib/chef/knife/bootstrap/windows-chef-client-msi.erb +302 -0
- data/lib/chef/knife/bootstrap_windows_base.rb +473 -0
- data/lib/chef/knife/bootstrap_windows_ssh.rb +115 -0
- data/lib/chef/knife/bootstrap_windows_winrm.rb +102 -0
- data/lib/chef/knife/core/windows_bootstrap_context.rb +356 -0
- data/lib/chef/knife/knife_windows_base.rb +33 -0
- data/lib/chef/knife/windows_cert_generate.rb +155 -0
- data/lib/chef/knife/windows_cert_install.rb +68 -0
- data/lib/chef/knife/windows_helper.rb +36 -0
- data/lib/chef/knife/windows_listener_create.rb +107 -0
- data/lib/chef/knife/winrm.rb +127 -0
- data/lib/chef/knife/winrm_base.rb +128 -0
- data/lib/chef/knife/winrm_knife_base.rb +315 -0
- data/lib/chef/knife/winrm_session.rb +101 -0
- data/lib/chef/knife/winrm_shared_options.rb +54 -0
- data/lib/chef/knife/wsman_endpoint.rb +44 -0
- data/lib/chef/knife/wsman_test.rb +118 -0
- data/lib/knife-winops/path_helper.rb +242 -0
- data/lib/knife-winops/version.rb +6 -0
- data/spec/assets/fake_trusted_certs/excluded.txt +2 -0
- data/spec/assets/fake_trusted_certs/github.pem +42 -0
- data/spec/assets/fake_trusted_certs/google.crt +41 -0
- data/spec/assets/win_fake_trusted_cert_script.txt +89 -0
- data/spec/dummy_winrm_connection.rb +21 -0
- data/spec/functional/bootstrap_download_spec.rb +229 -0
- data/spec/spec_helper.rb +93 -0
- data/spec/unit/knife/bootstrap_options_spec.rb +164 -0
- data/spec/unit/knife/bootstrap_template_spec.rb +98 -0
- data/spec/unit/knife/bootstrap_windows_winrm_spec.rb +410 -0
- data/spec/unit/knife/core/windows_bootstrap_context_spec.rb +292 -0
- data/spec/unit/knife/windows_cert_generate_spec.rb +90 -0
- data/spec/unit/knife/windows_cert_install_spec.rb +51 -0
- data/spec/unit/knife/windows_listener_create_spec.rb +76 -0
- data/spec/unit/knife/winrm_session_spec.rb +101 -0
- data/spec/unit/knife/winrm_spec.rb +494 -0
- data/spec/unit/knife/wsman_test_spec.rb +209 -0
- metadata +157 -0
data/RELEASE_NOTES.md
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
<!---
|
2
|
+
This file is reset every time a new release is done. The contents of this file are for the currently unreleased version.
|
3
|
+
|
4
|
+
Example Note:
|
5
|
+
|
6
|
+
## Example Heading
|
7
|
+
Details about the thing that changed that needs to get included in the Release Notes in markdown.
|
8
|
+
-->
|
9
|
+
# knife-winops 1.9.0 release notes:
|
10
|
+
|
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.
|
14
|
+
|
15
|
+
```
|
16
|
+
knife winrm "role:web" "net stats srv" -X Administrator -P 'super_secret_password' -C 4
|
17
|
+
```
|
data/Rakefile
ADDED
@@ -0,0 +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
|
data/appveyor.yml
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
version: "master-{build}"
|
2
|
+
|
3
|
+
os: Windows Server 2012
|
4
|
+
platform:
|
5
|
+
- x64
|
6
|
+
|
7
|
+
environment:
|
8
|
+
bundle_gemfile: ci.gemfile
|
9
|
+
|
10
|
+
matrix:
|
11
|
+
- ruby_version: "23"
|
12
|
+
chef_version: "~> 12.0"
|
13
|
+
|
14
|
+
- ruby_version: "24"
|
15
|
+
chef_version: "master"
|
16
|
+
|
17
|
+
clone_folder: c:\projects\knife-winops
|
18
|
+
clone_depth: 1
|
19
|
+
branches:
|
20
|
+
only:
|
21
|
+
- master
|
22
|
+
|
23
|
+
install:
|
24
|
+
- winrm quickconfig -q
|
25
|
+
- SET PATH=C:\Ruby%ruby_version%\bin;%PATH%
|
26
|
+
- echo %PATH%
|
27
|
+
- ruby --version
|
28
|
+
- gem --version
|
29
|
+
- gem install bundler -v 1.11.2 --quiet --no-ri --no-rdoc
|
30
|
+
- bundler --version
|
31
|
+
|
32
|
+
build_script:
|
33
|
+
- bundle install || bundle install || bundle install
|
34
|
+
|
35
|
+
test_script:
|
36
|
+
- bundle exec rake
|
data/ci.gemfile
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
source "https://rubygems.org"
|
2
|
+
|
3
|
+
# Specify your gem's dependencies in knife-winops.gemspec
|
4
|
+
gemspec
|
5
|
+
|
6
|
+
if ENV['CHEF_VERSION'] == 'master'
|
7
|
+
gem 'chef', github: 'chef/chef'
|
8
|
+
else
|
9
|
+
gem 'chef', ENV['CHEF_VERSION']
|
10
|
+
end
|
11
|
+
|
12
|
+
gem "rspec", '~> 3.0'
|
13
|
+
gem "ruby-wmi"
|
14
|
+
gem "httpclient"
|
15
|
+
gem 'rake'
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "knife-winops/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "knife-winops"
|
7
|
+
s.version = Knife::Windows::VERSION
|
8
|
+
s.platform = Gem::Platform::RUBY
|
9
|
+
s.authors = ["Robbert-Jan Sperna Weiland"]
|
10
|
+
s.email = ["rspernaweiland@schubergphilis.com"]
|
11
|
+
s.license = "Apache-2.0"
|
12
|
+
s.homepage = "https://github.com/RobbertJanSW/knife-winops"
|
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`.split("\n")
|
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
|
@@ -0,0 +1,44 @@
|
|
1
|
+
<Task version="1.2" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
|
2
|
+
<RegistrationInfo>
|
3
|
+
<Date>2018-03-30T16:38:25</Date>
|
4
|
+
<Author>Administrator</Author>
|
5
|
+
</RegistrationInfo>
|
6
|
+
<Triggers>
|
7
|
+
<TimeTrigger>
|
8
|
+
<StartBoundary>2018-03-30T00:00:00</StartBoundary>
|
9
|
+
<Enabled>true</Enabled>
|
10
|
+
</TimeTrigger>
|
11
|
+
</Triggers>
|
12
|
+
<Principals>
|
13
|
+
<Principal id="Author">
|
14
|
+
<UserId>S-1-5-18</UserId>
|
15
|
+
<RunLevel>LeastPrivilege</RunLevel>
|
16
|
+
</Principal>
|
17
|
+
</Principals>
|
18
|
+
<Settings>
|
19
|
+
<MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy>
|
20
|
+
<DisallowStartIfOnBatteries>true</DisallowStartIfOnBatteries>
|
21
|
+
<StopIfGoingOnBatteries>true</StopIfGoingOnBatteries>
|
22
|
+
<AllowHardTerminate>true</AllowHardTerminate>
|
23
|
+
<StartWhenAvailable>false</StartWhenAvailable>
|
24
|
+
<RunOnlyIfNetworkAvailable>false</RunOnlyIfNetworkAvailable>
|
25
|
+
<IdleSettings>
|
26
|
+
<StopOnIdleEnd>true</StopOnIdleEnd>
|
27
|
+
<RestartOnIdle>false</RestartOnIdle>
|
28
|
+
</IdleSettings>
|
29
|
+
<AllowStartOnDemand>true</AllowStartOnDemand>
|
30
|
+
<Enabled>true</Enabled>
|
31
|
+
<Hidden>false</Hidden>
|
32
|
+
<RunOnlyIfIdle>false</RunOnlyIfIdle>
|
33
|
+
<WakeToRun>false</WakeToRun>
|
34
|
+
<ExecutionTimeLimit>P3D</ExecutionTimeLimit>
|
35
|
+
<Priority>7</Priority>
|
36
|
+
</Settings>
|
37
|
+
<Actions Context="Author">
|
38
|
+
<Exec>
|
39
|
+
<Command>powershell.exe</Command>
|
40
|
+
<Arguments>-ExecutionPolicy Unrestricted -File <%= bootstrap_directory %>\bootstrap.ps1</Arguments>
|
41
|
+
<WorkingDirectory><%= bootstrap_directory %></WorkingDirectory>
|
42
|
+
</Exec>
|
43
|
+
</Actions>
|
44
|
+
</Task>
|
@@ -0,0 +1,134 @@
|
|
1
|
+
$global:config = @{}
|
2
|
+
|
3
|
+
function log($msg) {
|
4
|
+
$timestamp = Get-Date -Format "[yyyy-MM-dd hh:mm:ss]"
|
5
|
+
add-content "$($config['CHEF_PS_LOG'])" "$timestamp $msg"
|
6
|
+
}
|
7
|
+
|
8
|
+
function msi_url() {
|
9
|
+
$machine_os = $config['CHEF_MACHINE_OS']
|
10
|
+
$machine_arch = $config['CHEF_MACHINE_ARCH']
|
11
|
+
$download_context = $config['CHEF_DOWNLOAD_CONTEXT']
|
12
|
+
$version = $config['CHEF_VERSION']
|
13
|
+
$msi_url = $config['CHEF_REMOTE_SOURCE_MSI_URL']
|
14
|
+
|
15
|
+
if ($version -eq $null) { $version = '&v=latest' }
|
16
|
+
|
17
|
+
if ($msi_url.length -gt 4) {
|
18
|
+
$msi_url
|
19
|
+
} else {
|
20
|
+
$url = "https://www.chef.io/chef/download?p=windows"
|
21
|
+
if ($machine_os -ne $null) { $url += "&pv=$($machine_os)" }
|
22
|
+
if ($machine_arch -ne $null) { $url += "&m=$($machine_arch)" }
|
23
|
+
if ($download_context -ne $null) { $url += "&DownloadContext=$($download_context)" }
|
24
|
+
$url += $version
|
25
|
+
$url
|
26
|
+
}
|
27
|
+
}
|
28
|
+
|
29
|
+
function report_status($exitcode) {
|
30
|
+
set-content "$($config['CHEF_PS_EXITCODE'])" "$exitcode"
|
31
|
+
}
|
32
|
+
|
33
|
+
function ps_exit() {
|
34
|
+
Start-Sleep 5
|
35
|
+
while (Test-Path "$($config['CHEF_PS_LOG'])") { Remove-Item "$($config['CHEF_PS_LOG'])" -Force -ErrorAction SilentlyContinue }
|
36
|
+
exit 99
|
37
|
+
}
|
38
|
+
|
39
|
+
function cleanup() {
|
40
|
+
Remove-Item "$($config['CHEF_LOCAL_MSI_PATH'])" -Force -ErrorAction SilentlyContinue
|
41
|
+
Remove-Item "$($config['CHEF_CLIENT_MSI_LOG_PATH'])" -Force -ErrorAction SilentlyContinue
|
42
|
+
}
|
43
|
+
|
44
|
+
# Windows 2008 compatible way of loading config:
|
45
|
+
$shell_variables = Get-ItemProperty 'HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Environment'
|
46
|
+
|
47
|
+
$cmd_input_variables = @("CHEF_PS_LOG", "CHEF_PS_EXITCODE", "CHEF_REMOTE_SOURCE_MSI_URL", "CHEF_LOCAL_MSI_PATH", "CHEF_http_proxy","CHEF_CLIENT_MSI_LOG_PATH","CHEF_ENVIRONMENT_OPTION","CHEF_BOOTSTRAP_DIRECTORY","CHEF_CUSTOM_INSTALL_COMMAND","CHEF_CUSTOM_RUN_COMMAND","CHEF_EXTRA_MSI_PARAMETERS","CHEF_MACHINE_OS","CHEF_MACHINE_ARCH","CHEF_DOWNLOAD_CONTEXT","CHEF_VERSION")
|
48
|
+
$cmd_input_variables | ForEach-Object {
|
49
|
+
$config[$_] = $shell_variables.$($_)
|
50
|
+
}
|
51
|
+
log "`nConfig loaded from environment:$($config | Out-String -Width 150)"
|
52
|
+
|
53
|
+
log "Removing bootstrap files left by potential earlier run"
|
54
|
+
cleanup
|
55
|
+
|
56
|
+
log "Setting up Webclient"
|
57
|
+
$webClient = new-object System.Net.WebClient;
|
58
|
+
if ($config['CHEF_http_proxy'] -ne '') {
|
59
|
+
log "Configuring proxy $($config['CHEF_http_proxy']) in Webclient"
|
60
|
+
$WebProxy = New-Object System.Net.WebProxy($config['CHEF_http_proxy'],$true)
|
61
|
+
$WebClient.Proxy = $WebProxy
|
62
|
+
}
|
63
|
+
|
64
|
+
log "Testing for existing Chef client install"
|
65
|
+
if (Test-Path HKLM:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Installer\\UpgradeCodes\\C58A706DAFDB80F438DEE2BCD4DCB65C) {
|
66
|
+
log "Existing install detected. Skipping Chef-client download and install"
|
67
|
+
} else {
|
68
|
+
log "No Chef client install detected."
|
69
|
+
$download_link = msi_url
|
70
|
+
log "Starting download from $($download_link) to $( $config['CHEF_LOCAL_MSI_PATH'] )"
|
71
|
+
$webClient.DownloadFile($download_link, $config['CHEF_LOCAL_MSI_PATH'] );
|
72
|
+
|
73
|
+
log "Download done. Checking local file."
|
74
|
+
if (!(Test-Path "$($config['CHEF_LOCAL_MSI_PATH'])")) {
|
75
|
+
log "Download failed. Local MSI not found."
|
76
|
+
report_status 3; ps_exit
|
77
|
+
}
|
78
|
+
$filesize = (Get-Item "$($config['CHEF_LOCAL_MSI_PATH'])").length
|
79
|
+
if ($filesize -eq 0) {
|
80
|
+
log "DOWNLOAD FAILED - Filesize is 0."
|
81
|
+
report_status 2; ps_exit
|
82
|
+
}
|
83
|
+
log "Download filesize is $filesize"
|
84
|
+
|
85
|
+
log "Starting Chef client install"
|
86
|
+
if ($config['CHEF_CUSTOM_INSTALL_COMMAND'] ) {
|
87
|
+
log "Running custom install command $($config['CHEF_CUSTOM_INSTALL_COMMAND'])"
|
88
|
+
$install_process = Start-Process -PassThru -Wait "$env:comspec" -ArgumentList "/v /e /c`"start /wait cmd /c %CHEF_CUSTOM_INSTALL_COMMAND% & exit !errorlevel!;`""
|
89
|
+
} else {
|
90
|
+
log "msiexec.exe /qn /log `"$($config['CHEF_CLIENT_MSI_LOG_PATH'])`" /i `"$($config['CHEF_LOCAL_MSI_PATH'])`" $($config['CHEF_EXTRA_MSI_PARAMETERS'])"
|
91
|
+
$install_process = Start-Process -PassThru -Wait msiexec.exe -ArgumentList "/qn /log `"$($config['CHEF_CLIENT_MSI_LOG_PATH'])`" /i `"$($config['CHEF_LOCAL_MSI_PATH'])`" $($config['CHEF_EXTRA_MSI_PARAMETERS'])"
|
92
|
+
}
|
93
|
+
$install_exitcode = $install_process.ExitCode
|
94
|
+
|
95
|
+
log "MSI install returned exit code $install_exitcode"
|
96
|
+
if ($install_exitcode -ne 0) { report_status 36512; ps_exit }
|
97
|
+
}
|
98
|
+
|
99
|
+
log "Cleaning up Chef bootstrap environment variables"
|
100
|
+
$cmd_input_variables | ForEach-Object {
|
101
|
+
REG delete "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment" /F /V $_
|
102
|
+
}
|
103
|
+
|
104
|
+
log "Cleaning up Powershell logfile and starting first Chef run"
|
105
|
+
report_status 0
|
106
|
+
Start-Sleep 1
|
107
|
+
while (Test-Path "$($config['CHEF_PS_LOG'])") { Remove-Item "$($config['CHEF_PS_LOG'])" -Force -ErrorAction SilentlyContinue }
|
108
|
+
|
109
|
+
if ($config['CHEF_CUSTOM_RUN_COMMAND']) {
|
110
|
+
# Default to successful run of custom command
|
111
|
+
$chefrun_exitcode = 0
|
112
|
+
Try {
|
113
|
+
Invoke-Expression $config['CHEF_CUSTOM_RUN_COMMAND']
|
114
|
+
} catch {
|
115
|
+
$chefrun_exitcode = $_.FullyQualifiedErrorId
|
116
|
+
}
|
117
|
+
} else {
|
118
|
+
$chefrun_process = Start-Process -PassThru -Wait c:/opscode/chef/bin/chef-client.bat -ArgumentList "-c `"$($config['CHEF_BOOTSTRAP_DIRECTORY'])/client.rb`" -j `"$($config['CHEF_BOOTSTRAP_DIRECTORY'])/first-boot.json`" $($config['CHEF_ENVIRONMENT_OPTION']) -L `"$($config['CHEF_BOOTSTRAP_DIRECTORY'])/firstrun.log`""
|
119
|
+
$chefrun_exitcode = [int]$chefrun_process.ExitCode
|
120
|
+
}
|
121
|
+
|
122
|
+
log "Chef run done. Cleaning up Chef firstrun logfile to get control back to bootstrap cmd"
|
123
|
+
While (Test-Path "$($config['CHEF_BOOTSTRAP_DIRECTORY'])/firstrun.log") { Remove-Item "$($config['CHEF_BOOTSTRAP_DIRECTORY'])/firstrun.log" -Force -ErrorAction SilentlyContinue }
|
124
|
+
|
125
|
+
log "First Chef run returned exit code $chefrun_exitcode. We're done."
|
126
|
+
if ($chefrun_exitcode -ne 0) {
|
127
|
+
report_status $chefrun_exitcode; ps_exit
|
128
|
+
}
|
129
|
+
|
130
|
+
log "Cleaning up"
|
131
|
+
report_status 0
|
132
|
+
c:/windows/system32/schtasks.exe /F /delete /tn Chef_bootstrap
|
133
|
+
cleanup
|
134
|
+
ps_exit
|
@@ -0,0 +1,15 @@
|
|
1
|
+
@echo off
|
2
|
+
set shown=0
|
3
|
+
REM This next line switches the codepage to prevent running into a 'Out of memory' bug
|
4
|
+
REM in more.com on Windows 2008 (and maybe newer) systems.
|
5
|
+
chcp 437 > nul 2>&1
|
6
|
+
:tail
|
7
|
+
if NOT EXIST "%1" (
|
8
|
+
IF NOT %shown%==0 goto :eof
|
9
|
+
goto tail
|
10
|
+
)
|
11
|
+
for /f "tokens=1 delims=*" %%l in ('findstr /R /V "^$" %1 ^| more +%shown%') DO (
|
12
|
+
echo %%l
|
13
|
+
set /A shown=shown+1
|
14
|
+
)
|
15
|
+
goto tail
|
@@ -0,0 +1,302 @@
|
|
1
|
+
@rem
|
2
|
+
@rem Original knife-windows author:: Seth Chisamore (<schisamo@chef.io>)
|
3
|
+
@rem Copyright:: Copyright (c) 2011-2016 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
|
+
@rem Determine the version and the architecture
|
25
|
+
|
26
|
+
@FOR /F "usebackq tokens=1-8 delims=.[] " %%A IN (`ver`) DO (
|
27
|
+
@set WinMajor=%%D
|
28
|
+
@set WinMinor=%%E
|
29
|
+
@set WinBuild=%%F
|
30
|
+
)
|
31
|
+
|
32
|
+
@echo Detected Windows Version %WinMajor%.%WinMinor% Build %WinBuild%
|
33
|
+
|
34
|
+
@set LATEST_OS_VERSION_MAJOR=6
|
35
|
+
@set LATEST_OS_VERSION_MINOR=3
|
36
|
+
|
37
|
+
@if /i %WinMajor% GTR %LATEST_OS_VERSION_MAJOR% goto VersionUnknown
|
38
|
+
@if /i %WinMajor% EQU %LATEST_OS_VERSION_MAJOR% (
|
39
|
+
@if /i %WinMinor% GTR %LATEST_OS_VERSION_MINOR% goto VersionUnknown
|
40
|
+
)
|
41
|
+
|
42
|
+
goto Version%WinMajor%.%WinMinor%
|
43
|
+
|
44
|
+
:VersionUnknown
|
45
|
+
@rem If this is an unknown version of windows set the default
|
46
|
+
@set MACHINE_OS=2008r2
|
47
|
+
@echo Warning: Unknown version of Windows, assuming default of Windows %MACHINE_OS%
|
48
|
+
goto architecture_select
|
49
|
+
|
50
|
+
:Version6.0
|
51
|
+
@set MACHINE_OS=2008
|
52
|
+
goto architecture_select
|
53
|
+
|
54
|
+
:Version5.2
|
55
|
+
@set MACHINE_OS=2003r2
|
56
|
+
goto architecture_select
|
57
|
+
|
58
|
+
:Version6.1
|
59
|
+
@set MACHINE_OS=2008r2
|
60
|
+
goto architecture_select
|
61
|
+
|
62
|
+
:Version6.2
|
63
|
+
@set MACHINE_OS=2012
|
64
|
+
goto architecture_select
|
65
|
+
|
66
|
+
@rem Currently Windows Server 2012 R2 is treated as equivalent to Windows Server 2012
|
67
|
+
:Version6.3
|
68
|
+
goto Version6.2
|
69
|
+
|
70
|
+
:architecture_select
|
71
|
+
<% if knife_config[:architecture] %>
|
72
|
+
@set MACHINE_ARCH=<%= knife_config[:architecture] %>
|
73
|
+
|
74
|
+
<% if knife_config[:architecture] == "x86_64" %>
|
75
|
+
IF "%PROCESSOR_ARCHITECTURE%"=="x86" IF not defined PROCESSOR_ARCHITEW6432 (
|
76
|
+
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"
|
77
|
+
echo Exiting without bootstrapping. > "&2"
|
78
|
+
exit /b 1
|
79
|
+
)
|
80
|
+
<% end %>
|
81
|
+
<% else %>
|
82
|
+
@set MACHINE_ARCH=x86_64
|
83
|
+
IF "%PROCESSOR_ARCHITECTURE%"=="x86" IF not defined PROCESSOR_ARCHITEW6432 @set MACHINE_ARCH=i686
|
84
|
+
<% end %>
|
85
|
+
|
86
|
+
<% unless @chef_config[:knife][:bootstrap_debug] %>
|
87
|
+
@echo off
|
88
|
+
<% end %>
|
89
|
+
|
90
|
+
echo Passing all settings to the system environment
|
91
|
+
<% if @config[:bootstrap_proxy] -%>
|
92
|
+
setx CHEF_HTTP_PROXY "<%= @config[:bootstrap_proxy] %>" /m
|
93
|
+
<% elsif knife_config[:bootstrap_proxy] -%>
|
94
|
+
setx CHEF_HTTP_PROXY "<%= knife_config[:bootstrap_proxy] %>" /m
|
95
|
+
<% end -%>
|
96
|
+
|
97
|
+
<% if @config[:msi_url] -%>
|
98
|
+
setx CHEF_REMOTE_SOURCE_MSI_URL "<%= @config[:msi_url] %>" /m
|
99
|
+
set CHEF_REMOTE_SOURCE_MSI_URL="<%= @config[:msi_url] %>"
|
100
|
+
<% end %>
|
101
|
+
|
102
|
+
<% if @chef_config[:knife][:bootstrap_install_command] %>
|
103
|
+
setx CHEF_CUSTOM_INSTALL_COMMAND "<%= (@chef_config[:knife][:bootstrap_install_command]).gsub(/(\")/, '\\"') %>" /m
|
104
|
+
<% end %>
|
105
|
+
|
106
|
+
<% if @chef_config[:knife][:bootstrap_run_command] %>
|
107
|
+
setx CHEF_CUSTOM_RUN_COMMAND "<%= (@chef_config[:knife][:bootstrap_run_command]).gsub(/(\")/, '\\"') %>" /m
|
108
|
+
<% end %>
|
109
|
+
|
110
|
+
<% if @config[:bootstrap_run_command] %>
|
111
|
+
setx CHEF_CUSTOM_RUN_COMMAND "<%= (@config[:bootstrap_run_command]).gsub(/(\")/, '\\"') %>" /m
|
112
|
+
<% end %>
|
113
|
+
|
114
|
+
<% if @config[:install_as_service] %>
|
115
|
+
setx CHEF_EXTRA_MSI_PARAMETERS "ADDLOCAL=\"ChefClientFeature,ChefServiceFeature\"" /m
|
116
|
+
<% end %>
|
117
|
+
|
118
|
+
setx CHEF_ENVIRONMENT_OPTION "<%= bootstrap_environment.nil? ? '' : " -E #{bootstrap_environment}" %>" /m
|
119
|
+
setx CHEF_LOCAL_MSI_PATH "<%= local_download_path %>" /m
|
120
|
+
|
121
|
+
setx CHEF_CLIENT_MSI_LOG_PATH "%TEMP%\chef-client-msi.log" /m
|
122
|
+
set CHEF_CLIENT_MSI_LOG_PATH=%TEMP%\chef-client-msi.log
|
123
|
+
|
124
|
+
setx CHEF_PS_EXITCODE "<%= bootstrap_directory %>\ps_exitcode.txt" /m
|
125
|
+
set CHEF_PS_EXITCODE=<%= bootstrap_directory %>\ps_exitcode.txt
|
126
|
+
|
127
|
+
setx CHEF_PS_LOG "<%= bootstrap_directory %>\ps_log.txt" /m
|
128
|
+
set CHEF_PS_LOG=<%= bootstrap_directory %>\ps_log.txt
|
129
|
+
|
130
|
+
setx CHEF_BOOTSTRAP_DIRECTORY "<%= bootstrap_directory %>" /m
|
131
|
+
set CHEF_BOOTSTRAP_DIRECTORY="<%= bootstrap_directory %>"
|
132
|
+
|
133
|
+
setx CHEF_MACHINE_OS %MACHINE_OS% /m
|
134
|
+
set CHEF_MACHINE_OS=%MACHINE_OS%
|
135
|
+
|
136
|
+
setx CHEF_MACHINE_ARCH %MACHINE_ARCH% /m
|
137
|
+
set CHEF_MACHINE_ARCH=%MACHINE_ARCH%
|
138
|
+
|
139
|
+
setx CHEF_DOWNLOAD_CONTEXT PowerShell /m
|
140
|
+
set CHEF_DOWNLOAD_CONTEXT=PowerShell
|
141
|
+
|
142
|
+
setx CHEF_VERSION "<%= chef_version_in_url %>" /m
|
143
|
+
set CHEF_VERSION="<%= chef_version_in_url %>"
|
144
|
+
|
145
|
+
echo Checking for existing directory "%CHEF_BOOTSTRAP_DIRECTORY%"...
|
146
|
+
IF NOT EXIST %CHEF_BOOTSTRAP_DIRECTORY% (
|
147
|
+
echo Existing directory not found, creating.
|
148
|
+
mkdir %CHEF_BOOTSTRAP_DIRECTORY%
|
149
|
+
) else (
|
150
|
+
echo Existing directory found, skipping creation.
|
151
|
+
)
|
152
|
+
|
153
|
+
echo Clean up potential existing Powershell bootstrap logfile
|
154
|
+
del %CHEF_PS_LOG% /Q 2> nul
|
155
|
+
del %CHEF_PS_EXITCODE% /Q 2> nul
|
156
|
+
|
157
|
+
@echo Writing required files
|
158
|
+
> <%= bootstrap_directory %>\writefile.ps1 (
|
159
|
+
<%= win_ps_write_filechunk %>
|
160
|
+
)
|
161
|
+
|
162
|
+
<%= win_ps_bootstrap(bootstrap_directory+'\bootstrap.ps1') %>
|
163
|
+
<%= win_cmd_tail(bootstrap_directory+'\tail.cmd') %>
|
164
|
+
<%= win_schedtask_xml(bootstrap_directory+'\Chef_bootstrap.xml') %>
|
165
|
+
|
166
|
+
<% if @config[:payload_folder] -%>
|
167
|
+
mkdir <%= bootstrap_directory %>\extra_files
|
168
|
+
<%= win_folder_cp(@config[:payload_folder], bootstrap_directory+'\extra_files') %>
|
169
|
+
<% end -%>
|
170
|
+
|
171
|
+
<% if @config[:chef_server] && (defined? client_pem) && client_pem -%>
|
172
|
+
echo Clearing and writing client key...
|
173
|
+
del <%= bootstrap_directory %>\client.pem /Q 2> nul
|
174
|
+
> <%= bootstrap_directory %>\client.pem (
|
175
|
+
<%= escape_and_echo(::File.read(::File.expand_path(client_pem))) %>
|
176
|
+
)
|
177
|
+
echo Client key written
|
178
|
+
<% end -%>
|
179
|
+
|
180
|
+
<% if validation_key -%>
|
181
|
+
echo Writing validation key...
|
182
|
+
> <%= bootstrap_directory %>\validation.pem (
|
183
|
+
<%= validation_key.match('^echo\.') ? validation_key : escape_and_echo(validation_key) %>
|
184
|
+
)
|
185
|
+
echo Validation key written.
|
186
|
+
<% end -%>
|
187
|
+
|
188
|
+
<% if secret -%>
|
189
|
+
> <%= bootstrap_directory %>\encrypted_data_bag_secret (
|
190
|
+
<%= secret %>
|
191
|
+
)
|
192
|
+
<% end -%>
|
193
|
+
|
194
|
+
<%# Generate Ohai Hints -%>
|
195
|
+
<% unless @chef_config[:knife][:hints].nil? || @chef_config[:knife][:hints].empty? -%>
|
196
|
+
mkdir <%= bootstrap_directory %>\ohai\hints
|
197
|
+
|
198
|
+
<% @chef_config[:knife][:hints].each do |name, hash| -%>
|
199
|
+
> <%= bootstrap_directory %>\ohai\hints\<%= name %>.json (
|
200
|
+
<%= escape_and_echo(hash.to_json) %>
|
201
|
+
)
|
202
|
+
<% end -%>
|
203
|
+
<% end -%>
|
204
|
+
|
205
|
+
> <%= bootstrap_directory %>\client.rb (
|
206
|
+
<%= config_content %>
|
207
|
+
)
|
208
|
+
<% if @config[:bootstrap_proxy] -%>
|
209
|
+
findstr /V /I _proxy <%= bootstrap_directory %>\client.rb > <%= bootstrap_directory %>\chef_client.rb
|
210
|
+
echo http_proxy "<%= @config[:bootstrap_proxy] %>" >> <%= bootstrap_directory %>\chef_client.rb
|
211
|
+
echo https_proxy "<%= @config[:bootstrap_proxy] %>" >> <%= bootstrap_directory %>\chef_client.rb
|
212
|
+
move /Y <%= bootstrap_directory %>\chef_client.rb <%= bootstrap_directory %>\client.rb
|
213
|
+
<% end -%>
|
214
|
+
|
215
|
+
> <%= bootstrap_directory %>\first-boot.json (
|
216
|
+
<%= first_boot %>
|
217
|
+
)
|
218
|
+
|
219
|
+
rem The scheduled task creation could use error handling (feels like a corner case though):
|
220
|
+
c:/windows/system32/schtasks.exe /Create /XML <%= bootstrap_directory %>\Chef_bootstrap.xml /tn Chef_bootstrap
|
221
|
+
|
222
|
+
echo *******************************************************************
|
223
|
+
echo Starting Powershell bootstrap scheduled task
|
224
|
+
c:/windows/system32/schtasks.exe /run /tn Chef_bootstrap
|
225
|
+
|
226
|
+
<% unless @chef_config[:knife][:bootstrap_debug] %>
|
227
|
+
@echo off
|
228
|
+
<% end %>
|
229
|
+
|
230
|
+
echo *******************************************************************
|
231
|
+
echo Waiting for Powershell bootstrap log file to appear
|
232
|
+
<%= win_cmd_wait_for_file('CHEF_PS_LOG') %>
|
233
|
+
|
234
|
+
echo Tailing Powershell bootstrap log
|
235
|
+
call <%= bootstrap_directory %>\tail.cmd "%CHEF_PS_LOG%" 2> nul
|
236
|
+
|
237
|
+
echo *******************************************************************
|
238
|
+
echo Chef Powershell Bootstrap exited. Checking exit code.
|
239
|
+
|
240
|
+
<%= win_ps_exitcheck %>
|
241
|
+
IF NOT !psexitcode!==0 (
|
242
|
+
IF !psexitcode!==36512 (
|
243
|
+
echo *******************************************************************
|
244
|
+
echo Now dumping MSI error log %CHEF_CLIENT_MSI_LOG_PATH%
|
245
|
+
echo *******************************************************************
|
246
|
+
type %CHEF_CLIENT_MSI_LOG_PATH% 2> nul
|
247
|
+
echo *******************************************************************
|
248
|
+
echo Done dumping MSI log. Exiting...
|
249
|
+
exit !psexitcode!
|
250
|
+
)
|
251
|
+
echo *******************************************************************
|
252
|
+
echo Powershell bootstrap script exit code was not 0! Stopping!
|
253
|
+
echo The exit code of the script was !psexitcode!
|
254
|
+
exit !psexitcode!
|
255
|
+
)
|
256
|
+
echo Powershell bootstrap script reported succesful Chef install.
|
257
|
+
<% unless @chef_config[:knife][:bootstrap_run_command] || @config[:bootstrap_run_command] %>
|
258
|
+
set CHEF_CLIENT_LOG=<%= bootstrap_directory %>\firstrun.log
|
259
|
+
<%= win_cmd_wait_for_file('CHEF_CLIENT_LOG') %>
|
260
|
+
echo *******************************************************************
|
261
|
+
call <%= bootstrap_directory %>\tail.cmd "<%= bootstrap_directory %>\firstrun.log" 2> nul
|
262
|
+
<% end %>
|
263
|
+
|
264
|
+
<% if @config[:bootstrap_tail_file] %>
|
265
|
+
echo Tailing custom log file <%= @config[:bootstrap_tail_file] %>
|
266
|
+
set CUSTOM_LOG=<%= @config[:bootstrap_tail_file] %>
|
267
|
+
<%= win_cmd_wait_for_file('CUSTOM_LOG') %>
|
268
|
+
echo *******************************************************************
|
269
|
+
call <%= bootstrap_directory %>\tail.cmd "<%= @config[:bootstrap_tail_file] %>" 2> nul
|
270
|
+
<% end %>
|
271
|
+
|
272
|
+
echo *******************************************************************
|
273
|
+
echo Chef Powershell Bootstrap exited. Checking exit code.
|
274
|
+
|
275
|
+
<%= win_ps_exitcheck %>
|
276
|
+
IF NOT !psexitcode!==0 (
|
277
|
+
echo *******************************************************************
|
278
|
+
<% unless @chef_config[:knife][:bootstrap_run_command] %>
|
279
|
+
echo First Chef run exit code was not 0
|
280
|
+
echo Now dumping Chef stacktrace log
|
281
|
+
echo *******************************************************************
|
282
|
+
type c:\chef\cache\chef-stacktrace.out 2> nul
|
283
|
+
echo *******************************************************************
|
284
|
+
echo Done dumping Chef stacktrace log. Exiting...
|
285
|
+
<% else %>
|
286
|
+
echo Custom bootstrap command run exit code was not 0
|
287
|
+
<% end %>
|
288
|
+
) else (
|
289
|
+
<% unless @chef_config[:knife][:bootstrap_run_command] %>
|
290
|
+
echo Powershell bootstrap script and the first Chef run ran successfully! Running cleanup.
|
291
|
+
<% else %>
|
292
|
+
echo Custom bootstrap command ran succesfully. Running cleanup.
|
293
|
+
<% end %>
|
294
|
+
)
|
295
|
+
|
296
|
+
del %CHEF_PS_LOG% /Q 2> nul
|
297
|
+
del %CHEF_PS_EXITCODE% /Q 2> nul
|
298
|
+
del <%= bootstrap_directory+'\tail.cmd' %> /Q 2> nul
|
299
|
+
del <%= bootstrap_directory+'\bootstrap.ps1' %> /Q 2> nul
|
300
|
+
del <%= bootstrap_directory+'\writefile.ps1' %> /Q 2> nul
|
301
|
+
|
302
|
+
exit !psexitcode!
|