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.
Files changed (40) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +33 -0
  3. data/Gemfile +1 -1
  4. data/Gemfile.lock +59 -34
  5. data/LICENSE.txt +1 -1
  6. data/README.md +27 -10
  7. data/development/Cheffile.lock +1 -5
  8. data/development/Vagrantfile +81 -71
  9. data/docs/buckets/apt-lists.md +18 -0
  10. data/docs/how-does-it-work.md +5 -6
  11. data/docs/index.md +24 -5
  12. data/docs/template.html +1 -0
  13. data/docs/usage.md +81 -28
  14. data/lib/vagrant-cachier/action/clean.rb +1 -1
  15. data/lib/vagrant-cachier/action/configure_bucket_root.rb +46 -0
  16. data/lib/vagrant-cachier/action/install_buckets.rb +47 -0
  17. data/lib/vagrant-cachier/bucket.rb +55 -0
  18. data/lib/vagrant-cachier/bucket/apt.rb +3 -12
  19. data/lib/vagrant-cachier/bucket/apt_cacher.rb +1 -13
  20. data/lib/vagrant-cachier/bucket/apt_lists.rb +24 -0
  21. data/lib/vagrant-cachier/bucket/chef.rb +1 -14
  22. data/lib/vagrant-cachier/bucket/composer.rb +1 -14
  23. data/lib/vagrant-cachier/bucket/gem.rb +4 -17
  24. data/lib/vagrant-cachier/bucket/npm.rb +1 -14
  25. data/lib/vagrant-cachier/bucket/pacman.rb +1 -14
  26. data/lib/vagrant-cachier/bucket/rvm.rb +4 -17
  27. data/lib/vagrant-cachier/bucket/yum.rb +4 -15
  28. data/lib/vagrant-cachier/bucket/zypper.rb +4 -15
  29. data/lib/vagrant-cachier/cap/debian/apt_lists_dir.rb +13 -0
  30. data/lib/vagrant-cachier/capabilities.rb +64 -0
  31. data/lib/vagrant-cachier/config.rb +35 -10
  32. data/lib/vagrant-cachier/hooks.rb +27 -0
  33. data/lib/vagrant-cachier/plugin.rb +12 -80
  34. data/lib/vagrant-cachier/version.rb +1 -1
  35. data/locales/en.yml +3 -7
  36. data/vagrant-cachier.gemspec +11 -1
  37. metadata +20 -12
  38. data/lib/vagrant-cachier/action/ensure_single_cache_root.rb +0 -64
  39. data/lib/vagrant-cachier/errors.rb +0 -9
  40. 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
+ ```
@@ -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 monkey patch `Vagrant::Builtin::Provision` and
24
- will set things up for each configured cache bucket _before and after_ running each
25
- defined provisioner. Before halting the machine, it will also revert the changes
26
- required to set things up by hooking into calls to `Vagrant::Builtin::GracefulHalt`
27
- so that you can repackage the machine for others to use without requiring users to
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.2+ and run:
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
- config.cache.auto_detect = true
27
- # If you are using VirtualBox, you might want to enable NFS for shared folders
28
- # config.cache.enable_nfs = true
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
- ## Compatible providers
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
- ## Auto detect supported cache buckets
3
+ ## Being nice to others
4
4
 
5
- This is the easiest way to get started with plugin. By adding the code below to
6
- your `Vagrantfile` you can enable automatic detection of supported cache _buckets_:
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
- config.cache.auto_detect = true
12
+ if Vagrant.has_plugin?("vagrant-cachier")
13
+ # ... vagrant-cachier configs ...
14
+ end
12
15
  end
13
16
  ```
14
17
 
15
- This will make vagrant-cachier do its best to find out what is supported on the
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
- _Please refer to the "Available Buckets" menu above to find out which buckets
31
- are supported._
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
- ## Cache scope
24
+ ### `:box` scope
34
25
 
35
- By default downloaded packages will get stored on a folder scoped to base boxes
36
- under your `$HOME/.vagrant.d/cache`. The idea is to leverage the cache by allowing
37
- downloaded packages to be reused across projects. So, if your `Vagrantfile` has
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
- config.cache.auto_detect = true
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
- config.cache.scope = :machine
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/cache/<box-name>/<optional-bucket-name>
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.debug "Removing symlink for '#{symlink}'"
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] << guest_path
13
+ return if @env[:cache_dirs].include?(guest_path)
17
14
 
18
- machine.communicate.tap do |comm|
19
- comm.execute("mkdir -p /tmp/vagrant-cache/#{@name}/partial")
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