opendelivery 0.4.4 → 0.4.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +8 -8
- data/lib/opendelivery/domain.rb +45 -80
- data/lib/opendelivery.rb +0 -5
- metadata +13 -18
- data/lib/opendelivery/machine_image.rb +0 -78
- data/lib/opendelivery/source_control.rb +0 -101
- data/lib/opendelivery/stack.rb +0 -177
- data/lib/opendelivery/storage.rb +0 -74
- data/lib/opsworks.rb +0 -320
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
ZTgxZDRiNTAzYWFhNzE0ZDM1OGE3NGE1NDRjYjljYmE0OGUyYjZlYg==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
MTUxODE0YzQ4YjdjODgyZWNlNGE5Y2ZiNWFkNmVjMWEzY2YwYjUzNg==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
NmM4ZTdhNmZhNTcyYThjOWRkZjAyNjNhM2RhZjVmOTIxOWE2OTQyM2RmMDJh
|
10
|
+
OTRmMWJhMTJkZTQ5Y2M0NjU2MTg0MDY4ODkwY2M0NDc3NWE4ZTcxNjUyYWY4
|
11
|
+
MTIyMzdmNzNjOWMzMjZmNDg5Mjg5YWEyNzZhZWY1NjViN2ViYTY=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
Y2VmNTU0NWFmMDE1ZThjODEzODdlMzU0NmZjNWJiY2IyNDkzZTk3NmI5NDY4
|
14
|
+
ZDU3NzA3NWJkZWE3Mzk5ZDEwOTA1N2NiZjc3ZDQzYzJhYzQ5MDllYzZhNzBh
|
15
|
+
MTAwZmE4ZjI3MDdkZjIzZTFiNzI1ODg0NDliMTM5MWJjOGFhMjI=
|
data/lib/opendelivery/domain.rb
CHANGED
@@ -20,7 +20,7 @@
|
|
20
20
|
#OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
21
|
#THE SOFTWARE.
|
22
22
|
|
23
|
-
require 'aws-sdk'
|
23
|
+
require 'aws-sdk-core'
|
24
24
|
require 'encrypto_signo'
|
25
25
|
|
26
26
|
module OpenDelivery
|
@@ -30,108 +30,67 @@ module OpenDelivery
|
|
30
30
|
@key_path = File.read(key_path) unless key_path.nil?
|
31
31
|
|
32
32
|
if region.nil?
|
33
|
-
@sdb =
|
33
|
+
@sdb = Aws::SimpleDB::Client.new
|
34
34
|
else
|
35
|
-
@sdb =
|
35
|
+
@sdb = Aws::SimpleDB::Client.new(:region => region)
|
36
36
|
end
|
37
37
|
end
|
38
38
|
|
39
39
|
def create(domain)
|
40
|
-
|
41
|
-
@sdb.domains.create(domain)
|
42
|
-
end
|
40
|
+
@sdb.create_domain(domain_name: domain)
|
43
41
|
end
|
44
42
|
|
45
43
|
def destroy(domain)
|
46
|
-
|
47
|
-
@sdb.domains[domain].delete
|
48
|
-
end
|
44
|
+
@sdb.delete_domain(domain_name: domain)
|
49
45
|
end
|
50
46
|
|
51
47
|
def destroy_item(domain, item_name)
|
52
|
-
|
53
|
-
|
54
|
-
end
|
48
|
+
@sdb.delete_attributes(domain_name: domain,
|
49
|
+
item_name: item_name)
|
55
50
|
end
|
56
51
|
|
57
52
|
def load_stack_properties(domain, stack)
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
53
|
+
stack.resources.each do |resource|
|
54
|
+
set_property(domain,
|
55
|
+
stack.name,
|
56
|
+
resource.resource_type,
|
57
|
+
resource.physical_resource_id)
|
62
58
|
end
|
63
59
|
end
|
64
60
|
|
65
|
-
def get_encrypted_property(domain, item_name, key
|
66
|
-
value = get_property(domain, item_name, key
|
67
|
-
|
61
|
+
def get_encrypted_property(domain, item_name, key)
|
62
|
+
value = get_property(domain, item_name, key)
|
63
|
+
EncryptoSigno.decrypt(@key_path, value.chomp)
|
68
64
|
end
|
69
65
|
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
AWS::SimpleDB.consistent_reads do
|
77
|
-
item = @sdb.domains[domain].items[item_name]
|
78
|
-
if !item.nil?
|
79
|
-
item.attributes.each do |att|
|
80
|
-
col_name = nil
|
81
|
-
|
82
|
-
att_array = att.name.split('|')
|
83
|
-
col_title = att_array.first
|
84
|
-
|
85
|
-
if att_array.length > 1
|
86
|
-
col_name = att_array[1]
|
87
|
-
end
|
66
|
+
def get_property(domain, item_name, key)
|
67
|
+
get_attributes_response = @sdb.get_attributes(domain_name: domain,
|
68
|
+
item_name: item_name,
|
69
|
+
attribute_names: [key],
|
70
|
+
consistent_read: true)
|
88
71
|
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
if name.nil?
|
94
|
-
# Not given a name to search for, just return the first one
|
95
|
-
# we have found.
|
96
|
-
attribute = att
|
97
|
-
break
|
98
|
-
else
|
99
|
-
|
100
|
-
# Give a 'name' search criteria, so match it against this column
|
101
|
-
if name == col_name
|
102
|
-
# 'name' criteria matches "|name" value, found a match
|
103
|
-
attribute = att
|
104
|
-
break
|
105
|
-
else
|
106
|
-
# 'name' criteria did not match, keep searching
|
107
|
-
end
|
108
|
-
|
109
|
-
end
|
110
|
-
end
|
111
|
-
end
|
112
|
-
if !attribute.nil?
|
113
|
-
value = attribute.values[index]
|
114
|
-
if !value.nil?
|
115
|
-
property_value = value.chomp
|
116
|
-
end
|
117
|
-
end
|
118
|
-
end
|
72
|
+
if get_attributes_response.attributes.empty?
|
73
|
+
nil
|
74
|
+
else
|
75
|
+
get_attributes_response.attributes.first.value.chomp
|
119
76
|
end
|
120
|
-
return property_value
|
121
77
|
end
|
122
78
|
|
123
|
-
def set_encrypted_property(domain, item_name, key, value
|
79
|
+
def set_encrypted_property(domain, item_name, key, value)
|
124
80
|
encrypted_value = EncryptoSigno.encrypt(@key_path, value.chomp)
|
125
|
-
set_property(domain, item_name, key, encrypted_value
|
81
|
+
set_property(domain, item_name, key, encrypted_value)
|
126
82
|
end
|
127
83
|
|
128
|
-
def set_property(domain, item_name, key, value
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
84
|
+
def set_property(domain, item_name, key, value)
|
85
|
+
@sdb.put_attributes(domain_name: domain,
|
86
|
+
item_name: item_name,
|
87
|
+
attributes: [
|
88
|
+
{
|
89
|
+
name: key,
|
90
|
+
value: value,
|
91
|
+
replace: true,
|
92
|
+
}
|
93
|
+
])
|
135
94
|
end
|
136
95
|
|
137
96
|
def load_domain(domain, json_file)
|
@@ -140,9 +99,15 @@ module OpenDelivery
|
|
140
99
|
|
141
100
|
obj.each do |item, attributes|
|
142
101
|
attributes.each do |key,value|
|
143
|
-
|
144
|
-
|
145
|
-
|
102
|
+
@sdb.put_attributes(domain_name: domain,
|
103
|
+
item_name: item,
|
104
|
+
attributes: [
|
105
|
+
{
|
106
|
+
name: key,
|
107
|
+
value: value,
|
108
|
+
replace: true,
|
109
|
+
}
|
110
|
+
])
|
146
111
|
end
|
147
112
|
end
|
148
113
|
end
|
data/lib/opendelivery.rb
CHANGED
@@ -20,12 +20,7 @@
|
|
20
20
|
#OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
21
|
#THE SOFTWARE.
|
22
22
|
|
23
|
-
require 'opendelivery/source_control.rb'
|
24
23
|
require 'opendelivery/domain.rb'
|
25
|
-
require 'opendelivery/machine_image.rb'
|
26
|
-
require 'opendelivery/stack.rb'
|
27
|
-
require 'opendelivery/storage.rb'
|
28
|
-
|
29
24
|
|
30
25
|
module OpenDelivery
|
31
26
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: opendelivery
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.
|
4
|
+
version: 0.4.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Brian Jakovich
|
@@ -83,33 +83,33 @@ dependencies:
|
|
83
83
|
- !ruby/object:Gem::Version
|
84
84
|
version: 2.9.0
|
85
85
|
- !ruby/object:Gem::Dependency
|
86
|
-
name:
|
86
|
+
name: aws-sdk
|
87
87
|
requirement: !ruby/object:Gem::Requirement
|
88
88
|
requirements:
|
89
|
-
- -
|
89
|
+
- - ~>
|
90
90
|
- !ruby/object:Gem::Version
|
91
|
-
version: 1.0
|
92
|
-
type: :
|
91
|
+
version: '1.0'
|
92
|
+
type: :development
|
93
93
|
prerelease: false
|
94
94
|
version_requirements: !ruby/object:Gem::Requirement
|
95
95
|
requirements:
|
96
|
-
- -
|
96
|
+
- - ~>
|
97
97
|
- !ruby/object:Gem::Version
|
98
|
-
version: 1.0
|
98
|
+
version: '1.0'
|
99
99
|
- !ruby/object:Gem::Dependency
|
100
|
-
name:
|
100
|
+
name: encrypto_signo
|
101
101
|
requirement: !ruby/object:Gem::Requirement
|
102
102
|
requirements:
|
103
|
-
- -
|
103
|
+
- - '='
|
104
104
|
- !ruby/object:Gem::Version
|
105
|
-
version:
|
105
|
+
version: 1.0.0
|
106
106
|
type: :runtime
|
107
107
|
prerelease: false
|
108
108
|
version_requirements: !ruby/object:Gem::Requirement
|
109
109
|
requirements:
|
110
|
-
- -
|
110
|
+
- - '='
|
111
111
|
- !ruby/object:Gem::Version
|
112
|
-
version:
|
112
|
+
version: 1.0.0
|
113
113
|
- !ruby/object:Gem::Dependency
|
114
114
|
name: aws-sdk-core
|
115
115
|
requirement: !ruby/object:Gem::Requirement
|
@@ -146,11 +146,6 @@ extra_rdoc_files: []
|
|
146
146
|
files:
|
147
147
|
- lib/opendelivery.rb
|
148
148
|
- lib/opendelivery/domain.rb
|
149
|
-
- lib/opendelivery/machine_image.rb
|
150
|
-
- lib/opendelivery/source_control.rb
|
151
|
-
- lib/opendelivery/stack.rb
|
152
|
-
- lib/opendelivery/storage.rb
|
153
|
-
- lib/opsworks.rb
|
154
149
|
homepage: http://stelligent.com
|
155
150
|
licenses:
|
156
151
|
- MIT
|
@@ -164,7 +159,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
164
159
|
requirements:
|
165
160
|
- - ! '>='
|
166
161
|
- !ruby/object:Gem::Version
|
167
|
-
version:
|
162
|
+
version: 2.0.0
|
168
163
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
169
164
|
requirements:
|
170
165
|
- - ! '>='
|
@@ -1,78 +0,0 @@
|
|
1
|
-
#Copyright (c) 2014 Stelligent Systems LLC
|
2
|
-
#
|
3
|
-
#MIT LICENSE
|
4
|
-
#
|
5
|
-
#Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
-
#of this software and associated documentation files (the "Software"), to deal
|
7
|
-
#in the Software without restriction, including without limitation the rights
|
8
|
-
#to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
-
#copies of the Software, and to permit persons to whom the Software is
|
10
|
-
#furnished to do so, subject to the following conditions:
|
11
|
-
#
|
12
|
-
#The above copyright notice and this permission notice shall be included in
|
13
|
-
#all copies or substantial portions of the Software.
|
14
|
-
#
|
15
|
-
#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
-
#IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
-
#FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
-
#AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
-
#LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
-
#OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
-
#THE SOFTWARE.
|
22
|
-
|
23
|
-
require 'aws-sdk'
|
24
|
-
|
25
|
-
module OpenDelivery
|
26
|
-
class MachineImage
|
27
|
-
|
28
|
-
def initialize(region=nil)
|
29
|
-
if region.nil?
|
30
|
-
@ec2 = AWS::EC2.new
|
31
|
-
@sdb = AWS::SimpleDB.new
|
32
|
-
@auto_scale = AWS::AutoScaling.new
|
33
|
-
@domain = OpenDelivery::Domain.new
|
34
|
-
else
|
35
|
-
@ec2 = AWS::EC2.new(:region => region)
|
36
|
-
@sdb = AWS::SimpleDB.new(:region => region)
|
37
|
-
@auto_scale = AWS::AutoScaling.new(:region => region)
|
38
|
-
@domain = OpenDelivery::Domain.new(:region => region)
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
def create(domain, stack_name)
|
43
|
-
instance_id = prep_instance(domain, stack_name)
|
44
|
-
image = @ec2.images.create(
|
45
|
-
instance_id: instance_id,
|
46
|
-
name: image_name)
|
47
|
-
|
48
|
-
wait_for_image(image)
|
49
|
-
end
|
50
|
-
|
51
|
-
protected
|
52
|
-
|
53
|
-
def wait_for_image(image)
|
54
|
-
# Waiting for AWS to realize the image is ready to start
|
55
|
-
sleep 10
|
56
|
-
|
57
|
-
while image.state != :available
|
58
|
-
sleep 10
|
59
|
-
case image.state
|
60
|
-
when :failed
|
61
|
-
image.delete
|
62
|
-
raise RuntimeError, 'Image Creation Failed'
|
63
|
-
end
|
64
|
-
end
|
65
|
-
end
|
66
|
-
|
67
|
-
def prep_instance(domain, stack_name)
|
68
|
-
group_name = @domain.get_property(domain, stack_name, "AWS::AutoScaling::AutoScalingGroup")
|
69
|
-
instance = @auto_scale.groups[group_name].auto_scaling_instances.first.id
|
70
|
-
@ec2.instances[instance].stop
|
71
|
-
|
72
|
-
while @ec2.instances[instance].status != :stopped
|
73
|
-
sleep 10
|
74
|
-
end
|
75
|
-
return instance
|
76
|
-
end
|
77
|
-
end
|
78
|
-
end
|
@@ -1,101 +0,0 @@
|
|
1
|
-
#Copyright (c) 2014 Stelligent Systems LLC
|
2
|
-
#
|
3
|
-
#MIT LICENSE
|
4
|
-
#
|
5
|
-
#Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
-
#of this software and associated documentation files (the "Software"), to deal
|
7
|
-
#in the Software without restriction, including without limitation the rights
|
8
|
-
#to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
-
#copies of the Software, and to permit persons to whom the Software is
|
10
|
-
#furnished to do so, subject to the following conditions:
|
11
|
-
#
|
12
|
-
#The above copyright notice and this permission notice shall be included in
|
13
|
-
#all copies or substantial portions of the Software.
|
14
|
-
#
|
15
|
-
#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
-
#IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
-
#FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
-
#AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
-
#LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
-
#OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
-
#THE SOFTWARE.
|
22
|
-
|
23
|
-
module OpenDelivery
|
24
|
-
class SourceControl
|
25
|
-
def initialize(dir)
|
26
|
-
@dir = dir
|
27
|
-
end
|
28
|
-
|
29
|
-
def log(lines=10)
|
30
|
-
Dir.chdir(@dir) do
|
31
|
-
`git log --stat -n #{lines}`
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
def status
|
36
|
-
Dir.chdir(@dir) do
|
37
|
-
`git status -sb`
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
def remove_missing_files(status)
|
42
|
-
removed_files = []
|
43
|
-
files = find_removed_files(status)
|
44
|
-
files.each do |file|
|
45
|
-
Dir.chdir(@dir) do
|
46
|
-
removed_files << `git rm -rf #{file}`
|
47
|
-
end
|
48
|
-
end
|
49
|
-
removed_files
|
50
|
-
end
|
51
|
-
|
52
|
-
def add(files)
|
53
|
-
Dir.chdir(@dir) do
|
54
|
-
`git add #{files} -v`
|
55
|
-
end
|
56
|
-
end
|
57
|
-
|
58
|
-
def commit(message)
|
59
|
-
Dir.chdir(@dir) do
|
60
|
-
`git commit -m "#{message}"`
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
|
-
def push
|
65
|
-
Dir.chdir(@dir) do
|
66
|
-
`git push`
|
67
|
-
end
|
68
|
-
end
|
69
|
-
|
70
|
-
def pull
|
71
|
-
Dir.chdir(@dir) do
|
72
|
-
@result = `git pull`
|
73
|
-
end
|
74
|
-
if $?.to_i != 0
|
75
|
-
raise "Your pull failed. Probably because of a merge conflict!"
|
76
|
-
end
|
77
|
-
@result
|
78
|
-
end
|
79
|
-
|
80
|
-
def conflicted(status)
|
81
|
-
status.each_line do |stat|
|
82
|
-
if stat.match(/^UU /) || stat.match(/^U /) || stat.match(/^U /)
|
83
|
-
raise "You have file conflicts when trying to merge. Because this could end up horribly, we won't try to automatically fix these conflicts. Please go an manually merge the files!"
|
84
|
-
end
|
85
|
-
end
|
86
|
-
end
|
87
|
-
|
88
|
-
protected
|
89
|
-
|
90
|
-
|
91
|
-
def find_removed_files(status)
|
92
|
-
statuses = []
|
93
|
-
status.each_line do |stat|
|
94
|
-
if stat.match(/^ D /)
|
95
|
-
statuses << stat.split[1]
|
96
|
-
end
|
97
|
-
end
|
98
|
-
statuses
|
99
|
-
end
|
100
|
-
end
|
101
|
-
end
|
data/lib/opendelivery/stack.rb
DELETED
@@ -1,177 +0,0 @@
|
|
1
|
-
#Copyright (c) 2014 Stelligent Systems LLC
|
2
|
-
#
|
3
|
-
#MIT LICENSE
|
4
|
-
#
|
5
|
-
#Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
-
#of this software and associated documentation files (the "Software"), to deal
|
7
|
-
#in the Software without restriction, including without limitation the rights
|
8
|
-
#to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
-
#copies of the Software, and to permit persons to whom the Software is
|
10
|
-
#furnished to do so, subject to the following conditions:
|
11
|
-
#
|
12
|
-
#The above copyright notice and this permission notice shall be included in
|
13
|
-
#all copies or substantial portions of the Software.
|
14
|
-
#
|
15
|
-
#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
-
#IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
-
#FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
-
#AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
-
#LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
-
#OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
-
#THE SOFTWARE.
|
22
|
-
|
23
|
-
require 'aws-sdk'
|
24
|
-
|
25
|
-
module OpenDelivery
|
26
|
-
class Stack
|
27
|
-
|
28
|
-
def initialize(region=nil)
|
29
|
-
if region.nil?
|
30
|
-
@cfn = AWS::CloudFormation.new
|
31
|
-
@autoscaling = AWS::AutoScaling.new
|
32
|
-
else
|
33
|
-
@autoscaling = AWS::AutoScaling.new(:region => region)
|
34
|
-
@cfn = AWS::CloudFormation.new(:region => region)
|
35
|
-
end
|
36
|
-
@domain = OpenDelivery::Domain.new(region)
|
37
|
-
end
|
38
|
-
|
39
|
-
|
40
|
-
SUCCESS_STATUSES = [ "CREATE_COMPLETE",
|
41
|
-
"UPDATE_COMPLETE" ]
|
42
|
-
|
43
|
-
FAILURE_STATUSES = [ "CREATE_FAILED",
|
44
|
-
"ROLLBACK_FAILED",
|
45
|
-
"ROLLBACK_COMPLETE",
|
46
|
-
"DELETE_FAILED",
|
47
|
-
"UPDATE_ROLLBACK_FAILED",
|
48
|
-
"UPDATE_ROLLBACK_COMPLETE",
|
49
|
-
"DELETE_COMPLETE" ]
|
50
|
-
|
51
|
-
PROGRESS_STATUSES = [ "CREATE_IN_PROGRESS",
|
52
|
-
"ROLLBACK_IN_PROGRESS",
|
53
|
-
"DELETE_IN_PROGRESS",
|
54
|
-
"UPDATE_IN_PROGRESS",
|
55
|
-
"UPDATE_COMPLETE_CLEANUP_IN_PROGRESS",
|
56
|
-
"UPDATE_ROLLBACK_IN_PROGRESS",
|
57
|
-
"UPDATE_ROLLBACK_COMPLETE_CLEANUP_IN_PROGRESS" ]
|
58
|
-
|
59
|
-
def watch(stack_name, sleep_time, silent=false)
|
60
|
-
success = false
|
61
|
-
begin
|
62
|
-
stack = @cfn.stacks[stack_name]
|
63
|
-
success = watch_loop(stack, sleep_time, silent)
|
64
|
-
rescue AWS::CloudFormation::Errors::ValidationError => msg
|
65
|
-
print_status "Exception raised: #{msg}"
|
66
|
-
success = false
|
67
|
-
end
|
68
|
-
return success
|
69
|
-
end
|
70
|
-
|
71
|
-
|
72
|
-
def create(stack_name, template, parameters = {}, wait=false, domain=nil, tags = {})
|
73
|
-
@cfn.stacks.create(stack_name,
|
74
|
-
File.open(template, "r").read,
|
75
|
-
:parameters => parameters,
|
76
|
-
:tags => tags,
|
77
|
-
:capabilities => ["CAPABILITY_IAM"],
|
78
|
-
:disable_rollback => true)
|
79
|
-
end
|
80
|
-
|
81
|
-
def destroy(stack_name, domain=nil, wait=false)
|
82
|
-
stack = @cfn.stacks[stack_name]
|
83
|
-
if stack.exists?
|
84
|
-
resume_scaling_activities(stack_name)
|
85
|
-
stack.delete
|
86
|
-
while wait and stack.exists?
|
87
|
-
sleep 20
|
88
|
-
end
|
89
|
-
@domain.destroy_item(domain, stack_name)
|
90
|
-
else
|
91
|
-
raise "Stack: #{stack_name} doesn't exist, therefore it cannot be destroyed"
|
92
|
-
end
|
93
|
-
end
|
94
|
-
|
95
|
-
def list
|
96
|
-
@cfn.stacks.each do |stack|
|
97
|
-
puts "Stack Name: #{stack.name} | Status: #{stack.status}"
|
98
|
-
end
|
99
|
-
end
|
100
|
-
|
101
|
-
def resume_scaling_activities(stack_name)
|
102
|
-
stack = @cfn.stacks[stack_name]
|
103
|
-
stack.resources.each do |resource|
|
104
|
-
if resource.resource_type == "AWS::AutoScaling::AutoScalingGroup"
|
105
|
-
begin
|
106
|
-
@autoscaling.groups[resource.physical_resource_id].resume_all_processes
|
107
|
-
rescue Exception => e
|
108
|
-
puts "ASG operation failed with [#{e.message}]"
|
109
|
-
end
|
110
|
-
end
|
111
|
-
end
|
112
|
-
end
|
113
|
-
|
114
|
-
protected
|
115
|
-
|
116
|
-
def wait_for_stack(stack, wait)
|
117
|
-
if wait
|
118
|
-
while stack.status != "CREATE_COMPLETE"
|
119
|
-
sleep 20
|
120
|
-
|
121
|
-
if FAILURE_STATUSES.include? stack.status
|
122
|
-
stack.delete
|
123
|
-
end
|
124
|
-
end
|
125
|
-
end
|
126
|
-
end
|
127
|
-
|
128
|
-
def print_status(status, silent=false)
|
129
|
-
timestamp = Time.now.strftime("%Y.%m.%d %H:%M:%S:%L")
|
130
|
-
unless silent
|
131
|
-
puts "#{timestamp}: #{status}"
|
132
|
-
end
|
133
|
-
end
|
134
|
-
|
135
|
-
def watch_loop(stack, sleep_time, silent)
|
136
|
-
keep_watching = true
|
137
|
-
success = false
|
138
|
-
abort_count = 10
|
139
|
-
while(keep_watching) do
|
140
|
-
begin
|
141
|
-
stack_status = stack.status
|
142
|
-
if (SUCCESS_STATUSES.include? stack_status)
|
143
|
-
status = "Success: #{stack_status}"
|
144
|
-
print_status(status, silent)
|
145
|
-
success = true
|
146
|
-
keep_watching = false
|
147
|
-
elsif (PROGRESS_STATUSES.include? stack_status)
|
148
|
-
status = "In Progress: #{stack_status}"
|
149
|
-
print_status(status, silent)
|
150
|
-
success = false
|
151
|
-
keep_watching = true
|
152
|
-
elsif (FAILURE_STATUSES.include? stack_status)
|
153
|
-
status = "Failed: #{stack_status}"
|
154
|
-
print_status(status, silent)
|
155
|
-
success = false
|
156
|
-
keep_watching = false
|
157
|
-
else
|
158
|
-
status = "didn't find #{stack_status} in the list of expected statuses"
|
159
|
-
print_status(status, silent)
|
160
|
-
success = false
|
161
|
-
abort_count = abort_count - 1
|
162
|
-
# if we get too many unknown statuses, assume something has gone horribly wrong and quit.
|
163
|
-
keep_watching = (abort_count > 0)
|
164
|
-
end
|
165
|
-
rescue AWS::CloudFormation::Errors::Throttling
|
166
|
-
status = "Rate limit exceeded, retrying..."
|
167
|
-
print_status(status, silent)
|
168
|
-
sleep(sleep_time * 0.1)
|
169
|
-
end
|
170
|
-
if keep_watching
|
171
|
-
sleep(sleep_time)
|
172
|
-
end
|
173
|
-
end
|
174
|
-
return success
|
175
|
-
end
|
176
|
-
end
|
177
|
-
end
|
data/lib/opendelivery/storage.rb
DELETED
@@ -1,74 +0,0 @@
|
|
1
|
-
#Copyright (c) 2014 Stelligent Systems LLC
|
2
|
-
#
|
3
|
-
#MIT LICENSE
|
4
|
-
#
|
5
|
-
#Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
-
#of this software and associated documentation files (the "Software"), to deal
|
7
|
-
#in the Software without restriction, including without limitation the rights
|
8
|
-
#to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
-
#copies of the Software, and to permit persons to whom the Software is
|
10
|
-
#furnished to do so, subject to the following conditions:
|
11
|
-
#
|
12
|
-
#The above copyright notice and this permission notice shall be included in
|
13
|
-
#all copies or substantial portions of the Software.
|
14
|
-
#
|
15
|
-
#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
-
#IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
-
#FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
-
#AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
-
#LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
-
#OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
-
#THE SOFTWARE.
|
22
|
-
|
23
|
-
require 'aws-sdk'
|
24
|
-
|
25
|
-
module OpenDelivery
|
26
|
-
class Storage
|
27
|
-
|
28
|
-
def initialize(region=nil)
|
29
|
-
if region.nil?
|
30
|
-
@s3 = AWS::S3.new
|
31
|
-
else
|
32
|
-
@s3 = AWS::S3.new(:region => region)
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
def copy(bucket, key, desired_key)
|
37
|
-
@s3.buckets[bucket].objects[key].copy_to(desired_key)
|
38
|
-
end
|
39
|
-
|
40
|
-
def upload(bucket, file, key)
|
41
|
-
@s3.buckets[bucket].objects[key].write(:file => file)
|
42
|
-
end
|
43
|
-
|
44
|
-
def download(bucket, key, output_directory)
|
45
|
-
# Puke if the bucket doesn't exist
|
46
|
-
raise "Bucket #{bucket} doesn't exist" unless @s3.buckets[bucket].exists?
|
47
|
-
|
48
|
-
# Puke if the key doesn't exist. This can cause problems with some bucket policies, so we catch and re-throw
|
49
|
-
begin
|
50
|
-
raise "File with key #{key} doesn't exist in bucket #{bucket}" unless @s3.buckets[bucket].objects[key].exists?
|
51
|
-
rescue Exception => e
|
52
|
-
raise "Exception [#{e.message}] occurred downloading key #{key} from bucket #{bucket}"
|
53
|
-
end
|
54
|
-
|
55
|
-
obj = @s3.buckets[bucket].objects[key]
|
56
|
-
|
57
|
-
base = Pathname.new("#{obj.key}").basename
|
58
|
-
|
59
|
-
Dir.mkdir(output_directory) unless File.exists?(output_directory)
|
60
|
-
|
61
|
-
File.open("#{output_directory}/#{base}", 'wb') do |file|
|
62
|
-
obj.read do |chunk|
|
63
|
-
file.write(chunk)
|
64
|
-
end
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
def add_timestamp(identifier, artifact)
|
69
|
-
timestamp = Time.now.strftime("%Y.%m.%d.%H.%M.%S.%L")
|
70
|
-
stamped_artifact = "#{artifact}-#{identifier}-#{timestamp}"
|
71
|
-
return stamped_artifact
|
72
|
-
end
|
73
|
-
end
|
74
|
-
end
|
data/lib/opsworks.rb
DELETED
@@ -1,320 +0,0 @@
|
|
1
|
-
#Copyright (c) 2014 Stelligent Systems LLC
|
2
|
-
#
|
3
|
-
#MIT LICENSE
|
4
|
-
#
|
5
|
-
#Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
-
#of this software and associated documentation files (the "Software"), to deal
|
7
|
-
#in the Software without restriction, including without limitation the rights
|
8
|
-
#to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
-
#copies of the Software, and to permit persons to whom the Software is
|
10
|
-
#furnished to do so, subject to the following conditions:
|
11
|
-
#
|
12
|
-
#The above copyright notice and this permission notice shall be included in
|
13
|
-
#all copies or substantial portions of the Software.
|
14
|
-
#
|
15
|
-
#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
-
#IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
-
#FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
-
#AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
-
#LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
-
#OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
-
#THE SOFTWARE.
|
22
|
-
|
23
|
-
require 'aws-sdk'
|
24
|
-
|
25
|
-
module OpsWorks
|
26
|
-
|
27
|
-
def create_and_launch_stack(stack_description)
|
28
|
-
stack_id = create_stack(stack_description)
|
29
|
-
launch_stack(stack_id)
|
30
|
-
deploy_apps(stack_id)
|
31
|
-
stack_id
|
32
|
-
end
|
33
|
-
|
34
|
-
def create_and_launch_stack_in_order(stack_description, layers_by_order)
|
35
|
-
stack_id = create_stack(stack_description)
|
36
|
-
launch_stack_in_order(stack_id, layers_by_order)
|
37
|
-
deploy_apps(stack_id)
|
38
|
-
stack_id
|
39
|
-
end
|
40
|
-
|
41
|
-
def create_stack(stack_description)
|
42
|
-
opsworks_client = AWS::OpsWorks::Client::V20130218.new
|
43
|
-
|
44
|
-
response = opsworks_client.create_stack(stack_description.stack_description)
|
45
|
-
stack_id = response[:stack_id]
|
46
|
-
|
47
|
-
wait_on_opsworks_sg_creation(stack_description.stack_description[:vpc_id]) if stack_description.stack_description[:vpc_id]
|
48
|
-
|
49
|
-
layer_descriptions = stack_description.layer_descriptions
|
50
|
-
layer_descriptions.each do |layer_description|
|
51
|
-
layer_description[:layer][:stack_id] = stack_id
|
52
|
-
|
53
|
-
response = opsworks_client.create_layer(layer_description[:layer])
|
54
|
-
layer_id = response[:layer_id]
|
55
|
-
layer_description[:layer][:layer_id] = layer_id
|
56
|
-
|
57
|
-
layer_description[:instances].each do |instance_description|
|
58
|
-
instance_description[:stack_id] = stack_id
|
59
|
-
instance_description[:layer_ids] = [layer_id]
|
60
|
-
|
61
|
-
save_off = instance_description[:extra_layers]
|
62
|
-
instance_description.delete :extra_layers
|
63
|
-
response = opsworks_client.create_instance(instance_description)
|
64
|
-
instance_description[:instance_id] = response[:instance_id]
|
65
|
-
instance_description[:extra_layers] = save_off
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
|
-
layer_descriptions.each do |layer_description|
|
70
|
-
layer_description[:instances].each do |instance_description|
|
71
|
-
if instance_description[:extra_layers]
|
72
|
-
instance_description[:extra_layers].each do |extra_layer_name|
|
73
|
-
found_extra_layer = layer_descriptions.find { |desc| desc[:layer][:name] == extra_layer_name }
|
74
|
-
|
75
|
-
raise "missing extra layer: #{extra_layer_name}" unless found_extra_layer
|
76
|
-
instance_description[:layer_ids] << found_extra_layer[:layer][:layer_id]
|
77
|
-
response = opsworks_client.update_instance(:instance_id => instance_description[:instance_id],
|
78
|
-
:layer_ids => instance_description[:layer_ids])
|
79
|
-
end
|
80
|
-
end
|
81
|
-
end
|
82
|
-
end
|
83
|
-
|
84
|
-
stack_description.app_descriptions.each do |app_description|
|
85
|
-
app_description[:stack_id] = stack_id
|
86
|
-
response = opsworks_client.create_app(app_description)
|
87
|
-
end
|
88
|
-
|
89
|
-
stack_id
|
90
|
-
end
|
91
|
-
|
92
|
-
def launch_stack(stack_id)
|
93
|
-
opsworks_client = AWS::OpsWorks::Client::V20130218.new
|
94
|
-
|
95
|
-
opsworks_client.start_stack(:stack_id => stack_id)
|
96
|
-
|
97
|
-
wait_on_setup(stack_id)
|
98
|
-
|
99
|
-
wait_on_all_configures(stack_id)
|
100
|
-
end
|
101
|
-
|
102
|
-
|
103
|
-
def launch_stack_in_order(stack_id, layers_by_order)
|
104
|
-
opsworks_client = AWS::OpsWorks::Client::V20130218.new
|
105
|
-
|
106
|
-
layers_by_order.each do |layer_names|
|
107
|
-
layer_names.each do |layer_name|
|
108
|
-
|
109
|
-
response = opsworks_client.describe_layers( :stack_id => stack_id)
|
110
|
-
layer = response[:layers].find { |layer| layer[:shortname] == layer_name }
|
111
|
-
raise "layer #{layer_name} not found in stack: #{stack_id}" if layer.nil?
|
112
|
-
|
113
|
-
response = opsworks_client.describe_instances( :layer_id => layer[:layer_id])
|
114
|
-
response[:instances].each do |instance|
|
115
|
-
opsworks_client.start_instance( :instance_id => instance[:instance_id])
|
116
|
-
end
|
117
|
-
end
|
118
|
-
|
119
|
-
layer_names.each do |layer_name|
|
120
|
-
response = opsworks_client.describe_layers( :stack_id => stack_id)
|
121
|
-
layer = response[:layers].find { |layer| layer[:shortname] == layer_name }
|
122
|
-
raise "layer #{layer_name} not found in stack: #{stack_id}" if layer.nil?
|
123
|
-
|
124
|
-
wait_on_layer_setup(layer[:layer_id])
|
125
|
-
wait_on_layer_configures(layer[:layer_id])
|
126
|
-
end
|
127
|
-
end
|
128
|
-
end
|
129
|
-
|
130
|
-
def deploy_apps(stack_id)
|
131
|
-
deployment_ids = []
|
132
|
-
opsworks_client = AWS::OpsWorks::Client::V20130218.new
|
133
|
-
response = opsworks_client.describe_apps(:stack_id => stack_id)
|
134
|
-
response[:apps].each do |app|
|
135
|
-
|
136
|
-
puts "DEPLOYING THE APP: #{app}"
|
137
|
-
response = opsworks_client.create_deployment(:stack_id => stack_id,
|
138
|
-
:app_id => app[:app_id],
|
139
|
-
:command => {
|
140
|
-
:name => 'deploy',
|
141
|
-
:args => deployment_args_factory(app)
|
142
|
-
})
|
143
|
-
deployment_ids << response[:deployment_id]
|
144
|
-
end
|
145
|
-
|
146
|
-
max_attempts = 250
|
147
|
-
num_attempts = 0
|
148
|
-
|
149
|
-
deployments_complete = false
|
150
|
-
until deployments_complete
|
151
|
-
response = opsworks_client.describe_deployments(:deployment_ids => deployment_ids)
|
152
|
-
deployments_complete = response[:deployments].inject(true) do |status, deployment|
|
153
|
-
puts "Deployment status: #{deployment[:status]}"
|
154
|
-
|
155
|
-
if deployment[:status] == 'failed'
|
156
|
-
raise 'deployment failed'
|
157
|
-
end
|
158
|
-
|
159
|
-
status and (deployment[:status] == 'successful')
|
160
|
-
end
|
161
|
-
num_attempts += 1
|
162
|
-
if num_attempts >= max_attempts
|
163
|
-
raise 'stuck waiting on configure command max attempts'
|
164
|
-
end
|
165
|
-
sleep 10
|
166
|
-
end
|
167
|
-
deployment_ids
|
168
|
-
end
|
169
|
-
|
170
|
-
def discover_private_ips(stack_id, layer_name)
|
171
|
-
opsworks_client = AWS::OpsWorks::Client::V20130218.new
|
172
|
-
response = opsworks_client.describe_layers( :stack_id => stack_id)
|
173
|
-
layer = response[:layers].find { |layer| layer[:name] == layer_name }
|
174
|
-
raise "layer #{layer_name} not found in stack: #{stack_id}" if layer.nil?
|
175
|
-
|
176
|
-
response = opsworks_client.describe_instances( :layer_id => layer[:layer_id] )
|
177
|
-
response[:instances].collect { |instance| instance[:private_ip] }
|
178
|
-
end
|
179
|
-
|
180
|
-
def discover_public_ips(stack_id, layer_name)
|
181
|
-
opsworks_client = AWS::OpsWorks::Client::V20130218.new
|
182
|
-
response = opsworks_client.describe_layers( :stack_id => stack_id)
|
183
|
-
layer = response[:layers].find { |layer| layer[:name] == layer_name }
|
184
|
-
raise "layer #{layer_name} not found in stack: #{stack_id}" if layer.nil?
|
185
|
-
|
186
|
-
response = opsworks_client.describe_instances( :layer_id => layer[:layer_id] )
|
187
|
-
response[:instances].collect { |instance| instance[:public_ip] }
|
188
|
-
end
|
189
|
-
|
190
|
-
protected
|
191
|
-
|
192
|
-
def deployment_args_factory(app)
|
193
|
-
if app[:type] == 'rails'
|
194
|
-
{
|
195
|
-
'migrate' => %w{true}
|
196
|
-
}
|
197
|
-
else
|
198
|
-
{}
|
199
|
-
end
|
200
|
-
end
|
201
|
-
|
202
|
-
private
|
203
|
-
|
204
|
-
def wait_on_opsworks_sg_creation(vpc_id)
|
205
|
-
opsworks_security_group_names.each do |sg_name|
|
206
|
-
while AWS.ec2.security_groups.filter('vpc-id', vpc_id).filter('group-name', sg_name).count == 0
|
207
|
-
puts "Waiting on #{sg_name}, #{a = a ? a+1 : 1}"
|
208
|
-
sleep 1
|
209
|
-
end
|
210
|
-
end
|
211
|
-
end
|
212
|
-
|
213
|
-
def opsworks_security_group_names
|
214
|
-
%w{AWS-OpsWorks-Default-Server AWS-OpsWorks-Blank-Server AWS-OpsWorks-Custom-Server AWS-OpsWorks-Rails-App-Server AWS-OpsWorks-PHP-App-Server}
|
215
|
-
end
|
216
|
-
|
217
|
-
|
218
|
-
def complete(status)
|
219
|
-
failure(status) or success(status)
|
220
|
-
end
|
221
|
-
|
222
|
-
def failure(status)
|
223
|
-
%w{setup_failed start_failed terminated connection_lost}.include? status
|
224
|
-
end
|
225
|
-
|
226
|
-
def success(status)
|
227
|
-
%w{online}.include? status
|
228
|
-
end
|
229
|
-
|
230
|
-
def wait_on_setup(stack_id)
|
231
|
-
opsworks_client = AWS::OpsWorks::Client::V20130218.new
|
232
|
-
|
233
|
-
setup_complete = false
|
234
|
-
until setup_complete
|
235
|
-
response = opsworks_client.describe_instances(:stack_id => stack_id)
|
236
|
-
setup_complete = response[:instances].inject(true) do |status, instance|
|
237
|
-
if failure(instance[:status])
|
238
|
-
raise 'setup failed'
|
239
|
-
end
|
240
|
-
|
241
|
-
instance_status(instance)
|
242
|
-
|
243
|
-
status and complete(instance[:status])
|
244
|
-
end
|
245
|
-
sleep 10
|
246
|
-
end
|
247
|
-
end
|
248
|
-
|
249
|
-
def wait_on_layer_setup(layer_id)
|
250
|
-
opsworks_client = AWS::OpsWorks::Client::V20130218.new
|
251
|
-
|
252
|
-
setup_complete = false
|
253
|
-
until setup_complete
|
254
|
-
response = opsworks_client.describe_instances(:layer_id => layer_id)
|
255
|
-
setup_complete = response[:instances].inject(true) do |status, instance|
|
256
|
-
if failure(instance[:status])
|
257
|
-
raise 'setup failed'
|
258
|
-
end
|
259
|
-
|
260
|
-
instance_status(instance)
|
261
|
-
|
262
|
-
status and complete(instance[:status])
|
263
|
-
end
|
264
|
-
sleep 10
|
265
|
-
end
|
266
|
-
end
|
267
|
-
|
268
|
-
def instance_status(instance)
|
269
|
-
puts "Instance: #{instance[:instance_id]} has status #{instance[:status]}"
|
270
|
-
end
|
271
|
-
|
272
|
-
def configure_status(configure_command)
|
273
|
-
puts "Configure command: #{configure_command}"
|
274
|
-
end
|
275
|
-
|
276
|
-
def wait_on_all_configures(stack_id)
|
277
|
-
opsworks_client = AWS::OpsWorks::Client::V20130218.new
|
278
|
-
response = opsworks_client.describe_instances(:stack_id => stack_id)
|
279
|
-
response[:instances].each do |instance|
|
280
|
-
wait_on_configure(instance[:instance_id])
|
281
|
-
end
|
282
|
-
end
|
283
|
-
|
284
|
-
def wait_on_layer_configures(layer_id)
|
285
|
-
opsworks_client = AWS::OpsWorks::Client::V20130218.new
|
286
|
-
response = opsworks_client.describe_instances(:layer_id => layer_id)
|
287
|
-
response[:instances].each do |instance|
|
288
|
-
wait_on_configure(instance[:instance_id])
|
289
|
-
end
|
290
|
-
end
|
291
|
-
|
292
|
-
def wait_on_configure(instance_id)
|
293
|
-
opsworks_client = AWS::OpsWorks::Client::V20130218.new
|
294
|
-
|
295
|
-
max_attempts = 250
|
296
|
-
num_attempts = 0
|
297
|
-
|
298
|
-
while true
|
299
|
-
response = opsworks_client.describe_commands(:instance_id => instance_id)
|
300
|
-
configure_command = response[:commands].find { |command| command[:type] == 'configure' }
|
301
|
-
|
302
|
-
configure_status(configure_command)
|
303
|
-
|
304
|
-
unless configure_command.nil?
|
305
|
-
#i guess just bail if superseded, waiting on configure events is somewhat dubious after seeing more complex stacks in action anyway!
|
306
|
-
if %w{successful superseded}.include? configure_command[:status]
|
307
|
-
return
|
308
|
-
elsif configure_command[:status] == 'failed'
|
309
|
-
raise 'configure failed'
|
310
|
-
end
|
311
|
-
end
|
312
|
-
num_attempts += 1
|
313
|
-
if num_attempts >= max_attempts
|
314
|
-
raise 'stuck waiting on configure command max attempts'
|
315
|
-
end
|
316
|
-
sleep 10
|
317
|
-
end
|
318
|
-
end
|
319
|
-
|
320
|
-
end
|