syncwrap 2.5.1 → 2.6.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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