test-kitchen-provisioners 0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +3 -0
- data/.travis.yml +6 -0
- data/Gemfile +9 -0
- data/LICENSE.txt +22 -0
- data/README.md +28 -0
- data/Rakefile +0 -0
- data/lib/kitchen/provisioner/apt.rb +16 -0
- data/lib/kitchen/provisioner/chef_apt_ruby_roles_chef_zero.rb +58 -0
- data/lib/kitchen/provisioner/ruby_roles.rb +32 -0
- data/spec/kitchen/provisioner/apt_spec.rb +10 -0
- data/spec/kitchen/provisioner/chef_apt_ruby_roles_chef_zero_spec.rb +69 -0
- data/spec/kitchen/provisioner/ruby_roles_spec.rb +46 -0
- data/spec/spec_helper.rb +9 -0
- data/test-kitchen-provisioners.gemspec +18 -0
- metadata +98 -0
data/.gitignore
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 David Genord II
|
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,28 @@
|
|
1
|
+
test-kitchen-provisioners
|
2
|
+
=========================
|
3
|
+
|
4
|
+
A collection of provisioners to be used in [test-kitchen](https://github.com/opscode/test-kitchen) runs to
|
5
|
+
add functionality to the Provisioner system.
|
6
|
+
|
7
|
+
Unfortunately as Provisioners were not built with chaining in mind, these may come across as a bit hackish.
|
8
|
+
|
9
|
+
## Usage
|
10
|
+
|
11
|
+
gem install test-kitchen-provisioners
|
12
|
+
|
13
|
+
Set the `provisioner` value in `.kitchen.yml` to one of the available provisioners.
|
14
|
+
|
15
|
+
## Available Providers
|
16
|
+
|
17
|
+
### ChefAptRubyRolesChefZero
|
18
|
+
|
19
|
+
provisioner: chef_apt_ruby_roles_chef_zero
|
20
|
+
|
21
|
+
A chain provisioners that ensure:
|
22
|
+
|
23
|
+
1. Aptitude update is called before chef-zero starts. This lets us not have to make every single cookbook
|
24
|
+
reliant on the apt cookbook.
|
25
|
+
2. Ruby roles get converted to JSON. chef-zero only knows how to work with JSON files, but we like Ruby.
|
26
|
+
This provider runs against the cookbook sandbox on the host machine before the files are uploaded to the VM
|
27
|
+
3. Calls the built-in chef-zero provisioner to continue as normal.
|
28
|
+
|
data/Rakefile
ADDED
File without changes
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'kitchen'
|
2
|
+
require 'kitchen/provisioner/base'
|
3
|
+
|
4
|
+
module Kitchen
|
5
|
+
module Provisioner
|
6
|
+
|
7
|
+
# Apt Provisioner
|
8
|
+
# This makes sure that aptitude is up-to-date at the beginning of the
|
9
|
+
# chef run before cookbooks are pulled in.
|
10
|
+
class Apt < Base
|
11
|
+
def run_command
|
12
|
+
"#{sudo("aptitude")} update"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require 'kitchen/provisioner/apt'
|
2
|
+
require 'kitchen/provisioner/ruby_roles'
|
3
|
+
require 'kitchen/provisioner/chef_zero'
|
4
|
+
|
5
|
+
module Kitchen
|
6
|
+
module Provisioner
|
7
|
+
|
8
|
+
# This Provisioner combines the roles of the Apt, Ruby Roles, and ChefZero
|
9
|
+
# provisioners, to ensure a server is ready to run before ChefZero starts its magic
|
10
|
+
# Must be named "Chef..." otherwise TestKitchen won't understand that we intend to use chef
|
11
|
+
class ChefAptRubyRolesChefZero < Base
|
12
|
+
def initialize(instance, options)
|
13
|
+
super
|
14
|
+
@apt = Apt.new(instance, options)
|
15
|
+
@chef_zero = ChefZero.new(instance, options)
|
16
|
+
@ruby_roles = RubyRoles.new(instance, options)
|
17
|
+
end
|
18
|
+
|
19
|
+
def install_command
|
20
|
+
@chef_zero.install_command
|
21
|
+
end
|
22
|
+
|
23
|
+
def init_command
|
24
|
+
@chef_zero.init_command
|
25
|
+
end
|
26
|
+
|
27
|
+
# Let chef-zero create the sandbox then convert the Ruby-based role files
|
28
|
+
# into JSON before uploads happen (which happen right after this returns)
|
29
|
+
def create_sandbox
|
30
|
+
sandbox_path = @chef_zero.create_sandbox
|
31
|
+
@ruby_roles.roles_path = File.join(sandbox_path, "roles")
|
32
|
+
@ruby_roles.create_sandbox
|
33
|
+
sandbox_path
|
34
|
+
end
|
35
|
+
|
36
|
+
def prepare_command
|
37
|
+
@chef_zero.prepare_command
|
38
|
+
end
|
39
|
+
|
40
|
+
# Run the apt provisioner before starting up chef-zero
|
41
|
+
def run_command
|
42
|
+
[
|
43
|
+
@apt.run_command,
|
44
|
+
@chef_zero.run_command
|
45
|
+
].join(" && ")
|
46
|
+
end
|
47
|
+
|
48
|
+
def cleanup_sandbox
|
49
|
+
@chef_zero.cleanup_sandbox
|
50
|
+
end
|
51
|
+
|
52
|
+
def home_path
|
53
|
+
@chef_zero.home_path
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'kitchen'
|
2
|
+
require 'kitchen/provisioner/base'
|
3
|
+
require 'chef'
|
4
|
+
|
5
|
+
module Kitchen
|
6
|
+
module Provisioner
|
7
|
+
|
8
|
+
# RubyRoles Provisioner
|
9
|
+
# This provisioner, when given a path to a cookbook's roles directory, will iterate through
|
10
|
+
# each Ruby-written role and generate the JSON version.
|
11
|
+
# This then allows the ChefZero tool to pick up these roles, as it only knows about JSON
|
12
|
+
class RubyRoles < Base
|
13
|
+
|
14
|
+
attr_accessor :roles_path
|
15
|
+
|
16
|
+
def create_sandbox
|
17
|
+
# From https://gist.github.com/red56/834890
|
18
|
+
Dir.glob(File.join(@roles_path, "*.rb")).each do |ruby_role_file_name|
|
19
|
+
role = Chef::Role.new
|
20
|
+
role.from_file(ruby_role_file_name)
|
21
|
+
json_file_name = ruby_role_file_name.gsub(/rb$/, "json")
|
22
|
+
|
23
|
+
File.open(json_file_name, "w+") do |json_file|
|
24
|
+
json_file.write(JSON.pretty_generate(role))
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'kitchen/provisioner/apt'
|
3
|
+
|
4
|
+
describe Kitchen::Provisioner::Apt do
|
5
|
+
it "runs aptitude update" do
|
6
|
+
provisioner = Kitchen::Provisioner::Apt.new(BogusInstance.new, nil)
|
7
|
+
expect(provisioner).to receive(:sudo).with("aptitude").and_return("aptitude")
|
8
|
+
expect(provisioner.run_command).to eq("aptitude update")
|
9
|
+
end
|
10
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'kitchen/provisioner/chef_apt_ruby_roles_chef_zero'
|
3
|
+
|
4
|
+
describe Kitchen::Provisioner::ChefAptRubyRolesChefZero do
|
5
|
+
|
6
|
+
before do
|
7
|
+
@provisioner = Kitchen::Provisioner::ChefAptRubyRolesChefZero.new(BogusInstance.new, nil)
|
8
|
+
@apt = @provisioner.instance_variable_get("@apt")
|
9
|
+
@ruby_roles = @provisioner.instance_variable_get("@ruby_roles")
|
10
|
+
@chef_zero = @provisioner.instance_variable_get("@chef_zero")
|
11
|
+
end
|
12
|
+
|
13
|
+
it "installs chef zero" do
|
14
|
+
expect(@chef_zero).to receive(:install_command)
|
15
|
+
expect(@ruby_roles).not_to receive(:install_command)
|
16
|
+
expect(@apt).not_to receive(:install_command)
|
17
|
+
|
18
|
+
@provisioner.install_command
|
19
|
+
end
|
20
|
+
|
21
|
+
it "inits chef zero" do
|
22
|
+
expect(@chef_zero).to receive(:init_command)
|
23
|
+
expect(@ruby_roles).not_to receive(:init_command)
|
24
|
+
expect(@apt).not_to receive(:init_command)
|
25
|
+
|
26
|
+
@provisioner.init_command
|
27
|
+
end
|
28
|
+
|
29
|
+
it "creates sandbox for chef zero and converts ruby roles" do
|
30
|
+
expect(@chef_zero).to receive(:create_sandbox).and_return("path").ordered
|
31
|
+
expect(@ruby_roles).to receive(:roles_path=).with("path/roles").ordered
|
32
|
+
expect(@ruby_roles).to receive(:create_sandbox).ordered
|
33
|
+
expect(@apt).not_to receive(:create_sandbox)
|
34
|
+
|
35
|
+
@provisioner.create_sandbox
|
36
|
+
end
|
37
|
+
|
38
|
+
it "prepares chef zero" do
|
39
|
+
expect(@chef_zero).to receive(:prepare_command)
|
40
|
+
expect(@ruby_roles).not_to receive(:prepare_command)
|
41
|
+
expect(@apt).not_to receive(:prepare_command)
|
42
|
+
|
43
|
+
@provisioner.prepare_command
|
44
|
+
end
|
45
|
+
|
46
|
+
it "runs apt, ruby roles, then chef-zero, in that order" do
|
47
|
+
expect(@apt).to receive(:run_command).and_return("apt me").ordered
|
48
|
+
expect(@chef_zero).to receive(:run_command).and_return("chef me").ordered
|
49
|
+
expect(@ruby_roles).not_to receive(:run_command)
|
50
|
+
|
51
|
+
expect(@provisioner.run_command).to eq("apt me && chef me")
|
52
|
+
end
|
53
|
+
|
54
|
+
it "cleans up the chef zero sandbox" do
|
55
|
+
expect(@chef_zero).to receive(:cleanup_sandbox)
|
56
|
+
expect(@ruby_roles).not_to receive(:cleanup_sandbox)
|
57
|
+
expect(@apt).not_to receive(:cleanup_sandbox)
|
58
|
+
|
59
|
+
@provisioner.cleanup_sandbox
|
60
|
+
end
|
61
|
+
|
62
|
+
it "returns the home path of chef zero" do
|
63
|
+
expect(@chef_zero).to receive(:home_path)
|
64
|
+
expect(@ruby_roles).not_to receive(:home_path)
|
65
|
+
expect(@apt).not_to receive(:home_path)
|
66
|
+
|
67
|
+
@provisioner.home_path
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'kitchen/provisioner/ruby_roles'
|
3
|
+
|
4
|
+
describe Kitchen::Provisioner::RubyRoles do
|
5
|
+
before do
|
6
|
+
# Sorry, can't use FakeFS because chef completely bypasses the
|
7
|
+
# entire File api when reading the file.
|
8
|
+
FileUtils.mkdir_p("tmp/roles")
|
9
|
+
end
|
10
|
+
|
11
|
+
after do
|
12
|
+
FileUtils.rm_r("tmp/roles")
|
13
|
+
end
|
14
|
+
|
15
|
+
it "converts any existing Ruby chef roles into JSON" do
|
16
|
+
File.open("tmp/roles/role1.rb", "w+") do |role|
|
17
|
+
role.puts <<EOC
|
18
|
+
name "role1"
|
19
|
+
description "I define how things work"
|
20
|
+
|
21
|
+
run_list("recipe[test::role1]")
|
22
|
+
EOC
|
23
|
+
end
|
24
|
+
|
25
|
+
File.open("tmp/roles/role2.rb", "w+") do |role|
|
26
|
+
role.puts <<EOC
|
27
|
+
name "role2"
|
28
|
+
description "I define how other things work"
|
29
|
+
|
30
|
+
run_list("recipe[test::role2]")
|
31
|
+
EOC
|
32
|
+
end
|
33
|
+
|
34
|
+
File.open("tmp/roles/role3.js", "w+") do |role|
|
35
|
+
role.puts "This is role thingy 3"
|
36
|
+
end
|
37
|
+
|
38
|
+
provisioner = Kitchen::Provisioner::RubyRoles.new(BogusInstance.new, nil)
|
39
|
+
provisioner.roles_path = "tmp/roles"
|
40
|
+
provisioner.create_sandbox
|
41
|
+
|
42
|
+
expect(File.exists?("tmp/roles/role1.json")).to be_true
|
43
|
+
expect(File.exists?("tmp/roles/role2.json")).to be_true
|
44
|
+
expect(File.exists?("tmp/roles/role3.json")).to be_false
|
45
|
+
end
|
46
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
Gem::Specification.new do |gem|
|
2
|
+
gem.name = "test-kitchen-provisioners"
|
3
|
+
gem.version = "0.1"
|
4
|
+
gem.license = "MIT"
|
5
|
+
gem.authors = ["Collective Idea"]
|
6
|
+
gem.email = ["info@collectiveidea.com"]
|
7
|
+
|
8
|
+
gem.summary = "A collection of helpful provisioniners for working with Test Kitchen"
|
9
|
+
gem.description = gem.summary
|
10
|
+
gem.homepage = "https://github.com/collectiveidea/test-kitchen-provisioners"
|
11
|
+
|
12
|
+
gem.files = `git ls-files`.split($/)
|
13
|
+
gem.test_files = gem.files.grep(%r{spec})
|
14
|
+
gem.require_paths = ["lib"]
|
15
|
+
|
16
|
+
gem.add_dependency "chef", "~> 11.6.0"
|
17
|
+
gem.add_dependency "test-kitchen", "1.0.0.beta.2"
|
18
|
+
end
|
metadata
ADDED
@@ -0,0 +1,98 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: test-kitchen-provisioners
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: '0.1'
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Collective Idea
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-08-03 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: chef
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 11.6.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: 11.6.0
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: test-kitchen
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - '='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: 1.0.0.beta.2
|
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: 1.0.0.beta.2
|
46
|
+
description: A collection of helpful provisioniners for working with Test Kitchen
|
47
|
+
email:
|
48
|
+
- info@collectiveidea.com
|
49
|
+
executables: []
|
50
|
+
extensions: []
|
51
|
+
extra_rdoc_files: []
|
52
|
+
files:
|
53
|
+
- .gitignore
|
54
|
+
- .travis.yml
|
55
|
+
- Gemfile
|
56
|
+
- LICENSE.txt
|
57
|
+
- README.md
|
58
|
+
- Rakefile
|
59
|
+
- lib/kitchen/provisioner/apt.rb
|
60
|
+
- lib/kitchen/provisioner/chef_apt_ruby_roles_chef_zero.rb
|
61
|
+
- lib/kitchen/provisioner/ruby_roles.rb
|
62
|
+
- spec/kitchen/provisioner/apt_spec.rb
|
63
|
+
- spec/kitchen/provisioner/chef_apt_ruby_roles_chef_zero_spec.rb
|
64
|
+
- spec/kitchen/provisioner/ruby_roles_spec.rb
|
65
|
+
- spec/spec_helper.rb
|
66
|
+
- test-kitchen-provisioners.gemspec
|
67
|
+
homepage: https://github.com/collectiveidea/test-kitchen-provisioners
|
68
|
+
licenses:
|
69
|
+
- MIT
|
70
|
+
post_install_message:
|
71
|
+
rdoc_options: []
|
72
|
+
require_paths:
|
73
|
+
- lib
|
74
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
75
|
+
none: false
|
76
|
+
requirements:
|
77
|
+
- - ! '>='
|
78
|
+
- !ruby/object:Gem::Version
|
79
|
+
version: '0'
|
80
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ! '>='
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: '0'
|
86
|
+
requirements: []
|
87
|
+
rubyforge_project:
|
88
|
+
rubygems_version: 1.8.25
|
89
|
+
signing_key:
|
90
|
+
specification_version: 3
|
91
|
+
summary: A collection of helpful provisioniners for working with Test Kitchen
|
92
|
+
test_files:
|
93
|
+
- spec/kitchen/provisioner/apt_spec.rb
|
94
|
+
- spec/kitchen/provisioner/chef_apt_ruby_roles_chef_zero_spec.rb
|
95
|
+
- spec/kitchen/provisioner/ruby_roles_spec.rb
|
96
|
+
- spec/spec_helper.rb
|
97
|
+
- test-kitchen-provisioners.gemspec
|
98
|
+
has_rdoc:
|