capistrano-net_storage 0.5.0 → 1.0.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
  SHA256:
3
- metadata.gz: f402751b93d15bbc8660b9669a18977ac69d67381d45c0316afd89d185f750fe
4
- data.tar.gz: 38905906ddf2c6aae2706679eb907b6970c1099e058eb8f8c676932656cc3f7d
3
+ metadata.gz: ff8a4495e5e93c5beafb4e28a03e7c4193b29d09d044070010d65490abf1cf66
4
+ data.tar.gz: 3ab025f3a318d792b5752beddc0eb9a2a8f5ce1ac31a3e196925da772fd3a1ce
5
5
  SHA512:
6
- metadata.gz: 3c61f03392a39f8f69c824fc196ef3e056c206e1c00ecce038e73f18b8782074d4ef5895fbf65d4c5e42666950ab0b0c53b99ceeeeb5d428122c92caa1dc8373
7
- data.tar.gz: cd42fc4f35a13075920dff572727a93e4f9db1d28249833d0af85a5edc82d661303a2595511ab2b7067f5a3939cead39d5a5a68ffe7a2577799ea94f03b9c099
6
+ metadata.gz: 52a6a1c75575a63469395ded4e89c448045791fa45ff01f899462859b741e562d9b1055309b0773f80617cc635b71651ec0d32a5e792cc5cd29a0833b8ca9b47
7
+ data.tar.gz: be6cb831bb78fe7781f87fc17304a7384ee697f7c345cb99298e49f5f1693f3034ff35f2cf3389e5ff281c00f78acd811e33758018268913cc43d00e7ccafb7e
data/CHANGELOG.md CHANGED
@@ -1,3 +1,66 @@
1
+ ## 1.0.0 (2023/08/07)
2
+
3
+ **Scalable by Default**
4
+
5
+ Major Update by @aeroastro
6
+
7
+ The main objective of this update is scalable by default. You can enjoy the scalability and fine-tuned settings just out of the box.
8
+
9
+ New Features:
10
+
11
+ - `:net_storage_multi_app_mode` (default: `false`) has been introduced to deploy a repository with multiple applications (#14)
12
+ - This mode is more convenient than `repo_tree` when there is a dependency among subdirectories.
13
+ - Plugin style is now officially supported for Capistrano >= 3.7 (#22)
14
+ - Officially supported task hook point is introduced `after 'net_storage:prepare_archive'` (#22)
15
+ - `:net_storage_keep_remote_archives` has been introduced to control the number of remote archives (#24)
16
+
17
+ Changes
18
+
19
+ - Default archiver is now `.tar.gz` instead of `.zip` to improve integrity (#19)
20
+ - Default value of `:net_storage_config_files` has been changed from `nil` to `[]` (#20)
21
+ - Minimum required Ruby version is now 2.7 (#21)
22
+ - Minimum required Bundler version is now 2.1 (#21)
23
+ - Minimum required Capistrano version is now 3.7.0 (#22)
24
+ - `:net_storage_archive_on_missing` has been renamed to `:net_storage_reuse_archive` (#22)
25
+ - Default value of `:net_storage_max_parallels` is now 1000 (#22)
26
+ - Default value of `:net_storage_local_base_path` is now `.local_net_storage` (#22)
27
+ - `:net_storage_local_#{mirror,releases,bundle,archives}_path` has been removed from settings (#22)
28
+ - `:net_storage_with_bundle` is renamed to `:net_storage_skip_bundle` (#22)
29
+ - Default value of `:net_storage_skip_bundle` is changed to conduct `bundle install` (#22)
30
+ - Default value of `:net_storage_upload_files_by_rsync` is now `true` (#22)
31
+
32
+
33
+ Bug Fixes:
34
+
35
+ - `IOError: closed stream` error from SSHKit has been fixed. (#13)
36
+ - Deprecation warning of `bundle install --path` and other option have been fixed (#14)
37
+ - Fix bug when `config_files` is an empty array (#14)
38
+ - Fix deprecation warning coming from Bundler.with_clean_env (#21)
39
+ - Allow Capistrano::NetStorage to deploy different Ruby versions (#28)
40
+
41
+ Improvement:
42
+
43
+ - The speed of config file deployment is dramatically improved by reducing `rsync` to 1 command (#13)
44
+ - The need of `.bundle/config` deployment is properly removed, and deployment becomes faster. (#14)
45
+ - Jitter duration has been introduced to increase stability for `rsync` and transport layer. (#22)
46
+
47
+ Internal Improvement (mainly for maintainers and plugin developers):
48
+
49
+ - Delegation system has been improved.
50
+ - `file_extension` is delegated to `:archiver` class (#14)
51
+ - Checking `local_bundle_path` is delegated to `:bundler` class (#14)
52
+ - `rsync` mechanism between cache and install directory has been improved (#14)
53
+ - Caching at `Capistrano::NetStorage::Config` has been removed to remove potential bugs (#14)
54
+ - `Capistrano::NetStorage::Transport#cleanup` is now mandatory (#15)
55
+ - GitHub Actions have been introduced for CI (#16, #17, #18)
56
+ - `:net_storage_archiver` class must implement `Capistrano::NetStorage::Archiver::SomeClass#.file_extension` (#22)
57
+ - `Capistrano::NetStorage::Config#archive_suffix` now shows deprecation warnings. (#22)
58
+ - All the default settings can be consulted via `Capistrano::NetStorage::Plugin#set_defaults` (#22)
59
+ - `:net_storage_servers` has been removed (#22)
60
+ - Large-scale refactoring (#22)
61
+ - `NotImplementedError` message has been improved to ease debugging for plugin developers (#25)
62
+
63
+
1
64
  ## 0.4.0 (2022/05/17)
2
65
 
3
66
  Fix Bug:
data/README.md CHANGED
@@ -1,5 +1,6 @@
1
1
  [![Gem Version](https://badge.fury.io/rb/capistrano-net_storage.svg)](https://badge.fury.io/rb/capistrano-net_storage)
2
- [![Build Status](https://travis-ci.org/DeNADev/capistrano-net_storage.svg?branch=master)](https://travis-ci.org/DeNADev/capistrano-net_storage)
2
+ [![Test](https://github.com/DeNADev/capistrano-net_storage/actions/workflows/test.yml/badge.svg)](https://github.com/DeNADev/capistrano-net_storage/actions/workflows/test.yml?query=branch%3Amaster)
3
+
3
4
  # Capistrano::NetStorage
4
5
 
5
6
  **Capistrano::NetStorage** is a [Capistrano](http://capistranorb.com/) plugin to deploy application
@@ -13,13 +14,14 @@ Logically, this tool enables _O(1)_ deployment.
13
14
 
14
15
  The image below illustrates the concept of **Capistrano::NetStorage**.
15
16
 
16
- ![concept](https://github.com/DeNADev/capistrano-net_storage/raw/resource/images/concept.png)
17
+ ![concept](docs/images/concept.png)
17
18
 
18
- This library goes following procedures as _capistrano tasks_:
19
+ This library conducts the following procedures as _capistrano tasks_:
19
20
 
20
21
  1. Prepare an archive of application to upload.
21
- * Clone or update source code repository on deploy server.
22
- * Do `bundle install` by an option.
22
+ * Clone and update source code repository on deploy server.
23
+ * Extract the internals to local release directory.
24
+ * Further prepare the local release. (e.g. `bundle install` and `assets:precompile`)
23
25
  2. Upload the archive to _remote storage_.
24
26
  3. Download the archive from _remote storage_ on application servers.
25
27
  * This task is executed in parallel way.
@@ -44,26 +46,39 @@ Or install it yourself as:
44
46
 
45
47
  Set Capistrano variables by `set name, value`.
46
48
 
49
+ You can consult configuration of Capistrano itself at https://capistranorb.com/documentation/getting-started/configuration/
50
+
51
+ Configurations of Capistrano::NetStorage are as follows:
52
+
53
+ #### General Settings
54
+
55
+ Name | Default | Description
56
+ ------|---------|------------
57
+ `:net_storage_transport` | NO DEFAULT | Transport class for _remote storage_ e.g. `Capistrano::NetStorage::S3`
58
+ `:net_storage_config_files` | `[]` | Files to sync `config/` directory on target servers' application directory
59
+
60
+ #### Settings for Behavioral Changes
61
+
62
+ Name | Default | Description
63
+ ------|---------|------------
64
+ `:net_storage_skip_bundle` | `false` | Skip `bundle install` when creating archive (might be work for non-Ruby app)
65
+ `:net_storage_multi_app_mode` | `false` | Deploy a repository with multiple Rails apps at the top directory
66
+
67
+ #### Other Settings
68
+
69
+ **NOTE: We strongly recommend the defaults for integrity and performance. Change at your own risk.**
70
+
47
71
  Name | Default | Description
48
72
  ------|---------|------------
49
- `:scm` | `nil` | Set `:net_storage` for capistrano before v3.7
50
- `:branch` | `master` | Target branch of SCM to release
51
- `:keep_releases` | `5` | Numbers to keep released versions
52
- `:net_storage_archiver` | `Capistrano::NetStorage::Archiver::Zip` | Archiver class
73
+ `:net_storage_archiver` | `Capistrano::NetStorage::Archiver::TarGzip` | Archiver class
53
74
  `:net_storage_scm` | `Capistrano::NetStorage::SCM::Git` | Internal scm class for application repository
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
- `:net_storage_config_files` | `nil` | Files to sync `config/` directory on target servers' application directory
57
- `:net_storage_max_parallels` | number of servers | Max concurrency for remote tasks
75
+ `:net_storage_upload_files_by_rsync` | `true` | Use rsync(1) to deploy config files
58
76
  `:net_storage_rsync_options` | `#{ssh_options}` | SSH options for rsync command to sync configs
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
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
77
+ `:net_storage_max_parallels` | 1000 | Max concurrency for remote tasks. (This default is being tuned by maintainers.)
78
+ `:net_storage_reuse_archive` | `true` | If `true`, it reuses archive with the same commit hash at remote storage and uploads archives only when it does not exist.
79
+ `:net_storage_local_base_path` | `.local_net_storage` | Base directory on deploy server
66
80
  `:net_storage_archives_path` | `#{deploy_to}/net_storage_archives` | Archive directories on application server
81
+ `:net_storage_keep_remote_archives` | 10 | Number of archive files keep on remote storage
67
82
 
68
83
  ### Transport Plugins
69
84
 
@@ -76,6 +91,8 @@ If you wish a plugin for other types of _remote storage_, you can develop it. It
76
91
 
77
92
  ## Usage
78
93
 
94
+ Below is the typical usage of Capistrano::NetStorage.
95
+
79
96
  Edit Capfile:
80
97
 
81
98
  ```ruby
@@ -86,34 +103,37 @@ require 'capistrano/setup'
86
103
  require 'capistrano/deploy'
87
104
 
88
105
  # Includes tasks from other gems included in your Gemfile
89
- if Gem::Version.new(Capistrano::VERSION) < Gem::Version.new('3.7.0')
90
- require 'capistrano/net_storage'
91
- else
92
- require "capistrano/net_storage/plugin"
93
- install_plugin Capistrano::NetStorage::Plugin
94
- end
106
+ require "capistrano/net_storage/plugin"
107
+ install_plugin Capistrano::NetStorage::Plugin
95
108
 
96
109
  # Load transport plugin for Capistrano::NetStorage
97
- # require 'capistrano/net_storage/s3'
110
+ require 'capistrano/net_storage/s3' # or your_custom_transport
98
111
  ```
99
112
 
100
113
  Edit your `config/deploy.rb`:
101
114
 
102
115
  ```ruby
103
- if Gem::Version.new(Capistrano::VERSION) < Gem::Version.new('3.7.0')
104
- set :scm, :net_storage
105
- end
106
- set :net_storage_transport, Your::TransportPluginModule
107
- # set :net_storage_transport, Capistrano::NetStorage::S3::Transport # w/ capistrano-net_storage-s3
108
- # set :net_storage_config_files, [your_config_files]
109
- # set :net_storage_with_bundle, true
110
- # set :net_storage_archiver, Capistrano::NetStorage::Archiver::TarGzip
116
+ set :net_storage_transport, Capistrano::NetStorage::S3::Transport # or YourCustomTransport class
117
+ set :net_storage_config_files, Pathname('path/to/config').glob('*.yml')
111
118
  ```
112
119
 
113
- ## Example
120
+ When you want to further prepare the release before deployment, you can write it as follows:
114
121
 
115
- You can see typical usage of this library by
116
- [capistrano-net_storage_demo](https://github.com/DeNADev/capistrano-net_storage_demo).
122
+ ```ruby
123
+ namespace :your_namespace do
124
+ task :prepare_archive do
125
+ run_locally do
126
+ within Capistrano::NetStorage.config.local_release_app_path do
127
+ # The resultant artifacts are to be archived with other files
128
+ execute :bundle, 'exec', 'rake', 'build_in_memory_cache_bundle'
129
+ execute :bundle, 'exec', 'rake', 'assets:precompile'
130
+ end
131
+ end
132
+ end
133
+ end
134
+
135
+ after 'net_storage:prepare_archive', 'your_namespace:prepare_archive'
136
+ ```
117
137
 
118
138
  ## License
119
139
 
@@ -123,4 +143,4 @@ Copyright (c) 2017 DeNA Co., Ltd., IKEDA Kiyoshi
123
143
 
124
144
  ## Special Thanks
125
145
 
126
- The previous version of this program was originally developed by @bobpp.
146
+ The previous version of this program was originally developed by @bobpp.
@@ -16,12 +16,12 @@ Gem::Specification.new do |spec|
16
16
  spec.homepage = 'https://github.com/DeNADev/capistrano-net_storage'
17
17
  spec.license = 'MIT'
18
18
 
19
- spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
19
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(\.github|docs|test|spec|features)/}) }
20
20
  spec.require_paths = ['lib']
21
- spec.required_ruby_version = '>= 2.0'
21
+ spec.required_ruby_version = '>= 2.7'
22
22
 
23
- spec.add_runtime_dependency 'capistrano', '>= 3.3.3'
24
- spec.add_runtime_dependency 'bundler'
23
+ spec.add_runtime_dependency 'capistrano', '>= 3.7'
24
+ spec.add_runtime_dependency 'bundler', '>= 2.1'
25
25
 
26
26
  spec.add_development_dependency 'rake'
27
27
  spec.add_development_dependency 'rspec'
@@ -1,25 +1,22 @@
1
1
  module Capistrano
2
2
  module NetStorage
3
3
  module Archiver
4
- # Abstract class to archive and extract whole application contents
5
- # @abstract
4
+ # Abstract class to archive release in local and extract release in remote
6
5
  class Base
7
- # Check prerequisites to archive
8
- # @abstract
9
6
  def check
10
- raise NotImplementedError
7
+ raise NotImplementedError, "Implement `#{self.class}#{__method__}` to check prerequisites for Archiver"
11
8
  end
12
9
 
13
- # Create archive
14
- # @abstract
15
10
  def archive
16
- raise NotImplementedError
11
+ raise NotImplementedError, "Implement `#{self.class}#{__method__}` to create archive from `Capistrano::NetStorage.config.local_release_path` to `Capistrano::NetStorage.config.local_archive_path`"
17
12
  end
18
13
 
19
- # Extract archive
20
- # @abstract
21
14
  def extract
22
- raise NotImplementedError
15
+ raise NotImplementedError, "Implement `#{self.class}#{__method__}` to extract archive from `Capistrano::NetStorage.config.archive_path` to `release_path`"
16
+ end
17
+
18
+ def self.file_extension
19
+ raise NotImplementedError, "Implement `#{self.class}#{__method__}` to return file extension String such as 'zip' or 'tar.gz'"
23
20
  end
24
21
  end
25
22
  end
@@ -1,10 +1,7 @@
1
1
  require 'capistrano/net_storage/archiver/base'
2
- require 'capistrano/net_storage/utils'
3
2
 
4
3
  # Archiver class for .tar.gz format
5
4
  class Capistrano::NetStorage::Archiver::TarGzip < Capistrano::NetStorage::Archiver::Base
6
- include Capistrano::NetStorage::Utils
7
-
8
5
  def check
9
6
  run_locally do
10
7
  execute :which, 'tar'
@@ -12,22 +9,27 @@ class Capistrano::NetStorage::Archiver::TarGzip < Capistrano::NetStorage::Archiv
12
9
  end
13
10
 
14
11
  def archive
15
- c = config
12
+ config = Capistrano::NetStorage.config
13
+
16
14
  run_locally do
17
- within c.local_release_path do
18
- execute :tar, 'czf', c.local_archive_path, '.'
15
+ within config.local_release_path do
16
+ execute :tar, 'czf', config.local_archive_path, '.'
19
17
  end
20
18
  end
21
19
  end
22
20
 
23
21
  def extract
24
- c = config
25
- on c.servers, in: :groups, limit: c.max_parallels do
26
- execute :mkdir, '-p', c.archives_path
22
+ config = Capistrano::NetStorage.config
23
+
24
+ on release_roles(:all), in: :groups, limit: config.max_parallels do
27
25
  execute :mkdir, '-p', release_path
28
26
  within release_path do
29
- execute :tar, 'xzf', c.archive_path
27
+ execute :tar, 'xzf', config.archive_path
30
28
  end
31
29
  end
32
30
  end
31
+
32
+ def self.file_extension
33
+ 'tar.gz'
34
+ end
33
35
  end
@@ -1,10 +1,7 @@
1
1
  require 'capistrano/net_storage/archiver/base'
2
- require 'capistrano/net_storage/utils'
3
2
 
4
3
  # Archiver class for zip format
5
4
  class Capistrano::NetStorage::Archiver::Zip < Capistrano::NetStorage::Archiver::Base
6
- include Capistrano::NetStorage::Utils
7
-
8
5
  def check
9
6
  run_locally do
10
7
  execute :which, 'zip'
@@ -12,22 +9,28 @@ class Capistrano::NetStorage::Archiver::Zip < Capistrano::NetStorage::Archiver::
12
9
  end
13
10
 
14
11
  def archive
15
- c = config
12
+ config = Capistrano::NetStorage.config
13
+
16
14
  run_locally do
17
- within c.local_release_path do
18
- execute :zip, c.local_archive_path, '-r', '.'
15
+ within config.local_release_path do
16
+ execute :zip, config.local_archive_path, '-r', '.'
19
17
  end
20
18
  end
21
19
  end
22
20
 
23
21
  def extract
24
- c = config
25
- on c.servers, in: :groups, limit: c.max_parallels do
26
- execute :mkdir, '-p', c.archives_path
22
+ config = Capistrano::NetStorage.config
23
+
24
+ on release_roles(:all), in: :groups, limit: config.max_parallels do
25
+ execute :mkdir, '-p', config.archives_path
27
26
  execute :mkdir, '-p', release_path
28
27
  within release_path do
29
- execute :unzip, c.archive_path
28
+ execute :unzip, config.archive_path
30
29
  end
31
30
  end
32
31
  end
32
+
33
+ def self.file_extension
34
+ 'zip'
35
+ end
33
36
  end
@@ -0,0 +1,55 @@
1
+ require 'bundler'
2
+
3
+ module Capistrano
4
+ module NetStorage
5
+ module Bundler
6
+ class Default
7
+ def check
8
+ config = Capistrano::NetStorage.config
9
+
10
+ run_locally do
11
+ execute :which, 'bundle'
12
+ execute :mkdir, '-p', config.local_bundle_path
13
+ end
14
+ end
15
+
16
+ # bundle install locally. `.bundle/config` and installed gems are to be included in the release and archive.
17
+ def install
18
+ config = Capistrano::NetStorage.config
19
+
20
+ run_locally do
21
+ within config.local_release_app_path do
22
+ ::Bundler.with_unbundled_env do
23
+ with rbenv_version: nil, rbenv_dir: nil do
24
+ bundle = if test :rbenv, 'version'
25
+ %w[rbenv exec bundle]
26
+ else
27
+ %w[bundle]
28
+ end
29
+
30
+ install_path = Pathname.new('vendor/bundle') # must be a relative path for portability between local and remote
31
+ execute :mkdir, '-p', install_path
32
+
33
+ # Sync installed gems from shared directory to speed up installation
34
+ execute :rsync, '-a', '--delete', "#{config.local_bundle_path}/", install_path
35
+
36
+ # Always set config
37
+ execute *bundle, 'config', 'set', '--local', 'deployment', 'true'
38
+ execute *bundle, 'config', 'set', '--local', 'path', install_path
39
+ execute *bundle, 'config', 'set', '--local', 'without', 'development test'
40
+ execute *bundle, 'config', 'set', '--local', 'disable_shared_gems', 'true'
41
+
42
+ execute *bundle, 'install', '--quiet'
43
+ execute *bundle, 'clean'
44
+
45
+ # Sync back to shared directory for the next release
46
+ execute :rsync, '-a', '--delete', "#{install_path}/", config.local_bundle_path
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,15 @@
1
+ module Capistrano
2
+ module NetStorage
3
+ module Bundler
4
+ class Null
5
+ def check
6
+ # Do nothing
7
+ end
8
+
9
+ def install
10
+ # Do nothing
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -1,35 +1,20 @@
1
- require 'capistrano/net_storage/utils'
2
-
3
1
  module Capistrano
4
2
  module NetStorage
5
3
  # Executor class for cleaning tasks
6
4
  class Cleaner
7
- include Capistrano::NetStorage::Utils
5
+ # Check for prerequisites.
6
+ # Same interface to delegated class
7
+ def check
8
+ end
8
9
 
9
10
  # Clean up old release directories on local.
10
11
  # Assumes they are under +config.local_releases_path+
11
12
  # @see Capistrano::NetStorage::Config#local_releases_path
12
13
  def cleanup_local_releases
13
- c = config
14
- run_locally do
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
14
+ config = Capistrano::NetStorage.config
23
15
 
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
16
+ run_locally do
17
+ Capistrano::NetStorage::Cleaner.clean_targets(config.local_releases_path, /^\d{14}$/)
33
18
  end
34
19
  end
35
20
 
@@ -37,24 +22,10 @@ module Capistrano
37
22
  # Assumes they are under +config.local_archives_path+
38
23
  # @see Capistrano::NetStorage::Config#local_archives_path
39
24
  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
25
+ config = Capistrano::NetStorage.config
48
26
 
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
27
+ run_locally do
28
+ Capistrano::NetStorage::Cleaner.clean_targets(config.local_archives_path, /^\d{14}\..+$/) # Do not care file extension
58
29
  end
59
30
  end
60
31
 
@@ -62,42 +33,37 @@ module Capistrano
62
33
  # Assumes they are under +config.archives_path+
63
34
  # @see Capistrano::NetStorage::Config#archives_path
64
35
  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 }
36
+ config = Capistrano::NetStorage.config
69
37
 
70
- if invalid.any?
71
- warn "Invalid contents in #{c.archives_path} on #{host}:\n#{invalid.join("\n")}"
72
- end
38
+ on release_roles(:all), in: :groups, limit: config.max_parallels do
39
+ Capistrano::NetStorage::Cleaner.clean_targets(config.archives_path, /^\d{14}\..+$/) # Do not care file extension
40
+ end
41
+ end
73
42
 
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
43
+ def self.clean_targets(target_parent_path, target_regexp)
44
+ files_or_directories = backend.capture(:ls, '-x', target_parent_path).split
45
+ targets, invalid = files_or_directories.partition { |e| target_regexp =~ e }
79
46
 
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
47
+ if invalid.any?
48
+ backend.warn "Invalid targets in #{target_parent_path} on #{backend.host}: #{invalid.inspect}"
49
+ end
90
50
 
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
96
- else
97
- info "No old archives (keeping newest #{fetch(:keep_releases)}) in #{c.archives_path} on #{host}"
51
+ if targets.count > fetch(:keep_releases)
52
+ backend.info "Keeping #{fetch(:keep_releases)} of #{targets.count} in #{target_parent_path} on #{backend.host}"
53
+ old_targets = (targets - targets.last(fetch(:keep_releases))).map do |target|
54
+ target_parent_path.join(target).to_s
55
+ end
56
+ old_targets.each_slice(100) do |old_targets_batch|
57
+ backend.execute :rm, '-rf', *old_targets_batch
98
58
  end
59
+ else
60
+ backend.info "No old targets (keeping newest #{fetch(:keep_releases)}) in #{target_parent_path} on #{backend.host}"
99
61
  end
100
62
  end
63
+
64
+ def self.backend
65
+ SSHKit::Backend.current
66
+ end
101
67
  end
102
68
  end
103
69
  end