luban 0.5.1 → 0.5.5

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 5d4ff5719088dde2272d1acffdb8f0929872f02c
4
- data.tar.gz: a02e072d9d3760b30c3c6f22f3029cf69b6a95e0
3
+ metadata.gz: 22f7040c1da873d1aa03672d4918506c4c6eef8d
4
+ data.tar.gz: 6df3eeefecd1377d4e0b6db086f57859f08cc5d1
5
5
  SHA512:
6
- metadata.gz: 54678b14d233074638fd1f03950dc37fb3598c71bedd45c3a1426adc8acbcc8c58f1613357dc4e7c87a790bfa66fd960ce6b0e87c968940b204ff43d6f33bb22
7
- data.tar.gz: c93eb97c9383c8e88b1020affe8318cdbe4ad6ae36e7ef3bc2691feb3fd49cab3f874b6f35e3582b567e46b11695e52242b54d2fed8d3a990389fa8f078aee17
6
+ metadata.gz: 299133650c4099b5f8e61f45998d91388b87edfb168676eee5ad07eda8c5e2652c358984e464551bea814826ae01b87eca6326ccaf77ad881e29d63a428c3e05
7
+ data.tar.gz: 9dcb174a692218a5f921af3e58c1b017ec1362b220b9bc19bfecaa13ae6fc1ecb95b6a89d64760f1cbed84bcdcb7ddac46cf3a32ad4108a436461972354b7698
data/CHANGELOG.md CHANGED
@@ -1,5 +1,18 @@
1
1
  # Change log
2
2
 
3
+ ## Version 0.5.5 (WIP)
4
+
5
+ Minor enhancements:
6
+ * Refactored app/service profile templates initialization
7
+ * Refactored Service::Worker to abstract general behavior for Service/Application
8
+ * Refactored Service::Configurator to abstract general configuration for Service/Application
9
+ * Refactored Service::Controller to abstract general control for Service/Application
10
+ * Changed attribute :name to :type in Application::Repository for better naming
11
+ * Changed attribute :release_name to :release_type in Application::Publisher for better naming
12
+ * Removed deploy commands in Service because deploy commands exist ONLY in application level
13
+ * Renamed application Builder to Constructor for better naming convention in Luban
14
+ * Minor refactoring
15
+
3
16
  ## Version 0.5.1 (Jun 24, 2016)
4
17
 
5
18
  Minor enhancements:
@@ -46,11 +46,20 @@ module Luban
46
46
  alias_method :require_package, :package
47
47
 
48
48
  def source(from = nil, **opts)
49
- from.nil? ? @source : (@source = opts.merge(name: 'app', from: from))
49
+ return @source if from.nil?
50
+ @source = opts.merge(type: 'app', from: from)
51
+ if source_version.nil?
52
+ abort "Aborted! Please specify the source version with :tag, :branch or :ref."
53
+ end
54
+ @source
55
+ end
56
+
57
+ def source_version
58
+ @source[:tag] || @source[:branch] || @source[:ref]
50
59
  end
51
60
 
52
61
  def profile(from = nil, **opts)
53
- from.nil? ? @profile : (@profile = opts.merge(name: 'profile', from: from))
62
+ from.nil? ? @profile : (@profile = opts.merge(type: 'profile', from: from))
54
63
  end
55
64
 
56
65
  def password_for(user); parent.password_for(user); end
@@ -64,7 +73,7 @@ module Luban
64
73
  def setup(args:, opts:)
65
74
  show_app_environment
66
75
  promptless_authen(args: args, opts: opts)
67
- build!(args: args, opts: opts)
76
+ setup!(args: args, opts: opts)
68
77
  end
69
78
 
70
79
  def build(args:, opts:)
@@ -118,22 +127,23 @@ module Luban
118
127
 
119
128
  def init_profiles(args:, opts:)
120
129
  show_app_environment
121
- if opts[:app]
122
- init_profile(args: args, opts: opts)
123
- elsif opts[:service].nil?
124
- init_profile(args: args, opts: opts)
125
- init_service_profiles(args: args, opts: opts)
126
- elsif opts[:service].is_a?(TrueClass)
127
- init_service_profiles(args: args, opts: opts)
128
- else
129
- services[opts[:service]].init_profile(args: args, opts: opts)
130
- end
130
+ init_profile(args: args, opts: opts)
131
+ init_service_profiles(args: args, opts: opts)
131
132
  end
132
133
 
133
- def init_profile(args:, opts:); end
134
+ def init_profile(args:, opts:)
135
+ if opts[:app] or opts[:service].nil?
136
+ init_profile!(args: args, opts: opts.merge(default_templates: default_templates))
137
+ end
138
+ end
134
139
 
135
140
  def init_service_profiles(args:, opts:)
136
- services.values.each { |s| s.init_profile(args: args, opts: opts) }
141
+ return if opts[:app]
142
+ if services.has_key?(opts[:service])
143
+ services[opts[:service]].init_profile(args: args, opts: opts)
144
+ else
145
+ services.values.each { |s| s.init_profile(args: args, opts: opts) }
146
+ end
137
147
  end
138
148
 
139
149
  protected
@@ -184,8 +194,8 @@ module Luban
184
194
 
185
195
  def setup_init_profiles
186
196
  _services = services.keys
187
- command :init do
188
- desc 'Initialize deployment application/service profiles'
197
+ task :init do
198
+ desc 'Initialize deployment app/service profiles'
189
199
  switch :app, "Application profile ONLY", short: :a
190
200
  option :service, "Service profile ONLY", short: :s, nullable: true,
191
201
  within: _services.push(nil), type: :symbol
@@ -193,12 +203,18 @@ module Luban
193
203
  end
194
204
  end
195
205
 
206
+ def compose_task_options(opts)
207
+ super.merge(name: 'app').tap do |o|
208
+ o.merge!(version: source_version) if has_source?
209
+ end
210
+ end
211
+
196
212
  def show_app_environment
197
213
  puts "#{display_name} in #{parent.class.name}"
198
214
  end
199
215
 
200
- %i(build destroy cleanup).each do |task|
201
- dispatch_task "#{task}!", to: :builder, as: task
216
+ %i(setup destroy cleanup).each do |task|
217
+ dispatch_task "#{task}!", to: :constructor, as: task
202
218
  end
203
219
 
204
220
  def build_repositories(args:, opts:)
@@ -207,11 +223,12 @@ module Luban
207
223
  end
208
224
 
209
225
  def deploy_profile(args:, opts:)
210
- update_profile!(args: args, opts: opts)
226
+ update_profile(args: args, opts: opts)
211
227
  deploy_profile!(args: args, opts: opts.merge(repository: profile))
212
228
  end
213
229
 
214
- def update_profile!(args:, opts:)
230
+ def update_profile(args:, opts:)
231
+ update_profile!(args: args, opts: opts)
215
232
  services.each_value { |s| s.send(:update_profile, args: args, opts: opts) }
216
233
  end
217
234
 
@@ -230,6 +247,8 @@ module Luban
230
247
 
231
248
  dispatch_task :promptless_authen!, to: :authenticator, as: :promptless_authen
232
249
  dispatch_task :public_key!, to: :authenticator, as: :public_key, locally: true
250
+ dispatch_task :init_profile!, to: :configurator, as: :init_profile, locally: true
251
+ dispatch_task :update_profile!, to: :configurator, as: :update_profile, locally: true
233
252
  dispatch_task :build_repository!, to: :repository, as: :build, locally: true
234
253
  dispatch_task :package_release!, to: :repository, as: :package, locally: true
235
254
  dispatch_task :publish_release!, to: :publisher, as: :publish
@@ -0,0 +1,9 @@
1
+ module Luban
2
+ module Deployment
3
+ class Application
4
+ class Configurator < Worker
5
+ include Luban::Deployment::Service::Configurator::Base
6
+ end
7
+ end
8
+ end
9
+ end
@@ -1,9 +1,7 @@
1
1
  module Luban
2
2
  module Deployment
3
3
  class Application
4
- class Builder < Luban::Deployment::Worker::Base
5
- include Luban::Deployment::Worker::Paths::Remote
6
-
4
+ class Constructor < Worker
7
5
  def envrc_template_file
8
6
  @envrc_template_file ||= find_template_file("envrc.erb")
9
7
  end
@@ -12,7 +10,7 @@ module Luban
12
10
  @unset_envrc_template_file ||= find_template_file("unset_envrc.erb")
13
11
  end
14
12
 
15
- def build
13
+ def setup
16
14
  bootstrap
17
15
  create_envrc_files
18
16
  end
@@ -0,0 +1,9 @@
1
+ module Luban
2
+ module Deployment
3
+ class Application
4
+ class Controller < Worker
5
+ include Luban::Deployment::Service::Controller::Base
6
+ end
7
+ end
8
+ end
9
+ end
@@ -1,10 +1,8 @@
1
1
  module Luban
2
2
  module Deployment
3
3
  class Application
4
- class Publisher < Luban::Deployment::Worker::Base
5
- include Luban::Deployment::Worker::Paths::Remote
6
-
7
- def release_name; task.opts.release[:name]; end
4
+ class Publisher < Worker
5
+ def release_type; task.opts.release[:type]; end
8
6
  def release_tag; task.opts.release[:tag]; end
9
7
  def release_package_path; task.opts.release[:path]; end
10
8
  def release_md5; task.opts.release[:md5]; end
@@ -13,15 +11,15 @@ module Luban
13
11
  def gems_source; bundled_gems[:gems_cache]; end
14
12
  def gems; bundled_gems[:gems]; end
15
13
 
16
- def publish_app?; release_name == 'app'; end
17
- def publish_profile?; release_name == 'profile'; end
14
+ def publish_app?; release_type == 'app'; end
15
+ def publish_profile?; release_type == 'profile'; end
18
16
 
19
17
  def display_name
20
- @display_name ||= "#{application} #{release_name} (release: #{release_tag})"
18
+ @display_name ||= "#{application} #{release_type} (release: #{release_tag})"
21
19
  end
22
20
 
23
21
  def releases_path
24
- @releases_path ||= super.join(release_name)
22
+ @releases_path ||= super.join(release_type)
25
23
  end
26
24
 
27
25
  def release_path
@@ -119,7 +117,7 @@ module Luban
119
117
  end
120
118
 
121
119
  def create_symlinks
122
- send("create_#{release_name}_symlinks")
120
+ send("create_#{release_type}_symlinks")
123
121
  create_shared_symlinks_for(:directory, linked_dirs)
124
122
  create_shared_symlinks_for(:directory, bundle_linked_dirs) if file?(gemfile)
125
123
  end
@@ -136,7 +134,7 @@ module Luban
136
134
  end
137
135
 
138
136
  def create_release_symlink(target_dir)
139
- assure_symlink(release_path, target_dir.join(release_name))
137
+ assure_symlink(release_path, target_dir.join(release_type))
140
138
  end
141
139
 
142
140
  def create_shared_symlinks_for(type, linked_paths)
@@ -7,7 +7,7 @@ module Luban
7
7
 
8
8
  DefaultRevisionSize = 12
9
9
 
10
- attr_reader :name
10
+ attr_reader :type
11
11
  attr_reader :from
12
12
  attr_reader :scm
13
13
  attr_reader :revision
@@ -23,11 +23,11 @@ module Luban
23
23
  end
24
24
 
25
25
  def clone_path
26
- @clone_path ||= workspace_path.join('repositories').join(name)
26
+ @clone_path ||= workspace_path.join('repositories').join(type)
27
27
  end
28
28
 
29
29
  def releases_path
30
- @releases_path ||= workspace_path.join('releases').join(name)
30
+ @releases_path ||= workspace_path.join('releases').join(type)
31
31
  end
32
32
 
33
33
  def release_package_path
@@ -47,7 +47,7 @@ module Luban
47
47
  end
48
48
 
49
49
  def release_prefix
50
- @release_prefix ||= "#{stage}-#{project}-#{application}-#{name}"
50
+ @release_prefix ||= "#{stage}-#{project}-#{application}-#{type}"
51
51
  end
52
52
 
53
53
  def release_tag
@@ -75,17 +75,17 @@ module Luban
75
75
  assure_dirs(clone_path, releases_path)
76
76
  if cloned? and !force?
77
77
  update_revision
78
- update_result "Skipped! Local #{name} repository has been built ALREADY.", status: :skipped
78
+ update_result "Skipped! Local #{type} repository has been built ALREADY.", status: :skipped
79
79
  else
80
80
  if available?
81
81
  if build!
82
82
  update_revision
83
- update_result "Successfully built local #{name} repository."
83
+ update_result "Successfully built local #{type} repository."
84
84
  else
85
- update_result "FAILED to build local #{name} repository!", status: :failed, level: :error
85
+ update_result "FAILED to build local #{type} repository!", status: :failed, level: :error
86
86
  end
87
87
  else
88
- update_result "Aborted! Remote #{name} repository is NOT available.", status: :failed, level: :error
88
+ update_result "Aborted! Remote #{type} repository is NOT available.", status: :failed, level: :error
89
89
  end
90
90
  end
91
91
  end
@@ -94,16 +94,16 @@ module Luban
94
94
  if cloned?
95
95
  if package!
96
96
  cleanup_releases
97
- update_result "Successfully package local #{name} repository to #{release_package_path}.",
98
- release: { name: name, tag: release_tag,
97
+ update_result "Successfully package local #{type} repository to #{release_package_path}.",
98
+ release: { type: type, tag: release_tag,
99
99
  path: release_package_path,
100
100
  md5: md5_for_file(release_package_path),
101
101
  bundled_gems: bundle_gems }
102
102
  else
103
- update_result "FAILED to package local #{name} repository!", status: :failed, level: :error
103
+ update_result "FAILED to package local #{type} repository!", status: :failed, level: :error
104
104
  end
105
105
  else
106
- update_result "Aborted! Local #{name} package is NOT built yet!", status: :failed, level: :error
106
+ update_result "Aborted! Local #{type} package is NOT built yet!", status: :failed, level: :error
107
107
  end
108
108
  end
109
109
 
@@ -0,0 +1,22 @@
1
+ module Luban
2
+ module Deployment
3
+ class Application
4
+ class Worker < Luban::Deployment::Worker::Base
5
+ include Luban::Deployment::Worker::Paths::Remote
6
+ include Luban::Deployment::Service::Worker::Base
7
+
8
+ def service_name
9
+ @service_name ||= task.opts.name
10
+ end
11
+
12
+ def service_version
13
+ @service_version ||= task.opts.version
14
+ end
15
+
16
+ def service_full_name
17
+ @service_full_name ||= "#{service_name}-#{service_version}"
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -1,5 +1,9 @@
1
1
  require_relative 'application/base'
2
+ require_relative 'application/worker'
2
3
  require_relative 'application/authenticator'
3
- require_relative 'application/builder'
4
+ require_relative 'application/constructor'
4
5
  require_relative 'application/repository'
5
6
  require_relative 'application/publisher'
7
+ require_relative 'application/configurator'
8
+ require_relative 'application/controller'
9
+
@@ -208,6 +208,12 @@ module Luban
208
208
  locally ? result.first[:__return__] : result
209
209
  end
210
210
 
211
+ def default_templates_path; end
212
+
213
+ def default_templates
214
+ default_templates_path.nil? ? [] : default_templates_path.children
215
+ end
216
+
211
217
  protected
212
218
 
213
219
  def on_configure
@@ -217,6 +223,7 @@ module Luban
217
223
  load_configuration
218
224
  validate_parameters
219
225
  load_libraries
226
+ include_default_templates_path unless default_templates_path.nil?
220
227
  setup_cli
221
228
  end
222
229
 
@@ -249,6 +256,14 @@ module Luban
249
256
 
250
257
  def load_libraries; end
251
258
 
259
+ def include_default_templates_path
260
+ if default_templates_path.is_a?(Pathname)
261
+ default_templates_paths.unshift(default_templates_path)
262
+ else
263
+ abort "Aborted! Default templates path for #{self.class.name} MUST be a Pathname."
264
+ end
265
+ end
266
+
252
267
  def setup_cli
253
268
  setup_descriptions
254
269
  setup_tasks
@@ -2,11 +2,10 @@ module Luban
2
2
  module Deployment
3
3
  module Service
4
4
  class Base < Luban::Deployment::Package::Base
5
- include Luban::Deployment::Command::Tasks::Deploy
6
5
  include Luban::Deployment::Command::Tasks::Control
7
6
 
8
- def self.service_action(name, dispatch_to: nil, locally: false, &blk)
9
- define_method(name) do |args:, opts:|
7
+ def self.service_action(action, dispatch_to: nil, as: action, locally: false, &blk)
8
+ define_method(action) do |args:, opts:|
10
9
  if current_version
11
10
  send("#{__method__}!", args: args, opts: opts.merge(version: current_version))
12
11
  else
@@ -14,64 +13,30 @@ module Luban
14
13
  end
15
14
  end
16
15
  unless dispatch_to.nil?
17
- dispatch_task "#{name}!", to: dispatch_to, as: name, locally: locally, &blk
18
- protected "#{name}!"
16
+ dispatch_task "#{action}!", to: dispatch_to, as: as, locally: locally, &blk
17
+ protected "#{action}!"
19
18
  end
20
19
  end
21
20
 
22
21
  Luban::Deployment::Command::Tasks::Control::Actions.each do |action|
23
22
  service_action action, dispatch_to: :controller
24
23
  end
25
- service_action :update_profile, dispatch_to: :configurator, locally: true
26
-
27
- def has_templates?
28
- respond_to?(:default_templates_path, true)
24
+ %i(init_profile update_profile).each do |action|
25
+ service_action action, dispatch_to: :configurator, locally: true
29
26
  end
30
27
 
28
+ alias_method :orig_init_profile, :init_profile
29
+
31
30
  def init_profile(args:, opts:)
32
- return unless has_templates?
33
- require 'fileutils'
34
- puts " Initializing #{name} profile"
35
- templates_path = config_finder[:application].profile_templates_path.join(name.to_s)
36
- profile_path = config_finder[:application].stage_profile_path.join(name.to_s)
37
- [templates_path, profile_path].each { |p| FileUtils.mkdir(p) unless p.directory? }
38
- init_profile_templates.each do |src_path|
39
- next unless src_path.file?
40
- dst_path = (src_path.extname == '.erb' ? templates_path : profile_path).
41
- join(src_path.basename)
42
- print " - #{dst_path.basename}"
43
- if dst_path.file?
44
- puts " [skipped]"
45
- else
46
- FileUtils.cp(src_path, dst_path)
47
- puts " [created]"
48
- end
49
- end
31
+ orig_init_profile(args: args, opts: opts.merge(default_templates: default_templates))
50
32
  end
51
33
 
52
34
  protected
53
35
 
54
- def on_configure
55
- super
56
- include_default_templates_path if has_templates?
57
- end
58
-
59
- def include_default_templates_path
60
- if default_templates_path.is_a?(Pathname)
61
- default_templates_paths.unshift(default_templates_path)
62
- else
63
- abort "Aborted! Default templates path for #{self.class.name} MUST be a Pathname."
64
- end
65
- end
66
-
67
36
  def set_parameters
68
37
  super
69
38
  linked_dirs.push('log', 'pids')
70
39
  end
71
-
72
- def init_profile_templates
73
- default_templates_path.children
74
- end
75
40
  end
76
41
  end
77
42
  end
@@ -2,55 +2,87 @@ module Luban
2
2
  module Deployment
3
3
  module Service
4
4
  class Configurator < Worker
5
- def stage_profile_path
6
- @stage_profile_path ||=
7
- config_finder[:application].stage_profile_path.join(service_name)
8
- end
5
+ module Base
6
+ def stage_profile_path
7
+ @stage_profile_path ||=
8
+ config_finder[:application].stage_profile_path.join(service_name)
9
+ end
9
10
 
10
- def profile_templates_path
11
- @profile_templates_path ||=
12
- config_finder[:application].profile_templates_path.join(service_name)
13
- end
11
+ def profile_templates_path
12
+ @profile_templates_path ||=
13
+ config_finder[:application].profile_templates_path.join(service_name)
14
+ end
14
15
 
15
- def stage_profile_templates_path
16
- @stage_profile_templates_path ||=
17
- config_finder[:application].stage_profile_templates_path.join(service_name)
18
- end
16
+ def stage_profile_templates_path
17
+ @stage_profile_templates_path ||=
18
+ config_finder[:application].stage_profile_templates_path.join(service_name)
19
+ end
19
20
 
20
- def profile_templates(format: "erb")
21
- return @profile_templates unless @profile_templates.nil?
22
- @profile_templates = []
23
- [profile_templates_path, stage_profile_templates_path].each do |path|
24
- Dir.chdir(path) { @profile_templates |= Dir["**/*.#{format}"] } if path.directory?
21
+ def profile_templates(format: "erb")
22
+ return @profile_templates unless @profile_templates.nil?
23
+ @profile_templates = []
24
+ [profile_templates_path, stage_profile_templates_path].each do |path|
25
+ Dir.chdir(path) { @profile_templates |= Dir["**/*.#{format}"] } if path.directory?
26
+ end
27
+ @profile_templates
25
28
  end
26
- @profile_templates
27
- end
28
29
 
29
- def update_profile
30
- assure_dirs(stage_profile_path)
31
- render_profile
32
- update_logrotate_files
33
- end
30
+ def default_templates; task.opts.default_templates; end
34
31
 
35
- protected
32
+ def init_profile
33
+ return if default_templates.empty?
34
+ puts " Initializing #{service_name} profile"
35
+ assure_dirs(profile_templates_path, stage_profile_path)
36
+ upload_profile_templates
37
+ end
36
38
 
37
- def render_profile
38
- profile_templates.each { |template_file| render_profile_by_template(template_file) }
39
- end
39
+ def update_profile
40
+ assure_dirs(stage_profile_path)
41
+ render_profile
42
+ update_logrotate_files
43
+ end
40
44
 
41
- def render_profile_by_template(template_file)
42
- profile_file = stage_profile_path.join(template_file).sub_ext('')
43
- assure_dirs(profile_file.dirname)
44
- upload_by_template(file_to_upload: profile_file,
45
- template_file: find_template_file(File.join(service_name, template_file)),
46
- auto_revision: true)
47
- end
45
+ protected
48
46
 
49
- def update_logrotate_files
50
- if file?(stage_profile_path.join(logrotate_file_name))
51
- logrotate_files.push(logrotate_file_path)
47
+ def upload_profile_templates
48
+ default_templates.each do |src_path|
49
+ next unless file?(src_path)
50
+ basename = src_path.basename
51
+ dst_path = if src_path.extname == '.erb'
52
+ profile_templates_path
53
+ else
54
+ stage_profile_path
55
+ end.join(basename)
56
+ print " - #{basename}"
57
+ if file?(dst_path)
58
+ puts " [skipped]"
59
+ else
60
+ upload!(src_path, dst_path)
61
+ puts " [created]"
62
+ end
63
+ end
64
+ end
65
+
66
+ def render_profile
67
+ profile_templates.each { |template_file| render_profile_by_template(template_file) }
68
+ end
69
+
70
+ def render_profile_by_template(template_file)
71
+ profile_file = stage_profile_path.join(template_file).sub_ext('')
72
+ assure_dirs(profile_file.dirname)
73
+ upload_by_template(file_to_upload: profile_file,
74
+ template_file: find_template_file(File.join(service_name, template_file)),
75
+ auto_revision: true)
76
+ end
77
+
78
+ def update_logrotate_files
79
+ if file?(stage_profile_path.join(logrotate_file_name))
80
+ logrotate_files.push(logrotate_file_path)
81
+ end
52
82
  end
53
83
  end
84
+
85
+ include Base
54
86
  end
55
87
  end
56
88
  end
@@ -2,210 +2,214 @@ module Luban
2
2
  module Deployment
3
3
  module Service
4
4
  class Controller < Worker
5
- def pid
6
- capture(:cat, "#{pid_file_path} 2>/dev/null")
7
- end
8
-
9
- def process_started?
10
- !!process_grep.keys.first
11
- end
12
-
13
- def process_stopped?
14
- !process_started?
15
- end
16
-
17
- def pid_file_orphaned?
18
- process_stopped? and pid_file_exists?
19
- end
5
+ module Base
6
+ def pid
7
+ capture(:cat, "#{pid_file_path} 2>/dev/null")
8
+ end
20
9
 
21
- def pid_file_missing?
22
- process_started? and !pid_file_exists?
23
- end
10
+ def process_started?
11
+ !!process_grep.keys.first
12
+ end
24
13
 
25
- def pid_file_exists?
26
- file?(pid_file_path, "-s") # file is NOT zero size
27
- end
14
+ def process_stopped?
15
+ !process_started?
16
+ end
28
17
 
29
- %i(process_pattern start_command stop_command).each do |m|
30
- define_method(m) do
31
- raise NotImplementedError, "#{self.class.name}##{__method__} is an abstract method."
18
+ def pid_file_orphaned?
19
+ process_stopped? and pid_file_exists?
32
20
  end
33
- end
34
21
 
35
- def monitor_executable
36
- @monitor_executable ||= env_path.join("#{stage}.#{process_monitor[:env]}").
37
- join('bin').join(process_monitor[:name])
38
- end
22
+ def pid_file_missing?
23
+ process_started? and !pid_file_exists?
24
+ end
39
25
 
40
- def monitor_command
41
- @monitor_command ||= "#{monitor_executable} monitor #{service_entry}"
42
- end
26
+ def pid_file_exists?
27
+ file?(pid_file_path, "-s") # file is NOT zero size
28
+ end
43
29
 
44
- def unmonitor_command
45
- @unmonitor_command ||= "#{monitor_executable} unmonitor #{service_entry}"
46
- end
30
+ %i(process_pattern start_command stop_command).each do |m|
31
+ define_method(m) do
32
+ raise NotImplementedError, "#{self.class.name}##{__method__} is an abstract method."
33
+ end
34
+ end
47
35
 
48
- def start_process
49
- if process_started?
50
- update_result "Skipped! Already started #{package_full_name}", status: :skipped
51
- return
36
+ def monitor_executable
37
+ @monitor_executable ||= env_path.join("#{stage}.#{process_monitor[:env]}").
38
+ join('bin').join(process_monitor[:name])
52
39
  end
53
40
 
54
- output = start_process!
55
- if check_until { process_started? }
56
- update_result "Start #{package_full_name}: [OK] #{output}"
57
- monitor_process
58
- else
59
- remove_orphaned_pid_file
60
- update_result "Start #{package_full_name}: [FAILED] #{output}",
61
- status: :failed, level: :error
41
+ def monitor_command
42
+ @monitor_command ||= "#{monitor_executable} monitor #{service_entry}"
62
43
  end
63
- end
64
44
 
65
- def stop_process
66
- if process_stopped?
67
- update_result "Skipped! Already stopped #{package_full_name}", status: :skipped
68
- return
45
+ def unmonitor_command
46
+ @unmonitor_command ||= "#{monitor_executable} unmonitor #{service_entry}"
69
47
  end
70
48
 
71
- unmonitor_process
72
- output = stop_process! || 'OK'
73
- if check_until { process_stopped? }
74
- update_result "Stop #{package_full_name}: [OK] #{output}"
75
- else
76
- remove_orphaned_pid_file
77
- update_result "Stop #{package_full_name}: [FAILED] #{output}",
78
- status: :failed, level: :error
49
+ def start_process
50
+ if process_started?
51
+ update_result "Skipped! Already started #{service_full_name}", status: :skipped
52
+ return
53
+ end
54
+
55
+ output = start_process!
56
+ if check_until { process_started? }
57
+ update_result "Start #{service_full_name}: [OK] #{output}"
58
+ monitor_process
59
+ else
60
+ remove_orphaned_pid_file
61
+ update_result "Start #{service_full_name}: [FAILED] #{output}",
62
+ status: :failed, level: :error
63
+ end
79
64
  end
80
- end
81
65
 
82
- def restart_process
83
- if process_started?
66
+ def stop_process
67
+ if process_stopped?
68
+ update_result "Skipped! Already stopped #{service_full_name}", status: :skipped
69
+ return
70
+ end
71
+
84
72
  unmonitor_process
85
- output = stop_process!
73
+ output = stop_process! || 'OK'
86
74
  if check_until { process_stopped? }
87
- info "Stop #{package_full_name}: [OK] #{output}"
75
+ update_result "Stop #{service_full_name}: [OK] #{output}"
88
76
  else
89
77
  remove_orphaned_pid_file
90
- update_result "Stop #{package_full_name}: [FAILED] #{output}",
78
+ update_result "Stop #{service_full_name}: [FAILED] #{output}",
91
79
  status: :failed, level: :error
92
- return
93
80
  end
94
81
  end
95
82
 
96
- output = start_process!
97
- if check_until { process_started? }
98
- update_result "Restart #{package_full_name}: [OK] #{output}"
99
- monitor_process
100
- else
101
- remove_orphaned_pid_file
102
- update_result "Restart #{package_full_name}: [FAILED] #{output}",
103
- status: :failed, level: :error
104
- end
105
- end
106
-
107
- def check_process
108
- update_result check_process!
109
- end
83
+ def restart_process
84
+ if process_started?
85
+ unmonitor_process
86
+ output = stop_process!
87
+ if check_until { process_stopped? }
88
+ info "Stop #{service_full_name}: [OK] #{output}"
89
+ else
90
+ remove_orphaned_pid_file
91
+ update_result "Stop #{service_full_name}: [FAILED] #{output}",
92
+ status: :failed, level: :error
93
+ return
94
+ end
95
+ end
110
96
 
111
- def kill_process
112
- if process_stopped?
113
- update_result "Skipped! Already stopped #{package_full_name}", status: :skipped
114
- return
97
+ output = start_process!
98
+ if check_until { process_started? }
99
+ update_result "Restart #{service_full_name}: [OK] #{output}"
100
+ monitor_process
101
+ else
102
+ remove_orphaned_pid_file
103
+ update_result "Restart #{service_full_name}: [FAILED] #{output}",
104
+ status: :failed, level: :error
105
+ end
115
106
  end
116
107
 
117
- unmonitor_process
118
- output = kill_process!
119
- if check_until { process_stopped? }
120
- remove_orphaned_pid_file
121
- update_result "Kill #{package_full_name}: [OK] #{output}"
122
- else
123
- update_result "Kill #{package_full_name}: [FAILED] #{output}"
108
+ def check_process
109
+ update_result check_process!
124
110
  end
125
- end
126
111
 
127
- def process_monitor_defined?
128
- !process_monitor[:name].nil?
129
- end
112
+ def kill_process
113
+ if process_stopped?
114
+ update_result "Skipped! Already stopped #{service_full_name}", status: :skipped
115
+ return
116
+ end
130
117
 
131
- def monitor_process
132
- if process_monitor_defined?
133
- if monitor_process!
134
- info "Turned on process monitor for #{service_entry}"
118
+ unmonitor_process
119
+ output = kill_process!
120
+ if check_until { process_stopped? }
121
+ remove_orphaned_pid_file
122
+ update_result "Kill #{service_full_name}: [OK] #{output}"
135
123
  else
136
- info "Failed to turn on process monitor for #{service_entry}"
124
+ update_result "Kill #{service_full_name}: [FAILED] #{output}"
137
125
  end
138
126
  end
139
- end
140
127
 
141
- def unmonitor_process
142
- if process_monitor_defined?
143
- if unmonitor_process!
144
- info "Turned off process monitor for #{service_entry}"
145
- else
146
- info "Failed to turn off process monitor for #{service_entry}"
128
+ def process_monitor_defined?
129
+ !process_monitor[:name].nil?
130
+ end
131
+
132
+ def monitor_process
133
+ if process_monitor_defined?
134
+ if monitor_process!
135
+ info "Turned on process monitor for #{service_entry}"
136
+ else
137
+ info "Failed to turn on process monitor for #{service_entry}"
138
+ end
139
+ end
140
+ end
141
+
142
+ def unmonitor_process
143
+ if process_monitor_defined?
144
+ if unmonitor_process!
145
+ info "Turned off process monitor for #{service_entry}"
146
+ else
147
+ info "Failed to turn off process monitor for #{service_entry}"
148
+ end
147
149
  end
148
150
  end
149
- end
150
151
 
151
- def default_pending_seconds; 30; end
152
- def default_pending_interval; 1; end
152
+ def default_pending_seconds; 30; end
153
+ def default_pending_interval; 1; end
153
154
 
154
- protected
155
+ protected
155
156
 
156
- def check_until(pending_seconds: default_pending_seconds,
157
- pending_interval: default_pending_interval)
158
- succeeded = false
159
- (pending_seconds/pending_interval).times do
160
- sleep pending_interval
161
- break if (succeeded = yield)
157
+ def check_until(pending_seconds: default_pending_seconds,
158
+ pending_interval: default_pending_interval)
159
+ succeeded = false
160
+ (pending_seconds/pending_interval).times do
161
+ sleep pending_interval
162
+ break if (succeeded = yield)
163
+ end
164
+ succeeded
162
165
  end
163
- succeeded
164
- end
165
166
 
166
- def start_process!
167
- capture("#{start_command} 2>&1")
168
- end
167
+ def start_process!
168
+ capture("#{start_command} 2>&1")
169
+ end
169
170
 
170
- def stop_process!
171
- capture("#{stop_command} 2>&1")
172
- end
171
+ def stop_process!
172
+ capture("#{stop_command} 2>&1")
173
+ end
173
174
 
174
- def check_process!
175
- if pid_file_missing?
176
- "#{package_full_name}: started but PID file does NOT exist - #{pid_file_path}"
177
- elsif process_started?
178
- "#{package_full_name}: started (PID #{pid})"
179
- elsif pid_file_orphaned?
180
- "#{package_full_name}: stopped but PID file exists - #{pid_file_path}"
181
- else
182
- "#{package_full_name}: stopped"
175
+ def check_process!
176
+ if pid_file_missing?
177
+ "#{service_full_name}: started but PID file does NOT exist - #{pid_file_path}"
178
+ elsif process_started?
179
+ "#{service_full_name}: started (PID #{pid})"
180
+ elsif pid_file_orphaned?
181
+ "#{service_full_name}: stopped but PID file exists - #{pid_file_path}"
182
+ else
183
+ "#{service_full_name}: stopped"
184
+ end
183
185
  end
184
- end
185
186
 
186
- def kill_process!(pattern = process_pattern)
187
- capture(:pkill, "-9 -f \"#{pattern}\"")
188
- end
187
+ def kill_process!(pattern = process_pattern)
188
+ capture(:pkill, "-9 -f \"#{pattern}\"")
189
+ end
189
190
 
190
- def process_grep(pattern = process_pattern)
191
- capture(:pgrep, "-l -f \"#{pattern}\" 2>/dev/null").split.inject({}) do |h, p|
192
- pid, pname = p.split(' ', 2)
193
- h[pid] = pname
194
- h
191
+ def process_grep(pattern = process_pattern)
192
+ capture(:pgrep, "-l -f \"#{pattern}\" 2>/dev/null").split.inject({}) do |h, p|
193
+ pid, pname = p.split(' ', 2)
194
+ h[pid] = pname
195
+ h
196
+ end
195
197
  end
196
- end
197
198
 
198
- def remove_orphaned_pid_file
199
- rm(pid_file_path) if pid_file_orphaned?
200
- end
199
+ def remove_orphaned_pid_file
200
+ rm(pid_file_path) if pid_file_orphaned?
201
+ end
201
202
 
202
- def monitor_process!
203
- test("#{monitor_command} 2>&1")
204
- end
203
+ def monitor_process!
204
+ test("#{monitor_command} 2>&1")
205
+ end
205
206
 
206
- def unmonitor_process!
207
- test("#{unmonitor_command} 2>&1")
207
+ def unmonitor_process!
208
+ test("#{unmonitor_command} 2>&1")
209
+ end
208
210
  end
211
+
212
+ include Base
209
213
  end
210
214
  end
211
215
  end
@@ -2,8 +2,8 @@ module Luban
2
2
  module Deployment
3
3
  module Service
4
4
  class Installer < Luban::Deployment::Package::Installer
5
- include Paths
5
+ include Worker::Base
6
6
  end
7
7
  end
8
8
  end
9
- end
9
+ end
@@ -1,40 +1,70 @@
1
1
  module Luban
2
2
  module Deployment
3
3
  module Service
4
- module Paths
5
- include Luban::Deployment::Worker::Paths::Remote::Service
4
+ class Worker < Luban::Deployment::Package::Worker
5
+ module Base
6
+ def service_name
7
+ @service_name ||= package_name
8
+ end
6
9
 
7
- def service_name
8
- @service_name ||= package_name.downcase
9
- end
10
+ def service_version
11
+ @service_version ||= package_version
12
+ end
10
13
 
11
- def service_entry
12
- @service_entry ||= "#{env_name.gsub('/', '.')}.#{service_name}"
13
- end
14
+ def service_full_name
15
+ @service_full_name ||= package_full_name
16
+ end
14
17
 
15
- def profile_path
16
- @profile_path ||= super.join(service_name)
17
- end
18
+ def service_entry
19
+ @service_entry ||= "#{env_name.gsub('/', '.')}.#{service_name}"
20
+ end
18
21
 
19
- def control_file_name
20
- @control_file_name ||= "#{service_name}.conf"
21
- end
22
+ def profile_path
23
+ @profile_path ||= shared_path.join('profile').join(service_name)
24
+ end
22
25
 
23
- def logrotate_file_name
24
- @logrotate_file_name ||= "#{service_name}.logrotate"
25
- end
26
+ def log_path
27
+ @log_path ||= shared_path.join('log')
28
+ end
26
29
 
27
- def pid_file_name
28
- @pid_file_name ||= "#{service_name}.pid"
29
- end
30
+ def log_file_path
31
+ @log_file_path ||= log_path.join(log_file_name)
32
+ end
33
+
34
+ def log_file_name
35
+ @log_file_name ||= "#{service_name}.log"
36
+ end
30
37
 
31
- def log_file_name
32
- @log_file_name ||= "#{service_name}.log"
38
+ def pids_path
39
+ @pids_path ||= shared_path.join('pids')
40
+ end
41
+
42
+ def pid_file_path
43
+ @pid_file_path ||= pids_path.join(pid_file_name)
44
+ end
45
+
46
+ def pid_file_name
47
+ @pid_file_name ||= "#{service_name}.pid"
48
+ end
49
+
50
+ def control_file_path
51
+ @control_file_path ||= profile_path.join(control_file_name)
52
+ end
53
+
54
+ def control_file_name
55
+ @control_file_name ||= "#{service_name}.conf"
56
+ end
57
+
58
+ def logrotate_file_path
59
+ @logrotate_file_path ||= profile_path.join(logrotate_file_name)
60
+ end
61
+
62
+ def logrotate_file_name
63
+ @logrotate_file_name ||= "#{service_name}.logrotate"
64
+ end
33
65
  end
34
- end
35
66
 
36
- class Worker < Luban::Deployment::Package::Worker
37
- include Paths
67
+ include Base
38
68
  end
39
69
  end
40
70
  end
@@ -1,5 +1,5 @@
1
1
  require_relative 'cli/command'
2
2
  require_relative 'cli/project'
3
- require_relative 'cli/application'
4
3
  require_relative 'cli/package'
5
4
  require_relative 'cli/service'
5
+ require_relative 'cli/application'
@@ -6,9 +6,43 @@ module Luban
6
6
  module Generator
7
7
  using Luban::CLI::CoreRefinements
8
8
 
9
+ module Utils
10
+ def mkdir(path)
11
+ if path.directory?
12
+ puts " [skipped]"
13
+ else
14
+ FileUtils.mkdir(path)
15
+ puts " [created]"
16
+ end
17
+ end
18
+
19
+ def copy_file(src_path, dst_path)
20
+ if dst_path.file?
21
+ puts " [skipped]"
22
+ else
23
+ FileUtils.cp(src_path, dst_path)
24
+ puts " [created]"
25
+ end
26
+ end
27
+
28
+ def render_file(template_path, output_path, context: binding)
29
+ if output_path.file?
30
+ puts " [skipped]"
31
+ else
32
+ require 'erb'
33
+ File.open(output_path, 'w') do |f|
34
+ f.write ERB.new(File.read(template_path), nil, '<>').result(context)
35
+ end
36
+ puts " [created]"
37
+ end
38
+ end
39
+ end
40
+
9
41
  module Base
10
42
  protected
11
43
 
44
+ include Utils
45
+
12
46
  def skeletons_path
13
47
  @skeletons_path ||=
14
48
  Pathname.new(__FILE__).dirname.join('..').join('templates').realpath
@@ -52,36 +86,6 @@ module Luban
52
86
  end
53
87
  end
54
88
 
55
- def mkdir(path)
56
- if path.directory?
57
- puts " [skipped]"
58
- else
59
- FileUtils.mkdir(path)
60
- puts " [created]"
61
- end
62
- end
63
-
64
- def copy_file(src_path, dst_path)
65
- if dst_path.file?
66
- puts " [skipped]"
67
- else
68
- FileUtils.cp(src_path, dst_path)
69
- puts " [created]"
70
- end
71
- end
72
-
73
- def render_file(template_path, output_path, context: binding)
74
- if output_path.file?
75
- puts " [skipped]"
76
- else
77
- require 'erb'
78
- File.open(output_path, 'w') do |f|
79
- f.write ERB.new(File.read(template_path), nil, '<>').result(context)
80
- end
81
- puts " [created]"
82
- end
83
- end
84
-
85
89
  def placeholder?(basename)
86
90
  basename.to_s =~ /^__stage/
87
91
  end
@@ -1,5 +1,5 @@
1
1
  module Luban
2
2
  module Deployment
3
- VERSION = "0.5.1"
3
+ VERSION = "0.5.5"
4
4
  end
5
5
  end
@@ -72,52 +72,6 @@ module Luban
72
72
  def luban_install_path
73
73
  @luban_install_path ||= project_path.join('.luban')
74
74
  end
75
-
76
- module Service
77
- def profile_path
78
- @profile_path ||= shared_path.join('profile')
79
- end
80
-
81
- def log_path
82
- @log_path ||= shared_path.join('log')
83
- end
84
-
85
- def log_file_path
86
- @log_file_path ||= log_path.join(log_file_name)
87
- end
88
-
89
- def log_file_name
90
- raise NotImplementedError, "#{self.class.name}#log_file_name is an abstract method."
91
- end
92
-
93
- def pids_path
94
- @pids_path ||= shared_path.join('pids')
95
- end
96
-
97
- def pid_file_path
98
- @pid_file_path ||= pids_path.join(pid_file_name)
99
- end
100
-
101
- def pid_file_name
102
- raise NotImplementedError, "#{self.class.name}#pid_file_name is an abstract method."
103
- end
104
-
105
- def control_file_path
106
- @control_file_path ||= profile_path.join(control_file_name)
107
- end
108
-
109
- def control_file_name
110
- raise NotImplementedError, "#{self.class.name}#control_file_name is an abstract method."
111
- end
112
-
113
- def logrotate_file_path
114
- @logrotate_file_path ||= profile_path.join(logrotate_file_name)
115
- end
116
-
117
- def logrotate_file_name
118
- raise NotImplementedError, "#{self.class.name}#logrotate_file_name is an abstract method."
119
- end
120
- end
121
75
  end
122
76
  end
123
77
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: luban
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.1
4
+ version: 0.5.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rubyist Lei
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2016-06-24 00:00:00.000000000 Z
11
+ date: 2016-06-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: luban-cli
@@ -103,11 +103,14 @@ files:
103
103
  - lib/luban/deployment/cli/application.rb
104
104
  - lib/luban/deployment/cli/application/authenticator.rb
105
105
  - lib/luban/deployment/cli/application/base.rb
106
- - lib/luban/deployment/cli/application/builder.rb
106
+ - lib/luban/deployment/cli/application/configurator.rb
107
+ - lib/luban/deployment/cli/application/constructor.rb
108
+ - lib/luban/deployment/cli/application/controller.rb
107
109
  - lib/luban/deployment/cli/application/publisher.rb
108
110
  - lib/luban/deployment/cli/application/repository.rb
109
111
  - lib/luban/deployment/cli/application/scm/git.rb
110
112
  - lib/luban/deployment/cli/application/scm/rsync.rb
113
+ - lib/luban/deployment/cli/application/worker.rb
111
114
  - lib/luban/deployment/cli/command.rb
112
115
  - lib/luban/deployment/cli/package.rb
113
116
  - lib/luban/deployment/cli/package/base.rb