vagrant 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 (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