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.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//, # 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