capchef 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/lib/capchef.rb +57 -0
- data/lib/capchef_recipes.rb +83 -0
- data/lib/capchef_utility_recipes.rb +15 -0
- metadata +91 -0
data/lib/capchef.rb
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
module Capchef
|
2
|
+
extend self
|
3
|
+
|
4
|
+
# Default to /tmp but allow change in case it is noexec
|
5
|
+
def tmpdir
|
6
|
+
@tmpdir ||= '/tmp'
|
7
|
+
end
|
8
|
+
|
9
|
+
def tmpdir=(tmpdir)
|
10
|
+
@tmpdir = tmpdir
|
11
|
+
end
|
12
|
+
|
13
|
+
def path
|
14
|
+
@path ||= '/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin'
|
15
|
+
end
|
16
|
+
|
17
|
+
def path=(path)
|
18
|
+
@path = path
|
19
|
+
end
|
20
|
+
|
21
|
+
def prepend_path(dir)
|
22
|
+
@path = "#{dir}:#{path}"
|
23
|
+
end
|
24
|
+
|
25
|
+
# Runs +command+ as root invoking the command with su -c
|
26
|
+
# and handling the root password prompt.
|
27
|
+
#
|
28
|
+
# surun "/etc/init.d/apache reload"
|
29
|
+
# # Executes
|
30
|
+
# # su - -c '/etc/init.d/apache reload'
|
31
|
+
#
|
32
|
+
def surun(cap, command, options={})
|
33
|
+
@root_password ||= cap.fetch(:root_password, Capistrano::CLI.password_prompt("root password: "))
|
34
|
+
cap.run("su -c 'cd; PATH=#{path}; #{command}'", options) do |channel, stream, output|
|
35
|
+
puts "[#{channel[:host]}] #{output}" if output
|
36
|
+
channel.send_data("#{@root_password}\n") if output && output =~ /^Password:/
|
37
|
+
yield channel, stream, output if block_given?
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def surun_script(cap, script, options={})
|
42
|
+
# TBD - We can change this to use /tmp as its no longer noexec
|
43
|
+
raise "No such file: #{script}" unless File.exist?(script)
|
44
|
+
basename = File.basename(script)
|
45
|
+
tmpdir = "/tmp/#{basename}.#$$"
|
46
|
+
remote_script = "#{tmpdir}/#{basename}"
|
47
|
+
cap.run "mkdir #{tmpdir}", options
|
48
|
+
cap.upload script, remote_script, options
|
49
|
+
cap.run "chmod 0755 #{remote_script}", options
|
50
|
+
if block_given?
|
51
|
+
yield remote_script
|
52
|
+
else
|
53
|
+
surun cap, remote_script, options
|
54
|
+
end
|
55
|
+
cap.run "rm -rf #{tmpdir}", options
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
require 'erb'
|
2
|
+
require 'yaml'
|
3
|
+
require 'json'
|
4
|
+
require 'tempfile'
|
5
|
+
require 'zlib'
|
6
|
+
require 'archive/tar/minitar'
|
7
|
+
require 'capchef'
|
8
|
+
include Archive::Tar
|
9
|
+
|
10
|
+
Capistrano::Configuration.instance.load do
|
11
|
+
# User settings
|
12
|
+
#set :user, 'deploy' unless exists?(:user)
|
13
|
+
#set :group,'www-data' unless exists?(:group)
|
14
|
+
|
15
|
+
# Git settings for capistrano
|
16
|
+
default_run_options[:pty] = true
|
17
|
+
ssh_options[:forward_agent] = true
|
18
|
+
|
19
|
+
namespace :chef do
|
20
|
+
desc 'Install chef recipes on remote machines.'
|
21
|
+
task :default do
|
22
|
+
Capchef.prepend_path(chef_solo_path) if exists?(:chef_solo_path)
|
23
|
+
|
24
|
+
raise 'No nodes.yml' unless File.exist?('nodes.yml')
|
25
|
+
config = YAML.load(ERB.new(File.read('nodes.yml')).result(binding))
|
26
|
+
|
27
|
+
remote_tmpdir = "/tmp/chef_solo.#$$"
|
28
|
+
run "mkdir #{remote_tmpdir}"
|
29
|
+
remote_node_file = "#{remote_tmpdir}/node.json"
|
30
|
+
remote_solo_file = "#{remote_tmpdir}/solo.rb"
|
31
|
+
remote_cookbooks_tgz = "#{remote_tmpdir}/cookbooks.tgz"
|
32
|
+
remote_roles_tgz = "#{remote_tmpdir}/roles.tgz"
|
33
|
+
|
34
|
+
valid_hosts = []
|
35
|
+
find_servers_for_task(current_task).each do |s|
|
36
|
+
host_config = config[s.host]
|
37
|
+
if host_config
|
38
|
+
valid_hosts << s.host
|
39
|
+
put host_config.to_json, remote_node_file, :hosts => s.host
|
40
|
+
else
|
41
|
+
$stderr.puts "WARNING: #{s.host} not configured in nodes.yml, skipping"
|
42
|
+
end
|
43
|
+
end
|
44
|
+
if valid_hosts.empty?
|
45
|
+
$stderr.puts 'No configured hosts'
|
46
|
+
exit 1
|
47
|
+
end
|
48
|
+
|
49
|
+
solo_rb = "file_cache_path '/etc/chef'\ncookbook_path '/etc/chef/cookbooks'\nrole_path '/etc/chef/roles'\n"
|
50
|
+
put solo_rb, remote_solo_file, :hosts => valid_hosts
|
51
|
+
begin
|
52
|
+
tmp_cookbooks_tgz = Tempfile.new('cookbooks')
|
53
|
+
Dir.chdir('chef-repo') do
|
54
|
+
Minitar.pack('cookbooks', Zlib::GzipWriter.new(tmp_cookbooks_tgz))
|
55
|
+
tmp_cookbooks_tgz.close
|
56
|
+
upload tmp_cookbooks_tgz.path, remote_cookbooks_tgz, :hosts => valid_hosts
|
57
|
+
|
58
|
+
sio_roles_tgz = StringIO.new
|
59
|
+
gzip = Zlib::GzipWriter.new(sio_roles_tgz)
|
60
|
+
Minitar::Writer.open(gzip) do |tar|
|
61
|
+
#Minitar::Writer.open(sio_roles_tgz) do |tar|
|
62
|
+
Find.find('roles') do |role_file|
|
63
|
+
# TODO: This does not work (how do I specify a role in JSON?
|
64
|
+
if role_file.match(/\.yml$/)
|
65
|
+
data = YAML.load(ERB.new(File.read(role_file)).result(binding)).to_json
|
66
|
+
new_role_file = role_file.sub(/\.yml$/, '.json')
|
67
|
+
tar.add_file_simple(new_role_file, :size=>data.size, :mode=>0644, :mtime=>File.mtime(role_file)) { |f| f.write(data) }
|
68
|
+
else
|
69
|
+
Minitar.pack_file(role_file, tar)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
gzip.close
|
74
|
+
put sio_roles_tgz.string, remote_roles_tgz, :hosts => valid_hosts
|
75
|
+
end
|
76
|
+
Capchef.surun(self, "mkdir -p /etc/chef; cd /etc/chef; rm -rf cookbooks roles; tar zxf #{remote_cookbooks_tgz}; tar zxf #{remote_roles_tgz}; chef-solo -c #{remote_solo_file} -j #{remote_node_file}", :hosts => valid_hosts)
|
77
|
+
ensure
|
78
|
+
tmp_cookbooks_tgz.unlink
|
79
|
+
run "rm -rf #{remote_tmpdir}"
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'capchef'
|
2
|
+
|
3
|
+
Capistrano::Configuration.instance.load do
|
4
|
+
default_run_options[:pty] = true
|
5
|
+
ssh_options[:forward_agent] = true
|
6
|
+
|
7
|
+
namespace :utility do
|
8
|
+
desc "execute basic command line functions. ie. cap exec cmd='ps -eaf | grep redis' optional arg: HOSTS=ip1,ip2 (replace cmd with sudo for sudo commands)"
|
9
|
+
task :default do
|
10
|
+
run(ENV['cmd']) if ENV['cmd']
|
11
|
+
Capchef.surun(self, ENV['sudo']) if ENV['sudo']
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
metadata
ADDED
@@ -0,0 +1,91 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: capchef
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease:
|
5
|
+
version: 0.0.1
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Brad Pardee
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
|
13
|
+
date: 2011-09-03 00:00:00 -04:00
|
14
|
+
default_executable:
|
15
|
+
dependencies:
|
16
|
+
- !ruby/object:Gem::Dependency
|
17
|
+
name: capistrano
|
18
|
+
prerelease: false
|
19
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
20
|
+
none: false
|
21
|
+
requirements:
|
22
|
+
- - ">="
|
23
|
+
- !ruby/object:Gem::Version
|
24
|
+
version: "0"
|
25
|
+
type: :runtime
|
26
|
+
version_requirements: *id001
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: json
|
29
|
+
prerelease: false
|
30
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
31
|
+
none: false
|
32
|
+
requirements:
|
33
|
+
- - ">="
|
34
|
+
- !ruby/object:Gem::Version
|
35
|
+
version: "0"
|
36
|
+
type: :runtime
|
37
|
+
version_requirements: *id002
|
38
|
+
- !ruby/object:Gem::Dependency
|
39
|
+
name: minitar
|
40
|
+
prerelease: false
|
41
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
42
|
+
none: false
|
43
|
+
requirements:
|
44
|
+
- - ">="
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: "0"
|
47
|
+
type: :runtime
|
48
|
+
version_requirements: *id003
|
49
|
+
description: Chef capistrano recipes so you can configure your machines without a server
|
50
|
+
email:
|
51
|
+
- bradpardee@gmail.com
|
52
|
+
executables: []
|
53
|
+
|
54
|
+
extensions: []
|
55
|
+
|
56
|
+
extra_rdoc_files: []
|
57
|
+
|
58
|
+
files:
|
59
|
+
- lib/capchef.rb
|
60
|
+
- lib/capchef_recipes.rb
|
61
|
+
- lib/capchef_utility_recipes.rb
|
62
|
+
has_rdoc: true
|
63
|
+
homepage: http://github.com/ClarityServices/capchef
|
64
|
+
licenses: []
|
65
|
+
|
66
|
+
post_install_message:
|
67
|
+
rdoc_options: []
|
68
|
+
|
69
|
+
require_paths:
|
70
|
+
- lib
|
71
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
72
|
+
none: false
|
73
|
+
requirements:
|
74
|
+
- - ">="
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: "0"
|
77
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
78
|
+
none: false
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: "0"
|
83
|
+
requirements: []
|
84
|
+
|
85
|
+
rubyforge_project:
|
86
|
+
rubygems_version: 1.5.1
|
87
|
+
signing_key:
|
88
|
+
specification_version: 3
|
89
|
+
summary: Chef capistrano recipes
|
90
|
+
test_files: []
|
91
|
+
|