wakame-vdc-agents 10.11.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) hide show
  1. data/LICENSE +202 -0
  2. data/NOTICE +1 -0
  3. data/Rakefile +142 -0
  4. data/bin/hva +972 -0
  5. data/bin/nsa +147 -0
  6. data/bin/sta +182 -0
  7. data/config/hva.conf.example +10 -0
  8. data/config/initializers/isono.rb +43 -0
  9. data/config/initializers/passenger.rb +6 -0
  10. data/config/initializers/sequel.rb +21 -0
  11. data/config/nsa.conf.example +9 -0
  12. data/config/path_resolver.rb +12 -0
  13. data/lib/dcmgr.rb +115 -0
  14. data/lib/dcmgr/endpoints/core_api.rb +1004 -0
  15. data/lib/dcmgr/endpoints/core_api_mock.rb +816 -0
  16. data/lib/dcmgr/endpoints/errors.rb +55 -0
  17. data/lib/dcmgr/endpoints/metadata.rb +129 -0
  18. data/lib/dcmgr/logger.rb +44 -0
  19. data/lib/dcmgr/models/account.rb +104 -0
  20. data/lib/dcmgr/models/account_resource.rb +16 -0
  21. data/lib/dcmgr/models/base.rb +69 -0
  22. data/lib/dcmgr/models/base_new.rb +371 -0
  23. data/lib/dcmgr/models/frontend_system.rb +38 -0
  24. data/lib/dcmgr/models/host_pool.rb +102 -0
  25. data/lib/dcmgr/models/image.rb +46 -0
  26. data/lib/dcmgr/models/instance.rb +255 -0
  27. data/lib/dcmgr/models/instance_netfilter_group.rb +16 -0
  28. data/lib/dcmgr/models/instance_nic.rb +68 -0
  29. data/lib/dcmgr/models/instance_spec.rb +21 -0
  30. data/lib/dcmgr/models/ip_lease.rb +42 -0
  31. data/lib/dcmgr/models/netfilter_group.rb +88 -0
  32. data/lib/dcmgr/models/netfilter_rule.rb +21 -0
  33. data/lib/dcmgr/models/network.rb +32 -0
  34. data/lib/dcmgr/models/physical_host.rb +67 -0
  35. data/lib/dcmgr/models/request_log.rb +25 -0
  36. data/lib/dcmgr/models/ssh_key_pair.rb +55 -0
  37. data/lib/dcmgr/models/storage_pool.rb +134 -0
  38. data/lib/dcmgr/models/tag.rb +126 -0
  39. data/lib/dcmgr/models/tag_mapping.rb +28 -0
  40. data/lib/dcmgr/models/volume.rb +130 -0
  41. data/lib/dcmgr/models/volume_snapshot.rb +47 -0
  42. data/lib/dcmgr/node_modules/hva_collector.rb +134 -0
  43. data/lib/dcmgr/node_modules/sta_collector.rb +72 -0
  44. data/lib/dcmgr/scheduler.rb +12 -0
  45. data/lib/dcmgr/scheduler/find_last.rb +16 -0
  46. data/lib/dcmgr/scheduler/find_random.rb +16 -0
  47. data/lib/dcmgr/stm/instance.rb +25 -0
  48. data/lib/dcmgr/stm/snapshot_context.rb +33 -0
  49. data/lib/dcmgr/stm/volume_context.rb +65 -0
  50. data/lib/dcmgr/web/base.rb +21 -0
  51. data/lib/sinatra/accept_media_types.rb +128 -0
  52. data/lib/sinatra/lazy_auth.rb +56 -0
  53. data/lib/sinatra/rabbit.rb +278 -0
  54. data/lib/sinatra/respond_to.rb +272 -0
  55. data/lib/sinatra/sequel_transaction.rb +27 -0
  56. data/lib/sinatra/static_assets.rb +83 -0
  57. data/lib/sinatra/url_for.rb +44 -0
  58. metadata +270 -0
@@ -0,0 +1,38 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ module Dcmgr::Models
4
+ class FrontendSystem < BaseNew
5
+
6
+ plugin :single_table_inheritance, :kind
7
+
8
+ inheritable_schema do
9
+ String :kind, :null=>false
10
+ String :key, :null=>false, :size=>40, :unique=>true
11
+ String :credential
12
+ end
13
+
14
+ def authenticate
15
+ raise NotImplementedError
16
+ end
17
+
18
+ class PassThru < FrontendSystem
19
+
20
+ def authenticate(env)
21
+ end
22
+ end
23
+
24
+ class HttpBasic < FrontendSystem
25
+
26
+ def authenticate(env)
27
+ end
28
+ end
29
+
30
+ class RemoteIP < FrontendSystem
31
+
32
+ def authenticate(env)
33
+ self.key == env['HTTP_REMOTE_ADDR']
34
+ end
35
+ end
36
+
37
+ end
38
+ end
@@ -0,0 +1,102 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ module Dcmgr::Models
4
+ class HostPool < AccountResource
5
+ taggable 'hp'
6
+ with_timestamps
7
+
8
+ HYPERVISOR_XEN_34=:'xen-3.4'
9
+ HYPERVISOR_XEN_40=:'xen-4.0'
10
+ HYPERVISOR_KVM=:'kvm'
11
+
12
+ ARCH_X86=:x86.to_s
13
+ ARCH_X86_64=:x86_64.to_s
14
+
15
+ SUPPORTED_ARCH=[ARCH_X86, ARCH_X86_64]
16
+
17
+ inheritable_schema do
18
+ String :node_id, :size=>80, :null=>true
19
+
20
+ String :arch, :size=>10, :null=>false # :x86, :x86_64
21
+ String :hypervisor, :size=>30, :null=>false
22
+ Fixnum :network_id, :null=>false
23
+
24
+ Fixnum :offering_cpu_cores, :null=>false, :unsigned=>true
25
+ Fixnum :offering_memory_size, :null=>false, :unsigned=>true
26
+ Fixnum :allow_memory_overcommit, :null=>false, :default=>1
27
+ end
28
+
29
+ one_to_many :instances
30
+ many_to_one :node, :class=>Isono::Models::NodeState, :key=>:node_id, :primary_key=>:node_id
31
+ many_to_one :network
32
+
33
+ def after_initialize
34
+ super
35
+ end
36
+
37
+ def validate
38
+ super
39
+ unless self.node_id =~ /^hva-/
40
+ errors.add(:node_id, "hva node has to be associated: #{self.node_id}")
41
+ end
42
+
43
+ unless SUPPORTED_ARCH.member?(self.arch)
44
+ errors.add(:arch, "unknown architecture type: #{self.arch}")
45
+ end
46
+
47
+ unless self.offering_cpu_cores > 0
48
+ errors.add(:offering_cpu_cores, "it must have digit more than zero")
49
+ end
50
+ unless self.offering_memory_size > 0
51
+ errors.add(:offering_memory_size, "it must have digit more than zero")
52
+ end
53
+ end
54
+
55
+ def to_hash
56
+ super.merge(:status=>self.status)
57
+ end
58
+
59
+ # Check if the resources exist depending on the HostPool.
60
+ # @return [boolean]
61
+ def depend_resources?
62
+ !self.instances_dataset.runnings.empty?
63
+ end
64
+
65
+ # Factory method for Instance model to run on this HostPool.
66
+ # @param [Models::Account] account
67
+ # @param [Models::Image] image
68
+ # @param [Models::InstanceSpec] spec
69
+ # @return [Models::Instance] created new Instance object.
70
+ def create_instance(account, image, spec, &blk)
71
+ raise ArgumentError unless image.is_a?(Image)
72
+ raise ArgumentError unless spec.is_a?(InstanceSpec)
73
+ i = Instance.new &blk
74
+ i.account_id = account.canonical_uuid
75
+ i.image = image
76
+ i.instance_spec = spec
77
+ i.host_pool = self
78
+ i.save
79
+
80
+ # TODO: set vnic spec from InstanceSpec
81
+ vnic = i.add_nic
82
+ IpLease.lease(vnic)
83
+ i
84
+ end
85
+
86
+ def status
87
+ node.nil? ? :offline : node.state
88
+ end
89
+
90
+ # Returns true/false if the host pool has enough capacity to run the spec.
91
+ # @param [InstanceSpec] spec
92
+ def check_capacity(spec)
93
+ raise TypeError unless spec.is_a?(InstanceSpec)
94
+ inst_on_hp = self.instances_dataset.lives.all
95
+
96
+ (self.offering_cpu_cores > inst_on_hp.inject(0) {|t, i| t += i.spec.cpu_cores } + spec.cpu_cores) &&
97
+ (self.offering_memory_size > inst_on_hp.inject(0) {|t, i| t += i.spec.memory_size } + spec.memory_size)
98
+ end
99
+
100
+
101
+ end
102
+ end
@@ -0,0 +1,46 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ module Dcmgr::Models
4
+ # Metadata catalogs for bootable image file.
5
+ class Image < AccountResource
6
+ taggable 'wmi'
7
+ with_timestamps
8
+
9
+ BOOT_DEV_SAN=1
10
+ BOOT_DEV_LOCAL=2
11
+
12
+ inheritable_schema do
13
+ Fixnum :boot_dev_type, :null=>false, :default=>BOOT_DEV_SAN
14
+ Text :source, :null=>false
15
+ String :arch, :size=>10, :null=>false
16
+ Text :description
17
+ #Fixnum :parent_image_id
18
+
19
+ String :state, :size=>20, :null=>false, :default=>:init.to_s
20
+ end
21
+
22
+ # serialize plugin must be defined at the bottom of all class
23
+ # method calls.
24
+ # Possible source column data:
25
+ # vdc volume:
26
+ # {:type=>:vdcvol, :account_id=>'a-xxxxx', :snapshot_id=>'snap-xxxxxx'}
27
+ # {:type=>:http, :uri=>'http://localhost/xxx/xxx'}
28
+ plugin :serialization
29
+ serialize_attributes :yaml, :source
30
+
31
+ def validate
32
+ unless [BOOT_DEV_SAN, BOOT_DEV_LOCAL].member?(self.boot_dev_type)
33
+ errors.add(:boot_dev_type, "Invalid boot dev type: #{self.boot_dev_type}")
34
+ end
35
+
36
+ unless HostPool::SUPPORTED_ARCH.member?(self.arch)
37
+ errors.add(:arch, "Unsupported arch type: #{self.arch}")
38
+ end
39
+ end
40
+
41
+ def to_hash
42
+ super.merge({:source=>self.source.dup, :description=>description.to_s})
43
+ end
44
+
45
+ end
46
+ end
@@ -0,0 +1,255 @@
1
+ # -*- coding: utf-8 -*-
2
+
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()
10
+ class Instance < AccountResource
11
+ taggable 'i'
12
+
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
20
+ String :ssh_key_pair_id
21
+
22
+ Text :user_data, :null=>false, :default=>''
23
+ Text :runtime_config, :null=>false, :default=>''
24
+
25
+ Time :terminated_at
26
+ index :state
27
+ index :terminated_at
28
+ # can not use same hostname within an account.
29
+ index [:account_id, :hostname], {:unique=>true}
30
+ end
31
+ with_timestamps
32
+
33
+ many_to_one :image
34
+ many_to_one :instance_spec
35
+ alias :spec :instance_spec
36
+ many_to_one :host_pool
37
+ one_to_many :volume
38
+ one_to_many :instance_nic
39
+ alias :nic :instance_nic
40
+ one_to_many :instance_netfilter_groups
41
+ many_to_many :netfilter_groups, :join_table=>:instance_netfilter_groups
42
+ many_to_one :ssh_key_pair
43
+
44
+ subset(:lives, {:terminated_at => nil})
45
+
46
+ # serialization plugin must be defined at the bottom of all class
47
+ # method calls.
48
+ # Possible column data:
49
+ # kvm:
50
+ # {:vnc_port=>11}
51
+ plugin :serialization
52
+ serialize_attributes :yaml, :runtime_config
53
+
54
+ def validate
55
+ super
56
+
57
+ # TODO: hostname column validation
58
+ end
59
+
60
+ def before_validation
61
+ super
62
+
63
+ self[:user_data] = '' if self.user_data.nil?
64
+ self[:hostname] = self.uuid if self.hostname.nil?
65
+ end
66
+
67
+ # dump column data as hash with details of associated models.
68
+ # this is for internal use.
69
+ def to_hash
70
+ h = super
71
+ h = h.merge({:user_data => user_data.to_s, # Sequel::BLOB -> String
72
+ :runtime_config => self.runtime_config, # yaml -> hash
73
+ :image=>image.to_hash,
74
+ :host_pool=>host_pool.to_hash,
75
+ :instance_nics=>instance_nic.map {|n| n.to_hash },
76
+ :instance_spec=>instance_spec.to_hash,
77
+ })
78
+ h[:volume]={}
79
+ if self.volume
80
+ self.volume.each { |v|
81
+ h[:volume][v.canonical_uuid] = v.to_hash_document
82
+ }
83
+ end
84
+ h
85
+ end
86
+
87
+ # returns hash data for API response on
88
+ # GET instances/[uuid]
89
+ #
90
+ # @exmaple Example output data.
91
+ # { :id=>
92
+ # :cpu_cores
93
+ # :memory_size
94
+ # :image_id
95
+ # :network => {'global1'=>{:ipaddr=>'111.111.111.111'}}
96
+ # :volume => {'uuid'=>{:guest_device_name=>,}}
97
+ # :ssh_key_pair => 'xxxxx',
98
+ # :netfilter_group => ['rule1', 'rule2']
99
+ # :created_at
100
+ # :state
101
+ # :status
102
+ # }
103
+ def to_api_document
104
+ h = {
105
+ :id => canonical_uuid,
106
+ :cpu_cores => instance_spec.cpu_cores,
107
+ :memory_size => instance_spec.memory_size,
108
+ :image_id => image.canonical_uuid,
109
+ :created_at => self.created_at,
110
+ :state => self.state,
111
+ :status => self.status,
112
+ :ssh_key_pair => nil,
113
+ :network => [],
114
+ :volume => [],
115
+ :netfilter_group => [],
116
+ }
117
+ if self.ssh_key_pair
118
+ h[:ssh_key_pair] = self.ssh_key_pair.name
119
+ end
120
+
121
+ if instance_nic
122
+ instance_nic.each { |n|
123
+ if n.ip
124
+ h[:network] << {
125
+ :network_name => n.ip.network.name,
126
+ :ipaddr => n.ip.ipv4
127
+ }
128
+ end
129
+ }
130
+ end
131
+
132
+ if self.volume
133
+ self.volume.each { |v|
134
+ h[:volume] << {
135
+ :vol_id => v.canonical_uuid,
136
+ :guest_device_name=>v.guest_device_name,
137
+ :state=>v.state,
138
+ }
139
+ }
140
+ end
141
+
142
+ if self.netfilter_groups
143
+ self.netfilter_groups.each { |n|
144
+ h[:netfilter_group] << n.name
145
+ }
146
+ end
147
+ h
148
+ end
149
+
150
+ # Returns the hypervisor type for the instance.
151
+ def hypervisor
152
+ self.host_pool.hypervisor
153
+ end
154
+
155
+ # Returns the architecture type of the image
156
+ def arch
157
+ self.image.arch
158
+ end
159
+
160
+ def cpu_cores
161
+ self.instance_spec.cpu_cores
162
+ end
163
+
164
+ def memory_size
165
+ self.instance_spec.memory_size
166
+ end
167
+
168
+ def config
169
+ self.instance_spec.config
170
+ end
171
+
172
+ def add_nic(vifname=nil, vendor_id=nil)
173
+ vifname ||= "vif-#{self[:uuid]}"
174
+ # TODO: get default vendor ID based on the hypervisor.
175
+ vendor_id ||= '00:ff:f1'
176
+ nic = InstanceNic.new({:vif=>vifname,
177
+ :mac_addr=>vendor_id
178
+ })
179
+ nic.instance = self
180
+ nic.save
181
+ end
182
+
183
+ # Join this instance to the list of netfilter group using group's uuid.
184
+ # @param [String,Array] netfilter_group_uuids
185
+ def join_netfilter_group(netfilter_group_uuids)
186
+ netfilter_group_uuids = [netfilter_group_uuids] if netfilter_group_uuids.is_a?(String)
187
+ joined_group_uuids = self.netfilter_groups.map { |netfilter_group|
188
+ netfilter_group.canonical_uuid
189
+ }
190
+ target_group_uuids = netfilter_group_uuids.uniq - joined_group_uuids.uniq
191
+ target_group_uuids.uniq!
192
+
193
+ target_group_uuids.map { |target_group_uuid|
194
+ if ng = NetfilterGroup[target_group_uuid]
195
+ InstanceNetfilterGroup.create(:instance_id => self.id,
196
+ :netfilter_group_id => ng.id)
197
+ end
198
+ }
199
+ end
200
+
201
+ def ips
202
+ self.instance_nic.map { |nic| nic.ip }
203
+ end
204
+
205
+ def netfilter_group_instances
206
+ instances = self.netfilter_groups.map { |g| g.instances }
207
+
208
+ instances.flatten!.uniq! if instances.size > 0
209
+ instances
210
+ end
211
+
212
+ def fqdn_hostname
213
+ sprintf("%s.%s.%s", self.hostname, self.account.uuid, self.host_pool.network.domain_name)
214
+ end
215
+
216
+ # Retrieve all networks belong to this instance
217
+ # @return [Array[Models::Network]]
218
+ def networks
219
+ instance_nic.select { |nic|
220
+ !nic.ip.nil?
221
+ }.map { |nic|
222
+ nic.ip.network
223
+ }.group_by { |net|
224
+ net.name
225
+ }.values.map { |i|
226
+ i.first
227
+ }
228
+ end
229
+
230
+ # Join this instance to the list of netfilter group using group name.
231
+ # @param [String] account_id uuid of current account.
232
+ # @param [String,Array] nfgroup_names
233
+ def join_nfgroup_by_name(account_id, nfgroup_names)
234
+ nfgroup_names = [nfgroup_names] if nfgroup_names.is_a?(String)
235
+
236
+ uuids = nfgroup_names.map { |n|
237
+ ng = NetfilterGroup.for_update.filter(:account_id=>account_id,
238
+ :name=>n).first
239
+ ng.nil? ? nil : ng.canonical_uuid
240
+ }
241
+ # clean up nils
242
+ join_netfilter_group(uuids.compact.uniq)
243
+ end
244
+
245
+ def self.lock!
246
+ super()
247
+ Image.lock!
248
+ InstanceSpec.lock!
249
+ InstanceNic.lock!
250
+ Volume.lock!
251
+ VolumeSnapshot.lock!
252
+ IpLease.lock!
253
+ end
254
+ end
255
+ end
@@ -0,0 +1,16 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ module Dcmgr::Models
4
+ class InstanceNetfilterGroup < BaseNew
5
+
6
+ inheritable_schema do
7
+ Fixnum :instance_id, :null=>false
8
+ Fixnum :netfilter_group_id, :null=>false
9
+ end
10
+ # with_timestamps
11
+
12
+ many_to_one :instance
13
+ many_to_one :netfilter_group
14
+ end
15
+
16
+ end