kontena-cli 1.2.0 → 1.2.1.rc1
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 +4 -4
- data/VERSION +1 -1
- data/lib/kontena/cli/stacks/common.rb +1 -1
- data/lib/kontena/cli/stacks/yaml/reader.rb +3 -3
- data/lib/kontena/cli/stacks/yaml/validator_v3.rb +30 -11
- data/lib/kontena/command.rb +1 -0
- data/omnibus/config/software/kontena.rb +1 -0
- data/spec/kontena/cli/stacks/common_spec.rb +102 -0
- data/spec/kontena/cli/stacks/yaml/validator_v3_spec.rb +19 -0
- data/spec/kontena/kontena_cli_spec.rb +8 -2
- metadata +6 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: b18a8f9e16992007d8e29291e6205621b696c764
|
|
4
|
+
data.tar.gz: b48e57f00c487866a628536651900c9ac85abc16
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 791b963130649a9850ac5f953557a5c8334ec7b479106293180c9ad2383157709f1e3b82394d8c38fd819a3420d7c6f134fd8260d9f5ff1209d162975de41b0d
|
|
7
|
+
data.tar.gz: 861eeadeb19f458d1738c46f10dc8c8580f62958d419313f76d13c6be1c080a33c344fa178d8d21e14c2472c7edbd14d92217d6244e2726c6c805b28f3330a33
|
data/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
1.2.
|
|
1
|
+
1.2.1.rc1
|
|
@@ -97,7 +97,7 @@ module Kontena::Cli::Stacks
|
|
|
97
97
|
end
|
|
98
98
|
|
|
99
99
|
def stack_read_and_dump(filename, name: nil, values: nil, defaults: nil)
|
|
100
|
-
reader = reader_from_yaml(filename, name: name, values: values)
|
|
100
|
+
reader = reader_from_yaml(filename, name: name, values: values, defaults: defaults)
|
|
101
101
|
stack = stack_from_reader(reader)
|
|
102
102
|
dump_variables(reader) if values_to
|
|
103
103
|
stack
|
|
@@ -73,7 +73,7 @@ module Kontena::Cli::Stacks
|
|
|
73
73
|
warnings: false
|
|
74
74
|
)
|
|
75
75
|
)
|
|
76
|
-
)
|
|
76
|
+
) || {}
|
|
77
77
|
rescue Psych::SyntaxError => ex
|
|
78
78
|
raise ex, "Error while parsing #{file} : #{ex.message}"
|
|
79
79
|
end
|
|
@@ -92,13 +92,13 @@ module Kontena::Cli::Stacks
|
|
|
92
92
|
raise_on_unknown: true
|
|
93
93
|
)
|
|
94
94
|
)
|
|
95
|
-
)
|
|
95
|
+
) || {}
|
|
96
96
|
rescue Psych::SyntaxError => ex
|
|
97
97
|
raise ex, "Error while parsing #{file} : #{ex.message}"
|
|
98
98
|
end
|
|
99
99
|
|
|
100
100
|
def raw_yaml
|
|
101
|
-
@raw_yaml ||= ::YAML.safe_load(raw_content)
|
|
101
|
+
@raw_yaml ||= ::YAML.safe_load(raw_content) || {}
|
|
102
102
|
end
|
|
103
103
|
|
|
104
104
|
# @return [Opto::Group]
|
|
@@ -31,6 +31,24 @@ module Kontena::Cli::Stacks
|
|
|
31
31
|
Validations::CustomValidators.load
|
|
32
32
|
end
|
|
33
33
|
|
|
34
|
+
# borrowed from server/app/helpers/volumes_helpers.rb
|
|
35
|
+
def parse_volume(vol)
|
|
36
|
+
elements = vol.split(':')
|
|
37
|
+
if elements.size >= 2 # Bind mount or volume used
|
|
38
|
+
if elements[0].start_with?('/') && elements[1] && elements[1].start_with?('/') # Bind mount
|
|
39
|
+
{bind_mount: elements[0], path: elements[1], flags: elements[2..-1].join(',')}
|
|
40
|
+
elsif !elements[0].start_with?('/') && elements[1].start_with?('/') # Real volume
|
|
41
|
+
{volume: elements[0], path: elements[1], flags: elements[2..-1].join(',')}
|
|
42
|
+
else
|
|
43
|
+
{error: "volume definition not in right format: #{vol}" }
|
|
44
|
+
end
|
|
45
|
+
elsif elements.size == 1 && elements[0].start_with?('/') # anon volume
|
|
46
|
+
{bind_mount: nil, path: elements[0], flags: nil} # anon vols do not support flags
|
|
47
|
+
else
|
|
48
|
+
{error: "volume definition not in right format: #{vol}" }
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
34
52
|
##
|
|
35
53
|
# @param [Hash] yaml
|
|
36
54
|
# @param [TrueClass|FalseClass] strict
|
|
@@ -55,18 +73,14 @@ module Kontena::Cli::Stacks
|
|
|
55
73
|
option_errors = validate_options(options)
|
|
56
74
|
result[:errors] << { 'services' => { service => option_errors.errors } } unless option_errors.valid?
|
|
57
75
|
if options['volumes']
|
|
58
|
-
|
|
59
|
-
mount_points.each do |mount_point, occurences|
|
|
60
|
-
next unless occurences > 1
|
|
61
|
-
result[:errors] << { 'services' => { service => { 'volumes' => { mount_point => "mount point defined #{occurences} times" } } } }
|
|
62
|
-
end
|
|
63
|
-
|
|
76
|
+
mount_path_occurences = Hash.new(0)
|
|
64
77
|
options['volumes'].each do |volume|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
78
|
+
parsed = parse_volume(volume)
|
|
79
|
+
if parsed[:error]
|
|
80
|
+
result[:errors] << { 'services' => { service => { 'volumes' => { volume => parsed[:error] } } } }
|
|
81
|
+
elsif parsed[:path]
|
|
82
|
+
mount_path_occurences[parsed[:path]] += 1
|
|
83
|
+
volume_name = parsed[:volume]
|
|
70
84
|
if volume_name && !volume_name.start_with?('/')
|
|
71
85
|
if yaml.key?('volumes')
|
|
72
86
|
unless yaml['volumes'][volume_name]
|
|
@@ -76,8 +90,13 @@ module Kontena::Cli::Stacks
|
|
|
76
90
|
result[:errors] << { 'services' => { service => { 'volumes' => { volume => 'defines volume name, but file does not contain volumes definitions' } } } }
|
|
77
91
|
end
|
|
78
92
|
end
|
|
93
|
+
else
|
|
94
|
+
result[:errors] << { 'services' => { service => { 'volumes' => { volume => 'mount point missing' } } } }
|
|
79
95
|
end
|
|
80
96
|
end
|
|
97
|
+
mount_path_occurences.select {|path, occurences| occurences > 1 }.each do |path, occurences|
|
|
98
|
+
result[:errors] << { 'services' => { service => { 'volumes' => { path => "mount point defined #{occurences} times" } } } }
|
|
99
|
+
end
|
|
81
100
|
end
|
|
82
101
|
end
|
|
83
102
|
else
|
data/lib/kontena/command.rb
CHANGED
|
@@ -210,6 +210,7 @@ class Kontena::Command < Clamp::Command
|
|
|
210
210
|
if ex.message.include?('Unable to verify certificate')
|
|
211
211
|
$stderr.puts " [#{Kontena.pastel.red('error')}] The server uses a certificate signed by an unknown authority."
|
|
212
212
|
$stderr.puts " You can trust this server by copying server CA pem file to: #{Kontena.pastel.yellow("~/.kontena/certs/<hostname>.pem")}"
|
|
213
|
+
$stderr.puts " If kontena cannot find your system ca bundle, you can set #{Kontena.pastel.yellow('SSL_CERT_DIR=/etc/ssl/certs')} env variable to load them from another location."
|
|
213
214
|
$stderr.puts " Protip: you can bypass the certificate check by setting #{Kontena.pastel.yellow('SSL_IGNORE_ERRORS=true')} env variable, but any data you send to the server could be intercepted by others."
|
|
214
215
|
abort
|
|
215
216
|
else
|
|
@@ -7,6 +7,7 @@ dependency "libxml2"
|
|
|
7
7
|
dependency "libxslt"
|
|
8
8
|
whitelist_file "./wrappers/sh/kontena"
|
|
9
9
|
build do
|
|
10
|
+
gem "install rb-readline -v 0.5.4 --no-ri --no-doc"
|
|
10
11
|
gem "install nokogiri -v 1.6.8 --no-ri --no-doc"
|
|
11
12
|
gem "install kontena-cli -v #{default_version} --no-ri --no-doc"
|
|
12
13
|
copy "sh/kontena", "#{install_dir}/bin/kontena"
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
require "kontena/cli/stacks/common"
|
|
2
|
+
require "kontena/cli/stacks/yaml/reader"
|
|
3
|
+
|
|
4
|
+
describe Kontena::Cli::Stacks::Common do
|
|
5
|
+
|
|
6
|
+
let(:klass) do
|
|
7
|
+
Class.new(Kontena::Command) do
|
|
8
|
+
include Kontena::Cli::Stacks::Common
|
|
9
|
+
include Kontena::Cli::Common
|
|
10
|
+
include Kontena::Cli::Stacks::Common::StackNameParam
|
|
11
|
+
include Kontena::Cli::Stacks::Common::StackFileOrNameParam
|
|
12
|
+
include Kontena::Cli::Stacks::Common::StackNameOption
|
|
13
|
+
include Kontena::Cli::Stacks::Common::StackValuesToOption
|
|
14
|
+
include Kontena::Cli::Stacks::Common::StackValuesFromOption
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
let(:subject) { klass.new('') }
|
|
19
|
+
|
|
20
|
+
context 'stack yaml reader methods' do
|
|
21
|
+
let(:reader) { double(:reader) }
|
|
22
|
+
|
|
23
|
+
before(:each) do
|
|
24
|
+
allow(reader).to receive(:execute).and_return({ errors: [], notifications: [] })
|
|
25
|
+
allow(reader).to receive(:raw_content).and_return("")
|
|
26
|
+
allow(reader).to receive(:stack_name).and_return('foo')
|
|
27
|
+
allow(subject).to receive(:set_env_variables).and_return(true)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
describe '#stack_read_and_dump' do
|
|
31
|
+
it 'passes args to reader' do
|
|
32
|
+
expect(Kontena::Cli::Stacks::YAML::Reader).to receive(:new).with('foo', values: { 'value' => 'value' }, defaults: { 'default' => 'default' }).and_return(reader)
|
|
33
|
+
subject.stack_read_and_dump('foo', name: 'name', values: { 'value' => 'value' }, defaults: { 'default' => 'default' })
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
it 'returns a stack hash' do
|
|
37
|
+
expect(Kontena::Cli::Stacks::YAML::Reader).to receive(:new).and_return(reader)
|
|
38
|
+
expect(subject.stack_read_and_dump('foo')).to be_kind_of Hash
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
describe '#stack_from_yaml' do
|
|
43
|
+
it 'passes args to reader' do
|
|
44
|
+
expect(Kontena::Cli::Stacks::YAML::Reader).to receive(:new).with('foo', values: { 'value' => 'value' }, defaults: { 'default' => 'default' }).and_return(reader)
|
|
45
|
+
subject.stack_from_yaml('foo', name: 'name', values: { 'value' => 'value' }, defaults: { 'default' => 'default' })
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
it 'returns a stack hash' do
|
|
49
|
+
expect(Kontena::Cli::Stacks::YAML::Reader).to receive(:new).and_return(reader)
|
|
50
|
+
expect(subject.stack_from_yaml('foo')).to be_kind_of Hash
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
describe '#reader_from_yaml' do
|
|
55
|
+
it 'passes args to reader' do
|
|
56
|
+
expect(Kontena::Cli::Stacks::YAML::Reader).to receive(:new).with('foo', values: { 'value' => 'value' }, defaults: { 'default' => 'default' }).and_return(reader)
|
|
57
|
+
subject.reader_from_yaml('foo', name: 'name', values: { 'value' => 'value' }, defaults: { 'default' => 'default' })
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
it 'returns a reader' do
|
|
61
|
+
expect(Kontena::Cli::Stacks::YAML::Reader).to receive(:new).and_return(reader)
|
|
62
|
+
expect(subject.reader_from_yaml('foo')).to eq reader
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
describe '#stack_name' do
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
describe '#stack_from_reader' do
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
describe '#stack_from_yaml' do
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
describe '#require_config_file' do
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
describe '#generate_volumes' do
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
describe '#generate_services' do
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
describe '#set_env_variables' do
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
describe '#current_dir' do
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
describe '#display_notifications' do
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
describe '#hint_on_validation_notifications' do
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
describe '#abort_on_validation_errors' do
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
describe '#stacks_client' do
|
|
101
|
+
end
|
|
102
|
+
end
|
|
@@ -324,6 +324,7 @@ describe Kontena::Cli::Stacks::YAML::ValidatorV3 do
|
|
|
324
324
|
|
|
325
325
|
}
|
|
326
326
|
end
|
|
327
|
+
|
|
327
328
|
it 'fails validation if volumes are not declared' do
|
|
328
329
|
result = subject.validate(stack)
|
|
329
330
|
expect(result[:errors]).not_to be_empty
|
|
@@ -361,6 +362,24 @@ describe Kontena::Cli::Stacks::YAML::ValidatorV3 do
|
|
|
361
362
|
expect(result[:errors]).to be_empty
|
|
362
363
|
end
|
|
363
364
|
|
|
365
|
+
it 'validation passes when mount points are defined with :ro' do
|
|
366
|
+
stack['services']['foo']['volumes'] = ['/var/foo:/foo:ro', '/tmp/foo:/bar:ro']
|
|
367
|
+
result = subject.validate(stack)
|
|
368
|
+
expect(result[:errors]).to be_empty
|
|
369
|
+
end
|
|
370
|
+
|
|
371
|
+
it 'validation fails when same mount point is defined multiple times' do
|
|
372
|
+
stack['services']['foo']['volumes'] = ['/var/foo:/foo', '/tmp/foo:/foo']
|
|
373
|
+
result = subject.validate(stack)
|
|
374
|
+
expect(result[:errors]).to include({"services"=>{"foo"=>{"volumes"=>{"/foo"=>"mount point defined 2 times"}}}})
|
|
375
|
+
end
|
|
376
|
+
|
|
377
|
+
it 'validation fails when same mount point is defined multiple times mixing :ro' do
|
|
378
|
+
stack['services']['foo']['volumes'] = ['/var/foo:/foo', '/tmp/foo:/foo:ro']
|
|
379
|
+
result = subject.validate(stack)
|
|
380
|
+
expect(result[:errors]).to include({"services"=>{"foo"=>{"volumes"=>{"/foo"=>"mount point defined 2 times"}}}})
|
|
381
|
+
end
|
|
382
|
+
|
|
364
383
|
it 'bind mount do not need ext volumes' do
|
|
365
384
|
stack['services']['foo']['volumes'] = ['/var/run/docker.sock:/var/run/docker.sock']
|
|
366
385
|
result = subject.validate(stack)
|
|
@@ -12,10 +12,16 @@ describe Kontena do
|
|
|
12
12
|
Kontena.reset_prompt
|
|
13
13
|
end
|
|
14
14
|
|
|
15
|
-
it 'uses light prompt on
|
|
16
|
-
|
|
15
|
+
it 'uses light prompt on simple terminals' do
|
|
16
|
+
expect(ENV).to receive(:[]).with('KONTENA_SIMPLE_TERM').and_return('true')
|
|
17
17
|
expect(Kontena.prompt).to be_kind_of(Kontena::LightPrompt)
|
|
18
18
|
end
|
|
19
|
+
|
|
20
|
+
it 'uses fancy prompt on fancy terminals' do
|
|
21
|
+
expect($stdout).to receive(:tty?).at_least(:once).and_return(true)
|
|
22
|
+
expect(ENV).to receive(:[]).with('KONTENA_SIMPLE_TERM').and_return(nil)
|
|
23
|
+
expect(Kontena.prompt).to be_kind_of(TTY::Prompt)
|
|
24
|
+
end
|
|
19
25
|
end
|
|
20
26
|
|
|
21
27
|
describe '#minor_version' do
|
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: 1.2.
|
|
4
|
+
version: 1.2.1.rc1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Kontena, Inc
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2017-04-
|
|
11
|
+
date: 2017-04-27 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: bundler
|
|
@@ -611,6 +611,7 @@ files:
|
|
|
611
611
|
- spec/kontena/cli/services/unlink_command_spec.rb
|
|
612
612
|
- spec/kontena/cli/services/update_command_spec.rb
|
|
613
613
|
- spec/kontena/cli/stacks/build_command_spec.rb
|
|
614
|
+
- spec/kontena/cli/stacks/common_spec.rb
|
|
614
615
|
- spec/kontena/cli/stacks/deploy_command_spec.rb
|
|
615
616
|
- spec/kontena/cli/stacks/events_command_spec.rb
|
|
616
617
|
- spec/kontena/cli/stacks/install_command_spec.rb
|
|
@@ -661,9 +662,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
661
662
|
version: 2.1.0
|
|
662
663
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
663
664
|
requirements:
|
|
664
|
-
- - "
|
|
665
|
+
- - ">"
|
|
665
666
|
- !ruby/object:Gem::Version
|
|
666
|
-
version:
|
|
667
|
+
version: 1.3.1
|
|
667
668
|
requirements: []
|
|
668
669
|
rubyforge_project:
|
|
669
670
|
rubygems_version: 2.6.8
|
|
@@ -756,6 +757,7 @@ test_files:
|
|
|
756
757
|
- spec/kontena/cli/services/unlink_command_spec.rb
|
|
757
758
|
- spec/kontena/cli/services/update_command_spec.rb
|
|
758
759
|
- spec/kontena/cli/stacks/build_command_spec.rb
|
|
760
|
+
- spec/kontena/cli/stacks/common_spec.rb
|
|
759
761
|
- spec/kontena/cli/stacks/deploy_command_spec.rb
|
|
760
762
|
- spec/kontena/cli/stacks/events_command_spec.rb
|
|
761
763
|
- spec/kontena/cli/stacks/install_command_spec.rb
|