syncwrap 2.5.1 → 2.6.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.
- 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
|