chef-provisioning 0.15
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/CHANGELOG.md +207 -0
- data/LICENSE +201 -0
- data/README.md +260 -0
- data/Rakefile +6 -0
- data/lib/chef/provider/load_balancer.rb +77 -0
- data/lib/chef/provider/machine.rb +176 -0
- data/lib/chef/provider/machine_batch.rb +191 -0
- data/lib/chef/provider/machine_execute.rb +35 -0
- data/lib/chef/provider/machine_file.rb +54 -0
- data/lib/chef/provider/machine_image.rb +60 -0
- data/lib/chef/provisioning.rb +95 -0
- data/lib/chef/provisioning/action_handler.rb +68 -0
- data/lib/chef/provisioning/add_prefix_action_handler.rb +31 -0
- data/lib/chef/provisioning/chef_image_spec.rb +108 -0
- data/lib/chef/provisioning/chef_load_balancer_spec.rb +108 -0
- data/lib/chef/provisioning/chef_machine_spec.rb +84 -0
- data/lib/chef/provisioning/chef_provider_action_handler.rb +74 -0
- data/lib/chef/provisioning/chef_run_data.rb +139 -0
- data/lib/chef/provisioning/convergence_strategy.rb +28 -0
- data/lib/chef/provisioning/convergence_strategy/install_cached.rb +156 -0
- data/lib/chef/provisioning/convergence_strategy/install_msi.rb +58 -0
- data/lib/chef/provisioning/convergence_strategy/install_sh.rb +55 -0
- data/lib/chef/provisioning/convergence_strategy/no_converge.rb +39 -0
- data/lib/chef/provisioning/convergence_strategy/precreate_chef_objects.rb +183 -0
- data/lib/chef/provisioning/driver.rb +304 -0
- data/lib/chef/provisioning/image_spec.rb +72 -0
- data/lib/chef/provisioning/load_balancer_spec.rb +86 -0
- data/lib/chef/provisioning/machine.rb +112 -0
- data/lib/chef/provisioning/machine/basic_machine.rb +84 -0
- data/lib/chef/provisioning/machine/unix_machine.rb +278 -0
- data/lib/chef/provisioning/machine/windows_machine.rb +104 -0
- data/lib/chef/provisioning/machine_spec.rb +82 -0
- data/lib/chef/provisioning/recipe_dsl.rb +103 -0
- data/lib/chef/provisioning/transport.rb +95 -0
- data/lib/chef/provisioning/transport/ssh.rb +343 -0
- data/lib/chef/provisioning/transport/winrm.rb +151 -0
- data/lib/chef/provisioning/version.rb +5 -0
- data/lib/chef/resource/chef_data_bag_resource.rb +148 -0
- data/lib/chef/resource/load_balancer.rb +57 -0
- data/lib/chef/resource/machine.rb +124 -0
- data/lib/chef/resource/machine_batch.rb +78 -0
- data/lib/chef/resource/machine_execute.rb +28 -0
- data/lib/chef/resource/machine_file.rb +34 -0
- data/lib/chef/resource/machine_image.rb +35 -0
- data/lib/chef_metal.rb +1 -0
- metadata +217 -0
@@ -0,0 +1,151 @@
|
|
1
|
+
require 'chef/provisioning/transport'
|
2
|
+
require 'base64'
|
3
|
+
require 'timeout'
|
4
|
+
|
5
|
+
class Chef
|
6
|
+
module Provisioning
|
7
|
+
class Transport
|
8
|
+
# Transport to handle the WinRM connection protocol.
|
9
|
+
class WinRM < Chef::Provisioning::Transport
|
10
|
+
#
|
11
|
+
# Create a new WinRM transport.
|
12
|
+
#
|
13
|
+
# == Arguments
|
14
|
+
# - endpoint: the WinRM endpoint, e.g. http://145.14.51.45:5985/wsman.
|
15
|
+
# - type: the connection type, e.g. :plaintext.
|
16
|
+
# - options: options hash, including both WinRM options and transport options.
|
17
|
+
# For transport options, see the Transport.options definition. WinRM
|
18
|
+
# options include :user, :pass, :disable_sspi => true, among others.
|
19
|
+
# - global_config: an options hash that looks suspiciously similar to
|
20
|
+
# Chef::Config, containing at least the key :log_level.
|
21
|
+
#
|
22
|
+
# The actual connection is made as ::WinRM::WinRMWebService.new(endpoint, type, options)
|
23
|
+
#
|
24
|
+
def initialize(endpoint, type, options, global_config)
|
25
|
+
@endpoint = endpoint
|
26
|
+
@type = type
|
27
|
+
@options = options
|
28
|
+
@config = global_config
|
29
|
+
end
|
30
|
+
|
31
|
+
attr_reader :endpoint
|
32
|
+
attr_reader :type
|
33
|
+
attr_reader :options
|
34
|
+
attr_reader :config
|
35
|
+
|
36
|
+
def execute(command, execute_options = {})
|
37
|
+
output = with_execute_timeout(execute_options) do
|
38
|
+
session.set_timeout(execute_timeout(execute_options))
|
39
|
+
session.run_powershell_script(command) do |stdout, stderr|
|
40
|
+
stream_chunk(execute_options, stdout, stderr)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
WinRMResult.new(command, execute_options, config, output)
|
44
|
+
end
|
45
|
+
|
46
|
+
def read_file(path)
|
47
|
+
result = execute("[Convert]::ToBase64String((Get-Content #{escape(path)} -Encoding byte -ReadCount 0))")
|
48
|
+
if result.exitstatus == 0
|
49
|
+
Base64.decode64(result.stdout)
|
50
|
+
else
|
51
|
+
nil
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def write_file(path, content)
|
56
|
+
chunk_size = options[:chunk_size] || 1024
|
57
|
+
# TODO if we could marshal this data directly, we wouldn't have to base64 or do this godawful slow stuff :(
|
58
|
+
index = 0
|
59
|
+
execute("
|
60
|
+
$ByteArray = [System.Convert]::FromBase64String(#{escape(Base64.encode64(content[index..index+chunk_size-1]))})
|
61
|
+
$file = [System.IO.File]::Open(#{escape(path)}, 'Create', 'Write')
|
62
|
+
$file.Write($ByteArray, 0, $ByteArray.Length)
|
63
|
+
$file.Close
|
64
|
+
").error!
|
65
|
+
index += chunk_size
|
66
|
+
while index < content.length
|
67
|
+
execute("
|
68
|
+
$ByteArray = [System.Convert]::FromBase64String(#{escape(Base64.encode64(content[index..index+chunk_size-1]))})
|
69
|
+
$file = [System.IO.File]::Open(#{escape(path)}, 'Append', 'Write')
|
70
|
+
$file.Write($ByteArray, 0, $ByteArray.Length)
|
71
|
+
$file.Close
|
72
|
+
").error!
|
73
|
+
index += chunk_size
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def disconnect
|
78
|
+
#
|
79
|
+
end
|
80
|
+
|
81
|
+
def escape(string)
|
82
|
+
"\"#{string.gsub("\"", "`\"")}\""
|
83
|
+
end
|
84
|
+
|
85
|
+
def available?
|
86
|
+
# If you can't pwd within 10 seconds, you can't pwd
|
87
|
+
execute('pwd', :timeout => 10)
|
88
|
+
true
|
89
|
+
rescue Timeout::Error, Errno::EHOSTUNREACH, Errno::ETIMEDOUT, Errno::ECONNREFUSED, Errno::ECONNRESET, ::WinRM::WinRMHTTPTransportError, ::WinRM::WinRMWebServiceError, ::WinRM::WinRMWSManFault
|
90
|
+
Chef::Log.debug("unavailable: network connection failed or broke: #{$!.inspect}")
|
91
|
+
disconnect
|
92
|
+
false
|
93
|
+
rescue ::WinRM::WinRMAuthorizationError
|
94
|
+
Chef::Log.debug("unavailable: winrm authentication error: #{$!.inspect} ")
|
95
|
+
disconnect
|
96
|
+
false
|
97
|
+
end
|
98
|
+
|
99
|
+
def make_url_available_to_remote(local_url)
|
100
|
+
uri = URI(local_url)
|
101
|
+
host = Socket.getaddrinfo(uri.host, uri.scheme, nil, :STREAM)[0][3]
|
102
|
+
if host == '127.0.0.1' || host == '::1'
|
103
|
+
raise 'Unable to converge locally via winrm. Local converge is currently only supported with SSH. You may only converge with winrm against a chef-server.'
|
104
|
+
end
|
105
|
+
local_url
|
106
|
+
end
|
107
|
+
|
108
|
+
protected
|
109
|
+
|
110
|
+
def session
|
111
|
+
@session ||= begin
|
112
|
+
require 'kconv' # Really, people? *sigh*
|
113
|
+
require 'winrm'
|
114
|
+
::WinRM::WinRMWebService.new(endpoint, type, options)
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
class WinRMResult
|
119
|
+
def initialize(command, options, config, output)
|
120
|
+
@command = command
|
121
|
+
@options = options
|
122
|
+
@config = config
|
123
|
+
@exitstatus = output[:exitcode]
|
124
|
+
@stdout = ''
|
125
|
+
@stderr = ''
|
126
|
+
output[:data].each do |data|
|
127
|
+
@stdout << data[:stdout] if data[:stdout]
|
128
|
+
@stderr << data[:stderr] if data[:stderr]
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
attr_reader :stdout
|
133
|
+
attr_reader :stderr
|
134
|
+
attr_reader :exitstatus
|
135
|
+
attr_reader :command
|
136
|
+
attr_reader :options
|
137
|
+
attr_reader :config
|
138
|
+
|
139
|
+
def error!
|
140
|
+
if exitstatus != 0
|
141
|
+
msg = "Error: command '#{command}' exited with code #{exitstatus}.\n"
|
142
|
+
msg << "STDOUT: #{stdout}" if !options[:stream] && !options[:stream_stdout] && config[:log_level] != :debug
|
143
|
+
msg << "STDERR: #{stderr}" if !options[:stream] && !options[:stream_stderr] && config[:log_level] != :debug
|
144
|
+
raise msg
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
@@ -0,0 +1,148 @@
|
|
1
|
+
require 'chef/resource/lwrp_base'
|
2
|
+
require 'cheffish'
|
3
|
+
|
4
|
+
# A resource that is backed by a data bag in a Chef server somewhere
|
5
|
+
class Chef::Resource::ChefDataBagResource < Chef::Resource::LWRPBase
|
6
|
+
|
7
|
+
# The key to store this thing under (/data/bag/<<name>>).
|
8
|
+
attr_reader :name
|
9
|
+
|
10
|
+
class << self
|
11
|
+
# The name of the databag to store the item in.
|
12
|
+
attr_reader :databag_name
|
13
|
+
# A list of attributes to be persisted into the databag.
|
14
|
+
attr_reader :stored_attributes
|
15
|
+
end
|
16
|
+
|
17
|
+
def initialize(name, run_context=nil)
|
18
|
+
super
|
19
|
+
Chef::Log.debug("Re-hydrating #{name} from #{self.class.databag_name}...")
|
20
|
+
self.hydrate
|
21
|
+
end
|
22
|
+
|
23
|
+
# @return [Array] List of attributes that are stored in the databag
|
24
|
+
def self.stored_attributes
|
25
|
+
@stored_attributes || []
|
26
|
+
end
|
27
|
+
|
28
|
+
# Set databag name
|
29
|
+
# @return [Void]
|
30
|
+
def self.databag_name= name
|
31
|
+
Chef::Log.debug("Setting databag name to #{name}")
|
32
|
+
@databag_name = name
|
33
|
+
end
|
34
|
+
|
35
|
+
# Mark an attribute as stored by adding it to the internal tracking list {stored_attributes}
|
36
|
+
# and then delegating to {Chef::Resource::LWRPBase#attribute}
|
37
|
+
# @param attr_name [Symbol] Name of the attribute as a symbol
|
38
|
+
# @return [Void]
|
39
|
+
def self.stored_attribute(attr_name)
|
40
|
+
@stored_attributes ||= []
|
41
|
+
@stored_attributes << attr_name
|
42
|
+
self.attribute attr_name
|
43
|
+
end
|
44
|
+
|
45
|
+
# Load persisted data from the server's databag. If the databag does not exist on the
|
46
|
+
# server, returns nil.
|
47
|
+
#
|
48
|
+
# @param chef_server [Hash] A hash representing which Chef server to talk to
|
49
|
+
# @option chef_server [String] :chef_server_url URL to the Chef server
|
50
|
+
# @option chef_server [Hash] :options Options for when talking to the Chef server
|
51
|
+
# @option options [String] :client_name The node name making the call
|
52
|
+
# @option options [String] :signing_key_filename Path to the signing key
|
53
|
+
# @return [Object] an instance of this class re-hydrated from the data hash stored in the
|
54
|
+
# databag.
|
55
|
+
def hydrate(chef_server = Cheffish.default_chef_server)
|
56
|
+
chef_api = Cheffish.chef_server_api(chef_server)
|
57
|
+
begin
|
58
|
+
data = chef_api.get("/data/#{self.class.databag_name}/#{name}")
|
59
|
+
load_from_hash(data)
|
60
|
+
Chef::Log.debug("Rehydrating resource from #{self.class.databag_name}/#{name}: #{data}")
|
61
|
+
rescue Net::HTTPServerException => e
|
62
|
+
if e.response.code == '404'
|
63
|
+
nil
|
64
|
+
else
|
65
|
+
raise
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
# Load instance variable data from a hash. For each key,value pair, set @<key> to value
|
71
|
+
# @param hash [Hash] Hash containing the instance variable data
|
72
|
+
# @return [Object] self after having been populated with data.
|
73
|
+
def load_from_hash hash
|
74
|
+
hash.each do |k,v|
|
75
|
+
self.instance_variable_set("@#{k}", v)
|
76
|
+
end
|
77
|
+
self
|
78
|
+
end
|
79
|
+
|
80
|
+
# Convert the values in {stored_attributes} to a hash for storing in a databag
|
81
|
+
# @return [Hash] a hash of (k,v) pairs where k is each record in {stored_attributes}
|
82
|
+
def storage_hash
|
83
|
+
ignored = []
|
84
|
+
|
85
|
+
hash = {}
|
86
|
+
(self.class.stored_attributes - ignored).each do |attr_name|
|
87
|
+
varname = "@#{attr_name.to_s.gsub('@', '')}"
|
88
|
+
key = varname.gsub('@', '')
|
89
|
+
hash[key] = self.instance_variable_get varname
|
90
|
+
end
|
91
|
+
|
92
|
+
hash
|
93
|
+
end
|
94
|
+
|
95
|
+
|
96
|
+
# Save this entity to the server. If you have significant information that
|
97
|
+
# could be lost, you should do this as quickly as possible.
|
98
|
+
# @return [Void]
|
99
|
+
def save
|
100
|
+
|
101
|
+
create_databag_if_needed self.class.databag_name
|
102
|
+
|
103
|
+
# Clone for inline_resource
|
104
|
+
_databag_name = self.class.databag_name
|
105
|
+
_hash = self.storage_hash
|
106
|
+
_name = self.name
|
107
|
+
|
108
|
+
Cheffish.inline_resource(self, @action) do
|
109
|
+
chef_data_bag_item _name do
|
110
|
+
data_bag _databag_name
|
111
|
+
raw_data _hash
|
112
|
+
action :create
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
# Delete this entity from the server
|
118
|
+
# @return [Void]
|
119
|
+
def delete
|
120
|
+
# Clone for inline_resource
|
121
|
+
_name = self.name
|
122
|
+
_databag_name = self.class.databag_name
|
123
|
+
|
124
|
+
Cheffish.inline_resource(self, @action) do
|
125
|
+
chef_data_bag_item _name do
|
126
|
+
data_bag _databag_name
|
127
|
+
action :delete
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
def new_resource
|
133
|
+
self
|
134
|
+
end
|
135
|
+
|
136
|
+
private
|
137
|
+
# Create the databag with Cheffish if required
|
138
|
+
# @return [Void]
|
139
|
+
def create_databag_if_needed databag_name
|
140
|
+
_databag_name = databag_name
|
141
|
+
Cheffish.inline_resource(self, @action) do
|
142
|
+
chef_data_bag _databag_name do
|
143
|
+
action :create
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'chef/resource/lwrp_base'
|
2
|
+
require 'cheffish'
|
3
|
+
require 'chef_metal'
|
4
|
+
require 'cheffish/merged_config'
|
5
|
+
|
6
|
+
class Chef
|
7
|
+
class Resource
|
8
|
+
class LoadBalancer < Chef::Resource::LWRPBase
|
9
|
+
|
10
|
+
self.resource_name = 'load_balancer'
|
11
|
+
|
12
|
+
def initialize(*args)
|
13
|
+
super
|
14
|
+
@chef_environment = run_context.cheffish.current_environment
|
15
|
+
@chef_server = run_context.cheffish.current_chef_server
|
16
|
+
@driver = run_context.chef_metal.current_driver
|
17
|
+
@load_balancer_options = run_context.chef_metal.current_load_balancer_options
|
18
|
+
end
|
19
|
+
|
20
|
+
actions :create, :destroy
|
21
|
+
default_action :create
|
22
|
+
|
23
|
+
# Driver attributes
|
24
|
+
attribute :driver
|
25
|
+
attribute :load_balancer_options
|
26
|
+
attribute :name, :kind_of => String, :name_attribute => true
|
27
|
+
attribute :machines
|
28
|
+
|
29
|
+
def add_load_balancer_options(options)
|
30
|
+
@load_balancer_options = Cheffish::MergedConfig.new(options, @load_balancer_options)
|
31
|
+
end
|
32
|
+
|
33
|
+
|
34
|
+
# This is here because metal users will probably want to do things like:
|
35
|
+
# machine "foo"
|
36
|
+
# action :destroy
|
37
|
+
# end
|
38
|
+
#
|
39
|
+
# with_load_balancer_options :bootstrap_options => {...}
|
40
|
+
# machine "foo"
|
41
|
+
# converge true
|
42
|
+
# end
|
43
|
+
#
|
44
|
+
# Without this, the first resource's machine options will obliterate the second
|
45
|
+
# resource's machine options, and then unexpected (and undesired) things happen.
|
46
|
+
def load_prior_resource
|
47
|
+
Chef::Log.debug "Overloading #{self.resource_name} load_prior_resource with NOOP"
|
48
|
+
end
|
49
|
+
|
50
|
+
# chef client version and omnibus
|
51
|
+
# chef-zero boot method?
|
52
|
+
# chef-client -z boot method?
|
53
|
+
# pushy boot method?
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
@@ -0,0 +1,124 @@
|
|
1
|
+
require 'chef/resource/lwrp_base'
|
2
|
+
require 'cheffish'
|
3
|
+
require 'chef/provisioning'
|
4
|
+
require 'cheffish/merged_config'
|
5
|
+
|
6
|
+
class Chef
|
7
|
+
class Resource
|
8
|
+
class Machine < Chef::Resource::LWRPBase
|
9
|
+
|
10
|
+
self.resource_name = 'machine'
|
11
|
+
|
12
|
+
def initialize(*args)
|
13
|
+
super
|
14
|
+
@chef_environment = run_context.cheffish.current_environment
|
15
|
+
@chef_server = run_context.cheffish.current_chef_server
|
16
|
+
@driver = run_context.chef_provisioning.current_driver
|
17
|
+
@machine_options = run_context.chef_provisioning.current_machine_options
|
18
|
+
end
|
19
|
+
|
20
|
+
actions :allocate, :ready, :setup, :converge, :converge_only, :destroy, :stop
|
21
|
+
default_action :converge
|
22
|
+
|
23
|
+
# Driver attributes
|
24
|
+
attribute :driver
|
25
|
+
|
26
|
+
# Machine options
|
27
|
+
attribute :machine_options
|
28
|
+
|
29
|
+
# Node attributes
|
30
|
+
Cheffish.node_attributes(self)
|
31
|
+
|
32
|
+
# Client keys
|
33
|
+
# Options to generate private key (size, type, etc.) when the server doesn't have it
|
34
|
+
attribute :private_key_options, :kind_of => Hash
|
35
|
+
attribute :allow_overwrite_keys, :kind_of => [TrueClass, FalseClass]
|
36
|
+
|
37
|
+
# Optionally pull the public key out to a file
|
38
|
+
attribute :public_key_path, :kind_of => String
|
39
|
+
attribute :public_key_format, :kind_of => String
|
40
|
+
|
41
|
+
# If you really want to force the private key to be a certain key, pass these
|
42
|
+
attribute :source_key
|
43
|
+
attribute :source_key_path, :kind_of => String
|
44
|
+
attribute :source_key_pass_phrase
|
45
|
+
|
46
|
+
# Client attributes
|
47
|
+
attribute :admin, :kind_of => [TrueClass, FalseClass]
|
48
|
+
attribute :validator, :kind_of => [TrueClass, FalseClass]
|
49
|
+
|
50
|
+
# Client Ohai hints, allows machine to enable hints
|
51
|
+
# e.g. ohai_hint 'ec2' => { 'a' => 'b' } creates file ec2.json with json contents { 'a': 'b' }
|
52
|
+
attribute :ohai_hints, :kind_of => Hash
|
53
|
+
|
54
|
+
# Allows you to turn convergence off in the :create action by writing "converge false"
|
55
|
+
# or force it with "true"
|
56
|
+
attribute :converge, :kind_of => [TrueClass, FalseClass]
|
57
|
+
|
58
|
+
# A list of files to upload, in the format REMOTE_PATH => LOCAL_PATH|HASH.
|
59
|
+
# == Examples
|
60
|
+
# files '/remote/path.txt' => '/local/path.txt'
|
61
|
+
# files '/remote/path.txt' => { :local_path => '/local/path.txt' }
|
62
|
+
# files '/remote/path.txt' => { :content => 'woo' }
|
63
|
+
attribute :files, :kind_of => Hash
|
64
|
+
|
65
|
+
# The named machine_image to start from. Specify the name of a machine_image
|
66
|
+
# object and the default machine_options will be set to use that image.
|
67
|
+
# == Examples
|
68
|
+
# from_image 'company_base_image'
|
69
|
+
attribute :from_image, :kind_of => String
|
70
|
+
|
71
|
+
# A single file to upload, in the format REMOTE_PATH, LOCAL_PATH|HASH.
|
72
|
+
# This directive may be passed multiple times, and multiple files will be uploaded.
|
73
|
+
# == Examples
|
74
|
+
# file '/remote/path.txt', '/local/path.txt'
|
75
|
+
# file '/remote/path.txt', { :local_path => '/local/path.txt' }
|
76
|
+
# file '/remote/path.txt', { :content => 'woo' }
|
77
|
+
def file(remote_path, local = nil)
|
78
|
+
@files ||= {}
|
79
|
+
if remote_path.is_a?(Hash)
|
80
|
+
if local
|
81
|
+
raise "file(Hash, something) does not make sense. Either pass a hash, or pass a pair, please."
|
82
|
+
end
|
83
|
+
remote_path.each_pair do |remote, local|
|
84
|
+
@files[remote] = local
|
85
|
+
end
|
86
|
+
elsif remote_path.is_a?(String)
|
87
|
+
if !local
|
88
|
+
raise "Must pass both a remote path and a local path to file directive"
|
89
|
+
end
|
90
|
+
@files[remote_path] = local
|
91
|
+
else
|
92
|
+
raise "file remote_path must be a String, but is a #{remote_path.class}"
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
def add_machine_options(options)
|
97
|
+
@machine_options = Cheffish::MergedConfig.new(options, @machine_options)
|
98
|
+
end
|
99
|
+
|
100
|
+
|
101
|
+
# This is here because provisioning users will probably want to do things like:
|
102
|
+
# machine "foo"
|
103
|
+
# action :destroy
|
104
|
+
# end
|
105
|
+
#
|
106
|
+
# @example
|
107
|
+
# with_machine_options :bootstrap_options => { ... }
|
108
|
+
# machine "foo"
|
109
|
+
# converge true
|
110
|
+
# end
|
111
|
+
#
|
112
|
+
# Without this, the first resource's machine options will obliterate the second
|
113
|
+
# resource's machine options, and then unexpected (and undesired) things happen.
|
114
|
+
def load_prior_resource
|
115
|
+
Chef::Log.debug "Overloading #{self.resource_name} load_prior_resource with NOOP"
|
116
|
+
end
|
117
|
+
|
118
|
+
# chef client version and omnibus
|
119
|
+
# chef-zero boot method?
|
120
|
+
# chef-client -z boot method?
|
121
|
+
# pushy boot method?
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|