vagrant-openstack-plugin-tom 0.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +20 -0
- data/.travis.yml +11 -0
- data/Authors.txt +11 -0
- data/CHANGELOG.md +185 -0
- data/Gemfile +10 -0
- data/LICENSE.txt +23 -0
- data/README.md +278 -0
- data/Rakefile +21 -0
- data/dummy.box +0 -0
- data/example_box/README.md +13 -0
- data/example_box/metadata.json +3 -0
- data/example_vagrant_file +24 -0
- data/lib/vagrant-openstack-plugin.rb +53 -0
- data/lib/vagrant-openstack-plugin/action.rb +268 -0
- data/lib/vagrant-openstack-plugin/action/connect_openstack.rb +90 -0
- data/lib/vagrant-openstack-plugin/action/create_network_interfaces.rb +52 -0
- data/lib/vagrant-openstack-plugin/action/create_orchestration_stack.rb +97 -0
- data/lib/vagrant-openstack-plugin/action/create_server.rb +263 -0
- data/lib/vagrant-openstack-plugin/action/delete_orchestration_stack.rb +78 -0
- data/lib/vagrant-openstack-plugin/action/delete_server.rb +84 -0
- data/lib/vagrant-openstack-plugin/action/hard_reboot_server.rb +27 -0
- data/lib/vagrant-openstack-plugin/action/is_created.rb +16 -0
- data/lib/vagrant-openstack-plugin/action/is_paused.rb +16 -0
- data/lib/vagrant-openstack-plugin/action/is_snapshoting.rb +24 -0
- data/lib/vagrant-openstack-plugin/action/is_suspended.rb +16 -0
- data/lib/vagrant-openstack-plugin/action/message_already_created.rb +16 -0
- data/lib/vagrant-openstack-plugin/action/message_already_paused.rb +16 -0
- data/lib/vagrant-openstack-plugin/action/message_already_suspended.rb +16 -0
- data/lib/vagrant-openstack-plugin/action/message_not_created.rb +16 -0
- data/lib/vagrant-openstack-plugin/action/message_server_running.rb +16 -0
- data/lib/vagrant-openstack-plugin/action/message_snapshot_done.rb +16 -0
- data/lib/vagrant-openstack-plugin/action/message_snapshot_in_progress.rb +16 -0
- data/lib/vagrant-openstack-plugin/action/message_will_not_destroy.rb +16 -0
- data/lib/vagrant-openstack-plugin/action/pause_server.rb +27 -0
- data/lib/vagrant-openstack-plugin/action/read_ssh_info.rb +103 -0
- data/lib/vagrant-openstack-plugin/action/read_state.rb +39 -0
- data/lib/vagrant-openstack-plugin/action/reboot_server.rb +27 -0
- data/lib/vagrant-openstack-plugin/action/resume_server.rb +31 -0
- data/lib/vagrant-openstack-plugin/action/suspend_server.rb +27 -0
- data/lib/vagrant-openstack-plugin/action/sync_folders.rb +104 -0
- data/lib/vagrant-openstack-plugin/action/take_snapshot.rb +26 -0
- data/lib/vagrant-openstack-plugin/action/wait_for_state.rb +39 -0
- data/lib/vagrant-openstack-plugin/action/wait_for_task.rb +44 -0
- data/lib/vagrant-openstack-plugin/action/warn_networks.rb +19 -0
- data/lib/vagrant-openstack-plugin/command.rb +70 -0
- data/lib/vagrant-openstack-plugin/command/command_snapshot.rb +43 -0
- data/lib/vagrant-openstack-plugin/config.rb +246 -0
- data/lib/vagrant-openstack-plugin/errors.rb +71 -0
- data/lib/vagrant-openstack-plugin/plugin.rb +45 -0
- data/lib/vagrant-openstack-plugin/provider.rb +50 -0
- data/lib/vagrant-openstack-plugin/version.rb +5 -0
- data/locales/en.yml +154 -0
- data/spec/vagrant-openstack-plugin/config_spec.rb +152 -0
- data/vagrant-openstack-plugin.gemspec +24 -0
- metadata +142 -0
| @@ -0,0 +1,52 @@ | |
| 1 | 
            +
            require "log4r"
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            require 'vagrant/util/scoped_hash_override'
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            module VagrantPlugins
         | 
| 6 | 
            +
              module OpenStack
         | 
| 7 | 
            +
                module Action
         | 
| 8 | 
            +
                  class CreateNetworkInterfaces
         | 
| 9 | 
            +
                    include Vagrant::Util::ScopedHashOverride
         | 
| 10 | 
            +
             | 
| 11 | 
            +
                    def initialize(app, env)
         | 
| 12 | 
            +
                      @app    = app
         | 
| 13 | 
            +
                      @logger = Log4r::Logger.new("vagrant_openstack::action::create_network_interfaces")
         | 
| 14 | 
            +
                    end
         | 
| 15 | 
            +
             | 
| 16 | 
            +
                    def call(env)
         | 
| 17 | 
            +
                      networks_to_configure = []
         | 
| 18 | 
            +
                      env[:machine].config.vm.networks.each_with_index do |network, slot_number|
         | 
| 19 | 
            +
                        type = network[0]
         | 
| 20 | 
            +
                        original_options = network[1]
         | 
| 21 | 
            +
                        next if type != :private_network
         | 
| 22 | 
            +
                        next if original_options[:auto_config] === false
         | 
| 23 | 
            +
                        next if slot_number == 0
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                        options = scoped_hash_override(original_options, :openstack)
         | 
| 26 | 
            +
             | 
| 27 | 
            +
                        @logger.info "Configuring interface slot_number #{slot_number} options #{options}"
         | 
| 28 | 
            +
             | 
| 29 | 
            +
                        network_to_configure = {
         | 
| 30 | 
            +
                          :interface => slot_number,
         | 
| 31 | 
            +
                        }
         | 
| 32 | 
            +
             | 
| 33 | 
            +
                        if options[:ip]
         | 
| 34 | 
            +
                          network_to_configure = {
         | 
| 35 | 
            +
                            :type    => :static,
         | 
| 36 | 
            +
                            :ip      => options[:ip],
         | 
| 37 | 
            +
                            :netmask => "255.255.255.0",
         | 
| 38 | 
            +
                          }.merge(network_to_configure)
         | 
| 39 | 
            +
                        else
         | 
| 40 | 
            +
                          network_to_configure[:type] = :dhcp
         | 
| 41 | 
            +
                        end
         | 
| 42 | 
            +
             | 
| 43 | 
            +
                        networks_to_configure.push(network_to_configure)
         | 
| 44 | 
            +
                      end
         | 
| 45 | 
            +
                      env[:ui].info I18n.t('vagrant.actions.vm.network.configuring')
         | 
| 46 | 
            +
                      env[:machine].guest.capability(:configure_networks, networks_to_configure)
         | 
| 47 | 
            +
                      @app.call(env)
         | 
| 48 | 
            +
                    end
         | 
| 49 | 
            +
                  end
         | 
| 50 | 
            +
                end
         | 
| 51 | 
            +
              end
         | 
| 52 | 
            +
            end
         | 
| @@ -0,0 +1,97 @@ | |
| 1 | 
            +
            require "fog"
         | 
| 2 | 
            +
            require "log4r"
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            module VagrantPlugins
         | 
| 5 | 
            +
              module OpenStack
         | 
| 6 | 
            +
                module Action
         | 
| 7 | 
            +
                  class CreateOrchestrationStack
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                    def initialize(app, env)
         | 
| 10 | 
            +
                      @app    = app
         | 
| 11 | 
            +
                      @logger = Log4r::Logger.new(
         | 
| 12 | 
            +
                        "vagrant_openstack::action::create_orchestration_stack")
         | 
| 13 | 
            +
                    end
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                    def call(env)
         | 
| 16 | 
            +
                      # Get the config.
         | 
| 17 | 
            +
                      config = env[:machine].provider_config
         | 
| 18 | 
            +
             | 
| 19 | 
            +
                      # Are we going to handle orchestration stacks?
         | 
| 20 | 
            +
                      if not config.orchestration_stack_name
         | 
| 21 | 
            +
                        return @app.call(env)
         | 
| 22 | 
            +
                      end
         | 
| 23 | 
            +
             | 
| 24 | 
            +
                      # Create new fog orchestration service.
         | 
| 25 | 
            +
                      env[:openstack_orchestration] = Fog::Orchestration.new(
         | 
| 26 | 
            +
                        env[:fog_openstack_params])
         | 
| 27 | 
            +
             | 
| 28 | 
            +
                      # Check if stack is already created.
         | 
| 29 | 
            +
                      env[:openstack_orchestration].list_stacks.body['stacks'].each do |stack|
         | 
| 30 | 
            +
                        if config.orchestration_stack_name == stack['stack_name']
         | 
| 31 | 
            +
                          return @app.call(env)
         | 
| 32 | 
            +
                        end
         | 
| 33 | 
            +
                      end
         | 
| 34 | 
            +
             | 
| 35 | 
            +
                      # To avoid confusion, only one source for orchestration template
         | 
| 36 | 
            +
                      # should be set.
         | 
| 37 | 
            +
                      if [config.orchestration_cfn_template,
         | 
| 38 | 
            +
                          config.orchestration_cfn_template_file,
         | 
| 39 | 
            +
                          config.orchestration_cfn_template_url].count(nil) != 2
         | 
| 40 | 
            +
                        raise Errors::OrchestrationTemplateError,
         | 
| 41 | 
            +
                          :err => 'One source for orchestration template should be specified.'
         | 
| 42 | 
            +
                      end
         | 
| 43 | 
            +
             | 
| 44 | 
            +
                      # Prepare parameters for new orchestration stack.
         | 
| 45 | 
            +
                      # TODO: configurable parameters
         | 
| 46 | 
            +
                      stack_params = {
         | 
| 47 | 
            +
                        :disable_rollback   => false,
         | 
| 48 | 
            +
                        :timeout_in_minutes => 5,
         | 
| 49 | 
            +
                      }
         | 
| 50 | 
            +
             | 
| 51 | 
            +
                      # Set template source.
         | 
| 52 | 
            +
                      if config.orchestration_cfn_template
         | 
| 53 | 
            +
                        stack_params[:template] = config.orchestration_cfn_template
         | 
| 54 | 
            +
                      elsif config.orchestration_cfn_template_file
         | 
| 55 | 
            +
                        if not File.exist?(config.orchestration_cfn_template_file)
         | 
| 56 | 
            +
                          raise Errors::OrchestrationNoTemplateFileError,
         | 
| 57 | 
            +
                            :fname => config.orchestration_cfn_template_file
         | 
| 58 | 
            +
                        end
         | 
| 59 | 
            +
             | 
| 60 | 
            +
                        # Load template file content. Newlines can cause parse error of
         | 
| 61 | 
            +
                        # input JSON string.
         | 
| 62 | 
            +
                        stack_params[:template] = ''
         | 
| 63 | 
            +
                        File.open(config.orchestration_cfn_template_file) { |file|
         | 
| 64 | 
            +
                          file.each_line do |line|
         | 
| 65 | 
            +
                            stack_params[:template] << line
         | 
| 66 | 
            +
                          end
         | 
| 67 | 
            +
                        }
         | 
| 68 | 
            +
                      else
         | 
| 69 | 
            +
                        stack_params[:template_url] = config.orchestration_cfn_template_url
         | 
| 70 | 
            +
                      end
         | 
| 71 | 
            +
             | 
| 72 | 
            +
                      # Set template parameters.
         | 
| 73 | 
            +
                      stack_params[:parameters] = config.orchestration_cfn_template_parameters
         | 
| 74 | 
            +
             | 
| 75 | 
            +
                      # Create new stack.
         | 
| 76 | 
            +
                      env[:ui].info(I18n.t("vagrant_openstack.creating_orchestration_stack"))
         | 
| 77 | 
            +
                      stack = env[:openstack_orchestration].create_stack(
         | 
| 78 | 
            +
                        config.orchestration_stack_name, stack_params)
         | 
| 79 | 
            +
             | 
| 80 | 
            +
                      # Write UUID of newly created stack into file for later use (stack removal).
         | 
| 81 | 
            +
                      created_stacks_fname = env[:machine].data_dir + 'orchestration_stacks'
         | 
| 82 | 
            +
                      message = 'Saving information about created orchestration stack '
         | 
| 83 | 
            +
                      message << "#{config.orchestration_stack_name}, "
         | 
| 84 | 
            +
                      message << "UUID=#{stack.body['stack']['id']} "
         | 
| 85 | 
            +
                      message << "to file #{created_stacks_fname}."
         | 
| 86 | 
            +
                      @logger.info(message)
         | 
| 87 | 
            +
             | 
| 88 | 
            +
                      File.open(created_stacks_fname, 'a') do |file|
         | 
| 89 | 
            +
                        file.puts stack.body['stack']['id']
         | 
| 90 | 
            +
                      end
         | 
| 91 | 
            +
             | 
| 92 | 
            +
                      @app.call(env)
         | 
| 93 | 
            +
                    end
         | 
| 94 | 
            +
                  end
         | 
| 95 | 
            +
                end
         | 
| 96 | 
            +
              end
         | 
| 97 | 
            +
            end
         | 
| @@ -0,0 +1,263 @@ | |
| 1 | 
            +
            require "fog"
         | 
| 2 | 
            +
            require "log4r"
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            require 'vagrant/util/retryable'
         | 
| 5 | 
            +
             | 
| 6 | 
            +
            module VagrantPlugins
         | 
| 7 | 
            +
              module OpenStack
         | 
| 8 | 
            +
                module Action
         | 
| 9 | 
            +
                  # This creates the OpenStack server.
         | 
| 10 | 
            +
                  class CreateServer
         | 
| 11 | 
            +
                    include Vagrant::Util::Retryable
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                    def initialize(app, env)
         | 
| 14 | 
            +
                      @app    = app
         | 
| 15 | 
            +
                      @logger = Log4r::Logger.new("vagrant_openstack::action::create_server")
         | 
| 16 | 
            +
                    end
         | 
| 17 | 
            +
             | 
| 18 | 
            +
                    def call(env)
         | 
| 19 | 
            +
                      # Get the configs
         | 
| 20 | 
            +
                      config   = env[:machine].provider_config
         | 
| 21 | 
            +
             | 
| 22 | 
            +
                      # Find the flavor
         | 
| 23 | 
            +
                      env[:ui].info(I18n.t("vagrant_openstack.finding_flavor"))
         | 
| 24 | 
            +
                      flavor = find_matching(env[:openstack_compute].flavors.all, config.flavor)
         | 
| 25 | 
            +
                      raise Errors::NoMatchingFlavor if !flavor
         | 
| 26 | 
            +
             | 
| 27 | 
            +
                      # Find the image
         | 
| 28 | 
            +
                      env[:ui].info(I18n.t("vagrant_openstack.finding_image"))
         | 
| 29 | 
            +
                      image = find_matching(env[:openstack_compute].images, config.image)
         | 
| 30 | 
            +
                      raise Errors::NoMatchingImage if !image
         | 
| 31 | 
            +
             | 
| 32 | 
            +
                      # Figure out the name for the server
         | 
| 33 | 
            +
                      server_name = config.server_name || env[:machine].name
         | 
| 34 | 
            +
             | 
| 35 | 
            +
                      # Build the options for launching...
         | 
| 36 | 
            +
                      options = {
         | 
| 37 | 
            +
                        :flavor_ref  => flavor.id,
         | 
| 38 | 
            +
                        :image_ref   => image.id,
         | 
| 39 | 
            +
                        :name        => server_name,
         | 
| 40 | 
            +
                        :key_name    => config.keypair_name,
         | 
| 41 | 
            +
                        :metadata    => config.metadata,
         | 
| 42 | 
            +
                        :user_data   => config.user_data,
         | 
| 43 | 
            +
                        :security_groups => config.security_groups,
         | 
| 44 | 
            +
                        :os_scheduler_hints => config.scheduler_hints,
         | 
| 45 | 
            +
                        :availability_zone => config.availability_zone
         | 
| 46 | 
            +
                      }
         | 
| 47 | 
            +
                      
         | 
| 48 | 
            +
                      # Fallback to only one network, otherwise `config.networks` overrides
         | 
| 49 | 
            +
                      unless config.networks
         | 
| 50 | 
            +
                        if config.network
         | 
| 51 | 
            +
                          config.networks = [ config.network ]
         | 
| 52 | 
            +
                        else
         | 
| 53 | 
            +
                          config.networks = []
         | 
| 54 | 
            +
                        end
         | 
| 55 | 
            +
                      end
         | 
| 56 | 
            +
             | 
| 57 | 
            +
                      # Find networks if provided
         | 
| 58 | 
            +
                      unless config.networks.empty?
         | 
| 59 | 
            +
                        env[:ui].info(I18n.t("vagrant_openstack.finding_network"))
         | 
| 60 | 
            +
                        options[:nics] = Array.new
         | 
| 61 | 
            +
                        config.networks.each_with_index do |os_network_name, i|
         | 
| 62 | 
            +
             | 
| 63 | 
            +
                          # Use the configured OpenStack network, if it exists.
         | 
| 64 | 
            +
                          os_network = find_matching(env[:openstack_network].networks, os_network_name)
         | 
| 65 | 
            +
                          if os_network
         | 
| 66 | 
            +
                            current = { :net_id => os_network.id }
         | 
| 67 | 
            +
             | 
| 68 | 
            +
                            # Match the OpenStack network to a corresponding
         | 
| 69 | 
            +
                            # config.vm.network option.  If there is one, use that for its
         | 
| 70 | 
            +
                            # IP address.
         | 
| 71 | 
            +
                            config_network = env[:machine].config.vm.networks[i]
         | 
| 72 | 
            +
                            if config_network
         | 
| 73 | 
            +
                              ip_address = config_network[1][:ip]
         | 
| 74 | 
            +
                              current[:v4_fixed_ip] = ip_address if ip_address
         | 
| 75 | 
            +
                            end
         | 
| 76 | 
            +
             | 
| 77 | 
            +
                            options[:nics] << current
         | 
| 78 | 
            +
                          end
         | 
| 79 | 
            +
                        end
         | 
| 80 | 
            +
                        env[:ui].info("options[:nics]: #{options[:nics]}")
         | 
| 81 | 
            +
                      end
         | 
| 82 | 
            +
                     
         | 
| 83 | 
            +
                      # Output the settings we're going to use to the user
         | 
| 84 | 
            +
                      env[:ui].info(I18n.t("vagrant_openstack.launching_server"))
         | 
| 85 | 
            +
                      env[:ui].info(" -- Flavor: #{flavor.name}")
         | 
| 86 | 
            +
                      env[:ui].info(" -- Image: #{image.name}")
         | 
| 87 | 
            +
                      env[:ui].info(" -- Name: #{server_name}")
         | 
| 88 | 
            +
                      config.networks.each do |n|
         | 
| 89 | 
            +
                        env[:ui].info(" -- Network: #{n}")
         | 
| 90 | 
            +
                      end
         | 
| 91 | 
            +
                      if config.security_groups
         | 
| 92 | 
            +
                        env[:ui].info(" -- Security Groups: #{config.security_groups}")
         | 
| 93 | 
            +
                      end
         | 
| 94 | 
            +
             | 
| 95 | 
            +
                      # Create the server
         | 
| 96 | 
            +
                      server = env[:openstack_compute].servers.create(options)
         | 
| 97 | 
            +
             | 
| 98 | 
            +
                      # Store the ID right away so we can track it
         | 
| 99 | 
            +
                      env[:machine].id = server.id
         | 
| 100 | 
            +
             | 
| 101 | 
            +
                      # Wait for the server to finish building
         | 
| 102 | 
            +
                      env[:ui].info(I18n.t("vagrant_openstack.waiting_for_build"))
         | 
| 103 | 
            +
                      retryable(:on => Fog::Errors::TimeoutError, :tries => 200) do
         | 
| 104 | 
            +
                        # If we're interrupted don't worry about waiting
         | 
| 105 | 
            +
                        next if env[:interrupted]
         | 
| 106 | 
            +
             | 
| 107 | 
            +
                        # Set the progress
         | 
| 108 | 
            +
                        env[:ui].clear_line
         | 
| 109 | 
            +
                        env[:ui].report_progress(server.progress, 100, false)
         | 
| 110 | 
            +
             | 
| 111 | 
            +
                        # Wait for the server to be ready
         | 
| 112 | 
            +
                        begin
         | 
| 113 | 
            +
                          server.wait_for(5) { ready? }
         | 
| 114 | 
            +
                          # Once the server is up and running assign a floating IP if we have one
         | 
| 115 | 
            +
                          floating_ip = config.floating_ip
         | 
| 116 | 
            +
                          # try to automatically allocate and  associate a floating IP
         | 
| 117 | 
            +
                          if floating_ip && floating_ip.to_sym == :auto
         | 
| 118 | 
            +
                            if config.floating_ip_pool
         | 
| 119 | 
            +
                              env[:ui].info("Allocating floating IP address from pool: #{config.floating_ip_pool}")
         | 
| 120 | 
            +
                              address = env[:openstack_compute].allocate_address(config.floating_ip_pool).body["floating_ip"]
         | 
| 121 | 
            +
                              if address["ip"].nil?
         | 
| 122 | 
            +
                                raise Errors::FloatingIPNotAllocated
         | 
| 123 | 
            +
                              else
         | 
| 124 | 
            +
                                floating_ip = address["ip"]
         | 
| 125 | 
            +
                              end
         | 
| 126 | 
            +
                            else
         | 
| 127 | 
            +
                              addresses = env[:openstack_compute].addresses
         | 
| 128 | 
            +
                              free_floating = addresses.find_index {|a| a.fixed_ip.nil?}
         | 
| 129 | 
            +
                              if free_floating.nil?
         | 
| 130 | 
            +
                                raise Errors::FloatingIPNotFound
         | 
| 131 | 
            +
                              else
         | 
| 132 | 
            +
                                floating_ip = addresses[free_floating].ip
         | 
| 133 | 
            +
                              end
         | 
| 134 | 
            +
                            end
         | 
| 135 | 
            +
                          end
         | 
| 136 | 
            +
                           
         | 
| 137 | 
            +
                          # try to automatically associate the next available unassigned ip in the given pool
         | 
| 138 | 
            +
                          if floating_ip && floating_ip.to_sym == :associate_unassigned
         | 
| 139 | 
            +
                            if config.floating_ip_pool
         | 
| 140 | 
            +
                              env[:ui].info("Associating floating IP address from pool: #{config.floating_ip_pool}")
         | 
| 141 | 
            +
                              addresses = env[:openstack_compute].addresses
         | 
| 142 | 
            +
             | 
| 143 | 
            +
                              # grab the next available IP in this pool which is not currently allocated:
         | 
| 144 | 
            +
                              address = env[:openstack_compute].addresses.find { |thisone|
         | 
| 145 | 
            +
                                  (thisone.attributes[:pool].eql? config.floating_ip_pool and thisone.attributes[:instance_id].nil?)
         | 
| 146 | 
            +
                              }
         | 
| 147 | 
            +
             | 
| 148 | 
            +
                              if address.nil?
         | 
| 149 | 
            +
                                raise Errors::FloatingUnassignedIPNotFound
         | 
| 150 | 
            +
                              else
         | 
| 151 | 
            +
                                  floating_ip = address.attributes[:ip]
         | 
| 152 | 
            +
                              end
         | 
| 153 | 
            +
                              result = env[:openstack_compute].associate_address(server.id,floating_ip)
         | 
| 154 | 
            +
                              if result[:status] != 202
         | 
| 155 | 
            +
                                raise Errors::FloatingIPFailedAssociate
         | 
| 156 | 
            +
                              else
         | 
| 157 | 
            +
                                env[:ui].info("Found and Associated floating IP address #{address.attributes[:ip]} from pool #{config.floating_ip_pool}")
         | 
| 158 | 
            +
                              end
         | 
| 159 | 
            +
                            else
         | 
| 160 | 
            +
                              raise Errors::FloatingUnassignedRequiresPool
         | 
| 161 | 
            +
                            end
         | 
| 162 | 
            +
                          end
         | 
| 163 | 
            +
                            
         | 
| 164 | 
            +
                          if floating_ip
         | 
| 165 | 
            +
                            floater = env[:openstack_compute].addresses.find { |thisone| thisone.ip.eql? floating_ip }
         | 
| 166 | 
            +
                            floater.server = server
         | 
| 167 | 
            +
                          end
         | 
| 168 | 
            +
                          
         | 
| 169 | 
            +
                          # Process disks if provided
         | 
| 170 | 
            +
                          volumes = Array.new
         | 
| 171 | 
            +
                          if config.disks && !config.disks.empty?
         | 
| 172 | 
            +
                            env[:ui].info(I18n.t("vagrant_openstack.creating_disks"))
         | 
| 173 | 
            +
                            config.disks.each do |disk|
         | 
| 174 | 
            +
                              volume = env[:openstack_compute].volumes.all.find{|v| v.name ==
         | 
| 175 | 
            +
                                                                      disk["name"] and 
         | 
| 176 | 
            +
                                                                    v.description ==
         | 
| 177 | 
            +
                                                                      disk["description"] and
         | 
| 178 | 
            +
                                                                    v.size ==
         | 
| 179 | 
            +
                                                                      disk["size"] and
         | 
| 180 | 
            +
                                                                    v.ready? }
         | 
| 181 | 
            +
                              if volume
         | 
| 182 | 
            +
                                env[:ui].info("re-using volume: #{disk["name"]}")
         | 
| 183 | 
            +
                                disk["volume_id"] = volume.id
         | 
| 184 | 
            +
                              else
         | 
| 185 | 
            +
                                env[:ui].info("creating volume: #{disk["name"]}")
         | 
| 186 | 
            +
                                disk["volume_id"] = env[:openstack_compute].create_volume(
         | 
| 187 | 
            +
                                                     disk["name"], disk["description"], disk["size"]).\
         | 
| 188 | 
            +
                                                     data[:body]["volume"]["id"]
         | 
| 189 | 
            +
                                volumes << { :id => disk["volume_id"] }
         | 
| 190 | 
            +
                              end
         | 
| 191 | 
            +
             | 
| 192 | 
            +
                              # mount points are not expected to be meaningful
         | 
| 193 | 
            +
                              # add useful support if your cloud respects them
         | 
| 194 | 
            +
                              begin
         | 
| 195 | 
            +
                                # Assume instance has only one disk
         | 
| 196 | 
            +
                                nova_offset = 1
         | 
| 197 | 
            +
                                # Increase counter in case we have swap or ephemeral disks.
         | 
| 198 | 
            +
                                if flavor.swap != 0
         | 
| 199 | 
            +
                                    nova_offset += 1
         | 
| 200 | 
            +
                                end
         | 
| 201 | 
            +
                                if flavor.ephemeral != 0
         | 
| 202 | 
            +
                                    nova_offset += 1
         | 
| 203 | 
            +
                                end
         | 
| 204 | 
            +
                                server.attach_volume(disk["volume_id"], "/dev/vd#{("c".."z").to_a[server.volume_attachments.length + nova_offset]}")
         | 
| 205 | 
            +
                                server.wait_for{ volume_attachments.any?{|vol| vol["id"]==disk["volume_id"]} }
         | 
| 206 | 
            +
                              rescue Excon::Errors::Error => e
         | 
| 207 | 
            +
                                raise Errors::VolumeBadState, :volume => disk["name"], :state => e.message
         | 
| 208 | 
            +
                              end
         | 
| 209 | 
            +
                            end
         | 
| 210 | 
            +
                          end
         | 
| 211 | 
            +
             | 
| 212 | 
            +
                          # store this so we can use it later
         | 
| 213 | 
            +
                          env[:floating_ip] = floating_ip
         | 
| 214 | 
            +
                          
         | 
| 215 | 
            +
                        rescue RuntimeError => e
         | 
| 216 | 
            +
                          # If we don't have an error about a state transition, then
         | 
| 217 | 
            +
                          # we just move on.
         | 
| 218 | 
            +
                          raise if e.message !~ /should have transitioned/
         | 
| 219 | 
            +
                          raise Errors::CreateBadState, :state => server.state.downcase
         | 
| 220 | 
            +
                        end
         | 
| 221 | 
            +
                      end
         | 
| 222 | 
            +
             | 
| 223 | 
            +
                      if !env[:interrupted]
         | 
| 224 | 
            +
                        # Clear the line one more time so the progress is removed
         | 
| 225 | 
            +
                        env[:ui].clear_line
         | 
| 226 | 
            +
             | 
| 227 | 
            +
                        # Wait for SSH to become available
         | 
| 228 | 
            +
                        env[:ui].info(I18n.t("vagrant_openstack.waiting_for_ssh"))
         | 
| 229 | 
            +
                        while true
         | 
| 230 | 
            +
                          begin
         | 
| 231 | 
            +
                            # If we're interrupted then just back out
         | 
| 232 | 
            +
                            break if env[:interrupted]
         | 
| 233 | 
            +
                            break if env[:machine].communicate.ready?
         | 
| 234 | 
            +
                          rescue Errno::ENETUNREACH, Errno::EHOSTUNREACH
         | 
| 235 | 
            +
                          end
         | 
| 236 | 
            +
                          sleep 2
         | 
| 237 | 
            +
                        end
         | 
| 238 | 
            +
             | 
| 239 | 
            +
                        env[:ui].info(I18n.t("vagrant_openstack.ready"))
         | 
| 240 | 
            +
                      end
         | 
| 241 | 
            +
             | 
| 242 | 
            +
                      @app.call(env)
         | 
| 243 | 
            +
                    end
         | 
| 244 | 
            +
             | 
| 245 | 
            +
                    protected
         | 
| 246 | 
            +
             | 
| 247 | 
            +
                    # This method finds a matching _thing_ in a collection of
         | 
| 248 | 
            +
                    # _things_. This works matching if the ID or NAME equals to
         | 
| 249 | 
            +
                    # `name`. Or, if `name` is a regexp, a partial match is chosen
         | 
| 250 | 
            +
                    # as well.
         | 
| 251 | 
            +
                    def find_matching(collection, name)
         | 
| 252 | 
            +
                      collection.each do |single|
         | 
| 253 | 
            +
                        return single if single.id == name
         | 
| 254 | 
            +
                        return single if single.name == name
         | 
| 255 | 
            +
                        return single if name.is_a?(Regexp) && name =~ single.name
         | 
| 256 | 
            +
                      end
         | 
| 257 | 
            +
             | 
| 258 | 
            +
                      nil
         | 
| 259 | 
            +
                    end
         | 
| 260 | 
            +
                  end
         | 
| 261 | 
            +
                end
         | 
| 262 | 
            +
              end
         | 
| 263 | 
            +
            end
         | 
| @@ -0,0 +1,78 @@ | |
| 1 | 
            +
            require "fog"
         | 
| 2 | 
            +
            require "log4r"
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            module VagrantPlugins
         | 
| 5 | 
            +
              module OpenStack
         | 
| 6 | 
            +
                module Action
         | 
| 7 | 
            +
                  class DeleteOrchestrationStack
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                    def initialize(app, env)
         | 
| 10 | 
            +
                      @app    = app
         | 
| 11 | 
            +
                      @logger = Log4r::Logger.new(
         | 
| 12 | 
            +
                        "vagrant_openstack::action::delete_orchestration_stack")
         | 
| 13 | 
            +
                    end
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                    def call(env)
         | 
| 16 | 
            +
                      # Get the config.
         | 
| 17 | 
            +
                      config = env[:machine].provider_config
         | 
| 18 | 
            +
             | 
| 19 | 
            +
                      # Load IDs for orchestration stacks created by vagrant and this
         | 
| 20 | 
            +
                      # project.
         | 
| 21 | 
            +
                      created_stacks_fname = env[:machine].data_dir + 'orchestration_stacks'
         | 
| 22 | 
            +
             | 
| 23 | 
            +
                      # Return if no action is needed. 
         | 
| 24 | 
            +
                      if not config.orchestration_stack_destroy or not File.exist?(created_stacks_fname)
         | 
| 25 | 
            +
                        env[:machine].id = nil
         | 
| 26 | 
            +
                        return @app.call(env)
         | 
| 27 | 
            +
                      end
         | 
| 28 | 
            +
             | 
| 29 | 
            +
                      # Create new fog orchestration service.
         | 
| 30 | 
            +
                      env[:openstack_orchestration] = Fog::Orchestration.new(
         | 
| 31 | 
            +
                        env[:fog_openstack_params])
         | 
| 32 | 
            +
             | 
| 33 | 
            +
                      # Load IDs of stacks to be deleted.
         | 
| 34 | 
            +
                      available_stacks = env[:openstack_orchestration].list_stacks.body['stacks']
         | 
| 35 | 
            +
                      stacks_to_delete = []
         | 
| 36 | 
            +
                      File.open(created_stacks_fname) { |file|
         | 
| 37 | 
            +
                        file.each_line do |stack_id|
         | 
| 38 | 
            +
                          stack = find_stack(available_stacks, stack_id.chomp!)
         | 
| 39 | 
            +
                          next if not stack
         | 
| 40 | 
            +
                          stacks_to_delete << stack
         | 
| 41 | 
            +
                        end
         | 
| 42 | 
            +
                      }
         | 
| 43 | 
            +
             | 
| 44 | 
            +
                      # Delete stacks.
         | 
| 45 | 
            +
                      if stacks_to_delete.length > 0
         | 
| 46 | 
            +
                        env[:ui].info(I18n.t("vagrant_openstack.deleting_orchestration_stacks"))
         | 
| 47 | 
            +
                      end
         | 
| 48 | 
            +
             | 
| 49 | 
            +
                      stacks_to_delete.each do |stack|
         | 
| 50 | 
            +
                        @logger.info("Removing orchestration stack #{stack['stack_name']} (#{stack['id']}).")
         | 
| 51 | 
            +
                        env[:openstack_orchestration].delete_stack(
         | 
| 52 | 
            +
                          stack['stack_name'], stack['id'])
         | 
| 53 | 
            +
             | 
| 54 | 
            +
                        stacks_from_file.delete(stack)
         | 
| 55 | 
            +
                      end
         | 
| 56 | 
            +
             | 
| 57 | 
            +
                      # Delete file holding created stack IDs.
         | 
| 58 | 
            +
                      @logger.info("Deleting file #{created_stacks_fname}.")
         | 
| 59 | 
            +
                      File.delete(created_stacks_fname)
         | 
| 60 | 
            +
             | 
| 61 | 
            +
                      env[:machine].id = nil
         | 
| 62 | 
            +
                      @app.call(env)
         | 
| 63 | 
            +
                    end
         | 
| 64 | 
            +
             | 
| 65 | 
            +
                    private
         | 
| 66 | 
            +
             | 
| 67 | 
            +
                    def find_stack(available_stacks, stack_id)
         | 
| 68 | 
            +
                      available_stacks.each do |stack|
         | 
| 69 | 
            +
                        if stack['id'] == stack_id
         | 
| 70 | 
            +
                          return stack
         | 
| 71 | 
            +
                        end
         | 
| 72 | 
            +
                      end
         | 
| 73 | 
            +
                      false
         | 
| 74 | 
            +
                    end
         | 
| 75 | 
            +
                  end
         | 
| 76 | 
            +
                end
         | 
| 77 | 
            +
              end
         | 
| 78 | 
            +
            end
         |