vagrant-cachier 0.5.1 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +33 -0
- data/Gemfile +1 -1
- data/Gemfile.lock +59 -34
- data/LICENSE.txt +1 -1
- data/README.md +27 -10
- data/development/Cheffile.lock +1 -5
- data/development/Vagrantfile +81 -71
- data/docs/buckets/apt-lists.md +18 -0
- data/docs/how-does-it-work.md +5 -6
- data/docs/index.md +24 -5
- data/docs/template.html +1 -0
- data/docs/usage.md +81 -28
- data/lib/vagrant-cachier/action/clean.rb +1 -1
- data/lib/vagrant-cachier/action/configure_bucket_root.rb +46 -0
- data/lib/vagrant-cachier/action/install_buckets.rb +47 -0
- data/lib/vagrant-cachier/bucket.rb +55 -0
- data/lib/vagrant-cachier/bucket/apt.rb +3 -12
- data/lib/vagrant-cachier/bucket/apt_cacher.rb +1 -13
- data/lib/vagrant-cachier/bucket/apt_lists.rb +24 -0
- data/lib/vagrant-cachier/bucket/chef.rb +1 -14
- data/lib/vagrant-cachier/bucket/composer.rb +1 -14
- data/lib/vagrant-cachier/bucket/gem.rb +4 -17
- data/lib/vagrant-cachier/bucket/npm.rb +1 -14
- data/lib/vagrant-cachier/bucket/pacman.rb +1 -14
- data/lib/vagrant-cachier/bucket/rvm.rb +4 -17
- data/lib/vagrant-cachier/bucket/yum.rb +4 -15
- data/lib/vagrant-cachier/bucket/zypper.rb +4 -15
- data/lib/vagrant-cachier/cap/debian/apt_lists_dir.rb +13 -0
- data/lib/vagrant-cachier/capabilities.rb +64 -0
- data/lib/vagrant-cachier/config.rb +35 -10
- data/lib/vagrant-cachier/hooks.rb +27 -0
- data/lib/vagrant-cachier/plugin.rb +12 -80
- data/lib/vagrant-cachier/version.rb +1 -1
- data/locales/en.yml +3 -7
- data/vagrant-cachier.gemspec +11 -1
- metadata +20 -12
- data/lib/vagrant-cachier/action/ensure_single_cache_root.rb +0 -64
- data/lib/vagrant-cachier/errors.rb +0 -9
- data/lib/vagrant-cachier/provision_ext.rb +0 -74
@@ -0,0 +1,18 @@
|
|
1
|
+
# APT lists
|
2
|
+
|
3
|
+
Used by Debian-like Linux distros, will get configured under guest's `/var/lib/apt/lists`.
|
4
|
+
|
5
|
+
As explained on [Wikipedia](http://en.wikipedia.org/wiki/Advanced_Packaging_Tool#Files),
|
6
|
+
`/var/lib/apt/lists` is the "storage area for state information for each package
|
7
|
+
resource specified in sources.list". By enabling this bucket, `apt` will be able
|
8
|
+
to install cached packages without hitting the remote repositories for the main
|
9
|
+
package lists, [being particularly useful when developing offline](https://github.com/fgrehm/vagrant-cachier/pull/84#issue-27311414).
|
10
|
+
|
11
|
+
To manually enable it:
|
12
|
+
|
13
|
+
```ruby
|
14
|
+
Vagrant.configure("2") do |config|
|
15
|
+
config.vm.box = 'some-debian-box'
|
16
|
+
config.cache.enable :apt_lists
|
17
|
+
end
|
18
|
+
```
|
data/docs/how-does-it-work.md
CHANGED
@@ -20,12 +20,11 @@ _as part of_ the boot process (synced folders are actually `lxc-start` parameter
|
|
20
20
|
and as of now we are not able to get some information that this plugin requires
|
21
21
|
about the guest machine / container before it is actually up and running.
|
22
22
|
|
23
|
-
Under the hood, the plugin will
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
install the plugin as well.
|
23
|
+
Under the hood, the plugin will hook into Vagrant in order to set things up for each
|
24
|
+
configured cache bucket _before and after_ running each defined provisioner. Before
|
25
|
+
halting the machine, it will also revert the changes required to set things up by
|
26
|
+
hooking into calls to `Vagrant::Builtin::GracefulHalt` so that you can repackage
|
27
|
+
the machine for others to use without requiring users to install the plugin as well.
|
29
28
|
|
30
29
|
Please keep in mind that this plugin won't do magic, if you are compiling things
|
31
30
|
during provisioning or manually downloading packages outside of a bucket you
|
data/docs/index.md
CHANGED
@@ -9,7 +9,7 @@ multiple package managers and Linux distros.
|
|
9
9
|
|
10
10
|
## Installation
|
11
11
|
|
12
|
-
Make sure you have Vagrant 1.
|
12
|
+
Make sure you have Vagrant 1.4+ and run:
|
13
13
|
|
14
14
|
```
|
15
15
|
vagrant plugin install vagrant-cachier
|
@@ -23,21 +23,40 @@ from within your `Vagrantfile`:
|
|
23
23
|
```ruby
|
24
24
|
Vagrant.configure("2") do |config|
|
25
25
|
config.vm.box = 'your-box'
|
26
|
-
|
27
|
-
|
28
|
-
|
26
|
+
if Vagrant.has_plugin?("vagrant-cachier")
|
27
|
+
# Configure cached packages to be shared between instances of the same base box.
|
28
|
+
# More info on the "Usage" link above
|
29
|
+
config.cache.scope = :box
|
30
|
+
|
31
|
+
# If you are using VirtualBox, you might want to use that to enable NFS for
|
32
|
+
# shared folders. This is also very useful for vagrant-libvirt if you want
|
33
|
+
# bi-directional sync
|
34
|
+
config.cache.synced_folder_opts = {
|
35
|
+
type: :nfs,
|
36
|
+
# The nolock option can be useful for an NFSv3 client that wants to avoid the
|
37
|
+
# NLM sideband protocol. Without this option, apt-get might hang if it tries
|
38
|
+
# to lock files needed for /var/cache/* operations. All of this can be avoided
|
39
|
+
# by using NFSv4 everywhere. Please note that the tcp option is not the default.
|
40
|
+
mount_options: ['rw', 'vers=3', 'tcp', 'nolock']
|
41
|
+
}
|
42
|
+
end
|
29
43
|
end
|
30
44
|
```
|
31
45
|
|
32
46
|
For more information please check out the links on the menu above.
|
33
47
|
|
34
48
|
|
35
|
-
##
|
49
|
+
## Providers that are known to work
|
36
50
|
|
37
51
|
* Vagrant's built in VirtualBox provider
|
38
52
|
* [vagrant-lxc](https://github.com/fgrehm/vagrant-lxc)
|
39
53
|
* [VMware providers](http://www.vagrantup.com/vmware) with NFS enabled (See
|
40
54
|
[GH-24](https://github.com/fgrehm/vagrant-cachier/issues/24) for more info)
|
55
|
+
* [vagrant-libvirt](https://github.com/pradels/vagrant-libvirt)
|
56
|
+
* [vagrant-kvm](https://github.com/adrahon/vagrant-kvm)
|
57
|
+
|
58
|
+
_Please note that as of v0.6.0 the plugin will automatically disable any
|
59
|
+
previously defined configs for [cloud providers](lib/vagrant-cachier/plugin.rb#L19-22)_
|
41
60
|
|
42
61
|
|
43
62
|
## Contributing
|
data/docs/template.html
CHANGED
@@ -83,6 +83,7 @@
|
|
83
83
|
<a class="dropdown-toggle" data-toggle="dropdown" href="#">Available Buckets <span class="caret"></span></a>
|
84
84
|
<ul class="dropdown-menu">
|
85
85
|
<li><a tabindex="-1" href="buckets/apt">APT</a></li>
|
86
|
+
<li><a tabindex="-1" href="buckets/apt-lists">apt-lists</a></li>
|
86
87
|
<li><a tabindex="-1" href="buckets/apt-cacher">apt-cacher</a></li>
|
87
88
|
<li><a tabindex="-1" href="buckets/chef">Chef</a></li>
|
88
89
|
<li><a tabindex="-1" href="buckets/composer">Composer</a></li>
|
data/docs/usage.md
CHANGED
@@ -1,51 +1,46 @@
|
|
1
1
|
# Usage
|
2
2
|
|
3
|
-
##
|
3
|
+
## Being nice to others
|
4
4
|
|
5
|
-
|
6
|
-
|
5
|
+
It is a good practice to wrap plugin specific configuration with `has_plugin?` checks
|
6
|
+
so the user's Vagrantfiles do not break if `vagrant-cachier` is uninstalled or
|
7
|
+
the Vagrantfile is shared with people that don't have the plugin installed:
|
7
8
|
|
8
9
|
```ruby
|
9
10
|
Vagrant.configure("2") do |config|
|
10
11
|
# ...
|
11
|
-
|
12
|
+
if Vagrant.has_plugin?("vagrant-cachier")
|
13
|
+
# ... vagrant-cachier configs ...
|
14
|
+
end
|
12
15
|
end
|
13
16
|
```
|
14
17
|
|
15
|
-
|
16
|
-
guest machine and will set buckets accordingly.
|
17
|
-
|
18
|
-
## Enable buckets as needed
|
19
|
-
|
20
|
-
If for whatever reason you need to have a fined grained control over what buckets
|
21
|
-
are configured, you can do so by "cherry picking" them on your `Vagrantfile`:
|
22
|
-
|
23
|
-
```ruby
|
24
|
-
Vagrant.configure("2") do |config|
|
25
|
-
config.cache.enable :apt
|
26
|
-
config.cache.enable :gem
|
27
|
-
end
|
28
|
-
```
|
18
|
+
## Cache scope
|
29
19
|
|
30
|
-
|
31
|
-
|
20
|
+
This is the only required configuration for the plugin to work and should be present
|
21
|
+
on your project's specific `Vagrantfile` or on your `~/.vagrant.d/Vagrantfile` in
|
22
|
+
order to enable it.
|
32
23
|
|
33
|
-
|
24
|
+
### `:box` scope
|
34
25
|
|
35
|
-
By
|
36
|
-
under your
|
37
|
-
downloaded packages to be reused across projects. So, if your
|
38
|
-
something like:
|
26
|
+
By setting `cache.scope` to `:box`, downloaded packages will get stored on a folder
|
27
|
+
scoped to base boxes under your `~/.vagrant.d/cache`. The idea is to leverage the
|
28
|
+
cache by allowing downloaded packages to be reused across projects. So, if your
|
29
|
+
`Vagrantfile` has something like:
|
39
30
|
|
40
31
|
```ruby
|
41
32
|
Vagrant.configure("2") do |config|
|
42
33
|
config.vm.box = 'some-box'
|
43
|
-
|
34
|
+
if Vagrant.has_plugin?("vagrant-cachier")
|
35
|
+
config.cache.scope = :box
|
36
|
+
end
|
44
37
|
end
|
45
38
|
```
|
46
39
|
|
47
40
|
The cached files will be stored under `$HOME/.vagrant.d/cache/some-box`.
|
48
41
|
|
42
|
+
### `:machine` scope
|
43
|
+
|
49
44
|
If you are on a [multi VM environment](http://docs.vagrantup.com/v2/multi-machine/index.html),
|
50
45
|
there is a huge chance that you'll end up having issues by sharing the same bucket
|
51
46
|
across different machines. For example, if you `apt-get install` from two machines
|
@@ -56,13 +51,71 @@ to be based on machines:
|
|
56
51
|
```ruby
|
57
52
|
Vagrant.configure("2") do |config|
|
58
53
|
config.vm.box = 'some-box'
|
59
|
-
|
54
|
+
if Vagrant.has_plugin?("vagrant-cachier")
|
55
|
+
config.cache.scope = :machine
|
56
|
+
end
|
60
57
|
end
|
61
58
|
```
|
62
59
|
|
63
60
|
This will tell vagrant-cachier to download packages to `.vagrant/machines/<machine-name>/cache`
|
64
61
|
on your current project directory.
|
65
62
|
|
63
|
+
## Cache buckets automatic detection
|
64
|
+
|
65
|
+
This is the easiest way to get started with plugin and is enabled by default.
|
66
|
+
Under the hood, `vagrant-cachier` does its best to find out what is supported on the
|
67
|
+
guest machine and will set buckets accordingly.
|
68
|
+
|
69
|
+
If you want that behavior to be disabled, you can set `cache.auto_detect` to `false`
|
70
|
+
from your Vagrantfile:
|
71
|
+
|
72
|
+
```ruby
|
73
|
+
Vagrant.configure("2") do |config|
|
74
|
+
config.vm.box = 'some-box'
|
75
|
+
if Vagrant.has_plugin?("vagrant-cachier")
|
76
|
+
config.cache.scope = :machine # or :box
|
77
|
+
config.cache.auto_detect = false
|
78
|
+
end
|
79
|
+
end
|
80
|
+
```
|
81
|
+
|
82
|
+
## Enable buckets as needed
|
83
|
+
|
84
|
+
If for whatever reason you need to have a fined grained control over what buckets
|
85
|
+
are configured, you can do so by "cherry picking" them on your `Vagrantfile`:
|
86
|
+
|
87
|
+
```ruby
|
88
|
+
Vagrant.configure("2") do |config|
|
89
|
+
config.cache.auto_detect = false
|
90
|
+
config.cache.enable :apt
|
91
|
+
config.cache.enable :gem
|
92
|
+
end
|
93
|
+
```
|
94
|
+
|
95
|
+
_Please refer to the "Available Buckets" menu above to find out which buckets
|
96
|
+
are supported._
|
97
|
+
|
98
|
+
## Custom cache buckets synced folders options
|
99
|
+
|
100
|
+
For fine grained control over the cache bucket synced folder options you can use
|
101
|
+
the `synced_folder_opts` config. That's useful if, for example, you are using
|
102
|
+
VirtualBox and want to enable NFS for improved performance:
|
103
|
+
|
104
|
+
```ruby
|
105
|
+
Vagrant.configure("2") do |config|
|
106
|
+
config.cache.synced_folder_opts = {
|
107
|
+
type: :nfs,
|
108
|
+
# The nolock option can be useful for an NFSv3 client that wants to avoid the
|
109
|
+
# NLM sideband protocol. Without this option, apt-get might hang if it tries
|
110
|
+
# to lock files needed for /var/cache/* operations. All of this can be avoided
|
111
|
+
# by using NFSv4 everywhere. Please note that the tcp option is not the default.
|
112
|
+
mount_options: ['rw', 'vers=3', 'tcp', 'nolock']
|
113
|
+
}
|
114
|
+
end
|
115
|
+
```
|
116
|
+
|
117
|
+
Please referer to http://docs.vagrantup.com/v2/synced-folders/basic_usage.html for
|
118
|
+
more information about the supported parameters.
|
66
119
|
|
67
120
|
## Finding out disk space used by buckets
|
68
121
|
|
@@ -95,5 +148,5 @@ the code below if you are on a Linux machine:
|
|
95
148
|
$ rm -rf $HOME/.vagrant.d/cache/<box-name>/<optional-bucket-name>
|
96
149
|
|
97
150
|
# scope = :machine
|
98
|
-
$ rm -rf .vagrant/
|
151
|
+
$ rm -rf .vagrant/machines/<machine-name>/cache/<optional-bucket-name>
|
99
152
|
```
|
@@ -56,7 +56,7 @@ module VagrantPlugins
|
|
56
56
|
|
57
57
|
def remove_symlink(symlink)
|
58
58
|
if @machine.communicate.test("test -L #{symlink}")
|
59
|
-
@logger.
|
59
|
+
@logger.info "Removing symlink for '#{symlink}'"
|
60
60
|
@machine.communicate.sudo("unlink #{symlink}")
|
61
61
|
end
|
62
62
|
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'timeout'
|
2
|
+
|
3
|
+
module VagrantPlugins
|
4
|
+
module Cachier
|
5
|
+
class Action
|
6
|
+
class ConfigureBucketRoot
|
7
|
+
def initialize(app, env)
|
8
|
+
@app = app
|
9
|
+
@logger = Log4r::Logger.new("vagrant::cachier::action::clean")
|
10
|
+
end
|
11
|
+
|
12
|
+
def call(env)
|
13
|
+
@env = env
|
14
|
+
|
15
|
+
if !env[:cache_buckets_folder_configured] && env[:machine].config.cache.enabled?
|
16
|
+
setup_buckets_folder
|
17
|
+
env[:cache_buckets_folder_configured] = true
|
18
|
+
end
|
19
|
+
|
20
|
+
@app.call env
|
21
|
+
end
|
22
|
+
|
23
|
+
def setup_buckets_folder
|
24
|
+
FileUtils.mkdir_p(cache_root.to_s) unless cache_root.exist?
|
25
|
+
|
26
|
+
synced_folder_opts = {id: "vagrant-cache"}
|
27
|
+
synced_folder_opts.merge!(@env[:machine].config.cache.synced_folder_opts || {})
|
28
|
+
|
29
|
+
@env[:machine].config.vm.synced_folder cache_root, '/tmp/vagrant-cache', synced_folder_opts
|
30
|
+
@env[:cache_dirs] = []
|
31
|
+
end
|
32
|
+
|
33
|
+
def cache_root
|
34
|
+
@cache_root ||= case @env[:machine].config.cache.scope.to_sym
|
35
|
+
when :box
|
36
|
+
@env[:home_path].join('cache', @env[:machine].box.name)
|
37
|
+
when :machine
|
38
|
+
@env[:machine].data_dir.parent.join('cache')
|
39
|
+
else
|
40
|
+
raise "Unknown cache scope: '#{@env[:machine].config.cache.scope}'"
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require_relative '../bucket'
|
2
|
+
|
3
|
+
module VagrantPlugins
|
4
|
+
module Cachier
|
5
|
+
class Action
|
6
|
+
class InstallBuckets
|
7
|
+
def initialize(app, env, opts = {})
|
8
|
+
@app = app
|
9
|
+
@logger = Log4r::Logger.new("vagrant::cachier::action::clean")
|
10
|
+
@opts = opts
|
11
|
+
end
|
12
|
+
|
13
|
+
def call(env)
|
14
|
+
@app.call(env)
|
15
|
+
|
16
|
+
return unless env[:machine].config.cache.enabled?
|
17
|
+
|
18
|
+
chmod_bucket_root(env[:machine]) if @opts[:chmod]
|
19
|
+
configure_cache_buckets(env)
|
20
|
+
end
|
21
|
+
|
22
|
+
def chmod_bucket_root(machine)
|
23
|
+
@logger.info "'chmod'ing bucket root dir to 777..."
|
24
|
+
machine.communicate.sudo 'mkdir -p /tmp/vagrant-cache && chmod 777 /tmp/vagrant-cache'
|
25
|
+
end
|
26
|
+
|
27
|
+
def configure_cache_buckets(env)
|
28
|
+
if env[:machine].config.cache.auto_detect
|
29
|
+
Bucket.auto_detect(env)
|
30
|
+
end
|
31
|
+
|
32
|
+
return unless env[:machine].config.cache.buckets.any?
|
33
|
+
|
34
|
+
env[:ui].info 'Configuring cache buckets...'
|
35
|
+
cache_config = env[:machine].config.cache
|
36
|
+
cache_config.buckets.each do |bucket_name, configs|
|
37
|
+
@logger.info "Installing #{bucket_name} with configs #{configs.inspect}"
|
38
|
+
Bucket.install(bucket_name, env, configs)
|
39
|
+
end
|
40
|
+
|
41
|
+
data_file = env[:machine].data_dir.join('cache_dirs')
|
42
|
+
data_file.open('w') { |f| f.print env[:cache_dirs].uniq.join("\n") }
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -29,6 +29,60 @@ module VagrantPlugins
|
|
29
29
|
@env = env
|
30
30
|
@configs = configs
|
31
31
|
end
|
32
|
+
|
33
|
+
def machine
|
34
|
+
@env[:machine]
|
35
|
+
end
|
36
|
+
|
37
|
+
def guest
|
38
|
+
machine.guest
|
39
|
+
end
|
40
|
+
|
41
|
+
def comm
|
42
|
+
machine.communicate
|
43
|
+
end
|
44
|
+
|
45
|
+
# TODO: "merge" symlink and user_symlink methods
|
46
|
+
def symlink(guest_path, bucket_path = "/tmp/vagrant-cache/#{@name}", create_parent: true)
|
47
|
+
return if @env[:cache_dirs].include?(guest_path)
|
48
|
+
|
49
|
+
@env[:cache_dirs] << guest_path
|
50
|
+
comm.execute("mkdir -p #{bucket_path}")
|
51
|
+
unless symlink?(guest_path)
|
52
|
+
comm.sudo("mkdir -p `dirname #{guest_path}`") if create_parent
|
53
|
+
if empty_dir?(bucket_path) && !empty_dir?(guest_path)
|
54
|
+
# Warm up cache with guest machine data
|
55
|
+
comm.sudo("shopt -s dotglob && mv #{guest_path}/* #{bucket_path}")
|
56
|
+
end
|
57
|
+
comm.sudo("rm -rf #{guest_path}")
|
58
|
+
comm.sudo("ln -s #{bucket_path} #{guest_path}")
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def user_symlink(guest_path)
|
63
|
+
return if @env[:cache_dirs].include?(guest_path)
|
64
|
+
|
65
|
+
@env[:cache_dirs] << guest_path
|
66
|
+
bucket_path = "/tmp/vagrant-cache/#{@name}"
|
67
|
+
comm.execute("mkdir -p #{bucket_path}")
|
68
|
+
unless symlink?(guest_path)
|
69
|
+
comm.execute("mkdir -p `dirname #{guest_path}`")
|
70
|
+
if empty_dir?(bucket_path) && !empty_dir?(guest_path)
|
71
|
+
# Warm up cache with guest machine data
|
72
|
+
comm.execute("shopt -s dotglob && mv #{guest_path}/* #{bucket_path}")
|
73
|
+
end
|
74
|
+
comm.execute("rm -rf #{guest_path}")
|
75
|
+
comm.execute("ln -s #{bucket_path} #{guest_path}")
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def empty_dir?(path)
|
80
|
+
not comm.test("test \"$(ls -A #{path} 2>/dev/null)\"")
|
81
|
+
end
|
82
|
+
|
83
|
+
def symlink?(path)
|
84
|
+
comm.test("test -L #{path}")
|
85
|
+
end
|
32
86
|
end
|
33
87
|
end
|
34
88
|
end
|
@@ -40,6 +94,7 @@ require_relative "bucket/pacman"
|
|
40
94
|
require_relative "bucket/yum"
|
41
95
|
require_relative "bucket/rvm"
|
42
96
|
require_relative "bucket/apt_cacher"
|
97
|
+
require_relative "bucket/apt_lists"
|
43
98
|
require_relative "bucket/composer"
|
44
99
|
require_relative "bucket/npm"
|
45
100
|
require_relative "bucket/zypper"
|
@@ -7,22 +7,13 @@ module VagrantPlugins
|
|
7
7
|
end
|
8
8
|
|
9
9
|
def install
|
10
|
-
machine = @env[:machine]
|
11
|
-
guest = machine.guest
|
12
|
-
|
13
10
|
if guest.capability?(:apt_cache_dir)
|
14
11
|
guest_path = guest.capability(:apt_cache_dir)
|
15
12
|
|
16
|
-
@env[:cache_dirs]
|
13
|
+
return if @env[:cache_dirs].include?(guest_path)
|
17
14
|
|
18
|
-
|
19
|
-
|
20
|
-
unless comm.test("test -L #{guest_path}")
|
21
|
-
comm.sudo("rm -rf #{guest_path}")
|
22
|
-
comm.sudo("mkdir -p `dirname #{guest_path}`")
|
23
|
-
comm.sudo("ln -s /tmp/vagrant-cache/#{@name} #{guest_path}")
|
24
|
-
end
|
25
|
-
end
|
15
|
+
symlink(guest_path)
|
16
|
+
comm.execute("mkdir -p /tmp/vagrant-cache/#{@name}/partial")
|
26
17
|
else
|
27
18
|
@env[:ui].info I18n.t('vagrant_cachier.skipping_bucket', bucket: 'APT')
|
28
19
|
end
|