kontena-cli 0.17.0.pre1 → 0.17.0.pre2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1ad6422b172a48accf054239e4dab6b61fa03f55
4
- data.tar.gz: 536fafed2231e6fcece9120b06402aa88cab080b
3
+ metadata.gz: cc49a645052d88c4af58c2588b91c8579d56948b
4
+ data.tar.gz: 7cf02e974c1fdd082b7ee3895fe29e658680a89d
5
5
  SHA512:
6
- metadata.gz: 889ecc5b3aef9a47aab715c3bfc4cb1a5200589b2c8fab55ceb00c7ac5d95f2d2fb8ceb06638c5f3de870920de2102c3722f9c120d20b3c494c1c875a57942db
7
- data.tar.gz: 2140338ef86e138a7fdf5de202b7d8246e4402ade84327a493aea66307552daeca81c38a27b7b866804ef81cc219d95236713c65ff4736b83452c9fd624f034a
6
+ metadata.gz: 1f36d29da645638bf7ee06ad4c1f108d9c58dac907d3dd445b126c8cf6bee7e5edcace485fec66664d52c9deb03915097d1e55ad0806b22e7ba5ffb8435d48a9
7
+ data.tar.gz: 6874cbb4cac691b9f3477d3fc31f1e4004b7afafaab10dc34793b0cad756df653e8efd56116db4a237f7439ca023116c1f137bc64de35a2d14ea525185639574
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.17.0.pre1
1
+ 0.17.0.pre2
@@ -1,9 +1,11 @@
1
+ require_relative 'containers/list_command'
1
2
  require_relative 'containers/exec_command'
2
3
  require_relative 'containers/inspect_command'
3
4
  require_relative 'containers/logs_command'
4
5
 
5
6
  class Kontena::Cli::ContainerCommand < Kontena::Command
6
7
 
8
+ subcommand ["list", "ls"], "List grid containers", Kontena::Cli::Containers::ListCommand
7
9
  subcommand "exec", "Execute command inside a container", Kontena::Cli::Containers::ExecCommand
8
10
  subcommand "inspect", "Inspect the container", Kontena::Cli::Containers::InspectCommand
9
11
  subcommand "logs", "Show container logs", Kontena::Cli::Containers::LogsCommand
@@ -1,11 +1,9 @@
1
1
  require_relative '../grid_options'
2
- require_relative './containers_helper'
3
2
 
4
3
  module Kontena::Cli::Containers
5
4
  class ExecCommand < Kontena::Command
6
5
  include Kontena::Cli::Common
7
6
  include Kontena::Cli::GridOptions
8
- include ContainersHelper
9
7
 
10
8
  parameter "CONTAINER_ID", "Container id"
11
9
  parameter "CMD ...", "Command"
@@ -14,11 +12,8 @@ module Kontena::Cli::Containers
14
12
  require_api_url
15
13
  token = require_token
16
14
 
17
- cmd = build_command(cmd_list)
18
- payload = {cmd: ["sh", "-c", cmd]}
19
-
20
- service_name = container_id.match(/(.+)-(\d+)/)[1] rescue nil
21
- result = client(token).post("containers/#{current_grid}/#{service_name}/#{container_id}/exec", payload)
15
+ payload = {cmd: ["sh", "-c", Shellwords.join(cmd_list)]}
16
+ result = client(token).post("containers/#{current_grid}/#{container_id}/exec", payload)
22
17
 
23
18
  puts result[0].join(" ") unless result[0].size == 0
24
19
  STDERR.puts result[1].join(" ") unless result[1].size == 0
@@ -9,14 +9,8 @@ module Kontena::Cli::Containers
9
9
  require_api_url
10
10
  token = require_token
11
11
 
12
- match = container_id.match(/(.+)-(\d+)/)
13
- if match
14
- service_name = match[1]
15
- result = client(token).get("containers/#{current_grid}/#{service_name}/#{container_id}/inspect")
16
- puts JSON.pretty_generate(result)
17
- else
18
- exit_with_error("Cannot resolve container service")
19
- end
12
+ result = client(token).get("containers/#{current_grid}/#{container_id}/inspect")
13
+ puts JSON.pretty_generate(result)
20
14
  end
21
15
  end
22
16
  end
@@ -0,0 +1,60 @@
1
+ require_relative '../grid_options'
2
+
3
+ module Kontena::Cli::Containers
4
+ class ListCommand < Kontena::Command
5
+ include Kontena::Util
6
+ include Kontena::Cli::Common
7
+ include Kontena::Cli::GridOptions
8
+
9
+ option ['--all', '-a'], :flag, 'Show all containers'
10
+
11
+ def execute
12
+ require_api_url
13
+ token = require_token
14
+
15
+ params = '?'
16
+ params << 'all=1' if all?
17
+ result = client(token).get("containers/#{current_grid}#{params}")
18
+ containers = result['containers']
19
+ id_column = longest_string_in_array(containers.map {|c| "#{c['node']['name']}/#{c['name']}"})
20
+ image_column = longest_string_in_array(containers.map {|c| c['image'] })
21
+ columns = "%-#{id_column + 2}s %-#{image_column + 2}s %-30s %-20s %-10s"
22
+ puts columns % [ 'CONTAINER ID', 'IMAGE', 'COMMAND', 'CREATED', 'STATUS']
23
+ result['containers'].reverse.each do |container|
24
+ puts columns % [
25
+ "#{container['node']['name']}/#{container['name']}",
26
+ container['image'],
27
+ "\"#{container['cmd'].to_a.join(' ')[0..26]}\"",
28
+ "#{time_ago(container['created_at'])} ago",
29
+ container_status(container)
30
+ ]
31
+ end
32
+ end
33
+
34
+ def longest_string_in_array(array)
35
+ longest = 0
36
+ array.each do |item|
37
+ longest = item.length if item.length > longest
38
+ end
39
+
40
+ longest
41
+ end
42
+
43
+ def container_status(container)
44
+ s = container['state']
45
+ if s['paused']
46
+ 'paused'.freeze
47
+ elsif s['restarting']
48
+ 'restarting'.freeze
49
+ elsif s['oom_killed']
50
+ 'oom_killed'.freeze
51
+ elsif s['dead']
52
+ 'dead'.freeze
53
+ elsif s['running']
54
+ 'running'.freeze
55
+ else
56
+ 'stopped'.freeze
57
+ end
58
+ end
59
+ end
60
+ end
@@ -12,9 +12,7 @@ module Kontena::Cli::Containers
12
12
  def execute
13
13
  require_api_url
14
14
 
15
- service_name = container_id.match(/(.+)-(\d+)/)[1] rescue nil
16
-
17
- show_logs("containers/#{current_grid}/#{service_name}/#{container_id}/logs") do |log|
15
+ show_logs("containers/#{current_grid}/#{container_id}/logs") do |log|
18
16
  show_log(log)
19
17
  end
20
18
  end
@@ -87,6 +87,11 @@ module Kontena::Cli::Registry
87
87
 
88
88
  data = {
89
89
  name: 'registry',
90
+ stack: 'kontena/registry',
91
+ version: Kontena::Cli::VERSION,
92
+ source: '---',
93
+ registry: 'file://',
94
+ expose: 'api',
90
95
  services: [
91
96
  {
92
97
  name: 'api',
@@ -102,10 +107,11 @@ module Kontena::Cli::Registry
102
107
  }
103
108
 
104
109
  client(token).post("grids/#{current_grid}/stacks", data)
105
- client(token).post("stacks/#{current_grid}/registry/deploy", {})
110
+ deployment = client(token).post("stacks/#{current_grid}/registry/deploy", {})
106
111
  spinner "Deploying #{data[:name].colorize(:cyan)} stack " do
107
- sleep 1 until client(token).get("stacks/#{current_grid}/registry")['state'] == 'deploying'
108
- sleep 1 until client(token).get("stacks/#{current_grid}/registry")['state'] == 'running'
112
+ deployment['service_deploys'].each do |service_deploy|
113
+ wait_for_deploy_to_finish(token, service_deploy)
114
+ end
109
115
  end
110
116
  puts "\n"
111
117
  puts "Docker Registry #{REGISTRY_VERSION} is now running at registry.#{current_grid}.kontena.local."
@@ -7,7 +7,7 @@ module Kontena::Cli::Vpn
7
7
  require 'rbconfig'
8
8
  require_api_url
9
9
  payload = {cmd: ['/usr/local/bin/ovpn_getclient', 'KONTENA_VPN_CLIENT']}
10
- stdout, stderr = client(require_token).post("containers/#{current_grid}/vpn/vpn-1/exec", payload)
10
+ stdout, stderr = client(require_token).post("services/#{current_grid}/vpn/server/containers/1/exec", payload)
11
11
  if linux?
12
12
  stdout << "\n"
13
13
  stdout << "script-security 2 system\n"
@@ -12,14 +12,20 @@ module Kontena::Cli::Vpn
12
12
  token = require_token
13
13
  preferred_node = node
14
14
 
15
- vpn = client(token).get("services/#{current_grid}/vpn") rescue nil
16
- exit_with_error('Vpn already exists') if vpn
15
+ name = 'vpn'
16
+ vpn = client(token).get("stacks/#{current_grid}/#{name}") rescue nil
17
+ exit_with_error('Vpn stack already exists') if vpn
17
18
 
18
19
  node = find_node(token, preferred_node)
19
20
 
20
21
  vpn_ip = node_vpn_ip(node)
21
22
  data = {
22
- name: 'vpn',
23
+ name: name,
24
+ stack: 'kontena/vpn',
25
+ version: Kontena::Cli::VERSION,
26
+ registry: 'file://',
27
+ source: '---',
28
+ expose: 'server',
23
29
  services: [
24
30
  name: 'server',
25
31
  stateful: true,
@@ -36,13 +42,15 @@ module Kontena::Cli::Vpn
36
42
  affinity: ["node==#{node['name']}"]
37
43
  ]
38
44
  }
45
+
39
46
  client(token).post("grids/#{current_grid}/stacks", data)
40
- client(token).post("stacks/#{current_grid}/vpn/deploy", {})
41
- spinner "Deploying vpn service " do
42
- sleep 1 while client(token).get("stacks/#{current_grid}/vpn")['state'] == 'deploying'
43
- sleep 1 while client(token).get("stacks/#{current_grid}/vpn")['state'] == 'running'
47
+ deployment = client(token).post("stacks/#{current_grid}/#{name}/deploy", {})
48
+ spinner "Deploying #{pastel.cyan(name)} service " do
49
+ deployment['service_deploys'].each do |service_deploy|
50
+ wait_for_deploy_to_finish(token, service_deploy)
51
+ end
44
52
  end
45
- spinner "generating #{name.colorize(:cyan)} keys (this will take a while) " do
53
+ spinner "Generating #{pastel.cyan(name)} keys (this will take a while) " do
46
54
  wait_for_configuration_to_finish(token)
47
55
  end
48
56
  puts "#{name.colorize(:cyan)} service is now started (udp://#{vpn_ip}:1194)."
@@ -53,8 +61,8 @@ module Kontena::Cli::Vpn
53
61
  finished = false
54
62
  payload = {cmd: ['/usr/local/bin/ovpn_getclient', 'KONTENA_VPN_CLIENT']}
55
63
  until finished
56
- sleep 30
57
- stdout, stderr = client(require_token).post("containers/#{current_grid}/vpn/vpn-1/exec", payload)
64
+ sleep 3
65
+ stdout, stderr = client(require_token).post("services/#{current_grid}/vpn/server/containers/1/exec", payload)
58
66
  finished = true if stdout.join('').include?('BEGIN PRIVATE KEY'.freeze)
59
67
  end
60
68
 
@@ -11,11 +11,11 @@ module Kontena::Cli::Vpn
11
11
  confirm unless forced?
12
12
  name = 'vpn'
13
13
 
14
- vpn = client(token).get("stacks/#{current_grid}/vpn") rescue nil
14
+ vpn = client(token).get("stacks/#{current_grid}/#{name}") rescue nil
15
15
  exit_with_error("VPN stack does not exist") if vpn.nil?
16
16
 
17
17
  spinner "Removing #{name.colorize(:cyan)} service " do
18
- client(token).delete("stacks/#{current_grid}/vpn")
18
+ client(token).delete("stacks/#{current_grid}/#{name}")
19
19
  end
20
20
  end
21
21
  end
@@ -28,6 +28,30 @@ module Kontena
28
28
  nil
29
29
  end
30
30
 
31
+ def time_ago(time)
32
+ now = Time.now.to_i
33
+ time = DateTime.parse(time).to_time.to_i
34
+ diff = now - time
35
+ if diff > 60 * 60 * 24
36
+ "#{diff / 60 / 60 / 24} days"
37
+ elsif diff > 60 * 60
38
+ "#{diff / 60 / 60} hours"
39
+ elsif diff > 60
40
+ "#{diff / 60} minutes"
41
+ else
42
+ "#{diff} seconds"
43
+ end
44
+ end
45
+
46
+ def longest_string_in_array(array)
47
+ longest = 0
48
+ array.each do |item|
49
+ longest = item.length if item.length > longest
50
+ end
51
+
52
+ longest
53
+ end
54
+
31
55
  module_function(:which)
32
56
 
33
57
  module ClassMethods
@@ -0,0 +1,16 @@
1
+ require_relative "../../../spec_helper"
2
+ require 'kontena/cli/grid_options'
3
+ require "kontena/cli/containers/list_command"
4
+
5
+ describe Kontena::Cli::Containers::ListCommand do
6
+ include ClientHelpers
7
+
8
+ context "for a single container with logs" do
9
+
10
+ it "fetches containers" do
11
+ expect(client).to receive(:get).with('containers/test-grid?').and_return({'containers' => []})
12
+
13
+ subject.run([])
14
+ end
15
+ end
16
+ end
@@ -34,11 +34,11 @@ describe Kontena::Cli::Containers::LogsCommand do
34
34
  end
35
35
 
36
36
  it "shows all logs" do
37
- allow(client).to receive(:get).with('containers/test-grid/test-mysql/test-mysql-1/logs', {
37
+ allow(client).to receive(:get).with('containers/test-grid/node-1/test-mysql-1/logs', {
38
38
  limit: 100,
39
39
  }) { { 'logs' => logs } }
40
40
 
41
- expect { subject.run(['test-mysql-1']) }.to output(<<LOGS
41
+ expect { subject.run(['node-1/test-mysql-1']) }.to output(<<LOGS
42
42
  2016-09-07T15:19:04.362690 test-mysql-1: mysql log message 1
43
43
  2016-09-07T15:19:04.500000 test-mysql-1: mysql log message 2
44
44
  2016-09-07T15:19:06.100000 test-mysql-1: mysql log message 3
@@ -47,7 +47,7 @@ LOGS
47
47
  end
48
48
 
49
49
  it "errors for an invalid --lines" do
50
- expect { subject.run(["--lines=invalid", "test-mysql-1"]) }.to raise_error(Clamp::UsageError, "option '--lines': invalid value for Integer(): \"invalid\"")
50
+ expect { subject.run(["--lines=invalid", "node-1/test-mysql-1"]) }.to raise_error(Clamp::UsageError, "option '--lines': invalid value for Integer(): \"invalid\"")
51
51
  end
52
52
  end
53
53
  end
@@ -2,30 +2,27 @@ require_relative "../../../spec_helper"
2
2
  require "kontena/cli/vpn/create_command"
3
3
 
4
4
  describe Kontena::Cli::Vpn::CreateCommand do
5
-
5
+
6
6
  include ClientHelpers
7
7
 
8
8
  let(:subject) { described_class.new(File.basename($0)) }
9
9
 
10
10
  describe '#execute' do
11
11
  it 'should abort if vpn already exists' do
12
- expect(client).to receive(:get).with("services/test-grid/vpn").and_return({vpn: true})
12
+ expect(client).to receive(:get).with("stacks/test-grid/vpn").and_return({})
13
13
 
14
14
  expect {
15
15
  subject.execute
16
16
  }.to raise_error SystemExit
17
17
  end
18
-
19
-
20
18
  end
21
19
 
22
20
  describe '#find_node' do
23
-
24
21
  it 'should abort if no online nodes exists' do
25
22
  expect(client).to receive(:get).with("grids/test-grid/nodes").and_return(
26
- {
23
+ {
27
24
  'nodes' => [
28
- {'connected' => false},
25
+ {'connected' => false},
29
26
  {'connected' => false, 'public_ip' => '1.2.3.4'}
30
27
  ]
31
28
  })
@@ -37,9 +34,9 @@ describe Kontena::Cli::Vpn::CreateCommand do
37
34
 
38
35
  it 'should return first online node with public ip' do
39
36
  expect(client).to receive(:get).with("grids/test-grid/nodes").and_return(
40
- {
37
+ {
41
38
  'nodes' => [
42
- {'connected' => true},
39
+ {'connected' => true},
43
40
  {'connected' => true, 'public_ip' => '1.2.3.4'}
44
41
  ]
45
42
  })
@@ -50,9 +47,9 @@ describe Kontena::Cli::Vpn::CreateCommand do
50
47
 
51
48
  it 'should return preferred node' do
52
49
  expect(client).to receive(:get).with("grids/test-grid/nodes").and_return(
53
- {
50
+ {
54
51
  'nodes' => [
55
- {'connected' => true},
52
+ {'connected' => true},
56
53
  {'name' => 'preferred', 'connected' => true, 'public_ip' => '1.2.3.4'}
57
54
  ]
58
55
  })
@@ -63,9 +60,9 @@ describe Kontena::Cli::Vpn::CreateCommand do
63
60
 
64
61
  it 'should abort if no online nodes exists' do
65
62
  expect(client).to receive(:get).with("grids/test-grid/nodes").and_return(
66
- {
63
+ {
67
64
  'nodes' => [
68
- {'connected' => true},
65
+ {'connected' => true},
69
66
  {'name' => 'preferred', 'connected' => true, 'public_ip' => '1.2.3.4'}
70
67
  ]
71
68
  })
@@ -78,7 +75,6 @@ describe Kontena::Cli::Vpn::CreateCommand do
78
75
  end
79
76
 
80
77
  describe '#node_vpn_ip' do
81
-
82
78
  it 'return ip when set' do
83
79
  allow(subject).to receive(:ip).and_return('1.2.3.4')
84
80
 
@@ -111,6 +107,5 @@ describe Kontena::Cli::Vpn::CreateCommand do
111
107
  }
112
108
  expect(subject.node_vpn_ip(node)).to eq('10.1.1.2')
113
109
  end
114
-
115
110
  end
116
111
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kontena-cli
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.17.0.pre1
4
+ version: 0.17.0.pre2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kontena, Inc
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-11-21 00:00:00.000000000 Z
11
+ date: 2016-11-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -227,9 +227,9 @@ files:
227
227
  - lib/kontena/cli/common.rb
228
228
  - lib/kontena/cli/config.rb
229
229
  - lib/kontena/cli/container_command.rb
230
- - lib/kontena/cli/containers/containers_helper.rb
231
230
  - lib/kontena/cli/containers/exec_command.rb
232
231
  - lib/kontena/cli/containers/inspect_command.rb
232
+ - lib/kontena/cli/containers/list_command.rb
233
233
  - lib/kontena/cli/containers/logs_command.rb
234
234
  - lib/kontena/cli/etcd/common.rb
235
235
  - lib/kontena/cli/etcd/get_command.rb
@@ -440,7 +440,7 @@ files:
440
440
  - spec/kontena/cli/cloud/logout_command_spec.rb
441
441
  - spec/kontena/cli/cloud/master/add_command_spec.rb
442
442
  - spec/kontena/cli/common_spec.rb
443
- - spec/kontena/cli/containers/containers_helper_spec.rb
443
+ - spec/kontena/cli/containers/list_command_spec.rb
444
444
  - spec/kontena/cli/containers/logs_command_spec.rb
445
445
  - spec/kontena/cli/grids/trusted_subnets/add_command_spec.rb
446
446
  - spec/kontena/cli/grids/trusted_subnets/list_command_spec.rb
@@ -552,7 +552,7 @@ test_files:
552
552
  - spec/kontena/cli/cloud/logout_command_spec.rb
553
553
  - spec/kontena/cli/cloud/master/add_command_spec.rb
554
554
  - spec/kontena/cli/common_spec.rb
555
- - spec/kontena/cli/containers/containers_helper_spec.rb
555
+ - spec/kontena/cli/containers/list_command_spec.rb
556
556
  - spec/kontena/cli/containers/logs_command_spec.rb
557
557
  - spec/kontena/cli/grids/trusted_subnets/add_command_spec.rb
558
558
  - spec/kontena/cli/grids/trusted_subnets/list_command_spec.rb
@@ -1,22 +0,0 @@
1
- module Kontena
2
- module Cli
3
- module Containers
4
- module ContainersHelper
5
-
6
- # @param [Array<String>] args
7
- # @return [String]
8
- def build_command(args)
9
- return args.first if args.size == 1
10
-
11
- args.reduce('') do |cmd, arg|
12
- if arg.include?(' ') || arg.include?('"')
13
- arg = '"' + arg.gsub('"', '\\"') + '"'
14
- end
15
- cmd + ' ' + arg
16
- end.strip
17
- end
18
-
19
- end
20
- end
21
- end
22
- end
@@ -1,16 +0,0 @@
1
- require "kontena/cli/containers/containers_helper"
2
-
3
- describe Kontena::Cli::Containers::ContainersHelper do
4
- let(:subject) do
5
- Class.new { include Kontena::Cli::Containers::ContainersHelper }.new
6
- end
7
-
8
- describe '#build_command' do
9
- it 'parses commands correctly' do
10
- expect(subject.build_command(['echo $ID'])).to eq('echo $ID')
11
- expect(subject.build_command(['echo', 'ID', '$ID'])).to eq('echo ID $ID')
12
- expect(subject.build_command(['echo', 'ID: $ID'])).to eq('echo "ID: $ID"')
13
- expect(subject.build_command(['echo', '{"ID": "123"}'])).to eq('echo "{\\"ID\\": \\"123\\"}"')
14
- end
15
- end
16
- end