Class: OpenNebula::Role
- Inherits:
-
Object
- Object
- OpenNebula::Role
- Defined in:
- lib/models/role.rb
Overview
Service Role Class (Generic Role type)
Constant Summary collapse
- LOG_COMP =
'ROL'- STATE =
{ 'PENDING' => 0, 'DEPLOYING' => 1, 'RUNNING' => 2, 'UNDEPLOYING' => 3, 'WARNING' => 4, 'DONE' => 5, 'FAILED_UNDEPLOYING' => 6, 'FAILED_DEPLOYING' => 7, 'SCALING' => 8, 'FAILED_SCALING' => 9, 'COOLDOWN' => 10, 'HOLD' => 11 }
- STATE_STR =
[ 'PENDING', 'DEPLOYING', 'RUNNING', 'UNDEPLOYING', 'WARNING', 'DONE', 'FAILED_UNDEPLOYING', 'FAILED_DEPLOYING', 'SCALING', 'FAILED_SCALING', 'COOLDOWN', 'HOLD' ]
- FAILURE_STATES =
[ 'BOOT_FAILURE', 'BOOT_MIGRATE_FAILURE', 'PROLOG_MIGRATE_FAILURE', 'PROLOG_FAILURE', 'EPILOG_FAILURE', 'EPILOG_STOP_FAILURE', 'EPILOG_UNDEPLOY_FAILURE', 'PROLOG_MIGRATE_POWEROFF_FAILURE', 'PROLOG_MIGRATE_SUSPEND_FAILURE', 'PROLOG_MIGRATE_UNKNOWN_FAILURE', 'BOOT_UNDEPLOY_FAILURE', 'BOOT_STOPPED_FAILURE', 'PROLOG_RESUME_FAILURE', 'PROLOG_UNDEPLOY_FAILURE' ]
- RECOVER_DEPLOY_STATES =
[ 'FAILED_DEPLOYING', 'DEPLOYING', 'PENDING' ]
- RECOVER_UNDEPLOY_STATES =
[ 'FAILED_UNDEPLOYING', 'UNDEPLOYING' ]
- RECOVER_SCALE_STATES =
[ 'FAILED_SCALING', 'SCALING' ]
- SCALE_WAYS =
{ 'UP' => 0, 'DOWN' => 1 }
- SCHEDULE_ACTIONS =
Actions that can be performed on the VMs of a given Role
[ 'terminate', 'terminate-hard', 'undeploy', 'undeploy-hard', 'hold', 'release', 'stop', 'suspend', 'resume', 'reboot', 'reboot-hard', 'poweroff', 'poweroff-hard', 'snapshot-create', 'snapshot-revert', 'snapshot-delete', 'disk-snapshot-create', 'disk-snapshot-revert', 'disk-snapshot-delete' ]
- VM_INFO =
Information to save in document
['ID', 'UID', 'GID', 'UNAME', 'GNAME', 'NAME']
- IMMUTABLE_ATTRS =
List of attributes that can’t be changed in update operation last_vmname: this is internal information managed by OneFlow server nodes: this is internal information managed by OneFlow server parents: this has only sense in deploy operation state: this is internal information managed by OneFlow server template_id: this will affect scale operation cardinality: this is internal information managed by OneFlow server
[ 'cardinality', 'last_vmname', 'nodes', 'parents', 'state', 'template_id' ]
Instance Attribute Summary collapse
-
#service ⇒ Object
readonly
Returns the value of attribute service.
Class Method Summary collapse
-
.for(body, service) ⇒ Role
Return a role object based on type attribute of the role template.
-
.init_default_cooldown(default_cooldown) ⇒ Object
rubocop:disable Style/ClassVars.
- .init_default_shutdown(shutdown_action) ⇒ Object
- .init_default_vm_name_template(vm_name_template) ⇒ Object
- .init_default_vr_name_template(vr_name_template) ⇒ Object
- .init_force_deletion(force_deletion) ⇒ Object
-
.vm_failure?(vm_state, lcm_state) ⇒ true, false
Returns true if the VM state is failure.
Instance Method Summary collapse
-
#any_parent_on_hold? ⇒ Boolean
Checks if any parent role is currently on hold.
- #batch_action(action, period, vms_per_period, args) ⇒ Object
-
#can_recover_deploy? ⇒ Boolean
Determines whether the current deployment can be recovered based on its state and the states of its parent roles.
- #can_recover_scale? ⇒ Boolean
-
#can_recover_undeploy? ⇒ Boolean
Determines if the current deployment can be recovered and undeployed based on its state and the states of its child roles.
-
#can_release? ⇒ Boolean
Checks if the current role is in a state where it can be released.
-
#cardinality ⇒ Integer
Returns the role cardinality.
-
#cardinality=(target_cardinality) ⇒ Object
Sets a new cardinality for this role.
-
#check_new_template(template) ⇒ Boolean, String
Check that changes values are correct.
- #chown(uid, gid) ⇒ Object
- #clean_scale_way ⇒ Object
- #cooldown ⇒ Object
-
#deploy ⇒ Object
Deployment.
- #elasticity_policies ⇒ Object
- #info_nodes(vm_pool) ⇒ Object
-
#initialize(body, service) ⇒ Role
constructor
A new instance of Role.
-
#max_cardinality ⇒ Integer?
Returns the role max cardinality.
-
#min_cardinality ⇒ Integer?
Returns the role min cardinality.
- #name ⇒ Object
-
#nodes ⇒ Array
Returns the nodes of the role.
- #nodes_ids ⇒ Object
-
#on_hold=(on_hold) ⇒ Object
Change the ‘on_hold` option value.
-
#on_hold? ⇒ true, false
Returns the ‘on_hold` role option.
-
#parents ⇒ Array
Returns the role parents.
- #recover_deploy(report) ⇒ Object
- #recover_scale ⇒ Object
- #recover_undeploy ⇒ Object
-
#release ⇒ Array, Bool
Release all the nodes in this role.
-
#scale?(vm_pool) ⇒ Array<Integer>
Returns a positive, 0, or negative number of nodes to adjust, according to the elasticity and scheduled policies.
- #scale_way(_) ⇒ Object
-
#scheduled_policies ⇒ Object
Scheduler.
-
#service_on_hold? ⇒ true, false
Returns the ‘on_hold` service option.
-
#shutdown(recover) ⇒ Array<true, nil>, Array<false, String>
Terminate all the nodes in this role.
- #state ⇒ Object
-
#state=(state) ⇒ Object
Sets a new state.
-
#state_str ⇒ String
Returns the string representation of the service state.
-
#update(template) ⇒ nil, OpenNebula::Error
Updates the role.
- #update_cooldown(new_cooldown) ⇒ Object
- #update_elasticity_policies(new_policies) ⇒ Object
- #update_scheduled_policies(new_policies) ⇒ Object
Constructor Details
#initialize(body, service) ⇒ Role
Returns a new instance of Role.
203 204 205 206 207 208 209 |
# File 'lib/models/role.rb', line 203 def initialize(body, service) @body = body @service = service @body['nodes'] ||= [] @body['on_hold'] = false if @body['on_hold'].nil? end |
Instance Attribute Details
#service ⇒ Object (readonly)
Returns the value of attribute service.
33 34 35 |
# File 'lib/models/role.rb', line 33 def service @service end |
Class Method Details
.for(body, service) ⇒ Role
Return a role object based on type attribute of the role template
150 151 152 153 154 155 156 157 158 159 160 161 |
# File 'lib/models/role.rb', line 150 def for(body, service) role_type = body.fetch('type', 'vm') case role_type.downcase when 'vm' VMRole.new(body, service) when 'vr' VRRole.new(body, service) else raise "Unsupported role type: #{role_type}" end end |
.init_default_cooldown(default_cooldown) ⇒ Object
rubocop:disable Style/ClassVars
180 181 182 |
# File 'lib/models/role.rb', line 180 def init_default_cooldown(default_cooldown) @@default_cooldown = default_cooldown end |
.init_default_shutdown(shutdown_action) ⇒ Object
184 185 186 |
# File 'lib/models/role.rb', line 184 def init_default_shutdown(shutdown_action) @@default_shutdown = shutdown_action end |
.init_default_vm_name_template(vm_name_template) ⇒ Object
192 193 194 |
# File 'lib/models/role.rb', line 192 def init_default_vm_name_template(vm_name_template) @@vm_name_template = vm_name_template end |
.init_default_vr_name_template(vr_name_template) ⇒ Object
196 197 198 |
# File 'lib/models/role.rb', line 196 def init_default_vr_name_template(vr_name_template) @@vr_name_template = vr_name_template end |
.init_force_deletion(force_deletion) ⇒ Object
188 189 190 |
# File 'lib/models/role.rb', line 188 def init_force_deletion(force_deletion) @@force_deletion = force_deletion end |
.vm_failure?(vm_state, lcm_state) ⇒ true, false
Returns true if the VM state is failure
167 168 169 170 171 172 173 174 175 176 177 |
# File 'lib/models/role.rb', line 167 def vm_failure?(vm_state, lcm_state) vm_state_str = VirtualMachine::VM_STATE[vm_state.to_i] lcm_state_str = VirtualMachine::LCM_STATE[lcm_state.to_i] if vm_state_str == 'ACTIVE' && FAILURE_STATES.include?(lcm_state_str) return true end false end |
Instance Method Details
#any_parent_on_hold? ⇒ Boolean
Checks if any parent role is currently on hold.
330 331 332 333 334 335 336 337 |
# File 'lib/models/role.rb', line 330 def any_parent_on_hold? parents.each do |parent| next unless @service.roles[parent] return true if @service.roles[parent].on_hold? end false end |
#batch_action(action, period, vms_per_period, args) ⇒ Object
428 429 430 |
# File 'lib/models/role.rb', line 428 def batch_action(action, period, vms_per_period, args) raise NotImplementedError end |
#can_recover_deploy? ⇒ Boolean
Determines whether the current deployment can be recovered based on its state and the states of its parent roles.
519 520 521 522 523 524 525 526 527 528 529 530 531 |
# File 'lib/models/role.rb', line 519 def can_recover_deploy? if state != STATE['PENDING'] return RECOVER_DEPLOY_STATES.include? STATE_STR[state] end parents.each do |parent| next unless @service.roles[parent] return false if @service.roles[parent].state != STATE['RUNNING'] end true end |
#can_recover_scale? ⇒ Boolean
553 554 555 556 557 |
# File 'lib/models/role.rb', line 553 def can_recover_scale? return false unless RECOVER_SCALE_STATES.include? STATE_STR[state] true end |
#can_recover_undeploy? ⇒ Boolean
Determines if the current deployment can be recovered and undeployed based on its state and the states of its child roles.
537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 |
# File 'lib/models/role.rb', line 537 def can_recover_undeploy? if !RECOVER_UNDEPLOY_STATES.include? STATE_STR[state] # TODO, check childs if !empty? check if can be undeployed @service.roles.each do |role_name, role| next if role_name == name if role.parents.include?(name) && role.state != STATE['DONE'] return false end end end true end |
#can_release? ⇒ Boolean
Checks if the current role is in a state where it can be released.
384 385 386 |
# File 'lib/models/role.rb', line 384 def can_release? state == STATE['HOLD'] end |
#cardinality ⇒ Integer
Returns the role cardinality
288 289 290 |
# File 'lib/models/role.rb', line 288 def cardinality @body['cardinality'].to_i end |
#cardinality=(target_cardinality) ⇒ Object
Sets a new cardinality for this role
294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 |
# File 'lib/models/role.rb', line 294 def cardinality=(target_cardinality) if target_cardinality > cardinality dir = 'up' else dir = 'down' end msg = "Role #{name} scaling #{dir} from #{cardinality} to " \ "#{target_cardinality} nodes" Log.info(LOG_COMP, msg, @service.id) @service.log_info(msg) @body['cardinality'] = target_cardinality.to_i end |
#check_new_template(template) ⇒ Boolean, String
Check that changes values are correct
406 407 408 409 410 411 412 413 414 |
# File 'lib/models/role.rb', line 406 def check_new_template(template) IMMUTABLE_ATTRS.each do |attr| next if template[attr] == @body[attr] return [false, "role/#{attr}"] end [true, nil] end |
#chown(uid, gid) ⇒ Object
388 389 390 |
# File 'lib/models/role.rb', line 388 def chown(uid, gid) raise NotImplementedError end |
#clean_scale_way ⇒ Object
476 477 478 |
# File 'lib/models/role.rb', line 476 def clean_scale_way return NotImplementedError end |
#cooldown ⇒ Object
464 465 466 |
# File 'lib/models/role.rb', line 464 def cooldown raise NotImplementedError end |
#deploy ⇒ Object
Deployment
484 485 486 |
# File 'lib/models/role.rb', line 484 def deploy raise NotImplementedError end |
#elasticity_policies ⇒ Object
456 457 458 |
# File 'lib/models/role.rb', line 456 def elasticity_policies raise NotImplementedError end |
#info_nodes(vm_pool) ⇒ Object
249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 |
# File 'lib/models/role.rb', line 249 def info_nodes(vm_pool) ret = [] monitoring = vm_pool[:monitoring] vm_pool = vm_pool[:vm_pool] @body['nodes'].each do |node| id = node['deploy_id'] vm = vm_pool.retrieve_xmlelements("/VM_POOL/VM[ID=#{id}]")[0] if vm.nil? Log.error LOG_COMP, "Error getting VM #{id}", @service.id else obj = {} obj['deploy_id'] = node['deploy_id'] hash = vm.to_hash vm_monit = monitoring.select {|v| v['ID'].to_i == id }[0] hash['VM']['MONITORING'] = vm_monit if vm_monit obj['vm_info'] = hash ret << obj end end ret end |
#max_cardinality ⇒ Integer?
Returns the role max cardinality
438 439 440 |
# File 'lib/models/role.rb', line 438 def max_cardinality raise NotImplementedError end |
#min_cardinality ⇒ Integer?
Returns the role min cardinality
444 445 446 |
# File 'lib/models/role.rb', line 444 def min_cardinality raise NotImplementedError end |
#name ⇒ Object
211 212 213 |
# File 'lib/models/role.rb', line 211 def name @body['name'] end |
#nodes ⇒ Array
Returns the nodes of the role
241 242 243 |
# File 'lib/models/role.rb', line 241 def nodes @body['nodes'] end |
#nodes_ids ⇒ Object
245 246 247 |
# File 'lib/models/role.rb', line 245 def nodes_ids @body['nodes'].map {|node| node['deploy_id'] } end |
#on_hold=(on_hold) ⇒ Object
Change the ‘on_hold` option value
311 312 313 |
# File 'lib/models/role.rb', line 311 def on_hold=(on_hold) @body['on_hold'] = on_hold end |
#on_hold? ⇒ true, false
Returns the ‘on_hold` role option
317 318 319 |
# File 'lib/models/role.rb', line 317 def on_hold? @body['on_hold'] end |
#parents ⇒ Array
Returns the role parents
282 283 284 |
# File 'lib/models/role.rb', line 282 def parents @body['parents'] || [] end |
#recover_deploy(report) ⇒ Object
559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 |
# File 'lib/models/role.rb', line 559 def recover_deploy(report) nodes = @body['nodes'] deployed_nodes = [] nodes.each do |node| vm_id = node['deploy_id'] vm = OpenNebula::VirtualMachine.new_with_id(vm_id, @service.client) rc = vm.info if OpenNebula.is_error?(rc) msg = "Role #{name} : Retry failed for VM "\ "#{vm_id}; #{rc.message}" Log.error LOG_COMP, msg, @service.id next true end vm_state = vm.state lcm_state = vm.lcm_state # ACTIVE/RUNNING next false if vm_state == 3 && lcm_state == 3 && !report next true if vm_state == '6' # Delete DONE nodes if Role.vm_failure?(vm_state, lcm_state) rc = vm.recover(2) if OpenNebula.is_error?(rc) msg = "Role #{name} : Retry failed for VM "\ "#{vm_id}; #{rc.message}" Log.error LOG_COMP, msg, @service.id @service.log_error(msg) else deployed_nodes << vm_id end else vm.resume deployed_nodes << vm_id end end rc = deploy unless rc[0] return [false, "Error deploying nodes for role `#{name}`"] end deployed_nodes.concat(rc[0]) deployed_nodes end |
#recover_scale ⇒ Object
627 628 629 |
# File 'lib/models/role.rb', line 627 def recover_scale raise NotImplementedError end |
#recover_undeploy ⇒ Object
617 618 619 620 621 622 623 624 625 |
# File 'lib/models/role.rb', line 617 def recover_undeploy undeployed_nodes = [] rc = shutdown(true) undeployed_nodes.concat(rc[0]) if rc[1].nil? undeployed_nodes end |
#release ⇒ Array, Bool
Release all the nodes in this role
346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 |
# File 'lib/models/role.rb', line 346 def release release_nodes = [] success = true # Release all vms in the role nodes.each do |node| vm_id = node['deploy_id'] Log.debug(LOG_COMP, "Role #{name}: Releasing VM #{vm_id}", @service.id) vm = OpenNebula::VirtualMachine.new_with_id(vm_id, @service.client) rc = vm.release if OpenNebula.is_error?(rc) msg = "Role #{name}: Release failed for VM #{vm_id}, " \ "#{rc.message}" Log.error(LOG_COMP, msg, @service.id) @service.log_error(msg) success = false else Log.debug(LOG_COMP, "Role #{name}: Release success for VM #{vm_id}", @service.id) release_nodes << vm_id end end [release_nodes, success] end |
#scale?(vm_pool) ⇒ Array<Integer>
Returns a positive, 0, or negative number of nodes to adjust,
according to the elasticity and scheduled policies
452 453 454 |
# File 'lib/models/role.rb', line 452 def scale?(vm_pool) raise NotImplementedError end |
#scale_way(_) ⇒ Object
472 473 474 |
# File 'lib/models/role.rb', line 472 def scale_way(_) return NotImplementedError end |
#scheduled_policies ⇒ Object
Scheduler
420 421 422 |
# File 'lib/models/role.rb', line 420 def scheduled_policies @body['scheduled_policies'] end |
#service_on_hold? ⇒ true, false
Returns the ‘on_hold` service option
323 324 325 |
# File 'lib/models/role.rb', line 323 def service_on_hold? @service.on_hold? end |
#shutdown(recover) ⇒ Array<true, nil>, Array<false, String>
Terminate all the nodes in this role
495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 |
# File 'lib/models/role.rb', line 495 def shutdown(recover) if nodes.size != cardinality n_nodes = nodes.size - cardinality else n_nodes = nodes.size end rc = shutdown_nodes(nodes, n_nodes, recover) unless rc[0] return [false, "Error undeploying nodes for role `#{name}`"] end [rc[1], nil] end |
#state ⇒ Object
215 216 217 |
# File 'lib/models/role.rb', line 215 def state @body['state'] end |
#state=(state) ⇒ Object
Sets a new state
221 222 223 224 225 226 227 228 229 230 231 |
# File 'lib/models/role.rb', line 221 def state=(state) return if state < 0 || state > STATE_STR.size @body['state'] = state.to_i Log.info( LOG_COMP, "Role #{name} new state: #{STATE_STR[state]}", @service.id ) end |
#state_str ⇒ String
Returns the string representation of the service state
235 236 237 |
# File 'lib/models/role.rb', line 235 def state_str STATE_STR[state] end |
#update(template) ⇒ nil, OpenNebula::Error
Updates the role
396 397 398 |
# File 'lib/models/role.rb', line 396 def update(template) raise NotImplementedError end |
#update_cooldown(new_cooldown) ⇒ Object
468 469 470 |
# File 'lib/models/role.rb', line 468 def update_cooldown(new_cooldown) raise NotImplementedError end |
#update_elasticity_policies(new_policies) ⇒ Object
460 461 462 |
# File 'lib/models/role.rb', line 460 def update_elasticity_policies(new_policies) raise NotImplementedError end |
#update_scheduled_policies(new_policies) ⇒ Object
424 425 426 |
# File 'lib/models/role.rb', line 424 def update_scheduled_policies(new_policies) @body['scheduled_policies'] = new_policies end |