Class: Kitchen::Transport::Dokken::Connection

Inherits:
Base::Connection
  • Object
show all
Defined in:
lib/kitchen/transport/dokken.rb

Overview

A connection to one runner container.

Author:

Constant Summary collapse

RSYNC_PATH =

Where rsync is expected to live. Kept as a constant so the availability check and the command line cannot drift apart.

"/usr/bin/rsync".freeze

Instance Method Summary collapse

Instance Method Details

#docker_connection::Docker::Connection

The docker-api connection this transport talks to.

Returns:

  • (::Docker::Connection)

    a memoised connection



97
98
99
# File 'lib/kitchen/transport/dokken.rb', line 97

def docker_connection
  @docker_connection ||= ::Docker::Connection.new(options[:docker_host_url], options[:docker_host_options])
end

#execute(command) ⇒ void

This method returns an undefined value.

Run a command inside the runner container.

Parameters:

  • command (String, nil)

    the command to run; nil is a no-op

Raises:



106
107
108
109
110
111
112
113
114
115
116
117
118
# File 'lib/kitchen/transport/dokken.rb', line 106

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_commandKitchen::LoginCommand

Build the command kitchen login runs to drop the user into the runner container.

tput reports the terminal size with a trailing newline; that has to be stripped, or bash reads the embedded newline in COLUMNS as the start of another command line.

Returns:

  • (Kitchen::LoginCommand)

    the command to exec



432
433
434
435
436
437
438
# File 'lib/kitchen/transport/dokken.rb', line 432

def 
  @runner = options[:instance_name].to_s
  cols = `tput cols`.strip
  lines = `tput lines`.strip
  args = ["exec", "-e", "COLUMNS=#{cols}", "-e", "LINES=#{lines}", "-it", @runner, "/bin/bash", "-login", "-i"]
  LoginCommand.new(options[:login_command], args)
end

#upload(locals, remote) ⇒ void

This method returns an undefined value.

Copy the kitchen sandbox into the data container.

Parameters:

  • locals (Array<String>)

    local paths to copy

  • remote (String)

    the destination path inside the container

Raises:

  • (Kitchen::UserError)

    if docker_host_url is not tcp:// or unix://

  • (Kitchen::Transport::TransportFailed)

    if the copy fails



127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
# File 'lib/kitchen/transport/dokken.rb', line 127

def upload(locals, remote)
  # Every route through ssh_endpoint reads the data container out of
  # state, so being handed none is not a transfer that fails -- it is
  # a caller that should not have asked. Said plainly here rather than
  # as `undefined method '[]' for nil` from three frames down.
  if options[:data_container].nil?
    raise Kitchen::Transport::TransportFailed,
      "Cannot upload to #{options[:instance_name]}: no data container was created " \
      "for this instance. Files are only shipped over ssh when the docker daemon " \
      "cannot read the local filesystem; otherwise the sandbox is bind-mounted."
  end

  ssh_ip, ssh_port = ssh_endpoint

  debug "ssh_ip : #{ssh_ip}"
  debug "ssh_port : #{ssh_port}"

  upload_files(locals, remote, ssh_ip, ssh_port, write_insecure_key)
end