-
Notifications
You must be signed in to change notification settings - Fork 288
Expand file tree
/
Copy pathexec.rb
More file actions
107 lines (95 loc) · 3.2 KB
/
exec.rb
File metadata and controls
107 lines (95 loc) · 3.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# This class represents a Docker Exec Instance.
class Docker::Exec
include Docker::Base
# Convert details about the object into a string
#
# @return [String] String representation of the Exec instance object
def to_s
"Docker::Exec { :id => #{self.id}, :connection => #{self.connection} }"
end
# Create a new Exec instance in a running container. Please note, this does
# NOT execute the instance - you must run #start. Also, each instance is
# one-time use only.
#
# @param options [Hash] Parameters to pass in to the API.
# @param conn [Docker::Connection] Connection to Docker Remote API
#
# @return [Docker::Exec] self
def self.create(options = {}, conn = Docker.connection)
container = options.delete('Container')
resp = conn.post("/containers/#{container}/exec", {},
:body => options.to_json)
hash = Docker::Util.parse_json(resp) || {}
new(conn, hash)
end
# Get info about the Exec instance
#
def json
Docker::Util.parse_json(connection.get(path_for(:json), {}))
end
# Start the Exec instance. The Exec instance is deleted after this so this
# command can only be run once.
#
# @param options [Hash] Options to dictate behavior of the instance
# @option options [Object] :stdin (nil) The object to pass to STDIN.
# @option options [TrueClass, FalseClass] :detach (false) Whether to attach
# to STDOUT/STDERR.
# @option options [TrueClass, FalseClass] :tty (false) Whether to attach using
# a pseudo-TTY.
#
# @return [Array, Array, Int] The STDOUT, STDERR and exit code
def start!(options = {}, &block)
# Parse the Options
tty = !!options.delete(:tty)
detached = !!options.delete(:detach)
stdin = options.delete(:stdin)
# Create API Request Body
body = {
"Tty" => tty,
"Detach" => detached
}
excon_params = { :body => body.to_json }
opts = {
:stream => true, :stdout => true, :stderr => true
}.merge(options)
msgs = Docker::Messages.new
unless detached
if stdin
excon_params[:hijack_block] = Docker::Util.hijack_for(stdin, block,
msgs, tty)
else
excon_params[:response_block] = Docker::Util.attach_for(block,
msgs, tty)
end
end
connection.post(path_for(:start), opts, excon_params)
[msgs.stdout_messages, msgs.stderr_messages, self.json['ExitCode']]
end
# #start! performs the associated action and returns the output.
# #start does the same, but rescues from ServerErrors.
[:start].each do |method|
define_method(method) do |*args|
begin; public_send(:"#{method}!", *args); rescue ServerError; self end
end
end
# Resize the TTY associated with the Exec instance
#
# @param query [Hash] API query parameters
# @option query [Fixnum] h Height of the TTY
# @option query [Fixnum] w Width of the TTY
#
# @return [Docker::Exec] self
def resize(query = {})
connection.post(path_for(:resize), query)
self
end
# Get the request URI for the given endpoint
#
# @param endpoint [Symbol] The endpoint to grab
# @return [String] The full Remote API endpoint with ID
def path_for(endpoint)
"/exec/#{self.id}/#{endpoint}"
end
private :path_for
private_class_method :new
end