This commit is contained in:
Fabio Rehm 2014-02-25 23:57:39 -03:00
commit 1e56a616e9
37 changed files with 686 additions and 556 deletions

View file

@ -1,5 +1,35 @@
## [0.5.2](https://github.com/fgrehm/vagrant-cachier/compare/v0.5.1...master) (unreleased) ## [0.6.0](https://github.com/fgrehm/vagrant-cachier/compare/v0.5.1...v0.6.0) (Feb 26, 2014)
BACKWARDS INCOMPATIBILITY:
- Plugin activation is now triggered by the `cache.scope` config and that config
is now required. Previous versions of the plugin had it set to `:box` but
there is no consensus whether `:box` and `:machine` is better. This is to
highlight that you need to think about the caching strategy you are going
to use. For more information and to discuss this move please check [GH-17](https://github.com/fgrehm/vagrant-cachier/issues/17).
- Because `cache.scope` is now a requirement and in order to reduce the amount of
configuration required by the plugin, we enabled automatic bucket detection by
default. To revert to the old behavior you can disable it globally from your
`~/.vagrant.d/Vagrantfile`.
- Support for Vagrant < 1.4 is gone, please use a previous plugin version if
you are running Vagrant 1.2 / 1.3
- Automatic handling of multiple machine scoped cache dirs from versions
prior to 0.3.0 of this plugin was removed.
- Support for `enable_nfs` has been deprecated and will be removed on 0.7.0,
please use `cache.synced_folder_opts = {type: :nfs}` instead.
FEATURES:
- Warm up cache buckets with files available on guest in case bucket is empty
- Support for offline provisioning of apt-packages by caching `/var/lib/apt/lists` [GH-84]
- Support for specifying custom cache bucket synced folder opts
- Support to force disabe the plugin [GH-72]
- Automatically disable the plugin for cloud providers [GH-45]
- Skip configuration of buckets that have been configured already [GH-85]
BUG FIXES:
- Properly fix NFS support for Vagrant 1.4+ [GH-76]
## [0.5.1](https://github.com/fgrehm/vagrant-cachier/compare/v0.5.0...v0.5.1) (Dec 20, 2013) ## [0.5.1](https://github.com/fgrehm/vagrant-cachier/compare/v0.5.0...v0.5.1) (Dec 20, 2013)

View file

@ -4,7 +4,7 @@ source 'https://rubygems.org'
gemspec gemspec
group :development do group :development do
gem 'vagrant', github: 'mitchellh/vagrant' gem 'vagrant', github: 'mitchellh/vagrant', tag: 'v1.4.3'
gem 'vagrant-lxc', github: 'fgrehm/vagrant-lxc' gem 'vagrant-lxc', github: 'fgrehm/vagrant-lxc'
gem 'vagrant-pristine', github: 'fgrehm/vagrant-pristine' gem 'vagrant-pristine', github: 'fgrehm/vagrant-pristine'
gem 'vagrant-global-status', github: 'fgrehm/vagrant-global-status' gem 'vagrant-global-status', github: 'fgrehm/vagrant-global-status'

View file

@ -1,104 +1,129 @@
GIT GIT
remote: git://github.com/fgrehm/vagrant-global-status.git remote: git://github.com/fgrehm/vagrant-global-status.git
revision: a0295400a0e47756cbcb8f97ed9f4449b1fb6b56 revision: 8ae82e2c57b085a030137a40e9b3d232f42e5117
specs: specs:
vagrant-global-status (0.1.1) vagrant-global-status (0.1.5.dev)
GIT GIT
remote: git://github.com/fgrehm/vagrant-lxc.git remote: git://github.com/fgrehm/vagrant-lxc.git
revision: 225af5622767059708278db29d42941e93d41994 revision: 1083f100adc4cf1bd20e7eb794ecfda94ef8b365
specs: specs:
vagrant-lxc (0.6.4.dev) vagrant-lxc (0.7.1.dev)
GIT GIT
remote: git://github.com/fgrehm/vagrant-pristine.git remote: git://github.com/fgrehm/vagrant-pristine.git
revision: 4638491786943bfbf6f115b1fc379f069963fe46 revision: 503dbc47848c81d0fbfa6840491856f518d244a1
specs: specs:
vagrant-pristine (0.3.0) vagrant-pristine (0.3.0)
GIT GIT
remote: git://github.com/mitchellh/vagrant.git remote: git://github.com/mitchellh/vagrant.git
revision: 57e95323b6600b146167f0f14f83b22dd31dd03f revision: 4f0eb9504cc786d5a57a43814427e8eb35407a4c
tag: v1.4.3
specs: specs:
vagrant (1.3.6.dev) vagrant (1.4.3)
childprocess (~> 0.3.7) childprocess (~> 0.3.7)
erubis (~> 2.7.0) erubis (~> 2.7.0)
i18n (~> 0.6.0) i18n (~> 0.6.0)
log4r (~> 1.1.9) log4r (~> 1.1.9)
net-scp (~> 1.1.0) net-scp (~> 1.1.0)
net-ssh (~> 2.6.6) net-ssh (>= 2.6.6, < 2.8.0)
PATH PATH
remote: . remote: .
specs: specs:
vagrant-cachier (0.5.2.dev) vagrant-cachier (0.6.0)
GEM GEM
remote: https://rubygems.org/ remote: https://rubygems.org/
specs: specs:
archive-tar-minitar (0.5.2) archive-tar-minitar (0.5.2)
chef (11.6.0) chef (11.8.2)
erubis chef-zero (~> 1.6, >= 1.6.2)
highline (>= 1.6.9) diff-lcs (~> 1.2, >= 1.2.4)
erubis (~> 2.7)
highline (~> 1.6, >= 1.6.9)
json (>= 1.4.4, <= 1.7.7) json (>= 1.4.4, <= 1.7.7)
mixlib-authentication (>= 1.3.0) mime-types (~> 1.16)
mixlib-cli (~> 1.3.0) mixlib-authentication (~> 1.3)
mixlib-config (>= 1.1.2) mixlib-cli (~> 1.3)
mixlib-log (>= 1.3.0) mixlib-config (~> 2.0)
mixlib-shellout mixlib-log (~> 1.3)
mixlib-shellout (~> 1.2)
net-ssh (~> 2.6) net-ssh (~> 2.6)
net-ssh-multi (~> 1.1.0) net-ssh-multi (~> 1.1.0)
ohai (>= 0.6.0) ohai (~> 6.0)
pry (~> 0.9)
puma (~> 1.6)
rest-client (>= 1.0.4, < 1.7.0) rest-client (>= 1.0.4, < 1.7.0)
yajl-ruby (~> 1.1) yajl-ruby (~> 1.1)
chef-zero (1.7.2)
hashie (~> 2.0)
json
mixlib-log (~> 1.3)
moneta (< 0.7.0)
rack
childprocess (0.3.9) childprocess (0.3.9)
ffi (~> 1.0, >= 1.0.11) ffi (~> 1.0, >= 1.0.11)
coderay (1.1.0)
diff-lcs (1.2.5)
erubis (2.7.0) erubis (2.7.0)
ffi (1.9.0) ffi (1.9.3)
highline (1.6.19) hashie (2.0.5)
i18n (0.6.5) highline (1.6.20)
i18n (0.6.9)
ipaddress (0.8.0) ipaddress (0.8.0)
json (1.7.7) json (1.7.7)
librarian (0.1.0) librarian (0.1.1)
highline highline
thor (~> 0.15) thor (~> 0.15)
librarian-chef (0.0.1) librarian-chef (0.0.2)
archive-tar-minitar (>= 0.5.2) archive-tar-minitar (>= 0.5.2)
chef (>= 0.10) chef (>= 0.10)
librarian (~> 0.1.0) librarian (~> 0.1.0)
log4r (1.1.10) log4r (1.1.10)
mime-types (1.23) method_source (0.8.2)
mime-types (1.25.1)
mixlib-authentication (1.3.0) mixlib-authentication (1.3.0)
mixlib-log mixlib-log
mixlib-cli (1.3.0) mixlib-cli (1.4.0)
mixlib-config (1.1.2) mixlib-config (2.1.0)
mixlib-log (1.6.0) mixlib-log (1.6.0)
mixlib-shellout (1.2.0) mixlib-shellout (1.3.0)
moneta (0.6.0)
net-scp (1.1.2) net-scp (1.1.2)
net-ssh (>= 2.6.5) net-ssh (>= 2.6.5)
net-ssh (2.6.8) net-ssh (2.7.0)
net-ssh-gateway (1.2.0) net-ssh-gateway (1.2.0)
net-ssh (>= 2.6.5) net-ssh (>= 2.6.5)
net-ssh-multi (1.1) net-ssh-multi (1.1)
net-ssh (>= 2.1.4) net-ssh (>= 2.1.4)
net-ssh-gateway (>= 0.99.0) net-ssh-gateway (>= 0.99.0)
ohai (6.18.0) ohai (6.20.0)
ipaddress ipaddress
mixlib-cli mixlib-cli
mixlib-config mixlib-config
mixlib-log mixlib-log
mixlib-shellout mixlib-shellout
systemu systemu (~> 2.5.2)
yajl-ruby yajl-ruby
rake (10.1.0) pry (0.9.12.4)
coderay (~> 1.0)
method_source (~> 0.8)
slop (~> 3.4)
puma (1.6.3)
rack (~> 1.2)
rack (1.5.2)
rake (10.1.1)
rest-client (1.6.7) rest-client (1.6.7)
mime-types (>= 1.16) mime-types (>= 1.16)
slop (3.4.7)
systemu (2.5.2) systemu (2.5.2)
thor (0.18.1) thor (0.18.1)
vagrant-librarian-chef (0.1.2) vagrant-librarian-chef (0.1.4)
librarian-chef librarian-chef
vagrant-omnibus (1.1.2) vagrant-omnibus (1.2.1)
yajl-ruby (1.1.0) yajl-ruby (1.2.0)
PLATFORMS PLATFORMS
ruby ruby

View file

@ -1,5 +1,7 @@
# vagrant-cachier # vagrant-cachier
[![Gem Version](https://badge.fury.io/rb/vagrant-cachier.png)](http://badge.fury.io/rb/vagrant-cachier) [![Gittip](http://img.shields.io/gittip/fgrehm.svg)](https://www.gittip.com/fgrehm/)
A [Vagrant](http://www.vagrantup.com/) plugin that helps you reduce the amount of A [Vagrant](http://www.vagrantup.com/) plugin that helps you reduce the amount of
coffee you drink while waiting for boxes to be provisioned by sharing a common coffee you drink while waiting for boxes to be provisioned by sharing a common
package cache among similiar VM instances. Kinda like [vagrant-apt_cache](https://github.com/avit/vagrant-apt_cache) package cache among similiar VM instances. Kinda like [vagrant-apt_cache](https://github.com/avit/vagrant-apt_cache)
@ -9,7 +11,7 @@ multiple package managers and Linux distros.
## Installation ## Installation
Make sure you have Vagrant 1.2+ and run: Make sure you have Vagrant 1.4+ and run:
``` ```
vagrant plugin install vagrant-cachier vagrant plugin install vagrant-cachier
@ -17,16 +19,26 @@ vagrant plugin install vagrant-cachier
## Quick start ## Quick start
The easiest way to set things up is just to enable [cache buckets auto detection](http://fgrehm.viewdocs.io/vagrant-cachier/usage)
from within your `Vagrantfile`:
```ruby ```ruby
Vagrant.configure("2") do |config| Vagrant.configure("2") do |config|
config.vm.box = 'your-box' config.vm.box = 'your-box'
if Vagrant.has_plugin?("vagrant-cachier") if Vagrant.has_plugin?("vagrant-cachier")
config.cache.auto_detect = true # Configure cached packages to be shared between instances of the same base box.
# If you are using VirtualBox, you might want to enable NFS for shared folders # More info on http://fgrehm.viewdocs.io/vagrant-cachier/usage
# config.cache.enable_nfs = true config.cache.scope = :box
# If you are using VirtualBox, you might want to use that to enable NFS for
# shared folders. This is also very useful for vagrant-libvirt if you want
# bi-directional sync
config.cache.synced_folder_opts = {
type: :nfs,
# The nolock option can be useful for an NFSv3 client that wants to avoid the
# NLM sideband protocol. Without this option, apt-get might hang if it tries
# to lock files needed for /var/cache/* operations. All of this can be avoided
# by using NFSv4 everywhere. Please note that the tcp option is not the default.
mount_options: ['rw', 'vers=3', 'tcp', 'nolock']
}
# For more information please check http://docs.vagrantup.com/v2/synced-folders/basic_usage.html
end end
end end
``` ```
@ -35,12 +47,17 @@ For more information please read the documentation available at
http://fgrehm.viewdocs.io/vagrant-cachier. http://fgrehm.viewdocs.io/vagrant-cachier.
## Compatible providers ## Providers that are known to work
* Vagrant's built in VirtualBox provider * Vagrant's built in VirtualBox provider
* [vagrant-lxc](https://github.com/fgrehm/vagrant-lxc) * [vagrant-lxc](https://github.com/fgrehm/vagrant-lxc)
* [VMware providers](http://www.vagrantup.com/vmware) with NFS enabled (See * [VMware providers](http://www.vagrantup.com/vmware) with NFS enabled (See
[GH-24](https://github.com/fgrehm/vagrant-cachier/issues/24) for more info) [GH-24](https://github.com/fgrehm/vagrant-cachier/issues/24) for more info)
* [docker-provider](https://github.com/fgrehm/docker-provider)
* _[Let me know if it is compatible with other providers!](https://github.com/fgrehm/vagrant-cachier/issues/new)_
_Please note that as of v0.6.0 the plugin will automatically disable any
previously defined configs for [cloud providers](lib/vagrant-cachier/plugin.rb#L19-22)_
## Contributing ## Contributing
@ -50,5 +67,3 @@ http://fgrehm.viewdocs.io/vagrant-cachier.
3. Commit your changes (`git commit -am 'Add some feature'`) 3. Commit your changes (`git commit -am 'Add some feature'`)
4. Push to the branch (`git push origin my-new-feature`) 4. Push to the branch (`git push origin my-new-feature`)
5. Create new Pull Request 5. Create new Pull Request
[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/fgrehm/vagrant-cachier/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

View file

@ -1,11 +1,7 @@
SITE SITE
remote: http://community.opscode.com/api/v1 remote: http://community.opscode.com/api/v1
specs: specs:
chef_handler (1.1.4) java (1.19.2)
java (1.12.0)
windows (>= 0.0.0)
windows (1.10.0)
chef_handler (>= 0.0.0)
DEPENDENCIES DEPENDENCIES
java (>= 0) java (>= 0)

View file

@ -12,116 +12,126 @@ Vagrant.configure("2") do |config|
config.cache.scope = :machine config.cache.scope = :machine
config.cache.auto_detect = true config.cache.auto_detect = true
config.cache.enable_nfs = true config.cache.synced_folder_opts = { type: :nfs }
config.omnibus.chef_version = :latest config.vm.provider :virtualbox do |vb|
config.vm.provision :chef_solo do |chef| vb.customize [ "modifyvm", :id, "--memory", 256, "--cpus", "1" ]
chef.add_recipe "java::oracle"
chef.json = {
:java => {
:oracle => {
:accept_oracle_download_terms => true
}
}
}
end end
# Installs RVM
config.vm.provision :shell, inline: '
if ! [ -d /home/vagrant/.rvm ]; then
HOME=/home/vagrant su -p vagrant -l -c "curl -L https://get.rvm.io | bash -s stable"
fi
'
# Here we have the RVM cache bucket configured, so we install 2.0.0
config.vm.provision :shell, inline: '
if ! [ -d /home/vagrant/.rvm/rubies/ruby-1.9.3* ]; then
HOME=/home/vagrant su -p vagrant -l -c "rvm install 1.9.3 && rvm use 1.9.3 --default"
fi
'
config.vm.provision :shell, inline: '
if ! [ -d /home/vagrant/.nvm ]; then
apt-get install git -y
HOME=/home/vagrant su -p vagrant -l -c "
curl https://raw.github.com/creationix/nvm/master/install.sh | sh
"
fi
'
config.vm.provision :shell, inline: '
if ! [ -d /home/vagrant/.nvm/v0.10* ]; then
HOME=/home/vagrant su -p vagrant -l -c "
nvm install 0.10
nvm alias default 0.10
"
fi
'
configure_private_network = lambda do |node, suffix| configure_private_network = lambda do |node, suffix|
node.vm.network :private_network, ip: "192.168.50.#{suffix}" node.vm.network :private_network, ip: "192.168.50.#{suffix}"
end end
debian_like_configs = lambda do |debian| initial_debian_setup = lambda do |debian, git_pkg = 'git'|
# Here we have the RubyGems cache bucket configured to the right path, so we debian.vm.provision :shell, inline: "apt-get update && apt-get install -y #{git_pkg} php5-cli curl wget htop"
# bundle the project end
debian.vm.provision :shell, inline: '
sudo apt-get install -y git php5-cli install_nvm_and_rvm = lambda do |node|
HOME=/home/vagrant su -p vagrant -l -c "cd /vagrant && bundle" # Installs RVM
node.vm.provision :shell, inline: '
if ! [ -d /home/vagrant/.rvm ]; then
HOME=/home/vagrant su -p vagrant -l -c "curl -L https://get.rvm.io | bash -s stable"
fi
'
# Here we have the RVM cache bucket configured, so we install 2.0.0
node.vm.provision :shell, inline: '
if ! [ -d /home/vagrant/.rvm/rubies/ruby-2.0.0* ]; then
HOME=/home/vagrant su -p vagrant -l -c "rvm install 2.0.0 && rvm use 2.0.0 --default"
fi
'
node.vm.provision :shell, inline: '
if ! [ -d /home/vagrant/.nvm ]; then
apt-get install git -y
HOME=/home/vagrant su -p vagrant -l -c "
curl https://raw.github.com/creationix/nvm/master/install.sh | sh
"
fi
'
node.vm.provision :shell, inline: '
if ! [ -d /home/vagrant/.nvm/v0.10* ]; then
HOME=/home/vagrant su -p vagrant -l -c "
nvm install 0.10
nvm alias default 0.10
"
fi
' '
end end
config.vm.define :ubuntu do |ubuntu| config.vm.define :ubuntu do |ubuntu|
ubuntu.vm.box = "quantal64" ubuntu.vm.box = "quantal64"
debian_like_configs.call ubuntu
configure_private_network.call ubuntu, 10 configure_private_network.call ubuntu, 10
initial_debian_setup.call(ubuntu)
install_nvm_and_rvm.call(ubuntu)
ubuntu.omnibus.chef_version = :latest
ubuntu.vm.provision :chef_solo do |chef|
chef.add_recipe "java::oracle"
chef.json = {
:java => {
:oracle => {
:accept_oracle_download_terms => true
}
}
}
end
end end
config.vm.define :lucid do |lucid| config.vm.define :lucid do |lucid|
lucid.vm.box = "lucid64" lucid.vm.box = "lucid64"
debian_like_configs.call lucid # Disable NFS
lucid.cache.synced_folder_opts = { }
configure_private_network.call lucid, 11 configure_private_network.call lucid, 11
initial_debian_setup.call(lucid, 'git-core')
install_nvm_and_rvm.call(lucid)
end end
config.vm.define :debian do |debian| config.vm.define :debian do |debian|
debian.vm.box = "squeeze64" debian.vm.box = "squeeze64"
debian.vm.box_url = 'http://f.willianfernandes.com.br/vagrant-boxes/DebianSqueeze64.box' debian.vm.box_url = 'http://f.willianfernandes.com.br/vagrant-boxes/DebianSqueeze64.box'
debian_like_configs.call debian
configure_private_network.call debian, 12 configure_private_network.call debian, 12
initial_debian_setup.call(debian)
install_nvm_and_rvm.call(debian)
end end
config.vm.define :centos do |centos| config.vm.define :centos do |centos|
centos.vm.box = 'centos6_64' centos.vm.box = 'centos6_64'
centos.vm.box_url = 'http://developer.nrel.gov/downloads/vagrant-boxes/CentOS-6.4-x86_64-v20130309.box' centos.vm.box_url = 'http://developer.nrel.gov/downloads/vagrant-boxes/CentOS-6.4-x86_64-v20130309.box'
configure_private_network.call centos, 13 configure_private_network.call centos, 13
# Here we have the RubyGems cache bucket configured to the right path, so we
# bundle the project
centos.vm.provision :shell, inline: ' centos.vm.provision :shell, inline: '
yum install -y libffi-devel ruby-devel git (
HOME=/home/vagrant su -p vagrant -l -c "cd /vagrant && bundle"' mkdir -p /tmp/epel
cd /tmp/epel
wget http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm
wget http://rpms.famillecollet.com/enterprise/remi-release-6.rpm
sudo rpm -Uvh remi-release-6*.rpm epel-release-6*.rpm
)
yum install -y libffi-devel ruby-devel git
'
centos.vm.provision :shell, inline: 'gem install bundler'
end end
config.vm.define :arch do |arch| config.vm.define :arch do |arch|
arch.vm.box = 'arch64' arch.vm.box = 'arch64'
arch.vm.box_url = 'http://vagrant.pouss.in/archlinux_2012-07-02.box' arch.vm.box_url = 'https://dl.dropboxusercontent.com/u/6750592/Arch_Linux_2013.11_x64.box'
configure_private_network.call arch, 14 # Disable NFS
arch.vm.provision :shell, inline: ' arch.cache.synced_folder_opts = { }
pacman -Syu --noconfirm libffi git
HOME=/home/vagrant su -p vagrant -l -c "cd /vagrant && bundle"' arch.vm.provision :shell, inline: 'pacman -Syu --noconfirm libffi git ruby && gem install bundler'
end end
# Please note that we are not able to install chef on the VM, so when bringing
# this up we should always pass in `--provision-with=shell`
#
# TODO: Find out how to install chef on this or other box or find one that has
# it pre installed
config.vm.define :opensuse do |suse| config.vm.define :opensuse do |suse|
suse.vm.box = 'opensuse-12' suse.vm.box = 'opensuse-12'
suse.vm.box_url = 'http://sourceforge.net/projects/opensusevagrant/files/12.3/opensuse-12.3-64.box/download' suse.vm.box_url = 'http://sourceforge.net/projects/opensusevagrant/files/12.3/opensuse-12.3-64.box/download'
configure_private_network.call suse, 15 # Disable NFS
suse.cache.enable_nfs = false suse.cache.synced_folder_opts = { }
# This seems to not be working
suse.omnibus.chef_version = nil
suse.vm.provision :shell, inline: 'time zypper install -y git' suse.vm.provision :shell, inline: 'time zypper install -y git'
end end
end end

18
docs/buckets/apt-lists.md Normal file
View file

@ -0,0 +1,18 @@
# APT lists
Used by Debian-like Linux distros, will get configured under guest's `/var/lib/apt/lists`.
As explained on [Wikipedia](http://en.wikipedia.org/wiki/Advanced_Packaging_Tool#Files),
`/var/lib/apt/lists` is the "storage area for state information for each package
resource specified in sources.list". By enabling this bucket, `apt` will be able
to install cached packages without hitting the remote repositories for the main
package lists, [being particularly useful when developing offline](https://github.com/fgrehm/vagrant-cachier/pull/84#issue-27311414).
To manually enable it:
```ruby
Vagrant.configure("2") do |config|
config.vm.box = 'some-debian-box'
config.cache.enable :apt_lists
end
```

View file

@ -20,12 +20,11 @@ _as part of_ the boot process (synced folders are actually `lxc-start` parameter
and as of now we are not able to get some information that this plugin requires and as of now we are not able to get some information that this plugin requires
about the guest machine / container before it is actually up and running. about the guest machine / container before it is actually up and running.
Under the hood, the plugin will monkey patch `Vagrant::Builtin::Provision` and Under the hood, the plugin will hook into Vagrant in order to set things up for each
will set things up for each configured cache bucket _before and after_ running each configured cache bucket _before and after_ running each defined provisioner. Before
defined provisioner. Before halting the machine, it will also revert the changes halting the machine, it will also revert the changes required to set things up by
required to set things up by hooking into calls to `Vagrant::Builtin::GracefulHalt` hooking into calls to `Vagrant::Builtin::GracefulHalt` so that you can repackage
so that you can repackage the machine for others to use without requiring users to the machine for others to use without requiring users to install the plugin as well.
install the plugin as well.
Please keep in mind that this plugin won't do magic, if you are compiling things Please keep in mind that this plugin won't do magic, if you are compiling things
during provisioning or manually downloading packages outside of a bucket you during provisioning or manually downloading packages outside of a bucket you

View file

@ -9,7 +9,7 @@ multiple package managers and Linux distros.
## Installation ## Installation
Make sure you have Vagrant 1.2+ and run: Make sure you have Vagrant 1.4+ and run:
``` ```
vagrant plugin install vagrant-cachier vagrant plugin install vagrant-cachier
@ -24,9 +24,21 @@ from within your `Vagrantfile`:
Vagrant.configure("2") do |config| Vagrant.configure("2") do |config|
config.vm.box = 'your-box' config.vm.box = 'your-box'
if Vagrant.has_plugin?("vagrant-cachier") if Vagrant.has_plugin?("vagrant-cachier")
config.cache.auto_detect = true # Configure cached packages to be shared between instances of the same base box.
# If you are using VirtualBox, you might want to enable NFS for shared folders # More info on the "Usage" link above
# config.cache.enable_nfs = true config.cache.scope = :box
# If you are using VirtualBox, you might want to use that to enable NFS for
# shared folders. This is also very useful for vagrant-libvirt if you want
# bi-directional sync
config.cache.synced_folder_opts = {
type: :nfs,
# The nolock option can be useful for an NFSv3 client that wants to avoid the
# NLM sideband protocol. Without this option, apt-get might hang if it tries
# to lock files needed for /var/cache/* operations. All of this can be avoided
# by using NFSv4 everywhere. Please note that the tcp option is not the default.
mount_options: ['rw', 'vers=3', 'tcp', 'nolock']
}
end end
end end
``` ```
@ -34,12 +46,17 @@ end
For more information please check out the links on the menu above. For more information please check out the links on the menu above.
## Compatible providers ## Providers that are known to work
* Vagrant's built in VirtualBox provider * Vagrant's built in VirtualBox provider
* [vagrant-lxc](https://github.com/fgrehm/vagrant-lxc) * [vagrant-lxc](https://github.com/fgrehm/vagrant-lxc)
* [VMware providers](http://www.vagrantup.com/vmware) with NFS enabled (See * [VMware providers](http://www.vagrantup.com/vmware) with NFS enabled (See
[GH-24](https://github.com/fgrehm/vagrant-cachier/issues/24) for more info) [GH-24](https://github.com/fgrehm/vagrant-cachier/issues/24) for more info)
* [vagrant-libvirt](https://github.com/pradels/vagrant-libvirt)
* [vagrant-kvm](https://github.com/adrahon/vagrant-kvm)
_Please note that as of v0.6.0 the plugin will automatically disable any
previously defined configs for [cloud providers](lib/vagrant-cachier/plugin.rb#L19-22)_
## Contributing ## Contributing

View file

@ -83,6 +83,7 @@
<a class="dropdown-toggle" data-toggle="dropdown" href="#">Available Buckets <span class="caret"></span></a> <a class="dropdown-toggle" data-toggle="dropdown" href="#">Available Buckets <span class="caret"></span></a>
<ul class="dropdown-menu"> <ul class="dropdown-menu">
<li><a tabindex="-1" href="buckets/apt">APT</a></li> <li><a tabindex="-1" href="buckets/apt">APT</a></li>
<li><a tabindex="-1" href="buckets/apt-lists">apt-lists</a></li>
<li><a tabindex="-1" href="buckets/apt-cacher">apt-cacher</a></li> <li><a tabindex="-1" href="buckets/apt-cacher">apt-cacher</a></li>
<li><a tabindex="-1" href="buckets/chef">Chef</a></li> <li><a tabindex="-1" href="buckets/chef">Chef</a></li>
<li><a tabindex="-1" href="buckets/composer">Composer</a></li> <li><a tabindex="-1" href="buckets/composer">Composer</a></li>

View file

@ -1,56 +1,46 @@
# Usage # Usage
## Auto detect supported cache buckets ## Being nice to others
This is the easiest way to get started with plugin. By adding the code below to It is a good practice to wrap plugin specific configuration with `has_plugin?` checks
your `Vagrantfile` you can enable automatic detection of supported cache _buckets_. so the user's Vagrantfiles do not break if `vagrant-cachier` is uninstalled or
It is a good practise to wrap plugin specific configuration with `has_plugin?` checks the Vagrantfile is shared with people that don't have the plugin installed:
so the user's Vagrantfiles do not break if plugin is uninstalled or Vagrantfile shared
with people not having the plugin installed.
```ruby ```ruby
Vagrant.configure("2") do |config| Vagrant.configure("2") do |config|
# ... # ...
if Vagrant.has_plugin?("vagrant-cachier") if Vagrant.has_plugin?("vagrant-cachier")
config.cache.auto_detect = true # ... vagrant-cachier configs ...
end end
end end
``` ```
This will make vagrant-cachier do its best to find out what is supported on the
guest machine and will set buckets accordingly.
## Enable buckets as needed
If for whatever reason you need to have a fined grained control over what buckets
are configured, you can do so by "cherry picking" them on your `Vagrantfile`:
```ruby
Vagrant.configure("2") do |config|
config.cache.enable :apt
config.cache.enable :gem
end
```
_Please refer to the "Available Buckets" menu above to find out which buckets
are supported._
## Cache scope ## Cache scope
By default downloaded packages will get stored on a folder scoped to base boxes This is the only required configuration for the plugin to work and should be present
under your `$HOME/.vagrant.d/cache`. The idea is to leverage the cache by allowing on your project's specific `Vagrantfile` or on your `~/.vagrant.d/Vagrantfile` in
downloaded packages to be reused across projects. So, if your `Vagrantfile` has order to enable it.
something like:
### `:box` scope
By setting `cache.scope` to `:box`, downloaded packages will get stored on a folder
scoped to base boxes under your `~/.vagrant.d/cache`. The idea is to leverage the
cache by allowing downloaded packages to be reused across projects. So, if your
`Vagrantfile` has something like:
```ruby ```ruby
Vagrant.configure("2") do |config| Vagrant.configure("2") do |config|
config.vm.box = 'some-box' config.vm.box = 'some-box'
config.cache.auto_detect = true if Vagrant.has_plugin?("vagrant-cachier")
config.cache.scope = :box
end
end end
``` ```
The cached files will be stored under `$HOME/.vagrant.d/cache/some-box`. The cached files will be stored under `$HOME/.vagrant.d/cache/some-box`.
### `:machine` scope
If you are on a [multi VM environment](http://docs.vagrantup.com/v2/multi-machine/index.html), If you are on a [multi VM environment](http://docs.vagrantup.com/v2/multi-machine/index.html),
there is a huge chance that you'll end up having issues by sharing the same bucket there is a huge chance that you'll end up having issues by sharing the same bucket
across different machines. For example, if you `apt-get install` from two machines across different machines. For example, if you `apt-get install` from two machines
@ -61,13 +51,71 @@ to be based on machines:
```ruby ```ruby
Vagrant.configure("2") do |config| Vagrant.configure("2") do |config|
config.vm.box = 'some-box' config.vm.box = 'some-box'
config.cache.scope = :machine if Vagrant.has_plugin?("vagrant-cachier")
config.cache.scope = :machine
end
end end
``` ```
This will tell vagrant-cachier to download packages to `.vagrant/machines/<machine-name>/cache` This will tell vagrant-cachier to download packages to `.vagrant/machines/<machine-name>/cache`
on your current project directory. on your current project directory.
## Cache buckets automatic detection
This is the easiest way to get started with plugin and is enabled by default.
Under the hood, `vagrant-cachier` does its best to find out what is supported on the
guest machine and will set buckets accordingly.
If you want that behavior to be disabled, you can set `cache.auto_detect` to `false`
from your Vagrantfile:
```ruby
Vagrant.configure("2") do |config|
config.vm.box = 'some-box'
if Vagrant.has_plugin?("vagrant-cachier")
config.cache.scope = :machine # or :box
config.cache.auto_detect = false
end
end
```
## Enable buckets as needed
If for whatever reason you need to have a fined grained control over what buckets
are configured, you can do so by "cherry picking" them on your `Vagrantfile`:
```ruby
Vagrant.configure("2") do |config|
config.cache.auto_detect = false
config.cache.enable :apt
config.cache.enable :gem
end
```
_Please refer to the "Available Buckets" menu above to find out which buckets
are supported._
## Custom cache buckets synced folders options
For fine grained control over the cache bucket synced folder options you can use
the `synced_folder_opts` config. That's useful if, for example, you are using
VirtualBox and want to enable NFS for improved performance:
```ruby
Vagrant.configure("2") do |config|
config.cache.synced_folder_opts = {
type: :nfs,
# The nolock option can be useful for an NFSv3 client that wants to avoid the
# NLM sideband protocol. Without this option, apt-get might hang if it tries
# to lock files needed for /var/cache/* operations. All of this can be avoided
# by using NFSv4 everywhere. Please note that the tcp option is not the default.
mount_options: ['rw', 'vers=3', 'tcp', 'nolock']
}
end
```
Please referer to http://docs.vagrantup.com/v2/synced-folders/basic_usage.html for
more information about the supported parameters.
## Finding out disk space used by buckets ## Finding out disk space used by buckets
@ -100,5 +148,5 @@ the code below if you are on a Linux machine:
$ rm -rf $HOME/.vagrant.d/cache/<box-name>/<optional-bucket-name> $ rm -rf $HOME/.vagrant.d/cache/<box-name>/<optional-bucket-name>
# scope = :machine # scope = :machine
$ rm -rf .vagrant/cache/<box-name>/<optional-bucket-name> $ rm -rf .vagrant/machines/<machine-name>/cache/<optional-bucket-name>
``` ```

View file

@ -56,7 +56,7 @@ module VagrantPlugins
def remove_symlink(symlink) def remove_symlink(symlink)
if @machine.communicate.test("test -L #{symlink}") if @machine.communicate.test("test -L #{symlink}")
@logger.debug "Removing symlink for '#{symlink}'" @logger.info "Removing symlink for '#{symlink}'"
@machine.communicate.sudo("unlink #{symlink}") @machine.communicate.sudo("unlink #{symlink}")
end end
end end

View file

@ -0,0 +1,46 @@
require 'timeout'
module VagrantPlugins
module Cachier
class Action
class ConfigureBucketRoot
def initialize(app, env)
@app = app
@logger = Log4r::Logger.new("vagrant::cachier::action::clean")
end
def call(env)
@env = env
if !env[:cache_buckets_folder_configured] && env[:machine].config.cache.enabled?
setup_buckets_folder
env[:cache_buckets_folder_configured] = true
end
@app.call env
end
def setup_buckets_folder
FileUtils.mkdir_p(cache_root.to_s) unless cache_root.exist?
synced_folder_opts = {id: "vagrant-cache"}
synced_folder_opts.merge!(@env[:machine].config.cache.synced_folder_opts || {})
@env[:machine].config.vm.synced_folder cache_root, '/tmp/vagrant-cache', synced_folder_opts
@env[:cache_dirs] = []
end
def cache_root
@cache_root ||= case @env[:machine].config.cache.scope.to_sym
when :box
@env[:home_path].join('cache', @env[:machine].box.name)
when :machine
@env[:machine].data_dir.parent.join('cache')
else
raise "Unknown cache scope: '#{@env[:machine].config.cache.scope}'"
end
end
end
end
end
end

View file

@ -1,64 +0,0 @@
require_relative '../errors'
module VagrantPlugins
module Cachier
class Action
class EnsureSingleCacheRoot
def initialize(app, env)
@app = app
end
def call(env)
@env = env
# If the cache is scoped to boxes or the existing cache dirs are not
# provider specific, there's nothing we need to do
if cache_scoped_to_machine? && provider_specific_cache_dirs.any?
ensure_single_cache_root_exists!
end
@app.call(env)
end
def cache_scoped_to_machine?
@env[:machine].config.cache.enabled? &&
@env[:machine].config.cache.scope.to_sym == :machine
end
def ensure_single_cache_root_exists!
if provider_specific_cache_dirs.size > 1
cache_dirs = provider_specific_cache_dirs.map do |dir|
" - #{dir.to_s.gsub(/^#{@env[:root_path]}\//, '')}"
end
machine_path = @env[:machine].data_dir.parent.to_s.gsub(/^#{@env[:root_path]}\//, '')
raise Cachier::Errors::MultipleProviderSpecificCacheDirsFound,
machine: @env[:machine].name,
machine_path: machine_path,
dirs: cache_dirs.join("\n")
else
current_path = provider_specific_cache_dirs.first.to_s.gsub(/^#{@env[:root_path]}\//, '')
new_path = @env[:machine].data_dir.parent.join('cache')
FileUtils.rm_rf new_path.to_s if new_path.directory?
new_path = new_path.to_s.gsub(/^#{@env[:root_path]}\//, '')
# If we got here there is a single provider specific cacher dir, so
# let's be nice with users and just fix it ;)
@env[:ui].warn I18n.t('vagrant_cachier.will_fix_machine_cache_dir',
current_path: current_path,
new_path: new_path)
FileUtils.mv current_path, new_path
end
end
def provider_specific_cache_dirs
return @provider_specific_cache_dirs if @provider_specific_cache_dirs
# By default data_dir points to ./.vagrant/machines/<NAME>/<PROVIDER>,
# so we go one directory up
machine_dir = @env[:machine].data_dir.parent
@provider_specific_cache_dirs = Pathname.glob(machine_dir.join('*/cache'))
end
end
end
end
end

View file

@ -0,0 +1,47 @@
require_relative '../bucket'
module VagrantPlugins
module Cachier
class Action
class InstallBuckets
def initialize(app, env, opts = {})
@app = app
@logger = Log4r::Logger.new("vagrant::cachier::action::clean")
@opts = opts
end
def call(env)
@app.call(env)
return unless env[:machine].config.cache.enabled?
chmod_bucket_root(env[:machine]) if @opts[:chmod]
configure_cache_buckets(env)
end
def chmod_bucket_root(machine)
@logger.info "'chmod'ing bucket root dir to 777..."
machine.communicate.sudo 'mkdir -p /tmp/vagrant-cache && chmod 777 /tmp/vagrant-cache'
end
def configure_cache_buckets(env)
if env[:machine].config.cache.auto_detect
Bucket.auto_detect(env)
end
return unless env[:machine].config.cache.buckets.any?
env[:ui].info 'Configuring cache buckets...'
cache_config = env[:machine].config.cache
cache_config.buckets.each do |bucket_name, configs|
@logger.info "Installing #{bucket_name} with configs #{configs.inspect}"
Bucket.install(bucket_name, env, configs)
end
data_file = env[:machine].data_dir.join('cache_dirs')
data_file.open('w') { |f| f.print env[:cache_dirs].uniq.join("\n") }
end
end
end
end
end

View file

@ -29,6 +29,60 @@ module VagrantPlugins
@env = env @env = env
@configs = configs @configs = configs
end end
def machine
@env[:machine]
end
def guest
machine.guest
end
def comm
machine.communicate
end
# TODO: "merge" symlink and user_symlink methods
def symlink(guest_path, bucket_path = "/tmp/vagrant-cache/#{@name}", create_parent: true)
return if @env[:cache_dirs].include?(guest_path)
@env[:cache_dirs] << guest_path
comm.execute("mkdir -p #{bucket_path}")
unless symlink?(guest_path)
comm.sudo("mkdir -p `dirname #{guest_path}`") if create_parent
if empty_dir?(bucket_path) && !empty_dir?(guest_path)
# Warm up cache with guest machine data
comm.sudo("shopt -s dotglob && mv #{guest_path}/* #{bucket_path}")
end
comm.sudo("rm -rf #{guest_path}")
comm.sudo("ln -s #{bucket_path} #{guest_path}")
end
end
def user_symlink(guest_path)
return if @env[:cache_dirs].include?(guest_path)
@env[:cache_dirs] << guest_path
bucket_path = "/tmp/vagrant-cache/#{@name}"
comm.execute("mkdir -p #{bucket_path}")
unless symlink?(guest_path)
comm.execute("mkdir -p `dirname #{guest_path}`")
if empty_dir?(bucket_path) && !empty_dir?(guest_path)
# Warm up cache with guest machine data
comm.execute("shopt -s dotglob && mv #{guest_path}/* #{bucket_path}")
end
comm.execute("rm -rf #{guest_path}")
comm.execute("ln -s #{bucket_path} #{guest_path}")
end
end
def empty_dir?(path)
not comm.test("test \"$(ls -A #{path} 2>/dev/null)\"")
end
def symlink?(path)
comm.test("test -L #{path}")
end
end end
end end
end end
@ -40,6 +94,7 @@ require_relative "bucket/pacman"
require_relative "bucket/yum" require_relative "bucket/yum"
require_relative "bucket/rvm" require_relative "bucket/rvm"
require_relative "bucket/apt_cacher" require_relative "bucket/apt_cacher"
require_relative "bucket/apt_lists"
require_relative "bucket/composer" require_relative "bucket/composer"
require_relative "bucket/npm" require_relative "bucket/npm"
require_relative "bucket/zypper" require_relative "bucket/zypper"

View file

@ -7,22 +7,13 @@ module VagrantPlugins
end end
def install def install
machine = @env[:machine]
guest = machine.guest
if guest.capability?(:apt_cache_dir) if guest.capability?(:apt_cache_dir)
guest_path = guest.capability(:apt_cache_dir) guest_path = guest.capability(:apt_cache_dir)
@env[:cache_dirs] << guest_path return if @env[:cache_dirs].include?(guest_path)
machine.communicate.tap do |comm| symlink(guest_path)
comm.execute("mkdir -p /tmp/vagrant-cache/#{@name}/partial") comm.execute("mkdir -p /tmp/vagrant-cache/#{@name}/partial")
unless comm.test("test -L #{guest_path}")
comm.sudo("rm -rf #{guest_path}")
comm.sudo("mkdir -p `dirname #{guest_path}`")
comm.sudo("ln -s /tmp/vagrant-cache/#{@name} #{guest_path}")
end
end
else else
@env[:ui].info I18n.t('vagrant_cachier.skipping_bucket', bucket: 'APT') @env[:ui].info I18n.t('vagrant_cachier.skipping_bucket', bucket: 'APT')
end end

View file

@ -9,22 +9,10 @@ module VagrantPlugins
end end
def install def install
machine = @env[:machine]
guest = machine.guest
if guest.capability?(:apt_cacher_dir) if guest.capability?(:apt_cacher_dir)
if guest_path = guest.capability(:apt_cacher_dir) if guest_path = guest.capability(:apt_cacher_dir)
if machine.config.cache.enable_nfs if machine.config.cache.enable_nfs
@env[:cache_dirs] << guest_path symlink(guest_path)
machine.communicate.tap do |comm|
comm.execute("mkdir -p /tmp/vagrant-cache/#{@name}")
unless comm.test("test -L #{guest_path}")
comm.sudo("rm -rf #{guest_path}")
comm.sudo("mkdir -p `dirname #{guest_path}`")
comm.sudo("ln -s /tmp/vagrant-cache/#{@name} #{guest_path}")
end
end
else else
@env[:ui].info I18n.t('vagrant_cachier.nfs_required', bucket: 'apt-cacher') @env[:ui].info I18n.t('vagrant_cachier.nfs_required', bucket: 'apt-cacher')
end end

View file

@ -0,0 +1,24 @@
module VagrantPlugins
module Cachier
class Bucket
class AptLists < Bucket
def self.capability
:apt_lists_dir
end
def install
if guest.capability?(:apt_lists_dir)
guest_path = guest.capability(:apt_lists_dir)
return if @env[:cache_dirs].include?(guest_path)
symlink(guest_path)
comm.execute("mkdir -p /tmp/vagrant-cache/#{@name}/partial")
else
@env[:ui].info I18n.t('vagrant_cachier.skipping_bucket', bucket: 'apt-lists')
end
end
end
end
end
end

View file

@ -7,22 +7,9 @@ module VagrantPlugins
end end
def install def install
machine = @env[:machine]
guest = machine.guest
if guest.capability?(:chef_file_cache_path) if guest.capability?(:chef_file_cache_path)
guest_path = guest.capability(:chef_file_cache_path) guest_path = guest.capability(:chef_file_cache_path)
symlink(guest_path) if guest_path
@env[:cache_dirs] << guest_path
machine.communicate.tap do |comm|
comm.execute("mkdir -p /tmp/vagrant-cache/#{@name}")
unless comm.test("test -L #{guest_path}")
comm.sudo("rm -rf #{guest_path}")
comm.sudo("mkdir -p `dirname #{guest_path}`")
comm.sudo("ln -s /tmp/vagrant-cache/#{@name} #{guest_path}")
end
end
else else
@env[:ui].info I18n.t('vagrant_cachier.skipping_bucket', bucket: 'Chef') @env[:ui].info I18n.t('vagrant_cachier.skipping_bucket', bucket: 'Chef')
end end

View file

@ -7,22 +7,9 @@ module VagrantPlugins
end end
def install def install
machine = @env[:machine]
guest = machine.guest
if guest.capability?(:composer_path) if guest.capability?(:composer_path)
if composer_path = guest.capability(:composer_path) if composer_path = guest.capability(:composer_path)
bucket_path = "/tmp/vagrant-cache/#{@name}" symlink(composer_path, create_parent: false)
@env[:cache_dirs] << composer_path
machine.communicate.tap do |comm|
comm.execute("mkdir -p #{bucket_path}")
unless comm.test("test -L #{composer_path}")
comm.sudo("rm -rf #{composer_path}")
comm.sudo("ln -s #{bucket_path} #{composer_path}")
end
end
end end
else else
@env[:ui].info I18n.t('vagrant_cachier.skipping_bucket', bucket: 'Composer') @env[:ui].info I18n.t('vagrant_cachier.skipping_bucket', bucket: 'Composer')

View file

@ -7,26 +7,13 @@ module VagrantPlugins
end end
def install def install
machine = @env[:machine]
guest = machine.guest
if guest.capability?(:gemdir) if guest.capability?(:gemdir)
if gemdir_path = guest.capability(:gemdir) if gemdir_path = guest.capability(:gemdir)
prefix = gemdir_path.split('/').last prefix = gemdir_path.split('/').last
bucket_path = "/tmp/vagrant-cache/#{@name}/#{prefix}" bucket_path = "/tmp/vagrant-cache/#{@name}/#{prefix}"
machine.communicate.tap do |comm| gem_cache_path = "#{gemdir_path}/cache"
comm.execute("mkdir -p #{bucket_path}")
gem_cache_path = "#{gemdir_path}/cache" symlink(gem_cache_path, bucket_path)
@env[:cache_dirs] << gem_cache_path
unless comm.test("test -L #{gem_cache_path}")
comm.sudo("rm -rf #{gem_cache_path}")
comm.sudo("mkdir -p `dirname #{gem_cache_path}`")
comm.sudo("ln -s #{bucket_path} #{gem_cache_path}")
end
end
end end
else else
@env[:ui].info I18n.t('vagrant_cachier.skipping_bucket', bucket: 'RubyGems') @env[:ui].info I18n.t('vagrant_cachier.skipping_bucket', bucket: 'RubyGems')

View file

@ -7,22 +7,9 @@ module VagrantPlugins
end end
def install def install
machine = @env[:machine]
guest = machine.guest
if guest.capability?(:npm_cache_dir) if guest.capability?(:npm_cache_dir)
guest_path = guest.capability(:npm_cache_dir) guest_path = guest.capability(:npm_cache_dir)
user_symlink(guest_path) if guest_path
@env[:cache_dirs] << guest_path
machine.communicate.tap do |comm|
comm.execute("mkdir -p /tmp/vagrant-cache/#{@name}")
unless comm.test("test -L #{guest_path}")
comm.execute("rm -rf #{guest_path}")
comm.execute("mkdir -p `dirname #{guest_path}`")
comm.execute("ln -s /tmp/vagrant-cache/#{@name} #{guest_path}")
end
end
else else
@env[:ui].info I18n.t('vagrant_cachier.skipping_bucket', bucket: 'npm') @env[:ui].info I18n.t('vagrant_cachier.skipping_bucket', bucket: 'npm')
end end

View file

@ -7,22 +7,9 @@ module VagrantPlugins
end end
def install def install
machine = @env[:machine]
guest = machine.guest
if guest.capability?(:pacman_cache_dir) if guest.capability?(:pacman_cache_dir)
guest_path = guest.capability(:pacman_cache_dir) guest_path = guest.capability(:pacman_cache_dir)
symlink(guest_path)
@env[:cache_dirs] << guest_path
machine.communicate.tap do |comm|
comm.execute("mkdir -p /tmp/vagrant-cache/#{@name}")
unless comm.test("test -L #{guest_path}")
comm.sudo("rm -rf #{guest_path}")
comm.sudo("mkdir -p `dirname #{guest_path}`")
comm.sudo("ln -s /tmp/vagrant-cache/#{@name} #{guest_path}")
end
end
else else
@env[:ui].info I18n.t('vagrant_cachier.skipping_bucket', bucket: 'Pacman') @env[:ui].info I18n.t('vagrant_cachier.skipping_bucket', bucket: 'Pacman')
end end

View file

@ -7,26 +7,13 @@ module VagrantPlugins
end end
def install def install
machine = @env[:machine]
guest = machine.guest
if guest.capability?(:rvm_path) if guest.capability?(:rvm_path)
if rvm_path = guest.capability(:rvm_path) if rvm_path = guest.capability(:rvm_path)
prefix = rvm_path.split('/').last prefix = rvm_path.split('/').last
bucket_path = "/tmp/vagrant-cache/#{@name}/#{prefix}" bucket_path = "/tmp/vagrant-cache/#{@name}/#{prefix}"
machine.communicate.tap do |comm| rvm_cache_path = "#{rvm_path}/archives"
comm.execute("mkdir -p #{bucket_path}")
rvm_cache_path = "#{rvm_path}/archives" symlink(rvm_cache_path, bucket_path)
@env[:cache_dirs] << rvm_cache_path
unless comm.test("test -L #{rvm_cache_path}")
comm.sudo("rm -rf #{rvm_cache_path}")
comm.sudo("mkdir -p `dirname #{rvm_cache_path}`")
comm.sudo("ln -s #{bucket_path} #{rvm_cache_path}")
end
end
end end
else else
@env[:ui].info I18n.t('vagrant_cachier.skipping_bucket', bucket: 'RVM') @env[:ui].info I18n.t('vagrant_cachier.skipping_bucket', bucket: 'RVM')

View file

@ -7,25 +7,14 @@ module VagrantPlugins
end end
def install def install
machine = @env[:machine]
guest = machine.guest
if guest.capability?(:yum_cache_dir) if guest.capability?(:yum_cache_dir)
guest_path = guest.capability(:yum_cache_dir) guest_path = guest.capability(:yum_cache_dir)
return if @env[:cache_dirs].include?(guest_path)
@env[:cache_dirs] << guest_path # Ensure caching is enabled
comm.sudo("sed -i 's/keepcache=0/keepcache=1/g' /etc/yum.conf")
machine.communicate.tap do |comm| symlink(guest_path)
# Ensure caching is enabled
comm.sudo("sed -i 's/keepcache=0/keepcache=1/g' /etc/yum.conf")
comm.execute("mkdir -p /tmp/vagrant-cache/#{@name}")
unless comm.test("test -L #{guest_path}")
comm.sudo("rm -rf #{guest_path}")
comm.sudo("mkdir -p `dirname #{guest_path}`")
comm.sudo("ln -s /tmp/vagrant-cache/#{@name} #{guest_path}")
end
end
else else
@env[:ui].info I18n.t('vagrant_cachier.skipping_bucket', bucket: 'Yum') @env[:ui].info I18n.t('vagrant_cachier.skipping_bucket', bucket: 'Yum')
end end

View file

@ -7,25 +7,14 @@ module VagrantPlugins
end end
def install def install
machine = @env[:machine]
guest = machine.guest
if guest.capability?(:zypper_cache_dir) if guest.capability?(:zypper_cache_dir)
guest_path = guest.capability(:zypper_cache_dir) guest_path = guest.capability(:zypper_cache_dir)
return if @env[:cache_dirs].include?(guest_path)
@env[:cache_dirs] << guest_path # Ensure caching is enabled
comm.sudo("zypper modifyrepo --keep-packages --all")
machine.communicate.tap do |comm| symlink(guest_path)
# Ensure caching is enabled
comm.sudo("zypper modifyrepo --keep-packages --all")
comm.execute("mkdir -p /tmp/vagrant-cache/#{@name}")
unless comm.test("test -L #{guest_path}")
comm.sudo("rm -rf #{guest_path}")
comm.sudo("mkdir -p `dirname #{guest_path}`")
comm.sudo("ln -s /tmp/vagrant-cache/#{@name} #{guest_path}")
end
end
else else
@env[:ui].info I18n.t('vagrant_cachier.skipping_bucket', bucket: 'Zypper') @env[:ui].info I18n.t('vagrant_cachier.skipping_bucket', bucket: 'Zypper')
end end

View file

@ -0,0 +1,13 @@
module VagrantPlugins
module Cachier
module Cap
module Debian
module AptListsDir
def self.apt_lists_dir(machine)
'/var/lib/apt/lists'
end
end
end
end
end
end

View file

@ -0,0 +1,64 @@
module VagrantPlugins
module Cachier
class Plugin < Vagrant.plugin('2')
guest_capability 'linux', 'gemdir' do
require_relative 'cap/linux/gemdir'
Cap::Linux::Gemdir
end
guest_capability 'linux', 'rvm_path' do
require_relative 'cap/linux/rvm_path'
Cap::Linux::RvmPath
end
guest_capability 'linux', 'composer_path' do
require_relative 'cap/linux/composer_path'
Cap::Linux::ComposerPath
end
guest_capability 'linux', 'chef_file_cache_path' do
require_relative 'cap/linux/chef_file_cache_path'
Cap::Linux::ChefFileCachePath
end
guest_capability 'linux', 'npm_cache_dir' do
require_relative 'cap/linux/npm_cache_dir'
Cap::Linux::NpmCacheDir
end
guest_capability 'debian', 'apt_cache_dir' do
require_relative 'cap/debian/apt_cache_dir'
Cap::Debian::AptCacheDir
end
guest_capability 'debian', 'apt_cacher_dir' do
require_relative 'cap/debian/apt_cacher_dir'
Cap::Debian::AptCacherDir
end
guest_capability 'debian', 'apt_lists_dir' do
require_relative 'cap/debian/apt_lists_dir'
Cap::Debian::AptListsDir
end
guest_capability 'redhat', 'yum_cache_dir' do
require_relative 'cap/redhat/yum_cache_dir'
Cap::RedHat::YumCacheDir
end
guest_capability 'suse', 'yum_cache_dir' do
# Disable Yum on suse guests
end
guest_capability 'arch', 'pacman_cache_dir' do
require_relative 'cap/arch/pacman_cache_dir'
Cap::Arch::PacmanCacheDir
end
guest_capability 'suse', 'zypper_cache_dir' do
require_relative 'cap/suse/zypper_cache_dir'
Cap::SuSE::ZypperCacheDir
end
end
end
end

View file

@ -1,24 +1,39 @@
module VagrantPlugins module VagrantPlugins
module Cachier module Cachier
class Config < Vagrant.plugin(2, :config) class Config < Vagrant.plugin(2, :config)
attr_accessor :scope, :auto_detect, :enable_nfs attr_accessor :scope, :auto_detect, :synced_folder_opts
attr_reader :buckets attr_reader :buckets
ALLOWED_SCOPES = %w( box machine ) ALLOWED_SCOPES = %w( box machine )
def initialize def initialize
@scope = UNSET_VALUE @scope = UNSET_VALUE
@auto_detect = UNSET_VALUE @auto_detect = UNSET_VALUE
@enable_nfs = UNSET_VALUE @synced_folder_opts = UNSET_VALUE
@ui = Vagrant::UI::Colored.new
end end
def enable(bucket, opts = {}) def enable(bucket, opts = {})
(@buckets ||= {})[bucket] = opts (@buckets ||= {})[bucket] = opts
end end
def enable_nfs=(value)
@ui.warn "The `enable_nfs` config for vagrant-cachier has been deprecated " \
"and will be removed on 0.7.0, please use " \
"`synced_folder_opts = { type: :nfs }` instead.\n"
@synced_folder_opts = { type: :nfs } if value
end
def validate(machine) def validate(machine)
errors = _detected_errors errors = _detected_errors
if enabled? && backed_by_cloud_provider?(machine)
machine.ui.warn(I18n.t('vagrant_cachier.backed_by_cloud_provider',
provider: machine.provider_name))
disable!
end
if enabled? && ! ALLOWED_SCOPES.include?(@scope.to_s) if enabled? && ! ALLOWED_SCOPES.include?(@scope.to_s)
errors << I18n.t('vagrant_cachier.unknown_cache_scope', errors << I18n.t('vagrant_cachier.unknown_cache_scope',
allowed: ALLOWED_SCOPES.inspect, allowed: ALLOWED_SCOPES.inspect,
@ -28,18 +43,28 @@ module VagrantPlugins
{ "vagrant cachier" => errors } { "vagrant cachier" => errors }
end end
def enabled?
return @enabled unless @enabled.nil?
@enabled = @scope != UNSET_VALUE
end
def disable!
@enabled = false
end
def finalize! def finalize!
return unless enabled? return unless enabled?
@scope = :box if @scope == UNSET_VALUE @auto_detect = true if @auto_detect == UNSET_VALUE
@auto_detect = false if @auto_detect == UNSET_VALUE @synced_folder_opts = nil if @synced_folder_opts == UNSET_VALUE
@enable_nfs = false if @enable_nfs == UNSET_VALUE @buckets = @buckets ? @buckets.dup : {}
@buckets = @buckets ? @buckets.dup : {}
end end
def enabled? private
@enabled ||= @auto_detect != UNSET_VALUE ||
@buckets != nil def backed_by_cloud_provider?(machine)
CLOUD_PROVIDERS.include?(machine.provider_name.to_s)
end end
end end
end end

View file

@ -1,9 +0,0 @@
module VagrantPlugins
module Cachier
module Errors
class MultipleProviderSpecificCacheDirsFound < Vagrant::Errors::VagrantError
error_key(:multiple_provider_specific_cache_dirs_found)
end
end
end
end

View file

@ -0,0 +1,27 @@
module VagrantPlugins
module Cachier
class Plugin < Vagrant.plugin('2')
action_hook VagrantPlugins::Cachier::Plugin::ALL_ACTIONS do |hook|
require_relative 'action/configure_bucket_root'
require_relative 'action/install_buckets'
hook.before Vagrant::Action::Builtin::Provision, Action::ConfigureBucketRoot
# This will do the initial buckets installation
hook.after Vagrant::Action::Builtin::Provision, Action::InstallBuckets, chmod: true
end
# This ensure buckets are reconfigured after provisioners runs
action_hook :provisioner_run do |hook|
require_relative 'action/install_buckets'
hook.after :run_provisioner, Action::InstallBuckets
end
clean_action_hook = lambda do |hook|
require_relative 'action/clean'
hook.before Vagrant::Action::Builtin::GracefulHalt, Action::Clean
end
action_hook 'remove-guest-symlinks-on-halt', :machine_action_halt, &clean_action_hook
action_hook 'remove-guest-symlinks-on-package', :machine_action_package, &clean_action_hook
end
end
end

View file

@ -1,6 +1,7 @@
require_relative 'provision_ext' # TODO: Switch to Vagrant.require_version before 1.0.0
Vagrant::Action::Builtin::Provision.class_eval do # see: https://github.com/mitchellh/vagrant/blob/bc55081e9ffaa6820113e449a9f76b293a29b27d/lib/vagrant.rb#L202-L228
include VagrantPlugins::Cachier::ProvisionExt unless Gem::Requirement.new('>= 1.4.0').satisfied_by?(Gem::Version.new(Vagrant::VERSION))
raise 'vagrant-cachier requires Vagrant >= 1.4.0 in order to work!'
end end
# Add our custom translations to the load path # Add our custom translations to the load path
@ -10,87 +11,18 @@ module VagrantPlugins
module Cachier module Cachier
class Plugin < Vagrant.plugin('2') class Plugin < Vagrant.plugin('2')
name 'vagrant-cachier' name 'vagrant-cachier'
config 'cache' do config 'cache' do
require_relative "config" require_relative "config"
Config Config
end end
guest_capability 'linux', 'gemdir' do
require_relative 'cap/linux/gemdir'
Cap::Linux::Gemdir
end
guest_capability 'linux', 'rvm_path' do
require_relative 'cap/linux/rvm_path'
Cap::Linux::RvmPath
end
guest_capability 'linux', 'composer_path' do
require_relative 'cap/linux/composer_path'
Cap::Linux::ComposerPath
end
guest_capability 'linux', 'chef_file_cache_path' do
require_relative 'cap/linux/chef_file_cache_path'
Cap::Linux::ChefFileCachePath
end
guest_capability 'linux', 'npm_cache_dir' do
require_relative 'cap/linux/npm_cache_dir'
Cap::Linux::NpmCacheDir
end
guest_capability 'debian', 'apt_cache_dir' do
require_relative 'cap/debian/apt_cache_dir'
Cap::Debian::AptCacheDir
end
guest_capability 'debian', 'apt_cacher_dir' do
require_relative 'cap/debian/apt_cacher_dir'
Cap::Debian::AptCacherDir
end
guest_capability 'redhat', 'yum_cache_dir' do
require_relative 'cap/redhat/yum_cache_dir'
Cap::RedHat::YumCacheDir
end
guest_capability 'suse', 'yum_cache_dir' do
# Disable Yum on suse guests
end
guest_capability 'arch', 'pacman_cache_dir' do
require_relative 'cap/arch/pacman_cache_dir'
Cap::Arch::PacmanCacheDir
end
guest_capability 'suse', 'zypper_cache_dir' do
require_relative 'cap/suse/zypper_cache_dir'
Cap::SuSE::ZypperCacheDir
end
# TODO: This should be generic, we don't want to hard code every single
# possible provider action class that Vagrant might have
ensure_single_cache_root = lambda do |hook|
require_relative 'action/ensure_single_cache_root'
hook.before VagrantPlugins::ProviderVirtualBox::Action::Boot, Action::EnsureSingleCacheRoot
if defined?(Vagrant::LXC)
# TODO: Require just the boot action file once its "require dependencies" are sorted out
require 'vagrant-lxc/action'
hook.before Vagrant::LXC::Action::Boot, Action::EnsureSingleCacheRoot
end
end
action_hook 'ensure-single-cache-root-exists-on-up', :machine_action_up, &ensure_single_cache_root
action_hook 'ensure-single-cache-root-exists-on-reload', :machine_action_reload, &ensure_single_cache_root
clean_action_hook = lambda do |hook|
require_relative 'action/clean'
hook.before Vagrant::Action::Builtin::GracefulHalt, Action::Clean
end
action_hook 'remove-guest-symlinks-on-halt', :machine_action_halt, &clean_action_hook
action_hook 'remove-guest-symlinks-on-package', :machine_action_package, &clean_action_hook
end end
# Keep an eye on https://github.com/mitchellh/vagrant/wiki/Available-Vagrant-Plugins#wiki-providers
# for more.
CLOUD_PROVIDERS = %w( aws cloudstack digitalocean hp joyent openstack rackspace
softlayer proxmox managed )
end end
end end
require_relative "hooks"
require_relative "capabilities"

View file

@ -1,74 +0,0 @@
require_relative 'bucket'
module VagrantPlugins
module Cachier
module ProvisionExt
def self.included(base)
base.class_eval do
def cachier_debug(msg)
@logger.debug "[CACHIER] #{msg}"
end
alias :old_call :call
def call(env)
@env = env
return old_call(env) unless env[:machine].config.cache.enabled?
FileUtils.mkdir_p(cache_root.to_s) unless cache_root.exist?
synced_folder_opts = {id: "vagrant-cache"}
if env[:machine].config.cache.enable_nfs
# REFACTOR: Drop the `nfs: true` argument once we drop support for Vagrant < 1.4
synced_folder_opts.merge!({ nfs: true, type: 'nfs' })
end
env[:machine].config.vm.synced_folder cache_root, '/tmp/vagrant-cache', synced_folder_opts
env[:cache_dirs] = []
old_call(env)
configure_cache_buckets
end
alias :old_run_provisioner :run_provisioner
def run_provisioner(*args)
configure_cache_buckets
old_run_provisioner(*args)
end
def configure_cache_buckets
return unless @env[:machine].config.cache.enabled?
if @env[:machine].config.cache.auto_detect
Bucket.auto_detect(@env)
end
return unless @env[:machine].config.cache.buckets.any?
@env[:ui].info 'Configuring cache buckets...'
cache_config = @env[:machine].config.cache
cache_config.buckets.each do |bucket_name, configs|
cachier_debug "Installing #{bucket_name} with configs #{configs.inspect}"
Bucket.install(bucket_name, @env, configs)
end
data_file = @env[:machine].data_dir.join('cache_dirs')
data_file.open('w') { |f| f.print @env[:cache_dirs].uniq.join("\n") }
end
def cache_root
@cache_root ||= case @env[:machine].config.cache.scope.to_sym
when :box
@env[:home_path].join('cache', @env[:machine].box.name)
when :machine
@env[:machine].data_dir.parent.join('cache')
else
raise "Unknown cache scope: '#{@env[:machine].config.cache.scope}'"
end
end
end
end
end
end
end

View file

@ -1,5 +1,5 @@
module VagrantPlugins module VagrantPlugins
module Cachier module Cachier
VERSION = "0.5.2.dev" VERSION = "0.6.0"
end end
end end

View file

@ -16,10 +16,6 @@ en:
scoped cache dirs starting with the 0.3.0 version of the plugin. scoped cache dirs starting with the 0.3.0 version of the plugin.
unable_to_ssh: |- unable_to_ssh: |-
vagrant-cachier was unable to SSH into the VM to remove symlinks! vagrant-cachier was unable to SSH into the VM to remove symlinks!
vagrant: backed_by_cloud_provider: |-
errors: The machine is backed by a cloud provider (%{provider}), caching
multiple_provider_specific_cache_dirs_found: |- will be disabled.
There are multiple provider specific cache dirs for the '%{machine}' machine:
%{dirs}
Please move one of them up to `%{machine_path}/cache` and remove the others
before bringing the machine up again.

View file

@ -8,7 +8,7 @@ Gem::Specification.new do |spec|
spec.version = VagrantPlugins::Cachier::VERSION spec.version = VagrantPlugins::Cachier::VERSION
spec.authors = ["Fabio Rehm"] spec.authors = ["Fabio Rehm"]
spec.email = ["fgrehm@gmail.com"] spec.email = ["fgrehm@gmail.com"]
spec.description = %q{Speed up vagrant boxes provisioning} spec.description = %q{Caffeine reducer}
spec.summary = spec.description spec.summary = spec.description
spec.homepage = "https://github.com/fgrehm/vagrant-cachier" spec.homepage = "https://github.com/fgrehm/vagrant-cachier"
spec.license = "MIT" spec.license = "MIT"
@ -17,4 +17,14 @@ Gem::Specification.new do |spec|
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) } spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
spec.test_files = spec.files.grep(%r{^(test|spec|features)/}) spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
spec.require_paths = ["lib"] spec.require_paths = ["lib"]
spec.post_install_message = %q{
If you are new to vagrant-cachier just follow along with the docs available
at http://fgrehm.viewdocs.io/vagrant-cachier.
If you are a long time user, please note that plugin has gone through many
backwards incompatible changes since 0.6.0 so checkout
https://github.com/fgrehm/vagrant-cachier/blob/master/CHANGELOG.md
before continuing and caching all the things :)
}
end end