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