host_machine_sync_folders-patched.rb comes from YungSang/vagrant-docker-helper
Created
July 27, 2014 05:28
-
-
Save scottatron/7e1686a07675e21a7496 to your computer and use it in GitHub Desktop.
Vagrant Docker host VM with NFS support
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require "digest/md5" | |
require "securerandom" | |
require "log4r" | |
require "vagrant/action/builtin/mixin_synced_folders" | |
require Vagrant.source_root.join("plugins/providers/docker/action/host_machine_sync_folders.rb") | |
module VagrantPlugins | |
module DockerProvider | |
module Action | |
# This action is responsible for creating the host machine if | |
# we need to. The host machine is where Docker containers will | |
# live. | |
class HostMachineSyncFolders | |
include Vagrant::Action::Builtin::MixinSyncedFolders | |
def initialize(app, env) | |
@app = app | |
@logger = Log4r::Logger.new("vagrant::docker::hostmachine") | |
end | |
def call(env) | |
return @app.call(env) if !env[:machine].provider.host_vm? | |
if !env.has_key?(:host_machine_sync_folders) | |
env[:host_machine_sync_folders] = true | |
end | |
host_machine = env[:machine].provider.host_vm | |
# Lock while we make changes | |
begin | |
env[:machine].provider.host_vm_lock do | |
setup_synced_folders(host_machine, env) | |
end | |
rescue Vagrant::Errors::EnvironmentLockedError | |
sleep 1 | |
retry | |
end | |
@app.call(env) | |
end | |
protected | |
def setup_synced_folders(host_machine, env) | |
# Write the host machine SFID if we have one | |
id_path = host_machine.data_dir.join("host_machine_sfid") | |
host_sfid = nil | |
if !id_path.file? | |
host_sfid = SecureRandom.uuid | |
id_path.open("w") do |f| | |
f.binmode | |
f.write("#{host_sfid}\n") | |
end | |
else | |
host_sfid = id_path.read.chomp | |
end | |
# Create a UI for this machine that stays at the detail level | |
proxy_ui = host_machine.ui.dup | |
proxy_ui.opts[:bold] = false | |
proxy_ui.opts[:prefix_spaces] = true | |
proxy_ui.opts[:target] = env[:machine].name.to_s | |
# Read the existing folders that are setup | |
existing_folders = synced_folders(host_machine, cached: true) | |
existing_ids = {} | |
if existing_folders | |
existing_folders.each do |impl, fs| | |
fs.each do |_name, data| | |
if data[:docker_sfid] && data[:docker_host_sfid] == host_sfid | |
existing_ids[data[:docker_sfid]] = data | |
end | |
end | |
end | |
end | |
host_vm_build_dir_options = env[:machine].provider_config.host_vm_build_dir_options || {} | |
# Sync some folders so that our volumes work later. | |
new_config = VagrantPlugins::Kernel_V2::VMConfig.new | |
our_folders = synced_folders(env[:machine]) | |
our_folders.each do |type, folders| | |
folders.each do |id, data| | |
data = data.dup | |
if type == :docker | |
# We don't use the Docker type explicitly on the host VM | |
data.delete(:type) | |
end | |
# Expand the hostpath relative to _our_ root path. Otherwise, | |
# it expands it relative to the proxy VM, which is not what | |
# we want. | |
data[:hostpath] = File.expand_path( | |
data[:hostpath], env[:machine].env.root_path) | |
# Generate an ID that is deterministic based on our machine | |
# and Vagrantfile path... | |
id = Digest::MD5.hexdigest( | |
"#{env[:machine].env.root_path}" + | |
"#{data[:hostpath]}" + | |
"#{data[:guestpath]}" + | |
"#{env[:machine].name}") | |
# Generate a new guestpath | |
data[:docker_guestpath] = data[:guestpath] | |
data[:docker_sfid] = id | |
data[:docker_host_sfid] = host_sfid | |
data[:id] = id[0...6] + rand(10000).to_s | |
# If we specify exact then we know what we're doing | |
if !data[:docker__exact] | |
data[:guestpath] = | |
"/var/lib/docker/docker_#{Time.now.to_i}_#{rand(100000)}" | |
end | |
if host_vm_build_dir_options[:type] && host_vm_build_dir_options[:type] == "nfs" && | |
host_vm_build_dir_options[:mount_options] | |
data[:mount_options] = host_vm_build_dir_options[:mount_options] | |
end | |
# Add this synced folder onto the new config if we haven't | |
# already shared it before. | |
if !existing_ids.has_key?(id) | |
# A bit of a hack for VirtualBox to mount our | |
# folder as transient. This can be removed once | |
# the VirtualBox synced folder mechanism is smarter. | |
data[:virtualbox__transient] = true | |
new_config.synced_folder( | |
data[:hostpath], | |
data[:guestpath], | |
data) | |
else | |
# We already have the folder, so just load its data | |
data = existing_ids[id] | |
end | |
# Remove from our machine | |
env[:machine].config.vm.synced_folders.delete(id) | |
# Add the "fixed" folder to our machine | |
data = data.merge({ | |
hostpath_exact: true, | |
type: :docker, | |
}) | |
env[:machine].config.vm.synced_folder( | |
data[:guestpath], | |
data[:docker_guestpath], | |
data) | |
end | |
end | |
if !env[:host_machine_sync_folders] | |
@logger.info("Not syncing folders because container created.") | |
return | |
end | |
action_env = { synced_folders_config: new_config } | |
# Prepare NFS | |
if host_vm_build_dir_options[:type] && host_vm_build_dir_options[:type] == "nfs" | |
nfs_host_ip = nil | |
host_machine.provider.driver.read_network_interfaces.each do |adapter, opts| | |
if opts[:type] == :hostonly | |
host_machine.provider.driver.read_host_only_interfaces.each do |interface| | |
if interface[:name] == opts[:hostonly] | |
nfs_host_ip = interface[:ip] | |
end | |
end | |
end | |
end | |
action_env[:nfs_host_ip] = nfs_host_ip | |
nfs_machine_ip = nil | |
host_machine.config.vm.networks.each do |type, options| | |
if type == :private_network && options[:ip].is_a?(String) | |
nfs_machine_ip = options[:ip] | |
end | |
end | |
action_env[:nfs_machine_ip] = nfs_machine_ip | |
end | |
if !new_config.synced_folders.empty? | |
# Sync the folders! | |
env[:machine].ui.output(I18n.t( | |
"docker_provider.host_machine_syncing_folders")) | |
host_machine.with_ui(proxy_ui) do | |
begin | |
host_machine.action(:sync_folders, action_env) | |
rescue Vagrant::Errors::MachineActionLockedError | |
sleep 1 | |
retry | |
rescue Vagrant::Errors::UnimplementedProviderAction | |
callable = Vagrant::Action::Builder.new | |
callable.use Vagrant::Action::Builtin::SyncedFolders | |
host_machine.action_raw(:sync_folders, callable, action_env) | |
end | |
end | |
end | |
end | |
end | |
end | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require_relative "host_machine_sync_folders-patched.rb" | |
Vagrant.configure("2") do |config| | |
config.vm.define "docker-host" | |
# Has patches for NFS | |
# http://vagrantcloud.com/yungsang/boot2docker | |
config.vm.box = "yungsang/boot2docker" | |
config.vm.provider "virtualbox" do |v, override| | |
# On VirtualBox, we don't have guest additions or a functional vboxsf | |
# in TinyCore Linux, so tell Vagrant that so it can be smarter. | |
v.check_guest_additions = false | |
v.functional_vboxsf = false | |
override.vm.network "private_network", ip: "192.168.33.10" | |
end | |
# Disabled because we don't actually need it for the Docker host VM. | |
config.vm.synced_folder ".", "/vagrant", disabled: true | |
# Change TinyCore Linux mirror as repo.tinycorelinux.net doesn't work for me in Australia | |
# Full list of mirrors at: http://wiki.tinycorelinux.net/wiki:mirrors | |
config.vm.provision 'shell', inline: 'echo http://tinycore.mirror.uber.com.au > /opt/tcemirror' | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment