vgrnt 0.0.2 → 0.0.3

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: fb4cac36b1177589050fa58858980c56079b17de
4
- data.tar.gz: 416ceaa0f01fb0180beebcef368b875a8c22f77d
3
+ metadata.gz: 03a6d4695c381a141cfe79bc0e9e1f59a935b86f
4
+ data.tar.gz: 715132621d0eca3a4e2d56b9193fcabbd14c9c13
5
5
  SHA512:
6
- metadata.gz: 862fd1c84e7e9c1bd8b7b1a89b4e24f6bef0848d771cce4aa906fad992052a697d391b79b22acd84bdd16d77fc43fcc5b7f4cac392a3a192ecb65e8faa6f088f
7
- data.tar.gz: 295bac036eab4ea6fdb88959080803d5d0bc63e7032926f1e3323a913b7c02c63537be72cec99caa1f8f22bb9e20eb93ad62a21d6b3669b6f8d28cce9a3c57c6
6
+ metadata.gz: ff27c6d4a016745f9b270a37c3b4ead82389e309384065ed121b98bcf3b3c96251e2a2c300b7fc80f1cf746a4599b29387288eb4bac5d78b6661a0d62c6e725f
7
+ data.tar.gz: 1fbb99c60ba3c748d8921c8349e2a93cda9396b49f8fe1f1582a199acb1a8b2ba24bbf213694b50dfca267eb0faa25101090c918aebcdc6d74739f0647072f9e
data/.gitignore CHANGED
@@ -1 +1,6 @@
1
1
  pkg/
2
+ vendor
3
+ .rspec
4
+ Gemfile.lock
5
+ .bundle
6
+ .vagrant
@@ -0,0 +1,4 @@
1
+ language: "ruby"
2
+ rvm:
3
+ - "1.8.7"
4
+ - "1.9.3"
@@ -1,3 +1,14 @@
1
+ ## [0.0.3](https://github.com/dergachev/vagrant/compare/v0.0.2...v0.0.3) (Nov 12, 2013)
2
+
3
+ FEATURES:
4
+
5
+ - Added support for `vgrnt status`
6
+
7
+ IMPROVEMENTS:
8
+
9
+ - Refactored codebase a bit
10
+ - Implemented acceptance tests (unit tests still non-existant)
11
+
1
12
  ## [0.0.2](https://github.com/dergachev/vagrant/compare/v0.0.1...v0.0.2) (Oct 30, 2013)
2
13
 
3
14
  BUGFIX:
data/Gemfile CHANGED
File without changes
data/README.md CHANGED
@@ -1,29 +1,38 @@
1
- vgrnt
1
+ vgrnt [![Gem Version](https://badge.fury.io/rb/vgrnt.png)](http://badge.fury.io/rb/vgrnt) [![Build Status](https://travis-ci.org/dergachev/vgrnt.png)](https://travis-ci.org/dergachev/vgrnt)
2
2
  =====
3
3
 
4
- [![Gem Version](https://badge.fury.io/rb/vgrnt.png)](http://badge.fury.io/rb/vgrnt)
5
-
6
4
  `vgrnt` is a partial reimplementation of a few `vagrant` operations that I
7
- found to be unbearably slow. For example:
5
+ found to be unbearably slow in my typical usage. Here's a benchmark on my
6
+ quad-core 2013 MacBook Pro:
8
7
 
9
8
  ```bash
10
- time vagrant ssh -- '/bin/true'
11
- # real 0m1.969s
9
+ time vagrant status
10
+ # real 0m2.895s
12
11
 
13
- time vgrnt ssh -- '/bin/true'
14
- # real 0m0.538s
12
+ time vgrnt status
13
+ # real 0m0.316s
15
14
  ```
16
15
 
17
- It achieves this by naively reimplementing these commands, without requiring
18
- superfluous gems (not even vagrant) or parsing the Vagrantfile. Given how
19
- ashamed I am of such ugly hacks, the name `vgrnt` was chosen to be deliberately
20
- unpronouncable. If you must use it, probably best to keep it to yourself.
16
+ This is achieved by naively reimplementing these commands, without requiring
17
+ superfluous gems. Given how ashamed I am of the ugly hacks involved, the name
18
+ `vgrnt` was chosen to be deliberately unpronouncable. If you must use it,
19
+ probably best to keep it to yourself.
21
20
 
21
+ ## Usage
22
22
 
23
- ## vgrnt ssh
23
+ ### vgrnt status
24
24
 
25
- Same as `vagrant ssh` but faster. Will read `.vgrnt-sshconfig` file for SSH options, or try to
26
- guess the options by shelling out to VBoxManage.
25
+ Same as `vagrant status` but faster.
26
+
27
+ ```
28
+ vgrnt status
29
+ ```
30
+
31
+ Does its dirty work by sneaking around in your Vagrantfile and the `./.vagrant` directory.
32
+
33
+ ### vgrnt ssh
34
+
35
+ Same as `vagrant ssh` but faster.
27
36
 
28
37
  ```
29
38
  vgrnt ssh
@@ -31,7 +40,11 @@ vgrnt ssh vm-name # supports multi-vm environments
31
40
  vgrnt ssh -- ls /tmp # extra ssh args after --
32
41
  ```
33
42
 
34
- ## vgrnt ssh-config
43
+ Will read `.vgrnt-sshconfig` file for SSH options, or try to
44
+ guess the options by shelling out to VBoxManage.
45
+
46
+
47
+ ### vgrnt ssh-config
35
48
 
36
49
  Runs `vgrnt ssh-config > .vgrnt-sshconfig`. Use this if `vgrnt ssh` doesn't
37
50
  seem to work, because you have a non-standard setup.
@@ -43,7 +56,7 @@ vgrnt ssh-config
43
56
  vgrnt ssh-config vm-name # supports multi-vm environments
44
57
  ```
45
58
 
46
- ## vgrnt vboxmanage
59
+ ### vgrnt vboxmanage
47
60
 
48
61
  Simplifies calling `VBoxManage` on the already created VM. Injects
49
62
  the VM ID (eg 0398e43a-d35f-4c84-bc81-6807f5d11262) in the right spot.
@@ -64,49 +77,84 @@ vgrnt vboxmanage metrics query VM_ID
64
77
  # => VBoxManage metrics query 0398e43a-d35f-4c84-bc81-6807f5d11262
65
78
  ```
66
79
 
67
- ## TODO
80
+ ## Installation
68
81
 
69
- * vgrnt status (can pull it out from vboxmanage)
70
- * vgrnt reprovision (equivalent to running `vagrant ssh -- chef-solo /tmp...`
71
- * vgrnt destroy (how hard is it to kill a VM??)
72
- * vgrnt snapshot (it's currently implemented as a vagrant plugin, but who needs decoupling?)
82
+ vgrnt *should not* be installed as a vagrant plugin. Instead, just install the gem:
73
83
 
74
- ## Caveats
84
+ gem install vgrnt --no-rdoc --no-ri
75
85
 
86
+ vgrnt only works with Vagrant 1.1+ running on Linux/OSX, with the VirtualBox provider.
76
87
 
77
- * At the moment, it requires OSX/Linux and Virtualbox.
78
- * Only works from vagrant project root, not in a subfolder
79
- * Tests, what tests?
88
+ ## Why is Vagrant slow?
80
89
 
81
- ## Installation
90
+ Vagrant itself isn't actually slow. The lag is mostly as a result of popular
91
+ but poorly constructed plugins:
82
92
 
83
- vgrnt *should not* be installed as a vagrant plugin. Instead, simply
84
- Ensure you have Vagrant 1.1+ installed, then run:
93
+ ```bash
94
+ time vgrnt ssh -- '/bin/true'
95
+ # real 0m0.387s
85
96
 
86
- gem install vgrnt --no-rdoc --no-ri
97
+ time vagrant ssh -- '/bin/true'
98
+ # real 0m2.102s
99
+
100
+ for P in $(vagrant plugin list | awk '{print $1}' ) ; do
101
+ vagrant plugin uninstall $P
102
+ done
103
+ # Uninstalling the 'vagrant-berkshelf' plugin...
104
+ # Uninstalling the 'vagrant-cachier' plugin...
105
+ # Uninstalling the 'vagrant-omnibus' plugin...
106
+
107
+ time vagrant ssh -- '/bin/true'
108
+ # real 0m0.716s
109
+ ```
87
110
 
111
+ In my case, the culprit is [vagrant-berkshelf eager-loading
112
+ dependencies](https://github.com/RiotGames/vagrant-berkshelf/issues/101).
113
+ However, any vagrant plugins introduce lag, so perhaps Vagrant's plugin
114
+ architecture could be modified to make this less of a problem.
115
+
116
+ ## Caveats
117
+
118
+ * At the moment, it requires OSX/Linux and Virtualbox.
119
+ * Only works from vagrant project root, not in a subfolder
120
+
121
+ ## Todo
122
+
123
+ * Ipmlement `vgrnt reprovision`
124
+ - roughly equivalent to running `vagrant ssh -- chef-solo /tmp...`
125
+ * Integrate `vagrant-vbox-snapshot` plugin.
126
+ * Simplify everything by using VAGRANT_NO_PLUGINS env variable
127
+ - See https://github.com/mitchellh/vagrant/blob/master/lib/vagrant.rb#L179
88
128
 
89
129
  ## Development
90
130
 
91
- To develop on this plugin, do the following:
131
+ To hack on this plugin, do the following:
92
132
 
93
133
  ```
94
- # get the repo, and then make a feature branch (REPLACE WITH YOUR FORK)
95
- git clone https://github.com/dergachev/vagrant-vboxmanage.git
96
- cd vagrant-vboxmanage
134
+ # fork the repo to your account
135
+
136
+ # clone your fork, and create a feature branch to work on
137
+ git clone https://github.com/USERNAME/vgrnt.git
138
+ cd vgrnt
97
139
  git checkout -b MY-NEW-FEATURE
98
140
 
99
141
  # installs the vagrant gem, which is a dev dependency
100
- bundle install
142
+ bundle install
101
143
 
102
144
  # hack on the plugin
103
- vim lib/vagrant-vboxmanage.rb # or any other file
145
+ vim lib/vgrnt/base.rb # or any other file
146
+
147
+ # test out your changes in the context of this repo
148
+ cd spec/acceptance/fixtures/simple
149
+ bundle exec vgrnt ssh -- 'ls /tmp'
104
150
 
105
- # test out your changes, in the context provided by the development vagrant gem, and the local Vagrantfile.
106
- bundle exec vagrant snapshot ...
151
+ # run ALL the tests (not just unit)
152
+ bundle exec rake acceptance:prepare # spin up VMs to test against
153
+ bundle exec rake spec
154
+ bundle exec rake acceptance:clean # destroy testing VMs
107
155
 
108
156
  # commit, push, and do a pull-request
109
157
  ```
110
158
 
111
- See [DEVNOTES.md](https://github.com/dergachev/vagrant-vboxmanage/blob/master/DEVNOTES.md)
159
+ See [DEVNOTES.md](https://github.com/dergachev/vgrnt/blob/master/docs/DEVNOTES.md)
112
160
  for the notes I compiled while developing this plugin.
data/Rakefile CHANGED
@@ -1,2 +1,46 @@
1
1
  require 'bundler'
2
+ require 'rspec/core/rake_task'
3
+
2
4
  Bundler::GemHelper.install_tasks
5
+
6
+ RSpec::Core::RakeTask.new(:spec)
7
+
8
+ desc "Run unit tests"
9
+ RSpec::Core::RakeTask.new('spec:unit') { |t| t.pattern = "./spec/unit/**/*_spec.rb" }
10
+
11
+ desc "Run acceptance tests (requires VBoxManage)"
12
+ RSpec::Core::RakeTask.new('spec:acceptance') { |t| t.pattern = "./spec/acceptance/**/*_spec.rb" }
13
+
14
+ desc "Run acceptance tests (requires VBoxManage)"
15
+ RSpec::Core::RakeTask.new('spec:acceptance:fast') do |t|
16
+ t.rspec_opts = "--tag ~slow"
17
+ t.pattern = "./spec/acceptance/**/*_spec.rb"
18
+ end
19
+
20
+ desc 'Default task which runs all specs'
21
+ task :default => 'spec:unit'
22
+
23
+ desc "Start all VMs required by tests"
24
+ task "acceptance:prepare" do
25
+ Dir["spec/acceptance/fixtures/{simple,multivm}"].each do |d|
26
+ # not doing this in parallel / background due to Vagrant bug
27
+ # see https://github.com/mitchellh/vagrant/pull/2484
28
+ Dir.chdir(d) do |d|
29
+ puts "In " + `pwd`
30
+ sh "VAGRANT_NO_PLUGINS=1 vagrant up"
31
+ end
32
+ end
33
+ end
34
+
35
+ desc "Stop all VMs started by tests"
36
+ task "acceptance:clean" do
37
+ Dir["spec/acceptance/fixtures/*"].each do |d|
38
+ Dir.chdir(d) do |d|
39
+ Dir[".vagrant/machines/*"].each do |name|
40
+ name = File.basename(name)
41
+ puts "In " + `pwd`
42
+ sh "VAGRANT_NO_PLUGINS=1 vagrant destroy #{name} -f > /dev/null &"
43
+ end
44
+ end
45
+ end
46
+ end
File without changes
@@ -33,3 +33,26 @@ git push --tags
33
33
  * http://timelessrepo.com/making-ruby-gems
34
34
  * http://asciicasts.com/episodes/245-new-gem-with-bundler
35
35
 
36
+ ## Nov 6 2013 - Notes on rspec
37
+
38
+ Ruby:
39
+
40
+ * http://stackoverflow.com/questions/2232/calling-bash-commands-from-ruby
41
+
42
+ How to write a test:
43
+
44
+ * https://github.com/dergachev/rspec-tutorial/blob/master/spec/acceptance/rspec_tutorial_spec.rb
45
+ * http://blog.davidchelimsky.net/blog/2012/05/13/spec-smell-explicit-use-of-subject/
46
+ * http://betterspecs.org/
47
+
48
+ Rspec features:
49
+
50
+ * https://www.relishapp.com/rspec/rspec-expectations/docs/built-in-matchers
51
+ * https://www.relishapp.com/rspec/rspec-core/v/2-0/docs/hooks/before-and-after-hooks
52
+
53
+ Setting up the rake spec tasks:
54
+
55
+ * https://www.relishapp.com/rspec/rspec-core/v/2-4/docs/command-line/tag-option#filter-examples-with-a-simple-tag-and-@
56
+ * https://github.com/fgrehm/vagrant-lxc/blob/master/spec/acceptance_helper.rb
57
+ * https://www.relishapp.com/rspec/rspec-core/docs/command-line/rake-task
58
+ * https://github.com/fgrehm/vagrant-lxc/blob/master/tasks/spec.rake
File without changes
File without changes
@@ -1,18 +1,26 @@
1
1
  require 'thor'
2
+ require 'open3'
3
+ require 'vgrnt/util/virtualbox'
4
+ require 'vgrnt/util/vagrantfile'
2
5
 
3
6
  module Vgrnt
4
7
  class Logger
5
8
 
9
+ def stdout(str)
10
+ $stdout.puts str unless str.empty?
11
+ end
12
+
6
13
  def notice(str)
7
- $stderr.puts str
14
+ $stderr.puts str unless str.empty?
8
15
  end
9
16
 
10
17
  def debug(str)
11
- $stderr.puts str if ENV['VAGRANT_LOG'] == 'debug'
18
+ $stderr.puts str if !str.empty? && ENV['VAGRANT_LOG'] == 'debug'
12
19
  end
13
20
 
14
21
  def error(str)
15
- $stderr.puts "\e[31m" + str + "\e[0m" # terminal codes for red
22
+ # terminal codes for red
23
+ $stderr.puts "\e[31m" + str + "\e[0m" unless str.empty?
16
24
  end
17
25
  end
18
26
 
@@ -24,31 +32,6 @@ module Vgrnt
24
32
  end
25
33
  end
26
34
 
27
- class Util
28
- def self.getRunningMachines
29
- machines = {}
30
-
31
- ids = Dir.glob(".vagrant/machines/*/*/id")
32
- ids.each do |id_file|
33
- machine_name = id_file[ /^.vagrant\/machines\/(\w+)\/\w+\/id$/ ,1]
34
- machine_id = IO.read(id_file)
35
- machine_status = `VBoxManage showvminfo #{machine_id} --machinereadable`
36
-
37
- # Forwarding(0)="ssh,tcp,127.0.0.1,2222,,22"
38
- # Forwarding(1)="ssh,tcp,,2222,,22"
39
- ssh_info = machine_status.scan( /^Forwarding\(\d+\)="ssh,tcp,([0-9.]*),([0-9]+),/ ).first
40
-
41
- machines[machine_name] = {
42
- :id => machine_id,
43
- :ssh_ip => ssh_info[0].empty? ? '127.0.0.1' : ssh_info[0],
44
- :ssh_port => ssh_info[1],
45
- :state => machine_status.scan( /^VMState="(.*)"$/ ).first.first # VMState="running"
46
- }
47
- end
48
- # puts machines.inspect
49
- return machines
50
- end
51
- end
52
35
 
53
36
  class App < Thor
54
37
 
@@ -69,15 +52,16 @@ module Vgrnt
69
52
  if File.exists?(".vgrnt-sshconfig")
70
53
  @logger.debug "Using .vgrnt-sshconf"
71
54
  ssh_command = "ssh -F .vgrnt-sshconfig #{target_vm} #{args.join(' ')}"
72
- else
55
+ else
73
56
  @logger.debug ".vgrnt-sshconfig file not found; using VBoxManage to get connection info."
74
- machine = Util::getRunningMachines()[target_vm]
57
+ machine = Util::VirtualBox::runningMachines()[target_vm]
58
+ ssh_info = Util::VirtualBox::machineSSH(target_vm)
75
59
 
76
- if machine && machine[:state] == 'running'
60
+ if machine && machine[:state] == 'running'
77
61
  # found by running "VAGRANT_LOG=debug vagrant ssh"
78
62
  default_ssh_args = [
79
- "vagrant@#{machine[:ssh_ip]}",
80
- "-p", machine[:ssh_port],
63
+ "vagrant@#{ssh_info[:ssh_ip]}",
64
+ "-p", ssh_info[:ssh_port],
81
65
  "-o", "DSAAuthentication=yes", "-o", "LogLevel=FATAL", "-o", "StrictHostKeyChecking=no",
82
66
  "-o", "UserKnownHostsFile=/dev/null", "-o", "IdentitiesOnly=yes",
83
67
  "-i", "~/.vagrant.d/insecure_private_key"
@@ -90,21 +74,39 @@ module Vgrnt
90
74
  end
91
75
  end
92
76
 
93
- exec ssh_command
77
+ puts `#{ssh_command}`
94
78
  end
95
79
 
96
80
  desc "ssh-config [vm-name]", "Store output of 'vagrant ssh-config' to .vgrnt-sshconfig"
97
81
  def ssh_config(target="default")
98
- output = `vagrant ssh-config #{target}`
82
+ output = `VAGRANT_NO_PLUGINS=1 vagrant ssh-config #{target}`
99
83
  if $? && !output.empty?
100
84
  IO.write('.vgrnt-sshconfig', output)
101
- @logger.notice "Created ./.vgrnt-sshconfig with the following:", output
85
+ @logger.notice "Created ./.vgrnt-sshconfig with the following: " + output
102
86
  else
103
87
  @logger.error "Call to 'vagrant ssh-config' failed."
104
88
  exit 1
105
89
  end
106
90
  end
107
91
 
92
+ desc "status [vm-name]", "Wrapper on vagrant status"
93
+ def status(target_vm = 'default')
94
+ machines = Util::VirtualBox::runningMachines()
95
+
96
+ puts "Current machine states (as detected by vgrnt):\n\n"
97
+ machines.each do |machine_name, machine|
98
+ puts "#{machine_name.ljust(25)} #{machine[:state]} (virtualbox)"
99
+ end
100
+ defined_vms = Util::Vagrantfile::defined_vms()
101
+
102
+ defined_vms.each do |machine_name|
103
+ machine_name = machine_name.to_s # they're usually symbols
104
+ if !machines[machine_name]
105
+ puts "#{machine_name.ljust(25)} not created (virtualbox)"
106
+ end
107
+ end
108
+ end
109
+
108
110
  # desc "provision", "Run vagrant provision like last time"
109
111
  # def provision
110
112
  # raise "Not implemented yet. Likely requires creating vagrant-vgrnt."
@@ -134,7 +136,7 @@ module Vgrnt
134
136
 
135
137
  # of form `VBoxManage showvminfo uuid|name ...`
136
138
  vboxmanage_commands_standard = vboxmanage_commands_all - vboxmanage_commands_special
137
- machine = Util::getRunningMachines()[target_vm]
139
+ machine = Util::VirtualBox::runningMachines()[target_vm]
138
140
  if !machine
139
141
  @logger.error "The specified target vm (#{target_vm}) has not been started."
140
142
  exit 1
@@ -148,9 +150,6 @@ module Vgrnt
148
150
  else
149
151
  # TODO: handle substitution for commands like `usbfilter add 0 --target <uuid|name>`
150
152
 
151
- # @logger.error "Support for non-standard vboxmanage commands (such as #{vboxmanage_subcommand}) is not implemented yet."
152
- # exit 1
153
-
154
153
  @logger.debug "Non-standard vboxmanage command detected (#{vboxmanage_subcommand}). Substituting 'VM_ID' for VM id."
155
154
 
156
155
  # [VM_ID] is an optional literal token which will be replaced by the UUID of the VM referenced by Vagrant
@@ -160,12 +159,10 @@ module Vgrnt
160
159
 
161
160
  @logger.debug "Executing: #{command}"
162
161
  #TODO: windows support (path to VBoxManage.exe")
163
- exec command
162
+ Open3.popen3(command) do |stdin, stdout, stderr|
163
+ @logger.stdout stdout.read
164
+ @logger.error stderr.read
165
+ end
164
166
  end
165
167
  end
166
168
  end
167
-
168
- # if __FILE__ == $0
169
- # raise "vgrnt: must be run from vagrant project root" unless File.exists? 'Vagrantfile'
170
- # Vgrnt::App.start
171
- # end
@@ -0,0 +1,38 @@
1
+ # TODO: test me
2
+
3
+ $vagrant_config_vms = []
4
+
5
+ module Vagrant
6
+ def self.configure(*args, &block)
7
+ yield Vgrnt::Util::Vagrantfile::Proxy.new
8
+ end
9
+ end
10
+
11
+ module Vgrnt
12
+ module Util
13
+ module Vagrantfile
14
+ class Proxy
15
+ def define(*args)
16
+ # $stderr.puts "Called define with args (#{args.join(", ")})"
17
+ $vagrant_config_vms << args.first
18
+ end
19
+
20
+ def method_missing(name, *args, &block)
21
+ return self
22
+ end
23
+ end
24
+
25
+ def self.defined_vms
26
+ # clear any previous value (else tests fail depending on exec order)
27
+ # NOT PARALLEL SAFE (not sure how to do this given static methods)
28
+ $vagrant_config_vms = []
29
+ load('./Vagrantfile')
30
+ # puts $vagrant_config_vms.inspect
31
+ if $vagrant_config_vms.empty?
32
+ $vagrant_config_vms << :default
33
+ end
34
+ return $vagrant_config_vms
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,49 @@
1
+ # TODO testing - stubout VBoxManage showvminfo (use fixtures for its output),
2
+ # then write unit tests for getRunningMachines (consider using erb file for the fixtures)
3
+ module Vgrnt
4
+ module Util
5
+ class VirtualBox
6
+ def self.machineSSH(target)
7
+ machine = self.runningMachines()[target]
8
+ return nil unless machine && machine[:state] == 'running'
9
+
10
+ # Forwarding(0)="ssh,tcp,127.0.0.1,2222,,22"
11
+ # Forwarding(1)="ssh,tcp,,2222,,22"
12
+ ssh_info = machine[:showvminfo].scan( /^Forwarding\(\d+\)="ssh,tcp,([0-9.]*),([0-9]+),/ ).first
13
+
14
+ return {
15
+ :ssh_ip => ssh_info[0].empty? ? '127.0.0.1' : ssh_info[0],
16
+ :ssh_port => ssh_info[1]
17
+ }
18
+ end
19
+
20
+ def self.showvminfo_command(machine_id)
21
+ return "VBoxManage showvminfo #{machine_id} --machinereadable"
22
+ end
23
+
24
+ def self.showvminfo(machine_id)
25
+ return `#{self.showvminfo_command(machine_id)}`
26
+ end
27
+
28
+ def self.runningMachines
29
+ machines = {}
30
+
31
+ ids = Dir.glob(".vagrant/machines/*/*/id")
32
+ ids.each do |id_file|
33
+ machine_name = id_file[ /^.vagrant\/machines\/(\w+)\/\w+\/id$/ ,1]
34
+ machine_id = IO.read(id_file)
35
+
36
+ machine_info = self.showvminfo(machine_id)
37
+
38
+ machines[machine_name] = {
39
+ :id => machine_id,
40
+ :showvminfo => machine_info,
41
+ :state => machine_info.scan( /^VMState="(.*)"$/ ).first.first # VMState="running"
42
+ }
43
+ end
44
+ return machines
45
+ end
46
+
47
+ end
48
+ end
49
+ end
@@ -1,3 +1,3 @@
1
1
  module Vgrnt
2
- VERSION = "0.0.2"
2
+ VERSION = "0.0.3"
3
3
  end
@@ -0,0 +1,114 @@
1
+ require 'acceptance/support/acceptance_helper'
2
+
3
+ describe Vgrnt::App do
4
+
5
+ context "when running from ./spec/acceptance/fixtures/simple" do
6
+ before(:all) { vagrant_up('./spec/acceptance/fixtures/simple') }
7
+ let(:vagrant_path) { './spec/acceptance/fixtures/simple' }
8
+
9
+ describe "#ssh" do
10
+ it 'works with default VM specified explicitly' do
11
+ output = vagrant_stdout { Vgrnt::App.start(%w{ssh default -- whoami}) }
12
+ expect(output).to eq "vagrant\n"
13
+ end
14
+
15
+ it 'works with default VM specified implicitly' do
16
+ output = vagrant_stdout { Vgrnt::App.start(%w{ssh -- whoami}) }
17
+ expect(output).to eq "vagrant\n"
18
+ end
19
+ end
20
+
21
+ describe "#ssh-config", :slow do
22
+
23
+ before(:each) { delete_in_vagrant_env '.vgrnt-sshconfig' }
24
+ after(:each) { delete_in_vagrant_env '.vgrnt-sshconfig' }
25
+
26
+ it 'with default VM specified explicitly' do
27
+ expect( in_vagrant_env { File.exists? '.vgrnt-sshconfig' } ).to be_false
28
+ stderr = vagrant_stderr { Vgrnt::App.start(%w{ssh-config default}) }
29
+ expect( in_vagrant_env { File.exists? '.vgrnt-sshconfig' } ).to be_true
30
+ end
31
+
32
+ it "works with #ssh" do
33
+ output = vagrant_stdout { Vgrnt::App.start(%w{ssh default -- whoami}) }
34
+ expect(output).to eq "vagrant\n"
35
+ end
36
+ end
37
+
38
+ describe "#vboxmanage" do
39
+ it "runs displays usage when run with no arguments" do
40
+ output = vagrant_stdout { Vgrnt::App.start(%w{vboxmanage}) }
41
+ expect(output).to include "Usage:"
42
+ end
43
+
44
+ it "runs regular command (showvminfo)" do
45
+ output = vagrant_stdout { Vgrnt::App.start(%w{vboxmanage default -- showvminfo}) }
46
+ expect(output).to match /Name.*vgrnt-test/
47
+ end
48
+
49
+ it "substitutes VM_UUID in irregular commands (guestproperty enumerate VM_UUID)" do
50
+ output = vagrant_stdout { Vgrnt::App.start(%w{vboxmanage default -- guestproperty enumerate VM_UUID}) }
51
+ expect(output).to include "Name: /VirtualBox/GuestInfo/OS/Product"
52
+ end
53
+ end
54
+
55
+ describe "#status" do
56
+ it "correctly identifies running machines" do
57
+ # default saved (virtualbox)
58
+ output = vagrant_stdout { Vgrnt::App.start(%w{status}) }
59
+ expect(output).to match /default +running \(virtualbox\)/
60
+ end
61
+
62
+ it "is identical to 'vagrant status'", :slow do
63
+ # default saved (virtualbox)
64
+ vagrant_output = vagrant_stdout { puts `VAGRANT_NO_PLUGINS=1 vagrant status | grep '(virtualbox)$'` }
65
+ expect(vagrant_output).to match /default +running \(virtualbox\)/
66
+
67
+ vgrnt_output = vagrant_stdout { Vgrnt::App.start(%w{status}) }
68
+ expect(vgrnt_output).to include(vagrant_output)
69
+ end
70
+ end
71
+ end
72
+
73
+ context "when running from ./spec/acceptance/fixtures/neveron" do
74
+ before(:all) { vagrant_destroy('./spec/acceptance/fixtures/neveron') }
75
+ let(:vagrant_path) { './spec/acceptance/fixtures/neveron' }
76
+
77
+ describe "#status" do
78
+ it "correctly identifies not created machines" do
79
+ # default saved (virtualbox)
80
+ output = vagrant_stdout { Vgrnt::App.start(%w{status}) }
81
+ expect(output).to match /default +not created \(virtualbox\)/
82
+ end
83
+
84
+ it "is identical to 'vagrant status'", :slow do
85
+ # default saved (virtualbox)
86
+ vagrant_output = vagrant_stdout { puts `VAGRANT_NO_PLUGINS=1 vagrant status | grep '(virtualbox)$'` }
87
+ expect(vagrant_output).to match /default +not created \(virtualbox\)/
88
+
89
+ vgrnt_output = vagrant_stdout { Vgrnt::App.start(%w{status}) }
90
+ expect(vgrnt_output).to include(vagrant_output)
91
+ end
92
+ end
93
+ end
94
+
95
+ context "when running in fixtures/multivm" do
96
+ before(:all) { vagrant_up('./spec/acceptance/fixtures/multivm') }
97
+ let(:vagrant_path) { './spec/acceptance/fixtures/multivm' }
98
+
99
+ describe "#status" do
100
+ it "correctly identifies multiple running machines" do
101
+ # default saved (virtualbox)
102
+ output = vagrant_stdout { Vgrnt::App.start(%w{status}) }
103
+ expect(output).to match /^vm1 +running \(virtualbox\)/
104
+ expect(output).to match /^vm2 +running \(virtualbox\)/
105
+ end
106
+ end
107
+
108
+ describe "#ssh" do
109
+ it 'works with multivm environments' do
110
+ expect(vagrant_stdout { Vgrnt::App.start(%w{ssh vm1 -- whoami}) }).to eq "vagrant\n"
111
+ end
112
+ end
113
+ end
114
+ end
@@ -0,0 +1,16 @@
1
+ # -*- mode: ruby -*-
2
+ # vi: set ft=ruby :
3
+
4
+ Vagrant.configure("2") do |config|
5
+
6
+ config.vm.box = "precise64"
7
+ config.vm.box_url = "http://files.vagrantup.com/precise64.box"
8
+
9
+ config.vm.provider :virtualbox do |vb|
10
+ vb.customize ["modifyvm", :id, "--memory", "128"]
11
+ end
12
+
13
+ config.vm.define :vm1
14
+ config.vm.define :vm2
15
+
16
+ end
@@ -0,0 +1,9 @@
1
+ # -*- mode: ruby -*-
2
+ # vi: set ft=ruby :
3
+
4
+ # Fixture::neveron - all the tests will assume that we never turn on this fixture
5
+
6
+ Vagrant.configure('2') do |config|
7
+ config.vm.box = "precise64"
8
+ config.vm.box_url = "http://files.vagrantup.com/precise64.box"
9
+ end
@@ -0,0 +1,20 @@
1
+ # -*- mode: ruby -*-
2
+ # vi: set ft=ruby :
3
+
4
+ # Vagrantfile API/syntax version. Don't touch unless you know what you're doing!
5
+ Vagrant.configure("2") do |config|
6
+ config.vm.box = "precise64"
7
+ config.vm.box_url = "http://files.vagrantup.com/precise64.box"
8
+
9
+ # config.vm.network :private_network, ip: "192.168.33.10"
10
+ # config.vm.network :public_network
11
+ # config.ssh.forward_agent = true
12
+
13
+ config.vm.provider :virtualbox do |vb|
14
+ # vgrnt-test is hardcoded in util-spec.rb
15
+ vb.name = "vgrnt-test"
16
+
17
+ vb.customize ["modifyvm", :id, "--memory", "128"]
18
+ end
19
+
20
+ end
@@ -0,0 +1,72 @@
1
+ require 'spec_helper'
2
+
3
+ module AcceptanceExampleGroup
4
+ # Captures and returns stream activity during block.
5
+ # Only supports :stdout and :stdin
6
+ # Note that it fails to capture output of exec or system calls.
7
+ def capture(stream)
8
+ begin
9
+ stream = stream.to_s
10
+ eval "$#{stream} = StringIO.new"
11
+ yield
12
+ result = eval("$#{stream}").string
13
+ ensure
14
+ eval("$#{stream} = #{stream.upcase}")
15
+ end
16
+ result
17
+ end
18
+
19
+ def in_vagrant_env_dir(vagrant_homedir, &block)
20
+ # unless (vagrant_homedir)
21
+ # vagrant_homedir = './spec/acceptance/fixtures/simple'
22
+ # end
23
+ Dir.chdir( vagrant_homedir, &block)
24
+ end
25
+
26
+ def capture_in_vagrant_env(stream=nil, &block)
27
+ capture(stream) { in_vagrant_env &block }
28
+ end
29
+
30
+ def vagrant_stderr(&block)
31
+ capture_in_vagrant_env(:stderr, &block)
32
+ end
33
+
34
+ def vagrant_stdout(&block)
35
+ capture_in_vagrant_env(:stdout, &block)
36
+ end
37
+
38
+ def delete_in_vagrant_env(file)
39
+ in_vagrant_env { File.delete(file) if File.exists?(file) }
40
+ end
41
+
42
+ def in_vagrant_env(&block)
43
+ in_vagrant_env_dir(vagrant_path, &block)
44
+ end
45
+
46
+ def vagrant_up(path)
47
+ in_vagrant_env_dir(path) do
48
+ s = Vgrnt::Util::VirtualBox::runningMachines()
49
+ # raise s['default'].inspect
50
+ unless s && s['default'] && s['default'][:state] == 'running'
51
+ `VAGRANT_NO_PLUGINS=1 vagrant up`
52
+ end
53
+ end
54
+ end
55
+
56
+ def vagrant_destroy(path)
57
+ in_vagrant_env_dir(path) do
58
+ s = Vgrnt::Util::VirtualBox::runningMachines()
59
+ if s && s['default'] && s['default'] && ([nil, "poweroff"].include? s['default'][:state])
60
+ `VAGRANT_NO_PLUGINS=1 vagrant destroy -f`
61
+ end
62
+ end
63
+ end
64
+
65
+ end
66
+
67
+ RSpec.configure do |config|
68
+ config.include AcceptanceExampleGroup, :type => :acceptance, :example_group => {
69
+ :file_path => /\bspec\/acceptance\//
70
+ }
71
+ end
72
+
@@ -0,0 +1,63 @@
1
+ require 'acceptance/support/acceptance_helper'
2
+
3
+ describe "VBoxManage environment" do
4
+ # def in_vagrant_env(&block)
5
+ # in_vagrant_env_dir './spec/acceptance/fixtures/simple', &block
6
+ # end
7
+
8
+ before(:all) { vagrant_up('./spec/acceptance/fixtures/simple') }
9
+ let(:vagrant_path) { './spec/acceptance/fixtures/simple' }
10
+
11
+ it 'ensure we can execute VBoxManage' do
12
+ return_code = system("VBoxManage list vms > /dev/null")
13
+ expect(return_code).to eq true
14
+ end
15
+
16
+ it 'ensure vgrnt-test VM is recognized' do
17
+ expect(`VBoxManage list vms`).to include 'vgrnt-test'
18
+ end
19
+
20
+ it 'ensure vgrnt-test VM is running' do
21
+ expect(`VBoxManage showvminfo vgrnt-test --machinereadable | grep VMState`).to include '"running"'
22
+ end
23
+ end
24
+
25
+
26
+ describe Vgrnt::Util::VirtualBox do
27
+
28
+ context "when running from ./spec/acceptance/fixtures/simple" do
29
+ before(:all) { vagrant_up('./spec/acceptance/fixtures/simple') }
30
+ let(:vagrant_path) { './spec/acceptance/fixtures/simple' }
31
+
32
+ describe "::showvminfo" do
33
+ it 'ensure vgrnt-test VM is running' do
34
+ expect(Vgrnt::Util::VirtualBox::showvminfo('vgrnt-test')).to include 'UUID'
35
+ end
36
+ end
37
+
38
+ describe "::runningMachines" do
39
+ it 'ensure .vgrnt directory exists' do
40
+ expect(in_vagrant_env { File.exists? '.vagrant' }).to be_true
41
+ end
42
+
43
+ it 'ensure vgrnt-test VM is running' do
44
+ runningmachines = in_vagrant_env { Vgrnt::Util::VirtualBox::runningMachines() }
45
+ expect(runningmachines['default'][:state]).to eq 'running'
46
+ end
47
+ end
48
+
49
+ describe "::machineSSH" do
50
+ let :machine_ssh_info do
51
+ in_vagrant_env { Vgrnt::Util::VirtualBox::machineSSH('default') }
52
+ end
53
+
54
+ it 'extracts SSH hostname' do
55
+ expect(machine_ssh_info[:ssh_ip]).to eq '127.0.0.1'
56
+ end
57
+
58
+ it 'extracts SSH port, within the 22xx range' do
59
+ expect(machine_ssh_info[:ssh_port]).to match /^22..$/
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,8 @@
1
+ require 'vgrnt'
2
+
3
+ RSpec.configure do |config|
4
+ config.treat_symbols_as_metadata_keys_with_true_values = true
5
+ config.run_all_when_everything_filtered = true
6
+ config.color_enabled = true
7
+ config.order = 'random'
8
+ end
@@ -0,0 +1,13 @@
1
+ require 'spec_helper'
2
+
3
+ # RSpec.configure do |c|
4
+ # c.include Helpers
5
+ # end
6
+
7
+ describe Vgrnt::Util::VirtualBox do
8
+ describe "::showvminfo_command" do
9
+ it 'should generate VBoxManage command' do
10
+ expect(Vgrnt::Util::VirtualBox::showvminfo_command('test')).to eq 'VBoxManage showvminfo test --machinereadable'
11
+ end
12
+ end
13
+ end
@@ -19,4 +19,5 @@ Gem::Specification.new do |spec|
19
19
 
20
20
  spec.add_development_dependency "bundler"
21
21
  spec.add_development_dependency "rake"
22
+ spec.add_development_dependency "rspec"
22
23
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: vgrnt
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alex Dergachev
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-10-30 00:00:00.000000000 Z
11
+ date: 2013-11-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: thor
@@ -52,6 +52,20 @@ dependencies:
52
52
  - - '>='
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - '>='
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
55
69
  description:
56
70
  email: alex@evolvingweb.ca
57
71
  executables:
@@ -60,6 +74,7 @@ extensions: []
60
74
  extra_rdoc_files: []
61
75
  files:
62
76
  - .gitignore
77
+ - .travis.yml
63
78
  - CHANGELOG.md
64
79
  - Gemfile
65
80
  - README.md
@@ -70,7 +85,17 @@ files:
70
85
  - docs/vboxmanage-irregular-commands.txt
71
86
  - lib/vgrnt.rb
72
87
  - lib/vgrnt/base.rb
88
+ - lib/vgrnt/util/vagrantfile.rb
89
+ - lib/vgrnt/util/virtualbox.rb
73
90
  - lib/vgrnt/version.rb
91
+ - spec/acceptance/app_spec.rb
92
+ - spec/acceptance/fixtures/multivm/Vagrantfile
93
+ - spec/acceptance/fixtures/neveron/Vagrantfile
94
+ - spec/acceptance/fixtures/simple/Vagrantfile
95
+ - spec/acceptance/support/acceptance_helper.rb
96
+ - spec/acceptance/util_spec.rb
97
+ - spec/spec_helper.rb
98
+ - spec/unit/util_spec.rb
74
99
  - vgrnt.gemspec
75
100
  homepage: https://github.com/dergachev/vgrnt
76
101
  licenses:
@@ -96,4 +121,12 @@ rubygems_version: 2.0.3
96
121
  signing_key:
97
122
  specification_version: 4
98
123
  summary: Speeds up a few common vagrant operations through dirty hacks.
99
- test_files: []
124
+ test_files:
125
+ - spec/acceptance/app_spec.rb
126
+ - spec/acceptance/fixtures/multivm/Vagrantfile
127
+ - spec/acceptance/fixtures/neveron/Vagrantfile
128
+ - spec/acceptance/fixtures/simple/Vagrantfile
129
+ - spec/acceptance/support/acceptance_helper.rb
130
+ - spec/acceptance/util_spec.rb
131
+ - spec/spec_helper.rb
132
+ - spec/unit/util_spec.rb