wakame-vdc-agents 10.11.0 → 10.12.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -2,22 +2,10 @@
2
2
 
3
3
  module Dcmgr::Models
4
4
  class TagMapping < BaseNew
5
- TYPE_ACCOUNT = 0
6
- TYPE_TAG = 1
7
- TYPE_USER = 2
8
- TYPE_INSTANCE = 3
9
- TYPE_INSTANCE_IMAGE = 4
10
- TYPE_HV_CONTROLLER = 5
11
- TYPE_HV_AGENT = 6
12
- TYPE_PHYSICAL_HOST = 7
13
- TYPE_PHYSICAL_HOST_LOCATION = 8
14
- TYPE_IMAGE_STORAGE_HOST = 9
15
- TYPE_IMAGE_STORAGE = 10
16
-
17
5
  inheritable_schema do
18
6
  Fixnum :tag_id, :null=>false
7
+ String :uuid, :null=>false, :size=>20
19
8
  index :tag_id
20
- String :uuid, :null=>false, :fixed=>true, :size=>20
21
9
  index :uuid
22
10
  end
23
11
 
@@ -0,0 +1,17 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ module Dcmgr::Models
4
+ # VLAN lease information
5
+ class VlanLease < AccountResource
6
+ taggable 'vlan'
7
+
8
+ inheritable_schema do
9
+ Fixnum :tag_id, :null=>false
10
+
11
+ index :tag_id, {:unique=>true}
12
+ end
13
+ with_timestamps
14
+
15
+ one_to_many :networks
16
+ end
17
+ end
@@ -27,6 +27,7 @@ module Dcmgr::Models
27
27
  String :state, :null=>false, :default=>STATE_TYPE_REGISTERING
28
28
  Fixnum :size, :null=>false
29
29
  Fixnum :instance_id
30
+ Fixnum :boot_dev, :null=>false, :default=>0
30
31
  String :snapshot_id
31
32
  String :host_device_name
32
33
  String :guest_device_name
@@ -41,6 +42,11 @@ module Dcmgr::Models
41
42
  end
42
43
  with_timestamps
43
44
 
45
+ many_to_one :storage_pool
46
+ many_to_one :instance
47
+
48
+ plugin ArchiveChangedColumn, :histories
49
+
44
50
  # serialization plugin must be defined at the bottom of all class
45
51
  # method calls.
46
52
  # Possible column data:
@@ -48,9 +54,6 @@ module Dcmgr::Models
48
54
  # {:iqn=>'iqn.1986-03.com.sun:02:a1024afa-775b-65cf-b5b0-aa17f3476bfc', :lun=>0}
49
55
  plugin :serialization, :yaml, :transport_information
50
56
 
51
- many_to_one :storage_pool
52
- many_to_one :instance
53
-
54
57
  class DiskError < RuntimeError; end
55
58
  class RequestError < RuntimeError; end
56
59
 
@@ -93,7 +96,7 @@ module Dcmgr::Models
93
96
  vl = vl.grep(data[:target].to_sym, "%#{filter}%")
94
97
  end
95
98
  vl.all.map{|row|
96
- row.to_hash_document
99
+ row.to_api_document
97
100
  }
98
101
  end
99
102
 
@@ -108,18 +111,32 @@ module Dcmgr::Models
108
111
  end
109
112
 
110
113
  def merge_pool_data
111
- v = self.to_hash_document
112
- v.merge(:storage_pool=>storage_pool.to_hash_document)
114
+ v = self.to_hash
115
+ v.merge(:storage_pool=>storage_pool.to_hash)
113
116
  end
114
117
 
115
- def to_hash_document
116
- h = self.values.dup
117
- h[:id] = h[:uuid] = h[:export_path] = self.canonical_uuid
118
+ def to_hash
119
+ h = super
118
120
  # yaml -> hash translation
119
121
  h[:transport_information]=self.transport_information
120
122
  h
121
123
  end
122
124
 
125
+ # Hash data for API response.
126
+ def to_api_document
127
+ h = {
128
+ :id => self.canonical_uuid,
129
+ :uuid => self.canonical_uuid,
130
+ :size => self.size,
131
+ :snapshot_id => self.snapshot_id,
132
+ :created_at => self.created_at,
133
+ :attached_at => self.attached_at,
134
+ :state => self.state,
135
+ :instance_id => (self.instance && self.instance.canonical_uuid),
136
+ :deleted_at => self.deleted_at,
137
+ }
138
+ end
139
+
123
140
  def create_snapshot(account_id)
124
141
  vs = VolumeSnapshot.create(:account_id=>account_id,
125
142
  :storage_pool_id=>self.storage_pool_id,
@@ -22,11 +22,20 @@ module Dcmgr::Models
22
22
  with_timestamps
23
23
 
24
24
  many_to_one :storage_pool
25
-
26
- def to_hash_document
27
- h = self.values.dup
28
- h[:id] = h[:uuid] = self.canonical_uuid
29
- h
25
+ plugin ArchiveChangedColumn, :histories
26
+
27
+ class RequestError < RuntimeError; end
28
+
29
+ # Hash data for API response.
30
+ def to_api_document
31
+ h = {
32
+ :id => self.canonical_uuid,
33
+ :uuid => self.canonical_uuid,
34
+ :state => self.state,
35
+ :size => self.size,
36
+ :origin_volume_id => self.origin_volume_id,
37
+ :created_at => self.created_at,
38
+ }
30
39
  end
31
40
 
32
41
  # create volume inherite from this snapshot for the account.
@@ -39,9 +48,13 @@ module Dcmgr::Models
39
48
  Volume[origin_volume_id]
40
49
  end
41
50
 
42
- def delete_snapshot
43
- self.state = STATE_TYPE_DELETING
44
- self.save_changes
51
+ def self.delete_snapshot(account_id, uuid)
52
+ vs = self.dataset.where(:account_id => account_id).where(:uuid => uuid.split('-').last).first
53
+ if vs.state.to_sym != :available
54
+ raise RequestError, "invalid delete request"
55
+ end
56
+ vs.state = :deleting
57
+ vs.save_changes
45
58
  end
46
59
  end
47
60
  end
@@ -34,7 +34,15 @@ module Dcmgr
34
34
  def update_instance(instance_id, data)
35
35
  Models::Instance.lock!
36
36
  inst = Models::Instance[instance_id]
37
- inst.set_fields(data, [:state]).save
37
+ raise "UnknownInstanceID" if inst.nil?
38
+ if data[:state] == :terminated
39
+ inst.terminated_at = data[:terminated_at]
40
+ # Instance#destroy do not really delete row.
41
+ # just for chain react destroy hooks in the associated models.
42
+ inst.destroy
43
+ else
44
+ inst.set(data).save
45
+ end
38
46
  # do not respond model object.
39
47
  nil
40
48
  end
@@ -52,14 +60,31 @@ module Dcmgr
52
60
  inst = Models::Instance[instance_id]
53
61
  raise "UnknownInstanceID" if inst.nil?
54
62
 
55
- insts = inst.netfilter_group_instances
56
- ips = insts.map { |instance|
57
- next if instance.nil?
58
- instance.ips.map { |ip| ip.ipv4 unless ip.nil? }
59
- }
63
+ ipv4s = inst.netfilter_groups.map { |netfilter_group|
64
+ next if netfilter_group.nil?
65
+ netfilter_group.instance_netfilter_groups.map { |instance_netfilter_group|
66
+ next if instance_netfilter_group.nil?
67
+ instance_netfilter_group.instance_dataset.lives.all.map { |instance|
68
+ next if instance.nil?
69
+ instance.ips.map { |ip|
70
+ next if ip.nil?
71
+ ip.ipv4
72
+ }
73
+ }
74
+ }
75
+ }.flatten.uniq.compact
76
+ ipv4s
77
+ end
60
78
 
61
- ips.flatten! if ips.size > 0
62
- ips.compact
79
+ # def get_instances_of_account_netfilter_group(account_id, netfilter_group_id)
80
+ def get_instances_of_account_netfilter_group(account_id, netfilter_group_name)
81
+ Models::NetfilterGroup.lock!
82
+ ng_map = Models::NetfilterGroup.find(:account_id => account_id, :name => netfilter_group_name)
83
+ raise "UnknownNetfilterGroupID" if ng_map.nil?
84
+ inst_maps = ng_map.instance_netfilter_groups.map { |instance_netfilter_group|
85
+ instance_netfilter_group.instance_dataset.lives.all.map { |inst| inst.to_hash }
86
+ }.flatten.uniq.compact
87
+ inst_maps
63
88
  end
64
89
 
65
90
  def get_network(network_id)
@@ -79,33 +104,55 @@ module Dcmgr
79
104
 
80
105
  def get_dhcp_conf(network_name)
81
106
  Models::Network.lock!
82
- network = Models::Network.find(:name=>network_name)
83
- raise "Unknown network name: #{network_name}" if network.nil?
84
- prefix = IPAddress::Prefix32.new(network.prefix)
85
- h = {
86
- :ipv4_gw=>network.ipv4_gw,
87
- :netmask => prefix.to_ip,
88
- :prefix => network.prefix,
89
- :dns_server=> network.dns_server,
90
- :domain_name => network.domain_name,
91
- :mac2addr => [],
92
- :addr2host=> [],
93
- }
94
-
95
- network.ip_lease.each { |ip|
96
- # ignore IPs unbound to vnic.
97
- next if ip.instance_nic.nil? || ip.instance_nic.instance.nil?
98
-
99
- h[:mac2addr] << {
100
- :mac_addr => ip.instance_nic.pretty_mac_addr,
101
- :ipaddr => ip.ipv4
107
+
108
+ build_network_segment = proc { |network|
109
+ gwaddr = network.ipaddress
110
+ h = {
111
+ :uuid => network.canonical_uuid,
112
+ :ipv4_first => gwaddr.network.first.to_s,
113
+ :ipv4_last => gwaddr.network.last.to_s,
114
+ :ipv4_gw=>network.ipv4_gw,
115
+ :netmask => gwaddr.network.prefix.to_ip,
116
+ :prefix => network.prefix,
117
+ :dns_server=> network.dns_server,
118
+ :domain_name => network.domain_name,
119
+ :metadata_server => network.metadata_server,
120
+ :mac2addr => [],
121
+ :addr2host=> [],
102
122
  }
103
- h[:addr2host] << {
104
- :hostname => ip.instance_nic.instance.fqdn_hostname,
105
- :ipaddr => ip.ipv4
123
+
124
+ network.ip_lease_dataset.filter(:type=>Models::IpLease::TYPE_AUTO).each { |ip|
125
+ # ignore IPs unbound to vnic.
126
+ next if ip.instance_nic.nil? || ip.instance_nic.instance.nil?
127
+
128
+ h[:mac2addr] << {
129
+ :mac_addr => ip.instance_nic.pretty_mac_addr,
130
+ :ipaddr => ip.ipv4
131
+ }
132
+ h[:addr2host] << {
133
+ :hostname => ip.instance_nic.instance.fqdn_hostname,
134
+ :ipaddr => ip.ipv4
135
+ }
106
136
  }
137
+
138
+ h
107
139
  }
108
140
 
141
+ network_set = nil
142
+ Tags::NetworkPool
143
+ Models::Network
144
+ case network = Models::Taggable.find(network_name)
145
+ when Models::Network
146
+ network_set = [network]
147
+ when Tags::NetworkPool
148
+ network_set = network.mapped_uuids.map {|m| Models::Network[m.uuid] }
149
+ else
150
+ raise "Unknown network name: #{network_name}"
151
+ end
152
+ h = {}
153
+ network_set.each {|n|
154
+ h[n.canonical_uuid] = build_network_segment.call(n)
155
+ }
109
156
  h
110
157
  end
111
158
 
@@ -113,19 +160,22 @@ module Dcmgr
113
160
  Models::NetfilterGroup.lock!
114
161
  g = Models::NetfilterGroup[netfilter_group_id]
115
162
  raise "UnknownNetfilterGroupID" if g.nil?
116
- inst_maps = g.instances.map { |instance| instance.to_hash unless instance.nil? }
117
- inst_maps.compact
163
+ inst_maps = g.instance_netfilter_groups.map { |instance_netfilter_group|
164
+ instance_netfilter_group.instance_dataset.lives.all.map { |inst| inst.to_hash }
165
+ }.flatten.uniq.compact
166
+ inst_maps
118
167
  end
119
168
 
120
169
  def get_alive_instances(node_id)
121
170
  Models::HostPool.lock!
122
171
  hp = Models::HostPool.find(:node_id => node_id)
123
172
  raise "UnknownNodeID", node_id if hp.nil?
124
-
125
- inst_on_hp = hp.instances_dataset.lives.all.map { |inst|
126
- inst.to_hash
127
- }
128
- inst_on_hp.uniq! if inst_on_hp.size > 0
173
+ hps = Models::HostPool.where(:account_id => hp.account_id).all
174
+ inst_on_hp = hps.map { |hp|
175
+ inst_on_hp = hp.instances_dataset.lives.all.map { |inst|
176
+ inst.to_hash
177
+ }
178
+ }.flatten.uniq.compact
129
179
  inst_on_hp
130
180
  end
131
181
 
@@ -0,0 +1,65 @@
1
+ # -*- coding: utf-8 -*-
2
+ require 'isono'
3
+
4
+ module Dcmgr
5
+ module NodeModules
6
+ class InstanceHA < Isono::NodeModules::Base
7
+ include Dcmgr::Logger
8
+
9
+ initialize_hook do
10
+ @thread_pool = Isono::ThreadPool.new
11
+ event = Isono::NodeModules::EventChannel.new(node)
12
+ event.subscribe('hva/fault_instance', '#') { |args|
13
+ @thread_pool.pass {
14
+ inst_id = args[0]
15
+ inst = Models::Instance[inst_id]
16
+ # check if the instance has HA enable.
17
+ next if inst.ha_enabled == 0
18
+ myinstance.restart_instance(inst)
19
+ }
20
+ }
21
+ end
22
+
23
+ terminate_hook do
24
+ @thread_pool.shutdown
25
+ end
26
+
27
+ def restart_instance(inst)
28
+ # terminate and cleanup
29
+ begin
30
+ jobrpc.run("kvm-handle.#{inst.host_pool.node_id}", 'cleanup', inst.canonical_uuid)
31
+ rescue => e
32
+ # termination may fail
33
+ end
34
+
35
+ # TODO: pick a new host node
36
+ Isono::NodeModules::DataStore.barrier {
37
+ inst.state = :failingover
38
+ inst.save
39
+ }
40
+
41
+ # start a new backup instance
42
+ case inst.image.boot_dev_type
43
+ when Models::Image::BOOT_DEV_SAN
44
+ boot_vol = inst.volume.find {|v| v.boot_dev == 1 }
45
+ res = jobrpc.submit("kvm-handle.#{inst.host_pool.node_id}", 'run_vol_store', inst.canonical_uuid, boot_vol.canonical_uuid)
46
+ when Models::Image::BOOT_DEV_LOCAL
47
+ res = jobrpc.submit("kvm-handle.#{inst.host_pool.node_id}", 'run_local_store', inst.canonical_uuid)
48
+ else
49
+ raise "Unknown boot type"
50
+ end
51
+ logger.info("#{inst.canonical_uuid} has been restarted")
52
+ end
53
+
54
+ private
55
+ def event
56
+ @event ||= Isono::NodeModules::EventChannel.new(node)
57
+ end
58
+
59
+ def jobrpc
60
+ @jobrpc ||= Isono::NodeModules::JobChannel.new(node)
61
+ end
62
+
63
+ end
64
+ end
65
+ end
@@ -29,7 +29,7 @@ module Dcmgr
29
29
  def get_snapshot(snapshot_id)
30
30
  Models::VolumeSnapshot.lock!
31
31
  vs = Dcmgr::Models::VolumeSnapshot[snapshot_id]
32
- vs.to_hash_document
32
+ vs.to_hash
33
33
  end
34
34
 
35
35
  def update_volume(data)
@@ -0,0 +1,54 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ module Dcmgr::Tags
4
+ include Dcmgr
5
+ KEY_MAP={10=>:NetworkPool, 11=>:HostPool, 12=>:StoragePool}.freeze
6
+ MODEL_MAP=KEY_MAP.invert.freeze
7
+
8
+ def self.type_id(class_or_sym)
9
+ k = case class_or_sym
10
+ when String, Symbol
11
+ class_or_sym.to_sym
12
+ when Class
13
+ class_or_sym.to_s.split('::').last.to_sym
14
+ end
15
+
16
+ MODEL_MAP[k] || raise("Unknown key to get type_id: #{class_or_sym}")
17
+ end
18
+
19
+ class NetworkPool < Models::Tag
20
+ def accept_mapping?(to)
21
+ to.is_a?(Dcmgr::Models::Network)
22
+ end
23
+
24
+ def pick()
25
+ lst = mapped_uuids.map { |t|
26
+ Dcmgr::Models::Network[t.uuid]
27
+ }.sort_by{ |n|
28
+ n.available_ip_nums
29
+ }.reverse.first
30
+ end
31
+ end
32
+
33
+ class HostPool < Models::Tag
34
+ def accept_mapping?(to)
35
+ to.is_a?(Dcmgr::Models::HostNode)
36
+ end
37
+
38
+ def pick(spec)
39
+ mapped_uuids.map { |t|
40
+ Dcmgr::Models::HostPool[t.uuid]
41
+ }.find_all { |h|
42
+ h.check_capacity(spec)
43
+ }.sort_by { |h|
44
+ h.instances.count
45
+ }.reverse.first
46
+ end
47
+ end
48
+
49
+ class StoragePool < Models::Tag
50
+ def accept_mapping?(to)
51
+ to.is_a?(Dcmgr::Models::StorageNode)
52
+ end
53
+ end
54
+ end