luban 0.8.10 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 93138388605dfd36238452d9c61eda0ba31c838f
4
- data.tar.gz: bfe1d55d44ef71c128c855115aacd1a679b998a4
3
+ metadata.gz: b1c840fa119a9368e8e98cae2dfc701d2f31ead8
4
+ data.tar.gz: 10bc13a1c416506baae0a5aff9e88a17a61ee604
5
5
  SHA512:
6
- metadata.gz: 93051b080c0bfca59e1f44fed83e752be9271b5849feb63927f50c94bbeef072165c1064ba779101c7f695e636406a419616b2b289ebe2624a0db342ed7bba17
7
- data.tar.gz: 0e0aa51ed17722f15313f15490e739079efd8180c0e59883847e75cd2ebb4336cce0927b9d637741cee97f1497f5ff6cde50a5e7719f4cca12540cf5c0eda640
6
+ metadata.gz: 95ce838aecc0b93916935fc3469366826403599abcef453b8cada2b83063329eca02b7d0b25b0cbeb3e339a2cc5eb016f0f9e50c53947e64077ebfaf3d535718
7
+ data.tar.gz: af1aae4d01bb04f54097738a7a23c8b184842895e1e67be8705b95e15e523cbc9f1ae49ddf80dab129a1bad6691e5f5d0a3feb138258a2ac49161548b5b59ff9
data/CHANGELOG.md CHANGED
@@ -1,5 +1,33 @@
1
1
  # Change log
2
2
 
3
+ ## Version 0.9.0 (Oct 12, 2016)
4
+
5
+ New features:
6
+ * Added package for Logrotate
7
+ * Added dependent package for Popt
8
+ * Added support for log archival which is done thru Uber
9
+ * Added two convenient methods, #touch and #truncate, in module Utils
10
+
11
+ Minor enhancements:
12
+ * Set keep_releases differently for app and profile publication
13
+ * Made application always deployable
14
+ * Application has/has no cronjobs to update which implies deployable
15
+ * Deprecated symlinks for logrotate configuration files
16
+ * As a result, directory "etc" is removed as well since it is no more necessary
17
+ * No more place holder cronjob entries if there are no more cronjobs defined
18
+ * Refactored profile templates handling in service configurator
19
+ * Cleaned up profile files that have been excluded
20
+ * Made luban_roles as the default roles when setting up cronjobs
21
+ * Added back support for build environment variables like LDFLAGS/CFLAGS
22
+ * Upgraded OpenSSL for Ruby to version 1.0.2j
23
+ * Upgraded Bundler for Ruby to version 1.13.3
24
+ * Added Rubygems dependency for Ruby (version >= 1.9.3)
25
+ * As a side effect, package option #rubygems for Ruby can be set for all Ruby versions
26
+ * Minor code cleanup
27
+
28
+ Bug fixes:
29
+ * Added an extra validation for URL existence test
30
+
3
31
  ## Version 0.8.10 (Sept 29, 2016)
4
32
 
5
33
  Minor enhancements:
@@ -56,7 +56,7 @@ module Luban
56
56
  def has_services?; !services.empty?; end
57
57
 
58
58
  def provisionable?; has_packages?; end
59
- def deployable?; has_source? or has_profile? end
59
+ def deployable?; true; end
60
60
  def controllable?; has_source? or has_services?; end
61
61
 
62
62
  def use_package?(package_name, package_version, servers: [])
@@ -20,13 +20,11 @@ module Luban
20
20
  end
21
21
 
22
22
  def destroy_project
23
- rm(etc_path.join('*', "#{stage}.#{project}.*"))
24
23
  rmdir(project_path)
25
24
  update_result "The project environment is destroyed."
26
25
  end
27
26
 
28
27
  def destroy_app
29
- rm(etc_path.join('*', "#{stage}.#{project}.#{application}.*"))
30
28
  rmdir(app_path)
31
29
  update_result "The application environment is destroyed."
32
30
  end
@@ -39,7 +37,7 @@ module Luban
39
37
  protected
40
38
 
41
39
  def bootstrap
42
- assure_dirs(logrotate_path, downloads_path,
40
+ assure_dirs(downloads_path, archived_logs_path,
43
41
  tmp_path, app_bin_path, app_tmp_path,
44
42
  releases_path, shared_path)
45
43
  end
@@ -55,7 +55,11 @@ module Luban
55
55
  return
56
56
  end
57
57
  if updated?
58
- update_result "Skipped! ALREADY updated crontab.", status: :skipped
58
+ if has_cronjobs?
59
+ update_result "Skipped! ALREADY updated crontab.", status: :skipped
60
+ else
61
+ update_result "Skipped! No crontab for #{user}.", status: :skipped
62
+ end
59
63
  return
60
64
  end
61
65
 
@@ -86,11 +90,19 @@ module Luban
86
90
 
87
91
  def deploy_cronjobs!
88
92
  rm(crontab_file_path) if force?
89
- upload_by_template(file_to_upload: crontab_file_path,
90
- template_file: crontab_template_file,
91
- header_file: crontab_header_template_file,
92
- footer_file: crontab_footer_template_file,
93
- auto_revision: true)
93
+ if has_cronjobs?
94
+ upload_by_template(file_to_upload: crontab_file_path,
95
+ template_file: crontab_template_file,
96
+ header_file: crontab_header_template_file,
97
+ footer_file: crontab_footer_template_file,
98
+ auto_revision: true)
99
+ else
100
+ if file?(crontab_file_path, "-s")
101
+ truncate(crontab_file_path)
102
+ else
103
+ touch(crontab_file_path) unless file?(crontab_file_path)
104
+ end
105
+ end
94
106
  end
95
107
 
96
108
  def crontab_entry(command:, schedule:, output: "", type: :shell, disabled: false)
@@ -101,6 +113,7 @@ module Luban
101
113
  unless respond_to?(command_composer)
102
114
  abort "Aborted! Unknown cronjob type: #{type.inspect}"
103
115
  end
116
+ command = instance_exec(&command) if command.respond_to?(:call)
104
117
  command = send(command_composer, command, output: output)
105
118
  entry = "#{schedule} #{command}"
106
119
  disabled ? "# DISABLED - #{entry}" : entry
@@ -112,15 +125,21 @@ module Luban
112
125
  found = false
113
126
  crontab = crontab.split("\n").inject([]) do |lines, line|
114
127
  if found || line == crontab_open
115
- lines << new_crontab unless (found = line != crontab_close)
128
+ unless (found = line != crontab_close)
129
+ lines << new_crontab unless new_crontab.empty?
130
+ end
116
131
  else
117
132
  lines << line
118
133
  end
119
134
  lines
120
135
  end
121
- crontab << new_crontab unless crontab.include?(new_crontab)
122
- upload!(StringIO.new(crontab.join("\n")), tmp_crontab_file_path)
123
- test(:crontab, tmp_crontab_file_path, "2>&1")
136
+ crontab << new_crontab unless new_crontab.empty? or crontab.include?(new_crontab)
137
+ if crontab.empty?
138
+ test(:crontab, "-r", "2>&1")
139
+ else
140
+ upload!(StringIO.new(crontab.join("\n")), tmp_crontab_file_path)
141
+ test(:crontab, tmp_crontab_file_path, "2>&1")
142
+ end
124
143
  ensure
125
144
  rm(tmp_crontab_file_path)
126
145
  end
@@ -92,7 +92,7 @@ module Luban
92
92
 
93
93
  def publish!
94
94
  rollout_release
95
- cleanup_releases
95
+ send("cleanup_#{release_type}_releases")
96
96
  end
97
97
 
98
98
  def rollout_release
@@ -100,7 +100,7 @@ module Luban
100
100
  upload!(release_package_path.to_s, upload_to.to_s)
101
101
  if md5_matched?(upload_to, release_md5) and
102
102
  test(:tar, "-xzf #{upload_to} -C #{releases_path}")
103
- execute(:touch, release_path)
103
+ touch(release_path)
104
104
  create_symlinks
105
105
  update_releases_log
106
106
  else
@@ -119,7 +119,6 @@ module Luban
119
119
 
120
120
  def create_profile_symlinks
121
121
  create_release_symlink(shared_path)
122
- create_etc_symlinks
123
122
  end
124
123
 
125
124
  def create_app_symlinks
@@ -135,23 +134,13 @@ module Luban
135
134
 
136
135
  def create_symlinks_for_linked_dirs
137
136
  create_linked_dirs(linked_dirs, from: shared_path, to: release_path)
137
+ assure_symlink(archived_logs_path, log_path.join(archived_logs_path.basename))
138
138
  end
139
139
 
140
140
  def create_symlinks_for_linked_files
141
141
  create_linked_files(linked_files, from: profile_path, to: release_path.join('config'))
142
142
  end
143
143
 
144
- def create_etc_symlinks
145
- create_logrotate_symlinks
146
- end
147
-
148
- def create_logrotate_symlinks
149
- logrotate_files.each do |path|
150
- target_file = "#{stage}.#{project}.#{application}.#{path.basename}"
151
- assure_symlink(path, logrotate_path.join(target_file))
152
- end
153
- end
154
-
155
144
  def update_releases_log
156
145
  execute %{echo "[$(date -u)][#{user}] #{release_log_message}" >> #{releases_log_path}}
157
146
  end
@@ -160,13 +149,16 @@ module Luban
160
149
  "#{release_name} in #{stage} #{project} is published successfully."
161
150
  end
162
151
 
163
- def cleanup_releases(keep_releases = 5)
152
+ def cleanup_releases(keep_releases = 1)
164
153
  files = capture(:ls, '-xtd', releases_path.join("#{release_version}-*")).split(" ")
165
154
  if files.count > keep_releases
166
155
  files.last(files.count - keep_releases).each { |f| rmdir(f) }
167
156
  end
168
157
  end
169
158
 
159
+ def cleanup_app_releases; cleanup_releases(5); end
160
+ def cleanup_profile_releases; cleanup_releases; end
161
+
170
162
  def bundle_gems
171
163
  assure_dirs(bundle_config_path, gems_cache_path, bundle_path)
172
164
  sync_gems_cache
@@ -42,6 +42,15 @@ module Luban
42
42
  def bundle_command(cmd, **opts)
43
43
  shell_command("#{bundle_executable} exec #{cmd}", **opts)
44
44
  end
45
+
46
+ def app_archives_path
47
+ @app_archives_path ||=
48
+ archives_path.join("#{stage}.#{project}", application, hostname)
49
+ end
50
+
51
+ def archived_logs_path
52
+ @archived_logs_path ||= app_archives_path.join('archived_logs')
53
+ end
45
54
  end
46
55
  end
47
56
  end
@@ -203,7 +203,7 @@ module Luban
203
203
 
204
204
  def has_cronjobs?; !cronjobs.empty?; end
205
205
 
206
- def cronjob(roles: nil, hosts: nil, **job)
206
+ def cronjob(roles: luban_roles, hosts: nil, **job)
207
207
  validate_cronjob(job)
208
208
  roles = Array(roles)
209
209
  hosts = Array(hosts)
@@ -46,8 +46,7 @@ module Luban
46
46
  def configure_build_env_variables
47
47
  @build_env_vars = {
48
48
  ldflags: [ENV['LDFLAGS'].to_s],
49
- cflags: [ENV['CFLAGS'].to_s],
50
- cppflags: [ENV['CPPFLAGS'].to_s]
49
+ cflags: [ENV['CFLAGS'].to_s]
51
50
  }
52
51
  if child?
53
52
  configure_parent_build_env_variables
@@ -58,7 +57,6 @@ module Luban
58
57
  def configure_parent_build_env_variables
59
58
  parent.build_env_vars[:ldflags] << "-L#{lib_path}"
60
59
  parent.build_env_vars[:cflags] << "-I#{include_path}"
61
- parent.build_env_vars[:cppflags] << "-I#{include_path}"
62
60
  end
63
61
 
64
62
  def configure_parent_build_options
@@ -67,6 +65,13 @@ module Luban
67
65
  end
68
66
  end
69
67
 
68
+ def compose_build_env_variables
69
+ build_env_vars.inject({}) do |vars, (k, v)|
70
+ vars[k] = "#{v.join(' ').strip}" unless v.all?(&:empty?)
71
+ vars
72
+ end
73
+ end
74
+
70
75
  def configure_build_options
71
76
  @configure_opts = default_configure_opts
72
77
  @configure_opts |= task.opts.configure_opts unless task.opts.configure_opts.nil?
@@ -302,7 +302,7 @@ module Luban
302
302
  end
303
303
 
304
304
  def bootstrap_install
305
- assure_dirs(etc_path, tmp_path, app_bin_path,
305
+ assure_dirs(tmp_path, app_bin_path,
306
306
  package_tmp_path, install_path, install_log_path)
307
307
  end
308
308
 
@@ -18,15 +18,23 @@ module Luban
18
18
  config_finder[:application].stage_profile_templates_path.join(profile_name)
19
19
  end
20
20
 
21
- def profile_templates(format: "erb")
22
- return @profile_templates unless @profile_templates.nil?
23
- @profile_templates = []
21
+ def available_profile_templates(format: "erb")
22
+ return @available_profile_templates unless @available_profile_templates.nil?
23
+ templates = []
24
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.tap do |templates|
28
- templates.reject! { |t| exclude_template?(t) }
25
+ Dir.chdir(path) { templates |= Dir["**/*.#{format}"] } if path.directory?
29
26
  end
27
+ @available_profile_templates = templates
28
+ end
29
+
30
+ def profile_templates(format: "erb")
31
+ @profile_templates ||=
32
+ available_profile_templates(format: format).reject { |t| exclude_template?(t) }
33
+ end
34
+
35
+ def excluded_profile_templates(format: "erb")
36
+ @excluded_profile_templates ||=
37
+ available_profile_templates(format: format).select { |t| exclude_template?(t) }
30
38
  end
31
39
 
32
40
  def exclude_template?(template); false; end
@@ -43,7 +51,7 @@ module Luban
43
51
  def update_profile
44
52
  assure_dirs(stage_profile_path)
45
53
  render_profile
46
- update_logrotate_files
54
+ cleanup_profile
47
55
  end
48
56
 
49
57
  protected
@@ -79,9 +87,10 @@ module Luban
79
87
  auto_revision: true)
80
88
  end
81
89
 
82
- def update_logrotate_files
83
- if file?(stage_profile_path.join(logrotate_file_name))
84
- logrotate_files.push(logrotate_file_path)
90
+ def cleanup_profile
91
+ excluded_profile_templates.each do |template_file|
92
+ profile_file = stage_profile_path.join(template_file).sub_ext('')
93
+ rm(profile_file) if file?(profile_file)
85
94
  end
86
95
  end
87
96
  end
@@ -73,14 +73,6 @@ module Luban
73
73
  def control_file_name
74
74
  @control_file_name ||= "#{service_name}.conf"
75
75
  end
76
-
77
- def logrotate_file_path
78
- @logrotate_file_path ||= profile_path.join(logrotate_file_name)
79
- end
80
-
81
- def logrotate_file_name
82
- @logrotate_file_name ||= "#{service_name}.logrotate"
83
- end
84
76
  end
85
77
 
86
78
  include Base
@@ -23,7 +23,7 @@ module Luban
23
23
  assure_dirs(target_path.dirname)
24
24
  rmdir(target_path) if directory?(target_path)
25
25
  source_path = from.join(path)
26
- assure_symlink(source_path, target_path) #if directory?(source_path)
26
+ assure_symlink(source_path, target_path)
27
27
  end
28
28
  end
29
29
 
@@ -33,7 +33,7 @@ module Luban
33
33
  assure_dirs(target_path.dirname)
34
34
  rm(target_path) if file?(target_path)
35
35
  source_path = from.join(path)
36
- assure_symlink(source_path, target_path) #if file?(source_path)
36
+ assure_symlink(source_path, target_path)
37
37
  end
38
38
  end
39
39
  end
@@ -52,6 +52,14 @@ module Luban
52
52
  execute(:mkdir, '-p', *opts, path)
53
53
  end
54
54
 
55
+ def truncate(path)
56
+ execute(:cat, "/dev/null", ">", path)
57
+ end
58
+
59
+ def touch(path)
60
+ execute(:touch, path)
61
+ end
62
+
55
63
  def rm(*opts, path)
56
64
  execute(:rm, '-f', *opts, path)
57
65
  end
@@ -106,13 +114,10 @@ module Luban
106
114
 
107
115
  def url_exists?(url)
108
116
  # Sent HEAD request to avoid downloading the file contents
109
- test("curl -s -L -I -o /dev/null -f #{url}")
110
-
111
- # Other effective ways to check url existence with curl
112
-
117
+ test("curl -s -L -I -o /dev/null -f #{url}") or
113
118
  # In case HEAD request is refused,
114
119
  # only the first byte of the file is requested
115
- # test("curl -s -L -o /dev/null -f -r 0-0 #{url}")
120
+ test("curl -s -L -o /dev/null -f -r 0-0 #{url}")
116
121
 
117
122
  # Alternatively, http code (200) can be validated
118
123
  # capture("curl -s -L -I -o /dev/null -w '%{http_code}' #{url}") == '200'
@@ -0,0 +1,43 @@
1
+ module Luban
2
+ module Deployment
3
+ module Packages
4
+ class Logrotate < Luban::Deployment::Package::Base
5
+ apply_to :all do
6
+ before_install do
7
+ depend_on 'popt', version: '1.16'
8
+ end
9
+ end
10
+
11
+ class Installer < Luban::Deployment::Package::Installer
12
+ define_executable 'logrotate'
13
+
14
+ def source_repo
15
+ @source_repo ||= "https://github.com"
16
+ end
17
+
18
+ def source_url_root
19
+ @source_url_root ||= "logrotate/logrotate/releases/download/#{package_major_version}"
20
+ end
21
+
22
+ def installed?
23
+ return false unless file?(logrotate_executable)
24
+ pattern = "logrotate #{package_major_version}"
25
+ match?("#{logrotate_executable} --version 2>&1", pattern)
26
+ end
27
+
28
+ def bin_path
29
+ @bin_path ||= install_path.join('sbin')
30
+ end
31
+
32
+ protected
33
+
34
+ def configure_package!
35
+ with compose_build_env_variables do
36
+ test("./autogen.sh", ">> #{install_log_file_path} 2>&1") and super
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,38 @@
1
+ module Luban
2
+ module Deployment
3
+ module Packages
4
+ class Popt < Luban::Deployment::Package::Base
5
+ class Installer < Luban::Deployment::Package::Installer
6
+ def header_file
7
+ @header_file ||= include_path.join('popt.h')
8
+ end
9
+
10
+ def shared_obj_file
11
+ @shared_obj_file ||= lib_path.join("libpopt.#{lib_extension}")
12
+ end
13
+
14
+ def source_repo
15
+ @source_repo ||= "http://rpm5.org"
16
+ end
17
+
18
+ def source_url_root
19
+ @source_url_root ||= "files/popt"
20
+ end
21
+
22
+ def installed?
23
+ file?(header_file) and file?(shared_obj_file)
24
+ end
25
+
26
+ protected
27
+
28
+ def configure_build_options
29
+ super
30
+ @configure_opts.unshift("--disable-static")
31
+ end
32
+
33
+ def update_binstubs!; end
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -46,14 +46,15 @@ module Luban
46
46
 
47
47
  apply_to '>= 1.9.3' do
48
48
  before_install do
49
- depend_on 'openssl', version: '1.0.2h'
49
+ depend_on 'openssl', version: '1.0.2j'
50
+ depend_on 'rubygems', version: '2.6.7'
50
51
  #depend_on 'yaml', version: '0.1.6'
51
52
  end
52
53
  end
53
54
 
54
55
  apply_to :all do
55
56
  after_install do
56
- depend_on 'bundler', version: '1.12.3'
57
+ depend_on 'bundler', version: '1.13.3'
57
58
  end
58
59
  end
59
60
 
@@ -72,7 +73,7 @@ module Luban
72
73
  provision_tasks[:install].switch :install_doc, "Install Ruby document"
73
74
  provision_tasks[:install].switch :install_tcl, "Install with Tcl"
74
75
  provision_tasks[:install].switch :install_tk, "Install with Tk"
75
- provision_tasks[:install].option :rubygems, "Rubygems version (effective for v1.9.2 or below)"
76
+ provision_tasks[:install].option :rubygems, "Rubygems version"
76
77
  provision_tasks[:install].option :bundler, "Bundler version"
77
78
  provision_tasks[:install].option :openssl, "OpenSSL version (effective for v1.9.3 or above)"
78
79
  end
@@ -33,7 +33,6 @@ module Luban
33
33
  end
34
34
 
35
35
  def source_repo
36
- #@source_repo ||= "http://production.cf.rubygems.org"
37
36
  @source_repo ||= "https://rubygems.org"
38
37
  end
39
38
 
@@ -119,7 +119,6 @@ module Luban
119
119
 
120
120
  parameter :application
121
121
  parameter :scm_role
122
- parameter :logrotate_files
123
122
 
124
123
  def env_name
125
124
  @env_name ||= "#{stage}.#{project}/#{application}"
@@ -137,8 +136,6 @@ module Luban
137
136
 
138
137
  def set_default_application_parameters
139
138
  set_default :scm_role, :scm
140
- set_default :logrotate_files, []
141
-
142
139
  setup_default_application_config_finder
143
140
  end
144
141
 
@@ -1,6 +1,3 @@
1
- <% unless has_cronjobs? -%>
2
- # !!! No cronjobs for <%= user %> !!!
3
- <% end -%>
4
1
  <% cronjobs.each do |cronjob| -%>
5
2
  <%= "#{crontab_entry(**cronjob)}" %>
6
3
  <% end -%>
@@ -1,5 +1,5 @@
1
1
  module Luban
2
2
  module Deployment
3
- VERSION = "0.8.10"
3
+ VERSION = "0.9.0"
4
4
  end
5
5
  end
@@ -21,13 +21,10 @@ module Luban
21
21
  @env_path ||= luban_root_path.join('env')
22
22
  end
23
23
 
24
- def etc_path
25
- @etc_path ||= luban_root_path.join('etc')
26
- end
27
-
28
- def logrotate_path
29
- @logrotate_path = etc_path.join('logrotate')
24
+ def archives_path
25
+ @archives_path ||= luban_root_path.join('archives')
30
26
  end
27
+ alias_method :local_archives_path, :archives_path
31
28
 
32
29
  def tmp_path
33
30
  @tmp_path ||= luban_root_path.join('tmp')
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.8.10
4
+ version: 0.9.0
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-09-29 00:00:00.000000000 Z
11
+ date: 2016-10-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: luban-cli
@@ -143,7 +143,9 @@ files:
143
143
  - lib/luban/deployment/helpers/utils.rb
144
144
  - lib/luban/deployment/packages/bundler.rb
145
145
  - lib/luban/deployment/packages/git.rb
146
+ - lib/luban/deployment/packages/logrotate.rb
146
147
  - lib/luban/deployment/packages/openssl.rb
148
+ - lib/luban/deployment/packages/popt.rb
147
149
  - lib/luban/deployment/packages/ruby.rb
148
150
  - lib/luban/deployment/packages/rubygems.rb
149
151
  - lib/luban/deployment/packages/yaml.rb
@@ -200,7 +202,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
200
202
  version: '0'
201
203
  requirements: []
202
204
  rubyforge_project:
203
- rubygems_version: 2.5.1
205
+ rubygems_version: 2.6.7
204
206
  signing_key:
205
207
  specification_version: 4
206
208
  summary: Ruby framework for server automation and application deployment