syncwrap 1.5.2 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (107) hide show
  1. checksums.yaml +7 -0
  2. data/History.rdoc +19 -0
  3. data/Manifest.txt +82 -34
  4. data/README.rdoc +96 -48
  5. data/Rakefile +0 -65
  6. data/bin/syncwrap +27 -0
  7. data/examples/LAYOUT.rdoc +70 -0
  8. data/examples/Rakefile +16 -0
  9. data/examples/ec2.rb +44 -0
  10. data/examples/hello.rb +14 -0
  11. data/examples/hello_binding.rb +27 -0
  12. data/examples/jruby.rb +11 -0
  13. data/examples/private/aws.json +4 -0
  14. data/examples/rput.rb +24 -0
  15. data/examples/sync/home/bob/.ssh/authorized_keys +1 -0
  16. data/examples/sync/tmp/sample.erb +3 -0
  17. data/lib/syncwrap/amazon_ec2.rb +236 -0
  18. data/lib/syncwrap/amazon_ws.rb +308 -0
  19. data/lib/syncwrap/base.rb +4 -2
  20. data/lib/syncwrap/cli.rb +328 -0
  21. data/lib/syncwrap/component.rb +443 -0
  22. data/lib/syncwrap/components/commercial_jdk.rb +76 -0
  23. data/lib/syncwrap/components/cruby_vm.rb +144 -0
  24. data/lib/syncwrap/components/etc_hosts.rb +44 -0
  25. data/lib/syncwrap/{geminabox.rb → components/geminabox.rb} +12 -17
  26. data/lib/syncwrap/components/hashdot.rb +97 -0
  27. data/lib/syncwrap/components/iyyov.rb +144 -0
  28. data/lib/syncwrap/components/iyyov_daemon.rb +125 -0
  29. data/lib/syncwrap/components/jruby_vm.rb +122 -0
  30. data/lib/syncwrap/components/mdraid.rb +204 -0
  31. data/lib/syncwrap/components/network.rb +99 -0
  32. data/lib/syncwrap/components/open_jdk.rb +70 -0
  33. data/lib/syncwrap/components/postgresql.rb +159 -0
  34. data/lib/syncwrap/components/qpid.rb +303 -0
  35. data/lib/syncwrap/components/rhel.rb +71 -0
  36. data/lib/syncwrap/components/run_user.rb +99 -0
  37. data/lib/syncwrap/components/ubuntu.rb +85 -0
  38. data/lib/syncwrap/components/users.rb +200 -0
  39. data/lib/syncwrap/context.rb +260 -0
  40. data/lib/syncwrap/distro.rb +53 -60
  41. data/lib/syncwrap/formatter.rb +149 -0
  42. data/lib/syncwrap/host.rb +134 -0
  43. data/lib/syncwrap/main.rb +62 -0
  44. data/lib/syncwrap/path_util.rb +55 -0
  45. data/lib/syncwrap/rsync.rb +227 -0
  46. data/lib/syncwrap/ruby_support.rb +110 -0
  47. data/lib/syncwrap/shell.rb +207 -0
  48. data/lib/syncwrap.rb +367 -1
  49. data/{etc → sync/etc}/gemrc +1 -3
  50. data/sync/etc/hosts.erb +8 -0
  51. data/{etc/init.d/iyyov → sync/etc/init.d/iyyov.erb} +35 -7
  52. data/sync/etc/sysconfig/pgsql/postgresql.erb +2 -0
  53. data/sync/src/hashdot/Makefile.erb +98 -0
  54. data/sync/src/hashdot/profiles/default.hdp.erb +25 -0
  55. data/sync/src/hashdot/profiles/jruby-common.hdp +28 -0
  56. data/sync/src/hashdot/profiles/jruby-shortlived.hdp +9 -0
  57. data/sync/src/hashdot/profiles/jruby.hdp.erb +13 -0
  58. data/sync/src/hashdot/profiles/shortlived.hdp +6 -0
  59. data/sync/var/iyyov/default/config.rb +1 -0
  60. data/sync/var/iyyov/default/daemon.rb.erb +15 -0
  61. data/sync/var/iyyov/jobs.rb.erb +4 -0
  62. data/test/muddled_sync.rb +13 -0
  63. data/test/setup.rb +39 -0
  64. data/test/sync/d1/bar +1 -0
  65. data/test/sync/d1/foo.erb +1 -0
  66. data/test/sync/d3/d2/bar +1 -0
  67. data/test/sync/d3/d2/foo.erb +1 -0
  68. data/test/test_components.rb +108 -0
  69. data/test/test_context.rb +107 -0
  70. data/test/test_context_rput.rb +289 -0
  71. data/test/test_rsync.rb +138 -0
  72. data/test/test_shell.rb +233 -0
  73. data/test/test_space.rb +218 -0
  74. data/test/test_space_main.rb +40 -0
  75. data/test/zfile +1 -0
  76. metadata +204 -71
  77. data/etc/sysconfig/pgsql/postgresql +0 -2
  78. data/lib/syncwrap/aws.rb +0 -448
  79. data/lib/syncwrap/common.rb +0 -161
  80. data/lib/syncwrap/ec2.rb +0 -59
  81. data/lib/syncwrap/hashdot.rb +0 -70
  82. data/lib/syncwrap/iyyov.rb +0 -139
  83. data/lib/syncwrap/java.rb +0 -61
  84. data/lib/syncwrap/jruby.rb +0 -118
  85. data/lib/syncwrap/postgresql.rb +0 -135
  86. data/lib/syncwrap/qpid.rb +0 -251
  87. data/lib/syncwrap/remote_task.rb +0 -199
  88. data/lib/syncwrap/rhel.rb +0 -67
  89. data/lib/syncwrap/ubuntu.rb +0 -78
  90. data/lib/syncwrap/user_run.rb +0 -102
  91. data/test/test_syncwrap.rb +0 -202
  92. data/var/iyyov/jobs.rb +0 -11
  93. /data/{etc → sync/etc}/corosync/corosync.conf +0 -0
  94. /data/{etc → sync/etc}/corosync/uidgid.d/qpid +0 -0
  95. /data/{etc → sync/etc}/init.d/qpidd +0 -0
  96. /data/{etc → sync/etc}/sysctl.d/61-postgresql-shm.conf +0 -0
  97. /data/{usr/local → sync/jruby}/bin/jgem +0 -0
  98. /data/{postgresql → sync/postgresql}/rhel/pg_hba.conf +0 -0
  99. /data/{postgresql → sync/postgresql}/rhel/pg_ident.conf +0 -0
  100. /data/{postgresql → sync/postgresql}/rhel/postgresql.conf +0 -0
  101. /data/{postgresql → sync/postgresql}/ubuntu/environment +0 -0
  102. /data/{postgresql → sync/postgresql}/ubuntu/pg_ctl.conf +0 -0
  103. /data/{postgresql → sync/postgresql}/ubuntu/pg_hba.conf +0 -0
  104. /data/{postgresql → sync/postgresql}/ubuntu/pg_ident.conf +0 -0
  105. /data/{postgresql → sync/postgresql}/ubuntu/postgresql.conf +0 -0
  106. /data/{postgresql → sync/postgresql}/ubuntu/start.conf +0 -0
  107. /data/{usr → sync/usr}/local/etc/qpidd.conf +0 -0
@@ -0,0 +1,200 @@
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/path_util'
19
+
20
+ module SyncWrap
21
+
22
+ # Provision developer user accounts, sudo access, and synchronize
23
+ # home directory files.
24
+ class Users < Component
25
+ include PathUtil
26
+
27
+ # The list of user names to install. If default nil, home_users
28
+ # will be determined by the set of home directories found in
29
+ # local_home_root - exclude_users.
30
+ attr_accessor :home_users
31
+
32
+ # Local home root directory, to be resolved against sync_paths.
33
+ # (Default: home)
34
+ attr_accessor :local_home_root
35
+
36
+ # Set of users to exclude from synchronization (default: [])
37
+ attr_accessor :exclude_users
38
+
39
+ # If set, override the :ssh_user for this Component install, since
40
+ # typically the 'normal' user (i.e your developer account) has not
41
+ # yet been created or given sudo access. (Default: nil)
42
+ attr_accessor :ssh_user
43
+
44
+ # A PEM file for the ssh_user. A relative path in interpreted as
45
+ # relative to the sync file from which this component is
46
+ # created. If the pem file is not found, a warning will be issued
47
+ # and ssh_user and ssh_user_pem will not be used.
48
+ # (Default: nil)
49
+ attr_accessor :ssh_user_pem
50
+
51
+ # Users should be the first component to attempt ssh access. On
52
+ # new host creation, install may be run before the ssh port is
53
+ # actually available (boot completed, etc.). This provides an
54
+ # additional timeout in seconds for establishing the first ssh
55
+ # session. (default: 180 seconds)
56
+ attr_accessor :ssh_access_timeout
57
+
58
+ # Use the StrictHostKeyChecking=no ssh option when connected to a
59
+ # newly created host (whose key will surely not be known yet.)
60
+ # (Default: true)
61
+ attr_accessor :lenient_host_key
62
+
63
+ def initialize( opts = {} )
64
+ @home_users = nil
65
+ @local_home_root = "home"
66
+ @exclude_users = []
67
+ @ssh_user = nil
68
+ @ssh_user_pem = nil
69
+ @ssh_access_timeout = 180.0
70
+ @lenient_host_key = true
71
+ super
72
+
73
+ if @ssh_user_pem
74
+ @ssh_user_pem =
75
+ relativize( path_relative_to_caller( @ssh_user_pem, caller ) )
76
+ unless File.exist?( @ssh_user_pem )
77
+ warn( "WARNING: Users pem #{@ssh_user_pem} not found. " +
78
+ "Will not use #{@ssh_user}.\n" +
79
+ "Components may fail without sudo access" )
80
+ @ssh_user = nil
81
+ @ssh_user_pem = nil
82
+ end
83
+ end
84
+ end
85
+
86
+ def install
87
+ ensure_ssh_access if host[ :just_created ] && ssh_access_timeout > 0
88
+
89
+ rdir = find_source( local_home_root )
90
+ users = home_users
91
+ users ||= rdir && Dir.entries( rdir ).select do |d|
92
+ ( d !~ /^\./ && File.directory?( File.join( rdir, d ) ) )
93
+ end
94
+ users ||= []
95
+ users -= exclude_users
96
+
97
+ users.each do |u|
98
+ create_user( u )
99
+ set_sudoers( u )
100
+ end
101
+
102
+ users.each do |u|
103
+ sync_home_files( u )
104
+ end
105
+
106
+ users.each do |u|
107
+ fix_home_permissions( u )
108
+ end
109
+
110
+ #FIXME: Add special case for 'root' user?
111
+ end
112
+
113
+ def ensure_ssh_access
114
+ flags = ssh_flags
115
+ if lenient_host_key
116
+ flags[ :ssh_options ] ||= {}
117
+ flags[ :ssh_options ][ 'StrictHostKeyChecking' ] = 'no'
118
+ end
119
+
120
+ start = Time.now
121
+ loop do
122
+ accept = [0]
123
+ # Allow non-sucess until timeout
124
+ # 255: ssh (i.e. can't connect, sshd not yet up)
125
+ # 1: sudo error (user_data sudoers update has not yet completed)
126
+ accept += [1, 255] unless ( Time.now - start ) >= ssh_access_timeout
127
+
128
+ code,_ = capture( 'sudo true', flags.merge( accept: accept ) )
129
+ break if code == 0
130
+ sleep 1 # ssh timeouts also apply, but make sure we don't spin
131
+ end
132
+ end
133
+
134
+ # Create user if not already present
135
+ def create_user( user )
136
+ sudo <<-SH
137
+ if ! id #{user} >/dev/null 2>&1; then
138
+ useradd #{user}
139
+ fi
140
+ SH
141
+ end
142
+
143
+ def sync_home_files( user )
144
+ rput( "#{local_home_root}/#{user}", user: user )
145
+ rescue SourceNotFound
146
+ false
147
+ end
148
+
149
+ def fix_home_permissions( user )
150
+ sudo <<-SH
151
+ if [ -e '/home/#{user}/.ssh' ]; then
152
+ chmod 700 /home/#{user}/.ssh
153
+ chmod -R o-rwx /home/#{user}/.ssh
154
+ fi
155
+ SH
156
+ end
157
+
158
+ def set_sudoers( user )
159
+ #FIXME: make this a template?
160
+ #FIXME: Use local_root for secure_path? (Order issue)
161
+ #Relax, less overrides needed for Ubuntu?
162
+ sudo <<-SH
163
+ echo '#{user} ALL=(ALL) NOPASSWD:ALL' > /etc/sudoers.d/#{user}
164
+ echo 'Defaults:#{user} !requiretty' >> /etc/sudoers.d/#{user}
165
+ echo 'Defaults:#{user} secure_path = /sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin' \
166
+ >> /etc/sudoers.d/#{user}
167
+ chmod 440 /etc/sudoers.d/#{user}
168
+ SH
169
+
170
+ #FIXME: Centos 6.5:
171
+ # secure_path is the same as above already
172
+ #FIXME: echo 'Defaults:#{user} always_set_home' >> /etc/sudoers.d/#{user}
173
+ end
174
+
175
+ protected
176
+
177
+ def sh( command, opts = {}, &block )
178
+ super( command, ssh_flags.merge( opts ), &block )
179
+ end
180
+
181
+ def rput( *args )
182
+ opts = args.last.is_a?( Hash ) ? ssh_flags.merge( args.pop ) : ssh_flags
183
+ super( *args, opts )
184
+ end
185
+
186
+ def ssh_flags
187
+ flags = {}
188
+ if ssh_user
189
+ flags[ :ssh_user ] = ssh_user
190
+ if ssh_user_pem
191
+ flags[ :ssh_user_pem ] = ssh_user_pem
192
+ flags[ :ssh_options ] = { 'IdentitiesOnly' => 'yes' }
193
+ end
194
+ end
195
+ flags
196
+ end
197
+
198
+ end
199
+
200
+ end
@@ -0,0 +1,260 @@
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/shell'
18
+ require 'syncwrap/rsync'
19
+
20
+ module SyncWrap
21
+
22
+ # A single-thread execution context for a single Host.
23
+ #
24
+ # Context implements much of the interface and behavior defined by
25
+ # Component, via use of the Shell and Rsync module mixins.
26
+ class Context
27
+ include Shell
28
+ include Rsync
29
+
30
+ class << self
31
+ # Return the current (thread local) Context, or nil.
32
+ def current
33
+ Thread.current[:syncwrap_context]
34
+ end
35
+
36
+ # Set the current Context to ctx and return any prior Context or
37
+ # nil.
38
+ def swap( ctx )
39
+ old = current
40
+ Thread.current[:syncwrap_context] = ctx
41
+ old
42
+ end
43
+ end
44
+
45
+ # The current Host of this context
46
+ attr_reader :host
47
+
48
+ # Construct given host and default_options to use for all #sh and
49
+ # #rput calls.
50
+ def initialize( host, opts = {} )
51
+ @host = host
52
+ reset_queue
53
+ @queue_locked = false
54
+ @default_options = opts
55
+
56
+ super()
57
+ end
58
+
59
+ # Set (thread local) current context to self, yield to block, then
60
+ # #flush and reset the context.
61
+ def with
62
+ prior = Context.swap( self )
63
+ yield
64
+ flush
65
+ ensure
66
+ Context.swap( prior )
67
+ end
68
+
69
+ # Return true if being executed, by constructed default options,
70
+ # in dryrun mode.
71
+ def dryrun?
72
+ @default_options[ :dryrun ]
73
+ end
74
+
75
+ # Return true if :verbose is set in constructed default options.
76
+ def verbose?
77
+ @default_options[ :verbose ]
78
+ end
79
+
80
+ # See Component#sh for interface details
81
+ def sh( command, opts = {} )
82
+ opts = @default_options.merge( opts )
83
+ close = opts.delete( :close )
84
+
85
+ flush if opts != @queued_opts #may still be a no-op
86
+
87
+ @queued_cmd << command
88
+ @queued_opts = opts
89
+
90
+ if close
91
+ prev, @queue_locked = @queue_locked, true
92
+ end
93
+
94
+ begin
95
+ yield if block_given?
96
+ @queued_cmd << close if close
97
+ ensure
98
+ @queue_locked = prev if close
99
+ end
100
+ nil
101
+ end
102
+
103
+ # See Component#flush for interface details
104
+ def flush
105
+ if @queued_cmd.length > 0
106
+ begin
107
+ if @queue_locked
108
+ raise NestingError, 'Queue at flush: ' + @queued_cmd.join( '\n' )
109
+ end
110
+ run_shell( @queued_cmd, @queued_opts )
111
+ ensure
112
+ reset_queue
113
+ end
114
+ end
115
+ nil
116
+ end
117
+
118
+ # See Component#capture for interface details.
119
+ def capture( command, opts = {} )
120
+ opts = @default_options.merge( coalesce: false, dryrun: false ).merge( opts )
121
+ flush
122
+ capture_shell( command, opts )
123
+ end
124
+
125
+ # See Component#rput for interface details.
126
+ def rput( *args )
127
+ opts = @default_options
128
+ opts = opts.merge( args.pop ) if args.last.is_a?( Hash )
129
+ opts = opts.merge( coalesce: false )
130
+
131
+ flush
132
+
133
+ srcs, target = expand_implied_target( args )
134
+
135
+ srcs = resolve_sources( srcs, Array( opts[ :sync_paths ] ) )
136
+
137
+ changes = []
138
+
139
+ if opts[:erb_process] != false
140
+ sdirs, sfiles = srcs.partition { |src| File.directory?( src ) }
141
+ serbs, sfiles = sfiles.partition { |src| src =~ /\.erb$/ }
142
+ plains = sdirs + sfiles #might not have/is not templates
143
+ maybes = sdirs + serbs #might have/is templates
144
+
145
+ if maybes.empty?
146
+ changes = rsync( plains, target, opts ) unless plains.empty?
147
+ else
148
+ process_templates( maybes, opts ) do |processed|
149
+ unless processed.empty? || plains.empty?
150
+ opts = opts.dup
151
+ opts[ :excludes ] = Array( opts[ :excludes ] ) + [ '*.erb' ]
152
+ end
153
+ new_srcs = plains + processed
154
+ changes = rsync( new_srcs, target, opts ) unless new_srcs.empty?
155
+ end
156
+ end
157
+ else
158
+ changes = rsync( srcs, target, opts ) unless srcs.empty?
159
+ end
160
+
161
+ changes
162
+ end
163
+
164
+ # Returns the path to the the specified src, first found in
165
+ # :sync_paths option. Returns nil if not found.
166
+ def find_source( src, opts = {} )
167
+ opts = @default_options.merge( opts )
168
+ resolve_source( src, Array( opts[ :sync_paths ] ) )
169
+ end
170
+
171
+ private
172
+
173
+ def ssh_host_name
174
+ host.space.ssh_host_name( host )
175
+ end
176
+
177
+ def reset_queue
178
+ @queued_cmd = []
179
+ @queued_opts = {}
180
+ end
181
+
182
+ def run_shell( command, opts = {} )
183
+ args = ssh_args( ssh_host_name, command, opts )
184
+ capture_stream( args, host, :sh, opts )
185
+ end
186
+
187
+ def capture_shell( command, opts = {} )
188
+ args = ssh_args( ssh_host_name, command, opts )
189
+ exit_code, outputs = capture_stream( args, host, :capture, opts )
190
+ [ exit_code, collect_stream( opts[ :coalesce ] ? :err : :out, outputs ) ]
191
+ end
192
+
193
+ def rsync( srcs, target, opts )
194
+ args = rsync_args( ssh_host_name, srcs, target, opts )
195
+ exit_code, outputs = capture_stream( args, host, :rsync, opts )
196
+
197
+ # Return array of --itemize-changes on standard out.
198
+ collect_stream( :out, outputs ).
199
+ split( "\n" ).
200
+ map { |l| l =~ /^(\S{11})\s(.+)$/ && [$1, $2] }. #itemize-changes
201
+ compact
202
+ end
203
+
204
+ def capture_stream( args, host, mode, opts )
205
+ accept = opts[ :accept ] || [ 0 ]
206
+ success_msg = ( accept == [ 0 ] ) ? "success" : "accepted"
207
+
208
+ # When :verbose -> nil -> try_lock
209
+ stream_output = opts[ :verbose ] ? nil : false
210
+ fmt = host.space.formatter
211
+ do_color = !opts[ :coalesce ]
212
+
213
+ begin
214
+ exit_code, outputs = capture3( args ) do |stream, chunk|
215
+ if stream_output.nil?
216
+ if fmt.lock.try_lock
217
+ stream_output = true
218
+ fmt.write_header( host, mode, opts, :stream )
219
+ if mode == :rsync
220
+ cmd = args.join(' ') + "\n"
221
+ fmt.write_command_output( :cmd, cmd, do_color )
222
+ end
223
+ else
224
+ stream_output = false
225
+ end
226
+ end
227
+
228
+ if stream_output
229
+ fmt.write_command_output( stream, chunk, do_color )
230
+ fmt.flush
231
+ end
232
+ end
233
+ failed = !accept.include?( exit_code )
234
+
235
+ if stream_output
236
+ fmt.output_terminate
237
+ fmt.write_result( "Exit #{exit_code} (#{success_msg})" ) unless failed
238
+ end
239
+ ensure
240
+ fmt.lock.unlock if stream_output
241
+ end
242
+
243
+ if !stream_output && ( failed || opts[ :verbose ] )
244
+ fmt.sync do
245
+ fmt.write_header( host, mode, opts )
246
+ if mode == :rsync
247
+ fmt.write_command_output( :cmd, args.join(' ') + "\n", do_color )
248
+ end
249
+ fmt.write_command_outputs( outputs, do_color )
250
+ fmt.write_result( "Exit #{exit_code} (#{success_msg})" ) unless failed
251
+ end
252
+ end
253
+
254
+ raise CommandFailure, "#{args[0]} exit code: #{exit_code}" if failed
255
+ [ exit_code, outputs ]
256
+ end
257
+
258
+ end
259
+
260
+ end
@@ -1,5 +1,5 @@
1
1
  #--
2
- # Copyright (c) 2011-2013 David Kellum
2
+ # Copyright (c) 2011-2014 David Kellum
3
3
  #
4
4
  # Licensed under the Apache License, Version 2.0 (the "License"); you
5
5
  # may not use this file except in compliance with the License. You may
@@ -16,77 +16,70 @@
16
16
 
17
17
  require 'syncwrap/base'
18
18
 
19
- # Support for distro specializations.
20
- module SyncWrap::Distro
19
+ module SyncWrap
21
20
 
22
- # A Hash of internal/common package names to distro specific package
23
- # names. Here defined as empty.
24
- attr_reader :packages_map
21
+ # Support module and inteface for (Linux) distribution components.
22
+ module Distro
25
23
 
26
- def initialize
27
- super
24
+ # The root directory for local, non-distro managed installs
25
+ # (default: /usr/local)
26
+ attr_accessor :local_root
28
27
 
29
- @packages_map = {}
30
- end
28
+ # A Hash of internal/common package names to distro specific package
29
+ # names.
30
+ attr_reader :packages_map
31
31
 
32
- # Map internal/common names and return distro-specific names. If a
33
- # mapping does not exist, assume internal name is a common name.
34
- def dist_map_packages( *pkgs )
35
- pkgs.flatten.compact.map { |pkg| packages_map[ pkg ] || pkg }
36
- end
32
+ def initialize( *args )
33
+ @local_root = '/usr/local'
34
+ @packages_map = {}
37
35
 
38
- # Install the specified packages using distro-specific mapped
39
- # package names and command via dist_install_s. The last argument is
40
- # interpreted as options if it is a Hash.
41
- # === Options
42
- # :succeed:: Always succeed (useful for local rpms which might
43
- # already be installed.
44
- # :minimal:: Avoid additional "optional" packages when possible.
45
- def dist_install( *args )
46
- sudo( dist_install_s( *args ) )
47
- end
36
+ super( *args )
37
+ end
48
38
 
49
- # Generate command to install the specified packages using
50
- # distro-specific mapped package names. The last argument is
51
- # interpreted as options if it is a Hash.
52
- def dist_install_s( *args )
53
- raise "Include a distro-specific module, e.g. Ubuntu, RHEL"
54
- end
39
+ # Return self, and in Context, the specific Distro component.
40
+ def distro
41
+ self
42
+ end
55
43
 
56
- # Uninstall specified packages using distro-specific mapped
57
- # package names and command.
58
- def dist_uninstall( *args )
59
- sudo( dist_uninstall_s( *args ) )
60
- end
44
+ # Map internal/common names and return distro-specific names. If a
45
+ # mapping does not exist, return the original name.
46
+ def dist_map_packages( *pkgs )
47
+ pkgs.flatten.compact.map { |pkg| packages_map[ pkg ] || pkg }
48
+ end
61
49
 
62
- # Return command to uninstall specified packages using
63
- # distro-specific mapped package names.
64
- def dist_uninstall_s( *args )
65
- raise "Include a distro-specific module, e.g. Ubuntu, RHEL"
66
- end
50
+ # Install the specified packages using distro-specific mapped
51
+ # package names. A trailing hash is interpreted as options, see
52
+ # below.
53
+ #
54
+ # ==== Options
55
+ #
56
+ # :succeed:: Always succeed (useful for local rpms which might
57
+ # already be installed.
58
+ #
59
+ # :minimal:: Avoid additional "optional" packages when possible.
60
+ def dist_install( *pkgs )
61
+ raise "Include a distro-specific component, e.g. Ubuntu, RHEL"
62
+ end
67
63
 
68
- # Install a System V style init.d script (already placed at remote
69
- # /etc/init.d/<name>) via distro-specific command
70
- def dist_install_init_service( name )
71
- sudo( dist_install_init_service_s( name ) )
72
- end
64
+ # Uninstall specified packages using distro-specific mapped
65
+ # package names and command.
66
+ def dist_uninstall( *pkgs )
67
+ raise "Include a distro-specific component, e.g. Ubuntu, RHEL"
68
+ end
73
69
 
74
- # Return command to install a System V style init.d script (already
75
- # placed at remote /etc/init.d/<name>).
76
- def dist_install_init_service_s( name )
77
- raise "Include a distro-specific module, e.g. Ubuntu, RHEL"
78
- end
70
+ # Install a System V style init.d script (already placed at remote
71
+ # /etc/init.d/<name>) via distro-specific command
72
+ def dist_install_init_service( name )
73
+ raise "Include a distro-specific component, e.g. Ubuntu, RHEL"
74
+ end
79
75
 
80
- # Run via sudo, the System V style, distro specific `service`
81
- # command, typically supporting 'start', 'stop', 'restart',
82
- # 'status', etc. arguments.
83
- def dist_service( *args )
84
- sudo( dist_service_s( *args ) )
85
- end
76
+ # Run via sudo, the System V style, distro specific `service`
77
+ # command, typically supporting 'start', 'stop', 'restart',
78
+ # 'status', etc. arguments.
79
+ def dist_service( *args )
80
+ raise "Include a distro-specific component, e.g. Ubuntu, RHEL"
81
+ end
86
82
 
87
- # Return the System V style, distro specific `service` command.
88
- def dist_service_s( *args )
89
- raise "Include a distro-specific module, e.g. Ubuntu, RHEL"
90
83
  end
91
84
 
92
85
  end