knife-windows 0.5.2 → 0.5.3
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +19 -6
- data/lib/chef/knife/bootstrap/windows-shell.erb +1 -0
- data/lib/chef/knife/bootstrap_windows_ssh.rb +123 -0
- data/lib/chef/knife/{winrm_bootstrap.rb → bootstrap_windows_winrm.rb} +24 -98
- data/lib/chef/knife/core/windows_bootstrap_context.rb +22 -2
- data/lib/chef/knife/mixin/windows/bootstrap.rb +94 -0
- data/lib/knife-windows/version.rb +1 -1
- metadata +5 -3
data/README.rdoc
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
= DESCRIPTION:
|
4
4
|
|
5
|
-
This
|
5
|
+
This plugin adds additional functionality to the Chef Knife CLI tool for configuring/interacting with nodes running Microsoft Windows. The subcommands should function on any system running Ruby 1.9.1+ but nodes being configured via these subcommands require Windows Remote Management (WinRM) 1.0+. WinRM allows you to call native objects in Windows. This includes, but is not limited to, running batch scripts, powershell scripts and fetching WMI variables. For more information on WinRM, please visit {Microsoft's WinRM site}[http://msdn.microsoft.com/en-us/library/aa384426(v=VS.85).aspx]. You will want to familiarize yourself with (certain key aspects) of WinRM because you will be {writing scripts/running commands} with this tool to get you from (specific point A) to (specific point B).
|
6
6
|
|
7
7
|
WinRM is built into Windows 7 and Windows Server 2008+. It can also be easily installed in older version of Windows, including:
|
8
8
|
|
@@ -12,6 +12,8 @@ WinRM is built into Windows 7 and Windows Server 2008+. It can also be easily i
|
|
12
12
|
|
13
13
|
More information can be found on {Microsoft Support article 968930}[http://support.microsoft.com/?kbid=968930].
|
14
14
|
|
15
|
+
This subcommands in this plugin have been tested and verified to work on Windows Server 2008 R2.
|
16
|
+
|
15
17
|
= SUBCOMMANDS:
|
16
18
|
|
17
19
|
This plugin provides the following Knife subcommands. Specific command options can be found by invoking the subcommand with a --+help+ flag
|
@@ -34,13 +36,23 @@ Or force a chef run:
|
|
34
36
|
|
35
37
|
This subcommand operates in a very similar manner as {knife ssh}[http://wiki.opscode.com/display/chef/Knife#Knife-SSHSubcommand]...just leveraging the WinRM protocol for communication. It also include's +knife+ +ssh+'s "{interactive session mode}[http://wiki.opscode.com/display/chef/Knife#Knife-InteractiveMode]"
|
36
38
|
|
37
|
-
== knife winrm
|
39
|
+
== knife bootstrap windows winrm
|
38
40
|
|
39
41
|
Performs a Chef Bootstrap (via the WinRM protocol) on the target node. The goal of the bootstrap is to get Chef installed on the target system so it can run Chef Client with a Chef Server. The main assumption is a baseline OS installation exists. It is primarily intended for Chef Client systems that talk to a Chef server.
|
40
42
|
|
41
|
-
|
43
|
+
This subcommand operates in a very similar manner as {knife bootstrap}[http://wiki.opscode.com/display/chef/Knife+Bootstrap]...just leveraging the WinRM protocol for communication. An initial run_list for the node can also be passed to the subcommand. Example usage:
|
44
|
+
|
45
|
+
knife bootstrap windows winrm ec2-50-xx-xx-124.compute-1.amazonaws.com -r 'role[webserver],role[production]' -x Administrator -P 'super_secret_password'
|
46
|
+
|
47
|
+
== knife bootstrap windows ssh
|
48
|
+
|
49
|
+
Performs a Chef Bootstrap (via the SSH protocol) on the target node. The goal of the bootstrap is to get Chef installed on the target system so it can run Chef Client with a Chef Server. The main assumption is a baseline OS installation exists. It is primarily intended for Chef Client systems that talk to a Chef server.
|
50
|
+
|
51
|
+
This subcommand assumes the SSH session will use Windows native cmd.exe command shell vs a bash shell through an emulated cygwin layer. Most popular Windows based SSHd daemons like {freeSSHd}[http://www.freesshd.com/] and {WinSSHD}[http://www.bitvise.com/winsshd] behave this way.
|
52
|
+
|
53
|
+
An initial run_list for the node can also be passed to the subcommand. Example usage:
|
42
54
|
|
43
|
-
knife
|
55
|
+
knife bootstrap windows ssh ec2-50-xx-xx-124.compute-1.amazonaws.com -r 'role[webserver],role[production]' -x Administrator -i ~/.ssh/id_rsa
|
44
56
|
|
45
57
|
= BOOTSTRAP TEMPLATES:
|
46
58
|
|
@@ -51,13 +63,14 @@ This gem provides the following bootstrap templates:
|
|
51
63
|
This bootstrap template does the following:
|
52
64
|
|
53
65
|
* Installs Ruby 1.8.7 via the {Ruby Installer for Windows}[http://rubyinstaller.org/] which also includes the latest version of RubyGems
|
66
|
+
* Installs the RubyInstaller Development Kit (DevKit). The RubyInstaller Development Kit (DevKit) is a MSYS/MinGW based toolkit than enables you to build many of the native C/C++ extensions available for Ruby.
|
54
67
|
* Installs required Windows-related gems from RubyGems.org
|
55
|
-
* Installs latest Chef version from RubyGems.org including {Ohai}[https://rubygems.org/gems/ohai] and {Chef}[https://rubygems.org/gems/chef].
|
68
|
+
* Installs latest Chef version from RubyGems.org including {Ohai}[https://rubygems.org/gems/ohai] and {Chef}[https://rubygems.org/gems/chef]. The Chef version is configurable using the *--bootstrap-version* option.
|
56
69
|
* Writes the validation.pem per the local knife configuration.
|
57
70
|
* Writes a default config file for Chef (C:\chef\client.rb) using values from the +knife.rb+.
|
58
71
|
* Creates a JSON attributes file containing the specified run list and run Chef.
|
59
72
|
|
60
|
-
This is the default bootstrap template used by the +
|
73
|
+
This is the default bootstrap template used by both the +windows+ +bootstrap+ subcommands.
|
61
74
|
|
62
75
|
= REQUIREMENTS/SETUP:
|
63
76
|
|
@@ -0,0 +1,123 @@
|
|
1
|
+
#
|
2
|
+
# Author:: Seth Chisamore (<schisamo@opscode.com>)
|
3
|
+
# Copyright:: Copyright (c) 2011 Opscode, 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 File.join(File.dirname(__FILE__), 'mixin/windows/bootstrap')
|
20
|
+
|
21
|
+
class Chef
|
22
|
+
class Knife
|
23
|
+
class BootstrapWindowsSsh < Bootstrap
|
24
|
+
|
25
|
+
include Chef::Mixin::Bootstrap
|
26
|
+
|
27
|
+
deps do
|
28
|
+
require 'chef/knife/core/windows_bootstrap_context'
|
29
|
+
require 'chef/json_compat'
|
30
|
+
require 'tempfile'
|
31
|
+
require 'highline'
|
32
|
+
require 'net/ssh'
|
33
|
+
require 'net/ssh/multi'
|
34
|
+
Chef::Knife::Ssh.load_deps
|
35
|
+
end
|
36
|
+
|
37
|
+
banner "knife bootstrap windows ssh FQDN (options)"
|
38
|
+
|
39
|
+
option :ssh_user,
|
40
|
+
:short => "-x USERNAME",
|
41
|
+
:long => "--ssh-user USERNAME",
|
42
|
+
:description => "The ssh username",
|
43
|
+
:default => "root"
|
44
|
+
|
45
|
+
option :ssh_password,
|
46
|
+
:short => "-P PASSWORD",
|
47
|
+
:long => "--ssh-password PASSWORD",
|
48
|
+
:description => "The ssh password"
|
49
|
+
|
50
|
+
option :ssh_port,
|
51
|
+
:short => "-p PORT",
|
52
|
+
:long => "--ssh-port PORT",
|
53
|
+
:description => "The ssh port",
|
54
|
+
:default => "22",
|
55
|
+
:proc => Proc.new { |key| Chef::Config[:knife][:ssh_port] = key }
|
56
|
+
|
57
|
+
option :identity_file,
|
58
|
+
:short => "-i IDENTITY_FILE",
|
59
|
+
:long => "--identity-file IDENTITY_FILE",
|
60
|
+
:description => "The SSH identity file used for authentication"
|
61
|
+
|
62
|
+
option :chef_node_name,
|
63
|
+
:short => "-N NAME",
|
64
|
+
:long => "--node-name NAME",
|
65
|
+
:description => "The Chef node name for your new node"
|
66
|
+
|
67
|
+
option :prerelease,
|
68
|
+
:long => "--prerelease",
|
69
|
+
:description => "Install the pre-release chef gems"
|
70
|
+
|
71
|
+
option :bootstrap_version,
|
72
|
+
:long => "--bootstrap-version VERSION",
|
73
|
+
:description => "The version of Chef to install",
|
74
|
+
:proc => Proc.new { |v| Chef::Config[:knife][:bootstrap_version] = v }
|
75
|
+
|
76
|
+
option :bootstrap_proxy,
|
77
|
+
:long => "--bootstrap-proxy PROXY_URL",
|
78
|
+
:description => "The proxy server for the node being bootstrapped",
|
79
|
+
:proc => Proc.new { |p| Chef::Config[:knife][:bootstrap_proxy] = p }
|
80
|
+
|
81
|
+
option :distro,
|
82
|
+
:short => "-d DISTRO",
|
83
|
+
:long => "--distro DISTRO",
|
84
|
+
:description => "Bootstrap a distro using a template",
|
85
|
+
:default => "windows-shell"
|
86
|
+
|
87
|
+
option :template_file,
|
88
|
+
:long => "--template-file TEMPLATE",
|
89
|
+
:description => "Full path to location of template to use",
|
90
|
+
:default => false
|
91
|
+
|
92
|
+
option :run_list,
|
93
|
+
:short => "-r RUN_LIST",
|
94
|
+
:long => "--run-list RUN_LIST",
|
95
|
+
:description => "Comma separated list of roles/recipes to apply",
|
96
|
+
:proc => lambda { |o| o.split(",") },
|
97
|
+
:default => []
|
98
|
+
|
99
|
+
option :no_host_key_verify,
|
100
|
+
:long => "--no-host-key-verify",
|
101
|
+
:description => "Disable host key verification",
|
102
|
+
:boolean => true,
|
103
|
+
:default => false
|
104
|
+
|
105
|
+
def run
|
106
|
+
bootstrap
|
107
|
+
end
|
108
|
+
|
109
|
+
def run_command(command = '')
|
110
|
+
ssh = Chef::Knife::Ssh.new
|
111
|
+
ssh.name_args = [ server_name, command ]
|
112
|
+
ssh.config[:ssh_user] = locate_config_value(:ssh_user)
|
113
|
+
ssh.config[:ssh_password] = locate_config_value(:ssh_password)
|
114
|
+
ssh.config[:ssh_port] = locate_config_value(:ssh_port)
|
115
|
+
ssh.config[:identity_file] = config[:identity_file]
|
116
|
+
ssh.config[:manual] = true
|
117
|
+
ssh.config[:no_host_key_verify] = config[:no_host_key_verify]
|
118
|
+
ssh
|
119
|
+
end
|
120
|
+
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
@@ -16,21 +16,22 @@
|
|
16
16
|
# limitations under the License.
|
17
17
|
#
|
18
18
|
|
19
|
-
require '
|
20
|
-
require 'erubis'
|
19
|
+
require File.join(File.dirname(__FILE__), 'mixin/windows/bootstrap')
|
21
20
|
|
22
21
|
class Chef
|
23
22
|
class Knife
|
24
|
-
class
|
23
|
+
class BootstrapWindowsWinrm < Bootstrap
|
24
|
+
|
25
|
+
include Chef::Mixin::Bootstrap
|
25
26
|
|
26
27
|
deps do
|
27
28
|
require 'chef/knife/core/windows_bootstrap_context'
|
28
29
|
require 'chef/json_compat'
|
29
30
|
require 'tempfile'
|
30
|
-
|
31
|
+
Chef::Knife::Winrm.load_deps
|
31
32
|
end
|
32
33
|
|
33
|
-
banner "knife winrm
|
34
|
+
banner "knife bootstrap windows winrm FQDN (options)"
|
34
35
|
|
35
36
|
option :winrm_user,
|
36
37
|
:short => "-x USERNAME",
|
@@ -48,14 +49,19 @@ class Chef
|
|
48
49
|
option :winrm_port,
|
49
50
|
:short => "-p PORT",
|
50
51
|
:long => "--winrm-port PORT",
|
51
|
-
:description => "The WinRM port",
|
52
|
+
:description => "The WinRM port, by default this is 5985",
|
52
53
|
:default => "5985",
|
53
54
|
:proc => Proc.new { |key| Chef::Config[:knife][:winrm_port] = key }
|
54
55
|
|
56
|
+
option :identity_file,
|
57
|
+
:short => "-i IDENTITY_FILE",
|
58
|
+
:long => "--identity-file IDENTITY_FILE",
|
59
|
+
:description => "The SSH identity file used for authentication"
|
60
|
+
|
55
61
|
option :winrm_transport,
|
56
62
|
:short => "-t TRANSPORT",
|
57
63
|
:long => "--winrm-transport TRANSPORT",
|
58
|
-
:description => "The WinRM transport type
|
64
|
+
:description => "The WinRM transport type. valid choices are [ssl, plaintext]",
|
59
65
|
:default => 'plaintext',
|
60
66
|
:proc => Proc.new { |transport| Chef::Config[:knife][:winrm_transport] = transport }
|
61
67
|
|
@@ -97,6 +103,11 @@ class Chef
|
|
97
103
|
:description => "The version of Chef to install",
|
98
104
|
:proc => Proc.new { |v| Chef::Config[:knife][:bootstrap_version] = v }
|
99
105
|
|
106
|
+
option :bootstrap_proxy,
|
107
|
+
:long => "--bootstrap-proxy PROXY_URL",
|
108
|
+
:description => "The proxy server for the node being bootstrapped",
|
109
|
+
:proc => Proc.new { |p| Chef::Config[:knife][:bootstrap_proxy] = p }
|
110
|
+
|
100
111
|
option :distro,
|
101
112
|
:short => "-d DISTRO",
|
102
113
|
:long => "--distro DISTRO",
|
@@ -115,110 +126,25 @@ class Chef
|
|
115
126
|
:proc => lambda { |o| o.split(",") },
|
116
127
|
:default => []
|
117
128
|
|
118
|
-
# TODO: This should go away when CHEF-2193 is fixed
|
119
|
-
def load_template(template=nil)
|
120
|
-
# Are we bootstrapping using an already shipped template?
|
121
|
-
if config[:template_file]
|
122
|
-
bootstrap_files = config[:template_file]
|
123
|
-
else
|
124
|
-
bootstrap_files = []
|
125
|
-
bootstrap_files << File.join(File.dirname(__FILE__), 'bootstrap', "#{config[:distro]}.erb")
|
126
|
-
bootstrap_files << File.join(Dir.pwd, ".chef", "bootstrap", "#{config[:distro]}.erb")
|
127
|
-
bootstrap_files << File.join(ENV['HOME'], '.chef', 'bootstrap', "#{config[:distro]}.erb")
|
128
|
-
bootstrap_files << Gem.find_files(File.join("chef","knife","bootstrap","#{config[:distro]}.erb"))
|
129
|
-
end
|
130
|
-
|
131
|
-
template = Array(bootstrap_files).find do |bootstrap_template|
|
132
|
-
Chef::Log.debug("Looking for bootstrap template in #{File.dirname(bootstrap_template)}")
|
133
|
-
File.exists?(bootstrap_template)
|
134
|
-
end
|
135
|
-
|
136
|
-
unless template
|
137
|
-
ui.info("Can not find bootstrap definition for #{config[:distro]}")
|
138
|
-
raise Errno::ENOENT
|
139
|
-
end
|
140
|
-
|
141
|
-
Chef::Log.debug("Found bootstrap template in #{File.dirname(template)}")
|
142
|
-
|
143
|
-
IO.read(template).chomp
|
144
|
-
end
|
145
|
-
|
146
|
-
def render_template(template=nil)
|
147
|
-
context = Knife::Core::WindowsBootstrapContext.new(config, config[:run_list], Chef::Config)
|
148
|
-
Erubis::Eruby.new(template).evaluate(context)
|
149
|
-
end
|
150
|
-
|
151
129
|
def run
|
152
|
-
|
153
|
-
validate_name_args!
|
154
|
-
|
155
|
-
@node_name = Array(@name_args).first
|
156
|
-
# back compat--templates may use this setting:
|
157
|
-
config[:server_name] = @node_name
|
158
|
-
|
159
|
-
$stdout.sync = true
|
160
|
-
|
161
|
-
ui.info("Bootstrapping Chef on #{ui.color(@node_name, :bold)}")
|
162
|
-
# create a bootstrap.bat file on the node
|
163
|
-
# we have to run the remote commands in 2047 char chunks
|
164
|
-
create_bootstrap_bat_command do |command_chunk, chunk_num|
|
165
|
-
knife_winrm("echo \"Rendering bootstrap.bat chunk #{chunk_num}\" && #{command_chunk}").run
|
166
|
-
end
|
167
|
-
|
168
|
-
# execute the bootstrap.bat file
|
169
|
-
knife_winrm(bootstrap_command).run
|
130
|
+
bootstrap
|
170
131
|
end
|
171
132
|
|
172
|
-
|
173
|
-
# if Array(@name_args).first.nil?
|
174
|
-
# ui.error("Must pass an FQDN or ip to bootstrap")
|
175
|
-
# exit 1
|
176
|
-
# end
|
177
|
-
# end
|
178
|
-
#
|
179
|
-
# def server_name
|
180
|
-
# Array(@name_args).first
|
181
|
-
# end
|
182
|
-
|
183
|
-
def knife_winrm(command = '')
|
133
|
+
def run_command(command = '')
|
184
134
|
winrm = Chef::Knife::Winrm.new
|
185
135
|
winrm.name_args = [ server_name, command ]
|
186
|
-
winrm.config[:winrm_user] =
|
187
|
-
winrm.config[:winrm_password] =
|
188
|
-
winrm.config[:winrm_transport] =
|
136
|
+
winrm.config[:winrm_user] = locate_config_value(:winrm_user)
|
137
|
+
winrm.config[:winrm_password] = locate_config_value(:winrm_password)
|
138
|
+
winrm.config[:winrm_transport] = locate_config_value(:winrm_transport)
|
189
139
|
winrm.config[:kerberos_keytab_file] = Chef::Config[:knife][:kerberos_keytab_file] if Chef::Config[:knife][:kerberos_keytab_file]
|
190
140
|
winrm.config[:kerberos_realm] = Chef::Config[:knife][:kerberos_realm] if Chef::Config[:knife][:kerberos_realm]
|
191
141
|
winrm.config[:kerberos_service] = Chef::Config[:knife][:kerberos_service] if Chef::Config[:knife][:kerberos_service]
|
192
142
|
winrm.config[:ca_trust_file] = Chef::Config[:knife][:ca_trust_file] if Chef::Config[:knife][:ca_trust_file]
|
193
143
|
winrm.config[:manual] = true
|
194
|
-
winrm.config[:winrm_port] =
|
144
|
+
winrm.config[:winrm_port] = locate_config_value(:winrm_port)
|
195
145
|
winrm
|
196
146
|
end
|
197
147
|
|
198
|
-
def bootstrap_command
|
199
|
-
@bootstrap_command ||= "cmd /C #{bootstrap_bat_file}"
|
200
|
-
end
|
201
|
-
|
202
|
-
def create_bootstrap_bat_command(&block)
|
203
|
-
bootstrap_bat = []
|
204
|
-
chunk_num = 0
|
205
|
-
render_template(load_template(config[:bootstrap_template])).each_line do |line|
|
206
|
-
# escape WIN BATCH special chars
|
207
|
-
line.gsub!(/[(<|>)^]/).each{|m| "^#{m}"}
|
208
|
-
# windows commands are limited to 2047 characters
|
209
|
-
if((bootstrap_bat + [line]).join(" && ").size > 2047 )
|
210
|
-
yield bootstrap_bat.join(" && "), chunk_num += 1
|
211
|
-
bootstrap_bat = []
|
212
|
-
end
|
213
|
-
bootstrap_bat << ">> #{bootstrap_bat_file} (echo.#{line.chomp.strip})"
|
214
|
-
end
|
215
|
-
yield bootstrap_bat.join(" && "), chunk_num += 1
|
216
|
-
end
|
217
|
-
|
218
|
-
def bootstrap_bat_file
|
219
|
-
"%TEMP%\\bootstrap.bat"
|
220
|
-
end
|
221
|
-
|
222
148
|
end
|
223
149
|
end
|
224
150
|
end
|
@@ -60,6 +60,13 @@ CONFIG
|
|
60
60
|
else
|
61
61
|
client_rb << "# Using default node name (fqdn)\n"
|
62
62
|
end
|
63
|
+
|
64
|
+
if knife_config[:bootstrap_proxy]
|
65
|
+
client_rb << "\n"
|
66
|
+
client_rb << %Q{http_proxy "#{knife_config[:bootstrap_proxy]}"\n}
|
67
|
+
client_rb << %Q{https_proxy "#{knife_config[:bootstrap_proxy]}"\n}
|
68
|
+
end
|
69
|
+
|
63
70
|
escape_and_echo(client_rb)
|
64
71
|
end
|
65
72
|
|
@@ -75,11 +82,24 @@ CONFIG
|
|
75
82
|
win_wget = <<-WGET
|
76
83
|
url = WScript.Arguments.Named("url")
|
77
84
|
path = WScript.Arguments.Named("path")
|
78
|
-
Set objXMLHTTP = CreateObject("MSXML2.ServerXMLHTTP")
|
79
|
-
|
85
|
+
Set objXMLHTTP = CreateObject("MSXML2.ServerXMLHTTP.6.0")
|
86
|
+
Set wshShell = CreateObject( "WScript.Shell" )
|
87
|
+
Set objUserVariables = wshShell.Environment("USER")
|
88
|
+
|
89
|
+
'http proxy is optional
|
90
|
+
'attempt to read from HTTP_PROXY env var first
|
80
91
|
On Error Resume Next
|
92
|
+
|
93
|
+
If NOT (objUserVariables("HTTP_PROXY") = "") Then
|
94
|
+
objXMLHTTP.setProxy 2, objUserVariables("HTTP_PROXY")
|
95
|
+
|
96
|
+
'fall back to named arg
|
97
|
+
ElseIf NOT (WScript.Arguments.Named("proxy") = "") Then
|
81
98
|
objXMLHTTP.setProxy 2, WScript.Arguments.Named("proxy")
|
99
|
+
End If
|
100
|
+
|
82
101
|
On Error Goto 0
|
102
|
+
|
83
103
|
objXMLHTTP.open "GET", url, false
|
84
104
|
objXMLHTTP.send()
|
85
105
|
If objXMLHTTP.Status = 200 Then
|
@@ -0,0 +1,94 @@
|
|
1
|
+
require 'chef/knife'
|
2
|
+
require 'erubis'
|
3
|
+
|
4
|
+
class Chef
|
5
|
+
module Mixin
|
6
|
+
module Bootstrap
|
7
|
+
|
8
|
+
# TODO: This should go away when CHEF-2193 is fixed
|
9
|
+
def load_template(template=nil)
|
10
|
+
# Are we bootstrapping using an already shipped template?
|
11
|
+
if config[:template_file]
|
12
|
+
bootstrap_files = config[:template_file]
|
13
|
+
else
|
14
|
+
bootstrap_files = []
|
15
|
+
bootstrap_files << File.join(File.dirname(__FILE__), 'bootstrap', "#{config[:distro]}.erb")
|
16
|
+
bootstrap_files << File.join(Dir.pwd, ".chef", "bootstrap", "#{config[:distro]}.erb")
|
17
|
+
bootstrap_files << File.join(ENV['HOME'], '.chef', 'bootstrap', "#{config[:distro]}.erb")
|
18
|
+
bootstrap_files << Gem.find_files(File.join("chef","knife","bootstrap","#{config[:distro]}.erb"))
|
19
|
+
bootstrap_files.flatten!
|
20
|
+
end
|
21
|
+
|
22
|
+
template = Array(bootstrap_files).find do |bootstrap_template|
|
23
|
+
Chef::Log.debug("Looking for bootstrap template in #{File.dirname(bootstrap_template)}")
|
24
|
+
::File.exists?(bootstrap_template)
|
25
|
+
end
|
26
|
+
|
27
|
+
unless template
|
28
|
+
ui.info("Can not find bootstrap definition for #{config[:distro]}")
|
29
|
+
raise Errno::ENOENT
|
30
|
+
end
|
31
|
+
|
32
|
+
Chef::Log.debug("Found bootstrap template in #{File.dirname(template)}")
|
33
|
+
|
34
|
+
IO.read(template).chomp
|
35
|
+
end
|
36
|
+
|
37
|
+
def render_template(template=nil)
|
38
|
+
context = Knife::Core::WindowsBootstrapContext.new(config, config[:run_list], Chef::Config)
|
39
|
+
Erubis::Eruby.new(template).evaluate(context)
|
40
|
+
end
|
41
|
+
|
42
|
+
def bootstrap(proto=nil)
|
43
|
+
|
44
|
+
validate_name_args!
|
45
|
+
|
46
|
+
@node_name = Array(@name_args).first
|
47
|
+
# back compat--templates may use this setting:
|
48
|
+
config[:server_name] = @node_name
|
49
|
+
|
50
|
+
$stdout.sync = true
|
51
|
+
|
52
|
+
ui.info("Bootstrapping Chef on #{ui.color(@node_name, :bold)}")
|
53
|
+
# create a bootstrap.bat file on the node
|
54
|
+
# we have to run the remote commands in 2047 char chunks
|
55
|
+
create_bootstrap_bat_command do |command_chunk, chunk_num|
|
56
|
+
run_command("cmd.exe /C echo \"Rendering bootstrap.bat chunk #{chunk_num}\" && #{command_chunk}").run
|
57
|
+
end
|
58
|
+
|
59
|
+
# execute the bootstrap.bat file
|
60
|
+
run_command(bootstrap_command).run
|
61
|
+
end
|
62
|
+
|
63
|
+
def bootstrap_command
|
64
|
+
@bootstrap_command ||= "cmd.exe /C #{bootstrap_bat_file}"
|
65
|
+
end
|
66
|
+
|
67
|
+
def create_bootstrap_bat_command(&block)
|
68
|
+
bootstrap_bat = []
|
69
|
+
chunk_num = 0
|
70
|
+
render_template(load_template(config[:bootstrap_template])).each_line do |line|
|
71
|
+
# escape WIN BATCH special chars
|
72
|
+
line.gsub!(/[(<|>)^]/).each{|m| "^#{m}"}
|
73
|
+
# windows commands are limited to 2047 characters
|
74
|
+
if((bootstrap_bat + [line]).join(" && ").size > 2047 )
|
75
|
+
yield bootstrap_bat.join(" && "), chunk_num += 1
|
76
|
+
bootstrap_bat = []
|
77
|
+
end
|
78
|
+
bootstrap_bat << ">> #{bootstrap_bat_file} (echo.#{line.chomp.strip})"
|
79
|
+
end
|
80
|
+
yield bootstrap_bat.join(" && "), chunk_num += 1
|
81
|
+
end
|
82
|
+
|
83
|
+
def bootstrap_bat_file
|
84
|
+
"%TEMP%\\bootstrap.bat"
|
85
|
+
end
|
86
|
+
|
87
|
+
def locate_config_value(key)
|
88
|
+
key = key.to_sym
|
89
|
+
Chef::Config[:knife][key] || config[key]
|
90
|
+
end
|
91
|
+
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: knife-windows
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 0.5.
|
5
|
+
version: 0.5.3
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Seth Chisamore
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2011-05-
|
13
|
+
date: 2011-05-13 00:00:00 -07:00
|
14
14
|
default_executable:
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
@@ -42,9 +42,11 @@ files:
|
|
42
42
|
- Rakefile
|
43
43
|
- knife-windows.gemspec
|
44
44
|
- lib/chef/knife/bootstrap/windows-shell.erb
|
45
|
+
- lib/chef/knife/bootstrap_windows_ssh.rb
|
46
|
+
- lib/chef/knife/bootstrap_windows_winrm.rb
|
45
47
|
- lib/chef/knife/core/windows_bootstrap_context.rb
|
48
|
+
- lib/chef/knife/mixin/windows/bootstrap.rb
|
46
49
|
- lib/chef/knife/winrm.rb
|
47
|
-
- lib/chef/knife/winrm_bootstrap.rb
|
48
50
|
- lib/knife-windows/version.rb
|
49
51
|
has_rdoc: true
|
50
52
|
homepage: https://github.com/opscode/knife-windows
|