Class: VagrantPlugins::ProviderOpenStack::Action::Boot

Inherits:
Object
  • Object
show all
Includes:
Vagrant::Util::Retryable
Defined in:
lib/vagrant-openstack/action/boot.rb

Overview

This creates the openstack server.

Instance Method Summary collapse

Constructor Details

#initialize(app, env) ⇒ Boot

Returns a new instance of Boot.



13
14
15
16
# File 'lib/vagrant-openstack/action/boot.rb', line 13

def initialize(app, env)
  @app    = app
  @logger = Log4r::Logger.new("vagrant_openstack::action::create_server")
end

Instance Method Details

#call(env) ⇒ Object

Raises:

  • (Errors::NoMatchingFlavor)


18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
# File 'lib/vagrant-openstack/action/boot.rb', line 18

def call(env)
  # Get the configs
  config   = env[:machine].provider_config

  # Find the flavor
  env[:ui].info(I18n.t("vagrant_openstack.finding_flavor"))
  flavor = find_matching(env[:os_connection].flavors.all, config.flavor)
  raise Errors::NoMatchingFlavor if !flavor

  # Find the image
  env[:ui].info(I18n.t("vagrant_openstack.finding_image"))
  images = env[:os_connection].images.all
  if images.nil? || images.empty?
    image = env[:os_connection].images.get(config.image)
  else
    image = find_matching(env[:os_connection].images.all, config.image)
  end
  raise Errors::NoMatchingImage if !image

  # Figure out the name for the server
  server_name = config.name || env[:machine].name

  # If we're using the default keypair, then show a warning
  default_key_path = Vagrant.source_root.join("keys/vagrant.pub").to_s
  public_key_path  = File.expand_path(config.public_key_path, env[:root_path])

  if default_key_path == public_key_path
    env[:ui].warn(I18n.t("vagrant_openstack.warn_insecure_ssh"))
  end

  # Output the settings we're going to use to the user
  env[:ui].info(I18n.t("vagrant_openstack.launching_server"))
  env[:ui].info(" -- Flavor: #{flavor.name}")
  env[:ui].info(" -- Image: #{image.name}")
  env[:ui].info(" -- Name: #{server_name}")

  # Build the options for launching...
  options = {
    :flavor_ref   => flavor.id,
    :image_ref    => image.id,
    :name        => server_name,
    }

  if not config.security_groups.nil? and not config.security_groups.empty? then
      options.store(:security_groups, config.security_groups)
  end

  if not config.keypair.nil?
      options.store(:key_name, config.keypair)
  else
      options.store(:personality, [
      {
        :path     => "/root/.ssh/authorized_keys",
        :contents => IO.read(public_key_path)
      }
    ])
  end
  # Create the server
  server = env[:os_connection].servers.create(options)

  # Store the ID right away so we can track it
  env[:machine].id = server.id

  # Wait for the server to finish building
  env[:ui].info(I18n.t("vagrant_openstack.waiting_for_build"))
  retryable(:on => Fog::Errors::TimeoutError, :tries => 200) do
    # If we're interrupted don't worry about waiting
    next if env[:interrupted]

    # Set the progress
    env[:ui].clear_line
    env[:ui].report_progress(server.progress, 100, false)

    # Wait for the server to be ready
    begin
      server.wait_for(5) { ready? }
    rescue RuntimeError => e
      # If we don't have an error about a state transition, then
      # we just move on.
      raise if e.message !~ /should have transitioned/
      raise Errors::CreateBadState, :state => server.state
    end
  end

  if !env[:interrupted]
    # Clear the line one more time so the progress is removed
    env[:ui].clear_line

    floating_ip = config.floating_ip
    if floating_ip.nil?
        floating_ip = env[:os_connection].allocate_address.body["floating_ip"]["ip"]
    end

    env[:ui].info(I18n.t("vagrant_openstack.associating_ip",
                        :ip => floating_ip,
                        :id => server.id))

    env[:os_connection].associate_address(server.id, floating_ip)

    # Wait for SSH to become available
    env[:ui].info(I18n.t("vagrant_openstack.waiting_for_ssh"))
    while true
      # If we're interrupted then just back out
      break if env[:interrupted]
      break if env[:machine].communicate.ready?
      sleep 2
    end

    env[:ui].info(I18n.t("vagrant_openstack.ready"))
  end

  @app.call(env)
end