vagrant-aws 0.5.0 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +5 -1
- data/README.md +17 -6
- data/lib/vagrant-aws/action.rb +24 -9
- data/lib/vagrant-aws/action/connect_aws.rb +2 -1
- data/lib/vagrant-aws/action/package_instance.rb +192 -0
- data/lib/vagrant-aws/action/run_instance.rb +47 -20
- data/lib/vagrant-aws/action/terminate_instance.rb +5 -1
- data/lib/vagrant-aws/config.rb +46 -29
- data/lib/vagrant-aws/errors.rb +8 -0
- data/lib/vagrant-aws/version.rb +1 -1
- data/locales/en.yml +17 -0
- data/spec/vagrant-aws/config_spec.rb +13 -4
- data/templates/metadata.json.erb +3 -0
- data/templates/vagrant-aws_package_Vagrantfile.erb +5 -0
- data/vagrant-aws.gemspec +2 -3
- metadata +14 -29
- data/lib/vagrant-aws/action/sync_folders.rb +0 -130
- data/spec/vagrant-aws/actions/syncfolders_spec.rb +0 -28
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8af2e697fcbbf3ff15a67a92539b492944ba5784
|
4
|
+
data.tar.gz: 3729da1381c5fed78328854b5a447d104fb82212
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1f3c1b091c706c26507221206a92de3f8b7ba8d9f421c37de7164f84ed652838afa0d59127243e3ae863435a553c61f37b6bcd17d548c5c39946354b637fac53
|
7
|
+
data.tar.gz: 07c726e7633b5913e74d0e522044607253248d6bff1d00dde238f9d9ff54cd6764adc4c33dc3cce442d827dc48571a1c95c6b1774d144fe0b8884c5ac9deef9b
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
# Vagrant AWS Provider
|
2
|
+
[![Gitter](https://badges.gitter.im/Join Chat.svg)](https://gitter.im/mitchellh/vagrant-aws?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
2
3
|
|
3
4
|
<span class="badges">
|
4
5
|
[![Gem Version](https://badge.fury.io/rb/vagrant-aws.png)][gem]
|
@@ -20,8 +21,9 @@ EC2 and VPC.
|
|
20
21
|
* SSH into the instances.
|
21
22
|
* Provision the instances with any built-in Vagrant provisioner.
|
22
23
|
* Minimal synced folder support via `rsync`.
|
23
|
-
* Define region-
|
24
|
+
* Define region-specific configurations so Vagrant can manage machines
|
24
25
|
in multiple regions.
|
26
|
+
* Package running instances into new vagrant-aws friendly boxes
|
25
27
|
|
26
28
|
## Usage
|
27
29
|
|
@@ -61,6 +63,7 @@ Vagrant.configure("2") do |config|
|
|
61
63
|
config.vm.provider :aws do |aws, override|
|
62
64
|
aws.access_key_id = "YOUR KEY"
|
63
65
|
aws.secret_access_key = "YOUR SECRET KEY"
|
66
|
+
aws.session_token = "SESSION TOKEN"
|
64
67
|
aws.keypair_name = "KEYPAIR NAME"
|
65
68
|
|
66
69
|
aws.ami = "ami-7747d01e"
|
@@ -105,17 +108,25 @@ This provider exposes quite a few provider-specific configuration options:
|
|
105
108
|
the instance. If nil, it will use the default set by Amazon.
|
106
109
|
* `instance_ready_timeout` - The number of seconds to wait for the instance
|
107
110
|
to become "ready" in AWS. Defaults to 120 seconds.
|
108
|
-
* `
|
109
|
-
|
111
|
+
* `instance_package_timeout` - The number of seconds to wait for the instance
|
112
|
+
to be burnt into an AMI during packaging. Defaults to 600 seconds.
|
113
|
+
* `instance_type` - The type of instance, such as "m3.medium". The default
|
114
|
+
value of this if not specified is "m3.medium". "m1.small" has been
|
115
|
+
deprecated in "us-east-1" and "m3.medium" is the smallest instance
|
116
|
+
type to support both paravirtualization and hvm AMIs
|
110
117
|
* `keypair_name` - The name of the keypair to use to bootstrap AMIs
|
111
118
|
which support it.
|
119
|
+
* `session_token` - The session token provided by STS
|
112
120
|
* `private_ip_address` - The private IP address to assign to an instance
|
113
121
|
within a [VPC](http://aws.amazon.com/vpc/)
|
122
|
+
* `elastic_ip` - Can be set to 'true', or to an existing Elastic IP address.
|
123
|
+
If true, allocate a new Elastic IP address to the instance. If set
|
124
|
+
to an existing Elastic IP address, assign the address to the instance.
|
114
125
|
* `region` - The region to start the instance in, such as "us-east-1"
|
115
126
|
* `secret_access_key` - The secret access key for accessing AWS
|
116
127
|
* `security_groups` - An array of security groups for the instance. If this
|
117
128
|
instance will be launched in VPC, this must be a list of security group
|
118
|
-
Name.
|
129
|
+
Name. For a nondefault VPC, you must use security group IDs instead (http://docs.aws.amazon.com/cli/latest/reference/ec2/run-instances.html).
|
119
130
|
* `iam_instance_profile_arn` - The Amazon resource name (ARN) of the IAM Instance
|
120
131
|
Profile to associate with the instance
|
121
132
|
* `iam_instance_profile_name` - The name of the IAM Instance Profile to associate
|
@@ -184,8 +195,8 @@ There is minimal support for synced folders. Upon `vagrant up`,
|
|
184
195
|
`rsync` (if available) to uni-directionally sync the folder to
|
185
196
|
the remote machine over SSH.
|
186
197
|
|
187
|
-
|
188
|
-
|
198
|
+
See [Vagrant Synced folders: rsync](https://docs.vagrantup.com/v2/synced-folders/rsync.html)
|
199
|
+
|
189
200
|
|
190
201
|
## Other Examples
|
191
202
|
|
data/lib/vagrant-aws/action.rb
CHANGED
@@ -8,6 +8,21 @@ module VagrantPlugins
|
|
8
8
|
# Include the built-in modules so we can use them as top-level things.
|
9
9
|
include Vagrant::Action::Builtin
|
10
10
|
|
11
|
+
def self.action_package
|
12
|
+
Vagrant::Action::Builder.new.tap do |b|
|
13
|
+
b.use Call, IsCreated do |env, b2|
|
14
|
+
if !env[:result]
|
15
|
+
b2.use MessageNotCreated
|
16
|
+
next
|
17
|
+
end
|
18
|
+
|
19
|
+
# Connect to AWS and then Create a package from the server instance
|
20
|
+
b2.use ConnectAWS
|
21
|
+
b2.use PackageInstance
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
11
26
|
# This action is called to halt the remote machine.
|
12
27
|
def self.action_halt
|
13
28
|
Vagrant::Action::Builder.new.tap do |b|
|
@@ -30,16 +45,16 @@ module VagrantPlugins
|
|
30
45
|
b.use Call, DestroyConfirm do |env, b2|
|
31
46
|
if env[:result]
|
32
47
|
b2.use ConfigValidate
|
33
|
-
|
48
|
+
b2.use Call, IsCreated do |env2, b3|
|
34
49
|
if !env2[:result]
|
35
50
|
b3.use MessageNotCreated
|
36
51
|
next
|
37
52
|
end
|
53
|
+
b3.use ConnectAWS
|
54
|
+
b3.use ElbDeregisterInstance
|
55
|
+
b3.use TerminateInstance
|
56
|
+
b3.use ProvisionerCleanup if defined?(ProvisionerCleanup)
|
38
57
|
end
|
39
|
-
b2.use ConnectAWS
|
40
|
-
b2.use ElbDeregisterInstance
|
41
|
-
b2.use TerminateInstance
|
42
|
-
b2.use ProvisionerCleanup if defined?(ProvisionerCleanup)
|
43
58
|
else
|
44
59
|
b2.use MessageWillNotDestroy
|
45
60
|
end
|
@@ -58,7 +73,7 @@ module VagrantPlugins
|
|
58
73
|
end
|
59
74
|
|
60
75
|
b2.use Provision
|
61
|
-
b2.use
|
76
|
+
b2.use SyncedFolders
|
62
77
|
end
|
63
78
|
end
|
64
79
|
end
|
@@ -117,7 +132,7 @@ module VagrantPlugins
|
|
117
132
|
def self.action_prepare_boot
|
118
133
|
Vagrant::Action::Builder.new.tap do |b|
|
119
134
|
b.use Provision
|
120
|
-
b.use
|
135
|
+
b.use SyncedFolders
|
121
136
|
b.use WarnNetworks
|
122
137
|
b.use ElbRegisterInstance
|
123
138
|
end
|
@@ -126,7 +141,7 @@ module VagrantPlugins
|
|
126
141
|
# This action is called to bring the box up from nothing.
|
127
142
|
def self.action_up
|
128
143
|
Vagrant::Action::Builder.new.tap do |b|
|
129
|
-
b.use
|
144
|
+
b.use HandleBox
|
130
145
|
b.use ConfigValidate
|
131
146
|
b.use ConnectAWS
|
132
147
|
b.use Call, IsCreated do |env1, b1|
|
@@ -177,12 +192,12 @@ module VagrantPlugins
|
|
177
192
|
autoload :MessageAlreadyCreated, action_root.join("message_already_created")
|
178
193
|
autoload :MessageNotCreated, action_root.join("message_not_created")
|
179
194
|
autoload :MessageWillNotDestroy, action_root.join("message_will_not_destroy")
|
195
|
+
autoload :PackageInstance, action_root.join("package_instance")
|
180
196
|
autoload :ReadSSHInfo, action_root.join("read_ssh_info")
|
181
197
|
autoload :ReadState, action_root.join("read_state")
|
182
198
|
autoload :RunInstance, action_root.join("run_instance")
|
183
199
|
autoload :StartInstance, action_root.join("start_instance")
|
184
200
|
autoload :StopInstance, action_root.join("stop_instance")
|
185
|
-
autoload :SyncFolders, action_root.join("sync_folders")
|
186
201
|
autoload :TerminateInstance, action_root.join("terminate_instance")
|
187
202
|
autoload :TimedProvision, action_root.join("timed_provision") # some plugins now expect this action to exist
|
188
203
|
autoload :WaitForState, action_root.join("wait_for_state")
|
@@ -30,6 +30,7 @@ module VagrantPlugins
|
|
30
30
|
else
|
31
31
|
fog_config[:aws_access_key_id] = region_config.access_key_id
|
32
32
|
fog_config[:aws_secret_access_key] = region_config.secret_access_key
|
33
|
+
fog_config[:aws_session_token] = region_config.session_token
|
33
34
|
end
|
34
35
|
|
35
36
|
fog_config[:endpoint] = region_config.endpoint if region_config.endpoint
|
@@ -37,7 +38,7 @@ module VagrantPlugins
|
|
37
38
|
|
38
39
|
@logger.info("Connecting to AWS...")
|
39
40
|
env[:aws_compute] = Fog::Compute.new(fog_config)
|
40
|
-
env[:aws_elb] = Fog::AWS::ELB.new(fog_config.except(:provider))
|
41
|
+
env[:aws_elb] = Fog::AWS::ELB.new(fog_config.except(:provider, :endpoint))
|
41
42
|
|
42
43
|
@app.call(env)
|
43
44
|
end
|
@@ -0,0 +1,192 @@
|
|
1
|
+
require "log4r"
|
2
|
+
require 'vagrant/util/template_renderer'
|
3
|
+
require 'vagrant-aws/util/timer'
|
4
|
+
require 'vagrant/action/general/package'
|
5
|
+
|
6
|
+
module VagrantPlugins
|
7
|
+
module AWS
|
8
|
+
module Action
|
9
|
+
# This action packages a running aws-based server into an
|
10
|
+
# aws-based vagrant box. It does so by burning the associated
|
11
|
+
# vagrant-aws server instance, into an AMI via fog. Upon
|
12
|
+
# successful AMI burning, the action will create a .box tarball
|
13
|
+
# writing a Vagrantfile with the fresh AMI id into it.
|
14
|
+
|
15
|
+
# Vagrant itself comes with a general package action, which
|
16
|
+
# this plugin action does call. The general action provides
|
17
|
+
# the actual packaging as well as other options such as
|
18
|
+
# --include for including additional files and --vagrantfile
|
19
|
+
# which is pretty much not useful here anyway.
|
20
|
+
|
21
|
+
# The virtualbox package plugin action was loosely used
|
22
|
+
# as a model for this class.
|
23
|
+
|
24
|
+
class PackageInstance < Vagrant::Action::General::Package
|
25
|
+
include Vagrant::Util::Retryable
|
26
|
+
|
27
|
+
def initialize(app, env)
|
28
|
+
@app = app
|
29
|
+
@logger = Log4r::Logger.new("vagrant_aws::action::package_instance")
|
30
|
+
env["package.include"] ||= []
|
31
|
+
env["package.output"] ||= "package.box"
|
32
|
+
end
|
33
|
+
|
34
|
+
alias_method :general_call, :call
|
35
|
+
def call(env)
|
36
|
+
# Initialize metrics if they haven't been
|
37
|
+
env[:metrics] ||= {}
|
38
|
+
|
39
|
+
# This block attempts to burn the server instance into an AMI
|
40
|
+
begin
|
41
|
+
# Get the Fog server object for given machine
|
42
|
+
server = env[:aws_compute].servers.get(env[:machine].id)
|
43
|
+
|
44
|
+
env[:ui].info(I18n.t("vagrant_aws.packaging_instance", :instance_id => server.id))
|
45
|
+
|
46
|
+
# Make the request to AWS to create an AMI from machine's instance
|
47
|
+
ami_response = server.service.create_image server.id, "#{server.tags["Name"]} Package - #{Time.now.strftime("%Y%m%d-%H%M%S")}", ""
|
48
|
+
|
49
|
+
# Find ami id
|
50
|
+
@ami_id = ami_response.data[:body]["imageId"]
|
51
|
+
|
52
|
+
# Attempt to burn the aws instance into an AMI within timeout
|
53
|
+
env[:metrics]["instance_ready_time"] = Util::Timer.time do
|
54
|
+
|
55
|
+
# Get the config, to set the ami burn timeout
|
56
|
+
region = env[:machine].provider_config.region
|
57
|
+
region_config = env[:machine].provider_config.get_region_config(region)
|
58
|
+
tries = region_config.instance_package_timeout / 2
|
59
|
+
|
60
|
+
env[:ui].info(I18n.t("vagrant_aws.burning_ami", :ami_id => @ami_id))
|
61
|
+
|
62
|
+
# Check the status of the AMI every 2 seconds until the ami burn timeout has been reached
|
63
|
+
begin
|
64
|
+
retryable(:on => Fog::Errors::TimeoutError, :tries => tries) do
|
65
|
+
# If we're interrupted don't worry about waiting
|
66
|
+
next if env[:interrupted]
|
67
|
+
|
68
|
+
# Need to update the ami_obj on each cycle
|
69
|
+
ami_obj = server.service.images.get(@ami_id)
|
70
|
+
|
71
|
+
# Wait for the server to be ready, raise error if timeout reached
|
72
|
+
server.wait_for(2) {
|
73
|
+
if ami_obj.state == "failed"
|
74
|
+
raise Errors::InstancePackageError,
|
75
|
+
ami_id: ami_obj.id,
|
76
|
+
err: ami_obj.state
|
77
|
+
return
|
78
|
+
else
|
79
|
+
# Successful AMI burn will result in true here
|
80
|
+
ami_obj.ready?
|
81
|
+
end
|
82
|
+
}
|
83
|
+
end
|
84
|
+
rescue Fog::Errors::TimeoutError
|
85
|
+
# Notify the user upon timeout
|
86
|
+
raise Errors::InstancePackageTimeout,
|
87
|
+
timeout: region_config.instance_package_timeout
|
88
|
+
end
|
89
|
+
end
|
90
|
+
env[:ui].info(I18n.t("vagrant_aws.packaging_instance_complete", :time_seconds => env[:metrics]["instance_ready_time"].to_i))
|
91
|
+
rescue Fog::Compute::AWS::Error => e
|
92
|
+
raise Errors::FogError, :message => e.message
|
93
|
+
end
|
94
|
+
|
95
|
+
# Handles inclusions from --include and --vagrantfile options
|
96
|
+
setup_package_files(env)
|
97
|
+
|
98
|
+
# Setup the temporary directory for the tarball files
|
99
|
+
@temp_dir = env[:tmp_path].join(Time.now.to_i.to_s)
|
100
|
+
env["export.temp_dir"] = @temp_dir
|
101
|
+
FileUtils.mkpath(env["export.temp_dir"])
|
102
|
+
|
103
|
+
# Create the Vagrantfile and metadata.json files from templates to go in the box
|
104
|
+
create_vagrantfile(env)
|
105
|
+
create_metadata_file(env)
|
106
|
+
|
107
|
+
# Just match up a couple environmental variables so that
|
108
|
+
# the superclass will do the right thing. Then, call the
|
109
|
+
# superclass to actually create the tarball (.box file)
|
110
|
+
env["package.directory"] = env["export.temp_dir"]
|
111
|
+
general_call(env)
|
112
|
+
|
113
|
+
# Always call recover to clean up the temp dir
|
114
|
+
clean_temp_dir
|
115
|
+
end
|
116
|
+
|
117
|
+
protected
|
118
|
+
|
119
|
+
# Cleanup temp dir and files
|
120
|
+
def clean_temp_dir
|
121
|
+
if @temp_dir && File.exist?(@temp_dir)
|
122
|
+
FileUtils.rm_rf(@temp_dir)
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
# This method generates the Vagrantfile at the root of the box. Taken from
|
127
|
+
# VagrantPlugins::ProviderVirtualBox::Action::PackageVagrantfile
|
128
|
+
def create_vagrantfile env
|
129
|
+
File.open(File.join(env["export.temp_dir"], "Vagrantfile"), "w") do |f|
|
130
|
+
f.write(TemplateRenderer.render("vagrant-aws_package_Vagrantfile", {
|
131
|
+
region: env[:machine].provider_config.region,
|
132
|
+
ami: @ami_id,
|
133
|
+
template_root: template_root
|
134
|
+
}))
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
# This method generates the metadata.json file at the root of the box.
|
139
|
+
def create_metadata_file env
|
140
|
+
File.open(File.join(env["export.temp_dir"], "metadata.json"), "w") do |f|
|
141
|
+
f.write(TemplateRenderer.render("metadata.json", {
|
142
|
+
template_root: template_root
|
143
|
+
}))
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
# Sets up --include and --vagrantfile files which may be added as optional
|
148
|
+
# parameters. Taken from VagrantPlugins::ProviderVirtualBox::Action::SetupPackageFiles
|
149
|
+
def setup_package_files(env)
|
150
|
+
files = {}
|
151
|
+
env["package.include"].each do |file|
|
152
|
+
source = Pathname.new(file)
|
153
|
+
dest = nil
|
154
|
+
|
155
|
+
# If the source is relative then we add the file as-is to the include
|
156
|
+
# directory. Otherwise, we copy only the file into the root of the
|
157
|
+
# include directory. Kind of strange, but seems to match what people
|
158
|
+
# expect based on history.
|
159
|
+
if source.relative?
|
160
|
+
dest = source
|
161
|
+
else
|
162
|
+
dest = source.basename
|
163
|
+
end
|
164
|
+
|
165
|
+
# Assign the mapping
|
166
|
+
files[file] = dest
|
167
|
+
end
|
168
|
+
|
169
|
+
if env["package.vagrantfile"]
|
170
|
+
# Vagrantfiles are treated special and mapped to a specific file
|
171
|
+
files[env["package.vagrantfile"]] = "_Vagrantfile"
|
172
|
+
end
|
173
|
+
|
174
|
+
# Verify the mapping
|
175
|
+
files.each do |from, _|
|
176
|
+
raise Vagrant::Errors::PackageIncludeMissing,
|
177
|
+
file: from if !File.exist?(from)
|
178
|
+
end
|
179
|
+
|
180
|
+
# Save the mapping
|
181
|
+
env["package.files"] = files
|
182
|
+
end
|
183
|
+
|
184
|
+
# Used to find the base location of aws-vagrant templates
|
185
|
+
def template_root
|
186
|
+
AWS.source_root.join("templates")
|
187
|
+
end
|
188
|
+
|
189
|
+
end
|
190
|
+
end
|
191
|
+
end
|
192
|
+
end
|
@@ -95,11 +95,10 @@ module VagrantPlugins
|
|
95
95
|
if !security_groups.empty?
|
96
96
|
security_group_key = options[:subnet_id].nil? ? :groups : :security_group_ids
|
97
97
|
options[security_group_key] = security_groups
|
98
|
+
env[:ui].warn(I18n.t("vagrant_aws.warn_ssh_access")) unless allows_ssh_port?(env, security_groups, subnet_id)
|
98
99
|
end
|
99
100
|
|
100
101
|
begin
|
101
|
-
env[:ui].warn(I18n.t("vagrant_aws.warn_ssh_access")) unless allows_ssh_port?(env, security_groups, subnet_id)
|
102
|
-
|
103
102
|
server = env[:aws_compute].servers.create(options)
|
104
103
|
rescue Fog::Compute::AWS::NotFound => e
|
105
104
|
# Invalid subnet doesn't have its own error so we catch and
|
@@ -132,7 +131,7 @@ module VagrantPlugins
|
|
132
131
|
next if env[:interrupted]
|
133
132
|
|
134
133
|
# Wait for the server to be ready
|
135
|
-
server.wait_for(2) { ready? }
|
134
|
+
server.wait_for(2, 5) { ready? }
|
136
135
|
end
|
137
136
|
rescue Fog::Errors::TimeoutError
|
138
137
|
# Delete the instance
|
@@ -149,7 +148,7 @@ module VagrantPlugins
|
|
149
148
|
# Allocate and associate an elastic IP if requested
|
150
149
|
if elastic_ip
|
151
150
|
domain = subnet_id ? 'vpc' : 'standard'
|
152
|
-
do_elastic_ip(env, domain, server)
|
151
|
+
do_elastic_ip(env, domain, server, elastic_ip)
|
153
152
|
end
|
154
153
|
|
155
154
|
if !env[:interrupted]
|
@@ -198,26 +197,45 @@ module VagrantPlugins
|
|
198
197
|
!rules.select { |r| (r["fromPort"]..r["toPort"]).include?(port) }.empty?
|
199
198
|
end
|
200
199
|
|
201
|
-
def do_elastic_ip(env, domain, server)
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
200
|
+
def do_elastic_ip(env, domain, server, elastic_ip)
|
201
|
+
if elastic_ip =~ /\d+\.\d+\.\d+\.\d+/
|
202
|
+
begin
|
203
|
+
address = env[:aws_compute].addresses.get(elastic_ip)
|
204
|
+
rescue
|
205
|
+
handle_elastic_ip_error(env, "Could not retrieve Elastic IP: #{elastic_ip}")
|
206
|
+
end
|
207
|
+
if address.nil?
|
208
|
+
handle_elastic_ip_error(env, "Elastic IP not available: #{elastic_ip}")
|
209
|
+
end
|
210
|
+
@logger.debug("Public IP #{address.public_ip}")
|
211
|
+
else
|
212
|
+
begin
|
213
|
+
allocation = env[:aws_compute].allocate_address(domain)
|
214
|
+
rescue
|
215
|
+
handle_elastic_ip_error(env, "Could not allocate Elastic IP.")
|
216
|
+
end
|
217
|
+
@logger.debug("Public IP #{allocation.body['publicIp']}")
|
209
218
|
end
|
210
|
-
@logger.debug("Public IP #{allocation.body['publicIp']}")
|
211
219
|
|
212
220
|
# Associate the address and save the metadata to a hash
|
221
|
+
h = nil
|
213
222
|
if domain == 'vpc'
|
214
223
|
# VPC requires an allocation ID to assign an IP
|
215
|
-
|
216
|
-
|
224
|
+
if address
|
225
|
+
association = env[:aws_compute].associate_address(server.id, nil, nil, address.allocation_id)
|
226
|
+
else
|
227
|
+
association = env[:aws_compute].associate_address(server.id, nil, nil, allocation.body['allocationId'])
|
228
|
+
# Only store release data for an allocated address
|
229
|
+
h = { :allocation_id => allocation.body['allocationId'], :association_id => association.body['associationId'], :public_ip => allocation.body['publicIp'] }
|
230
|
+
end
|
217
231
|
else
|
218
232
|
# Standard EC2 instances only need the allocated IP address
|
219
|
-
|
220
|
-
|
233
|
+
if address
|
234
|
+
association = env[:aws_compute].associate_address(server.id, address.public_ip)
|
235
|
+
else
|
236
|
+
association = env[:aws_compute].associate_address(server.id, allocation.body['publicIp'])
|
237
|
+
h = { :public_ip => allocation.body['publicIp'] }
|
238
|
+
end
|
221
239
|
end
|
222
240
|
|
223
241
|
unless association.body['return']
|
@@ -228,12 +246,21 @@ module VagrantPlugins
|
|
228
246
|
end
|
229
247
|
|
230
248
|
# Save this IP to the data dir so it can be released when the instance is destroyed
|
231
|
-
|
232
|
-
|
233
|
-
|
249
|
+
if h
|
250
|
+
ip_file = env[:machine].data_dir.join('elastic_ip')
|
251
|
+
ip_file.open('w+') do |f|
|
252
|
+
f.write(h.to_json)
|
253
|
+
end
|
234
254
|
end
|
235
255
|
end
|
236
256
|
|
257
|
+
def handle_elastic_ip_error(env, message)
|
258
|
+
@logger.debug(message)
|
259
|
+
terminate(env)
|
260
|
+
raise Errors::FogError,
|
261
|
+
:message => message
|
262
|
+
end
|
263
|
+
|
237
264
|
def terminate(env)
|
238
265
|
destroy_env = env.dup
|
239
266
|
destroy_env.delete(:interrupted)
|
@@ -12,7 +12,11 @@ module VagrantPlugins
|
|
12
12
|
end
|
13
13
|
|
14
14
|
def call(env)
|
15
|
-
server
|
15
|
+
server = env[:aws_compute].servers.get(env[:machine].id)
|
16
|
+
region = env[:machine].provider_config.region
|
17
|
+
region_config = env[:machine].provider_config.get_region_config(region)
|
18
|
+
|
19
|
+
elastic_ip = region_config.elastic_ip
|
16
20
|
|
17
21
|
# Release the elastic IP
|
18
22
|
ip_file = env[:machine].data_dir.join('elastic_ip')
|
data/lib/vagrant-aws/config.rb
CHANGED
@@ -24,7 +24,12 @@ module VagrantPlugins
|
|
24
24
|
# @return [Fixnum]
|
25
25
|
attr_accessor :instance_ready_timeout
|
26
26
|
|
27
|
-
# The
|
27
|
+
# The timeout to wait for an instance to successfully burn into an AMI.
|
28
|
+
#
|
29
|
+
# @return [Fixnum]
|
30
|
+
attr_accessor :instance_package_timeout
|
31
|
+
|
32
|
+
# The type of instance to launch, such as "m3.medium"
|
28
33
|
#
|
29
34
|
# @return [String]
|
30
35
|
attr_accessor :instance_type
|
@@ -39,9 +44,10 @@ module VagrantPlugins
|
|
39
44
|
# @return [String]
|
40
45
|
attr_accessor :private_ip_address
|
41
46
|
|
42
|
-
#
|
47
|
+
# If true, acquire and attach an elastic IP address.
|
48
|
+
# If set to an IP address, assign to the instance.
|
43
49
|
#
|
44
|
-
# @return [
|
50
|
+
# @return [String]
|
45
51
|
attr_accessor :elastic_ip
|
46
52
|
|
47
53
|
# The name of the AWS region in which to create the instance.
|
@@ -64,6 +70,11 @@ module VagrantPlugins
|
|
64
70
|
# @return [String]
|
65
71
|
attr_accessor :secret_access_key
|
66
72
|
|
73
|
+
# The token associated with the key for accessing AWS.
|
74
|
+
#
|
75
|
+
# @return [String]
|
76
|
+
attr_accessor :session_token
|
77
|
+
|
67
78
|
# The security groups to set on the instance. For VPC this must
|
68
79
|
# be a list of IDs. For EC2, it can be either.
|
69
80
|
#
|
@@ -145,32 +156,34 @@ module VagrantPlugins
|
|
145
156
|
attr_accessor :elb
|
146
157
|
|
147
158
|
def initialize(region_specific=false)
|
148
|
-
@access_key_id
|
149
|
-
@ami
|
150
|
-
@availability_zone
|
151
|
-
@instance_ready_timeout
|
152
|
-
@
|
153
|
-
@
|
154
|
-
@
|
155
|
-
@
|
156
|
-
@
|
157
|
-
@
|
158
|
-
@
|
159
|
-
@
|
160
|
-
@
|
161
|
-
@
|
162
|
-
@
|
163
|
-
@
|
164
|
-
@
|
165
|
-
@
|
159
|
+
@access_key_id = UNSET_VALUE
|
160
|
+
@ami = UNSET_VALUE
|
161
|
+
@availability_zone = UNSET_VALUE
|
162
|
+
@instance_ready_timeout = UNSET_VALUE
|
163
|
+
@instance_package_timeout = UNSET_VALUE
|
164
|
+
@instance_type = UNSET_VALUE
|
165
|
+
@keypair_name = UNSET_VALUE
|
166
|
+
@private_ip_address = UNSET_VALUE
|
167
|
+
@region = UNSET_VALUE
|
168
|
+
@endpoint = UNSET_VALUE
|
169
|
+
@version = UNSET_VALUE
|
170
|
+
@secret_access_key = UNSET_VALUE
|
171
|
+
@session_token = UNSET_VALUE
|
172
|
+
@security_groups = UNSET_VALUE
|
173
|
+
@subnet_id = UNSET_VALUE
|
174
|
+
@tags = {}
|
175
|
+
@user_data = UNSET_VALUE
|
176
|
+
@use_iam_profile = UNSET_VALUE
|
177
|
+
@block_device_mapping = []
|
178
|
+
@elastic_ip = UNSET_VALUE
|
166
179
|
@iam_instance_profile_arn = UNSET_VALUE
|
167
180
|
@iam_instance_profile_name = UNSET_VALUE
|
168
|
-
@terminate_on_shutdown
|
169
|
-
@ssh_host_attribute
|
170
|
-
@monitoring
|
171
|
-
@ebs_optimized
|
172
|
-
@associate_public_ip
|
173
|
-
@elb
|
181
|
+
@terminate_on_shutdown = UNSET_VALUE
|
182
|
+
@ssh_host_attribute = UNSET_VALUE
|
183
|
+
@monitoring = UNSET_VALUE
|
184
|
+
@ebs_optimized = UNSET_VALUE
|
185
|
+
@associate_public_ip = UNSET_VALUE
|
186
|
+
@elb = UNSET_VALUE
|
174
187
|
|
175
188
|
# Internal state (prefix with __ so they aren't automatically
|
176
189
|
# merged)
|
@@ -255,6 +268,7 @@ module VagrantPlugins
|
|
255
268
|
# will default to nil if the environment variables are not present.
|
256
269
|
@access_key_id = ENV['AWS_ACCESS_KEY'] if @access_key_id == UNSET_VALUE
|
257
270
|
@secret_access_key = ENV['AWS_SECRET_KEY'] if @secret_access_key == UNSET_VALUE
|
271
|
+
@session_token = ENV['AWS_SESSION_TOKEN'] if @session_token == UNSET_VALUE
|
258
272
|
|
259
273
|
# AMI must be nil, since we can't default that
|
260
274
|
@ami = nil if @ami == UNSET_VALUE
|
@@ -262,8 +276,11 @@ module VagrantPlugins
|
|
262
276
|
# Set the default timeout for waiting for an instance to be ready
|
263
277
|
@instance_ready_timeout = 120 if @instance_ready_timeout == UNSET_VALUE
|
264
278
|
|
265
|
-
#
|
266
|
-
@
|
279
|
+
# Set the default timeout for waiting for an instance to burn into and ami
|
280
|
+
@instance_package_timeout = 600 if @instance_package_timeout == UNSET_VALUE
|
281
|
+
|
282
|
+
# Default instance type is an m3.medium
|
283
|
+
@instance_type = "m3.medium" if @instance_type == UNSET_VALUE
|
267
284
|
|
268
285
|
# Keypair defaults to nil
|
269
286
|
@keypair_name = nil if @keypair_name == UNSET_VALUE
|
data/lib/vagrant-aws/errors.rb
CHANGED
@@ -19,6 +19,14 @@ module VagrantPlugins
|
|
19
19
|
error_key(:instance_ready_timeout)
|
20
20
|
end
|
21
21
|
|
22
|
+
class InstancePackageError < VagrantAWSError
|
23
|
+
error_key(:instance_package_error)
|
24
|
+
end
|
25
|
+
|
26
|
+
class InstancePackageTimeout < VagrantAWSError
|
27
|
+
error_key(:instance_package_timeout)
|
28
|
+
end
|
29
|
+
|
22
30
|
class RsyncError < VagrantAWSError
|
23
31
|
error_key(:rsync_error)
|
24
32
|
end
|
data/lib/vagrant-aws/version.rb
CHANGED
data/locales/en.yml
CHANGED
@@ -2,6 +2,8 @@ en:
|
|
2
2
|
vagrant_aws:
|
3
3
|
already_status: |-
|
4
4
|
The machine is already %{status}.
|
5
|
+
burning_ami: |-
|
6
|
+
Waiting for the AMI '%{ami_id}' to burn...
|
5
7
|
elb:
|
6
8
|
adjusting: |-
|
7
9
|
Adjusting availability zones of ELB %{elb_name}...
|
@@ -26,6 +28,10 @@ en:
|
|
26
28
|
to SSH into it.
|
27
29
|
not_created: |-
|
28
30
|
Instance is not created. Please run `vagrant up` first.
|
31
|
+
packaging_instance: |-
|
32
|
+
Burning instance %{instance_id} into an ami
|
33
|
+
packaging_instance_complete: |-
|
34
|
+
Burn was successful in %{time_seconds}s
|
29
35
|
ready: |-
|
30
36
|
Machine is booted and ready for use!
|
31
37
|
rsync_not_found_warning: |-
|
@@ -85,6 +91,17 @@ en:
|
|
85
91
|
set waiting for the instance to become ready is %{timeout} seconds.
|
86
92
|
Please verify that the machine properly boots. If you need more time
|
87
93
|
set the `instance_ready_timeout` configuration on the AWS provider.
|
94
|
+
instance_package_error: |-
|
95
|
+
There was an error packaging the instance. See details below for more info.
|
96
|
+
|
97
|
+
AMI Id: %{ami_id}
|
98
|
+
Error: %{err}
|
99
|
+
instance_package_timeout: |-
|
100
|
+
The AMI failed to become "ready" in AWS. The timeout currently
|
101
|
+
set waiting for the instance to become ready is %{timeout} seconds. For
|
102
|
+
larger instances AMI burning may take long periods of time. Please
|
103
|
+
ensure the timeout is set high enough, it can be changed by adjusting
|
104
|
+
the `instance_package_timeout` configuration on the AWS provider.
|
88
105
|
rsync_error: |-
|
89
106
|
There was an error when attempting to rsync a shared folder.
|
90
107
|
Please inspect the error message below for more info.
|
@@ -19,11 +19,13 @@ describe VagrantPlugins::AWS::Config do
|
|
19
19
|
its("ami") { should be_nil }
|
20
20
|
its("availability_zone") { should be_nil }
|
21
21
|
its("instance_ready_timeout") { should == 120 }
|
22
|
-
its("
|
22
|
+
its("instance_package_timeout") { should == 600 }
|
23
|
+
its("instance_type") { should == "m3.medium" }
|
23
24
|
its("keypair_name") { should be_nil }
|
24
25
|
its("private_ip_address") { should be_nil }
|
25
26
|
its("region") { should == "us-east-1" }
|
26
27
|
its("secret_access_key") { should be_nil }
|
28
|
+
its("session_token") { should be_nil }
|
27
29
|
its("security_groups") { should == [] }
|
28
30
|
its("subnet_id") { should be_nil }
|
29
31
|
its("iam_instance_profile_arn") { should be_nil }
|
@@ -46,9 +48,9 @@ describe VagrantPlugins::AWS::Config do
|
|
46
48
|
# each of these attributes to "foo" in isolation, and reads the value
|
47
49
|
# and asserts the proper result comes back out.
|
48
50
|
[:access_key_id, :ami, :availability_zone, :instance_ready_timeout,
|
49
|
-
:instance_type, :keypair_name, :ssh_host_attribute,
|
50
|
-
:region, :secret_access_key, :
|
51
|
-
:subnet_id, :tags, :elastic_ip, :terminate_on_shutdown,
|
51
|
+
:instance_package_timeout, :instance_type, :keypair_name, :ssh_host_attribute,
|
52
|
+
:ebs_optimized, :region, :secret_access_key, :session_token, :monitoring,
|
53
|
+
:associate_public_ip, :subnet_id, :tags, :elastic_ip, :terminate_on_shutdown,
|
52
54
|
:iam_instance_profile_arn, :iam_instance_profile_name,
|
53
55
|
:use_iam_profile, :user_data, :block_device_mapping].each do |attribute|
|
54
56
|
|
@@ -75,12 +77,14 @@ describe VagrantPlugins::AWS::Config do
|
|
75
77
|
|
76
78
|
its("access_key_id") { should be_nil }
|
77
79
|
its("secret_access_key") { should be_nil }
|
80
|
+
its("session_token") { should be_nil }
|
78
81
|
end
|
79
82
|
|
80
83
|
context "with EC2 credential environment variables" do
|
81
84
|
before :each do
|
82
85
|
ENV.stub(:[]).with("AWS_ACCESS_KEY").and_return("access_key")
|
83
86
|
ENV.stub(:[]).with("AWS_SECRET_KEY").and_return("secret_key")
|
87
|
+
ENV.stub(:[]).with("AWS_SESSION_TOKEN").and_return("session_token")
|
84
88
|
end
|
85
89
|
|
86
90
|
subject do
|
@@ -91,6 +95,7 @@ describe VagrantPlugins::AWS::Config do
|
|
91
95
|
|
92
96
|
its("access_key_id") { should == "access_key" }
|
93
97
|
its("secret_access_key") { should == "secret_key" }
|
98
|
+
its("session_token") { should == "session_token" }
|
94
99
|
end
|
95
100
|
end
|
96
101
|
|
@@ -101,6 +106,7 @@ describe VagrantPlugins::AWS::Config do
|
|
101
106
|
let(:config_keypair_name) { "foo" }
|
102
107
|
let(:config_region) { "foo" }
|
103
108
|
let(:config_secret_access_key) { "foo" }
|
109
|
+
let(:config_session_token) { "foo" }
|
104
110
|
|
105
111
|
def set_test_values(instance)
|
106
112
|
instance.access_key_id = config_access_key_id
|
@@ -109,6 +115,7 @@ describe VagrantPlugins::AWS::Config do
|
|
109
115
|
instance.keypair_name = config_keypair_name
|
110
116
|
instance.region = config_region
|
111
117
|
instance.secret_access_key = config_secret_access_key
|
118
|
+
instance.session_token = config_session_token
|
112
119
|
end
|
113
120
|
|
114
121
|
it "should raise an exception if not finalized" do
|
@@ -134,6 +141,7 @@ describe VagrantPlugins::AWS::Config do
|
|
134
141
|
its("keypair_name") { should == config_keypair_name }
|
135
142
|
its("region") { should == config_region }
|
136
143
|
its("secret_access_key") { should == config_secret_access_key }
|
144
|
+
its("session_token") { should == config_session_token }
|
137
145
|
end
|
138
146
|
|
139
147
|
context "with a specific config set" do
|
@@ -158,6 +166,7 @@ describe VagrantPlugins::AWS::Config do
|
|
158
166
|
its("keypair_name") { should == config_keypair_name }
|
159
167
|
its("region") { should == region_name }
|
160
168
|
its("secret_access_key") { should == config_secret_access_key }
|
169
|
+
its("session_token") { should == config_session_token }
|
161
170
|
end
|
162
171
|
|
163
172
|
describe "inheritance of parent config" do
|
data/vagrant-aws.gemspec
CHANGED
@@ -18,9 +18,8 @@ Gem::Specification.new do |s|
|
|
18
18
|
s.add_runtime_dependency "fog", "~> 1.22"
|
19
19
|
|
20
20
|
s.add_development_dependency "rake"
|
21
|
-
s.add_development_dependency "rspec
|
22
|
-
s.add_development_dependency "rspec-
|
23
|
-
s.add_development_dependency "rspec-mocks", "~> 2.12.1"
|
21
|
+
s.add_development_dependency "rspec", "~> 2.12"
|
22
|
+
s.add_development_dependency "rspec-its"
|
24
23
|
|
25
24
|
# The following block of code determines the files that should be included
|
26
25
|
# in the gem. It does this by reading all the files in the directory where
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: vagrant-aws
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mitchell Hashimoto
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-12-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: fog
|
@@ -39,47 +39,33 @@ dependencies:
|
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
|
-
name: rspec
|
42
|
+
name: rspec
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: 2.12
|
47
|
+
version: '2.12'
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: 2.12
|
54
|
+
version: '2.12'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
|
-
name: rspec-
|
56
|
+
name: rspec-its
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
|
-
- - "
|
60
|
-
- !ruby/object:Gem::Version
|
61
|
-
version: 2.12.1
|
62
|
-
type: :development
|
63
|
-
prerelease: false
|
64
|
-
version_requirements: !ruby/object:Gem::Requirement
|
65
|
-
requirements:
|
66
|
-
- - "~>"
|
67
|
-
- !ruby/object:Gem::Version
|
68
|
-
version: 2.12.1
|
69
|
-
- !ruby/object:Gem::Dependency
|
70
|
-
name: rspec-mocks
|
71
|
-
requirement: !ruby/object:Gem::Requirement
|
72
|
-
requirements:
|
73
|
-
- - "~>"
|
59
|
+
- - ">="
|
74
60
|
- !ruby/object:Gem::Version
|
75
|
-
version:
|
61
|
+
version: '0'
|
76
62
|
type: :development
|
77
63
|
prerelease: false
|
78
64
|
version_requirements: !ruby/object:Gem::Requirement
|
79
65
|
requirements:
|
80
|
-
- - "
|
66
|
+
- - ">="
|
81
67
|
- !ruby/object:Gem::Version
|
82
|
-
version:
|
68
|
+
version: '0'
|
83
69
|
description: Enables Vagrant to manage machines in EC2 and VPC.
|
84
70
|
email: mitchell@hashicorp.com
|
85
71
|
executables: []
|
@@ -98,7 +84,6 @@ files:
|
|
98
84
|
- example_box/metadata.json
|
99
85
|
- lib/vagrant-aws.rb
|
100
86
|
- lib/vagrant-aws/action.rb
|
101
|
-
- lib/vagrant-aws/action/.sync_folders.rb.swp
|
102
87
|
- lib/vagrant-aws/action/connect_aws.rb
|
103
88
|
- lib/vagrant-aws/action/elb_deregister_instance.rb
|
104
89
|
- lib/vagrant-aws/action/elb_register_instance.rb
|
@@ -107,12 +92,12 @@ files:
|
|
107
92
|
- lib/vagrant-aws/action/message_already_created.rb
|
108
93
|
- lib/vagrant-aws/action/message_not_created.rb
|
109
94
|
- lib/vagrant-aws/action/message_will_not_destroy.rb
|
95
|
+
- lib/vagrant-aws/action/package_instance.rb
|
110
96
|
- lib/vagrant-aws/action/read_ssh_info.rb
|
111
97
|
- lib/vagrant-aws/action/read_state.rb
|
112
98
|
- lib/vagrant-aws/action/run_instance.rb
|
113
99
|
- lib/vagrant-aws/action/start_instance.rb
|
114
100
|
- lib/vagrant-aws/action/stop_instance.rb
|
115
|
-
- lib/vagrant-aws/action/sync_folders.rb
|
116
101
|
- lib/vagrant-aws/action/terminate_instance.rb
|
117
102
|
- lib/vagrant-aws/action/timed_provision.rb
|
118
103
|
- lib/vagrant-aws/action/wait_for_state.rb
|
@@ -126,9 +111,9 @@ files:
|
|
126
111
|
- lib/vagrant-aws/version.rb
|
127
112
|
- locales/en.yml
|
128
113
|
- spec/spec_helper.rb
|
129
|
-
- spec/vagrant-aws/actions/.syncfolders_spec.rb.swp
|
130
|
-
- spec/vagrant-aws/actions/syncfolders_spec.rb
|
131
114
|
- spec/vagrant-aws/config_spec.rb
|
115
|
+
- templates/metadata.json.erb
|
116
|
+
- templates/vagrant-aws_package_Vagrantfile.erb
|
132
117
|
- vagrant-aws.gemspec
|
133
118
|
homepage: http://www.vagrantup.com
|
134
119
|
licenses:
|
@@ -150,7 +135,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
150
135
|
version: 1.3.6
|
151
136
|
requirements: []
|
152
137
|
rubyforge_project: vagrant-aws
|
153
|
-
rubygems_version: 2.
|
138
|
+
rubygems_version: 2.4.5
|
154
139
|
signing_key:
|
155
140
|
specification_version: 4
|
156
141
|
summary: Enables Vagrant to manage machines in EC2 and VPC.
|
@@ -1,130 +0,0 @@
|
|
1
|
-
require "log4r"
|
2
|
-
|
3
|
-
require "vagrant/util/subprocess"
|
4
|
-
|
5
|
-
require "vagrant/util/scoped_hash_override"
|
6
|
-
|
7
|
-
require "vagrant/util/which"
|
8
|
-
|
9
|
-
module VagrantPlugins
|
10
|
-
module AWS
|
11
|
-
module Action
|
12
|
-
# This middleware uses `rsync` to sync the folders over to the
|
13
|
-
# AWS instance.
|
14
|
-
class SyncFolders
|
15
|
-
include Vagrant::Util::ScopedHashOverride
|
16
|
-
|
17
|
-
def initialize(app, env)
|
18
|
-
@app = app
|
19
|
-
@logger = Log4r::Logger.new("vagrant_aws::action::sync_folders")
|
20
|
-
end
|
21
|
-
|
22
|
-
def call(env)
|
23
|
-
@app.call(env)
|
24
|
-
|
25
|
-
ssh_info = env[:machine].ssh_info
|
26
|
-
|
27
|
-
unless Vagrant::Util::Which.which('rsync')
|
28
|
-
env[:ui].warn(I18n.t('vagrant_aws.rsync_not_found_warning', :side => "host"))
|
29
|
-
return
|
30
|
-
end
|
31
|
-
|
32
|
-
if env[:machine].communicate.execute('which rsync', :error_check => false) != 0
|
33
|
-
env[:ui].warn(I18n.t('vagrant_aws.rsync_not_found_warning', :side => "guest"))
|
34
|
-
return
|
35
|
-
end
|
36
|
-
|
37
|
-
env[:machine].config.vm.synced_folders.each do |id, data|
|
38
|
-
data = scoped_hash_override(data, :aws)
|
39
|
-
|
40
|
-
# Ignore disabled shared folders
|
41
|
-
next if data[:disabled]
|
42
|
-
|
43
|
-
hostpath = File.expand_path(data[:hostpath], env[:root_path])
|
44
|
-
guestpath = data[:guestpath]
|
45
|
-
|
46
|
-
# Make sure there is a trailing slash on the host path to
|
47
|
-
# avoid creating an additional directory with rsync
|
48
|
-
hostpath = "#{hostpath}/" if hostpath !~ /\/$/
|
49
|
-
|
50
|
-
# on windows rsync.exe requires cygdrive-style paths
|
51
|
-
if Vagrant::Util::Platform.windows?
|
52
|
-
hostpath = hostpath.gsub(/^(\w):/) { "/cygdrive/#{$1}" }
|
53
|
-
end
|
54
|
-
|
55
|
-
env[:ui].info(I18n.t("vagrant_aws.rsync_folder",
|
56
|
-
:hostpath => hostpath,
|
57
|
-
:guestpath => guestpath))
|
58
|
-
|
59
|
-
# Create the host path if it doesn't exist and option flag is set
|
60
|
-
if data[:create]
|
61
|
-
begin
|
62
|
-
FileUtils::mkdir_p(hostpath)
|
63
|
-
rescue => err
|
64
|
-
raise Errors::MkdirError,
|
65
|
-
:hostpath => hostpath,
|
66
|
-
:err => err
|
67
|
-
end
|
68
|
-
end
|
69
|
-
|
70
|
-
# Create the guest path
|
71
|
-
env[:machine].communicate.sudo("mkdir -p '#{guestpath}'")
|
72
|
-
env[:machine].communicate.sudo(
|
73
|
-
"chown -R #{ssh_info[:username]} '#{guestpath}'")
|
74
|
-
|
75
|
-
#collect rsync excludes specified :rsync_excludes=>['path1',...] in synced_folder options
|
76
|
-
excludes = ['.vagrant/', 'Vagrantfile', *Array(data[:rsync_excludes])].uniq
|
77
|
-
|
78
|
-
ssh_options = ["StrictHostKeyChecking=no"]
|
79
|
-
# Use proxy command if it's set
|
80
|
-
if ssh_info[:proxy_command]
|
81
|
-
ssh_options.push("ProxyCommand #{ssh_info[:proxy_command]}")
|
82
|
-
end
|
83
|
-
|
84
|
-
# Rsync over to the guest path using the SSH info
|
85
|
-
command = [
|
86
|
-
"rsync", "--verbose", "--archive", "-z", "--delete",
|
87
|
-
*excludes.map{|e|['--exclude', e]}.flatten,
|
88
|
-
"-e", "ssh -p #{ssh_info[:port]} #{ssh_key_options(ssh_info)} " +
|
89
|
-
ssh_options_to_args(ssh_options).join(' '),
|
90
|
-
hostpath,
|
91
|
-
"#{ssh_info[:username]}@#{ssh_info[:host]}:#{guestpath}"]
|
92
|
-
|
93
|
-
# we need to fix permissions when using rsync.exe on windows, see
|
94
|
-
# http://stackoverflow.com/questions/5798807/rsync-permission-denied-created-directories-have-no-permissions
|
95
|
-
if Vagrant::Util::Platform.windows?
|
96
|
-
command.insert(1, "--chmod", "ugo=rwX")
|
97
|
-
end
|
98
|
-
|
99
|
-
r = Vagrant::Util::Subprocess.execute(*command)
|
100
|
-
if r.exit_code != 0
|
101
|
-
raise Errors::RsyncError,
|
102
|
-
:guestpath => guestpath,
|
103
|
-
:hostpath => hostpath,
|
104
|
-
:stderr => r.stderr
|
105
|
-
end
|
106
|
-
end
|
107
|
-
end
|
108
|
-
|
109
|
-
# Generate a ssh(1) command line list of options
|
110
|
-
#
|
111
|
-
# @param [Array] options An array of ssh options. E.g.
|
112
|
-
# `StrictHostKeyChecking=no` see ssh_config(5) for more
|
113
|
-
# @return [Array] Computed list of command line arguments
|
114
|
-
def ssh_options_to_args(options)
|
115
|
-
# Bail early if we get something that is not an array of options
|
116
|
-
return [] unless options
|
117
|
-
|
118
|
-
return options.map { |o| "-o '#{o}'" }
|
119
|
-
end
|
120
|
-
|
121
|
-
private
|
122
|
-
|
123
|
-
def ssh_key_options(ssh_info)
|
124
|
-
# Ensure that `private_key_path` is an Array (for Vagrant < 1.4)
|
125
|
-
Array(ssh_info[:private_key_path]).map { |path| "-i '#{path}' " }.join
|
126
|
-
end
|
127
|
-
end
|
128
|
-
end
|
129
|
-
end
|
130
|
-
end
|
@@ -1,28 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
require 'vagrant-aws/action/sync_folders'
|
3
|
-
|
4
|
-
describe VagrantPlugins::AWS::Action::SyncFolders do
|
5
|
-
let(:app) { nil }
|
6
|
-
let(:env) { {} }
|
7
|
-
subject(:action) { described_class.new(app, env) }
|
8
|
-
|
9
|
-
describe '#ssh_options_to_args' do
|
10
|
-
subject(:args) { action.ssh_options_to_args(options) }
|
11
|
-
|
12
|
-
context 'with no ssh options' do
|
13
|
-
let(:options) { [] }
|
14
|
-
|
15
|
-
it { should eql [] }
|
16
|
-
end
|
17
|
-
|
18
|
-
context 'with one option' do
|
19
|
-
let(:options) { ['StrictHostKeyChecking=no'] }
|
20
|
-
it { should eql ["-o 'StrictHostKeyChecking=no'"] }
|
21
|
-
end
|
22
|
-
|
23
|
-
context 'with multiple options' do
|
24
|
-
let(:options) { ['SHKC=no', 'Port=222'] }
|
25
|
-
it { should eql ["-o 'SHKC=no'", "-o 'Port=222'"] }
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|