-
-
Save cariandrum22/278973172442d6f54a0c3ab83a86469f to your computer and use it in GitHub Desktop.
docker-machine/ boot2docker with NFS instead of vboxsf
This file contains 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
#!/usr/bin/env ruby | |
# Usage | |
# $ docker-machine create my-machine123 -d virtualbox | |
# $ ruby <(curl -L https://git.io/v6r1A) my-machine123 | |
# https://gist.github.com/cariandrum22/278973172442d6f54a0c3ab83a86469f | |
# fork from https://gist.github.com/mattes/4d7f435d759ca2581347 | |
# I owe you a lot, mattes. | |
require 'erb' | |
require 'optparse' | |
BOOTLOCAL_SH_TEMPLATE = <<EOL | |
#/bin/bash | |
sudo umount /Users | |
sudo /usr/local/etc/init.d/nfs-client start | |
sudo mount -t nfs -o noacl,async <%= ip %>:/Users /Users | |
EOL | |
.freeze | |
class DockerMachineNfs | |
def initialize(machine_name, driver) | |
@bootlocal = BOOTLOCAL_SH_TEMPLATE | |
case driver | |
when 'virtualbox' then | |
@uid = `id -u`.chomp | |
@gid = `id -g`.chomp | |
@dmachine_name = machine_name | |
@dmachine_ip = `docker-machine ip #{machine_name}`.chomp | |
@vboxnet_ip = VirtualBox.get_vboxnet_ip(VirtualBox.get_hostonly_adapter(machine_name)) | |
else | |
raise 'This script dose not support selected driver: ' + driver | |
end | |
yield self if block_given? | |
end | |
def setup_nfs_server | |
# create record in local /etc/exports and restart nsfd | |
puts 'Update /etc/exports ...' | |
`echo '\n/Users #{@dmachine_ip} -alldirs -mapall=#{@uid}:#{@gid}\n' | sudo tee -a /etc/exports` | |
`awk '!a[$0]++' /etc/exports | sudo tee /etc/exports` # removes duplicate lines | |
`sudo nfsd restart` | |
sleep 2 | |
checkexports = `sudo nfsd checkexports 2>&1` | |
if checkexports == '' | |
puts ' > Done.' | |
else | |
raise 'exec `sudo nfsd checkexports`: ' + checkexports | |
end | |
end | |
def setup_nfs_client | |
# render bootlocal.sh and copy bootlocal.sh over to boot2docker | |
# (this will override an existing /var/lib/boot2docker/bootlocal.sh) | |
puts 'Update boot2docker virtual machine ...' | |
ip = @vboxnet_ip | |
first = true | |
ERB.new(@bootlocal).result(binding).split("\n").each do |l| | |
`docker-machine ssh #{@dmachine_name} 'echo \"#{l}\" | sudo tee #{first ? '' : '-a'} /var/lib/boot2docker/bootlocal.sh'` | |
first = false | |
end | |
`docker-machine ssh #{@dmachine_name} 'sudo chmod +x /var/lib/boot2docker/bootlocal.sh'` | |
`docker-machine ssh #{@dmachine_name} 'sudo sync'` | |
puts "Restart #{@dmachine_name} ..." | |
`docker-machine restart #{@dmachine_name}` | |
puts ' > Done.' | |
end | |
def check | |
puts "Check if NFS is mounted on docker-machine \"#{@dmachine_name}\"." | |
sleep 2 | |
result = <<-EOS | |
> failed: Try `docker-machine ssh #{@dmachine_name} df`. | |
Output should include something like this: '#{@vboxnet_ip}:/Users [...] /Users' | |
EOS | |
`docker-machine ssh #{@dmachine_name} df`.each_line do |l| | |
result = ' > Done.' if %r{^#{@vboxnet_ip}:/Users.*/Users$} =~ l.chomp | |
end | |
puts result | |
end | |
end | |
module VirtualBox | |
class << self | |
def get_hostonly_adapter(machine_name) | |
puts 'Get vbox hostonly adapter name ...' | |
vboxnet_name = `VBoxManage showvminfo #{machine_name} --machinereadable | grep hostonlyadapter` | |
.scan(/"(.*)"/).flatten.first.chomp | |
raise 'error: unable to find name of vboxnet' if vboxnet_name == '' | |
puts ' > ' + vboxnet_name | |
vboxnet_name | |
end | |
def get_vboxnet_ip(vboxnet_name) | |
puts 'Get vbox net ip address ...' | |
`VBoxManage list hostonlyifs`.split("\n\n").each do |vboxnet| | |
if vboxnet.scan(/Name: *(.+?)\n/).flatten.first.chomp == vboxnet_name | |
vboxip = vboxnet.scan(/IPAddress: *(.*)\n/).flatten.first.chomp | |
puts ' > ' + vboxip | |
return vboxip | |
else | |
next | |
end | |
end | |
end | |
end | |
end | |
def main | |
options = { driver: 'virtualbox' } | |
OptionParser.new do |op| | |
op.on('-d', '--driver "virtualbox"', 'docker-machine driver (default:virtualbox)') { |v| options[:driver] = v } | |
op.parse!(ARGV) | |
end | |
if ARGV.length != 1 | |
puts "Usage: #{File.basename(__FILE__)} machine_name" | |
exit 1 | |
end | |
machine_name = ARGV[0] | |
driver = options[:driver] | |
DockerMachineNfs.new(machine_name, driver) do |d| | |
d.setup_nfs_server | |
d.setup_nfs_client | |
d.check | |
end | |
end | |
main |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment