vgrnt 0.0.2 → 0.0.3

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