chef-provisioning 2.0.1 → 2.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +906 -899
- data/Gemfile +17 -17
- data/LICENSE +201 -201
- data/README.md +312 -312
- data/Rakefile +55 -55
- data/chef-provisioning.gemspec +38 -38
- data/lib/chef/provider/load_balancer.rb +75 -75
- data/lib/chef/provider/machine.rb +219 -219
- data/lib/chef/provider/machine_batch.rb +224 -224
- data/lib/chef/provider/machine_execute.rb +36 -36
- data/lib/chef/provider/machine_file.rb +55 -55
- data/lib/chef/provider/machine_image.rb +105 -105
- data/lib/chef/provisioning.rb +110 -110
- data/lib/chef/provisioning/action_handler.rb +68 -68
- data/lib/chef/provisioning/add_prefix_action_handler.rb +35 -35
- data/lib/chef/provisioning/chef_managed_entry_store.rb +128 -128
- data/lib/chef/provisioning/chef_provider_action_handler.rb +74 -74
- data/lib/chef/provisioning/chef_run_data.rb +132 -132
- data/lib/chef/provisioning/convergence_strategy.rb +28 -28
- data/lib/chef/provisioning/convergence_strategy/ignore_convergence_failure.rb +54 -54
- data/lib/chef/provisioning/convergence_strategy/install_cached.rb +188 -188
- data/lib/chef/provisioning/convergence_strategy/install_msi.rb +71 -71
- data/lib/chef/provisioning/convergence_strategy/install_sh.rb +71 -71
- data/lib/chef/provisioning/convergence_strategy/no_converge.rb +35 -35
- data/lib/chef/provisioning/convergence_strategy/precreate_chef_objects.rb +255 -255
- data/lib/chef/provisioning/driver.rb +323 -323
- data/lib/chef/provisioning/load_balancer_spec.rb +14 -14
- data/lib/chef/provisioning/machine.rb +112 -112
- data/lib/chef/provisioning/machine/basic_machine.rb +84 -84
- data/lib/chef/provisioning/machine/unix_machine.rb +288 -288
- data/lib/chef/provisioning/machine/windows_machine.rb +108 -108
- data/lib/chef/provisioning/machine_image_spec.rb +34 -34
- data/lib/chef/provisioning/machine_spec.rb +58 -58
- data/lib/chef/provisioning/managed_entry.rb +121 -121
- data/lib/chef/provisioning/managed_entry_store.rb +136 -136
- data/lib/chef/provisioning/recipe_dsl.rb +99 -99
- data/lib/chef/provisioning/rspec.rb +27 -27
- data/lib/chef/provisioning/transport.rb +100 -100
- data/lib/chef/provisioning/transport/ssh.rb +403 -403
- data/lib/chef/provisioning/transport/winrm.rb +144 -144
- data/lib/chef/provisioning/version.rb +5 -5
- data/lib/chef/resource/chef_data_bag_resource.rb +146 -146
- data/lib/chef/resource/load_balancer.rb +57 -57
- data/lib/chef/resource/machine.rb +128 -128
- data/lib/chef/resource/machine_batch.rb +78 -78
- data/lib/chef/resource/machine_execute.rb +30 -30
- data/lib/chef/resource/machine_file.rb +34 -34
- data/lib/chef/resource/machine_image.rb +35 -35
- data/lib/chef_metal.rb +1 -1
- data/spec/chef/provisioning/convergence_strategy/ignore_convergence_failure_spec.rb +86 -86
- data/spec/spec_helper.rb +27 -27
- metadata +10 -4
@@ -1,108 +1,108 @@
|
|
1
|
-
require 'chef/provisioning/machine/basic_machine'
|
2
|
-
|
3
|
-
class Chef
|
4
|
-
module Provisioning
|
5
|
-
class Machine
|
6
|
-
class WindowsMachine < BasicMachine
|
7
|
-
def initialize(machine_spec, transport, convergence_strategy)
|
8
|
-
super
|
9
|
-
end
|
10
|
-
|
11
|
-
# Options include:
|
12
|
-
#
|
13
|
-
# command_prefix - prefix to put in front of any command, e.g. sudo
|
14
|
-
attr_reader :options
|
15
|
-
|
16
|
-
# Delete file
|
17
|
-
def delete_file(action_handler, path)
|
18
|
-
if file_exists?(path)
|
19
|
-
action_handler.perform_action "delete file #{escape(path)} on #{machine_spec.name}" do
|
20
|
-
transport.execute("Remove-Item #{escape(path)}").error!
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
def is_directory?(path)
|
26
|
-
parse_boolean(transport.execute("Test-Path #{escape(path)} -pathtype container", :read_only => true).stdout)
|
27
|
-
end
|
28
|
-
|
29
|
-
# Return true or false depending on whether file exists
|
30
|
-
def file_exists?(path)
|
31
|
-
parse_boolean(transport.execute("Test-Path #{escape(path)}", :read_only => true).stdout)
|
32
|
-
end
|
33
|
-
|
34
|
-
def files_different?(path, local_path, content=nil)
|
35
|
-
if !file_exists?(path) || (local_path && !File.exists?(local_path))
|
36
|
-
return true
|
37
|
-
end
|
38
|
-
|
39
|
-
# Get remote checksum of file (from http://stackoverflow.com/a/13926809)
|
40
|
-
result = transport.execute(<<-EOM, :read_only => true)
|
41
|
-
$md5 = [System.Security.Cryptography.MD5]::Create("MD5")
|
42
|
-
$fd = [System.IO.File]::OpenRead(#{path.inspect})
|
43
|
-
$buf = new-object byte[] (1024*1024*8) # 8mb buffer
|
44
|
-
while (($read_len = $fd.Read($buf,0,$buf.length)) -eq $buf.length){
|
45
|
-
$total += $buf.length
|
46
|
-
$md5.TransformBlock($buf,$offset,$buf.length,$buf,$offset)
|
47
|
-
}
|
48
|
-
# finalize the last read
|
49
|
-
$md5.TransformFinalBlock($buf,0,$read_len)
|
50
|
-
$hash = $md5.Hash
|
51
|
-
# convert hash bytes to hex formatted string
|
52
|
-
$hash | foreach { $hash_txt += $_.ToString("x2") }
|
53
|
-
$hash_txt
|
54
|
-
EOM
|
55
|
-
result.error!
|
56
|
-
remote_sum = result.stdout.split(' ')[0]
|
57
|
-
digest = Digest::SHA256.new
|
58
|
-
if content
|
59
|
-
digest.update(content)
|
60
|
-
else
|
61
|
-
File.open(local_path, 'rb') do |io|
|
62
|
-
while (buf = io.read(4096)) && buf.length > 0
|
63
|
-
digest.update(buf)
|
64
|
-
end
|
65
|
-
end
|
66
|
-
end
|
67
|
-
remote_sum != digest.hexdigest
|
68
|
-
end
|
69
|
-
|
70
|
-
def create_dir(action_handler, path)
|
71
|
-
if !file_exists?(path)
|
72
|
-
action_handler.perform_action "create directory #{path} on #{machine_spec.name}" do
|
73
|
-
transport.execute("New-Item #{escape(path)} -Type directory")
|
74
|
-
end
|
75
|
-
end
|
76
|
-
end
|
77
|
-
|
78
|
-
def system_drive
|
79
|
-
transport.execute('$env:SystemDrive').stdout.strip
|
80
|
-
end
|
81
|
-
|
82
|
-
# Set file attributes { :owner, :group, :rights }
|
83
|
-
# def set_attributes(action_handler, path, attributes)
|
84
|
-
# end
|
85
|
-
|
86
|
-
# Get file attributes { :owner, :group, :rights }
|
87
|
-
# def get_attributes(path)
|
88
|
-
# end
|
89
|
-
|
90
|
-
def dirname_on_machine(path)
|
91
|
-
path.split(/[\\\/]/)[0..-2].join('\\')
|
92
|
-
end
|
93
|
-
|
94
|
-
def escape(string)
|
95
|
-
transport.escape(string)
|
96
|
-
end
|
97
|
-
|
98
|
-
def parse_boolean(string)
|
99
|
-
if string =~ /^\s*true\s*$/mi
|
100
|
-
true
|
101
|
-
else
|
102
|
-
false
|
103
|
-
end
|
104
|
-
end
|
105
|
-
end
|
106
|
-
end
|
107
|
-
end
|
108
|
-
end
|
1
|
+
require 'chef/provisioning/machine/basic_machine'
|
2
|
+
|
3
|
+
class Chef
|
4
|
+
module Provisioning
|
5
|
+
class Machine
|
6
|
+
class WindowsMachine < BasicMachine
|
7
|
+
def initialize(machine_spec, transport, convergence_strategy)
|
8
|
+
super
|
9
|
+
end
|
10
|
+
|
11
|
+
# Options include:
|
12
|
+
#
|
13
|
+
# command_prefix - prefix to put in front of any command, e.g. sudo
|
14
|
+
attr_reader :options
|
15
|
+
|
16
|
+
# Delete file
|
17
|
+
def delete_file(action_handler, path)
|
18
|
+
if file_exists?(path)
|
19
|
+
action_handler.perform_action "delete file #{escape(path)} on #{machine_spec.name}" do
|
20
|
+
transport.execute("Remove-Item #{escape(path)}").error!
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def is_directory?(path)
|
26
|
+
parse_boolean(transport.execute("Test-Path #{escape(path)} -pathtype container", :read_only => true).stdout)
|
27
|
+
end
|
28
|
+
|
29
|
+
# Return true or false depending on whether file exists
|
30
|
+
def file_exists?(path)
|
31
|
+
parse_boolean(transport.execute("Test-Path #{escape(path)}", :read_only => true).stdout)
|
32
|
+
end
|
33
|
+
|
34
|
+
def files_different?(path, local_path, content=nil)
|
35
|
+
if !file_exists?(path) || (local_path && !File.exists?(local_path))
|
36
|
+
return true
|
37
|
+
end
|
38
|
+
|
39
|
+
# Get remote checksum of file (from http://stackoverflow.com/a/13926809)
|
40
|
+
result = transport.execute(<<-EOM, :read_only => true)
|
41
|
+
$md5 = [System.Security.Cryptography.MD5]::Create("MD5")
|
42
|
+
$fd = [System.IO.File]::OpenRead(#{path.inspect})
|
43
|
+
$buf = new-object byte[] (1024*1024*8) # 8mb buffer
|
44
|
+
while (($read_len = $fd.Read($buf,0,$buf.length)) -eq $buf.length){
|
45
|
+
$total += $buf.length
|
46
|
+
$md5.TransformBlock($buf,$offset,$buf.length,$buf,$offset)
|
47
|
+
}
|
48
|
+
# finalize the last read
|
49
|
+
$md5.TransformFinalBlock($buf,0,$read_len)
|
50
|
+
$hash = $md5.Hash
|
51
|
+
# convert hash bytes to hex formatted string
|
52
|
+
$hash | foreach { $hash_txt += $_.ToString("x2") }
|
53
|
+
$hash_txt
|
54
|
+
EOM
|
55
|
+
result.error!
|
56
|
+
remote_sum = result.stdout.split(' ')[0]
|
57
|
+
digest = Digest::SHA256.new
|
58
|
+
if content
|
59
|
+
digest.update(content)
|
60
|
+
else
|
61
|
+
File.open(local_path, 'rb') do |io|
|
62
|
+
while (buf = io.read(4096)) && buf.length > 0
|
63
|
+
digest.update(buf)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
remote_sum != digest.hexdigest
|
68
|
+
end
|
69
|
+
|
70
|
+
def create_dir(action_handler, path)
|
71
|
+
if !file_exists?(path)
|
72
|
+
action_handler.perform_action "create directory #{path} on #{machine_spec.name}" do
|
73
|
+
transport.execute("New-Item #{escape(path)} -Type directory")
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def system_drive
|
79
|
+
transport.execute('$env:SystemDrive').stdout.strip
|
80
|
+
end
|
81
|
+
|
82
|
+
# Set file attributes { :owner, :group, :rights }
|
83
|
+
# def set_attributes(action_handler, path, attributes)
|
84
|
+
# end
|
85
|
+
|
86
|
+
# Get file attributes { :owner, :group, :rights }
|
87
|
+
# def get_attributes(path)
|
88
|
+
# end
|
89
|
+
|
90
|
+
def dirname_on_machine(path)
|
91
|
+
path.split(/[\\\/]/)[0..-2].join('\\')
|
92
|
+
end
|
93
|
+
|
94
|
+
def escape(string)
|
95
|
+
transport.escape(string)
|
96
|
+
end
|
97
|
+
|
98
|
+
def parse_boolean(string)
|
99
|
+
if string =~ /^\s*true\s*$/mi
|
100
|
+
true
|
101
|
+
else
|
102
|
+
false
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
@@ -1,34 +1,34 @@
|
|
1
|
-
require 'chef/provisioning/managed_entry'
|
2
|
-
|
3
|
-
class Chef
|
4
|
-
module Provisioning
|
5
|
-
#
|
6
|
-
# Specification for a image. Sufficient information to find and contact it
|
7
|
-
# after it has been set up.
|
8
|
-
#
|
9
|
-
class MachineImageSpec < ManagedEntry
|
10
|
-
alias :location :reference
|
11
|
-
alias :location= :reference=
|
12
|
-
|
13
|
-
def from_image
|
14
|
-
data['from_image']
|
15
|
-
end
|
16
|
-
def from_image=(value)
|
17
|
-
data['from_image'] = value
|
18
|
-
end
|
19
|
-
def run_list
|
20
|
-
data['run_list']
|
21
|
-
end
|
22
|
-
def run_list=(value)
|
23
|
-
data['run_list'] = value
|
24
|
-
end
|
25
|
-
def machine_options
|
26
|
-
@machine_options
|
27
|
-
end
|
28
|
-
def machine_options=(value)
|
29
|
-
Chef::Log.warn("Machine options are no longer stored in machine_image_spec. Drivers that store machine_options will stop working with Provisioning 1.0.")
|
30
|
-
@machine_options = value
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
1
|
+
require 'chef/provisioning/managed_entry'
|
2
|
+
|
3
|
+
class Chef
|
4
|
+
module Provisioning
|
5
|
+
#
|
6
|
+
# Specification for a image. Sufficient information to find and contact it
|
7
|
+
# after it has been set up.
|
8
|
+
#
|
9
|
+
class MachineImageSpec < ManagedEntry
|
10
|
+
alias :location :reference
|
11
|
+
alias :location= :reference=
|
12
|
+
|
13
|
+
def from_image
|
14
|
+
data['from_image']
|
15
|
+
end
|
16
|
+
def from_image=(value)
|
17
|
+
data['from_image'] = value
|
18
|
+
end
|
19
|
+
def run_list
|
20
|
+
data['run_list']
|
21
|
+
end
|
22
|
+
def run_list=(value)
|
23
|
+
data['run_list'] = value
|
24
|
+
end
|
25
|
+
def machine_options
|
26
|
+
@machine_options
|
27
|
+
end
|
28
|
+
def machine_options=(value)
|
29
|
+
Chef::Log.warn("Machine options are no longer stored in machine_image_spec. Drivers that store machine_options will stop working with Provisioning 1.0.")
|
30
|
+
@machine_options = value
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -1,58 +1,58 @@
|
|
1
|
-
require 'chef/provisioning/managed_entry'
|
2
|
-
|
3
|
-
class Chef
|
4
|
-
module Provisioning
|
5
|
-
#
|
6
|
-
# Specification for a machine. Sufficient information to find and contact it
|
7
|
-
# after it has been set up.
|
8
|
-
#
|
9
|
-
class MachineSpec < ManagedEntry
|
10
|
-
def initialize(*args)
|
11
|
-
super
|
12
|
-
data['name'] ||= name
|
13
|
-
# Upgrade from metal to chef_provisioning ASAP.
|
14
|
-
if data['normal'] && !data['normal']['chef_provisioning'] && data['normal']['metal']
|
15
|
-
data['normal']['chef_provisioning'] = data['normal'].delete('metal')
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
alias :node :data
|
20
|
-
|
21
|
-
def attrs
|
22
|
-
data['normal'] ||= {}
|
23
|
-
data['normal']['chef_provisioning'] ||= {}
|
24
|
-
end
|
25
|
-
|
26
|
-
#
|
27
|
-
# Location of this machine. This should be a freeform hash, with enough
|
28
|
-
# information for the driver to look it up and create a Machine object to
|
29
|
-
# access it.
|
30
|
-
#
|
31
|
-
# This MUST include a 'driver_url' attribute with the driver's URL in it.
|
32
|
-
#
|
33
|
-
# chef-provisioning will do its darnedest to not lose this information.
|
34
|
-
#
|
35
|
-
def reference
|
36
|
-
attrs['reference'] || attrs['location']
|
37
|
-
end
|
38
|
-
|
39
|
-
#
|
40
|
-
# Set the location for this machine.
|
41
|
-
#
|
42
|
-
def reference=(value)
|
43
|
-
attrs.delete('location')
|
44
|
-
attrs['reference'] = value
|
45
|
-
end
|
46
|
-
|
47
|
-
alias :location :reference
|
48
|
-
alias :location= :reference=
|
49
|
-
|
50
|
-
def from_image
|
51
|
-
attrs['from_image']
|
52
|
-
end
|
53
|
-
def from_image=(value)
|
54
|
-
attrs['from_image'] = value
|
55
|
-
end
|
56
|
-
end
|
57
|
-
end
|
58
|
-
end
|
1
|
+
require 'chef/provisioning/managed_entry'
|
2
|
+
|
3
|
+
class Chef
|
4
|
+
module Provisioning
|
5
|
+
#
|
6
|
+
# Specification for a machine. Sufficient information to find and contact it
|
7
|
+
# after it has been set up.
|
8
|
+
#
|
9
|
+
class MachineSpec < ManagedEntry
|
10
|
+
def initialize(*args)
|
11
|
+
super
|
12
|
+
data['name'] ||= name
|
13
|
+
# Upgrade from metal to chef_provisioning ASAP.
|
14
|
+
if data['normal'] && !data['normal']['chef_provisioning'] && data['normal']['metal']
|
15
|
+
data['normal']['chef_provisioning'] = data['normal'].delete('metal')
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
alias :node :data
|
20
|
+
|
21
|
+
def attrs
|
22
|
+
data['normal'] ||= {}
|
23
|
+
data['normal']['chef_provisioning'] ||= {}
|
24
|
+
end
|
25
|
+
|
26
|
+
#
|
27
|
+
# Location of this machine. This should be a freeform hash, with enough
|
28
|
+
# information for the driver to look it up and create a Machine object to
|
29
|
+
# access it.
|
30
|
+
#
|
31
|
+
# This MUST include a 'driver_url' attribute with the driver's URL in it.
|
32
|
+
#
|
33
|
+
# chef-provisioning will do its darnedest to not lose this information.
|
34
|
+
#
|
35
|
+
def reference
|
36
|
+
attrs['reference'] || attrs['location']
|
37
|
+
end
|
38
|
+
|
39
|
+
#
|
40
|
+
# Set the location for this machine.
|
41
|
+
#
|
42
|
+
def reference=(value)
|
43
|
+
attrs.delete('location')
|
44
|
+
attrs['reference'] = value
|
45
|
+
end
|
46
|
+
|
47
|
+
alias :location :reference
|
48
|
+
alias :location= :reference=
|
49
|
+
|
50
|
+
def from_image
|
51
|
+
attrs['from_image']
|
52
|
+
end
|
53
|
+
def from_image=(value)
|
54
|
+
attrs['from_image'] = value
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -1,121 +1,121 @@
|
|
1
|
-
class Chef
|
2
|
-
module Provisioning
|
3
|
-
#
|
4
|
-
# Specification for a managed thing. Remembers where it was stored, and lets
|
5
|
-
# you stuff reference data in it.
|
6
|
-
#
|
7
|
-
class ManagedEntry
|
8
|
-
def initialize(managed_entry_store, resource_type, name, data=nil)
|
9
|
-
@managed_entry_store = managed_entry_store
|
10
|
-
@resource_type = resource_type
|
11
|
-
@name = name
|
12
|
-
@data = data || {}
|
13
|
-
end
|
14
|
-
|
15
|
-
attr_reader :managed_entry_store
|
16
|
-
attr_reader :resource_type
|
17
|
-
attr_reader :name
|
18
|
-
attr_reader :data
|
19
|
-
|
20
|
-
def attrs
|
21
|
-
data
|
22
|
-
end
|
23
|
-
|
24
|
-
#
|
25
|
-
# Globally unique identifier for this machine. Does not depend on the machine's
|
26
|
-
# reference or existence.
|
27
|
-
#
|
28
|
-
def id
|
29
|
-
managed_entry_store.identifier(resource_type, name)
|
30
|
-
end
|
31
|
-
|
32
|
-
#
|
33
|
-
# Reference to this managed thing. This should be a freeform hash, with enough
|
34
|
-
# information for the driver to look it up and create a Machine object to
|
35
|
-
# access it.
|
36
|
-
#
|
37
|
-
# This MUST include a 'driver_url' attribute with the driver's URL in it.
|
38
|
-
#
|
39
|
-
# chef-provisioning will do its darnedest to not lose this information.
|
40
|
-
#
|
41
|
-
def reference
|
42
|
-
# Backcompat: old data bags didn't have the "reference" field. If we have
|
43
|
-
# no reference field in the data, and the data bag is non-empty, return
|
44
|
-
# the root of the data bag.
|
45
|
-
attrs['reference'] || attrs['location'] || (attrs == {} ? nil : attrs)
|
46
|
-
end
|
47
|
-
|
48
|
-
#
|
49
|
-
# Set the reference for this machine.
|
50
|
-
#
|
51
|
-
def reference=(value)
|
52
|
-
self.attrs['reference'] = value
|
53
|
-
end
|
54
|
-
|
55
|
-
# URL to the driver.
|
56
|
-
def driver_url
|
57
|
-
attrs['driver_url'] || (reference ? reference['driver_url'] : nil)
|
58
|
-
end
|
59
|
-
def driver_url=(value)
|
60
|
-
attrs['driver_url'] = value
|
61
|
-
end
|
62
|
-
|
63
|
-
#
|
64
|
-
# Save this node to the server. If you have significant information that
|
65
|
-
# could be lost, you should do this as quickly as possible. Data will be
|
66
|
-
# saved automatically for you after allocate_machine and ready_machine.
|
67
|
-
#
|
68
|
-
def save(action_handler)
|
69
|
-
managed_entry_store.save_data(resource_type, name, data, action_handler)
|
70
|
-
end
|
71
|
-
|
72
|
-
def delete(action_handler)
|
73
|
-
managed_entry_store.delete_data(resource_type, name, action_handler)
|
74
|
-
end
|
75
|
-
|
76
|
-
|
77
|
-
#
|
78
|
-
# Subclass interface
|
79
|
-
#
|
80
|
-
|
81
|
-
#
|
82
|
-
# Get the given data
|
83
|
-
#
|
84
|
-
# @param resource_type [Symbol] The type of thing to retrieve (:machine, :machine_image, :load_balancer, :aws_vpc, :aws_subnet, ...)
|
85
|
-
# @param name [String] The unique identifier of the thing to retrieve
|
86
|
-
#
|
87
|
-
# @return [Hash,Array] The data, or `nil` if the data does not exist. Will be JSON- and YAML-compatible (Hash, Array, String, Integer, Boolean, Nil)
|
88
|
-
#
|
89
|
-
def get_data(resource_type, name)
|
90
|
-
raise NotImplementedError, :delete_data
|
91
|
-
end
|
92
|
-
|
93
|
-
#
|
94
|
-
# Save the given data
|
95
|
-
#
|
96
|
-
# @param resource_type [Symbol] The type of thing to save (:machine, :machine_image, :load_balancer, :aws_vpc, :aws_subnet ...)
|
97
|
-
# @param name [String] The unique identifier of the thing to save
|
98
|
-
# @param data [Hash,Array] The data to save. Must be JSON- and YAML-compatible (Hash, Array, String, Integer, Boolean, Nil)
|
99
|
-
#
|
100
|
-
def save_data(resource_type, name, data, action_handler)
|
101
|
-
raise NotImplementedError, :delete_data
|
102
|
-
end
|
103
|
-
|
104
|
-
#
|
105
|
-
# Delete the given data
|
106
|
-
#
|
107
|
-
# @param resource_type [Symbol] The type of thing to delete (:machine, :machine_image, :load_balancer, :aws_vpc, :aws_subnet, ...)
|
108
|
-
# @param name [String] The unique identifier of the thing to delete
|
109
|
-
#
|
110
|
-
# @return [Boolean] Whether anything was deleted or not.
|
111
|
-
#
|
112
|
-
def delete_data(resource_type, name, action_handler)
|
113
|
-
raise NotImplementedError, :delete_data
|
114
|
-
end
|
115
|
-
|
116
|
-
def identifier(resource_type, name)
|
117
|
-
raise NotImplementedError, :identifier
|
118
|
-
end
|
119
|
-
end
|
120
|
-
end
|
121
|
-
end
|
1
|
+
class Chef
|
2
|
+
module Provisioning
|
3
|
+
#
|
4
|
+
# Specification for a managed thing. Remembers where it was stored, and lets
|
5
|
+
# you stuff reference data in it.
|
6
|
+
#
|
7
|
+
class ManagedEntry
|
8
|
+
def initialize(managed_entry_store, resource_type, name, data=nil)
|
9
|
+
@managed_entry_store = managed_entry_store
|
10
|
+
@resource_type = resource_type
|
11
|
+
@name = name
|
12
|
+
@data = data || {}
|
13
|
+
end
|
14
|
+
|
15
|
+
attr_reader :managed_entry_store
|
16
|
+
attr_reader :resource_type
|
17
|
+
attr_reader :name
|
18
|
+
attr_reader :data
|
19
|
+
|
20
|
+
def attrs
|
21
|
+
data
|
22
|
+
end
|
23
|
+
|
24
|
+
#
|
25
|
+
# Globally unique identifier for this machine. Does not depend on the machine's
|
26
|
+
# reference or existence.
|
27
|
+
#
|
28
|
+
def id
|
29
|
+
managed_entry_store.identifier(resource_type, name)
|
30
|
+
end
|
31
|
+
|
32
|
+
#
|
33
|
+
# Reference to this managed thing. This should be a freeform hash, with enough
|
34
|
+
# information for the driver to look it up and create a Machine object to
|
35
|
+
# access it.
|
36
|
+
#
|
37
|
+
# This MUST include a 'driver_url' attribute with the driver's URL in it.
|
38
|
+
#
|
39
|
+
# chef-provisioning will do its darnedest to not lose this information.
|
40
|
+
#
|
41
|
+
def reference
|
42
|
+
# Backcompat: old data bags didn't have the "reference" field. If we have
|
43
|
+
# no reference field in the data, and the data bag is non-empty, return
|
44
|
+
# the root of the data bag.
|
45
|
+
attrs['reference'] || attrs['location'] || (attrs == {} ? nil : attrs)
|
46
|
+
end
|
47
|
+
|
48
|
+
#
|
49
|
+
# Set the reference for this machine.
|
50
|
+
#
|
51
|
+
def reference=(value)
|
52
|
+
self.attrs['reference'] = value
|
53
|
+
end
|
54
|
+
|
55
|
+
# URL to the driver.
|
56
|
+
def driver_url
|
57
|
+
attrs['driver_url'] || (reference ? reference['driver_url'] : nil)
|
58
|
+
end
|
59
|
+
def driver_url=(value)
|
60
|
+
attrs['driver_url'] = value
|
61
|
+
end
|
62
|
+
|
63
|
+
#
|
64
|
+
# Save this node to the server. If you have significant information that
|
65
|
+
# could be lost, you should do this as quickly as possible. Data will be
|
66
|
+
# saved automatically for you after allocate_machine and ready_machine.
|
67
|
+
#
|
68
|
+
def save(action_handler)
|
69
|
+
managed_entry_store.save_data(resource_type, name, data, action_handler)
|
70
|
+
end
|
71
|
+
|
72
|
+
def delete(action_handler)
|
73
|
+
managed_entry_store.delete_data(resource_type, name, action_handler)
|
74
|
+
end
|
75
|
+
|
76
|
+
|
77
|
+
#
|
78
|
+
# Subclass interface
|
79
|
+
#
|
80
|
+
|
81
|
+
#
|
82
|
+
# Get the given data
|
83
|
+
#
|
84
|
+
# @param resource_type [Symbol] The type of thing to retrieve (:machine, :machine_image, :load_balancer, :aws_vpc, :aws_subnet, ...)
|
85
|
+
# @param name [String] The unique identifier of the thing to retrieve
|
86
|
+
#
|
87
|
+
# @return [Hash,Array] The data, or `nil` if the data does not exist. Will be JSON- and YAML-compatible (Hash, Array, String, Integer, Boolean, Nil)
|
88
|
+
#
|
89
|
+
def get_data(resource_type, name)
|
90
|
+
raise NotImplementedError, :delete_data
|
91
|
+
end
|
92
|
+
|
93
|
+
#
|
94
|
+
# Save the given data
|
95
|
+
#
|
96
|
+
# @param resource_type [Symbol] The type of thing to save (:machine, :machine_image, :load_balancer, :aws_vpc, :aws_subnet ...)
|
97
|
+
# @param name [String] The unique identifier of the thing to save
|
98
|
+
# @param data [Hash,Array] The data to save. Must be JSON- and YAML-compatible (Hash, Array, String, Integer, Boolean, Nil)
|
99
|
+
#
|
100
|
+
def save_data(resource_type, name, data, action_handler)
|
101
|
+
raise NotImplementedError, :delete_data
|
102
|
+
end
|
103
|
+
|
104
|
+
#
|
105
|
+
# Delete the given data
|
106
|
+
#
|
107
|
+
# @param resource_type [Symbol] The type of thing to delete (:machine, :machine_image, :load_balancer, :aws_vpc, :aws_subnet, ...)
|
108
|
+
# @param name [String] The unique identifier of the thing to delete
|
109
|
+
#
|
110
|
+
# @return [Boolean] Whether anything was deleted or not.
|
111
|
+
#
|
112
|
+
def delete_data(resource_type, name, action_handler)
|
113
|
+
raise NotImplementedError, :delete_data
|
114
|
+
end
|
115
|
+
|
116
|
+
def identifier(resource_type, name)
|
117
|
+
raise NotImplementedError, :identifier
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|