capistrano-net_storage 0.5.0 → 1.0.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
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