toft-puppet 0.0.9
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/Gemfile +3 -0
- data/Gemfile.lock +62 -0
- data/Rakefile +121 -0
- data/features/checker.feature +14 -0
- data/features/chef.feature +70 -0
- data/features/command.feature +20 -0
- data/features/node.feature +41 -0
- data/features/puppet.feature +40 -0
- data/features/step_definitions/centos/checks.rb +9 -0
- data/features/step_definitions/checker.rb +15 -0
- data/features/step_definitions/chef.rb +43 -0
- data/features/step_definitions/command.rb +28 -0
- data/features/step_definitions/node.rb +65 -0
- data/features/step_definitions/puppet.rb +7 -0
- data/features/support/env.rb +25 -0
- data/fixtures/chef/attributes.json +9 -0
- data/fixtures/chef/cookbooks/test/attributes/default.rb +4 -0
- data/fixtures/chef/cookbooks/test/recipes/attribute.rb +19 -0
- data/fixtures/chef/cookbooks/test/recipes/default.rb +4 -0
- data/fixtures/chef/cookbooks/test/recipes/role.rb +4 -0
- data/fixtures/chef/roles/test.rb +3 -0
- data/fixtures/puppet/conf/fileserver.conf +3 -0
- data/fixtures/puppet/conf/puppet.conf +15 -0
- data/fixtures/puppet/conf/puppet_exec.conf +9 -0
- data/fixtures/puppet/conf/puppet_fileserver.conf +8 -0
- data/fixtures/puppet/conf/puppet_modules.conf +7 -0
- data/fixtures/puppet/conf/puppet_template.conf +8 -0
- data/fixtures/puppet/manifests/fileserver/conf/test_fileserver +1 -0
- data/fixtures/puppet/manifests/nodes/test_node.pp +26 -0
- data/fixtures/puppet/manifests/site.pp +1 -0
- data/fixtures/puppet/manifests/templates/template_test +2 -0
- data/fixtures/puppet/manifests/test.pp +8 -0
- data/fixtures/puppet/manifests/test_fileserver.pp +14 -0
- data/fixtures/puppet/manifests/test_install.pp +5 -0
- data/fixtures/puppet/manifests/test_module.pp +5 -0
- data/fixtures/puppet/manifests/test_service.pp +11 -0
- data/fixtures/puppet/manifests/test_template.pp +12 -0
- data/fixtures/puppet/modules/test_module/manifests/init.pp +8 -0
- data/lib/toft.rb +39 -0
- data/lib/toft/chef/chef_attributes.rb +29 -0
- data/lib/toft/chef/chef_runner.rb +77 -0
- data/lib/toft/command_executor.rb +16 -0
- data/lib/toft/file_checker.rb +47 -0
- data/lib/toft/node.rb +243 -0
- data/lib/toft/node_controller.rb +32 -0
- data/lib/toft/puppet/puppet_runner.rb +38 -0
- data/lib/toft/version.rb +3 -0
- data/scripts/bin/centos/lxc-prepare-host +172 -0
- data/scripts/bin/centos/provision_vagrant +11 -0
- data/scripts/bin/share/install-chef-ubuntu.sh +19 -0
- data/scripts/bin/share/lxc-create-centos-image +60 -0
- data/scripts/bin/ubuntu/lxc-create-ubuntu-image +77 -0
- data/scripts/bin/ubuntu/lxc-prepare-host +199 -0
- data/scripts/bin/ubuntu/provision_vagrant +9 -0
- data/scripts/lxc-templates/files/rc.local +38 -0
- data/scripts/lxc-templates/lxc-centos-6 +279 -0
- data/scripts/lxc-templates/lxc-lenny +255 -0
- data/scripts/lxc-templates/lxc-lucid +313 -0
- data/scripts/lxc-templates/lxc-natty +237 -0
- data/spec/fixtures/illegal_syntax.json +1 -0
- data/spec/spec_helper.rb +6 -0
- data/spec/toft/chef/chef_attributes_spec.rb +39 -0
- data/spec/toft/chef/chef_runner_spec.rb +34 -0
- data/spec/toft/node_spec.rb +18 -0
- data/spec/toft/puppet/puppet_runner_spec.rb +26 -0
- metadata +234 -0
@@ -0,0 +1,28 @@
|
|
1
|
+
Then /^Running ssh command "([^"]*)" on "([^"]*)" should succeed$/ do |cmd, node|
|
2
|
+
lambda { find(node).run_ssh(cmd) }.should_not raise_error
|
3
|
+
end
|
4
|
+
|
5
|
+
Then /^Running ssh command "([^"]*)" on "([^"]*)" should fail$/ do |cmd, node|
|
6
|
+
lambda { find(node).run_ssh(cmd) }.should raise_error
|
7
|
+
end
|
8
|
+
|
9
|
+
Then /^Rm "([^"]*)" on "([^"]*)" should fail$/ do |dir, node|
|
10
|
+
lambda { find(node).rm(dir) }.should raise_error
|
11
|
+
end
|
12
|
+
|
13
|
+
Then /^Rm "([^"]*)" on "([^"]*)" should succeed$/ do |dir, node|
|
14
|
+
lambda { find(node).rm(dir) }.should_not raise_error
|
15
|
+
end
|
16
|
+
|
17
|
+
Then /^the result of running ssh command "([^"]*)" on "([^"]*)" should contain "([^"]*)"$/ do |cmd, node, s|
|
18
|
+
r = find(node).run_ssh(cmd)
|
19
|
+
r.stdout.should include(s)
|
20
|
+
end
|
21
|
+
|
22
|
+
Then /^the result of running ssh command "([^"]*)" on "([^"]*)" should fail because of "([^"]*)"$/ do |cmd, node, s|
|
23
|
+
begin
|
24
|
+
r = find(node).run_ssh(cmd)
|
25
|
+
rescue CommandExecutionError => e
|
26
|
+
e.stdout.should include(s)
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
Given /^I have a clean running node n1$/ do
|
2
|
+
@n1.start
|
3
|
+
@n1.rm "/tmp/stub"
|
4
|
+
end
|
5
|
+
|
6
|
+
When /^I add another node "([^"]*)" with ip "([^"]*)"$/ do |node, ip|
|
7
|
+
create_node node, {:ip => ip, :type => CONTAINER_TYPE}
|
8
|
+
end
|
9
|
+
|
10
|
+
When /^I add another node "([^"]*)"$/ do |node|
|
11
|
+
n = create_node node, {:type => CONTAINER_TYPE}
|
12
|
+
n.start
|
13
|
+
end
|
14
|
+
|
15
|
+
When /^I destroy node "([^"]*)"$/ do |node|
|
16
|
+
destroy_node node
|
17
|
+
end
|
18
|
+
|
19
|
+
When /^Node "([^"]*)" is destroyed$/ do |node|
|
20
|
+
find(node).destroy
|
21
|
+
end
|
22
|
+
|
23
|
+
Then /^There should be ([^"]*) nodes in the environment$/ do |count|
|
24
|
+
find(:all).size.should == count.to_i
|
25
|
+
end
|
26
|
+
|
27
|
+
Then /^the node "([^"]*)" should be stopped$/ do |node|
|
28
|
+
find(node).should_not be_running
|
29
|
+
end
|
30
|
+
|
31
|
+
When /^I start node "([^"]*)"$/ do |node|
|
32
|
+
find(node).start
|
33
|
+
end
|
34
|
+
|
35
|
+
When /^I stop node "([^"]*)"$/ do |node|
|
36
|
+
find(node).stop
|
37
|
+
end
|
38
|
+
|
39
|
+
Then /^the node "([^"]*)" should be running$/ do |node|
|
40
|
+
find(node).should be_running
|
41
|
+
end
|
42
|
+
|
43
|
+
Then /^Node "([^"]*)" should have ip address same with that obtained from inside it through ssh$/ do |node|
|
44
|
+
n = find(node)
|
45
|
+
n.run_ssh("ifconfig eth0 | grep 'inet addr:'").stdout.should include(n.ip)
|
46
|
+
end
|
47
|
+
|
48
|
+
When /^I add cname "([^"]*)" to "([^"]*)"$/ do |cname, node|
|
49
|
+
find(node).add_cname cname
|
50
|
+
end
|
51
|
+
|
52
|
+
When /^I remove cname "([^"]*)" from "([^"]*)"$/ do |cname, node|
|
53
|
+
find(node).remove_cname cname
|
54
|
+
end
|
55
|
+
|
56
|
+
When /^I change the internal hostname for "([^"]*)" to "([^"]*)"$/ do |node_hostname, internal_hostname|
|
57
|
+
r = find(node_hostname)
|
58
|
+
r.run_ssh("hostname #{internal_hostname}")
|
59
|
+
r.run_ssh("echo 127.0.0.1 #{internal_hostname} >> /etc/hosts")
|
60
|
+
end
|
61
|
+
|
62
|
+
|
63
|
+
Then /^Hostname of Node "([^"]*)" should match its name$/ do |node|
|
64
|
+
find(node).hostname.should == node
|
65
|
+
end
|
@@ -0,0 +1,7 @@
|
|
1
|
+
When /^I run puppet manifest "([^"]*)" on node "([^"]*)"$/ do |run_list, node|
|
2
|
+
find(node).run_puppet run_list
|
3
|
+
end
|
4
|
+
|
5
|
+
When /^I run puppet manifest "([^"]*)" with config file "([^"]*)" on node "([^"]*)"$/ do |run_list, conf_file, node|
|
6
|
+
find(node).run_puppet(run_list, :conf_file => conf_file)
|
7
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
$:.unshift(File.dirname(__FILE__) + '/../../lib')
|
2
|
+
require 'rspec/expectations'
|
3
|
+
require 'toft'
|
4
|
+
|
5
|
+
CHEF_FIXTURE_PATH = File.dirname(__FILE__) + '/../../fixtures/chef'
|
6
|
+
PUPPET_FIXTURE_PATH = File.dirname(__FILE__) + '/../../fixtures/puppet'
|
7
|
+
|
8
|
+
CONTAINER_TYPE = "centos-6"
|
9
|
+
|
10
|
+
World(Toft)
|
11
|
+
|
12
|
+
include Toft
|
13
|
+
n1 = create_node "n1", {:ip => "192.168.20.2", :type => CONTAINER_TYPE}
|
14
|
+
|
15
|
+
Before do
|
16
|
+
Toft.cookbook_path = CHEF_FIXTURE_PATH + '/cookbooks'
|
17
|
+
Toft.role_path = CHEF_FIXTURE_PATH + '/roles'
|
18
|
+
Toft.manifest_path = PUPPET_FIXTURE_PATH
|
19
|
+
|
20
|
+
@n1 = n1
|
21
|
+
end
|
22
|
+
|
23
|
+
at_exit do
|
24
|
+
n1.destroy
|
25
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
directory "/tmp/stub/#{node.one}" do
|
2
|
+
action :create
|
3
|
+
recursive true
|
4
|
+
end
|
5
|
+
|
6
|
+
directory "/tmp/stub/#{node.two.two}" do
|
7
|
+
action :create
|
8
|
+
recursive true
|
9
|
+
end
|
10
|
+
|
11
|
+
directory "/tmp/stub/#{node.two.one}" do
|
12
|
+
action :create
|
13
|
+
recursive true
|
14
|
+
end
|
15
|
+
|
16
|
+
directory "/tmp/stub/#{node.three}" do
|
17
|
+
action :create
|
18
|
+
recursive true
|
19
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
[main]
|
2
|
+
modulepath = /tmp/puppet/modules
|
3
|
+
templatedir = /tmp/puppet/manifests/templates
|
4
|
+
node_terminus = exec
|
5
|
+
external_nodes = /tmp/puppet/tools/extnode.pl
|
6
|
+
fileserverconfig = /tmp/puppet/conf/fileserver.conf
|
7
|
+
logdir = /var/log/puppet
|
8
|
+
vardir = /var/lib/puppet
|
9
|
+
ssldir = /var/lib/puppet/ssl
|
10
|
+
rundir = /var/run/puppet
|
11
|
+
report = true
|
12
|
+
server = puppet.dev.int.realestate.com.au
|
13
|
+
reportserver = puppet.dev.int.realestate.com.au
|
14
|
+
diff = diff
|
15
|
+
diff_args = -u
|
@@ -0,0 +1 @@
|
|
1
|
+
This is a test for the fileserver config
|
@@ -0,0 +1,26 @@
|
|
1
|
+
node /^correct.*/ inherits default_node {
|
2
|
+
|
3
|
+
file { "/tmp/puppet_test_correct":
|
4
|
+
ensure => present,
|
5
|
+
mode => '0666',
|
6
|
+
}
|
7
|
+
|
8
|
+
}
|
9
|
+
|
10
|
+
node /^incorrect.*/ inherits default_node {
|
11
|
+
|
12
|
+
file { "/tmp/puppet_test_incorrect":
|
13
|
+
ensure => present,
|
14
|
+
mode => '0666',
|
15
|
+
}
|
16
|
+
|
17
|
+
}
|
18
|
+
|
19
|
+
node default_node {
|
20
|
+
|
21
|
+
file { "/tmp/puppet_test_default":
|
22
|
+
ensure => present,
|
23
|
+
mode => '0666',
|
24
|
+
}
|
25
|
+
|
26
|
+
}
|
@@ -0,0 +1 @@
|
|
1
|
+
import "nodes/*.pp"
|
data/lib/toft.rb
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'toft/node_controller'
|
2
|
+
require 'toft/file_checker'
|
3
|
+
require 'toft/chef/chef_attributes'
|
4
|
+
require 'toft/chef/chef_runner'
|
5
|
+
require 'toft/puppet/puppet_runner'
|
6
|
+
|
7
|
+
module Toft
|
8
|
+
DYNAMIC_IP = "0.0.0.0"
|
9
|
+
DOMAIN = "foo"
|
10
|
+
|
11
|
+
class << self
|
12
|
+
attr_accessor :manifest_path, :cookbook_path, :role_path
|
13
|
+
end
|
14
|
+
|
15
|
+
def create_node(hostname, options = {})
|
16
|
+
NodeController.instance.create_node(hostname, options)
|
17
|
+
end
|
18
|
+
|
19
|
+
def find(name)
|
20
|
+
return NodeController.instance.nodes if name === :all
|
21
|
+
NodeController.instance.nodes[name] if name.is_a? String
|
22
|
+
end
|
23
|
+
|
24
|
+
def destroy_node(hostname)
|
25
|
+
NodeController.instance.destroy_node(hostname)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
class NilClass
|
30
|
+
def blank?
|
31
|
+
true
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
class String
|
36
|
+
def blank?
|
37
|
+
empty?
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'json'
|
2
|
+
|
3
|
+
module Toft
|
4
|
+
class ChefAttributes
|
5
|
+
attr_reader :attributes
|
6
|
+
|
7
|
+
def initialize(cuke_ast_table = nil)
|
8
|
+
@attributes = {}
|
9
|
+
cuke_ast_table.hashes.each do |row|
|
10
|
+
add_attribute row[:key], row[:value]
|
11
|
+
end unless cuke_ast_table.nil?
|
12
|
+
end
|
13
|
+
|
14
|
+
def add_attribute(key, value)
|
15
|
+
stat = "attributes"
|
16
|
+
head = attributes
|
17
|
+
key.split(".").each do |k|
|
18
|
+
head[k] ||= Hash.new
|
19
|
+
head = head[k]
|
20
|
+
stat += "[\"#{k}\"]"
|
21
|
+
end
|
22
|
+
eval "#{stat}=\"#{value}\""
|
23
|
+
end
|
24
|
+
|
25
|
+
def to_json
|
26
|
+
attributes.to_json
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
require 'toft/chef/chef_attributes'
|
2
|
+
require 'fileutils'
|
3
|
+
|
4
|
+
module Toft
|
5
|
+
module Chef
|
6
|
+
class ChefRunner
|
7
|
+
include FileUtils
|
8
|
+
|
9
|
+
DEST_CHEF_TMP = "/tmp/toft-chef-tmp"
|
10
|
+
DEST_COOKBOOK_PATH = "#{DEST_CHEF_TMP}/cookbooks"
|
11
|
+
DEST_ROLE_PATH = "#{DEST_CHEF_TMP}/roles"
|
12
|
+
DEST_CHEF_SOLO_PATH = "#{DEST_CHEF_TMP}/solo.rb"
|
13
|
+
DEST_CHEF_JSON_PATH = "#{DEST_CHEF_TMP}/solo.json"
|
14
|
+
|
15
|
+
def initialize(root_dir, &command_runner)
|
16
|
+
@root_dir = root_dir
|
17
|
+
@command_runner = command_runner
|
18
|
+
end
|
19
|
+
|
20
|
+
def run(run_list, params = {})
|
21
|
+
override_attributes_hash = parse_attributes params[:json], params[:attributes]
|
22
|
+
copy_chef_material
|
23
|
+
generate_solo_rb
|
24
|
+
generate_json ([] << run_list).flatten, override_attributes_hash
|
25
|
+
@command_runner.call "chef-solo -c #{DEST_CHEF_SOLO_PATH} -j #{DEST_CHEF_JSON_PATH}"
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
def parse_attributes(json_file_path, chef_attributes)
|
30
|
+
chef_attributes = chef_attributes || ChefAttributes.new
|
31
|
+
chef_attributes_from_json ||= {}
|
32
|
+
chef_attributes_from_json = read_json_file json_file_path unless json_file_path.blank?
|
33
|
+
chef_attributes_from_json.merge chef_attributes.attributes
|
34
|
+
end
|
35
|
+
|
36
|
+
def read_json_file(json_file_path)
|
37
|
+
JSON.parse(File.read(json_file_path))
|
38
|
+
end
|
39
|
+
|
40
|
+
def copy_chef_material
|
41
|
+
raise ArgumentError, "Toft.cookbook_path can not be empty!" if Toft.cookbook_path.blank?
|
42
|
+
rm_rf "#{@root_dir}#{DEST_CHEF_TMP}"
|
43
|
+
mkdir_p "#{@root_dir}#{DEST_CHEF_TMP}"
|
44
|
+
cp_r Toft.cookbook_path, "#{@root_dir}#{DEST_COOKBOOK_PATH}"
|
45
|
+
cp_r Toft.role_path, "#{@root_dir}#{DEST_ROLE_PATH}" unless roles_missing?
|
46
|
+
end
|
47
|
+
|
48
|
+
def roles_missing?
|
49
|
+
Toft.role_path.blank?
|
50
|
+
end
|
51
|
+
|
52
|
+
def generate_solo_rb
|
53
|
+
solo = <<-EOF
|
54
|
+
file_cache_path "/tmp/chef-file-cache"
|
55
|
+
cookbook_path ["#{DEST_COOKBOOK_PATH}"]
|
56
|
+
EOF
|
57
|
+
solo += "role_path [\"#{DEST_ROLE_PATH}\"]" unless roles_missing?
|
58
|
+
|
59
|
+
File.open("#{@root_dir}#{DEST_CHEF_SOLO_PATH}", 'w') do |f|
|
60
|
+
f.write(solo);
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def generate_json(run_list, override_attributes_hash)
|
65
|
+
run_list = {"run_list" => run_list}
|
66
|
+
run_list.merge!(override_attributes_hash)
|
67
|
+
File.open("#{@root_dir}#{DEST_CHEF_JSON_PATH}", 'w') do |f|
|
68
|
+
f.write(run_list.to_json);
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def cmd(cmd)
|
73
|
+
raise "Command execution failed: [#{cmd}]" unless system cmd
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|