providers/docker: use a custom communicator to go through host VM
This commit is contained in:
parent
bdade7d5a6
commit
e947960c09
|
@ -23,7 +23,7 @@ module Vagrant
|
|||
#
|
||||
# @return [Boolean]
|
||||
def self.match?(machine)
|
||||
false
|
||||
true
|
||||
end
|
||||
|
||||
# Initializes the communicator with the machine that we will be
|
||||
|
|
|
@ -0,0 +1,83 @@
|
|||
module VagrantPlugins
|
||||
module DockerProvider
|
||||
# This communicator uses the host VM as proxy to communicate to the
|
||||
# actual Docker container via SSH.
|
||||
class Communicator < Vagrant.plugin("2", :communicator)
|
||||
def initialize(machine)
|
||||
@machine = machine
|
||||
@host_vm = machine.provider.host_vm
|
||||
|
||||
# We only work on the Docker provider
|
||||
if machine.provider_name != :docker
|
||||
raise Errors::CommunicatorNotDocker
|
||||
end
|
||||
end
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
# Communicator Methods
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
def ready?
|
||||
# We can't be ready if we can't talk to the host VM
|
||||
return false if !@host_vm.communicate.ready?
|
||||
|
||||
# We're ready if we can establish an SSH connection to the container
|
||||
@host_vm.communicate.test("#{container_ssh_command} exit")
|
||||
end
|
||||
|
||||
def download(from, to)
|
||||
raise "NOT IMPLEMENTED YET"
|
||||
end
|
||||
|
||||
def execute(command, opts=nil, &block)
|
||||
@host_vm.communicate.execute(
|
||||
"#{container_ssh_command} #{command}", opts, &block)
|
||||
end
|
||||
|
||||
def sudo(command, opts=nil)
|
||||
end
|
||||
|
||||
def test(command, **opts)
|
||||
opts = { error_check: false }.merge(opts)
|
||||
execute(command, opts) == 0
|
||||
end
|
||||
|
||||
def upload(from, to)
|
||||
# First, we upload this to the host VM to some temporary directory.
|
||||
to_temp = "/tmp/docker_#{Time.now.to_i}_#{rand(100000)}"
|
||||
@host_vm.communicate.upload(from, to_temp)
|
||||
|
||||
# Then, we use `cat` to get that file into the Docker container.
|
||||
@host_vm.communicate.execute(
|
||||
"#{container_ssh_command} 'cat >#{to}' <#{to_temp}")
|
||||
|
||||
# Remove the temporary file
|
||||
@host_vm.communicate.execute("rm #{to_temp}", error_check: false)
|
||||
end
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
# Other Methods
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
# This returns the raw SSH command string that can be used to
|
||||
# connect via SSH to the container if you're on the same machine
|
||||
# as the container.
|
||||
#
|
||||
# @return [String]
|
||||
def container_ssh_command
|
||||
# Get the container's SSH info
|
||||
info = @machine.ssh_info
|
||||
info[:port] ||= 22
|
||||
|
||||
# Build the SSH command
|
||||
"ssh -i /home/vagrant/insecure " +
|
||||
"-o Compression=yes " +
|
||||
"-o ConnectTimeout=5 " +
|
||||
"-o StrictHostKeyChecking=no " +
|
||||
"-o UserKnownHostsFile=/dev/null " +
|
||||
"-p#{info[:port]} " +
|
||||
"#{info[:username]}@#{info[:host]}"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -5,6 +5,10 @@ module VagrantPlugins
|
|||
error_namespace("docker_provider.errors")
|
||||
end
|
||||
|
||||
class CommunicatorNonDocker < DockerError
|
||||
error_key(:communicator_non_docker)
|
||||
end
|
||||
|
||||
class ExecuteError < DockerError
|
||||
error_key(:execute_error)
|
||||
end
|
||||
|
|
|
@ -28,6 +28,12 @@ module VagrantPlugins
|
|||
Command::Logs
|
||||
end
|
||||
|
||||
communicator(:docker_hostvm) do
|
||||
require_relative "communicator"
|
||||
init!
|
||||
Communicator
|
||||
end
|
||||
|
||||
config(:docker, :provider) do
|
||||
require_relative 'config'
|
||||
init!
|
||||
|
|
|
@ -11,6 +11,12 @@ module VagrantPlugins
|
|||
def initialize(machine)
|
||||
@logger = Log4r::Logger.new("vagrant::provider::docker")
|
||||
@machine = machine
|
||||
|
||||
if host_vm?
|
||||
# We need to use a special communicator that proxies our
|
||||
# SSH requests over our host VM to the container itself.
|
||||
@machine.config.vm.communicator = :docker_hostvm
|
||||
end
|
||||
end
|
||||
|
||||
# @see Vagrant::Plugin::V2::Provider#action
|
||||
|
|
|
@ -63,6 +63,12 @@ en:
|
|||
run exits and doesn't keep running.
|
||||
|
||||
errors:
|
||||
communicator_non_docker: |-
|
||||
The "docker_hostvm" communicator was specified on a machine that
|
||||
is not provided by the Docker provider. This is a bug with your
|
||||
Vagrantfile. Please contact the creator of your Vagrant environment
|
||||
and notify them to not use this communicator for anything except the
|
||||
"docker" provider.
|
||||
config:
|
||||
cmd_not_set: |-
|
||||
The Docker command has not been set!
|
||||
|
|
Loading…
Reference in New Issue