Method: Beaker::OpenStack#provision

Defined in:
lib/beaker/hypervisor/openstack.rb

#provisionObject

Create new instances in OpenStack



185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
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
# File 'lib/beaker/hypervisor/openstack.rb', line 185

def provision
  @logger.notify "Provisioning OpenStack"

  @hosts.each do |host|
    ip = get_ip
    hostname = ip.ip.gsub! '.','-'
    host[:vmhostname] = hostname+'.rfc1918.puppetlabs.net'
    @logger.debug "Provisioning #{host.name} (#{host[:vmhostname]})"
    options = {
      :flavor_ref => flavor(host[:flavor]).id,
      :image_ref  => image(host[:image]).id,
      :nics       => [ {'net_id' => network(@options[:openstack_network]).id } ],
      :name       => host[:vmhostname],
      :hostname   => host[:vmhostname],
      :user_data  => host[:user_data] || "#cloud-config\nmanage_etc_hosts: true\n",
    }
    options[:key_name] = key_name(host)
    options[:security_groups] = security_groups(@options[:security_group]) unless @options[:security_group].nil?
    vm = @compute_client.servers.create(options)

    #wait for the new instance to start up
    start = Time.now
    try = 1
    attempts = @options[:timeout].to_i / SLEEPWAIT

    while try <= attempts
      begin
        vm.wait_for(5) { ready? }
        break
      rescue Fog::Errors::TimeoutError => e
        if try >= attempts
          @logger.debug "Failed to connect to new OpenStack instance #{host.name} (#{host[:vmhostname]})"
          raise e
        end
        @logger.debug "Timeout connecting to instance #{host.name} (#{host[:vmhostname]}), trying again..."
      end
      sleep SLEEPWAIT
      try += 1
    end

    # Associate a public IP to the server
    # Create if there are no floating ips available
    #
    # Do we already have an address?
    @logger.debug vm.addresses
    address=nil
    begin
      # Here we try and assign an address from a floating IP pool
      # This seems to fail on some implementations (FloatingIpPoolNotFound)
      ip.ip.gsub! '-','.'
      ip.server = vm
      address = ip.ip

    rescue Fog::Compute::OpenStack::NotFound
      # Here, we fail to just trying to use an address that's already assigned if there is one
      # There may be better logic, but this worked in the original implementation
      # There might be an argument for checking whether an address is reachable a la
      # port_open? logic in host.rb but maybe race conditions

      begin
        if vm.addresses[@options[:openstack_network]]
          address = vm.addresses[@options[:openstack_network]].map{ |network| network['addr'] }.first
        end
      rescue NoMethodError
        @logger.debug "No current address retrievable from OpenStack data"
      end

    end

    raise 'Could not find or assign an address to the instance' unless address
    host[:ip] = address

    @logger.debug "OpenStack host #{host.name} (#{host[:vmhostname]}) assigned ip: #{host[:ip]}"

    #set metadata
    vm..update({:jenkins_build_url => @options[:jenkins_build_url].to_s,
                        :department        => @options[:department].to_s,
                        :project           => @options[:project].to_s })
    @vms << vm

    #enable root if user is not root
    enable_root(host)

    provision_storage(host, vm)
  end

  hack_etc_hosts @hosts, @options

end