vagrant 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
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