capistrano-net_storage 0.3.2 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 507fe8707e3df873b757a6a44e830852f67d4444
4
- data.tar.gz: 15d1fa62fb07eabb8c40fbe22cb5007f9bef445f
2
+ SHA256:
3
+ metadata.gz: 24781ed3a7d2676ccff180118e8c68fa4aa185d379d4ab6943f2c48d3c222b0f
4
+ data.tar.gz: 6e955db0ccdc03e9179d47f9c21193cb0dbb85e8172291b3d0c584de0a7b406e
5
5
  SHA512:
6
- metadata.gz: 06d7db8a593c0badde8a5f16f833a3f42f4ab1add488fcb88b1f6bb51f48d8d65a4feac9c14b833c6393de6d0d13225d54752d33afe244e0fb6c3c6033a5ac36
7
- data.tar.gz: d17853a6e94973c78e41f1ac807e635da7ca33d50bd131559a443e75ef6fabc0cd82d14e8344f67bdecaeab5f50196f448a969ccb37a3b5389495926bd010e28
6
+ metadata.gz: a9160786565510e2b34110fdda42339ab107ccea6a27b86ba064b41bd8ac69fe08a218ee702ea853acedd3d6b271689ac64d0e08853105af8b1f49b109484607
7
+ data.tar.gz: 37863818bb0bd9b07c37c72e0309482f67a879575d6e4d65b6dd21dfed3a839cd4a07d80e084bc1ef84ebbf0809e1c3660f2c914e2032e9131de4c7949fa5b6c
@@ -0,0 +1,7 @@
1
+ ### Summary
2
+
3
+ ### Other Information
4
+
5
+ ### Checklist
6
+
7
+ * [ ] By placing an "x" in the box, I hereby understand, accept and agree to be bound by the terms and conditions of the [Contribution License Agreement](https://dena.github.io/cla/).
data/.travis.yml CHANGED
@@ -1,13 +1,11 @@
1
1
  sudo: false
2
2
  language: ruby
3
3
  rvm:
4
- - 2.0.0
5
- - 2.1.8
6
- - 2.2.0
7
- - 2.3.5
8
- - 2.4.2
4
+ - 2.6.3
5
+ - 2.5.5
6
+ - 2.4.6
9
7
 
10
- before_install: gem install bundler -v 1.14.6
8
+ before_install: gem install bundler
11
9
  install: bundle install
12
10
  script: bundle exec rake spec
13
11
  notifications:
data/CHANGELOG.md CHANGED
@@ -1,3 +1,21 @@
1
+ ## 0.4.0 (2022/05/17)
2
+
3
+ Fix Bug:
4
+
5
+ - Fix a cleanup issue reported at #9 (#12) @naro143
6
+ - Before:
7
+ - Archives such as `.tar.gz` and `.zip` are handled in `releases` directory of each server.
8
+ - Incomplete deployment leads to uncollected garbage directory under `releases`.
9
+ - After:
10
+ - Archives are handled within `#{deploy_to}/net_storage_archives` directory of each server.
11
+ - NetStorage cleanup `net_storage_archives` directory just as Capistrano do in `releases` directory.
12
+ - One successful deployment can cleanup old archives and there is no more Capistrano warnings.
13
+ - This includes the same cleanup policy for `local_releases_path` and `local_archives_path` of NetStorage.
14
+
15
+ Changes:
16
+
17
+ - Change task name `net_storage:cleanup_remote_release` to `net_storage:cleanup_archives_on_remote_storage`
18
+
1
19
  ## 0.3.2 (2017/11/7)
2
20
 
3
21
  Fix Bug:
data/README.md CHANGED
@@ -49,15 +49,21 @@ Set Capistrano variables by `set name, value`.
49
49
  `:scm` | `nil` | Set `:net_storage` for capistrano before v3.7
50
50
  `:branch` | `master` | Target branch of SCM to release
51
51
  `:keep_releases` | `5` | Numbers to keep released versions
52
- `:net_storage_transport` | `nil` | Transport class for _remote storage_
53
52
  `:net_storage_archiver` | `Capistrano::NetStorage::Archiver::Zip` | Archiver class
54
53
  `:net_storage_scm` | `Capistrano::NetStorage::SCM::Git` | Internal scm class for application repository
55
- `:net_storage_with_bundle` | `false` | Do `bundle install` when creating archive
54
+ `:net_storage_transport` | `nil` | Transport class for _remote storage_
55
+ `:net_storage_archive_on_missing` | `true` | If `true`, create and upload archive only when target archive is missing on remote storage
56
56
  `:net_storage_config_files` | `nil` | Files to sync `config/` directory on target servers' application directory
57
57
  `:net_storage_max_parallels` | number of servers | Max concurrency for remote tasks
58
- `:net_storage_archive_on_missing` | `true` | If `true`, create and upload archive only when target archive is missing on remote storage
58
+ `:net_storage_rsync_options` | `#{ssh_options}` | SSH options for rsync command to sync configs
59
59
  `:net_storage_upload_files_by_rsync` | `false` | Use rsync(1) to deploy config files
60
+ `:net_storage_with_bundle` | `false` | Do `bundle install` when creating archive
60
61
  `:net_storage_local_base_path` | `.local_repo` | Base directory on deploy server
62
+ `:net_storage_local_mirror_path` | `#{net_storage_local_base_path}/mirror` | Path to clone repository on deploy server
63
+ `:net_storage_local_releases_path` | `#{net_storage_local_base_path}/releases` | Path to keep release directories on deploy server
64
+ `:net_storage_local_bundle_path` | `#{net_storage_local_base_path}/bundle` | Shared directory to install gems on deploy server
65
+ `:net_storage_local_archives_path` | `#{net_storage_local_base_path}/archives` | Archive directories on deploy server
66
+ `:net_storage_archives_path` | `#{deploy_to}/net_storage_archives` | Archive directories on application server
61
67
 
62
68
  ### Transport Plugins
63
69
 
@@ -16,8 +16,7 @@ module Capistrano
16
16
  raise NotImplementedError
17
17
  end
18
18
 
19
- # Extract archive.
20
- # Archive file should be cleaned up after extracted.
19
+ # Extract archive
21
20
  # @abstract
22
21
  def extract
23
22
  raise NotImplementedError
@@ -23,10 +23,10 @@ class Capistrano::NetStorage::Archiver::TarGzip < Capistrano::NetStorage::Archiv
23
23
  def extract
24
24
  c = config
25
25
  on c.servers, in: :groups, limit: c.max_parallels do
26
+ execute :mkdir, '-p', c.archives_path
26
27
  execute :mkdir, '-p', release_path
27
28
  within release_path do
28
29
  execute :tar, 'xzf', c.archive_path
29
- execute :rm, '-f', c.archive_path
30
30
  end
31
31
  end
32
32
  end
@@ -23,8 +23,11 @@ class Capistrano::NetStorage::Archiver::Zip < Capistrano::NetStorage::Archiver::
23
23
  def extract
24
24
  c = config
25
25
  on c.servers, in: :groups, limit: c.max_parallels do
26
- execute :unzip, c.archive_path, '-d', release_path
27
- execute :rm, '-f', c.archive_path
26
+ execute :mkdir, '-p', c.archives_path
27
+ execute :mkdir, '-p', release_path
28
+ within release_path do
29
+ execute :unzip, c.archive_path
30
+ end
28
31
  end
29
32
  end
30
33
  end
@@ -6,22 +6,95 @@ module Capistrano
6
6
  class Cleaner
7
7
  include Capistrano::NetStorage::Utils
8
8
 
9
- # Clean up local release directories and archives.
9
+ # Clean up old release directories on local.
10
10
  # Assumes they are under +config.local_releases_path+
11
11
  # @see Capistrano::NetStorage::Config#local_releases_path
12
- def cleanup_local_release
12
+ def cleanup_local_releases
13
13
  c = config
14
14
  run_locally do
15
- releases = capture(:ls, '-xtr', c.local_releases_path).split
16
- # Contains archive files and extracted directories
17
- if releases.count > fetch(:keep_releases) * 2
18
- info "Keeping #{fetch(:keep_releases)} * 2 of #{releases.count} local releases"
19
- olds_str = (releases - releases.last(fetch(:keep_releases) * 2)).map do |file|
20
- c.local_releases_path.join(file)
21
- end.join(' ')
22
- execute :rm, '-rf', olds_str
15
+ contents = capture(:ls, '-x', c.local_releases_path).split
16
+ # reference
17
+ # https://github.com/capistrano/capistrano/blob/cc4f31fdfcb4a21c569422a95868d0bb52844c75/lib/capistrano/tasks/deploy.rake#L152
18
+ releases, invalid = contents.partition { |e| /^\d{14}$/ =~ e }
19
+
20
+ if invalid.any?
21
+ warn "Invalid contents in #{c.local_releases_path} on local:\n#{invalid.join("\n")}"
22
+ end
23
+
24
+ if releases.count > fetch(:keep_releases)
25
+ info "Keeping #{fetch(:keep_releases)} of #{releases.count} releases on local"
26
+ old_releases = (releases - releases.last(fetch(:keep_releases))).map do |release|
27
+ c.local_releases_path.join(release).to_s
28
+ end
29
+ execute :rm, '-rf', *old_releases
30
+ else
31
+ info "No old releases (keeping newest #{fetch(:keep_releases)}) in #{c.local_releases_path} on local"
32
+ end
33
+ end
34
+ end
35
+
36
+ # Clean up old archive files on local.
37
+ # Assumes they are under +config.local_archives_path+
38
+ # @see Capistrano::NetStorage::Config#local_archives_path
39
+ def cleanup_local_archives
40
+ c = config
41
+ run_locally do
42
+ contents = capture(:ls, '-x', c.local_archives_path).split
43
+ archives, invalid = contents.partition { |e| /^\d{14}\.#{Regexp.escape(c.archive_suffix)}$/ =~ e }
44
+
45
+ if invalid.any?
46
+ warn "Invalid contents in #{c.local_archives_path} on local:\n#{invalid.join("\n")}"
47
+ end
48
+
49
+ if archives.count > fetch(:keep_releases)
50
+ info "Keeping #{fetch(:keep_releases)} of #{archives.count} archives on local"
51
+ old_archives = (archives - archives.last(fetch(:keep_releases))).map do |archive|
52
+ c.local_archives_path.join(archive).to_s
53
+ end
54
+ execute :rm, '-f', *old_archives
55
+ else
56
+ info "No old archives (keeping newest #{fetch(:keep_releases)}) in #{c.local_archives_path} on local"
57
+ end
58
+ end
59
+ end
60
+
61
+ # Clean up old archive files on remote servers.
62
+ # Assumes they are under +config.archives_path+
63
+ # @see Capistrano::NetStorage::Config#archives_path
64
+ def cleanup_archives
65
+ c = config
66
+ on c.servers, in: :groups, limit: c.max_parallels do |host|
67
+ contents = capture(:ls, '-x', c.archives_path).split
68
+ archives, invalid = contents.partition { |e| /^\d{14}\.#{Regexp.escape(c.archive_suffix)}$/ =~ e }
69
+
70
+ if invalid.any?
71
+ warn "Invalid contents in #{c.archives_path} on #{host}:\n#{invalid.join("\n")}"
72
+ end
73
+
74
+ if archives.count > fetch(:keep_releases)
75
+ info "Keeping #{fetch(:keep_releases)} of #{archives.count} archives on #{host}"
76
+ old_archives = (archives - archives.last(fetch(:keep_releases))).map do |archive|
77
+ c.archives_path.join(archive).to_s
78
+ end
79
+
80
+ if test("[ -d #{current_path} ]")
81
+ current_release = capture(:readlink, current_path).to_s
82
+ current_release_archive = c.archives_path.join("#{File.basename(current_release)}.#{c.archive_suffix}")
83
+ if old_archives.include?(current_release_archive)
84
+ warn "Current release archive was marked for being removed but it's going to be skipped on #{host}"
85
+ old_archives.delete(current_release_archive)
86
+ end
87
+ else
88
+ debug "There is no current release present on #{host}"
89
+ end
90
+
91
+ if old_archives.any?
92
+ old_archives.each_slice(100) do |old_archives_batch|
93
+ execute :rm, '-f', *old_archives_batch
94
+ end
95
+ end
23
96
  else
24
- info "No old local releases in #{c.local_releases_path}"
97
+ info "No old archives (keeping newest #{fetch(:keep_releases)}) in #{c.archives_path} on #{host}"
25
98
  end
26
99
  end
27
100
  end
@@ -53,7 +53,7 @@ module Capistrano
53
53
  @skip_bundle
54
54
  end
55
55
 
56
- # If +true+, create archive ONLY when it's not found on Network Storage.
56
+ # If +true+, create archive ONLY when it's not found on remote storage.
57
57
  # Otherwise, create archive ALWAYS.
58
58
  # Defaults to +true+
59
59
  def archive_on_missing?
@@ -83,56 +83,63 @@ module Capistrano
83
83
  # Path settings
84
84
  #
85
85
 
86
- # Path of base directory on localhost
86
+ # Path of base directory on local
87
87
  # @return [Pathname]
88
88
  def local_base_path
89
89
  @local_base_path ||= pathname(fetch(:net_storage_local_base_path, "#{Dir.pwd}/.local_repo"))
90
90
  end
91
91
 
92
- # Path to clone repository on localhost
92
+ # Path to clone repository on local
93
93
  # @return [Pathname]
94
94
  def local_mirror_path
95
95
  @local_mirror_path ||= pathname(fetch(:net_storage_local_mirror_path))
96
96
  @local_mirror_path ||= local_base_path.join('mirror')
97
97
  end
98
98
 
99
- # Path to keep release directories and archives on localhost
99
+ # Path to keep release directories on local
100
100
  # @return [Pathname]
101
101
  def local_releases_path
102
102
  @local_releases_path ||= pathname(fetch(:net_storage_local_releases_path))
103
103
  @local_releases_path ||= local_base_path.join('releases')
104
104
  end
105
105
 
106
- # Path to take a snapshot of repository for release
106
+ # Path to take a snapshot of repository for release on local
107
107
  # @return [Pathname]
108
108
  def local_release_path
109
- @local_release_path ||= pathname(fetch(:net_storage_local_release_path))
110
109
  @local_release_path ||= local_releases_path.join(release_timestamp)
111
110
  end
112
111
 
113
- # Shared directory to install gems
112
+ # Shared directory to install gems on local
114
113
  # @return [Pathname]
115
114
  def local_bundle_path
116
115
  @local_bundle_path ||= pathname(fetch(:net_storage_local_bundle_path))
117
116
  @local_bundle_path ||= local_base_path.join('bundle')
118
117
  end
119
118
 
120
- # Destination path to archive application on localhost
119
+ # Path of archive directories on local
120
+ # @return [Pathname]
121
+ def local_archives_path
122
+ @local_archives_path ||= pathname(fetch(:net_storage_local_archives_path))
123
+ @local_archives_path ||= local_base_path.join('archives')
124
+ end
125
+
126
+ # Destination path to archive application on local
121
127
  # @return [Pathname]
122
128
  def local_archive_path
123
- @local_archive_path ||= pathname(fetch(:net_storage_local_archive_path))
124
- @local_archive_path ||= pathname("#{local_release_path}.#{archive_suffix}")
129
+ @local_archive_path ||= local_archives_path.join("#{release_timestamp}.#{archive_suffix}")
125
130
  end
126
131
 
127
- # Path of archive file to be downloaded on servers
132
+ # Path of archive directories on remote servers
133
+ # @return [Pathname]
134
+ def archives_path
135
+ @archives_path ||= pathname(fetch(:net_storage_archives_path))
136
+ @archives_path ||= deploy_path.join('net_storage_archives')
137
+ end
138
+
139
+ # Path of archive file to be downloaded on remote servers
128
140
  # @return [Pathname]
129
141
  def archive_path
130
- @archive_path ||= pathname(fetch(:net_storage_archive_path))
131
- @archive_path ||= begin
132
- # Set release_timestamp if not set
133
- fetch(:release_path, set_release_path)
134
- pathname("#{release_path}.#{archive_suffix}")
135
- end
142
+ @archive_path ||= archives_path.join("#{release_timestamp}.#{archive_suffix}")
136
143
  end
137
144
 
138
145
  # Suffix of archive file
@@ -1,7 +1,7 @@
1
1
  module Capistrano
2
2
  module NetStorage
3
3
  module Transport
4
- # Abstract class to transport archive from/to Network Storage
4
+ # Abstract class to transport archive from/to remote storage
5
5
  # @abstract
6
6
  class Base
7
7
  # Check prerequisites for transport
@@ -1,5 +1,5 @@
1
1
  module Capistrano
2
2
  module NetStorage
3
- VERSION = '0.3.2'
3
+ VERSION = '0.4.0'
4
4
  end
5
5
  end
@@ -43,19 +43,31 @@ namespace :net_storage do
43
43
  end
44
44
  after 'net_storage:create_release', 'net_storage:sync_config'
45
45
 
46
- desc 'Clean up local old archives and snapshots'
47
- task :cleanup_local_release do
48
- Capistrano::NetStorage.cleaner.cleanup_local_release
46
+ desc 'Clean up old release directories on local'
47
+ task :cleanup_local_releases do
48
+ Capistrano::NetStorage.cleaner.cleanup_local_releases
49
49
  end
50
- after 'deploy:cleanup', 'net_storage:cleanup_local_release'
50
+ after 'deploy:cleanup', 'net_storage:cleanup_local_releases'
51
51
 
52
- desc 'Clean up old archives on remote storage'
53
- task :cleanup_remote_release do
52
+ desc 'Clean up old archive files on remote storage'
53
+ task :cleanup_archives_on_remote_storage do
54
54
  transport = Capistrano::NetStorage.transport
55
55
  next unless transport.respond_to?(:cleanup)
56
56
  transport.cleanup
57
57
  end
58
- after 'net_storage:cleanup_local_release', 'net_storage:cleanup_remote_release'
58
+ after 'deploy:cleanup', 'net_storage:cleanup_archives_on_remote_storage'
59
+
60
+ desc 'Clean up old archive files on remote servers'
61
+ task :cleanup_archives do
62
+ Capistrano::NetStorage.cleaner.cleanup_archives
63
+ end
64
+ after 'deploy:cleanup', 'net_storage:cleanup_archives'
65
+
66
+ desc 'Clean up old archive files on local'
67
+ task :cleanup_local_archives do
68
+ Capistrano::NetStorage.cleaner.cleanup_local_archives
69
+ end
70
+ after 'deploy:cleanup', 'net_storage:cleanup_local_archives'
59
71
 
60
72
  task prepare_archive: %i(net_storage:scm:update net_storage:check:bundler) do
61
73
  config = Capistrano::NetStorage.config
@@ -103,6 +115,7 @@ namespace :net_storage do
103
115
  config.local_base_path,
104
116
  config.local_mirror_path,
105
117
  config.local_releases_path,
118
+ config.local_archives_path,
106
119
  ]
107
120
  dirs << config.local_bundle_path unless config.skip_bundle?
108
121
  run_locally do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: capistrano-net_storage
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.2
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - progrhyme
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-11-07 00:00:00.000000000 Z
11
+ date: 2022-05-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: capistrano
@@ -102,6 +102,7 @@ executables: []
102
102
  extensions: []
103
103
  extra_rdoc_files: []
104
104
  files:
105
+ - ".github/PULL_REQUEST_TEMPLATE.md"
105
106
  - ".gitignore"
106
107
  - ".rspec"
107
108
  - ".travis.yml"
@@ -149,8 +150,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
149
150
  - !ruby/object:Gem::Version
150
151
  version: '0'
151
152
  requirements: []
152
- rubyforge_project:
153
- rubygems_version: 2.6.13
153
+ rubygems_version: 3.0.3
154
154
  signing_key:
155
155
  specification_version: 4
156
156
  summary: Capistrano SCM Plugin for fast deployment via remote storage