22require 'json'
33require 'uri'
44require 'securerandom'
5+ require 'centurion/ssh'
56
67module Centurion ; end
78
89class Centurion ::DockerViaApi
9- def initialize ( hostname , port , tls_args = { } , api_version = nil )
10- @tls_args = default_tls_args ( tls_args [ :tls ] ) . merge ( tls_args . reject { |k , v | v . nil? } ) # Required by tls_enable?
11- @base_uri = "http#{ 's' if tls_enable? } ://#{ hostname } :#{ port } "
10+ def initialize ( hostname , port , connection_opts = { } , api_version = nil )
11+ @tls_args = default_tls_args ( connection_opts [ :tls ] ) . merge ( connection_opts . reject { |k , v | v . nil? } ) # Required by tls_enable?
12+ if connection_opts [ :ssh ]
13+ @base_uri = hostname
14+ @ssh = true
15+ @ssh_user = connection_opts [ :ssh_user ]
16+ @ssh_log_level = connection_opts [ :ssh_log_level ]
17+ else
18+ @base_uri = "http#{ 's' if tls_enable? } ://#{ hostname } :#{ port } "
19+ end
1220 api_version ||= "/v1.12"
1321 @docker_api_version = api_version
1422 configure_excon_globally
@@ -17,7 +25,7 @@ def initialize(hostname, port, tls_args = {}, api_version = nil)
1725 def ps ( options = { } )
1826 path = @docker_api_version + "/containers/json"
1927 path += "?all=1" if options [ :all ]
20- response = Excon . get ( @base_uri + path , tls_excon_arguments )
28+ response = with_excon { | e | e . get ( path : path ) }
2129
2230 raise unless response . status == 200
2331 JSON . load ( response . body )
@@ -27,61 +35,64 @@ def inspect_image(image, tag = "latest")
2735 repository = "#{ image } :#{ tag } "
2836 path = @docker_api_version + "/images/#{ repository } /json"
2937
30- response = Excon . get (
31- @base_uri + path ,
32- tls_excon_arguments . merge ( headers : { 'Accept' => 'application/json' } )
33- )
38+ response = with_excon do |e |
39+ e . get (
40+ path : path ,
41+ headers : { 'Accept' => 'application/json' }
42+ )
43+ end
3444 raise response . inspect unless response . status == 200
3545 JSON . load ( response . body )
3646 end
3747
3848 def remove_container ( container_id )
3949 path = @docker_api_version + "/containers/#{ container_id } "
40- response = Excon . delete (
41- @base_uri + path ,
42- tls_excon_arguments
43- )
50+ response = with_excon do |e |
51+ e . delete (
52+ path : path ,
53+ )
54+ end
4455 raise response . inspect unless response . status == 204
4556 true
4657 end
4758
4859 def stop_container ( container_id , timeout = 30 )
4960 path = @docker_api_version + "/containers/#{ container_id } /stop?t=#{ timeout } "
50- response = Excon . post (
51- @base_uri + path ,
52- tls_excon_arguments . merge (
61+ response = with_excon do | e |
62+ e . post (
63+ path : path ,
5364 # Wait for both the docker stop timeout AND the kill AND
5465 # potentially a very slow HTTP server.
5566 read_timeout : timeout + 120
5667 )
57- )
68+ end
5869 raise response . inspect unless response . status == 204
5970 true
6071 end
6172
6273 def create_container ( configuration , name = nil )
6374 path = @docker_api_version + "/containers/create"
64- response = Excon . post (
65- @base_uri + path ,
66- tls_excon_arguments . merge (
67- query : name ? { name : " #{ name } -#{ SecureRandom . hex ( 7 ) } "} : nil ,
75+ response = with_excon do | e |
76+ e . post (
77+ path : path ,
78+ query : name ? "name= #{ name } -#{ SecureRandom . hex ( 7 ) } " : nil ,
6879 body : configuration . to_json ,
6980 headers : { "Content-Type" => "application/json" }
7081 )
71- )
82+ end
7283 raise response . inspect unless response . status == 201
7384 JSON . load ( response . body )
7485 end
7586
7687 def start_container ( container_id , configuration )
7788 path = @docker_api_version + "/containers/#{ container_id } /start"
78- response = Excon . post (
79- @base_uri + path ,
80- tls_excon_arguments . merge (
89+ response = with_excon do | e |
90+ e . post (
91+ path : path ,
8192 body : configuration . to_json ,
8293 headers : { "Content-Type" => "application/json" }
8394 )
84- )
95+ end
8596 case response . status
8697 when 204
8798 true
@@ -94,14 +105,14 @@ def start_container(container_id, configuration)
94105
95106 def restart_container ( container_id , timeout = 30 )
96107 path = @docker_api_version + "/containers/#{ container_id } /restart?t=#{ timeout } "
97- response = Excon . post (
98- @base_uri + path ,
99- tls_excon_arguments . merge (
108+ response = with_excon do | e |
109+ e . post (
110+ path : path ,
100111 # Wait for both the docker stop timeout AND the kill AND
101112 # potentially a very slow HTTP server.
102113 read_timeout : timeout + 120
103114 )
104- )
115+ end
105116 case response . status
106117 when 204
107118 true
@@ -116,10 +127,11 @@ def restart_container(container_id, timeout = 30)
116127
117128 def inspect_container ( container_id )
118129 path = @docker_api_version + "/containers/#{ container_id } /json"
119- response = Excon . get (
120- @base_uri + path ,
121- tls_excon_arguments
122- )
130+ response = with_excon do |e |
131+ e . get (
132+ path : path ,
133+ )
134+ end
123135 raise response . inspect unless response . status == 200
124136 JSON . load ( response . body )
125137 end
@@ -172,4 +184,19 @@ def default_tls_args(tls_enabled)
172184 { }
173185 end
174186 end
187+
188+ def with_excon ( &block )
189+ if @ssh
190+ with_excon_via_ssh ( &block )
191+ else
192+ yield Excon . new ( @base_uri , tls_excon_arguments )
193+ end
194+ end
195+
196+ def with_excon_via_ssh
197+ Centurion ::SSH . with_docker_socket ( @base_uri , @ssh_user , @ssh_log_level ) do |socket |
198+ conn = Excon . new ( 'unix:///' , socket : socket )
199+ yield conn
200+ end
201+ end
175202end
0 commit comments