Class: VagrantPlugins::VagrantCommunicatorDocker::Communicator
- Inherits:
-
Object
- Object
- VagrantPlugins::VagrantCommunicatorDocker::Communicator
- Defined in:
- lib/vagrant-communicator-docker/vagrant-communicator-docker.rb
Overview
This class provides communication with Docker instances
Class Method Summary collapse
Instance Method Summary collapse
-
#download(from, to) ⇒ Object
Download a file from the remote machine to the local machine.
-
#execute(command, opts = nil) {|type, data| ... } ⇒ Integer
Execute a command on the remote machine.
-
#initialize(machine) ⇒ Communicator
constructor
A new instance of Communicator.
- #ready? ⇒ Boolean
-
#reset! ⇒ Object
a persistent connection to the remote machine, this connection should be terminated and re-established.
-
#sudo(command, opts = nil) ⇒ Object
Executes a command on the remote machine with administrative privileges.
-
#test(command, opts = nil) ⇒ Object
Executes a command and returns true if the command succeeded, and false otherwise.
-
#upload(from, to) ⇒ Object
Upload a file to the remote machine.
-
#wait_for_ready(duration) ⇒ Boolean
wait_for_ready waits until the communicator is ready, blocking until then.
Constructor Details
#initialize(machine) ⇒ Communicator
Returns a new instance of Communicator.
19 20 21 22 23 24 25 26 |
# File 'lib/vagrant-communicator-docker/vagrant-communicator-docker.rb', line 19 def initialize(machine) @logger = Log4r::Logger.new("vagrant::communication::docker") @machine = machine @machineID = machine.id @logger.debug("MACHINE ID #{@machineID}") @logger.debug("MACHINE SHELL: #{@machine.config.communicator.bash_shell}") @logger.debug("SHELL WAIT: #{@machine.config.communicator.bash_wait}") end |
Class Method Details
.match?(machine) ⇒ Boolean
14 15 16 17 |
# File 'lib/vagrant-communicator-docker/vagrant-communicator-docker.rb', line 14 def self.match?(machine) # All machines are currently expected to be docker instances. return true end |
Instance Method Details
#download(from, to) ⇒ Object
Download a file from the remote machine to the local machine.
70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 |
# File 'lib/vagrant-communicator-docker/vagrant-communicator-docker.rb', line 70 def download(from, to) wait_for_ready(@machine.config.communicator.bash_wait) @logger.debug("DOCKER COMMUNICATOR - DOWNLOAD from: #{from} to: #{to}") tempfile = "/tmp/#{SecureRandom.urlsafe_base64}.tar" @logger.debug("DOCKER COMMUNICATOR - tempfile - #{tempfile}") File.open(tempfile, "w") do |file| @container.archive_out(from) do |chunk| file.write(chunk) end end Gem::Package::TarReader.new( File.open(tempfile) ) do |tar| tar.each do |entry| File.open to, "wb" do |f| f.print entry.read end end end end |
#execute(command, opts = nil) {|type, data| ... } ⇒ Integer
Execute a command on the remote machine. The exact semantics of this method are up to the implementor, but in general the users of this class will expect this to be a shell.
This method gives you no way to write data back to the remote machine, so only execute commands that don’t expect input.
117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 |
# File 'lib/vagrant-communicator-docker/vagrant-communicator-docker.rb', line 117 def execute(command, opts=nil) begin @logger.debug("DOCKER COMMUNICATOR - EXECUTE: #{command}") wait_for_ready(@machine.config.communicator.bash_wait) @logger.debug("DOCKER COMMUNICATOR - Ready to EXECUTE") result = @container.exec([@machine.config.communicator.bash_shell, '-c' , command], tty: true) @logger.debug(result) if result.first.length > 0 result.first.first.each_line do |line| yield :stdout, line if block_given? end end return result.last rescue => e @logger.info("DOCKER COMMUNICATOR: Error running command " + command + " on guest using shell #{@machine.config.communicator.bash_shell}") @logger.error ([e.]+e.backtrace).join($/) end return 255 end |
#ready? ⇒ Boolean
28 29 30 31 32 33 34 35 36 37 38 39 40 |
# File 'lib/vagrant-communicator-docker/vagrant-communicator-docker.rb', line 28 def ready? begin @logger.info(Docker.version) @container = Docker::Container.get(@machineID) @logger.debug(@container.json) # If we reached this point then we successfully connected @logger.debug("DOCKER COMMUNICATOR connected to #{@machineID}") true rescue @logger.debug("DOCKER COMMUNICATOR - Could not make connection to #{@machineID}") false end end |
#reset! ⇒ Object
a persistent connection to the remote machine, this connection should be terminated and re-established. The communicator instance should be in a “fresh” state after calling this method.
165 166 167 |
# File 'lib/vagrant-communicator-docker/vagrant-communicator-docker.rb', line 165 def reset! @logger.debug("DOCKER COMMUNICATOR - RESET - NOT IMPLEMENTED") end |
#sudo(command, opts = nil) ⇒ Object
Executes a command on the remote machine with administrative privileges. See #execute for documentation, as the API is the same.
142 143 144 145 |
# File 'lib/vagrant-communicator-docker/vagrant-communicator-docker.rb', line 142 def sudo(command, opts=nil) @logger.debug("DOCKER COMMUNICATOR - EXECUTE WITH SUDO: #{command}") execute(command, opts) end |
#test(command, opts = nil) ⇒ Object
Executes a command and returns true if the command succeeded, and false otherwise. By default, this executes as a normal user, and it is up to the communicator implementation if they expose an option for running tests as an administrator.
153 154 155 156 157 158 159 |
# File 'lib/vagrant-communicator-docker/vagrant-communicator-docker.rb', line 153 def test(command, opts=nil) result = execute(command) if result == 0 return true end return false end |
#upload(from, to) ⇒ Object
Upload a file to the remote machine.
94 95 96 97 98 99 100 101 |
# File 'lib/vagrant-communicator-docker/vagrant-communicator-docker.rb', line 94 def upload(from, to) wait_for_ready(@machine.config.communicator.bash_wait) to_folder = File.dirname(to) from_filename = File.basename(from) @logger.debug("DOCKER COMMUNICATOR - upload from: #{from} to: #{to_folder} from_filename: #{from_filename}") @container.archive_in(from, File.dirname(to), overwrite: true) execute("mv #{to_folder}/#{from_filename} #{to}") end |
#wait_for_ready(duration) ⇒ Boolean
wait_for_ready waits until the communicator is ready, blocking until then. It will wait up to the given duration or raise an exception if something goes wrong.
49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
# File 'lib/vagrant-communicator-docker/vagrant-communicator-docker.rb', line 49 def wait_for_ready(duration) # By default, we implement a naive solution. begin Timeout.timeout(duration) do while true return true if ready? sleep 0.5 end end rescue Timeout::Error # We timed out, we failed. @logger.debug("DOCKER COMMUNICATOR - Timeout to ready") end return false end |