Class: Bosh::Director::DeploymentPlan::ResourcePool

Inherits:
Object
  • Object
show all
Includes:
ValidationHelper
Defined in:
lib/bosh/director/deployment_plan/resource_pool.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from ValidationHelper

#invalid_type, #safe_property

Constructor Details

#initialize(deployment_plan, spec, logger) ⇒ ResourcePool

Returns a new instance of ResourcePool.

Parameters:

  • deployment_plan (DeploymentPlan)

    Deployment plan

  • spec (Hash)

    Raw resource pool spec from the deployment manifest

  • logger (Logger)

    Director logger



41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/bosh/director/deployment_plan/resource_pool.rb', line 41

def initialize(deployment_plan, spec, logger)
  @deployment_plan = deployment_plan

  @logger = logger

  @name = safe_property(spec, "name", class: String)
  @size = safe_property(spec, "size", class: Integer, optional: true)

  @cloud_properties =
    safe_property(spec, "cloud_properties", class: Hash, default: {})

  stemcell_spec = safe_property(spec, "stemcell", class: Hash)
  @stemcell = Stemcell.new(self, stemcell_spec)

  network_name = safe_property(spec, "network", class: String)
  @network = @deployment_plan.network(network_name)

  if @network.nil?
    raise ResourcePoolUnknownNetwork,
          "Resource pool `#{@name}' references " +
          "an unknown network `#{network_name}'"
  end

  @env = safe_property(spec, "env", class: Hash, default: {})

  @idle_vms = []
  @allocated_vms = []
  @reserved_capacity = 0
  @reserved_errand_capacity = 0
end

Instance Attribute Details

#allocated_vmsArray<DeploymentPlan::IdleVm] List of allocated idle VMs (readonly)

Returns Array<DeploymentPlan::IdleVm] List of allocated idle VMs.

Returns:

  • (Array<DeploymentPlan::IdleVm] List of allocated idle VMs)

    Array<DeploymentPlan::IdleVm] List of allocated idle VMs



33
34
35
# File 'lib/bosh/director/deployment_plan/resource_pool.rb', line 33

def allocated_vms
  @allocated_vms
end

#cloud_propertiesHash (readonly)

Returns Cloud properties.

Returns:

  • (Hash)

    Cloud properties



24
25
26
# File 'lib/bosh/director/deployment_plan/resource_pool.rb', line 24

def cloud_properties
  @cloud_properties
end

#deployment_planDeploymentPlan (readonly)

Returns Deployment plan.

Returns:



15
16
17
# File 'lib/bosh/director/deployment_plan/resource_pool.rb', line 15

def deployment_plan
  @deployment_plan
end

#envHash (readonly)

Returns Resource pool environment.

Returns:

  • (Hash)

    Resource pool environment



27
28
29
# File 'lib/bosh/director/deployment_plan/resource_pool.rb', line 27

def env
  @env
end

#idle_vmsArray<DeploymentPlan::IdleVm> (readonly)

Returns List of idle VMs.

Returns:

  • (Array<DeploymentPlan::IdleVm>)

    List of idle VMs



30
31
32
# File 'lib/bosh/director/deployment_plan/resource_pool.rb', line 30

def idle_vms
  @idle_vms
end

#nameString (readonly)

Returns Resource pool name.

Returns:

  • (String)

    Resource pool name



9
10
11
# File 'lib/bosh/director/deployment_plan/resource_pool.rb', line 9

def name
  @name
end

#networkDeploymentPlan::Network (readonly)

Returns Network spec.

Returns:



21
22
23
# File 'lib/bosh/director/deployment_plan/resource_pool.rb', line 21

def network
  @network
end

#reserved_capacityInteger (readonly)

Returns Number of VMs reserved.

Returns:

  • (Integer)

    Number of VMs reserved



36
37
38
# File 'lib/bosh/director/deployment_plan/resource_pool.rb', line 36

def reserved_capacity
  @reserved_capacity
end

#sizeInteger (readonly)

Returns Expected resource pool size (in VMs).

Returns:

  • (Integer)

    Expected resource pool size (in VMs)



12
13
14
# File 'lib/bosh/director/deployment_plan/resource_pool.rb', line 12

def size
  @size
end

#stemcellDeploymentPlan::Stemcell (readonly)

Returns Stemcell spec.

Returns:



18
19
20
# File 'lib/bosh/director/deployment_plan/resource_pool.rb', line 18

def stemcell
  @stemcell
end

Instance Method Details

#add_allocated_vmObject



141
142
143
# File 'lib/bosh/director/deployment_plan/resource_pool.rb', line 141

def add_allocated_vm
  register_allocated_vm(Vm.new(self))
end

#add_idle_vmObject

Adds a new VM to idle_vms



123
124
125
126
127
128
# File 'lib/bosh/director/deployment_plan/resource_pool.rb', line 123

def add_idle_vm
  @logger.info("ResourcePool `#{name}' - Adding idle VM (index=#{@idle_vms.size})")
  idle_vm = Vm.new(self)
  @idle_vms << idle_vm
  idle_vm
end

#allocate_vmObject



130
131
132
133
134
135
136
137
138
139
# File 'lib/bosh/director/deployment_plan/resource_pool.rb', line 130

def allocate_vm
  if @idle_vms.empty? && dynamically_sized?
    vm = Vm.new(self)
  else
    vm = @idle_vms.pop
    raise ResourcePoolNotEnoughCapacity, "Resource pool `#{@name}' has no more VMs to allocate" if vm.nil?
  end

  register_allocated_vm(vm)
end

#deallocate_vm(vm_cid) ⇒ Object



145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
# File 'lib/bosh/director/deployment_plan/resource_pool.rb', line 145

def deallocate_vm(vm_cid)
  deallocated_vm = @allocated_vms.find { |vm| vm.model.cid == vm_cid }
  if deallocated_vm.nil?
    raise DirectorError, "Resource pool `#{@name}' does not contain an allocated VM with the cid `#{vm_cid}'"
  end

  @logger.info("ResourcePool `#{name}' - Deallocating VM: #{deallocated_vm.model.cid}")
  @allocated_vms.delete(deallocated_vm)

  deallocated_vm.release_reservation

  add_idle_vm unless dynamically_sized? # don't refill if dynamically sized

  nil
end

#extra_vm_countInteger

Returns a number of VMs that need to be deleted in order to bring this resource pool to the desired size

Returns:

  • (Integer)


193
194
195
196
# File 'lib/bosh/director/deployment_plan/resource_pool.rb', line 193

def extra_vm_count
  return @idle_vms.size if dynamically_sized?
  @idle_vms.size + @allocated_vms.size - @size
end

#process_idle_vmsvoid

This method returns an undefined value.

Creates idle VMs for any missing resource pool VMs and reserves dynamic networks for all idle VMs.



89
90
91
92
93
94
95
96
97
98
99
# File 'lib/bosh/director/deployment_plan/resource_pool.rb', line 89

def process_idle_vms
  # First, see if we need any data structures to balance the pool size
  missing_vm_count.times { add_idle_vm }

  # Second, see if some of idle VMs still need network reservations
  idle_vms.each do |idle_vm|
    unless idle_vm.has_network_reservation?
      idle_vm.use_reservation(reserve_dynamic_network)
    end
  end
end

#reserve_capacity(n) ⇒ void

This method returns an undefined value.

Checks if there is enough capacity to run extra N VMs, raise error if not enough capacity



165
166
167
168
169
170
171
172
173
# File 'lib/bosh/director/deployment_plan/resource_pool.rb', line 165

def reserve_capacity(n)
  needed = @reserved_capacity + n
  if !dynamically_sized? && needed > @size
    raise ResourcePoolNotEnoughCapacity,
          "Resource pool `#{@name}' is not big enough: " +
          "#{needed} VMs needed, capacity is #{@size}"
  end
  @reserved_capacity = needed
end

#reserve_dynamic_network(origin = "Resource pool `#{@name}'") ⇒ NetworkReservation

Tries to obtain one dynamic reservation in its own network

Returns:

Raises:



116
117
118
119
120
# File 'lib/bosh/director/deployment_plan/resource_pool.rb', line 116

def reserve_dynamic_network(origin="Resource pool `#{@name}'")
  reservation = NetworkReservation.new_dynamic
  @network.reserve!(reservation, origin)
  reservation
end

#reserve_dynamic_networksObject

Attempts to allocate a dynamic IP addresses for all VMs (unless they already have one).



103
104
105
106
107
108
109
110
111
# File 'lib/bosh/director/deployment_plan/resource_pool.rb', line 103

def reserve_dynamic_networks
  vms.each do |vm|
    unless vm.has_network_reservation?
      instance = vm.bound_instance
      origin = instance ? "Job instance `#{instance}' in resource pool `#{@name}'" : nil
      vm.network_reservation = reserve_dynamic_network(origin)
    end
  end
end

#reserve_errand_capacity(n) ⇒ void

This method returns an undefined value.

Checks if there is enough capacity to run _up to_ N VMs, raise error if not enough capacity. Only enough capacity to run the largest errand is required, because errands can only run one at a time.



181
182
183
184
185
186
187
188
# File 'lib/bosh/director/deployment_plan/resource_pool.rb', line 181

def reserve_errand_capacity(n)
  needed = n - @reserved_errand_capacity

  if needed > 0
    reserve_capacity(needed)
    @reserved_errand_capacity = n
  end
end

#specHash

Returns resource pools spec as Hash (usually for agent to serialize)

Returns:

  • (Hash)

    Resource pool spec



78
79
80
81
82
83
84
# File 'lib/bosh/director/deployment_plan/resource_pool.rb', line 78

def spec
  {
    "name" => @name,
    "cloud_properties" => @cloud_properties,
    "stemcell" => @stemcell.spec
  }
end

#vmsObject



72
73
74
# File 'lib/bosh/director/deployment_plan/resource_pool.rb', line 72

def vms
  @allocated_vms + @idle_vms
end