class Kubectl::Exec

Handles running kubectl exec

Attributes

stdin_thread[R]
stdout_thread[R]

Public Class Methods

new(kubectl) click to toggle source
# File lib/kuberun/kubectl/exec.rb, line 13
def initialize(kubectl)
  @kubectl = kubectl
end

Public Instance Methods

exec(pod:, command:) click to toggle source
# File lib/kuberun/kubectl/exec.rb, line 17
def exec(pod:, command:)
  old_state = `stty -g`

  PTY.spawn("#{kubectl_base_command('exec', resource: pod)} #{command}") do |out, inp, pid|
    pty_process(out, inp, pid, old_state)
  end
end

Private Instance Methods

cleanup_pty(old_stty_state) click to toggle source
# File lib/kuberun/kubectl/exec.rb, line 72
def cleanup_pty(old_stty_state)
  stdout_thread&.kill
  stdin_thread&.kill
  $stdout.puts
  $stdout.flush

  system("stty #{old_stty_state}")
end
prepare_stdin_thread(inp) click to toggle source
# File lib/kuberun/kubectl/exec.rb, line 29
def prepare_stdin_thread(inp)
  @stdin_thread = Thread.new do
    until inp.closed?
      input = $stdin.getch
      inp.write(input)
      inp.flush
    end
  end
end
prepare_stdout_thread(out) click to toggle source
# File lib/kuberun/kubectl/exec.rb, line 39
def prepare_stdout_thread(out)
  @stdout_thread = Thread.new do
    until out.eof?
      $stdout.print(out.readchar)
      $stdout.flush
    end
  rescue Errno::EIO, EOFError
    nil
  end
end
pty_process(out, inp, pid, old_state) click to toggle source
# File lib/kuberun/kubectl/exec.rb, line 50
def pty_process(out, inp, pid, old_state)
  prepare_stdin_thread(inp)
  prepare_stdout_thread(out)

  stdin_thread.run

  wait_for_process(pid)

  stdout_thread.join
  stdin_thread.kill

  sleep 0.1
ensure
  cleanup_pty(old_state)
end
wait_for_process(pid) click to toggle source
# File lib/kuberun/kubectl/exec.rb, line 66
def wait_for_process(pid)
  Process.waitpid(pid)
rescue StandardError
  nil # "rescue nil" is there in case process already ended.
end