bmabey-vagrant 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (115) hide show
  1. data/.gitignore +12 -0
  2. data/Gemfile +17 -0
  3. data/LICENSE +21 -0
  4. data/README.md +53 -0
  5. data/Rakefile +41 -0
  6. data/VERSION +1 -0
  7. data/bin/.gitignore +0 -0
  8. data/bin/vagrant +15 -0
  9. data/bin/vagrant-box +34 -0
  10. data/bin/vagrant-down +27 -0
  11. data/bin/vagrant-halt +28 -0
  12. data/bin/vagrant-init +27 -0
  13. data/bin/vagrant-package +29 -0
  14. data/bin/vagrant-reload +29 -0
  15. data/bin/vagrant-resume +27 -0
  16. data/bin/vagrant-ssh +27 -0
  17. data/bin/vagrant-status +29 -0
  18. data/bin/vagrant-suspend +27 -0
  19. data/bin/vagrant-up +29 -0
  20. data/config/default.rb +26 -0
  21. data/keys/README.md +10 -0
  22. data/keys/vagrant +27 -0
  23. data/keys/vagrant.pub +1 -0
  24. data/lib/vagrant.rb +19 -0
  25. data/lib/vagrant/actions/base.rb +118 -0
  26. data/lib/vagrant/actions/box/add.rb +22 -0
  27. data/lib/vagrant/actions/box/destroy.rb +14 -0
  28. data/lib/vagrant/actions/box/download.rb +72 -0
  29. data/lib/vagrant/actions/box/unpackage.rb +43 -0
  30. data/lib/vagrant/actions/collection.rb +36 -0
  31. data/lib/vagrant/actions/runner.rb +132 -0
  32. data/lib/vagrant/actions/vm/boot.rb +47 -0
  33. data/lib/vagrant/actions/vm/customize.rb +17 -0
  34. data/lib/vagrant/actions/vm/destroy.rb +23 -0
  35. data/lib/vagrant/actions/vm/down.rb +12 -0
  36. data/lib/vagrant/actions/vm/export.rb +41 -0
  37. data/lib/vagrant/actions/vm/forward_ports.rb +46 -0
  38. data/lib/vagrant/actions/vm/halt.rb +14 -0
  39. data/lib/vagrant/actions/vm/import.rb +18 -0
  40. data/lib/vagrant/actions/vm/move_hard_drive.rb +51 -0
  41. data/lib/vagrant/actions/vm/package.rb +65 -0
  42. data/lib/vagrant/actions/vm/provision.rb +49 -0
  43. data/lib/vagrant/actions/vm/reload.rb +17 -0
  44. data/lib/vagrant/actions/vm/resume.rb +16 -0
  45. data/lib/vagrant/actions/vm/shared_folders.rb +81 -0
  46. data/lib/vagrant/actions/vm/start.rb +18 -0
  47. data/lib/vagrant/actions/vm/suspend.rb +16 -0
  48. data/lib/vagrant/actions/vm/up.rb +40 -0
  49. data/lib/vagrant/active_list.rb +73 -0
  50. data/lib/vagrant/box.rb +152 -0
  51. data/lib/vagrant/busy.rb +73 -0
  52. data/lib/vagrant/commands.rb +219 -0
  53. data/lib/vagrant/config.rb +183 -0
  54. data/lib/vagrant/downloaders/base.rb +16 -0
  55. data/lib/vagrant/downloaders/file.rb +17 -0
  56. data/lib/vagrant/downloaders/http.rb +47 -0
  57. data/lib/vagrant/environment.rb +263 -0
  58. data/lib/vagrant/provisioners/base.rb +29 -0
  59. data/lib/vagrant/provisioners/chef.rb +103 -0
  60. data/lib/vagrant/provisioners/chef_server.rb +84 -0
  61. data/lib/vagrant/provisioners/chef_solo.rb +97 -0
  62. data/lib/vagrant/ssh.rb +104 -0
  63. data/lib/vagrant/util.rb +51 -0
  64. data/lib/vagrant/util/errors.rb +36 -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 +61 -0
  68. data/templates/Vagrantfile.erb +8 -0
  69. data/templates/errors.yml +117 -0
  70. data/test/test_helper.rb +163 -0
  71. data/test/vagrant/actions/base_test.rb +32 -0
  72. data/test/vagrant/actions/box/add_test.rb +37 -0
  73. data/test/vagrant/actions/box/destroy_test.rb +18 -0
  74. data/test/vagrant/actions/box/download_test.rb +131 -0
  75. data/test/vagrant/actions/box/unpackage_test.rb +100 -0
  76. data/test/vagrant/actions/collection_test.rb +110 -0
  77. data/test/vagrant/actions/runner_test.rb +265 -0
  78. data/test/vagrant/actions/vm/boot_test.rb +55 -0
  79. data/test/vagrant/actions/vm/customize_test.rb +16 -0
  80. data/test/vagrant/actions/vm/destroy_test.rb +36 -0
  81. data/test/vagrant/actions/vm/down_test.rb +32 -0
  82. data/test/vagrant/actions/vm/export_test.rb +88 -0
  83. data/test/vagrant/actions/vm/forward_ports_test.rb +104 -0
  84. data/test/vagrant/actions/vm/halt_test.rb +27 -0
  85. data/test/vagrant/actions/vm/import_test.rb +43 -0
  86. data/test/vagrant/actions/vm/move_hard_drive_test.rb +108 -0
  87. data/test/vagrant/actions/vm/package_test.rb +181 -0
  88. data/test/vagrant/actions/vm/provision_test.rb +108 -0
  89. data/test/vagrant/actions/vm/reload_test.rb +47 -0
  90. data/test/vagrant/actions/vm/resume_test.rb +27 -0
  91. data/test/vagrant/actions/vm/shared_folders_test.rb +176 -0
  92. data/test/vagrant/actions/vm/start_test.rb +36 -0
  93. data/test/vagrant/actions/vm/suspend_test.rb +27 -0
  94. data/test/vagrant/actions/vm/up_test.rb +107 -0
  95. data/test/vagrant/active_list_test.rb +190 -0
  96. data/test/vagrant/box_test.rb +151 -0
  97. data/test/vagrant/busy_test.rb +83 -0
  98. data/test/vagrant/commands_test.rb +307 -0
  99. data/test/vagrant/config_test.rb +256 -0
  100. data/test/vagrant/downloaders/base_test.rb +27 -0
  101. data/test/vagrant/downloaders/file_test.rb +26 -0
  102. data/test/vagrant/downloaders/http_test.rb +40 -0
  103. data/test/vagrant/environment_test.rb +607 -0
  104. data/test/vagrant/provisioners/base_test.rb +33 -0
  105. data/test/vagrant/provisioners/chef_server_test.rb +187 -0
  106. data/test/vagrant/provisioners/chef_solo_test.rb +149 -0
  107. data/test/vagrant/provisioners/chef_test.rb +117 -0
  108. data/test/vagrant/ssh_test.rb +222 -0
  109. data/test/vagrant/util/errors_test.rb +57 -0
  110. data/test/vagrant/util/stacked_proc_runner_test.rb +43 -0
  111. data/test/vagrant/util/template_renderer_test.rb +138 -0
  112. data/test/vagrant/util_test.rb +64 -0
  113. data/test/vagrant/vm_test.rb +114 -0
  114. data/vagrant.gemspec +216 -0
  115. metadata +285 -0
@@ -0,0 +1,18 @@
1
+ module Vagrant
2
+ module Actions
3
+ module VM
4
+ class Start < Base
5
+ def prepare
6
+ # Start is a "meta-action" so it really just queues up a bunch
7
+ # of other actions in its place:
8
+ steps = [ForwardPorts, SharedFolders, Boot]
9
+ steps.unshift(Customize) unless @runner.vm.saved?
10
+
11
+ steps.each do |action_klass|
12
+ @runner.add_action(action_klass)
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,16 @@
1
+ module Vagrant
2
+ module Actions
3
+ module VM
4
+ class Suspend < Base
5
+ def execute!
6
+ if !@runner.vm.running?
7
+ raise ActionException.new(:vm_not_running_for_suspend)
8
+ end
9
+
10
+ logger.info "Saving VM state and suspending execution..."
11
+ @runner.vm.save_state(true)
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,40 @@
1
+ module Vagrant
2
+ module Actions
3
+ module VM
4
+ class Up < Base
5
+ def prepare
6
+ # If the dotfile is not a file, raise error
7
+ if File.exist?(@runner.env.dotfile_path) && !File.file?(@runner.env.dotfile_path)
8
+ raise ActionException.new(:dotfile_error, :env => @runner.env)
9
+ end
10
+
11
+ # Up is a "meta-action" so it really just queues up a bunch
12
+ # of other actions in its place:
13
+ steps = [Import, Customize, ForwardPorts, SharedFolders, Boot]
14
+ steps << Provision if !@runner.env.config.vm.provisioner.nil?
15
+ steps.insert(0, MoveHardDrive) if @runner.env.config.vm.hd_location
16
+
17
+ steps.each do |action_klass|
18
+ @runner.add_action(action_klass)
19
+ end
20
+ end
21
+
22
+ def after_import
23
+ persist
24
+ setup_mac_address
25
+ end
26
+
27
+ def persist
28
+ logger.info "Persisting the VM UUID (#{@runner.uuid})..."
29
+ @runner.env.persist_vm
30
+ end
31
+
32
+ def setup_mac_address
33
+ logger.info "Matching MAC addresses..."
34
+ @runner.vm.nics.first.macaddress = @runner.env.config.vm.base_mac
35
+ @runner.vm.save(true)
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,73 @@
1
+ module Vagrant
2
+ # This class represents the active list of vagrant virtual
3
+ # machines.
4
+ class ActiveList
5
+ FILENAME = "active.json"
6
+
7
+ @@list = nil
8
+
9
+ # The environment this active list belongs to
10
+ attr_accessor :env
11
+
12
+ # Creates the instance of the ActiveList, with the given environment
13
+ # if specified
14
+ def initialize(env=nil)
15
+ @env = env
16
+ end
17
+
18
+ # Parses and returns the list of UUIDs from the active VM
19
+ # JSON file. This will cache the result, which can be reloaded
20
+ # by setting the `reload` parameter to true.
21
+ #
22
+ # @return [Array<String>]
23
+ def list(reload=false)
24
+ return @list unless @list.nil? || reload
25
+
26
+ @list ||= []
27
+ return @list unless File.file?(path)
28
+ File.open(path, "r") do |f|
29
+ @list = JSON.parse(f.read)
30
+ end
31
+
32
+ @list
33
+ end
34
+
35
+ # Returns an array of {Vagrant::VM} objects which are currently
36
+ # active.
37
+ def vms
38
+ list.collect { |uuid| Vagrant::VM.find(uuid) }.compact
39
+ end
40
+
41
+ # Returns an array of UUIDs filtered so each is verified to exist.
42
+ def filtered_list
43
+ vms.collect { |vm| vm.uuid }
44
+ end
45
+
46
+ # Adds a virtual environment to the list of active virtual machines
47
+ def add(vm)
48
+ list << vm.uuid
49
+ list.uniq!
50
+ save
51
+ end
52
+
53
+ # Remove a virtual environment from the list of active virtual machines
54
+ def remove(vm)
55
+ vm = vm.uuid if vm.is_a?(Vagrant::VM)
56
+ list.delete(vm)
57
+ save
58
+ end
59
+
60
+ # Persists the list down to the JSON file.
61
+ def save
62
+ File.open(path, "w+") do |f|
63
+ f.write(filtered_list.to_json)
64
+ end
65
+ end
66
+
67
+ # Returns the path to the JSON file which holds the UUIDs of the
68
+ # active virtual machines managed by Vagrant.
69
+ def path
70
+ File.join(env.home_path, FILENAME)
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,152 @@
1
+ module Vagrant
2
+ # Represents a "box," which is simply a packaged vagrant environment.
3
+ # Boxes are simply `tar` files which contain an exported VirtualBox
4
+ # virtual machine, at the least. They are created with `vagrant package`
5
+ # and may contain additional files if specified by the creator. This
6
+ # class serves to help manage these boxes, although most of the logic
7
+ # is kicked out to actions.
8
+ #
9
+ # What can the {Box} class do?
10
+ #
11
+ # * Find boxes
12
+ # * Add existing boxes (from some URI)
13
+ # * Delete existing boxes
14
+ #
15
+ # # Finding Boxes
16
+ #
17
+ # Using the {Box.find} method, you can search for existing boxes. This
18
+ # method will return `nil` if none is found or an instance of {Box}
19
+ # otherwise.
20
+ #
21
+ # box = Vagrant::Box.find("base")
22
+ # if box.nil?
23
+ # puts "Box not found!"
24
+ # else
25
+ # puts "Box exists at #{box.directory}"
26
+ # end
27
+ #
28
+ # # Adding a Box
29
+ #
30
+ # Boxes can be added from any URI. Some schemas aren't supported; if this
31
+ # is the case, the error will output to the logger.
32
+ #
33
+ # Vagrant::Box.add("foo", "http://myfiles.com/foo.box")
34
+ #
35
+ # # Destroying a box
36
+ #
37
+ # Boxes can be deleted as well. This method is _final_ and there is no way
38
+ # to undo this action once it is completed.
39
+ #
40
+ # box = Vagrant::Box.find("foo")
41
+ # box.destroy
42
+ #
43
+ class Box < Actions::Runner
44
+ # The name of the box.
45
+ attr_accessor :name
46
+
47
+ # The URI for a new box. This is not available for existing boxes.
48
+ attr_accessor :uri
49
+
50
+ # The temporary path to the downloaded or copied box. This should
51
+ # only be used internally.
52
+ attr_accessor :temp_path
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
+
59
+ class <<self
60
+ # Returns an array of all created boxes, as strings.
61
+ #
62
+ # @return [Array<String>]
63
+ def all(env)
64
+ results = []
65
+
66
+ Dir.open(env.boxes_path) do |dir|
67
+ dir.each do |d|
68
+ next if d == "." || d == ".." || !File.directory?(File.join(env.boxes_path, d))
69
+ results << d.to_s
70
+ end
71
+ end
72
+
73
+ results
74
+ end
75
+
76
+ # Finds a box with the given name. This method searches for a box
77
+ # with the given name, returning `nil` if none is found or returning
78
+ # a {Box} instance otherwise.
79
+ #
80
+ # @param [String] name The name of the box
81
+ # @return [Box] Instance of {Box} representing the box found
82
+ def find(env, name)
83
+ return nil unless File.directory?(directory(env, name))
84
+ new(env, name)
85
+ end
86
+
87
+ # Adds a new box with given name from the given URI. This method
88
+ # begins the process of adding a box from a given URI by setting up
89
+ # the {Box} instance and calling {#add}.
90
+ #
91
+ # @param [String] name The name of the box
92
+ # @param [String] uri URI to the box file
93
+ def add(env, name, uri)
94
+ box = new
95
+ box.name = name
96
+ box.uri = uri
97
+ box.env = env
98
+ box.add
99
+ end
100
+
101
+ # Returns the directory to a box of the given name. The name given
102
+ # as a parameter is not checked for existence; this method simply
103
+ # returns the directory which would be used if the box did exist.
104
+ #
105
+ # @param [String] name Name of the box whose directory you're interested in.
106
+ # @return [String] Full path to the box directory.
107
+ def directory(env, name)
108
+ File.join(env.boxes_path, name)
109
+ end
110
+ end
111
+
112
+ # Creates a new box instance. Given an optional `name` parameter,
113
+ # newly created instance will have that name, otherwise it defaults
114
+ # to `nil`.
115
+ #
116
+ # **Note:** This method does not actually _create_ the box, but merely
117
+ # returns a new, abstract representation of it. To add a box, see {#add}.
118
+ def initialize(env=nil, name=nil)
119
+ @name = name
120
+ @env = env
121
+ end
122
+
123
+ # Returns path to the OVF file of the box. The OVF file is an open
124
+ # virtual machine file which contains specifications of the exported
125
+ # virtual machine this box contains.
126
+ #
127
+ # @return [String]
128
+ def ovf_file
129
+ File.join(directory, Vagrant.config.vm.box_ovf)
130
+ end
131
+
132
+ # Begins the process of adding a box to the vagrant installation. This
133
+ # method requires that `name` and `uri` be set. The logic of this method
134
+ # is kicked out to the {Actions::Box::Add add box} action.
135
+ def add
136
+ execute!(Actions::Box::Add)
137
+ end
138
+
139
+ # Beings the process of destroying this box.
140
+ def destroy
141
+ execute!(Actions::Box::Destroy)
142
+ end
143
+
144
+ # Returns the directory to the location of this boxes content in the local
145
+ # filesystem.
146
+ #
147
+ # @return [String]
148
+ def directory
149
+ self.class.directory(env, self.name)
150
+ end
151
+ end
152
+ end
@@ -0,0 +1,73 @@
1
+ module Vagrant
2
+ def self.busy?
3
+ Busy.busy?
4
+ end
5
+
6
+ def self.busy(&block)
7
+ Busy.busy(&block)
8
+ end
9
+
10
+ class Busy
11
+ extend Vagrant::Util
12
+
13
+ @@busy = false
14
+ @@mutex = Mutex.new
15
+ @@trap_thread = nil
16
+
17
+ class << self
18
+ def busy?
19
+ @@busy
20
+ end
21
+
22
+ def busy=(val)
23
+ @@busy = val
24
+ end
25
+
26
+ def busy(&block)
27
+ @@mutex.synchronize do
28
+ begin
29
+ Signal.trap("INT") { wait_for_not_busy }
30
+ Busy.busy = true
31
+ runner = Thread.new(block) { block.call }
32
+ runner.join
33
+ ensure
34
+ # In the case an exception is thrown, make sure we restore
35
+ # busy back to some sane state.
36
+ Busy.busy = false
37
+
38
+ # Make sure that the trap thread completes, if it is running
39
+ trap_thread.join if trap_thread
40
+
41
+ # And restore the INT trap to the default
42
+ Signal.trap("INT", "DEFAULT")
43
+ end
44
+ end
45
+ end
46
+
47
+ def wait_for_not_busy(sleeptime=5)
48
+ @@trap_thread ||= Thread.new do
49
+ # Wait while the app is busy
50
+ loop do
51
+ break unless busy?
52
+ logger.info "Waiting for vagrant to clean itself up..."
53
+ sleep sleeptime
54
+ end
55
+
56
+ # Exit out of the entire script
57
+ logger.info "Exiting vagrant..."
58
+ exit
59
+ end
60
+ end
61
+
62
+ # Used for testing
63
+ def reset_trap_thread!
64
+ @@trap_thread = nil
65
+ end
66
+
67
+ # Returns the trap thread
68
+ def trap_thread
69
+ @@trap_thread
70
+ end
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,219 @@
1
+ module Vagrant
2
+ # Contains all the command-line commands invoked by the
3
+ # binaries. Having them all in one location assists with
4
+ # documentation and also takes the commands out of some of
5
+ # the other classes.
6
+ class Commands
7
+ include Vagrant::Util
8
+
9
+ # The environment which these commands will act on
10
+ attr_reader :env
11
+
12
+ # Initialize a new {Commands} instance for the given environment.
13
+ # This merely prepares the {env} variable.
14
+ def initialize(env)
15
+ @env = env
16
+ end
17
+
18
+ # Bring up a vagrant instance. This handles everything from importing
19
+ # the base VM, setting up shared folders, forwarded ports, etc to
20
+ # provisioning the instance with chef. {up} also starts the instance,
21
+ # running it in the background.
22
+ def up
23
+ if env.vm
24
+ logger.info "VM already created. Starting VM if its not already running..."
25
+ env.vm.start
26
+ else
27
+ env.require_box
28
+ env.create_vm.execute!(Actions::VM::Up)
29
+ end
30
+ end
31
+
32
+ # Tear down a vagrant instance. This not only shuts down the instance
33
+ # (if its running), but also deletes it from the system, including the
34
+ # hard disks associated with it.
35
+ #
36
+ # This command requires that an instance already be brought up with
37
+ # `vagrant up`.
38
+ def down
39
+ env.require_persisted_vm
40
+ env.vm.destroy
41
+ end
42
+
43
+ # Reload the environment. This is almost equivalent to the {up} command
44
+ # except that it doesn't import the VM and do the initialize bootstrapping
45
+ # of the instance. Instead, it forces a shutdown (if its running) of the
46
+ # VM, updates the metadata (shared folders, forwarded ports), restarts
47
+ # the VM, and then reruns the provisioning if enabled.
48
+ def reload
49
+ env.require_persisted_vm
50
+ env.vm.execute!(Actions::VM::Reload)
51
+ end
52
+
53
+ # SSH into the vagrant instance. This will setup an SSH connection into
54
+ # the vagrant instance, replacing the running ruby process with the SSH
55
+ # connection.
56
+ #
57
+ # This command requires that an instance already be brought up with
58
+ # `vagrant up`.
59
+ def ssh
60
+ env.require_persisted_vm
61
+ env.ssh.connect
62
+ end
63
+
64
+ # Halts a running vagrant instance. This forcibly halts the instance;
65
+ # it is the equivalent of pulling the power on a machine. The instance
66
+ # can be restarted again with {up}.
67
+ #
68
+ # This command requires than an instance already be brought up with
69
+ # `vagrant up`.
70
+ def halt
71
+ env.require_persisted_vm
72
+ env.vm.execute!(Actions::VM::Halt)
73
+ end
74
+
75
+ # Suspend a running vagrant instance. This suspends the instance, saving
76
+ # the state of the VM and "pausing" it. The instance can be resumed
77
+ # again with {resume}.
78
+ #
79
+ # This command requires that an instance already be brought up with
80
+ # `vagrant up`.
81
+ def suspend
82
+ env.require_persisted_vm
83
+ env.vm.suspend
84
+ end
85
+
86
+ # Resume a running vagrant instance. This resumes an already suspended
87
+ # instance (from {suspend}).
88
+ #
89
+ # This command requires that an instance already be brought up with
90
+ # `vagrant up`.
91
+ def resume
92
+ env.require_persisted_vm
93
+ env.vm.resume
94
+ end
95
+
96
+ # Export and package the current vm
97
+ #
98
+ # This command requires that an instance be powered off
99
+ def package(out_path=nil, include_files=[])
100
+ env.require_persisted_vm
101
+ error_and_exit(:vm_power_off_to_package) unless env.vm.powered_off?
102
+
103
+ env.vm.package(out_path, include_files)
104
+ end
105
+
106
+ # Manages the `vagrant box` command, allowing the user to add
107
+ # and remove boxes. This single command, given an array, determines
108
+ # which action to take and calls the respective action method
109
+ # (see {box_add} and {box_remove})
110
+ def box(argv)
111
+ sub_commands = ["list", "add", "remove"]
112
+
113
+ if !sub_commands.include?(argv[0])
114
+ error_and_exit(:command_box_invalid)
115
+ end
116
+
117
+ send("box_#{argv[0]}", env, *argv[1..-1])
118
+ end
119
+
120
+ # Lists all added boxes
121
+ def box_list(env)
122
+ boxes = Box.all(env).sort
123
+
124
+ wrap_output do
125
+ if !boxes.empty?
126
+ puts "Installed Vagrant Boxes:\n\n"
127
+ boxes.each do |box|
128
+ Kernel.puts box
129
+ end
130
+ else
131
+ Kernel.puts "No Vagrant Boxes Added!"
132
+ end
133
+ end
134
+ end
135
+
136
+ # Adds a box to the local filesystem, given a URI.
137
+ def box_add(env, name, path)
138
+ Box.add(env, name, path)
139
+ end
140
+
141
+ # Removes a box.
142
+ def box_remove(env, name)
143
+ box = Box.find(env, name)
144
+ if box.nil?
145
+ error_and_exit(:box_remove_doesnt_exist)
146
+ return # for tests
147
+ end
148
+
149
+ box.destroy
150
+ end
151
+
152
+ # Outputs the status of the current environment. This command outputs
153
+ # useful information such as whether or not the environment is created
154
+ # and if its running, suspended, etc.
155
+ def status
156
+ wrap_output do
157
+ if !env.vm
158
+ puts <<-msg
159
+ The environment has not yet been created. Run `vagrant up` to create the
160
+ environment.
161
+ msg
162
+ else
163
+ additional_msg = ""
164
+ if env.vm.vm.running?
165
+ additional_msg = <<-msg
166
+ To stop this VM, you can run `vagrant halt` to shut it down forcefully,
167
+ or you can run `vagrant suspend` to simply suspend the virtual machine.
168
+ In either case, to restart it again, simply run a `vagrant up`.
169
+ msg
170
+ elsif env.vm.vm.saved?
171
+ additional_msg = <<-msg
172
+ To resume this VM, simply run `vagrant up`.
173
+ msg
174
+ elsif env.vm.vm.powered_off?
175
+ additional_msg = <<-msg
176
+ To restart this VM, simply run `vagrant up`.
177
+ msg
178
+ end
179
+
180
+ if !additional_msg.empty?
181
+ additional_msg.chomp!
182
+ additional_msg = "\n\n#{additional_msg}"
183
+ end
184
+
185
+ puts <<-msg
186
+ The environment has been created. The status of the current environment's
187
+ virtual machine is: "#{env.vm.vm.state}."#{additional_msg}
188
+ msg
189
+ end
190
+ end
191
+ end
192
+
193
+ class << self
194
+ # Initializes a directory for use with vagrant. This command copies an
195
+ # initial `Vagrantfile` into the current working directory so you can
196
+ # begin using vagrant. The configuration file contains some documentation
197
+ # to get you started.
198
+ def init(default_box=nil)
199
+ rootfile_path = File.join(Dir.pwd, Environment::ROOTFILE_NAME)
200
+ if File.exist?(rootfile_path)
201
+ error_and_exit(:rootfile_already_exists)
202
+ end
203
+
204
+ # Copy over the rootfile template into this directory
205
+ default_box ||= "base"
206
+ File.open(rootfile_path, 'w+') do |f|
207
+ f.write(TemplateRenderer.render(Environment::ROOTFILE_NAME, :default_box => default_box))
208
+ end
209
+ end
210
+
211
+ # Runs a command in the current environment by loading the environment
212
+ # of the current working directory prior to executing.
213
+ def execute(command, *args)
214
+ env = Environment.load!
215
+ env.commands.send(command, *args)
216
+ end
217
+ end
218
+ end
219
+ end