wakame-vdc-dcmgr 11.06.0 → 11.12.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (136) hide show
  1. data/Rakefile +19 -31
  2. data/bin/collector +6 -1
  3. data/config/db/migrations/0001_v1110_origin.rb +446 -0
  4. data/config/dcmgr.conf.example +51 -0
  5. data/lib/dcmgr.rb +99 -22
  6. data/lib/dcmgr/cli/base.rb +34 -1
  7. data/lib/dcmgr/cli/host.rb +24 -20
  8. data/lib/dcmgr/cli/image.rb +38 -19
  9. data/lib/dcmgr/cli/keypair.rb +16 -12
  10. data/lib/dcmgr/cli/network.rb +189 -81
  11. data/lib/dcmgr/cli/quota.rb +2 -2
  12. data/lib/dcmgr/cli/security_group.rb +106 -0
  13. data/lib/dcmgr/cli/spec.rb +144 -39
  14. data/lib/dcmgr/cli/storage.rb +16 -15
  15. data/lib/dcmgr/cli/tag.rb +20 -14
  16. data/lib/dcmgr/cli/vlan.rb +5 -5
  17. data/lib/dcmgr/drivers/backing_store.rb +32 -0
  18. data/lib/dcmgr/drivers/comstar.rb +81 -0
  19. data/lib/dcmgr/drivers/iijgio_storage.rb +9 -19
  20. data/lib/dcmgr/drivers/iscsi_target.rb +41 -0
  21. data/lib/dcmgr/drivers/kvm.rb +161 -28
  22. data/lib/dcmgr/drivers/linux_iscsi.rb +60 -0
  23. data/lib/dcmgr/drivers/local_storage.rb +24 -0
  24. data/lib/dcmgr/drivers/lxc.rb +167 -125
  25. data/lib/dcmgr/drivers/raw.rb +74 -0
  26. data/lib/dcmgr/drivers/s3_storage.rb +7 -19
  27. data/lib/dcmgr/drivers/snapshot_storage.rb +18 -28
  28. data/lib/dcmgr/drivers/storage_initiator.rb +28 -0
  29. data/lib/dcmgr/drivers/sun_iscsi.rb +32 -0
  30. data/lib/dcmgr/drivers/zfs.rb +77 -0
  31. data/lib/dcmgr/endpoints/core_api.rb +315 -263
  32. data/lib/dcmgr/endpoints/errors.rb +21 -10
  33. data/lib/dcmgr/endpoints/metadata.rb +360 -23
  34. data/lib/dcmgr/helpers/cli_helper.rb +6 -3
  35. data/lib/dcmgr/helpers/ec2_metadata_helper.rb +9 -0
  36. data/lib/dcmgr/helpers/nic_helper.rb +11 -0
  37. data/lib/dcmgr/helpers/snapshot_storage_helper.rb +34 -0
  38. data/lib/dcmgr/models/account.rb +0 -6
  39. data/lib/dcmgr/models/account_resource.rb +0 -4
  40. data/lib/dcmgr/models/base_new.rb +14 -2
  41. data/lib/dcmgr/models/dhcp_range.rb +38 -0
  42. data/lib/dcmgr/models/frontend_system.rb +0 -6
  43. data/lib/dcmgr/models/history.rb +0 -11
  44. data/lib/dcmgr/models/host_node.rb +131 -0
  45. data/lib/dcmgr/models/hostname_lease.rb +0 -8
  46. data/lib/dcmgr/models/image.rb +31 -18
  47. data/lib/dcmgr/models/instance.rb +137 -143
  48. data/lib/dcmgr/models/instance_nic.rb +52 -29
  49. data/lib/dcmgr/models/instance_security_group.rb +9 -0
  50. data/lib/dcmgr/models/instance_spec.rb +163 -31
  51. data/lib/dcmgr/models/ip_lease.rb +10 -21
  52. data/lib/dcmgr/models/mac_lease.rb +30 -11
  53. data/lib/dcmgr/models/network.rb +148 -27
  54. data/lib/dcmgr/models/physical_network.rb +18 -0
  55. data/lib/dcmgr/models/quota.rb +0 -10
  56. data/lib/dcmgr/models/request_log.rb +3 -18
  57. data/lib/dcmgr/models/security_group.rb +66 -0
  58. data/lib/dcmgr/models/security_group_rule.rb +145 -0
  59. data/lib/dcmgr/models/ssh_key_pair.rb +16 -19
  60. data/lib/dcmgr/models/{storage_pool.rb → storage_node.rb} +35 -25
  61. data/lib/dcmgr/models/tag.rb +0 -14
  62. data/lib/dcmgr/models/tag_mapping.rb +1 -7
  63. data/lib/dcmgr/models/vlan_lease.rb +2 -8
  64. data/lib/dcmgr/models/volume.rb +49 -37
  65. data/lib/dcmgr/models/volume_snapshot.rb +15 -17
  66. data/lib/dcmgr/node_modules/hva_collector.rb +69 -28
  67. data/lib/dcmgr/node_modules/instance_ha.rb +23 -12
  68. data/lib/dcmgr/node_modules/instance_monitor.rb +16 -2
  69. data/lib/dcmgr/node_modules/openflow_controller.rb +784 -0
  70. data/lib/dcmgr/node_modules/scheduler.rb +189 -0
  71. data/lib/dcmgr/node_modules/service_netfilter.rb +452 -227
  72. data/lib/dcmgr/node_modules/service_openflow.rb +731 -0
  73. data/lib/dcmgr/node_modules/sta_collector.rb +20 -0
  74. data/lib/dcmgr/node_modules/sta_tgt_initializer.rb +35 -0
  75. data/lib/dcmgr/rack/request_logger.rb +11 -6
  76. data/lib/dcmgr/rpc/hva_handler.rb +256 -110
  77. data/lib/dcmgr/rpc/sta_handler.rb +244 -0
  78. data/lib/dcmgr/scheduler.rb +122 -8
  79. data/lib/dcmgr/scheduler/host_node/exclude_same.rb +24 -0
  80. data/lib/dcmgr/scheduler/host_node/find_first.rb +12 -0
  81. data/lib/dcmgr/scheduler/host_node/least_usage.rb +28 -0
  82. data/lib/dcmgr/scheduler/host_node/per_instance.rb +18 -0
  83. data/lib/dcmgr/scheduler/host_node/specify_node.rb +26 -0
  84. data/lib/dcmgr/scheduler/network/flat_single.rb +23 -0
  85. data/lib/dcmgr/scheduler/network/nat_one_to_one.rb +23 -0
  86. data/lib/dcmgr/scheduler/network/per_instance.rb +39 -0
  87. data/lib/dcmgr/scheduler/network/vif_template.rb +19 -0
  88. data/lib/dcmgr/scheduler/storage_node/find_first.rb +13 -0
  89. data/lib/dcmgr/scheduler/storage_node/least_usage.rb +23 -0
  90. data/lib/dcmgr/storage_service.rb +39 -40
  91. data/lib/dcmgr/tags.rb +3 -3
  92. data/lib/dcmgr/version.rb +1 -1
  93. data/lib/dcmgr/vnet.rb +105 -0
  94. data/lib/dcmgr/vnet/factories.rb +141 -0
  95. data/lib/dcmgr/vnet/isolators/by_securitygroup.rb +21 -0
  96. data/lib/dcmgr/vnet/isolators/dummy.rb +17 -0
  97. data/lib/dcmgr/vnet/netfilter/cache.rb +51 -0
  98. data/lib/dcmgr/vnet/netfilter/chain.rb +66 -0
  99. data/lib/dcmgr/vnet/netfilter/controller.rb +193 -0
  100. data/lib/dcmgr/vnet/netfilter/ebtables_rule.rb +53 -0
  101. data/lib/dcmgr/vnet/netfilter/iptables_rule.rb +45 -0
  102. data/lib/dcmgr/vnet/netfilter/task_manager.rb +459 -0
  103. data/lib/dcmgr/vnet/tasks/accept_all_dns.rb +19 -0
  104. data/lib/dcmgr/vnet/tasks/accept_arp_broadcast.rb +24 -0
  105. data/lib/dcmgr/vnet/tasks/accept_arp_from_friends.rb +34 -0
  106. data/lib/dcmgr/vnet/tasks/accept_arp_from_gateway.rb +21 -0
  107. data/lib/dcmgr/vnet/tasks/accept_arp_to_host.rb +30 -0
  108. data/lib/dcmgr/vnet/tasks/accept_ip_from_friends.rb +26 -0
  109. data/lib/dcmgr/vnet/tasks/accept_ip_from_gateway.rb +23 -0
  110. data/lib/dcmgr/vnet/tasks/accept_ip_to_anywhere.rb +18 -0
  111. data/lib/dcmgr/vnet/tasks/accept_related_established.rb +45 -0
  112. data/lib/dcmgr/vnet/tasks/accept_wakame_dhcp_only.rb +33 -0
  113. data/lib/dcmgr/vnet/tasks/accept_wakame_dns_only.rb +33 -0
  114. data/lib/dcmgr/vnet/tasks/debug_iptables.rb +21 -0
  115. data/lib/dcmgr/vnet/tasks/drop_arp_forwarding.rb +27 -0
  116. data/lib/dcmgr/vnet/tasks/drop_arp_to_host.rb +24 -0
  117. data/lib/dcmgr/vnet/tasks/drop_ip_from_anywhere.rb +18 -0
  118. data/lib/dcmgr/vnet/tasks/drop_ip_spoofing.rb +34 -0
  119. data/lib/dcmgr/vnet/tasks/drop_mac_spoofing.rb +33 -0
  120. data/lib/dcmgr/vnet/tasks/exclude_from_nat.rb +47 -0
  121. data/lib/dcmgr/vnet/tasks/security_group.rb +37 -0
  122. data/lib/dcmgr/vnet/tasks/static_nat.rb +54 -0
  123. data/lib/dcmgr/vnet/tasks/translate_metadata_address.rb +32 -0
  124. data/web/metadata/config.ru +1 -1
  125. metadata +174 -89
  126. data/lib/dcmgr/cli/group.rb +0 -101
  127. data/lib/dcmgr/endpoints/core_api_mock.rb +0 -865
  128. data/lib/dcmgr/models/host_pool.rb +0 -122
  129. data/lib/dcmgr/models/instance_netfilter_group.rb +0 -16
  130. data/lib/dcmgr/models/netfilter_group.rb +0 -89
  131. data/lib/dcmgr/models/netfilter_rule.rb +0 -21
  132. data/lib/dcmgr/scheduler/find_last.rb +0 -16
  133. data/lib/dcmgr/scheduler/find_random.rb +0 -16
  134. data/lib/dcmgr/stm/instance.rb +0 -25
  135. data/lib/dcmgr/stm/snapshot_context.rb +0 -33
  136. data/lib/dcmgr/stm/volume_context.rb +0 -65
@@ -0,0 +1,244 @@
1
+ # -*- coding: utf-8 -*-
2
+ require 'isono'
3
+ require 'fileutils'
4
+
5
+ module Dcmgr
6
+ module Rpc
7
+
8
+ class StaHandler < EndpointBuilder
9
+ include Dcmgr::Logger
10
+ include Dcmgr::Helpers::CliHelper
11
+
12
+ def select_backing_store
13
+ backing_store = @node.manifest.config.backing_store
14
+ @backing_store = Dcmgr::Drivers::BackingStore.select_backing_store(backing_store)
15
+ end
16
+
17
+ def select_iscsi_target
18
+ iscsi_target = @node.manifest.config.iscsi_target
19
+ @iscsi_target = Dcmgr::Drivers::IscsiTarget.select_iscsi_target(iscsi_target, @node)
20
+ end
21
+
22
+ # Setup volume file from snapshot storage and register to
23
+ # sotrage target.
24
+ def setup_and_export_volume
25
+ snapshot_file = nil
26
+ unless @volume[:snapshot_id].nil?
27
+ @snapshot = rpc.request('sta-collector', 'get_snapshot', @volume[:snapshot_id])
28
+ raise "Invalid snapshot state: #{@snapshot[:state]}" unless @snapshot[:state].to_s == 'available'
29
+ snap_filename = @destination[:filename]
30
+
31
+ begin
32
+ storage_service = Dcmgr::StorageService.new(@destination[:driver], {
33
+ :account_id => @snapshot[:account_id],
34
+ :access_key => @destination[:access_key],
35
+ :secret_key => @destination[:secret_key],
36
+ })
37
+ snapshot_storage = storage_service.snapshot_storage(@destination[:bucket], @destination[:path])
38
+ snapshot_storage.download(snap_filename)
39
+ snapshot_file = snapshot_storage.snapshot(snap_filename)
40
+ logger.info("download to #{@destination[:driver]}: #{snap_filename}")
41
+ rescue => e
42
+ logger.error(e)
43
+ raise "snapshot not downloaded"
44
+ end
45
+ end
46
+
47
+ logger.info("creating new volume #{@volume_id}")
48
+
49
+ rpc.request('sta-collector', 'update_volume', @volume_id, {:state=>:creating, :export_path=>@volume[:uuid]})
50
+
51
+ select_backing_store
52
+ @backing_store.create_volume(StaContext.new(self), snapshot_file)
53
+
54
+ unless @volume[:snapshot_id].nil?
55
+ snapshot_storage.clear
56
+ end
57
+
58
+ select_iscsi_target
59
+ opt = @iscsi_target.create(StaContext.new(self))
60
+ rpc.request('sta-collector', 'update_volume', @volume_id, {:state=>:available, :transport_information=>opt})
61
+ logger.info("registered iscsi target: #{@volume_id}")
62
+ end
63
+
64
+ job :create_volume, proc {
65
+ @volume_id = request.args[0]
66
+ @destination = Dcmgr::StorageService.repository(request.args[1])
67
+ @volume = rpc.request('sta-collector', 'get_volume', @volume_id)
68
+ raise "Invalid volume state: #{@volume[:state]}" unless @volume[:state].to_s == 'pending'
69
+
70
+ setup_and_export_volume
71
+ }, proc {
72
+ # TODO: need to clear generated temp files or remote files in remote snapshot repository.
73
+ rpc.request('sta-collector', 'update_volume', @volume_id, {:state=>:deleted, :deleted_at=>Time.now.utc})
74
+ logger.error("Failed to run create_volume: #{@volume_id}")
75
+ }
76
+
77
+ # create volume and chain to run instance.
78
+ job :create_volume_and_run_instance, proc {
79
+ @volume_id = request.args[0]
80
+ @instance_id = request.args[1]
81
+ @destination = Dcmgr::StorageService.repository(request.args[2])
82
+
83
+ @volume = rpc.request('sta-collector', 'get_volume', @volume_id)
84
+ raise "Invalid volume state: #{@volume[:state]}" unless @volume[:state].to_s == 'pending'
85
+
86
+ setup_and_export_volume
87
+
88
+ @instance = rpc.request('hva-collector', 'get_instance', @instance_id)
89
+ jobreq.submit("hva-handle.#{@instance[:host_node][:node_id]}", 'run_vol_store', @instance_id, @volume_id)
90
+ }, proc {
91
+ # TODO: need to clear generated temp files or remote files in remote snapshot repository.
92
+ rpc.request('sta-collector', 'update_volume', @volume_id, {:state=>:deleted, :deleted_at=>Time.now.utc})
93
+ rpc.request('hva-collector', 'update_instance', @instance_id, {:state=>:terminated, :terminated_at=>Time.now.utc})
94
+ logger.error("Failed to run create_volume_and_run_instance: #{@instance_id}, #{@volume_id}")
95
+ }
96
+
97
+ job :delete_volume do
98
+ @volume_id = request.args[0]
99
+ @volume = rpc.request('sta-collector', 'get_volume', @volume_id)
100
+ logger.info("#{@volume_id}: start deleting volume.")
101
+ errcount = 0
102
+ if @volume[:state].to_s == 'deleted'
103
+ raise "#{@volume_id}: Invalid volume state: deleted"
104
+ end
105
+ if @volume[:state].to_s != 'deregistering'
106
+ logger.warn("#{@volume_id}: Unexpected volume state but try destroy resource: #{@volume[:state]}")
107
+ end
108
+
109
+ # deregisterd iscsi target
110
+ select_iscsi_target
111
+ begin
112
+ @iscsi_target.delete(StaContext.new(self))
113
+ rescue => e
114
+ logger.error("#{@volume_id}: Failed to delete ISCSI target entry.")
115
+ errcount += 1
116
+ end
117
+
118
+ rpc.request('sta-collector', 'update_volume', @volume_id, {:state=>:deleting})
119
+
120
+ # delete volume
121
+ select_backing_store
122
+ begin
123
+ @backing_store.delete_volume(StaContext.new(self))
124
+ rescue => e
125
+ logger.error("#{@volume_id}: Failed to delete zfs volume: #{@volume[:storage_node][:export_path]}/#{@volume[:uuid]}")
126
+ errcount += 1
127
+ end
128
+
129
+ rpc.request('sta-collector', 'update_volume', @volume_id, {:state=>:deleted, :deleted_at=>Time.now.utc})
130
+ if errcount > 0
131
+ logger.info("#{@volume_id}: Encountered one or more errors during deleting.")
132
+ else
133
+ logger.info("#{@volume_id}: Deleted volume successfully.")
134
+ end
135
+ end
136
+
137
+ job :create_snapshot, proc {
138
+ @snapshot_id = request.args[0]
139
+ @destination = Dcmgr::StorageService.repository(request.args[1])
140
+ @snapshot = rpc.request('sta-collector', 'get_snapshot', @snapshot_id) unless @snapshot_id.nil?
141
+ @volume = rpc.request('sta-collector', 'get_volume', @snapshot[:origin_volume_id])
142
+
143
+ logger.info("create new snapshot: #{@snapshot_id}")
144
+ raise "Invalid volume state: #{@volume[:state]}" unless %w(available attached).member?(@volume[:state].to_s)
145
+
146
+ begin
147
+ storage_service = Dcmgr::StorageService.new(@destination[:driver], {
148
+ :account_id => @snapshot[:account_id],
149
+ :access_key => @destination[:access_key],
150
+ :secret_key => @destination[:secret_key],
151
+ })
152
+ snapshot_storage = storage_service.snapshot_storage(@destination[:bucket], @destination[:path])
153
+ select_backing_store
154
+
155
+ snap_filename = @destination[:filename]
156
+ @backing_store.create_snapshot(StaContext.new(self), snapshot_storage.snapshot(snap_filename))
157
+
158
+ snapshot_storage.upload(snap_filename)
159
+ snapshot_storage.clear
160
+ logger.info("upload to #{@destination[:driver]}: #{snap_filename}")
161
+ rescue => e
162
+ logger.error(e)
163
+ raise "snapshot has not be uploaded"
164
+ end
165
+
166
+ rpc.request('sta-collector', 'update_snapshot', @snapshot_id, {:state=>:available})
167
+ logger.info("created new snapshot: #{@snapshot_id}")
168
+ }, proc {
169
+ # TODO: need to clear generated temp files or remote files in remote snapshot repository.
170
+ rpc.request('sta-collector', 'update_snapshot', @snapshot_id, {:state=>:deleted, :deleted_at=>Time.now.utc})
171
+ logger.error("Failed to run create_snapshot: #{@snapshot_id}")
172
+ }
173
+
174
+ job :delete_snapshot do
175
+ @snapshot_id = request.args[0]
176
+ @destination = Dcmgr::StorageService.repository(request.args[1])
177
+ @snapshot = rpc.request('sta-collector', 'get_snapshot', @snapshot_id)
178
+ @volume = rpc.request('sta-collector', 'get_volume', @snapshot[:origin_volume_id])
179
+ logger.info("deleting snapshot: #{@snapshot_id}")
180
+ raise "Invalid snapshot state: #{@snapshot[:state]}" unless @snapshot[:state].to_s == 'deleting'
181
+ begin
182
+ storage_service = Dcmgr::StorageService.new(@destination[:driver], {
183
+ :account_id => @snapshot[:account_id],
184
+ :access_key => @destination[:access_key],
185
+ :secret_key => @destination[:secret_key],
186
+ })
187
+ snapshot_storage = storage_service.snapshot_storage(@destination[:bucket], @destination[:path])
188
+ snapshot_storage.delete(@destination[:filename])
189
+ rescue => e
190
+ logger.error(e)
191
+ raise "snapshot has not be deleted"
192
+ end
193
+
194
+ rpc.request('sta-collector', 'update_snapshot', @snapshot_id, {:state=>:deleted, :deleted_at=>Time.now.utc})
195
+ logger.info("deleted snapshot: #{@snapshot_id}")
196
+ end
197
+
198
+ def rpc
199
+ @rpc ||= Isono::NodeModules::RpcChannel.new(@node)
200
+ end
201
+
202
+ def jobreq
203
+ @jobreq ||= Isono::NodeModules::JobChannel.new(@node)
204
+ end
205
+
206
+ def event
207
+ @event ||= Isono::NodeModules::EventChannel.new(@node)
208
+ end
209
+ end
210
+
211
+ class StaContext
212
+
213
+ def initialize(stahandler)
214
+ raise "Invalid Class: #{stahandler}" unless stahandler.instance_of?(StaHandler)
215
+ @sta = stahandler
216
+ end
217
+
218
+ def volume_id
219
+ @sta.instance_variable_get(:@volume_id)
220
+ end
221
+
222
+ def snapshot_id
223
+ @sta.instance_variable_get(:@snapshot_id)
224
+ end
225
+
226
+ def destination
227
+ @sta.instance_variable_get(:@destination)
228
+ end
229
+
230
+ def volume
231
+ @sta.instance_variable_get(:@volume)
232
+ end
233
+
234
+ def snapshot
235
+ @sta.instance_variable_get(:@snapshot)
236
+ end
237
+
238
+ def node
239
+ @sta.instance_variable_get(:@node)
240
+ end
241
+ end
242
+
243
+ end
244
+ end
@@ -1,12 +1,126 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ require 'extlib/module'
4
+ require 'configuration'
1
5
 
2
6
  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'
7
+ module Scheduler
8
+ class SchedulerError < StandardError; end
9
+ class HostNodeSchedulingError < SchedulerError; end
10
+ class StorageNodeSchedulingError < SchedulerError; end
11
+ class NetworkSchedulingError < SchedulerError; end
12
+
13
+ # Factory method for HostNode scheduler
14
+ def self.host_node()
15
+ c = scheduler_class(Dcmgr.conf.host_node_scheduler, ::Dcmgr::Scheduler::HostNode)
16
+ if Dcmgr.conf.host_node_scheduler.respond_to?(:options)
17
+ c.new(Dcmgr.conf.host_node_scheduler.options)
18
+ else
19
+ c.new
20
+ end
21
+ end
22
+
23
+ # Factory method for HostNode scheduler for HA
24
+ def self.host_node_ha()
25
+ c = scheduler_class(Dcmgr.conf.host_node_ha_scheduler, ::Dcmgr::Scheduler::HostNode)
26
+ if Dcmgr.conf.host_node_ha_scheduler.respond_to?(:options)
27
+ c.new(Dcmgr.conf.host_node_ha_scheduler.options)
28
+ else
29
+ c.new
30
+ end
31
+ end
32
+
33
+ # Factory method for StorageNode scheduler
34
+ def self.storage_node()
35
+ c = scheduler_class(Dcmgr.conf.storage_node_scheduler, ::Dcmgr::Scheduler::StorageNode)
36
+ if Dcmgr.conf.storage_node_scheduler.respond_to?(:options)
37
+ c.new(Dcmgr.conf.storage_node_scheduler.options)
38
+ else
39
+ c.new
40
+ end
41
+ end
42
+
43
+ # Factory method for Network scheduler
44
+ def self.network()
45
+ c = scheduler_class(Dcmgr.conf.network_scheduler, ::Dcmgr::Scheduler::Network)
46
+ if Dcmgr.conf.network_scheduler.respond_to?(:options)
47
+ c.new(Dcmgr.conf.network_scheduler.options)
48
+ else
49
+ c.new
50
+ end
51
+ end
52
+
53
+ # common scheduler class finder
54
+ def self.scheduler_class(input, namespace)
55
+ c = case input
56
+ when Symbol
57
+ namespace.const_get(input)
58
+ when ::Configuration
59
+ if input.respond_to?(:scheduler)
60
+ namespace.const_get(input.scheduler)
61
+ else
62
+ raise "Missing configuration key: scheduler"
63
+ end
64
+ else
65
+ raise "Unknown #{namespace.to_s} scheduler: #{input}"
66
+ end
67
+ raise TypeError unless c < Module.find_const("#{namespace.to_s}Scheduler")
68
+ c
69
+ end
70
+
71
+ # Allocate HostNode to Instance object.
72
+ class HostNodeScheduler
73
+ def initialize(options=nil)
74
+ @options = options
75
+ end
76
+
77
+ # @param Models::Instance instance
78
+ # @return Models::HostNode
79
+ def schedule(instance)
80
+ raise NotImplementedError
81
+ end
82
+ end
83
+
84
+ # Allocate StorageNode to Volume object.
85
+ class StorageNodeScheduler
86
+ def initialize(options=nil)
87
+ @options = options
88
+ end
89
+
90
+ # @param Models::Volume volume
91
+ # @return nil
92
+ def schedule(volume)
93
+ if volume.snapshot_id
94
+ # use same same storage node if it is local snapshot.
95
+ if volume.snapshot.destination == 'local'
96
+ volume.storage_node = Models::StorageNode[volume.snapshot.storage_node_id]
97
+ else
98
+ schedule_node(volume)
99
+ end
100
+ else
101
+ schedule_node(volume)
102
+ end
103
+ raise StorageNodeSchedulingError if volume.storage_node.nil?
104
+ end
105
+
106
+ protected
107
+ def schedule_node(volume)
108
+ raise NotImplementedError
109
+ end
110
+ end
111
+
112
+ # Manage vnic for instances and assign network object.
113
+ class NetworkScheduler
114
+ def initialize(options=nil)
115
+ @options = options
116
+ end
117
+
118
+ # @param Models::HostNode host_node
119
+ # @return Models::Network
120
+ def schedule(instance)
121
+ raise NotImplementedError
122
+ end
123
+ end
124
+
11
125
  end
12
126
  end
@@ -0,0 +1,24 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ module Dcmgr
4
+ module Scheduler
5
+ module HostNode
6
+
7
+ class ExcludeSame < HostNodeScheduler
8
+ include Dcmgr::Logger
9
+
10
+ def schedule(instance)
11
+ ds = Models::HostNode.online_nodes.filter(:arch=>instance.spec.arch,
12
+ :hypervisor=>instance.spec.hypervisor)
13
+
14
+ host_node = ds.all.find_all { |hn|
15
+ hn.node_id != instance.host_node.node_id
16
+ }.first
17
+
18
+ raise HostNodeSchedulingError if host_node.nil?
19
+ instance.host_node = host_node
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,12 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ module Dcmgr; module Scheduler; module HostNode
4
+ class FindFirst < HostNodeScheduler
5
+
6
+ def schedule(instance)
7
+ host_node = Models::HostNode.first
8
+ raise HostNodeScheduleError if host_node.nil?
9
+ instance.host_node = host_node
10
+ end
11
+ end
12
+ end; end; end
@@ -0,0 +1,28 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ module Dcmgr
4
+ module Scheduler
5
+ module HostNode
6
+
7
+ # Find host node which has the largest available capacity.
8
+ class LeastUsage < HostNodeScheduler
9
+ include Dcmgr::Logger
10
+
11
+ def schedule(instance)
12
+ ds = Models::HostNode.online_nodes.filter(:arch=>instance.spec.arch,
13
+ :hypervisor=>instance.spec.hypervisor)
14
+
15
+ host_node = ds.all.find_all { |hn|
16
+ hn.available_cpu_cores >= instance.cpu_cores && \
17
+ hn.available_memory_size >= instance.memory_size
18
+ }.sort_by { |hn|
19
+ hn.available_memory_size
20
+ }.reverse.first
21
+
22
+ raise HostNodeSchedulingError if host_node.nil?
23
+ instance.host_node = host_node
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,18 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ module Dcmgr
4
+ module Scheduler
5
+ module HostNode
6
+ # Meta scheduler calls another scheduler specified by API.
7
+ class PerInstance < HostNodeScheduler
8
+
9
+ def schedule(instance)
10
+ sched_name = instance.request_params[:host_node_scheduler]
11
+
12
+ sched = Scheduler.scheduler_class(sched_name, ::Dcmgr::Scheduler::HostNode)
13
+ sched.schedule(instance)
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end