knife-winops 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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!
|