tengine_resource 0.5.13

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.
Files changed (100) hide show
  1. data/.document +5 -0
  2. data/.rspec +1 -0
  3. data/Gemfile +30 -0
  4. data/Gemfile.lock +106 -0
  5. data/README.rdoc +20 -0
  6. data/Rakefile +42 -0
  7. data/VERSION +1 -0
  8. data/bin/tengine_resource_watchd +8 -0
  9. data/config/.gitignore +2 -0
  10. data/config/watchd.yml.erb.example +52 -0
  11. data/lib/tengine/resource.rb +29 -0
  12. data/lib/tengine/resource/config.rb +6 -0
  13. data/lib/tengine/resource/config/resource.rb +194 -0
  14. data/lib/tengine/resource/credential.rb +156 -0
  15. data/lib/tengine/resource/credential/ec2.rb +5 -0
  16. data/lib/tengine/resource/credential/ec2/dummy.rb +148 -0
  17. data/lib/tengine/resource/credential/ec2/launch_options.rb +179 -0
  18. data/lib/tengine/resource/drivers/resource_control_driver.rb +58 -0
  19. data/lib/tengine/resource/net_ssh.rb +134 -0
  20. data/lib/tengine/resource/observer.rb +25 -0
  21. data/lib/tengine/resource/physical_server.rb +7 -0
  22. data/lib/tengine/resource/provider.rb +82 -0
  23. data/lib/tengine/resource/provider/ec2.rb +187 -0
  24. data/lib/tengine/resource/provider/wakame.rb +615 -0
  25. data/lib/tengine/resource/server.rb +62 -0
  26. data/lib/tengine/resource/virtual_server.rb +62 -0
  27. data/lib/tengine/resource/virtual_server_image.rb +34 -0
  28. data/lib/tengine/resource/virtual_server_type.rb +21 -0
  29. data/lib/tengine/resource/watcher.rb +121 -0
  30. data/lib/tengine_resource.rb +4 -0
  31. data/spec/fixtures/goku_at_ec2_ap_northeast.rb +177 -0
  32. data/spec/mongoid.yml +35 -0
  33. data/spec/spec_helper.rb +40 -0
  34. data/spec/support/ec2.rb +129 -0
  35. data/spec/support/mongo_index_key_log.rb +91 -0
  36. data/spec/tengine/resource/bugfix/watcher_for_wakame_spec.rb +232 -0
  37. data/spec/tengine/resource/credential_spec.rb +205 -0
  38. data/spec/tengine/resource/drivers/resource_control_driver_spec.rb +84 -0
  39. data/spec/tengine/resource/net_ssh_spec.rb +148 -0
  40. data/spec/tengine/resource/physical_server_spec.rb +47 -0
  41. data/spec/tengine/resource/provider/ec2_spec.rb +473 -0
  42. data/spec/tengine/resource/provider/test_files/describe_host_nodes.json +22 -0
  43. data/spec/tengine/resource/provider/test_files/describe_images.json +23 -0
  44. data/spec/tengine/resource/provider/test_files/describe_instance_specs.json +23 -0
  45. data/spec/tengine/resource/provider/test_files/describe_instances.json +56 -0
  46. data/spec/tengine/resource/provider/test_files/run_instances.json +30 -0
  47. data/spec/tengine/resource/provider/test_files/terminate_instances.json +3 -0
  48. data/spec/tengine/resource/provider/wakame/00_describe_host_nodes_0_physical_servers.json +8 -0
  49. data/spec/tengine/resource/provider/wakame/01_describe_host_nodes_10_physical_servers.json +139 -0
  50. data/spec/tengine/resource/provider/wakame/02_describe_host_nodes_60_physical_servers.json +795 -0
  51. data/spec/tengine/resource/provider/wakame/10_describe_instances_0_virtual_servers.json +8 -0
  52. data/spec/tengine/resource/provider/wakame/11_describe_instances_10_virtual_servers.json +469 -0
  53. data/spec/tengine/resource/provider/wakame/12_describe_instances_after_run_instances.json +280 -0
  54. data/spec/tengine/resource/provider/wakame/13_describe_instances_after_terminate_instances.json +279 -0
  55. data/spec/tengine/resource/provider/wakame/20_describe_images_0_virtual_server_images.json +8 -0
  56. data/spec/tengine/resource/provider/wakame/21_describe_images_5_virtual_server_images.json +84 -0
  57. data/spec/tengine/resource/provider/wakame/22_describe_images_60_virtual_server_images.json +856 -0
  58. data/spec/tengine/resource/provider/wakame/30_describe_instance_specs_0_virtual_server_specs.json +8 -0
  59. data/spec/tengine/resource/provider/wakame/31_describe_instance_specs_4_virtual_server_specs.json +66 -0
  60. data/spec/tengine/resource/provider/wakame/40_run_instances_0_virtual_servers.json +1 -0
  61. data/spec/tengine/resource/provider/wakame/41_run_instances_1_virtual_servers.json +22 -0
  62. data/spec/tengine/resource/provider/wakame/42_run_instances_5_virtual_servers.json +106 -0
  63. data/spec/tengine/resource/provider/wakame/50_terminate_instances_0_virtual_servers.json +1 -0
  64. data/spec/tengine/resource/provider/wakame/51_terminate_instances_3_virtual_servers.json +5 -0
  65. data/spec/tengine/resource/provider/wakame/sync_physical_servers_spec.rb +114 -0
  66. data/spec/tengine/resource/provider/wakame/sync_virtual_server_images_spec.rb +116 -0
  67. data/spec/tengine/resource/provider/wakame/sync_virtual_server_types_spec.rb +116 -0
  68. data/spec/tengine/resource/provider/wakame/sync_virtual_servers_spec.rb +216 -0
  69. data/spec/tengine/resource/provider/wakame_api_spec.rb +319 -0
  70. data/spec/tengine/resource/provider/wakame_spec.rb +339 -0
  71. data/spec/tengine/resource/provider_spec.rb +252 -0
  72. data/spec/tengine/resource/server_spec.rb +195 -0
  73. data/spec/tengine/resource/test_files/.gitignore +6 -0
  74. data/spec/tengine/resource/test_files/00_describe_host_nodes_0_physical_servers.json +8 -0
  75. data/spec/tengine/resource/test_files/01_describe_host_nodes_10_physical_servers.json +139 -0
  76. data/spec/tengine/resource/test_files/02_describe_host_nodes_60_physical_servers.json +795 -0
  77. data/spec/tengine/resource/test_files/10_describe_instances_0_virtual_servers.json +8 -0
  78. data/spec/tengine/resource/test_files/11_describe_instances_10_virtual_servers.json +469 -0
  79. data/spec/tengine/resource/test_files/12_describe_instances_after_run_instances.json +280 -0
  80. data/spec/tengine/resource/test_files/13_describe_instances_after_terminate_instances.json +279 -0
  81. data/spec/tengine/resource/test_files/14_describe_instances_after_run_1_instance.json +55 -0
  82. data/spec/tengine/resource/test_files/20_describe_images_0_virtual_server_images.json +8 -0
  83. data/spec/tengine/resource/test_files/21_describe_images_5_virtual_server_images.json +84 -0
  84. data/spec/tengine/resource/test_files/22_describe_images_60_virtual_server_images.json +856 -0
  85. data/spec/tengine/resource/test_files/30_describe_instance_specs_0_virtual_server_specs.json +8 -0
  86. data/spec/tengine/resource/test_files/31_describe_instance_specs_4_virtual_server_specs.json +66 -0
  87. data/spec/tengine/resource/test_files/40_run_instances_0_virtual_servers.json +1 -0
  88. data/spec/tengine/resource/test_files/41_run_instances_1_virtual_servers.json +22 -0
  89. data/spec/tengine/resource/test_files/42_run_instances_5_virtual_servers.json +106 -0
  90. data/spec/tengine/resource/test_files/43_run_instances_1_virtual_servers_without_aws_availability_zone.json +22 -0
  91. data/spec/tengine/resource/test_files/50_terminate_instances_0_virtual_servers.json +1 -0
  92. data/spec/tengine/resource/test_files/51_terminate_instances_3_virtual_servers.json +5 -0
  93. data/spec/tengine/resource/virtual_server_image_spec.rb +94 -0
  94. data/spec/tengine/resource/virtual_server_spec.rb +116 -0
  95. data/spec/tengine/resource/virtual_server_type_spec.rb +4 -0
  96. data/spec/tengine/resource/watcher_spec.rb +1026 -0
  97. data/spec/tengine_resource_spec.rb +5 -0
  98. data/tengine_resource.gemspec +171 -0
  99. data/tmp/log/.gitignore +1 -0
  100. metadata +286 -0
@@ -0,0 +1,62 @@
1
+ # -*- coding: utf-8 -*-
2
+ require 'mongoid'
3
+
4
+ class Tengine::Resource::Server
5
+ include Mongoid::Document
6
+ include Mongoid::Timestamps
7
+ include Tengine::Core::CollectionAccessible
8
+ include Tengine::Core::Validation
9
+ include Tengine::Core::FindByName
10
+
11
+ field :name , :type => String
12
+ field :description , :type => String
13
+ field :provided_id , :type => String
14
+ field :status , :type => String
15
+
16
+ field :addresses , :type => Hash, :default => {}
17
+ map_yaml_accessor :addresses
18
+
19
+ field :address_order , :type => Array, :default => ['private_ip_address', 'private_dns_name', 'ip_address', 'dns_name']
20
+
21
+ field :properties , :type => Hash
22
+ map_yaml_accessor :properties
23
+
24
+ validates :name, :presence => true, :format => BASE_NAME.options
25
+
26
+ validates :name, :uniqueness => {:scope => :provider_id}, :if => :need_to_validate_name_uniqueness?
27
+ index [[:name, Mongo::ASCENDING], [:provider_id, Mongo::ASCENDING], ], :unique => true
28
+
29
+ index([ [:status, Mongo::ASCENDING], [:_type, Mongo::ASCENDING], ])
30
+
31
+ has_many :guest_servers, :class_name => "Tengine::Resource::VirtualServer", :inverse_of => :host_server
32
+
33
+ def need_to_validate_name_uniqueness?; true; end
34
+
35
+ class << self
36
+ def find_or_create_by_name!(attrs = {}, &block)
37
+ result = Tengine::Resource::Server.first(:conditions => {:name => attrs[:name]})
38
+ result ||= self.create!(attrs)
39
+ result
40
+ end
41
+ end
42
+
43
+ def hostname_or_ipv4
44
+ address_order.map{|key| addresses[key]}.detect{|s| !s.blank?} # nilだけでなく空文字列も考慮する必要があります
45
+ end
46
+
47
+ def hostname_or_ipv4?
48
+ !!hostname_or_ipv4
49
+ end
50
+
51
+ %w[public_hostname public_ipv4 local_hostname local_ipv4].each do |address_key|
52
+ class_eval(<<-END_OF_METHOD, __FILE__, __LINE__ + 1)
53
+ def #{address_key}
54
+ addresses['#{address_key}']
55
+ end
56
+ def #{address_key}=(value)
57
+ addresses['#{address_key}'] = value
58
+ end
59
+ END_OF_METHOD
60
+ end
61
+
62
+ end
@@ -0,0 +1,62 @@
1
+ # -*- coding: utf-8 -*-
2
+ class Tengine::Resource::VirtualServer < Tengine::Resource::Server
3
+ field :provided_image_id, :type => String
4
+ field :provided_type_id, :type => String
5
+
6
+ belongs_to :host_server, :inverse_of => :guest_servers, :index => true,
7
+ :class_name => "Tengine::Resource::Server"
8
+ belongs_to :provider, :index => true, :inverse_of => :virtual_servers,
9
+ :class_name => "Tengine::Resource::Provider"
10
+
11
+ validates_uniqueness_of :provided_id, :scope => :provider_id, :unless => :ignore_provided_id_uniqueness
12
+ index [[:provided_id, Mongo::ASCENDING], [:provider_id, Mongo::ASCENDING], ], :unique => true
13
+
14
+ ## launch_modeに関する実装
15
+
16
+ class LaunchValidator < ActiveModel::Validator
17
+ def validate(record)
18
+ base_attrs = record.attributes.dup.freeze
19
+ error_names = []
20
+ (1..record.launch_count).each do |idx|
21
+ # see also Tengine::Resource::Provider::Ec2#create_virtual_servers
22
+ name = sprintf("%s%03d", record.name, idx) # 1 origin
23
+ server = Tengine::Resource::VirtualServer.new(base_attrs.merge(
24
+ :ignore_provided_id_uniqueness => true,
25
+ :name => name
26
+ ))
27
+ next if server.valid?
28
+ server.errors.each do |key, msg|
29
+ if key == :name
30
+ error_names << server.name
31
+ else
32
+ record.errors.add(key, msg)
33
+ end
34
+ end
35
+ end
36
+ unless error_names.empty?
37
+ # record.name = error_names.join(",")
38
+ # record.errors.add(:name, :taken)
39
+ record.errors.add(:name, "に指定された%sは既に登録されています" % error_names.join(","))
40
+ end
41
+ end
42
+ end
43
+
44
+ validates_with LaunchValidator, :if => Proc.new{|r| r.launch_mode?}
45
+
46
+ attr_accessor :ignore_provided_id_uniqueness
47
+
48
+ attr_reader :launch_count
49
+ attr_reader :launch_count_max
50
+ def launch_count=(val); @launch_count = val ? val.to_i : nil; end
51
+ def launch_count_max=(val); @launch_count_max = val ? val.to_i : nil; end
52
+
53
+ def launch_mode?
54
+ !launch_count.nil?
55
+ end
56
+
57
+ # launch_mode?の場合はnameの一意性のバリデーションは行わない
58
+ def need_to_validate_name_uniqueness?
59
+ !launch_mode?
60
+ end
61
+
62
+ end
@@ -0,0 +1,34 @@
1
+ require 'mongoid'
2
+
3
+ class Tengine::Resource::VirtualServerImage
4
+ include Mongoid::Document
5
+ include Mongoid::Timestamps
6
+ include Tengine::Core::Validation
7
+ include Tengine::Core::FindByName
8
+
9
+ field :name, :type => String
10
+ field :description, :type => String
11
+ field :provided_id, :type => String
12
+ field :provided_description, :type => String
13
+
14
+ belongs_to :provider, :inverse_of => :virtual_server_images, :index => true,
15
+ :class_name => "Tengine::Resource::Provider"
16
+
17
+ validates :name, :presence => true, :uniqueness => true, :format => BASE_NAME.options
18
+ index :name, :unique => true
19
+
20
+ index([ [:description, Mongo::ASCENDING], ])
21
+ index([ [:description, Mongo::DESCENDING], ])
22
+ index([ [:provided_description, Mongo::ASCENDING], ])
23
+ index([ [:provided_description, Mongo::DESCENDING], ])
24
+ index([ [:provided_id, Mongo::ASCENDING], ])
25
+ index([ [:provided_id, Mongo::DESCENDING], ])
26
+
27
+ class << self
28
+ def find_or_create_by_name!(attrs = {}, &block)
29
+ result = self.first(:conditions => {:name => attrs[:name]})
30
+ result ||= self.create!(attrs)
31
+ result
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,21 @@
1
+ require 'tengine/resource'
2
+
3
+ class Tengine::Resource::VirtualServerType
4
+ include Mongoid::Document
5
+ include Mongoid::Timestamps
6
+ include Tengine::Core::CollectionAccessible
7
+ include Tengine::Core::Validation
8
+
9
+ field :provided_id, :type => String
10
+ field :caption, :type => String
11
+ field :cpu_cores, :type => Integer
12
+ field :memory_size, :type => Integer
13
+ field :properties, :type => Hash
14
+ map_yaml_accessor :properties
15
+
16
+ referenced_in :provider, :inverse_of => :virtual_server_types, :index => true,
17
+ :class_name => "Tengine::Resource::Provider"
18
+
19
+ validates :provided_id, :presence => true, :uniqueness => {:scope => :provider_id}
20
+ index [ [:provider_id, Mongo::ASCENDING] , [:provided_id, Mongo::ASCENDING] ], :unique => true
21
+ end
@@ -0,0 +1,121 @@
1
+ # -*- coding: utf-8 -*-
2
+ require 'daemons'
3
+ require 'mongoid'
4
+ require 'eventmachine'
5
+ require 'tengine/event'
6
+ require 'tengine/mq'
7
+ require 'tengine/resource/config'
8
+ require 'tengine/core/mongoid_fix'
9
+
10
+ class Tengine::Resource::Watcher
11
+
12
+ attr_reader :config, :pid
13
+
14
+ def initialize(argv = [])
15
+ @config = Tengine::Resource::Config::Resource.parse(argv)
16
+ @pid = sprintf("process:%s/%d", ENV["MM_SERVER_NAME"], Process.pid)
17
+ @mq_config = config[:event_queue].to_hash
18
+ @mq_config[:sender] = { :keep_connection => true }
19
+ @daemonize_options = {
20
+ :app_name => 'tengine_resource_watchd',
21
+ :ARGV => [config[:action]],
22
+ :ontop => !config[:process][:daemon],
23
+ # :monitor => true,
24
+ :multiple => true,
25
+ :dir_mode => :normal,
26
+ :dir => File.expand_path(config[:process][:pid_dir]),
27
+ }
28
+
29
+ # 必要なディレクトリの生成
30
+ FileUtils.mkdir_p(File.expand_path(config[:process][:pid_dir]))
31
+
32
+ Tengine::Core::MethodTraceable.disabled = !config[:verbose]
33
+ rescue Exception
34
+ puts "[#{$!.class.name}] #{$!.message}\n " << $!.backtrace.join("\n ")
35
+ raise
36
+ end
37
+
38
+ def mq_suite
39
+ @mq_suite ||= Tengine::Mq::Suite.new(@mq_config)
40
+ Tengine::Event.mq_suite = @mq_suite
41
+ end
42
+
43
+ def sender
44
+ @sender ||= Tengine::Event::Sender.new(mq_suite)
45
+ Tengine::Event.default_sender = @sender
46
+ end
47
+
48
+ def run(__file__)
49
+ case config[:action].to_sym
50
+ when :start
51
+ start_daemon(__file__)
52
+ when :stop
53
+ stop_daemon(__file__)
54
+ when :restart
55
+ stop_daemon(__file__)
56
+ start_daemon(__file__)
57
+ end
58
+ end
59
+
60
+ def start_daemon(__file__)
61
+ fname = File.basename __file__
62
+ cwd = Dir.getwd
63
+ Daemons.run_proc(fname, @daemonize_options) do
64
+ Dir.chdir(cwd) { self.start }
65
+ end
66
+ end
67
+
68
+ def stop_daemon(__file__)
69
+ fname = File.basename __file__
70
+ Daemons.run_proc(fname, @daemonize_options)
71
+ end
72
+
73
+ def start
74
+ @config.setup_loggers
75
+ # observerの登録
76
+ Mongoid.observers = Tengine::Resource::Observer
77
+ Mongoid.instantiate_observers
78
+
79
+ Mongoid.config.from_hash(config[:db])
80
+ Mongoid.config.option(:persist_in_safe_mode, :default => true)
81
+
82
+ EM.run do
83
+ sender.wait_for_connection do
84
+ providers = Tengine::Resource::Provider.all
85
+ providers.each do |provider|
86
+
87
+ provider.retry_on_error = true if provider.respond_to?(:retry_on_error=)
88
+ # polling_intervalが 0 以下の場合は、問い合わせを行わない
89
+ if (polling_interval = provider.polling_interval) > 0
90
+ # 仮想サーバタイプの監視
91
+ provider.virtual_server_type_watch
92
+ mutex = Tengine::Core::Mutex.new "#{provider.name}@#{self.class}", provider.polling_interval
93
+ @periodic = EM.add_periodic_timer(provider.polling_interval) do
94
+ mutex.synchronize do
95
+ # 物理サーバの監視
96
+ provider.physical_server_watch
97
+ mutex.heartbeat
98
+ # 仮想サーバの監視
99
+ provider.virtual_server_watch
100
+ mutex.heartbeat
101
+ # 仮想サーバイメージの監視
102
+ provider.virtual_server_image_watch
103
+ end
104
+ end
105
+ end
106
+ end
107
+ end
108
+ end
109
+ end
110
+
111
+ def shutdown
112
+ EM.run do
113
+ EM.cancel_timer @periodic if @periodic
114
+ sender.stop
115
+ end
116
+ end
117
+
118
+ extend Tengine::Core::MethodTraceable
119
+ method_trace(*instance_methods(false))
120
+
121
+ end
@@ -0,0 +1,4 @@
1
+ require 'tengine_core'
2
+ require 'tengine/resource'
3
+
4
+ Tengine.plugins.add(Tengine::Resource)
@@ -0,0 +1,177 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ class GokuAtEc2ApNortheast
4
+ # # memoize については http://wota.jp/ac/?date=20081025#p11 などを参照してください
5
+ # extend ActiveSupport::Memoizable
6
+
7
+ def provider
8
+ Tengine::Resource::Provider::Ec2.find_or_create_by_name!({
9
+ :name => "goku_at_ec2_ap-northeast-1",
10
+ :connection_settings => {
11
+ :access_key => '12345',
12
+ :secret_access_key => '1234567',
13
+ :default_region => 'ap-northeast-1',
14
+ }
15
+ })
16
+ end
17
+
18
+ def goku_ssh_pw
19
+ Tengine::Resource::Credential.find_or_create_by_name!(
20
+ :name => "goku_ssh_pw",
21
+ :auth_type_key => :ssh_password,
22
+ :auth_values => {
23
+ :username => 'goku',
24
+ :password => 'dragonball'
25
+ })
26
+ end
27
+
28
+ def gohan_ssh_pk
29
+ Tengine::Resource::Credential.find_or_create_by_name!(
30
+ :name => "gohan_ssh_pk",
31
+ :auth_type_key => :ssh_public_key,
32
+ :auth_values => {
33
+ :username => 'gohan',
34
+ :private_keys => "1234567890",
35
+ :passphrase => 'dragonball'
36
+ })
37
+ end
38
+
39
+ def physical_servers
40
+ [availability_zone(1), availability_zone(2)]
41
+ end
42
+
43
+ def availability_zone(idx)
44
+ name = "ap-notrheast-1" + ("a".ord - 1 + idx).chr
45
+ Tengine::Resource::PhysicalServer.find_or_create_by_name!(
46
+ :provider_id => provider.id,
47
+ :name => name, :provided_id => name, :status => "available")
48
+ end
49
+
50
+ def virtual_server_images
51
+ [
52
+ hadoop_image,
53
+ mysql_image,
54
+ rails_image
55
+ ]
56
+ end
57
+
58
+ def hadoop_image
59
+ Tengine::Resource::VirtualServerImage.find_or_create_by_name!(
60
+ :provider_id => provider.id,
61
+ :name => "hadoop_image1",
62
+ :provided_id => "ami-10000001")
63
+ end
64
+
65
+ def mysql_image
66
+ Tengine::Resource::VirtualServerImage.find_or_create_by_name!(
67
+ :provider_id => provider.id,
68
+ :name => "mysql_image1",
69
+ :provided_id => "ami-10000002")
70
+ end
71
+
72
+ def rails_image
73
+ Tengine::Resource::VirtualServerImage.find_or_create_by_name!(
74
+ :provider_id => provider.id,
75
+ :name => "rails_image1",
76
+ :provided_id => "ami-10000003")
77
+ end
78
+
79
+ def virtual_server_types
80
+ [
81
+ m1_small,
82
+ m1_large,
83
+ m1_xlarge,
84
+ t1_micro,
85
+ ]
86
+ end
87
+
88
+ def m1_small
89
+ Tengine::Resource::VirtualServerType.find_or_create_by(:provider_id => provider.id,
90
+ :caption => "m1.small", :provided_id => "m1.small", :cpu_cores => 1, :memory_size => 17 * (10 ** 8))
91
+ end
92
+
93
+ def m1_large
94
+ Tengine::Resource::VirtualServerType.find_or_create_by(:provider_id => provider.id,
95
+ :caption => "m1.large", :provided_id => "m1.large", :cpu_cores => 4, :memory_size => 75 * (10 ** 8))
96
+ end
97
+
98
+ def m1_xlarge
99
+ Tengine::Resource::VirtualServerType.find_or_create_by(:provider_id => provider.id,
100
+ :caption => "m1.xlarge", :provided_id => "m1.xlarge", :cpu_cores => 8, :memory_size => 15 * (10 ** 9))
101
+ end
102
+
103
+ def t1_micro
104
+ Tengine::Resource::VirtualServerType.find_or_create_by(:provider_id => provider.id,
105
+ :caption => "t1.micro", :provided_id => "t1.micro", :cpu_cores => 2, :memory_size => 613 * (10 ** 6))
106
+ end
107
+
108
+
109
+ def virtual_servers
110
+ [
111
+ hadoop_master_node,
112
+ hadoop_slave_node(1),
113
+ hadoop_slave_node(2),
114
+ hadoop_slave_node(3),
115
+ mysql_master,
116
+ mysql_slave(1),
117
+ mysql_slave(2),
118
+ rails_server(1)
119
+ ]
120
+ end
121
+
122
+ def hadoop_master_node
123
+ Tengine::Resource::VirtualServer.find_or_create_by_name!(
124
+ :addresses => hostnames_and_ips(1),
125
+ :provider_id => provider.id,
126
+ :provided_image_id => hadoop_image.provided_id,
127
+ :host_server_id => availability_zone(1).id, :status => "available",
128
+ :name => "hadoop_master_node", :provided_id => "i-10000001")
129
+ end
130
+
131
+ def hadoop_slave_node(idx)
132
+ Tengine::Resource::VirtualServer.find_or_create_by_name!(
133
+ :addresses => hostnames_and_ips(idx + 10),
134
+ :provider_id => provider.id,
135
+ :provided_image_id => hadoop_image.provided_id,
136
+ :host_server_id => availability_zone(1).id, :status => "available",
137
+ :name => "hadoop_slave_node#{idx}", :provided_id => "i-1000001#{idx}")
138
+ end
139
+
140
+ def mysql_master
141
+ Tengine::Resource::VirtualServer.find_or_create_by_name!(
142
+ :addresses => hostnames_and_ips(20),
143
+ :provider_id => provider.id,
144
+ :provided_image_id => mysql_image.provided_id,
145
+ :host_server_id => availability_zone(1).id, :status => "available",
146
+ :name => "mysql_master", :provided_id => "i-10000020")
147
+ end
148
+
149
+ def mysql_slave(idx)
150
+ Tengine::Resource::VirtualServer.find_or_create_by_name!(
151
+ :addresses => hostnames_and_ips(idx + 20),
152
+ :provider_id => provider.id,
153
+ :provided_image_id => mysql_image.provided_id,
154
+ :host_server_id => availability_zone(1).id, :status => "available",
155
+ :name => "mysql_slave#{idx}", :provided_id => "i-1000002#{idx}")
156
+ end
157
+
158
+ def rails_server(idx)
159
+ Tengine::Resource::VirtualServer.find_or_create_by_name!(
160
+ :addresses => hostnames_and_ips(idx + 30),
161
+ :provider_id => provider.id,
162
+ :provided_image_id => rails_image.provided_id,
163
+ :host_server_id => availability_zone(1).id, :status => "available",
164
+ :name => "rails#{idx}", :provided_id => "i-1000003#{idx}")
165
+ end
166
+
167
+ private
168
+ def hostnames_and_ips(idx)
169
+ {
170
+ 'dns_name' => "ec2-184-72-20-#{idx}.ap-northeast-1.compute.amazonaws.com",
171
+ 'ip_address' => "184.72.20.#{idx}",
172
+ 'private_dns_name' => "ip-10-162-153-#{idx}.ap-northeast-1.compute.internal",
173
+ 'private_ip_address' => "10.162.153.#{idx}",
174
+ }
175
+ end
176
+
177
+ end