Class: VagrantPlugins::AWS::Action::PackageInstance

Inherits:
Vagrant::Action::General::Package
  • Object
show all
Includes:
Vagrant::Util::Retryable
Defined in:
lib/vagrant-aws/action/package_instance.rb

Overview

The virtualbox package plugin action was loosely used as a model for this class.

Instance Method Summary collapse

Constructor Details

#initialize(app, env) ⇒ PackageInstance

Returns a new instance of PackageInstance.



27
28
29
30
31
# File 'lib/vagrant-aws/action/package_instance.rb', line 27

def initialize(app, env)
  super
  @logger = Log4r::Logger.new("vagrant_aws::action::package_instance")
  env["package.include"] ||= []
end

Instance Method Details

#call(env) ⇒ Object



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
# File 'lib/vagrant-aws/action/package_instance.rb', line 34

def call(env)
  # Initialize metrics if they haven't been
  env[:metrics] ||= {}

  # This block attempts to burn the server instance into an AMI
  begin
    # Get the Fog server object for given machine
    server = env[:aws_compute].servers.get(env[:machine].id)

    env[:ui].info(I18n.t("vagrant_aws.packaging_instance", :instance_id => server.id))
    
    # Make the request to AWS to create an AMI from machine's instance
    ami_response = server.service.create_image server.id, "#{server.tags["Name"]} Package - #{Time.now.strftime("%Y%m%d-%H%M%S")}", ""

    # Find ami id
    @ami_id = ami_response.data[:body]["imageId"]

    # Attempt to burn the aws instance into an AMI within timeout
    env[:metrics]["instance_ready_time"] = Util::Timer.time do
      
      # Get the config, to set the ami burn timeout
      region = env[:machine].provider_config.region
      region_config = env[:machine].provider_config.get_region_config(region)
      tries = region_config.instance_package_timeout / 2

      env[:ui].info(I18n.t("vagrant_aws.burning_ami", :ami_id => @ami_id))
      if !region_config.package_tags.empty?
        server.service.create_tags(@ami_id, region_config.package_tags)
      end

      # Check the status of the AMI every 2 seconds until the ami burn timeout has been reached
      begin
        retryable(:on => Fog::Errors::TimeoutError, :tries => tries) do
          # If we're interrupted don't worry about waiting
          next if env[:interrupted]

          # Need to update the ami_obj on each cycle
          ami_obj = server.service.images.get(@ami_id)

          # Wait for the server to be ready, raise error if timeout reached 
          server.wait_for(2) {
            if ami_obj.state == "failed"
              raise Errors::InstancePackageError, 
                ami_id: ami_obj.id,
                err: ami_obj.state
            end

            ami_obj.ready?
          }
        end
      rescue Fog::Errors::TimeoutError
        # Notify the user upon timeout
        raise Errors::InstancePackageTimeout,
          timeout: region_config.instance_package_timeout
      end
    end
    env[:ui].info(I18n.t("vagrant_aws.packaging_instance_complete", :time_seconds => env[:metrics]["instance_ready_time"].to_i))
  rescue Fog::Compute::AWS::Error => e
    raise Errors::FogError, :message => e.message
  end

  # Handles inclusions from --include and --vagrantfile options
  setup_package_files(env)

  # Setup the temporary directory for the tarball files
  @temp_dir = env[:tmp_path].join(Time.now.to_i.to_s)
  env["export.temp_dir"] = @temp_dir
  FileUtils.mkpath(env["export.temp_dir"])

  # Create the Vagrantfile and metadata.json files from templates to go in the box
  create_vagrantfile(env)
  (env)

  # Just match up a couple environmental variables so that
  # the superclass will do the right thing. Then, call the
  # superclass to actually create the tarball (.box file)
  env["package.directory"] = env["export.temp_dir"]
  general_call(env)
  
  # Always call recover to clean up the temp dir
  clean_temp_dir
end

#general_callObject



33
# File 'lib/vagrant-aws/action/package_instance.rb', line 33

alias_method :general_call, :call