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,72 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
require 'isono'
|
3
|
+
|
4
|
+
module Dcmgr
|
5
|
+
module NodeModules
|
6
|
+
class StaCollector < Isono::NodeModules::Base
|
7
|
+
|
8
|
+
initialize_hook do
|
9
|
+
app = Isono::Rack::ObjectMethod.new(myinstance)
|
10
|
+
rpc = Isono::NodeModules::RpcChannel.new(node)
|
11
|
+
rpc.register_endpoint('sta-collector', Isono::Rack.build do
|
12
|
+
use Isono::Rack::DataStore
|
13
|
+
run proc { |req, res|
|
14
|
+
Thread.current[Models::BaseNew::LOCK_TABLES_KEY] = {}
|
15
|
+
app.call(req, res)
|
16
|
+
}
|
17
|
+
end)
|
18
|
+
end
|
19
|
+
|
20
|
+
terminate_hook do
|
21
|
+
end
|
22
|
+
|
23
|
+
def get_volume(volume_id)
|
24
|
+
Models::Volume.lock!
|
25
|
+
v = Dcmgr::Models::Volume[volume_id]
|
26
|
+
v.merge_pool_data
|
27
|
+
end
|
28
|
+
|
29
|
+
def get_snapshot(snapshot_id)
|
30
|
+
Models::VolumeSnapshot.lock!
|
31
|
+
vs = Dcmgr::Models::VolumeSnapshot[snapshot_id]
|
32
|
+
vs.to_hash_document
|
33
|
+
end
|
34
|
+
|
35
|
+
def update_volume(data)
|
36
|
+
Models::Volume.lock!
|
37
|
+
v = Dcmgr::Models::Volume[data[:volume_id]]
|
38
|
+
|
39
|
+
column = case data[:state]
|
40
|
+
when :creating
|
41
|
+
[:state, :export_path]
|
42
|
+
when :available
|
43
|
+
if !data[:transport_information].nil?
|
44
|
+
[:state, :transport_information]
|
45
|
+
else
|
46
|
+
[:state, :host_device_name, :instance_id, :detached_at]
|
47
|
+
end
|
48
|
+
when :attaching
|
49
|
+
[:state, :host_device_name]
|
50
|
+
when :attached
|
51
|
+
[:state, :guest_device_name, :attached_at]
|
52
|
+
when :detaching
|
53
|
+
[:state, :guest_device_name]
|
54
|
+
else
|
55
|
+
[:state]
|
56
|
+
end
|
57
|
+
|
58
|
+
v.set_fields(data, column).save
|
59
|
+
# do not respond model object.
|
60
|
+
nil
|
61
|
+
end
|
62
|
+
|
63
|
+
def update_snapshot(data)
|
64
|
+
Models::VolumeSnapshot.lock!
|
65
|
+
vs = Dcmgr::Models::VolumeSnapshot[data[:snapshot_id]]
|
66
|
+
vs.set_fields(data, [:state]).save
|
67
|
+
# do not respond model object.
|
68
|
+
nil
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
|
2
|
+
module Dcmgr
|
3
|
+
module PhysicalHostScheduler
|
4
|
+
class NoPhysicalHostError < StandardError; end
|
5
|
+
|
6
|
+
autoload :Algorithm1, 'dcmgr/scheduler/algorithm1'
|
7
|
+
autoload :Algorithm2, 'dcmgr/scheduler/algorithm2'
|
8
|
+
autoload :FindFirst, 'dcmgr/scheduler/find_first'
|
9
|
+
autoload :FindLast, 'dcmgr/scheduler/find_last'
|
10
|
+
autoload :FindRandom, 'dcmgr/scheduler/find_random'
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
|
2
|
+
module Dcmgr
|
3
|
+
module PhysicalHostScheduler
|
4
|
+
# This is a simple host scheduler which gets back a host found
|
5
|
+
# at the top of hosts list.
|
6
|
+
class FindLast
|
7
|
+
def assign_to_instance(hosts, instance)
|
8
|
+
Dcmgr::logger.debug "assign to instance (%d hosts)" % hosts.length
|
9
|
+
p 'hosts'
|
10
|
+
p hosts
|
11
|
+
return hosts.last
|
12
|
+
raise NoPhysicalHostError.new("can't assign physical host")
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
|
2
|
+
module Dcmgr
|
3
|
+
module PhysicalHostScheduler
|
4
|
+
# This is a simple host scheduler which gets back a host found
|
5
|
+
# at the top of hosts list.
|
6
|
+
class FindRandom
|
7
|
+
def assign_to_instance(hosts, instance)
|
8
|
+
Dcmgr::logger.debug "assign to instance (%d hosts)" % hosts.length
|
9
|
+
hvc_host = hosts[ rand(hosts.length) ]
|
10
|
+
p 'hvc_host'
|
11
|
+
p hvc_host
|
12
|
+
raise NoPhysicalHostError.new("can't assign physical host")
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'statemachine'
|
4
|
+
|
5
|
+
module Dcmgr::Stm
|
6
|
+
class Instance
|
7
|
+
STM = Statemachine.build {
|
8
|
+
startstate :pending
|
9
|
+
superstate :instance_condition do
|
10
|
+
trans :pending, :on_create, :starting
|
11
|
+
trans :starting, :on_started, :running
|
12
|
+
trans :running, :on_shutdown, :shuttingdown
|
13
|
+
trans :shuttingdown, :on_terminated, :terminated
|
14
|
+
|
15
|
+
event :on_fail, :failed
|
16
|
+
end
|
17
|
+
|
18
|
+
trans :failed, :on_fail, :failed
|
19
|
+
}
|
20
|
+
|
21
|
+
def initialize
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
require 'statemachine'
|
3
|
+
|
4
|
+
module Dcmgr::Stm
|
5
|
+
class SnapshotContext < OpenStruct
|
6
|
+
|
7
|
+
attr_reader :stm
|
8
|
+
|
9
|
+
def initialize(snapshot_id=nil)
|
10
|
+
super({:snapshot_id=>snapshot_id})
|
11
|
+
@stm = Statemachine.build {
|
12
|
+
trans :registering, :on_create, :creating
|
13
|
+
trans :creating, :on_create, :available
|
14
|
+
trans :available, :on_delete, :deleting
|
15
|
+
trans :deleting, :on_delete, :deleted
|
16
|
+
|
17
|
+
trans :registering, :on_fail, :failed
|
18
|
+
trans :creating, :on_fail, :failed
|
19
|
+
trans :available, :on_fail, :failed
|
20
|
+
trans :deleting, :on_fail, :failed
|
21
|
+
}
|
22
|
+
@stm.context = self
|
23
|
+
end
|
24
|
+
|
25
|
+
def state
|
26
|
+
@stm.state
|
27
|
+
end
|
28
|
+
|
29
|
+
def to_hash
|
30
|
+
@table.dup.merge({:state=>@stm.state})
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
require 'statemachine'
|
3
|
+
|
4
|
+
module Dcmgr::Stm
|
5
|
+
class VolumeContext < OpenStruct
|
6
|
+
attr_reader :stm
|
7
|
+
|
8
|
+
def initialize(volume_id=nil)
|
9
|
+
super({:volume_id => volume_id,
|
10
|
+
:export_path => nil,
|
11
|
+
:transport_information => nil,
|
12
|
+
:instance_id => nil,
|
13
|
+
:host_device_name => nil,
|
14
|
+
:guest_device_name => nil,
|
15
|
+
:deleted_at => nil,
|
16
|
+
:attached_at => nil,
|
17
|
+
:detached_at => nil,
|
18
|
+
})
|
19
|
+
@stm = Statemachine.build {
|
20
|
+
startstate :registering
|
21
|
+
superstate :volume_condition do
|
22
|
+
trans :registering, :on_create, :creating
|
23
|
+
trans :creating, :on_register, :available
|
24
|
+
trans :available, :on_attach, :attaching
|
25
|
+
trans :attaching, :on_attach, :attached
|
26
|
+
trans :attached, :on_detach, :detaching
|
27
|
+
trans :detaching, :on_detach, :available
|
28
|
+
|
29
|
+
event :on_fail, :failed
|
30
|
+
event :on_deregister, :deregistering
|
31
|
+
end
|
32
|
+
|
33
|
+
trans :failed, :on_create, :creating
|
34
|
+
trans :failed, :on_register, :available
|
35
|
+
trans :failed, :on_fail, :failed
|
36
|
+
trans :failed, :on_deregister, :deleting
|
37
|
+
trans :failed, :on_delete, :deleted
|
38
|
+
trans :deregistering, :on_delete, :deleting
|
39
|
+
trans :deleting, :on_delete, :deleted
|
40
|
+
trans :deleted, :on_delete, :deleted
|
41
|
+
}
|
42
|
+
@stm.context = self
|
43
|
+
end
|
44
|
+
|
45
|
+
def state
|
46
|
+
@stm.state
|
47
|
+
end
|
48
|
+
|
49
|
+
def to_hash(hash={})
|
50
|
+
@table.dup.merge({:state=>@stm.state}).merge(hash)
|
51
|
+
end
|
52
|
+
|
53
|
+
def on_delete
|
54
|
+
self.deleted_at = Time.now
|
55
|
+
end
|
56
|
+
|
57
|
+
def on_attach
|
58
|
+
self.attached_at = Time.now
|
59
|
+
end
|
60
|
+
|
61
|
+
def on_detach
|
62
|
+
self.detached_at = Time.now
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'sinatra'
|
2
|
+
require 'sequel'
|
3
|
+
|
4
|
+
module Dcmgr::Web
|
5
|
+
class Base < Sinatra::Base
|
6
|
+
set :logger, false
|
7
|
+
helpers { include Dcmgr::Helpers }
|
8
|
+
|
9
|
+
def self.public_crud model
|
10
|
+
model.actions {|action, pattern, proc|
|
11
|
+
Dcmgr::logger.debug "REGISTER: %s %s" % [action, pattern]
|
12
|
+
self.send action, pattern, &proc
|
13
|
+
}
|
14
|
+
end
|
15
|
+
|
16
|
+
not_found do
|
17
|
+
logger.debug "not found: #{request.request_method} #{request.path}"
|
18
|
+
"not found"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,128 @@
|
|
1
|
+
module Rack
|
2
|
+
class Request
|
3
|
+
# The media types of the HTTP_ACCEPT header ordered according to their
|
4
|
+
# "quality" (preference level), without any media type parameters.
|
5
|
+
#
|
6
|
+
# ===== Examples
|
7
|
+
#
|
8
|
+
# env['HTTP_ACCEPT'] #=> 'application/xml;q=0.8,text/html,text/plain;q=0.9'
|
9
|
+
#
|
10
|
+
# req = Rack::Request.new(env)
|
11
|
+
# req.accept_media_types #=> ['text/html', 'text/plain', 'application/xml']
|
12
|
+
# req.accept_media_types.prefered #=> 'text/html'
|
13
|
+
#
|
14
|
+
# For more information, see:
|
15
|
+
# * Acept header: http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.1
|
16
|
+
# * Quality values: http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.9
|
17
|
+
#
|
18
|
+
# ===== Returns
|
19
|
+
# AcceptMediaTypes:: ordered list of accept header's media types
|
20
|
+
#
|
21
|
+
def accept_media_types
|
22
|
+
@accept_media_types ||= Rack::AcceptMediaTypes.new(@env['HTTP_ACCEPT'])
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
# AcceptMediaTypes is intended for wrapping env['HTTP_ACCEPT'].
|
27
|
+
#
|
28
|
+
# It allows ordering of its values (accepted media types) according to their
|
29
|
+
# "quality" (preference level).
|
30
|
+
#
|
31
|
+
# This wrapper is typically used to determine the request's prefered media
|
32
|
+
# type (see example below).
|
33
|
+
#
|
34
|
+
# ===== Examples
|
35
|
+
#
|
36
|
+
# env['HTTP_ACCEPT'] #=> 'application/xml;q=0.8,text/html,text/plain;q=0.9'
|
37
|
+
#
|
38
|
+
# types = Rack::AcceptMediaTypes.new(env['HTTP_ACCEPT'])
|
39
|
+
# types #=> ['text/html', 'text/plain', 'application/xml']
|
40
|
+
# types.prefered #=> 'text/html'
|
41
|
+
#
|
42
|
+
# ===== Notes
|
43
|
+
#
|
44
|
+
# For simplicity, media type parameters are striped, as they are seldom used
|
45
|
+
# in practice. Users who need them are excepted to parse the Accept header
|
46
|
+
# manually.
|
47
|
+
#
|
48
|
+
# ===== References
|
49
|
+
#
|
50
|
+
# HTTP 1.1 Specs:
|
51
|
+
# * http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.1
|
52
|
+
# * http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.9
|
53
|
+
#
|
54
|
+
class AcceptMediaTypes < Array
|
55
|
+
|
56
|
+
#--
|
57
|
+
# NOTE
|
58
|
+
# Reason for special handling of nil accept header:
|
59
|
+
#
|
60
|
+
# "If no Accept header field is present, then it is assumed that the client
|
61
|
+
# accepts all media types."
|
62
|
+
#
|
63
|
+
def initialize(header)
|
64
|
+
if header.nil?
|
65
|
+
replace(['*/*'])
|
66
|
+
else
|
67
|
+
replace(order(header.gsub(/ /, '').split(/,/)))
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
# The client's prefered media type.
|
72
|
+
def prefered
|
73
|
+
first
|
74
|
+
end
|
75
|
+
|
76
|
+
private
|
77
|
+
|
78
|
+
# Order media types by quality values, remove invalid types, and return media ranges.
|
79
|
+
#
|
80
|
+
def order(types) #:nodoc:
|
81
|
+
types.map {|type| AcceptMediaType.new(type) }.reverse.sort.reverse.select {|type| type.valid? }.map {|type| type.range }
|
82
|
+
end
|
83
|
+
|
84
|
+
# http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.1
|
85
|
+
#
|
86
|
+
class AcceptMediaType #:nodoc:
|
87
|
+
include Comparable
|
88
|
+
|
89
|
+
# media-range = ( "*/*"
|
90
|
+
# | ( type "/" "*" )
|
91
|
+
# | ( type "/" subtype )
|
92
|
+
# ) *( ";" parameter )
|
93
|
+
attr_accessor :range
|
94
|
+
|
95
|
+
# qvalue = ( "0" [ "." 0*3DIGIT ] )
|
96
|
+
# | ( "1" [ "." 0*3("0") ] )
|
97
|
+
attr_accessor :quality
|
98
|
+
|
99
|
+
def initialize(type)
|
100
|
+
self.range, *params = type.split(';')
|
101
|
+
self.quality = extract_quality(params)
|
102
|
+
end
|
103
|
+
|
104
|
+
def <=>(type)
|
105
|
+
self.quality <=> type.quality
|
106
|
+
end
|
107
|
+
|
108
|
+
# "A weight is normalized to a real number in the range 0 through 1,
|
109
|
+
# where 0 is the minimum and 1 the maximum value. If a parameter has a
|
110
|
+
# quality value of 0, then content with this parameter is `not
|
111
|
+
# acceptable' for the client."
|
112
|
+
#
|
113
|
+
def valid?
|
114
|
+
self.quality.between?(0.1, 1)
|
115
|
+
end
|
116
|
+
|
117
|
+
private
|
118
|
+
# Extract value from 'q=FLOAT' parameter if present, otherwise assume 1
|
119
|
+
#
|
120
|
+
# "The default value is q=1."
|
121
|
+
#
|
122
|
+
def extract_quality(params)
|
123
|
+
q = params.detect {|p| p.match(/q=\d\.?\d{0,3}/) }
|
124
|
+
q ? q.split('=').last.to_f : 1.0
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'sinatra/base'
|
2
|
+
|
3
|
+
# Lazy Basic HTTP authentication. Authentication is only forced when the
|
4
|
+
# credentials are actually needed.
|
5
|
+
module Sinatra
|
6
|
+
module LazyAuth
|
7
|
+
class LazyCredentials
|
8
|
+
def initialize(app)
|
9
|
+
@app = app
|
10
|
+
@provided = false
|
11
|
+
end
|
12
|
+
|
13
|
+
def user
|
14
|
+
credentials!
|
15
|
+
@user
|
16
|
+
end
|
17
|
+
|
18
|
+
def password
|
19
|
+
credentials!
|
20
|
+
@password
|
21
|
+
end
|
22
|
+
|
23
|
+
def provided?
|
24
|
+
@provided
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
def credentials!
|
29
|
+
unless provided?
|
30
|
+
auth = Rack::Auth::Basic::Request.new(@app.request.env)
|
31
|
+
unless auth.provided? && auth.basic? && auth.credentials
|
32
|
+
@app.authorize!
|
33
|
+
end
|
34
|
+
@user = auth.credentials[0]
|
35
|
+
@password = auth.credentials[1]
|
36
|
+
@provided = true
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
|
42
|
+
def authorize!
|
43
|
+
r = "#{DRIVER}-deltacloud@#{HOSTNAME}"
|
44
|
+
response['WWW-Authenticate'] = %(Basic realm="#{r}")
|
45
|
+
throw(:halt, [401, "Not authorized\n"])
|
46
|
+
end
|
47
|
+
|
48
|
+
# Request the current user's credentials. Actual credentials are only
|
49
|
+
# requested when an attempt is made to get the user name or password
|
50
|
+
def credentials
|
51
|
+
LazyCredentials.new(self)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
helpers LazyAuth
|
56
|
+
end
|