powcloud-sprinkle 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +5 -0
- data/CREDITS +33 -0
- data/MIT-LICENSE +20 -0
- data/README.markdown +241 -0
- data/Rakefile +50 -0
- data/VERSION +1 -0
- data/bin/sprinkle +90 -0
- data/examples/packages/build_essential.rb +9 -0
- data/examples/packages/databases/mysql.rb +13 -0
- data/examples/packages/databases/sqlite3.rb +16 -0
- data/examples/packages/phusion.rb +55 -0
- data/examples/packages/ruby/rails.rb +9 -0
- data/examples/packages/ruby/ruby.rb +17 -0
- data/examples/packages/ruby/rubygems.rb +17 -0
- data/examples/packages/scm/git.rb +11 -0
- data/examples/packages/scm/subversion.rb +4 -0
- data/examples/packages/servers/apache.rb +15 -0
- data/examples/rails/README +15 -0
- data/examples/rails/deploy.rb +2 -0
- data/examples/rails/packages/database.rb +9 -0
- data/examples/rails/packages/essential.rb +9 -0
- data/examples/rails/packages/rails.rb +29 -0
- data/examples/rails/packages/scm.rb +11 -0
- data/examples/rails/packages/search.rb +11 -0
- data/examples/rails/packages/server.rb +28 -0
- data/examples/rails/rails.rb +73 -0
- data/examples/sprinkle/sprinkle.rb +38 -0
- data/lib/sprinkle/actors/actors.rb +17 -0
- data/lib/sprinkle/actors/capistrano.rb +140 -0
- data/lib/sprinkle/actors/local.rb +37 -0
- data/lib/sprinkle/actors/ssh.rb +123 -0
- data/lib/sprinkle/actors/vlad.rb +78 -0
- data/lib/sprinkle/configurable.rb +31 -0
- data/lib/sprinkle/deployment.rb +73 -0
- data/lib/sprinkle/extensions/arbitrary_options.rb +10 -0
- data/lib/sprinkle/extensions/array.rb +5 -0
- data/lib/sprinkle/extensions/blank_slate.rb +5 -0
- data/lib/sprinkle/extensions/dsl_accessor.rb +15 -0
- data/lib/sprinkle/extensions/string.rb +10 -0
- data/lib/sprinkle/extensions/symbol.rb +7 -0
- data/lib/sprinkle/installers/apt.rb +52 -0
- data/lib/sprinkle/installers/binary.rb +46 -0
- data/lib/sprinkle/installers/bsd_port.rb +33 -0
- data/lib/sprinkle/installers/deb.rb +38 -0
- data/lib/sprinkle/installers/freebsd_pkg.rb +37 -0
- data/lib/sprinkle/installers/freebsd_portinstall.rb +36 -0
- data/lib/sprinkle/installers/gem.rb +64 -0
- data/lib/sprinkle/installers/install_package.rb +79 -0
- data/lib/sprinkle/installers/installer.rb +120 -0
- data/lib/sprinkle/installers/mac_port.rb +38 -0
- data/lib/sprinkle/installers/noop.rb +20 -0
- data/lib/sprinkle/installers/openbsd_pkg.rb +47 -0
- data/lib/sprinkle/installers/opensolaris_pkg.rb +43 -0
- data/lib/sprinkle/installers/push_text.rb +45 -0
- data/lib/sprinkle/installers/rake.rb +37 -0
- data/lib/sprinkle/installers/rpm.rb +37 -0
- data/lib/sprinkle/installers/smart.rb +29 -0
- data/lib/sprinkle/installers/source.rb +190 -0
- data/lib/sprinkle/installers/transfer.rb +164 -0
- data/lib/sprinkle/installers/yum.rb +37 -0
- data/lib/sprinkle/package.rb +309 -0
- data/lib/sprinkle/policy.rb +125 -0
- data/lib/sprinkle/script.rb +23 -0
- data/lib/sprinkle/verifiers/directory.rb +16 -0
- data/lib/sprinkle/verifiers/executable.rb +53 -0
- data/lib/sprinkle/verifiers/file.rb +26 -0
- data/lib/sprinkle/verifiers/package.rb +26 -0
- data/lib/sprinkle/verifiers/process.rb +21 -0
- data/lib/sprinkle/verifiers/rpm.rb +21 -0
- data/lib/sprinkle/verifiers/ruby.rb +25 -0
- data/lib/sprinkle/verifiers/symlink.rb +30 -0
- data/lib/sprinkle/verify.rb +114 -0
- data/lib/sprinkle.rb +32 -0
- data/script/console +8 -0
- data/script/destroy +14 -0
- data/script/generate +14 -0
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +17 -0
- data/spec/sprinkle/actors/capistrano_spec.rb +265 -0
- data/spec/sprinkle/actors/local_spec.rb +29 -0
- data/spec/sprinkle/configurable_spec.rb +46 -0
- data/spec/sprinkle/deployment_spec.rb +80 -0
- data/spec/sprinkle/extensions/array_spec.rb +19 -0
- data/spec/sprinkle/extensions/string_spec.rb +21 -0
- data/spec/sprinkle/installers/apt_spec.rb +70 -0
- data/spec/sprinkle/installers/bsd_port_spec.rb +42 -0
- data/spec/sprinkle/installers/freebsd_pkg_spec.rb +49 -0
- data/spec/sprinkle/installers/freebsd_portinstall_spec.rb +42 -0
- data/spec/sprinkle/installers/gem_spec.rb +107 -0
- data/spec/sprinkle/installers/installer_spec.rb +151 -0
- data/spec/sprinkle/installers/mac_port_spec.rb +42 -0
- data/spec/sprinkle/installers/noop_spec.rb +23 -0
- data/spec/sprinkle/installers/openbsd_pkg_spec.rb +49 -0
- data/spec/sprinkle/installers/opensolaris_pkg_spec.rb +49 -0
- data/spec/sprinkle/installers/push_text_spec.rb +66 -0
- data/spec/sprinkle/installers/rake_spec.rb +29 -0
- data/spec/sprinkle/installers/rpm_spec.rb +50 -0
- data/spec/sprinkle/installers/source_spec.rb +371 -0
- data/spec/sprinkle/installers/transfer_spec.rb +98 -0
- data/spec/sprinkle/installers/yum_spec.rb +49 -0
- data/spec/sprinkle/package_spec.rb +466 -0
- data/spec/sprinkle/policy_spec.rb +126 -0
- data/spec/sprinkle/script_spec.rb +51 -0
- data/spec/sprinkle/sprinkle_spec.rb +25 -0
- data/spec/sprinkle/verify_spec.rb +174 -0
- metadata +244 -0
@@ -0,0 +1,125 @@
|
|
1
|
+
require 'highline/import'
|
2
|
+
|
3
|
+
module Sprinkle
|
4
|
+
# = Policies
|
5
|
+
#
|
6
|
+
# A policy defines a set of packages which are required for a certain
|
7
|
+
# role (app, database, etc.). All policies defined will be run and all
|
8
|
+
# packages required by the policy will be installed. So whereas defining
|
9
|
+
# a Sprinkle::Package merely defines it, defining a Sprinkle::Policy
|
10
|
+
# actually causes those packages to install.
|
11
|
+
#
|
12
|
+
# == A Basic Example
|
13
|
+
#
|
14
|
+
# policy :blog, :roles => :app do
|
15
|
+
# require :webserver
|
16
|
+
# require :database
|
17
|
+
# require :rails
|
18
|
+
# end
|
19
|
+
#
|
20
|
+
# This says that for the blog on the app role, it requires certain
|
21
|
+
# packages. The :roles option is <em>exactly</em> the same as a capistrano
|
22
|
+
# or vlad role. A role merely defines what server the commands are run
|
23
|
+
# on. This way, a single Sprinkle script can provision an entire group
|
24
|
+
# of servers.
|
25
|
+
#
|
26
|
+
# To define a role, put in your actor specific configuration file (recipe or
|
27
|
+
# script file):
|
28
|
+
#
|
29
|
+
# role :app, "208.28.38.44"
|
30
|
+
#
|
31
|
+
# The capistrano and vlad syntax is the same for that. If you're using a
|
32
|
+
# custom actor, you may have to do it differently.
|
33
|
+
#
|
34
|
+
# == Multiple Policies
|
35
|
+
#
|
36
|
+
# You may specify as many policies as you'd like. If the packages you're
|
37
|
+
# requiring are properly defined with verification blocks, then
|
38
|
+
# no software will be installed twice, so you may require a webserver on
|
39
|
+
# multiple packages within the same role without having to wait for
|
40
|
+
# that package to install repeatedly.
|
41
|
+
module Policy
|
42
|
+
POLICIES = [] #:nodoc:
|
43
|
+
|
44
|
+
# Defines a single policy. Currently the only option, which is also
|
45
|
+
# required, is :roles, which defines which servers a policy is
|
46
|
+
# used on.
|
47
|
+
def policy(name, options = {}, &block)
|
48
|
+
p = Policy.new(name, options, &block)
|
49
|
+
POLICIES << p
|
50
|
+
p
|
51
|
+
end
|
52
|
+
|
53
|
+
class Policy #:nodoc:
|
54
|
+
attr_reader :name, :packages
|
55
|
+
|
56
|
+
def initialize(name, metadata = {}, &block)
|
57
|
+
raise 'No name provided' unless name
|
58
|
+
raise 'No roles provided' unless metadata[:roles]
|
59
|
+
|
60
|
+
@name = name
|
61
|
+
@roles = metadata[:roles]
|
62
|
+
@packages = []
|
63
|
+
self.instance_eval(&block)
|
64
|
+
end
|
65
|
+
|
66
|
+
def requires(package, options = {})
|
67
|
+
@packages << package
|
68
|
+
end
|
69
|
+
|
70
|
+
def to_s; name; end
|
71
|
+
|
72
|
+
def process(deployment)
|
73
|
+
all = []
|
74
|
+
|
75
|
+
cloud_info "--> Cloud hierarchy for policy #{@name}"
|
76
|
+
|
77
|
+
@packages.each do |p|
|
78
|
+
cloud_info "\nPolicy #{@name} requires package #{p}"
|
79
|
+
|
80
|
+
package = Sprinkle::Package::PACKAGES[p]
|
81
|
+
raise "Package definition not found for key: #{p}" unless package
|
82
|
+
package = select_package(p, package) if package.is_a? Array # handle virtual package selection
|
83
|
+
|
84
|
+
tree = package.tree do |parent, child, depth|
|
85
|
+
indent = "\t" * depth; cloud_info "#{indent}Package #{parent.name} requires #{child.name}"
|
86
|
+
end
|
87
|
+
|
88
|
+
all << tree
|
89
|
+
end
|
90
|
+
|
91
|
+
normalize(all) do |package|
|
92
|
+
package.process(deployment, @roles)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
private
|
97
|
+
|
98
|
+
def cloud_info(message)
|
99
|
+
logger.info(message) if Sprinkle::OPTIONS[:cloud] or logger.debug?
|
100
|
+
end
|
101
|
+
|
102
|
+
def select_package(name, packages)
|
103
|
+
if packages.size <= 1
|
104
|
+
package = packages.first
|
105
|
+
else
|
106
|
+
package = choose do |menu|
|
107
|
+
menu.prompt = "Multiple choices exist for virtual package #{name}"
|
108
|
+
menu.choices *packages.collect(&:to_s)
|
109
|
+
end
|
110
|
+
package = Sprinkle::Package::PACKAGES[package]
|
111
|
+
end
|
112
|
+
|
113
|
+
cloud_info "Selecting #{package.to_s} for virtual package #{name}"
|
114
|
+
|
115
|
+
package
|
116
|
+
end
|
117
|
+
|
118
|
+
def normalize(all, &block)
|
119
|
+
all = all.flatten.uniq
|
120
|
+
cloud_info "\n--> Normalized installation order for all packages: #{all.collect(&:name).join(', ')}"
|
121
|
+
all.each &block
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Sprinkle
|
2
|
+
# = Programmatically Run Sprinkle
|
3
|
+
#
|
4
|
+
# Sprinkle::Script gives you a way to programatically run a given
|
5
|
+
# sprinkle script.
|
6
|
+
class Script
|
7
|
+
# Run a given sprinkle script. This method is <b>blocking</b> so
|
8
|
+
# it will not return until the sprinkling is complete or fails.
|
9
|
+
#--
|
10
|
+
# FIXME: Improve documentation, possibly notify user how to tell
|
11
|
+
# if a sprinkling failed.
|
12
|
+
#++
|
13
|
+
def self.sprinkle(script, filename = '__SCRIPT__')
|
14
|
+
powder = new
|
15
|
+
powder.instance_eval script, filename
|
16
|
+
powder.sprinkle
|
17
|
+
end
|
18
|
+
|
19
|
+
def sprinkle #:nodoc:
|
20
|
+
@deployment.process if @deployment
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Sprinkle
|
2
|
+
module Verifiers
|
3
|
+
# = Directory Verifier
|
4
|
+
#
|
5
|
+
# Defines a verify which can be used to test the existence of a
|
6
|
+
# directory.
|
7
|
+
module Directory
|
8
|
+
Sprinkle::Verify.register(Sprinkle::Verifiers::Directory)
|
9
|
+
|
10
|
+
# Tests that the directory <tt>dir</tt> exists.
|
11
|
+
def has_directory(dir)
|
12
|
+
@commands << "test -d #{dir}"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module Sprinkle
|
2
|
+
module Verifiers
|
3
|
+
# = Executable Verifier
|
4
|
+
#
|
5
|
+
# Contains a verifier to check the existance of an executable
|
6
|
+
# script on your server.
|
7
|
+
#
|
8
|
+
# == Example Usage
|
9
|
+
#
|
10
|
+
# First, absolute path to an executable:
|
11
|
+
#
|
12
|
+
# verify { has_executable '/usr/special/secret/bin/scipt' }
|
13
|
+
#
|
14
|
+
# Second, a global executable which would be available anywhere on the
|
15
|
+
# command line:
|
16
|
+
#
|
17
|
+
# verify { has_executable 'grep' }
|
18
|
+
module Executable
|
19
|
+
Sprinkle::Verify.register(Sprinkle::Verifiers::Executable)
|
20
|
+
|
21
|
+
# Checks if <tt>path</tt> is an executable script. This verifier is "smart" because
|
22
|
+
# if the path contains a forward slash '/' then it assumes you're checking an
|
23
|
+
# absolute path to an executable. If no '/' is in the path, it assumes you're
|
24
|
+
# checking for a global executable that would be available anywhere on the command line.
|
25
|
+
def has_executable(path)
|
26
|
+
# Be smart: If the path includes a forward slash, we're checking
|
27
|
+
# an absolute path. Otherwise, we're checking a global executable
|
28
|
+
if path.include?('/')
|
29
|
+
@commands << "test -x #{path}"
|
30
|
+
else
|
31
|
+
@commands << "[ -n \"`echo \\`which #{path}\\``\" ]"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
# Same as has_executable but with checking for e certain version number.
|
36
|
+
# Last option is the parameter to append for getting the version (which
|
37
|
+
# defaults to "-v").
|
38
|
+
def has_executable_with_version(path, version, get_version = '-v')
|
39
|
+
if path.include?('/')
|
40
|
+
@commands << "[ -x #{path} -a -n \"`#{path} #{get_version} 2> /dev/null | egrep -e \\\"#{version}\\\"`\" ]"
|
41
|
+
else
|
42
|
+
@commands << "[ -n \"`echo \\`which #{path}\\``\" -a -n \"`\\`which #{path}\\` #{get_version} 2>&1 | egrep -e \\\"#{version}\\\"`\" ]"
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
# Same as has_executable but checking output of a certain command
|
47
|
+
# with grep.
|
48
|
+
def has_version_in_grep(cmd, version)
|
49
|
+
@commands << "[ -n \"`#{cmd} 2> /dev/null | egrep -e \\\"#{version}\\\"`\" ]"
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Sprinkle
|
2
|
+
module Verifiers
|
3
|
+
# = File Verifier
|
4
|
+
#
|
5
|
+
# Contains a verifier to check the existance of a file.
|
6
|
+
#
|
7
|
+
# == Example Usage
|
8
|
+
#
|
9
|
+
# verify { has_file '/etc/apache2/apache2.conf' }
|
10
|
+
#
|
11
|
+
# verify { file_contains '/etc/apache2/apache2.conf', 'mod_gzip'}
|
12
|
+
#
|
13
|
+
module File
|
14
|
+
Sprinkle::Verify.register(Sprinkle::Verifiers::File)
|
15
|
+
|
16
|
+
# Checks to make sure <tt>path</tt> is a file on the remote server.
|
17
|
+
def has_file(path)
|
18
|
+
@commands << "test -f #{path}"
|
19
|
+
end
|
20
|
+
|
21
|
+
def file_contains(path, text)
|
22
|
+
@commands << "grep '#{text}' #{path}"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Sprinkle
|
2
|
+
module Verifiers
|
3
|
+
module Package
|
4
|
+
Sprinkle::Verify.register(Sprinkle::Verifiers::Package)
|
5
|
+
|
6
|
+
def has_package(*packages)
|
7
|
+
if packages.is_a?(Array) && packages.first.is_a?(Array)
|
8
|
+
packages = packages.first
|
9
|
+
else
|
10
|
+
packages = [packages] unless packages.is_a? Array
|
11
|
+
end
|
12
|
+
|
13
|
+
packages.each do |pak|
|
14
|
+
case Sprinkle::Installers::InstallPackage.installer
|
15
|
+
when :yum
|
16
|
+
@commands << "[ -n \"`yum list installed #{pak} 2> /dev/null | egrep -e \\\"#{pak}\\\"`\" ]"
|
17
|
+
else
|
18
|
+
raise "Unknown InstallPackage.installer"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
alias_method :has_packages, :has_package
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Sprinkle
|
2
|
+
module Verifiers
|
3
|
+
# = Process Verifier
|
4
|
+
#
|
5
|
+
# Contains a verifier to check that a process is running.
|
6
|
+
#
|
7
|
+
# == Example Usage
|
8
|
+
#
|
9
|
+
# verify { has_process 'httpd' }
|
10
|
+
#
|
11
|
+
module Process
|
12
|
+
Sprinkle::Verify.register(Sprinkle::Verifiers::Process)
|
13
|
+
|
14
|
+
# Checks to make sure <tt>process</tt> is a process running
|
15
|
+
# on the remote server.
|
16
|
+
def has_process(process)
|
17
|
+
@commands << "ps aux | grep '#{process}' | grep -v grep"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Sprinkle
|
2
|
+
module Verifiers
|
3
|
+
# = RPM Verifier
|
4
|
+
#
|
5
|
+
# Contains a verifier to check the existance of an RPM package.
|
6
|
+
#
|
7
|
+
# == Example Usage
|
8
|
+
#
|
9
|
+
# verify { has_rpm 'ntp' }
|
10
|
+
#
|
11
|
+
module Rpm
|
12
|
+
Sprinkle::Verify.register(Sprinkle::Verifiers::Rpm)
|
13
|
+
|
14
|
+
# Checks to make sure <tt>package</tt> exists in the rpm installed database on the remote server.
|
15
|
+
def has_rpm(package)
|
16
|
+
@commands << "rpm -qa | grep #{package}"
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Sprinkle
|
2
|
+
module Verifiers
|
3
|
+
# = Ruby Verifiers
|
4
|
+
#
|
5
|
+
# The verifiers in this module are ruby specific.
|
6
|
+
module Ruby
|
7
|
+
Sprinkle::Verify.register(Sprinkle::Verifiers::Ruby)
|
8
|
+
|
9
|
+
# Checks if ruby can require the <tt>files</tt> given. <tt>rubygems</tt>
|
10
|
+
# is always included first.
|
11
|
+
def ruby_can_load(*files)
|
12
|
+
# Always include rubygems first
|
13
|
+
files = files.unshift('rubygems').collect { |x| "require '#{x}'" }
|
14
|
+
|
15
|
+
@commands << "ruby -e \"#{files.join(';')}\""
|
16
|
+
end
|
17
|
+
|
18
|
+
# Checks if a gem exists by calling "sudo gem list" and grepping against it.
|
19
|
+
def has_gem(name, version=nil)
|
20
|
+
version = version.nil? ? '' : version.gsub('.', '\.')
|
21
|
+
@commands << "sudo gem list | grep -e '^#{name} (.*#{version}.*)$'"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Sprinkle
|
2
|
+
module Verifiers
|
3
|
+
# = Symlink Verifier
|
4
|
+
#
|
5
|
+
# Contains a verifier to check the existance of a symbolic link.
|
6
|
+
#
|
7
|
+
# == Example Usage
|
8
|
+
#
|
9
|
+
# First, checking for the existence of a symlink:
|
10
|
+
#
|
11
|
+
# verify { has_symlink '/usr/special/secret/pointer' }
|
12
|
+
#
|
13
|
+
# Second, checking that the symlink points to a specific place:
|
14
|
+
#
|
15
|
+
# verify { has_symlink '/usr/special/secret/pointer', '/usr/local/realfile' }
|
16
|
+
module Symlink
|
17
|
+
Sprinkle::Verify.register(Sprinkle::Verifiers::Symlink)
|
18
|
+
|
19
|
+
# Checks that <tt>symlink</tt> is a symbolic link. If <tt>file</tt> is
|
20
|
+
# given, it checks that <tt>symlink</tt> points to <tt>file</tt>
|
21
|
+
def has_symlink(symlink, file = nil)
|
22
|
+
if file.nil?
|
23
|
+
@commands << "test -L #{symlink}"
|
24
|
+
else
|
25
|
+
@commands << "test '#{file}' = `readlink #{symlink}`"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,114 @@
|
|
1
|
+
module Sprinkle
|
2
|
+
# = Verification Methods
|
3
|
+
#
|
4
|
+
# As documented in Sprinkle::Package, you may define a block on a package
|
5
|
+
# which verifies that a package was installed correctly. If this verification
|
6
|
+
# block fails, Sprinkle will stop the script gracefully, raising the error.
|
7
|
+
#
|
8
|
+
# In addition to checking post install if it was successfully, verification
|
9
|
+
# blocks are also ran before an install to see if a package is <em>already</em>
|
10
|
+
# installed. If this is the case, the package is skipped and Sprinkle continues
|
11
|
+
# with the next package. This behavior can be overriden by setting the -f flag on
|
12
|
+
# the sprinkle script or setting Sprinkle::OPTIONS[:force] to true if you're
|
13
|
+
# using sprinkle programmatically.
|
14
|
+
#
|
15
|
+
# == An Example
|
16
|
+
#
|
17
|
+
# The following verifies that rails was installed correctly be checking to see
|
18
|
+
# if the 'rails' command is available on the command line:
|
19
|
+
#
|
20
|
+
# package :rails do
|
21
|
+
# gem 'rails'
|
22
|
+
#
|
23
|
+
# verify do
|
24
|
+
# has_executable 'rails'
|
25
|
+
# end
|
26
|
+
# end
|
27
|
+
#
|
28
|
+
# == Available Verifiers
|
29
|
+
#
|
30
|
+
# There are a variety of available methods for use in the verification block.
|
31
|
+
# The standard methods are defined in the Sprinkle::Verifiers module, so see
|
32
|
+
# their corresponding documentation.
|
33
|
+
#
|
34
|
+
# == Custom Verifiers
|
35
|
+
#
|
36
|
+
# If you feel that the built-in verifiers do not offer a certain aspect of
|
37
|
+
# verification which you need, you may create your own verifier! Simply wrap
|
38
|
+
# any method in a module which you want to use:
|
39
|
+
#
|
40
|
+
# module MagicBeansVerifier
|
41
|
+
# def has_magic_beans(sauce)
|
42
|
+
# @commands << '[ -z "`echo $' + sauce + '`"]'
|
43
|
+
# end
|
44
|
+
# end
|
45
|
+
#
|
46
|
+
# The method can append as many commands as it wishes to the @commands array.
|
47
|
+
# These commands will be run on the remote server and <b>MUST</b> give an
|
48
|
+
# exit status of 0 if successful or other if unsuccessful.
|
49
|
+
#
|
50
|
+
# To register your verifier, call the register method on Sprinkle::Verify:
|
51
|
+
#
|
52
|
+
# Sprinle::Verify.register(MagicBeansVerifier)
|
53
|
+
#
|
54
|
+
# And now you may use it like any other verifier:
|
55
|
+
#
|
56
|
+
# package :magic_beans do
|
57
|
+
# gem 'magic_beans'
|
58
|
+
#
|
59
|
+
# verify { has_magic_beans('ranch') }
|
60
|
+
# end
|
61
|
+
class Verify
|
62
|
+
include Sprinkle::Configurable
|
63
|
+
attr_accessor :package, :description, :commands #:nodoc:
|
64
|
+
|
65
|
+
class <<self
|
66
|
+
# Register a verification module
|
67
|
+
def register(new_module)
|
68
|
+
class_eval { include new_module }
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def initialize(package, description = '', &block) #:nodoc:
|
73
|
+
raise 'Verify requires a block.' unless block
|
74
|
+
|
75
|
+
@package = package
|
76
|
+
@description = description
|
77
|
+
@commands = []
|
78
|
+
@options ||= {}
|
79
|
+
@options[:padding] = 4
|
80
|
+
|
81
|
+
self.instance_eval(&block)
|
82
|
+
end
|
83
|
+
|
84
|
+
def process(roles, pre = false) #:nodoc:
|
85
|
+
assert_delivery
|
86
|
+
|
87
|
+
description = @description.empty? ? @package.name : @description
|
88
|
+
|
89
|
+
if logger.debug?
|
90
|
+
logger.debug "#{@package.name}#{description} verification sequence: #{@commands.join('; ')} for roles: #{roles}\n"
|
91
|
+
end
|
92
|
+
|
93
|
+
unless Sprinkle::OPTIONS[:testing]
|
94
|
+
logger.info "#{" " * @options[:padding]}--> Verifying #{description}..."
|
95
|
+
|
96
|
+
unless @delivery.process(@package.name, @commands, roles, true)
|
97
|
+
# Verification failed, halt sprinkling gracefully.
|
98
|
+
raise Sprinkle::VerificationFailed.new(@package, description)
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
class VerificationFailed < Exception #:nodoc:
|
105
|
+
attr_accessor :package, :description
|
106
|
+
|
107
|
+
def initialize(package, description)
|
108
|
+
super("Verifying #{package.name}#{description} failed.")
|
109
|
+
|
110
|
+
@package = package
|
111
|
+
@description = description
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|