sunshine 1.0.0.pre
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/History.txt +237 -0
- data/Manifest.txt +70 -0
- data/README.txt +277 -0
- data/Rakefile +46 -0
- data/bin/sunshine +5 -0
- data/examples/deploy.rb +61 -0
- data/examples/deploy_tasks.rake +112 -0
- data/examples/standalone_deploy.rb +31 -0
- data/lib/commands/add.rb +96 -0
- data/lib/commands/default.rb +169 -0
- data/lib/commands/list.rb +322 -0
- data/lib/commands/restart.rb +62 -0
- data/lib/commands/rm.rb +83 -0
- data/lib/commands/run.rb +151 -0
- data/lib/commands/start.rb +72 -0
- data/lib/commands/stop.rb +61 -0
- data/lib/sunshine/app.rb +876 -0
- data/lib/sunshine/binder.rb +70 -0
- data/lib/sunshine/crontab.rb +143 -0
- data/lib/sunshine/daemon.rb +380 -0
- data/lib/sunshine/daemons/ar_sendmail.rb +28 -0
- data/lib/sunshine/daemons/delayed_job.rb +30 -0
- data/lib/sunshine/daemons/nginx.rb +104 -0
- data/lib/sunshine/daemons/rainbows.rb +35 -0
- data/lib/sunshine/daemons/server.rb +66 -0
- data/lib/sunshine/daemons/unicorn.rb +26 -0
- data/lib/sunshine/dependencies.rb +103 -0
- data/lib/sunshine/dependency_lib.rb +200 -0
- data/lib/sunshine/exceptions.rb +54 -0
- data/lib/sunshine/healthcheck.rb +83 -0
- data/lib/sunshine/output.rb +131 -0
- data/lib/sunshine/package_managers/apt.rb +48 -0
- data/lib/sunshine/package_managers/dependency.rb +349 -0
- data/lib/sunshine/package_managers/gem.rb +54 -0
- data/lib/sunshine/package_managers/yum.rb +62 -0
- data/lib/sunshine/remote_shell.rb +241 -0
- data/lib/sunshine/repo.rb +128 -0
- data/lib/sunshine/repos/git_repo.rb +122 -0
- data/lib/sunshine/repos/rsync_repo.rb +29 -0
- data/lib/sunshine/repos/svn_repo.rb +78 -0
- data/lib/sunshine/server_app.rb +554 -0
- data/lib/sunshine/shell.rb +384 -0
- data/lib/sunshine.rb +391 -0
- data/templates/logrotate/logrotate.conf.erb +11 -0
- data/templates/nginx/nginx.conf.erb +109 -0
- data/templates/nginx/nginx_optimize.conf +23 -0
- data/templates/nginx/nginx_proxy.conf +13 -0
- data/templates/rainbows/rainbows.conf.erb +18 -0
- data/templates/tasks/sunshine.rake +114 -0
- data/templates/unicorn/unicorn.conf.erb +6 -0
- data/test/fixtures/app_configs/test_app.yml +11 -0
- data/test/fixtures/sunshine_test/test_upload +0 -0
- data/test/mocks/mock_object.rb +179 -0
- data/test/mocks/mock_open4.rb +117 -0
- data/test/test_helper.rb +188 -0
- data/test/unit/test_app.rb +489 -0
- data/test/unit/test_binder.rb +20 -0
- data/test/unit/test_crontab.rb +128 -0
- data/test/unit/test_git_repo.rb +26 -0
- data/test/unit/test_healthcheck.rb +70 -0
- data/test/unit/test_nginx.rb +107 -0
- data/test/unit/test_rainbows.rb +26 -0
- data/test/unit/test_remote_shell.rb +102 -0
- data/test/unit/test_repo.rb +42 -0
- data/test/unit/test_server.rb +324 -0
- data/test/unit/test_server_app.rb +425 -0
- data/test/unit/test_shell.rb +97 -0
- data/test/unit/test_sunshine.rb +157 -0
- data/test/unit/test_svn_repo.rb +55 -0
- data/test/unit/test_unicorn.rb +22 -0
- metadata +217 -0
@@ -0,0 +1,131 @@
|
|
1
|
+
module Sunshine
|
2
|
+
|
3
|
+
##
|
4
|
+
# The Output class handles all of the logging to the shell
|
5
|
+
# during the Sunshine runtime.
|
6
|
+
|
7
|
+
class Output
|
8
|
+
|
9
|
+
COLORS = {
|
10
|
+
Logger::UNKNOWN => :red,
|
11
|
+
Logger::FATAL => :red,
|
12
|
+
Logger::ERROR => :red,
|
13
|
+
Logger::WARN => :yellow,
|
14
|
+
Logger::INFO => :default,
|
15
|
+
Logger::DEBUG => :cyan,
|
16
|
+
}
|
17
|
+
|
18
|
+
attr_accessor :logger, :indent, :level
|
19
|
+
|
20
|
+
def initialize(options={})
|
21
|
+
@logger = Logger.new options[:output] || $stdout
|
22
|
+
@logger.formatter = lambda{|sev, time, progname, msg| msg}
|
23
|
+
@level = @logger.level = options[:level] || Logger::DEBUG
|
24
|
+
@indent = 0
|
25
|
+
end
|
26
|
+
|
27
|
+
##
|
28
|
+
# Prints messages according to the standard output format.
|
29
|
+
# Options supported:
|
30
|
+
# :level: level of the log message
|
31
|
+
# :indent: indentation of the message
|
32
|
+
def print(title, message, options={})
|
33
|
+
severity = options[:level] || Logger::DEBUG
|
34
|
+
color = COLORS[severity]
|
35
|
+
|
36
|
+
options[:indent] = 0 if options[:indent] < 0
|
37
|
+
indent = " " * (options[:indent].to_i * 2)
|
38
|
+
|
39
|
+
print_string = message.split("\n")
|
40
|
+
print_string.map!{|m| "#{indent}[#{title}] #{m.chomp}"}
|
41
|
+
print_string = "#{print_string.join("\n")} \n"
|
42
|
+
print_string = print_string.foreground(color)
|
43
|
+
print_string = print_string.bright if indent.empty?
|
44
|
+
|
45
|
+
@logger.add(severity, print_string)
|
46
|
+
end
|
47
|
+
|
48
|
+
##
|
49
|
+
# Generic log message which handles log indentation (for clarity).
|
50
|
+
# Log indentation if achieved done by passing a block:
|
51
|
+
#
|
52
|
+
# output.log("MAIN", "Main thing is happening") do
|
53
|
+
# ...
|
54
|
+
# output.log("SUB1", "Sub process thing") do
|
55
|
+
# ...
|
56
|
+
# output.log("SUB2", "Innermost process thing")
|
57
|
+
# end
|
58
|
+
# end
|
59
|
+
#
|
60
|
+
# output.log("MAIN", "Start something else")
|
61
|
+
#
|
62
|
+
# ------
|
63
|
+
# > [MAIN] Main thing is happening
|
64
|
+
# > [SUB1] Sub process thing
|
65
|
+
# > [SUB2] Innermost process thing
|
66
|
+
# >
|
67
|
+
# > [MAIN] Start something else
|
68
|
+
#
|
69
|
+
# Log level is set to the instance's default unless
|
70
|
+
# specified in the options argument with :level => Logger::LEVEL.
|
71
|
+
# The default log level is Logger::INFO
|
72
|
+
#
|
73
|
+
# Best practice for using log levels is to call the level methods
|
74
|
+
# which all work similarly to the log method:
|
75
|
+
# unknown, fatal, error, warn, info, debug
|
76
|
+
def log(title, message, options={}, &block)
|
77
|
+
unless Sunshine.trace?
|
78
|
+
return block.call if block_given?
|
79
|
+
return
|
80
|
+
end
|
81
|
+
|
82
|
+
options = {:indent => @indent}.merge(options)
|
83
|
+
self.print(title, message, options)
|
84
|
+
if block_given?
|
85
|
+
@indent = @indent + 1
|
86
|
+
begin
|
87
|
+
block.call
|
88
|
+
ensure
|
89
|
+
@indent = @indent - 1 unless @indent <= 0
|
90
|
+
@logger << "\n"
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
##
|
96
|
+
# Log a message of log level unknown.
|
97
|
+
def unknown(title, message, options={}, &block)
|
98
|
+
self.log(title, message, options.merge(:level => Logger::UNKNOWN), &block)
|
99
|
+
end
|
100
|
+
|
101
|
+
##
|
102
|
+
# Log a message of log level fatal.
|
103
|
+
def fatal(title, message, options={}, &block)
|
104
|
+
self.log(title, message, options.merge(:level => Logger::FATAL), &block)
|
105
|
+
end
|
106
|
+
|
107
|
+
##
|
108
|
+
# Log a message of log level error.
|
109
|
+
def error(title, message, options={}, &block)
|
110
|
+
self.log(title, message, options.merge(:level => Logger::ERROR), &block)
|
111
|
+
end
|
112
|
+
|
113
|
+
##
|
114
|
+
# Log a message of log level warn.
|
115
|
+
def warn(title, message, options={}, &block)
|
116
|
+
self.log(title, message, options.merge(:level => Logger::WARN), &block)
|
117
|
+
end
|
118
|
+
|
119
|
+
##
|
120
|
+
# Log a message of log level info.
|
121
|
+
def info(title, message, options={}, &block)
|
122
|
+
self.log(title, message, options.merge(:level => Logger::INFO), &block)
|
123
|
+
end
|
124
|
+
|
125
|
+
##
|
126
|
+
# Log a message of log level debug.
|
127
|
+
def debug(title, message, options={}, &block)
|
128
|
+
self.log(title, message, options.merge(:level => Logger::DEBUG), &block)
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module Sunshine
|
2
|
+
|
3
|
+
##
|
4
|
+
# The Apt dependency class supports basic apt-get features:
|
5
|
+
#
|
6
|
+
# dependency_lib.instance_eval do
|
7
|
+
# apt "ruby", :version => '1.9'
|
8
|
+
# end
|
9
|
+
#
|
10
|
+
# See the Dependency class for more info.
|
11
|
+
|
12
|
+
class Apt < Dependency
|
13
|
+
|
14
|
+
def initialize(name, options={}, &block)
|
15
|
+
super(name, options) do
|
16
|
+
pkg_name = build_pkg_name @pkg.dup, options
|
17
|
+
|
18
|
+
install "apt-get install -y #{pkg_name}"
|
19
|
+
uninstall "apt-get remove -y #{pkg_name}"
|
20
|
+
|
21
|
+
@pkg = "#{@pkg}-#{options[:version]}" if options[:version]
|
22
|
+
check_test "apt-cache search ^#{@pkg} | grep -c ^#{@pkg}", '-ge 1'
|
23
|
+
|
24
|
+
instance_eval(&block) if block_given?
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def build_pkg_name pkg_name, options={}
|
32
|
+
pkg_name << "=#{options[:version]}" if options[:version]
|
33
|
+
|
34
|
+
pkg_name
|
35
|
+
end
|
36
|
+
|
37
|
+
|
38
|
+
def run_command(command, options={})
|
39
|
+
if @dependency_lib
|
40
|
+
if @dependency_lib.exist?('apt')
|
41
|
+
@dependency_lib.install 'apt', options
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
super
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,349 @@
|
|
1
|
+
module Sunshine
|
2
|
+
|
3
|
+
##
|
4
|
+
# Dependency objects let you define how to install, check, and remove
|
5
|
+
# a described package, including parent dependency lookup and installation.
|
6
|
+
#
|
7
|
+
# Dependency.new "ruby", :tree => dependency_lib do
|
8
|
+
# install "sudo yum install ruby"
|
9
|
+
# uninstall "sudo yum remove ruby"
|
10
|
+
# check_test "yum list installed ruby | grep -c ruby", "-ge 1"
|
11
|
+
# end
|
12
|
+
#
|
13
|
+
# Dependencies are more commonly defined through a Settler class'
|
14
|
+
# constructor methods:
|
15
|
+
#
|
16
|
+
# dependency_lib.instance_eval do
|
17
|
+
# dependency 'custom' do
|
18
|
+
# requires 'yum', 'ruby'
|
19
|
+
# install 'sudo yum install custom'
|
20
|
+
# uninstall 'sudo yum remove custom'
|
21
|
+
# check 'yum list installed custom'
|
22
|
+
# end
|
23
|
+
# end
|
24
|
+
#
|
25
|
+
# The Dependency class is simple to inherit and use as a built-in part of
|
26
|
+
# Settler (see the Yum implementation for more info):
|
27
|
+
#
|
28
|
+
# class Yum < Dependency
|
29
|
+
# def initialize(name, options={}, &block)
|
30
|
+
# super(dep_lib, name, options) do
|
31
|
+
# # Define install, check, and uninstall scripts specific to yum
|
32
|
+
# end
|
33
|
+
# end
|
34
|
+
# ...
|
35
|
+
# end
|
36
|
+
#
|
37
|
+
# Once a subclass is defined a constructor method is added automatically
|
38
|
+
# to the Settler class:
|
39
|
+
#
|
40
|
+
# dependency_lib.instance_eval do
|
41
|
+
# yum "ruby", :version => '1.9'
|
42
|
+
# end
|
43
|
+
|
44
|
+
class Dependency
|
45
|
+
|
46
|
+
class CmdError < Exception; end
|
47
|
+
class InstallError < Exception; end
|
48
|
+
class UninstallError < Exception; end
|
49
|
+
|
50
|
+
|
51
|
+
##
|
52
|
+
# Check if sudo should be used
|
53
|
+
|
54
|
+
def self.sudo
|
55
|
+
@sudo ||= nil
|
56
|
+
end
|
57
|
+
|
58
|
+
|
59
|
+
##
|
60
|
+
# Assign a sudo value. A value of nil means 'don't assign sudo',
|
61
|
+
# true means sudo, string means sudo -u, false means, explicitely
|
62
|
+
# don't use sudo. Yum and Gem dependency types default to sudo=true.
|
63
|
+
|
64
|
+
def self.sudo= value
|
65
|
+
@sudo = value
|
66
|
+
end
|
67
|
+
|
68
|
+
|
69
|
+
attr_reader :name, :pkg, :parents, :children
|
70
|
+
|
71
|
+
def initialize name, options={}, &block
|
72
|
+
@dependency_lib = options[:tree]
|
73
|
+
|
74
|
+
@name = name.to_s
|
75
|
+
@pkg = options[:pkg] || @name
|
76
|
+
@options = options.dup
|
77
|
+
|
78
|
+
@install = nil
|
79
|
+
@uninstall = nil
|
80
|
+
@check = nil
|
81
|
+
|
82
|
+
@parents = []
|
83
|
+
@children = []
|
84
|
+
|
85
|
+
@shell = Sunshine.shell
|
86
|
+
|
87
|
+
requires(*options[:requires]) if options[:requires]
|
88
|
+
|
89
|
+
instance_eval(&block) if block_given?
|
90
|
+
end
|
91
|
+
|
92
|
+
|
93
|
+
##
|
94
|
+
# Append a child dependency
|
95
|
+
|
96
|
+
def add_child name
|
97
|
+
@children << name
|
98
|
+
end
|
99
|
+
|
100
|
+
|
101
|
+
##
|
102
|
+
# Get direct child dependencies
|
103
|
+
|
104
|
+
def child_dependencies
|
105
|
+
@children
|
106
|
+
end
|
107
|
+
|
108
|
+
|
109
|
+
##
|
110
|
+
# Define the command that checks if the dependency is installed.
|
111
|
+
# The check command must have an appropriate exitcode:
|
112
|
+
#
|
113
|
+
# dep.check "test -s 'yum list installed depname'"
|
114
|
+
|
115
|
+
def check cmd_str=nil, &block
|
116
|
+
@check = cmd_str || block
|
117
|
+
end
|
118
|
+
|
119
|
+
|
120
|
+
##
|
121
|
+
# Define checking that the dependency is installed via unix's 'test':
|
122
|
+
#
|
123
|
+
# dep.check_test "yum list installed depname | grep -c depname", "-ge 1"
|
124
|
+
|
125
|
+
def check_test cmd_str, condition_str
|
126
|
+
check "test \"$(#{cmd_str})\" #{condition_str}"
|
127
|
+
end
|
128
|
+
|
129
|
+
|
130
|
+
##
|
131
|
+
# Define the install command for the dependency:
|
132
|
+
#
|
133
|
+
# dep.install "yum install depname"
|
134
|
+
|
135
|
+
def install cmd=nil, &block
|
136
|
+
@install = cmd || block
|
137
|
+
end
|
138
|
+
|
139
|
+
|
140
|
+
##
|
141
|
+
# Run the install command for the dependency
|
142
|
+
# Allows options:
|
143
|
+
# :call:: obj - an object that responds to call will be passed the bash cmd
|
144
|
+
# :skip_parents:: true - install regardless of missing parent dependencies
|
145
|
+
#
|
146
|
+
# runner = lambda{|str| system(str)}
|
147
|
+
# dep.install! :call => runner
|
148
|
+
|
149
|
+
def install! options={}
|
150
|
+
return if installed?(options)
|
151
|
+
|
152
|
+
if options[:skip_parents]
|
153
|
+
missing = missing_parents?
|
154
|
+
if missing
|
155
|
+
raise(InstallError, "Could not install #{@name}. "+
|
156
|
+
"Missing dependencies #{missing.join(", ")}")
|
157
|
+
end
|
158
|
+
else
|
159
|
+
install_parents!(options)
|
160
|
+
end
|
161
|
+
|
162
|
+
run_command(@install, options)
|
163
|
+
raise(InstallError, "Failed installing #{@name}") unless
|
164
|
+
installed?(options)
|
165
|
+
end
|
166
|
+
|
167
|
+
|
168
|
+
##
|
169
|
+
# Call install on direct parent dependencies
|
170
|
+
# Allows options:
|
171
|
+
# :call:: obj - an object that responds to call will be passed the bash cmd
|
172
|
+
#
|
173
|
+
# runner = lambda{|str| system(str)}
|
174
|
+
# dep.install_parents! :call => runner
|
175
|
+
|
176
|
+
def install_parents! options={}
|
177
|
+
return unless @dependency_lib
|
178
|
+
|
179
|
+
@parents.each do |dep|
|
180
|
+
@dependency_lib.get(dep, options).install!(options)
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
|
185
|
+
##
|
186
|
+
# Run the check command to verify that the dependency is installed
|
187
|
+
# Allows options:
|
188
|
+
# :call:: obj - an object that responds to call will be passed the bash cmd
|
189
|
+
#
|
190
|
+
# runner = lambda{|str| system(str)}
|
191
|
+
# dep.installed? :call => runner
|
192
|
+
|
193
|
+
def installed? options={}
|
194
|
+
run_command @check, options
|
195
|
+
rescue => e
|
196
|
+
false
|
197
|
+
end
|
198
|
+
|
199
|
+
|
200
|
+
##
|
201
|
+
# Checks if any parents dependencies are missing
|
202
|
+
# Allows options:
|
203
|
+
# :call:: obj - an object that responds to call will be passed the bash cmd
|
204
|
+
#
|
205
|
+
# runner = lambda{|str| system(str)}
|
206
|
+
# dep.missing_parents? :call => runner
|
207
|
+
|
208
|
+
|
209
|
+
def missing_parents? options={}
|
210
|
+
return unless @dependency_lib
|
211
|
+
|
212
|
+
missing = []
|
213
|
+
@parents.each do |dep|
|
214
|
+
parent_dep = @dependency_lib.get dep, options
|
215
|
+
|
216
|
+
missing << dep unless parent_dep.installed?(options)
|
217
|
+
|
218
|
+
return missing if options[:limit] && options[:limit] == missing.length
|
219
|
+
end
|
220
|
+
|
221
|
+
missing.empty? ? nil : missing
|
222
|
+
end
|
223
|
+
|
224
|
+
|
225
|
+
##
|
226
|
+
# Get direct parent dependencies
|
227
|
+
|
228
|
+
def parent_dependencies
|
229
|
+
@parents
|
230
|
+
end
|
231
|
+
|
232
|
+
|
233
|
+
##
|
234
|
+
# Define which dependencies this dependency relies on:
|
235
|
+
#
|
236
|
+
# dep.requires 'rubygems', 'rdoc'
|
237
|
+
|
238
|
+
def requires *deps
|
239
|
+
return unless @dependency_lib
|
240
|
+
|
241
|
+
@parents.concat(deps).uniq!
|
242
|
+
deps.each do |dep|
|
243
|
+
@dependency_lib.dependencies[dep].each{|d| d.add_child(@name) }
|
244
|
+
end
|
245
|
+
end
|
246
|
+
|
247
|
+
|
248
|
+
##
|
249
|
+
# Define the uninstall command for the dependency:
|
250
|
+
#
|
251
|
+
# dep.uninstall "yum remove depname"
|
252
|
+
|
253
|
+
def uninstall cmd=nil, &block
|
254
|
+
@uninstall = cmd || block
|
255
|
+
end
|
256
|
+
|
257
|
+
|
258
|
+
##
|
259
|
+
# Run the uninstall command for the dependency
|
260
|
+
# Allows options:
|
261
|
+
# :call:: obj - an object that responds to call will be passed the bash cmd
|
262
|
+
# :force:: true - uninstalls regardless of child dependencies
|
263
|
+
# :remove_children:: true - removes direct child dependencies
|
264
|
+
# :remove_children:: :recursive - removes children recursively
|
265
|
+
|
266
|
+
def uninstall! options={}
|
267
|
+
if !options[:remove_children] && !options[:force]
|
268
|
+
raise UninstallError, "The #{@name} has child dependencies."
|
269
|
+
end
|
270
|
+
uninstall_children!(options) if options[:remove_children]
|
271
|
+
run_command(@uninstall, options)
|
272
|
+
raise(UninstallError, "Failed removing #{@name}") if installed?(options)
|
273
|
+
end
|
274
|
+
|
275
|
+
|
276
|
+
##
|
277
|
+
# Removes child dependencies
|
278
|
+
# Allows options:
|
279
|
+
# :call:: obj - an object that responds to call will be passed the bash cmd
|
280
|
+
# :force:: true - uninstalls regardless of child dependencies
|
281
|
+
# :remove_children:: true - removes direct child dependencies
|
282
|
+
# :remove_children:: :recursive - removes children recursively
|
283
|
+
|
284
|
+
def uninstall_children! options={}
|
285
|
+
return unless @dependency_lib
|
286
|
+
|
287
|
+
options = options.dup
|
288
|
+
|
289
|
+
@children.each do |dep|
|
290
|
+
options.delete(:remove_children) unless
|
291
|
+
options[:remove_children] == :recursive
|
292
|
+
|
293
|
+
@dependency_lib.get(dep, options).uninstall!(options)
|
294
|
+
end
|
295
|
+
end
|
296
|
+
|
297
|
+
|
298
|
+
##
|
299
|
+
# Alias for name
|
300
|
+
|
301
|
+
def to_s
|
302
|
+
@name
|
303
|
+
end
|
304
|
+
|
305
|
+
|
306
|
+
private
|
307
|
+
|
308
|
+
def run_command command, options={}
|
309
|
+
shell = options[:call] || @shell
|
310
|
+
|
311
|
+
if Proc === command
|
312
|
+
command.call shell, self.class.sudo
|
313
|
+
|
314
|
+
else
|
315
|
+
shell.call command, :sudo => self.class.sudo
|
316
|
+
end
|
317
|
+
end
|
318
|
+
|
319
|
+
|
320
|
+
def self.short_class_name str
|
321
|
+
str.to_s.split(":").last
|
322
|
+
end
|
323
|
+
|
324
|
+
|
325
|
+
def self.underscore str
|
326
|
+
str.gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
|
327
|
+
gsub(/([a-z\d])([A-Z])/,'\1_\2').downcase
|
328
|
+
end
|
329
|
+
|
330
|
+
|
331
|
+
def self.inherited(subclass)
|
332
|
+
class_name = short_class_name subclass.to_s
|
333
|
+
method_name = underscore class_name
|
334
|
+
|
335
|
+
DependencyLib.class_eval <<-STR, __FILE__, __LINE__ + 1
|
336
|
+
def #{method_name}(name, options={}, &block)
|
337
|
+
dep = #{class_name}.new(name, options.merge(:tree => self), &block)
|
338
|
+
self.add dep
|
339
|
+
dep
|
340
|
+
end
|
341
|
+
STR
|
342
|
+
|
343
|
+
DependencyLib.dependency_types << subclass
|
344
|
+
end
|
345
|
+
|
346
|
+
inherited self
|
347
|
+
|
348
|
+
end
|
349
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
module Sunshine
|
2
|
+
|
3
|
+
##
|
4
|
+
# The Gem dependency class supports most of rubygem's installation features:
|
5
|
+
#
|
6
|
+
# dependency_lib.instance_eval do
|
7
|
+
# gem "rdoc", :version => '~>0.8',
|
8
|
+
# :source => 'http://gemcutter.org',
|
9
|
+
# :opts => '--use-lib blah' # Anything after --
|
10
|
+
# end
|
11
|
+
#
|
12
|
+
# See the Dependency class for more info.
|
13
|
+
|
14
|
+
class Gem < Dependency
|
15
|
+
|
16
|
+
self.sudo = true
|
17
|
+
|
18
|
+
|
19
|
+
def initialize(name, options={}, &block)
|
20
|
+
super(name, options) do
|
21
|
+
version = options[:version] ? " --version '#{options[:version]}'" : ""
|
22
|
+
|
23
|
+
source = if options[:source]
|
24
|
+
" --source #{options[:source]} --source http://gemcutter.org"
|
25
|
+
end
|
26
|
+
|
27
|
+
install_opts = " --no-ri --no-rdoc"
|
28
|
+
if options[:opts]
|
29
|
+
install_opts = "#{install_opts} -- #{options[:opts]}"
|
30
|
+
end
|
31
|
+
|
32
|
+
install "gem install #{@pkg}#{version}#{source}#{install_opts}"
|
33
|
+
uninstall "gem uninstall #{@pkg}#{version}"
|
34
|
+
check "gem list #{@pkg} -i#{version}"
|
35
|
+
|
36
|
+
requires(*options[:require].to_a) if options[:require]
|
37
|
+
|
38
|
+
instance_eval(&block) if block_given?
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
def run_command(command, options={})
|
46
|
+
if @dependency_lib
|
47
|
+
@dependency_lib.install 'rubygems', options if
|
48
|
+
@dependency_lib.exist?('rubygems')
|
49
|
+
end
|
50
|
+
|
51
|
+
super
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
module Sunshine
|
2
|
+
|
3
|
+
##
|
4
|
+
# The Yum dependency class supports most of yum's installation features:
|
5
|
+
#
|
6
|
+
# dependency_lib.instance_eval do
|
7
|
+
# yum "ruby", :version => '1.9',
|
8
|
+
# :rel => 'release-num',
|
9
|
+
# :arch => 'i386',
|
10
|
+
# :epoch => 'some-epoch'
|
11
|
+
# end
|
12
|
+
#
|
13
|
+
# See the Dependency class for more info.
|
14
|
+
|
15
|
+
class Yum < Dependency
|
16
|
+
|
17
|
+
self.sudo = true
|
18
|
+
|
19
|
+
|
20
|
+
def initialize(name, options={}, &block)
|
21
|
+
super(name, options) do
|
22
|
+
pkg_name = build_pkg_name @pkg.dup, options
|
23
|
+
|
24
|
+
install "yum install -y #{pkg_name}"
|
25
|
+
uninstall "yum remove -y #{pkg_name}"
|
26
|
+
check_test "yum list installed #{pkg_name} | grep -c #{@pkg}", '-ge 1'
|
27
|
+
|
28
|
+
instance_eval(&block) if block_given?
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def build_pkg_name pkg_name, options={}
|
36
|
+
if options[:version]
|
37
|
+
pkg_name << "-#{options[:version]}"
|
38
|
+
|
39
|
+
if options[:rel]
|
40
|
+
pkg_name << "-#{options[:rel]}"
|
41
|
+
|
42
|
+
pkg_name = "#{options[:epoch]}:#{pkg_name}" if
|
43
|
+
options[:arch] && options[:epoch]
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
pkg_name << ".#{options[:arch]}" if options[:arch]
|
48
|
+
pkg_name
|
49
|
+
end
|
50
|
+
|
51
|
+
|
52
|
+
def run_command(command, options={})
|
53
|
+
if @dependency_lib
|
54
|
+
if @dependency_lib.exist?('yum')
|
55
|
+
@dependency_lib.install 'yum', options
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
super
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|