wakame-vdc-dcmgr 11.06.0 → 11.12.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (136) hide show
  1. data/Rakefile +19 -31
  2. data/bin/collector +6 -1
  3. data/config/db/migrations/0001_v1110_origin.rb +446 -0
  4. data/config/dcmgr.conf.example +51 -0
  5. data/lib/dcmgr.rb +99 -22
  6. data/lib/dcmgr/cli/base.rb +34 -1
  7. data/lib/dcmgr/cli/host.rb +24 -20
  8. data/lib/dcmgr/cli/image.rb +38 -19
  9. data/lib/dcmgr/cli/keypair.rb +16 -12
  10. data/lib/dcmgr/cli/network.rb +189 -81
  11. data/lib/dcmgr/cli/quota.rb +2 -2
  12. data/lib/dcmgr/cli/security_group.rb +106 -0
  13. data/lib/dcmgr/cli/spec.rb +144 -39
  14. data/lib/dcmgr/cli/storage.rb +16 -15
  15. data/lib/dcmgr/cli/tag.rb +20 -14
  16. data/lib/dcmgr/cli/vlan.rb +5 -5
  17. data/lib/dcmgr/drivers/backing_store.rb +32 -0
  18. data/lib/dcmgr/drivers/comstar.rb +81 -0
  19. data/lib/dcmgr/drivers/iijgio_storage.rb +9 -19
  20. data/lib/dcmgr/drivers/iscsi_target.rb +41 -0
  21. data/lib/dcmgr/drivers/kvm.rb +161 -28
  22. data/lib/dcmgr/drivers/linux_iscsi.rb +60 -0
  23. data/lib/dcmgr/drivers/local_storage.rb +24 -0
  24. data/lib/dcmgr/drivers/lxc.rb +167 -125
  25. data/lib/dcmgr/drivers/raw.rb +74 -0
  26. data/lib/dcmgr/drivers/s3_storage.rb +7 -19
  27. data/lib/dcmgr/drivers/snapshot_storage.rb +18 -28
  28. data/lib/dcmgr/drivers/storage_initiator.rb +28 -0
  29. data/lib/dcmgr/drivers/sun_iscsi.rb +32 -0
  30. data/lib/dcmgr/drivers/zfs.rb +77 -0
  31. data/lib/dcmgr/endpoints/core_api.rb +315 -263
  32. data/lib/dcmgr/endpoints/errors.rb +21 -10
  33. data/lib/dcmgr/endpoints/metadata.rb +360 -23
  34. data/lib/dcmgr/helpers/cli_helper.rb +6 -3
  35. data/lib/dcmgr/helpers/ec2_metadata_helper.rb +9 -0
  36. data/lib/dcmgr/helpers/nic_helper.rb +11 -0
  37. data/lib/dcmgr/helpers/snapshot_storage_helper.rb +34 -0
  38. data/lib/dcmgr/models/account.rb +0 -6
  39. data/lib/dcmgr/models/account_resource.rb +0 -4
  40. data/lib/dcmgr/models/base_new.rb +14 -2
  41. data/lib/dcmgr/models/dhcp_range.rb +38 -0
  42. data/lib/dcmgr/models/frontend_system.rb +0 -6
  43. data/lib/dcmgr/models/history.rb +0 -11
  44. data/lib/dcmgr/models/host_node.rb +131 -0
  45. data/lib/dcmgr/models/hostname_lease.rb +0 -8
  46. data/lib/dcmgr/models/image.rb +31 -18
  47. data/lib/dcmgr/models/instance.rb +137 -143
  48. data/lib/dcmgr/models/instance_nic.rb +52 -29
  49. data/lib/dcmgr/models/instance_security_group.rb +9 -0
  50. data/lib/dcmgr/models/instance_spec.rb +163 -31
  51. data/lib/dcmgr/models/ip_lease.rb +10 -21
  52. data/lib/dcmgr/models/mac_lease.rb +30 -11
  53. data/lib/dcmgr/models/network.rb +148 -27
  54. data/lib/dcmgr/models/physical_network.rb +18 -0
  55. data/lib/dcmgr/models/quota.rb +0 -10
  56. data/lib/dcmgr/models/request_log.rb +3 -18
  57. data/lib/dcmgr/models/security_group.rb +66 -0
  58. data/lib/dcmgr/models/security_group_rule.rb +145 -0
  59. data/lib/dcmgr/models/ssh_key_pair.rb +16 -19
  60. data/lib/dcmgr/models/{storage_pool.rb → storage_node.rb} +35 -25
  61. data/lib/dcmgr/models/tag.rb +0 -14
  62. data/lib/dcmgr/models/tag_mapping.rb +1 -7
  63. data/lib/dcmgr/models/vlan_lease.rb +2 -8
  64. data/lib/dcmgr/models/volume.rb +49 -37
  65. data/lib/dcmgr/models/volume_snapshot.rb +15 -17
  66. data/lib/dcmgr/node_modules/hva_collector.rb +69 -28
  67. data/lib/dcmgr/node_modules/instance_ha.rb +23 -12
  68. data/lib/dcmgr/node_modules/instance_monitor.rb +16 -2
  69. data/lib/dcmgr/node_modules/openflow_controller.rb +784 -0
  70. data/lib/dcmgr/node_modules/scheduler.rb +189 -0
  71. data/lib/dcmgr/node_modules/service_netfilter.rb +452 -227
  72. data/lib/dcmgr/node_modules/service_openflow.rb +731 -0
  73. data/lib/dcmgr/node_modules/sta_collector.rb +20 -0
  74. data/lib/dcmgr/node_modules/sta_tgt_initializer.rb +35 -0
  75. data/lib/dcmgr/rack/request_logger.rb +11 -6
  76. data/lib/dcmgr/rpc/hva_handler.rb +256 -110
  77. data/lib/dcmgr/rpc/sta_handler.rb +244 -0
  78. data/lib/dcmgr/scheduler.rb +122 -8
  79. data/lib/dcmgr/scheduler/host_node/exclude_same.rb +24 -0
  80. data/lib/dcmgr/scheduler/host_node/find_first.rb +12 -0
  81. data/lib/dcmgr/scheduler/host_node/least_usage.rb +28 -0
  82. data/lib/dcmgr/scheduler/host_node/per_instance.rb +18 -0
  83. data/lib/dcmgr/scheduler/host_node/specify_node.rb +26 -0
  84. data/lib/dcmgr/scheduler/network/flat_single.rb +23 -0
  85. data/lib/dcmgr/scheduler/network/nat_one_to_one.rb +23 -0
  86. data/lib/dcmgr/scheduler/network/per_instance.rb +39 -0
  87. data/lib/dcmgr/scheduler/network/vif_template.rb +19 -0
  88. data/lib/dcmgr/scheduler/storage_node/find_first.rb +13 -0
  89. data/lib/dcmgr/scheduler/storage_node/least_usage.rb +23 -0
  90. data/lib/dcmgr/storage_service.rb +39 -40
  91. data/lib/dcmgr/tags.rb +3 -3
  92. data/lib/dcmgr/version.rb +1 -1
  93. data/lib/dcmgr/vnet.rb +105 -0
  94. data/lib/dcmgr/vnet/factories.rb +141 -0
  95. data/lib/dcmgr/vnet/isolators/by_securitygroup.rb +21 -0
  96. data/lib/dcmgr/vnet/isolators/dummy.rb +17 -0
  97. data/lib/dcmgr/vnet/netfilter/cache.rb +51 -0
  98. data/lib/dcmgr/vnet/netfilter/chain.rb +66 -0
  99. data/lib/dcmgr/vnet/netfilter/controller.rb +193 -0
  100. data/lib/dcmgr/vnet/netfilter/ebtables_rule.rb +53 -0
  101. data/lib/dcmgr/vnet/netfilter/iptables_rule.rb +45 -0
  102. data/lib/dcmgr/vnet/netfilter/task_manager.rb +459 -0
  103. data/lib/dcmgr/vnet/tasks/accept_all_dns.rb +19 -0
  104. data/lib/dcmgr/vnet/tasks/accept_arp_broadcast.rb +24 -0
  105. data/lib/dcmgr/vnet/tasks/accept_arp_from_friends.rb +34 -0
  106. data/lib/dcmgr/vnet/tasks/accept_arp_from_gateway.rb +21 -0
  107. data/lib/dcmgr/vnet/tasks/accept_arp_to_host.rb +30 -0
  108. data/lib/dcmgr/vnet/tasks/accept_ip_from_friends.rb +26 -0
  109. data/lib/dcmgr/vnet/tasks/accept_ip_from_gateway.rb +23 -0
  110. data/lib/dcmgr/vnet/tasks/accept_ip_to_anywhere.rb +18 -0
  111. data/lib/dcmgr/vnet/tasks/accept_related_established.rb +45 -0
  112. data/lib/dcmgr/vnet/tasks/accept_wakame_dhcp_only.rb +33 -0
  113. data/lib/dcmgr/vnet/tasks/accept_wakame_dns_only.rb +33 -0
  114. data/lib/dcmgr/vnet/tasks/debug_iptables.rb +21 -0
  115. data/lib/dcmgr/vnet/tasks/drop_arp_forwarding.rb +27 -0
  116. data/lib/dcmgr/vnet/tasks/drop_arp_to_host.rb +24 -0
  117. data/lib/dcmgr/vnet/tasks/drop_ip_from_anywhere.rb +18 -0
  118. data/lib/dcmgr/vnet/tasks/drop_ip_spoofing.rb +34 -0
  119. data/lib/dcmgr/vnet/tasks/drop_mac_spoofing.rb +33 -0
  120. data/lib/dcmgr/vnet/tasks/exclude_from_nat.rb +47 -0
  121. data/lib/dcmgr/vnet/tasks/security_group.rb +37 -0
  122. data/lib/dcmgr/vnet/tasks/static_nat.rb +54 -0
  123. data/lib/dcmgr/vnet/tasks/translate_metadata_address.rb +32 -0
  124. data/web/metadata/config.ru +1 -1
  125. metadata +174 -89
  126. data/lib/dcmgr/cli/group.rb +0 -101
  127. data/lib/dcmgr/endpoints/core_api_mock.rb +0 -865
  128. data/lib/dcmgr/models/host_pool.rb +0 -122
  129. data/lib/dcmgr/models/instance_netfilter_group.rb +0 -16
  130. data/lib/dcmgr/models/netfilter_group.rb +0 -89
  131. data/lib/dcmgr/models/netfilter_rule.rb +0 -21
  132. data/lib/dcmgr/scheduler/find_last.rb +0 -16
  133. data/lib/dcmgr/scheduler/find_random.rb +0 -16
  134. data/lib/dcmgr/stm/instance.rb +0 -25
  135. data/lib/dcmgr/stm/snapshot_context.rb +0 -33
  136. data/lib/dcmgr/stm/volume_context.rb +0 -65
@@ -1,55 +1,29 @@
1
1
  # -*- coding: utf-8 -*-
2
2
 
3
3
  module Dcmgr::Models
4
- # Model class which represents Virtual Machine or Isolated Instace
5
- # running on HostPool.
6
- #
7
- # @exmaple Create new instance
8
- # hp = HostPool['hp-xxxxx']
9
- # inst = hp.create_instance()
4
+ # Model class for running virtual instance.
10
5
  class Instance < AccountResource
11
6
  taggable 'i'
12
7
 
13
- inheritable_schema do
14
- Fixnum :host_pool_id, :null=>false
15
- Fixnum :image_id, :null=>false
16
- Fixnum :instance_spec_id, :null=>false
17
- String :state, :size=>20, :null=>false, :default=>:init.to_s
18
- String :status, :size=>20, :null=>false, :default=>:init.to_s
19
- String :hostname, :null=>false, :size=>32
20
- # TODO: remove ssh_key_pair_id column
21
- String :ssh_key_pair_id
22
- Fixnum :ha_enabled, :null=>false, :default=>0
23
- Float :quota_weight, :null=>false, :default=>0.0
24
- Fixnum :cpu_cores, :null=>false, :unsigned=>true
25
- Fixnum :memory_size, :null=>false, :unsigned=>true
26
-
27
- Text :user_data, :null=>false, :default=>''
28
- Text :runtime_config, :null=>false, :default=>''
29
- Text :ssh_key_data, :null=>true
30
-
31
- Time :terminated_at
32
- index :state
33
- index :terminated_at
34
- end
35
- with_timestamps
36
-
37
8
  many_to_one :image
38
9
  many_to_one :instance_spec
39
10
  alias :spec :instance_spec
40
- many_to_one :host_pool
11
+ many_to_one :host_node
41
12
  one_to_many :volume
42
13
  one_to_many :instance_nic
43
14
  alias :nic :instance_nic
44
- many_to_many :netfilter_groups, :join_table=>:instance_netfilter_groups
15
+ many_to_many :security_groups, :join_table=>:instance_security_groups
45
16
  # TODO: remove ssh_key_pair_id column
46
17
  many_to_one :ssh_key_pair
47
18
 
48
19
  plugin ArchiveChangedColumn, :histories
49
20
 
50
21
  subset(:lives, {:terminated_at => nil})
22
+ subset(:runnings, {:state => 'running'})
23
+ subset(:stops, {:state => 'stopped'})
51
24
 
52
- RECENT_TERMED_PERIOD=(60 * 15)
25
+ #RECENT_TERMED_PERIOD=(60 * 15)
26
+ RECENT_TERMED_PERIOD = Dcmgr.conf.recent_terminated_instance_period
53
27
  # lists the instances which alives and died within
54
28
  # RECENT_TERMED_PERIOD sec.
55
29
  # it was difficult for me to write exprs in virtual row syntax as
@@ -62,11 +36,12 @@ module Dcmgr::Models
62
36
  # method calls.
63
37
  # Possible column data:
64
38
  # kvm:
65
- # {:vnc_port=>11, :telnet_port=>1111}
39
+ # {:vnc_port=>11}
66
40
  plugin :serialization
67
41
  serialize_attributes :yaml, :runtime_config
68
42
  # equal to SshKeyPair#to_hash
69
43
  serialize_attributes :yaml, :ssh_key_data
44
+ serialize_attributes :yaml, :request_params
70
45
 
71
46
  module ValidationMethods
72
47
  def self.hostname_uniqueness(account_id, hostname)
@@ -74,8 +49,12 @@ module Dcmgr::Models
74
49
  end
75
50
  end
76
51
 
52
+ class HostError < RuntimeError; end
53
+
77
54
  def validate
78
55
  super
56
+ # do not run validation if the row is maked as deleted.
57
+ return true if self.terminated_at
79
58
 
80
59
  unless self.hostname =~ /\A[0-9a-z][0-9a-z\-]{0,31}\Z/
81
60
  errors.add(:hostname, "Invalid hostname syntax")
@@ -100,20 +79,6 @@ module Dcmgr::Models
100
79
  end
101
80
  @update_hostname = true
102
81
  end
103
-
104
- # check runtime_config column
105
- case self.hypervisor
106
- when HostPool::HYPERVISOR_KVM
107
- r1 = self.runtime_config
108
- self.host_pool.instances.each { |i|
109
- next true if i.id == self.id
110
- r2 = i.runtime_config
111
- unless r1[:vnc_port] != r2[:vnc_port] && r1[:telnet_port] != r2[:telnet_port]
112
- errors.add(:runtime_config, "#{self.canonical_uuid}.runtime_config conflicted with #{i.canonical_uuid}")
113
- break
114
- end
115
- }
116
- end
117
82
  end
118
83
 
119
84
  def before_validation
@@ -145,7 +110,7 @@ module Dcmgr::Models
145
110
  # sum() returns nil if there is no instance rows.
146
111
  lives_weight = self.class.filter(:account_id=>self.account_id).lives.sum(:quota_weight) || 0.0
147
112
  unless lives_weight <= self.account.quota.instance_total_weight
148
- raise "Out of quota limit: #{self.account_id}'s current weight capacity: #{lives_weight} (<= #{self.account.quota.instance_total_weight})"
113
+ raise HostError, "Out of quota limit: #{self.account_id}'s current weight capacity: #{lives_weight} (<= #{self.account.quota.instance_total_weight})"
149
114
  end
150
115
 
151
116
  super
@@ -154,7 +119,7 @@ module Dcmgr::Models
154
119
  def before_destroy
155
120
  HostnameLease.filter(:account_id=>self.account_id, :hostname=>self.hostname).destroy
156
121
  self.instance_nic.each { |o| o.destroy }
157
- self.remove_all_netfilter_groups
122
+ self.remove_all_security_groups
158
123
  self.volume.each { |v|
159
124
  v.instance_id = nil
160
125
  v.state = :available
@@ -163,9 +128,9 @@ module Dcmgr::Models
163
128
  super
164
129
  end
165
130
 
166
- # override Sequel::Model#_delete not to delete rows but to set
131
+ # override Sequel::Model#delete not to delete rows but to set
167
132
  # delete flags.
168
- def _delete
133
+ def delete
169
134
  self.terminated_at ||= Time.now
170
135
  self.state = :terminated if self.state != :terminated
171
136
  self.status = :offline if self.status != :offline
@@ -177,12 +142,15 @@ module Dcmgr::Models
177
142
  def to_hash
178
143
  h = super
179
144
  h.merge!({:user_data => user_data.to_s, # Sequel::BLOB -> String
180
- :runtime_config => self.runtime_config, # yaml -> hash
181
- :image=>image.to_hash,
182
- :host_pool=>host_pool.to_hash,
183
- :instance_nics=>instance_nic.map {|n| n.to_hash },
184
- :ips => instance_nic.map { |n| n.ip.map {|i| unless i.is_natted? then i.ipv4 else nil end} if n.ip }.flatten.compact,
185
- :nat_ips => instance_nic.map { |n| n.ip.map {|i| if i.is_natted? then i.ipv4 else nil end} if n.ip }.flatten.compact,
145
+ :runtime_config => self.runtime_config, # yaml -> hash
146
+ :ssh_key_data => self.ssh_key_data, # yaml -> hash
147
+ :image=>image.to_hash,
148
+ :host_node=> (host_node.nil? ? nil : host_node.to_hash),
149
+ :instance_nics=>instance_nic.map {|n| n.to_hash },
150
+ :ips => instance_nic.map { |n| n.ip.map {|i| unless i.is_natted? then i.ipv4 else nil end} if n.ip }.flatten.compact,
151
+ :nat_ips => instance_nic.map { |n| n.ip.map {|i| if i.is_natted? then i.ipv4 else nil end} if n.ip }.flatten.compact,
152
+ :security_groups => self.security_groups.map {|n| n.canonical_uuid },
153
+ :vif=>[],
186
154
  })
187
155
  h.merge!({:instance_spec=>instance_spec.to_hash}) unless instance_spec.nil?
188
156
  h[:volume]={}
@@ -191,6 +159,25 @@ module Dcmgr::Models
191
159
  h[:volume][v.canonical_uuid] = v.to_hash
192
160
  }
193
161
  end
162
+ if self.instance_nic
163
+ self.instance_nic.each { |vif|
164
+ ent = vif.to_hash.merge({
165
+ :vif_id=>vif.canonical_uuid,
166
+ })
167
+ direct_lease = vif.direct_ip_lease.first
168
+ if direct_lease.nil?
169
+ else
170
+ outside_lease = direct_lease.nat_outside_lease
171
+ ent[:ipv4] = {
172
+ :network => vif.network.nil? ? nil : vif.network.to_hash,
173
+ :address=> direct_lease.ipv4,
174
+ :nat_network => vif.nat_network.nil? ? nil : vif.nat_network.to_hash,
175
+ :nat_address => outside_lease.nil? ? nil : outside_lease.ipv4,
176
+ }
177
+ end
178
+ h[:vif] << ent
179
+ }
180
+ end
194
181
  h
195
182
  end
196
183
 
@@ -205,7 +192,7 @@ module Dcmgr::Models
205
192
  # :network => [{:network_name=>'nw-xxxxxxx', :ipaddr=>'111.111.111.111'}]
206
193
  # :volume => [{'uuid'=>{:guest_device_name=>,}]
207
194
  # :ssh_key_pair => 'xxxxx',
208
- # :netfilter_group => ['rule1', 'rule2']
195
+ # :security_groups => ['rule1', 'rule2']
209
196
  # :created_at
210
197
  # :state
211
198
  # :status
@@ -214,8 +201,10 @@ module Dcmgr::Models
214
201
  def to_api_document
215
202
  h = {
216
203
  :id => canonical_uuid,
204
+ :host_node => self.host_node && self.host_node.canonical_uuid,
217
205
  :cpu_cores => cpu_cores,
218
206
  :memory_size => memory_size,
207
+ :arch => spec.arch,
219
208
  :image_id => image.canonical_uuid,
220
209
  :created_at => self.created_at,
221
210
  :state => self.state,
@@ -223,66 +212,60 @@ module Dcmgr::Models
223
212
  :ssh_key_pair => nil,
224
213
  :network => [],
225
214
  :volume => [],
226
- :netfilter_group => [],
215
+ :security_groups => self.security_groups.map {|n| n.canonical_uuid },
227
216
  :vif => [],
217
+ :hostname => hostname,
218
+ :ha_enabled => ha_enabled,
219
+ :instance_spec_id => instance_spec.canonical_uuid,
228
220
  }
229
221
  if self.ssh_key_data
230
- h[:ssh_key_pair] = self.ssh_key_data[:name]
222
+ h[:ssh_key_pair] = self.ssh_key_data[:uuid]
231
223
  end
232
224
 
233
- if instance_nic
234
- instance_nic.each { |n|
235
- direct_lease_ds = n.direct_ip_lease_dataset
236
- next if direct_lease_ds.first.nil?
237
- outside_lease_ds = n.nat_ip_lease_dataset
238
-
225
+ instance_nic.each { |vif|
226
+ direct_lease_ds = vif.direct_ip_lease_dataset
227
+ if direct_lease_ds.first
228
+ outside_lease_ds = vif.nat_ip_lease_dataset
229
+
239
230
  h[:network] << {
240
- :network_name => n.network.canonical_uuid,
231
+ :network_name => vif.network.canonical_uuid,
241
232
  :ipaddr => direct_lease_ds.all.map {|lease| lease.ipv4 }.compact,
242
- :nat_ipaddr => outside_lease_ds.all.map {|lease| lease.ipv4 }.compact
233
+ :dns_name => vif.network.domain_name && self.fqdn_hostname,
234
+ :nat_network_name => vif.nat_network && vif.nat_network.canonical_uuid,
235
+ :nat_ipaddr => outside_lease_ds.all.map {|lease| lease.ipv4 }.compact,
236
+ :nat_dns_name => vif.nat_network && vif.nat_network.domain_name && self.nat_fqdn_hostname,
243
237
  }
244
- }
245
- end
238
+ end
246
239
 
247
- if instance_nic
248
- instance_nic.each { |vif|
249
- ent = {
250
- :vif_id=>vif.canonical_uuid,
251
- }
252
- direct_lease = vif.direct_ip_lease.first
253
- if direct_lease.nil?
254
- else
255
- outside_lease = direct_lease.nat_outside_lease
256
- ent[:ipv4] = {
257
- :address=> direct_lease.ipv4,
258
- :nat_address => outside_lease.nil? ? nil : outside_lease.ipv4,
259
- }
260
- end
261
- h[:vif] << ent
240
+ ent = {
241
+ :vif_id=>vif.canonical_uuid,
262
242
  }
263
- end
264
-
265
- if self.volume
266
- self.volume.each { |v|
267
- h[:volume] << {
268
- :vol_id => v.canonical_uuid,
269
- :guest_device_name=>v.guest_device_name,
270
- :state=>v.state,
243
+ direct_lease = direct_lease_ds.first
244
+ if direct_lease.nil?
245
+ else
246
+ outside_lease = direct_lease.nat_outside_lease
247
+ ent[:ipv4] = {
248
+ :address=> direct_lease.ipv4,
249
+ :nat_address => outside_lease.nil? ? nil : outside_lease.ipv4,
271
250
  }
272
- }
273
- end
251
+ end
252
+ h[:vif] << ent
253
+ }
274
254
 
275
- if self.netfilter_groups
276
- self.netfilter_groups.each { |n|
277
- h[:netfilter_group] << n.name
255
+ self.volume.each { |v|
256
+ h[:volume] << {
257
+ :vol_id => v.canonical_uuid,
258
+ :guest_device_name=>v.guest_device_name,
259
+ :state=>v.state,
278
260
  }
279
- end
261
+ }
262
+
280
263
  h
281
264
  end
282
265
 
283
266
  # Returns the hypervisor type for the instance.
284
267
  def hypervisor
285
- self.host_pool.hypervisor
268
+ self.instance_spec.hypervisor
286
269
  end
287
270
 
288
271
  # Returns the architecture type of the image
@@ -294,30 +277,36 @@ module Dcmgr::Models
294
277
  self.instance_spec.config
295
278
  end
296
279
 
297
- def add_nic(network, vendor_id=nil)
298
- # TODO: get default vendor ID based on the hypervisor.
299
- vendor_id ||= '00:ff:f1'
300
- nic = InstanceNic.new(:mac_addr=>vendor_id)
301
- nic.network = network
302
- nic.nat_network = network.nat_network
280
+ def add_nic(vif_template)
281
+ # Choose vendor ID of mac address.
282
+ vendor_id = if vif_template[:vendor_id]
283
+ vif_template[:vendor_id]
284
+ elsif Dcmgr.conf.mac_address_vendor_id
285
+ Dcmgr.conf.mac_address_vendor_id
286
+ else
287
+ MacLease.default_vendor_id(self.instance_spec.hypervisor)
288
+ end
289
+ m = MacLease.lease(vendor_id)
290
+ nic = InstanceNic.new(:mac_addr=>m.mac_addr)
303
291
  nic.instance = self
292
+ nic.device_index = vif_template[:index]
304
293
  nic.save
305
294
  end
306
295
 
307
- # Join this instance to the list of netfilter group using group's uuid.
308
- # @param [String,Array] netfilter_group_uuids
309
- def join_netfilter_group(netfilter_group_uuids)
310
- netfilter_group_uuids = [netfilter_group_uuids] if netfilter_group_uuids.is_a?(String)
311
- joined_group_uuids = self.netfilter_groups.map { |netfilter_group|
312
- netfilter_group.canonical_uuid
296
+ # Join this instance to the list of security group using group's uuid.
297
+ # @param [String,Array] security_group_uuids
298
+ def join_security_group(security_group_uuids)
299
+ security_group_uuids = [security_group_uuids] if security_group_uuids.is_a?(String)
300
+ joined_group_uuids = self.security_groups.map { |security_group|
301
+ security_group.canonical_uuid
313
302
  }
314
- target_group_uuids = netfilter_group_uuids.uniq - joined_group_uuids.uniq
303
+ target_group_uuids = security_group_uuids.uniq - joined_group_uuids.uniq
315
304
  target_group_uuids.uniq!
316
305
 
317
306
  target_group_uuids.map { |target_group_uuid|
318
- if ng = NetfilterGroup[target_group_uuid]
319
- InstanceNetfilterGroup.create(:instance_id => self.id,
320
- :netfilter_group_id => ng.id)
307
+ if sg = SecurityGroup[target_group_uuid]
308
+ InstanceSecurityGroup.create(:instance_id => self.id,
309
+ :security_group_id => sg.id)
321
310
  end
322
311
  }
323
312
  end
@@ -326,15 +315,12 @@ module Dcmgr::Models
326
315
  self.instance_nic.map { |nic| nic.ip }
327
316
  end
328
317
 
329
- # def netfilter_group_instances
330
- # instances = self.netfilter_groups.map { |g| g.instances }
331
- #
332
- # instances.flatten!.uniq! if instances.size > 0
333
- # instances
334
- # end
335
-
336
318
  def fqdn_hostname
337
- sprintf("%s.%s.%s", self.hostname, self.account.uuid, self.nic.first.network.domain_name)
319
+ self.nic.first.fqdn_hostname
320
+ end
321
+
322
+ def nat_fqdn_hostname
323
+ self.nic.first.nat_fqdn_hostname
338
324
  end
339
325
 
340
326
  # Retrieve all networks belong to this instance
@@ -351,21 +337,6 @@ module Dcmgr::Models
351
337
  }
352
338
  end
353
339
 
354
- # Join this instance to the list of netfilter group using group name.
355
- # @param [String] account_id uuid of current account.
356
- # @param [String,Array] nfgroup_names
357
- def join_nfgroup_by_name(account_id, nfgroup_names)
358
- nfgroup_names = [nfgroup_names] if nfgroup_names.is_a?(String)
359
-
360
- uuids = nfgroup_names.map { |n|
361
- ng = NetfilterGroup.for_update.filter(:account_id=>account_id,
362
- :name=>n).first
363
- ng.nil? ? nil : ng.canonical_uuid
364
- }
365
- # clean up nils
366
- join_netfilter_group(uuids.compact.uniq)
367
- end
368
-
369
340
  def self.lock!
370
341
  super()
371
342
  Image.lock!
@@ -374,8 +345,6 @@ module Dcmgr::Models
374
345
  Volume.lock!
375
346
  VolumeSnapshot.lock!
376
347
  IpLease.lock!
377
- HostnameLease.lock!
378
- Network.lock!
379
348
  end
380
349
 
381
350
  def live?
@@ -385,9 +354,34 @@ module Dcmgr::Models
385
354
  def set_ssh_key_pair(ssh_key_pair)
386
355
  raise ArgumentError unless ssh_key_pair.is_a?(SshKeyPair)
387
356
  self.ssh_key_data = ssh_key_pair.to_hash
357
+ # Do not copy private key.
358
+ self.ssh_key_data.delete(:private_key)
388
359
  # TODO: remove ssh_key_pair_id column
389
360
  self.ssh_key_pair_id = ssh_key_pair.canonical_uuid
390
361
  end
391
-
362
+
363
+
364
+ # Factory method for Models::Instance object.
365
+ # This method helps to set association values have to be
366
+ # set mandatry until initial save to the database.
367
+ def self.entry_new(account, image, spec, params, &blk)
368
+ raise ArgumentError unless account.is_a?(Account)
369
+ raise ArgumentError unless image.is_a?(Image)
370
+ raise ArgumentError unless spec.is_a?(InstanceSpec)
371
+ # Mash is passed in some cases.
372
+ raise ArgumentError unless params.class == ::Hash
373
+
374
+ i = self.new &blk
375
+ i.account_id = account.canonical_uuid
376
+ i.image = image
377
+ i.instance_spec = spec
378
+ i.cpu_cores = spec.cpu_cores
379
+ i.memory_size = spec.memory_size
380
+ i.quota_weight = spec.quota_weight
381
+ i.request_params = params.dup
382
+
383
+ i
384
+ end
385
+
392
386
  end
393
387
  end
@@ -5,18 +5,6 @@ module Dcmgr::Models
5
5
  class InstanceNic < BaseNew
6
6
  taggable 'vif'
7
7
 
8
- inheritable_schema do
9
- Fixnum :instance_id, :null=>false
10
- Fixnum :network_id, :null=>false
11
- Fixnum :nat_network_id
12
- Fixnum :bandwidth_group_id
13
- String :mac_addr, :null=>false, :size=>12
14
-
15
- index :mac_addr
16
- end
17
- with_timestamps
18
-
19
- many_to_one :bandwidth_group
20
8
  many_to_one :instance
21
9
  many_to_one :nat_network, :key => :nat_network_id, :class => Network
22
10
  many_to_one :network
@@ -27,48 +15,83 @@ module Dcmgr::Models
27
15
  one_to_many(:nat_ip_lease, :class=>IpLease, :read_only=>true) do |ds|
28
16
  ds.where(:network_id=>self.nat_network_id)
29
17
  end
18
+
19
+ subset(:alives, {:deleted_at => nil})
30
20
 
31
- def to_hash
32
- h = values.dup.merge(super)
33
- h.delete(:instance_id)
34
- h
21
+ def to_api_document
22
+ hash = super
23
+ hash.delete(instance_id)
24
+ hash
25
+ end
26
+
27
+ def release_ip_lease
28
+ ip_dataset.destroy
29
+ end
30
+
31
+ #Override the delete method to keep the row and just mark it as deleted
32
+ def delete
33
+ self.deleted_at ||= Time.now
34
+ self.save
35
35
  end
36
36
 
37
37
  def before_validation
38
- newlease=nil
39
- m = self[:mac_addr] = normalize_mac_addr(self[:mac_addr])
40
- if m
41
- if m.size == 6
42
- newlease = MacLease.lease(m)
43
- else
44
- MacLease.create(:mac_addr=>m)
45
- end
46
- else
47
- newlease = MacLease.lease()
38
+ self[:mac_addr] = normalize_mac_addr(self[:mac_addr])
39
+
40
+ # set maximum index number if the nic has no index value and
41
+ # is attached to instance.
42
+ if self.instance_id && self.device_index.nil?
43
+ max_idx = self.class.alives.filter(:instance_id=>self.instance_id).max(:device_index)
44
+ self.device_index = max_idx.nil? ? 0 : (max_idx + 1)
48
45
  end
49
- self[:mac_addr] = newlease.mac_addr if newlease
50
46
 
51
47
  super
52
48
  end
53
49
 
54
50
  def before_destroy
55
- MacLease.find(:mac_addr=>self.mac_addr).destroy
56
- ip_dataset.destroy
51
+ maclease = MacLease.find(:mac_addr=>self.mac_addr)
52
+ maclease.destroy if maclease
53
+ release_ip_lease
57
54
  super
58
55
  end
59
56
 
60
57
  def validate
61
58
  super
62
59
 
60
+ # do not run validation if the row is maked as deleted.
61
+ return true if self.deleted_at
62
+
63
63
  unless self.mac_addr.size == 12 && self.mac_addr =~ /^[0-9a-f]{12}$/
64
64
  errors.add(:mac_addr, "Invalid mac address syntax: #{self.mac_addr}")
65
65
  end
66
+ if MacLease.find(:mac_addr=>self.mac_addr).nil?
67
+ errors.add(:mac_addr, "MAC address is not on the MAC lease database.")
68
+ end
69
+
70
+ # find duplicate device index.
71
+ if self.instance_id
72
+ idx = self.class.alives.filter(:instance_id=>self.instance_id).select(:device_index).all
73
+ if idx.uniq.size != idx.size
74
+ errors.add(:device_index, "Duplicate device index.")
75
+ end
76
+ end
66
77
  end
67
78
 
68
79
  def pretty_mac_addr(delim=':')
69
80
  self.mac_addr.unpack('A2'*6).join(delim)
70
81
  end
71
82
 
83
+ def fqdn_hostname
84
+ raise "Instance is not associated: #{self.canonical_uuid}" if self.instance.nil?
85
+ raise "Network is not associated: #{self.canonical_uuid}" if self.network.nil?
86
+ sprintf("%s.%s.%s", self.instance.hostname, self.instance.account.uuid, self.network.domain_name)
87
+ end
88
+
89
+ def nat_fqdn_hostname
90
+ raise "Instance is not associated: #{self.canonical_uuid}" if self.instance.nil?
91
+ raise "Network is not associated: #{self.canonical_uuid}" if self.network.nil?
92
+ sprintf("%s.%s.%s", self.instance.hostname, self.instance.account.uuid, self.nat_network.domain_name)
93
+ end
94
+
72
95
  private
73
96
  def normalize_mac_addr(str)
74
97
  str = str.downcase.gsub(/[^0-9a-f]/, '')