powcloud-sprinkle 0.3.0
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 +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,164 @@
|
|
|
1
|
+
# Blatantly stole this from Chef
|
|
2
|
+
class TemplateError < RuntimeError
|
|
3
|
+
attr_reader :original_exception, :context
|
|
4
|
+
SOURCE_CONTEXT_WINDOW = 2 unless defined? SOURCE_CONTEXT_WINDOW
|
|
5
|
+
|
|
6
|
+
def initialize(original_exception, template, context)
|
|
7
|
+
@original_exception, @template, @context = original_exception, template, context
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def message
|
|
11
|
+
@original_exception.message
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def line_number
|
|
15
|
+
@line_number ||= $1.to_i if original_exception.backtrace.find {|line| line =~ /\(erubis\):(\d+)/ }
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def source_location
|
|
19
|
+
"on line ##{line_number}"
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def source_listing
|
|
23
|
+
return nil if line_number.nil?
|
|
24
|
+
|
|
25
|
+
@source_listing ||= begin
|
|
26
|
+
line_index = line_number - 1
|
|
27
|
+
beginning_line = line_index <= SOURCE_CONTEXT_WINDOW ? 0 : line_index - SOURCE_CONTEXT_WINDOW
|
|
28
|
+
source_size = SOURCE_CONTEXT_WINDOW * 2 + 1
|
|
29
|
+
lines = @template.split(/\n/)
|
|
30
|
+
contextual_lines = lines[beginning_line, source_size]
|
|
31
|
+
output = []
|
|
32
|
+
contextual_lines.each_with_index do |line, index|
|
|
33
|
+
line_number = (index+beginning_line+1).to_s.rjust(3)
|
|
34
|
+
output << "#{line_number}: #{line}"
|
|
35
|
+
end
|
|
36
|
+
output.join("\n")
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def to_s
|
|
41
|
+
"\n\n#{self.class} (#{message}) #{source_location}:\n\n" +
|
|
42
|
+
"#{source_listing}\n\n #{original_exception.backtrace.join("\n ")}\n\n"
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
module Sprinkle
|
|
47
|
+
module Installers
|
|
48
|
+
# Beware, another strange "installer" coming your way.
|
|
49
|
+
#
|
|
50
|
+
# = File transfer installer
|
|
51
|
+
#
|
|
52
|
+
# This installer pushes files from the local disk to remote servers.
|
|
53
|
+
#
|
|
54
|
+
# == Example Usage
|
|
55
|
+
#
|
|
56
|
+
# Installing a nginx.conf onto remote servers
|
|
57
|
+
#
|
|
58
|
+
# package :nginx_conf do
|
|
59
|
+
# transfer 'files/nginx.conf', '/etc/nginx.conf'
|
|
60
|
+
# end
|
|
61
|
+
#
|
|
62
|
+
# If you user has access to 'sudo' and theres a file that requires
|
|
63
|
+
# priveledges, you can pass :sudo => true
|
|
64
|
+
#
|
|
65
|
+
# package :nginx_conf do
|
|
66
|
+
# transfer 'files/nginx.conf', '/etc/nginx.conf', :sudo => true
|
|
67
|
+
# end
|
|
68
|
+
#
|
|
69
|
+
# By default, transfers are recursive and you can move whole directories
|
|
70
|
+
# via this method. If you wish to disable recursive transfers, you can pass
|
|
71
|
+
# recursive => false, although it will not be obeyed when using the Vlad actor.
|
|
72
|
+
#
|
|
73
|
+
# If you pass the option :render => true, this tells transfer that the source file
|
|
74
|
+
# is an ERB template to be rendered locally before being transferred (you can declare
|
|
75
|
+
# variables in the package scope). When render is true, recursive is turned off.
|
|
76
|
+
#
|
|
77
|
+
# package :nginx_conf do
|
|
78
|
+
# nginx_port = 8080
|
|
79
|
+
# transfer 'files/nginx.conf', '/etc/nginx.conf', :render => true
|
|
80
|
+
# end
|
|
81
|
+
#
|
|
82
|
+
# Finally, should you need to run commands before or after the file transfer (making
|
|
83
|
+
# directories or changing permissions), you can use the pre/post :install directives
|
|
84
|
+
# and they will be run.
|
|
85
|
+
class Transfer < Installer
|
|
86
|
+
attr_accessor :source, :destination #:nodoc:
|
|
87
|
+
|
|
88
|
+
def initialize(parent, source, destination, options={}, &block) #:nodoc:
|
|
89
|
+
super parent, options, &block
|
|
90
|
+
@source = source
|
|
91
|
+
@destination = destination
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def install_commands
|
|
95
|
+
nil
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def self.render_template(template, context, prefix)
|
|
99
|
+
require 'tempfile'
|
|
100
|
+
require 'erubis'
|
|
101
|
+
|
|
102
|
+
begin
|
|
103
|
+
eruby = Erubis::Eruby.new(template)
|
|
104
|
+
output = eruby.result(context)
|
|
105
|
+
rescue Object => e
|
|
106
|
+
raise TemplateError.new(e, template, context)
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
final_tempfile = Tempfile.new(prefix)
|
|
110
|
+
final_tempfile.print(output)
|
|
111
|
+
final_tempfile.close
|
|
112
|
+
final_tempfile
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
def render_template(template, context, prefix)
|
|
116
|
+
self.class.render_template(template, context, prefix)
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
def render_template_file(path, context, prefix)
|
|
120
|
+
template = File.read(path)
|
|
121
|
+
tempfile = render_template(template, binding(), @package.name)
|
|
122
|
+
tempfile
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
def process(roles) #:nodoc:
|
|
126
|
+
assert_delivery
|
|
127
|
+
|
|
128
|
+
if logger.debug?
|
|
129
|
+
logger.debug "transfer: #{@source} -> #{@destination} for roles: #{roles}\n"
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
unless Sprinkle::OPTIONS[:testing]
|
|
133
|
+
pre = pre_commands(:install)
|
|
134
|
+
unless pre.empty?
|
|
135
|
+
sequence = pre; sequence = sequence.join('; ') if sequence.is_a? Array
|
|
136
|
+
logger.info "#{@package.name} pre-transfer commands: #{sequence} for roles: #{roles}\n"
|
|
137
|
+
@delivery.process @package.name, sequence, roles
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
recursive = @options[:recursive]
|
|
141
|
+
|
|
142
|
+
if options[:render]
|
|
143
|
+
tempfile = render_template_file(@source, binding(), @package.name)
|
|
144
|
+
sourcepath = tempfile.path
|
|
145
|
+
logger.info "Rendering template #{@source} to temporary file #{sourcepath}"
|
|
146
|
+
recursive = false
|
|
147
|
+
else
|
|
148
|
+
sourcepath = @source
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
logger.info "--> Transferring #{sourcepath} to #{@destination} for roles: #{roles}"
|
|
152
|
+
@delivery.transfer(@package.name, sourcepath, @destination, roles, recursive)
|
|
153
|
+
|
|
154
|
+
post = post_commands(:install)
|
|
155
|
+
unless post.empty?
|
|
156
|
+
sequence = post; sequence = sequence.join('; ') if sequence.is_a? Array
|
|
157
|
+
logger.info "#{@package.name} post-transfer commands: #{sequence} for roles: #{roles}\n"
|
|
158
|
+
@delivery.process @package.name, sequence, roles
|
|
159
|
+
end
|
|
160
|
+
end
|
|
161
|
+
end
|
|
162
|
+
end
|
|
163
|
+
end
|
|
164
|
+
end
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
module Sprinkle
|
|
2
|
+
module Installers
|
|
3
|
+
# = Yum Package Installer
|
|
4
|
+
#
|
|
5
|
+
# The Yum package installer installs RPM packages.
|
|
6
|
+
#
|
|
7
|
+
# == Example Usage
|
|
8
|
+
#
|
|
9
|
+
# Installing the magic_beans RPM via Yum. Its all the craze these days.
|
|
10
|
+
#
|
|
11
|
+
# package :magic_beans do
|
|
12
|
+
# yum 'magic_beans'
|
|
13
|
+
# end
|
|
14
|
+
#
|
|
15
|
+
# You may also specify multiple rpms as an array:
|
|
16
|
+
#
|
|
17
|
+
# package :magic_beans do
|
|
18
|
+
# yum %w(magic_beans magic_sauce)
|
|
19
|
+
# end
|
|
20
|
+
class Yum < Installer
|
|
21
|
+
attr_accessor :packages #:nodoc:
|
|
22
|
+
|
|
23
|
+
def initialize(parent, packages, &block) #:nodoc:
|
|
24
|
+
super parent, &block
|
|
25
|
+
packages = [packages] unless packages.is_a? Array
|
|
26
|
+
@packages = packages
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
protected
|
|
30
|
+
|
|
31
|
+
def install_commands #:nodoc:
|
|
32
|
+
"yum install #{@packages.join(' ')} -y"
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
@@ -0,0 +1,309 @@
|
|
|
1
|
+
module Sprinkle
|
|
2
|
+
# = Packages
|
|
3
|
+
#
|
|
4
|
+
# A package defines one or more things to provision onto the server.
|
|
5
|
+
# There is a lot of flexibility in a way a package is defined but
|
|
6
|
+
# let me give you a basic example:
|
|
7
|
+
#
|
|
8
|
+
# package :ruby do
|
|
9
|
+
# description 'Ruby MRI'
|
|
10
|
+
# version '1.8.6'
|
|
11
|
+
# apt 'ruby'
|
|
12
|
+
#
|
|
13
|
+
# verify { has_executable 'ruby' }
|
|
14
|
+
# end
|
|
15
|
+
#
|
|
16
|
+
# The above would define a package named 'ruby' and give it a description
|
|
17
|
+
# and explicitly say its version. It is installed via apt and to verify
|
|
18
|
+
# the installation was successful sprinkle will check for the executable
|
|
19
|
+
# 'ruby' being availble. Pretty simple, right?
|
|
20
|
+
#
|
|
21
|
+
# <b>Note:</b> Defining a package does not INSTALL it. To install a
|
|
22
|
+
# package, you must require it in a Sprinkle::Policy block.
|
|
23
|
+
#
|
|
24
|
+
# == Pre-Requirements
|
|
25
|
+
#
|
|
26
|
+
# Most packages have some sort of pre-requisites in order to be installed.
|
|
27
|
+
# Sprinkle allows you to define the requirements of the package, which
|
|
28
|
+
# will be installed before the package itself. An example below:
|
|
29
|
+
#
|
|
30
|
+
# package :rubygems do
|
|
31
|
+
# source 'http://rubyforge.org/rubygems.tgz'
|
|
32
|
+
# requires :ruby
|
|
33
|
+
# end
|
|
34
|
+
#
|
|
35
|
+
# In this case, when rubygems is being installed, Sprinkle will first
|
|
36
|
+
# provision the server with Ruby to make sure the requirements are met.
|
|
37
|
+
# In turn, if ruby has requirements, it installs those first, and so on.
|
|
38
|
+
#
|
|
39
|
+
# == Verifications
|
|
40
|
+
#
|
|
41
|
+
# Most of the time its important to know whether the software you're
|
|
42
|
+
# attempting to install was installed successfully or not. For this,
|
|
43
|
+
# Sprinkle provides verifications. Verifications are one or more blocks
|
|
44
|
+
# which define rules with which Sprinkle can check if it installed
|
|
45
|
+
# the package successfully. If these verification blocks fail, then
|
|
46
|
+
# Sprinkle will gracefully stop the entire process. An example below:
|
|
47
|
+
#
|
|
48
|
+
# package :rubygems do
|
|
49
|
+
# source 'http://rubyforge.org/rubygems.tgz'
|
|
50
|
+
# requires :ruby
|
|
51
|
+
#
|
|
52
|
+
# verify { has_executable 'gem' }
|
|
53
|
+
# end
|
|
54
|
+
#
|
|
55
|
+
# In addition to verifying an installation was successfully, by default
|
|
56
|
+
# Sprinkle runs these verifications <em>before</em> the installation to
|
|
57
|
+
# check if the package is already installed. If the verifications pass
|
|
58
|
+
# before installing the package, it skips the package. To override this
|
|
59
|
+
# behavior, set the -f flag on the sprinkle script or set the
|
|
60
|
+
# :force option to true in Sprinkle::OPTIONS
|
|
61
|
+
#
|
|
62
|
+
# For more information on verifications and to see all the available
|
|
63
|
+
# verifications, see Sprinkle::Verify
|
|
64
|
+
#
|
|
65
|
+
# == Virtual Packages
|
|
66
|
+
#
|
|
67
|
+
# Sometimes, there are multiple packages available for a single task. An
|
|
68
|
+
# example is a database package. It can contain mySQL, postgres, or sqlite!
|
|
69
|
+
# This is where virtual packages come in handy. They are defined as follows:
|
|
70
|
+
#
|
|
71
|
+
# package :sqlite3, :provides => :database do
|
|
72
|
+
# apt 'sqlite3'
|
|
73
|
+
# end
|
|
74
|
+
#
|
|
75
|
+
# The :provides option allows you to reference this package either by :sqlite3
|
|
76
|
+
# or by :database. But whereas the package name is unique, multiple packages may
|
|
77
|
+
# share the same provision. If this is the case, when running Sprinkle, the
|
|
78
|
+
# script will ask you which provision you want to install. At this time, you
|
|
79
|
+
# can only install one.
|
|
80
|
+
#
|
|
81
|
+
# == Meta-Packages
|
|
82
|
+
#
|
|
83
|
+
# A package doesn't require an installer. If you want to define a package which
|
|
84
|
+
# merely encompasses other packages, that is fine too. Example:
|
|
85
|
+
#
|
|
86
|
+
# package :meta do
|
|
87
|
+
# requires :magic_beans
|
|
88
|
+
# requires :magic_sauce
|
|
89
|
+
# end
|
|
90
|
+
#
|
|
91
|
+
#--
|
|
92
|
+
# FIXME: Should probably document recommendations.
|
|
93
|
+
#++
|
|
94
|
+
module Package
|
|
95
|
+
PACKAGES = {}
|
|
96
|
+
|
|
97
|
+
def package(name, metadata = {}, &block)
|
|
98
|
+
package = Package.new(name, metadata, &block)
|
|
99
|
+
PACKAGES[name] = package
|
|
100
|
+
|
|
101
|
+
if package.provides
|
|
102
|
+
(PACKAGES[package.provides] ||= []) << package
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
package
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
class Package #:nodoc:
|
|
109
|
+
include ArbitraryOptions
|
|
110
|
+
attr_accessor :name, :provides, :installers, :dependencies, :recommends, :verifications
|
|
111
|
+
|
|
112
|
+
def initialize(name, metadata = {}, &block)
|
|
113
|
+
raise 'No package name supplied' unless name
|
|
114
|
+
|
|
115
|
+
@name = name
|
|
116
|
+
@provides = metadata[:provides]
|
|
117
|
+
@dependencies = []
|
|
118
|
+
@recommends = []
|
|
119
|
+
@optional = []
|
|
120
|
+
@verifications = []
|
|
121
|
+
@installers = []
|
|
122
|
+
self.instance_eval &block
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
def freebsd_pkg(*names, &block)
|
|
126
|
+
@installers << Sprinkle::Installers::FreebsdPkg.new(self, *names, &block)
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
def freebsd_portinstall(port, &block)
|
|
130
|
+
@installers << Sprinkle::Installers::FreebsdPortinstall.new(self, port, &block)
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
def openbsd_pkg(*names, &block)
|
|
134
|
+
@installers << Sprinkle::Installers::OpenbsdPkg.new(self, *names, &block)
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
def opensolaris_pkg(*names, &block)
|
|
138
|
+
@installers << Sprinkle::Installers::OpensolarisPkg.new(self, *names, &block)
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
def bsd_port(port, &block)
|
|
142
|
+
@installers << Sprinkle::Installers::BsdPort.new(self, port, &block)
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
def mac_port(port, &block)
|
|
146
|
+
@installers << Sprinkle::Installers::MacPort.new(self, port, &block)
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
def apt(*names, &block)
|
|
150
|
+
@installers << Sprinkle::Installers::Apt.new(self, *names, &block)
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
def deb(*names, &block)
|
|
154
|
+
@installers << Sprinkle::Installers::Deb.new(self, *names, &block)
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
def rpm(*names, &block)
|
|
158
|
+
@installers << Sprinkle::Installers::Rpm.new(self, *names, &block)
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
def yum(*names, &block)
|
|
162
|
+
@installers << Sprinkle::Installers::Yum.new(self, *names, &block)
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
def gem(name, options = {}, &block)
|
|
166
|
+
@recommends << :rubygems
|
|
167
|
+
@installers << Sprinkle::Installers::Gem.new(self, name, options, &block)
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
def source(source, options = {}, &block)
|
|
171
|
+
@recommends << :build_essential # Ubuntu/Debian
|
|
172
|
+
@installers << Sprinkle::Installers::Source.new(self, source, options, &block)
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
def binary(source, options = {}, &block)
|
|
176
|
+
@installers << Sprinkle::Installers::Binary.new(self, source, options, &block)
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
def rake(name, options = {}, &block)
|
|
180
|
+
@installers << Sprinkle::Installers::Rake.new(self, name, options, &block)
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
def noop(&block)
|
|
184
|
+
@installers << Sprinkle::Installers::Noop.new(self, name, options, &block)
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
def push_text(text, path, options = {}, &block)
|
|
188
|
+
@installers << Sprinkle::Installers::PushText.new(self, text, path, options, &block)
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
def transfer(source, destination, options = {}, &block)
|
|
192
|
+
@installers << Sprinkle::Installers::Transfer.new(self, source, destination, options, &block)
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
def verify(description = '', &block)
|
|
196
|
+
@verifications << Sprinkle::Verify.new(self, description, &block)
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
def process(deployment, roles)
|
|
200
|
+
return if meta_package?
|
|
201
|
+
|
|
202
|
+
# Run a pre-test to see if the software is already installed. If so,
|
|
203
|
+
# we can skip it, unless we have the force option turned on!
|
|
204
|
+
unless @verifications.empty? || Sprinkle::OPTIONS[:force]
|
|
205
|
+
begin
|
|
206
|
+
process_verifications(deployment, roles, true)
|
|
207
|
+
|
|
208
|
+
logger.info "--> #{self.name} already installed for roles: #{roles}"
|
|
209
|
+
return
|
|
210
|
+
rescue Sprinkle::VerificationFailed => e
|
|
211
|
+
# Continue
|
|
212
|
+
end
|
|
213
|
+
end
|
|
214
|
+
|
|
215
|
+
@installers.each do |installer|
|
|
216
|
+
installer.defaults(deployment)
|
|
217
|
+
installer.process(roles)
|
|
218
|
+
end
|
|
219
|
+
|
|
220
|
+
process_verifications(deployment, roles)
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
def process_verifications(deployment, roles, pre = false)
|
|
224
|
+
return if @verifications.blank?
|
|
225
|
+
|
|
226
|
+
if pre
|
|
227
|
+
logger.info "--> Checking if #{self.name} is already installed for roles: #{roles}"
|
|
228
|
+
else
|
|
229
|
+
logger.info "--> Verifying #{self.name} was properly installed for roles: #{roles}"
|
|
230
|
+
end
|
|
231
|
+
|
|
232
|
+
@verifications.each do |v|
|
|
233
|
+
v.defaults(deployment)
|
|
234
|
+
v.process(roles)
|
|
235
|
+
end
|
|
236
|
+
end
|
|
237
|
+
|
|
238
|
+
def requires(*packages)
|
|
239
|
+
@dependencies << packages
|
|
240
|
+
@dependencies.flatten!
|
|
241
|
+
end
|
|
242
|
+
|
|
243
|
+
def recommends(*packages)
|
|
244
|
+
@recommends << packages
|
|
245
|
+
@recommends.flatten!
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
def optional(*packages)
|
|
249
|
+
@optional << packages
|
|
250
|
+
@optional.flatten!
|
|
251
|
+
end
|
|
252
|
+
|
|
253
|
+
def tree(depth = 1, &block)
|
|
254
|
+
packages = []
|
|
255
|
+
|
|
256
|
+
@recommends.each do |dep|
|
|
257
|
+
package = PACKAGES[dep]
|
|
258
|
+
next unless package # skip missing recommended packages as they're allowed to not exist
|
|
259
|
+
block.call(self, package, depth) if block
|
|
260
|
+
packages << package.tree(depth + 1, &block)
|
|
261
|
+
end
|
|
262
|
+
|
|
263
|
+
@dependencies.each do |dep|
|
|
264
|
+
package = PACKAGES[dep]
|
|
265
|
+
package = select_package(dep, package) if package.is_a? Array
|
|
266
|
+
|
|
267
|
+
raise "Package definition not found for key: #{dep}" unless package
|
|
268
|
+
block.call(self, package, depth) if block
|
|
269
|
+
packages << package.tree(depth + 1, &block)
|
|
270
|
+
end
|
|
271
|
+
|
|
272
|
+
packages << self
|
|
273
|
+
|
|
274
|
+
@optional.each do |dep|
|
|
275
|
+
package = PACKAGES[dep]
|
|
276
|
+
next unless package # skip missing optional packages as they're allow to not exist
|
|
277
|
+
block.call(self, package, depth) if block
|
|
278
|
+
packages << package.tree(depth + 1, &block)
|
|
279
|
+
end
|
|
280
|
+
|
|
281
|
+
packages
|
|
282
|
+
end
|
|
283
|
+
|
|
284
|
+
def to_s; @name; end
|
|
285
|
+
|
|
286
|
+
private
|
|
287
|
+
|
|
288
|
+
def select_package(name, packages)
|
|
289
|
+
if packages.size <= 1
|
|
290
|
+
package = packages.first
|
|
291
|
+
else
|
|
292
|
+
package = choose do |menu|
|
|
293
|
+
menu.prompt = "Multiple choices exist for virtual package #{name}"
|
|
294
|
+
menu.choices *packages.collect(&:to_s)
|
|
295
|
+
end
|
|
296
|
+
package = Sprinkle::Package::PACKAGES[package]
|
|
297
|
+
end
|
|
298
|
+
|
|
299
|
+
cloud_info "Selecting #{package.to_s} for virtual package #{name}"
|
|
300
|
+
|
|
301
|
+
package
|
|
302
|
+
end
|
|
303
|
+
|
|
304
|
+
def meta_package?
|
|
305
|
+
@installers.blank?
|
|
306
|
+
end
|
|
307
|
+
end
|
|
308
|
+
end
|
|
309
|
+
end
|