vagrantup 0.3.4 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (125) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +2 -2
  3. data/README.md +2 -2
  4. data/Rakefile +1 -1
  5. data/VERSION +1 -1
  6. data/config/default.rb +13 -3
  7. data/lib/vagrant.rb +10 -13
  8. data/lib/vagrant/actions/base.rb +14 -2
  9. data/lib/vagrant/actions/box/download.rb +2 -7
  10. data/lib/vagrant/actions/box/verify.rb +1 -1
  11. data/lib/vagrant/actions/runner.rb +0 -1
  12. data/lib/vagrant/actions/vm/boot.rb +2 -6
  13. data/lib/vagrant/actions/vm/customize.rb +7 -5
  14. data/lib/vagrant/actions/vm/destroy.rb +4 -3
  15. data/lib/vagrant/actions/vm/down.rb +6 -3
  16. data/lib/vagrant/actions/vm/export.rb +2 -4
  17. data/lib/vagrant/actions/vm/forward_ports.rb +77 -16
  18. data/lib/vagrant/actions/vm/halt.rb +10 -2
  19. data/lib/vagrant/actions/vm/import.rb +2 -4
  20. data/lib/vagrant/actions/vm/move_hard_drive.rb +2 -2
  21. data/lib/vagrant/actions/vm/network.rb +120 -0
  22. data/lib/vagrant/actions/vm/package.rb +11 -7
  23. data/lib/vagrant/actions/vm/provision.rb +3 -3
  24. data/lib/vagrant/actions/vm/reload.rb +2 -9
  25. data/lib/vagrant/actions/vm/shared_folders.rb +19 -39
  26. data/lib/vagrant/actions/vm/start.rb +10 -2
  27. data/lib/vagrant/actions/vm/up.rb +5 -6
  28. data/lib/vagrant/active_list.rb +23 -13
  29. data/lib/vagrant/box.rb +2 -2
  30. data/lib/vagrant/busy.rb +3 -3
  31. data/lib/vagrant/command.rb +2 -2
  32. data/lib/vagrant/commands/base.rb +40 -20
  33. data/lib/vagrant/commands/destroy.rb +17 -3
  34. data/lib/vagrant/commands/halt.rb +23 -3
  35. data/lib/vagrant/commands/package.rb +54 -14
  36. data/lib/vagrant/commands/provision.rb +31 -0
  37. data/lib/vagrant/commands/reload.rb +16 -3
  38. data/lib/vagrant/commands/resume.rb +16 -3
  39. data/lib/vagrant/commands/ssh.rb +25 -3
  40. data/lib/vagrant/commands/ssh_config.rb +20 -5
  41. data/lib/vagrant/commands/status.rb +107 -40
  42. data/lib/vagrant/commands/suspend.rb +16 -3
  43. data/lib/vagrant/commands/up.rb +26 -7
  44. data/lib/vagrant/config.rb +82 -12
  45. data/lib/vagrant/downloaders/base.rb +8 -1
  46. data/lib/vagrant/downloaders/http.rb +31 -19
  47. data/lib/vagrant/environment.rb +146 -49
  48. data/lib/vagrant/provisioners/base.rb +19 -5
  49. data/lib/vagrant/provisioners/chef.rb +12 -4
  50. data/lib/vagrant/provisioners/chef_server.rb +13 -6
  51. data/lib/vagrant/provisioners/chef_solo.rb +7 -3
  52. data/lib/vagrant/resource_logger.rb +126 -0
  53. data/lib/vagrant/ssh.rb +109 -8
  54. data/lib/vagrant/systems/base.rb +70 -0
  55. data/lib/vagrant/systems/linux.rb +137 -0
  56. data/lib/vagrant/util.rb +1 -45
  57. data/lib/vagrant/util/error_helper.rb +13 -0
  58. data/lib/vagrant/util/glob_loader.rb +22 -0
  59. data/lib/vagrant/util/output_helper.rb +9 -0
  60. data/lib/vagrant/util/plain_logger.rb +12 -0
  61. data/lib/vagrant/util/platform.rb +7 -2
  62. data/lib/vagrant/util/template_renderer.rb +2 -2
  63. data/lib/vagrant/util/translator.rb +35 -0
  64. data/lib/vagrant/vm.rb +91 -10
  65. data/templates/crontab_entry.erb +1 -0
  66. data/templates/network_entry.erb +8 -0
  67. data/templates/ssh_config.erb +1 -0
  68. data/templates/{errors.yml → strings.yml} +111 -3
  69. data/templates/sync.erb +14 -0
  70. data/test/test_helper.rb +46 -3
  71. data/test/vagrant/actions/box/download_test.rb +0 -17
  72. data/test/vagrant/actions/vm/boot_test.rb +3 -10
  73. data/test/vagrant/actions/vm/customize_test.rb +6 -0
  74. data/test/vagrant/actions/vm/destroy_test.rb +6 -5
  75. data/test/vagrant/actions/vm/down_test.rb +5 -11
  76. data/test/vagrant/actions/vm/export_test.rb +1 -0
  77. data/test/vagrant/actions/vm/forward_ports_test.rb +92 -15
  78. data/test/vagrant/actions/vm/halt_test.rb +36 -4
  79. data/test/vagrant/actions/vm/import_test.rb +2 -0
  80. data/test/vagrant/actions/vm/network_test.rb +237 -0
  81. data/test/vagrant/actions/vm/package_test.rb +35 -5
  82. data/test/vagrant/actions/vm/provision_test.rb +3 -3
  83. data/test/vagrant/actions/vm/reload_test.rb +1 -1
  84. data/test/vagrant/actions/vm/shared_folders_test.rb +41 -74
  85. data/test/vagrant/actions/vm/start_test.rb +41 -3
  86. data/test/vagrant/actions/vm/up_test.rb +10 -21
  87. data/test/vagrant/active_list_test.rb +28 -43
  88. data/test/vagrant/commands/base_test.rb +25 -4
  89. data/test/vagrant/commands/destroy_test.rb +24 -12
  90. data/test/vagrant/commands/halt_test.rb +33 -11
  91. data/test/vagrant/commands/package_test.rb +77 -57
  92. data/test/vagrant/commands/provision_test.rb +50 -0
  93. data/test/vagrant/commands/reload_test.rb +27 -11
  94. data/test/vagrant/commands/resume_test.rb +25 -14
  95. data/test/vagrant/commands/ssh_config_test.rb +40 -17
  96. data/test/vagrant/commands/ssh_test.rb +52 -13
  97. data/test/vagrant/commands/status_test.rb +21 -1
  98. data/test/vagrant/commands/suspend_test.rb +25 -14
  99. data/test/vagrant/commands/up_test.rb +25 -19
  100. data/test/vagrant/config_test.rb +74 -18
  101. data/test/vagrant/downloaders/base_test.rb +2 -1
  102. data/test/vagrant/downloaders/http_test.rb +18 -8
  103. data/test/vagrant/environment_test.rb +245 -77
  104. data/test/vagrant/provisioners/base_test.rb +4 -4
  105. data/test/vagrant/provisioners/chef_server_test.rb +18 -7
  106. data/test/vagrant/provisioners/chef_solo_test.rb +17 -7
  107. data/test/vagrant/provisioners/chef_test.rb +22 -9
  108. data/test/vagrant/resource_logger_test.rb +144 -0
  109. data/test/vagrant/ssh_session_test.rb +46 -0
  110. data/test/vagrant/ssh_test.rb +42 -2
  111. data/test/vagrant/systems/linux_test.rb +174 -0
  112. data/test/vagrant/util/error_helper_test.rb +5 -0
  113. data/test/vagrant/util/output_helper_test.rb +5 -0
  114. data/test/vagrant/util/plain_logger_test.rb +17 -0
  115. data/test/vagrant/util/platform_test.rb +18 -0
  116. data/test/vagrant/util/{errors_test.rb → translator_test.rb} +25 -21
  117. data/test/vagrant/util_test.rb +12 -49
  118. data/test/vagrant/vm_test.rb +133 -11
  119. data/vagrant.gemspec +39 -15
  120. metadata +38 -14
  121. data/lib/vagrant/commands/down.rb +0 -16
  122. data/lib/vagrant/util/errors.rb +0 -36
  123. data/lib/vagrant/util/progress_meter.rb +0 -33
  124. data/test/vagrant/commands/down_test.rb +0 -17
  125. data/test/vagrant/util/progress_meter_test.rb +0 -33
@@ -6,10 +6,18 @@ module Vagrant
6
6
  raise ActionException.new(:vm_not_running) unless @runner.vm.running?
7
7
 
8
8
  @runner.invoke_around_callback(:halt) do
9
- logger.info "Forcing shutdown of VM..."
10
- @runner.vm.stop
9
+ @runner.system.halt if !options[:force]
10
+
11
+ if @runner.vm.state(true) != :powered_off
12
+ logger.info "Forcing shutdown of VM..."
13
+ @runner.vm.stop
14
+ end
11
15
  end
12
16
  end
17
+
18
+ def force?
19
+ !!options[:force]
20
+ end
13
21
  end
14
22
  end
15
23
  end
@@ -2,18 +2,16 @@ module Vagrant
2
2
  module Actions
3
3
  module VM
4
4
  class Import < Base
5
- include Util::ProgressMeter
6
-
7
5
  def execute!
8
6
  @runner.invoke_around_callback(:import) do
9
7
  Busy.busy do
10
8
  logger.info "Importing base VM (#{@runner.env.box.ovf_file})..."
11
9
  # Use the first argument passed to the action
12
10
  @runner.vm = VirtualBox::VM.import(@runner.env.box.ovf_file) do |progress|
13
- update_progress(progress.percent, 100, false)
11
+ logger.report_progress(progress.percent, 100, false)
14
12
  end
15
13
 
16
- complete_progress
14
+ logger.clear_progress
17
15
 
18
16
  raise ActionException.new(:virtualbox_import_failure) unless @runner.vm
19
17
  end
@@ -26,7 +26,7 @@ module Vagrant
26
26
 
27
27
  def clone_and_attach
28
28
  logger.info "Cloning current VM Disk to new location (#{new_image_path})..."
29
- hard_drive.image = hard_drive.image.clone(new_image_path, Vagrant.config.vm.disk_image_format, true)
29
+ hard_drive.image = hard_drive.image.clone(new_image_path, @runner.env.config.vm.disk_image_format, true)
30
30
 
31
31
  logger.info "Attaching new disk to VM ..."
32
32
  @runner.vm.save
@@ -43,7 +43,7 @@ module Vagrant
43
43
 
44
44
  # Returns the path to the new location for the hard drive
45
45
  def new_image_path
46
- File.join(Vagrant.config.vm.hd_location, hard_drive.image.filename)
46
+ File.join(@runner.env.config.vm.hd_location, hard_drive.image.filename)
47
47
  end
48
48
  end
49
49
  end
@@ -0,0 +1,120 @@
1
+ module Vagrant
2
+ module Actions
3
+ module VM
4
+ class Network < Base
5
+ def before_destroy
6
+ # We need to check if the host only network specified by any
7
+ # of the adapters would not have any more clients if it was
8
+ # destroyed. And if so, then destroy the host only network
9
+ # itself.
10
+ interfaces = runner.vm.network_adapters.collect do |adapter|
11
+ adapter.host_interface_object
12
+ end
13
+
14
+ interfaces.compact.uniq.each do |interface|
15
+ # Destroy the network interface if there is only one
16
+ # attached VM (which must be this VM)
17
+ if interface.attached_vms.length == 1
18
+ logger.info "Destroying unused network interface..."
19
+ interface.destroy
20
+ end
21
+ end
22
+ end
23
+
24
+ def before_boot
25
+ assign_network if enable_network?
26
+ end
27
+
28
+ def after_boot
29
+ if enable_network?
30
+ logger.info "Enabling host only network..."
31
+
32
+ runner.system.prepare_host_only_network
33
+
34
+ runner.env.config.vm.network_options.compact.each do |network_options|
35
+ runner.system.enable_host_only_network(network_options)
36
+ end
37
+ end
38
+ end
39
+
40
+ def enable_network?
41
+ !runner.env.config.vm.network_options.compact.empty?
42
+ end
43
+
44
+ # Enables and assigns the host only network to the proper
45
+ # adapter on the VM, and saves the adapter.
46
+ def assign_network
47
+ logger.info "Preparing host only network..."
48
+
49
+ runner.env.config.vm.network_options.compact.each do |network_options|
50
+ adapter = runner.vm.network_adapters[network_options[:adapter]]
51
+ adapter.enabled = true
52
+ adapter.attachment_type = :host_only
53
+ adapter.host_interface = network_name(network_options)
54
+ adapter.save
55
+ end
56
+ end
57
+
58
+ # Returns the name of the proper host only network, or creates
59
+ # it if it does not exist. Vagrant determines if the host only
60
+ # network exists by comparing the netmask and the IP.
61
+ def network_name(net_options)
62
+ # First try to find a matching network
63
+ interfaces = VirtualBox::Global.global.host.network_interfaces
64
+ interfaces.each do |ni|
65
+ if net_options[:name]
66
+ return ni.name if net_options[:name] == ni.name
67
+ else
68
+ return ni.name if matching_network?(ni, net_options)
69
+ end
70
+ end
71
+
72
+ raise ActionException.new(:network_not_found, :name => net_options[:name]) if net_options[:name]
73
+
74
+ # One doesn't exist, create it.
75
+ logger.info "Creating new host only network for environment..."
76
+
77
+ ni = interfaces.create
78
+ ni.enable_static(network_ip(net_options[:ip], net_options[:netmask]),
79
+ net_options[:netmask])
80
+ ni.name
81
+ end
82
+
83
+ # Tests if a network matches the given options by applying the
84
+ # netmask to the IP of the network and also to the IP of the
85
+ # virtual machine and see if they match.
86
+ def matching_network?(interface, net_options)
87
+ interface.network_mask == net_options[:netmask] &&
88
+ apply_netmask(interface.ip_address, interface.network_mask) ==
89
+ apply_netmask(net_options[:ip], net_options[:netmask])
90
+ end
91
+
92
+ # Applies a netmask to an IP and returns the corresponding
93
+ # parts.
94
+ def apply_netmask(ip, netmask)
95
+ ip = split_ip(ip)
96
+ netmask = split_ip(netmask)
97
+
98
+ ip.map do |part|
99
+ part & netmask.shift
100
+ end
101
+ end
102
+
103
+ # Splits an IP and converts each portion into an int.
104
+ def split_ip(ip)
105
+ ip.split(".").map do |i|
106
+ i.to_i
107
+ end
108
+ end
109
+
110
+ # Returns a "network IP" which is a "good choice" for the IP
111
+ # for the actual network based on the netmask.
112
+ def network_ip(ip, netmask)
113
+ parts = apply_netmask(ip, netmask)
114
+ parts[3] += 1;
115
+ parts.join(".")
116
+ end
117
+ end
118
+ end
119
+ end
120
+ end
@@ -2,20 +2,16 @@ module Vagrant
2
2
  module Actions
3
3
  module VM
4
4
  class Package < Base
5
- attr_accessor :out_path
6
- attr_accessor :include_files
7
5
  attr_reader :export_action
8
6
 
9
- def initialize(vm, out_path = nil, include_files = nil, *args)
7
+ def initialize(*args)
10
8
  super
11
- @out_path = out_path || "package"
12
- @include_files = include_files || []
13
9
  @temp_path = nil
14
10
  end
15
11
 
16
12
  def prepare
17
13
  # Verify the existance of all the additional files, if any
18
- @include_files.each do |file|
14
+ include_files.each do |file|
19
15
  raise ActionException.new(:package_include_file_doesnt_exist, :filename => file) unless File.exists?(file)
20
16
  end
21
17
 
@@ -28,6 +24,14 @@ module Vagrant
28
24
  compress
29
25
  end
30
26
 
27
+ def out_path
28
+ options[:output] || "package"
29
+ end
30
+
31
+ def include_files
32
+ options[:include] || []
33
+ end
34
+
31
35
  def tar_path
32
36
  File.join(FileUtils.pwd, "#{out_path}#{@runner.env.config.package.extension}")
33
37
  end
@@ -64,7 +68,7 @@ module Vagrant
64
68
 
65
69
  def compress
66
70
  logger.info "Packaging VM into #{tar_path}..."
67
- File.open(tar_path, File::CREAT | File::WRONLY, 0644) do |tar|
71
+ File.open(tar_path, Platform.tar_file_options) do |tar|
68
72
  Archive::Tar::Minitar::Output.open(tar) do |output|
69
73
  begin
70
74
  current_dir = FileUtils.pwd
@@ -11,7 +11,7 @@ module Vagrant
11
11
  end
12
12
 
13
13
  def prepare
14
- provisioner = Vagrant.config.vm.provisioner
14
+ provisioner = @runner.env.config.vm.provisioner
15
15
 
16
16
  if provisioner.nil?
17
17
  logger.info("Provisioning not enabled, ignoring this step")
@@ -19,7 +19,7 @@ module Vagrant
19
19
  end
20
20
 
21
21
  if provisioner.is_a?(Class)
22
- @provisioner = provisioner.new(@runner.env)
22
+ @provisioner = provisioner.new(@runner)
23
23
  raise ActionException.new(:provisioner_invalid_class) unless @provisioner.is_a?(Provisioners::Base)
24
24
  elsif provisioner.is_a?(Symbol)
25
25
  # We have a few hard coded provisioners for built-ins
@@ -30,7 +30,7 @@ module Vagrant
30
30
 
31
31
  provisioner_klass = mapping[provisioner]
32
32
  raise ActionException.new(:provisioner_unknown_type, :provisioner => provisioner.to_s) if provisioner_klass.nil?
33
- @provisioner = provisioner_klass.new(@runner.env)
33
+ @provisioner = provisioner_klass.new(@runner)
34
34
  end
35
35
 
36
36
  logger.info "Provisioning enabled with #{@provisioner.class}"
@@ -3,7 +3,7 @@ module Vagrant
3
3
  module VM
4
4
  class Reload < Base
5
5
  def prepare
6
- steps = [Customize, ForwardPorts, SharedFolders, Boot]
6
+ steps = [Customize, ForwardPorts, SharedFolders, Network, Boot]
7
7
  steps.unshift(Halt) if @runner.vm.running?
8
8
  steps << Provision if !@runner.env.config.vm.provisioner.nil?
9
9
 
@@ -11,14 +11,7 @@ module Vagrant
11
11
  @runner.add_action(action_klass)
12
12
  end
13
13
  end
14
-
15
- def after_halt
16
- # This sleep is here to allow the VM to clean itself up. There appears
17
- # nothing [obvious] in the VirtualBox API to automate this. For now, this
18
- # is an interim solution.
19
- sleep 1
20
- end
21
14
  end
22
15
  end
23
16
  end
24
- end
17
+ end
@@ -5,7 +5,7 @@ module Vagrant
5
5
  def shared_folders
6
6
  @runner.env.config.vm.shared_folders.inject([]) do |acc, data|
7
7
  name, value = data
8
- acc << [name, File.expand_path(value[:hostpath]), value[:guestpath]]
8
+ acc << [name, File.expand_path(value[:hostpath], @runner.env.root_path), value[:guestpath], value[:syncpath]].compact
9
9
  end
10
10
  end
11
11
 
@@ -17,24 +17,30 @@ module Vagrant
17
17
  def after_boot
18
18
  logger.info "Mounting shared folders..."
19
19
 
20
- @runner.env.ssh.execute do |ssh|
21
- shared_folders.each do |name, hostpath, guestpath|
22
- logger.info "-- #{name}: #{guestpath}"
23
- ssh.exec!("sudo mkdir -p #{guestpath}")
24
- mount_folder(ssh, name, guestpath)
25
- ssh.exec!("sudo chown #{Vagrant.config.ssh.username} #{guestpath}")
20
+ @runner.ssh.execute do |ssh|
21
+ @runner.system.prepare_sync(ssh) if @runner.env.config.vm.sync_required
22
+
23
+ shared_folders.each do |name, hostpath, guestpath, syncpath|
24
+ logger.info "-- #{name}: #{syncpath ? guestpath + " -sync-> " + syncpath : guestpath}"
25
+ @runner.system.mount_shared_folder(ssh, name, guestpath)
26
+ if syncpath
27
+ @runner.system.create_sync(ssh, :syncpath => syncpath, :guestpath => guestpath)
28
+ end
26
29
  end
27
30
  end
28
31
  end
29
32
 
30
33
  def clear_shared_folders
31
- logger.info "Clearing previously set shared folders..."
34
+ if runner.vm.shared_folders.length > 0
35
+ logger.info "Clearing previously set shared folders..."
32
36
 
33
- @runner.vm.shared_folders.each do |shared_folder|
34
- shared_folder.destroy
35
- end
37
+ folders = @runner.vm.shared_folders.dup
38
+ folders.each do |shared_folder|
39
+ shared_folder.destroy
40
+ end
36
41
 
37
- @runner.reload!
42
+ @runner.reload!
43
+ end
38
44
  end
39
45
 
40
46
  def create_metadata
@@ -49,33 +55,7 @@ module Vagrant
49
55
 
50
56
  @runner.vm.save
51
57
  end
52
-
53
- def mount_folder(ssh, name, guestpath, sleeptime=5)
54
- # Note: This method seems pretty OS-specific and could also use
55
- # some configuration options. For now its duct tape and "works"
56
- # but should be looked at in the future.
57
-
58
- # Determine the permission string to attach to the mount command
59
- perms = []
60
- perms << "uid=#{@runner.env.config.vm.shared_folder_uid}"
61
- perms << "gid=#{@runner.env.config.vm.shared_folder_gid}"
62
- perms = " -o #{perms.join(",")}" if !perms.empty?
63
-
64
- attempts = 0
65
- while true
66
- result = ssh.exec!("sudo mount -t vboxsf#{perms} #{name} #{guestpath}") do |ch, type, data|
67
- # net/ssh returns the value in ch[:result] (based on looking at source)
68
- ch[:result] = !!(type == :stderr && data =~ /No such device/i)
69
- end
70
-
71
- break unless result
72
-
73
- attempts += 1
74
- raise ActionException.new(:vm_mount_fail) if attempts >= 10
75
- sleep sleeptime
76
- end
77
- end
78
58
  end
79
59
  end
80
60
  end
81
- end
61
+ end
@@ -6,12 +6,20 @@ module Vagrant
6
6
  # Start is a "meta-action" so it really just queues up a bunch
7
7
  # of other actions in its place:
8
8
  steps = [Boot]
9
- steps.unshift([Customize, ForwardPorts, SharedFolders]) unless @runner.vm.saved?
9
+ if !@runner.vm || !@runner.vm.saved?
10
+ steps.unshift([Customize, ForwardPorts, SharedFolders, Network])
11
+ steps << Provision if provision?
12
+ end
10
13
 
11
14
  steps.flatten.each do |action_klass|
12
- @runner.add_action(action_klass)
15
+ @runner.add_action(action_klass, options)
13
16
  end
14
17
  end
18
+
19
+ def provision?
20
+ enabled = options[:provision].nil? ? true : options[:provision]
21
+ !@runner.env.config.vm.provisioner.nil? && enabled
22
+ end
15
23
  end
16
24
  end
17
25
  end
@@ -10,23 +10,22 @@ module Vagrant
10
10
 
11
11
  # Up is a "meta-action" so it really just queues up a bunch
12
12
  # of other actions in its place:
13
- steps = [Import, Customize, ForwardPorts, SharedFolders, Boot]
14
- steps << Provision if !@runner.env.config.vm.provisioner.nil?
13
+ steps = [Import, Start]
15
14
  steps.insert(0, MoveHardDrive) if @runner.env.config.vm.hd_location
16
15
 
17
16
  steps.each do |action_klass|
18
- @runner.add_action(action_klass)
17
+ @runner.add_action(action_klass, options)
19
18
  end
20
19
  end
21
20
 
22
21
  def after_import
23
- persist
22
+ update_dotfile
24
23
  setup_mac_address
25
24
  end
26
25
 
27
- def persist
26
+ def update_dotfile
28
27
  logger.info "Persisting the VM UUID (#{@runner.uuid})..."
29
- @runner.env.persist_vm
28
+ @runner.env.update_dotfile
30
29
  end
31
30
 
32
31
  def setup_mac_address
@@ -23,30 +23,40 @@ module Vagrant
23
23
  def list(reload=false)
24
24
  return @list unless @list.nil? || reload
25
25
 
26
- @list ||= []
26
+ @list ||= {}
27
27
  return @list unless File.file?(path)
28
28
  File.open(path, "r") do |f|
29
- @list = JSON.parse(f.read)
29
+ begin
30
+ @list = JSON.parse(f.read)
31
+ rescue Exception
32
+ @list = {}
33
+ end
34
+
35
+ # This forces earlier versions of Vagrant to use the new hash
36
+ # format. Clearing out the old data isn't a big deal since it
37
+ # was never used.
38
+ @list = {} unless @list.is_a?(Hash)
30
39
  end
31
40
 
32
41
  @list
33
42
  end
34
43
 
35
- # Returns an array of {Vagrant::VM} objects which are currently
36
- # active.
37
- def vms
38
- list.collect { |uuid| Vagrant::VM.find(uuid) }.compact
39
- end
40
-
41
44
  # Returns an array of UUIDs filtered so each is verified to exist.
42
- def filtered_list
43
- vms.collect { |vm| vm.uuid }
45
+ def filter_list
46
+ list.each do |uuid, data|
47
+ list.delete(uuid) unless Vagrant::VM.find(uuid, env)
48
+ end
49
+
50
+ list
44
51
  end
45
52
 
46
53
  # Adds a virtual environment to the list of active virtual machines
47
54
  def add(vm)
48
- list << vm.uuid
49
- list.uniq!
55
+ list[vm.uuid] = {
56
+ :path => env.root_path,
57
+ :created_at => Time.now.to_i
58
+ }
59
+
50
60
  save
51
61
  end
52
62
 
@@ -60,7 +70,7 @@ module Vagrant
60
70
  # Persists the list down to the JSON file.
61
71
  def save
62
72
  File.open(path, "w+") do |f|
63
- f.write(filtered_list.to_json)
73
+ f.write(filter_list.to_json)
64
74
  end
65
75
  end
66
76