wakame-vdc-agents 10.11.0

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 (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