vagrant-aws 0.5.0 → 0.6.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 +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
|
+
[](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]
|
@@ -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
|