capistrano-systemd-ng 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 7e98a1566194f4df7c6c9db43a9ad46b94dd306e04f951b9bb238e497f61066f
4
+ data.tar.gz: b8316d110262ce8e20c7ab222a28df7a35786e2724091c111ada97de3d4b3e31
5
+ SHA512:
6
+ metadata.gz: 7c18bf423a59970a616448be2d7d955cddb65dcce6754b0e3ab02c90129431628e58a6da3173c067e7f99c52ad888430ea54ed25f0636b8308d61462a7d168f6
7
+ data.tar.gz: 37b19e87c582fb4b28b5187a72bf1b8ca2c5b8ab132b65dd992a8b2ed806808fb4705cf80982d4b0b9286e36f272fa60f5de216ac1ed2452e393ea9369e52c5f
@@ -0,0 +1,13 @@
1
+ version: 2
2
+ updates:
3
+ - package-ecosystem: bundler
4
+ directory: "/"
5
+ schedule:
6
+ interval: daily
7
+ time: '10:00'
8
+ timezone: Asia/Tokyo
9
+ open-pull-requests-limit: 10
10
+ reviewers:
11
+ - minimum2scp
12
+ - nagachika
13
+ - akm
@@ -0,0 +1,33 @@
1
+ #
2
+ # https://help.github.com/en/actions/automating-your-workflow-with-github-actions
3
+ #
4
+
5
+ name: CI
6
+
7
+ on:
8
+ push:
9
+ branches:
10
+ - '**'
11
+
12
+ jobs:
13
+ test:
14
+ name: Test
15
+ runs-on: ubuntu-latest
16
+ strategy:
17
+ matrix:
18
+ ruby-version: [2.7, '3.0', 3.1]
19
+ fail-fast: false
20
+ if: "!contains(github.event.head_commit.message, '[ci skip]')"
21
+ steps:
22
+ # https://github.com/actions/checkout
23
+ - uses: actions/checkout@v2
24
+
25
+ # https://github.com/ruby/setup-ruby
26
+ - uses: ruby/setup-ruby@v1
27
+ with:
28
+ ruby-version: ${{ matrix.ruby-version }}
29
+ bundler-cache: true
30
+
31
+ - name: Test
32
+ run: bundle exec rake spec
33
+
data/.gitignore ADDED
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in capistrano-systemd-ng.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2016 YAMADA Tsuyoshi
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,304 @@
1
+ # capistrano-systemd-ng
2
+
3
+ [![Gem Version](https://badge.fury.io/rb/capistrano-systemd-ng.png)](https://rubygems.org/gems/capistrano-systemd-ng) [![CI](https://github.com/HLFH/capistrano-systemd-ng/actions/workflows/ci.yml/badge.svg)](https://github.com/HLFH/capistrano-systemd-ng/actions/workflows/ci.yml)
4
+
5
+ This gem adds capistrano tasks to control multiple services with systemd.
6
+ This gem supports capistrano > 3.17.0.
7
+
8
+ ## Installation
9
+
10
+ Add this line to your application's Gemfile:
11
+
12
+ ```ruby
13
+ gem 'capistrano-systemd-ng', require: false
14
+ ```
15
+
16
+ And then execute:
17
+
18
+ $ bundle
19
+
20
+ Or install it yourself as:
21
+
22
+ $ gem install capistrano-systemd-ng
23
+
24
+ ## Usage
25
+
26
+ Add these lines to your Capfile:
27
+
28
+ ```ruby
29
+ require "capistrano/systemd/multiservice"
30
+ install_plugin Capistrano::Systemd::MultiService.new_service("example1")
31
+ install_plugin Capistrano::Systemd::MultiService.new_service("example2")
32
+ ```
33
+
34
+ And put `config/systemd/example1.service.erb` (and `config/systemd/example2.service.erb`, ...) like this:
35
+
36
+ ```
37
+ [Unit]
38
+ Description = <%= fetch(:application) %> application server example1
39
+
40
+ [Service]
41
+ Environment = RAILS_ENV=<%= fetch(:rails_env) %>
42
+ Environment = PWD=<%= current_path %>
43
+ WorkingDirectory = <%= current_path %>
44
+ ExecStart = bundle exec some-application-server start
45
+ User = exampleuser
46
+ Group = examplegroup
47
+
48
+ [Install]
49
+ WantedBy = multi-user.target
50
+ ```
51
+
52
+ * see [systemd.service(5)](https://www.freedesktop.org/software/systemd/man/systemd.service.html) for details
53
+ * when `:application` is set to `foo`, this file will be installed as `foo_example1.service` (and `foo_example2.service`, ...)
54
+
55
+ And add these lines to config/deploy.rb if you want to reload/restart services on deploy:
56
+
57
+ ```ruby
58
+ after 'deploy:publishing', 'systemd:example1:restart'
59
+ after 'deploy:publishing', 'systemd:example2:reload-or-restart'
60
+ ```
61
+
62
+ And then deploy.
63
+
64
+ ```shell
65
+ # Upload and install systemd service unit files before deploy
66
+ cap STAGE systemd:example1:setup systemd:example2:setup
67
+
68
+ # Deploy as usual
69
+ cap STAGE deploy
70
+ ```
71
+
72
+ ### User services
73
+
74
+ To have the service installed under your own user rather than root
75
+
76
+ ```ruby
77
+ require "capistrano/systemd/multiservice"
78
+ install_plugin Capistrano::Systemd::MultiService.new_service("example1", service_type: 'user')
79
+ install_plugin Capistrano::Systemd::MultiService.new_service("example2", service_type: 'user')
80
+ ```
81
+
82
+ If using the user service type services will be installed in your users home directory under ``` /.config/systemd/user ```.
83
+ Systemd commands on those services can be run by passing a `--user` flag, e.g. ```systemctl --user list-unit-files```
84
+ Nothing else in setup should require change and Capistrano tasks should remain the same as when installing system services.
85
+
86
+ ## Capistrano Tasks
87
+
88
+ With `install_plugin Capistrano::Systemd::MultiService.new_service("example1")`,
89
+ following tasks are defined.
90
+
91
+ - `systemd:example1:setup`
92
+ - `systemd:example1:remove`
93
+ - `systemd:example1:validate`
94
+ - `systemd:example1:daemon-reload`
95
+ - `systemd:example1:start`
96
+ - `systemd:example1:stop`
97
+ - `systemd:example1:reload`
98
+ - `systemd:example1:restart`
99
+ - `systemd:example1:reload-or-restart`
100
+ - `systemd:example1:enable`
101
+ - `systemd:example1:disable`
102
+
103
+ See lib/capistrano/tasks/systemd/multiservice/system\_service.rake, lib/capistrano/systemd/multiservice/system\_service.rb for details.
104
+
105
+ ## Configuration Variables
106
+
107
+ With `install_plugin Capistrano::Systemd::MultiService.new_service("example1")`,
108
+ following Configuration variables are defined.
109
+
110
+ - `:systemd_example1_role`
111
+ - `:systemd_example1_units_src`
112
+ - `:systemd_example1_units_dir`
113
+ - `:systemd_example1_units_dest`
114
+ - `:systemd_example1_instances`
115
+ - `:systemd_example1_service`
116
+ - `:systemd_example1_instance_services`
117
+
118
+ See lib/capistrano/systemd/multiservice/system\_service.rb for details.
119
+
120
+ ## Examples
121
+
122
+ ### Rails application with unicorn and delayed\_job
123
+
124
+ #### `Capfile`
125
+
126
+ ```ruby
127
+ ## ...snip...
128
+
129
+ require 'capistrano/systemd/multiservice'
130
+ install_plugin Capistrano::Systemd::MultiService.new_service('unicorn')
131
+ install_plugin Capistrano::Systemd::MultiService.new_service('delayed_job')
132
+
133
+ ## ...snip...
134
+ ```
135
+
136
+ #### `config/deploy.rb`
137
+
138
+ ```ruby
139
+ ## ...snip...
140
+
141
+ set :application, 'foo'
142
+
143
+ ## ...snip...
144
+
145
+ set :systemd_delayed_job_instances, ->{ 3.times.to_a }
146
+
147
+ after 'deploy:restart', 'systemd:unicorn:reload-or-restart'
148
+ after 'deploy:restart', 'systemd:delayed_job:restart'
149
+
150
+ after 'deploy:publishing', 'deploy:restart'
151
+
152
+ ## ...snip...
153
+ ```
154
+
155
+ #### `config/systemd/unicorn.service.erb`
156
+
157
+ This file will be installed as `foo_unicorn.service`.
158
+
159
+ ```
160
+ [Unit]
161
+ Description = <%= fetch(:application) %> unicorn rack server
162
+
163
+ [Service]
164
+ Environment = PATH=<%= fetch(:rbenv_path) %>/shims:/usr/local/bin:/usr/bin:/bin
165
+ Environment = RBENV_VERSION=<%= fetch(:rbenv_ruby) %>
166
+ Environment = RBENV_ROOT=<%= fetch(:rbenv_path) %>
167
+ Environment = RAILS_ENV=<%= fetch(:rails_env) %>
168
+ Environment = PWD=<%= current_path %>
169
+
170
+ WorkingDirectory = <%= current_path %>
171
+
172
+ ExecStart = <%= fetch(:rbenv_path) %>/bin/rbenv exec bundle exec unicorn -c <%= current_path %>/config/unicorn.rb
173
+ ExecReload = /bin/kill -USR2 $MAINPID
174
+
175
+ PIDFile = <%= shared_path %>/tmp/pids/unicorn.pid
176
+ KillSignal = SIGQUIT
177
+ KillMode = process
178
+ TimeoutStopSec = 62
179
+ Restart = always
180
+
181
+ User = app-user
182
+ Group = app-group
183
+
184
+ [Install]
185
+ WantedBy = multi-user.target
186
+ ```
187
+
188
+ #### `config/systemd/delayed_job.service.erb`
189
+
190
+ This file will be installed as `foo_delayed_job.service`.
191
+
192
+ ```
193
+ [Unit]
194
+ Description = <%= fetch(:application) %> delayed_job
195
+ Requires = <%= fetch(:"#{prefix}_instance_services").join(" ") %>
196
+
197
+ [Service]
198
+ Type = oneshot
199
+ RemainAfterExit = yes
200
+ ExecStart = /bin/true
201
+ ExecReload = /bin/true
202
+
203
+ [Install]
204
+ WantedBy = multi-user.target
205
+ ```
206
+
207
+ #### `config/systemd/delayed_job@.service.erb`
208
+
209
+ This file will be installed as `foo_delayed_job@.service`, and creates 3 instanced service units
210
+ `foo_delayed_job@0.service`, `foo_delayed_job@1.service`, `foo_delayed_job@2.service`
211
+ because `:systemd_delayed_job_instances` is set to `->{ 3.times.to_a }` in `config/deploy.rb`.
212
+
213
+ ```
214
+ [Unit]
215
+ Description = <%= fetch(:application) %> delayed_job (instance %i)
216
+ PartOf = <%= fetch(:"#{prefix}_service") %>
217
+ ReloadPropagatedFrom = <%= fetch(:"#{prefix}_service") %>
218
+
219
+ [Service]
220
+ Type = forking
221
+
222
+ Environment = PATH=<%= fetch(:rbenv_path) %>/shims:/usr/local/bin:/usr/bin:/bin
223
+ Environment = RBENV_VERSION=<%= fetch(:rbenv_ruby) %>
224
+ Environment = RBENV_ROOT=<%= fetch(:rbenv_path) %>
225
+ Environment = RAILS_ENV=<%= fetch(:rails_env) %>
226
+ Environment = PWD=<%= current_path %>
227
+
228
+ WorkingDirectory = <%= current_path %>
229
+
230
+ ExecStart = <%= fetch(:rbenv_path) %>/bin/rbenv exec bundle exec bin/delayed_job -p <%= fetch(:application) %> -i %i start
231
+ ExecStop = <%= fetch(:rbenv_path) %>/bin/rbenv exec bundle exec bin/delayed_job -p <%= fetch(:application) %> -i %i stop
232
+ ExecReload = /bin/kill -HUP $MAINPID
233
+
234
+ PIDFile = <%= shared_path %>/tmp/pids/delayed_job.%i.pid
235
+ TimeoutStopSec = 22
236
+ Restart = always
237
+
238
+ User = app-user
239
+ Group = app-group
240
+
241
+ [Install]
242
+ WantedBy = multi-user.target
243
+ ```
244
+
245
+ #### `config/unicorn.rb`
246
+
247
+ ```ruby
248
+ shared_path = "/path/to/shared"
249
+
250
+ worker_processes 5
251
+ listen "#{shared_path}/tmp/sockets/unicorn.sock"
252
+ pid "#{shared_path}/tmp/pids/unicorn.pid"
253
+ stderr_path "#{shared_path}/log/unicorn_stderr.log"
254
+ stdout_path "#{shared_path}/log/unicorn_stdout.log"
255
+ preload_app true
256
+
257
+ before_exec do |server|
258
+ ENV["BUNDLE_GEMFILE"] = "/path/to/current/Gemfile"
259
+ end
260
+
261
+ before_fork do |server, worker|
262
+ if defined? ActiveRecord::Base
263
+ ActiveRecord::Base.connection.disconnect!
264
+ end
265
+
266
+ old_pid = "#{server.config[:pid]}.oldbin"
267
+ if old_pid != server.pid
268
+ begin
269
+ sig = (worker.nr + 1) >= server.worker_processes ? :QUIT : :TTOU
270
+ Process.kill(sig, File.read(old_pid).to_i)
271
+ rescue Errno::ENOENT, Errno::ESRCH
272
+ end
273
+ end
274
+
275
+ sleep 1
276
+ end
277
+
278
+ after_fork do |server, worker|
279
+ if defined?(ActiveRecord::Base)
280
+ ActiveRecord::Base.establish_connection
281
+ end
282
+ end
283
+ ```
284
+
285
+ #### Commands to setup systemd services and deploy
286
+
287
+ ```shell
288
+ # Upload and install systemd service unit files before deploy
289
+ cap STAGE systemd:unicorn:setup systemd:delayed_job:setup
290
+
291
+ # Deploy as usual
292
+ cap STAGE deploy
293
+ ```
294
+
295
+ ## Development
296
+
297
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
298
+
299
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
300
+
301
+ ## Contributing
302
+
303
+ Bug reports and pull requests are welcome on GitHub at https://github.com/HLFH/capistrano-systemd-ng.
304
+
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "capistrano/systemd/multiservice"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,29 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'capistrano/systemd/multiservice/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "capistrano-systemd-ng"
8
+ spec.version = Capistrano::Systemd::MultiService::VERSION
9
+ spec.authors = ["Gaspard d'Hautefeuille", "YAMADA Tsuyoshi"]
10
+ spec.email = ["github@dhautefeuille.eu"]
11
+
12
+ spec.summary = %q{Capistrano Plugin to control services by systemd}
13
+ spec.description = %q{Capistrano Plugin to control services by systemd (supports capistrano > 3.17.0)}
14
+ spec.homepage = "https://github.com/HLFH/capistrano-systemd-ng"
15
+ spec.license = "MIT"
16
+
17
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
18
+ f.match(%r{^(test|spec|features)/})
19
+ end
20
+ spec.bindir = "exe"
21
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
22
+ spec.require_paths = ["lib"]
23
+
24
+ spec.add_dependency "capistrano", ">= 3.7.0", "< 3.18.0"
25
+ spec.add_development_dependency "bundler"
26
+ spec.add_development_dependency "rake"
27
+ spec.add_development_dependency "rspec", "~> 3.0"
28
+ spec.add_development_dependency "mocha", "~> 1.2"
29
+ end
@@ -0,0 +1,124 @@
1
+ require "erb"
2
+ require "stringio"
3
+ require "capistrano/plugin"
4
+
5
+ module Capistrano
6
+ module Systemd
7
+ module MultiService
8
+ class SystemService < ::Capistrano::Plugin
9
+ attr_reader :app
10
+
11
+ def initialize(app)
12
+ @app = app
13
+ super()
14
+ end
15
+
16
+ def nsp
17
+ @app.to_sym
18
+ end
19
+
20
+ def prefix
21
+ "systemd_#{@app}"
22
+ end
23
+
24
+ def define_tasks
25
+ eval_rakefile File.expand_path("../../../tasks/systemd/multiservice/system_service.rake", __FILE__)
26
+ end
27
+
28
+ def register_hooks
29
+ after "deploy:check", "systemd:#{nsp}:validate"
30
+ after "systemd:#{nsp}:setup", "systemd:#{nsp}:daemon-reload"
31
+ after "systemd:#{nsp}:setup", "systemd:#{nsp}:enable"
32
+ before "systemd:#{nsp}:remove", "systemd:#{nsp}:disable"
33
+ after "systemd:#{nsp}:remove", "systemd:#{nsp}:daemon-reload"
34
+ end
35
+
36
+ def set_defaults
37
+ set_if_empty :"#{prefix}_role", ->{ :app }
38
+
39
+ set_if_empty :"#{prefix}_units_src", ->{ Dir["config/systemd/#{@app}{,@}.*.erb"].sort }
40
+
41
+ set_if_empty :"#{prefix}_units_dir", ->{ default_units_dir }
42
+
43
+ set_if_empty :"#{prefix}_units_dest", ->{
44
+ fetch(:"#{prefix}_units_src").map{|src|
45
+ "%s/%s_%s" % [ fetch(:"#{prefix}_units_dir"), fetch(:application), File.basename(src, ".erb") ]
46
+ }
47
+ }
48
+
49
+ set_if_empty :"#{prefix}_instances", ->{
50
+ if fetch(:"#{prefix}_units_dest").map{|dst| File.basename(dst) }.find{|f| f =~ /@\.service\z/ }
51
+ 1.times.to_a
52
+ else
53
+ nil
54
+ end
55
+ }
56
+
57
+ set_if_empty :"#{prefix}_service", ->{
58
+ service = fetch(:"#{prefix}_units_dest").map{|dst| File.basename(dst) }.find{|f| f =~ /\.service\z/ && f !~ /@\.service\z/ }
59
+ service || fetch(:"#{prefix}_instance_services")
60
+ }
61
+
62
+ set_if_empty :"#{prefix}_instance_services", ->{
63
+ if fetch(:"#{prefix}_instances")
64
+ fetch(:"#{prefix}_instances").map{|i|
65
+ service_template = fetch(:"#{prefix}_units_dest").map{|dst| File.basename(dst) }.find{|f| f =~ /@\.service\z/ }
66
+ service_template && service_template.sub(/@\.service\z/, "@#{i}.service")
67
+ }
68
+ else
69
+ []
70
+ end
71
+ }
72
+ end
73
+
74
+ def default_units_dir
75
+ "/etc/systemd/system"
76
+ end
77
+
78
+ def setup
79
+ fetch(:"#{prefix}_units_src").zip(fetch(:"#{prefix}_units_dest")).each do |src, dest|
80
+ buf = StringIO.new(ERB.new(File.read(src), nil, 2).result(binding))
81
+ setup_service buf, src, dest
82
+ end
83
+ end
84
+
85
+ def remove
86
+ backend.sudo :rm, '-f', '--', fetch(:"#{prefix}_units_dest")
87
+ end
88
+
89
+ def validate
90
+ fetch(:"#{prefix}_units_dest").each do |dest|
91
+ unless backend.test("[ -f #{dest} ]")
92
+ backend.error "#{dest} not found"
93
+ exit 1
94
+ end
95
+ end
96
+ end
97
+
98
+ def daemon_reload
99
+ systemctl :"daemon-reload"
100
+ end
101
+
102
+ %i[start stop reload restart reload-or-restart enable disable].each do |act|
103
+ define_method act.to_s.tr('-','_') do
104
+ systemctl act, fetch(:"#{prefix}_service")
105
+ end
106
+ end
107
+
108
+ def systemctl(*args)
109
+ args.unshift :sudo, :systemctl
110
+ backend.execute(*args)
111
+ end
112
+
113
+ private
114
+
115
+ def setup_service(buf, src, dest)
116
+ remote_tmp = "#{fetch(:tmp_dir)}/#{File.basename(src, ".erb")}"
117
+ backend.upload! buf, remote_tmp
118
+ backend.sudo :install, '-m 644 -o root -g root -D', remote_tmp, dest
119
+ backend.execute :rm, remote_tmp
120
+ end
121
+ end
122
+ end
123
+ end
124
+ end
@@ -0,0 +1,28 @@
1
+ require_relative './system_service'
2
+
3
+ module Capistrano
4
+ module Systemd
5
+ module MultiService
6
+ class UserService < SystemService
7
+ def systemctl(*args)
8
+ args.unshift :systemctl, '--user'
9
+ backend.execute(*args)
10
+ end
11
+
12
+ def remove
13
+ backend.execute :rm, '-f', '--', fetch(:"#{prefix}_units_dest")
14
+ end
15
+
16
+ def default_units_dir
17
+ "/home/#{fetch(:user)}/.config/systemd/user"
18
+ end
19
+
20
+ protected
21
+
22
+ def setup_service(buf, src, dest)
23
+ backend.upload! buf, dest
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,7 @@
1
+ module Capistrano
2
+ module Systemd
3
+ module MultiService
4
+ VERSION = "0.1.1"
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,23 @@
1
+ require "capistrano/systemd/multiservice/version"
2
+ require "capistrano/systemd/multiservice/system_service"
3
+ require "capistrano/systemd/multiservice/user_service"
4
+
5
+ module Capistrano
6
+ module Systemd
7
+ module MultiService
8
+ SERVICE_TYPES = %w[system user].freeze
9
+
10
+ class ServiceTypeError < RuntimeError; end
11
+
12
+ def self.new_service(app, service_type: 'system')
13
+ service_type = service_type.to_s
14
+ unless SERVICE_TYPES.include?(service_type)
15
+ raise ServiceTypeError,
16
+ "Service type has to be one of #{SERVICE_TYPES}"
17
+ end
18
+
19
+ const_get("#{service_type.capitalize}Service").new(app)
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,28 @@
1
+ # This trick lets us access the Capistrano::Systemd::MultiService plugin within `on` blocks
2
+ svc = self
3
+
4
+ namespace :systemd do
5
+ namespace svc.nsp do
6
+ {
7
+ setup: "Setup %{app} systemd unit file",
8
+ remove: "Remove %{app} systemd unit file",
9
+ validate: "Validate %{app} systemd unit file",
10
+ "daemon-reload": "Run systemctl daemon-reload",
11
+ start: "Run systemctl %{task_name} for %{app}",
12
+ stop: "Run systemctl %{task_name} for %{app}",
13
+ reload: "Run systemctl %{task_name} for %{app}",
14
+ restart: "Run systemctl %{task_name} for %{app}",
15
+ "reload-or-restart": "Run systemctl %{task_name} for %{app}",
16
+ enable: "Run systemctl %{task_name} for %{app}",
17
+ disable: "Run systemctl %{task_name} for %{app}",
18
+ }.each do |task_name, desc_template|
19
+ desc(desc_template % { app: svc.app, task_name: task_name})
20
+ task task_name do
21
+ on roles(fetch(:"#{svc.prefix}_role")) do
22
+ svc.__send__ task_name.to_s.tr('-', '_')
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
28
+
metadata ADDED
@@ -0,0 +1,137 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: capistrano-systemd-ng
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.1
5
+ platform: ruby
6
+ authors:
7
+ - Gaspard d'Hautefeuille
8
+ - YAMADA Tsuyoshi
9
+ autorequire:
10
+ bindir: exe
11
+ cert_chain: []
12
+ date: 2023-06-22 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: capistrano
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - ">="
19
+ - !ruby/object:Gem::Version
20
+ version: 3.7.0
21
+ - - "<"
22
+ - !ruby/object:Gem::Version
23
+ version: 3.18.0
24
+ type: :runtime
25
+ prerelease: false
26
+ version_requirements: !ruby/object:Gem::Requirement
27
+ requirements:
28
+ - - ">="
29
+ - !ruby/object:Gem::Version
30
+ version: 3.7.0
31
+ - - "<"
32
+ - !ruby/object:Gem::Version
33
+ version: 3.18.0
34
+ - !ruby/object:Gem::Dependency
35
+ name: bundler
36
+ requirement: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ type: :development
42
+ prerelease: false
43
+ version_requirements: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ - !ruby/object:Gem::Dependency
49
+ name: rake
50
+ requirement: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ type: :development
56
+ prerelease: false
57
+ version_requirements: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ - !ruby/object:Gem::Dependency
63
+ name: rspec
64
+ requirement: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '3.0'
69
+ type: :development
70
+ prerelease: false
71
+ version_requirements: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '3.0'
76
+ - !ruby/object:Gem::Dependency
77
+ name: mocha
78
+ requirement: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '1.2'
83
+ type: :development
84
+ prerelease: false
85
+ version_requirements: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '1.2'
90
+ description: Capistrano Plugin to control services by systemd (supports capistrano
91
+ > 3.17.0)
92
+ email:
93
+ - github@dhautefeuille.eu
94
+ executables: []
95
+ extensions: []
96
+ extra_rdoc_files: []
97
+ files:
98
+ - ".github/dependabot.yml"
99
+ - ".github/workflows/ci.yml"
100
+ - ".gitignore"
101
+ - ".rspec"
102
+ - Gemfile
103
+ - LICENSE
104
+ - README.md
105
+ - Rakefile
106
+ - bin/console
107
+ - bin/setup
108
+ - capistrano-systemd-ng.gemspec
109
+ - lib/capistrano/systemd/multiservice.rb
110
+ - lib/capistrano/systemd/multiservice/system_service.rb
111
+ - lib/capistrano/systemd/multiservice/user_service.rb
112
+ - lib/capistrano/systemd/multiservice/version.rb
113
+ - lib/capistrano/tasks/systemd/multiservice/system_service.rake
114
+ homepage: https://github.com/HLFH/capistrano-systemd-ng
115
+ licenses:
116
+ - MIT
117
+ metadata: {}
118
+ post_install_message:
119
+ rdoc_options: []
120
+ require_paths:
121
+ - lib
122
+ required_ruby_version: !ruby/object:Gem::Requirement
123
+ requirements:
124
+ - - ">="
125
+ - !ruby/object:Gem::Version
126
+ version: '0'
127
+ required_rubygems_version: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ requirements: []
133
+ rubygems_version: 3.4.14
134
+ signing_key:
135
+ specification_version: 4
136
+ summary: Capistrano Plugin to control services by systemd
137
+ test_files: []