diff --git a/README.md b/README.md index 2d2917f..5847e3f 100644 --- a/README.md +++ b/README.md @@ -55,6 +55,13 @@ gets installed, create a `Vagrantfile` like the one below and run `vagrant-lxc u ```ruby Vagrant.configure("2") do |config| config.vm.box = "ubuntu-cloud" + + # Share an additional folder to the guest Container. The first argument + # is the path on the host to the actual folder. The second argument is + # the path on the guest to mount the folder. And the optional third + # argument is a set of non-required options. + config.vm.synced_folder "/tmp", "/host_tmp" + config.vm.provider :lxc do |lxc| # Same as 'customize ["modifyvm", :id, "--memory", "1024"]' for VirtualBox lxc.start_opts << 'lxc.cgroup.memory.limit_in_bytes=400M' diff --git a/example/Vagrantfile b/example/Vagrantfile index 4692b2b..d528efb 100644 --- a/example/Vagrantfile +++ b/example/Vagrantfile @@ -7,6 +7,8 @@ Vagrant.configure("2") do |config| config.vm.box = "ubuntu-cloud" config.vm.hostname = 'ubuntu-cloud-box' + config.vm.synced_folder "/tmp", "/vagrant_data" + config.vm.provider :lxc do |lxc| lxc.start_opts << 'lxc.cgroup.memory.limit_in_bytes=400M' lxc.start_opts << 'lxc.cgroup.memory.memsw.limit_in_bytes=500M' diff --git a/lib/vagrant-lxc/action.rb b/lib/vagrant-lxc/action.rb index 92c80cf..8281cf3 100644 --- a/lib/vagrant-lxc/action.rb +++ b/lib/vagrant-lxc/action.rb @@ -9,6 +9,7 @@ require 'vagrant-lxc/action/created' require 'vagrant-lxc/action/destroy' require 'vagrant-lxc/action/handle_box_metadata' require 'vagrant-lxc/action/is_running' +require 'vagrant-lxc/action/share_folders' module Vagrant module LXC @@ -46,7 +47,7 @@ module Vagrant b.use Vagrant::Action::Builtin::Provision b.use Vagrant::Action::Builtin::EnvSet, :port_collision_repair => true b.use PrepareForwardedPortCollisionParams - b.use ClearSharedFolders + # b.use ClearSharedFolders b.use ShareFolders b.use Network b.use ForwardPorts @@ -86,7 +87,7 @@ module Vagrant end b.use action_start b.use AfterCreate - b.use Vagrant::Action::Builtin::SetHostname + # b.use Vagrant::Action::Builtin::SetHostname end end @@ -164,9 +165,6 @@ module Vagrant # TODO: Check if our requirements are met. class CheckLXC < BaseAction; end - # TODO: Implement folder sharing with "mount" - class ShareFolders < BaseAction; end - # TODO: Sets up all networking for the container instance. This includes # host only networks, bridged networking, forwarded ports, etc. class Network < BaseAction; end diff --git a/lib/vagrant-lxc/action/share_folders.rb b/lib/vagrant-lxc/action/share_folders.rb new file mode 100644 index 0000000..4afcce8 --- /dev/null +++ b/lib/vagrant-lxc/action/share_folders.rb @@ -0,0 +1,63 @@ +module Vagrant + module LXC + module Action + class ShareFolders < BaseAction + def call(env) + @env = env + prepare_folders + add_start_opts + @app.call env + end + + # This method returns an actual list of VirtualBox shared + # folders to create and their proper path. + def shared_folders + {}.tap do |result| + @env[:machine].config.vm.synced_folders.each do |id, data| + # Ignore NFS shared folders + next if data[:nfs] + + # This to prevent overwriting the actual shared folders data + result[id] = data.dup + end + end + end + + # Prepares the shared folders by verifying they exist and creating them + # if they don't. + def prepare_folders + shared_folders.each do |id, options| + hostpath = Pathname.new(options[:hostpath]).expand_path(@env[:root_path]) + + if !hostpath.directory? && options[:create] + # Host path doesn't exist, so let's create it. + @logger.debug("Host path doesn't exist, creating: #{hostpath}") + + begin + hostpath.mkpath + rescue Errno::EACCES + raise Vagrant::Errors::SharedFolderCreateFailed, + :path => hostpath.to_s + end + end + end + end + + def add_start_opts + @env[:ui].info I18n.t("vagrant.actions.vm.share_folders.creating") + + folders = [] + shared_folders.each do |id, data| + folders << { + :name => id, + :hostpath => File.expand_path(data[:hostpath], @env[:root_path]), + :guestpath => data[:guestpath] + } + end + config = @env[:machine].provider_config + @env[:machine].provider.container.share_folders(folders, config) + end + end + end + end +end diff --git a/lib/vagrant-lxc/container.rb b/lib/vagrant-lxc/container.rb index fac3d49..7be5ed8 100644 --- a/lib/vagrant-lxc/container.rb +++ b/lib/vagrant-lxc/container.rb @@ -66,6 +66,26 @@ module Vagrant end end + def rootfs_path + Pathname.new("#{CONTAINERS_PATH}/#{@name}/rootfs") + end + + def share_folders(folders, config) + folders.each do |folder| + guestpath = rootfs_path.join(folder[:guestpath].gsub(/^\//, '')) + unless guestpath.directory? + begin + system "sudo mkdir -p #{guestpath.to_s}" + rescue Errno::EACCES + raise Vagrant::Errors::SharedFolderCreateFailed, + :path => guestpath.to_s + end + end + + config.start_opts << "lxc.mount.entry=#{folder[:hostpath]} #{guestpath} none bind 0 0" + end + end + def start(config) # @logger.info('Starting container...') opts = config.start_opts.map { |opt| ["-s", opt] }.flatten