vagrant 0.3.4 → 0.4.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.
Files changed (124) hide show
  1. data/Gemfile +2 -2
  2. data/README.md +2 -2
  3. data/Rakefile +1 -1
  4. data/VERSION +1 -1
  5. data/config/default.rb +13 -3
  6. data/lib/vagrant.rb +10 -13
  7. data/lib/vagrant/actions/base.rb +14 -2
  8. data/lib/vagrant/actions/box/download.rb +2 -7
  9. data/lib/vagrant/actions/box/verify.rb +1 -1
  10. data/lib/vagrant/actions/runner.rb +0 -1
  11. data/lib/vagrant/actions/vm/boot.rb +2 -6
  12. data/lib/vagrant/actions/vm/customize.rb +7 -5
  13. data/lib/vagrant/actions/vm/destroy.rb +4 -3
  14. data/lib/vagrant/actions/vm/down.rb +6 -3
  15. data/lib/vagrant/actions/vm/export.rb +2 -4
  16. data/lib/vagrant/actions/vm/forward_ports.rb +77 -16
  17. data/lib/vagrant/actions/vm/halt.rb +10 -2
  18. data/lib/vagrant/actions/vm/import.rb +2 -4
  19. data/lib/vagrant/actions/vm/move_hard_drive.rb +2 -2
  20. data/lib/vagrant/actions/vm/network.rb +120 -0
  21. data/lib/vagrant/actions/vm/package.rb +11 -7
  22. data/lib/vagrant/actions/vm/provision.rb +3 -3
  23. data/lib/vagrant/actions/vm/reload.rb +2 -9
  24. data/lib/vagrant/actions/vm/shared_folders.rb +19 -39
  25. data/lib/vagrant/actions/vm/start.rb +10 -2
  26. data/lib/vagrant/actions/vm/up.rb +5 -6
  27. data/lib/vagrant/active_list.rb +23 -13
  28. data/lib/vagrant/box.rb +2 -2
  29. data/lib/vagrant/busy.rb +3 -3
  30. data/lib/vagrant/command.rb +2 -2
  31. data/lib/vagrant/commands/base.rb +40 -20
  32. data/lib/vagrant/commands/destroy.rb +17 -3
  33. data/lib/vagrant/commands/halt.rb +23 -3
  34. data/lib/vagrant/commands/package.rb +54 -14
  35. data/lib/vagrant/commands/provision.rb +31 -0
  36. data/lib/vagrant/commands/reload.rb +16 -3
  37. data/lib/vagrant/commands/resume.rb +16 -3
  38. data/lib/vagrant/commands/ssh.rb +25 -3
  39. data/lib/vagrant/commands/ssh_config.rb +20 -5
  40. data/lib/vagrant/commands/status.rb +107 -40
  41. data/lib/vagrant/commands/suspend.rb +16 -3
  42. data/lib/vagrant/commands/up.rb +26 -7
  43. data/lib/vagrant/config.rb +82 -12
  44. data/lib/vagrant/downloaders/base.rb +8 -1
  45. data/lib/vagrant/downloaders/http.rb +31 -19
  46. data/lib/vagrant/environment.rb +146 -49
  47. data/lib/vagrant/provisioners/base.rb +19 -5
  48. data/lib/vagrant/provisioners/chef.rb +12 -4
  49. data/lib/vagrant/provisioners/chef_server.rb +13 -6
  50. data/lib/vagrant/provisioners/chef_solo.rb +7 -3
  51. data/lib/vagrant/resource_logger.rb +126 -0
  52. data/lib/vagrant/ssh.rb +109 -8
  53. data/lib/vagrant/systems/base.rb +70 -0
  54. data/lib/vagrant/systems/linux.rb +137 -0
  55. data/lib/vagrant/util.rb +1 -45
  56. data/lib/vagrant/util/error_helper.rb +13 -0
  57. data/lib/vagrant/util/glob_loader.rb +22 -0
  58. data/lib/vagrant/util/output_helper.rb +9 -0
  59. data/lib/vagrant/util/plain_logger.rb +12 -0
  60. data/lib/vagrant/util/platform.rb +7 -2
  61. data/lib/vagrant/util/template_renderer.rb +2 -2
  62. data/lib/vagrant/util/translator.rb +35 -0
  63. data/lib/vagrant/vm.rb +91 -10
  64. data/templates/crontab_entry.erb +1 -0
  65. data/templates/network_entry.erb +8 -0
  66. data/templates/ssh_config.erb +1 -0
  67. data/templates/{errors.yml → strings.yml} +111 -3
  68. data/templates/sync.erb +14 -0
  69. data/test/test_helper.rb +46 -3
  70. data/test/vagrant/actions/box/download_test.rb +0 -17
  71. data/test/vagrant/actions/vm/boot_test.rb +3 -10
  72. data/test/vagrant/actions/vm/customize_test.rb +6 -0
  73. data/test/vagrant/actions/vm/destroy_test.rb +6 -5
  74. data/test/vagrant/actions/vm/down_test.rb +5 -11
  75. data/test/vagrant/actions/vm/export_test.rb +1 -0
  76. data/test/vagrant/actions/vm/forward_ports_test.rb +92 -15
  77. data/test/vagrant/actions/vm/halt_test.rb +36 -4
  78. data/test/vagrant/actions/vm/import_test.rb +2 -0
  79. data/test/vagrant/actions/vm/network_test.rb +237 -0
  80. data/test/vagrant/actions/vm/package_test.rb +35 -5
  81. data/test/vagrant/actions/vm/provision_test.rb +3 -3
  82. data/test/vagrant/actions/vm/reload_test.rb +1 -1
  83. data/test/vagrant/actions/vm/shared_folders_test.rb +41 -74
  84. data/test/vagrant/actions/vm/start_test.rb +41 -3
  85. data/test/vagrant/actions/vm/up_test.rb +10 -21
  86. data/test/vagrant/active_list_test.rb +28 -43
  87. data/test/vagrant/commands/base_test.rb +25 -4
  88. data/test/vagrant/commands/destroy_test.rb +24 -12
  89. data/test/vagrant/commands/halt_test.rb +33 -11
  90. data/test/vagrant/commands/package_test.rb +77 -57
  91. data/test/vagrant/commands/provision_test.rb +50 -0
  92. data/test/vagrant/commands/reload_test.rb +27 -11
  93. data/test/vagrant/commands/resume_test.rb +25 -14
  94. data/test/vagrant/commands/ssh_config_test.rb +40 -17
  95. data/test/vagrant/commands/ssh_test.rb +52 -13
  96. data/test/vagrant/commands/status_test.rb +21 -1
  97. data/test/vagrant/commands/suspend_test.rb +25 -14
  98. data/test/vagrant/commands/up_test.rb +25 -19
  99. data/test/vagrant/config_test.rb +74 -18
  100. data/test/vagrant/downloaders/base_test.rb +2 -1
  101. data/test/vagrant/downloaders/http_test.rb +18 -8
  102. data/test/vagrant/environment_test.rb +245 -77
  103. data/test/vagrant/provisioners/base_test.rb +4 -4
  104. data/test/vagrant/provisioners/chef_server_test.rb +18 -7
  105. data/test/vagrant/provisioners/chef_solo_test.rb +17 -7
  106. data/test/vagrant/provisioners/chef_test.rb +22 -9
  107. data/test/vagrant/resource_logger_test.rb +144 -0
  108. data/test/vagrant/ssh_session_test.rb +46 -0
  109. data/test/vagrant/ssh_test.rb +42 -2
  110. data/test/vagrant/systems/linux_test.rb +174 -0
  111. data/test/vagrant/util/error_helper_test.rb +5 -0
  112. data/test/vagrant/util/output_helper_test.rb +5 -0
  113. data/test/vagrant/util/plain_logger_test.rb +17 -0
  114. data/test/vagrant/util/platform_test.rb +18 -0
  115. data/test/vagrant/util/{errors_test.rb → translator_test.rb} +25 -21
  116. data/test/vagrant/util_test.rb +12 -49
  117. data/test/vagrant/vm_test.rb +133 -11
  118. data/vagrant.gemspec +39 -15
  119. metadata +64 -40
  120. data/lib/vagrant/commands/down.rb +0 -16
  121. data/lib/vagrant/util/errors.rb +0 -36
  122. data/lib/vagrant/util/progress_meter.rb +0 -33
  123. data/test/vagrant/commands/down_test.rb +0 -17
  124. data/test/vagrant/util/progress_meter_test.rb +0 -33
@@ -9,12 +9,27 @@ module Vagrant
9
9
  def execute(args=[])
10
10
  env.require_root_path
11
11
 
12
- parse_options(args)
12
+ args = parse_options(args)
13
+ show_single(args[0])
14
+ end
15
+
16
+ def show_single(name)
17
+ if name.nil? && env.multivm?
18
+ error_and_exit(:ssh_config_multivm)
19
+ return # for tests
20
+ end
21
+
22
+ vm = name.nil? ? env.vms.values.first : env.vms[name.to_sym]
23
+ if vm.nil?
24
+ error_and_exit(:unknown_vm, :vm => name)
25
+ return # for tests
26
+ end
27
+
13
28
  puts TemplateRenderer.render("ssh_config", {
14
29
  :host_key => options[:host] || "vagrant",
15
- :ssh_user => env.config.ssh.username,
16
- :ssh_port => env.ssh.port,
17
- :private_key_path => env.config.ssh.private_key_path
30
+ :ssh_user => vm.env.config.ssh.username,
31
+ :ssh_port => vm.ssh.port,
32
+ :private_key_path => vm.env.config.ssh.private_key_path
18
33
  })
19
34
  end
20
35
 
@@ -27,4 +42,4 @@ module Vagrant
27
42
  end
28
43
  end
29
44
  end
30
- end
45
+ end
@@ -5,54 +5,121 @@ module Vagrant
5
5
  # and if its running, suspended, etc.
6
6
  class Status < Base
7
7
  Base.subcommand "status", self
8
- description "Shows the status of the current environment."
8
+ description "Shows the status of the Vagrant environment."
9
9
 
10
10
  def execute(args=[])
11
- wrap_output do
12
- if !env.root_path
13
- puts <<-msg
14
- No vagrant environment detected. Run `vagrant init` to setup a Vagrantfile
15
- in the current directory to get started with Vagrant.
16
- msg
17
- elsif !env.vm
18
- puts <<-msg
19
- The environment has not yet been created. Run `vagrant up` to create the
20
- environment.
21
- msg
11
+ args = parse_options(args)
12
+ if args.length > 1
13
+ # There should never be more than 1 arg
14
+ show_help
15
+ return
16
+ end
17
+
18
+ if !options[:global]
19
+ show_local_status(*args)
20
+ else
21
+ show_global_status
22
+ end
23
+ end
24
+
25
+ # Shows the status of the CURRENT environment (the current working
26
+ # directory). If a specific VM was given, it will print out
27
+ # detailed information regarding that VM. If no single VM was
28
+ # specified and it is a multi-VM environment, it will simply
29
+ # show a listing of all the VMs and their short one word
30
+ # statuses.
31
+ def show_local_status(vm=nil)
32
+ if !env.root_path
33
+ wrap_output { puts Translator.t(:status_no_environment) }
34
+ return
35
+ end
36
+
37
+ if vm.nil?
38
+ if env.multivm?
39
+ # No specific VM was specified in a multi-vm environment,
40
+ # so show short info for each VM
41
+ show_list
42
+ return
22
43
  else
23
- additional_msg = ""
24
- if env.vm.vm.running?
25
- additional_msg = <<-msg
26
- To stop this VM, you can run `vagrant halt` to shut it down forcefully,
27
- or you can run `vagrant suspend` to simply suspend the virtual machine.
28
- In either case, to restart it again, simply run a `vagrant up`.
29
- msg
30
- elsif env.vm.vm.saved?
31
- additional_msg = <<-msg
32
- To resume this VM, simply run `vagrant up`.
33
- msg
34
- elsif env.vm.vm.powered_off?
35
- additional_msg = <<-msg
36
- To restart this VM, simply run `vagrant up`.
37
- msg
38
- end
39
-
40
- if !additional_msg.empty?
41
- additional_msg.chomp!
42
- additional_msg = "\n\n#{additional_msg}"
43
- end
44
-
45
- puts <<-msg
46
- The environment has been created. The status of the current environment's
47
- virtual machine is: "#{env.vm.vm.state}."#{additional_msg}
48
- msg
44
+ # Set the VM to just be the root VM
45
+ vm = env.vms.values.first
46
+ end
47
+ else
48
+ # Try to get the vm based on the name. If the specified VM
49
+ # doesn't exist, then error saying so
50
+ vm = env.vms[vm.to_sym] || error_and_exit(:unknown_vm, :vm => vm)
51
+ end
52
+
53
+ show_single(vm)
54
+ end
55
+
56
+ # Lists the available VMs and brief statuses about each.
57
+ def show_list
58
+ wrap_output do
59
+ puts Translator.t(:status_listing)
60
+ puts ""
61
+
62
+ env.vms.each do |name, vm|
63
+ state = vm.created? ? vm.vm.state : "not created"
64
+ puts "#{name.to_s.ljust(30)}#{state}"
49
65
  end
50
66
  end
51
67
  end
52
68
 
69
+ # Shows a paragraph of information based on the current state of
70
+ # a single, specified VM.
71
+ def show_single(vm)
72
+ string_key = nil
73
+
74
+ if !vm.created?
75
+ string_key = :status_not_created
76
+ else
77
+ additional_key = nil
78
+ if vm.vm.running?
79
+ additional_key = :status_created_running
80
+ elsif vm.vm.saved?
81
+ additional_key = :status_created_saved
82
+ elsif vm.vm.powered_off?
83
+ additional_key = :status_created_powered_off
84
+ end
85
+
86
+ string_key = [:status_created, {
87
+ :vm_state => vm.vm.state,
88
+ :additional_message => additional_key ? Translator.t(additional_key) : ""
89
+ }]
90
+ end
91
+
92
+ wrap_output { puts Translator.t(*string_key) }
93
+ end
94
+
95
+ # Shows the status of the GLOBAL Vagrant environment. This prints out
96
+ # a listing of the virtual machines which Vagrant manages (running or
97
+ # not).
98
+ def show_global_status
99
+ entries = []
100
+
101
+ env.active_list.list.each do |uuid, data|
102
+ vm = Vagrant::VM.find(uuid, env)
103
+ entries << Translator.t(:status_global_entry, {
104
+ :vm => vm,
105
+ :data => data
106
+ })
107
+ end
108
+
109
+ wrap_output { puts Translator.t(:status_global, :entries => entries) }
110
+ end
111
+
53
112
  def options_spec(opts)
54
- opts.banner = "Usage: vagrant status"
113
+ opts.banner = "Usage: vagrant status [--global]"
114
+
115
+ # Defaults
116
+ options[:global] = false
117
+ options[:vm] = nil
118
+
119
+ opts.on("-g", "--global", "Show global status of Vagrant (running VMs managed by Vagrant)") do |v|
120
+ options[:global] = true
121
+ end
55
122
  end
56
123
  end
57
124
  end
58
- end
125
+ end
@@ -11,8 +11,21 @@ module Vagrant
11
11
  description "Suspends the currently running vagrant environment"
12
12
 
13
13
  def execute(args=[])
14
- env.require_persisted_vm
15
- env.vm.suspend
14
+ all_or_single(args, :suspend)
15
+ end
16
+
17
+ def suspend_single(name)
18
+ vm = env.vms[name.to_sym]
19
+ if vm.nil?
20
+ error_and_exit(:unknown_vm, :vm => name)
21
+ return # for tests
22
+ end
23
+
24
+ if vm.created?
25
+ vm.suspend
26
+ else
27
+ vm.env.logger.info "VM '#{name}' not created. Ignoring."
28
+ end
16
29
  end
17
30
 
18
31
  def options_spec(opts)
@@ -20,4 +33,4 @@ module Vagrant
20
33
  end
21
34
  end
22
35
  end
23
- end
36
+ end
@@ -9,18 +9,37 @@ module Vagrant
9
9
  description "Creates the vagrant environment"
10
10
 
11
11
  def execute(args=[])
12
- if env.vm
13
- logger.info "VM already created. Starting VM if its not already running..."
14
- env.vm.start
12
+ all_or_single(args, :up)
13
+ end
14
+
15
+ def up_single(name)
16
+ vm = env.vms[name.to_sym]
17
+ if vm.nil?
18
+ error_and_exit(:unknown_vm, :vm => name)
19
+ return # for tests
20
+ end
21
+
22
+ if vm.created?
23
+ vm.env.logger.info "VM '#{name}' already created. Booting if its not already running..."
24
+ vm.start
15
25
  else
16
- env.require_box
17
- env.create_vm.execute!(Actions::VM::Up)
26
+ vm.env.require_box
27
+
28
+ vm.env.logger.info "Creating VM '#{name}'"
29
+ vm.up
18
30
  end
19
31
  end
20
32
 
21
33
  def options_spec(opts)
22
- opts.banner = "Usage: vagrant up"
34
+ opts.banner = "Usage: vagrant up [--no-provision]"
35
+
36
+ # Defaults
37
+ options[:provision] = true
38
+
39
+ opts.on("--no-provision", "Do not provision during this up.") do |v|
40
+ options[:provision] = false
41
+ end
23
42
  end
24
43
  end
25
44
  end
26
- end
45
+ end
@@ -29,10 +29,12 @@ module Vagrant
29
29
  push_proc(&block)
30
30
  end
31
31
 
32
- def execute!
33
- run_procs!(config)
34
- config.loaded!
35
- config
32
+ def execute!(config_object=nil)
33
+ config_object ||= config
34
+
35
+ run_procs!(config_object)
36
+ config_object.loaded!
37
+ config_object
36
38
  end
37
39
  end
38
40
  end
@@ -59,13 +61,17 @@ module Vagrant
59
61
 
60
62
  class SSHConfig < Base
61
63
  attr_accessor :username
62
- attr_accessor :password
63
64
  attr_accessor :host
65
+ attr_accessor :port
64
66
  attr_accessor :forwarded_port_key
65
67
  attr_accessor :max_tries
66
68
  attr_accessor :timeout
67
69
  attr_accessor :private_key_path
68
70
 
71
+ # The attribute(s) below do nothing. They are just kept here to
72
+ # prevent syntax errors for backwards compat.
73
+ attr_accessor :password
74
+
69
75
  def private_key_path
70
76
  File.expand_path(@private_key_path, env.root_path)
71
77
  end
@@ -74,40 +80,80 @@ module Vagrant
74
80
  class VMConfig < Base
75
81
  include Util::StackedProcRunner
76
82
 
83
+ attr_accessor :auto_port_range
77
84
  attr_accessor :box
78
85
  attr_accessor :box_ovf
79
86
  attr_accessor :base_mac
80
87
  attr_accessor :boot_mode
81
- attr_accessor :project_directory
88
+ attr_accessor :sync_opts
89
+ attr_accessor :sync_script
90
+ attr_accessor :sync_crontab_entry_file
91
+ attr_reader :sync_required
82
92
  attr_reader :forwarded_ports
83
93
  attr_reader :shared_folders
94
+ attr_reader :network_options
84
95
  attr_accessor :hd_location
85
96
  attr_accessor :disk_image_format
86
97
  attr_accessor :provisioner
87
98
  attr_accessor :shared_folder_uid
88
99
  attr_accessor :shared_folder_gid
100
+ attr_accessor :system
101
+
102
+ # Represents a SubVM. This class is only used here in the VMs
103
+ # hash.
104
+ class SubVM
105
+ include Util::StackedProcRunner
106
+
107
+ def options
108
+ @options ||= {}
109
+ end
110
+ end
89
111
 
90
112
  def initialize
91
113
  @forwarded_ports = {}
92
114
  @shared_folders = {}
93
115
  @provisioner = nil
116
+ @network_options = []
94
117
  end
95
118
 
96
- def forward_port(name, guestport, hostport, protocol="TCP")
97
- forwarded_ports[name] = {
119
+ def forward_port(name, guestport, hostport, options=nil)
120
+ options = {
98
121
  :guestport => guestport,
99
122
  :hostport => hostport,
100
- :protocol => protocol
101
- }
123
+ :protocol => "TCP",
124
+ :adapter => 0,
125
+ :auto => false
126
+ }.merge(options || {})
127
+
128
+ forwarded_ports[name] = options
102
129
  end
103
130
 
104
- def share_folder(name, guestpath, hostpath)
131
+ def share_folder(name, guestpath, hostpath = nil, opts = {})
132
+ guestpath, opts[:sync] = shift(guestpath, opts[:sync])
133
+
134
+ # TODO if both are nil the exception information will be unusable
135
+ if opts[:sync] == guestpath
136
+ raise Exception.new("The sync directory #{opts[:sync]} is identical to the shifted shared folder mount point #{guestpath}")
137
+ end
138
+
105
139
  @shared_folders[name] = {
140
+ :syncpath => opts[:sync],
106
141
  :guestpath => guestpath,
107
142
  :hostpath => hostpath
108
143
  }
109
144
  end
110
145
 
146
+ def network(ip, options=nil)
147
+ options = {
148
+ :ip => ip,
149
+ :netmask => "255.255.255.0",
150
+ :adapter => 1,
151
+ :name => nil
152
+ }.merge(options || {})
153
+
154
+ @network_options[options[:adapter]] = options
155
+ end
156
+
111
157
  def hd_location=(val)
112
158
  raise Exception.new("disk_storage must be set to a directory") unless File.directory?(val)
113
159
  @hd_location=val
@@ -124,6 +170,30 @@ module Vagrant
124
170
  def customize(&block)
125
171
  push_proc(&block)
126
172
  end
173
+
174
+ def has_multi_vms?
175
+ !defined_vms.empty?
176
+ end
177
+
178
+ def defined_vms
179
+ @defined_vms ||= {}
180
+ end
181
+
182
+ def define(name, options=nil, &block)
183
+ options ||= {}
184
+ defined_vms[name.to_sym] ||= SubVM.new
185
+ defined_vms[name.to_sym].options.merge!(options)
186
+ defined_vms[name.to_sym].push_proc(&block)
187
+ end
188
+
189
+ def shift(orig, sync)
190
+ if sync
191
+ @sync_required = true
192
+ [orig + '-sync', sync == true ? orig : sync]
193
+ else
194
+ [orig, sync]
195
+ end
196
+ end
127
197
  end
128
198
 
129
199
  class PackageConfig < Base
@@ -144,7 +214,7 @@ module Vagrant
144
214
  class Top < Base
145
215
  @@configures = []
146
216
 
147
- class <<self
217
+ class << self
148
218
  def configures_list
149
219
  @@configures ||= []
150
220
  end
@@ -5,6 +5,13 @@ module Vagrant
5
5
  class Base
6
6
  include Vagrant::Util
7
7
 
8
+ # The environment which this downloader is operating.
9
+ attr_reader :env
10
+
11
+ def initialize(env)
12
+ @env = env
13
+ end
14
+
8
15
  # Called prior to execution so any error checks can be done
9
16
  def prepare(source_url); end
10
17
 
@@ -13,4 +20,4 @@ module Vagrant
13
20
  def download!(source_url, destination_file); end
14
21
  end
15
22
  end
16
- end
23
+ end