vagrantup 0.1.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 +7 -0
- data/.gitignore +11 -0
- data/Gemfile +17 -0
- data/README.md +45 -0
- data/Rakefile +41 -0
- data/VERSION +1 -0
- data/bin/.gitignore +0 -0
- data/bin/vagrant +15 -0
- data/bin/vagrant-box +35 -0
- data/bin/vagrant-down +28 -0
- data/bin/vagrant-halt +29 -0
- data/bin/vagrant-init +28 -0
- data/bin/vagrant-package +30 -0
- data/bin/vagrant-reload +30 -0
- data/bin/vagrant-resume +28 -0
- data/bin/vagrant-ssh +28 -0
- data/bin/vagrant-suspend +28 -0
- data/bin/vagrant-up +30 -0
- data/config/default.rb +29 -0
- data/lib/vagrant.rb +14 -0
- data/lib/vagrant/actions/base.rb +93 -0
- data/lib/vagrant/actions/box/add.rb +22 -0
- data/lib/vagrant/actions/box/destroy.rb +14 -0
- data/lib/vagrant/actions/box/download.rb +63 -0
- data/lib/vagrant/actions/box/unpackage.rb +49 -0
- data/lib/vagrant/actions/runner.rb +128 -0
- data/lib/vagrant/actions/vm/destroy.rb +14 -0
- data/lib/vagrant/actions/vm/down.rb +12 -0
- data/lib/vagrant/actions/vm/export.rb +41 -0
- data/lib/vagrant/actions/vm/forward_ports.rb +32 -0
- data/lib/vagrant/actions/vm/halt.rb +14 -0
- data/lib/vagrant/actions/vm/import.rb +17 -0
- data/lib/vagrant/actions/vm/move_hard_drive.rb +53 -0
- data/lib/vagrant/actions/vm/package.rb +61 -0
- data/lib/vagrant/actions/vm/provision.rb +71 -0
- data/lib/vagrant/actions/vm/reload.rb +17 -0
- data/lib/vagrant/actions/vm/resume.rb +16 -0
- data/lib/vagrant/actions/vm/shared_folders.rb +69 -0
- data/lib/vagrant/actions/vm/start.rb +50 -0
- data/lib/vagrant/actions/vm/suspend.rb +16 -0
- data/lib/vagrant/actions/vm/up.rb +35 -0
- data/lib/vagrant/box.rb +129 -0
- data/lib/vagrant/busy.rb +73 -0
- data/lib/vagrant/commands.rb +174 -0
- data/lib/vagrant/config.rb +156 -0
- data/lib/vagrant/downloaders/base.rb +13 -0
- data/lib/vagrant/downloaders/file.rb +21 -0
- data/lib/vagrant/downloaders/http.rb +47 -0
- data/lib/vagrant/env.rb +140 -0
- data/lib/vagrant/ssh.rb +43 -0
- data/lib/vagrant/util.rb +45 -0
- data/lib/vagrant/vm.rb +57 -0
- data/script/vagrant-ssh-expect.sh +22 -0
- data/templates/Vagrantfile +8 -0
- data/test/test_helper.rb +91 -0
- data/test/vagrant/actions/base_test.rb +32 -0
- data/test/vagrant/actions/box/add_test.rb +37 -0
- data/test/vagrant/actions/box/destroy_test.rb +18 -0
- data/test/vagrant/actions/box/download_test.rb +118 -0
- data/test/vagrant/actions/box/unpackage_test.rb +101 -0
- data/test/vagrant/actions/runner_test.rb +236 -0
- data/test/vagrant/actions/vm/destroy_test.rb +24 -0
- data/test/vagrant/actions/vm/down_test.rb +32 -0
- data/test/vagrant/actions/vm/export_test.rb +88 -0
- data/test/vagrant/actions/vm/forward_ports_test.rb +50 -0
- data/test/vagrant/actions/vm/halt_test.rb +27 -0
- data/test/vagrant/actions/vm/import_test.rb +36 -0
- data/test/vagrant/actions/vm/move_hard_drive_test.rb +108 -0
- data/test/vagrant/actions/vm/package_test.rb +155 -0
- data/test/vagrant/actions/vm/provision_test.rb +103 -0
- data/test/vagrant/actions/vm/reload_test.rb +44 -0
- data/test/vagrant/actions/vm/resume_test.rb +27 -0
- data/test/vagrant/actions/vm/shared_folders_test.rb +117 -0
- data/test/vagrant/actions/vm/start_test.rb +55 -0
- data/test/vagrant/actions/vm/suspend_test.rb +27 -0
- data/test/vagrant/actions/vm/up_test.rb +76 -0
- data/test/vagrant/box_test.rb +92 -0
- data/test/vagrant/busy_test.rb +81 -0
- data/test/vagrant/commands_test.rb +252 -0
- data/test/vagrant/config_test.rb +123 -0
- data/test/vagrant/downloaders/base_test.rb +20 -0
- data/test/vagrant/downloaders/file_test.rb +32 -0
- data/test/vagrant/downloaders/http_test.rb +40 -0
- data/test/vagrant/env_test.rb +293 -0
- data/test/vagrant/ssh_test.rb +95 -0
- data/test/vagrant/util_test.rb +64 -0
- data/test/vagrant/vm_test.rb +96 -0
- metadata +263 -0
@@ -0,0 +1,41 @@
|
|
1
|
+
module Vagrant
|
2
|
+
module Actions
|
3
|
+
module VM
|
4
|
+
class Export < Base
|
5
|
+
attr_reader :temp_dir
|
6
|
+
|
7
|
+
def execute!
|
8
|
+
setup_temp_dir
|
9
|
+
export
|
10
|
+
end
|
11
|
+
|
12
|
+
def cleanup
|
13
|
+
if temp_dir
|
14
|
+
logger.info "Removing temporary export directory..."
|
15
|
+
FileUtils.rm_r(temp_dir)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def rescue(exception)
|
20
|
+
cleanup
|
21
|
+
end
|
22
|
+
|
23
|
+
def setup_temp_dir
|
24
|
+
@temp_dir = File.join(Env.tmp_path, Time.now.to_i.to_s)
|
25
|
+
|
26
|
+
logger.info "Creating temporary directory for export..."
|
27
|
+
FileUtils.mkpath(temp_dir)
|
28
|
+
end
|
29
|
+
|
30
|
+
def ovf_path
|
31
|
+
File.join(temp_dir, Vagrant.config.vm.box_ovf)
|
32
|
+
end
|
33
|
+
|
34
|
+
def export
|
35
|
+
logger.info "Exporting VM to #{ovf_path} ..."
|
36
|
+
@runner.vm.export(ovf_path, {}, true)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Vagrant
|
2
|
+
module Actions
|
3
|
+
module VM
|
4
|
+
class ForwardPorts < Base
|
5
|
+
def execute!
|
6
|
+
clear
|
7
|
+
forward_ports
|
8
|
+
end
|
9
|
+
|
10
|
+
def clear
|
11
|
+
logger.info "Deleting any previously set forwarded ports..."
|
12
|
+
@runner.vm.forwarded_ports.collect { |p| p.destroy(true) }
|
13
|
+
end
|
14
|
+
|
15
|
+
def forward_ports
|
16
|
+
logger.info "Forwarding ports..."
|
17
|
+
|
18
|
+
Vagrant.config.vm.forwarded_ports.each do |name, options|
|
19
|
+
logger.info "Forwarding \"#{name}\": #{options[:guestport]} => #{options[:hostport]}"
|
20
|
+
port = VirtualBox::ForwardedPort.new
|
21
|
+
port.name = name
|
22
|
+
port.hostport = options[:hostport]
|
23
|
+
port.guestport = options[:guestport]
|
24
|
+
@runner.vm.forwarded_ports << port
|
25
|
+
end
|
26
|
+
|
27
|
+
@runner.vm.save(true)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module Vagrant
|
2
|
+
module Actions
|
3
|
+
module VM
|
4
|
+
class Halt < Base
|
5
|
+
def execute!
|
6
|
+
raise ActionException.new("VM is not running! Nothing to shut down!") unless @runner.vm.running?
|
7
|
+
|
8
|
+
logger.info "Forcing shutdown of VM..."
|
9
|
+
@runner.vm.stop(true)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Vagrant
|
2
|
+
module Actions
|
3
|
+
module VM
|
4
|
+
class Import < Base
|
5
|
+
def execute!
|
6
|
+
@runner.invoke_around_callback(:import) do
|
7
|
+
Busy.busy do
|
8
|
+
logger.info "Importing base VM (#{Vagrant::Env.box.ovf_file})..."
|
9
|
+
# Use the first argument passed to the action
|
10
|
+
@runner.vm = VirtualBox::VM.import(Vagrant::Env.box.ovf_file)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module Vagrant
|
2
|
+
module Actions
|
3
|
+
module VM
|
4
|
+
class MoveHardDrive < Base
|
5
|
+
def execute!
|
6
|
+
unless @runner.powered_off?
|
7
|
+
error_and_exit(<<-error)
|
8
|
+
The virtual machine must be powered off to move its disk.
|
9
|
+
error
|
10
|
+
return
|
11
|
+
end
|
12
|
+
|
13
|
+
destroy_drive_after { clone_and_attach }
|
14
|
+
end
|
15
|
+
|
16
|
+
def hard_drive
|
17
|
+
@hard_drive ||= find_hard_drive
|
18
|
+
end
|
19
|
+
|
20
|
+
# TODO won't work if the first disk is not the boot disk or even if there are multiple disks
|
21
|
+
def find_hard_drive
|
22
|
+
@runner.vm.storage_controllers.each do |sc|
|
23
|
+
sc.devices.each do |d|
|
24
|
+
return d if d.image.is_a?(VirtualBox::HardDrive)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def clone_and_attach
|
30
|
+
logger.info "Cloning current VM Disk to new location (#{new_image_path})..."
|
31
|
+
hard_drive.image = hard_drive.image.clone(new_image_path, Vagrant.config.vm.disk_image_format, true)
|
32
|
+
|
33
|
+
logger.info "Attaching new disk to VM ..."
|
34
|
+
@runner.vm.save
|
35
|
+
end
|
36
|
+
|
37
|
+
def destroy_drive_after
|
38
|
+
old_image = hard_drive.image
|
39
|
+
|
40
|
+
yield
|
41
|
+
|
42
|
+
logger.info "Destroying old VM Disk (#{old_image.filename})..."
|
43
|
+
old_image.destroy(true)
|
44
|
+
end
|
45
|
+
|
46
|
+
# Returns the path to the new location for the hard drive
|
47
|
+
def new_image_path
|
48
|
+
File.join(Vagrant.config.vm.hd_location, hard_drive.image.filename)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
module Vagrant
|
2
|
+
module Actions
|
3
|
+
module VM
|
4
|
+
class Package < Base
|
5
|
+
attr_accessor :out_path
|
6
|
+
attr_accessor :include_files
|
7
|
+
attr_reader :export_action
|
8
|
+
|
9
|
+
def initialize(vm, out_path = nil, include_files = nil, *args)
|
10
|
+
super
|
11
|
+
@out_path = out_path || "package"
|
12
|
+
@include_files = include_files || []
|
13
|
+
@temp_path = nil
|
14
|
+
end
|
15
|
+
|
16
|
+
def prepare
|
17
|
+
# Verify the existance of all the additional files, if any
|
18
|
+
@include_files.each do |file|
|
19
|
+
raise ActionException.new("#{file} does not exist") unless File.exists?(file)
|
20
|
+
end
|
21
|
+
|
22
|
+
# Get the export action and store a reference to it
|
23
|
+
@export_action = @runner.find_action(Export)
|
24
|
+
raise ActionException.new("Package must be used in conjunction with export.") unless @export_action
|
25
|
+
end
|
26
|
+
|
27
|
+
def execute!
|
28
|
+
compress
|
29
|
+
end
|
30
|
+
|
31
|
+
def tar_path
|
32
|
+
File.join(FileUtils.pwd, "#{out_path}#{Vagrant.config.package.extension}")
|
33
|
+
end
|
34
|
+
|
35
|
+
def temp_path
|
36
|
+
export_action.temp_dir
|
37
|
+
end
|
38
|
+
|
39
|
+
def compress
|
40
|
+
logger.info "Packaging VM into #{tar_path} ..."
|
41
|
+
Tar.open(tar_path, File::CREAT | File::WRONLY, 0644, Tar::GNU) do |tar|
|
42
|
+
begin
|
43
|
+
current_dir = FileUtils.pwd
|
44
|
+
@include_files.each do |f|
|
45
|
+
logger.info "Packaging additional file: #{f}"
|
46
|
+
tar.append_file(f)
|
47
|
+
end
|
48
|
+
|
49
|
+
FileUtils.cd(temp_path)
|
50
|
+
|
51
|
+
# Append tree will append the entire directory tree unless a relative folder reference is used
|
52
|
+
tar.append_tree(".")
|
53
|
+
ensure
|
54
|
+
FileUtils.cd(current_dir)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
module Vagrant
|
2
|
+
module Actions
|
3
|
+
module VM
|
4
|
+
class Provision < Base
|
5
|
+
def execute!
|
6
|
+
chown_provisioning_folder
|
7
|
+
setup_json
|
8
|
+
setup_solo_config
|
9
|
+
run_chef_solo
|
10
|
+
end
|
11
|
+
|
12
|
+
def chown_provisioning_folder
|
13
|
+
logger.info "Setting permissions on provisioning folder..."
|
14
|
+
SSH.execute do |ssh|
|
15
|
+
ssh.exec!("sudo chown #{Vagrant.config.ssh.username} #{Vagrant.config.chef.provisioning_path}")
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def setup_json
|
20
|
+
logger.info "Generating JSON and uploading..."
|
21
|
+
|
22
|
+
# Set up initial configuration
|
23
|
+
data = {
|
24
|
+
:config => Vagrant.config,
|
25
|
+
:directory => Vagrant.config.vm.project_directory,
|
26
|
+
}
|
27
|
+
|
28
|
+
# And wrap it under the "vagrant" namespace
|
29
|
+
data = { :vagrant => data }
|
30
|
+
|
31
|
+
# Merge with the "extra data" which isn't put under the
|
32
|
+
# vagrant namespace by default
|
33
|
+
data.merge!(Vagrant.config.chef.json)
|
34
|
+
|
35
|
+
json = data.to_json
|
36
|
+
|
37
|
+
SSH.upload!(StringIO.new(json), File.join(Vagrant.config.chef.provisioning_path, "dna.json"))
|
38
|
+
end
|
39
|
+
|
40
|
+
def setup_solo_config
|
41
|
+
solo_file = <<-solo
|
42
|
+
file_cache_path "#{Vagrant.config.chef.provisioning_path}"
|
43
|
+
cookbook_path "#{cookbooks_path}"
|
44
|
+
solo
|
45
|
+
|
46
|
+
logger.info "Uploading chef-solo configuration script..."
|
47
|
+
SSH.upload!(StringIO.new(solo_file), File.join(Vagrant.config.chef.provisioning_path, "solo.rb"))
|
48
|
+
end
|
49
|
+
|
50
|
+
def run_chef_solo
|
51
|
+
logger.info "Running chef recipes..."
|
52
|
+
SSH.execute do |ssh|
|
53
|
+
ssh.exec!("cd #{Vagrant.config.chef.provisioning_path} && sudo chef-solo -c solo.rb -j dna.json") do |channel, data, stream|
|
54
|
+
# TODO: Very verbose. It would be easier to save the data and only show it during
|
55
|
+
# an error, or when verbosity level is set high
|
56
|
+
logger.info("#{stream}: #{data}")
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def cookbooks_path
|
62
|
+
File.join(Vagrant.config.chef.provisioning_path, "cookbooks")
|
63
|
+
end
|
64
|
+
|
65
|
+
def collect_shared_folders
|
66
|
+
["vagrant-provisioning", File.expand_path(Vagrant.config.chef.cookbooks_path, Env.root_path), cookbooks_path]
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Vagrant
|
2
|
+
module Actions
|
3
|
+
module VM
|
4
|
+
class Reload < Base
|
5
|
+
def prepare
|
6
|
+
steps = [ForwardPorts, SharedFolders, Start]
|
7
|
+
steps.unshift(Halt) if @runner.vm.running?
|
8
|
+
steps << Provision if Vagrant.config.chef.enabled
|
9
|
+
|
10
|
+
steps.each do |action_klass|
|
11
|
+
@runner.add_action(action_klass)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Vagrant
|
2
|
+
module Actions
|
3
|
+
module VM
|
4
|
+
class Resume < Base
|
5
|
+
def execute!
|
6
|
+
if !@runner.vm.saved?
|
7
|
+
raise ActionException.new("The vagrant virtual environment you are trying to resume is not in a suspended state.")
|
8
|
+
end
|
9
|
+
|
10
|
+
logger.info "Resuming suspended VM..."
|
11
|
+
@runner.start
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
module Vagrant
|
2
|
+
module Actions
|
3
|
+
module VM
|
4
|
+
class SharedFolders < Base
|
5
|
+
def shared_folders
|
6
|
+
shared_folders = @runner.invoke_callback(:collect_shared_folders)
|
7
|
+
|
8
|
+
# Basic filtering of shared folders. Basically only verifies that
|
9
|
+
# the result is an array of 3 elements. In the future this should
|
10
|
+
# also verify that the host path exists, the name is valid,
|
11
|
+
# and that the guest path is valid.
|
12
|
+
shared_folders.collect do |folder|
|
13
|
+
if folder.is_a?(Array) && folder.length == 3
|
14
|
+
folder
|
15
|
+
else
|
16
|
+
nil
|
17
|
+
end
|
18
|
+
end.compact
|
19
|
+
end
|
20
|
+
|
21
|
+
def before_boot
|
22
|
+
logger.info "Creating shared folders metadata..."
|
23
|
+
|
24
|
+
shared_folders.each do |name, hostpath, guestpath|
|
25
|
+
folder = VirtualBox::SharedFolder.new
|
26
|
+
folder.name = name
|
27
|
+
folder.hostpath = hostpath
|
28
|
+
@runner.vm.shared_folders << folder
|
29
|
+
end
|
30
|
+
|
31
|
+
@runner.vm.save(true)
|
32
|
+
end
|
33
|
+
|
34
|
+
def after_boot
|
35
|
+
logger.info "Mounting shared folders..."
|
36
|
+
|
37
|
+
Vagrant::SSH.execute do |ssh|
|
38
|
+
shared_folders.each do |name, hostpath, guestpath|
|
39
|
+
logger.info "-- #{name}: #{guestpath}"
|
40
|
+
ssh.exec!("sudo mkdir -p #{guestpath}")
|
41
|
+
mount_folder(ssh, name, guestpath)
|
42
|
+
ssh.exec!("sudo chown #{Vagrant.config.ssh.username} #{guestpath}")
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def mount_folder(ssh, name, guestpath, sleeptime=5)
|
48
|
+
# Note: This method seems pretty OS-specific and could also use
|
49
|
+
# some configuration options. For now its duct tape and "works"
|
50
|
+
# but should be looked at in the future.
|
51
|
+
attempts = 0
|
52
|
+
|
53
|
+
while true
|
54
|
+
result = ssh.exec!("sudo mount -t vboxsf #{name} #{guestpath}") do |ch, type, data|
|
55
|
+
# net/ssh returns the value in ch[:result] (based on looking at source)
|
56
|
+
ch[:result] = !!(type == :stderr && data =~ /No such device/i)
|
57
|
+
end
|
58
|
+
|
59
|
+
break unless result
|
60
|
+
|
61
|
+
attempts += 1
|
62
|
+
raise ActionException.new("Failed to mount shared folders. vboxsf was not available.") if attempts >= 10
|
63
|
+
sleep sleeptime
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
module Vagrant
|
2
|
+
module Actions
|
3
|
+
module VM
|
4
|
+
class Start < Base
|
5
|
+
def execute!
|
6
|
+
@runner.invoke_around_callback(:boot) do
|
7
|
+
# Startup the VM
|
8
|
+
boot
|
9
|
+
|
10
|
+
# Wait for it to complete booting, or error if we could
|
11
|
+
# never detect it booted up successfully
|
12
|
+
if !wait_for_boot
|
13
|
+
error_and_exit(<<-error)
|
14
|
+
Failed to connect to VM! Failed to boot?
|
15
|
+
error
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def collect_shared_folders
|
21
|
+
# The root shared folder for the project
|
22
|
+
["vagrant-root", Env.root_path, Vagrant.config.vm.project_directory]
|
23
|
+
end
|
24
|
+
|
25
|
+
def boot
|
26
|
+
logger.info "Booting VM..."
|
27
|
+
@runner.vm.start(:headless, true)
|
28
|
+
end
|
29
|
+
|
30
|
+
def wait_for_boot(sleeptime=5)
|
31
|
+
logger.info "Waiting for VM to boot..."
|
32
|
+
|
33
|
+
Vagrant.config[:ssh][:max_tries].to_i.times do |i|
|
34
|
+
logger.info "Trying to connect (attempt ##{i+1} of #{Vagrant.config[:ssh][:max_tries]})..."
|
35
|
+
|
36
|
+
if Vagrant::SSH.up?
|
37
|
+
logger.info "VM booted and ready for use!"
|
38
|
+
return true
|
39
|
+
end
|
40
|
+
|
41
|
+
sleep sleeptime
|
42
|
+
end
|
43
|
+
|
44
|
+
logger.info "Failed to connect to VM! Failed to boot?"
|
45
|
+
false
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|