class Kitchen::Transport::Dokken::Connection
@author Sean OMeara <sean@sean.io>
Public Instance Methods
docker_connection()
click to toggle source
# File lib/kitchen/transport/dokken.rb, line 70 def docker_connection @docker_connection ||= ::Docker::Connection.new(options[:docker_host_url], options[:docker_host_options]) end
execute(command)
click to toggle source
# File lib/kitchen/transport/dokken.rb, line 74 def execute(command) return if command.nil? with_retries { @runner = ::Docker::Container.get(instance_name, {}, docker_connection) } with_retries do o = @runner.exec(Shellwords.shellwords(command), wait: options[:timeout], "e" => { "TERM" => "xterm" }) do |_stream, chunk| logger << chunk end @exit_code = o[2] end raise Transport::DockerExecFailed.new("Docker Exec (#{@exit_code}) for command: [#{command}]", @exit_code) if @exit_code != 0 end
login_command()
click to toggle source
# File lib/kitchen/transport/dokken.rb, line 177 def login_command @runner = options[:instance_name].to_s cols = `tput cols` lines = `tput lines` args = ["exec", "-e", "COLUMNS=#{cols}", "-e", "LINES=#{lines}", "-it", @runner, "/bin/bash", "-login", "-i"] LoginCommand.new(options[:login_command], args) end
upload(locals, remote)
click to toggle source
# File lib/kitchen/transport/dokken.rb, line 88 def upload(locals, remote) if options[:host_ip_override] # Allow connecting to any ip/hostname to support sibling containers ssh_ip = options[:host_ip_override] ssh_port = options[:data_container][:NetworkSettings][:Ports][:"22/tcp"][0][:HostPort] elsif /unix:/.match?(options[:docker_host_url]) if options[:data_container][:NetworkSettings][:Ports][:"22/tcp"][0][:HostIp] == "0.0.0.0" ssh_ip = options[:data_container][:NetworkSettings][:IPAddress] ssh_port = "22" else # we should read the proper mapped ip, since this allows us to upload the files ssh_ip = options[:data_container][:NetworkSettings][:Ports][:"22/tcp"][0][:HostIp] ssh_port = options[:data_container][:NetworkSettings][:Ports][:"22/tcp"][0][:HostPort] end elsif /tcp:/.match?(options[:docker_host_url]) name = options[:data_container][:Name] # DOCKER_HOST docker_host_url_ip = options[:docker_host_url].split("tcp://")[1].split(":")[0] # mapped IP of data container candidate_ip = ::Docker::Container.all.find do |x| x.info["Names"][0].eql?(name) end.info["NetworkSettings"]["Networks"]["dokken"]["IPAddress"] # mapped port candidate_ssh_port = options[:data_container][:NetworkSettings][:Ports][:"22/tcp"][0][:HostPort] debug "candidate_ip - #{candidate_ip}" debug "candidate_ssh_port - #{candidate_ssh_port}" if port_open?(candidate_ip, candidate_ssh_port) debug "candidate_ip - #{candidate_ip}/#{candidate_ssh_port} open" ssh_ip = candidate_ip ssh_port = candidate_ssh_port elsif port_open?(candidate_ip, "22") ssh_ip = candidate_ip ssh_port = "22" debug "candidate_ip - #{candidate_ip}/22 open" else ssh_ip = docker_host_url_ip ssh_port = candidate_ssh_port end else raise Kitchen::UserError, "docker_host_url must be tcp:// or unix://" end debug "ssh_ip : #{ssh_ip}" debug "ssh_port : #{ssh_port}" tmpdir = Dir.tmpdir + "/dokken/" FileUtils.mkdir_p tmpdir.to_s, mode: 0o777 tmpdir += Process.uid.to_s FileUtils.mkdir_p tmpdir.to_s File.write("#{tmpdir}/id_rsa", insecure_ssh_private_key) FileUtils.chmod(0o600, "#{tmpdir}/id_rsa") begin rsync_cmd = "/usr/bin/rsync -a -e" rsync_cmd << " '" rsync_cmd << "ssh -2" rsync_cmd << " -i #{tmpdir}/id_rsa" rsync_cmd << " -o CheckHostIP=no" rsync_cmd << " -o Compression=no" rsync_cmd << " -o PasswordAuthentication=no" rsync_cmd << " -o StrictHostKeyChecking=no" rsync_cmd << " -o UserKnownHostsFile=/dev/null" rsync_cmd << " -o LogLevel=ERROR" rsync_cmd << " -p #{ssh_port}" rsync_cmd << "'" rsync_cmd << " #{locals.join(" ")} root@#{ssh_ip}:#{remote}" debug "rsync_cmd :#{rsync_cmd}:" `#{rsync_cmd}` rescue Errno::ENOENT debug "Rsync is not installed. Falling back to SCP." locals.each do |local| Net::SCP.upload!(ssh_ip, "root", local, remote, recursive: true, ssh: { port: ssh_port, keys: ["#{tmpdir}/id_rsa"] }) end end end
Private Instance Methods
image_prefix()
click to toggle source
# File lib/kitchen/transport/dokken.rb, line 197 def image_prefix options[:image_prefix] end
instance_name()
click to toggle source
# File lib/kitchen/transport/dokken.rb, line 187 def instance_name options[:instance_name] end
with_retries() { || ... }
click to toggle source
# File lib/kitchen/transport/dokken.rb, line 201 def with_retries tries = 20 begin yield # Only catch errors that can be fixed with retries. rescue ::Docker::Error::ServerError, # 404 ::Docker::Error::UnexpectedResponseError, # 400 ::Docker::Error::TimeoutError, ::Docker::Error::IOError => e tries -= 1 retry if tries > 0 raise e end end
work_image()
click to toggle source
# File lib/kitchen/transport/dokken.rb, line 191 def work_image return "#{image_prefix}/#{instance_name}" unless image_prefix.nil? instance_name end