Class: Bolt::Transport::Podman::Connection

Inherits:
Connection
  • Object
show all
Defined in:
lib/bolt/transport/podman/connection.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(target) ⇒ Connection

Returns a new instance of Connection.



12
13
14
15
16
17
18
19
# File 'lib/bolt/transport/podman/connection.rb', line 12

def initialize(target)
  raise Bolt::ValidationError, "Target #{target.safe_name} does not have a host" unless target.host
  @target = target
  @user = ENV['USER'] || Etc.getlogin
  @logger = Bolt::Logger.logger(target.safe_name)
  @container_info = {}
  @logger.trace("Initializing podman connection to #{target.safe_name}")
end

Instance Attribute Details

#targetObject (readonly)

Returns the value of attribute target.



10
11
12
# File 'lib/bolt/transport/podman/connection.rb', line 10

def target
  @target
end

#userObject (readonly)

Returns the value of attribute user.



10
11
12
# File 'lib/bolt/transport/podman/connection.rb', line 10

def user
  @user
end

Instance Method Details

#connectObject



33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/bolt/transport/podman/connection.rb', line 33

def connect
  # We don't actually have a connection, but we do need to
  # check that the container exists and is running.
  ps = execute_local_json_command('ps')
  container = Array(ps).find { |item|
    item["ID"].to_s.eql?(@target.host) ||
      item["Id"].to_s.start_with?(@target.host) ||
      Array(item["Names"]).include?(@target.host)
  }
  raise "Could not find a container with name or ID matching '#{@target.host}'" if container.nil?
  # Now find the indepth container information
  id = container["ID"] || container["Id"]
  output = execute_local_json_command('inspect', [id])
  # Store the container information for later
  @container_info = output.first
  @logger.trace { "Opened session" }
  true
rescue StandardError => e
  raise Bolt::Node::ConnectError.new(
    "Failed to connect to #{target.safe_name}: #{e.message}",
    'CONNECT_ERROR'
  )
end

#execute(command) ⇒ Object

Executes a command inside the target container. This is called from the shell class.

Parameters:

  • command (string)

    The command to run



60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/bolt/transport/podman/connection.rb', line 60

def execute(command)
  args = []
  args += %w[--interactive]
  args += %w[--tty] if target.options['tty']
  args += @env_vars if @env_vars

  if target.options['shell-command'] && !target.options['shell-command'].empty?
    # escape any double quotes in command
    command = command.gsub('"', '\"')
    command = "#{target.options['shell-command']} \"#{command}\""
  end

  podman_command = %w[podman exec] + args + [container_id] + Shellwords.split(command)
  @logger.trace { "Executing: #{podman_command.join(' ')}" }

  Open3.popen3(*podman_command)
rescue StandardError
  @logger.trace { "Command aborted" }
  raise
end

#run_cmd(cmd, env_vars) ⇒ Object



21
22
23
# File 'lib/bolt/transport/podman/connection.rb', line 21

def run_cmd(cmd, env_vars)
  Bolt::Util.exec_podman(cmd, env_vars)
end

#shellObject



25
26
27
28
29
30
31
# File 'lib/bolt/transport/podman/connection.rb', line 25

def shell
  @shell ||= if Bolt::Util.windows?
               Bolt::Shell::Powershell.new(target, self)
             else
               Bolt::Shell::Bash.new(target, self)
             end
end