vagrant-aws 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +5 -0
- data/Gemfile +4 -0
- data/README.md +65 -0
- data/Rakefile +10 -0
- data/lib/vagrant-aws.rb +14 -0
- data/lib/vagrant-aws/action/create.rb +56 -0
- data/lib/vagrant-aws/action/create_image.rb +106 -0
- data/lib/vagrant-aws/action/create_sshkey.rb +39 -0
- data/lib/vagrant-aws/action/deregister_image.rb +27 -0
- data/lib/vagrant-aws/action/populate_ssh.rb +41 -0
- data/lib/vagrant-aws/action/prepare_provisioners.rb +127 -0
- data/lib/vagrant-aws/action/resume.rb +20 -0
- data/lib/vagrant-aws/action/suspend.rb +20 -0
- data/lib/vagrant-aws/action/terminate.rb +21 -0
- data/lib/vagrant-aws/box.rb +20 -0
- data/lib/vagrant-aws/box_collection.rb +15 -0
- data/lib/vagrant-aws/command.rb +186 -0
- data/lib/vagrant-aws/config.rb +38 -0
- data/lib/vagrant-aws/environment.rb +79 -0
- data/lib/vagrant-aws/errors.rb +29 -0
- data/lib/vagrant-aws/middleware.rb +53 -0
- data/lib/vagrant-aws/system.rb +24 -0
- data/lib/vagrant-aws/version.rb +3 -0
- data/lib/vagrant-aws/vm.rb +94 -0
- data/lib/vagrant_init.rb +4 -0
- data/locales/en.yml +64 -0
- data/test/test_helper.rb +24 -0
- data/test/vagrant-aws/action/create_image_test.rb +63 -0
- data/test/vagrant-aws/action/create_ssh_key_test.rb +43 -0
- data/test/vagrant-aws/action/create_test.rb +65 -0
- data/test/vagrant-aws/action/terminate_test.rb +20 -0
- data/test/vagrant-aws/command_test.rb +21 -0
- data/test/vagrant-aws/config_test.rb +14 -0
- data/vagrant-aws.gemspec +29 -0
- metadata +165 -0
@@ -0,0 +1,24 @@
|
|
1
|
+
module Vagrant
|
2
|
+
module Systems
|
3
|
+
class Debian < Linux
|
4
|
+
def bootstrap_chef
|
5
|
+
vm.ssh.execute do |ssh|
|
6
|
+
commands = [
|
7
|
+
"apt-get -y --force-yes update",
|
8
|
+
"apt-get -y --force-yes install ruby ruby-dev libopenssl-ruby irb build-essential wget ssl-cert",
|
9
|
+
"cd /tmp && wget -nv http://production.cf.rubygems.org/rubygems/rubygems-1.7.2.tgz && tar zxf rubygems-1.7.2.tgz",
|
10
|
+
"cd rubygems-1.7.2 && ruby setup.rb --no-format-executable",
|
11
|
+
"gem install chef --no-ri --no-rdoc"
|
12
|
+
]
|
13
|
+
ssh.sudo!(commands) do |channel, type, data|
|
14
|
+
if type == :exit_status
|
15
|
+
ssh.check_exit_status(data, commands)
|
16
|
+
else
|
17
|
+
vm.env.ui.info("#{data}: #{type}")
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
require 'fog'
|
2
|
+
|
3
|
+
# Patch required by Vagrant::System
|
4
|
+
module Fog
|
5
|
+
module Compute
|
6
|
+
class AWS
|
7
|
+
class Server < Fog::Model
|
8
|
+
def running?
|
9
|
+
state == "running"
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
|
17
|
+
module VagrantAWS
|
18
|
+
|
19
|
+
class VM < Vagrant::VM
|
20
|
+
|
21
|
+
[:uuid, :package].each do |method|
|
22
|
+
undef_method(method)
|
23
|
+
end
|
24
|
+
|
25
|
+
class << self
|
26
|
+
def find(desc, env=nil, name=nil)
|
27
|
+
env.ui.info I18n.t("vagrant.plugins.aws.general.getting_status") if env
|
28
|
+
|
29
|
+
vm = Fog::Compute.new(:provider => 'AWS', :region => desc['region']).servers.get(desc['id'])
|
30
|
+
my_vm = new(:vm => vm, :env => env, :name => name)
|
31
|
+
|
32
|
+
# Recover key configuration values from data store not available from AWS directly
|
33
|
+
unless my_vm.env.nil?
|
34
|
+
my_vm.env.config.aws.region = desc['region']
|
35
|
+
end
|
36
|
+
|
37
|
+
my_vm
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
# Copied from Vagrant VM, but modified to generate a VagrantAWS::Environment
|
42
|
+
def initialize(opts=nil)
|
43
|
+
defaults = { :vm => nil, :env => nil, :name => nil }
|
44
|
+
|
45
|
+
opts = defaults.merge(opts || {})
|
46
|
+
|
47
|
+
@vm = opts[:vm]
|
48
|
+
@connection = @vm.connection if @vm # Initialize connection from intialized server
|
49
|
+
|
50
|
+
@name = opts[:name]
|
51
|
+
|
52
|
+
if !opts[:env].nil?
|
53
|
+
# We have an environment, so we create a new child environment
|
54
|
+
# specifically for this VM. This step will load any custom
|
55
|
+
# config and such.
|
56
|
+
@env = VagrantAWS::Environment.new({
|
57
|
+
:cwd => opts[:env].cwd,
|
58
|
+
:parent => opts[:env],
|
59
|
+
:vm => self
|
60
|
+
}).load!
|
61
|
+
|
62
|
+
# Load the associated system.
|
63
|
+
load_system!
|
64
|
+
end
|
65
|
+
|
66
|
+
@loaded_system_distro = false
|
67
|
+
end
|
68
|
+
|
69
|
+
def vm=(value)
|
70
|
+
@vm = value
|
71
|
+
env.local_data[:active] ||= {}
|
72
|
+
|
73
|
+
if value && value.id
|
74
|
+
env.local_data[:active][name.to_s] = {
|
75
|
+
'id' => value.id,
|
76
|
+
'region' => value.connection.instance_variable_get(:@region)
|
77
|
+
}
|
78
|
+
else
|
79
|
+
env.local_data[:active].delete(name.to_s)
|
80
|
+
end
|
81
|
+
|
82
|
+
# Commit the local data so that the next time vagrant is initialized,
|
83
|
+
# it realizes the VM exists
|
84
|
+
env.local_data.commit
|
85
|
+
end
|
86
|
+
|
87
|
+
def connection(region = nil)
|
88
|
+
@connection ||= Fog::Compute.new(
|
89
|
+
:provider => 'AWS',
|
90
|
+
:region => region || env.config.aws.region || nil
|
91
|
+
)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
data/lib/vagrant_init.rb
ADDED
data/locales/en.yml
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
en:
|
2
|
+
vagrant:
|
3
|
+
plugins:
|
4
|
+
aws:
|
5
|
+
general:
|
6
|
+
getting_status: "Getting latest environment status..."
|
7
|
+
errors:
|
8
|
+
not_yet_supported: This feature is not yet supported in Vagrant AWS.
|
9
|
+
key_name_not_specified: An AWS key name was not specified. Set `aws.key_name` in Vagrantfile.
|
10
|
+
private_key_file_not_specified: |-
|
11
|
+
Private key file was not specified. Set `aws.private_key_file` to
|
12
|
+
point to key file associated with the specified AWS key name.
|
13
|
+
ebs_device_required: |-
|
14
|
+
%{command} requires an EBS-backed instance. Please Amazon AWS documentation for
|
15
|
+
more information about EBS vs. instance store backed instances.
|
16
|
+
vm_create_failure: VM creation failed.
|
17
|
+
commands:
|
18
|
+
status:
|
19
|
+
running: |-
|
20
|
+
The VM is running. To stop this VM, you can run `vagrant aws suspend` to
|
21
|
+
stop but not destroy this VM (you only pay for the backing EBS volume,
|
22
|
+
not the hourly EC2 server cost) or `vagrant aws destroy` to destroy
|
23
|
+
the VM entirely.
|
24
|
+
stopping: |-
|
25
|
+
The VM is in the process of stopping (suspending). To resume this VM
|
26
|
+
after it has completely stopped, simply run `vagrant aws resume`.
|
27
|
+
stopped: To resume this VM, simply run `vagrant resume`.
|
28
|
+
pending: The VM is in the process of resuming.
|
29
|
+
not_created: |-
|
30
|
+
The environment has not yet been created. Run `vagrant aws resume` to
|
31
|
+
create the environment.
|
32
|
+
listing: |-
|
33
|
+
This environment represents multiple VMs. The VMs are all listed
|
34
|
+
above with their current state. For more information about a specific
|
35
|
+
VM, run `vagrant aws status NAME`.
|
36
|
+
actions:
|
37
|
+
create:
|
38
|
+
creating: "Creating VM ..."
|
39
|
+
created: |-
|
40
|
+
Created EC2 server %{id}. Waiting for server to become ready
|
41
|
+
(this may take a few minutes).
|
42
|
+
available: |-
|
43
|
+
Server available at %{dns}.
|
44
|
+
Waiting for SSH to become available. When ready run `vagrant aws ssh_config`
|
45
|
+
for more detailed connection information.
|
46
|
+
prepare_provisioners:
|
47
|
+
chef_not_detected: |-
|
48
|
+
%{binary} not detected. Bootstrapping %{binary} installation. This may
|
49
|
+
take a few minutes.
|
50
|
+
uploading_chef_resources: Uploading chef resources to VM.
|
51
|
+
create_image:
|
52
|
+
creating: |-
|
53
|
+
Creating AWS AMI. This make take a few minutes. The VM will not be available
|
54
|
+
during this period.
|
55
|
+
deregister_image:
|
56
|
+
deregistering:
|
57
|
+
Deregistering image %{image} with AWS.
|
58
|
+
create_ssh_key:
|
59
|
+
created: |-
|
60
|
+
No key pairs specified. Created AWS key pair named %{name}.
|
61
|
+
|
62
|
+
|
63
|
+
|
64
|
+
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require 'contest'
|
3
|
+
require 'mocha'
|
4
|
+
require 'vagrant-aws'
|
5
|
+
|
6
|
+
Fog.mock!
|
7
|
+
|
8
|
+
module Vagrant
|
9
|
+
module TestHelpers
|
10
|
+
|
11
|
+
# Creates and _loads_ a Vagrant environment at the given path.
|
12
|
+
# If no path is given, then a default {#vagrantfile} is used.
|
13
|
+
def vagrant_env(*args)
|
14
|
+
path = args.shift if Pathname === args.first
|
15
|
+
path ||= vagrantfile
|
16
|
+
VagrantAWS::Environment.new(:cwd => path).load!
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
class Test::Unit::TestCase
|
23
|
+
include Vagrant::TestHelpers
|
24
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class CreateImageTest < Test::Unit::TestCase
|
4
|
+
|
5
|
+
setup do
|
6
|
+
@app, @env = action_env
|
7
|
+
|
8
|
+
@env.env.vm = VagrantAWS::VM.new(:env => @env.env, :name => "default")
|
9
|
+
@middleware = VagrantAWS::Action::CreateImage.new(@app, @env)
|
10
|
+
|
11
|
+
@env["vm"].expects(:created?).returns(true)
|
12
|
+
|
13
|
+
@env["vm"].vm = @env["vm"].connection.servers.create
|
14
|
+
@env["vm"].vm.root_device_type = "ebs" # Fog mock instances are "instance-store" by default
|
15
|
+
|
16
|
+
@env["vm"].connection.data[:images] = { "notused" => { "imageId" => @env["vm"].vm.image_id }}
|
17
|
+
end
|
18
|
+
|
19
|
+
should "return error if instance not running" do
|
20
|
+
@env["vm"].vm.stubs(:running?).returns(false)
|
21
|
+
assert_raise(Vagrant::Errors::VMNotRunningError) do
|
22
|
+
@middleware.call(@env)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
context "instance running" do
|
27
|
+
setup do
|
28
|
+
@env["vm"].vm.stubs(:running?).returns(true)
|
29
|
+
end
|
30
|
+
|
31
|
+
should "not create image unless register specified" do
|
32
|
+
@env["vm"].connection.expects(:create_image).never
|
33
|
+
@middleware.call(@env)
|
34
|
+
end
|
35
|
+
|
36
|
+
should "create image if register specified" do
|
37
|
+
@env["vm"].connection.expects(:create_image => @env["vm"].connection.create_image(@env["vm"].vm.id, "test", "test"))
|
38
|
+
@env["image.register"] = true
|
39
|
+
@middleware.call(@env)
|
40
|
+
end
|
41
|
+
|
42
|
+
context "recovery" do
|
43
|
+
setup do
|
44
|
+
@internal_image = @env["vm"].connection.create_image(@env["vm"].vm.id, "test", "test")
|
45
|
+
@env["vm"].connection.stubs(:create_image).returns(@internal_image)
|
46
|
+
end
|
47
|
+
|
48
|
+
should "deregister if error during registration" do
|
49
|
+
@env["image.register"] = true
|
50
|
+
@middleware.call(@env)
|
51
|
+
@middleware.image.expects(:deregister).with(true)
|
52
|
+
@middleware.recover(@env)
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
|
57
|
+
should "call the next app" do
|
58
|
+
@app.expects(:call).once
|
59
|
+
@middleware.call(@env)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class CreateSSHKeyActionTest < Test::Unit::TestCase
|
4
|
+
setup do
|
5
|
+
@app, @env = action_env
|
6
|
+
|
7
|
+
@env.env.vm = VagrantAWS::VM.new(:env => @env.env, :name => "default")
|
8
|
+
@connection = @env["vm"].connection # We need to trigger the connection creation to load FOG models
|
9
|
+
|
10
|
+
@middleware = VagrantAWS::Action::CreateSSHKey.new(@app, @env)
|
11
|
+
|
12
|
+
@env["config"].aws.key_name = "default"
|
13
|
+
end
|
14
|
+
|
15
|
+
should "call the next app" do
|
16
|
+
@app.expects(:call).once
|
17
|
+
@middleware.call(@env)
|
18
|
+
end
|
19
|
+
|
20
|
+
should "not do anything if key name is provided" do
|
21
|
+
@env["vm"].connection.expects(:key_pairs).never
|
22
|
+
@middleware.call(@env)
|
23
|
+
end
|
24
|
+
|
25
|
+
context "no key specified" do
|
26
|
+
setup do
|
27
|
+
@env["config"].aws.key_name = nil
|
28
|
+
end
|
29
|
+
|
30
|
+
should "use pre-existing key pair if available" do
|
31
|
+
@env.env.expects(:ssh_keys).returns(["existing_key"])
|
32
|
+
@connection.data[:key_pairs] = { "notused" => { "keyName" => "existing_key"} }
|
33
|
+
@middleware.call(@env)
|
34
|
+
end
|
35
|
+
|
36
|
+
should "create key pair if none available" do
|
37
|
+
@env.env.expects(:ssh_keys).returns([])
|
38
|
+
File.stubs(:open).with(@env.env.ssh_keys_path.join("vagrantaws_#{Mac.addr.gsub(':','')}"), File::WRONLY|File::TRUNC|File::CREAT, 0600).returns(nil)
|
39
|
+
@middleware.call(@env)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class CreateActionTest < Test::Unit::TestCase
|
4
|
+
setup do
|
5
|
+
@app, @env = action_env
|
6
|
+
|
7
|
+
@env.env.vm = VagrantAWS::VM.new(:env => @env.env, :name => "default")
|
8
|
+
@connection = @env["vm"].connection # We need to trigger the connection creation to load FOG models
|
9
|
+
|
10
|
+
@middleware = VagrantAWS::Action::Create.new(@app, @env)
|
11
|
+
|
12
|
+
# Setup FOG mocks
|
13
|
+
@env["config"].aws.key_name = "default"
|
14
|
+
@connection.data[:key_pairs] = { "notused" => { "keyName" => "default"} }
|
15
|
+
@connection.data[:images] = { "default" => { "imageId" => @env["config"].aws.image, "imageState" => 'available' } }
|
16
|
+
end
|
17
|
+
|
18
|
+
should "call the next app" do
|
19
|
+
@app.expects(:call).once
|
20
|
+
@middleware.call(@env)
|
21
|
+
end
|
22
|
+
|
23
|
+
should "create running AWS server" do
|
24
|
+
@middleware.call(@env)
|
25
|
+
|
26
|
+
assert_not_nil @env["vm"].vm
|
27
|
+
assert_instance_of Fog::Compute::AWS::Server, @env["vm"].vm
|
28
|
+
assert @env["vm"].vm.running?
|
29
|
+
end
|
30
|
+
|
31
|
+
|
32
|
+
should "mark environment erroneous and not continue chain on failure" do
|
33
|
+
Fog::Compute::AWS::Servers.any_instance.stubs(:create).returns(nil)
|
34
|
+
@app.expects(:call).never
|
35
|
+
assert_raises(VagrantAWS::Errors::VMCreateFailure) {
|
36
|
+
@middleware.call(@env)
|
37
|
+
}
|
38
|
+
end
|
39
|
+
|
40
|
+
context "recovery" do
|
41
|
+
setup do
|
42
|
+
@env["vm"].stubs(:created?).returns(true)
|
43
|
+
end
|
44
|
+
|
45
|
+
should "not run the destroy action on recover if error is a VagrantError" do
|
46
|
+
@env["vagrant.error"] = Vagrant::Errors::VMImportFailure.new
|
47
|
+
@env.env.actions.expects(:run).never
|
48
|
+
@middleware.recover(@env)
|
49
|
+
end
|
50
|
+
|
51
|
+
should "not run the destroy action on recover if VM is not created" do
|
52
|
+
@env.env.vm.stubs(:created?).returns(false)
|
53
|
+
@env.env.actions.expects(:run).never
|
54
|
+
@middleware.recover(@env)
|
55
|
+
end
|
56
|
+
|
57
|
+
should "run the destroy action on recover" do
|
58
|
+
@env.env.vm.stubs(:created?).returns(true)
|
59
|
+
@env.env.actions.expects(:run).with(:aws_destroy).once
|
60
|
+
@middleware.recover(@env)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
|
3
|
+
class TerminateActionTest < Test::Unit::TestCase
|
4
|
+
setup do
|
5
|
+
@app, @env = action_env
|
6
|
+
@env.env.vm = VagrantAWS::VM.new(:env => @env.env, :name => "default")
|
7
|
+
@middleware = VagrantAWS::Action::Terminate.new(@app, @env)
|
8
|
+
|
9
|
+
@internal_vm = mock("internal")
|
10
|
+
@env.env.vm.stubs(:vm).returns(@internal_vm)
|
11
|
+
end
|
12
|
+
|
13
|
+
should "destroy VM and attached images" do
|
14
|
+
@internal_vm.expects(:destroy).once
|
15
|
+
@env["vm"].expects(:vm=).with(nil).once
|
16
|
+
@app.expects(:call).with(@env).once
|
17
|
+
@middleware.call(@env)
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class CommandTest < Test::Unit::TestCase
|
4
|
+
setup do
|
5
|
+
@env = vagrant_env
|
6
|
+
end
|
7
|
+
|
8
|
+
context "up" do
|
9
|
+
|
10
|
+
should "run aws_up" do
|
11
|
+
@env.config.aws.key_name = "default"
|
12
|
+
@env.vms.values.each do |vm|
|
13
|
+
vm.env.actions.expects(:run).with(:aws_up, {'provision.enabled' => true}).once
|
14
|
+
end
|
15
|
+
@env.cli("aws","up")
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
|
3
|
+
class ConfigTest < Test::Unit::TestCase
|
4
|
+
setup do
|
5
|
+
@config = VagrantAWS::Config.new
|
6
|
+
@errors = Vagrant::Config::ErrorRecorder.new
|
7
|
+
end
|
8
|
+
|
9
|
+
should "be valid by default" do
|
10
|
+
@config.validate(@errors)
|
11
|
+
assert @errors.errors.empty?
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|