wakame-vdc-dcmgr 10.11.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (59) hide show
  1. data/LICENSE +202 -0
  2. data/NOTICE +1 -0
  3. data/Rakefile +142 -0
  4. data/bin/collector +46 -0
  5. data/config/dcmgr.conf.example +9 -0
  6. data/config/initializers/isono.rb +43 -0
  7. data/config/initializers/passenger.rb +6 -0
  8. data/config/initializers/sequel.rb +21 -0
  9. data/config/path_resolver.rb +12 -0
  10. data/lib/dcmgr.rb +115 -0
  11. data/lib/dcmgr/endpoints/core_api.rb +1004 -0
  12. data/lib/dcmgr/endpoints/core_api_mock.rb +816 -0
  13. data/lib/dcmgr/endpoints/errors.rb +55 -0
  14. data/lib/dcmgr/endpoints/metadata.rb +129 -0
  15. data/lib/dcmgr/logger.rb +44 -0
  16. data/lib/dcmgr/models/account.rb +104 -0
  17. data/lib/dcmgr/models/account_resource.rb +16 -0
  18. data/lib/dcmgr/models/base.rb +69 -0
  19. data/lib/dcmgr/models/base_new.rb +371 -0
  20. data/lib/dcmgr/models/frontend_system.rb +38 -0
  21. data/lib/dcmgr/models/host_pool.rb +102 -0
  22. data/lib/dcmgr/models/image.rb +46 -0
  23. data/lib/dcmgr/models/instance.rb +255 -0
  24. data/lib/dcmgr/models/instance_netfilter_group.rb +16 -0
  25. data/lib/dcmgr/models/instance_nic.rb +68 -0
  26. data/lib/dcmgr/models/instance_spec.rb +21 -0
  27. data/lib/dcmgr/models/ip_lease.rb +42 -0
  28. data/lib/dcmgr/models/netfilter_group.rb +88 -0
  29. data/lib/dcmgr/models/netfilter_rule.rb +21 -0
  30. data/lib/dcmgr/models/network.rb +32 -0
  31. data/lib/dcmgr/models/physical_host.rb +67 -0
  32. data/lib/dcmgr/models/request_log.rb +25 -0
  33. data/lib/dcmgr/models/ssh_key_pair.rb +55 -0
  34. data/lib/dcmgr/models/storage_pool.rb +134 -0
  35. data/lib/dcmgr/models/tag.rb +126 -0
  36. data/lib/dcmgr/models/tag_mapping.rb +28 -0
  37. data/lib/dcmgr/models/volume.rb +130 -0
  38. data/lib/dcmgr/models/volume_snapshot.rb +47 -0
  39. data/lib/dcmgr/node_modules/hva_collector.rb +134 -0
  40. data/lib/dcmgr/node_modules/sta_collector.rb +72 -0
  41. data/lib/dcmgr/scheduler.rb +12 -0
  42. data/lib/dcmgr/scheduler/find_last.rb +16 -0
  43. data/lib/dcmgr/scheduler/find_random.rb +16 -0
  44. data/lib/dcmgr/stm/instance.rb +25 -0
  45. data/lib/dcmgr/stm/snapshot_context.rb +33 -0
  46. data/lib/dcmgr/stm/volume_context.rb +65 -0
  47. data/lib/dcmgr/web/base.rb +21 -0
  48. data/lib/sinatra/accept_media_types.rb +128 -0
  49. data/lib/sinatra/lazy_auth.rb +56 -0
  50. data/lib/sinatra/rabbit.rb +278 -0
  51. data/lib/sinatra/respond_to.rb +272 -0
  52. data/lib/sinatra/sequel_transaction.rb +27 -0
  53. data/lib/sinatra/static_assets.rb +83 -0
  54. data/lib/sinatra/url_for.rb +44 -0
  55. data/web/api/config.ru +20 -0
  56. data/web/api/public/index.html +0 -0
  57. data/web/metadata/config.ru +20 -0
  58. data/web/metadata/public/index.html +0 -0
  59. metadata +326 -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