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.
@@ -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
- dist_service( service_name, 'initdb' )
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: true }.merge( @puma_flags )
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
- rudo( "( cd #{rack_path}", close: ')' ) do
87
- rudo( "if [ -f puma.state -a -e control ]; then", close: else_start ) do
88
- if ( change_key && !changes ) && !always_restart?
89
- rudo 'true' #no-op
90
- else
91
- restart
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
- def restart
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 else_start
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
- [ "#{bundle_install_bin_stubs}/puma" ]
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
- [ "#{bundle_install_bin_stubs}/pumactl" ]
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 SyncWrap::Distro
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 the System V style init.d service
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
- sudo "/sbin/chkconfig #{name} on"
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 via sudo, the service command typically supporting 'start',
85
- # 'stop', 'restart', 'status', etc. arguments.
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
- sudo( [ '/sbin/service', *args ].join( ' ' ) )
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
@@ -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, the System V style, distro specific `service`
64
- # command, typically supporting 'start', 'stop', 'restart',
65
- # 'status', etc. arguments.
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(host.components, component_plan)
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
@@ -0,0 +1,13 @@
1
+ [Unit]
2
+ Description=Puma HTTP Server
3
+ After=network.target
4
+
5
+ [Service]
6
+ Type=simple
7
+ User=<%= run_user %>
8
+ WorkingDirectory=<%= rack_path %>
9
+ ExecStart=<%= puma_start_command %>
10
+ Restart=always
11
+
12
+ [Install]
13
+ WantedBy=multi-user.target