furnish-vagrant 0.0.1
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.
- data/.gitignore +18 -0
- data/Gemfile +6 -0
- data/Guardfile +10 -0
- data/LICENSE.txt +22 -0
- data/README.md +70 -0
- data/Rakefile +31 -0
- data/furnish-vagrant.gemspec +32 -0
- data/lib/furnish/provisioners/vagrant.rb +157 -0
- data/lib/furnish/vagrant/ui.rb +71 -0
- data/lib/furnish/vagrant/version.rb +6 -0
- data/test/helper.rb +14 -0
- data/test/test_vagrant.rb +229 -0
- metadata +235 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/Guardfile
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
# vim: ft=ruby
|
2
|
+
guard 'minitest' do
|
3
|
+
# with Minitest::Unit
|
4
|
+
watch(%r!^test/(.*)\/?test_(.*)\.rb!)
|
5
|
+
watch(%r!^test/helper\.rb!) { "test" }
|
6
|
+
end
|
7
|
+
|
8
|
+
guard 'rake', :failure_ok => true, :run_on_all => false, :task => 'rdoc_cov' do
|
9
|
+
watch(%r!^lib/(.*)([^/]+)\.rb!)
|
10
|
+
end
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Erik Hollensbe
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,70 @@
|
|
1
|
+
# Furnish::Vagrant
|
2
|
+
|
3
|
+
Vagrant driver for the Furnish provisioning system. Provides
|
4
|
+
Furnish::Provisioner::Vagrant to orchestrate using Vagrant 1.0.x to stand up
|
5
|
+
Virtualbox VMs. It does this by driving
|
6
|
+
[vagrant-prison](https://github.com/chef-workflow/vagrant-prison).
|
7
|
+
|
8
|
+
It has some interstitial relationship with
|
9
|
+
[furnish-ip](https://github.com/chef-workflow/furnish-ip) in that IPs must be
|
10
|
+
passed to this provisioner for it to work -- it will allocate host-only network
|
11
|
+
addresses to the VMs based on the input it receives.
|
12
|
+
|
13
|
+
If you plan on doing *any* development work against this library directly,
|
14
|
+
please read below under "Testing".
|
15
|
+
|
16
|
+
## Vagrant 1.1 ?
|
17
|
+
|
18
|
+
Furnish already does most of what Vagrant 1.1 does outside of its VirtualBox
|
19
|
+
support. We have no intention of supporting 1.1 and hope to deprecate this in
|
20
|
+
favor of a more VirtualBox-focused system later.
|
21
|
+
|
22
|
+
## Testing
|
23
|
+
|
24
|
+
First things first, there are no mocks here. This tests allocates numerous VMs,
|
25
|
+
will use gobs of ram and take quite a bit of time, and due to limitations in
|
26
|
+
both VBox and Vagrant, cannot be sped up by running in parallel. `guard` works
|
27
|
+
here, but for fast test cycles, it can be faster to run things directly instead
|
28
|
+
of waiting for `guard` to catch up. On my 8-core machine with 16GB and a SSD,
|
29
|
+
the current suite takes about 5 minutes to run and peaks at about 2G of ram.
|
30
|
+
This isn't changing.
|
31
|
+
|
32
|
+
For IP allocation, the network "10.10.10.0/24" is used and there's no
|
33
|
+
expectation these addresses won't work.
|
34
|
+
|
35
|
+
If things break, you may need to clean things up before tests will pass again.
|
36
|
+
Leaking whole machines is unfortunately a side effect of ... a broken
|
37
|
+
provisioner.
|
38
|
+
|
39
|
+
Starting the virtualbox GUI console, you should see machines that have randomly
|
40
|
+
generated names - `mktmpdir` is used underneath the hood, so this name actually
|
41
|
+
depends quite a bit by what platform you're on. On my OS X box, it's
|
42
|
+
`/tmp/dCAFEBABE`. The name of these machines will be a variant on that, the
|
43
|
+
`basename` of that temporary dir. `dCAFEBABE` in this case. All you have to do
|
44
|
+
is shut those machines down, and remove the machines (delete the disks too) to
|
45
|
+
get things back to a better state.
|
46
|
+
|
47
|
+
If you need to see vagrant's output to assist you while testing, run your tests
|
48
|
+
with `VAGRANT_DEBUG` set in your environment.
|
49
|
+
|
50
|
+
## Installation
|
51
|
+
|
52
|
+
Add this line to your application's Gemfile:
|
53
|
+
|
54
|
+
gem 'furnish-vagrant'
|
55
|
+
|
56
|
+
And then execute:
|
57
|
+
|
58
|
+
$ bundle
|
59
|
+
|
60
|
+
Or install it yourself as:
|
61
|
+
|
62
|
+
$ gem install furnish-vagrant
|
63
|
+
|
64
|
+
## Contributing
|
65
|
+
|
66
|
+
1. Fork it
|
67
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
68
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
69
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
70
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
2
|
+
require 'rake/testtask'
|
3
|
+
require 'rdoc/task'
|
4
|
+
|
5
|
+
Rake::TestTask.new do |t|
|
6
|
+
t.libs << "test"
|
7
|
+
t.test_files = FileList["test/test_*.rb"]
|
8
|
+
t.verbose = true
|
9
|
+
end
|
10
|
+
|
11
|
+
RDoc::Task.new do |rdoc|
|
12
|
+
rdoc.title = "Furnish -> Vagrant 1.0.x bridge"
|
13
|
+
rdoc.rdoc_files.include("lib/**/*.rb")
|
14
|
+
rdoc.rdoc_files -= ["lib/furnish/vagrant/version.rb"]
|
15
|
+
if ENV["RDOC_COVER"]
|
16
|
+
rdoc.options << "-C"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
desc "run tests with coverage report"
|
21
|
+
task "test:coverage" do
|
22
|
+
ENV["COVERAGE"] = "1"
|
23
|
+
Rake::Task["test"].invoke
|
24
|
+
end
|
25
|
+
|
26
|
+
desc "run rdoc with coverage report"
|
27
|
+
task :rdoc_cov do
|
28
|
+
# ugh
|
29
|
+
ENV["RDOC_COVER"] = "1"
|
30
|
+
ruby "-S rake rerdoc"
|
31
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'furnish/vagrant/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |gem|
|
7
|
+
gem.name = "furnish-vagrant"
|
8
|
+
gem.version = Furnish::Vagrant::VERSION
|
9
|
+
gem.authors = ["Erik Hollensbe"]
|
10
|
+
gem.email = ["erik+github@hollensbe.org"]
|
11
|
+
gem.description = %q{Furnish -> Vagrant 1.0.x bridge}
|
12
|
+
gem.summary = %q{Furnish -> Vagrant 1.0.x bridge}
|
13
|
+
gem.homepage = "https://github.com/chef-workflow/furnish-vagrant"
|
14
|
+
|
15
|
+
gem.files = `git ls-files`.split($/)
|
16
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
17
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
18
|
+
gem.require_paths = ["lib"]
|
19
|
+
|
20
|
+
gem.add_dependency 'vagrant-prison', '~> 0.1.0'
|
21
|
+
gem.add_dependency 'furnish', '~> 0.0.3'
|
22
|
+
|
23
|
+
gem.add_development_dependency 'furnish-ip', '~> 0.0.2'
|
24
|
+
gem.add_development_dependency 'rake'
|
25
|
+
gem.add_development_dependency 'minitest', '~> 4.5.0'
|
26
|
+
gem.add_development_dependency 'guard-minitest'
|
27
|
+
gem.add_development_dependency 'guard-rake'
|
28
|
+
gem.add_development_dependency 'rdoc'
|
29
|
+
gem.add_development_dependency 'rb-fsevent'
|
30
|
+
gem.add_development_dependency 'simplecov'
|
31
|
+
gem.add_development_dependency 'net-ssh'
|
32
|
+
end
|
@@ -0,0 +1,157 @@
|
|
1
|
+
require 'vagrant/prison'
|
2
|
+
require 'furnish/vagrant/ui'
|
3
|
+
|
4
|
+
module Furnish # :nodoc:
|
5
|
+
module Provisioner # :nodoc:
|
6
|
+
#
|
7
|
+
# Vagrant provisioner; this allows our existing vagrant needs to be
|
8
|
+
# satisified with Furnish.
|
9
|
+
#
|
10
|
+
# Uses Vagrant::Prison to accomplish sandboxing of Vagrant itself.
|
11
|
+
#
|
12
|
+
# A box or box_url must be supplied in the constructor. A number of servers
|
13
|
+
# must also be supplied, but will default to 1.
|
14
|
+
#
|
15
|
+
# During provisioning, the startup method is expected to get a list of IP
|
16
|
+
# addresses to configure vagrant's boxes with as a part of a host-only
|
17
|
+
# network. If the number of servers and the number of IP addresses received
|
18
|
+
# are not equal, provisioning will fail.
|
19
|
+
#
|
20
|
+
# See Furnish::IP (furnish-ip) gem for a provisioner which can be used to
|
21
|
+
# deal with IP allocation and vagrant.
|
22
|
+
#
|
23
|
+
class Vagrant
|
24
|
+
# Furnish provisioner requirement; name of Furnish::ProvisionerGroup
|
25
|
+
attr_accessor :name
|
26
|
+
|
27
|
+
# Vagrant's box_url argument. box will be coerced from this if it is not
|
28
|
+
# supplied.
|
29
|
+
attr_accessor :box_url
|
30
|
+
|
31
|
+
# Vagrant's box argument. if not supplied, will come from box_url. One of
|
32
|
+
# box or box_url must exist for provisioning to succeed.
|
33
|
+
attr_accessor :box
|
34
|
+
|
35
|
+
#
|
36
|
+
# Construct a new vagrant provisioner -- takes a hash of arguments.
|
37
|
+
#
|
38
|
+
# args:
|
39
|
+
# * :box - name of vagrant box
|
40
|
+
# * :box_url - url of vagrant box to download. box or box_url must exist.
|
41
|
+
# * :number_of_servers - integer value of servers to exist.
|
42
|
+
# * :db_name - this is a tag used to create the database where the Vagrant::Prison objects will be stored. "default" by default, intended for more advanced uses.
|
43
|
+
# * :customziations - an array of arguments that would go to vm.customize. If an array of arrays are supplied, vm.customize is called for each inner array with it as the argument.
|
44
|
+
#
|
45
|
+
def initialize(args)
|
46
|
+
unless args.kind_of?(Hash)
|
47
|
+
raise ArgumentError, "arguments must be a hash"
|
48
|
+
end
|
49
|
+
|
50
|
+
args.each do |k,v|
|
51
|
+
instance_variable_set("@#{k}", v)
|
52
|
+
end
|
53
|
+
|
54
|
+
normalize_box_args
|
55
|
+
normalize_customizations
|
56
|
+
|
57
|
+
@db_name ||= "default"
|
58
|
+
@number_of_servers ||= 1
|
59
|
+
@db = Palsy::Map.new('vm_prisons', @db_name)
|
60
|
+
end
|
61
|
+
|
62
|
+
#
|
63
|
+
# Helper method to structure supplied customizations.
|
64
|
+
#
|
65
|
+
def normalize_customizations
|
66
|
+
if @customizations
|
67
|
+
unless @customizations.kind_of?(Array)
|
68
|
+
raise ArgumentError, "customizations must be an array of customizations, or array of array of multiple customizations."
|
69
|
+
end
|
70
|
+
|
71
|
+
unless @customizations.all? { |x| x.kind_of?(Array) }
|
72
|
+
@customizations = [@customizations]
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
#
|
78
|
+
# Helper method to coerce box and box_url into something normal.
|
79
|
+
#
|
80
|
+
def normalize_box_args
|
81
|
+
if @box_url
|
82
|
+
@box = File.basename(@box_url).gsub(/\.box$/, '')
|
83
|
+
end
|
84
|
+
|
85
|
+
unless @box
|
86
|
+
raise ArgumentError, "#{self.class} must be configured with a box or box_url."
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
#
|
91
|
+
# Provision with vagrant. Expects a list of IP addresses used as its
|
92
|
+
# arguments.
|
93
|
+
#
|
94
|
+
# During provisioning, the startup method is expected to get a list of IP
|
95
|
+
# addresses to configure vagrant's boxes with as a part of a host-only
|
96
|
+
# network. If the number of servers and the number of IP addresses received
|
97
|
+
# are not equal, provisioning will fail.
|
98
|
+
#
|
99
|
+
def startup(*args)
|
100
|
+
ips = args.first
|
101
|
+
|
102
|
+
if ips.count != @number_of_servers
|
103
|
+
raise "The number of requested IP addresses does not match the number of requested servers"
|
104
|
+
end
|
105
|
+
|
106
|
+
@prison = ::Vagrant::Prison.new(Dir.mktmpdir, false)
|
107
|
+
|
108
|
+
@prison.name = name
|
109
|
+
|
110
|
+
@prison.configure do |config|
|
111
|
+
config.vm.box_url = @box_url
|
112
|
+
config.vm.box = @box
|
113
|
+
|
114
|
+
if @customizations
|
115
|
+
@customizations.each { |c| config.vm.customize c }
|
116
|
+
end
|
117
|
+
|
118
|
+
ips.each_with_index do |ip, x|
|
119
|
+
config.vm.define "#{name}-#{x}" do |this_config|
|
120
|
+
this_config.vm.network :hostonly, ip
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
@prison.construct(:ui_class => Furnish::Vagrant::UI)
|
126
|
+
@db[name] = @prison # eager save in case start has issues
|
127
|
+
|
128
|
+
return @prison.start ? ips : false
|
129
|
+
ensure
|
130
|
+
@db[name] = @prison
|
131
|
+
end
|
132
|
+
|
133
|
+
#
|
134
|
+
# Deprovision with Vagrant.
|
135
|
+
#
|
136
|
+
def shutdown
|
137
|
+
@prison ||= @db[name]
|
138
|
+
|
139
|
+
if @prison
|
140
|
+
@prison.configure_environment(:ui_class => Furnish::Vagrant::UI)
|
141
|
+
@prison.cleanup
|
142
|
+
end
|
143
|
+
|
144
|
+
@db.delete(name)
|
145
|
+
return true
|
146
|
+
end
|
147
|
+
|
148
|
+
#
|
149
|
+
# Report the information on this provisioner. Number of servers and the
|
150
|
+
# prison directory used for this provision.
|
151
|
+
#
|
152
|
+
def report
|
153
|
+
["#{@number_of_servers} servers; prison dir: #{@prison.dir}"]
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
require 'furnish/logger'
|
2
|
+
require 'vagrant/errors'
|
3
|
+
|
4
|
+
module Furnish # :nodoc:
|
5
|
+
module Vagrant
|
6
|
+
#
|
7
|
+
# This is a UI driver for Vagrant, that allows it to log through
|
8
|
+
# Furnish::Logger.
|
9
|
+
#
|
10
|
+
class UI
|
11
|
+
#--
|
12
|
+
# this class emulates vagrant's UI interface, it doesn't use any of it.
|
13
|
+
# like most things vagrant, its UI abstraction is about as flexible as a
|
14
|
+
# petrified brick.
|
15
|
+
#++
|
16
|
+
|
17
|
+
include Furnish::Logger::Mixins
|
18
|
+
|
19
|
+
class << self
|
20
|
+
##
|
21
|
+
# This is the debug_level concept from Furnish::Logger, and will be
|
22
|
+
# used to determine whether to log vagrant output or not.
|
23
|
+
#
|
24
|
+
# This value is shared across all UI objects, and defaults to 2 the
|
25
|
+
# first time a UI object is constructed.
|
26
|
+
attr_accessor :debug_level
|
27
|
+
end
|
28
|
+
|
29
|
+
##
|
30
|
+
# Resource name for Vagrant's use. See Vagrant::UI::Interface.
|
31
|
+
attr_accessor :resource
|
32
|
+
|
33
|
+
#
|
34
|
+
# Create a Furnish::Vagrant::UI object. See Vagrant::UI::Interface's
|
35
|
+
# constructor for more information.
|
36
|
+
#
|
37
|
+
def initialize(resource)
|
38
|
+
@resource = resource
|
39
|
+
self.class.debug_level ||= 2 # XXX this modifies all instances, not just this one.
|
40
|
+
end
|
41
|
+
|
42
|
+
#
|
43
|
+
# We don't really care about Vagrant's log levels, so they all go to this
|
44
|
+
# call. Makes an attempt to emulate vagrant's log output, consults the
|
45
|
+
# debug_level to determine whether to send anything to the log. If a
|
46
|
+
# resource has been set, adds that to the beginning of the log line.
|
47
|
+
#
|
48
|
+
def say(message, opts=nil)
|
49
|
+
res = resource
|
50
|
+
if_debug(self.class.debug_level) do
|
51
|
+
if res
|
52
|
+
puts "[%s] %s" % [res, message]
|
53
|
+
else
|
54
|
+
puts message
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
[:warn, :error, :info, :success].each { |m| alias_method m, :say }
|
60
|
+
[:clear_line, :report_progress].each { |m| define_method(m) { |*a| } }
|
61
|
+
|
62
|
+
#
|
63
|
+
# ask is useless for our needs so we just raise similar to
|
64
|
+
# Vagrant::UI::Silent.
|
65
|
+
#
|
66
|
+
def ask(*args)
|
67
|
+
raise Errors::UIExpectsTTY
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
data/test/helper.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'bundler/setup'
|
2
|
+
|
3
|
+
if ENV["COVERAGE"]
|
4
|
+
require 'simplecov'
|
5
|
+
SimpleCov.start do
|
6
|
+
add_filter '/test/'
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
require 'furnish/test'
|
11
|
+
require 'furnish/provisioners/auto_ip'
|
12
|
+
require 'furnish/provisioners/vagrant'
|
13
|
+
|
14
|
+
require 'minitest/autorun'
|
@@ -0,0 +1,229 @@
|
|
1
|
+
require 'helper'
|
2
|
+
require 'stringio'
|
3
|
+
|
4
|
+
#--
|
5
|
+
# XXX We can't use SchedulerTestCase here because we need to do failure testing,
|
6
|
+
# which the monitor will catch and abort over.
|
7
|
+
#++
|
8
|
+
class TestVagrant < Furnish::TestCase
|
9
|
+
BOX_URL = "http://files.vagrantup.com/precise32.box"
|
10
|
+
|
11
|
+
attr_reader :sched
|
12
|
+
|
13
|
+
def setup
|
14
|
+
super
|
15
|
+
|
16
|
+
if ENV["VAGRANT_DEBUG"]
|
17
|
+
Furnish.logger = Furnish::Logger.new($stdout, 3)
|
18
|
+
end
|
19
|
+
|
20
|
+
Furnish::Vagrant::UI.debug_level = 0
|
21
|
+
|
22
|
+
@sched = Furnish::Scheduler.new
|
23
|
+
sched.serial = true
|
24
|
+
setup_ip
|
25
|
+
end
|
26
|
+
|
27
|
+
def teardown
|
28
|
+
sched.teardown
|
29
|
+
|
30
|
+
if ENV["VAGRANT_DEBUG"]
|
31
|
+
# hack to get around the close cleanup in Furnish::TestCase
|
32
|
+
Furnish.logger = Furnish::Logger.new(StringIO.new("", "w"), 3)
|
33
|
+
end
|
34
|
+
|
35
|
+
super
|
36
|
+
end
|
37
|
+
|
38
|
+
def run_ssh(ip, cmd)
|
39
|
+
Net::SSH.start(ip, 'vagrant', :password => 'vagrant') do |ssh|
|
40
|
+
ssh.open_channel do |ch|
|
41
|
+
ch.on_open_failed do |ch, code, desc|
|
42
|
+
yield false, nil
|
43
|
+
end
|
44
|
+
|
45
|
+
ch.exec(cmd) do |ch, success|
|
46
|
+
yield ch, success
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
ssh.loop
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def check_ssh(ip, desc=nil)
|
55
|
+
run_ssh(ip, "ls") do |ch, success|
|
56
|
+
if ch
|
57
|
+
assert(true, "ssh check on #{ip}#{desc ? ": #{desc}" : ""}")
|
58
|
+
else
|
59
|
+
assert(false, "ssh check on #{ip}#{desc ? ": #{desc}" : ""}")
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def setup_ip
|
65
|
+
@ip = Furnish::IP.new("10.10.10.0/24")
|
66
|
+
# Allocate the first two addresses -- vagrant wants the subnet and the first IP.
|
67
|
+
@ip.allocated.add("10.10.10.0")
|
68
|
+
@ip.allocated.add("10.10.10.1")
|
69
|
+
end
|
70
|
+
|
71
|
+
def make_provisioner(num=1)
|
72
|
+
[
|
73
|
+
Furnish::Provisioner::AutoIP.new(@ip, num),
|
74
|
+
Furnish::Provisioner::Vagrant.new(
|
75
|
+
:box_url => BOX_URL,
|
76
|
+
:number_of_servers => num
|
77
|
+
)
|
78
|
+
]
|
79
|
+
end
|
80
|
+
|
81
|
+
def test_constructor
|
82
|
+
assert_raises(ArgumentError, "arguments must be a hash") do
|
83
|
+
Furnish::Provisioner::Vagrant.new(nil)
|
84
|
+
end
|
85
|
+
|
86
|
+
assert_raises(ArgumentError, "Furnish::Provisioner::Vagrant must be configured with a box or box_url") do
|
87
|
+
Furnish::Provisioner::Vagrant.new({})
|
88
|
+
end
|
89
|
+
|
90
|
+
assert(Furnish::Provisioner::Vagrant.new(:box_url => BOX_URL))
|
91
|
+
assert(Furnish::Provisioner::Vagrant.new(:box => "precise32"))
|
92
|
+
|
93
|
+
assert_raises(ArgumentError, "customizations must be an array of customizations, or array of array of multiple customizations.") do
|
94
|
+
Furnish::Provisioner::Vagrant.new(:box_url => BOX_URL, :customizations => 1)
|
95
|
+
end
|
96
|
+
|
97
|
+
assert(
|
98
|
+
Furnish::Provisioner::Vagrant.new(
|
99
|
+
:box_url => BOX_URL,
|
100
|
+
:customizations => %w[one two three]
|
101
|
+
)
|
102
|
+
)
|
103
|
+
|
104
|
+
assert(
|
105
|
+
Furnish::Provisioner::Vagrant.new(
|
106
|
+
:box_url => BOX_URL,
|
107
|
+
:customizations => [%w[one two three], %w[four five six]]
|
108
|
+
)
|
109
|
+
)
|
110
|
+
end
|
111
|
+
|
112
|
+
def test_basic_provision
|
113
|
+
sched.schedule_provision('test1', make_provisioner, [])
|
114
|
+
sched.run
|
115
|
+
|
116
|
+
assert_includes(sched.vm.solved, 'test1', 'test1 is provisioned')
|
117
|
+
check_ssh(@ip.group_ips('test1').first, 'test1 is booting properly')
|
118
|
+
|
119
|
+
sched.schedule_provision('test2', make_provisioner(3), [])
|
120
|
+
sched.run
|
121
|
+
|
122
|
+
assert_includes(sched.vm.solved, 'test2', 'test2 is provisioned')
|
123
|
+
|
124
|
+
@ip.group_ips('test2').each do |test_ip|
|
125
|
+
check_ssh(test_ip, "test2 group, ip #{test_ip} is booting properly")
|
126
|
+
end
|
127
|
+
|
128
|
+
assert_equal(3, @ip.group_ips('test2').count, '3 machines and IPs were allocated for test2 group')
|
129
|
+
|
130
|
+
assert_match(
|
131
|
+
/^1 servers; prison dir: /,
|
132
|
+
sched.vm.groups['test1'].last.report.first,
|
133
|
+
"report reflects number of servers provisioned for group test1"
|
134
|
+
)
|
135
|
+
|
136
|
+
assert_match(
|
137
|
+
/^3 servers; prison dir: /,
|
138
|
+
sched.vm.groups['test2'].last.report.first,
|
139
|
+
"report reflects number of servers provisioned for group test2"
|
140
|
+
)
|
141
|
+
end
|
142
|
+
|
143
|
+
def test_invalid_provision
|
144
|
+
mismatched_num = [
|
145
|
+
Furnish::Provisioner::AutoIP.new(@ip, 1),
|
146
|
+
Furnish::Provisioner::Vagrant.new(
|
147
|
+
:box_url => BOX_URL,
|
148
|
+
:number_of_servers => 3
|
149
|
+
)
|
150
|
+
]
|
151
|
+
|
152
|
+
sched.schedule_provision('test1', mismatched_num, [])
|
153
|
+
|
154
|
+
assert_raises(
|
155
|
+
RuntimeError,
|
156
|
+
"The number of requested IP addresses does not match the number of requested servers"
|
157
|
+
) { sched.run }
|
158
|
+
end
|
159
|
+
|
160
|
+
def test_customized_provision
|
161
|
+
customized = [
|
162
|
+
Furnish::Provisioner::AutoIP.new(@ip, 1),
|
163
|
+
Furnish::Provisioner::Vagrant.new(
|
164
|
+
:box_url => BOX_URL,
|
165
|
+
:number_of_servers => 1,
|
166
|
+
:customizations => [["modifyvm", :id, "--memory", 1024]]
|
167
|
+
)
|
168
|
+
]
|
169
|
+
|
170
|
+
sched.schedule_provision('test1', customized, [])
|
171
|
+
sched.run
|
172
|
+
|
173
|
+
assert_includes(sched.vm.solved, 'test1', 'test1 is provisioned')
|
174
|
+
|
175
|
+
ip = @ip.group_ips('test1').first
|
176
|
+
|
177
|
+
output = ''
|
178
|
+
exit_code = 0
|
179
|
+
|
180
|
+
run_ssh(ip, "free -m") do |ch, success|
|
181
|
+
ch.on_data do |ch, data|
|
182
|
+
output << data
|
183
|
+
end
|
184
|
+
|
185
|
+
ch.on_request('exit-status') do |ch, data|
|
186
|
+
exit_code += data.read_long
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
refute(output.empty?, "output returned successfully")
|
191
|
+
assert_equal(0, exit_code, "command succeeded")
|
192
|
+
|
193
|
+
mem_line = output.split(/\n/).grep(/^Mem/).first
|
194
|
+
usage = mem_line.split(/\s+/)[1]
|
195
|
+
assert_equal("1001", usage, "usage is higher with customizations")
|
196
|
+
end
|
197
|
+
|
198
|
+
def test_logger_interaction
|
199
|
+
Furnish.logger.puts "vagrant log tests are running"
|
200
|
+
|
201
|
+
io = StringIO.new("", "w")
|
202
|
+
Furnish.logger = Furnish::Logger.new(io, 0)
|
203
|
+
|
204
|
+
sched.schedule_provision('test1', make_provisioner, [])
|
205
|
+
sched.run
|
206
|
+
|
207
|
+
assert_includes(sched.vm.solved, 'test1', 'test1 is provisioned')
|
208
|
+
|
209
|
+
log = io.string
|
210
|
+
|
211
|
+
assert_match(/\[test1-0\]/, log, "vagrant log is showing up")
|
212
|
+
assert_match(/Importing base box 'precise32'/, log, "vagrant log is showing up")
|
213
|
+
|
214
|
+
io = StringIO.new("", "w")
|
215
|
+
Furnish.logger = Furnish::Logger.new(io, 0)
|
216
|
+
|
217
|
+
Furnish::Vagrant::UI.debug_level = 1
|
218
|
+
|
219
|
+
sched.schedule_provision('test2', make_provisioner, [])
|
220
|
+
sched.run
|
221
|
+
|
222
|
+
assert_includes(sched.vm.solved, 'test2', 'test2 is provisioned')
|
223
|
+
|
224
|
+
log = io.string
|
225
|
+
|
226
|
+
refute_match(/\[test2-0\]/, log, "vagrant log is showing up")
|
227
|
+
refute_match(/Importing base box 'precise32'/, log, "vagrant log is showing up")
|
228
|
+
end
|
229
|
+
end
|
metadata
ADDED
@@ -0,0 +1,235 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: furnish-vagrant
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Erik Hollensbe
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-03-23 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: vagrant-prison
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 0.1.0
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 0.1.0
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: furnish
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ~>
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: 0.0.3
|
38
|
+
type: :runtime
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ~>
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: 0.0.3
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: furnish-ip
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ~>
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: 0.0.2
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 0.0.2
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: rake
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
type: :development
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
name: minitest
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ~>
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: 4.5.0
|
86
|
+
type: :development
|
87
|
+
prerelease: false
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ~>
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: 4.5.0
|
94
|
+
- !ruby/object:Gem::Dependency
|
95
|
+
name: guard-minitest
|
96
|
+
requirement: !ruby/object:Gem::Requirement
|
97
|
+
none: false
|
98
|
+
requirements:
|
99
|
+
- - ! '>='
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: '0'
|
102
|
+
type: :development
|
103
|
+
prerelease: false
|
104
|
+
version_requirements: !ruby/object:Gem::Requirement
|
105
|
+
none: false
|
106
|
+
requirements:
|
107
|
+
- - ! '>='
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '0'
|
110
|
+
- !ruby/object:Gem::Dependency
|
111
|
+
name: guard-rake
|
112
|
+
requirement: !ruby/object:Gem::Requirement
|
113
|
+
none: false
|
114
|
+
requirements:
|
115
|
+
- - ! '>='
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
none: false
|
122
|
+
requirements:
|
123
|
+
- - ! '>='
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
version: '0'
|
126
|
+
- !ruby/object:Gem::Dependency
|
127
|
+
name: rdoc
|
128
|
+
requirement: !ruby/object:Gem::Requirement
|
129
|
+
none: false
|
130
|
+
requirements:
|
131
|
+
- - ! '>='
|
132
|
+
- !ruby/object:Gem::Version
|
133
|
+
version: '0'
|
134
|
+
type: :development
|
135
|
+
prerelease: false
|
136
|
+
version_requirements: !ruby/object:Gem::Requirement
|
137
|
+
none: false
|
138
|
+
requirements:
|
139
|
+
- - ! '>='
|
140
|
+
- !ruby/object:Gem::Version
|
141
|
+
version: '0'
|
142
|
+
- !ruby/object:Gem::Dependency
|
143
|
+
name: rb-fsevent
|
144
|
+
requirement: !ruby/object:Gem::Requirement
|
145
|
+
none: false
|
146
|
+
requirements:
|
147
|
+
- - ! '>='
|
148
|
+
- !ruby/object:Gem::Version
|
149
|
+
version: '0'
|
150
|
+
type: :development
|
151
|
+
prerelease: false
|
152
|
+
version_requirements: !ruby/object:Gem::Requirement
|
153
|
+
none: false
|
154
|
+
requirements:
|
155
|
+
- - ! '>='
|
156
|
+
- !ruby/object:Gem::Version
|
157
|
+
version: '0'
|
158
|
+
- !ruby/object:Gem::Dependency
|
159
|
+
name: simplecov
|
160
|
+
requirement: !ruby/object:Gem::Requirement
|
161
|
+
none: false
|
162
|
+
requirements:
|
163
|
+
- - ! '>='
|
164
|
+
- !ruby/object:Gem::Version
|
165
|
+
version: '0'
|
166
|
+
type: :development
|
167
|
+
prerelease: false
|
168
|
+
version_requirements: !ruby/object:Gem::Requirement
|
169
|
+
none: false
|
170
|
+
requirements:
|
171
|
+
- - ! '>='
|
172
|
+
- !ruby/object:Gem::Version
|
173
|
+
version: '0'
|
174
|
+
- !ruby/object:Gem::Dependency
|
175
|
+
name: net-ssh
|
176
|
+
requirement: !ruby/object:Gem::Requirement
|
177
|
+
none: false
|
178
|
+
requirements:
|
179
|
+
- - ! '>='
|
180
|
+
- !ruby/object:Gem::Version
|
181
|
+
version: '0'
|
182
|
+
type: :development
|
183
|
+
prerelease: false
|
184
|
+
version_requirements: !ruby/object:Gem::Requirement
|
185
|
+
none: false
|
186
|
+
requirements:
|
187
|
+
- - ! '>='
|
188
|
+
- !ruby/object:Gem::Version
|
189
|
+
version: '0'
|
190
|
+
description: Furnish -> Vagrant 1.0.x bridge
|
191
|
+
email:
|
192
|
+
- erik+github@hollensbe.org
|
193
|
+
executables: []
|
194
|
+
extensions: []
|
195
|
+
extra_rdoc_files: []
|
196
|
+
files:
|
197
|
+
- .gitignore
|
198
|
+
- Gemfile
|
199
|
+
- Guardfile
|
200
|
+
- LICENSE.txt
|
201
|
+
- README.md
|
202
|
+
- Rakefile
|
203
|
+
- furnish-vagrant.gemspec
|
204
|
+
- lib/furnish/provisioners/vagrant.rb
|
205
|
+
- lib/furnish/vagrant/ui.rb
|
206
|
+
- lib/furnish/vagrant/version.rb
|
207
|
+
- test/helper.rb
|
208
|
+
- test/test_vagrant.rb
|
209
|
+
homepage: https://github.com/chef-workflow/furnish-vagrant
|
210
|
+
licenses: []
|
211
|
+
post_install_message:
|
212
|
+
rdoc_options: []
|
213
|
+
require_paths:
|
214
|
+
- lib
|
215
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
216
|
+
none: false
|
217
|
+
requirements:
|
218
|
+
- - ! '>='
|
219
|
+
- !ruby/object:Gem::Version
|
220
|
+
version: '0'
|
221
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
222
|
+
none: false
|
223
|
+
requirements:
|
224
|
+
- - ! '>='
|
225
|
+
- !ruby/object:Gem::Version
|
226
|
+
version: '0'
|
227
|
+
requirements: []
|
228
|
+
rubyforge_project:
|
229
|
+
rubygems_version: 1.8.25
|
230
|
+
signing_key:
|
231
|
+
specification_version: 3
|
232
|
+
summary: Furnish -> Vagrant 1.0.x bridge
|
233
|
+
test_files:
|
234
|
+
- test/helper.rb
|
235
|
+
- test/test_vagrant.rb
|