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
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
|
# File 'lib/vagrant-aws/action/run_instance.rb', line 20
def call(env)
env[:metrics] ||= {}
region = env[:machine].provider_config.region
region_config = env[:machine].provider_config.get_region_config(region)
ami = region_config.ami
availability_zone = region_config.availability_zone
instance_type = region_config.instance_type
keypair = region_config.keypair_name
private_ip_address = region_config.private_ip_address
security_groups = region_config.security_groups
subnet_id = region_config.subnet_id
tags = region_config.tags
user_data = region_config.user_data
block_device_mapping = region_config.block_device_mapping
elastic_ip = region_config.elastic_ip
terminate_on_shutdown = region_config.terminate_on_shutdown
iam_instance_profile_arn = region_config.iam_instance_profile_arn
iam_instance_profile_name = region_config.iam_instance_profile_name
if !keypair
env[:ui].warn(I18n.t("vagrant_aws.launch_no_keypair"))
end
if subnet_id && !elastic_ip
env[:ui].warn(I18n.t("vagrant_aws.launch_vpc_warning"))
end
env[:ui].info(I18n.t("vagrant_aws.launching_instance"))
env[:ui].info(" -- Type: #{instance_type}")
env[:ui].info(" -- AMI: #{ami}")
env[:ui].info(" -- Region: #{region}")
env[:ui].info(" -- Availability Zone: #{availability_zone}") if availability_zone
env[:ui].info(" -- Keypair: #{keypair}") if keypair
env[:ui].info(" -- Subnet ID: #{subnet_id}") if subnet_id
env[:ui].info(" -- IAM Instance Profile ARN: #{iam_instance_profile_arn}") if iam_instance_profile_arn
env[:ui].info(" -- IAM Instance Profile Name: #{iam_instance_profile_name}") if iam_instance_profile_name
env[:ui].info(" -- Private IP: #{private_ip_address}") if private_ip_address
env[:ui].info(" -- Elastic IP: #{elastic_ip}") if elastic_ip
env[:ui].info(" -- User Data: yes") if user_data
env[:ui].info(" -- Security Groups: #{security_groups.inspect}") if !security_groups.empty?
env[:ui].info(" -- User Data: #{user_data}") if user_data
env[:ui].info(" -- Block Device Mapping: #{block_device_mapping}") if block_device_mapping
env[:ui].info(" -- Terminate On Shutdown: #{terminate_on_shutdown}")
options = {
:availability_zone => availability_zone,
:flavor_id => instance_type,
:image_id => ami,
:key_name => keypair,
:private_ip_address => private_ip_address,
:subnet_id => subnet_id,
:iam_instance_profile_arn => iam_instance_profile_arn,
:iam_instance_profile_name => iam_instance_profile_name,
:tags => tags,
:user_data => user_data,
:block_device_mapping => block_device_mapping,
:instance_initiated_shutdown_behavior => terminate_on_shutdown == true ? "terminate" : nil
}
if !security_groups.empty?
security_group_key = options[:subnet_id].nil? ? :groups : :security_group_ids
options[security_group_key] = security_groups
end
begin
env[:ui].warn(I18n.t("vagrant_aws.warn_ssh_access")) unless allows_ssh_port?(env, security_groups, subnet_id)
server = env[:aws_compute].servers.create(options)
rescue Fog::Compute::AWS::NotFound => e
if e.message =~ /subnet ID/
raise Errors::FogError,
:message => "Subnet ID not found: #{subnet_id}"
end
raise
rescue Fog::Compute::AWS::Error => e
raise Errors::FogError, :message => e.message
rescue Excon::Errors::HTTPStatusError => e
raise Errors::InternalFogError,
:error => e.message,
:response => e.response.body
end
env[:machine].id = server.id
env[:metrics]["instance_ready_time"] = Util::Timer.time do
tries = region_config.instance_ready_timeout / 2
env[:ui].info(I18n.t("vagrant_aws.waiting_for_ready"))
begin
retryable(:on => Fog::Errors::TimeoutError, :tries => tries) do
next if env[:interrupted]
server.wait_for(2) { ready? }
end
rescue Fog::Errors::TimeoutError
terminate(env)
raise Errors::InstanceReadyTimeout,
timeout: region_config.instance_ready_timeout
end
end
@logger.info("Time to instance ready: #{env[:metrics]["instance_ready_time"]}")
if elastic_ip
domain = subnet_id ? 'vpc' : 'standard'
do_elastic_ip(env, domain, server)
end
if !env[:interrupted]
env[:metrics]["instance_ssh_time"] = Util::Timer.time do
env[:ui].info(I18n.t("vagrant_aws.waiting_for_ssh"))
while true
break if env[:interrupted]
break if env[:machine].communicate.ready?
sleep 2
end
end
@logger.info("Time for SSH ready: #{env[:metrics]["instance_ssh_time"]}")
env[:ui].info(I18n.t("vagrant_aws.ready"))
end
terminate(env) if env[:interrupted]
@app.call(env)
end
|