vagrant 0.5.0 → 0.5.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -45,6 +45,7 @@ module Vagrant
45
45
  def run(callable, options=nil)
46
46
  callable = Builder.new.use(callable) if callable.kind_of?(Class)
47
47
  callable = self.class.actions[callable] if callable.kind_of?(Symbol)
48
+ raise Exceptions::UncallableAction.new(callable) if !callable
48
49
 
49
50
  action_environment = Action::Environment.new(env)
50
51
  action_environment.merge!(options || {})
@@ -0,0 +1,19 @@
1
+ require 'vagrant/action/general/package'
2
+
3
+ module Vagrant
4
+ class Action
5
+ module Box
6
+ # Packages a box which has already been unpackaged (such as
7
+ # for the `vagrant box repackage` command) by leveraging the
8
+ # general packager middleware.
9
+ class Package < General::Package
10
+ # Alias instead of calling super for testability
11
+ alias_method :general_call, :call
12
+ def call(env)
13
+ env["package.directory"] = env["box"].directory
14
+ general_call(env)
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -32,6 +32,7 @@ module Vagrant
32
32
  # halt - Halts the VM, attempting gracefully but then forcing
33
33
  # a restart if fails.
34
34
  halt = Builder.new do
35
+ use VM::DiscardState
35
36
  use VM::Halt
36
37
  use VM::DisableNetworks
37
38
  end
@@ -89,6 +90,7 @@ module Vagrant
89
90
  use VM::ClearForwardedPorts
90
91
  use VM::ClearSharedFolders
91
92
  use VM::Export
93
+ use VM::PackageVagrantfile
92
94
  use VM::Package
93
95
  end
94
96
 
@@ -109,6 +111,13 @@ module Vagrant
109
111
  end
110
112
 
111
113
  register :box_remove, box_remove
114
+
115
+ # box_repackage - Repackages a box.
116
+ box_repackage = Builder.new do
117
+ use Box::Package
118
+ end
119
+
120
+ register :box_repackage, box_repackage
112
121
  end
113
122
  end
114
123
  end
@@ -0,0 +1,96 @@
1
+ module Vagrant
2
+ class Action
3
+ module General
4
+ # A general packaging (tar) middleware. Given the following options,
5
+ # it will do the right thing:
6
+ #
7
+ # * package.output - The filename of the outputted package.
8
+ # * package.include - An array of files to include in the package.
9
+ # * package.directory - The directory which contains the contents to
10
+ # compress into the package.
11
+ #
12
+ # This middleware always produces the final file in the current working
13
+ # directory (FileUtils.pwd)
14
+ class Package
15
+ include Util
16
+
17
+ def initialize(app, env)
18
+ @app = app
19
+ @env = env
20
+ @env["package.output"] ||= env["config"].package.name
21
+ @env["package.include"] ||= []
22
+ end
23
+
24
+ def call(env)
25
+ @env = env
26
+
27
+ return env.error!(:package_output_exists) if File.exist?(tar_path)
28
+ return env.error!(:package_requires_directory) if !@env["package.directory"] || !File.directory?(@env["package.directory"])
29
+ return if !verify_included_files
30
+ compress
31
+
32
+ @app.call(env)
33
+
34
+ cleanup if env.error?
35
+ end
36
+
37
+ def cleanup
38
+ # Cleanup any packaged files if the packaging failed at some point.
39
+ File.delete(tar_path) if File.exist?(tar_path)
40
+ end
41
+
42
+ def verify_included_files
43
+ @env["package.include"].each do |file|
44
+ if !File.exist?(file)
45
+ @env.error!(:package_include_file_doesnt_exist, :filename => file)
46
+ return false
47
+ end
48
+ end
49
+
50
+ true
51
+ end
52
+
53
+ # This method copies the include files (passed in via command line)
54
+ # to the temporary directory so they are included in a sub-folder within
55
+ # the actual box
56
+ def copy_include_files
57
+ if @env["package.include"].length > 0
58
+ include_dir = File.join(@env["package.directory"], "include")
59
+ FileUtils.mkdir_p(include_dir)
60
+
61
+ @env["package.include"].each do |f|
62
+ @env.logger.info "Packaging additional file: #{f}"
63
+ FileUtils.cp(f, include_dir)
64
+ end
65
+ end
66
+ end
67
+
68
+ # Compress the exported file into a package
69
+ def compress
70
+ @env.logger.info "Compressing package to #{tar_path}..."
71
+ File.open(tar_path, Platform.tar_file_options) do |tar|
72
+ Archive::Tar::Minitar::Output.open(tar) do |output|
73
+ begin
74
+ current_dir = FileUtils.pwd
75
+
76
+ copy_include_files
77
+
78
+ FileUtils.cd(@env["package.directory"])
79
+ Dir.glob(File.join(".", "**", "*")).each do |entry|
80
+ Archive::Tar::Minitar.pack_file(entry, output)
81
+ end
82
+ ensure
83
+ FileUtils.cd(current_dir)
84
+ end
85
+ end
86
+ end
87
+ end
88
+
89
+ # Path to the final box output file
90
+ def tar_path
91
+ File.join(FileUtils.pwd, @env["package.output"])
92
+ end
93
+ end
94
+ end
95
+ end
96
+ end
@@ -10,10 +10,16 @@ module Vagrant
10
10
  end
11
11
 
12
12
  def call(env)
13
- env.logger.info "Disabling host only networks..."
13
+ logged = false
14
14
 
15
15
  env["vm"].vm.network_adapters.each do |adapter|
16
16
  next if adapter.attachment_type != :host_only
17
+
18
+ if !logged
19
+ env.logger.info "Disabling host only networks..."
20
+ logged = true
21
+ end
22
+
17
23
  adapter.enabled = false
18
24
  adapter.save
19
25
  end
@@ -0,0 +1,22 @@
1
+ module Vagrant
2
+ class Action
3
+ module VM
4
+ # Discards the saved state of the VM if its saved. If its
5
+ # not saved, does nothing.
6
+ class DiscardState
7
+ def initialize(app, env)
8
+ @app = app
9
+ end
10
+
11
+ def call(env)
12
+ if env["vm"].vm.saved?
13
+ env.logger.info "Discarding saved state of VM..."
14
+ env["vm"].vm.discard_state
15
+ end
16
+
17
+ @app.call(env)
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -1,97 +1,21 @@
1
+ require 'vagrant/action/general/package'
2
+
1
3
  module Vagrant
2
4
  class Action
3
5
  module VM
4
- class Package
5
- include Util
6
-
7
- def initialize(app, env)
8
- @app = app
9
- @env = env
10
- @env["package.output"] ||= env["config"].package.name
11
- @env["package.include"] ||= []
12
-
13
- env.error!(:box_file_exists, :output_file => tar_path) if File.exist?(tar_path)
14
- end
15
-
6
+ # A subclass of {General::Package} which simply makes sure that
7
+ # the package directory is set to the directory which the VM
8
+ # was exported to.
9
+ class Package < General::Package
10
+ # Doing this so that we can test that the parent is properly
11
+ # called in the unit tests.
12
+ alias_method :general_call, :call
16
13
  def call(env)
17
- @env = env
18
-
19
- return env.error!(:package_requires_export) if !@env["export.temp_dir"]
20
- return if !verify_included_files
21
- compress
22
-
23
- @app.call(env)
24
-
25
- cleanup if env.error?
26
- end
27
-
28
- def cleanup
29
- # Cleanup any packaged files if the packaging failed at some point.
30
- File.delete(tar_path) if File.exist?(tar_path)
31
- end
32
-
33
- def verify_included_files
34
- @env["package.include"].each do |file|
35
- if !File.exist?(file)
36
- @env.error!(:package_include_file_doesnt_exist, :filename => file)
37
- return false
38
- end
39
- end
40
-
41
- true
42
- end
43
-
44
- # This method copies the include files (passed in via command line)
45
- # to the temporary directory so they are included in a sub-folder within
46
- # the actual box
47
- def copy_include_files
48
- if @env["package.include"].length > 0
49
- include_dir = File.join(@env["export.temp_dir"], "include")
50
- FileUtils.mkdir_p(include_dir)
51
-
52
- @env["package.include"].each do |f|
53
- @env.logger.info "Packaging additional file: #{f}"
54
- FileUtils.cp(f, include_dir)
55
- end
56
- end
57
- end
58
-
59
- # This method creates the auto-generated Vagrantfile at the root of the
60
- # box. This Vagrantfile contains the MAC address so that the user doesn't
61
- # have to worry about it.
62
- def create_vagrantfile
63
- File.open(File.join(@env["export.temp_dir"], "Vagrantfile"), "w") do |f|
64
- f.write(TemplateRenderer.render("package_Vagrantfile", {
65
- :base_mac => @env["vm"].vm.network_adapters.first.mac_address
66
- }))
67
- end
68
- end
69
-
70
- # Compress the exported file into a package
71
- def compress
72
- @env.logger.info "Packaging VM into #{tar_path}..."
73
- File.open(tar_path, Platform.tar_file_options) do |tar|
74
- Archive::Tar::Minitar::Output.open(tar) do |output|
75
- begin
76
- current_dir = FileUtils.pwd
77
-
78
- copy_include_files
79
- create_vagrantfile
80
-
81
- FileUtils.cd(@env["export.temp_dir"])
82
- Dir.glob(File.join(".", "**", "*")).each do |entry|
83
- Archive::Tar::Minitar.pack_file(entry, output)
84
- end
85
- ensure
86
- FileUtils.cd(current_dir)
87
- end
88
- end
89
- end
90
- end
91
-
92
- # Path to the final box output file
93
- def tar_path
94
- File.join(FileUtils.pwd, @env["package.output"])
14
+ # Just match up a couple environmental variables so that
15
+ # the superclass will do the right thing. Then, call the
16
+ # superclass
17
+ env["package.directory"] = env["export.temp_dir"]
18
+ general_call(env)
95
19
  end
96
20
  end
97
21
  end
@@ -0,0 +1,33 @@
1
+ module Vagrant
2
+ class Action
3
+ module VM
4
+ # Puts a generated Vagrantfile into the package directory so that
5
+ # it can be included in the package.
6
+ class PackageVagrantfile
7
+ include Util
8
+
9
+ def initialize(app, env)
10
+ @app = app
11
+ @env = env
12
+ end
13
+
14
+ def call(env)
15
+ @env = env
16
+ create_vagrantfile
17
+ @app.call(env)
18
+ end
19
+
20
+ # This method creates the auto-generated Vagrantfile at the root of the
21
+ # box. This Vagrantfile contains the MAC address so that the user doesn't
22
+ # have to worry about it.
23
+ def create_vagrantfile
24
+ File.open(File.join(@env["package.directory"], "Vagrantfile"), "w") do |f|
25
+ f.write(TemplateRenderer.render("package_Vagrantfile", {
26
+ :base_mac => @env["vm"].vm.network_adapters.first.mac_address
27
+ }))
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -9,7 +9,7 @@ module Vagrant
9
9
  def call(env)
10
10
  if env["vm"].vm.saved?
11
11
  env.logger.info "Resuming suspended VM..."
12
- env["actions"].run(:start)
12
+ env["actions"].run(Boot)
13
13
  end
14
14
 
15
15
  @app.call(env)
@@ -132,11 +132,16 @@ module Vagrant
132
132
  env.actions.run(:box_add, { "box" => self })
133
133
  end
134
134
 
135
- # Beings the process of destroying this box.
135
+ # Begins the process of destroying this box.
136
136
  def destroy
137
137
  env.actions.run(:box_remove, { "box" => self })
138
138
  end
139
139
 
140
+ # Begins sequence to repackage this box.
141
+ def repackage(options=nil)
142
+ env.actions.run(:box_repackage, { "box" => self }.merge(options || {}))
143
+ end
144
+
140
145
  # Returns the directory to the location of this boxes content in the local
141
146
  # filesystem.
142
147
  #
@@ -27,4 +27,4 @@ module Vagrant
27
27
  end
28
28
  end
29
29
  end
30
- end
30
+ end
@@ -0,0 +1,35 @@
1
+ module Vagrant
2
+ class Commands
3
+ module Box
4
+ # Repackage a box which has been added.
5
+ class Repackage < BoxCommand
6
+ BoxCommand.subcommand "repackage", self
7
+ description "Repackages a box which has already been added."
8
+
9
+ def execute(args=[])
10
+ args = parse_options(args)
11
+ return show_help if args.length != 1
12
+
13
+ box = Vagrant::Box.find(env, args.first)
14
+ return error_and_exit(:box_repackage_doesnt_exist) if box.nil?
15
+ box.repackage(options)
16
+ end
17
+
18
+ def options_spec(opts)
19
+ opts.banner = "Usage: vagrant box repackage NAME [--output FILENAME] [--include FILES]"
20
+
21
+ options["package.output"] = nil
22
+ options["package.include"] = []
23
+
24
+ opts.on("--include x,y,z", Array, "List of files to include in the package") do |v|
25
+ options["package.include"] = v
26
+ end
27
+
28
+ opts.on("-o", "--output FILE", "File to save the package as.") do |v|
29
+ options["package.output"] = v
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -57,7 +57,7 @@ module Vagrant
57
57
  end
58
58
 
59
59
  def options_spec(opts)
60
- opts.banner = "Usage: vagrant package [--base BASE] [--include FILES]"
60
+ opts.banner = "Usage: vagrant package [--base BASE] [--output FILENAME] [--include FILES]"
61
61
 
62
62
  # Defaults
63
63
  options[:base] = nil
@@ -10,6 +10,7 @@ module Vagrant
10
10
  description "Reload the vagrant environment"
11
11
 
12
12
  def execute(args=[])
13
+ env.require_root_path
13
14
  all_or_single(args, :reload)
14
15
  end
15
16
 
@@ -9,6 +9,7 @@ module Vagrant
9
9
  description "Creates the vagrant environment"
10
10
 
11
11
  def execute(args=[])
12
+ env.require_root_path
12
13
  all_or_single(args, :up)
13
14
  end
14
15
 
@@ -0,0 +1,17 @@
1
+ module Vagrant
2
+ module Exceptions
3
+ # Raised when an action sequence is trying to be run for an uncallable
4
+ # action (not a lambda, middleware, or registered sequence).
5
+ class UncallableAction < ::Exception
6
+ def initialize(callable)
7
+ super()
8
+
9
+ @callable = callable
10
+ end
11
+
12
+ def to_s
13
+ @callable.inspect
14
+ end
15
+ end
16
+ end
17
+ end
@@ -40,6 +40,7 @@ module Vagrant
40
40
  end
41
41
 
42
42
  def nfs_cleanup
43
+ return if !File.exist?("/etc/exports")
43
44
  system("cat /etc/exports | grep 'VAGRANT-BEGIN: #{env.vm.uuid}' > /dev/null 2>&1")
44
45
 
45
46
  if $?.to_i == 0
@@ -39,6 +39,7 @@ module Vagrant
39
39
  end
40
40
 
41
41
  def nfs_cleanup
42
+ return if !File.exist?("/etc/exports")
42
43
  system("cat /etc/exports | grep 'VAGRANT-BEGIN: #{env.vm.uuid}' > /dev/null 2>&1")
43
44
 
44
45
  if $?.to_i == 0
@@ -16,6 +16,7 @@ module Vagrant
16
16
  # Chef solo specific config
17
17
  attr_accessor :cookbooks_path
18
18
  attr_accessor :roles_path
19
+ attr_accessor :recipe_url
19
20
 
20
21
  # Shared config
21
22
  attr_accessor :provisioning_path
@@ -27,7 +28,7 @@ module Vagrant
27
28
  @client_key_path = "/etc/chef/client.pem"
28
29
  @node_name = "client"
29
30
 
30
- @cookbooks_path = "cookbooks"
31
+ @cookbooks_path = ["cookbooks", [:vm, "cookbooks"]]
31
32
  @roles_path = []
32
33
  @provisioning_path = "/tmp/vagrant-chef"
33
34
  @log_level = :info
@@ -32,7 +32,8 @@ module Vagrant
32
32
  :node_name => env.config.chef.node_name,
33
33
  :provisioning_path => env.config.chef.provisioning_path,
34
34
  :cookbooks_path => cookbooks_path,
35
- :roles_path => roles_path
35
+ :recipe_url => env.config.chef.recipe_url,
36
+ :roles_path => roles_path,
36
37
  })
37
38
  end
38
39
 
@@ -49,23 +50,43 @@ module Vagrant
49
50
  end
50
51
 
51
52
  def host_folder_paths(paths)
52
- [paths].flatten.collect { |path| File.expand_path(path, env.root_path) }
53
+ # Convert single cookbook paths such as "cookbooks" or [:vm, "cookbooks"]
54
+ # into a proper array representation.
55
+ paths = [paths] if paths.is_a?(String) || paths.first.is_a?(Symbol)
56
+
57
+ paths.inject([]) do |acc, path|
58
+ path = [:host, path] if !path.is_a?(Array)
59
+ type, path = path
60
+
61
+ acc << File.expand_path(path, env.root_path) if type == :host
62
+ acc
63
+ end
53
64
  end
54
65
 
55
- def folder_path(folder, i)
56
- File.join(env.config.chef.provisioning_path, "#{folder}-#{i}")
66
+ def folder_path(*args)
67
+ File.expand_path(args.join("-"), env.config.chef.provisioning_path)
57
68
  end
58
69
 
59
70
  def folders_path(folders, folder)
71
+ # Convert single cookbook paths such as "cookbooks" or [:vm, "cookbooks"]
72
+ # into a proper array representation.
73
+ folders = [folders] if folders.is_a?(String) || folders.first.is_a?(Symbol)
74
+
75
+ # Convert each path to the proper absolute path depending on if the path
76
+ # is a host path or a VM path
60
77
  result = []
61
- folders.each_with_index do |host_path, i|
62
- result << folder_path(folder, i)
78
+ folders.each_with_index do |path, i|
79
+ path = [:host, path] if !path.is_a?(Array)
80
+ type, path = path
81
+
82
+ result << folder_path(folder, i) if type == :host
83
+ result << folder_path(path) if type == :vm
63
84
  end
64
85
 
65
86
  # We're lucky that ruby's string and array syntax for strings is the
66
87
  # same as JSON, so we can just convert to JSON here and use that
67
88
  result = result[0].to_s if result.length == 1
68
- result.to_json
89
+ result
69
90
  end
70
91
 
71
92
  def host_cookbook_paths
@@ -85,11 +106,11 @@ module Vagrant
85
106
  end
86
107
 
87
108
  def cookbooks_path
88
- folders_path(host_cookbook_paths, "cookbooks")
109
+ folders_path(env.config.chef.cookbooks_path, "cookbooks").to_json
89
110
  end
90
111
 
91
112
  def roles_path
92
- folders_path(host_role_paths, "roles")
113
+ folders_path(env.config.chef.roles_path, "roles").to_json
93
114
  end
94
115
  end
95
116
  end
@@ -2,5 +2,5 @@ module Vagrant
2
2
  # This will always be up to date with the current version of Vagrant,
3
3
  # since it is used to generate the gemspec and is also the source of
4
4
  # the version for `vagrant -v`
5
- VERSION = "0.5.0"
5
+ VERSION = "0.5.1"
6
6
  end
@@ -3,3 +3,7 @@ file_cache_path "<%= provisioning_path %>"
3
3
  cookbook_path <%= cookbooks_path %>
4
4
  role_path <%= roles_path %>
5
5
  log_level <%= log_level.inspect %>
6
+
7
+ <% if recipe_url %>
8
+ recipe_url "<%= recipe_url %>"
9
+ <% end %>
@@ -84,6 +84,11 @@
84
84
  Specified output file: <%= output_file %>
85
85
  :box_remove_doesnt_exist: |-
86
86
  The box you're attempting to remove does not exist!
87
+ :box_repackage_doesnt_exist: |-
88
+ The box you're attempting to repackage does not exist. Please check the
89
+ name you specified and try again. As a reminder, the repackage
90
+ command is for repackaging boxes which have been added through `vagrant box add`
91
+ but the box has been lost.
87
92
  :box_specified_doesnt_exist: |-
88
93
  Specified box `<%= box_name %>` does not exist!
89
94
 
@@ -171,6 +176,13 @@
171
176
  specific VM must be specified. This can be done by calling
172
177
  `vagrant package NAME` where NAME is a valid VM represented by
173
178
  your Vagrantfile.
179
+ :package_output_exists: |-
180
+ The specified file to save the package as already exists. Please
181
+ remove this file or specify a different filename for outputting.
182
+ :package_requires_directory: |-
183
+ A directory was not specified to package. This is an internal
184
+ issue. Please send the relevant stack trace (if any) and information
185
+ about this issue to the Vagrant team.
174
186
  :package_requires_export: |-
175
187
  Package must be used in conjunction with export.
176
188
  :provisioner_invalid_class: |-
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: vagrant
3
3
  version: !ruby/object:Gem::Version
4
- hash: 11
4
+ hash: 9
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 5
9
- - 0
10
- version: 0.5.0
9
+ - 1
10
+ version: 0.5.1
11
11
  platform: ruby
12
12
  authors:
13
13
  - Mitchell Hashimoto
@@ -16,7 +16,7 @@ autorequire:
16
16
  bindir: bin
17
17
  cert_chain: []
18
18
 
19
- date: 2010-07-26 00:00:00 -07:00
19
+ date: 2010-07-31 00:00:00 -07:00
20
20
  default_executable:
21
21
  dependencies:
22
22
  - !ruby/object:Gem::Dependency
@@ -193,6 +193,7 @@ files:
193
193
  - lib/vagrant/action/action_exception.rb
194
194
  - lib/vagrant/action/box/destroy.rb
195
195
  - lib/vagrant/action/box/download.rb
196
+ - lib/vagrant/action/box/package.rb
196
197
  - lib/vagrant/action/box/unpackage.rb
197
198
  - lib/vagrant/action/box/verify.rb
198
199
  - lib/vagrant/action/builder.rb
@@ -201,6 +202,7 @@ files:
201
202
  - lib/vagrant/action/env/set.rb
202
203
  - lib/vagrant/action/environment.rb
203
204
  - lib/vagrant/action/exception_catcher.rb
205
+ - lib/vagrant/action/general/package.rb
204
206
  - lib/vagrant/action/vm/boot.rb
205
207
  - lib/vagrant/action/vm/check_box.rb
206
208
  - lib/vagrant/action/vm/check_guest_additions.rb
@@ -212,6 +214,7 @@ files:
212
214
  - lib/vagrant/action/vm/destroy.rb
213
215
  - lib/vagrant/action/vm/destroy_unused_network_interfaces.rb
214
216
  - lib/vagrant/action/vm/disable_networks.rb
217
+ - lib/vagrant/action/vm/discard_state.rb
215
218
  - lib/vagrant/action/vm/export.rb
216
219
  - lib/vagrant/action/vm/forward_ports.rb
217
220
  - lib/vagrant/action/vm/forward_ports_helpers.rb
@@ -222,6 +225,7 @@ files:
222
225
  - lib/vagrant/action/vm/nfs.rb
223
226
  - lib/vagrant/action/vm/nfs_helpers.rb
224
227
  - lib/vagrant/action/vm/package.rb
228
+ - lib/vagrant/action/vm/package_vagrantfile.rb
225
229
  - lib/vagrant/action/vm/persist.rb
226
230
  - lib/vagrant/action/vm/provision.rb
227
231
  - lib/vagrant/action/vm/resume.rb
@@ -235,6 +239,7 @@ files:
235
239
  - lib/vagrant/commands/box/add.rb
236
240
  - lib/vagrant/commands/box/list.rb
237
241
  - lib/vagrant/commands/box/remove.rb
242
+ - lib/vagrant/commands/box/repackage.rb
238
243
  - lib/vagrant/commands/box.rb
239
244
  - lib/vagrant/commands/destroy.rb
240
245
  - lib/vagrant/commands/halt.rb
@@ -253,6 +258,7 @@ files:
253
258
  - lib/vagrant/downloaders/file.rb
254
259
  - lib/vagrant/downloaders/http.rb
255
260
  - lib/vagrant/environment.rb
261
+ - lib/vagrant/exceptions/uncallable_action.rb
256
262
  - lib/vagrant/hosts/base.rb
257
263
  - lib/vagrant/hosts/bsd.rb
258
264
  - lib/vagrant/hosts/linux.rb