vagrant 0.2.0 → 0.3.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 (149) hide show
  1. data/Gemfile +4 -4
  2. data/Rakefile +3 -3
  3. data/VERSION +1 -1
  4. data/bin/vagrant +5 -13
  5. data/config/default.rb +1 -0
  6. data/keys/README.md +8 -1
  7. data/keys/vagrant.ppk +26 -0
  8. data/lib/vagrant.rb +3 -3
  9. data/lib/vagrant/actions/base.rb +15 -4
  10. data/lib/vagrant/actions/box/add.rb +1 -1
  11. data/lib/vagrant/actions/box/download.rb +72 -66
  12. data/lib/vagrant/actions/box/unpackage.rb +1 -4
  13. data/lib/vagrant/actions/runner.rb +1 -1
  14. data/lib/vagrant/actions/vm/boot.rb +5 -7
  15. data/lib/vagrant/actions/vm/customize.rb +2 -2
  16. data/lib/vagrant/actions/vm/destroy.rb +2 -2
  17. data/lib/vagrant/actions/vm/down.rb +7 -0
  18. data/lib/vagrant/actions/vm/export.rb +10 -4
  19. data/lib/vagrant/actions/vm/forward_ports.rb +5 -15
  20. data/lib/vagrant/actions/vm/halt.rb +5 -3
  21. data/lib/vagrant/actions/vm/import.rb +10 -3
  22. data/lib/vagrant/actions/vm/move_hard_drive.rb +1 -3
  23. data/lib/vagrant/actions/vm/package.rb +33 -10
  24. data/lib/vagrant/actions/vm/provision.rb +4 -4
  25. data/lib/vagrant/actions/vm/reload.rb +1 -1
  26. data/lib/vagrant/actions/vm/resume.rb +1 -1
  27. data/lib/vagrant/actions/vm/shared_folders.rb +7 -7
  28. data/lib/vagrant/actions/vm/start.rb +3 -2
  29. data/lib/vagrant/actions/vm/suspend.rb +2 -2
  30. data/lib/vagrant/actions/vm/up.rb +7 -17
  31. data/lib/vagrant/active_list.rb +52 -45
  32. data/lib/vagrant/box.rb +18 -11
  33. data/lib/vagrant/busy.rb +7 -0
  34. data/lib/vagrant/command.rb +27 -0
  35. data/lib/vagrant/commands/base.rb +163 -0
  36. data/lib/vagrant/commands/box.rb +16 -0
  37. data/lib/vagrant/commands/box/add.rb +24 -0
  38. data/lib/vagrant/commands/box/list.rb +30 -0
  39. data/lib/vagrant/commands/box/remove.rb +31 -0
  40. data/lib/vagrant/commands/destroy.rb +23 -0
  41. data/lib/vagrant/commands/down.rb +16 -0
  42. data/lib/vagrant/commands/halt.rb +23 -0
  43. data/lib/vagrant/commands/init.rb +32 -0
  44. data/lib/vagrant/commands/package.rb +46 -0
  45. data/lib/vagrant/commands/reload.rb +22 -0
  46. data/lib/vagrant/commands/resume.rb +22 -0
  47. data/lib/vagrant/commands/ssh.rb +22 -0
  48. data/lib/vagrant/commands/ssh_config.rb +30 -0
  49. data/lib/vagrant/commands/status.rb +58 -0
  50. data/lib/vagrant/commands/suspend.rb +23 -0
  51. data/lib/vagrant/commands/up.rb +26 -0
  52. data/lib/vagrant/config.rb +21 -11
  53. data/lib/vagrant/downloaders/file.rb +5 -5
  54. data/lib/vagrant/downloaders/http.rb +10 -15
  55. data/lib/vagrant/environment.rb +259 -0
  56. data/lib/vagrant/provisioners/base.rb +7 -0
  57. data/lib/vagrant/provisioners/chef.rb +24 -9
  58. data/lib/vagrant/provisioners/chef_server.rb +23 -48
  59. data/lib/vagrant/provisioners/chef_solo.rb +48 -22
  60. data/lib/vagrant/ssh.rb +95 -46
  61. data/lib/vagrant/util.rb +2 -2
  62. data/lib/vagrant/util/errors.rb +36 -0
  63. data/lib/vagrant/util/platform.rb +12 -0
  64. data/lib/vagrant/util/progress_meter.rb +33 -0
  65. data/lib/vagrant/util/stacked_proc_runner.rb +35 -0
  66. data/lib/vagrant/util/template_renderer.rb +83 -0
  67. data/lib/vagrant/vm.rb +1 -0
  68. data/templates/{Vagrantfile → Vagrantfile.erb} +2 -2
  69. data/templates/chef_server_client.erb +16 -0
  70. data/templates/chef_solo_solo.erb +4 -0
  71. data/templates/errors.yml +157 -0
  72. data/templates/package_Vagrantfile.erb +11 -0
  73. data/templates/ssh_config.erb +7 -0
  74. data/test/test_helper.rb +12 -15
  75. data/test/vagrant/actions/box/add_test.rb +1 -2
  76. data/test/vagrant/actions/box/destroy_test.rb +0 -1
  77. data/test/vagrant/actions/box/download_test.rb +40 -15
  78. data/test/vagrant/actions/box/unpackage_test.rb +2 -3
  79. data/test/vagrant/actions/collection_test.rb +8 -5
  80. data/test/vagrant/actions/runner_test.rb +8 -6
  81. data/test/vagrant/actions/vm/boot_test.rb +12 -11
  82. data/test/vagrant/actions/vm/customize_test.rb +2 -3
  83. data/test/vagrant/actions/vm/destroy_test.rb +2 -3
  84. data/test/vagrant/actions/vm/down_test.rb +16 -3
  85. data/test/vagrant/actions/vm/export_test.rb +4 -5
  86. data/test/vagrant/actions/vm/forward_ports_test.rb +6 -5
  87. data/test/vagrant/actions/vm/halt_test.rb +8 -2
  88. data/test/vagrant/actions/vm/import_test.rb +5 -5
  89. data/test/vagrant/actions/vm/move_hard_drive_test.rb +4 -6
  90. data/test/vagrant/actions/vm/package_test.rb +60 -22
  91. data/test/vagrant/actions/vm/provision_test.rb +7 -16
  92. data/test/vagrant/actions/vm/reload_test.rb +3 -2
  93. data/test/vagrant/actions/vm/resume_test.rb +0 -1
  94. data/test/vagrant/actions/vm/shared_folders_test.rb +17 -12
  95. data/test/vagrant/actions/vm/start_test.rb +10 -3
  96. data/test/vagrant/actions/vm/suspend_test.rb +1 -2
  97. data/test/vagrant/actions/vm/up_test.rb +19 -11
  98. data/test/vagrant/active_list_test.rb +148 -129
  99. data/test/vagrant/box_test.rb +26 -14
  100. data/test/vagrant/busy_test.rb +15 -6
  101. data/test/vagrant/command_test.rb +53 -0
  102. data/test/vagrant/commands/base_test.rb +118 -0
  103. data/test/vagrant/commands/box/add_test.rb +34 -0
  104. data/test/vagrant/commands/box/list_test.rb +32 -0
  105. data/test/vagrant/commands/box/remove_test.rb +41 -0
  106. data/test/vagrant/commands/destroy_test.rb +32 -0
  107. data/test/vagrant/commands/down_test.rb +17 -0
  108. data/test/vagrant/commands/halt_test.rb +28 -0
  109. data/test/vagrant/commands/init_test.rb +55 -0
  110. data/test/vagrant/commands/package_test.rb +84 -0
  111. data/test/vagrant/commands/reload_test.rb +28 -0
  112. data/test/vagrant/commands/resume_test.rb +33 -0
  113. data/test/vagrant/commands/ssh_config_test.rb +54 -0
  114. data/test/vagrant/commands/ssh_test.rb +32 -0
  115. data/test/vagrant/commands/status_test.rb +20 -0
  116. data/test/vagrant/commands/suspend_test.rb +33 -0
  117. data/test/vagrant/commands/up_test.rb +41 -0
  118. data/test/vagrant/config_test.rb +42 -17
  119. data/test/vagrant/downloaders/file_test.rb +7 -0
  120. data/test/vagrant/downloaders/http_test.rb +12 -0
  121. data/test/vagrant/environment_test.rb +595 -0
  122. data/test/vagrant/provisioners/base_test.rb +7 -1
  123. data/test/vagrant/provisioners/chef_server_test.rb +41 -51
  124. data/test/vagrant/provisioners/chef_solo_test.rb +93 -62
  125. data/test/vagrant/provisioners/chef_test.rb +61 -15
  126. data/test/vagrant/ssh_test.rb +166 -38
  127. data/test/vagrant/util/errors_test.rb +57 -0
  128. data/test/vagrant/util/progress_meter_test.rb +33 -0
  129. data/test/vagrant/{stacked_proc_runner_test.rb → util/stacked_proc_runner_test.rb} +3 -3
  130. data/test/vagrant/util/template_renderer_test.rb +138 -0
  131. data/test/vagrant/vm_test.rb +3 -2
  132. data/vagrant.gemspec +88 -33
  133. metadata +94 -51
  134. data/bin/vagrant-box +0 -34
  135. data/bin/vagrant-down +0 -27
  136. data/bin/vagrant-halt +0 -28
  137. data/bin/vagrant-init +0 -27
  138. data/bin/vagrant-package +0 -29
  139. data/bin/vagrant-reload +0 -29
  140. data/bin/vagrant-resume +0 -27
  141. data/bin/vagrant-ssh +0 -27
  142. data/bin/vagrant-status +0 -29
  143. data/bin/vagrant-suspend +0 -27
  144. data/bin/vagrant-up +0 -29
  145. data/lib/vagrant/commands.rb +0 -234
  146. data/lib/vagrant/env.rb +0 -189
  147. data/lib/vagrant/stacked_proc_runner.rb +0 -33
  148. data/test/vagrant/commands_test.rb +0 -269
  149. data/test/vagrant/env_test.rb +0 -418
@@ -51,16 +51,21 @@ module Vagrant
51
51
  # only be used internally.
52
52
  attr_accessor :temp_path
53
53
 
54
+ # The environment which this box belongs to. Although this could
55
+ # actually be many environments, this points to the environment
56
+ # of a specific instance.
57
+ attr_accessor :env
58
+
54
59
  class <<self
55
60
  # Returns an array of all created boxes, as strings.
56
61
  #
57
62
  # @return [Array<String>]
58
- def all
63
+ def all(env)
59
64
  results = []
60
65
 
61
- Dir.open(Env.boxes_path) do |dir|
66
+ Dir.open(env.boxes_path) do |dir|
62
67
  dir.each do |d|
63
- next if d == "." || d == ".." || !File.directory?(File.join(Env.boxes_path, d))
68
+ next if d == "." || d == ".." || !File.directory?(File.join(env.boxes_path, d))
64
69
  results << d.to_s
65
70
  end
66
71
  end
@@ -74,9 +79,9 @@ module Vagrant
74
79
  #
75
80
  # @param [String] name The name of the box
76
81
  # @return [Box] Instance of {Box} representing the box found
77
- def find(name)
78
- return nil unless File.directory?(directory(name))
79
- new(name)
82
+ def find(env, name)
83
+ return nil unless File.directory?(directory(env, name))
84
+ new(env, name)
80
85
  end
81
86
 
82
87
  # Adds a new box with given name from the given URI. This method
@@ -85,10 +90,11 @@ module Vagrant
85
90
  #
86
91
  # @param [String] name The name of the box
87
92
  # @param [String] uri URI to the box file
88
- def add(name, uri)
93
+ def add(env, name, uri)
89
94
  box = new
90
95
  box.name = name
91
96
  box.uri = uri
97
+ box.env = env
92
98
  box.add
93
99
  end
94
100
 
@@ -98,8 +104,8 @@ module Vagrant
98
104
  #
99
105
  # @param [String] name Name of the box whose directory you're interested in.
100
106
  # @return [String] Full path to the box directory.
101
- def directory(name)
102
- File.join(Env.boxes_path, name)
107
+ def directory(env, name)
108
+ File.join(env.boxes_path, name)
103
109
  end
104
110
  end
105
111
 
@@ -109,8 +115,9 @@ module Vagrant
109
115
  #
110
116
  # **Note:** This method does not actually _create_ the box, but merely
111
117
  # returns a new, abstract representation of it. To add a box, see {#add}.
112
- def initialize(name=nil)
118
+ def initialize(env=nil, name=nil)
113
119
  @name = name
120
+ @env = env
114
121
  end
115
122
 
116
123
  # Returns path to the OVF file of the box. The OVF file is an open
@@ -139,7 +146,7 @@ module Vagrant
139
146
  #
140
147
  # @return [String]
141
148
  def directory
142
- self.class.directory(self.name)
149
+ self.class.directory(env, self.name)
143
150
  end
144
151
  end
145
152
  end
@@ -45,6 +45,13 @@ module Vagrant
45
45
  end
46
46
 
47
47
  def wait_for_not_busy(sleeptime=5)
48
+ if @@trap_thread
49
+ logger.info "Exiting vagrant immediately!"
50
+ Thread.kill(@@trap_thread)
51
+ abort
52
+ return # for tests
53
+ end
54
+
48
55
  @@trap_thread ||= Thread.new do
49
56
  # Wait while the app is busy
50
57
  loop do
@@ -0,0 +1,27 @@
1
+ module Vagrant
2
+ # This class handles commands from the command line program `vagrant`
3
+ # and redirects them to the proper sub-command, setting up the environment
4
+ # and executing.
5
+ class Command
6
+ attr_reader :env
7
+
8
+ class <<self
9
+ # Executes a given subcommand within the current environment (from the
10
+ # current working directory).
11
+ def execute(*args)
12
+ env = Environment.load!
13
+ env.commands.subcommand(*args)
14
+ end
15
+ end
16
+
17
+ def initialize(env)
18
+ @env = env
19
+ end
20
+
21
+ # Execute a subcommand with the given name and args. This method properly
22
+ # finds the subcommand, instantiates it, and executes.
23
+ def subcommand(*args)
24
+ Commands::Base.dispatch(env, *args)
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,163 @@
1
+ require 'optparse'
2
+
3
+ module Vagrant
4
+ class Commands
5
+ # This is the base command class which all sub-commands must
6
+ # inherit from. Subclasses of bases are expected to implement two
7
+ # methods: {#execute} and {#options_spec} (optional). The former
8
+ # defines the actual behavior of the command while the latter is a spec
9
+ # outlining the options that the command may take.
10
+ class Base
11
+ include Util
12
+
13
+ attr_reader :env
14
+
15
+ class <<self
16
+ # Contains the list of registered subcommands. The registered commands are
17
+ # stored in a hash table and are therefore unordered.
18
+ #
19
+ # @return [Hash]
20
+ def subcommands
21
+ @subcommands ||= {}
22
+ end
23
+
24
+ # Registers a command with `vagrant`. This method allows 3rd parties to
25
+ # dynamically add new commands to the `vagrant` command, allowing plugins
26
+ # to act as 1st class citizens within vagrant.
27
+ #
28
+ # @param [String] key The subcommand which will invoke the registered command.
29
+ # @param [Class] klass. The subcommand class (a subclass of {Base})
30
+ def subcommand(key, klass)
31
+ subcommands[key] = klass
32
+ end
33
+
34
+ # Dispatches a subcommand to the proper registered command. Otherwise, it
35
+ # prints a help message.
36
+ def dispatch(env, *args)
37
+ klass = subcommands[args[0]] unless args.empty?
38
+ if klass.nil?
39
+ # Run _this_ command!
40
+ command = self.new(env)
41
+ command.execute(args)
42
+ return
43
+ end
44
+
45
+ # Shift off the front arg, since we just consumed it in finding the
46
+ # subcommand.
47
+ args.shift
48
+
49
+ # Dispatch to the next class
50
+ klass.dispatch(env, *args)
51
+ end
52
+
53
+ # Prints out the list of supported commands and their descriptions (if
54
+ # available) then exits.
55
+ def puts_help
56
+ puts "Usage: vagrant SUBCOMMAND ...\n\n"
57
+
58
+ puts "Supported commands:"
59
+ subcommands.keys.sort.each do |key|
60
+ klass = subcommands[key]
61
+ next if klass.description.empty?
62
+
63
+ puts "#{' ' * 4}#{key.ljust(20)}#{klass.description}"
64
+ end
65
+
66
+ exit
67
+ end
68
+
69
+ # Sets or reads the description, depending on if the value is set in the
70
+ # parameter.
71
+ def description(value=nil)
72
+ @description ||= ''
73
+
74
+ return @description if value.nil?
75
+ @description = value
76
+ end
77
+ end
78
+
79
+ def initialize(env)
80
+ @env = env
81
+ end
82
+
83
+ # This method should be overriden by subclasses. This is the method
84
+ # which is called by {Vagrant::Command} when a command is being
85
+ # executed. The `args` parameter is an array of parameters to the
86
+ # command (similar to ARGV)
87
+ def execute(args)
88
+ parse_options(args)
89
+
90
+ if options[:version]
91
+ puts_version
92
+ else
93
+ # Just print out the help, since this top-level command does nothing
94
+ # on its own
95
+ self.class.puts_help
96
+ end
97
+ end
98
+
99
+ # This method is called by the base class to get the `optparse` configuration
100
+ # for the command.
101
+ def options_spec(opts)
102
+ opts.banner = "Usage: vagrant SUBCOMMAND"
103
+
104
+ opts.on("--version", "Output running Vagrant version.") do |v|
105
+ options[:version] = v
106
+ end
107
+ end
108
+
109
+ #-------------------------------------------------------------------
110
+ # Methods below are not meant to be overriden/implemented by subclasses
111
+ #-------------------------------------------------------------------
112
+
113
+ # Shows the version
114
+ def puts_version
115
+ File.open(File.join(PROJECT_ROOT, "VERSION"), "r") do |f|
116
+ puts f.read
117
+ end
118
+ end
119
+
120
+ # Returns the `OptionParser` instance to be used with this subcommand,
121
+ # based on the specs defined in {#options_spec}.
122
+ def option_parser(reload=false)
123
+ @option_parser = nil if reload
124
+ @option_parser ||= OptionParser.new do |opts|
125
+ options_spec(opts)
126
+ end
127
+ end
128
+
129
+ # The options for the given command. This will just be an empty hash
130
+ # until {#parse_options} is called.
131
+ def options
132
+ @options ||= {}
133
+ end
134
+
135
+ # Parse options out of the command-line. This method uses `optparse`
136
+ # to parse command line options.
137
+ def parse_options(args)
138
+ option_parser.parse!(args)
139
+ options
140
+ rescue OptionParser::InvalidOption
141
+ show_help
142
+ end
143
+
144
+ # Gets the description of the command. This is similar grabbed from the
145
+ # class level.
146
+ def description
147
+ self.class.description
148
+ end
149
+
150
+ # Prints the help for the given command. Prior to calling this method,
151
+ # {#parse_options} must be called or a nilerror will be raised. This
152
+ # is by design.
153
+ def show_help
154
+ if !description.empty?
155
+ puts "Description: #{description}"
156
+ end
157
+
158
+ puts option_parser.help
159
+ exit
160
+ end
161
+ end
162
+ end
163
+ end
@@ -0,0 +1,16 @@
1
+ module Vagrant
2
+ class Commands
3
+ # Manages the `vagrant box` command, allowing the user to add
4
+ # and remove boxes. This single command, given an array, determines
5
+ # which action to take and calls the respective action method
6
+ # (see {box_add} and {box_remove})
7
+ class BoxCommand < Base
8
+ Base.subcommand "box", self
9
+ description "Box commands"
10
+
11
+ def options_spec(opts)
12
+ opts.banner = "Usage: vagrant box SUBCOMMAND"
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,24 @@
1
+ module Vagrant
2
+ class Commands
3
+ # Adds a box to the local filesystem, given a URI.
4
+ module Box
5
+ class Add < BoxCommand
6
+ BoxCommand.subcommand "add", self
7
+ description "Add a box"
8
+
9
+ def execute(args)
10
+ if args.length != 2
11
+ show_help
12
+ return
13
+ end
14
+
15
+ Vagrant::Box.add(env, args[0], args[1])
16
+ end
17
+
18
+ def options_spec(opts)
19
+ opts.banner = "Usage: vagrant box add NAME URI"
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,30 @@
1
+ module Vagrant
2
+ class Commands
3
+ # Lists all added boxes
4
+ module Box
5
+ class List < BoxCommand
6
+ BoxCommand.subcommand "list", self
7
+ description "List all installed boxes"
8
+
9
+ def execute(args=[])
10
+ boxes = Vagrant::Box.all(env).sort
11
+
12
+ wrap_output do
13
+ if !boxes.empty?
14
+ puts "Installed Vagrant Boxes:\n\n"
15
+ boxes.each do |box|
16
+ puts box
17
+ end
18
+ else
19
+ puts "No Vagrant Boxes Added!"
20
+ end
21
+ end
22
+ end
23
+
24
+ def options_spec(opts)
25
+ opts.banner = "Usage: vagrant box list"
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,31 @@
1
+ module Vagrant
2
+ class Commands
3
+ # Removes a box permanently from the hard drive.
4
+ module Box
5
+ class Remove < BoxCommand
6
+ BoxCommand.subcommand "remove", self
7
+ description "Remove an installed box permanently."
8
+
9
+ def execute(args=[])
10
+ if args.length != 1
11
+ show_help
12
+ return
13
+ end
14
+
15
+
16
+ box = Vagrant::Box.find(env, args[0])
17
+ if box.nil?
18
+ error_and_exit(:box_remove_doesnt_exist)
19
+ return # for tests
20
+ end
21
+
22
+ box.destroy
23
+ end
24
+
25
+ def options_spec(opts)
26
+ opts.banner = "Usage: vagrant box remove NAME"
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,23 @@
1
+ module Vagrant
2
+ class Commands
3
+ # Destroys a vagrant instance. This not only shuts down the instance
4
+ # (if its running), but also deletes it from the system, including the
5
+ # hard disks associated with it.
6
+ #
7
+ # This command requires that an instance already be brought up with
8
+ # `vagrant up`.
9
+ class Destroy < Base
10
+ Base.subcommand "destroy", self
11
+ description "Destroys the vagrant environment"
12
+
13
+ def execute(args=[])
14
+ env.require_persisted_vm
15
+ env.vm.destroy
16
+ end
17
+
18
+ def options_spec(opts)
19
+ opts.banner = "Usage: vagrant destroy"
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,16 @@
1
+ module Vagrant
2
+ class Commands
3
+ # `vagrant down` is now `vagrant destroy`
4
+ class Down < Base
5
+ Base.subcommand "down", self
6
+
7
+ def execute(args=[])
8
+ error_and_exit(:command_deprecation_down)
9
+ end
10
+
11
+ def options_spec(opts)
12
+ opts.banner = "Usage: vagrant down"
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,23 @@
1
+ module Vagrant
2
+ class Commands
3
+ # Halts a running vagrant instance. This forcibly halts the instance;
4
+ # it is the equivalent of pulling the power on a machine. The instance
5
+ # can be restarted again with {up}.
6
+ #
7
+ # This command requires than an instance already be brought up with
8
+ # `vagrant up`.
9
+ class Halt < Base
10
+ Base.subcommand "halt", self
11
+ description "Halts the currently running vagrant environment"
12
+
13
+ def execute(args=[])
14
+ env.require_persisted_vm
15
+ env.vm.execute!(Actions::VM::Halt)
16
+ end
17
+
18
+ def options_spec(opts)
19
+ opts.banner = "Usage: vagrant halt"
20
+ end
21
+ end
22
+ end
23
+ end