syncwrap 1.5.2 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/History.rdoc +19 -0
- data/Manifest.txt +82 -34
- data/README.rdoc +96 -48
- data/Rakefile +0 -65
- data/bin/syncwrap +27 -0
- data/examples/LAYOUT.rdoc +70 -0
- data/examples/Rakefile +16 -0
- data/examples/ec2.rb +44 -0
- data/examples/hello.rb +14 -0
- data/examples/hello_binding.rb +27 -0
- data/examples/jruby.rb +11 -0
- data/examples/private/aws.json +4 -0
- data/examples/rput.rb +24 -0
- data/examples/sync/home/bob/.ssh/authorized_keys +1 -0
- data/examples/sync/tmp/sample.erb +3 -0
- data/lib/syncwrap/amazon_ec2.rb +236 -0
- data/lib/syncwrap/amazon_ws.rb +308 -0
- data/lib/syncwrap/base.rb +4 -2
- data/lib/syncwrap/cli.rb +328 -0
- data/lib/syncwrap/component.rb +443 -0
- data/lib/syncwrap/components/commercial_jdk.rb +76 -0
- data/lib/syncwrap/components/cruby_vm.rb +144 -0
- data/lib/syncwrap/components/etc_hosts.rb +44 -0
- data/lib/syncwrap/{geminabox.rb → components/geminabox.rb} +12 -17
- data/lib/syncwrap/components/hashdot.rb +97 -0
- data/lib/syncwrap/components/iyyov.rb +144 -0
- data/lib/syncwrap/components/iyyov_daemon.rb +125 -0
- data/lib/syncwrap/components/jruby_vm.rb +122 -0
- data/lib/syncwrap/components/mdraid.rb +204 -0
- data/lib/syncwrap/components/network.rb +99 -0
- data/lib/syncwrap/components/open_jdk.rb +70 -0
- data/lib/syncwrap/components/postgresql.rb +159 -0
- data/lib/syncwrap/components/qpid.rb +303 -0
- data/lib/syncwrap/components/rhel.rb +71 -0
- data/lib/syncwrap/components/run_user.rb +99 -0
- data/lib/syncwrap/components/ubuntu.rb +85 -0
- data/lib/syncwrap/components/users.rb +200 -0
- data/lib/syncwrap/context.rb +260 -0
- data/lib/syncwrap/distro.rb +53 -60
- data/lib/syncwrap/formatter.rb +149 -0
- data/lib/syncwrap/host.rb +134 -0
- data/lib/syncwrap/main.rb +62 -0
- data/lib/syncwrap/path_util.rb +55 -0
- data/lib/syncwrap/rsync.rb +227 -0
- data/lib/syncwrap/ruby_support.rb +110 -0
- data/lib/syncwrap/shell.rb +207 -0
- data/lib/syncwrap.rb +367 -1
- data/{etc → sync/etc}/gemrc +1 -3
- data/sync/etc/hosts.erb +8 -0
- data/{etc/init.d/iyyov → sync/etc/init.d/iyyov.erb} +35 -7
- data/sync/etc/sysconfig/pgsql/postgresql.erb +2 -0
- data/sync/src/hashdot/Makefile.erb +98 -0
- data/sync/src/hashdot/profiles/default.hdp.erb +25 -0
- data/sync/src/hashdot/profiles/jruby-common.hdp +28 -0
- data/sync/src/hashdot/profiles/jruby-shortlived.hdp +9 -0
- data/sync/src/hashdot/profiles/jruby.hdp.erb +13 -0
- data/sync/src/hashdot/profiles/shortlived.hdp +6 -0
- data/sync/var/iyyov/default/config.rb +1 -0
- data/sync/var/iyyov/default/daemon.rb.erb +15 -0
- data/sync/var/iyyov/jobs.rb.erb +4 -0
- data/test/muddled_sync.rb +13 -0
- data/test/setup.rb +39 -0
- data/test/sync/d1/bar +1 -0
- data/test/sync/d1/foo.erb +1 -0
- data/test/sync/d3/d2/bar +1 -0
- data/test/sync/d3/d2/foo.erb +1 -0
- data/test/test_components.rb +108 -0
- data/test/test_context.rb +107 -0
- data/test/test_context_rput.rb +289 -0
- data/test/test_rsync.rb +138 -0
- data/test/test_shell.rb +233 -0
- data/test/test_space.rb +218 -0
- data/test/test_space_main.rb +40 -0
- data/test/zfile +1 -0
- metadata +204 -71
- data/etc/sysconfig/pgsql/postgresql +0 -2
- data/lib/syncwrap/aws.rb +0 -448
- data/lib/syncwrap/common.rb +0 -161
- data/lib/syncwrap/ec2.rb +0 -59
- data/lib/syncwrap/hashdot.rb +0 -70
- data/lib/syncwrap/iyyov.rb +0 -139
- data/lib/syncwrap/java.rb +0 -61
- data/lib/syncwrap/jruby.rb +0 -118
- data/lib/syncwrap/postgresql.rb +0 -135
- data/lib/syncwrap/qpid.rb +0 -251
- data/lib/syncwrap/remote_task.rb +0 -199
- data/lib/syncwrap/rhel.rb +0 -67
- data/lib/syncwrap/ubuntu.rb +0 -78
- data/lib/syncwrap/user_run.rb +0 -102
- data/test/test_syncwrap.rb +0 -202
- data/var/iyyov/jobs.rb +0 -11
- /data/{etc → sync/etc}/corosync/corosync.conf +0 -0
- /data/{etc → sync/etc}/corosync/uidgid.d/qpid +0 -0
- /data/{etc → sync/etc}/init.d/qpidd +0 -0
- /data/{etc → sync/etc}/sysctl.d/61-postgresql-shm.conf +0 -0
- /data/{usr/local → sync/jruby}/bin/jgem +0 -0
- /data/{postgresql → sync/postgresql}/rhel/pg_hba.conf +0 -0
- /data/{postgresql → sync/postgresql}/rhel/pg_ident.conf +0 -0
- /data/{postgresql → sync/postgresql}/rhel/postgresql.conf +0 -0
- /data/{postgresql → sync/postgresql}/ubuntu/environment +0 -0
- /data/{postgresql → sync/postgresql}/ubuntu/pg_ctl.conf +0 -0
- /data/{postgresql → sync/postgresql}/ubuntu/pg_hba.conf +0 -0
- /data/{postgresql → sync/postgresql}/ubuntu/pg_ident.conf +0 -0
- /data/{postgresql → sync/postgresql}/ubuntu/postgresql.conf +0 -0
- /data/{postgresql → sync/postgresql}/ubuntu/start.conf +0 -0
- /data/{usr → sync/usr}/local/etc/qpidd.conf +0 -0
@@ -0,0 +1,443 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright (c) 2011-2014 David Kellum
|
3
|
+
#
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License"); you
|
5
|
+
# may not use this file except in compliance with the License. You
|
6
|
+
# may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
13
|
+
# implied. See the License for the specific language governing
|
14
|
+
# permissions and limitations under the License.
|
15
|
+
#++
|
16
|
+
|
17
|
+
require 'syncwrap/context'
|
18
|
+
|
19
|
+
module SyncWrap
|
20
|
+
|
21
|
+
# Base class and primary interface for component implementation.
|
22
|
+
#
|
23
|
+
# Much of the protected interface is ultimately delegated to a
|
24
|
+
# _current_ Context (arranged via Context#with). Without this, many
|
25
|
+
# of these methods will raise a ContextError.
|
26
|
+
#
|
27
|
+
# Components that require installation should implement a public
|
28
|
+
# no-argument `install` method which performs the installation via
|
29
|
+
# #rput, #sh et al. Complex installations can be broken into
|
30
|
+
# multiple methods called from install. If these are public and
|
31
|
+
# no-argument, they may also be called from the CLI or other
|
32
|
+
# external integrating code for testing or short-circuit
|
33
|
+
# operation. In general however, install should be fast enough to
|
34
|
+
# repeat in complete form. All such methods should be idempotent.
|
35
|
+
#
|
36
|
+
# Components may expose other public no-argument methods for
|
37
|
+
# external use which are not called via install. For example,
|
38
|
+
# diagnostic methods or uninstall.
|
39
|
+
#
|
40
|
+
# Components may also expose public utility methods (with or without
|
41
|
+
# arguments) that will be dynamically bound and may be used by
|
42
|
+
# higher (later) component instances stacked on the same Host.
|
43
|
+
class Component
|
44
|
+
|
45
|
+
# Construct given options that are applied via same name setters
|
46
|
+
# on self.
|
47
|
+
def initialize( opts = {} )
|
48
|
+
super()
|
49
|
+
opts.each do |name,val|
|
50
|
+
send( name.to_s + '=', val )
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
protected
|
55
|
+
|
56
|
+
# Return the Host of the current Context.
|
57
|
+
def host
|
58
|
+
ctx.host
|
59
|
+
end
|
60
|
+
|
61
|
+
# Enqueue a bash shell command or script fragment to be run on the
|
62
|
+
# host of the current Context. Newlines in command are interpreted
|
63
|
+
# as per bash. For example, it is common to use a here-document
|
64
|
+
# for readability:
|
65
|
+
#
|
66
|
+
# sh <<-SH
|
67
|
+
# if [ ! -e /var/#{fname} ]; then
|
68
|
+
# touch /var/#{fname}
|
69
|
+
# fi
|
70
|
+
# SH
|
71
|
+
# #=> nil
|
72
|
+
#
|
73
|
+
# If the current context host name is 'localhost' then the command
|
74
|
+
# is executed locally, without ssh and any ssh options will not be
|
75
|
+
# used.
|
76
|
+
#
|
77
|
+
# Returns nil.
|
78
|
+
#
|
79
|
+
# See also #flush, in particular for possible collateral
|
80
|
+
# Exceptions.
|
81
|
+
#
|
82
|
+
# === Command Queue and Composition
|
83
|
+
#
|
84
|
+
# The provided options are enqueued along with the
|
85
|
+
# command/fragment for deferred execution. If a subsequent call
|
86
|
+
# uses the same options, then it is effectively joined using a
|
87
|
+
# newline with the prior commands in the queue. If a subsequent
|
88
|
+
# call changes options, than any current commands in the queue are
|
89
|
+
# executed (via #flush) before the current command is enqueued
|
90
|
+
# with the new options. It is possible for commands to be enqueued
|
91
|
+
# and joined across multiple Components within the same Context.
|
92
|
+
#
|
93
|
+
# For example the following will be executed as a single composed
|
94
|
+
# script fragment:
|
95
|
+
#
|
96
|
+
# sh "if [! -e /var/foobar]; then"
|
97
|
+
# sh " touch /var/foobar"
|
98
|
+
# sh "fi" #=> nil
|
99
|
+
#
|
100
|
+
# However the following will result in remote errors:
|
101
|
+
#
|
102
|
+
# sh "if [! -e /var/foobar]; then"
|
103
|
+
# sudo "touch /var/foobar" #=> CommandFailure
|
104
|
+
# sh "fi"
|
105
|
+
#
|
106
|
+
# ...since the initial fragment on the line 1 is incomplete,
|
107
|
+
# when it is flushed and executed, due to line 2 changing
|
108
|
+
# options (to user:root).
|
109
|
+
#
|
110
|
+
# When composing more elaborate conditionals or loops via local
|
111
|
+
# methods, it is better to use the block form of #sh with the
|
112
|
+
# :close option, like so:
|
113
|
+
#
|
114
|
+
# sh( "if [! -e /var/foobar]; then", close: "fi" ) do
|
115
|
+
# sudo "touch /var/foobar" #=> NestingError
|
116
|
+
# end
|
117
|
+
#
|
118
|
+
# While executing the block, #flush is _locked_. The above fails
|
119
|
+
# with a NestingError and accurate stack trace, without running
|
120
|
+
# any potentially dangerous, incomplete bash fragments on the
|
121
|
+
# remote side. Replace the call to sudo with sh above and the
|
122
|
+
# composed single fragment will execute without error. The block
|
123
|
+
# form may be nested to arbitrary depth.
|
124
|
+
#
|
125
|
+
# === Options
|
126
|
+
#
|
127
|
+
# :user:: Execute command via sudo as the specified user, for
|
128
|
+
# example: :root or "root". See also :ssh_user
|
129
|
+
#
|
130
|
+
# :sudo_flags:: Additional Array of arguments to sudo, if used
|
131
|
+
# (see :user) Default: []
|
132
|
+
#
|
133
|
+
# :ssh_flags:: Array of flags in addition to, or overridden by
|
134
|
+
# :ssh_options (-o), :ssh_user (-l) and :ssh_user_pem
|
135
|
+
# (-i).
|
136
|
+
#
|
137
|
+
# :ssh_options:: Hash of ssh option key, value strings.
|
138
|
+
#
|
139
|
+
# :ssh_user:: The ssh -l (login_name) flag.
|
140
|
+
#
|
141
|
+
# :ssh_user_pem:: The ssh -i (identity_file) flag.
|
142
|
+
#
|
143
|
+
# :dryrun:: Don't actually execute commands, via `bash -n` dry
|
144
|
+
# run mode. (default: false)
|
145
|
+
#
|
146
|
+
# :verbose:: Show STDOUT/STDERR from commands (default: false)
|
147
|
+
#
|
148
|
+
# :sh_verbose:: Option values :v (or true) and :x are passed as
|
149
|
+
# `bash -v` and `bash -x` respectively, in order to
|
150
|
+
# echo command lines, interleaved with any command
|
151
|
+
# output. In the :x case, command output will be
|
152
|
+
# post expanded. This option should generally be set
|
153
|
+
# even if :verbose if false, since it will still be
|
154
|
+
# useful to error output on a CommandFailure.
|
155
|
+
# Default: nil (but :v via Space.default_options)
|
156
|
+
#
|
157
|
+
# :coalesce:: Coalesce (or merge) STDOUT to STDERR either via ssh
|
158
|
+
# or bash, to avoid out-of-order verbose output (due
|
159
|
+
# to buffering/timing). STDERR is used to increase
|
160
|
+
# incremental output through ssh, which tends to
|
161
|
+
# buffer STDOUT.
|
162
|
+
# Default: false (but true via Space.default_options)
|
163
|
+
#
|
164
|
+
# :error:: Pass bash the -e option to terminate early on errors.
|
165
|
+
# Default: true
|
166
|
+
#
|
167
|
+
# :close:: An additional bash fragment to append after the
|
168
|
+
# provided shell command/fragment and block has been
|
169
|
+
# enqueued. See usage example above. Default: nil
|
170
|
+
#
|
171
|
+
# :accept:: An array of Integer exit codes that will be accepted,
|
172
|
+
# and not result in a CommandFailure being
|
173
|
+
# raised. Generally this is only used with
|
174
|
+
# #capture. Default: [0]
|
175
|
+
#
|
176
|
+
def sh( command, opts = {}, &block )
|
177
|
+
ctx.sh( command, opts, &block )
|
178
|
+
end
|
179
|
+
|
180
|
+
# Equivalent to `sh( command, user: :root )`
|
181
|
+
def sudo( command, opts = {}, &block )
|
182
|
+
sh( command, { user: :root }.merge( opts ), &block )
|
183
|
+
end
|
184
|
+
|
185
|
+
# Equivalent to `sh( command, user: run_user )` where run_user
|
186
|
+
# would typically come from the RunUser component.
|
187
|
+
def rudo( command, opts = {}, &block )
|
188
|
+
sh( command, { user: run_user }.merge( opts ), &block )
|
189
|
+
end
|
190
|
+
|
191
|
+
# Capture and return [exit_code, stdout] from command, where
|
192
|
+
# stdout is the entire stream read into a String. Any commands
|
193
|
+
# already queued via #sh are executed via #flush beforehand, to
|
194
|
+
# avoid ambiguous order of remote changes. Raises a CommandFailure
|
195
|
+
# if the resulting exit_code is outside the specified :accept
|
196
|
+
# option codes (by default, [0] only).
|
197
|
+
#
|
198
|
+
# Specify :coalesce if you want stderr merged with stdout in the
|
199
|
+
# return. See #sh for additional options. The options :coalesce,
|
200
|
+
# and :dryrun are not inherited from the Space/Context default
|
201
|
+
# options and must be explicitly passed.
|
202
|
+
#
|
203
|
+
# For the better performance achieved with larger script fragments
|
204
|
+
# and fewer ssh sessions, you should attempt to use #sh remote
|
205
|
+
# conditionals instead of testing with #capture on the local
|
206
|
+
# side. But sometimes this can't be easily avoided.
|
207
|
+
def capture( command, opts = {} )
|
208
|
+
ctx.capture( command, opts )
|
209
|
+
end
|
210
|
+
|
211
|
+
# Return true if the current Context is executing in dryrun mode,
|
212
|
+
# as per the :dryrun default option or via the command line
|
213
|
+
# --dryrun flag. This allows additional explicit testing and
|
214
|
+
# handling of this mode when necessary.
|
215
|
+
def dryrun?
|
216
|
+
ctx.dryrun?
|
217
|
+
end
|
218
|
+
|
219
|
+
# Return true if :verbose is set in default options.
|
220
|
+
def verbose?
|
221
|
+
ctx.verbose?
|
222
|
+
end
|
223
|
+
|
224
|
+
# Return the path to the the specified src, as first found in the
|
225
|
+
# :sync_paths option as per #rput, Source Resolution. Return nil
|
226
|
+
# if not found. This allows optional, local behavior based on the
|
227
|
+
# existance of optional sources.
|
228
|
+
def find_source( src, opts = {} )
|
229
|
+
ctx.find_source( src, opts )
|
230
|
+
end
|
231
|
+
|
232
|
+
# Execute and empty the queue of any previous commands added with
|
233
|
+
# #sh or its variants.
|
234
|
+
#
|
235
|
+
# A CommandFailure is raised if commands return an exit_code that
|
236
|
+
# is not accepted via the :accept option (by default,
|
237
|
+
# non-zero). See #sh options :accept and :error.
|
238
|
+
#
|
239
|
+
# A NestingError is raised if called from within a #sh block.
|
240
|
+
#
|
241
|
+
# Returns nil.
|
242
|
+
def flush
|
243
|
+
ctx.flush
|
244
|
+
end
|
245
|
+
|
246
|
+
# Transfer files or entire directories to host, each resolved to a
|
247
|
+
# source root directory, while transparently processing any ERB
|
248
|
+
# (.erb) templates.
|
249
|
+
#
|
250
|
+
# === Arguments
|
251
|
+
#
|
252
|
+
# rput( src..., dest, {options} )
|
253
|
+
# rput( src, {options} )
|
254
|
+
#
|
255
|
+
# A trailing hash is interpreted as options, see below.
|
256
|
+
#
|
257
|
+
# If there are two or more remaining arguments, the last is
|
258
|
+
# interpreted as the remote destination, and should be an absolute
|
259
|
+
# path. If there is a single src argument, the destination is
|
260
|
+
# implied by finding its base directory and prepending '/'. Thus
|
261
|
+
# for example:
|
262
|
+
#
|
263
|
+
# rput( 'etc/gemrc', user: :root )
|
264
|
+
#
|
265
|
+
# has an implied destination of: "/etc/". The src and destination
|
266
|
+
# directories are interpreted as by `rsync`: glob patterns are
|
267
|
+
# expanded and trailing '/' is significant.
|
268
|
+
#
|
269
|
+
# Each src is searched in :sync_paths. See Source Resolution
|
270
|
+
# below.
|
271
|
+
#
|
272
|
+
# === Execution
|
273
|
+
#
|
274
|
+
# Before execution, any commands queued via #sh are flushed to
|
275
|
+
# avoid ambiguous order of remote changes.
|
276
|
+
#
|
277
|
+
# If the current context host name is 'localhost' then perform a
|
278
|
+
# local-only transfer. This is not via ssh, so ssh options are not
|
279
|
+
# applicable. The :user option will still be applied as by local
|
280
|
+
# `sudo`.
|
281
|
+
#
|
282
|
+
# On success, returns an array of format [ [change_code,
|
283
|
+
# file_name] ] for files changed, as parsed from the rsync
|
284
|
+
# --itemize-changes.
|
285
|
+
#
|
286
|
+
# Raises SourceNotFound is any src argument is not found (per
|
287
|
+
# below). On rsync failure, raises a CommandFailure.
|
288
|
+
#
|
289
|
+
# === Source Resolution
|
290
|
+
#
|
291
|
+
# For each src path in arguments, interpret each as a relative path
|
292
|
+
# from any of the provided :sync_paths (see in Options below),
|
293
|
+
# searched in order. The first matching source found will be
|
294
|
+
# used. If no source is found (or if sync_paths is not provided
|
295
|
+
# or empty) then raise a SourceNotFound exception. Note that a src
|
296
|
+
# trailing '/' is significant both to rsync itself and that only
|
297
|
+
# source directories will be matched.
|
298
|
+
#
|
299
|
+
# If a src path does not have a trailing '/' or '.erb' suffix
|
300
|
+
# already, if the non-suffixed file is not found within a given
|
301
|
+
# sync_path; then '.erb' is appended and tested as well. Thus if a
|
302
|
+
# src "foo.erb" is given, the template must exist. If instead
|
303
|
+
# 'foo' is given, then 'foo.erb' will be processed, if and only
|
304
|
+
# if, 'foo' does not already exist in a given sync_path. See ERB
|
305
|
+
# processing below.
|
306
|
+
#
|
307
|
+
# === ERB processing
|
308
|
+
#
|
309
|
+
# By default, any source files with an '.erb' suffix will be
|
310
|
+
# interpreted as ERB templates, processed locally, and transferred
|
311
|
+
# to the destination "in place" but without the '.erb'
|
312
|
+
# suffix. This applies both to individually referenced source files
|
313
|
+
# (with or without '.erb' suffix, see above) and '.erb' suffixed
|
314
|
+
# files nested at any level within a source directory.
|
315
|
+
#
|
316
|
+
# ERB templates are passed a custom binding which gives access to
|
317
|
+
# this component's instance methods, including dynamic binding to
|
318
|
+
# same host, prior component instance methods. Additional
|
319
|
+
# variables may be passed via the :erb_vars option.
|
320
|
+
#
|
321
|
+
# See various options controlling ERB processing below.
|
322
|
+
#
|
323
|
+
# === Options
|
324
|
+
#
|
325
|
+
# :user:: Files should be owned on destination by a user other
|
326
|
+
# than installer (ex: 'root'). See also :ssh_user
|
327
|
+
#
|
328
|
+
# :ssh_flags:: Array of flags to ssh via rsync -e, in addition to
|
329
|
+
# or overridden by :ssh_options (-o), :ssh_user (-l)
|
330
|
+
# and :ssh_user_pem (-i).
|
331
|
+
#
|
332
|
+
# :ssh_options:: Hash of ssh option key, value strings.
|
333
|
+
#
|
334
|
+
# :ssh_user:: The ssh -l (login_name) flag.
|
335
|
+
#
|
336
|
+
# :ssh_user_pem:: The ssh -i (identity_file) flag.
|
337
|
+
#
|
338
|
+
# :dryrun:: Don't actually make any changes, but report files
|
339
|
+
# that would be changed. (default: false)
|
340
|
+
#
|
341
|
+
# :recursive:: Recurse into sub-directories (default: true)
|
342
|
+
#
|
343
|
+
# :links:: Recreate symlinks on the destination (default: true)
|
344
|
+
#
|
345
|
+
# :checksum:: Use MD5 to determine changes; not just size,time
|
346
|
+
# (default: true) This is more costly but gives a
|
347
|
+
# more accurate representation of real file changes.
|
348
|
+
#
|
349
|
+
# :backup:: Make backup files on remote (default: true)
|
350
|
+
#
|
351
|
+
# :excludes:: One or more rsync compatible `--exclude` values, or
|
352
|
+
# :dev which excludes common development tree
|
353
|
+
# droppings like '*~'. Note that if you exclude
|
354
|
+
# "*.erb" then you probably also want to pass
|
355
|
+
# `erb_process: false`
|
356
|
+
#
|
357
|
+
# :perms:: Permission handling. The default (:E) is as per the
|
358
|
+
# rsync `--executability` flag: Only local exec (or
|
359
|
+
# non-exec) state will be transferred to remote files
|
360
|
+
# (including those pre-existing). This is most
|
361
|
+
# compatible with the limited permission tracking of
|
362
|
+
# a (D)VCS like git. Follow with your own remote chmod
|
363
|
+
# commands for finer control.
|
364
|
+
#
|
365
|
+
# If set to :p, use `rsync --perms` instead (which
|
366
|
+
# transfers all permission bits.)
|
367
|
+
#
|
368
|
+
# If set to a String "VALUE", instead use
|
369
|
+
# `rsync --perms --chmod=VALUE`
|
370
|
+
#
|
371
|
+
# :sync_paths:: Array of one or more local directories in which to
|
372
|
+
# find source files.
|
373
|
+
# Effectively required.
|
374
|
+
#
|
375
|
+
# :verbose:: Output stdout/stderr from rsync (default: false)
|
376
|
+
#
|
377
|
+
# :erb_process:: If false, treat '.erb' suffixed files as normal
|
378
|
+
# files (default: true)
|
379
|
+
#
|
380
|
+
# :erb_mode:: The trim_mode options as documented in ERB::new
|
381
|
+
# (default: '<>' trim NEWLINE on /^<%...%>$/ lines)
|
382
|
+
#
|
383
|
+
# :erb_vars:: Hash of additional variable names/values to pass to
|
384
|
+
# ERBs. These names will override the default
|
385
|
+
# component binding.
|
386
|
+
#
|
387
|
+
# Note finally that the :coalesce option is explicitly ignored,
|
388
|
+
# since separating rsync STDOUT/STDERR is required for parsing
|
389
|
+
# changes correctly.
|
390
|
+
def rput( *args )
|
391
|
+
opts = args.last.is_a?( Hash ) && args.pop || {}
|
392
|
+
opts = opts.dup
|
393
|
+
opts[ :erb_binding ] = custom_binding( opts[ :erb_vars ] || {} )
|
394
|
+
ctx.rput( *args, opts )
|
395
|
+
end
|
396
|
+
|
397
|
+
# Attempt to dynamically bind and delegate missing methods to
|
398
|
+
# Components that were added before self to the same Host.
|
399
|
+
def method_missing( meth, *args, &block )
|
400
|
+
pc = prior_component
|
401
|
+
if pc && pc.respond_to?( meth )
|
402
|
+
pc.send( meth, *args, &block )
|
403
|
+
else
|
404
|
+
super
|
405
|
+
end
|
406
|
+
end
|
407
|
+
|
408
|
+
# Include the same dynamically bound, earlier component methods
|
409
|
+
# via hook to respond_to?
|
410
|
+
def respond_to_missing?( meth, include_private = false )
|
411
|
+
super || ( ( pc = prior_component ) && pc.respond_to?( meth ) )
|
412
|
+
end
|
413
|
+
|
414
|
+
private
|
415
|
+
|
416
|
+
def ctx
|
417
|
+
Context.current or raise "ctx called out of SyncWrap::Context"
|
418
|
+
end
|
419
|
+
|
420
|
+
# Return the prior (added before) component instance on the same
|
421
|
+
# host, or nil if either not in context, or no such component.
|
422
|
+
def prior_component
|
423
|
+
( lc = Context.current ) && lc.host.prior_component( self )
|
424
|
+
end
|
425
|
+
|
426
|
+
def custom_binding( extra_vars = {} )
|
427
|
+
extra_vars.inject( clean_binding ) do |b,(k,v)|
|
428
|
+
# Can't yet rely on ruby 2.1 Binding#local_variable_set, so
|
429
|
+
# use this eval trick instead, to be able to set arbitrary value
|
430
|
+
# types.
|
431
|
+
ks = k.to_sym.to_s #for safety
|
432
|
+
b.eval("#{ks}=nil; lambda { |v| #{ks}=v }").call(v)
|
433
|
+
b
|
434
|
+
end
|
435
|
+
end
|
436
|
+
|
437
|
+
def clean_binding
|
438
|
+
Kernel.binding
|
439
|
+
end
|
440
|
+
|
441
|
+
end
|
442
|
+
|
443
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright (c) 2011-2014 David Kellum
|
3
|
+
#
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License"); you
|
5
|
+
# may not use this file except in compliance with the License. You may
|
6
|
+
# obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
13
|
+
# implied. See the License for the specific language governing
|
14
|
+
# permissions and limitations under the License.
|
15
|
+
#++
|
16
|
+
|
17
|
+
require 'syncwrap/component'
|
18
|
+
|
19
|
+
module SyncWrap
|
20
|
+
|
21
|
+
# Provision a Commmercial (i.e. Oracle) JDK or "Server JRE" (jrs_)
|
22
|
+
# via an HTTP accessable binary repository of your making.
|
23
|
+
# Commercial usage terms generally preclude sharing a public binary
|
24
|
+
# repository for these. Given the size, check-in or pushing from a
|
25
|
+
# development workstation is likely also a bad idea, though not
|
26
|
+
# difficult to implement.
|
27
|
+
#
|
28
|
+
# Oracle and Java are registered trademarks of Oracle and/or its
|
29
|
+
# affiliates.
|
30
|
+
#
|
31
|
+
# Host component dependencies: <Distro>
|
32
|
+
class CommercialJDK < Component
|
33
|
+
|
34
|
+
# HTTP URL to repo base directory. Note that the default
|
35
|
+
# (http://localhost/repo) is unlikely to work here.
|
36
|
+
attr_accessor :java_repo_base_url
|
37
|
+
|
38
|
+
# The name of the JDK, which is used for download via
|
39
|
+
# java_repo_base_url/<name>.tar.gz and the expected top level
|
40
|
+
# directory when unpackaged.
|
41
|
+
attr_accessor :jdk_name
|
42
|
+
|
43
|
+
def initialize( opts = {} )
|
44
|
+
@java_repo_base_url = 'http://localhost/repo'
|
45
|
+
@jdk_name = 'jrs-ora-1.7.0_51-x64'
|
46
|
+
|
47
|
+
super
|
48
|
+
end
|
49
|
+
|
50
|
+
# Complete URL to the jdk tarball within the java/binary repo
|
51
|
+
def jdk_url
|
52
|
+
File.join( @java_repo_base_url, @jdk_name + '.tar.gz' )
|
53
|
+
end
|
54
|
+
|
55
|
+
# Local jdk directory, within local_root, to be installed
|
56
|
+
def jdk_dir
|
57
|
+
"#{local_root}/lib/#{jdk_name}"
|
58
|
+
end
|
59
|
+
|
60
|
+
def install
|
61
|
+
bins = %w[ java jmap jstack jstat jps jinfo jhat javac ].
|
62
|
+
map { |b| "../lib/java/bin/#{b}" }.
|
63
|
+
join( ' ' )
|
64
|
+
|
65
|
+
sudo <<-SH
|
66
|
+
if [ ! -d #{jdk_dir} ]; then
|
67
|
+
curl -sSL #{jdk_url} | tar -C #{local_root}/lib -zxf -
|
68
|
+
cd #{local_root}/lib && ln -sfn #{jdk_name} java
|
69
|
+
cd #{local_root}/bin && ln -sfn #{bins} .
|
70
|
+
fi
|
71
|
+
SH
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
@@ -0,0 +1,144 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright (c) 2011-2014 David Kellum
|
3
|
+
#
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License"); you
|
5
|
+
# may not use this file except in compliance with the License. You may
|
6
|
+
# obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
13
|
+
# implied. See the License for the specific language governing
|
14
|
+
# permissions and limitations under the License.
|
15
|
+
#++
|
16
|
+
|
17
|
+
require 'syncwrap/component'
|
18
|
+
require 'syncwrap/components/rhel'
|
19
|
+
require 'syncwrap/ruby_support'
|
20
|
+
|
21
|
+
module SyncWrap
|
22
|
+
|
23
|
+
# Provision 'C' Ruby (ruby-lang.org - Matz Ruby Interpreter, MRI)
|
24
|
+
# from source code, compiled on the target host. This is currently
|
25
|
+
# the most reliable way for staying up-to-date on stable Ruby
|
26
|
+
# releases across the bulk of Linux server distros (which have
|
27
|
+
# conservative update policies).
|
28
|
+
#
|
29
|
+
# A reasonable alternative is to use distro provided packages. Since
|
30
|
+
# this varies so much based on distro particulars, but it is
|
31
|
+
# otherwise relatively easy to achieve (setup alt repos,
|
32
|
+
# dist_install, set alternatives) you are currently left to do this
|
33
|
+
# in your own component. Include RubySupport in that component for
|
34
|
+
# some common utility methods.
|
35
|
+
#
|
36
|
+
# Alternatives like RVM, rbenv, etc. are disfavored by this author
|
37
|
+
# for server provisioning because of their often arcane shell and
|
38
|
+
# environment modifications and obscure interations with non-/login
|
39
|
+
# or non-/interactive sessions. These are fine tools if needed for
|
40
|
+
# development however. Again you are currently on your own (beyond
|
41
|
+
# RubySupport) if you wish to go this route.
|
42
|
+
class CRubyVM < Component
|
43
|
+
include RubySupport
|
44
|
+
|
45
|
+
# The ruby version to install, like it appears in source packages
|
46
|
+
# from ruby-lang.org.
|
47
|
+
# (Default: 2.0.0-p353)
|
48
|
+
attr_accessor :ruby_version
|
49
|
+
|
50
|
+
# If true, attempt to uninstall any pre-existing distro packaged
|
51
|
+
# ruby, which might otherwise lead to errors and confusion.
|
52
|
+
# (Default: true)
|
53
|
+
attr_accessor :do_uninstall_distro_ruby
|
54
|
+
|
55
|
+
def initialize( opts = {} )
|
56
|
+
@ruby_version = "2.0.0-p353"
|
57
|
+
@do_uninstall_distro_ruby = true
|
58
|
+
|
59
|
+
super
|
60
|
+
end
|
61
|
+
|
62
|
+
def install
|
63
|
+
install_ruby
|
64
|
+
install_gemrc # from RubySupport
|
65
|
+
end
|
66
|
+
|
67
|
+
def ruby_command
|
68
|
+
"#{local_root}/bin/ruby"
|
69
|
+
end
|
70
|
+
|
71
|
+
def compact_version
|
72
|
+
ruby_version.sub( '-', '' )
|
73
|
+
end
|
74
|
+
|
75
|
+
# If the current ruby_command is not at the desired ruby_version,
|
76
|
+
# download source, configure, make and install.
|
77
|
+
def install_ruby
|
78
|
+
cond = <<-SH
|
79
|
+
rvr=`[ -x #{ruby_command} ] &&
|
80
|
+
#{ruby_command} -v | grep -o -E '[0-9]+(\\.[0-9]+)+(p[0-9]+)?' \
|
81
|
+
|| true`
|
82
|
+
if [ "$rvr" != "#{compact_version}" ]; then
|
83
|
+
SH
|
84
|
+
sudo( cond, close: "fi" ) do
|
85
|
+
install_build_deps
|
86
|
+
make_and_install
|
87
|
+
|
88
|
+
# only after a successful source install:
|
89
|
+
uninstall_distro_ruby if do_uninstall_distro_ruby
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def uninstall_distro_ruby
|
94
|
+
if distro.is_a?( RHEL )
|
95
|
+
dist_uninstall( %w[ ruby ruby18 ruby19 ruby20 ] )
|
96
|
+
else
|
97
|
+
dist_uninstall( %w[ ruby ruby1.8 ruby1.9 ruby1.9.1 ruby1.9.3 ruby2.0 ] )
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
alias :cruby_gem_install :gem_install
|
102
|
+
|
103
|
+
protected
|
104
|
+
|
105
|
+
def install_build_deps
|
106
|
+
if distro.is_a?( RHEL )
|
107
|
+
dist_install( %w[ gcc make autoconf zlib-devel
|
108
|
+
openssl-devel readline-devel libyaml-devel ] )
|
109
|
+
else
|
110
|
+
dist_install( %w[ gcc make autoconf zlib1g-dev
|
111
|
+
libssl-dev libreadline-dev libyaml-dev ] )
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
def make_and_install
|
116
|
+
# Arguably all but the final install should be run by an
|
117
|
+
# unprivileged user. But its more likely merged this way, and if
|
118
|
+
# "configure" or "make" can be exploited, so can "make install".
|
119
|
+
sudo <<-SH
|
120
|
+
[ -e /tmp/src ] && rm -rf /tmp/src || true
|
121
|
+
mkdir -p /tmp/src/ruby
|
122
|
+
cd /tmp/src/ruby
|
123
|
+
curl -sSL #{src_url} | tar -zxf -
|
124
|
+
cd ruby-#{ruby_version}
|
125
|
+
./configure --prefix=#{local_root} #{redirect?}
|
126
|
+
make #{redirect?}
|
127
|
+
make install #{redirect?}
|
128
|
+
cd / && rm -rf /tmp/src
|
129
|
+
SH
|
130
|
+
end
|
131
|
+
|
132
|
+
def src_url
|
133
|
+
[ 'http://cache.ruby-lang.org/pub/ruby',
|
134
|
+
ruby_version =~ /^(\d+\.\d+)/ && $1,
|
135
|
+
"ruby-#{ruby_version}.tar.gz" ].join( '/' )
|
136
|
+
end
|
137
|
+
|
138
|
+
def redirect?
|
139
|
+
verbose? ? "" : ">/dev/null"
|
140
|
+
end
|
141
|
+
|
142
|
+
end
|
143
|
+
|
144
|
+
end
|