syncwrap 2.5.1 → 2.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/History.rdoc +19 -0
- data/Manifest.txt +6 -0
- data/README.rdoc +6 -5
- data/lib/syncwrap/amazon_ec2.rb +3 -12
- data/lib/syncwrap/base.rb +1 -1
- data/lib/syncwrap/cli.rb +10 -0
- data/lib/syncwrap/components/arch.rb +8 -1
- data/lib/syncwrap/components/commercial_jdk.rb +21 -6
- data/lib/syncwrap/components/cruby_vm.rb +30 -5
- data/lib/syncwrap/components/debian.rb +31 -7
- data/lib/syncwrap/components/hashdot.rb +30 -4
- data/lib/syncwrap/components/iyyov.rb +13 -7
- data/lib/syncwrap/components/jruby_vm.rb +29 -4
- data/lib/syncwrap/components/lvm_cache.rb +116 -0
- data/lib/syncwrap/components/mdraid.rb +0 -9
- data/lib/syncwrap/components/postgresql.rb +24 -1
- data/lib/syncwrap/components/puma.rb +41 -12
- data/lib/syncwrap/components/rhel.rb +24 -6
- data/lib/syncwrap/components/ubuntu.rb +1 -0
- data/lib/syncwrap/distro.rb +32 -4
- data/lib/syncwrap/hash_support.rb +64 -0
- data/lib/syncwrap/host.rb +8 -0
- data/lib/syncwrap/main.rb +5 -0
- data/lib/syncwrap/systemd.rb +43 -0
- data/lib/syncwrap/user_data.rb +40 -0
- data/lib/syncwrap.rb +22 -1
- data/sync/etc/systemd/system/iyyov.service.erb +16 -0
- data/sync/etc/systemd/system/puma.service.erb +13 -0
- data/test/test_components.rb +4 -0
- data/test/test_space.rb +1 -0
- metadata +8 -2
@@ -0,0 +1,116 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright (c) 2011-2015 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 cache using a fast drive (like an SSD) over a
|
22
|
+
# slow drive (magnetic or network attached) via LVM's cache-pool
|
23
|
+
# mechanism and dm-cache.
|
24
|
+
#
|
25
|
+
# Host component dependencies: <Distro>
|
26
|
+
class LVMCache < Component
|
27
|
+
|
28
|
+
protected
|
29
|
+
|
30
|
+
# The target size of the cache metadata volume as a string. The
|
31
|
+
# dm-cache guidelines are 1/1000th of the cache volume size and a
|
32
|
+
# minimum of 8M (MiB). Default: '8M'
|
33
|
+
attr_accessor :meta_size
|
34
|
+
|
35
|
+
# The target size of the cache volume as a string. This may either
|
36
|
+
# express a percentage (via -l) or a real size (via -L, ex: '30G')
|
37
|
+
# Default: '100%FREE'
|
38
|
+
attr_accessor :cache_size
|
39
|
+
|
40
|
+
# A volume group instance number compatible with the naming used
|
41
|
+
# by MDRaid. The cache and cache-meta volumes must all be under
|
42
|
+
# the same volume group as the lv_cache_target volume.
|
43
|
+
# Default: 0 -> 'vg0'
|
44
|
+
attr_accessor :vg_instance
|
45
|
+
|
46
|
+
# The fast raw device to use as the cache, i.e. '/dev/xvdb'
|
47
|
+
# (required)
|
48
|
+
attr_accessor :raw_device
|
49
|
+
|
50
|
+
# The target volume name in the same volume group to
|
51
|
+
# cache. (required)
|
52
|
+
attr_accessor :lv_cache_target
|
53
|
+
|
54
|
+
# The name of the cache volume
|
55
|
+
# Default: lv_cache_target + '_cache'
|
56
|
+
attr_writer :lv_cache
|
57
|
+
|
58
|
+
# Array of additional flags to vgextend
|
59
|
+
# Default: ['-y']
|
60
|
+
attr_accessor :vgextend_flags
|
61
|
+
|
62
|
+
def lv_cache
|
63
|
+
@lv_cache || ( lv_cache_target + '_cache' )
|
64
|
+
end
|
65
|
+
|
66
|
+
def lv_cache_meta
|
67
|
+
lv_cache + '_meta'
|
68
|
+
end
|
69
|
+
|
70
|
+
def vg
|
71
|
+
"vg#{vg_instance}"
|
72
|
+
end
|
73
|
+
|
74
|
+
public
|
75
|
+
|
76
|
+
def initialize( opts = {} )
|
77
|
+
@meta_size = '8M'
|
78
|
+
@cache_size = '100%FREE'
|
79
|
+
@vg_instance = 0
|
80
|
+
@raw_device = nil
|
81
|
+
@lv_cache_target = nil
|
82
|
+
@lv_cache = nil
|
83
|
+
@vgextend_flags = %w[ -y ]
|
84
|
+
super
|
85
|
+
|
86
|
+
raise "LVMCache#raw_device not set" unless raw_device
|
87
|
+
raise "LVMCache#lv_cache_target not set" unless lv_cache_target
|
88
|
+
end
|
89
|
+
|
90
|
+
def install
|
91
|
+
dist_install( "lvm2", minimal: true )
|
92
|
+
sudo( "if ! lvs /dev/#{vg}/#{lv_cache}; then", close: "fi" ) do
|
93
|
+
unmount_device( raw_device )
|
94
|
+
sudo <<-SH
|
95
|
+
vgextend #{vgextend_flags.join ' '} #{vg} #{raw_device}
|
96
|
+
lvcreate -L #{meta_size} -n #{lv_cache_meta} #{vg} #{raw_device}
|
97
|
+
lvcreate #{cache_size_flag} -n #{lv_cache} #{vg} #{raw_device}
|
98
|
+
lvconvert --type cache-pool --cachemode writethrough --yes \
|
99
|
+
--poolmetadata #{vg}/#{lv_cache_meta} #{vg}/#{lv_cache}
|
100
|
+
lvconvert --type cache --cachepool #{vg}/#{lv_cache} #{vg}/#{lv_cache_target}
|
101
|
+
SH
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
protected
|
106
|
+
|
107
|
+
def cache_size_flag
|
108
|
+
if cache_size =~ /%/
|
109
|
+
"-l #{cache_size}"
|
110
|
+
else
|
111
|
+
"-L #{cache_size}"
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
end
|
@@ -144,15 +144,6 @@ module SyncWrap
|
|
144
144
|
|
145
145
|
private
|
146
146
|
|
147
|
-
def unmount_device( dev )
|
148
|
-
sudo <<-SH
|
149
|
-
if mount | grep -q '^#{dev} '; then
|
150
|
-
umount #{dev}
|
151
|
-
sed -r -i '\\|^#{dev}\\s|d' /etc/fstab
|
152
|
-
fi
|
153
|
-
SH
|
154
|
-
end
|
155
|
-
|
156
147
|
def create_raid( md )
|
157
148
|
rlevel = raid_level || default_raid_level
|
158
149
|
sudo <<-SH
|
@@ -195,6 +195,14 @@ module SyncWrap
|
|
195
195
|
# (Default: 300MB if #pg_version < 9.3)
|
196
196
|
attr_writer :shared_memory_max
|
197
197
|
|
198
|
+
# A command pattern to initialize the database on first
|
199
|
+
# install. This is used on systemd distro's only. The pattern is
|
200
|
+
# expanded using #pg_data_dir as the first (optional)
|
201
|
+
# replacement. The command is run by the postgres user.
|
202
|
+
#
|
203
|
+
# (Default: "/usr/bin/initdb %s")
|
204
|
+
attr_accessor :initdb_cmd
|
205
|
+
|
198
206
|
def shared_memory_max
|
199
207
|
@shared_memory_max || ( version_lt?(pg_version, [9,3]) && 300_000_000 )
|
200
208
|
end
|
@@ -232,6 +240,7 @@ module SyncWrap
|
|
232
240
|
@network_v4_mask = nil
|
233
241
|
@network_v6_mask = nil
|
234
242
|
@shared_memory_max = nil
|
243
|
+
@initdb_cmd = "/usr/bin/initdb %s"
|
235
244
|
super
|
236
245
|
end
|
237
246
|
|
@@ -281,7 +290,7 @@ module SyncWrap
|
|
281
290
|
chown postgres:postgres #{pg_data_dir}
|
282
291
|
chmod 700 #{pg_data_dir}
|
283
292
|
SH
|
284
|
-
|
293
|
+
pg_initdb
|
285
294
|
end
|
286
295
|
|
287
296
|
when Debian
|
@@ -300,6 +309,20 @@ module SyncWrap
|
|
300
309
|
changes
|
301
310
|
end
|
302
311
|
|
312
|
+
def pg_initdb
|
313
|
+
if distro.systemd?
|
314
|
+
if initdb_cmd
|
315
|
+
sudo <<-SH
|
316
|
+
su postgres -c '#{initdb_cmd % [ pg_data_dir ]}'
|
317
|
+
SH
|
318
|
+
else
|
319
|
+
raise ContextError, "PostgreSQL#initdb_cmd is required with systemd"
|
320
|
+
end
|
321
|
+
else
|
322
|
+
dist_service( service_name, 'initdb' )
|
323
|
+
end
|
324
|
+
end
|
325
|
+
|
303
326
|
# Update the \PostgreSQL configuration files
|
304
327
|
def pg_configure
|
305
328
|
files = %w[ pg_hba.conf pg_ident.conf postgresql.conf ]
|
@@ -49,7 +49,7 @@ module SyncWrap
|
|
49
49
|
control: "unix://#{rack_path}/control",
|
50
50
|
environment: "production",
|
51
51
|
port: 5874,
|
52
|
-
daemon:
|
52
|
+
daemon: !foreground? }.merge( @puma_flags )
|
53
53
|
end
|
54
54
|
|
55
55
|
protected
|
@@ -66,6 +66,11 @@ module SyncWrap
|
|
66
66
|
@always_restart
|
67
67
|
end
|
68
68
|
|
69
|
+
# The name of the systemd unit file to create for this instance of
|
70
|
+
# puma. If specified, the name should include a '.service' suffix.
|
71
|
+
# (Default: nil -> no unit)
|
72
|
+
attr_accessor :systemd_unit
|
73
|
+
|
69
74
|
public
|
70
75
|
|
71
76
|
def initialize( opts = {} )
|
@@ -74,6 +79,7 @@ module SyncWrap
|
|
74
79
|
@change_key = nil
|
75
80
|
@rack_path = nil
|
76
81
|
@puma_flags = {}
|
82
|
+
@systemd_unit = nil
|
77
83
|
super
|
78
84
|
end
|
79
85
|
|
@@ -83,12 +89,28 @@ module SyncWrap
|
|
83
89
|
end
|
84
90
|
|
85
91
|
changes = change_key && state[ change_key ]
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
+
|
93
|
+
if systemd_unit
|
94
|
+
uchanges = rput( '/etc/systemd/system/puma.service',
|
95
|
+
"/etc/systemd/system/#{systemd_unit}",
|
96
|
+
user: :root )
|
97
|
+
if !uchanges.empty?
|
98
|
+
systemctl( 'enable', systemd_unit )
|
99
|
+
end
|
100
|
+
if( change_key.nil? || changes || uchanges || always_restart? )
|
101
|
+
systemctl( 'restart', systemd_unit )
|
102
|
+
else
|
103
|
+
systemctl( 'start', systemd_unit )
|
104
|
+
end
|
105
|
+
else
|
106
|
+
rudo( "( cd #{rack_path}", close: ')' ) do
|
107
|
+
rudo( "if [ -f puma.state -a -e control ]; then",
|
108
|
+
close: bare_else_start ) do
|
109
|
+
if ( change_key && !changes ) && !always_restart?
|
110
|
+
rudo 'true' #no-op
|
111
|
+
else
|
112
|
+
bare_restart
|
113
|
+
end
|
92
114
|
end
|
93
115
|
end
|
94
116
|
end
|
@@ -97,11 +119,16 @@ module SyncWrap
|
|
97
119
|
|
98
120
|
protected
|
99
121
|
|
100
|
-
|
122
|
+
# By default, runs in foreground if a systemd_unit is specified.
|
123
|
+
def foreground?
|
124
|
+
!!systemd_unit
|
125
|
+
end
|
126
|
+
|
127
|
+
def bare_restart
|
101
128
|
rudo( ( pumactl_command + %w[ --state puma.state restart ] ).join( ' ' ) )
|
102
129
|
end
|
103
130
|
|
104
|
-
def
|
131
|
+
def bare_else_start
|
105
132
|
<<-SH
|
106
133
|
else
|
107
134
|
#{puma_start_command}
|
@@ -113,7 +140,7 @@ module SyncWrap
|
|
113
140
|
args = puma_flags.map do |key,value|
|
114
141
|
if value.is_a?( TrueClass )
|
115
142
|
key_to_arg( key )
|
116
|
-
elsif value.is_a?( FalseClass )
|
143
|
+
elsif value.nil? || value.is_a?( FalseClass )
|
117
144
|
nil
|
118
145
|
else
|
119
146
|
[ key_to_arg( key ), value && value.to_s ]
|
@@ -126,7 +153,8 @@ module SyncWrap
|
|
126
153
|
if puma_version
|
127
154
|
[ ruby_command, '-S', 'puma', "_#{puma_version}_" ]
|
128
155
|
else
|
129
|
-
[ "
|
156
|
+
[ File.expand_path( File.join( bundle_install_bin_stubs, "puma" ),
|
157
|
+
rack_path ) ]
|
130
158
|
end
|
131
159
|
end
|
132
160
|
|
@@ -134,7 +162,8 @@ module SyncWrap
|
|
134
162
|
if puma_version
|
135
163
|
[ ruby_command, '-S', 'pumactl', "_#{puma_version}_" ]
|
136
164
|
else
|
137
|
-
[ "
|
165
|
+
[ File.expand_path( File.join( bundle_install_bin_stubs, "pumactl" ),
|
166
|
+
rack_path ) ]
|
138
167
|
end
|
139
168
|
end
|
140
169
|
|
@@ -15,14 +15,18 @@
|
|
15
15
|
#++
|
16
16
|
|
17
17
|
require 'syncwrap/component'
|
18
|
+
require 'syncwrap/version_support'
|
18
19
|
require 'syncwrap/distro'
|
20
|
+
require 'syncwrap/systemd'
|
19
21
|
|
20
22
|
module SyncWrap
|
21
23
|
|
22
24
|
# Customizations for RedHat Enterprise Linux and base class for
|
23
25
|
# derivatives like CentOS and AmazonLinux.
|
24
26
|
class RHEL < Component
|
25
|
-
include
|
27
|
+
include Distro
|
28
|
+
include VersionSupport
|
29
|
+
include SystemD
|
26
30
|
|
27
31
|
# RHEL version, i.e. '6'. No default value.
|
28
32
|
attr_accessor :rhel_version
|
@@ -33,6 +37,10 @@ module SyncWrap
|
|
33
37
|
super
|
34
38
|
end
|
35
39
|
|
40
|
+
def systemd?
|
41
|
+
@is_systemd ||= version_gte?( rhel_version, [7] )
|
42
|
+
end
|
43
|
+
|
36
44
|
# Install the specified package names. A trailing hash is
|
37
45
|
# interpreted as options, see below.
|
38
46
|
#
|
@@ -76,15 +84,25 @@ module SyncWrap
|
|
76
84
|
sudo "/sbin/chkconfig --add #{name}"
|
77
85
|
end
|
78
86
|
|
79
|
-
# Enable
|
87
|
+
# Enable a service by (short) name either via RHEL/System V
|
88
|
+
# `chkconfig on` or systemd `systemctl enable`.
|
80
89
|
def dist_enable_init_service( name )
|
81
|
-
|
90
|
+
if systemd?
|
91
|
+
systemctl( 'enable', dot_service( name ) )
|
92
|
+
else
|
93
|
+
sudo "/sbin/chkconfig #{name} on"
|
94
|
+
end
|
82
95
|
end
|
83
96
|
|
84
|
-
# Run
|
85
|
-
# '
|
97
|
+
# Run the service command typically supporting 'start', 'stop',
|
98
|
+
# 'restart', 'status', etc. actions.
|
99
|
+
# Arguments are in order: shortname, action
|
86
100
|
def dist_service( *args )
|
87
|
-
|
101
|
+
if systemd?
|
102
|
+
dist_service_via_systemctl( *args )
|
103
|
+
else
|
104
|
+
sudo( [ '/sbin/service', *args ].join( ' ' ) )
|
105
|
+
end
|
88
106
|
end
|
89
107
|
|
90
108
|
end
|
@@ -32,6 +32,7 @@ module SyncWrap
|
|
32
32
|
# an approximation of the LTS lineage.
|
33
33
|
def debian_version
|
34
34
|
super ||
|
35
|
+
( version_gte?( ubuntu_version, [15,4] ) && '8' ) ||
|
35
36
|
( version_gte?( ubuntu_version, [14,4] ) && '7' ) ||
|
36
37
|
( version_gte?( ubuntu_version, [12,4] ) && '6' )
|
37
38
|
end
|
data/lib/syncwrap/distro.rb
CHANGED
@@ -55,18 +55,46 @@ module SyncWrap
|
|
55
55
|
end
|
56
56
|
|
57
57
|
# Install a System V style init.d script (already placed at remote
|
58
|
-
# /etc/init.d/<name>) via distro-specific command
|
58
|
+
# /etc/init.d/<name>) via distro-specific command. Note that this
|
59
|
+
# should not be called and may fail on a distro running systemd. A
|
60
|
+
# rough equivalent in this case is:
|
61
|
+
#
|
62
|
+
# systemctl( 'enable', 'name.service' )
|
63
|
+
#
|
64
|
+
# See #systemd?, SystemD#systemctl
|
65
|
+
#
|
59
66
|
def dist_install_init_service( name )
|
60
67
|
raise "Include a distro-specific component, e.g. Debian, RHEL"
|
61
68
|
end
|
62
69
|
|
63
|
-
# Run via sudo,
|
64
|
-
# command
|
65
|
-
#
|
70
|
+
# Run via sudo as root, either a System V (distro specific)
|
71
|
+
# `service` command or the systemd `systemctl` equivalent. In the
|
72
|
+
# System V case arguments are passed verbatim and are in the form:
|
73
|
+
# (name, command, options...) Typically supported commands
|
74
|
+
# include: start, stop, restart, reload and status. For maximum
|
75
|
+
# compatibility, in the systemd case only two arguments are
|
76
|
+
# allowed: shortname, command. Note the order is reversed from the
|
77
|
+
# use of systemctl.
|
66
78
|
def dist_service( *args )
|
67
79
|
raise "Include a distro-specific component, e.g. Debian, RHEL"
|
68
80
|
end
|
69
81
|
|
82
|
+
# If found mounted, unmount the specified device and also remove
|
83
|
+
# it from fstab.
|
84
|
+
def unmount_device( dev )
|
85
|
+
sudo <<-SH
|
86
|
+
if mount | grep -q '^#{dev} '; then
|
87
|
+
umount #{dev}
|
88
|
+
sed -r -i '\\|^#{dev}\\s|d' /etc/fstab
|
89
|
+
fi
|
90
|
+
SH
|
91
|
+
end
|
92
|
+
|
93
|
+
# Is the Distro running systemd?
|
94
|
+
def systemd?
|
95
|
+
false
|
96
|
+
end
|
97
|
+
|
70
98
|
end
|
71
99
|
|
72
100
|
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright (c) 2011-2015 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
|
+
module SyncWrap
|
18
|
+
|
19
|
+
# Support module for using a crytographic hash to verify the
|
20
|
+
# integrity of a file, for example a downloaded package.
|
21
|
+
module HashSupport
|
22
|
+
|
23
|
+
protected
|
24
|
+
|
25
|
+
# Enqueue a bash command to verify the specified file using the
|
26
|
+
# given hash. This command will fail if the file does not
|
27
|
+
# match. The hash :method can be specified in opts (i.e. :sha256)
|
28
|
+
# or will be guessed from the provided hex-encoded hash string
|
29
|
+
# length. Other opts are as per Component#sh, though options
|
30
|
+
# accept, pipefail and error are ignored. Use of :user can allow
|
31
|
+
# this command to be merged.
|
32
|
+
def hash_verify( hash, file, opts = {} )
|
33
|
+
opts = opts.dup
|
34
|
+
mth = ( opts.delete(:method) || guess_hash_method( hash ) ) or
|
35
|
+
raise( "Hash method unspecified and hash length " +
|
36
|
+
"#{hash.length} is non-standard" )
|
37
|
+
|
38
|
+
[ :accept, :pipefail, :error ].each { |k| opts.delete( k ) }
|
39
|
+
|
40
|
+
sh( <<-SH, opts )
|
41
|
+
echo "#{hash} #{file}" | /usr/bin/#{mth}sum -c -
|
42
|
+
SH
|
43
|
+
end
|
44
|
+
|
45
|
+
def guess_hash_method( hash )
|
46
|
+
case hash.length
|
47
|
+
when 32
|
48
|
+
:md5
|
49
|
+
when 40
|
50
|
+
:sha1
|
51
|
+
when 56
|
52
|
+
:sha224
|
53
|
+
when 64
|
54
|
+
:sha256
|
55
|
+
when 96
|
56
|
+
:sha384
|
57
|
+
when 128
|
58
|
+
:sha512
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
data/lib/syncwrap/host.rb
CHANGED
@@ -104,6 +104,14 @@ module SyncWrap
|
|
104
104
|
end
|
105
105
|
end
|
106
106
|
|
107
|
+
# Returns components under the specified role
|
108
|
+
def components_in_roles( roles )
|
109
|
+
roles.inject([]) do |m,r|
|
110
|
+
m += space.role( r ) if roles.include?( r )
|
111
|
+
m
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
107
115
|
# Return the last component added to this Host prior to the given
|
108
116
|
# component (either directly or via a role), or nil if there is no
|
109
117
|
# such component.
|
data/lib/syncwrap/main.rb
CHANGED
@@ -40,6 +40,11 @@ module SyncWrap
|
|
40
40
|
space.host( *args )
|
41
41
|
end
|
42
42
|
|
43
|
+
# Shorthand for space.compose
|
44
|
+
def compose( &block )
|
45
|
+
space.compose(&block)
|
46
|
+
end
|
47
|
+
|
43
48
|
# Merge options given, or (without opts) return space.default_options
|
44
49
|
def options( opts = nil ) # :doc:
|
45
50
|
if opts
|
@@ -0,0 +1,43 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright (c) 2011-2015 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
|
+
module SyncWrap
|
18
|
+
|
19
|
+
# Support module for the systemd service manager, PID 1
|
20
|
+
module SystemD
|
21
|
+
|
22
|
+
# Run systemd `systemctl` command with args via sudo as root.
|
23
|
+
def systemctl( *args )
|
24
|
+
sudo "/usr/bin/systemctl #{args.join ' '}"
|
25
|
+
end
|
26
|
+
|
27
|
+
# Expand given shortname to "shortname.service" as used for the
|
28
|
+
# systemd unit.
|
29
|
+
def dot_service( shortname )
|
30
|
+
shortname + ".service"
|
31
|
+
end
|
32
|
+
|
33
|
+
protected
|
34
|
+
|
35
|
+
# Provides Distro#dist_service compatibility via #systemctl. The
|
36
|
+
# argument order is swapped and shortname is passed through
|
37
|
+
# #dot_service.
|
38
|
+
def dist_service_via_systemctl( shortname, action )
|
39
|
+
systemctl( action, dot_service( shortname ) )
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright (c) 2011-2015 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
|
+
module SyncWrap
|
18
|
+
|
19
|
+
# Utility methods for generating scripts to pass as user data.
|
20
|
+
module UserData
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
# Returns an sh script to allow no password, no tty sudo for a
|
25
|
+
# specified user by writing a file to /etc/sudoers.d/<user>
|
26
|
+
def no_tty_sudoer( user )
|
27
|
+
script = <<-SH
|
28
|
+
#!/bin/sh -e
|
29
|
+
echo '#{user} ALL=(ALL) NOPASSWD:ALL' > /etc/sudoers.d/#{user}
|
30
|
+
echo 'Defaults:#{user} !requiretty' >> /etc/sudoers.d/#{user}
|
31
|
+
chmod 440 /etc/sudoers.d/#{user}
|
32
|
+
SH
|
33
|
+
script.split( "\n" ).map( &:strip ).join( "\n" )
|
34
|
+
end
|
35
|
+
|
36
|
+
module_function :no_tty_sudoer
|
37
|
+
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
data/lib/syncwrap.rb
CHANGED
@@ -77,6 +77,7 @@ module SyncWrap
|
|
77
77
|
sh_verbose: :v,
|
78
78
|
sync_paths: [ File.join( SyncWrap::GEM_ROOT, 'sync' ) ] }
|
79
79
|
@formatter = Formatter.new
|
80
|
+
@composed = 0
|
80
81
|
end
|
81
82
|
|
82
83
|
# Load the specified file path as per a sync.rb, into this
|
@@ -194,6 +195,18 @@ module SyncWrap
|
|
194
195
|
uniq
|
195
196
|
end
|
196
197
|
|
198
|
+
# Creates a new component class with &block as implementation of
|
199
|
+
# its :install method. Convenient for quick one-off glue but will
|
200
|
+
# you move to a real component class once it gets complex?
|
201
|
+
def compose( &block )
|
202
|
+
cc = Class.new(Component) do
|
203
|
+
define_method( :install, &block)
|
204
|
+
end
|
205
|
+
@composed += 1
|
206
|
+
self.class.const_set( "Composed#{@composed}", cc )
|
207
|
+
cc.new
|
208
|
+
end
|
209
|
+
|
197
210
|
# Returns a new component_plan from plan, looking up any Class
|
198
211
|
# string names and using :install for any missing methods:
|
199
212
|
#
|
@@ -279,8 +292,14 @@ module SyncWrap
|
|
279
292
|
private
|
280
293
|
|
281
294
|
def execute_host( host, component_plan = [], opts = {} )
|
295
|
+
comp_roles = opts[ :comp_roles ]
|
296
|
+
comps = if comp_roles && !comp_roles.empty?
|
297
|
+
host.components_in_roles( comp_roles )
|
298
|
+
else
|
299
|
+
host.components
|
300
|
+
end
|
282
301
|
# Important: resolve outside of context
|
283
|
-
comp_methods = resolve_component_methods(
|
302
|
+
comp_methods = resolve_component_methods(comps, component_plan)
|
284
303
|
ctx = Context.new( host, opts )
|
285
304
|
ctx.with do
|
286
305
|
comp_methods.each do |comp, mths|
|
@@ -372,6 +391,7 @@ module SyncWrap
|
|
372
391
|
autoload :Iyyov, 'syncwrap/components/iyyov'
|
373
392
|
autoload :IyyovDaemon, 'syncwrap/components/iyyov_daemon'
|
374
393
|
autoload :JRubyVM, 'syncwrap/components/jruby_vm'
|
394
|
+
autoload :LVMCache, 'syncwrap/components/lvm_cache'
|
375
395
|
autoload :MDRaid, 'syncwrap/components/mdraid'
|
376
396
|
autoload :Network, 'syncwrap/components/network'
|
377
397
|
autoload :OpenJDK, 'syncwrap/components/open_jdk'
|
@@ -392,5 +412,6 @@ module SyncWrap
|
|
392
412
|
# Additional autoloads (optional support)
|
393
413
|
autoload :AmazonEC2, 'syncwrap/amazon_ec2'
|
394
414
|
autoload :GitHelp, 'syncwrap/git_help'
|
415
|
+
autoload :UserData, 'syncwrap/user_data'
|
395
416
|
|
396
417
|
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
[Unit]
|
2
|
+
Description=Iyyov JRuby Job Control Daemon
|
3
|
+
# Introduced in systemd v218+:
|
4
|
+
# AssertFileIsExecutable=<%= jruby_gem_home %>/gems/iyyov-<%= iyyov_version %>-java/init/iyyov
|
5
|
+
|
6
|
+
[Service]
|
7
|
+
User=<%= run_user %>
|
8
|
+
Type=forking
|
9
|
+
ExecStart=<%= jruby_gem_home %>/gems/iyyov-<%= iyyov_version %>-java/init/iyyov jobs.rb
|
10
|
+
WorkingDirectory=<%= run_dir %>/iyyov
|
11
|
+
PIDFile=<%= run_dir %>/iyyov/iyyov.pid
|
12
|
+
Restart=always
|
13
|
+
ExecReload=/usr/bin/touch <%= run_dir %>/iyyov/jobs.rb
|
14
|
+
|
15
|
+
[Install]
|
16
|
+
WantedBy=multi-user.target
|