syncwrap 1.0.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.
@@ -0,0 +1,75 @@
1
+ #--
2
+ # Copyright (c) 2011-2012 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/distro'
18
+
19
+ # Provisions for install and configuration of PostgreSQL
20
+ module SyncWrap::PostgreSQL
21
+ include SyncWrap::Distro
22
+
23
+ def initialize
24
+ super
25
+ end
26
+
27
+ # Update PostgreSQL config files from local etc
28
+ def pg_configure
29
+ rput( 'etc/postgresql/9.1/main/', :user => 'postgres' )
30
+ end
31
+
32
+ def pg_install
33
+ dist_install 'postgresql'
34
+ end
35
+
36
+ def pg_start
37
+ dist_service( 'postgresql', 'start' )
38
+ end
39
+
40
+ def pg_stop
41
+ dist_service( 'postgresql', 'stop' )
42
+ end
43
+
44
+ def pg_adjust_sysctl
45
+ rput( 'etc/sysctl.d/61-postgresql-shm.conf', :user => 'root' )
46
+ sudo "sysctl -p /etc/sysctl.d/61-postgresql-shm.conf"
47
+ end
48
+
49
+ module Ubuntu
50
+ include SyncWrap::PostgreSQL
51
+
52
+ def initialize
53
+ super
54
+ end
55
+
56
+ end
57
+
58
+ module EC2
59
+ include SyncWrap::PostgreSQL
60
+
61
+ def initialize
62
+ super
63
+ end
64
+
65
+ def pg_relocate
66
+ # FIXME: Different default location on RHEL?
67
+ sudo <<-SH
68
+ mkdir -p /mnt/var/postgresql/
69
+ mv /var/lib/postgresql/9.1 /mnt/var/postgresql/
70
+ SH
71
+ end
72
+
73
+ end
74
+
75
+ end
@@ -0,0 +1,116 @@
1
+ #--
2
+ # Copyright (c) 2011-2012 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 'rake/remote_task'
18
+
19
+ require 'syncwrap/base'
20
+ require 'syncwrap/common'
21
+
22
+ # Implements common remoting methods in terms of rake/remote_task (and
23
+ # thus Vlad compatible)
24
+ module SyncWrap::RemoteTask
25
+ include SyncWrap::Common
26
+ include Rake::DSL
27
+
28
+ def initialize
29
+ super
30
+
31
+ # Defaults:
32
+ set( :sudo_flags, %w[ -H ] )
33
+ set( :rsync_flags, %w[ -rlpcb -ii ] )
34
+ end
35
+
36
+ # Implements SyncWrap::Common#run
37
+ def run( *args )
38
+ opts = args.last.is_a?( Hash ) && args.pop || {}
39
+
40
+ exit_multi = opts[ :error ].nil? || opts[ :error ] == :exit
41
+
42
+ args = cleanup_arg_lines( args, exit_multi )
43
+
44
+ #FIXME: Should cleanup multi-line commands
45
+ remote_task_current.run( *args )
46
+ end
47
+
48
+ # Implements SyncWrap::Common#sudo
49
+ def sudo( *args )
50
+ opts = args.last.is_a?( Hash ) && args.pop || {}
51
+
52
+ flags = opts[ :flags ] || []
53
+ if opts[ :user ]
54
+ flags += [ '-u', opts[ :user ] ]
55
+ end
56
+
57
+ unless opts[ :shell ] == false
58
+ exit_multi = opts[ :error ].nil? || opts[ :error ] == :exit
59
+ cmd = cleanup_arg_lines( args, exit_multi )
60
+ cmd = cmd.join( ' ' ).gsub( /"/, '\"' )
61
+ cmd = "sh -c \"#{cmd}\""
62
+ else
63
+ cmd = cleanup_arg_lines( args, false )
64
+ end
65
+
66
+ remote_task_current.sudo( [ flags, cmd ] )
67
+ end
68
+
69
+ # Implements SyncWrap::Common#rsync
70
+ def rsync( *args )
71
+ remote_task_current.rsync( *args )
72
+ end
73
+
74
+ def target_host
75
+ remote_task_current.target_host
76
+ end
77
+
78
+ # Implements Common#exec_conditional
79
+ def exec_conditional
80
+ yield
81
+ 0
82
+ rescue Rake::CommandFailedError => e
83
+ e.status
84
+ end
85
+
86
+ # Remove extra whitespace from multi-line and single arguments
87
+ def cleanup_arg_lines( args, exit_error_on_multi )
88
+ args.flatten.compact.map do |arg|
89
+ alines = arg.split( $/ )
90
+ if alines.length > 1 && exit_error_on_multi
91
+ alines.unshift( "set -e" )
92
+ end
93
+ alines.map { |f| f.strip }.join( $/ )
94
+ end
95
+ end
96
+
97
+ def remote_task( name, *args, &block )
98
+ Rake::RemoteTask.remote_task( name, *args, &block )
99
+ end
100
+
101
+ def set( *args )
102
+ Rake::RemoteTask.set( *args )
103
+ end
104
+
105
+ def host( host_name, *roles )
106
+ Rake::RemoteTask.host( host_name, *roles )
107
+ end
108
+
109
+ def role( role_name, host = nil, args = {} )
110
+ Rake::RemoteTask.role( role_name, host, args )
111
+ end
112
+
113
+ def remote_task_current
114
+ Thread.current[ :task ] or raise "Not running from a RemoteTask"
115
+ end
116
+ end
@@ -0,0 +1,55 @@
1
+ #--
2
+ # Copyright (c) 2011-2012 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/distro'
18
+
19
+ # Customizations for RedHat Enterprise Linux and derivatives like
20
+ # CentOS and Amazon Linux. Specific distros/versions may further
21
+ # override these.
22
+ module SyncWrap::RHEL
23
+ include SyncWrap::Distro
24
+
25
+ def initialize
26
+ super
27
+
28
+ packages_map.merge!( 'emacs' => 'emacs-nox',
29
+ 'postgresql' => 'postgresql-server' )
30
+ end
31
+
32
+ # FIXME
33
+ # rpm -Uvh \
34
+ # http://linux.mirrors.es.net/fedora-epel/6/x86_64/ \
35
+ # epel-release-6-7.noarch.rpm
36
+
37
+ def dist_install( *pkgs )
38
+ pkgs = dist_map_packages( pkgs )
39
+ sudo "yum install -qy #{pkgs.join( ' ' )}"
40
+ end
41
+
42
+ def dist_uninstall( *pkgs )
43
+ pkgs = dist_map_packages( pkgs )
44
+ sudo "yum remove -qy #{pkgs.join( ' ' )}"
45
+ end
46
+
47
+ def dist_install_init_service( name )
48
+ sudo "/sbin/chkconfig --add #{name}"
49
+ end
50
+
51
+ def dist_service( *args )
52
+ sudo( [ '/sbin/service' ] + args )
53
+ end
54
+
55
+ end
@@ -0,0 +1,49 @@
1
+ #--
2
+ # Copyright (c) 2011-2012 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/distro'
18
+
19
+ # Customizations for Ubuntu and possibly other Debian/apt packaged
20
+ # derivatives. Specific distros/versions may further specialize.
21
+ module SyncWrap::Ubuntu
22
+ include SyncWrap::Distro
23
+
24
+ def initialize
25
+ super
26
+
27
+ packages_map.merge!( 'apr' => 'libapr1',
28
+ 'apr-devel' => 'libapr1-dev' )
29
+ end
30
+
31
+ def dist_install( *pkgs )
32
+ pkgs = dist_map_packages( pkgs )
33
+ sudo "apt-get -yq install #{pkgs.join( ' ' )}"
34
+ end
35
+
36
+ def dist_uninstall( *pkgs )
37
+ pkgs = dist_map_packages( pkgs )
38
+ sudo "aptitude -yq purge #{pkgs.join( ' ' )}"
39
+ end
40
+
41
+ def dist_install_init_service( name )
42
+ sudo "/usr/sbin/update-rc.d #{name} defaults"
43
+ end
44
+
45
+ def dist_service( *args )
46
+ sudo( [ '/usr/sbin/service' ] + args )
47
+ end
48
+
49
+ end
@@ -0,0 +1,102 @@
1
+ #--
2
+ # Copyright (c) 2011-2012 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/common'
18
+
19
+ # Provisions for a (daemon) run user and var directory. Utilities for
20
+ # working with the same.
21
+ module SyncWrap::UserRun
22
+ include SyncWrap::Common
23
+
24
+ # A user for running deployed daemons, jobs (default: 'runr')
25
+ attr_accessor :user_run
26
+
27
+ # A group for running (default: 'runr')
28
+ attr_accessor :user_run_group
29
+
30
+ # Directory for persistent data, logs. (default: /var/local/runr)
31
+ attr_accessor :user_run_dir
32
+
33
+ def initialize
34
+ super
35
+
36
+ @user_run = 'runr'
37
+ @user_run_group = 'runr'
38
+
39
+ @user_run_dir = '/var/local/runr'
40
+ end
41
+
42
+ # Create and set owner/permission of run_dir, such that user_run may
43
+ # create new directories there.
44
+ def user_run_dir_setup
45
+ user_create
46
+ sudo <<-SH
47
+ mkdir -p #{user_run_dir}
48
+ chown #{user_run}:#{user_run_group} #{user_run_dir}
49
+ chmod 775 #{user_run_dir}
50
+ SH
51
+ end
52
+
53
+ # Create and set owner/permission of a named service directory under
54
+ # user_run_dir.
55
+ def user_run_service_dir_setup( sname, instance = nil )
56
+ sdir = user_run_service_dir( sname, instance )
57
+
58
+ sudo <<-SH
59
+ mkdir -p #{sdir}
60
+ chown #{user_run}:#{user_run_group} #{sdir}
61
+ chmod 775 #{sdir}
62
+ SH
63
+ end
64
+
65
+ def user_run_service_dir( sname, instance = nil )
66
+ "#{user_run_dir}/" + [ sname, instance ].compact.join( '-' )
67
+ end
68
+
69
+ # As per SyncWrap::Common#rput with :user => user_run
70
+ def user_run_rput( *args )
71
+ opts = args.last.is_a?( Hash ) && args.pop || {}
72
+ opts[ :user ] = user_run
73
+ args.push( opts )
74
+ rput( *args )
75
+ end
76
+
77
+ # Chown to user_run where args may be flags and files/directories.
78
+ def user_run_chown( *args )
79
+ flags, paths = args.partition { |a| a =~ /^-/ }
80
+ sudo( 'chown', flags, "#{user_run}:#{user_run_group}", paths )
81
+ end
82
+
83
+ def user_exist?
84
+ exec_conditional { run "id #{user_run}" } == 0
85
+ end
86
+
87
+ def user_create
88
+ user_create! unless user_exist?
89
+ end
90
+
91
+ def user_create!
92
+ if user_run_group == user_run
93
+ sudo "useradd #{user_run}"
94
+ else
95
+ sudo <<-SH
96
+ groupadd #{user_run_group}
97
+ useradd -g #{user_run_group} #{user_run}
98
+ SH
99
+ end
100
+ end
101
+
102
+ end
data/lib/syncwrap.rb ADDED
@@ -0,0 +1,17 @@
1
+ #--
2
+ # Copyright (c) 2011-2012 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/base'
@@ -0,0 +1,202 @@
1
+ #!/usr/bin/env jruby
2
+ #.hashdot.profile += jruby-shortlived
3
+
4
+ #--
5
+ # Copyright (c) 2011-2012 David Kellum
6
+ #
7
+ # Licensed under the Apache License, Version 2.0 (the "License"); you
8
+ # may not use this file except in compliance with the License. You
9
+ # may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing, software
14
+ # distributed under the License is distributed on an "AS IS" BASIS,
15
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
16
+ # implied. See the License for the specific language governing
17
+ # permissions and limitations under the License.
18
+ #++
19
+
20
+ require 'rubygems'
21
+ require 'bundler/setup'
22
+
23
+ require 'minitest/unit'
24
+ require 'minitest/autorun'
25
+
26
+ require 'syncwrap/java'
27
+ require 'syncwrap/hashdot'
28
+ require 'syncwrap/jruby'
29
+ require 'syncwrap/iyyov'
30
+ require 'syncwrap/ec2'
31
+ require 'syncwrap/ubuntu'
32
+ require 'syncwrap/rhel'
33
+ require 'syncwrap/postgresql'
34
+ require 'syncwrap/remote_task'
35
+
36
+ class TestSyncWrap < MiniTest::Unit::TestCase
37
+
38
+ class EveryWrapper
39
+ include SyncWrap::Java
40
+ include SyncWrap::Hashdot
41
+ include SyncWrap::JRuby
42
+ include SyncWrap::Iyyov
43
+
44
+ include SyncWrap::RHEL
45
+ include SyncWrap::Ubuntu # Not a recomendated combo
46
+
47
+ include SyncWrap::EC2
48
+ include SyncWrap::PostgreSQL::Ubuntu
49
+ include SyncWrap::PostgreSQL::EC2
50
+ end
51
+
52
+ def test_init
53
+ w = EveryWrapper.new
54
+ assert_equal( '/usr/local', w.common_prefix,
55
+ 'Common#initialize should run for defaults' )
56
+ assert_equal( 'runr', w.user_run,
57
+ 'UserRun#initialize should run for defaults' )
58
+ assert_equal( '1.1.3', w.iyyov_version,
59
+ 'Iyyov#initialize should run for defaults' )
60
+ end
61
+
62
+ def test_no_remoting_module
63
+ w = EveryWrapper.new
64
+ assert_raises( RuntimeError, <<-MSG ) { w.run( 'ls' ) }
65
+ Should raise when no remoting module is included.
66
+ MSG
67
+ end
68
+
69
+ class CommonWrapper
70
+ include SyncWrap::Common
71
+
72
+ attr_reader :last_args
73
+
74
+ def rsync( *args )
75
+ @last_args = args
76
+ end
77
+
78
+ def target_host
79
+ 'testhost'
80
+ end
81
+
82
+ end
83
+
84
+ def test_rput
85
+ w = CommonWrapper.new
86
+
87
+ w.rput( 'other/lang.sh', '/etc/' )
88
+
89
+ assert_equal( [ 'other/lang.sh',
90
+ 'testhost:/etc/' ],
91
+ w.last_args )
92
+
93
+ w.rput( 'etc/profile.d/lang.sh' )
94
+
95
+ assert_equal( [ 'etc/profile.d/lang.sh',
96
+ 'testhost:/etc/profile.d/' ],
97
+ w.last_args )
98
+
99
+ w.rput( 'etc/profile.d/' )
100
+
101
+ assert_equal( [ 'etc/profile.d/',
102
+ 'testhost:/etc/profile.d/' ],
103
+ w.last_args )
104
+
105
+ w.rput( 'etc/profile.d' )
106
+
107
+ assert_equal( [ 'etc/profile.d',
108
+ 'testhost:/etc/' ],
109
+ w.last_args )
110
+
111
+ w.rput( 'etc/profile.d/lang.sh', :user => 'root' )
112
+
113
+ assert_equal( [ '--rsync-path=sudo rsync',
114
+ 'etc/profile.d/lang.sh',
115
+ 'testhost:/etc/profile.d/'],
116
+ w.last_args )
117
+
118
+ w.rput( 'etc/profile.d/lang.sh', :user => 'runr' )
119
+
120
+ assert_equal( [ '--rsync-path=sudo -u runr rsync',
121
+ 'etc/profile.d/lang.sh',
122
+ 'testhost:/etc/profile.d/'],
123
+ w.last_args )
124
+
125
+ w.rput( 'etc/profile.d/lang.sh', :excludes => :dev )
126
+
127
+ assert_equal( [ '--cvs-exclude',
128
+ 'etc/profile.d/lang.sh',
129
+ 'testhost:/etc/profile.d/' ],
130
+ w.last_args )
131
+ end
132
+
133
+ class RemoteTaskWrapper
134
+ include SyncWrap::RemoteTask
135
+ end
136
+
137
+ class TestTask
138
+ attr_accessor :last_args
139
+
140
+ def with
141
+ Thread.current[ :task ] = self
142
+ yield self
143
+ ensure
144
+ Thread.current[ :task ] = nil
145
+ end
146
+
147
+ def run( *args )
148
+ @last_args = args
149
+ end
150
+
151
+ alias sudo run
152
+ end
153
+
154
+ def test_remote_not_in_task
155
+ w = RemoteTaskWrapper.new
156
+ assert_raises( RuntimeError ) { w.run( 'foo' ) }
157
+ end
158
+
159
+ def test_run
160
+ w = RemoteTaskWrapper.new
161
+ TestTask.new.with do |t|
162
+ w.run( 'foo' )
163
+ assert_equal( [ 'foo' ], t.last_args )
164
+
165
+ w.run( 'foo', 'bar', :opt => :bar )
166
+ assert_equal( [ 'foo', 'bar' ], t.last_args )
167
+
168
+ w.run <<-SH
169
+ mkdir -p foo
170
+ touch foo/goo
171
+ SH
172
+ assert_equal( [ [ 'set -e',
173
+ 'mkdir -p foo',
174
+ 'touch foo/goo' ].join( $/ ) ],
175
+ t.last_args )
176
+ end
177
+ end
178
+
179
+ def test_sudo
180
+ w = RemoteTaskWrapper.new
181
+ TestTask.new.with do |t|
182
+ w.sudo( 'foo' )
183
+ assert_equal( [ 'sh -c "foo"' ], t.last_args.flatten.compact )
184
+
185
+ w.sudo( 'foo', :shell => false )
186
+ assert_equal( [ 'foo' ], t.last_args.flatten.compact )
187
+
188
+ w.sudo( 'foo', 'bar', :user => 'postgres' )
189
+ assert_equal( [ '-u', 'postgres', 'sh -c "foo bar"' ],
190
+ t.last_args.flatten.compact )
191
+
192
+ w.sudo <<-SH
193
+ mkdir -p foo
194
+ touch foo/goo
195
+ SH
196
+
197
+ assert_equal( [ "sh -c \"set -e\nmkdir -p foo\ntouch foo/goo\"" ],
198
+ t.last_args.flatten.compact )
199
+ end
200
+ end
201
+
202
+ end
@@ -0,0 +1,25 @@
1
+ #!/usr/local/bin/jruby
2
+ #.hashdot.profile = jruby-shortlived
3
+ #--
4
+ # Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others.
5
+ # All rights reserved.
6
+ # See LICENSE.txt for permissions.
7
+ #++
8
+
9
+ require 'rubygems'
10
+ require 'rubygems/gem_runner'
11
+ require 'rubygems/exceptions'
12
+
13
+ required_version = Gem::Requirement.new ">= 1.8.7"
14
+
15
+ unless required_version.satisfied_by? Gem.ruby_version then
16
+ abort "Expected Ruby Version #{required_version}, is #{Gem.ruby_version}"
17
+ end
18
+
19
+ args = ARGV.clone
20
+
21
+ begin
22
+ Gem::GemRunner.new.run args
23
+ rescue Gem::SystemExitException => e
24
+ exit e.exit_code
25
+ end