kontena-cli 1.3.0.pre1 → 1.3.0.pre2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/VERSION +1 -1
- data/bin/kontena +2 -1
- data/lib/kontena/callback.rb +1 -1
- data/lib/kontena/callbacks/auth/01_list_and_select_grid_after_master_auth.rb +1 -2
- data/lib/kontena/callbacks/master/01_clear_current_master_after_terminate.rb +2 -3
- data/lib/kontena/callbacks/master/deploy/01_show_logo_before_deploy.rb +1 -2
- data/lib/kontena/callbacks/master/deploy/05_before_deploy_configuration_wizard.rb +2 -2
- data/lib/kontena/callbacks/master/deploy/40_install_ssl_certificate_after_deploy.rb +2 -2
- data/lib/kontena/callbacks/master/deploy/50_authenticate_after_deploy.rb +9 -9
- data/lib/kontena/callbacks/master/deploy/55_create_initial_grid_after_deploy.rb +2 -2
- data/lib/kontena/callbacks/master/deploy/56_set_server_provider_after_deploy.rb +1 -2
- data/lib/kontena/callbacks/master/deploy/60_configure_auth_provider_after_deploy.rb +1 -2
- data/lib/kontena/callbacks/master/deploy/70_invite_self_after_deploy.rb +2 -3
- data/lib/kontena/callbacks/master/deploy/90_proptip_after_deploy.rb +2 -2
- data/lib/kontena/cli/apps/common.rb +0 -1
- data/lib/kontena/cli/apps/init_command.rb +2 -0
- data/lib/kontena/cli/apps/kontena_yml_generator.rb +2 -1
- data/lib/kontena/cli/apps/list_command.rb +10 -2
- data/lib/kontena/cli/apps/yaml/reader.rb +2 -1
- data/lib/kontena/cli/apps/yaml/service_extender.rb +0 -1
- data/lib/kontena/cli/cloud/login_command.rb +51 -7
- data/lib/kontena/cli/cloud/master/list_command.rb +14 -11
- data/lib/kontena/cli/common.rb +36 -83
- data/lib/kontena/cli/config.rb +46 -29
- data/lib/kontena/cli/containers/list_command.rb +30 -41
- data/lib/kontena/cli/etcd/list_command.rb +12 -7
- data/lib/kontena/cli/external_registries/list_command.rb +14 -8
- data/lib/kontena/cli/grids/list_command.rb +18 -10
- data/lib/kontena/cli/grids/trusted_subnets/list_command.rb +7 -5
- data/lib/kontena/cli/grids/users/list_command.rb +9 -7
- data/lib/kontena/cli/localhost_web_server.rb +3 -3
- data/lib/kontena/cli/log_formatters/compact.rb +65 -0
- data/lib/kontena/cli/log_formatters/strip_color.rb +13 -0
- data/lib/kontena/cli/master/config/import_command.rb +2 -1
- data/lib/kontena/cli/master/config/set_command.rb +1 -1
- data/lib/kontena/cli/master/list_command.rb +16 -10
- data/lib/kontena/cli/master/token/list_command.rb +23 -12
- data/lib/kontena/cli/master/user/invite_command.rb +1 -1
- data/lib/kontena/cli/master/user/list_command.rb +17 -6
- data/lib/kontena/cli/nodes/labels/list_command.rb +3 -0
- data/lib/kontena/cli/nodes/list_command.rb +58 -37
- data/lib/kontena/cli/nodes/show_command.rb +1 -1
- data/lib/kontena/cli/plugins/install_command.rb +2 -2
- data/lib/kontena/cli/plugins/list_command.rb +19 -5
- data/lib/kontena/cli/plugins/uninstall_command.rb +1 -1
- data/lib/kontena/cli/services/containers_command.rb +7 -0
- data/lib/kontena/cli/services/envs/list_command.rb +6 -4
- data/lib/kontena/cli/services/list_command.rb +47 -36
- data/lib/kontena/cli/services/services_helper.rb +9 -16
- data/lib/kontena/cli/services/stats_command.rb +2 -1
- data/lib/kontena/cli/spinner.rb +3 -5
- data/lib/kontena/cli/stacks/common.rb +4 -4
- data/lib/kontena/cli/stacks/list_command.rb +42 -33
- data/lib/kontena/cli/stacks/registry/search_command.rb +6 -0
- data/lib/kontena/cli/stacks/registry/show_command.rb +2 -0
- data/lib/kontena/cli/stacks/registry_command.rb +1 -2
- data/lib/kontena/cli/stacks/validate_command.rb +1 -0
- data/lib/kontena/cli/stacks/yaml/reader.rb +3 -2
- data/lib/kontena/cli/stacks/yaml/service_extender.rb +0 -1
- data/lib/kontena/cli/stacks/yaml/validations.rb +1 -1
- data/lib/kontena/cli/table_generator.rb +125 -0
- data/lib/kontena/cli/vault/export_command.rb +7 -4
- data/lib/kontena/cli/vault/import_command.rb +3 -0
- data/lib/kontena/cli/vault/list_command.rb +23 -10
- data/lib/kontena/cli/volumes/create_command.rb +8 -4
- data/lib/kontena/cli/volumes/list_command.rb +15 -7
- data/lib/kontena/client.rb +44 -33
- data/lib/kontena/command.rb +7 -4
- data/lib/kontena/debug_instrumentor.rb +10 -9
- data/lib/kontena/main_command.rb +1 -3
- data/lib/kontena/plugin_manager.rb +15 -7
- data/lib/kontena/stacks_cache.rb +7 -7
- data/lib/kontena/stacks_client.rb +24 -5
- data/lib/kontena/util.rb +43 -15
- data/lib/kontena_cli.rb +71 -14
- data/spec/kontena/cli/cloud/login_command_spec.rb +42 -0
- data/spec/kontena/cli/containers/list_command_spec.rb +1 -2
- data/spec/kontena/cli/nodes/list_command_spec.rb +153 -126
- data/spec/kontena/cli/registry/create_spec.rb +22 -0
- data/spec/kontena/cli/services/stats_command_spec.rb +22 -0
- data/spec/kontena/cli/table_generator_spec.rb +118 -0
- data/spec/kontena/cli/version_command_spec.rb +2 -2
- data/spec/kontena/client_spec.rb +4 -3
- data/spec/support/client_helpers.rb +3 -3
- data/spec/support/output_helpers.rb +54 -8
- metadata +11 -2
data/lib/kontena/cli/common.rb
CHANGED
@@ -1,26 +1,21 @@
|
|
1
|
-
require '
|
2
|
-
require 'pastel'
|
3
|
-
require 'uri'
|
4
|
-
require 'io/console'
|
5
|
-
|
6
|
-
require 'kontena/cli/config'
|
7
|
-
require 'kontena/cli/spinner'
|
1
|
+
require 'forwardable'
|
8
2
|
|
9
3
|
module Kontena
|
10
4
|
module Cli
|
11
5
|
module Common
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
6
|
+
extend Forwardable
|
7
|
+
|
8
|
+
def_delegators :Kontena, :pastel, :prompt, :logger
|
9
|
+
def_delegators :prompt, :ask, :yes?
|
10
|
+
def_delegators :config,
|
11
|
+
:current_grid=, :require_current_grid, :current_master,
|
12
|
+
:current_master=, :require_current_master, :require_current_account,
|
13
|
+
:current_account
|
14
|
+
def_delegator Kontena::Cli::Spinner, :spin, :spinner
|
15
|
+
def_delegator Kontena::Cli::Config, :instance, :config
|
16
|
+
def_delegator Kontena::Cli::Config, :instance, :settings
|
17
|
+
def_delegator :config, :config_filename, :settings_filename
|
18
|
+
def_delegator :client, :server_version, :api_url_version
|
24
19
|
|
25
20
|
# Read from STDIN. If stdin is a console, use prompt to ask.
|
26
21
|
# @param [String] message
|
@@ -43,6 +38,10 @@ module Kontena
|
|
43
38
|
self.respond_to?(:verbose?) && self.verbose?
|
44
39
|
end
|
45
40
|
|
41
|
+
def running_quiet?
|
42
|
+
self.respond_to?(:quiet?) && self.quiet?
|
43
|
+
end
|
44
|
+
|
46
45
|
# Puts that puts even when self.silent?
|
47
46
|
def sputs(*msgs)
|
48
47
|
::Kernel.puts(*msgs)
|
@@ -87,9 +86,19 @@ module Kontena
|
|
87
86
|
def vspinner(msg, &block)
|
88
87
|
return vfakespinner(msg) unless block_given?
|
89
88
|
|
90
|
-
if running_verbose?
|
89
|
+
if running_verbose? && $stdout.tty?
|
91
90
|
spinner(msg, &block)
|
92
91
|
else
|
92
|
+
logger.debug { msg }
|
93
|
+
yield
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
def spin_if(obj_or_proc, message, &block)
|
98
|
+
if (obj_or_proc.respond_to?(:call) && obj_or_proc.call) || obj_or_proc
|
99
|
+
spinner(message, &block)
|
100
|
+
else
|
101
|
+
logger.debug { message }
|
93
102
|
yield
|
94
103
|
end
|
95
104
|
end
|
@@ -97,7 +106,7 @@ module Kontena
|
|
97
106
|
# Like vspinner but without actually running any block
|
98
107
|
def vfakespinner(msg, success: true)
|
99
108
|
if !running_verbose?
|
100
|
-
logger.debug msg
|
109
|
+
logger.debug { msg }
|
101
110
|
return
|
102
111
|
end
|
103
112
|
puts " [#{ success ? 'done'.colorize(:green) : 'fail'.colorize(:red)}] #{msg}"
|
@@ -113,10 +122,7 @@ module Kontena
|
|
113
122
|
$stderr.puts " [#{error}] #{msg}"
|
114
123
|
exit code
|
115
124
|
end
|
116
|
-
|
117
|
-
def config
|
118
|
-
Kontena::Cli::Config.instance
|
119
|
-
end
|
125
|
+
module_function :exit_with_error
|
120
126
|
|
121
127
|
def require_api_url
|
122
128
|
config.require_current_master.url
|
@@ -148,20 +154,8 @@ module Kontena
|
|
148
154
|
logger.debug "Refreshing failed: #{ex.class.name} : #{ex.message}"
|
149
155
|
end
|
150
156
|
|
151
|
-
def require_current_master
|
152
|
-
config.require_current_master
|
153
|
-
end
|
154
|
-
|
155
|
-
def require_current_account
|
156
|
-
config.require_current_account
|
157
|
-
end
|
158
|
-
|
159
|
-
def current_account
|
160
|
-
config.current_account
|
161
|
-
end
|
162
|
-
|
163
157
|
def kontena_account
|
164
|
-
@kontena_account ||= config.
|
158
|
+
@kontena_account ||= config.current_account
|
165
159
|
end
|
166
160
|
|
167
161
|
def cloud_auth?
|
@@ -171,10 +165,6 @@ module Kontena
|
|
171
165
|
true
|
172
166
|
end
|
173
167
|
|
174
|
-
def api_url_version
|
175
|
-
client.server_version
|
176
|
-
end
|
177
|
-
|
178
168
|
def cloud_client
|
179
169
|
@cloud_client ||= Kontena::Client.new(kontena_account.url, kontena_account.token, prefix: '/')
|
180
170
|
end
|
@@ -184,11 +174,13 @@ module Kontena
|
|
184
174
|
end
|
185
175
|
|
186
176
|
def client(token = nil, api_url = nil)
|
177
|
+
return @client if @client
|
178
|
+
|
187
179
|
if token.kind_of?(String)
|
188
180
|
token = Kontena::Cli::Config::Token.new(access_token: token)
|
189
181
|
end
|
190
182
|
|
191
|
-
@client
|
183
|
+
@client = Kontena::Client.new(
|
192
184
|
api_url || require_current_master.url,
|
193
185
|
token || require_current_master.token
|
194
186
|
)
|
@@ -198,26 +190,10 @@ module Kontena
|
|
198
190
|
@client = nil
|
199
191
|
end
|
200
192
|
|
201
|
-
def settings_filename
|
202
|
-
config.config_filename
|
203
|
-
end
|
204
|
-
|
205
|
-
def settings
|
206
|
-
config
|
207
|
-
end
|
208
|
-
|
209
193
|
def api_url
|
210
194
|
config.require_current_master.url
|
211
195
|
end
|
212
196
|
|
213
|
-
def current_grid=(grid)
|
214
|
-
config.current_grid=(grid)
|
215
|
-
end
|
216
|
-
|
217
|
-
def require_current_grid
|
218
|
-
config.require_current_grid
|
219
|
-
end
|
220
|
-
|
221
197
|
def clear_current_grid
|
222
198
|
current_master.delete_field(:grid) if require_current_master.respond_to?(:grid)
|
223
199
|
config.write
|
@@ -231,31 +207,11 @@ module Kontena
|
|
231
207
|
config.find_server_index(require_current_master.name)
|
232
208
|
end
|
233
209
|
|
234
|
-
def current_master
|
235
|
-
config.current_master
|
236
|
-
end
|
237
|
-
|
238
|
-
def current_master=(master_alias)
|
239
|
-
config.current_master = master_alias
|
240
|
-
end
|
241
|
-
|
242
210
|
def error(message = "Error")
|
243
211
|
prompt.error(message)
|
244
212
|
exit(1)
|
245
213
|
end
|
246
214
|
|
247
|
-
def ask(question = "")
|
248
|
-
prompt.ask(question)
|
249
|
-
end
|
250
|
-
|
251
|
-
def yes?(question = "")
|
252
|
-
prompt.yes?(question)
|
253
|
-
end
|
254
|
-
|
255
|
-
def prompt
|
256
|
-
::Kontena.prompt
|
257
|
-
end
|
258
|
-
|
259
215
|
def confirm_command(name, message = nil)
|
260
216
|
if self.respond_to?(:force?) && self.force?
|
261
217
|
return
|
@@ -289,10 +245,6 @@ module Kontena
|
|
289
245
|
config.add_server(master_info.merge('name' => server_name))
|
290
246
|
end
|
291
247
|
|
292
|
-
def spinner(msg, &block)
|
293
|
-
Kontena::Cli::Spinner.spin(msg, &block)
|
294
|
-
end
|
295
|
-
|
296
248
|
def any_key_to_continue_with_timeout(timeout=9)
|
297
249
|
return nil if running_silent?
|
298
250
|
return nil unless $stdout.tty?
|
@@ -352,6 +304,7 @@ module Kontena
|
|
352
304
|
def display_logo
|
353
305
|
puts File.read(File.expand_path('../../../../LOGO', __FILE__))
|
354
306
|
end
|
307
|
+
module_function :display_logo
|
355
308
|
end
|
356
309
|
end
|
357
310
|
end
|
data/lib/kontena/cli/config.rb
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
require 'ostruct'
|
2
2
|
require 'singleton'
|
3
3
|
require 'forwardable'
|
4
|
-
require 'json'
|
5
4
|
require 'logger'
|
5
|
+
autoload :JSON, 'json'
|
6
6
|
|
7
7
|
module Kontena
|
8
8
|
module Cli
|
@@ -13,10 +13,23 @@ module Kontena
|
|
13
13
|
class Config < OpenStruct
|
14
14
|
include Singleton
|
15
15
|
|
16
|
+
module Fields
|
17
|
+
def keys
|
18
|
+
@table.keys
|
19
|
+
end
|
20
|
+
|
21
|
+
def values_at(*fields)
|
22
|
+
(fields.first.is_a?(Array) ? fields.first : fields).map { |field| self[field] }
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
include Fields
|
27
|
+
|
16
28
|
attr_accessor :logger
|
17
29
|
attr_accessor :current_server
|
18
30
|
attr_reader :current_account
|
19
31
|
|
32
|
+
|
20
33
|
def self.reset_instance
|
21
34
|
Singleton.send :__init__, self
|
22
35
|
self
|
@@ -26,20 +39,22 @@ module Kontena
|
|
26
39
|
|
27
40
|
def initialize
|
28
41
|
super
|
29
|
-
@logger =
|
30
|
-
@logger.level = ENV["DEBUG"].nil? ? Logger::INFO : Logger::DEBUG
|
31
|
-
@logger.progname = 'CONFIG'
|
42
|
+
@logger = Kontena.logger
|
32
43
|
load_settings_from_env || load_settings_from_config_file
|
33
44
|
|
34
|
-
|
35
|
-
|
36
|
-
|
45
|
+
debug { "Configuration loaded with #{servers.count} servers." }
|
46
|
+
debug { "Current master: #{current_server || '(not selected)'}" }
|
47
|
+
debug { "Current grid: #{current_grid || '(not selected)'}" }
|
48
|
+
end
|
49
|
+
|
50
|
+
def debug(&block)
|
51
|
+
Kontena.logger.add(Logger::DEBUG, nil, 'CONFIG', &block)
|
37
52
|
end
|
38
53
|
|
39
54
|
# Craft a regular looking configuration based on ENV variables
|
40
55
|
def load_settings_from_env
|
41
56
|
return nil unless ENV['KONTENA_URL']
|
42
|
-
|
57
|
+
debug { 'Loading configuration from ENV' }
|
43
58
|
servers << Server.new(
|
44
59
|
url: ENV['KONTENA_URL'],
|
45
60
|
name: 'default',
|
@@ -48,11 +63,9 @@ module Kontena
|
|
48
63
|
parent_type: :master,
|
49
64
|
parent_name: 'default'
|
50
65
|
)
|
51
|
-
accounts << Account.new(
|
52
|
-
|
53
|
-
|
54
|
-
token: Token.new(access_token: ENV['KONTENA_ACCOUNT_TOKEN'], parent_type: :account, parent_name: 'default')
|
55
|
-
)
|
66
|
+
accounts << Account.new(kontena_account_data.merge(
|
67
|
+
token: Token.new(access_token: ENV['KONTENA_CLOUD_TOKEN'], parent_type: :account, parent_name: 'default')
|
68
|
+
))
|
56
69
|
|
57
70
|
self.current_master = 'default'
|
58
71
|
self.current_account = 'kontena'
|
@@ -84,7 +97,7 @@ module Kontena
|
|
84
97
|
if servers.find { |s| s['name'] == server.name}
|
85
98
|
server.name = "#{server.name}-2"
|
86
99
|
server.name.succ! until servers.find { |s| s['name'] == server.name }.nil?
|
87
|
-
|
100
|
+
debug { "Renamed server to #{server.name} because a duplicate was found in config" }
|
88
101
|
end
|
89
102
|
servers << server
|
90
103
|
end
|
@@ -115,22 +128,23 @@ module Kontena
|
|
115
128
|
accounts.delete_at(master_index) if master_index
|
116
129
|
accounts << Account.new(master_account_data)
|
117
130
|
|
118
|
-
self.current_account = settings['current_account'] || 'kontena'
|
131
|
+
self.current_account = ENV['KONTENA_CLOUD'] || settings['current_account'] || 'kontena'
|
119
132
|
end
|
120
133
|
|
121
134
|
def kontena_account_data
|
122
135
|
{
|
123
136
|
name: 'kontena',
|
124
|
-
url: 'https://cloud-api.kontena.io',
|
125
|
-
stacks_url: 'https://stacks.kontena.io',
|
126
|
-
token_endpoint: 'https://cloud-api.kontena.io/oauth2/token',
|
127
|
-
authorization_endpoint: 'https://cloud.kontena.io/login/oauth/authorize',
|
128
|
-
userinfo_endpoint: 'https://cloud-api.kontena.io/user',
|
129
|
-
token_post_content_type: 'application/x-www-form-urlencoded',
|
130
|
-
code_requires_basic_auth:
|
131
|
-
token_method: 'post',
|
132
|
-
scope: 'user',
|
133
|
-
client_id: nil
|
137
|
+
url: ENV['KONTENA_CLOUD_URL'] || 'https://cloud-api.kontena.io',
|
138
|
+
stacks_url: ENV['KONTENA_STACK_REGISTRY_URL'] || 'https://stacks.kontena.io',
|
139
|
+
token_endpoint: ENV['AUTH_TOKEN_ENDPOINT'] || 'https://cloud-api.kontena.io/oauth2/token',
|
140
|
+
authorization_endpoint: ENV['AUTH_AUTHORIZE_ENDPOINT'] || 'https://cloud.kontena.io/login/oauth/authorize',
|
141
|
+
userinfo_endpoint: ENV['AUTH_USERINFO_ENDPOINT'] || 'https://cloud-api.kontena.io/user',
|
142
|
+
token_post_content_type: ENV['AUTH_TOKEN_POST_CONTENT_TYPE'] || 'application/x-www-form-urlencoded',
|
143
|
+
code_requires_basic_auth: ENV['AUTH_CODE_REQUIRES_BASIC_AUTH'].to_s == true,
|
144
|
+
token_method: ENV['AUTH_TOKEN_METHOD'] || 'post',
|
145
|
+
scope: ENV['AUTH_USERINFO_SCOPE'] || 'user',
|
146
|
+
client_id: nil,
|
147
|
+
stacks_read_authentication: ENV['KONTENA_STACK_REGISTRY_READ_AUTHENTICATION'].to_s == 'true'
|
134
148
|
}
|
135
149
|
end
|
136
150
|
|
@@ -157,7 +171,7 @@ module Kontena
|
|
157
171
|
#
|
158
172
|
# @return [Hash]
|
159
173
|
def default_settings
|
160
|
-
|
174
|
+
debug { 'Configuration file not found, using default settings.' }
|
161
175
|
{
|
162
176
|
'current_server' => 'default',
|
163
177
|
'servers' => []
|
@@ -169,7 +183,7 @@ module Kontena
|
|
169
183
|
# @param [Hash] settings_hash
|
170
184
|
# @return [Hash] migrated_settings_hash
|
171
185
|
def migrate_legacy_settings(settings)
|
172
|
-
|
186
|
+
debug { "Migrating from legacy style configuration" }
|
173
187
|
{
|
174
188
|
'current_server' => 'default',
|
175
189
|
'servers' => [
|
@@ -186,7 +200,7 @@ module Kontena
|
|
186
200
|
#
|
187
201
|
# @return [Hash] config_data
|
188
202
|
def parse_config_file
|
189
|
-
|
203
|
+
debug { "Loading configuration from #{config_filename}" }
|
190
204
|
settings = JSON.load(File.read(config_filename))
|
191
205
|
if settings.has_key?('server')
|
192
206
|
settings = migrate_legacy_settings(settings)
|
@@ -437,7 +451,7 @@ module Kontena
|
|
437
451
|
# Does nothing if using settings from environment variables.
|
438
452
|
def write
|
439
453
|
return nil if ENV['KONTENA_URL']
|
440
|
-
|
454
|
+
debug { "Writing configuration to #{config_filename}" }
|
441
455
|
File.write(config_filename, to_json)
|
442
456
|
end
|
443
457
|
|
@@ -468,6 +482,7 @@ module Kontena
|
|
468
482
|
end
|
469
483
|
|
470
484
|
class Account < OpenStruct
|
485
|
+
include Fields
|
471
486
|
include TokenSerializer
|
472
487
|
include ConfigurationInstance
|
473
488
|
|
@@ -484,6 +499,7 @@ module Kontena
|
|
484
499
|
end
|
485
500
|
|
486
501
|
class Server < OpenStruct
|
502
|
+
include Fields
|
487
503
|
include TokenSerializer
|
488
504
|
include ConfigurationInstance
|
489
505
|
|
@@ -494,6 +510,7 @@ module Kontena
|
|
494
510
|
end
|
495
511
|
|
496
512
|
class Token < OpenStruct
|
513
|
+
include Fields
|
497
514
|
include ConfigurationInstance
|
498
515
|
|
499
516
|
# Hash representation of token data
|
@@ -3,56 +3,45 @@ module Kontena::Cli::Containers
|
|
3
3
|
include Kontena::Util
|
4
4
|
include Kontena::Cli::Common
|
5
5
|
include Kontena::Cli::GridOptions
|
6
|
+
include Kontena::Cli::TableGenerator::Helper
|
6
7
|
|
7
|
-
option ['
|
8
|
+
option ['-a', '--all'], :flag, 'Show all containers'
|
9
|
+
|
10
|
+
requires_current_master
|
11
|
+
requires_current_master_token
|
12
|
+
|
13
|
+
NON_STOP_STATES = ['paused', 'restarting', 'oom_killed', 'dead', 'running']
|
14
|
+
|
15
|
+
def fields
|
16
|
+
return ['id'] if quiet?
|
17
|
+
{ container_id: 'id', image: 'image', command: 'cmd', created: 'created_at', status: 'state' }
|
18
|
+
end
|
8
19
|
|
9
20
|
def execute
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
params = '?'
|
14
|
-
params << 'all=1' if all?
|
15
|
-
result = client(token).get("containers/#{current_grid}#{params}")
|
16
|
-
containers = result['containers']
|
17
|
-
id_column = longest_string_in_array(containers.map {|c| "#{c['node']['name']}/#{c['name']}"})
|
18
|
-
image_column = longest_string_in_array(containers.map {|c| c['image'] })
|
19
|
-
columns = "%-#{id_column + 2}s %-#{image_column + 2}s %-30s %-20s %-10s"
|
20
|
-
puts columns % [ 'CONTAINER ID', 'IMAGE', 'COMMAND', 'CREATED', 'STATUS']
|
21
|
-
result['containers'].reverse.each do |container|
|
22
|
-
puts columns % [
|
23
|
-
"#{container['node']['name']}/#{container['name']}",
|
24
|
-
container['image'],
|
25
|
-
"\"#{container['cmd'].to_a.join(' ')[0..26]}\"",
|
26
|
-
"#{time_ago(container['created_at'])} ago",
|
27
|
-
container_status(container)
|
28
|
-
]
|
21
|
+
result = spin_if(!quiet?, "Retrieving container list") do
|
22
|
+
Array(client.get("containers/#{current_grid}#{'?all=1' if all?}")['containers'])
|
29
23
|
end
|
30
|
-
end
|
31
24
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
25
|
+
print_table(result.reverse) do |row|
|
26
|
+
row['id'] = container_id(row)
|
27
|
+
row['created_at'] = time_ago(row['created_at'])
|
28
|
+
row['cmd'] = truncate_cmd(row)
|
29
|
+
row['state'] = container_state(row)
|
36
30
|
end
|
31
|
+
end
|
37
32
|
|
38
|
-
|
33
|
+
def container_id(row)
|
34
|
+
"#{row['node']['name']}/#{row['name']}"
|
39
35
|
end
|
40
36
|
|
41
|
-
def
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
elsif s['dead']
|
50
|
-
'dead'.freeze
|
51
|
-
elsif s['running']
|
52
|
-
'running'.freeze
|
53
|
-
else
|
54
|
-
'stopped'.freeze
|
55
|
-
end
|
37
|
+
def truncate_cmd(row)
|
38
|
+
cmd = row['cmd'].nil? ? '' : row['cmd'].join(' ')
|
39
|
+
cmd = "#{cmd[0..24]}#{pastel.cyan('..')}" if cmd.length > 26
|
40
|
+
"\"#{cmd}\""
|
41
|
+
end
|
42
|
+
|
43
|
+
def container_state(row)
|
44
|
+
NON_STOP_STATES.find { |state| row.fetch('state', {})[state] == true } || pastel.cyan('stopped')
|
56
45
|
end
|
57
46
|
end
|
58
47
|
end
|