wakame-vdc-agents 10.11.0
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +202 -0
- data/NOTICE +1 -0
- data/Rakefile +142 -0
- data/bin/hva +972 -0
- data/bin/nsa +147 -0
- data/bin/sta +182 -0
- data/config/hva.conf.example +10 -0
- data/config/initializers/isono.rb +43 -0
- data/config/initializers/passenger.rb +6 -0
- data/config/initializers/sequel.rb +21 -0
- data/config/nsa.conf.example +9 -0
- data/config/path_resolver.rb +12 -0
- data/lib/dcmgr.rb +115 -0
- data/lib/dcmgr/endpoints/core_api.rb +1004 -0
- data/lib/dcmgr/endpoints/core_api_mock.rb +816 -0
- data/lib/dcmgr/endpoints/errors.rb +55 -0
- data/lib/dcmgr/endpoints/metadata.rb +129 -0
- data/lib/dcmgr/logger.rb +44 -0
- data/lib/dcmgr/models/account.rb +104 -0
- data/lib/dcmgr/models/account_resource.rb +16 -0
- data/lib/dcmgr/models/base.rb +69 -0
- data/lib/dcmgr/models/base_new.rb +371 -0
- data/lib/dcmgr/models/frontend_system.rb +38 -0
- data/lib/dcmgr/models/host_pool.rb +102 -0
- data/lib/dcmgr/models/image.rb +46 -0
- data/lib/dcmgr/models/instance.rb +255 -0
- data/lib/dcmgr/models/instance_netfilter_group.rb +16 -0
- data/lib/dcmgr/models/instance_nic.rb +68 -0
- data/lib/dcmgr/models/instance_spec.rb +21 -0
- data/lib/dcmgr/models/ip_lease.rb +42 -0
- data/lib/dcmgr/models/netfilter_group.rb +88 -0
- data/lib/dcmgr/models/netfilter_rule.rb +21 -0
- data/lib/dcmgr/models/network.rb +32 -0
- data/lib/dcmgr/models/physical_host.rb +67 -0
- data/lib/dcmgr/models/request_log.rb +25 -0
- data/lib/dcmgr/models/ssh_key_pair.rb +55 -0
- data/lib/dcmgr/models/storage_pool.rb +134 -0
- data/lib/dcmgr/models/tag.rb +126 -0
- data/lib/dcmgr/models/tag_mapping.rb +28 -0
- data/lib/dcmgr/models/volume.rb +130 -0
- data/lib/dcmgr/models/volume_snapshot.rb +47 -0
- data/lib/dcmgr/node_modules/hva_collector.rb +134 -0
- data/lib/dcmgr/node_modules/sta_collector.rb +72 -0
- data/lib/dcmgr/scheduler.rb +12 -0
- data/lib/dcmgr/scheduler/find_last.rb +16 -0
- data/lib/dcmgr/scheduler/find_random.rb +16 -0
- data/lib/dcmgr/stm/instance.rb +25 -0
- data/lib/dcmgr/stm/snapshot_context.rb +33 -0
- data/lib/dcmgr/stm/volume_context.rb +65 -0
- data/lib/dcmgr/web/base.rb +21 -0
- data/lib/sinatra/accept_media_types.rb +128 -0
- data/lib/sinatra/lazy_auth.rb +56 -0
- data/lib/sinatra/rabbit.rb +278 -0
- data/lib/sinatra/respond_to.rb +272 -0
- data/lib/sinatra/sequel_transaction.rb +27 -0
- data/lib/sinatra/static_assets.rb +83 -0
- data/lib/sinatra/url_for.rb +44 -0
- 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
|