tengine_resource_ec2 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +15 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +125 -0
- data/README.rdoc +20 -0
- data/lib/tengine/resource_ec2/dummy_connection.rb +167 -0
- data/lib/tengine/resource_ec2/dummy_connection.rb~ +148 -0
- data/lib/tengine/resource_ec2/launch_options.rb +182 -0
- data/lib/tengine/resource_ec2/launch_options.rb~ +181 -0
- data/lib/tengine/resource_ec2/provider.rb +309 -0
- data/lib/tengine/resource_ec2/provider.rb~ +189 -0
- data/lib/tengine/resource_ec2.rb +8 -0
- data/lib/tengine_resource_ec2.rb +5 -0
- data/spec/fixtures/goku_at_ec2_ap_northeast.rb +177 -0
- data/tmp/.gitkeep +0 -0
- metadata +231 -0
checksums.yaml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
---
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
MGQ1NWRmMzBkYjljMTRlZTkyZjdiM2FmMmJhNjc2ZjBmOTFkZDkzZQ==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
NjMzNjhlMmFlNjhhMzgwODdkMzBjZjFjN2YxY2QyYmJlYjM0ZDI4MQ==
|
7
|
+
!binary "U0hBNTEy":
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
MjE0N2U4YTI3YzMwMzJjZjgzN2VlYzY1MDA1YzQ2NjYyODI1ZDJlZDQ2M2E4
|
10
|
+
NzA4YjgzYmI5MWJhODE0Nzk5MDY0NjVjMzExYzI5NzM3NTAwNjlmZDQ4Y2Zi
|
11
|
+
ZTIzYmFlZDhiN2EzNWE0N2M1ZTdkMzEyNjFiZGRhNGQ3OTdiMWY=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
NGU1NTNmN2ZmYjk2OTdjYzNiNTA5ZTA1YzY1OGU3NWFhNWJiM2ZiYmFhNGNm
|
14
|
+
ZTE4YzY1YjhmMTFlYmQyOWJhMmZlNTZkNDcxYWEwMTdmMDM5YjUwYzI2OGIx
|
15
|
+
ZjQ3NTg2NjQ3NDNmN2NhNmNkMGNmZWMzMTU4NjI3Y2I1M2NjNGQ=
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,125 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
tengine_resource_ec2 (1.2.0)
|
5
|
+
right_aws (~> 2.1.0)
|
6
|
+
tengine_resource (~> 1.2.0)
|
7
|
+
|
8
|
+
GEM
|
9
|
+
remote: http://rubygems.org/
|
10
|
+
specs:
|
11
|
+
ZenTest (4.9.1)
|
12
|
+
activemodel (3.2.12)
|
13
|
+
activesupport (= 3.2.12)
|
14
|
+
builder (~> 3.0.0)
|
15
|
+
activesupport (3.2.12)
|
16
|
+
i18n (~> 0.6)
|
17
|
+
multi_json (~> 1.0)
|
18
|
+
amq-client (0.9.12)
|
19
|
+
amq-protocol (>= 1.2.0)
|
20
|
+
eventmachine
|
21
|
+
amq-protocol (1.2.0)
|
22
|
+
amqp (0.9.10)
|
23
|
+
amq-client (~> 0.9.12)
|
24
|
+
amq-protocol (~> 1.2.0)
|
25
|
+
eventmachine
|
26
|
+
autotest (4.4.6)
|
27
|
+
ZenTest (>= 4.4.1)
|
28
|
+
builder (3.0.4)
|
29
|
+
coderay (1.0.9)
|
30
|
+
columnize (0.3.6)
|
31
|
+
daemons (1.1.9)
|
32
|
+
debugger (1.5.0)
|
33
|
+
columnize (>= 0.3.1)
|
34
|
+
debugger-linecache (~> 1.2.0)
|
35
|
+
debugger-ruby_core_source (~> 1.2.0)
|
36
|
+
debugger-linecache (1.2.0)
|
37
|
+
debugger-ruby_core_source (1.2.0)
|
38
|
+
diff-lcs (1.1.3)
|
39
|
+
eventmachine (1.0.3)
|
40
|
+
i18n (0.6.4)
|
41
|
+
macaddr (1.6.1)
|
42
|
+
systemu (~> 2.5.0)
|
43
|
+
method_source (0.8.1)
|
44
|
+
mongoid (3.1.3)
|
45
|
+
activemodel (~> 3.2)
|
46
|
+
moped (~> 1.4.2)
|
47
|
+
origin (~> 1.0)
|
48
|
+
tzinfo (~> 0.3.22)
|
49
|
+
moped (1.4.5)
|
50
|
+
multi_json (1.7.2)
|
51
|
+
net-ssh (2.5.2)
|
52
|
+
origin (1.1.0)
|
53
|
+
pry (0.9.12.1)
|
54
|
+
coderay (~> 1.0.5)
|
55
|
+
method_source (~> 0.8)
|
56
|
+
slop (~> 3.4)
|
57
|
+
pry-debugger (0.2.2)
|
58
|
+
debugger (~> 1.3)
|
59
|
+
pry (~> 0.9.10)
|
60
|
+
pry-doc (0.4.5)
|
61
|
+
pry (>= 0.9)
|
62
|
+
yard (>= 0.8)
|
63
|
+
rake (10.0.4)
|
64
|
+
right_aws (2.1.0)
|
65
|
+
right_http_connection (>= 1.2.5)
|
66
|
+
right_http_connection (1.3.0)
|
67
|
+
rspec (2.10.0)
|
68
|
+
rspec-core (~> 2.10.0)
|
69
|
+
rspec-expectations (~> 2.10.0)
|
70
|
+
rspec-mocks (~> 2.10.0)
|
71
|
+
rspec-core (2.10.1)
|
72
|
+
rspec-expectations (2.10.0)
|
73
|
+
diff-lcs (~> 1.1.3)
|
74
|
+
rspec-mocks (2.10.1)
|
75
|
+
selectable_attr (0.3.17)
|
76
|
+
i18n
|
77
|
+
simplecov (0.7.1)
|
78
|
+
multi_json (~> 1.0)
|
79
|
+
simplecov-html (~> 0.7.1)
|
80
|
+
simplecov-html (0.7.1)
|
81
|
+
slop (3.4.4)
|
82
|
+
systemu (2.5.2)
|
83
|
+
tengine_core (1.2.0)
|
84
|
+
activemodel (>= 3.1.0)
|
85
|
+
activesupport (>= 3.1.0)
|
86
|
+
daemons (~> 1.1.4)
|
87
|
+
mongoid (>= 3.0.22)
|
88
|
+
selectable_attr (~> 0.3.15)
|
89
|
+
tengine_event (~> 1.2.0)
|
90
|
+
tengine_support (~> 1.2.0)
|
91
|
+
tengine_event (1.2.0)
|
92
|
+
activesupport (>= 3.0.0)
|
93
|
+
amqp (~> 0.9.10)
|
94
|
+
tengine_support (~> 1.2.0)
|
95
|
+
uuid (~> 2.3.4)
|
96
|
+
tengine_resource (1.2.0)
|
97
|
+
net-ssh (~> 2.5.2)
|
98
|
+
tengine_core (~> 1.2.0)
|
99
|
+
tengine_support (~> 1.2.0)
|
100
|
+
text-table (~> 1.2.2)
|
101
|
+
thor (>= 0.14.6)
|
102
|
+
tengine_support (1.2.0)
|
103
|
+
activesupport (>= 3.0.0)
|
104
|
+
text-table (1.2.3)
|
105
|
+
thor (0.18.1)
|
106
|
+
tzinfo (0.3.37)
|
107
|
+
uuid (2.3.7)
|
108
|
+
macaddr (~> 1.0)
|
109
|
+
yard (0.8.6.1)
|
110
|
+
|
111
|
+
PLATFORMS
|
112
|
+
ruby
|
113
|
+
|
114
|
+
DEPENDENCIES
|
115
|
+
ZenTest (~> 4.9.0)
|
116
|
+
autotest
|
117
|
+
bundler
|
118
|
+
pry
|
119
|
+
pry-debugger
|
120
|
+
pry-doc
|
121
|
+
rake
|
122
|
+
rspec (~> 2.10.0)
|
123
|
+
simplecov
|
124
|
+
tengine_resource_ec2!
|
125
|
+
yard
|
data/README.rdoc
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
= tengine_resource
|
2
|
+
|
3
|
+
Description goes here.
|
4
|
+
|
5
|
+
== Contributing to tengine_resource
|
6
|
+
|
7
|
+
* Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
|
8
|
+
* Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
|
9
|
+
* Fork the project
|
10
|
+
* Start a feature/bugfix branch
|
11
|
+
* Commit and push until you are happy with your contribution
|
12
|
+
* Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
|
13
|
+
* Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
|
14
|
+
|
15
|
+
== License
|
16
|
+
tengine_resource is distributed under the MPL2.0 or LGPLv3 or the dual license of MPL2.0/LGPLv3
|
17
|
+
|
18
|
+
== Copyright
|
19
|
+
|
20
|
+
Copyright (c) 2012 Groovenauts, Inc.
|
@@ -0,0 +1,167 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
# EC2に実際には接続しないであたかも接続しているかのように見せるためのダミーです。
|
3
|
+
#
|
4
|
+
# 環境変数EC2_DUMMYがtrueの場合に、RightAws::Ec2の代わりにこのクラスからインスタンスが生成されます。
|
5
|
+
# 起動してから環境変数EC2_DUMMY_INTERVALで指定された秒数が経過したインスタンス(のダミー)はちゃんとrunningになるようになっています。
|
6
|
+
#
|
7
|
+
# [10/08/19 13:06:41] akimatter: モックはtestでしか使えません。
|
8
|
+
# [10/08/19 13:08:47] akimatter: developmentでは、RightAws::Ec2のインスタンスの代わりのダミー(一般的にはモックって言うけど、specのモックと区別して敢えてダミーします)を使うようにするべきかも。
|
9
|
+
# [10/08/19 13:09:19] akimatter: ただし、developmentでもダミーではなくEC2にちゃんと繋ぎたい場合もあるので、
|
10
|
+
# [10/08/19 13:09:41] akimatter: 環境変数か何かの設定でこれらの動作が変わる方が良いかと思います。
|
11
|
+
class Tengine::ResourceEc2::DummyConnection
|
12
|
+
cattr_accessor :last_instance_index
|
13
|
+
@@last_instance_index = 0
|
14
|
+
|
15
|
+
# クラス変数で生成しているインスタンスを保持したいところですが、
|
16
|
+
# それだとdevelopmentモードでクラスがロードされる度に保持している内容がクリア
|
17
|
+
# されてしまうのでNGでした。
|
18
|
+
# 他に影響を与えないように実装する手段が他に思いつかなかったので、グローバル変数を使います。
|
19
|
+
# cattr_accessor :instances
|
20
|
+
# @@instances = {}
|
21
|
+
def self.instances
|
22
|
+
$ec2_dummy_instances ||= {}
|
23
|
+
end
|
24
|
+
def self.instances=(value)
|
25
|
+
$ec2_dummy_instances = value
|
26
|
+
end
|
27
|
+
|
28
|
+
def instances
|
29
|
+
self.class.instances
|
30
|
+
end
|
31
|
+
|
32
|
+
def initialize(access_key, secret_access_key, options = {})
|
33
|
+
@access_key, @secret_access_key = access_key, secret_access_key
|
34
|
+
@options = options || {}
|
35
|
+
end
|
36
|
+
|
37
|
+
STATIC_ATTRS = {
|
38
|
+
:aws_reservation_id=>"r-71a46435",
|
39
|
+
:aws_owner=>"000000000888",
|
40
|
+
:aws_ramdisk_id=>"ari-c12e7f84",
|
41
|
+
:aws_product_codes=>[],
|
42
|
+
:monitoring_state=>"disabled",
|
43
|
+
:aws_instance_type=>"m1.small",
|
44
|
+
:root_device_type=>"instance-store",
|
45
|
+
:aws_reason=>"",
|
46
|
+
:aws_kernel_id=>"aki-773c6d32",
|
47
|
+
:aws_availability_zone=>"us-west-1a"
|
48
|
+
}
|
49
|
+
|
50
|
+
def launch_instances(image_id, options)
|
51
|
+
launch_time = Time.zone.now
|
52
|
+
count = options.delete(:min_count) || 1
|
53
|
+
options.delete(:max_count) # :max_countは無視
|
54
|
+
idx = 0
|
55
|
+
result = []
|
56
|
+
count.times do
|
57
|
+
instance_index = (self.class.last_instance_index += 1)
|
58
|
+
instanceid = "i-DMY%05d" % instance_index
|
59
|
+
instance_hash = {
|
60
|
+
:aws_instance_id => instanceid,
|
61
|
+
:aws_image_id => image_id,
|
62
|
+
:state_reason_code=>"pending",
|
63
|
+
:ssh_key_name => options[:key_name],
|
64
|
+
:aws_groups => options[:group_ids],
|
65
|
+
:state_reason_message=>"pending",
|
66
|
+
:aws_state_code=>0,
|
67
|
+
:dns_name=>"",
|
68
|
+
:private_dns_name => "",
|
69
|
+
:aws_launch_time => launch_time.iso8601,
|
70
|
+
:aws_state => "pending",
|
71
|
+
:ami_launch_index => idx.to_s,
|
72
|
+
}.update(STATIC_ATTRS.dup)
|
73
|
+
idx += 1
|
74
|
+
result << instance_hash
|
75
|
+
instances[instanceid] = instance_hash
|
76
|
+
end
|
77
|
+
result
|
78
|
+
end
|
79
|
+
|
80
|
+
def describe_instances(instance_ids = [])
|
81
|
+
update_instances
|
82
|
+
if instance_ids.empty?
|
83
|
+
instances.values.sort_by{|hash| hash[:aws_instance_id]}
|
84
|
+
else
|
85
|
+
instance_ids.map{|id| instances[id]}
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def terminate_instances(instance_ids)
|
90
|
+
update_instances
|
91
|
+
instance_ids.each do |instance_id|
|
92
|
+
update_status_running(instance_id) # 停止する前に一度はrunningにしておく
|
93
|
+
hash = instances[instance_id]
|
94
|
+
hash.update(
|
95
|
+
:state_reason_code=>"Client.UserInitiatedShutdown",
|
96
|
+
:state_reason_message=>"Client.UserInitiatedShutdown: User initiated shutdown",
|
97
|
+
:aws_state_code=>48,
|
98
|
+
:dns_name=>"",
|
99
|
+
:private_dns_name=>"",
|
100
|
+
:aws_state=>"terminated"
|
101
|
+
)
|
102
|
+
hash.delete(:ip_address)
|
103
|
+
hash.delete(:private_ip_address)
|
104
|
+
end
|
105
|
+
instance_ids.map do |instance_id|
|
106
|
+
{
|
107
|
+
:aws_prev_state_name => "running",
|
108
|
+
:aws_instance_id => instance_id,
|
109
|
+
:aws_current_state_code => 32,
|
110
|
+
:aws_current_state_name => "shutting-down",
|
111
|
+
:aws_prev_state_code => 16
|
112
|
+
}
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
|
117
|
+
def describe_availability_zones(*args)
|
118
|
+
[
|
119
|
+
{:region_name=>"us-east-1", :zone_name=>"us-east-1a", :zone_state=>"available"},
|
120
|
+
{:region_name=>"us-east-1", :zone_name=>"us-east-1b", :zone_state=>"available"},
|
121
|
+
{:region_name=>"us-east-1", :zone_name=>"us-east-1c", :zone_state=>"available"},
|
122
|
+
{:region_name=>"us-east-1", :zone_name=>"us-east-1d", :zone_state=>"available"}
|
123
|
+
]
|
124
|
+
end
|
125
|
+
|
126
|
+
def describe_images_by_owner(*args)
|
127
|
+
[]
|
128
|
+
end
|
129
|
+
|
130
|
+
def describe_images(*args)
|
131
|
+
[]
|
132
|
+
end
|
133
|
+
|
134
|
+
|
135
|
+
private
|
136
|
+
UPDATE_INTERVAL = (ENV['EC2_DUMMY_INTERVAL'] || 30).to_i.seconds
|
137
|
+
|
138
|
+
def update_instances
|
139
|
+
t = (Time.zone || Time).now
|
140
|
+
instances.each do |instanceid, hash|
|
141
|
+
next unless hash[:aws_state] == "pending"
|
142
|
+
launch_time = Time.zone.parse(hash[:aws_launch_time])
|
143
|
+
next if (t - launch_time) < UPDATE_INTERVAL
|
144
|
+
update_status_running(instanceid)
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
def update_status_running(instance_id)
|
149
|
+
hash = instances[instance_id]
|
150
|
+
unless hash
|
151
|
+
raise ArgumentError, "No instance found for #{instance_id.inspect}. " << instances.keys.map(&:to_s).join("\n") << " exist."
|
152
|
+
end
|
153
|
+
instance_index = hash[:aws_instance_id].sub(/^i\-DMY/, '').to_i
|
154
|
+
hash.update(
|
155
|
+
:aws_state_code=>16,
|
156
|
+
:dns_name=>"ec2-184-72-20-#{instance_index}.us-west-1.compute.amazonaws.com",
|
157
|
+
:ip_address=>"184.72.20.#{instance_index}",
|
158
|
+
:private_dns_name=>"ip-10-162-153-#{instance_index}.us-west-1.compute.internal",
|
159
|
+
:private_ip_address=>"10.162.153.#{instance_index}",
|
160
|
+
:aws_state=>"running",
|
161
|
+
:architecture=>"i386"
|
162
|
+
)
|
163
|
+
hash.delete(:state_reason_message)
|
164
|
+
hash.delete(:state_reason_code)
|
165
|
+
end
|
166
|
+
|
167
|
+
end
|
@@ -0,0 +1,148 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
# EC2に実際には接続しないであたかも接続しているかのように見せるためのダミーです。
|
3
|
+
#
|
4
|
+
# 環境変数EC2_DUMMYがtrueの場合に、RightAws::Ec2の代わりにこのクラスからインスタンスが生成されます。
|
5
|
+
# 起動してから環境変数EC2_DUMMY_INTERVALで指定された秒数が経過したインスタンス(のダミー)はちゃんとrunningになるようになっています。
|
6
|
+
#
|
7
|
+
# [10/08/19 13:06:41] akimatter: モックはtestでしか使えません。
|
8
|
+
# [10/08/19 13:08:47] akimatter: developmentでは、RightAws::Ec2のインスタンスの代わりのダミー(一般的にはモックって言うけど、specのモックと区別して敢えてダミーします)を使うようにするべきかも。
|
9
|
+
# [10/08/19 13:09:19] akimatter: ただし、developmentでもダミーではなくEC2にちゃんと繋ぎたい場合もあるので、
|
10
|
+
# [10/08/19 13:09:41] akimatter: 環境変数か何かの設定でこれらの動作が変わる方が良いかと思います。
|
11
|
+
class Tengine::Resource::Credential::Ec2::Dummy
|
12
|
+
cattr_accessor :last_instance_index
|
13
|
+
@@last_instance_index = 0
|
14
|
+
|
15
|
+
# クラス変数で生成しているインスタンスを保持したいところですが、
|
16
|
+
# それだとdevelopmentモードでクラスがロードされる度に保持している内容がクリア
|
17
|
+
# されてしまうのでNGでした。
|
18
|
+
# 他に影響を与えないように実装する手段が他に思いつかなかったので、グローバル変数を使います。
|
19
|
+
# cattr_accessor :instances
|
20
|
+
# @@instances = {}
|
21
|
+
def self.instances
|
22
|
+
$ec2_dummy_instances ||= {}
|
23
|
+
end
|
24
|
+
def self.instances=(value)
|
25
|
+
$ec2_dummy_instances = value
|
26
|
+
end
|
27
|
+
|
28
|
+
def instances
|
29
|
+
self.class.instances
|
30
|
+
end
|
31
|
+
|
32
|
+
def initialize(access_key, secret_access_key, options = {})
|
33
|
+
@access_key, @secret_access_key = access_key, secret_access_key
|
34
|
+
@options = options || {}
|
35
|
+
end
|
36
|
+
|
37
|
+
STATIC_ATTRS = {
|
38
|
+
:aws_reservation_id=>"r-71a46435",
|
39
|
+
:aws_owner=>"000000000888",
|
40
|
+
:aws_ramdisk_id=>"ari-c12e7f84",
|
41
|
+
:aws_product_codes=>[],
|
42
|
+
:monitoring_state=>"disabled",
|
43
|
+
:aws_instance_type=>"m1.small",
|
44
|
+
:root_device_type=>"instance-store",
|
45
|
+
:aws_reason=>"",
|
46
|
+
:aws_kernel_id=>"aki-773c6d32",
|
47
|
+
:aws_availability_zone=>"us-west-1a"
|
48
|
+
}
|
49
|
+
|
50
|
+
def launch_instances(image_id, options)
|
51
|
+
launch_time = Time.zone.now
|
52
|
+
count = options.delete(:min_count) || 1
|
53
|
+
options.delete(:max_count) # :max_countは無視
|
54
|
+
idx = 0
|
55
|
+
result = []
|
56
|
+
count.times do
|
57
|
+
instance_index = (self.class.last_instance_index += 1)
|
58
|
+
instanceid = "i-DMY%05d" % instance_index
|
59
|
+
instance_hash = {
|
60
|
+
:aws_instance_id => instanceid,
|
61
|
+
:aws_image_id => image_id,
|
62
|
+
:state_reason_code=>"pending",
|
63
|
+
:ssh_key_name => options[:key_name],
|
64
|
+
:aws_groups => options[:group_ids],
|
65
|
+
:state_reason_message=>"pending",
|
66
|
+
:aws_state_code=>0,
|
67
|
+
:dns_name=>"",
|
68
|
+
:private_dns_name => "",
|
69
|
+
:aws_launch_time => launch_time.iso8601,
|
70
|
+
:aws_state => "pending",
|
71
|
+
:ami_launch_index => idx.to_s,
|
72
|
+
}.update(STATIC_ATTRS.dup)
|
73
|
+
idx += 1
|
74
|
+
result << instance_hash
|
75
|
+
instances[instanceid] = instance_hash
|
76
|
+
end
|
77
|
+
result
|
78
|
+
end
|
79
|
+
|
80
|
+
def describe_instances(instance_ids = [])
|
81
|
+
update_instances
|
82
|
+
if instance_ids.empty?
|
83
|
+
instances.values.sort_by{|hash| hash[:aws_instance_id]}
|
84
|
+
else
|
85
|
+
instance_ids.map{|id| instances[id]}
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def terminate_instances(instance_ids)
|
90
|
+
update_instances
|
91
|
+
instance_ids.each do |instance_id|
|
92
|
+
update_status_running(instance_id) # 停止する前に一度はrunningにしておく
|
93
|
+
hash = instances[instance_id]
|
94
|
+
hash.update(
|
95
|
+
:state_reason_code=>"Client.UserInitiatedShutdown",
|
96
|
+
:state_reason_message=>"Client.UserInitiatedShutdown: User initiated shutdown",
|
97
|
+
:aws_state_code=>48,
|
98
|
+
:dns_name=>"",
|
99
|
+
:private_dns_name=>"",
|
100
|
+
:aws_state=>"terminated"
|
101
|
+
)
|
102
|
+
hash.delete(:ip_address)
|
103
|
+
hash.delete(:private_ip_address)
|
104
|
+
end
|
105
|
+
instance_ids.map do |instance_id|
|
106
|
+
{
|
107
|
+
:aws_prev_state_name => "running",
|
108
|
+
:aws_instance_id => instance_id,
|
109
|
+
:aws_current_state_code => 32,
|
110
|
+
:aws_current_state_name => "shutting-down",
|
111
|
+
:aws_prev_state_code => 16
|
112
|
+
}
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
private
|
117
|
+
UPDATE_INTERVAL = (ENV['EC2_DUMMY_INTERVAL'] || 30).to_i.seconds
|
118
|
+
|
119
|
+
def update_instances
|
120
|
+
t = Time.zone.now
|
121
|
+
instances.each do |instanceid, hash|
|
122
|
+
next unless hash[:aws_state] == "pending"
|
123
|
+
launch_time = Time.zone.parse(hash[:aws_launch_time])
|
124
|
+
next if (t - launch_time) < UPDATE_INTERVAL
|
125
|
+
update_status_running(instanceid)
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
def update_status_running(instance_id)
|
130
|
+
hash = instances[instance_id]
|
131
|
+
unless hash
|
132
|
+
raise ArgumentError, "No instance found for #{instance_id.inspect}. " << instances.keys.map(&:to_s).join("\n") << " exist."
|
133
|
+
end
|
134
|
+
instance_index = hash[:aws_instance_id].sub(/^i\-DMY/, '').to_i
|
135
|
+
hash.update(
|
136
|
+
:aws_state_code=>16,
|
137
|
+
:dns_name=>"ec2-184-72-20-#{instance_index}.us-west-1.compute.amazonaws.com",
|
138
|
+
:ip_address=>"184.72.20.#{instance_index}",
|
139
|
+
:private_dns_name=>"ip-10-162-153-#{instance_index}.us-west-1.compute.internal",
|
140
|
+
:private_ip_address=>"10.162.153.#{instance_index}",
|
141
|
+
:aws_state=>"running",
|
142
|
+
:architecture=>"i386"
|
143
|
+
)
|
144
|
+
hash.delete(:state_reason_message)
|
145
|
+
hash.delete(:state_reason_code)
|
146
|
+
end
|
147
|
+
|
148
|
+
end
|
@@ -0,0 +1,182 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
require 'tengine/support/core_ext/enumerable/map_to_hash'
|
3
|
+
|
4
|
+
class Tengine::ResourceEc2::LaunchOptions
|
5
|
+
|
6
|
+
def initialize(credential)
|
7
|
+
@credential = credential
|
8
|
+
end
|
9
|
+
|
10
|
+
LAUNCH_OPTIONS_KEYS = %w(current_region regions availability_zones key_pairs
|
11
|
+
security_groups images instance_types kernel_ids ramdisk_ids)
|
12
|
+
|
13
|
+
def launch_options(connection, current_region)
|
14
|
+
@connection, @current_region = connection, current_region
|
15
|
+
LAUNCH_OPTIONS_KEYS.map_to_hash{|m| send(m)}
|
16
|
+
ensure
|
17
|
+
@connection, @current_region = nil, nil
|
18
|
+
end
|
19
|
+
|
20
|
+
attr_reader :current_region
|
21
|
+
|
22
|
+
DEFAULT_REGION_CAPTIONS = {
|
23
|
+
"us-east-1" => "US East(Northern Virginia)" ,
|
24
|
+
"us-west-1" => "US West(Northern California)" ,
|
25
|
+
"eu-west-1" => "EU West(Ireland)" ,
|
26
|
+
"ap-southeast-1" => "Asia Pacific(Singapore)",
|
27
|
+
"ap-northeast-1" => "Asia Pacific(Tokyo)",
|
28
|
+
}.freeze
|
29
|
+
|
30
|
+
def regions
|
31
|
+
# ["eu-west-1", "us-east-1", "us-west-1", "ap-southeast-1"]
|
32
|
+
raw = @connection.describe_regions
|
33
|
+
raw.inject([]) do |dest, region|
|
34
|
+
dest << {"name" => region, "caption" => DEFAULT_REGION_CAPTIONS[region]}
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def availability_zones
|
39
|
+
# [
|
40
|
+
# {:region_name=>"us-east-1", :zone_name=>"us-east-1a", :zone_state=>"available"},
|
41
|
+
# {:region_name=>"us-east-1", :zone_name=>"us-east-1b", :zone_state=>"available"},
|
42
|
+
# {:region_name=>"us-east-1", :zone_name=>"us-east-1c", :zone_state=>"available"},
|
43
|
+
# {:region_name=>"us-east-1", :zone_name=>"us-east-1d", :zone_state=>"available"}
|
44
|
+
# ]
|
45
|
+
raw = @connection.describe_availability_zones
|
46
|
+
raw.map{|h| h[:zone_name]}.sort
|
47
|
+
end
|
48
|
+
|
49
|
+
def key_pairs
|
50
|
+
# [{:aws_key_name=>"west-dev01", :aws_fingerprint=>"7c:89:2f:c9:4a:1c:02:65:1b:14:dc:a5:c9:a0:da:fb:46:08:4a:99"}]
|
51
|
+
raw = @connection.describe_key_pairs
|
52
|
+
raw.map{|h| h[:aws_key_name]}
|
53
|
+
end
|
54
|
+
|
55
|
+
def security_groups
|
56
|
+
# [
|
57
|
+
# { :aws_owner=>"892601002221", :aws_group_name=>"default", :aws_description=>"default group",
|
58
|
+
# :aws_perms=>[{:owner=>"892601002221", :group=>"default"}, {:from_port=>"22", :to_port=>"22", :cidr_ips=>"0.0.0.0/0", :protocol=>"tcp"}]},
|
59
|
+
# { :aws_owner=>"892601002221", :aws_group_name=>"ruby-dev", :aws_description=>"for developmewnt with ruby",
|
60
|
+
# :aws_perms=>[{:from_port=>"80", :to_port=>"80", :cidr_ips=>"0.0.0.0/0", :protocol=>"tcp"}]}
|
61
|
+
# ]
|
62
|
+
raw = @connection.describe_security_groups
|
63
|
+
raw.map{|h| h[:aws_group_name]}
|
64
|
+
end
|
65
|
+
|
66
|
+
def images
|
67
|
+
# [
|
68
|
+
# {
|
69
|
+
# :aws_id=>"ami-5189d814",
|
70
|
+
# :aws_architecture=>"i386", :root_device_type=>"instance-store",
|
71
|
+
# :root_device_name=>"/dev/sda1",
|
72
|
+
# :aws_location=>"akm2000-us-west-2/dev-20100521-01.manifest.xml",
|
73
|
+
# :aws_image_type=>"machine", :aws_state=>"available",
|
74
|
+
# :aws_owner=>"892601002221", :aws_is_public=>false,
|
75
|
+
# :aws_kernel_id=>"aki-773c6d32", :aws_ramdisk_id=>"ari-c12e7f84",
|
76
|
+
# },
|
77
|
+
# ]
|
78
|
+
saved_images = Tengine::Resource::VirtualServerImage.all
|
79
|
+
# raw_images = @connection.describe_images_by_owner('self')
|
80
|
+
raw_images = @connection.describe_images(saved_images.map(&:provided_id).uniq.compact) #クラスタに登録されているAMI
|
81
|
+
# raw_images += @connection.describe_images_by_executable_by("self") # 実行可能なAMI
|
82
|
+
amiid_to_hash = raw_images.inject({}){|d, hash| d[hash[:aws_id]] = hash; d}
|
83
|
+
result = saved_images.map do |saved_image|
|
84
|
+
if ami = amiid_to_hash[saved_image.provided_id]
|
85
|
+
{
|
86
|
+
'id' => saved_image.id,
|
87
|
+
'name' => ami[:aws_id],
|
88
|
+
'caption' => saved_image.description,
|
89
|
+
'aws_architecture' => ami[:aws_architecture],
|
90
|
+
'aws_arch_root_dev' => to_aws_arch_root_dev(ami),
|
91
|
+
}
|
92
|
+
else
|
93
|
+
nil
|
94
|
+
end
|
95
|
+
end
|
96
|
+
result.compact.uniq
|
97
|
+
end
|
98
|
+
|
99
|
+
def instance_types
|
100
|
+
# rawなし
|
101
|
+
INSTANCE_TYPES
|
102
|
+
end
|
103
|
+
|
104
|
+
def kernel_ids
|
105
|
+
# [
|
106
|
+
# {
|
107
|
+
# :aws_id=>"aki-233c6d66",
|
108
|
+
# :aws_architecture=>"i386", :root_device_type=>"instance-store",
|
109
|
+
# :aws_location=>"ec2-paid-ibm-images-us-west-1/vmlinuz-2.6.16.60-0.29-xenpae.i386.manifest.xml",
|
110
|
+
# :aws_image_type=>"kernel", :aws_state=>"available", :aws_owner=>"470254534024",
|
111
|
+
# :aws_is_public=>true, :image_owner_alias=>"amazon",
|
112
|
+
# },
|
113
|
+
# ]
|
114
|
+
raw = amazon_images.select{|img| img[:aws_image_type] == 'kernel'}
|
115
|
+
raw.inject({}) do |dest, hash|
|
116
|
+
key = hash[:aws_architecture]
|
117
|
+
dest[key] ||= []
|
118
|
+
dest[key] << hash[:aws_id]
|
119
|
+
dest
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
def ramdisk_ids
|
124
|
+
# [
|
125
|
+
# {
|
126
|
+
# :aws_id=>"ari-2d3c6d68",
|
127
|
+
# :aws_architecture=>"i386", :root_device_type=>"instance-store",
|
128
|
+
# :aws_location=>"ec2-paid-ibm-images-us-west-1/initrd-2.6.16.60-0.29-xenpae.i386.manifest.xml",
|
129
|
+
# :aws_image_type=>"ramdisk", :aws_state=>"available", :aws_owner=>"470254534024",
|
130
|
+
# :aws_is_public=>true, :image_owner_alias=>"amazon"
|
131
|
+
# },
|
132
|
+
# ]
|
133
|
+
raw = amazon_images.select{|img| img[:aws_image_type] == 'ramdisk'}
|
134
|
+
raw.inject({}) do |dest, hash|
|
135
|
+
key = hash[:aws_architecture]
|
136
|
+
dest[key] ||= []
|
137
|
+
dest[key] << hash[:aws_id]
|
138
|
+
dest
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
private
|
143
|
+
|
144
|
+
def amazon_images
|
145
|
+
@amazon_images ||= @connection.describe_images_by_owner('amazon')
|
146
|
+
end
|
147
|
+
|
148
|
+
|
149
|
+
def to_aws_arch_root_dev(hash)
|
150
|
+
"#{hash[:aws_architecture]}_#{hash[:root_device_type]}"
|
151
|
+
end
|
152
|
+
|
153
|
+
INSTANCE_TYPES = {
|
154
|
+
'i386_instance-store' => [
|
155
|
+
{ "value" => "m1.small" , "caption" => "Small" },
|
156
|
+
{ "value" => "c1.medium" , "caption" => "High-CPU Medium" },
|
157
|
+
].freeze,
|
158
|
+
'i386_ebs' => [
|
159
|
+
{ "value" => "t1.micro" , "caption" => "Micro" },
|
160
|
+
{ "value" => "m1.small" , "caption" => "Small" },
|
161
|
+
{ "value" => "c1.medium" , "caption" => "High-CPU Medium" },
|
162
|
+
].freeze,
|
163
|
+
'x86_64_instance-store' => [
|
164
|
+
{ "value" => "m1.large" , "caption" => "Large" },
|
165
|
+
{ "value" => "m1.xlarge" , "caption" => "Extra Large" },
|
166
|
+
{ "value" => "m2.xlarge" , "caption" => "High-Memory Extra Large" },
|
167
|
+
{ "value" => "m2.2xlarge", "caption" => "High-Memory Double Extra Large" },
|
168
|
+
{ "value" => "m2.4xlarge", "caption" => "High-Memory Quadruple Extra Large" },
|
169
|
+
{ "value" => "c1.xlarge" , "caption" => "High-CPU Extra Large" },
|
170
|
+
].freeze,
|
171
|
+
'x86_64_ebs' => [
|
172
|
+
{ "value" => "t1.micro" , "caption" => "Micro" },
|
173
|
+
{ "value" => "m1.large" , "caption" => "Large" },
|
174
|
+
{ "value" => "m1.xlarge" , "caption" => "Extra Large" },
|
175
|
+
{ "value" => "m2.xlarge" , "caption" => "High-Memory Extra Large" },
|
176
|
+
{ "value" => "m2.2xlarge", "caption" => "High-Memory Double Extra Large" },
|
177
|
+
{ "value" => "m2.4xlarge", "caption" => "High-Memory Quadruple Extra Large" },
|
178
|
+
{ "value" => "c1.xlarge" , "caption" => "High-CPU Extra Large" },
|
179
|
+
].freeze,
|
180
|
+
}.freeze
|
181
|
+
|
182
|
+
end
|